#include "core/app/verify.hpp" #include "core/domain/bsdl_check.hpp" #include "core/domain/connect.hpp" #include "core/domain/modules.hpp" #include "core/domain/nets.hpp" #include "core/domain/parts.hpp" #include "core/domain/pins.hpp" #include "core/domain/signals.hpp" #include "core/domain/system.hpp" #include #include #include namespace app { VerifyReport verify(System *sys) { VerifyReport r; if (!sys) return r; // Pass 1 — typed pins: expected (model) vs actual (net) signal type. for (auto &mkv : *sys->modules()) { Module *mod = mkv.second; for (auto &pkv : *mod) { Part *prt = pkv.second; if (prt->connector_type.empty()) continue; for (auto &nkv : *prt) { Pin *pin = nkv.second; ++r.typed_pins; SignalType expected = pin->expected_signal_type(); if (expected == SignalType::Other) continue; Signal *s = pin->signal(); SignalType actual = s ? s->type : SignalType::Other; if (actual == expected) continue; RoleMismatch m; m.module = mod->name; m.part = prt->name; m.pin = pin->name; m.signal = s ? s->name : std::string("(NC)"); m.expected = expected; m.actual = actual; r.role_mismatches.push_back(std::move(m)); } } } // Pass 2 — bridged nets: flag Power/GndShield mixing. Compute the nets once // here and reuse them for the model checks below. std::vector nets = compute_all_nets(sys); r.total_nets = (int)nets.size(); for (const Net &n : nets) { if (n.members.size() < 2) continue; ++r.bridged_nets; SignalType dom; if (net_type_consistent(n, dom)) continue; NetInconsistency ni; for (const auto &mp : n.members) ni.members.push_back({mp.first->name, mp.second->name, mp.second->type}); r.net_inconsistencies.push_back(std::move(ni)); } // Pass 3 — orphans: pins with no signal and not bridged via a connection. std::unordered_set bridged_pins; for (auto &ckv : *sys->connections()) for (auto &wp : ckv.second->pin_map) { if (wp.first) bridged_pins.insert(wp.first); if (wp.second) bridged_pins.insert(wp.second); } for (auto &mkv : *sys->modules()) for (auto &pkv : *mkv.second) for (auto &nkv : *pkv.second) { Pin *pin = nkv.second; if (pin->signal() || bridged_pins.count(pin)) continue; bool dropped; if (pin->nc_origin == NcOrigin::ImportedUnconnected) { ++r.orphan_imported; dropped = false; } else if (pin->nc_origin == NcOrigin::DroppedSingleton) { ++r.orphan_dropped; dropped = true; } else { continue; } r.orphans.push_back({mkv.first, pkv.first, nkv.first, dropped}); } // Passes 4-7 — model-driven checks (reuse the nets from pass 2). r.pin_anomalies = check_pin_specs(sys, &nets); r.jtag_anomalies = check_jtag_chain(sys, &nets); r.conflict_anomalies = check_source_conflicts(sys); r.completeness_anomalies = check_bsdl_completeness(sys); return r; } } // namespace app