pcb-rnd knowledge pool
Netlist rewrite, hierarchic netlists
netlist2 by Tibor 'Igor2' Palinkas on 2019-02-16 | Tags: insight, netlist, hierarchic, hierarchical |
Abstract: Why the netlist code needs a rewrite and how hierarchic netlists will be eventually supported. Related topics: rats nest and subcircuits.
What's wrong with the old netlist code
The old netlist code is written around the GUI, not around a clean data model:
- Because of displaying reasons, probably inherited from the old Xaw port, the first two characters of the netname are special chars. The second character is a space and the first character is a space or a '*' for 'disable rats' flag. This hack saved a few bytes back when it mattered, but made the code more complicated everywhere.
- The data is stored in memory modelling the GUI, not modelling the situation we want to represent. Terms like "menu" and "entry" are used instead of "network" or "terminal", which doesn't make the code readable
- The old rat code that should run find.c to figure existing connections and match it up with the netlist is more complicated than it needs to be. It is probably both because the suboptimal API of the old find.c implementation and the suboptimal API of the old netlist code. Find.c got rewritten for the last release, netlist is being rewritten now: this gives us a chance to rewrite the rat code as well.
- There is no provision for hierarchic netlists.
Hierarchy in netlist and subcircuits
We normally work with a flat netlist. The netlist represents copper connections on the board. In the same time subcircuits are black boxes: we do have some information about them (e.g. internal connections between terminals) but we generally have no idea about what network is in there.
This setup is fine as long as a subcircuit represents an "atomic" component, e.g. an integrated circuit: we know it's really a bunch of transistors and wiring, but we are not interested in modelling it, for the pcb layout it is enough to place the terminals and take it as a black box.
However, the other important application of subcircuits will be reusable PCB layout modules. This requires subc-in-subc support, so such a module can contain further subcircuits (for parts).
A trivial example is a stereo audio amplifier: the user draws one channel as a subcircuit on the schematics and then a higher level schematic page will reference two channels. In pcb-rnd the user will be able to draw one channel as a subcircuit and then place two of them on the board. A channel would include a lot of wiring, vias and of course a few subcircuits for the parts (e.g. transistors) - this is subc-in-subc.
Implementation details
The above stereo amplifier would work like this. pcb-rnd would get a hierarchical netlist:
- a small, top level, flat board netlist - it would list a few connectors and two amplifier components, one for each channel
- for the connectors, the sub-netlist field would be left empty, which means they are atomic parts, subcircuits without internal netlists; refdes are CONN1, CONN2, ...
- for the amplifier component the sub-netlist field would contain a netlist name, the same name for both channels, let's call it ampch ; the refdes are A1 and A2.
- a second, flat netlist would be included in the same file; this netlist would be called ampch . This netlist would be the netlist derived from the amplifier channel schematic - can live as a standalone project, with refdes for transistors T1, T2, ...
- note that ampch is stored only once, and is used by both A1 and A2
- note that the subcircuit for A1 and A2 are not bringing their own netlists, but the board's ampch netlist will be used
First let's assume the user already has the amplifier subcircuit drawn and saved as a subcircuit. When laying out the PCB using the amplifier subcircuit, only the top level board netlist is important. It's still flat, and the whole process is pretty much the same as if the amplifier subcircuits were black boxes: they have terminals to connect to and we have a rather simple task to connect a few connector pins to a few amplifier terminals. The user doesn't even need to know there's an ampch netlist associated with the subcircuit.
When the amplifier subcircuit is placed, refdes for the subc parts become the full path: for A1's T2, it's "A1.T2". This syntax is similar to many netlists' syntax.
The hierarchic netlist starts to play a role when we run connection checks (rats optimization): it will look into A1 and A2 and will figure if connections are not as specified. Then if the user starts to edit the amplifier subcircuit, E.g. ext-edits A1, the relevant netlist section ( ampch ) is applied there.
An important aspect is that subcircuits will need to have their own netlists: that's how the user can do the initial amplifier channel layout. However, when a subc is imported onto a board, it should lose its own netlist and the board's hierarchical netlist should dictate the subcircuit instance's netlist.
This guarantees that the final board reflects the board netlist. In an optimal situation when the subc was initially drawn, it used the same netlist that ended up in the board's hierarchic netlist as ampch , so it won't make a difference. But in other cases the user is placing an outdated subcircuit, or there was some local change for this particular project in the schematic so board's ampch won't match the actual sucbircuit layout and pcb-rnd will throw errors on rats nest optimization.
Conclusion
At the end, the user interface would not change much: at any given time the user is (mostly) editing one level of the hierarchy, seeing (mostly) a flat netlist associated with that level. Hierarchy will start to matter when the user traverses levels, e.g. edits a subcircuit that represents a complex, non-atomic building block of the board. But this case leads back to (mostly) flat editing too.
On the simple end, for a board that doesn't need hierarchy, this setup doesn't introduce any complication or user visible change.
On the complex end, this setup can be nested to arbitrary depth, yet it will keep each level flat and even the netlist file will be sort of a flat list of netlist blocks. It becomes hierarchic only through how subcircuits refer to netlists. This setup is somewhat similar to how SPICE netlists handle hierarchy.
Rewrite state
module | add new | del old | task |
---|---|---|---|
core | done | done | netlist infra (structs and functions) |
core | done | done | rat optimization |
core | done | done | maintain both the input and patched netlists, netlist patching, back annotation |
core | done | done | rats_act.[ch] |
core | done | done | tool_line.c - new rats drawn in non-brave mode will not create nets that are visible in the brave mode until a board reload |
lib_gtk_common
dialogs | done | done | (new) netlist dialog; old user lead circle code deleted |
lib_gtk_common | done | done | tooltip: bu_dwg_tooltip.c |
dialogs | done | done | dlg_pinout.c (pinout dialog) |
io_dsn | done | done | netlist I/O - read done |
io_pcb | done | done | netlist I/O |
io_kicad_legacy | done | done | netlist I/O (has write code only) |
io_kicad | done | done | netlist I/O - read is not implemented at all |
io_lihata | done | done | netlist I/O |
export_ipcd356 | done | done | netlist export |
export_xy | done | done | pad net name (e.g. for ncap) |
import_sch | done | done | netlist import |
renumber | done | done | netlist related features |
mincut | done | done | netlist mapping |
report | done | done | netlist related features |
sketch_route | done | done | netlist related features |
oldactions | done | done | netlist related features |
autoroute | done | done | netlist related features |
autoplace | done | done | netlist related features |
smartdisperse | done | done | netlist related features |
netmap | done | done | netlist mapping |
hid_lesstif | done | done | netlist dialog - temporary loss of some features; will be fixed by using the new, DAD dialog |