Modified the "port renumber" command to use (case-insensitive)
natural sort instead of ASCII-based sorting, so that ports that are numbered arrays will be indexed properly by count. Also: Modified the "extresist" handling of substrate to draw the default substrate type over the entire cell area (less areas of nwell or other conflicting type). This allows extresist to extract the entire substrate as a resistive network. The result is ugly and may warrant some aggressive network simplification, but it should at least be realistic.
This commit is contained in:
parent
e72f85fd10
commit
3da6172706
|
|
@ -1407,9 +1407,14 @@ portFindLabel(editDef, port, unique, nonEdit)
|
|||
int
|
||||
complabel(const void *one, const void *two)
|
||||
{
|
||||
/* Natural sort order routine from DBcellname.c
|
||||
* replaces strcasecmp().
|
||||
*/
|
||||
int strcmpbynum();
|
||||
|
||||
Label *l1 = *((Label **)one);
|
||||
Label *l2 = *((Label **)two);
|
||||
return strcasecmp(l1->lab_text, l2->lab_text);
|
||||
return strcmpbynum(l1->lab_text, l2->lab_text);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2027,6 +2032,8 @@ CmdPort(w, cmd)
|
|||
* order of the label text). NOTE: Because SPICE is
|
||||
* case-insensitive, case-insensitive alphabetical order
|
||||
* is used.
|
||||
* Update (2/26/2023): Use *natural sort* order so that
|
||||
* indexes get sorted in numerical, not alphabetical, order.
|
||||
*/
|
||||
{
|
||||
int numlabels, n, p;
|
||||
|
|
|
|||
|
|
@ -820,6 +820,89 @@ DBCellGenerateSubstrate(scx, subType, notSubMask, subShieldMask, targetDef)
|
|||
return tempPlane;
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* DBCellGenerateSimpleSubstrate --
|
||||
*
|
||||
* This function is used by the extraction code in "extresist".
|
||||
* It is similar to DBCellGenerateSubstrate(), above. It finds space
|
||||
* tiles on the substrate plane and converts them to a substrate type
|
||||
* in the target, clipped to the cell boundary. This allows the
|
||||
* extraction to find and record all common (global) substrate regions,
|
||||
* without requiring a physical substrate type to be drawn into all cells.
|
||||
*
|
||||
* Unlike normal paint copying, this can only be done by painting the
|
||||
* substrate type over the entire cell area and then erasing all areas
|
||||
* belonging to not-substrate types in the source.
|
||||
*
|
||||
* Returns:
|
||||
* Nothing.
|
||||
*
|
||||
* Side Effects:
|
||||
* Paints into the targetUse's CellDef. This only happens if two
|
||||
* conditions are met:
|
||||
* (1) The techfile has defined "substrate"
|
||||
* (2) The techfile defines a type corresponding to the substrate
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Plane *
|
||||
DBCellGenerateSimpleSubstrate(scx, subType, notSubMask, targetDef)
|
||||
SearchContext *scx;
|
||||
TileType subType; /* Substrate paint type */
|
||||
TileTypeBitMask *notSubMask; /* Mask of types that are not substrate */
|
||||
CellDef *targetDef;
|
||||
{
|
||||
struct dbCopySubData csd;
|
||||
Plane *tempPlane;
|
||||
int plane;
|
||||
Rect rect;
|
||||
TileTypeBitMask allButSubMask;
|
||||
TileTypeBitMask defaultSubTypeMask;
|
||||
int dbEraseSubFunc();
|
||||
int dbPaintSubFunc();
|
||||
int dbEraseNonSub();
|
||||
int dbCopySubFunc();
|
||||
|
||||
GEOTRANSRECT(&scx->scx_trans, &scx->scx_area, &rect);
|
||||
|
||||
/* Clip to bounding box of the top level cell */
|
||||
GEOCLIP(&rect, &scx->scx_use->cu_def->cd_bbox);
|
||||
|
||||
plane = DBPlane(subType);
|
||||
|
||||
tempPlane = DBNewPlane((ClientData) TT_SPACE);
|
||||
DBClearPaintPlane(tempPlane);
|
||||
|
||||
csd.csd_subtype = subType;
|
||||
csd.csd_plane = tempPlane;
|
||||
csd.csd_pNum = plane;
|
||||
csd.csd_modified = FALSE;
|
||||
|
||||
/* Paint the substrate type in the temporary plane over the area of */
|
||||
/* the entire cell. */
|
||||
DBPaintPlane(tempPlane, &rect, DBStdPaintTbl(subType, plane),
|
||||
(PaintUndoInfo *)NULL);
|
||||
|
||||
/* Now erase all areas that are non-substrate types in the source */
|
||||
DBTreeSrTiles(scx, notSubMask, 0, dbEraseNonSub, (ClientData)&csd);
|
||||
|
||||
/* Finally, copy the destination plane contents onto tempPlane, */
|
||||
/* ignoring the substrate type. */
|
||||
TTMaskZero(&allButSubMask);
|
||||
TTMaskSetMask(&allButSubMask, &DBAllButSpaceBits);
|
||||
TTMaskClearType(&allButSubMask, subType);
|
||||
DBSrPaintArea((Tile *)NULL, targetDef->cd_planes[plane], &TiPlaneRect,
|
||||
&allButSubMask, dbCopySubFunc, (ClientData)&csd);
|
||||
|
||||
/* Now we have a plane where the substrate type occupies the whole */
|
||||
/* area of the cell except where there are conflicting types (e.g., */
|
||||
/* nwell). Return this plane. */
|
||||
return tempPlane;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback function for DBCellGenerateSubstrate()
|
||||
* Finds tiles in the source def that belong to the type that represents
|
||||
|
|
|
|||
|
|
@ -637,7 +637,7 @@ DBTopPrint(mw, dolist)
|
|||
|
||||
int strcmpbynum(const char *s1, const char *s2)
|
||||
{
|
||||
/* Like strcmp() but compare sequences of digits numerically */
|
||||
/* Like strcasecmp() but compare sequences of digits numerically */
|
||||
for (;;)
|
||||
{
|
||||
if (*s2 == '\0')
|
||||
|
|
@ -646,8 +646,11 @@ int strcmpbynum(const char *s1, const char *s2)
|
|||
return 1;
|
||||
else if (!(isdigit(*s1) && isdigit(*s2)))
|
||||
{
|
||||
if (*s1 != *s2)
|
||||
return (int)*s1 - (int)*s2;
|
||||
char c1, c2;
|
||||
c1 = tolower(*s1);
|
||||
c2 = tolower(*s2);
|
||||
if (c1 != c2)
|
||||
return (int)c1 - (int)c2;
|
||||
else
|
||||
{
|
||||
++s1;
|
||||
|
|
|
|||
|
|
@ -894,6 +894,7 @@ extern void DBCellCopyCells();
|
|||
extern void DBCellCopyAllCells();
|
||||
extern void DBFlatCopyMaskHints();
|
||||
extern Plane *DBCellGenerateSubstrate();
|
||||
extern Plane *DBCellGenerateSimpleSubstrate();
|
||||
|
||||
/* Contact image handling */
|
||||
extern TileType DBPlaneToResidue();
|
||||
|
|
|
|||
|
|
@ -292,10 +292,10 @@ extPrepSubstrate(def)
|
|||
TTMaskCom2(¬SubMask, &subMask);
|
||||
TTMaskAndMask(¬SubMask, &DBPlaneTypes[ExtCurStyle->exts_globSubstratePlane]);
|
||||
|
||||
/* Generate the full flattened substrate into ha->ha_cumFlat (which */
|
||||
/* was empty initially). This adds layer geometry for the */
|
||||
/* substrate in the typical case where the substrate may be space */
|
||||
/* (implicitly defined substrate). */
|
||||
/* Generate the full flattened substrate into a new plane structure */
|
||||
/* (called subPlane). This adds layer geometry for the substrate */
|
||||
/* in the typical case where the substrate may be space (implicitly */
|
||||
/* defined substrate). */
|
||||
|
||||
scx.scx_trans = GeoIdentityTransform;
|
||||
scx.scx_area = def->cd_bbox;
|
||||
|
|
@ -316,6 +316,81 @@ extPrepSubstrate(def)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* extResPrepSubstrate ---
|
||||
*
|
||||
* This works similarly to extPrepSubstrate above, but is used for the
|
||||
* "extresist" command, where the method is to make sure that the whole
|
||||
* substrate area of the cell has non-space tiles, so that these can be
|
||||
* used to estimate the resistance of the substrate from point to point,
|
||||
* and to eliminate isolated substrate regions, since those represent an
|
||||
* idealized cutoff of resistance that "extresist" is supposed to be
|
||||
* replacing with an accurate resitance network.
|
||||
*
|
||||
* Results:
|
||||
* Returns a Plane structure that is the original substrate plane from
|
||||
* CellDef "def", with the entire substrate region filled with the
|
||||
* substrate tile type. If a substrate plane or substrate type is not
|
||||
* defined by the technology, then the routine returns NULL.
|
||||
*
|
||||
* Side effects:
|
||||
* All modifications are limited to the returned plane structure.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Plane *
|
||||
extResPrepSubstrate(def)
|
||||
CellDef *def;
|
||||
{
|
||||
SearchContext scx;
|
||||
CellUse dummy;
|
||||
TileType subType;
|
||||
TileTypeBitMask subMask, notSubMask;
|
||||
Plane *subPlane, *savePlane;
|
||||
int pNum;
|
||||
|
||||
/* Determine if substrate copying is required. */
|
||||
|
||||
if (ExtCurStyle->exts_globSubstratePlane == -1) return NULL;
|
||||
|
||||
/* Find a type to use for the substrate, and the mask of all types */
|
||||
/* in the same plane as the substrate that are not connected to the */
|
||||
/* substrate. If there is not a simple type representing the substrate */
|
||||
/* then do not attempt to resolve substrate regions. */
|
||||
|
||||
if ((subType = ExtCurStyle->exts_globSubstrateDefaultType) == -1) return NULL;
|
||||
|
||||
TTMaskZero(&subMask);
|
||||
TTMaskSetMask(&subMask, &ExtCurStyle->exts_globSubstrateTypes);
|
||||
TTMaskCom2(¬SubMask, &subMask);
|
||||
TTMaskAndMask(¬SubMask, &DBPlaneTypes[ExtCurStyle->exts_globSubstratePlane]);
|
||||
|
||||
/* Generate the full flattened substrate into a new plane structure */
|
||||
/* (called subPlane). This adds layer geometry for the substrate */
|
||||
/* in the typical case where the substrate may be space (implicitly */
|
||||
/* defined substrate). */
|
||||
|
||||
scx.scx_trans = GeoIdentityTransform;
|
||||
scx.scx_area = def->cd_bbox;
|
||||
scx.scx_use = &dummy;
|
||||
dummy.cu_def = def;
|
||||
dummy.cu_id = NULL;
|
||||
|
||||
subPlane = DBCellGenerateSimpleSubstrate(&scx, subType, ¬SubMask, def);
|
||||
if (subPlane != NULL)
|
||||
{
|
||||
pNum = ExtCurStyle->exts_globSubstratePlane;
|
||||
savePlane = def->cd_planes[pNum];
|
||||
def->cd_planes[pNum] = subPlane;
|
||||
return savePlane;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
|
|||
|
|
@ -282,19 +282,24 @@ ResEachTile(tile, startpoint)
|
|||
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp=RT(tp))
|
||||
{
|
||||
t2 = TiGetRightType(tp);
|
||||
devptr = ExtCurStyle->exts_device[t2];
|
||||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
|
||||
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
|
||||
/* found device */
|
||||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2))
|
||||
{
|
||||
xj = LEFT(tile);
|
||||
yj = (TOP(tp) + BOTTOM(tp)) >> 1;
|
||||
ResNewSDDevice(tile, tp, xj, yj, RIGHTEDGE, &ResNodeQueue);
|
||||
devptr = ExtCurStyle->exts_device[t2];
|
||||
for (i = 0; i < devptr->exts_deviceSDCount; i++)
|
||||
{
|
||||
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[i]), t1))
|
||||
{
|
||||
/* found device */
|
||||
xj = LEFT(tile);
|
||||
yj = (TOP(tp) + BOTTOM(tp)) >> 1;
|
||||
ResNewSDDevice(tile, tp, xj, yj, RIGHTEDGE, &ResNodeQueue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if TTMaskHasType(&(ExtCurStyle->exts_nodeConn[t1]), t2)
|
||||
/* tile is junction */
|
||||
{
|
||||
/*junction rn_loc */
|
||||
/* tile is junction */
|
||||
xj = LEFT(tile);
|
||||
yj = (MAX(BOTTOM(tile), BOTTOM(tp)) + MIN(TOP(tile), TOP(tp))) >> 1;
|
||||
(void) ResProcessJunction(tile, tp, xj, yj, &ResNodeQueue);
|
||||
|
|
@ -304,20 +309,25 @@ ResEachTile(tile, startpoint)
|
|||
/* right */
|
||||
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp=LB(tp))
|
||||
{
|
||||
t2 = TiGetLeftType(tp);
|
||||
devptr = ExtCurStyle->exts_device[t2];
|
||||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
|
||||
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
|
||||
/* found device */
|
||||
t2 = TiGetLeftType(tp);
|
||||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2))
|
||||
{
|
||||
xj = RIGHT(tile);
|
||||
yj = (TOP(tp)+BOTTOM(tp))>>1;
|
||||
ResNewSDDevice(tile, tp, xj, yj, LEFTEDGE, &ResNodeQueue);
|
||||
devptr = ExtCurStyle->exts_device[t2];
|
||||
for (i = 0; i < devptr->exts_deviceSDCount; i++)
|
||||
{
|
||||
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[i]), t1))
|
||||
{
|
||||
/* found device */
|
||||
xj = RIGHT(tile);
|
||||
yj = (TOP(tp) + BOTTOM(tp)) >> 1;
|
||||
ResNewSDDevice(tile, tp, xj, yj, LEFTEDGE, &ResNodeQueue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if TTMaskHasType(&ExtCurStyle->exts_nodeConn[t1], t2)
|
||||
/* tile is junction */
|
||||
{
|
||||
/*junction rn_loc */
|
||||
/* tile is junction */
|
||||
xj = RIGHT(tile);
|
||||
yj = (MAX(BOTTOM(tile),BOTTOM(tp)) + MIN(TOP(tile), TOP(tp))) >> 1;
|
||||
(void)ResProcessJunction(tile, tp, xj, yj, &ResNodeQueue);
|
||||
|
|
@ -327,19 +337,25 @@ ResEachTile(tile, startpoint)
|
|||
/* top */
|
||||
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp=BL(tp))
|
||||
{
|
||||
t2 = TiGetBottomType(tp);
|
||||
devptr = ExtCurStyle->exts_device[t2];
|
||||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
|
||||
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
|
||||
/* found device */
|
||||
t2 = TiGetBottomType(tp);
|
||||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2))
|
||||
{
|
||||
yj = TOP(tile);
|
||||
xj = (LEFT(tp)+RIGHT(tp))>>1;
|
||||
ResNewSDDevice(tile, tp, xj, yj, BOTTOMEDGE, &ResNodeQueue);
|
||||
devptr = ExtCurStyle->exts_device[t2];
|
||||
for (i = 0; i < devptr->exts_deviceSDCount; i++)
|
||||
{
|
||||
if(TTMaskHasType(&(devptr->exts_deviceSDTypes[i]), t1))
|
||||
{
|
||||
/* found device */
|
||||
yj = TOP(tile);
|
||||
xj = (LEFT(tp)+RIGHT(tp))>>1;
|
||||
ResNewSDDevice(tile, tp, xj, yj, BOTTOMEDGE, &ResNodeQueue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if TTMaskHasType(&ExtCurStyle->exts_nodeConn[t1],t2)
|
||||
/* tile is junction */
|
||||
{
|
||||
/* tile is junction */
|
||||
yj = TOP(tile);
|
||||
xj = (MAX(LEFT(tile),LEFT(tp)) + MIN(RIGHT(tile),RIGHT(tp))) >> 1;
|
||||
ResProcessJunction(tile, tp, xj, yj, &ResNodeQueue);
|
||||
|
|
@ -349,19 +365,25 @@ ResEachTile(tile, startpoint)
|
|||
/* bottom */
|
||||
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp=TR(tp))
|
||||
{
|
||||
t2 = TiGetTopType(tp);
|
||||
devptr = ExtCurStyle->exts_device[t2];
|
||||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
|
||||
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
|
||||
/* found device */
|
||||
t2 = TiGetTopType(tp);
|
||||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2))
|
||||
{
|
||||
yj = BOTTOM(tile);
|
||||
xj = (LEFT(tp) + RIGHT(tp)) >> 1;
|
||||
ResNewSDDevice(tile, tp, xj, yj, TOPEDGE, &ResNodeQueue);
|
||||
devptr = ExtCurStyle->exts_device[t2];
|
||||
for (i = 0; i < devptr->exts_deviceSDCount; i++)
|
||||
{
|
||||
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[i]), t1))
|
||||
{
|
||||
/* found device */
|
||||
yj = BOTTOM(tile);
|
||||
xj = (LEFT(tp) + RIGHT(tp)) >> 1;
|
||||
ResNewSDDevice(tile, tp, xj, yj, TOPEDGE, &ResNodeQueue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if TTMaskHasType(&(ExtCurStyle->exts_nodeConn[t1]), t2)
|
||||
/* tile is junction */
|
||||
{
|
||||
/* tile is junction */
|
||||
yj = BOTTOM(tile);
|
||||
xj = (MAX(LEFT(tile),LEFT(tp)) + MIN(RIGHT(tile),RIGHT(tp))) >> 1;
|
||||
ResProcessJunction(tile, tp, xj, yj, &ResNodeQueue);
|
||||
|
|
|
|||
131
resis/ResMain.c
131
resis/ResMain.c
|
|
@ -1162,11 +1162,42 @@ ResCleanUpEverything()
|
|||
DBCellClearDef(ResUse->cu_def);
|
||||
}
|
||||
|
||||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ResGetTileFunc --
|
||||
*
|
||||
* Callback function used by FindStartTile() when searching for
|
||||
* terminal connections of a device that may be on planes other
|
||||
* than the plane of the device identifier type. Ignore space
|
||||
* tiles. Otherwise, for any tile found, record the tile in
|
||||
* the client data record and return 1 to stop the search.
|
||||
*
|
||||
* Results:
|
||||
* Return 0 if tile is a space tile, to keep the search going.
|
||||
* Return 1 otherwise to stop the search immediately because
|
||||
* a valid start tile has been found.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
ResGetTileFunc(tile, tpptr)
|
||||
Tile *tile, **tpptr;
|
||||
{
|
||||
if (TiGetType(tile) != TT_SPACE)
|
||||
{
|
||||
*tpptr = tile;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* FindStartTile-- To start the extraction, we need to find the first driver.
|
||||
* The sim file gives us the location of a point in or near (within 1
|
||||
* The sim file gives us the location of a point in or near (within 1
|
||||
* unit) of the device. FindStartTile looks for the device, then
|
||||
* for adjoining diffusion. The diffusion tile is returned.
|
||||
*
|
||||
|
|
@ -1186,8 +1217,9 @@ FindStartTile(goodies, SourcePoint)
|
|||
{
|
||||
Point workingPoint;
|
||||
Tile *tile, *tp;
|
||||
int pnum, t1, t2;
|
||||
int pnum, t1, t2, i;
|
||||
ExtDevice *devptr;
|
||||
Rect r;
|
||||
|
||||
/* If the drive point is on a contact, check for the contact residues */
|
||||
/* first, then the contact type itself. */
|
||||
|
|
@ -1284,57 +1316,80 @@ FindStartTile(goodies, SourcePoint)
|
|||
|
||||
devptr = ExtCurStyle->exts_device[t1];
|
||||
|
||||
/* left */
|
||||
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp))
|
||||
for (i = 0; i < devptr->exts_deviceSDCount; i++)
|
||||
{
|
||||
t2 = TiGetRightType(tp);
|
||||
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2))
|
||||
/* left */
|
||||
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp))
|
||||
{
|
||||
SourcePoint->p_x = LEFT(tile);
|
||||
SourcePoint->p_y = (MIN(TOP(tile),TOP(tp)) +
|
||||
t2 = TiGetRightType(tp);
|
||||
if ((t2 != TT_SPACE) && TTMaskHasType(&(devptr->exts_deviceSDTypes[i]), t2))
|
||||
{
|
||||
SourcePoint->p_x = LEFT(tile);
|
||||
SourcePoint->p_y = (MIN(TOP(tile),TOP(tp)) +
|
||||
MAX(BOTTOM(tile), BOTTOM(tp))) >> 1;
|
||||
return(tp);
|
||||
return(tp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* right */
|
||||
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp))
|
||||
{
|
||||
t2 = TiGetLeftType(tp);
|
||||
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2))
|
||||
/* right */
|
||||
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp))
|
||||
{
|
||||
SourcePoint->p_x = RIGHT(tile);
|
||||
SourcePoint->p_y = (MIN(TOP(tile), TOP(tp))+
|
||||
t2 = TiGetLeftType(tp);
|
||||
if ((t2 != TT_SPACE) && TTMaskHasType(&(devptr->exts_deviceSDTypes[i]), t2))
|
||||
{
|
||||
SourcePoint->p_x = RIGHT(tile);
|
||||
SourcePoint->p_y = (MIN(TOP(tile), TOP(tp))+
|
||||
MAX(BOTTOM(tile), BOTTOM(tp))) >> 1;
|
||||
return(tp);
|
||||
return(tp);
|
||||
}
|
||||
}
|
||||
|
||||
/* top */
|
||||
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp))
|
||||
{
|
||||
t2 = TiGetBottomType(tp);
|
||||
if ((t2 != TT_SPACE) && TTMaskHasType(&(devptr->exts_deviceSDTypes[i]), t2))
|
||||
{
|
||||
SourcePoint->p_y = TOP(tile);
|
||||
SourcePoint->p_x = (MIN(RIGHT(tile),RIGHT(tp)) +
|
||||
MAX(LEFT(tile), LEFT(tp))) >> 1;
|
||||
return(tp);
|
||||
}
|
||||
}
|
||||
|
||||
/* bottom */
|
||||
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp))
|
||||
{
|
||||
t2 = TiGetTopType(tp);
|
||||
if ((t2 != TT_SPACE) && TTMaskHasType(&(devptr->exts_deviceSDTypes[i]), t2))
|
||||
{
|
||||
SourcePoint->p_y = BOTTOM(tile);
|
||||
SourcePoint->p_x = (MIN(RIGHT(tile), RIGHT(tp)) +
|
||||
MAX(LEFT(tile), LEFT(tp))) >> 1;
|
||||
return(tp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* top */
|
||||
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp))
|
||||
/* Didn't find a terminal (S/D) type tile in the perimeter search. */
|
||||
/* Check if S/D types are in a different plane from the identifier. */
|
||||
|
||||
TiToRect(tile, &r);
|
||||
tp = NULL;
|
||||
for (i = 0; i < devptr->exts_deviceSDCount; i++)
|
||||
{
|
||||
t2 = TiGetBottomType(tp);
|
||||
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2))
|
||||
for (pnum = 0; pnum < DBNumPlanes; pnum++)
|
||||
{
|
||||
SourcePoint->p_y = TOP(tile);
|
||||
SourcePoint->p_x = (MIN(RIGHT(tile),RIGHT(tp)) +
|
||||
MAX(LEFT(tile), LEFT(tp))) >> 1;
|
||||
return(tp);
|
||||
DBSrPaintArea((Tile *)NULL, ResUse->cu_def->cd_planes[pnum],
|
||||
&r, &(devptr->exts_deviceSDTypes[i]), ResGetTileFunc, &tp);
|
||||
if (tp != NULL) return tp;
|
||||
}
|
||||
}
|
||||
|
||||
/* bottom */
|
||||
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp))
|
||||
{
|
||||
t2 = TiGetTopType(tp);
|
||||
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2))
|
||||
{
|
||||
SourcePoint->p_y = BOTTOM(tile);
|
||||
SourcePoint->p_x = (MIN(RIGHT(tile), RIGHT(tp)) +
|
||||
MAX(LEFT(tile), LEFT(tp))) >> 1;
|
||||
return(tp);
|
||||
}
|
||||
}
|
||||
/* Didn't find a terminal (S/D) type tile anywhere. Flag an error. */
|
||||
|
||||
TxError("Couldn't find a terminal of the device at %d %d\n",
|
||||
goodies->rg_devloc->p_x, goodies->rg_devloc->p_y);
|
||||
return((Tile *) NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,13 +83,24 @@ int ResPortIndex; /* Port ordering to backannotate into magic */
|
|||
extern ResSimNode *ResInitializeNode();
|
||||
extern CellUse *CmdGetSelectedCell();
|
||||
|
||||
/* Linked list structure to use to store the substrate plane from each */
|
||||
/* extracted CellDef so that they can be returned to the original after */
|
||||
/* extraction. */
|
||||
|
||||
struct saveList {
|
||||
Plane *sl_plane;
|
||||
CellDef *sl_def;
|
||||
struct saveList *sl_next;
|
||||
};
|
||||
|
||||
/* Structure stores information required to be sent to ExtResisForDef() */
|
||||
typedef struct
|
||||
{
|
||||
float tolerance;
|
||||
float tdiTolerance;
|
||||
float frequency;
|
||||
CellDef *mainDef;
|
||||
float tolerance;
|
||||
float tdiTolerance;
|
||||
float frequency;
|
||||
struct saveList *savePlanes;
|
||||
CellDef *mainDef;
|
||||
} ResisData;
|
||||
|
||||
/*
|
||||
|
|
@ -114,6 +125,7 @@ ExtResisForDef(celldef, resisdata)
|
|||
ResSimNode *node;
|
||||
int result, idx;
|
||||
char *devname;
|
||||
Plane *savePlane;
|
||||
|
||||
ResRDevList = NULL;
|
||||
ResOriginalNodes = NULL;
|
||||
|
|
@ -122,6 +134,18 @@ ExtResisForDef(celldef, resisdata)
|
|||
if (HashLookOnly(&ResProcessedTable, celldef->cd_name)) return;
|
||||
HashFind(&ResProcessedTable, celldef->cd_name);
|
||||
|
||||
/* Prepare the substrate for resistance extraction */
|
||||
savePlane = extResPrepSubstrate(celldef);
|
||||
if (savePlane != NULL)
|
||||
{
|
||||
struct saveList *newsl;
|
||||
newsl = (struct saveList *)mallocMagic(sizeof(struct saveList));
|
||||
newsl->sl_plane = savePlane;
|
||||
newsl->sl_def = celldef;
|
||||
newsl->sl_next = resisdata->savePlanes;
|
||||
resisdata->savePlanes = newsl;
|
||||
}
|
||||
|
||||
/* Get device information from the current extraction style */
|
||||
idx = 0;
|
||||
while (ExtGetDevInfo(idx++, &devname, NULL, NULL, NULL, NULL, NULL))
|
||||
|
|
@ -227,6 +251,7 @@ CmdExtResis(win, cmd)
|
|||
CellUse *selectedUse;
|
||||
ResisData resisdata;
|
||||
char *endptr; /* for use with strtod() */
|
||||
struct saveList *sl;
|
||||
|
||||
extern int resSubcircuitFunc(); /* Forward declaration */
|
||||
|
||||
|
|
@ -627,6 +652,7 @@ typedef enum {
|
|||
resisdata.tdiTolerance = tdiTolerance;
|
||||
resisdata.frequency = fhFrequency;
|
||||
resisdata.mainDef = mainDef;
|
||||
resisdata.savePlanes = (struct saveList *)NULL;
|
||||
|
||||
/* Do subcircuits (if any) first */
|
||||
HashInit(&ResProcessedTable, INITFLATSIZE, HT_STRINGKEYS);
|
||||
|
|
@ -636,6 +662,13 @@ typedef enum {
|
|||
ExtResisForDef(mainDef, &resisdata);
|
||||
HashKill(&ResProcessedTable);
|
||||
|
||||
/* Revert substrate planes */
|
||||
for (sl = resisdata.savePlanes; sl; sl = sl->sl_next)
|
||||
{
|
||||
ExtRevertSubstrate(sl->sl_def, sl->sl_plane);
|
||||
freeMagic(sl);
|
||||
}
|
||||
|
||||
/* turn back on undo stuff */
|
||||
UndoEnable();
|
||||
#ifdef LAPLACE
|
||||
|
|
@ -1337,6 +1370,14 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
|||
|
||||
if (simDev->drain == simNode)
|
||||
{
|
||||
if ((layoutDev->rd_fet_source != NULL) &&
|
||||
(layoutDev->rd_fet_drain == NULL))
|
||||
{
|
||||
/* Handle source/drain-tied devices */
|
||||
if (simDev->drain == simDev->source)
|
||||
layoutDev->rd_fet_drain = layoutDev->rd_fet_source;
|
||||
}
|
||||
|
||||
if (((source = layoutDev->rd_fet_source) != NULL) &&
|
||||
((drain = layoutDev->rd_fet_drain) != NULL))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -634,6 +634,7 @@ extern void ResSortByGate();
|
|||
extern void ResFixDevName();
|
||||
extern void ResWriteLumpFile();
|
||||
extern void ResSortBreaks();
|
||||
extern Plane *extResPrepSubstrate();
|
||||
|
||||
/* C99 compat */
|
||||
extern void ResAddToQueue();
|
||||
|
|
|
|||
Loading…
Reference in New Issue