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.