Second major code overhaul of 2026 ----------------------------------------- Implement the planned changes to "extresist": (1) Remove the .sim format as a requirement. extresist will get its node list from doing a standard extraction (extFindNodes() or ExtFindRegions(), whichever is appropriate. This should be able to be done as a relatively simple change, allowing "extresist" to be used without doing "ext2sim" as part of the process. (2) Move extresist into the "extract" code. "extresist" will become a command "extract do extresist" and "ext2spice extresist on|off" will determine if split nodes and terminals are kept apart in the final netlist or aggregated---Exactly as capacitance is done now. Need to figure out how "tile junk" client data and extract client data can exist simultaneously. "extresist" will run within "extBasic", being called on a node after the devices and nodes are identified; nodes created by ExtFindRegions() will get sub-divided into more nodes. The difficult case will be where a single tile gets multiple nodes (such as where other wires branch off the tile in the up or down direction). Maybe this can be done like ClientData for split tiles, with an indicator bit in ti_body? ----------------------------------------------------- For (1): Reading the "nodes" file only creates "node" entries, one per net. With an ExtFindRegions and ExtLabelRegions (or extFindNodes?) there should be an equivalent list from which node names, locations, and types can be taken. This information will be redundant, for now. Note that ExtResisForDef() runs extResPrepSubstrate() which is like extPrepSubstrate(), which is run from extCellFile(). So ExtResisForDef() could replace lines 150 to 174 with the ExtBasic calls to ExtFindRegions(), extFindNodes(), and ExtLabelRegions(). This is followed by temporary code that creates the tables and lists that the extresist code uses. Then, run the ResCheckSimNodes() code, or at least the part for a single node (which is ResRex.c lines 1071 to 1240) Add a ClientData record to a NodeRegion, and extresist can run by adding "tileJunk" records to the NodeRegion client data, and leave the region records in place. (done) Then need to figure out how to output the data all at once. Replace the "extresist" command with "extract do extresist". EXT_DOEXTRESIST. Maybe later replace "resistance" and make it equivalent to "extresist", or maybe make "resistance" *be* DOEXTRESIST and use "lumped" instead of "resistance" (I like this better). (done) "ext2spice extresist on" will then output the netlist exactly as it appears in the .ext file, while "ext2spice extresist off" will conglomerate the .tX and .nX sub-nodes and produce what is hopefully the equivalent of a netlist from a .ext file without "extract do extresist". We keep (maybe) HashTable ResNodeTable RDev *ResRDevList At issue: Doing it this way might be more convenient, but by keeping the NodeRegions in place and adding "tileJunk" records, it's harder to find where the subnets are connected. If the NodeRegions get replaced, then there are way more regions but, for example, a transistor terminal node is easily found by looking at the Region pointer connected to the terminal type. However, nodes are output by working through the node list and devices are output by working through the device list, so the information is readily available. Currently the "to-do" work starts at ExtBasic.c line 313. Pulled out the central part of ResCheckSimNodes() into "ResProcessNode()". This allows ExtBasic.c to loop over its own nodeList, prepare the ResSimNode structure, and then call ResProcessNode() to process a single network. These are all then bypassed: CmdExtResist() ExtResisForDef() extResPrepSubstrate() ResReadSim() ResCheckPorts() ResCheckSimNodes() (clean up ResNodeTable and ResRDevList) The only one of the bypassed routines which may need to be handled is "ResCheckPorts()". Possibly the ExtSubtree/ExtHier stuff can be used in place? The main issue is figuring out where the ports are. Unlike the original "extresist" method, it should be possible to do this properly. Punt on it for the moment. Try to compile with the separated-out ResProcessNode() routine. Okay, got that working. Now, the hard work: Prepare an extresist node record from ExtBasic.c. Don't worry about how ClientData records are managed, for now. Now, what does ResCleanUpEverything() do? We don't want to destroy the records until the end. Maybe node regions should be replaced by subnets here? And the resistors can be kept in a linked list or hash table to be output along with the devices. The issue here is that some tiles can contain multiple sub-nets, if there are wires branching off. Note, however, that wires can only branch off of a single rectangle in the north or south directions, due to the "maximum horizontal stripes" rule. What if subnets within a tile were handled by splitting the tile, which would only be done horizontally, and keeping the tiles separate by setting a flag in ti_body such that a long wire with many branches would be split into multiple segments with the flag set to 1010101. . ., which allows the normal tile handling to work. The flags can be cleaned up afterward and the tiles merged (maybe just erase and repaint the tile)? Note that this would never happen with split tiles. Probably okay with contacts? Due to the maximum horizontal stripes consideration, does ResCalcNorthSouth() *ever* get called?? Okay, a long vertical contact with metal branches on either side would invalidate my assumption, and yes, ResCalcNorthSouth() would be called. Okay, so never mind that one. Quandary: ResProcessNode() is pretty self-contained and cleans up after itself. But extBasic() finds all nodes and keeps them around for the duration of the extraction, and needs to have the extresist splits on hand for coupling capacitance calculations and all output. Maybe copy in a simplified form to yet another ClientData field on a nodeRegion. So there's another way to go about it: (1) When running extract, create the device record for extresist after running transList = ExtFindRegions(). This list does not change between being created and the transistors being output. (2) Create the node record for extresist after running extFindNodes(). (3) With this information, it's possible to run extresist on the node. Because nodes have all been marked with regions, use a ClientData record in NodeRegion to store the extresist working data. Clean up afterward; the NodeRegion records still remain in place on the tiles. The simplest approach is just to write the .res.ext annotation file as before, although with the extresist code being run before the .ext file is written, it is possible to combine the two. But the use of .res.ext is a quicker intermediate step that allows the extresist code to be checked for hierarchical operation, which it will now be able to do relatively smoothly, as it is not necessary to create multiple .sim and .node files for each subcircuit. Trickier: Replace NodeRegions with the subnet regions. One difficulty here is dealing with multiple subnets in a single tile. Simplifying the extresist code by removing references to ARIEL and LAPLACE (which are missing code and so cannot be reinstated without a lot of guesswork), and removing some apparently nonfunctional code having to do with events. To do after finding transistors: What's done in ResReadSim(): Specifically, ResSimDevice() and ResSimSubckt(). ResReadNode() is the only thing needed to be done for nodes. It calls ResInitializeNode() and sets location and (tile) type. Everything else in the structure is TBD. Another issue: The device type is determined by "extract" only during extOutputDevices. The device type in "devrec" is not computed until just before the device is output. But. . . is this really needed by extresist? It was being used by extresist because the device name is what's in the .sim file. You know what probably works best? (1) When nodes are written to the .ext file, save the information for extresist. (2) When devices are written to the .ext file, save the information for extresist. (3) Run extresist at the end of the cell def's extraction, and write the .res.ext file as usual. (Later, maybe, get rid of the .res.ext file and just re-write the annotated .ext file.) (4) Create a new method for annotated coupling capacitances. Recompute the coupling and output adjustments (positive for the new node/terminal nodes, negative for the original node). Coupling will be recomputed only for nets processed by extresist. Node substrate capacitance changes will be recorded in .res.ext (but---I think substrate capacitance is now unused in the node record, because there is a substrate node and substrate capacitance is now treated like coupling to that node; isn't that right?) (and there will be multiple substrate nodes, as well.) This can also be done in two steps: (1) Replace ResReadSim() with ResReadExt() and read back the .ext file immediately after writing it. (2) Remove the read-back and just generate the information on the fly. This also has the advantage that it can be tested in parts.