Overhauled the extresist code (again), this time to (1) correct for

a long-standing error (introduced with the "extresist geometry"
option) that can cause nets not to be extracted (due to the first
record not having extraction data, which was itself a long-standing
error in the code but which was not fixed correctly);  (2) handle
"device mosfet" type transistors (previously only handled the old
"fet" type extraction devices);  and (3) correct for the res.ext
file having a different scalefactor relative to the .ext file.  The
latter item was solved by forcing all input to scale like
ExtCurStyle->exts_unitsPerLambda, locally correcting all input as
needed.  Note that extresist still needs to handle other extraction
devices (e.g., resistors and capacitors) but those will require
additional handling in the routines which analyze the current path
to determine how to break up wires into paths.
This commit is contained in:
Tim Edwards 2019-12-08 17:37:48 -05:00
parent 31612b593f
commit fd737dbf80
11 changed files with 4226 additions and 103 deletions

View File

@ -122,55 +122,161 @@ cifPaintFunc(tile, table)
* Always returns 0 to keep the search alive. * Always returns 0 to keep the search alive.
* *
* Side effects: * Side effects:
* Scales the tile by cifScale, then expands its area by the * May paint into cifNewPlane
* remainder of the distance to meet the minimum dimension, as *
* defined by the grid distance (growDistance) in the current * Algorithm (based on maximum horizontal stripes rule):
* CIFOp, then paints this area into cifNewPlane using the table * Scan top and bottom boundaries from left to right. For any
* passed as parameter. * distance (including distance zero) sharing the same type (0 or 1)
* on both the tile top and bottom, find the diagonal length. If
* less than co_distance, then expand this area and paint.
* NOTE: This algorithm does not cover a number of geometry cases
* and needs to be reworked. It should be restricted to cases of
* layers that have "rect_only" DRC rules. Since the rule is usually
* needed for implants on FET gates to maintain the implant width for
* small gates, the "rect_only" requirement is not particularly
* constraining.
*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
int int
cifGrowMinFunc(tile, plane) cifGrowMinFunc(tile, table)
Tile *tile; Tile *tile;
Plane *plane; PaintResultType *table; /* Table to be used for painting. */
{ {
Rect area, *maxr; Rect area, parea;
int locDist, width, height; int locDist, width, height, h;
TileTypeBitMask mask; TileType type, tptype;
TileType type; Tile *tp, *tp2;
TiToRect(tile, &area); TiToRect(tile, &area);
type = TiGetType(tile);
TTMaskZero(&mask); area.r_xbot *= cifScale;
TTMaskSetType(&mask, type); area.r_xtop *= cifScale;
area.r_ybot *= cifScale;
area.r_ytop *= cifScale;
maxr = FindMaxRectangle2(&area, tile, plane, &mask); parea = area;
if (maxr == NULL) return 0; /* Should not happen */
maxr->r_xbot *= cifScale; /* Check whole tile for minimum width */
maxr->r_xtop *= cifScale; width = area.r_xtop - area.r_xbot;
maxr->r_ybot *= cifScale; if (width < growDistance)
maxr->r_ytop *= cifScale;
width = maxr->r_xtop - maxr->r_xbot;
height = maxr->r_ytop - maxr->r_ybot;
locDist = (growDistance - width) / 2;
if (locDist > 0)
{ {
maxr->r_xbot -= locDist; locDist = (growDistance - width) / 2;
maxr->r_xtop += locDist; area.r_xbot -= locDist;
} area.r_xtop += locDist;
locDist = (growDistance - height) / 2; /* If there is another tile on top or bottom, and the height is */
if (locDist > 0) /* less than minimum, then extend height in the direction of */
/* the bordering tile. Otherwise, if the height is less than */
/* minimum, then grow halfway in both directions. */
height = area.r_ytop - area.r_ybot;
if (height < growDistance)
{
bool freeTop, freeBot;
freeTop = freeBot = TRUE;
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp))
if (TiGetTopType(tp) == TiGetBottomType(tile))
{
freeBot = FALSE;
break;
}
for (tp2 = RT(tile); RIGHT(tp2) > LEFT(tile); tp2 = BL(tp2))
if (TiGetBottomType(tp2) == TiGetTopType(tile))
{
freeTop = FALSE;
break;
}
/* In the following, value h ensures that the euclidean */
/* distance between inside corners of the layer */
/* satisfies growDistance. */
if (freeTop == TRUE && freeBot == FALSE)
{
locDist = (growDistance - height) / 2;
h = (int)sqrt((double)(growDistance * growDistance) -
0.25 * (double)((growDistance + width) *
(growDistance + width)) + 0.5);
area.r_ybot -= h;
}
else if (freeTop == FALSE && freeBot == TRUE)
{
h = (int)sqrt((double)(growDistance * growDistance) -
0.25 * (double)((growDistance + width) *
(growDistance + width)) + 0.5);
area.r_ytop += h;
}
else {
locDist = (growDistance - height) / 2;
area.r_ybot -= locDist;
area.r_ytop += locDist;
}
}
}
DBPaintPlane(cifPlane, &area, table, (PaintUndoInfo *) NULL);
area = parea;
/* Scan bottom from left to right */
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp))
{ {
maxr->r_ybot -= locDist; tptype = TiGetTopType(tp);
maxr->r_ytop += locDist; /* Scan top from right to left across range of tp */
} for (tp2 = RT(tile); RIGHT(tp2) > LEFT(tile); tp2 = BL(tp2))
if (TiGetBottomType(tp2) == tptype)
{
/* Set range to length of overlap */
if ((LEFT(tp2) <= RIGHT(tp)) && (LEFT(tp2) >= LEFT(tp)))
{
area.r_xbot = LEFT(tp2) < LEFT(tile) ? LEFT(tile) : LEFT(tp2);
area.r_xtop = RIGHT(tp) > RIGHT(tile) ? RIGHT(tile) : RIGHT(tp);
}
else if ((RIGHT(tp2) >= LEFT(tp)) && (RIGHT(tp2) <= RIGHT(tp)))
{
area.r_xbot = LEFT(tp) < LEFT(tile) ? LEFT(tile) : LEFT(tp);
area.r_xtop = RIGHT(tp2) > RIGHT(tile) ? RIGHT(tile) : RIGHT(tp2);
}
else continue;
DBPaintPlane(cifPlane, maxr, CIFPaintTable, (PaintUndoInfo *) NULL); area.r_xbot *= cifScale;
area.r_xtop *= cifScale;
/* Does area violate minimum width requirement? */
width = area.r_xtop - area.r_xbot;
height = area.r_ytop - area.r_ybot;
/* Manhattan requirement (to-do: Euclidean) */
if (width < growDistance)
{
locDist = (growDistance - width) / 2;
parea.r_xbot = area.r_xbot - locDist;
parea.r_xtop = area.r_xtop + locDist;
}
else
{
parea.r_xbot = area.r_xbot;
parea.r_xtop = area.r_xtop;
}
if (height < growDistance)
{
locDist = (growDistance - height) / 2;
parea.r_ybot = area.r_ybot - locDist;
parea.r_ytop = area.r_ytop + locDist;
}
else
{
parea.r_ybot = area.r_ybot;
parea.r_ytop = area.r_ytop;
}
if ((width < growDistance) || (height < growDistance))
DBPaintPlane(cifPlane, &parea, table, (PaintUndoInfo *) NULL);
}
}
CIFTileOps += 1; CIFTileOps += 1;
return 0; return 0;
@ -3199,7 +3305,7 @@ CIFGenLayer(op, area, cellDef, temps, clientdata)
cifPlane = nextPlane; cifPlane = nextPlane;
cifScale = 1; cifScale = 1;
(void) DBSrPaintArea((Tile *) NULL, curPlane, &TiPlaneRect, (void) DBSrPaintArea((Tile *) NULL, curPlane, &TiPlaneRect,
&CIFSolidBits, cifGrowMinFunc, (ClientData)curPlane); &CIFSolidBits, cifGrowMinFunc, (ClientData)CIFPaintTable);
temp = curPlane; temp = curPlane;
curPlane = nextPlane; curPlane = nextPlane;
nextPlane = temp; nextPlane = temp;

3980
cif/CIFgen.c.test Normal file

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,7 @@ EFread.o: EFread.c ../tcltk/tclmagic.h ../utils/magic.h ../utils/malloc.h \
../utils/geometry.h ../utils/hash.h ../utils/utils.h ../tiles/tile.h \ ../utils/geometry.h ../utils/hash.h ../utils/utils.h ../tiles/tile.h \
../commands/commands.h ../windows/windows.h ../database/database.h \ ../commands/commands.h ../windows/windows.h ../database/database.h \
../extflat/extflat.h ../extflat/EFint.h ../extract/extract.h \ ../extflat/extflat.h ../extflat/EFint.h ../extract/extract.h \
../utils/paths.h ../extract/extractInt.h ../extract/extDebugInt.h ../utils/paths.h
EFsym.o: EFsym.c ../utils/magic.h ../utils/geometry.h ../utils/geofast.h \ EFsym.o: EFsym.c ../utils/magic.h ../utils/geometry.h ../utils/geofast.h \
../utils/hash.h ../utils/malloc.h ../utils/utils.h ../extflat/extflat.h \ ../utils/hash.h ../utils/malloc.h ../utils/utils.h ../extflat/extflat.h \
../extflat/EFint.h ../extflat/EFint.h

View File

@ -63,6 +63,8 @@ void efNodeMerge();
bool efConnBuildName(); bool efConnBuildName();
bool efConnInitSubs(); bool efConnInitSubs();
extern float locScale;
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
@ -177,10 +179,10 @@ efBuildNode(def, isSubsnode, nodeName, nodeCap, x, y, layerName, av, ac)
newnode->efnode_flags = (isSubsnode == TRUE) ? EF_SUBS_NODE : 0; newnode->efnode_flags = (isSubsnode == TRUE) ? EF_SUBS_NODE : 0;
newnode->efnode_cap = nodeCap; newnode->efnode_cap = nodeCap;
newnode->efnode_attrs = (EFAttr *) NULL; newnode->efnode_attrs = (EFAttr *) NULL;
newnode->efnode_loc.r_xbot = x; newnode->efnode_loc.r_xbot = (int)(0.5 + (float)x * locScale);
newnode->efnode_loc.r_ybot = y; newnode->efnode_loc.r_ybot = (int)(0.5 + (float)y * locScale);
newnode->efnode_loc.r_xtop = x + 1; newnode->efnode_loc.r_xtop = newnode->efnode_loc.r_xbot + 1;
newnode->efnode_loc.r_ytop = y + 1; newnode->efnode_loc.r_ytop = newnode->efnode_loc.r_ybot + 1;
newnode->efnode_client = (ClientData) NULL; newnode->efnode_client = (ClientData) NULL;
if (layerName) newnode->efnode_type = if (layerName) newnode->efnode_type =
efBuildAddStr(EFLayerNames, &EFLayerNumNames, MAXTYPES, layerName); efBuildAddStr(EFLayerNames, &EFLayerNumNames, MAXTYPES, layerName);
@ -686,7 +688,8 @@ efBuildDevice(def, class, type, r, argc, argv)
{ {
pn = *(argv[argstart] + 1) - '0'; pn = *(argv[argstart] + 1) - '0';
if (pn == 0) if (pn == 0)
devtmp.dev_area = atoi(pptr); devtmp.dev_area = (int)(0.5 + (float)atoi(pptr)
* locScale * locScale);
/* Otherwise, punt */ /* Otherwise, punt */
} }
break; break;
@ -697,15 +700,15 @@ efBuildDevice(def, class, type, r, argc, argv)
{ {
pn = *(argv[argstart] + 1) - '0'; pn = *(argv[argstart] + 1) - '0';
if (pn == 0) if (pn == 0)
devtmp.dev_perim = atoi(pptr); devtmp.dev_perim = (int)(0.5 + (float)atoi(pptr) * locScale);
/* Otherwise, use verbatim */ /* Otherwise, use verbatim */
} }
break; break;
case 'l': case 'l':
devtmp.dev_length = atoi(pptr); devtmp.dev_length = (int)(0.5 + (float)atoi(pptr) * locScale);
break; break;
case 'w': case 'w':
devtmp.dev_width = atoi(pptr); devtmp.dev_width = (int)(0.5 + (float)atoi(pptr) * locScale);
break; break;
case 'c': case 'c':
devtmp.dev_cap = (float)atof(pptr); devtmp.dev_cap = (float)atof(pptr);
@ -1248,8 +1251,9 @@ efBuildConnect(def, nodeName1, nodeName2, deltaC, av, ac)
conn->conn_next = def->def_conns; conn->conn_next = def->def_conns;
for (n = 0; n < efNumResistClasses && ac > 1; n++, ac -= 2) for (n = 0; n < efNumResistClasses && ac > 1; n++, ac -= 2)
{ {
conn->conn_pa[n].pa_area = atoi(*av++); conn->conn_pa[n].pa_area = (int)(0.5 + (float)atoi(*av++)
conn->conn_pa[n].pa_perim = atoi(*av++); * locScale * locScale);
conn->conn_pa[n].pa_perim = (int)(0.5 + (float)atoi(*av++) * locScale);
} }
for ( ; n < efNumResistClasses; n++) for ( ; n < efNumResistClasses; n++)
conn->conn_pa[n].pa_area = conn->conn_pa[n].pa_perim = 0; conn->conn_pa[n].pa_area = conn->conn_pa[n].pa_perim = 0;

View File

@ -38,6 +38,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "extflat/extflat.h" #include "extflat/extflat.h"
#include "extflat/EFint.h" #include "extflat/EFint.h"
#include "extract/extract.h" #include "extract/extract.h"
#include "extract/extractInt.h"
#include "utils/paths.h" #include "utils/paths.h"
#ifndef MAGIC_WRAPPER #ifndef MAGIC_WRAPPER
@ -96,6 +97,7 @@ keyTable[] =
/* 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 */
float locScale; /* Multiply values in the file by this on read-in */
/* Data local to this file */ /* Data local to this file */
static bool efReadDef(); static bool efReadDef();
@ -139,6 +141,7 @@ EFReadFile(name, dosubckt, resist, noscale)
if (def == NULL) if (def == NULL)
def = efDefNew(name); def = efDefNew(name);
locScale = 1.0;
rc = efReadDef(def, dosubckt, resist, noscale, TRUE); rc = efReadDef(def, dosubckt, resist, noscale, TRUE);
if (EFArgTech) EFTech = StrDup((char **) NULL, EFArgTech); if (EFArgTech) EFTech = StrDup((char **) NULL, EFArgTech);
if (EFScale == 0.0) EFScale = 1.0; if (EFScale == 0.0) EFScale = 1.0;
@ -265,6 +268,11 @@ readfile:
cscale = 1; cscale = 1;
} }
lscale = (float)atof(argv[3]); lscale = (float)atof(argv[3]);
if (lscale != ExtCurStyle->exts_unitsPerLambda)
{
locScale = lscale / ExtCurStyle->exts_unitsPerLambda;
lscale = ExtCurStyle->exts_unitsPerLambda;
}
if (lscale == 0.0) if (lscale == 0.0)
{ {
efReadError("Bad linear scaling = 0; reset to 1.\n"); efReadError("Bad linear scaling = 0; reset to 1.\n");
@ -283,10 +291,10 @@ readfile:
/* attr node xlo ylo xhi yhi type text */ /* attr node xlo ylo xhi yhi type text */
case ATTR: case ATTR:
r.r_xbot = atoi(argv[2]); r.r_xbot = (int)(0.5 + (float)atoi(argv[2]) * locScale);
r.r_ybot = atoi(argv[3]); r.r_ybot = (int)(0.5 + (float)atoi(argv[3]) * locScale);
r.r_xtop = atoi(argv[4]); r.r_xtop = (int)(0.5 + (float)atoi(argv[4]) * locScale);
r.r_ytop = atoi(argv[5]), r.r_ytop = (int)(0.5 + (float)atoi(argv[5]) * locScale),
efBuildAttr(def, argv[1], &r, argv[6], argv[7]); efBuildAttr(def, argv[1], &r, argv[6], argv[7]);
break; break;
@ -351,10 +359,10 @@ readfile:
break; /* we will deal with in efBuildDevice(). */ break; /* we will deal with in efBuildDevice(). */
} }
r.r_xbot = atoi(argv[3]); r.r_xbot = (int)(0.5 + (float)atoi(argv[3]) * locScale);
r.r_ybot = atoi(argv[4]); r.r_ybot = (int)(0.5 + (float)atoi(argv[4]) * locScale);
r.r_xtop = atoi(argv[5]); r.r_xtop = (int)(0.5 + (float)atoi(argv[5]) * locScale);
r.r_ytop = atoi(argv[6]); r.r_ytop = (int)(0.5 + (float)atoi(argv[6]) * locScale);
if (efBuildDevice(def, (char)n, argv[2], &r, argc - 7, &argv[7]) != 0) if (efBuildDevice(def, (char)n, argv[2], &r, argc - 7, &argv[7]) != 0)
{ {
@ -366,10 +374,10 @@ readfile:
/* for backwards compatibility */ /* for backwards compatibility */
/* fet type xlo ylo xhi yhi area perim substrate GATE T1 T2 ... */ /* fet type xlo ylo xhi yhi area perim substrate GATE T1 T2 ... */
case FET: case FET:
r.r_xbot = atoi(argv[2]); r.r_xbot = (int)(0.5 + (float)atoi(argv[2]) * locScale);
r.r_ybot = atoi(argv[3]); r.r_ybot = (int)(0.5 + (float)atoi(argv[3]) * locScale);
r.r_xtop = atoi(argv[4]); r.r_xtop = (int)(0.5 + (float)atoi(argv[4]) * locScale);
r.r_ytop = atoi(argv[5]); r.r_ytop = (int)(0.5 + (float)atoi(argv[5]) * locScale);
if (efBuildDevice(def, DEV_FET, argv[1], &r, argc - 6, &argv[6]) != 0) if (efBuildDevice(def, DEV_FET, argv[1], &r, argc - 6, &argv[6]) != 0)
{ {
efReadError("Incomplete terminal description for fet\n"); efReadError("Incomplete terminal description for fet\n");
@ -563,8 +571,8 @@ resistChanged:
/* distance driver receiver min max */ /* distance driver receiver min max */
case DIST: case DIST:
efBuildDist(def, argv[1], argv[2], efBuildDist(def, argv[1], argv[2],
(int)(lscale*atoi(argv[3])), (int)(lscale*atoi(argv[3])*locScale),
(int)(lscale*atoi(argv[4]))); (int)(lscale*atoi(argv[4])*locScale));
break; break;
/* killnode nodename */ /* killnode nodename */

View File

@ -130,7 +130,6 @@ ResProcessJunction(tile, tp, xj, yj, NodeList)
return; return;
} }
#endif #endif
if (j2->tj_status & RES_TILE_DONE) return; if (j2->tj_status & RES_TILE_DONE) return;
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
resptr->rn_te = (tElement *) NULL; resptr->rn_te = (tElement *) NULL;

View File

@ -135,20 +135,40 @@ ResPrintExtDev(outextfile, devices)
if (varsub != NULL) subsName = varsub; if (varsub != NULL) subsName = varsub;
} }
#endif #endif
/* Output according to device type and class. */
/* Code largely matches what's in ExtBasic.c extOutputDevices() */
/* Output according to device type */ if (devptr->exts_deviceClass != DEV_FET)
fprintf(outextfile,"device ");
/* fet type xl yl xh yh area perim sub gate t1 t2 */ fprintf(outextfile,"%s %s %d %d %d %d ",
fprintf(outextfile,"fet %s %d %d %d %d %d %d " extDevTable[devptr->exts_deviceClass],
"%s \"%s\" %d %s \"%s\" %d %s \"%s\" %d %s\n",
devptr->exts_deviceName, devptr->exts_deviceName,
devices->layout->rd_inside.r_ll.p_x, devices->layout->rd_inside.r_ll.p_x,
devices->layout->rd_inside.r_ll.p_y, devices->layout->rd_inside.r_ll.p_y,
devices->layout->rd_inside.r_ll.p_x + 1, devices->layout->rd_inside.r_ll.p_x + 1,
devices->layout->rd_inside.r_ll.p_y + 1, devices->layout->rd_inside.r_ll.p_y + 1);
devices->layout->rd_area,
devices->layout->rd_perim, switch (devptr->exts_deviceClass)
subsName, {
case DEV_FET:
fprintf(outextfile," %d %d",
devices->layout->rd_area,
devices->layout->rd_perim);
break;
case DEV_MOSFET:
case DEV_ASYMMETRIC:
case DEV_BJT:
fprintf(outextfile," %d %d",
devices->layout->rd_length,
devices->layout->rd_width);
break;
}
fprintf(outextfile, " \"%s\"", subsName);
fprintf(outextfile, " \"%s\" %d %s \"%s\" %d %s \"%s\" %d %s\n",
devices->gate->name, devices->gate->name,
devices->layout->rd_length * 2, devices->layout->rd_length * 2,
devices->rs_gattr, devices->rs_gattr,
@ -190,7 +210,7 @@ ResPrintExtNode(outextfile, nodelist, nodename)
ResSimNode *node,*ResInitializeNode(); ResSimNode *node,*ResInitializeNode();
bool DoKillNode = TRUE; bool DoKillNode = TRUE;
resNode *snode = nodelist; resNode *snode = nodelist;
/* If any of the subnode names match the original node name, then */ /* If any of the subnode names match the original node name, then */
/* we don't want to rip out that node with a "killnode" statement. */ /* we don't want to rip out that node with a "killnode" statement. */

View File

@ -229,12 +229,12 @@ ResReadNode(nodefile)
char *cp; char *cp;
float lambda; float lambda;
/* NOTE: Units from the .sim file or the .nodes file are in centimicrons /* NOTE: Units from the .nodes file are in centimicrons.
* when multiplied by resscale (units from the .sim file 1st line). * Divide by the extract scale (exts_unitsPerLambda) to get back
* multiply resscale by the extract scale (exts_unitsPerLambda) used to * to database units. This assumes that exts_unitsPerLambda doesn't
* generate .ext dimensions originally, to get back to database units. * change between output and readback.
*/ */
lambda = resscale * (float)ExtCurStyle->exts_unitsPerLambda; lambda = (float)ExtCurStyle->exts_unitsPerLambda;
fp = PaOpen(nodefile,"r",".nodes",".", (char *) NULL, (char **) NULL); fp = PaOpen(nodefile,"r",".nodes",".", (char *) NULL, (char **) NULL);
if (fp == NULL) if (fp == NULL)
@ -358,11 +358,10 @@ ResSimDevice(line,rpersquare,ttype)
} }
device->resistance = MagAtof(line[RDEV_LENGTH]) * rpersquare/MagAtof(line[RDEV_WIDTH]); device->resistance = MagAtof(line[RDEV_LENGTH]) * rpersquare/MagAtof(line[RDEV_WIDTH]);
} }
device->tnumber = ++Maxtnumber;
device->status = FALSE; device->status = FALSE;
device->nextDev = ResRDevList; device->nextDev = ResRDevList;
lambda = resscale * (float)ExtCurStyle->exts_unitsPerLambda; lambda = (float)ExtCurStyle->exts_unitsPerLambda / resscale;
device->location.p_x = (int)((float)atof(line[RDEV_DEVX]) / lambda); device->location.p_x = (int)((float)atof(line[RDEV_DEVX]) / lambda);
device->location.p_y = (int)((float)atof(line[RDEV_DEVY]) / lambda); device->location.p_y = (int)((float)atof(line[RDEV_DEVY]) / lambda);

View File

@ -35,21 +35,19 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#define INITFLATSIZE 1024 #define INITFLATSIZE 1024
#define MAXNAME 1000 #define MAXNAME 1000
/* Time constants are produced by multiplying attofarads by milliohms, */
/* time constants are produced by multiplying attofarads by milliohms, */
/* giving zeptoseconds (yes, really. Look it up). This constant */ /* giving zeptoseconds (yes, really. Look it up). This constant */
/* converts zeptoseconts to nanoseconds. */ /* converts zeptoseconds to nanoseconds. */
#define Z_TO_N 1e12 #define Z_TO_N 1e12
/* ResSimNode is a node read in from a sim file */ /* ResSimNode is a node read in from a sim file */
HashTable ResNodeTable; /* Hash table of sim file nodes */ HashTable ResNodeTable; /* Hash table of sim file nodes */
RDev *ResRDevList; /* Linked list of Sim devices */ RDev *ResRDevList; /* Linked list of Sim devices */
ResGlobalParams gparams; /* Junk passed between */ ResGlobalParams gparams; /* Junk passed between */
/* ResCheckSimNodes and */ /* ResCheckSimNodes and */
/* ResExtractNet. */ /* ResExtractNet. */
int Maxtnumber; /*maximum device number */
extern ResSimNode *ResOriginalNodes; /*Linked List of Nodes */ extern ResSimNode *ResOriginalNodes; /*Linked List of Nodes */
int resNodeNum; int resNodeNum;
@ -104,7 +102,6 @@ ExtResisForDef(celldef, resisdata)
ResRDevList = NULL; ResRDevList = NULL;
ResOriginalNodes = NULL; ResOriginalNodes = NULL;
Maxtnumber = 0;
HashInit(&ResNodeTable, INITFLATSIZE, HT_STRINGKEYS); HashInit(&ResNodeTable, INITFLATSIZE, HT_STRINGKEYS);
/* read in .sim file */ /* read in .sim file */
result = (ResReadSim(celldef->cd_name, result = (ResReadSim(celldef->cd_name,
@ -870,6 +867,19 @@ ResCheckSimNodes(celldef, resisdata)
return; return;
} }
/*
* Write a scale line at the top of the .res.ext file, as the
* scale may be different from the original .ext file.
*/
if (ResExtFile != NULL)
{
fprintf(ResExtFile, "scale %d %d %g\n",
ExtCurStyle->exts_resistScale,
ExtCurStyle->exts_capScale,
ExtCurStyle->exts_unitsPerLambda);
}
/* /*
* Write reference plane (substrate) definition and end statement * Write reference plane (substrate) definition and end statement
* to the FastHenry geometry file. * to the FastHenry geometry file.

View File

@ -954,26 +954,25 @@ ResDoSimplify(tolerance,rctol,goodies)
{ {
RCDelayStuff *rc = (RCDelayStuff *) ResNodeList->rn_client; RCDelayStuff *rc = (RCDelayStuff *) ResNodeList->rn_client;
if (rc != (RCDelayStuff *)NULL) goodies->rg_nodecap = totalcap;
{ ResCalculateTDi(ResOriginNode,(resResistor *)NULL,
goodies->rg_nodecap = totalcap;
ResCalculateTDi(ResOriginNode,(resResistor *)NULL,
goodies->rg_bigdevres); goodies->rg_bigdevres);
goodies->rg_Tdi = rc->rc_Tdi; if (rc != (RCDelayStuff *)NULL)
slownode = ResNodeList; goodies->rg_Tdi = rc->rc_Tdi;
for (node = ResNodeList; node != NULL; node = node->rn_more)
{
rc = (RCDelayStuff *)node->rn_client;
if (rc && (goodies->rg_Tdi < rc->rc_Tdi))
{
slownode = node;
goodies->rg_Tdi = rc->rc_Tdi;
}
}
slownode->rn_status |= RN_MAXTDI;
}
else else
goodies->rg_Tdi = 0; goodies->rg_Tdi = 0;
slownode = ResNodeList;
for (node = ResNodeList; node != NULL; node = node->rn_more)
{
rc = (RCDelayStuff *)node->rn_client;
if (rc && (goodies->rg_Tdi < rc->rc_Tdi))
{
slownode = node;
goodies->rg_Tdi = rc->rc_Tdi;
}
}
slownode->rn_status |= RN_MAXTDI;
} }
else else
{ {

View File

@ -296,7 +296,6 @@ typedef struct rdev
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. */
int tnumber; /* Device number */
int rs_ttype; /* device type */ int rs_ttype; /* device type */
char *rs_gattr; /* Gate attributes, if any */ char *rs_gattr; /* Gate attributes, if any */
char *rs_sattr; char *rs_sattr;
@ -572,7 +571,6 @@ extern RDev *ResRDevList;
extern REcell *ResBigEventList; extern REcell *ResBigEventList;
extern int ResOptionsFlags; extern int ResOptionsFlags;
extern char *ResCurrentNode; extern char *ResCurrentNode;
extern int Maxtnumber;
extern ResSimNode *ResOriginalNodes; extern ResSimNode *ResOriginalNodes;
#ifdef ARIEL #ifdef ARIEL
extern int ResMinEventTime; extern int ResMinEventTime;