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.
This commit is contained in:
R. Timothy Edwards 2026-01-27 11:56:47 -05:00
parent 297a05c4ed
commit 76f97c90e5
16 changed files with 420 additions and 824 deletions

68
README
View File

@ -132,3 +132,71 @@ around for the duration of the extraction, and needs to have the
extresist splits on hand for coupling capacitance calculations extresist splits on hand for coupling capacitance calculations
and all output. Maybe copy in a simplified form to yet another and all output. Maybe copy in a simplified form to yet another
ClientData field on a nodeRegion. 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.

View File

@ -37,6 +37,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "commands/commands.h" #include "commands/commands.h"
#include "database/database.h" #include "database/database.h"
#include "extflat/extflat.h" #include "extflat/extflat.h"
#include "extflat/extparse.h"
#include "extflat/EFint.h" #include "extflat/EFint.h"
#include "extract/extract.h" #include "extract/extract.h"
#include "extract/extractInt.h" #include "extract/extractInt.h"
@ -45,61 +46,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
/* C99 compat */ /* C99 compat */
#include "textio/textio.h" #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 */ /* Data shared with EFerror.c */
char *efReadFileName; /* Name of file currently being read */ char *efReadFileName; /* Name of file currently being read */
int efReadLineNum; /* Current line number in above file */ 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 */ /* Data local to this file */
static bool efReadDef(Def *def, bool dosubckt, bool resist, bool noscale, bool toplevel, bool isspice); 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))
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *

84
extflat/extparse.h Normal file
View File

@ -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 */

View File

@ -37,6 +37,7 @@ static char sccsid[] = "@(#)ExtBasic.c 4.13 MAGIC (Berkeley) 12/5/85";
#include "utils/malloc.h" #include "utils/malloc.h"
#include "textio/textio.h" #include "textio/textio.h"
#include "debug/debug.h" #include "debug/debug.h"
#include "extflat/extparse.h"
#include "extract/extract.h" #include "extract/extract.h"
#include "extract/extractInt.h" #include "extract/extractInt.h"
#include "utils/signals.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/styles.h"
#include "utils/stack.h" #include "utils/stack.h"
#include "utils/utils.h" #include "utils/utils.h"
#include "resis/resis.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
/* --------------------- Data local to this file ---------------------- */ /* --------------------- Data local to this file ---------------------- */
@ -301,28 +289,6 @@ extBasic(def, outFile)
if (!SigInterruptPending && (ExtDoWarn & EXTWARN_DUP) && !isabstract) if (!SigInterruptPending && (ExtDoWarn & EXTWARN_DUP) && !isabstract)
extFindDuplicateLabels(def, nodeList); 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). * Build up table of coupling capacitances (overlap, sidewall).
* This comes before extOutputNodes because we may have to adjust * This comes before extOutputNodes because we may have to adjust
@ -580,6 +546,24 @@ extBasic(def, outFile)
extOutputDevices(def, transList, outFile); extOutputDevices(def, transList, outFile);
} }
/* Integrated extresist --- Run "extresist" on the cell def just
* extracted and produce an annotation file "<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 */ /* Clean up */
if (coupleInitialized) if (coupleInitialized)
extCapHashKill(&extCoupleHash); extCapHashKill(&extCoupleHash);

View File

@ -5,7 +5,7 @@
MODULE = resis MODULE = resis
MAGICDIR = .. MAGICDIR = ..
SRCS = ResMain.c ResJunct.c ResMakeRes.c ResSimple.c ResPrint.c \ 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 ResFract.c ResUtils.c ResDebug.c
include ${MAGICDIR}/defs.mak include ${MAGICDIR}/defs.mak

View File

@ -112,7 +112,6 @@ ResSanityChecks(nodename, resistorList, nodeList, devlist)
{ {
int i; int i;
if (dev->rd_status & RES_DEV_PLUG) continue;
reached = FALSE; reached = FALSE;
for (i = 0; i != dev->rd_nterms; i++) for (i = 0; i != dev->rd_nterms; i++)
{ {

View File

@ -120,7 +120,6 @@ ResPrintDeviceList(fp, list)
int i; int i;
for (; list != NULL; list = list->rd_nextDev) for (; list != NULL; list = list->rd_nextDev)
{ {
if (list->rd_status & RES_DEV_PLUG) continue;
if (fp == stdout) if (fp == stdout)
TxPrintf("t w %d l %d ", list->rd_width, list->rd_length); TxPrintf("t w %d l %d ", list->rd_width, list->rd_length);
else else

View File

@ -41,7 +41,7 @@ int ResTileCount = 0; /* Number of tiles rn_status */
extern ExtRegion *ResFirst(); extern ExtRegion *ResFirst();
extern Tile *FindStartTile(); extern Tile *FindStartTile();
extern int ResEachTile(); extern int ResEachTile();
extern ResSimNode *ResInitializeNode(); extern ResExtNode *ResInitializeNode();
TileTypeBitMask ResSDTypesBitMask; TileTypeBitMask ResSDTypesBitMask;
TileTypeBitMask ResSubTypesBitMask; TileTypeBitMask ResSubTypesBitMask;
@ -201,13 +201,13 @@ ResMakePortBreakpoints(def)
TileTypeBitMask mask; TileTypeBitMask mask;
HashSearch hs; HashSearch hs;
HashEntry *entry; HashEntry *entry;
ResSimNode *node; ResExtNode *node;
int ResAddBreakpointFunc(); /* Forward Declaration */ int ResAddBreakpointFunc(); /* Forward Declaration */
HashStartSearch(&hs); HashStartSearch(&hs);
while((entry = HashNext(&ResNodeTable,&hs)) != NULL) while((entry = HashNext(&ResNodeTable,&hs)) != NULL)
{ {
node = (ResSimNode *)HashGetValue(entry); node = (ResExtNode *)HashGetValue(entry);
if (node->status & PORTNODE) if (node->status & PORTNODE)
{ {
if (node->rs_ttype <= 0) if (node->rs_ttype <= 0)
@ -281,7 +281,7 @@ ResMakeLabelBreakpoints(def, goodies)
Rect *rect; Rect *rect;
TileTypeBitMask mask; TileTypeBitMask mask;
HashEntry *entry; HashEntry *entry;
ResSimNode *node; ResExtNode *node;
Label *slab; Label *slab;
int ResAddBreakpointFunc(); /* Forward Declaration */ int ResAddBreakpointFunc(); /* Forward Declaration */
@ -353,7 +353,7 @@ int
ResAddBreakpointFunc(tile, dinfo, node) ResAddBreakpointFunc(tile, dinfo, node)
Tile *tile; Tile *tile;
TileType dinfo; /* (unused) */ TileType dinfo; /* (unused) */
ResSimNode *node; ResExtNode *node;
{ {
tileJunk *junk; tileJunk *junk;
@ -512,51 +512,6 @@ ResProcessTiles(goodies, origin)
resCurrentNode = NULL; resCurrentNode = NULL;
(void) ResEachTile(startTile, origin); (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 #ifdef PARANOID
else else
{ {
@ -1036,7 +991,7 @@ ResShaveContacts(tile, dinfo, def)
bool bool
ResExtractNet(node, goodies, cellname) ResExtractNet(node, goodies, cellname)
ResSimNode *node; ResExtNode *node;
ResGlobalParams *goodies; ResGlobalParams *goodies;
char *cellname; char *cellname;
{ {
@ -1103,11 +1058,6 @@ ResExtractNet(node, goodies, cellname)
DBCellClearDef(ResUse->cu_def); DBCellClearDef(ResUse->cu_def);
#ifdef ARIEL
if ((ResOptionsFlags & ResOpt_Power) &&
strcmp(node->name, goodies->rg_name) != 0) continue;
#endif
/* Copy Paint */ /* Copy Paint */
scx.scx_area.r_ll.p_x = node->location.p_x - 2; scx.scx_area.r_ll.p_x = node->location.p_x - 2;
@ -1239,30 +1189,6 @@ ResExtractNet(node, goodies, cellname)
ResFindNewContactTiles(ResContactList); ResFindNewContactTiles(ResContactList);
ResPreProcessDevices(DevTiles, ResDevList, ResUse->cu_def); 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 */ /* do extraction */
if (ResProcessTiles(goodies, &startpoint) != 0) return TRUE; if (ResProcessTiles(goodies, &startpoint) != 0) return TRUE;
return FALSE; return FALSE;

View File

@ -263,10 +263,6 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
{ {
resistor->rr_status = RES_EW; resistor->rr_status = RES_EW;
} }
#ifdef ARIEL
resistor->rr_csArea = height *
ExtCurStyle->exts_thick[resistor->rr_tt];
#endif
resistor->rr_value = resistor->rr_value =
(float)ExtCurStyle->exts_sheetResist[resistor->rr_tt] (float)ExtCurStyle->exts_sheetResist[resistor->rr_tt]
* (float)(p2->br_loc.p_x - p1->br_loc.p_x) * (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; resistor->rr_status = RES_NS;
} }
#ifdef ARIEL
resistor->rr_csArea = width
* ExtCurStyle->exts_thick[resistor->rr_tt];
#endif
resistor->rr_value = resistor->rr_value =
(float)ExtCurStyle->exts_sheetResist[resistor->rr_tt] (float)ExtCurStyle->exts_sheetResist[resistor->rr_tt]
* (float)(p2->br_loc.p_y - p1->br_loc.p_y) * (float)(p2->br_loc.p_y - p1->br_loc.p_y)
@ -916,11 +908,6 @@ ResDoContacts(contact, nodes, resList)
resistor->rr_value = resistor->rr_value =
(float)ExtCurStyle->exts_viaResist[contact->cp_type] / (float)ExtCurStyle->exts_viaResist[contact->cp_type] /
(float)(squaresx * squaresy); (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_tt = contact->cp_type;
resistor->rr_float.rr_area = 0; resistor->rr_float.rr_area = 0;
resistor->rr_status = 0; resistor->rr_status = 0;

View File

@ -150,14 +150,6 @@ ResFixRes(resptr, resptr2, resptr3, elimResis, newResis)
ASSERT(newResis->rr_value > 0, "series"); ASSERT(newResis->rr_value > 0, "series");
newResis->rr_float.rr_area += elimResis->rr_float.rr_area; 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) for (thisREl = resptr3->rn_re; (thisREl != NULL); thisREl = thisREl->re_nextEl)
{ {
if (thisREl->re_thisEl == elimResis) if (thisREl->re_thisEl == elimResis)
@ -206,9 +198,6 @@ ResFixParallel(elimResis, newResis)
newResis->rr_value = 0; newResis->rr_value = 0;
} }
newResis->rr_float.rr_area += elimResis->rr_float.rr_area; 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_connection1, elimResis);
ResDeleteResPointer(elimResis->rr_connection2, elimResis); ResDeleteResPointer(elimResis->rr_connection2, elimResis);
ResEliminateResistor(elimResis, &ResResList); ResEliminateResistor(elimResis, &ResResList);
@ -670,28 +659,13 @@ ResMergeNodes(node1, node2, pendingList, doneList)
/* merge device lists */ /* merge device lists */
workingDev = node2->rn_te; workingDev = node2->rn_te;
while (workingDev != NULL) 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++) for (j = 0; j != workingDev->te_thist->rd_nterms; j++)
if (workingDev->te_thist->rd_terminals[j] == node2) if (workingDev->te_thist->rd_terminals[j] == node2)
workingDev->te_thist->rd_terminals[j] = node1; workingDev->te_thist->rd_terminals[j] = node1;
}
tDev = workingDev; tDev = workingDev;
workingDev = workingDev->te_nextt; workingDev = workingDev->te_nextt;
tDev->te_nextt = node1->rn_te; tDev->te_nextt = node1->rn_te;
@ -749,11 +723,11 @@ ResMergeNodes(node1, node2, pendingList, doneList)
else if ((node2->rn_name != NULL) && (node2->rn_name != node1->rn_name)) else if ((node2->rn_name != NULL) && (node2->rn_name != node1->rn_name))
{ {
HashEntry *entry; HashEntry *entry;
ResSimNode *node; ResExtNode *node;
/* Check if node2 is a port */ /* Check if node2 is a port */
entry = HashFind(&ResNodeTable, node2->rn_name); entry = HashFind(&ResNodeTable, node2->rn_name);
node = (ResSimNode *)HashGetValue(entry); node = (ResExtNode *)HashGetValue(entry);
if (node && (node->status & PORTNODE)) if (node && (node->status & PORTNODE))
node1->rn_name = node2->rn_name; node1->rn_name = node2->rn_name;
} }

View File

@ -32,7 +32,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#define MAXNAME 1000 #define MAXNAME 1000
#define KV_TO_mV 1000000 #define KV_TO_mV 1000000
extern ResSimNode *ResInitializeNode(); extern ResExtNode *ResInitializeNode();
/* /*
@ -57,7 +57,7 @@ ResPrintExtRes(outextfile, resistors, nodename)
int nodenum=0; int nodenum=0;
char newname[MAXNAME]; char newname[MAXNAME];
HashEntry *entry; HashEntry *entry;
ResSimNode *node, *ResInitializeNode(); ResExtNode *node, *ResInitializeNode();
for (; resistors != NULL; resistors = resistors->rr_nextResistor) for (; resistors != NULL; resistors = resistors->rr_nextResistor)
{ {
@ -215,13 +215,13 @@ void
ResPrintExtNode(outextfile, nodelist, node) ResPrintExtNode(outextfile, nodelist, node)
FILE *outextfile; FILE *outextfile;
resNode *nodelist; resNode *nodelist;
ResSimNode *node; ResExtNode *node;
{ {
char *nodename = node->name; char *nodename = node->name;
int nodenum = 0; int nodenum = 0;
char newname[MAXNAME+32], tmpname[MAXNAME], *cp; char newname[MAXNAME+32], tmpname[MAXNAME], *cp;
HashEntry *entry; HashEntry *entry;
ResSimNode *newnode, *ResInitializeNode(); ResExtNode *newnode, *ResInitializeNode();
bool DoKillNode = TRUE; bool DoKillNode = TRUE;
bool NeedFix = FALSE; bool NeedFix = FALSE;
resNode *snode; resNode *snode;
@ -411,14 +411,14 @@ ResPrintFHNodes(fp, nodelist, nodename, nidx, celldef)
else else
{ {
HashEntry *entry; HashEntry *entry;
ResSimNode *simnode; ResExtNode *simnode;
/* If we process another sim file node while doing this */ /* If we process another sim file node while doing this */
/* one, mark it as status "REDUNDANT" so we don't duplicate */ /* one, mark it as status "REDUNDANT" so we don't duplicate */
/* the entry. */ /* the entry. */
entry = HashFind(&ResNodeTable, nodeptr->rn_name); entry = HashFind(&ResNodeTable, nodeptr->rn_name);
simnode = (ResSimNode *)HashGetValue(entry); simnode = (ResExtNode *)HashGetValue(entry);
if (simnode != NULL) if (simnode != NULL)
simnode->status |= REDUNDANT; simnode->status |= REDUNDANT;
} }

View File

@ -1,12 +1,13 @@
#ifndef lint #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 */ #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 "textio/txcommands.h"
#include "resis/resis.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_LENGTH 4
#define RDEV_WIDTH 5 #define RDEV_WIDTH 5
#define RDEV_DEVX 6 #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_TILE 6
#define RES_EXT_ATTR_TEXT 7 #define RES_EXT_ATTR_TEXT 7
#define MAXTOKEN 1024 #define MAXTOKEN 1024
#define MAXLINE 40 #define MAXLINE 40
#define MAXDIGIT 20 #define MAXDIGIT 20
ResExtNode *ResInitializeNode();
ResSimNode *ResInitializeNode(); ResExtNode *ResOriginalNodes; /*Linked List of Nodes */
ResSimNode *ResOriginalNodes; /*Linked List of Nodes */
static float resscale = 1.0; /* Scale factor */ static float resscale = 1.0; /* Scale factor */
char RDEV_NOATTR[1] = {'0'}; char RDEV_NOATTR[1] = {'0'};
ResFixPoint *ResFixList; 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();
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
* 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 int
ResReadSim(simfile, fetproc, capproc, resproc, attrproc, mergeproc, subproc) ResReadExt(char *extfile);
char *simfile;
int (*fetproc)(), (*capproc)(), (*resproc)();
int (*attrproc)(), (*mergeproc)(), (*subproc)();
{ {
char line[MAXLINE][MAXTOKEN]; char *line = NULL, *argv[128];
int result, fettype, extfile; int result, fettype, readdrivepoints;
FILE *fp, *fopen(); 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) if (fp == NULL)
{ {
TxError("Cannot open file %s%s\n", simfile, ".sim"); TxError("Cannot open file %s%s\n", extfile, ".ext");
return 1; return 1;
} }
extfile = 0; readdrivepoints = FALSE;
/* Read in file */ /* Read in the file. Makes use of various functions
while (gettokens(line, fp) != 0) * from extflat, mostly in EFread.c.
*/
EFSaveLocs = False;
efReadLineNum = 0;
while ((argc = efReadLine(&line, &size, fp, argv)) >= 0)
{ {
fettype = MINFINITY; n = LookupStruct(argv[0], (const LookupTable *)keyTable, sizeof keyTable[0]);
switch(line[0][0]) if (n < 0)
{ {
case '|': efReadError("Unrecognized token \"%s\" (ignored)\n", argv[0]);
if (strcmp(line[NODEUNITS],"units:") == 0) continue;
}
if (argc < keyTable[n].k_mintokens)
{ {
resscale = (float)atof(line[NODELAMBDA]); 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; if (resscale == 0.0) resscale = 1.0;
}
result=0;
break; break;
case 'e': case DEVICE:
fettype = DBTechNameType("efet"); ResReadSubckt(argc, argv);
break; break;
case 'd': case FET:
fettype = DBTechNameType("dfet"); ResReadDevice(argc, argv);
break; break;
case 'n': case MERGE:
fettype = DBTechNameType("nfet"); ResReadDrivePoint(argc, argv);
break; break;
case 'p': case NODE:
fettype = DBTechNameType("pfet"); case SUBSTRATE:
ResReadNode(argc, argv);
break; break;
case 'b': case PORT:
fettype = DBTechNameType("bnpn"); ResReadPort(argc, argv);
break; break;
case 'C': case ATTR:
if (capproc) result = (*capproc)(line); result = ResExtAttribute(curnodename,
break; argv[1], &readdrivepoints);
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':
break; break;
default: 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; 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]; /* to do: Handle CAP, RESISTOR, maybe others? */
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;
} }
} }
fclose(fp); fclose(fp);
@ -240,7 +178,7 @@ ResReadSim(simfile, fetproc, capproc, resproc, attrproc, mergeproc, subproc)
* ResReadNode-- Reads in a node file, puts location of nodes into node * ResReadNode-- Reads in a node file, puts location of nodes into node
* structures. * 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
* *
@ -248,104 +186,37 @@ ResReadSim(simfile, fetproc, capproc, resproc, attrproc, mergeproc, subproc)
*/ */
int int
ResReadNode(nodefile) ResReadNode(int argc, char *argv[])
char *nodefile;
{ {
char line[MAXLINE][MAXTOKEN];
FILE *fp, *fopen();
HashEntry *entry; HashEntry *entry;
ResSimNode *node; ResExtNode *node;
char *cp; char *cp;
float lambda; float lambda;
fp = PaOpen(nodefile, "r", ".nodes", ".", (char *)NULL, (char **)NULL);
if (fp == NULL)
{
TxError("Cannot open file %s%s\n", nodefile, ".nodes");
return 1;
}
while (gettokens(line,fp) != 0)
{
entry = HashFind(&ResNodeTable, line[NODES_NODENAME]); entry = HashFind(&ResNodeTable, line[NODES_NODENAME]);
node = ResInitializeNode(entry); node = ResInitializeNode(entry);
node->location.p_x = atoi(line[NODES_NODEX]); node->location.p_x = atoi(line[NODES_NODEX]);
node->location.p_y = atoi(line[NODES_NODEY]); 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'; if ((cp = strchr(line[NODES_NODETYPE], ';'))) *cp = '\0';
node->type = DBTechNameType(line[NODES_NODETYPE]); node->type = DBTechNameType(line[NODES_NODETYPE]);
if (node->type == -1) if (node->type == -1)
{ {
TxError("Bad tile type name in %s.nodes file for node %s\n", TxError("Bad tile type name in .ext file for node %s\n",
nodefile, node->name); node->name);
TxError("Did you use the newest version of ext2sim?\n");
fclose(fp);
return 1; return 1;
} }
}
fclose(fp);
return 0; return 0;
} }
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
* getline-- Gets a line from the current input file and breaks it into * ResReadSubckt-- Processes a subcircuit line from a ext file.
* 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.
* This uses the "user subcircuit" extension defined in * This uses the "user subcircuit" extension defined in
* IRSIM, although it is mostly intended as a way to work * 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. * when using extresist.
* *
* Results: returns 0 if line was added correctly. * Results: returns 0 if line was added correctly.
@ -356,7 +227,7 @@ gettokens(line, fp)
*/ */
int int
ResSimSubckt(line) ResReadSubckt(line)
char line[][MAXTOKEN]; char line[][MAXTOKEN];
{ {
RDev *device; RDev *device;
@ -473,7 +344,7 @@ ResSimSubckt(line)
TxError("Device %s has more than 4 ports (not handled).\n", line[i]); TxError("Device %s has more than 4 ports (not handled).\n", line[i]);
break; /* No method to handle more ports than this */ break; /* No method to handle more ports than this */
} }
rvalue += ResSimNewNode(line[k], k, device); rvalue += ResExtNewNode(line[k], k, device);
} }
return rvalue; 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. * Results: returns 0 if line was added correctly.
* *
@ -492,7 +363,7 @@ ResSimSubckt(line)
*/ */
int int
ResSimDevice(line, rpersquare, devptr) ResReadDevice(line, rpersquare, devptr)
char line[][MAXTOKEN]; char line[][MAXTOKEN];
float rpersquare; float rpersquare;
ExtDevice *devptr; ExtDevice *devptr;
@ -554,7 +425,7 @@ ResSimDevice(line, rpersquare, devptr)
device->rs_ttype = extGetDevType(devptr->exts_deviceName); 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" */ /* ext attributes are "a1","a2" */
/* Do conversion from one to the other here */ /* Do conversion from one to the other here */
/* NOTE: As of version 8.3.366, .ext attributes will end in two */ /* NOTE: As of version 8.3.366, .ext attributes will end in two */
@ -615,9 +486,9 @@ ResSimDevice(line, rpersquare, devptr)
} }
ResRDevList = device; ResRDevList = device;
device->layout = NULL; device->layout = NULL;
rvalue = ResSimNewNode(line[GATE], GATE, device) + rvalue = ResExtNewNode(line[GATE], GATE, device) +
ResSimNewNode(line[SOURCE], SOURCE, device) + ResExtNewNode(line[SOURCE], SOURCE, device) +
ResSimNewNode(line[DRAIN], DRAIN, device); ResExtNewNode(line[DRAIN], DRAIN, device);
return rvalue; 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. * Results: returns zero if node is added correctly, one otherwise.
* *
* Side Effects: Allocates a new ResSimNode * Side Effects: Allocates a new ResExtNode
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
int int
ResSimNewNode(line, type, device) ResExtNewNode(line, type, device)
char line[]; char line[];
int type; int type;
RDev *device; RDev *device;
{ {
HashEntry *entry; HashEntry *entry;
ResSimNode *node; ResExtNode *node;
devPtr *tptr; devPtr *tptr;
if (line[0] == '\0') 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 * node. Coupling capacitors are added twice, moving the capacitance
* to the substrate. * to the substrate.
* *
* Results: * Results:
* Always return 0 * Always return 0
* *
* Side Effects: modifies capacitance field of ResSimNode. * Side Effects: modifies capacitance field of ResExtNode.
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
int int
ResSimCapacitor(line) ResReadCapacitor(line)
char line[][MAXTOKEN]; char line[][MAXTOKEN];
{ {
HashEntry *entry1, *entry2; HashEntry *entry1, *entry2;
ResSimNode *node1, *node2; ResExtNode *node1, *node2;
if (line[COUPLETERMINAL1][0] == 0 || line[COUPLETERMINAL2][0] == 0) 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. * node.
* *
* Results * Results
* Return 0 to keep search going, 1 to abort * Return 0 to keep search going, 1 to abort
* *
* Side Effects: modifies resistance field of ResSimNode * Side Effects: modifies resistance field of ResExtNode
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
int int
ResSimResistor(line) ResReadResistor(line)
char line[][MAXTOKEN]; char line[][MAXTOKEN];
{ {
HashEntry *entry; HashEntry *entry;
ResSimNode *node; ResExtNode *node;
if (line[RESNODENAME][0] == 0) if (line[RESNODENAME][0] == 0)
{ {
@ -789,26 +660,27 @@ 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. * attribute. If it is, add it to the correct node's status flag.
* Only works with 5.0 1/line attributes * Only works with 5.0 1/line attributes
* *
* Results: * Results:
* Return 0 to keep search going, 1 to abort * Return 0 to keep search going, 1 to abort
* *
* Side Effects: modifies resistance field of ResSimNode * Side Effects: modifies resistance field of ResExtNode
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
int int
ResSimAttribute(aname, avalue, rootname, readextfile) ResReadAttribute(aname, avalue, readdrivepoints)
char *aname, *avalue, *rootname; char *aname;
int *readextfile; char *avalue;
bool *readdrivepoints;
{ {
HashEntry *entry; HashEntry *entry;
ResSimNode *node; ResExtNode *node;
char digit[MAXDIGIT]; char digit[MAXDIGIT];
int i; int i;
static int notwarned = TRUE; static int notwarned = TRUE;
@ -834,18 +706,14 @@ ResSimAttribute(aname, avalue, rootname, readextfile)
else if (strncmp(avalue, "res:force", 9) == 0) else if (strncmp(avalue, "res:force", 9) == 0)
{ {
if (node->status & SKIP) if (node->status & SKIP)
{
TxError("Warning: Node %s is both skipped and forced \n", aname); TxError("Warning: Node %s is both skipped and forced \n", aname);
}
else else
{
node->status |= FORCE; node->status |= FORCE;
} }
}
else if (strncmp(avalue, "res:min=", 8) == 0) else if (strncmp(avalue, "res:min=", 8) == 0)
{ {
node->status |= MINSIZE; node->status |= MINSIZE;
for (i = 0, avalue += 8; *avalue != '\0' && *avalue != ','; avalue++) for (i = 0, avalue += 8; *avalue != '\0'; avalue++)
{ {
digit[i++] = *avalue; digit[i++] = *avalue;
} }
@ -855,16 +723,14 @@ ResSimAttribute(aname, avalue, rootname, readextfile)
else if (strncmp(avalue, "res:drive", 9) == 0 && else if (strncmp(avalue, "res:drive", 9) == 0 &&
(ResOptionsFlags & ResOpt_Signal)) (ResOptionsFlags & ResOpt_Signal))
{ {
if (*readextfile == 0) if (*readdrivepoints == FALSE)
{ {
ResSimProcessDrivePoints(rootname); ResExtProcessDrivePoints(rootname);
*readextfile = 1; *readddrivepoints = TRUE;
} }
/* is the attribute in root.ext? */ /* is the attribute in root.ext? */
if (node->drivepoint.p_x != INFINITY) if (node->drivepoint.p_x != INFINITY)
{
node->status |= DRIVELOC; node->status |= DRIVELOC;
}
else else
{ {
if (notwarned) if (notwarned)
@ -873,34 +739,22 @@ ResSimAttribute(aname, avalue, rootname, readextfile)
notwarned = FALSE; 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; 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, * and we are doing a signal extraction,
* we need to search through the .ext file looking for attr labels that * 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 * contain this text. For efficiency, the .ext file is only parsed when
* the first res:drive is encountered. res:drive labels only work if * the first res:drive is encountered. res:drive labels only work if
* they are in the root cell. * 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: * Results:
* None. * None.
* *
@ -910,22 +764,13 @@ ResSimAttribute(aname, avalue, rootname, readextfile)
*/ */
void void
ResSimProcessDrivePoints(filename) ResExtProcessDrivePoints(FILE *fp)
char *filename;
{ {
char line[MAXLINE][MAXTOKEN]; char line[MAXLINE][MAXTOKEN];
FILE *fp; FILE *fp;
HashEntry *entry; 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 || if (strncmp(line[RES_EXT_ATTR], "attr", 4) != 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 * and we are checking for power supply noise, then we have to
* parse the .ext file looking for the fix label locations. This * parse the .ext file looking for the fix label locations. This
* is only done after the first res:fix label is encountered. * 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: * Results:
* None. * None.
@ -960,7 +807,7 @@ ResSimProcessDrivePoints(filename)
*/ */
void void
ResSimProcessFixPoints(filename) ResExtProcessFixPoints(filename)
char *filename; char *filename;
{ {
char line[MAXLINE][MAXTOKEN], *label, *c; 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 * Side Effects: May allocate a new ResExtNode.
* other node. All of the junkt from the first node is moved to
* the second node.
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
int ResExtNode *
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 *
ResInitializeNode(entry) ResInitializeNode(entry)
HashEntry *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); HashSetValue(entry, (char *) node);
node->nextnode = ResOriginalNodes; node->nextnode = ResOriginalNodes;
ResOriginalNodes = node; ResOriginalNodes = node;
node->status = FALSE; node->status = FALSE;
node->forward = (ResSimNode *) NULL; node->forward = (ResExtNode *) NULL;
node->capacitance = 0; node->capacitance = 0;
node->cap_vdd = 0; node->cap_vdd = 0;
node->cap_couple = 0; node->cap_couple = 0;

View File

@ -31,9 +31,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "utils/tech.h" #include "utils/tech.h"
#include "textio/txcommands.h" #include "textio/txcommands.h"
#include "resis/resis.h" #include "resis/resis.h"
#ifdef LAPLACE
#include "laplace.h"
#endif
#define INITFLATSIZE 1024 #define INITFLATSIZE 1024
#define MAXNAME 1000 #define MAXNAME 1000
@ -56,22 +53,17 @@ HashTable ResIncludeTable; /* Hash table of nodes to include */
HashTable ResProcessedTable; 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 */ HashTable ResNodeTable; /* Hash table of ext file nodes */
RDev *ResRDevList; /* Linked list of Sim devices */ RDev *ResRDevList; /* Linked list of Ext devices */
ResGlobalParams gparams; /* Junk passed between */ ResGlobalParams gparams; /* Junk passed between */
/* ResCheckSimNodes and */ /* ResCheckExtNodes and */
/* ResExtractNet. */ /* ResExtractNet. */
extern ResSimNode *ResOriginalNodes; /*Linked List of Nodes */ extern ResExtNode *ResOriginalNodes; /*Linked List of Nodes */
int resNodeNum; int resNodeNum;
#ifdef LAPLACE
int ResOptionsFlags = ResOpt_Simplify | ResOpt_Tdi | ResOpt_DoExtFile
| ResOpt_CacheLaplace;
#else
int ResOptionsFlags = ResOpt_Simplify | ResOpt_Tdi | ResOpt_DoExtFile; int ResOptionsFlags = ResOpt_Simplify | ResOpt_Tdi | ResOpt_DoExtFile;
#endif
char *ResCurrentNode; char *ResCurrentNode;
FILE *ResExtFile; FILE *ResExtFile;
@ -81,29 +73,9 @@ FILE *ResFHFile;
int ResPortIndex; /* Port ordering to backannotate into magic */ int ResPortIndex; /* Port ordering to backannotate into magic */
/* external declarations */ /* external declarations */
extern ResSimNode *ResInitializeNode(); extern ResExtNode *ResInitializeNode();
extern CellUse *CmdGetSelectedCell(); 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; HashSearch hs;
HashEntry *entry; HashEntry *entry;
devPtr *tptr, *oldtptr; devPtr *tptr, *oldtptr;
ResSimNode *node; ResExtNode *node;
int result, idx; int result, idx;
char *devname; char *devname;
Plane *savePlane; Plane *savePlane;
@ -160,10 +132,8 @@ ExtResisForDef(celldef, resisdata)
} }
HashInit(&ResNodeTable, INITFLATSIZE, HT_STRINGKEYS); HashInit(&ResNodeTable, INITFLATSIZE, HT_STRINGKEYS);
/* read in .sim file */ /* Read in the .ext file */
result = (ResReadSim(celldef->cd_name, result = (ResReadExt(celldef->cd_name) == 0);
ResSimDevice, ResSimCapacitor, ResSimResistor,
ResSimAttribute, ResSimMerge, ResSimSubckt) == 0);
/* Clean up the EFDevTypes table */ /* Clean up the EFDevTypes table */
for (idx = 0; idx < EFDevNumTypes; idx++) freeMagic(EFDevTypes[idx]); for (idx = 0; idx < EFDevNumTypes; idx++) freeMagic(EFDevTypes[idx]);
@ -184,7 +154,7 @@ ExtResisForDef(celldef, resisdata)
/* Extract networks for nets that require it. */ /* Extract networks for nets that require it. */
if (!(ResOptionsFlags & ResOpt_FastHenry) || if (!(ResOptionsFlags & ResOpt_FastHenry) ||
DBIsSubcircuit(celldef)) DBIsSubcircuit(celldef))
ResCheckSimNodes(celldef, resisdata); ResCheckExtNodes(celldef, resisdata);
if (ResOptionsFlags & ResOpt_Stat) if (ResOptionsFlags & ResOpt_Stat)
ResPrintStats((ResGlobalParams *)NULL, ""); ResPrintStats((ResGlobalParams *)NULL, "");
@ -195,7 +165,7 @@ ExtResisForDef(celldef, resisdata)
HashStartSearch(&hs); HashStartSearch(&hs);
while((entry = HashNext(&ResNodeTable, &hs)) != NULL) while((entry = HashNext(&ResNodeTable, &hs)) != NULL)
{ {
node=(ResSimNode *) HashGetValue(entry); node=(ResExtNode *) HashGetValue(entry);
tptr = node->firstDev; tptr = node->firstDev;
if (node == NULL) if (node == NULL)
{ {
@ -227,14 +197,13 @@ ExtResisForDef(celldef, resisdata)
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
* CmdExtResis-- reads in sim file and layout, and produces patches to the * CmdExtResis-- reads in ext file and layout, and produces patches to the
* .ext files and .sim files that include resistors. * .ext files that include resistors.
* *
* Results: * Results:
* None. * None.
* *
* Side Effects: Produces .res.sim file and .res.ext file for all nets that * Side Effects: Produces .res.ext file for all nets that require resistors.
* require resistors.
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -281,9 +250,6 @@ CmdExtResis(win, cmd)
"fasthenry [freq] extract subcircuit network geometry into .fh file", "fasthenry [freq] extract subcircuit network geometry into .fh file",
"geometry extract network centerline geometry (experimental)", "geometry extract network centerline geometry (experimental)",
"help print this message", "help print this message",
#ifdef LAPLACE
"laplace [on/off] solve Laplace's equation using FEM",
#endif
NULL NULL
}; };
@ -293,9 +259,6 @@ typedef enum {
RES_SIMP, RES_EXTOUT, RES_LUMPED, RES_SILENT, RES_SIMP, RES_EXTOUT, RES_LUMPED, RES_SILENT,
RES_SKIP, RES_IGNORE, RES_INCLUDE, RES_BOX, RES_CELL, RES_SKIP, RES_IGNORE, RES_INCLUDE, RES_BOX, RES_CELL,
RES_BLACKBOX, RES_FASTHENRY, RES_GEOMETRY, RES_HELP, RES_BLACKBOX, RES_FASTHENRY, RES_GEOMETRY, RES_HELP,
#ifdef LAPLACE
RES_LAPLACE,
#endif
RES_RUN RES_RUN
} ResOptions; } ResOptions;
@ -582,7 +545,7 @@ typedef enum {
CellDef *def; CellDef *def;
Rect rect; Rect rect;
int oldoptions; int oldoptions;
ResSimNode lnode; ResExtNode lnode;
if (ToolGetBoxWindow((Rect *) NULL, (int *) NULL) == NULL) if (ToolGetBoxWindow((Rect *) NULL, (int *) NULL) == NULL)
{ {
@ -598,25 +561,11 @@ typedef enum {
gparams.rg_status = DRIVEONLY; gparams.rg_status = DRIVEONLY;
oldoptions = ResOptionsFlags; oldoptions = ResOptionsFlags;
ResOptionsFlags = ResOpt_DoSubstrate | ResOpt_Signal | ResOpt_Box; 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.location = rect.r_ll;
lnode.type = tt; lnode.type = tt;
if (ResExtractNet(&lnode, &gparams, NULL) != 0) return; if (ResExtractNet(&lnode, &gparams, NULL) != 0) return;
ResPrintResistorList(stdout, ResResList); ResPrintResistorList(stdout, ResResList);
ResPrintDeviceList(stdout, ResRDevList); ResPrintDeviceList(stdout, ResRDevList);
#ifdef LAPLACE
if (ResOptionsFlags & ResOpt_DoLaplace)
{
TxPrintf("Laplace solved: %d matched %d\n",
LaplaceMissCount, LaplaceMatchCount);
}
#endif
ResOptionsFlags = oldoptions; ResOptionsFlags = oldoptions;
return; return;
} }
@ -634,11 +583,6 @@ typedef enum {
case RES_RUN: case RES_RUN:
ResOptionsFlags &= ~ResOpt_ExtractAll; ResOptionsFlags &= ~ResOpt_ExtractAll;
break; break;
#ifdef LAPLACE
case RES_LAPLACE:
LaplaceParseString(cmd);
return;
#endif
case RES_AMBIG: case RES_AMBIG:
TxPrintf("Ambiguous option: %s\n", cmd->tx_argv[1]); TxPrintf("Ambiguous option: %s\n", cmd->tx_argv[1]);
TxFlushOut(); TxFlushOut();
@ -651,10 +595,6 @@ typedef enum {
return; return;
} }
#ifdef LAPLACE
LaplaceMatchCount = 0;
LaplaceMissCount = 0;
#endif
/* turn off undo stuff */ /* turn off undo stuff */
UndoDisable(); UndoDisable();
@ -666,9 +606,6 @@ typedef enum {
return; return;
} }
ResOptionsFlags |= ResOpt_Signal; ResOptionsFlags |= ResOpt_Signal;
#ifdef ARIEL
ResOptionsFlags &= ~ResOpt_Power;
#endif
resisdata.rthresh = rthresh; resisdata.rthresh = rthresh;
resisdata.tdiTolerance = tdiTolerance; resisdata.tdiTolerance = tdiTolerance;
@ -695,13 +632,6 @@ typedef enum {
/* turn back on undo stuff */ /* turn back on undo stuff */
UndoEnable(); 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 */ /* Revert to the original flags in the case of FastHenry or */
/* geometry centerline extraction. */ /* geometry centerline extraction. */
@ -765,7 +695,7 @@ resPortFunc(scx, lab, tpath, result)
int pclass, puse; int pclass, puse;
Point portloc; Point portloc;
HashEntry *entry; HashEntry *entry;
ResSimNode *node; ResExtNode *node;
// Ignore the top level cell // Ignore the top level cell
if (scx->scx_use->cu_id == NULL) return 0; if (scx->scx_use->cu_id == NULL) return 0;
@ -904,7 +834,7 @@ ResCheckPorts(cellDef)
Point portloc; Point portloc;
Label *lab; Label *lab;
HashEntry *entry; HashEntry *entry;
ResSimNode *node; ResExtNode *node;
int result = 1; int result = 1;
for (lab = cellDef->cd_labels; lab; lab = lab->lab_next) for (lab = cellDef->cd_labels; lab; lab = lab->lab_next)
@ -930,7 +860,7 @@ ResCheckPorts(cellDef)
entry = HashFind(&ResNodeTable, lab->lab_text); entry = HashFind(&ResNodeTable, lab->lab_text);
result = 0; result = 0;
if ((node = (ResSimNode *) HashGetValue(entry)) != NULL) if ((node = (ResExtNode *) HashGetValue(entry)) != NULL)
{ {
TxPrintf("Port: name = %s exists, forcing drivepoint\n", TxPrintf("Port: name = %s exists, forcing drivepoint\n",
lab->lab_text); lab->lab_text);
@ -966,34 +896,6 @@ ResCheckPorts(cellDef)
return result; 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 int
ResProcessNode( ResProcessNode(
ResSimNode *node, /* Node record for network */ ResExtNode *node, /* Node record for network */
CellDef *celldef, /* Cell def being processed */ CellDef *celldef, /* Cell def being processed */
ResisData *resisdata, /* Extraction parameters kept here */ ResisData *resisdata, /* Extraction parameters kept here */
char *outfile, /* Name of output file */ 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 * device resistance; if it is, Extract the net
* resistance. If the maximum point to point resistance * resistance. If the maximum point to point resistance
* in the extracted net is still creater than the * in the extracted net is still creater than the
@ -1194,17 +1096,17 @@ ResProcessNode(
* *
* Results: none * Results: none
* *
* Side Effects: Writes networks to .res.ext and .res.sim files. * Side Effects: Writes networks to .res.ext files.
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
void void
ResCheckSimNodes(celldef, resisdata) ResCheckExtNodes(celldef, resisdata)
CellDef *celldef; CellDef *celldef;
ResisData *resisdata; ResisData *resisdata;
{ {
ResSimNode *node; ResExtNode *node;
int numext = 0; /* Number of nets extracted */ int numext = 0; /* Number of nets extracted */
int numout = 0; /* Number of nets output */ int numout = 0; /* Number of nets output */
int total = 0; /* Total number of nets processed */ int total = 0; /* Total number of nets processed */
@ -1339,8 +1241,8 @@ ResCheckSimNodes(celldef, resisdata)
* *
* Results:none * Results:none
* *
* Side Effects: Allocates new ResSimNodes. Modifies the terminal connections * Side Effects: Allocates new ResExtNodes. Modifies the terminal connections
* of sim Devices. * of ext Devices.
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1349,7 +1251,7 @@ void
ResFixUpConnections(simDev, layoutDev, simNode, nodename) ResFixUpConnections(simDev, layoutDev, simNode, nodename)
RDev *simDev; RDev *simDev;
resDevice *layoutDev; resDevice *layoutDev;
ResSimNode *simNode; ResExtNode *simNode;
char *nodename; char *nodename;
{ {
@ -1601,7 +1503,7 @@ ResFixDevName(line, type, device, layoutnode)
{ {
HashEntry *entry; HashEntry *entry;
ResSimNode *node; ResExtNode *node;
devPtr *tptr; devPtr *tptr;
if (layoutnode->rn_name != NULL) if (layoutnode->rn_name != NULL)
@ -1757,7 +1659,7 @@ ResSortByGate(DevpointerList)
void void
ResWriteLumpFile(node) ResWriteLumpFile(node)
ResSimNode *node; ResExtNode *node;
{ {
int lumpedres; int lumpedres;
@ -1852,7 +1754,7 @@ ResAlignNodes(nodelist, reslist)
int int
ResWriteExtFile(celldef, node, rctol, nidx, eidx) ResWriteExtFile(celldef, node, rctol, nidx, eidx)
CellDef *celldef; CellDef *celldef;
ResSimNode *node; ResExtNode *node;
float rctol; float rctol;
int *nidx, *eidx; int *nidx, *eidx;
{ {

View File

@ -383,15 +383,6 @@ ResMoveDevices(node1, node2)
device = devptr->te_thist; device = devptr->te_thist;
oldptr = devptr; oldptr = devptr;
devptr = devptr->te_nextt; 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");
}
else
{
if (device->rd_fet_gate == node1) if (device->rd_fet_gate == node1)
device->rd_fet_gate = node2; device->rd_fet_gate = node2;
else if (device->rd_fet_subs == node1) else if (device->rd_fet_subs == node1)
@ -403,7 +394,6 @@ ResMoveDevices(node1, node2)
else 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); " at %d, %d\n", node1->rn_loc.p_x, node1->rn_loc.p_y);
}
oldptr->te_nextt = node2->rn_te; oldptr->te_nextt = node2->rn_te;
node2->rn_te = oldptr; node2->rn_te = oldptr;
} }

View File

@ -140,8 +140,7 @@ resCurrentPrintFunc(node, resistor, filename)
for (workingDev = node->rn_te; workingDev != NULL; for (workingDev = node->rn_te; workingDev != NULL;
workingDev = workingDev->te_nextt) workingDev = workingDev->te_nextt)
{ {
if ((workingDev->te_thist->rd_status & RES_DEV_PLUG) || if (workingDev->te_thist->rd_gate != node)
workingDev->te_thist->rd_gate != node)
i_sum += workingDev->te_thist->rd_i; i_sum += workingDev->te_thist->rd_i;
} }
if (i_sum != 0.0) if (i_sum != 0.0)

View File

@ -57,10 +57,6 @@ typedef struct resistor
int rr_cl; /* resistor centerline for geometry */ int rr_cl; /* resistor centerline for geometry */
int rr_width; /* resistor width for geometry */ int rr_width; /* resistor width for geometry */
TileType rr_tt; /* type that composes this */ TileType rr_tt; /* type that composes this */
/* resistor. */
#ifdef ARIEL
int rr_csArea; /* crosssectional area in lamba**2*/
#endif
} resResistor; } resResistor;
#define rr_connection1 rr_node[0] #define rr_connection1 rr_node[0]
@ -92,10 +88,6 @@ typedef struct device
int rd_devtype; /* tiletype of device. */ int rd_devtype; /* tiletype of device. */
Rect rd_inside; /* 1x1 rectangle inside device */ Rect rd_inside; /* 1x1 rectangle inside device */
Tile *rd_tile; /* pointer to a tile in device */ Tile *rd_tile; /* pointer to a tile in device */
#ifdef ARIEL
float rd_i; /* Current injected from this device */
/* in milliamps */
#endif
} resDevice; } resDevice;
/* /*
@ -254,7 +246,7 @@ typedef struct resdevtile
/* /*
Goodies contains random stuff passed between the node extractor 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. tolerance are passed down, while the derived network is passed back.
*/ */
@ -271,7 +263,28 @@ typedef struct goodstuff
char *rg_name; char *rg_name;
} ResGlobalParams; } 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 */ /* Attaches to rn_client field of resNode */
typedef struct rcdelaystuff typedef struct rcdelaystuff
@ -281,7 +294,7 @@ typedef struct rcdelaystuff
} RCDelayStuff; } RCDelayStuff;
/* ResSim.c type declarations */ /* Type declarations */
typedef struct rdev typedef struct rdev
{ {
@ -291,10 +304,10 @@ typedef struct rdev
resDevice *layout; /* pointer to resDevice that */ resDevice *layout; /* pointer to resDevice that */
/* corresponds to RDev */ /* corresponds to RDev */
int status; int status;
struct ressimnode *gate; /* Terminals of transistor. */ struct resextnode *gate; /* Terminals of transistor. */
struct ressimnode *source; struct resextnode *source;
struct ressimnode *drain; struct resextnode *drain;
struct ressimnode *subs; /* Used with subcircuit type only */ struct resextnode *subs; /* Used with subcircuit type only */
Point location; /* Location of lower left point of */ Point location; /* Location of lower left point of */
/* device. */ /* device. */
float resistance; /* "Resistance" of device. */ float resistance; /* "Resistance" of device. */
@ -305,12 +318,12 @@ typedef struct rdev
char *rs_dattr; char *rs_dattr;
} RDev; } RDev;
typedef struct ressimnode typedef struct resextnode
{ {
struct ressimnode *nextnode; /* next node in OriginalNodes */ struct resextnode *nextnode; /* next node in OriginalNodes */
/* linked list. */ /* linked list. */
int status; 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. */ /* points to the merged node. */
float capacitance; /* capacitance between node and */ float capacitance; /* capacitance between node and */
/* GND for power connections */ /* GND for power connections */
@ -340,7 +353,7 @@ typedef struct ressimnode
tElement *rs_sublist[2]; /* pointers to Gnd and Vdd sub */ tElement *rs_sublist[2]; /* pointers to Gnd and Vdd sub */
/* strate connections, /* strate connections,
if they exist */ if they exist */
} ResSimNode; } ResExtNode;
#define RES_SUB_GND 0 #define RES_SUB_GND 0
#define RES_SUB_VDD 1 #define RES_SUB_VDD 1
@ -355,40 +368,6 @@ typedef struct devptr
/* is connected to node. */ /* is connected to node. */
} devPtr; } 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 */ typedef struct resfixpoint /* Keeps track of where voltage sources are */
{ {
struct resfixpoint *fp_next; struct resfixpoint *fp_next;
@ -400,30 +379,6 @@ typedef struct resfixpoint /* Keeps track of where voltage sources are */
char fp_name[1]; char fp_name[1];
} ResFixPoint; } 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 typedef struct capval
{ {
float cap[1][2]; /* multipliers telling what portion of capacitance is float cap[1][2]; /* multipliers telling what portion of capacitance is
@ -458,7 +413,6 @@ typedef struct capval
/* device flags */ /* device flags */
#define RES_DEV_SAVE 0x00000001 #define RES_DEV_SAVE 0x00000001
#define RES_DEV_PLUG 0x00000002
/* flags for tiles */ /* flags for tiles */
/* A tile which is part of a substrate region. */ /* A tile which is part of a substrate region. */
@ -473,11 +427,6 @@ typedef struct capval
#define RES_TILE_MARK 0x10 #define RES_TILE_MARK 0x10
/*another temporary marking flag */ /*another temporary marking flag */
#define RES_TILE_PUSHED 0x20 #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 */ /* tree walking flags */
#define RES_LOOP_OK 1 #define RES_LOOP_OK 1
#define RES_NO_LOOP 1 #define RES_NO_LOOP 1
@ -486,7 +435,7 @@ typedef struct capval
#define RES_NO_FLAGS 0 #define RES_NO_FLAGS 0
/* ResSim Constants */ /* Constants */
#define FORWARD 0x0000010 #define FORWARD 0x0000010
#define SKIP 0x0000020 #define SKIP 0x0000020
#define FORCE 0x0000040 #define FORCE 0x0000040
@ -561,16 +510,9 @@ typedef struct capval
#define ResOpt_Blackbox 0x00010000 #define ResOpt_Blackbox 0x00010000
#define ResOpt_Dump 0x00020000 #define ResOpt_Dump 0x00020000
#define ResOpt_DoSubstrate 0x00040000 #define ResOpt_DoSubstrate 0x00040000
#define ResOpt_GndPlugs 0x00200000
#define ResOpt_VddPlugs 0x00400000
#define ResOpt_CMOS 0x00800000 #define ResOpt_CMOS 0x00800000
#define ResOpt_Bipolar 0x01000000 #define ResOpt_Bipolar 0x01000000
#define ResOpt_Box 0x02000000 #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_VDisplay 0x10000000
#define ResOpt_IDisplay 0x20000000 #define ResOpt_IDisplay 0x20000000
@ -579,18 +521,9 @@ typedef struct capval
/* Assorted Variables */ /* Assorted Variables */
extern RDev *ResRDevList; extern RDev *ResRDevList;
extern REcell *ResBigEventList;
extern int ResOptionsFlags; extern int ResOptionsFlags;
extern char *ResCurrentNode; extern char *ResCurrentNode;
extern ResSimNode *ResOriginalNodes; extern ResExtNode *ResOriginalNodes;
#ifdef ARIEL
extern int ResMinEventTime;
extern int ResMaxEventTime;
typedef float ResCapElement[2];
extern ResCapElement *ResCapTableMax;
extern ResCapElement *ResCapTableMin;
extern HashTable ResPlugTable;
#endif
extern CellUse *ResUse; extern CellUse *ResUse;
extern CellDef *ResDef; extern CellDef *ResDef;
@ -604,10 +537,10 @@ extern resNode *ResNodeQueue;
extern resNode *ResOriginNode; extern resNode *ResOriginNode;
extern resNode *resCurrentNode; extern resNode *resCurrentNode;
extern HashTable ResNodeTable; extern HashTable ResNodeTable;
extern HashTable ResSimDevTable; extern HashTable ResExtDevTable;
extern ResFixPoint *ResFixList; extern ResFixPoint *ResFixList;
extern int ResTileCount; extern int ResTileCount;
extern ResSimNode **ResNodeArray; extern ResExtNode **ResNodeArray;
extern CellDef *mainDef; extern CellDef *mainDef;
extern TileTypeBitMask ResSDTypesBitMask; extern TileTypeBitMask ResSDTypesBitMask;
extern TileTypeBitMask ResSubTypesBitMask; extern TileTypeBitMask ResSubTypesBitMask;
@ -616,24 +549,26 @@ extern TileTypeBitMask ResNoMergeMask[NT];
extern ResGlobalParams gparams; extern ResGlobalParams gparams;
extern int ResPortIndex; extern int ResPortIndex;
extern int ResSimDevice(); /* Routines used by ResReadExt() */
extern int ResSimCombineParallel(); extern int ResReadDevice();
extern int ResSimCapacitor(); extern int ResReadCapacitor();
extern int ResSimResistor(); extern int ResReadResistor();
extern int ResSimAttribute(); extern int ResReadAttribute();
extern int ResSimMerge(); extern int ResReadMerge();
extern int ResSimSubckt(); extern int ResReadSubckt();
extern int ResProcessNode();
extern int ResExtCombineParallel();
extern int dbSrConnectStartFunc(); extern int dbSrConnectStartFunc();
extern int ResEach(),ResAddPlumbing(),ResRemovePlumbing(); extern int ResEach(),ResAddPlumbing(),ResRemovePlumbing();
extern float ResCalculateChildCapacitance(); extern float ResCalculateChildCapacitance();
extern ResDevTile *DBTreeCopyConnectDCS(); extern ResDevTile *DBTreeCopyConnectDCS();
extern Tile *ResFindTile(); extern Tile *ResFindTile();
extern resDevice *ResImageAddPlug();
extern resDevice *ResGetDevice(); extern resDevice *ResGetDevice();
extern tileJunk *resAddField(); extern tileJunk *resAddField();
extern int ResCheckPorts(); extern int ResCheckPorts();
extern int ResCheckBlackbox(); extern int ResCheckBlackbox();
extern void ResCheckSimNodes(); extern void ResCheckExtNodes();
extern void ResSortByGate(); extern void ResSortByGate();
extern void ResFixDevName(); extern void ResFixDevName();
extern void ResWriteLumpFile(); extern void ResWriteLumpFile();
@ -663,9 +598,10 @@ extern void ResPrintResistorList();
extern void ResPrintStats(); extern void ResPrintStats();
extern void ResProcessJunction(); extern void ResProcessJunction();
extern int ResReadNode(); extern int ResReadNode();
extern int ResReadSim(); extern int ResReadExt();
extern void ResRemoveFromQueue(); extern void ResRemoveFromQueue();
extern int ResSimNewNode(); extern int ResExtNewNode();
extern void ResExtProcessDrivePoints();
extern int ResWriteExtFile(); extern int ResWriteExtFile();
extern void ResPrintExtNode(); extern void ResPrintExtNode();
extern void ResPrintExtRes(); extern void ResPrintExtRes();