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:
parent
31612b593f
commit
fd737dbf80
176
cif/CIFgen.c
176
cif/CIFgen.c
|
|
@ -122,55 +122,161 @@ cifPaintFunc(tile, table)
|
|||
* Always returns 0 to keep the search alive.
|
||||
*
|
||||
* Side effects:
|
||||
* Scales the tile by cifScale, then expands its area by the
|
||||
* remainder of the distance to meet the minimum dimension, as
|
||||
* defined by the grid distance (growDistance) in the current
|
||||
* CIFOp, then paints this area into cifNewPlane using the table
|
||||
* passed as parameter.
|
||||
* May paint into cifNewPlane
|
||||
*
|
||||
* Algorithm (based on maximum horizontal stripes rule):
|
||||
* Scan top and bottom boundaries from left to right. For any
|
||||
* 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
|
||||
cifGrowMinFunc(tile, plane)
|
||||
cifGrowMinFunc(tile, table)
|
||||
Tile *tile;
|
||||
Plane *plane;
|
||||
PaintResultType *table; /* Table to be used for painting. */
|
||||
{
|
||||
Rect area, *maxr;
|
||||
int locDist, width, height;
|
||||
TileTypeBitMask mask;
|
||||
TileType type;
|
||||
Rect area, parea;
|
||||
int locDist, width, height, h;
|
||||
TileType type, tptype;
|
||||
Tile *tp, *tp2;
|
||||
|
||||
TiToRect(tile, &area);
|
||||
type = TiGetType(tile);
|
||||
|
||||
TTMaskZero(&mask);
|
||||
TTMaskSetType(&mask, type);
|
||||
area.r_xbot *= cifScale;
|
||||
area.r_xtop *= cifScale;
|
||||
area.r_ybot *= cifScale;
|
||||
area.r_ytop *= cifScale;
|
||||
|
||||
maxr = FindMaxRectangle2(&area, tile, plane, &mask);
|
||||
if (maxr == NULL) return 0; /* Should not happen */
|
||||
parea = area;
|
||||
|
||||
maxr->r_xbot *= cifScale;
|
||||
maxr->r_xtop *= cifScale;
|
||||
maxr->r_ybot *= cifScale;
|
||||
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)
|
||||
/* Check whole tile for minimum width */
|
||||
width = area.r_xtop - area.r_xbot;
|
||||
if (width < growDistance)
|
||||
{
|
||||
maxr->r_xbot -= locDist;
|
||||
maxr->r_xtop += locDist;
|
||||
}
|
||||
locDist = (growDistance - width) / 2;
|
||||
area.r_xbot -= locDist;
|
||||
area.r_xtop += locDist;
|
||||
|
||||
locDist = (growDistance - height) / 2;
|
||||
if (locDist > 0)
|
||||
/* If there is another tile on top or bottom, and the height is */
|
||||
/* 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;
|
||||
maxr->r_ytop += locDist;
|
||||
}
|
||||
tptype = TiGetTopType(tp);
|
||||
/* 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;
|
||||
return 0;
|
||||
|
|
@ -3199,7 +3305,7 @@ CIFGenLayer(op, area, cellDef, temps, clientdata)
|
|||
cifPlane = nextPlane;
|
||||
cifScale = 1;
|
||||
(void) DBSrPaintArea((Tile *) NULL, curPlane, &TiPlaneRect,
|
||||
&CIFSolidBits, cifGrowMinFunc, (ClientData)curPlane);
|
||||
&CIFSolidBits, cifGrowMinFunc, (ClientData)CIFPaintTable);
|
||||
temp = curPlane;
|
||||
curPlane = nextPlane;
|
||||
nextPlane = temp;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -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 \
|
||||
../commands/commands.h ../windows/windows.h ../database/database.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 \
|
||||
../utils/hash.h ../utils/malloc.h ../utils/utils.h ../extflat/extflat.h \
|
||||
../extflat/EFint.h
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ void efNodeMerge();
|
|||
bool efConnBuildName();
|
||||
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_cap = nodeCap;
|
||||
newnode->efnode_attrs = (EFAttr *) NULL;
|
||||
newnode->efnode_loc.r_xbot = x;
|
||||
newnode->efnode_loc.r_ybot = y;
|
||||
newnode->efnode_loc.r_xtop = x + 1;
|
||||
newnode->efnode_loc.r_ytop = y + 1;
|
||||
newnode->efnode_loc.r_xbot = (int)(0.5 + (float)x * locScale);
|
||||
newnode->efnode_loc.r_ybot = (int)(0.5 + (float)y * locScale);
|
||||
newnode->efnode_loc.r_xtop = newnode->efnode_loc.r_xbot + 1;
|
||||
newnode->efnode_loc.r_ytop = newnode->efnode_loc.r_ybot + 1;
|
||||
newnode->efnode_client = (ClientData) NULL;
|
||||
if (layerName) newnode->efnode_type =
|
||||
efBuildAddStr(EFLayerNames, &EFLayerNumNames, MAXTYPES, layerName);
|
||||
|
|
@ -686,7 +688,8 @@ efBuildDevice(def, class, type, r, argc, argv)
|
|||
{
|
||||
pn = *(argv[argstart] + 1) - '0';
|
||||
if (pn == 0)
|
||||
devtmp.dev_area = atoi(pptr);
|
||||
devtmp.dev_area = (int)(0.5 + (float)atoi(pptr)
|
||||
* locScale * locScale);
|
||||
/* Otherwise, punt */
|
||||
}
|
||||
break;
|
||||
|
|
@ -697,15 +700,15 @@ efBuildDevice(def, class, type, r, argc, argv)
|
|||
{
|
||||
pn = *(argv[argstart] + 1) - '0';
|
||||
if (pn == 0)
|
||||
devtmp.dev_perim = atoi(pptr);
|
||||
devtmp.dev_perim = (int)(0.5 + (float)atoi(pptr) * locScale);
|
||||
/* Otherwise, use verbatim */
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
devtmp.dev_length = atoi(pptr);
|
||||
devtmp.dev_length = (int)(0.5 + (float)atoi(pptr) * locScale);
|
||||
break;
|
||||
case 'w':
|
||||
devtmp.dev_width = atoi(pptr);
|
||||
devtmp.dev_width = (int)(0.5 + (float)atoi(pptr) * locScale);
|
||||
break;
|
||||
case 'c':
|
||||
devtmp.dev_cap = (float)atof(pptr);
|
||||
|
|
@ -1248,8 +1251,9 @@ efBuildConnect(def, nodeName1, nodeName2, deltaC, av, ac)
|
|||
conn->conn_next = def->def_conns;
|
||||
for (n = 0; n < efNumResistClasses && ac > 1; n++, ac -= 2)
|
||||
{
|
||||
conn->conn_pa[n].pa_area = atoi(*av++);
|
||||
conn->conn_pa[n].pa_perim = atoi(*av++);
|
||||
conn->conn_pa[n].pa_area = (int)(0.5 + (float)atoi(*av++)
|
||||
* locScale * locScale);
|
||||
conn->conn_pa[n].pa_perim = (int)(0.5 + (float)atoi(*av++) * locScale);
|
||||
}
|
||||
for ( ; n < efNumResistClasses; n++)
|
||||
conn->conn_pa[n].pa_area = conn->conn_pa[n].pa_perim = 0;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "extflat/extflat.h"
|
||||
#include "extflat/EFint.h"
|
||||
#include "extract/extract.h"
|
||||
#include "extract/extractInt.h"
|
||||
#include "utils/paths.h"
|
||||
|
||||
#ifndef MAGIC_WRAPPER
|
||||
|
|
@ -96,6 +97,7 @@ keyTable[] =
|
|||
/* Data shared with EFerror.c */
|
||||
char *efReadFileName; /* Name of file currently being read */
|
||||
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 */
|
||||
static bool efReadDef();
|
||||
|
|
@ -139,6 +141,7 @@ EFReadFile(name, dosubckt, resist, noscale)
|
|||
if (def == NULL)
|
||||
def = efDefNew(name);
|
||||
|
||||
locScale = 1.0;
|
||||
rc = efReadDef(def, dosubckt, resist, noscale, TRUE);
|
||||
if (EFArgTech) EFTech = StrDup((char **) NULL, EFArgTech);
|
||||
if (EFScale == 0.0) EFScale = 1.0;
|
||||
|
|
@ -265,6 +268,11 @@ readfile:
|
|||
cscale = 1;
|
||||
}
|
||||
lscale = (float)atof(argv[3]);
|
||||
if (lscale != ExtCurStyle->exts_unitsPerLambda)
|
||||
{
|
||||
locScale = lscale / ExtCurStyle->exts_unitsPerLambda;
|
||||
lscale = ExtCurStyle->exts_unitsPerLambda;
|
||||
}
|
||||
if (lscale == 0.0)
|
||||
{
|
||||
efReadError("Bad linear scaling = 0; reset to 1.\n");
|
||||
|
|
@ -283,10 +291,10 @@ readfile:
|
|||
|
||||
/* attr node xlo ylo xhi yhi type text */
|
||||
case ATTR:
|
||||
r.r_xbot = atoi(argv[2]);
|
||||
r.r_ybot = atoi(argv[3]);
|
||||
r.r_xtop = atoi(argv[4]);
|
||||
r.r_ytop = atoi(argv[5]),
|
||||
r.r_xbot = (int)(0.5 + (float)atoi(argv[2]) * locScale);
|
||||
r.r_ybot = (int)(0.5 + (float)atoi(argv[3]) * locScale);
|
||||
r.r_xtop = (int)(0.5 + (float)atoi(argv[4]) * locScale);
|
||||
r.r_ytop = (int)(0.5 + (float)atoi(argv[5]) * locScale),
|
||||
efBuildAttr(def, argv[1], &r, argv[6], argv[7]);
|
||||
break;
|
||||
|
||||
|
|
@ -351,10 +359,10 @@ readfile:
|
|||
break; /* we will deal with in efBuildDevice(). */
|
||||
}
|
||||
|
||||
r.r_xbot = atoi(argv[3]);
|
||||
r.r_ybot = atoi(argv[4]);
|
||||
r.r_xtop = atoi(argv[5]);
|
||||
r.r_ytop = atoi(argv[6]);
|
||||
r.r_xbot = (int)(0.5 + (float)atoi(argv[3]) * locScale);
|
||||
r.r_ybot = (int)(0.5 + (float)atoi(argv[4]) * locScale);
|
||||
r.r_xtop = (int)(0.5 + (float)atoi(argv[5]) * locScale);
|
||||
r.r_ytop = (int)(0.5 + (float)atoi(argv[6]) * locScale);
|
||||
|
||||
if (efBuildDevice(def, (char)n, argv[2], &r, argc - 7, &argv[7]) != 0)
|
||||
{
|
||||
|
|
@ -366,10 +374,10 @@ readfile:
|
|||
/* for backwards compatibility */
|
||||
/* fet type xlo ylo xhi yhi area perim substrate GATE T1 T2 ... */
|
||||
case FET:
|
||||
r.r_xbot = atoi(argv[2]);
|
||||
r.r_ybot = atoi(argv[3]);
|
||||
r.r_xtop = atoi(argv[4]);
|
||||
r.r_ytop = atoi(argv[5]);
|
||||
r.r_xbot = (int)(0.5 + (float)atoi(argv[2]) * locScale);
|
||||
r.r_ybot = (int)(0.5 + (float)atoi(argv[3]) * locScale);
|
||||
r.r_xtop = (int)(0.5 + (float)atoi(argv[4]) * locScale);
|
||||
r.r_ytop = (int)(0.5 + (float)atoi(argv[5]) * locScale);
|
||||
if (efBuildDevice(def, DEV_FET, argv[1], &r, argc - 6, &argv[6]) != 0)
|
||||
{
|
||||
efReadError("Incomplete terminal description for fet\n");
|
||||
|
|
@ -563,8 +571,8 @@ resistChanged:
|
|||
/* distance driver receiver min max */
|
||||
case DIST:
|
||||
efBuildDist(def, argv[1], argv[2],
|
||||
(int)(lscale*atoi(argv[3])),
|
||||
(int)(lscale*atoi(argv[4])));
|
||||
(int)(lscale*atoi(argv[3])*locScale),
|
||||
(int)(lscale*atoi(argv[4])*locScale));
|
||||
break;
|
||||
|
||||
/* killnode nodename */
|
||||
|
|
|
|||
|
|
@ -130,7 +130,6 @@ ResProcessJunction(tile, tp, xj, yj, NodeList)
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (j2->tj_status & RES_TILE_DONE) return;
|
||||
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
|
||||
resptr->rn_te = (tElement *) NULL;
|
||||
|
|
|
|||
|
|
@ -135,20 +135,40 @@ ResPrintExtDev(outextfile, devices)
|
|||
if (varsub != NULL) subsName = varsub;
|
||||
}
|
||||
#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,"fet %s %d %d %d %d %d %d "
|
||||
"%s \"%s\" %d %s \"%s\" %d %s \"%s\" %d %s\n",
|
||||
fprintf(outextfile,"%s %s %d %d %d %d ",
|
||||
extDevTable[devptr->exts_deviceClass],
|
||||
devptr->exts_deviceName,
|
||||
devices->layout->rd_inside.r_ll.p_x,
|
||||
devices->layout->rd_inside.r_ll.p_y,
|
||||
devices->layout->rd_inside.r_ll.p_x + 1,
|
||||
devices->layout->rd_inside.r_ll.p_y + 1,
|
||||
devices->layout->rd_area,
|
||||
devices->layout->rd_perim,
|
||||
subsName,
|
||||
devices->layout->rd_inside.r_ll.p_y + 1);
|
||||
|
||||
switch (devptr->exts_deviceClass)
|
||||
{
|
||||
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->layout->rd_length * 2,
|
||||
devices->rs_gattr,
|
||||
|
|
@ -190,7 +210,7 @@ ResPrintExtNode(outextfile, nodelist, nodename)
|
|||
ResSimNode *node,*ResInitializeNode();
|
||||
bool DoKillNode = TRUE;
|
||||
resNode *snode = nodelist;
|
||||
|
||||
|
||||
/* 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. */
|
||||
|
||||
|
|
|
|||
|
|
@ -229,12 +229,12 @@ ResReadNode(nodefile)
|
|||
char *cp;
|
||||
float lambda;
|
||||
|
||||
/* NOTE: Units from the .sim file or the .nodes file are in centimicrons
|
||||
* when multiplied by resscale (units from the .sim file 1st line).
|
||||
* multiply resscale by the extract scale (exts_unitsPerLambda) used to
|
||||
* generate .ext dimensions originally, to get back to database units.
|
||||
/* NOTE: Units from the .nodes file are in centimicrons.
|
||||
* Divide by the extract scale (exts_unitsPerLambda) to get back
|
||||
* to database units. This assumes that exts_unitsPerLambda doesn't
|
||||
* 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);
|
||||
if (fp == NULL)
|
||||
|
|
@ -358,11 +358,10 @@ ResSimDevice(line,rpersquare,ttype)
|
|||
}
|
||||
device->resistance = MagAtof(line[RDEV_LENGTH]) * rpersquare/MagAtof(line[RDEV_WIDTH]);
|
||||
}
|
||||
device->tnumber = ++Maxtnumber;
|
||||
device->status = FALSE;
|
||||
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_y = (int)((float)atof(line[RDEV_DEVY]) / lambda);
|
||||
|
||||
|
|
|
|||
|
|
@ -35,21 +35,19 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#define INITFLATSIZE 1024
|
||||
#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 */
|
||||
/* converts zeptoseconts to nanoseconds. */
|
||||
/* converts zeptoseconds to nanoseconds. */
|
||||
|
||||
#define Z_TO_N 1e12
|
||||
|
||||
/* ResSimNode is a node read in from a sim file */
|
||||
|
||||
|
||||
HashTable ResNodeTable; /* Hash table of sim file nodes */
|
||||
RDev *ResRDevList; /* Linked list of Sim devices */
|
||||
ResGlobalParams gparams; /* Junk passed between */
|
||||
/* ResCheckSimNodes and */
|
||||
/* ResExtractNet. */
|
||||
int Maxtnumber; /*maximum device number */
|
||||
extern ResSimNode *ResOriginalNodes; /*Linked List of Nodes */
|
||||
int resNodeNum;
|
||||
|
||||
|
|
@ -104,7 +102,6 @@ ExtResisForDef(celldef, resisdata)
|
|||
ResRDevList = NULL;
|
||||
ResOriginalNodes = NULL;
|
||||
|
||||
Maxtnumber = 0;
|
||||
HashInit(&ResNodeTable, INITFLATSIZE, HT_STRINGKEYS);
|
||||
/* read in .sim file */
|
||||
result = (ResReadSim(celldef->cd_name,
|
||||
|
|
@ -870,6 +867,19 @@ ResCheckSimNodes(celldef, resisdata)
|
|||
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
|
||||
* to the FastHenry geometry file.
|
||||
|
|
|
|||
|
|
@ -954,26 +954,25 @@ ResDoSimplify(tolerance,rctol,goodies)
|
|||
{
|
||||
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_Tdi = rc->rc_Tdi;
|
||||
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;
|
||||
}
|
||||
if (rc != (RCDelayStuff *)NULL)
|
||||
goodies->rg_Tdi = rc->rc_Tdi;
|
||||
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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -296,7 +296,6 @@ typedef struct rdev
|
|||
Point location; /* Location of lower left point of */
|
||||
/* device. */
|
||||
float resistance; /* "Resistance" of device. */
|
||||
int tnumber; /* Device number */
|
||||
int rs_ttype; /* device type */
|
||||
char *rs_gattr; /* Gate attributes, if any */
|
||||
char *rs_sattr;
|
||||
|
|
@ -572,7 +571,6 @@ extern RDev *ResRDevList;
|
|||
extern REcell *ResBigEventList;
|
||||
extern int ResOptionsFlags;
|
||||
extern char *ResCurrentNode;
|
||||
extern int Maxtnumber;
|
||||
extern ResSimNode *ResOriginalNodes;
|
||||
#ifdef ARIEL
|
||||
extern int ResMinEventTime;
|
||||
|
|
|
|||
Loading…
Reference in New Issue