Wednesday 13 February 2013

Re-redesign the gEDA slotting mechanism

The slotting mechanism that is the primary subject of my gEDA fork seems to work, and solves the opamp problem, presumably also the transistor problem, and supports heterogeneous slots, unlike the more inflexible [1] stock gEDA mechanism.

But the design of the mechanism is broken: it doesn't play nicely with hierarchical designs, especially not ones that re-use schematics as distinct copies of a functional block. John Doty pointed this use case out to me; he's probably one of the heavier users of gEDA's hierarchical nature.

Essentially, the attributes my slotting mechanism currently uses, point the wrong way. It is the symbols that point to the slots they inhabit, thereby pointing "up" in the hierarchy of schematics, which is a graph (hopefully an acyclic one) and not a tree. Because the hierarchy is a graph, a schematic may have multiple parents - schematics that contain a symbol with a source= attribute pointing to it. While it would be possible to store multiple upwards-pointing attributes in a sub-schematic, doing so would damage the utility of that page as a reusable element when it accumulated slotting-related attributes from all the projects which used it as a sub-schematic.

So the slotting attributes can't point "up". Can they point "down" instead? It would be better, but perhaps still too inflexible: schematics with sub-schematics can themselves be sub-schematics. gEDA's hierarchy of schematics isn't limited in depth [2]. Only a toplevel schematic for a particular assembly [3] should sensibly assign slots in concrete parts to the symbols below that need them, since only it has no super-schematic, therefore it cannot appear in a project in multiple instances.

Then if slots need to point "down" to the symbols occupying them, we'll need not just a pointer to the symbol object, but a path through the hierarchy by which to reach it. Without the path, it would be impossible to disambiguate references to the same symbol used in a sub-schematic to multiple parents. Something like this should do:

slotsymbol=opamp3:48aa3670-55de-4dad-9587-f54e9f196837/c2490daf-a9e8-4ec8-9941-62845fc9bb29

Interpretation: 48aa3670-55de-4dad-9587-f54e9f196837 is the UUID of a hierarchical symbol (a "COMPLEX" in libgeda jargon). Perhaps, a block symbol for a bandpass filter.


Then, one of its source= attributes will point to a sub-schematic which will have another symbol on it (perhaps a generic opamp triangle symbol) whose UUID is c2490daf-a9e8-4ec8-9941-62845fc9bb29. That particular opamp function is assigned to the slot "opamp3".


Having these paths encoded in the slotting associations will allow gschem to show different pin numbers on the same symbol, depending on which instance of a sub-schematic one is looking at. gschem cannot do this yet, of course; I will have to code this extra behaviour.

I should reverse the associations now, before anyone really starts using my fork for its slotting mechanism. Patches welcome - it's a big job.

[1] Stock gEDA doesn't understand heterogeneous slots, conflates the symbol for a function (a NAND gate, for example) with the symbol for a part (correspondingly, a 74LS00 in this example), relies on the user to manually track slot assignments, and relies on fragile hacks to produce the correct netlist (setting identical refdes= attributes - or, worse, using lowercase suffixes to trigger special-case treatment in PCB). You end up with multiple symbols with a split identity between function and part, that can easily take on incompatible attributes. Imagine two NAND gates intended to be gates in the same chip, but each carries a mutually incompatible footprint= attribute. Let's not even think of the different pin numbering schemes of the various package styles - stock gEDA would demand that you edit the slotdef= attributes. How baroque!

[2] The hierarchy of schematics needs to be acyclic though; I can't see any good coming from a cycle of schematics. There is a similar issue in the component library: the gEDA file format allows any object to appear as part of the graphical representation of a symbol, including other symbols, and specifically including itself. Semantically invalid, but syntactically okay. A hare and tortoise algorithm would be able to detect cycles, and one day I'll get around to adding such a check.

[3] We could have a design consisting of a backplane and a set of identical daughterboards; each of these daughterboards would have identically-numbered parts, and this wouldn't be a problem, because the daughterboard is an entire sub-project. The important bit here is that only the topmost schematic of a particular assembly, subproject, whatever you want to call a distinct domain of refdes values, should carry the slot assignments for all the abstract symbols and slots below it.