Beside an older comparison tool
Why a semantic diff and a netlist-export spreadsheet can disagree on the same two revisions, and which one is reading the design.
A team moving to agni diff and its audit tables usually has an older comparison beside it: a netlist
export run through a spreadsheet, or a script that diffs two exports line by line. The two will
disagree on some rows of the same pair of revisions, and most of those rows come from the export, not
the design. This page goes through the kinds we have seen, each on a small synthetic fixture, so you
can tell a real change from an artifact of how the old tool read the file.
agni does not reproduce an export’s mistakes to make the numbers match. Each row it reports is a fact about the design, so the comparison is worth having.
A pin named by a letter ¶
Diodes, transistors and connectors often name pins by letter: K and A on a diode, G, D and
S on a FET. Some exports split a pin reference with a pattern that expects a digit. Such an export
drops those pins, and their net then reads as changed between two identical revisions. agni keeps
the pin under its own name, so the same pair diffs clean:
$ agni diff letter_pin_rev_a.edn letter_pin_rev_b.edn
diff letter_pin_rev_a.edn -> letter_pin_rev_b.edn
Components: +0 -0 ~0
Nets: new 0 deleted 0 renamed 0 hard 0 soft 0
$ agni query letter_pin_rev_a.edn 'pin.net(?r, ?p, ?n) => ?r, ?p, ?n'
r p n provenance
D_K_ONLY A NET_ANODE_SIDE letter_pin_rev_a.edn
D_K_ONLY K NET_CATHODE_SIDE letter_pin_rev_a.edn
R1 1 NET_CATHODE_SIDE letter_pin_rev_a.edn
3 result(s)
If the older table shows a net as new in one revision and deleted in the other, and every pin on it is named by a letter, this is the likely cause.
A net with one pin ¶
A net that reaches a single pin is legitimate. It is a strap that leaves one side of a resistor open, or a test pad named for what it carries, and some exports leave it out to match another tool’s count. agni lists it, so its net count can be higher than the spreadsheet’s by the number of one-pin nets:
$ agni query one_pin_net.tel 'net.pin_count(?n, ?c) => ?n, ?c'
n c provenance
STRAP_1PIN 1 one_pin_net.tel
1 result(s)
single-pin-net reports such a net unless something marks it no-connect, so the extra row is a
question worth asking rather than noise.
A part named by an EDIF identifier ¶
An EDIF identifier cannot hold a -, so a netlist names a cell like PART-07 by a stand-in such as
PART_07 and carries the real name in (rename PART_07 "PART-07"). A tool keying its parts table on
the identifier lists PART_07, and one keying on the part number property lists PART-07, so the same
part can appear under two keys. agni reads the part number from the property’s string and names the
part type by the rename, never by the identifier:
$ agni query edif_renamed_part.edn 'component.mpn(?r, ?m) => ?r, ?m'
r m provenance
U1 PART-07 edif_renamed_part.edn
1 result(s)
Two package lines sharing a footprint ¶
A Telesis netlist lists part numbers in $PACKAGES, one line per part number, and two lines can name
the same footprint. agni gives each part the part number of its own line (agni issue 835). Some
exports drop a block’s last line. Such an export loses that line’s parts, and a parts table then
shows them as removed:
$ agni query duplicate_footprint_two_mpns.tel 'component.mpn(?r, ?m) => ?r, ?m'
r m provenance
TP_A MPN_SMALL_PAD duplicate_footprint_two_mpns.tel
TP_B MPN_LARGE_PAD duplicate_footprint_two_mpns.tel
2 result(s)
Reading a disagreement ¶
When the two tables disagree on a row, check the row against the design itself with one query, as each section above does, rather than against the other table. If agni’s answer matches the file, the row is an artifact of the export. Record which of these kinds it is, and the next reviewer does not have to do the same work. If it does not, that is a defect in agni’s reading of the file, and worth an issue with the smallest file that shows it.