Modified behavior with regard to substrate shield types being inside
a subcell: A further check is done to see if there are any devices that interact with the substrate in the shielded area in the same subcell. If not, then this is a trivial case where a different substrate area exists but does not impact the subcell and should be ignored. This change prevents some extraction errors where a substrate area can get isolated because there was an unrelated substrate area nearby. Also: Corrected parsing of "dsubckt" types when reading .ext files; this applies to any device where the optional substrate is omitted. There are apparently two conflicting methods when a device doesn't have a substrate: (1) Output "None" for the substrate, or (2) don't output anything. The 2nd method can be detected by counting the number of arguments on the line in the .ext file. The extflat/ EFread.c code handles both methods. ResReadExtFile() now does too, but probably code should be changed to just use method (1) always. Also: Prevented the "tile not visited" error message in "extresist" from printing duplicate messages for every device associated with the same tile. The message can appear when a labeled net has unconnected regions, and "extract do unique" is not used.
This commit is contained in:
parent
d44aeaa1d1
commit
381714e2d5
|
|
@ -115,23 +115,91 @@ bool extTestNMInteract(Tile *t1, TileType di1, Tile *t2, TileType di2)
|
|||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
* extHierSubShieldFunc --
|
||||
* extHierSubInteractFunc --
|
||||
*
|
||||
* Simple callback function for extHierSubstrate() that halts the
|
||||
* search if any substrate shield type is found in the search area
|
||||
* Simple callback function for extHierSubShielfFunc() that halts
|
||||
* the search if any type connecting to substrate is found in
|
||||
* the area.
|
||||
*
|
||||
* Results: 1 to stop the search.
|
||||
*
|
||||
* Side effects: None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
extHierSubShieldFunc(tile, dinfo, clientdata)
|
||||
Tile *tile; /* (unused) */
|
||||
TileType dinfo; /* (unused) */
|
||||
ClientData clientdata; /* (unused) */
|
||||
extHierSubInteractFunc(tile, dinfo, clientdata)
|
||||
Tile *tile; /* unused */
|
||||
TileType dinfo; /* unused */
|
||||
ClientData clientdata; /* unused */
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
* extHierSubShieldFunc --
|
||||
*
|
||||
* Callback function for extHierSubstrate() that halts the search
|
||||
* if any substrate shield type is found in the search area. To
|
||||
* avoid flagging substrate shields that overlap the search area
|
||||
* but do not interact with the cell, check the area of the
|
||||
* substrate shield for device types that connect to substrate
|
||||
* (ExtCurStyle->exts_subsDevTypes). If something is found, then
|
||||
* return 1 immediately to stop the search.
|
||||
*
|
||||
* Results: 1 if an interacting substrate shield is found, 0 otherwise.
|
||||
*
|
||||
* Side effects: None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
extHierSubShieldFunc(tile, dinfo, use)
|
||||
Tile *tile;
|
||||
TileType dinfo;
|
||||
CellUse *use;
|
||||
{
|
||||
Rect r, rsub;
|
||||
int pNum;
|
||||
TileType ttype;
|
||||
CellDef *subdef;
|
||||
Transform t;
|
||||
|
||||
if (IsSplit(tile))
|
||||
{
|
||||
ttype = TiGetLeftType(tile);
|
||||
if (!TTMaskHasType(&ExtCurStyle->exts_globSubstrateShieldTypes, ttype))
|
||||
ttype = TiGetRightType(tile);
|
||||
}
|
||||
else
|
||||
ttype = TiGetTypeExact(tile);
|
||||
|
||||
TiToRect(tile, &r);
|
||||
|
||||
/* Convert area of tile to the coordinates of the cell "subdef", which is
|
||||
* a child of the cell containing "tile".
|
||||
*/
|
||||
subdef = use->cu_def;
|
||||
GeoInvertTrans(&use->cu_transform, &t);
|
||||
GeoTransRect(&t, &r, &rsub);
|
||||
|
||||
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
|
||||
{
|
||||
if (TTMaskIntersect(&DBPlaneTypes[pNum], &ExtCurStyle->exts_subsDevTypes))
|
||||
{
|
||||
if (DBSrPaintNMArea((Tile *)NULL,
|
||||
subdef->cd_planes[pNum], dinfo, &rsub,
|
||||
&ExtCurStyle->exts_subsDevTypes,
|
||||
extHierSubInteractFunc, (ClientData)NULL) == 1)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
* extHierSubstrate --
|
||||
|
|
@ -229,7 +297,7 @@ extHierSubstrate(ha, use, x, y)
|
|||
if (DBSrPaintArea((Tile *) NULL,
|
||||
def->cd_planes[pNum], &subArea,
|
||||
&ExtCurStyle->exts_globSubstrateShieldTypes,
|
||||
extHierSubShieldFunc, (ClientData)NULL) != 0)
|
||||
extHierSubShieldFunc, PTR2CD(use)) != 0)
|
||||
{
|
||||
freeMagic(nodeList);
|
||||
ExtResetTiles(use->cu_def, CLIENTDEFAULT);
|
||||
|
|
|
|||
|
|
@ -836,6 +836,7 @@ extTechStyleInit(style)
|
|||
|
||||
style->exts_sidePlanes = style->exts_overlapPlanes = 0;
|
||||
TTMaskZero(&style->exts_deviceMask);
|
||||
TTMaskZero(&style->exts_subsDevTypes);
|
||||
style->exts_activeTypes = DBAllButSpaceAndDRCBits;
|
||||
|
||||
for (r = 0; r < NP; r++)
|
||||
|
|
@ -2355,6 +2356,9 @@ ExtTechLine(sectionName, argc, argv)
|
|||
}
|
||||
|
||||
TTMaskSetMask(&ExtCurStyle->exts_deviceMask, &types1);
|
||||
if (!TTMaskIsZero(&subsTypes))
|
||||
TTMaskSetMask(&ExtCurStyle->exts_subsDevTypes, &types1);
|
||||
|
||||
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
|
||||
if (TTMaskHasType(&types1, t))
|
||||
{
|
||||
|
|
@ -2380,6 +2384,7 @@ ExtTechLine(sectionName, argc, argv)
|
|||
|
||||
devptr->exts_next = ExtCurStyle->exts_device[t];
|
||||
ExtCurStyle->exts_device[t] = devptr;
|
||||
|
||||
#ifdef ARIEL
|
||||
{
|
||||
int z;
|
||||
|
|
@ -2867,6 +2872,8 @@ ExtTechLine(sectionName, argc, argv)
|
|||
}
|
||||
|
||||
TTMaskSetMask(&ExtCurStyle->exts_deviceMask, &types1);
|
||||
if (!TTMaskIsZero(&subsTypes))
|
||||
TTMaskSetMask(&ExtCurStyle->exts_subsDevTypes, &types1);
|
||||
|
||||
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -626,6 +626,13 @@ typedef struct extstyle
|
|||
*/
|
||||
TileTypeBitMask exts_deviceConn[NT];
|
||||
|
||||
/*
|
||||
* List of device types which connect to a substrate type. This
|
||||
* distinguishes between devices that make a connection to substrate
|
||||
* (e.g., FETs) and those that don't (e.g., MiM caps, metal resistors).
|
||||
*/
|
||||
TileTypeBitMask exts_subsDevTypes;
|
||||
|
||||
/*
|
||||
* Set of types to be considered for extraction. Types not in
|
||||
* this list cannot be nodes (e.g., implant layers)
|
||||
|
|
|
|||
|
|
@ -1492,7 +1492,7 @@ ResExtractNet(node, resisdata, cellname)
|
|||
resDevTerm *resdevList, *resdevNext;
|
||||
|
||||
resdevList = (resDevTerm *)HashGetValue(he);
|
||||
while (resdevList)
|
||||
if (resdevList)
|
||||
{
|
||||
/* Diagnostic */
|
||||
Tile *tp;
|
||||
|
|
@ -1501,9 +1501,12 @@ ResExtractNet(node, resisdata, cellname)
|
|||
(resdevList->rdt_term < 0) ? "Substrate" : "Terminal",
|
||||
tp->ti_ll.p_x, tp->ti_ll.p_y);
|
||||
|
||||
resdevNext = resdevList->rdt_next;
|
||||
freeMagic((char *)resdevList);
|
||||
resdevList = resdevNext;
|
||||
while (resdevList)
|
||||
{
|
||||
resdevNext = resdevList->rdt_next;
|
||||
freeMagic((char *)resdevList);
|
||||
resdevList = resdevNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
HashKill(&DevNodeTable);
|
||||
|
|
|
|||
|
|
@ -737,7 +737,7 @@ ResReadDevice(int argc,
|
|||
char *argv[])
|
||||
{
|
||||
RDev *device;
|
||||
int rvalue, i, j, k, w, l;
|
||||
int rvalue, i, j, k, w, l, n;
|
||||
ExtDevice *devptr;
|
||||
TileType ttype;
|
||||
HashEntry *entry;
|
||||
|
|
@ -791,13 +791,25 @@ ResReadDevice(int argc,
|
|||
* arbitrary number of terminals.
|
||||
*/
|
||||
|
||||
if (strcmp(argv[i], "None"))
|
||||
/* See code in extflat/EFbuild.c: Devices do not necessarily
|
||||
* declare a substrate terminal. This can be determined by
|
||||
* noting that all terminals other than the substrate come in
|
||||
* triplets of arguments, so if the remaining count of arguments
|
||||
* is divisible by 3, then there is no substrate node, and if
|
||||
* there is a remainder of 1, then there is. It would probably
|
||||
* be simpler if all devices just put "None" in this position.
|
||||
*/
|
||||
n = argc - i;
|
||||
if ((n % 3) == 1) /* Device has a substrate argument */
|
||||
{
|
||||
entry = HashFind(&ResNodeTable, argv[i]);
|
||||
device->subs = (ResExtNode *)HashGetValue(entry);
|
||||
ResNodeAddDevice(device->subs, device, SUBS);
|
||||
if (strcmp(argv[i], "None"))
|
||||
{
|
||||
entry = HashFind(&ResNodeTable, argv[i]);
|
||||
device->subs = (ResExtNode *)HashGetValue(entry);
|
||||
ResNodeAddDevice(device->subs, device, SUBS);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
entry = HashFind(&ResNodeTable, argv[i]);
|
||||
device->gate = (ResExtNode *)HashGetValue(entry);
|
||||
device->rs_gattr = StrDup((char **)NULL, argv[i + 2]);
|
||||
|
|
|
|||
Loading…
Reference in New Issue