From 76f97c90e51b7a7352bf5a1a8bc7b7e2318ba9e7 Mon Sep 17 00:00:00 2001 From: "R. Timothy Edwards" Date: Tue, 27 Jan 2026 11:56:47 -0500 Subject: [PATCH] Slowly working through things needed for removing the ".sim" file dependency of "extresist". Stopping and committing work in order to rebase from the master branch. --- README | 68 ++++ extflat/EFread.c | 60 +--- extflat/extparse.h | 84 +++++ extract/ExtBasic.c | 56 ++-- resis/Makefile | 2 +- resis/ResChecks.c | 1 - resis/ResDebug.c | 1 - resis/ResMain.c | 86 +---- resis/ResMakeRes.c | 13 - resis/ResMerge.c | 48 +-- resis/ResPrint.c | 12 +- resis/{ResReadSim.c => ResReadExt.c} | 460 ++++++++------------------- resis/ResRex.c | 156 ++------- resis/ResSimple.c | 28 +- resis/ResWrite.c | 5 +- resis/resis.h | 164 +++------- 16 files changed, 420 insertions(+), 824 deletions(-) create mode 100644 extflat/extparse.h rename resis/{ResReadSim.c => ResReadExt.c} (66%) diff --git a/README b/README index 1217f964..8ca356df 100644 --- a/README +++ b/README @@ -132,3 +132,71 @@ 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. diff --git a/extflat/EFread.c b/extflat/EFread.c index 68a74b76..1a7c70fc 100644 --- a/extflat/EFread.c +++ b/extflat/EFread.c @@ -37,6 +37,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "commands/commands.h" #include "database/database.h" #include "extflat/extflat.h" +#include "extflat/extparse.h" #include "extflat/EFint.h" #include "extract/extract.h" #include "extract/extractInt.h" @@ -45,61 +46,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ /* C99 compat */ #include "textio/textio.h" -#ifndef MAGIC_WRAPPER -/* This must match the definition for extDevTable in extract/ExtBasic.c */ -const char * const extDevTable[] = {"fet", "mosfet", "asymmetric", "bjt", "devres", - "devcap", "devcaprev", "vsource", "diode", "pdiode", - "ndiode", "subckt", "rsubckt", "msubckt", "csubckt", - "dsubckt", "veriloga", NULL}; -#endif - -/* - * The following table describes the kinds of lines - * that may be read in a .ext file. - */ -typedef enum -{ - ABSTRACT, ADJUST, ATTR, CAP, DEVICE, DIST, EQUIV, FET, KILLNODE, MERGE, - NODE, PARAMETERS, PORT, PRIMITIVE, RESISTOR, RESISTCLASS, RNODE, SCALE, - SUBCAP, SUBSTRATE, TECH, TIMESTAMP, USE, VERSION, EXT_STYLE -} Key; - -static const struct -{ - const char *k_name; /* Name of first token on line */ - Key k_key; /* Internal name for token of this type */ - int k_mintokens; /* Min total # of tokens on line of this type */ -} -keyTable[] = -{ - {"abstract", ABSTRACT, 0}, /* defines a LEF-like view */ - {"adjust", ADJUST, 4}, - {"attr", ATTR, 8}, - {"cap", CAP, 4}, - {"device", DEVICE, 11}, /* effectively replaces "fet" */ - {"distance", DIST, 4}, - {"equiv", EQUIV, 3}, - {"fet", FET, 12}, /* for backwards compatibility */ - {"killnode", KILLNODE, 2}, - {"merge", MERGE, 3}, - {"node", NODE, 7}, - {"parameters", PARAMETERS, 3}, - {"port", PORT, 8}, - {"primitive", PRIMITIVE, 0}, /* defines a primitive device */ - {"resist", RESISTOR, 4}, - {"resistclasses", RESISTCLASS, 1}, - {"rnode", RNODE, 5}, - {"scale", SCALE, 4}, - {"subcap", SUBCAP, 3}, - {"substrate", SUBSTRATE, 3}, - {"tech", TECH, 2}, - {"timestamp", TIMESTAMP, 2}, - {"use", USE, 9}, - {"version", VERSION, 2}, - {"style", EXT_STYLE, 2}, - {0} -}; - /* Data shared with EFerror.c */ char *efReadFileName; /* Name of file currently being read */ int efReadLineNum; /* Current line number in above file */ @@ -109,10 +55,6 @@ bool EFSaveLocs; /* If TRUE, save location of merged top-level nodes */ /* Data local to this file */ static bool efReadDef(Def *def, bool dosubckt, bool resist, bool noscale, bool toplevel, bool isspice); -/* atoCap - convert a string to a EFCapValue */ -#define atoCap(s) ((EFCapValue)atof(s)) - - /* * ---------------------------------------------------------------------------- * diff --git a/extflat/extparse.h b/extflat/extparse.h new file mode 100644 index 00000000..55944622 --- /dev/null +++ b/extflat/extparse.h @@ -0,0 +1,84 @@ +/* + * extparse.h + * + * Definitions for the .ext file parser. Relocated from EFread.c. + * + * ********************************************************************* + * * Copyright (C) 1985, 1990 Regents of the University of California. * + * * Permission to use, copy, modify, and distribute this * + * * software and its documentation for any purpose and without * + * * fee is hereby granted, provided that the above copyright * + * * notice appear in all copies. The University of California * + * * makes no representations about the suitability of this * + * * software for any purpose. It is provided "as is" without * + * * express or implied warranty. Export of this software outside * + * * of the United States of America may require an export license. * + * ********************************************************************* + */ + +/* These must be in the order of "known devices" in extract/extract.h. */ +/* This table is also used in extract/ExtBasic.c */ + +/* Note: "fet" refers to the original fet type; "mosfet" refers to the */ +/* new type. The main difference is that "fet" records area/perimeter */ +/* while "mosfet" records length/width. */ + +#ifndef MAGIC_WRAPPER +const char * const extDevTable[] = {"fet", "mosfet", "asymmetric", "bjt", "devres", + "devcap", "devcaprev", "vsource", "diode", "pdiode", + "ndiode", "subckt", "rsubckt", "msubckt", "csubckt", + "dsubckt", "veriloga", NULL}; +#endif + +/* + * The following table describes the kinds of lines + * that may be read in a .ext file. + */ +typedef enum +{ + ABSTRACT, ADJUST, ATTR, CAP, DEVICE, DIST, EQUIV, FET, KILLNODE, MERGE, + NODE, PARAMETERS, PORT, PRIMITIVE, RESISTOR, RESISTCLASS, RNODE, SCALE, + SUBCAP, SUBSTRATE, TECH, TIMESTAMP, USE, VERSION, EXT_STYLE +} Key; + +static const struct +{ + const char *k_name; /* Name of first token on line */ + Key k_key; /* Internal name for token of this type */ + int k_mintokens; /* Min total # of tokens on line of this type */ +} +keyTable[] = +{ + {"abstract", ABSTRACT, 0}, /* defines a LEF-like view */ + {"adjust", ADJUST, 4}, + {"attr", ATTR, 8}, + {"cap", CAP, 4}, + {"device", DEVICE, 11}, /* effectively replaces "fet" */ + {"distance", DIST, 4}, + {"equiv", EQUIV, 3}, + {"fet", FET, 12}, /* for backwards compatibility */ + {"killnode", KILLNODE, 2}, + {"merge", MERGE, 3}, + {"node", NODE, 7}, + {"parameters", PARAMETERS, 3}, + {"port", PORT, 8}, + {"primitive", PRIMITIVE, 0}, /* defines a primitive device */ + {"resist", RESISTOR, 4}, + {"resistclasses", RESISTCLASS, 1}, + {"rnode", RNODE, 5}, + {"scale", SCALE, 4}, + {"subcap", SUBCAP, 3}, + {"substrate", SUBSTRATE, 3}, + {"tech", TECH, 2}, + {"timestamp", TIMESTAMP, 2}, + {"use", USE, 9}, + {"version", VERSION, 2}, + {"style", EXT_STYLE, 2}, + {0} +}; + +/* atoCap - convert a string to a EFCapValue */ +#define atoCap(s) ((EFCapValue)atof(s)) + +extern int efReadLineNum; /* Current line number in the .ext file */ + diff --git a/extract/ExtBasic.c b/extract/ExtBasic.c index f70d863d..bda0a076 100644 --- a/extract/ExtBasic.c +++ b/extract/ExtBasic.c @@ -37,6 +37,7 @@ static char sccsid[] = "@(#)ExtBasic.c 4.13 MAGIC (Berkeley) 12/5/85"; #include "utils/malloc.h" #include "textio/textio.h" #include "debug/debug.h" +#include "extflat/extparse.h" #include "extract/extract.h" #include "extract/extractInt.h" #include "utils/signals.h" @@ -45,20 +46,7 @@ static char sccsid[] = "@(#)ExtBasic.c 4.13 MAGIC (Berkeley) 12/5/85"; #include "utils/styles.h" #include "utils/stack.h" #include "utils/utils.h" - -/* These must be in the order of "known devices" in extract.h. */ - -/* Note: "fet" refers to the original fet type; "mosfet" refers to the */ -/* new type. The main difference is that "fet" records area/perimeter */ -/* while "mosfet" records length/width. */ -/* Also: Note that this table is repeated in extflat/EFread.c when */ -/* ext2spice/ext2sim are compiled as separate programs (i.e., non-Tcl) */ - -#ifdef MAGIC_WRAPPER -const char * const extDevTable[] = {"fet", "mosfet", "asymmetric", "bjt", "devres", - "devcap", "devcaprev", "vsource", "diode", "pdiode", "ndiode", - "subckt", "rsubckt", "msubckt", "csubckt", "dsubckt", "veriloga", NULL}; -#endif +#include "resis/resis.h" /* --------------------- Data local to this file ---------------------- */ @@ -301,28 +289,6 @@ extBasic(def, outFile) if (!SigInterruptPending && (ExtDoWarn & EXTWARN_DUP) && !isabstract) extFindDuplicateLabels(def, nodeList); - /* - * If full R-C extraction is requested, then run it now. This - * code was previously run as the "extresist" command, but it - * makes more sense to be integral to the extraction process. - * It must be run prior to extFindCoupling() so that coupling - * capacitances are correctly assigned to subnets. - */ - if (!SigInterruptPending && (ExtOptions & EXT_DOEXTRESIST)) - { - ResSimNode *rsimnode; - ResisData resisdata; - int n_ext = 0, n_out = 0; - - for (reg = nodeList; reg && !SigInterruptPending; reg = reg->nreg_next) - { - rsimnode = ResCreateNode(); - ResProcessNode(rsimnode, def, &resisdata, &n_ext, &n_out); - - /* To be completed */ - } - } - /* * Build up table of coupling capacitances (overlap, sidewall). * This comes before extOutputNodes because we may have to adjust @@ -580,6 +546,24 @@ extBasic(def, outFile) extOutputDevices(def, transList, outFile); } + /* Integrated extresist --- Run "extresist" on the cell def just + * extracted and produce an annotation file ".res.ext". + */ + + if (ExtOptions & EXT_DOEXTRESIST) + { + ResisData resisdata; + + /* These need to be passed to extresist somehow. Most are unused. */ + resisdata.rthresh = 0; + resisdata.tdiTolerance = 1; + resisdata.frequency = 10e6; + resisdata.mainDef = def; + resisdata.savePlanes = (struct saveList *)NULL; /* unused */ + + ExtResisForDef(def, &resisdata); + } + /* Clean up */ if (coupleInitialized) extCapHashKill(&extCoupleHash); diff --git a/resis/Makefile b/resis/Makefile index 52aca230..14de864c 100644 --- a/resis/Makefile +++ b/resis/Makefile @@ -5,7 +5,7 @@ MODULE = resis MAGICDIR = .. SRCS = ResMain.c ResJunct.c ResMakeRes.c ResSimple.c ResPrint.c \ - ResReadSim.c ResRex.c ResBasic.c ResMerge.c ResChecks.c \ + ResReadExt.c ResRex.c ResBasic.c ResMerge.c ResChecks.c \ ResFract.c ResUtils.c ResDebug.c include ${MAGICDIR}/defs.mak diff --git a/resis/ResChecks.c b/resis/ResChecks.c index b82747ce..f3550e20 100644 --- a/resis/ResChecks.c +++ b/resis/ResChecks.c @@ -112,7 +112,6 @@ ResSanityChecks(nodename, resistorList, nodeList, devlist) { int i; - if (dev->rd_status & RES_DEV_PLUG) continue; reached = FALSE; for (i = 0; i != dev->rd_nterms; i++) { diff --git a/resis/ResDebug.c b/resis/ResDebug.c index 6358afc3..44f750e4 100644 --- a/resis/ResDebug.c +++ b/resis/ResDebug.c @@ -120,7 +120,6 @@ ResPrintDeviceList(fp, list) int i; for (; list != NULL; list = list->rd_nextDev) { - if (list->rd_status & RES_DEV_PLUG) continue; if (fp == stdout) TxPrintf("t w %d l %d ", list->rd_width, list->rd_length); else diff --git a/resis/ResMain.c b/resis/ResMain.c index 676c08fc..dcfc14f7 100644 --- a/resis/ResMain.c +++ b/resis/ResMain.c @@ -41,7 +41,7 @@ int ResTileCount = 0; /* Number of tiles rn_status */ extern ExtRegion *ResFirst(); extern Tile *FindStartTile(); extern int ResEachTile(); -extern ResSimNode *ResInitializeNode(); +extern ResExtNode *ResInitializeNode(); TileTypeBitMask ResSDTypesBitMask; TileTypeBitMask ResSubTypesBitMask; @@ -201,13 +201,13 @@ ResMakePortBreakpoints(def) TileTypeBitMask mask; HashSearch hs; HashEntry *entry; - ResSimNode *node; + ResExtNode *node; int ResAddBreakpointFunc(); /* Forward Declaration */ HashStartSearch(&hs); while((entry = HashNext(&ResNodeTable,&hs)) != NULL) { - node = (ResSimNode *)HashGetValue(entry); + node = (ResExtNode *)HashGetValue(entry); if (node->status & PORTNODE) { if (node->rs_ttype <= 0) @@ -281,7 +281,7 @@ ResMakeLabelBreakpoints(def, goodies) Rect *rect; TileTypeBitMask mask; HashEntry *entry; - ResSimNode *node; + ResExtNode *node; Label *slab; int ResAddBreakpointFunc(); /* Forward Declaration */ @@ -353,7 +353,7 @@ int ResAddBreakpointFunc(tile, dinfo, node) Tile *tile; TileType dinfo; /* (unused) */ - ResSimNode *node; + ResExtNode *node; { tileJunk *junk; @@ -512,51 +512,6 @@ ResProcessTiles(goodies, origin) resCurrentNode = NULL; (void) ResEachTile(startTile, origin); } -#ifdef ARIEL - else if (ResOptionsFlags & ResOpt_Power) - { - for (fix = ResFixList; fix != NULL; fix = fix->fp_next) - { - Tile *tile = fix->fp_tile; - if (tile == NULL) - { - tile = PlaneGetHint(ResDef->cd_planes[DBPlane(fix->fp_ttype)]); - GOTOPOINT(tile, &(fix->fp_loc)); - if (TiGetTypeExact(tile) != TT_SPACE) - { - fix->fp_tile = tile; - } - else - { - tile = NULL; - } - } - if (tile != NULL) - { - int x = fix->fp_loc.p_x; - int y = fix->fp_loc.p_y; - resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); - InitializeNode(resptr, x, y, RES_NODE_ORIGIN); - resptr->rn_status = TRUE; - resptr->rn_noderes = 0; - ResAddToQueue(resptr, &ResNodeQueue); - fix->fp_node = resptr; - NEWBREAK(resptr, tile, x, y, NULL); - } - } - for (fix = ResFixList; fix != NULL; fix = fix->fp_next) - { - Tile *tile = fix->fp_tile; - - if (tile != NULL && (((tileJunk *)TiGetClientPTR(tile)->tj_status & - RES_TILE_DONE) == 0) - { - resCurrentNode = fix->fp_node; - (void) ResEachTile(startile, (Point *)NULL); - } - } - } -#endif #ifdef PARANOID else { @@ -1036,7 +991,7 @@ ResShaveContacts(tile, dinfo, def) bool ResExtractNet(node, goodies, cellname) - ResSimNode *node; + ResExtNode *node; ResGlobalParams *goodies; char *cellname; { @@ -1103,11 +1058,6 @@ ResExtractNet(node, goodies, cellname) DBCellClearDef(ResUse->cu_def); -#ifdef ARIEL - if ((ResOptionsFlags & ResOpt_Power) && - strcmp(node->name, goodies->rg_name) != 0) continue; -#endif - /* Copy Paint */ scx.scx_area.r_ll.p_x = node->location.p_x - 2; @@ -1239,30 +1189,6 @@ ResExtractNet(node, goodies, cellname) ResFindNewContactTiles(ResContactList); ResPreProcessDevices(DevTiles, ResDevList, ResUse->cu_def); -#ifdef LAPLACE - if (ResOptionsFlags & ResOpt_DoLaplace) - { - for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) - { - Plane *plane = ResUse->cu_def->cd_planes[pNum]; - Rect *rect = &ResUse->cu_def->cd_bbox; - Res1d(plane, rect); - } - } -#endif - -#ifdef ARIEL - if (ResOptionsFlags & ResOpt_Power) - { - for (fix = startlist; fix != NULL; fix = fix->fp_next) - { - fix->fp_tile = PlaneGetHint(ResUse->cu_def->cd_planes[DBPlane(fix->fp_ttype)]); - GOTOPOINT(fix->fp_tile, &fix->fp_loc); - if (TiGetTypeExact(fix->fp_tile) == TT_SPACE) fix->fp_tile = NULL; - } - } -#endif - /* do extraction */ if (ResProcessTiles(goodies, &startpoint) != 0) return TRUE; return FALSE; diff --git a/resis/ResMakeRes.c b/resis/ResMakeRes.c index 01b224e4..e6665bc8 100644 --- a/resis/ResMakeRes.c +++ b/resis/ResMakeRes.c @@ -263,10 +263,6 @@ ResCalcEastWest(tile, pendingList, doneList, resList) { resistor->rr_status = RES_EW; } -#ifdef ARIEL - resistor->rr_csArea = height * - ExtCurStyle->exts_thick[resistor->rr_tt]; -#endif resistor->rr_value = (float)ExtCurStyle->exts_sheetResist[resistor->rr_tt] * (float)(p2->br_loc.p_x - p1->br_loc.p_x) @@ -440,10 +436,6 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList) { resistor->rr_status = RES_NS; } -#ifdef ARIEL - resistor->rr_csArea = width - * ExtCurStyle->exts_thick[resistor->rr_tt]; -#endif resistor->rr_value = (float)ExtCurStyle->exts_sheetResist[resistor->rr_tt] * (float)(p2->br_loc.p_y - p1->br_loc.p_y) @@ -916,11 +908,6 @@ ResDoContacts(contact, nodes, resList) resistor->rr_value = (float)ExtCurStyle->exts_viaResist[contact->cp_type] / (float)(squaresx * squaresy); -#ifdef ARIEL - resistor->rr_csArea = - (float)ExtCurStyle->exts_thick[contact->cp_type] / - (float)(squaresx * squaresy); -#endif resistor->rr_tt = contact->cp_type; resistor->rr_float.rr_area = 0; resistor->rr_status = 0; diff --git a/resis/ResMerge.c b/resis/ResMerge.c index d5f9fdfd..ee4b9a39 100644 --- a/resis/ResMerge.c +++ b/resis/ResMerge.c @@ -150,14 +150,6 @@ ResFixRes(resptr, resptr2, resptr3, elimResis, newResis) ASSERT(newResis->rr_value > 0, "series"); newResis->rr_float.rr_area += elimResis->rr_float.rr_area; -#ifdef ARIEL - if (elimResis->rr_csArea && elimResis->rr_csArea < newResis->rr_csArea - || newResis->rr_csArea == 0) - { - newResis->rr_csArea = elimResis->rr_csArea; - newResis->rr_tt = elimResis->rr_tt; - } -#endif for (thisREl = resptr3->rn_re; (thisREl != NULL); thisREl = thisREl->re_nextEl) { if (thisREl->re_thisEl == elimResis) @@ -206,9 +198,6 @@ ResFixParallel(elimResis, newResis) newResis->rr_value = 0; } newResis->rr_float.rr_area += elimResis->rr_float.rr_area; -#ifdef ARIEL - newResis->rr_csArea += elimResis->rr_csArea; -#endif ResDeleteResPointer(elimResis->rr_connection1, elimResis); ResDeleteResPointer(elimResis->rr_connection2, elimResis); ResEliminateResistor(elimResis, &ResResList); @@ -671,31 +660,16 @@ ResMergeNodes(node1, node2, pendingList, doneList) workingDev = node2->rn_te; while (workingDev != NULL) { - if (workingDev->te_thist->rd_status & RES_DEV_PLUG) - { - ResPlug *plug = (ResPlug *) workingDev->te_thist; - if (plug->rpl_node == node2) - plug->rpl_node = node1; - else - { - TxError("Bad plug node: is (%d %d), should be (%d %d)\n", - plug->rpl_node->rn_loc.p_x, plug->rpl_node->rn_loc.p_y, - node2->rn_loc.p_x, node2->rn_loc.p_y); - plug->rpl_node = NULL; - } - } - else - { - int j; + int j; - for (j = 0; j != workingDev->te_thist->rd_nterms; j++) - if (workingDev->te_thist->rd_terminals[j] == node2) - workingDev->te_thist->rd_terminals[j] = node1; - } - tDev = workingDev; - workingDev = workingDev->te_nextt; - tDev->te_nextt = node1->rn_te; - node1->rn_te = tDev; + for (j = 0; j != workingDev->te_thist->rd_nterms; j++) + if (workingDev->te_thist->rd_terminals[j] == node2) + workingDev->te_thist->rd_terminals[j] = node1; + + tDev = workingDev; + workingDev = workingDev->te_nextt; + tDev->te_nextt = node1->rn_te; + node1->rn_te = tDev; } /* append junction lists */ @@ -749,11 +723,11 @@ ResMergeNodes(node1, node2, pendingList, doneList) else if ((node2->rn_name != NULL) && (node2->rn_name != node1->rn_name)) { HashEntry *entry; - ResSimNode *node; + ResExtNode *node; /* Check if node2 is a port */ entry = HashFind(&ResNodeTable, node2->rn_name); - node = (ResSimNode *)HashGetValue(entry); + node = (ResExtNode *)HashGetValue(entry); if (node && (node->status & PORTNODE)) node1->rn_name = node2->rn_name; } diff --git a/resis/ResPrint.c b/resis/ResPrint.c index 33da3857..4f03d9e3 100644 --- a/resis/ResPrint.c +++ b/resis/ResPrint.c @@ -32,7 +32,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #define MAXNAME 1000 #define KV_TO_mV 1000000 -extern ResSimNode *ResInitializeNode(); +extern ResExtNode *ResInitializeNode(); /* @@ -57,7 +57,7 @@ ResPrintExtRes(outextfile, resistors, nodename) int nodenum=0; char newname[MAXNAME]; HashEntry *entry; - ResSimNode *node, *ResInitializeNode(); + ResExtNode *node, *ResInitializeNode(); for (; resistors != NULL; resistors = resistors->rr_nextResistor) { @@ -215,13 +215,13 @@ void ResPrintExtNode(outextfile, nodelist, node) FILE *outextfile; resNode *nodelist; - ResSimNode *node; + ResExtNode *node; { char *nodename = node->name; int nodenum = 0; char newname[MAXNAME+32], tmpname[MAXNAME], *cp; HashEntry *entry; - ResSimNode *newnode, *ResInitializeNode(); + ResExtNode *newnode, *ResInitializeNode(); bool DoKillNode = TRUE; bool NeedFix = FALSE; resNode *snode; @@ -411,14 +411,14 @@ ResPrintFHNodes(fp, nodelist, nodename, nidx, celldef) else { HashEntry *entry; - ResSimNode *simnode; + ResExtNode *simnode; /* If we process another sim file node while doing this */ /* one, mark it as status "REDUNDANT" so we don't duplicate */ /* the entry. */ entry = HashFind(&ResNodeTable, nodeptr->rn_name); - simnode = (ResSimNode *)HashGetValue(entry); + simnode = (ResExtNode *)HashGetValue(entry); if (simnode != NULL) simnode->status |= REDUNDANT; } diff --git a/resis/ResReadSim.c b/resis/ResReadExt.c similarity index 66% rename from resis/ResReadSim.c rename to resis/ResReadExt.c index 5147fe67..b792cffb 100644 --- a/resis/ResReadSim.c +++ b/resis/ResReadExt.c @@ -1,12 +1,13 @@ #ifndef lint -static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/resis/ResReadSim.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; +static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/resis/ResReadExt.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ /* *------------------------------------------------------------------------- * - * ResReadSim.c -- Routines to parse .sim files + * ResReadExt.c -- Routines to parse .ext files for information needed + * by extresist. * *------------------------------------------------------------------------- */ @@ -35,8 +36,9 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "textio/txcommands.h" #include "resis/resis.h" +/* constants defining where various fields can be found in .ext files. */ +/* (FIXME---Needs to be changed to positions in .ext files) */ -/* constants defining where various fields can be found in .sim files. */ #define RDEV_LENGTH 4 #define RDEV_WIDTH 5 #define RDEV_DEVX 6 @@ -70,163 +72,99 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #define RES_EXT_ATTR_TILE 6 #define RES_EXT_ATTR_TEXT 7 - #define MAXTOKEN 1024 #define MAXLINE 40 #define MAXDIGIT 20 +ResExtNode *ResInitializeNode(); -ResSimNode *ResInitializeNode(); - -ResSimNode *ResOriginalNodes; /*Linked List of Nodes */ -static float resscale=1.0; /* Scale factor */ -char RDEV_NOATTR[1]={'0'}; -ResFixPoint *ResFixList; - -#define nodeinit(n)\ -{\ - (n)->rn_more = ResNodeList;\ - (n)->rn_less = NULL;\ - if (ResNodeList)\ - ResNodeList->rn_less = n;\ - ResNodeList = n;\ - (n)->rn_te = NULL;\ - (n)->rn_re = NULL;\ - (n)->rn_je = NULL;\ - (n)->rn_ce = NULL;\ - (n)->rn_noderes = RES_INFINITY;\ - (n)->location.p_x = MINFINITY;\ - (n)->location.p_y = MINFINITY;\ - (n)->rn_why = 0;\ - (n)->rn_status = TRUE;\ -} - -/* Forward declarations */ - -extern void ResSimProcessDrivePoints(); +ResExtNode *ResOriginalNodes; /*Linked List of Nodes */ +static float resscale = 1.0; /* Scale factor */ +char RDEV_NOATTR[1] = {'0'}; +ResFixPoint *ResFixList; /* *------------------------------------------------------------------------- * - * ResReadSim-- + * ResReadExt-- * - * Results: returns 0 if sim file is correct, 1 if not. + * Results: returns 0 if ext file is correct, 1 if not. * - * Side Effects:Reads in SimTable and makes a hash table of nodes. + * Side Effects:Reads in ExtTable and makes a hash table of nodes. * *------------------------------------------------------------------------- */ int -ResReadSim(simfile, fetproc, capproc, resproc, attrproc, mergeproc, subproc) - char *simfile; - int (*fetproc)(), (*capproc)(), (*resproc)(); - int (*attrproc)(), (*mergeproc)(), (*subproc)(); - +ResReadExt(char *extfile); { - char line[MAXLINE][MAXTOKEN]; - int result, fettype, extfile; - FILE *fp, *fopen(); + char *line = NULL, *argv[128]; + int result, fettype, readdrivepoints; + int size = 0; + FILE *fp; - fp = PaOpen(simfile, "r", ".sim", ".", (char *)NULL, (char **)NULL); + fp = PaOpen(extfile, "r", ".ext", EFSearchPath, EFLibPath, (char **)NULL); if (fp == NULL) { - TxError("Cannot open file %s%s\n", simfile, ".sim"); + TxError("Cannot open file %s%s\n", extfile, ".ext"); return 1; } - extfile = 0; + readdrivepoints = FALSE; - /* Read in file */ - while (gettokens(line, fp) != 0) + /* Read in the file. Makes use of various functions + * from extflat, mostly in EFread.c. + */ + + EFSaveLocs = False; + efReadLineNum = 0; + + while ((argc = efReadLine(&line, &size, fp, argv)) >= 0) { - fettype = MINFINITY; - switch(line[0][0]) + n = LookupStruct(argv[0], (const LookupTable *)keyTable, sizeof keyTable[0]); + if (n < 0) { - case '|': - if (strcmp(line[NODEUNITS],"units:") == 0) - { - resscale = (float)atof(line[NODELAMBDA]); - if (resscale == 0.0) resscale = 1.0; - } - result=0; + efReadError("Unrecognized token \"%s\" (ignored)\n", argv[0]); + continue; + } + if (argc < keyTable[n].k_mintokens) + { + efReadError("Not enough tokens for %s line\n", argv[0]); + continue; + } + + /* We don't care about most tokens, only DEVICE, NODE, PORT, + * and SUBSTRATE; and MERGE is used to locate drive points. + */ + switch (keyTable[n].k_key) + { + case SCALE: + resscale = (float)atof(argv[1]); + if (resscale == 0.0) resscale = 1.0; break; - case 'e': - fettype = DBTechNameType("efet"); - break; - case 'd': - fettype = DBTechNameType("dfet"); + case DEVICE: + ResReadSubckt(argc, argv); break; - case 'n': - fettype = DBTechNameType("nfet"); + case FET: + ResReadDevice(argc, argv); break; - case 'p': - fettype = DBTechNameType("pfet"); + case MERGE: + ResReadDrivePoint(argc, argv); break; - case 'b': - fettype = DBTechNameType("bnpn"); + case NODE: + case SUBSTRATE: + ResReadNode(argc, argv); break; - case 'C': - if (capproc) result = (*capproc)(line); + case PORT: + ResReadPort(argc, argv); break; - case 'R': - if (resproc) result = (*resproc)(line); - break; - case '=': - /* Do not merge nodes, as this interferes with */ - /* extresist's primary function. */ - /* if (mergeproc) result = (*mergeproc)(line); */ - break; - case 'A': - if (attrproc) - { - result = (*attrproc)(line[ATTRIBUTENODENAME], - line[ATTRIBUTEVALUE], simfile, &extfile); - } - break; - case 'x': - fettype = DBNumTypes; - break; - case 'D': - case 'c': - case 'r': + case ATTR: + result = ResExtAttribute(curnodename, + argv[1], &readdrivepoints); break; default: - /* we expect fclose(fp) and early return to occur below, - * but code path might still modify result (maybe to zero) - * allowing us to loop again, which will then access 'fp' - */ - result = 1; break; - } - if ((fettype != MINFINITY) && (fettype < 0)) - { - TxError("Error in Reading device line of sim file: "); - TxError("Ambiguous or unknown device.\n"); - result = 1; - } - else if (fettype == DBNumTypes) - { - result = (*subproc)(line); - } - else if (fettype != MINFINITY) - { - float sheetr; - ExtDevice *devptr; - HashEntry *he; - devptr = ExtCurStyle->exts_device[fettype]; - he = HashLookOnly(&devptr->exts_deviceResist, "linear"); - if (he != NULL) - sheetr = (ResValue)(spointertype)HashGetValue(he); - else - sheetr = (ResValue)0.0; - result = (*fetproc)(line, sheetr, devptr); - } - if (result != 0) - { - TxError("Error in sim file %s\n", line[0]); - fclose(fp); - return 1; + /* to do: Handle CAP, RESISTOR, maybe others? */ } } fclose(fp); @@ -240,112 +178,45 @@ ResReadSim(simfile, fetproc, capproc, resproc, attrproc, mergeproc, subproc) * ResReadNode-- Reads in a node file, puts location of nodes into node * structures. * - * Results: returns 0 if nodes file is correct, 1 if not. + * Results: 0 if the node was read correctly, 1 otherwise. * - * Side Effects:see above + * Side Effects: see above * *------------------------------------------------------------------------- */ int -ResReadNode(nodefile) - char *nodefile; +ResReadNode(int argc, char *argv[]) { - char line[MAXLINE][MAXTOKEN]; - FILE *fp, *fopen(); HashEntry *entry; - ResSimNode *node; + ResExtNode *node; char *cp; float lambda; - fp = PaOpen(nodefile, "r", ".nodes", ".", (char *)NULL, (char **)NULL); - if (fp == NULL) + entry = HashFind(&ResNodeTable, line[NODES_NODENAME]); + node = ResInitializeNode(entry); + + node->location.p_x = atoi(line[NODES_NODEX]); + node->location.p_y = atoi(line[NODES_NODEY]); + if ((cp = strchr(line[NODES_NODETYPE], ';'))) *cp = '\0'; + node->type = DBTechNameType(line[NODES_NODETYPE]); + + if (node->type == -1) { - TxError("Cannot open file %s%s\n", nodefile, ".nodes"); + TxError("Bad tile type name in .ext file for node %s\n", + node->name); return 1; } - while (gettokens(line,fp) != 0) - { - entry = HashFind(&ResNodeTable, line[NODES_NODENAME]); - node = ResInitializeNode(entry); - - node->location.p_x = atoi(line[NODES_NODEX]); - node->location.p_y = atoi(line[NODES_NODEY]); -#ifdef ARIEL - node->rs_bbox.r_xbot = atoi(line[NODE_BBOX_LL_X]); - node->rs_bbox.r_ybot = atoi(line[NODE_BBOX_LL_Y]); - node->rs_bbox.r_xtop = atoi(line[NODE_BBOX_UR_X]); - node->rs_bbox.r_ytop = atoi(line[NODE_BBOX_UR_Y]); -#endif - if ((cp = strchr(line[NODES_NODETYPE], ';'))) *cp = '\0'; - node->type = DBTechNameType(line[NODES_NODETYPE]); - - if (node->type == -1) - { - TxError("Bad tile type name in %s.nodes file for node %s\n", - nodefile, node->name); - TxError("Did you use the newest version of ext2sim?\n"); - fclose(fp); - return 1; - } - } - fclose(fp); return 0; } /* *------------------------------------------------------------------------- * - * getline-- Gets a line from the current input file and breaks it into - * tokens. - * - * Results:returns the number of tokens in the current line - * - * Side Effects: loads up its input line with the tokens. - * - *------------------------------------------------------------------------- - */ - -int -gettokens(line, fp) - char line[][MAXTOKEN]; - FILE *fp; -{ - int i = 0, j = 0; - int c; - - while ((c = getc(fp)) != EOF && c != '\n') - { - switch(c) - { - case ' ': - case ' ' : - line[i++][j] = '\0'; - j = 0; - break; - default: - line[i][j++] = c; - break; - } - } - if (c == '\n') - { - line[i++][j] = '\0'; - j = 0; - } - for (j = i; j < MAXLINE; j++) - line[j][0] = '\0'; - - return i; -} - -/* - *------------------------------------------------------------------------- - * - * ResSimSubckt-- Processes a subcircuit line from a sim file. + * ResReadSubckt-- Processes a subcircuit line from a ext file. * This uses the "user subcircuit" extension defined in * IRSIM, although it is mostly intended as a way to work - * around the device type limitations of the .sim format + * around the device type limitations of the .ext format * when using extresist. * * Results: returns 0 if line was added correctly. @@ -356,7 +227,7 @@ gettokens(line, fp) */ int -ResSimSubckt(line) +ResReadSubckt(line) char line[][MAXTOKEN]; { RDev *device; @@ -473,7 +344,7 @@ ResSimSubckt(line) TxError("Device %s has more than 4 ports (not handled).\n", line[i]); break; /* No method to handle more ports than this */ } - rvalue += ResSimNewNode(line[k], k, device); + rvalue += ResExtNewNode(line[k], k, device); } return rvalue; @@ -482,7 +353,7 @@ ResSimSubckt(line) /* *------------------------------------------------------------------------- * - * ResSimDevice-- Processes a device line from a sim file. + * ResReadDevice-- Processes a device line from a ext file. * * Results: returns 0 if line was added correctly. * @@ -492,7 +363,7 @@ ResSimSubckt(line) */ int -ResSimDevice(line, rpersquare, devptr) +ResReadDevice(line, rpersquare, devptr) char line[][MAXTOKEN]; float rpersquare; ExtDevice *devptr; @@ -554,7 +425,7 @@ ResSimDevice(line, rpersquare, devptr) device->rs_ttype = extGetDevType(devptr->exts_deviceName); - /* sim attributes look like g=a1,a2 */ + /* ext attributes look like g=a1,a2 */ /* ext attributes are "a1","a2" */ /* Do conversion from one to the other here */ /* NOTE: As of version 8.3.366, .ext attributes will end in two */ @@ -615,9 +486,9 @@ ResSimDevice(line, rpersquare, devptr) } ResRDevList = device; device->layout = NULL; - rvalue = ResSimNewNode(line[GATE], GATE, device) + - ResSimNewNode(line[SOURCE], SOURCE, device) + - ResSimNewNode(line[DRAIN], DRAIN, device); + rvalue = ResExtNewNode(line[GATE], GATE, device) + + ResExtNewNode(line[SOURCE], SOURCE, device) + + ResExtNewNode(line[DRAIN], DRAIN, device); return rvalue; } @@ -625,24 +496,24 @@ ResSimDevice(line, rpersquare, devptr) /* *------------------------------------------------------------------------- * - * ResSimNewNode-- Adds a new node to the Node Hash Table. + * ResExtNewNode-- Adds a new node to the Node Hash Table. * * Results: returns zero if node is added correctly, one otherwise. * - * Side Effects: Allocates a new ResSimNode + * Side Effects: Allocates a new ResExtNode * *------------------------------------------------------------------------- */ int -ResSimNewNode(line, type, device) +ResExtNewNode(line, type, device) char line[]; int type; RDev *device; { HashEntry *entry; - ResSimNode *node; + ResExtNode *node; devPtr *tptr; if (line[0] == '\0') @@ -681,25 +552,25 @@ ResSimNewNode(line, type, device) /* *------------------------------------------------------------------------- * - * ResSimCapacitor-- Adds the capacitance from a C line to the appropriate + * ResReadCapacitor-- Adds the capacitance from a C line to the appropriate * node. Coupling capacitors are added twice, moving the capacitance * to the substrate. * * Results: * Always return 0 * - * Side Effects: modifies capacitance field of ResSimNode. + * Side Effects: modifies capacitance field of ResExtNode. * *------------------------------------------------------------------------- */ int -ResSimCapacitor(line) +ResReadCapacitor(line) char line[][MAXTOKEN]; { HashEntry *entry1, *entry2; - ResSimNode *node1, *node2; + ResExtNode *node1, *node2; if (line[COUPLETERMINAL1][0] == 0 || line[COUPLETERMINAL2][0] == 0) { @@ -752,23 +623,23 @@ ResSimCapacitor(line) /* *------------------------------------------------------------------------- * - * ResSimResistor-- Adds the capacitance from a R line to the appropriate + * ResReadResistor-- Adds the capacitance from a R line to the appropriate * node. * * Results * Return 0 to keep search going, 1 to abort * - * Side Effects: modifies resistance field of ResSimNode + * Side Effects: modifies resistance field of ResExtNode * *------------------------------------------------------------------------- */ int -ResSimResistor(line) +ResReadResistor(line) char line[][MAXTOKEN]; { HashEntry *entry; - ResSimNode *node; + ResExtNode *node; if (line[RESNODENAME][0] == 0) { @@ -789,29 +660,30 @@ ResSimResistor(line) /* *------------------------------------------------------------------------- * - * ResSimAttribute--checks to see if a node attribute is a resistance + * ResExtAttribute--checks to see if a node attribute is a resistance * attribute. If it is, add it to the correct node's status flag. * Only works with 5.0 1/line attributes * * Results: * Return 0 to keep search going, 1 to abort * - * Side Effects: modifies resistance field of ResSimNode + * Side Effects: modifies resistance field of ResExtNode * *------------------------------------------------------------------------- */ int -ResSimAttribute(aname, avalue, rootname, readextfile) - char *aname, *avalue, *rootname; - int *readextfile; +ResReadAttribute(aname, avalue, readdrivepoints) + char *aname; + char *avalue; + bool *readdrivepoints; { HashEntry *entry; - ResSimNode *node; + ResExtNode *node; char digit[MAXDIGIT]; int i; - static int notwarned=TRUE; + static int notwarned = TRUE; if (aname[0] == 0) { @@ -834,18 +706,14 @@ ResSimAttribute(aname, avalue, rootname, readextfile) else if (strncmp(avalue, "res:force", 9) == 0) { if (node->status & SKIP) - { TxError("Warning: Node %s is both skipped and forced \n", aname); - } else - { node->status |= FORCE; - } } else if (strncmp(avalue, "res:min=", 8) == 0) { node->status |= MINSIZE; - for (i = 0, avalue += 8; *avalue != '\0' && *avalue != ','; avalue++) + for (i = 0, avalue += 8; *avalue != '\0'; avalue++) { digit[i++] = *avalue; } @@ -855,16 +723,14 @@ ResSimAttribute(aname, avalue, rootname, readextfile) else if (strncmp(avalue, "res:drive", 9) == 0 && (ResOptionsFlags & ResOpt_Signal)) { - if (*readextfile == 0) + if (*readdrivepoints == FALSE) { - ResSimProcessDrivePoints(rootname); - *readextfile = 1; + ResExtProcessDrivePoints(rootname); + *readddrivepoints = TRUE; } /* is the attribute in root.ext? */ if (node->drivepoint.p_x != INFINITY) - { node->status |= DRIVELOC; - } else { if (notwarned) @@ -873,34 +739,22 @@ ResSimAttribute(aname, avalue, rootname, readextfile) notwarned = FALSE; } } -#ifdef ARIEL - else if (strncmp(avalue, "res:fix", 7) == 0 && - (ResOptionsFlags & ResOpt_Power)) - { - if (*readextfile == 0) - { - ResSimProcessFixPoints(rootname); - *readextfile = 1; - } - } -#endif - if ((avalue = strchr(avalue, ','))) - { - ResSimAttribute(aname, avalue + 1, rootname, readextfile); - } return 0; } /* *------------------------------------------------------------------------- * - * ResSimProcessDrivePoints -- if the sim file contains a res:drive attribute, + * ResExtProcessDrivePoints -- if the ext file contains a res:drive attribute, * and we are doing a signal extraction, * we need to search through the .ext file looking for attr labels that * contain this text. For efficiency, the .ext file is only parsed when * the first res:drive is encountered. res:drive labels only work if * they are in the root cell. * + * FIXME---The .ext file is being read and this routine should only + * read in additional lines as necessary. + * * Results: * None. * @@ -910,23 +764,14 @@ ResSimAttribute(aname, avalue, rootname, readextfile) */ void -ResSimProcessDrivePoints(filename) - char *filename; - +ResExtProcessDrivePoints(FILE *fp) { char line[MAXLINE][MAXTOKEN]; FILE *fp; HashEntry *entry; - ResSimNode *node; + ResExtNode *node; - fp = PaOpen(filename, "r", ".ext", (ExtLocalPath == NULL) ? "." : ExtLocalPath, - (char *)NULL, (char **)NULL); - if (fp == NULL) - { - TxError("Cannot open file %s%s\n", filename, ".ext"); - return; - } - while (gettokens(line,fp) != 0) + while (gettokens(line, fp) != 0) { if (strncmp(line[RES_EXT_ATTR], "attr", 4) != 0 || strncmp(line[RES_EXT_ATTR_TEXT], "\"res:drive\"", 11) != 0) @@ -944,11 +789,13 @@ ResSimProcessDrivePoints(filename) /* *------------------------------------------------------------------------- * - * ResSimProcessFixPoints -- if the sim file contains a "res:fix:name" label + * ResExtProcessFixPoints -- if the ext file contains a "res:fix:name" label * and we are checking for power supply noise, then we have to * parse the .ext file looking for the fix label locations. This * is only done after the first res:fix label is encountered. * + * (FIXME---This is now all in the .ext file so the information does + * not need to be read twice.) * * Results: * None. @@ -960,7 +807,7 @@ ResSimProcessDrivePoints(filename) */ void -ResSimProcessFixPoints(filename) +ResExtProcessFixPoints(filename) char *filename; { char line[MAXLINE][MAXTOKEN], *label, *c; @@ -1006,72 +853,31 @@ ResSimProcessFixPoints(filename) /* *------------------------------------------------------------------------- * - * ResSimMerge-- Processes = line in sim file + * ResInitializeNode -- + * Gets the node corresponding to a given hash table entry. If no + * such node exists, one is created. * - * Results: Success/Failure + * Results: Returns ResExtNode corresponding to entry. * - * Side Effects: The forward field of one node is set to point to the - * other node. All of the junkt from the first node is moved to - * the second node. + * Side Effects: May allocate a new ResExtNode. * *------------------------------------------------------------------------- */ -int -ResSimMerge(line) - char line[][MAXTOKEN]; - -{ - ResSimNode *node; - devPtr *ptr; - - if ((line[ALIASNAME][0] == '\0') || (line[REALNAME][0] == '\0')) - { - TxError("Bad node alias line\n"); - return(1); - } - node = ResInitializeNode(HashFind(&ResNodeTable, line[ALIASNAME])); - node->status |= FORWARD; - node->forward = ResInitializeNode(HashFind(&ResNodeTable, line[REALNAME])); - node->forward->resistance += node->resistance; - node->forward->capacitance += node->capacitance; - while (node->firstDev != NULL) - { - ptr = node->firstDev; - node->firstDev = node->firstDev->nextDev; - ptr->nextDev = node->forward->firstDev; - node->forward->firstDev = ptr; - } - return 0; -} - -/* - *------------------------------------------------------------------------- - * - * ResInitializeNode-- Gets the node corresponding to a given hash table - * entry. If no such node exists, one is created. - * - * Results:Returns ResSimNode corresponding to entry. - * - * Side Effects: May allocate a new ResSimNode. - * - *------------------------------------------------------------------------- - */ - -ResSimNode * +ResExtNode * ResInitializeNode(entry) HashEntry *entry; { - ResSimNode *node; + ResExtNode *node; - if ((node = (ResSimNode *) HashGetValue(entry)) == NULL) + if ((node = (ResExtNode *) HashGetValue(entry)) == NULL) { - node = (ResSimNode *)mallocMagic((unsigned)(sizeof(ResSimNode))); + node = (ResExtNode *)mallocMagic((unsigned)(sizeof(ResExtNode))); HashSetValue(entry, (char *) node); node->nextnode = ResOriginalNodes; ResOriginalNodes = node; node->status = FALSE; - node->forward = (ResSimNode *) NULL; + node->forward = (ResExtNode *) NULL; node->capacitance = 0; node->cap_vdd = 0; node->cap_couple = 0; diff --git a/resis/ResRex.c b/resis/ResRex.c index c453d0f0..6ecc7456 100644 --- a/resis/ResRex.c +++ b/resis/ResRex.c @@ -31,9 +31,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "utils/tech.h" #include "textio/txcommands.h" #include "resis/resis.h" -#ifdef LAPLACE -#include "laplace.h" -#endif #define INITFLATSIZE 1024 #define MAXNAME 1000 @@ -56,22 +53,17 @@ HashTable ResIncludeTable; /* Hash table of nodes to include */ HashTable ResProcessedTable; -/* ResSimNode is a node read in from a sim file */ +/* ResExtNode is a node read in from a .ext file */ -HashTable ResNodeTable; /* Hash table of sim file nodes */ -RDev *ResRDevList; /* Linked list of Sim devices */ +HashTable ResNodeTable; /* Hash table of ext file nodes */ +RDev *ResRDevList; /* Linked list of Ext devices */ ResGlobalParams gparams; /* Junk passed between */ - /* ResCheckSimNodes and */ + /* ResCheckExtNodes and */ /* ResExtractNet. */ -extern ResSimNode *ResOriginalNodes; /*Linked List of Nodes */ +extern ResExtNode *ResOriginalNodes; /*Linked List of Nodes */ int resNodeNum; -#ifdef LAPLACE -int ResOptionsFlags = ResOpt_Simplify | ResOpt_Tdi | ResOpt_DoExtFile - | ResOpt_CacheLaplace; -#else int ResOptionsFlags = ResOpt_Simplify | ResOpt_Tdi | ResOpt_DoExtFile; -#endif char *ResCurrentNode; FILE *ResExtFile; @@ -81,29 +73,9 @@ FILE *ResFHFile; int ResPortIndex; /* Port ordering to backannotate into magic */ /* external declarations */ -extern ResSimNode *ResInitializeNode(); +extern ResExtNode *ResInitializeNode(); extern CellUse *CmdGetSelectedCell(); -/* Linked list structure to use to store the substrate plane from each */ -/* extracted CellDef so that they can be returned to the original after */ -/* extraction. */ - -struct saveList { - Plane *sl_plane; - CellDef *sl_def; - struct saveList *sl_next; -}; - -/* Structure stores information required to be sent to ExtResisForDef() */ -typedef struct -{ - float tdiTolerance; - float frequency; - float rthresh; - struct saveList *savePlanes; - CellDef *mainDef; -} ResisData; - /* *------------------------------------------------------------------------- * @@ -123,7 +95,7 @@ ExtResisForDef(celldef, resisdata) HashSearch hs; HashEntry *entry; devPtr *tptr, *oldtptr; - ResSimNode *node; + ResExtNode *node; int result, idx; char *devname; Plane *savePlane; @@ -160,10 +132,8 @@ ExtResisForDef(celldef, resisdata) } HashInit(&ResNodeTable, INITFLATSIZE, HT_STRINGKEYS); - /* read in .sim file */ - result = (ResReadSim(celldef->cd_name, - ResSimDevice, ResSimCapacitor, ResSimResistor, - ResSimAttribute, ResSimMerge, ResSimSubckt) == 0); + /* Read in the .ext file */ + result = (ResReadExt(celldef->cd_name) == 0); /* Clean up the EFDevTypes table */ for (idx = 0; idx < EFDevNumTypes; idx++) freeMagic(EFDevTypes[idx]); @@ -184,7 +154,7 @@ ExtResisForDef(celldef, resisdata) /* Extract networks for nets that require it. */ if (!(ResOptionsFlags & ResOpt_FastHenry) || DBIsSubcircuit(celldef)) - ResCheckSimNodes(celldef, resisdata); + ResCheckExtNodes(celldef, resisdata); if (ResOptionsFlags & ResOpt_Stat) ResPrintStats((ResGlobalParams *)NULL, ""); @@ -195,7 +165,7 @@ ExtResisForDef(celldef, resisdata) HashStartSearch(&hs); while((entry = HashNext(&ResNodeTable, &hs)) != NULL) { - node=(ResSimNode *) HashGetValue(entry); + node=(ResExtNode *) HashGetValue(entry); tptr = node->firstDev; if (node == NULL) { @@ -227,14 +197,13 @@ ExtResisForDef(celldef, resisdata) /* *------------------------------------------------------------------------- * - * CmdExtResis-- reads in sim file and layout, and produces patches to the - * .ext files and .sim files that include resistors. + * CmdExtResis-- reads in ext file and layout, and produces patches to the + * .ext files that include resistors. * * Results: * None. * - * Side Effects: Produces .res.sim file and .res.ext file for all nets that - * require resistors. + * Side Effects: Produces .res.ext file for all nets that require resistors. * *------------------------------------------------------------------------- */ @@ -281,9 +250,6 @@ CmdExtResis(win, cmd) "fasthenry [freq] extract subcircuit network geometry into .fh file", "geometry extract network centerline geometry (experimental)", "help print this message", -#ifdef LAPLACE - "laplace [on/off] solve Laplace's equation using FEM", -#endif NULL }; @@ -293,9 +259,6 @@ typedef enum { RES_SIMP, RES_EXTOUT, RES_LUMPED, RES_SILENT, RES_SKIP, RES_IGNORE, RES_INCLUDE, RES_BOX, RES_CELL, RES_BLACKBOX, RES_FASTHENRY, RES_GEOMETRY, RES_HELP, -#ifdef LAPLACE - RES_LAPLACE, -#endif RES_RUN } ResOptions; @@ -582,7 +545,7 @@ typedef enum { CellDef *def; Rect rect; int oldoptions; - ResSimNode lnode; + ResExtNode lnode; if (ToolGetBoxWindow((Rect *) NULL, (int *) NULL) == NULL) { @@ -598,25 +561,11 @@ typedef enum { gparams.rg_status = DRIVEONLY; oldoptions = ResOptionsFlags; ResOptionsFlags = ResOpt_DoSubstrate | ResOpt_Signal | ResOpt_Box; -#ifdef LAPLACE - ResOptionsFlags |= (oldoptions & - (ResOpt_CacheLaplace | ResOpt_DoLaplace)); - LaplaceMatchCount = 0; - LaplaceMissCount = 0; -#endif lnode.location = rect.r_ll; lnode.type = tt; if (ResExtractNet(&lnode, &gparams, NULL) != 0) return; ResPrintResistorList(stdout, ResResList); ResPrintDeviceList(stdout, ResRDevList); -#ifdef LAPLACE - if (ResOptionsFlags & ResOpt_DoLaplace) - { - TxPrintf("Laplace solved: %d matched %d\n", - LaplaceMissCount, LaplaceMatchCount); - } -#endif - ResOptionsFlags = oldoptions; return; } @@ -634,11 +583,6 @@ typedef enum { case RES_RUN: ResOptionsFlags &= ~ResOpt_ExtractAll; break; -#ifdef LAPLACE - case RES_LAPLACE: - LaplaceParseString(cmd); - return; -#endif case RES_AMBIG: TxPrintf("Ambiguous option: %s\n", cmd->tx_argv[1]); TxFlushOut(); @@ -651,10 +595,6 @@ typedef enum { return; } -#ifdef LAPLACE - LaplaceMatchCount = 0; - LaplaceMissCount = 0; -#endif /* turn off undo stuff */ UndoDisable(); @@ -666,9 +606,6 @@ typedef enum { return; } ResOptionsFlags |= ResOpt_Signal; -#ifdef ARIEL - ResOptionsFlags &= ~ResOpt_Power; -#endif resisdata.rthresh = rthresh; resisdata.tdiTolerance = tdiTolerance; @@ -695,13 +632,6 @@ typedef enum { /* turn back on undo stuff */ UndoEnable(); -#ifdef LAPLACE - if (ResOptionsFlags & ResOpt_DoLaplace) - { - TxPrintf("Laplace solved: %d matched %d\n", - LaplaceMissCount, LaplaceMatchCount); - } -#endif /* Revert to the original flags in the case of FastHenry or */ /* geometry centerline extraction. */ @@ -765,7 +695,7 @@ resPortFunc(scx, lab, tpath, result) int pclass, puse; Point portloc; HashEntry *entry; - ResSimNode *node; + ResExtNode *node; // Ignore the top level cell if (scx->scx_use->cu_id == NULL) return 0; @@ -904,7 +834,7 @@ ResCheckPorts(cellDef) Point portloc; Label *lab; HashEntry *entry; - ResSimNode *node; + ResExtNode *node; int result = 1; for (lab = cellDef->cd_labels; lab; lab = lab->lab_next) @@ -930,7 +860,7 @@ ResCheckPorts(cellDef) entry = HashFind(&ResNodeTable, lab->lab_text); result = 0; - if ((node = (ResSimNode *) HashGetValue(entry)) != NULL) + if ((node = (ResExtNode *) HashGetValue(entry)) != NULL) { TxPrintf("Port: name = %s exists, forcing drivepoint\n", lab->lab_text); @@ -966,34 +896,6 @@ ResCheckPorts(cellDef) return result; } -/* - *------------------------------------------------------------------------- - * - * ResCreateNode --- - * - * Create a node structure for extresist for the method where - * ResProcessNode() is called from extBasic() as part of the - * "extract" command. - * - * Results: - * Returns the node structure to be passed to ResProcessNode(). - * - * Side effects: - * Memory is allocated for the node structure. - * - *------------------------------------------------------------------------- - */ - -ResSimNode *ResCreateNode() -{ - ResSimNode *node; - - /* To be completed */ - - return node; -} - - /* *------------------------------------------------------------------------- * @@ -1013,7 +915,7 @@ ResSimNode *ResCreateNode() int ResProcessNode( - ResSimNode *node, /* Node record for network */ + ResExtNode *node, /* Node record for network */ CellDef *celldef, /* Cell def being processed */ ResisData *resisdata, /* Extraction parameters kept here */ char *outfile, /* Name of output file */ @@ -1186,7 +1088,7 @@ ResProcessNode( /* *------------------------------------------------------------------------- * - * ResCheckSimNodes-- check to see if lumped resistance is greater than the + * ResCheckExtNodes-- check to see if lumped resistance is greater than the * device resistance; if it is, Extract the net * resistance. If the maximum point to point resistance * in the extracted net is still creater than the @@ -1194,17 +1096,17 @@ ResProcessNode( * * Results: none * - * Side Effects: Writes networks to .res.ext and .res.sim files. + * Side Effects: Writes networks to .res.ext files. * *------------------------------------------------------------------------- */ void -ResCheckSimNodes(celldef, resisdata) +ResCheckExtNodes(celldef, resisdata) CellDef *celldef; ResisData *resisdata; { - ResSimNode *node; + ResExtNode *node; int numext = 0; /* Number of nets extracted */ int numout = 0; /* Number of nets output */ int total = 0; /* Total number of nets processed */ @@ -1339,8 +1241,8 @@ ResCheckSimNodes(celldef, resisdata) * * Results:none * - * Side Effects: Allocates new ResSimNodes. Modifies the terminal connections - * of sim Devices. + * Side Effects: Allocates new ResExtNodes. Modifies the terminal connections + * of ext Devices. * *------------------------------------------------------------------------- */ @@ -1349,7 +1251,7 @@ void ResFixUpConnections(simDev, layoutDev, simNode, nodename) RDev *simDev; resDevice *layoutDev; - ResSimNode *simNode; + ResExtNode *simNode; char *nodename; { @@ -1601,7 +1503,7 @@ ResFixDevName(line, type, device, layoutnode) { HashEntry *entry; - ResSimNode *node; + ResExtNode *node; devPtr *tptr; if (layoutnode->rn_name != NULL) @@ -1757,7 +1659,7 @@ ResSortByGate(DevpointerList) void ResWriteLumpFile(node) - ResSimNode *node; + ResExtNode *node; { int lumpedres; @@ -1852,7 +1754,7 @@ ResAlignNodes(nodelist, reslist) int ResWriteExtFile(celldef, node, rctol, nidx, eidx) CellDef *celldef; - ResSimNode *node; + ResExtNode *node; float rctol; int *nidx, *eidx; { diff --git a/resis/ResSimple.c b/resis/ResSimple.c index 3e87d673..9eed823f 100644 --- a/resis/ResSimple.c +++ b/resis/ResSimple.c @@ -383,27 +383,17 @@ ResMoveDevices(node1, node2) device = devptr->te_thist; oldptr = devptr; devptr = devptr->te_nextt; - if (device->rd_status & RES_DEV_PLUG) - { - if (((ResPlug *)(device))->rpl_node == node1) - ((ResPlug *)(device))->rpl_node = node2; - else - TxError("Bad node connection in plug\n"); - } + if (device->rd_fet_gate == node1) + device->rd_fet_gate = node2; + else if (device->rd_fet_subs == node1) + device->rd_fet_subs = node2; + else if (device->rd_fet_source == node1) + device->rd_fet_source = node2; + else if (device->rd_fet_drain == node1) + device->rd_fet_drain = node2; else - { - if (device->rd_fet_gate == node1) - device->rd_fet_gate = node2; - else if (device->rd_fet_subs == node1) - device->rd_fet_subs = node2; - else if (device->rd_fet_source == node1) - device->rd_fet_source = node2; - else if (device->rd_fet_drain == node1) - device->rd_fet_drain = node2; - else - TxError("Missing Device connection in squish routines" + TxError("Missing Device connection in squish routines" " at %d, %d\n", node1->rn_loc.p_x, node1->rn_loc.p_y); - } oldptr->te_nextt = node2->rn_te; node2->rn_te = oldptr; } diff --git a/resis/ResWrite.c b/resis/ResWrite.c index 7b40e6d2..8458282a 100644 --- a/resis/ResWrite.c +++ b/resis/ResWrite.c @@ -140,9 +140,8 @@ resCurrentPrintFunc(node, resistor, filename) for (workingDev = node->rn_te; workingDev != NULL; workingDev = workingDev->te_nextt) { - if ((workingDev->te_thist->rd_status & RES_DEV_PLUG) || - workingDev->te_thist->rd_gate != node) - i_sum += workingDev->te_thist->rd_i; + if (workingDev->te_thist->rd_gate != node) + i_sum += workingDev->te_thist->rd_i; } if (i_sum != 0.0) { diff --git a/resis/resis.h b/resis/resis.h index f9129a3d..1da90a86 100644 --- a/resis/resis.h +++ b/resis/resis.h @@ -57,10 +57,6 @@ typedef struct resistor int rr_cl; /* resistor centerline for geometry */ int rr_width; /* resistor width for geometry */ TileType rr_tt; /* type that composes this */ - /* resistor. */ -#ifdef ARIEL - int rr_csArea; /* crosssectional area in lamba**2*/ -#endif } resResistor; #define rr_connection1 rr_node[0] @@ -92,10 +88,6 @@ typedef struct device int rd_devtype; /* tiletype of device. */ Rect rd_inside; /* 1x1 rectangle inside device */ Tile *rd_tile; /* pointer to a tile in device */ -#ifdef ARIEL - float rd_i; /* Current injected from this device */ - /* in milliamps */ -#endif } resDevice; /* @@ -254,7 +246,7 @@ typedef struct resdevtile /* Goodies contains random stuff passed between the node extractor - and ResCheckSimNodes. The location of a start tile and the resistive + and ResCheckExtNodes. The location of a start tile and the resistive tolerance are passed down, while the derived network is passed back. */ @@ -271,7 +263,28 @@ typedef struct goodstuff char *rg_name; } ResGlobalParams; -/* Used in RC delay calculations for Tdi filter */ +/* Linked list structure to use to store the substrate plane from each */ +/* extracted CellDef so that they can be returned to the original after */ +/* extraction. */ + +struct saveList { + Plane *sl_plane; + CellDef *sl_def; + struct saveList *sl_next; +}; + +/* Structure stores information required to be sent to ExtResisForDef() */ + +typedef struct +{ + float tdiTolerance; + float frequency; + float rthresh; + struct saveList *savePlanes; + CellDef *mainDef; +} ResisData; + +/* Structure used in RC delay calculations for Tdi filter. */ /* Attaches to rn_client field of resNode */ typedef struct rcdelaystuff @@ -281,7 +294,7 @@ typedef struct rcdelaystuff } RCDelayStuff; -/* ResSim.c type declarations */ +/* Type declarations */ typedef struct rdev { @@ -291,10 +304,10 @@ typedef struct rdev resDevice *layout; /* pointer to resDevice that */ /* corresponds to RDev */ int status; - struct ressimnode *gate; /* Terminals of transistor. */ - struct ressimnode *source; - struct ressimnode *drain; - struct ressimnode *subs; /* Used with subcircuit type only */ + struct resextnode *gate; /* Terminals of transistor. */ + struct resextnode *source; + struct resextnode *drain; + struct resextnode *subs; /* Used with subcircuit type only */ Point location; /* Location of lower left point of */ /* device. */ float resistance; /* "Resistance" of device. */ @@ -305,12 +318,12 @@ typedef struct rdev char *rs_dattr; } RDev; -typedef struct ressimnode +typedef struct resextnode { - struct ressimnode *nextnode; /* next node in OriginalNodes */ + struct resextnode *nextnode; /* next node in OriginalNodes */ /* linked list. */ int status; - struct ressimnode *forward; /* If node has been merged, this */ + struct resextnode *forward; /* If node has been merged, this */ /* points to the merged node. */ float capacitance; /* capacitance between node and */ /* GND for power connections */ @@ -340,7 +353,7 @@ typedef struct ressimnode tElement *rs_sublist[2]; /* pointers to Gnd and Vdd sub */ /* strate connections, if they exist */ -} ResSimNode; +} ResExtNode; #define RES_SUB_GND 0 #define RES_SUB_VDD 1 @@ -355,40 +368,6 @@ typedef struct devptr /* is connected to node. */ } devPtr; -/* ResTime.c type declarations */ - -typedef struct resevent /* Raw event list read in from rsim/tv */ -{ - int rv_node; /* node number */ - int rv_final; /* final value; (0,1, or X) */ - int rv_tmin; /* minimum event time in units of 100ps */ - int rv_tmax; /* maximum event time in units of 100ps */ - float rv_i; /* event current in milliamps */ - resDevice *rv_dev; /* device where charge drains */ -} ResEvent; - -typedef struct reseventcell -{ - ResEvent *rl_this; - struct reseventcell *rl_next; -} REcell; - -typedef struct rescurrentevent /* processed event used to feed relaxer */ -{ - struct rescurrentevent *ri_next; - float ri_i; - resDevice *ri_dev; -} ResCurrentEvent; - -typedef struct restimebin /* Holds one timestep's worth of Events */ -{ - struct restimebin *rb_next; - struct restimebin *rb_last; - int rb_start; - int rb_end; - ResCurrentEvent *rb_first; -} ResTimeBin; - typedef struct resfixpoint /* Keeps track of where voltage sources are */ { struct resfixpoint *fp_next; @@ -400,30 +379,6 @@ typedef struct resfixpoint /* Keeps track of where voltage sources are */ char fp_name[1]; } ResFixPoint; -typedef struct clump -{ - unsigned rp_status; - rElement *rp_grouplist; - nElement *rp_nodelist; - rElement *rp_downlist; - rElement *rp_singlelist; -} ResClump; - -/* the first two fields of this plug must be the the same as for - resDevice -*/ -typedef struct plug -{ - float rpl_i; /* current injected through - this plug - */ - int rpl_status; /* status bits for this plug */ - struct plug *rpl_next; /* next plug in this bin */ - Point rpl_loc; /*location of plug */ - int rpl_type; /*type of plug */ - resNode *rpl_node; /* this point's node */ -} ResPlug; - typedef struct capval { float cap[1][2]; /* multipliers telling what portion of capacitance is @@ -458,7 +413,6 @@ typedef struct capval /* device flags */ #define RES_DEV_SAVE 0x00000001 -#define RES_DEV_PLUG 0x00000002 /* flags for tiles */ /* A tile which is part of a substrate region. */ @@ -473,11 +427,6 @@ typedef struct capval #define RES_TILE_MARK 0x10 /*another temporary marking flag */ #define RES_TILE_PUSHED 0x20 -/* indicates that tile has unidirectional current flow */ -#ifdef LAPLACE -#define RES_TILE_1D 0x40 -#define RES_TILE_GDONE 0x80 -#endif /* tree walking flags */ #define RES_LOOP_OK 1 #define RES_NO_LOOP 1 @@ -486,7 +435,7 @@ typedef struct capval #define RES_NO_FLAGS 0 -/* ResSim Constants */ +/* Constants */ #define FORWARD 0x0000010 #define SKIP 0x0000020 #define FORCE 0x0000040 @@ -561,16 +510,9 @@ typedef struct capval #define ResOpt_Blackbox 0x00010000 #define ResOpt_Dump 0x00020000 #define ResOpt_DoSubstrate 0x00040000 -#define ResOpt_GndPlugs 0x00200000 -#define ResOpt_VddPlugs 0x00400000 #define ResOpt_CMOS 0x00800000 #define ResOpt_Bipolar 0x01000000 #define ResOpt_Box 0x02000000 -#ifdef LAPLACE -#define ResOpt_DoLaplace 0x04000000 -#define ResOpt_CacheLaplace 0x08000000 -#define ResOpt_Checkpoint 0x80000000 -#endif #define ResOpt_VDisplay 0x10000000 #define ResOpt_IDisplay 0x20000000 @@ -579,18 +521,9 @@ typedef struct capval /* Assorted Variables */ extern RDev *ResRDevList; -extern REcell *ResBigEventList; extern int ResOptionsFlags; extern char *ResCurrentNode; -extern ResSimNode *ResOriginalNodes; -#ifdef ARIEL -extern int ResMinEventTime; -extern int ResMaxEventTime; -typedef float ResCapElement[2]; -extern ResCapElement *ResCapTableMax; -extern ResCapElement *ResCapTableMin; -extern HashTable ResPlugTable; -#endif +extern ResExtNode *ResOriginalNodes; extern CellUse *ResUse; extern CellDef *ResDef; @@ -604,10 +537,10 @@ extern resNode *ResNodeQueue; extern resNode *ResOriginNode; extern resNode *resCurrentNode; extern HashTable ResNodeTable; -extern HashTable ResSimDevTable; +extern HashTable ResExtDevTable; extern ResFixPoint *ResFixList; extern int ResTileCount; -extern ResSimNode **ResNodeArray; +extern ResExtNode **ResNodeArray; extern CellDef *mainDef; extern TileTypeBitMask ResSDTypesBitMask; extern TileTypeBitMask ResSubTypesBitMask; @@ -616,24 +549,26 @@ extern TileTypeBitMask ResNoMergeMask[NT]; extern ResGlobalParams gparams; extern int ResPortIndex; -extern int ResSimDevice(); -extern int ResSimCombineParallel(); -extern int ResSimCapacitor(); -extern int ResSimResistor(); -extern int ResSimAttribute(); -extern int ResSimMerge(); -extern int ResSimSubckt(); +/* Routines used by ResReadExt() */ +extern int ResReadDevice(); +extern int ResReadCapacitor(); +extern int ResReadResistor(); +extern int ResReadAttribute(); +extern int ResReadMerge(); +extern int ResReadSubckt(); + +extern int ResProcessNode(); +extern int ResExtCombineParallel(); extern int dbSrConnectStartFunc(); extern int ResEach(),ResAddPlumbing(),ResRemovePlumbing(); extern float ResCalculateChildCapacitance(); extern ResDevTile *DBTreeCopyConnectDCS(); extern Tile *ResFindTile(); -extern resDevice *ResImageAddPlug(); extern resDevice *ResGetDevice(); extern tileJunk *resAddField(); extern int ResCheckPorts(); extern int ResCheckBlackbox(); -extern void ResCheckSimNodes(); +extern void ResCheckExtNodes(); extern void ResSortByGate(); extern void ResFixDevName(); extern void ResWriteLumpFile(); @@ -663,9 +598,10 @@ extern void ResPrintResistorList(); extern void ResPrintStats(); extern void ResProcessJunction(); extern int ResReadNode(); -extern int ResReadSim(); +extern int ResReadExt(); extern void ResRemoveFromQueue(); -extern int ResSimNewNode(); +extern int ResExtNewNode(); +extern void ResExtProcessDrivePoints(); extern int ResWriteExtFile(); extern void ResPrintExtNode(); extern void ResPrintExtRes();