P3.2: source precedence + model-vs-netlist conflict check
Rank the spec sources (spec_source_rank: UserOverride > Bsdl > ConnectorModel > Inferred > Imported); apply_model now refuses to overwrite a spec owned by a higher-rank source, so one model never clobbers a more authoritative one. New check_source_conflicts(System*) emits SourceConflict for a pin the BSDL declares power/ground (a must-connect rail) that the netlist leaves unconnected — a rail floated in the schematic; surfaced as a sixth `verify` pass. Unit tests (75 cases) green; the real 8-card system reports 0 conflicts (its rails are all connected) while the JTAG findings remain. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -159,3 +159,23 @@ TEST_CASE("check_jtag_chain reports an incomplete TAP") {
|
||||
auto a = check_jtag_chain(&sys);
|
||||
CHECK(count_kind(a, AnomalyKind::JtagTapIncomplete) == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("check_source_conflicts flags a BSDL rail left unconnected") {
|
||||
System sys;
|
||||
Module *m = sys.modules()->merge("M");
|
||||
Part *u = new Part("U1");
|
||||
m->add(u);
|
||||
|
||||
// A BSDL power pin with no signal → conflict (a rail floated in the netlist).
|
||||
Pin *vcc = new Pin("VCC");
|
||||
vcc->spec.function = PinFunction::Power;
|
||||
vcc->spec.source = SpecSource::Bsdl;
|
||||
u->add(vcc);
|
||||
|
||||
// A BSDL ground pin that IS connected → no conflict.
|
||||
Pin *gnd = mkpin(u, "GND", PinDirection::Power, PinFunction::Ground);
|
||||
wire(m, "GNDNET", {gnd, mkpin(u, "X", PinDirection::Out, PinFunction::Signal)});
|
||||
|
||||
auto a = check_source_conflicts(&sys);
|
||||
CHECK(count_kind(a, AnomalyKind::SourceConflict) == 1);
|
||||
}
|
||||
|
||||
@@ -68,3 +68,18 @@ TEST_CASE("apply_model does not overwrite a spec the model is silent about") {
|
||||
CHECK(part.get("DATA")->spec.function == PinFunction::Signal);
|
||||
CHECK(part.get("DATA")->spec.source == SpecSource::Bsdl);
|
||||
}
|
||||
|
||||
TEST_CASE("apply_model never overwrites a higher-precedence source") {
|
||||
Part part("U3");
|
||||
Pin *p = new Pin("VCC");
|
||||
p->spec.function = PinFunction::Ground; // user-set, deliberately != the model
|
||||
p->spec.source = SpecSource::UserOverride;
|
||||
part.add(p);
|
||||
|
||||
FakeModel m; // would set VCC = Power / Bsdl
|
||||
apply_model(&part, m);
|
||||
|
||||
// UserOverride (rank 5) outranks Bsdl (rank 4): kept untouched.
|
||||
CHECK(part.get("VCC")->spec.source == SpecSource::UserOverride);
|
||||
CHECK(part.get("VCC")->spec.function == PinFunction::Ground);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user