#include "system/nets.hpp" #include "system/connect.hpp" #include "system/modules.hpp" #include "system/parts.hpp" #include "system/pins.hpp" #include "system/signals.hpp" #include "system/system.hpp" #include #include #include namespace { using SigKey = std::pair; struct SigKeyHash { size_t operator()(const SigKey &k) const noexcept { return std::hash()(k.first) ^ (std::hash()(k.second) << 1); } }; std::unordered_map> build_bridges(System *sys) { std::unordered_map> br; if (!sys || !sys->connections()) return br; for (auto &kv : *sys->connections()) { for (auto &wp : kv.second->pin_map) { br[wp.first].push_back(wp.second); br[wp.second].push_back(wp.first); } } return br; } void bfs_net(const std::unordered_map> &bridges, Module *start_m, Signal *start_s, std::unordered_set &visited, Net &out) { if (!start_m || !start_s) return; SigKey start{start_m, start_s}; if (!visited.insert(start).second) return; std::queue q; q.push(start); while (!q.empty()) { auto [m, s] = q.front(); q.pop(); out.members.emplace_back(m, s); for (auto &pkv : *s) { auto it = bridges.find(pkv.second); if (it == bridges.end()) continue; for (Pin *other : it->second) { Signal *os = other->signal(); if (!os) continue; Part *opart = other->prnt; if (!opart) continue; Module *om = opart->prnt; if (!om) continue; SigKey k{om, os}; if (visited.insert(k).second) q.push(k); } } } } } // namespace Net find_net(System *sys, Module *m, Signal *s) { Net n; if (!sys || !m || !s) return n; auto bridges = build_bridges(sys); std::unordered_set visited; bfs_net(bridges, m, s, visited, n); return n; } Net find_net(System *sys, Pin *pin) { if (!sys || !pin || !pin->signal() || !pin->prnt) return {}; return find_net(sys, pin->prnt->prnt, pin->signal()); } std::vector compute_all_nets(System *sys) { std::vector nets; if (!sys || !sys->modules()) return nets; auto bridges = build_bridges(sys); std::unordered_set visited; for (auto &mkv : *sys->modules()) { Module *m = mkv.second; if (!m->signals) continue; for (auto &skv : *m->signals) { SigKey k{m, skv.second}; if (visited.count(k)) continue; Net n; bfs_net(bridges, m, skv.second, visited, n); if (!n.members.empty()) nets.push_back(std::move(n)); } } return nets; } bool net_type_consistent(const Net &net, SignalType &dominant) { bool seen_power = false, seen_gnd = false; for (auto &mp : net.members) { if (!mp.second) continue; switch (mp.second->type) { case SignalType::Power: seen_power = true; break; case SignalType::GndShield: seen_gnd = true; break; default: break; } } if (seen_power && seen_gnd) { dominant = SignalType::Power; return false; } dominant = seen_power ? SignalType::Power : seen_gnd ? SignalType::GndShield : SignalType::Other; return true; }