Corrected two separate issues with R-C extraction: (1) There was
a method that failed to work on devices with complex shapes on the device recognition layer, such as snake-geometry resistors. (2) The use of contact type "xpc" in the sky130 tech file as its own contact residue caused the contact tracing in extresist to fail. I opted to keep the unorthodox contact description in the tech file and wrote an extension to a routine in extresist to handle the case.
This commit is contained in:
parent
038f02d2b2
commit
814fb6f18d
203
resis/ResMain.c
203
resis/ResMain.c
|
|
@ -66,23 +66,31 @@ extern HashTable ResNodeTable;
|
||||||
void
|
void
|
||||||
ResInitializeConn()
|
ResInitializeConn()
|
||||||
{
|
{
|
||||||
TileType dev, diff;
|
TileType dev, ttype;
|
||||||
char *dev_name;
|
char *dev_name;
|
||||||
|
int i;
|
||||||
ExtDevice *devptr;
|
ExtDevice *devptr;
|
||||||
|
|
||||||
for (dev = TT_TECHDEPBASE; dev < TT_MAXTYPES; dev++)
|
for (dev = TT_TECHDEPBASE; dev < TT_MAXTYPES; dev++)
|
||||||
{
|
{
|
||||||
devptr = ExtCurStyle->exts_device[dev];
|
for (devptr = ExtCurStyle->exts_device[dev]; devptr; devptr = devptr->exts_next)
|
||||||
|
{
|
||||||
if ((devptr != NULL) && ((dev_name = devptr->exts_deviceName) != NULL)
|
if ((devptr != NULL) && ((dev_name = devptr->exts_deviceName) != NULL)
|
||||||
&& (strcmp(dev_name, "None")))
|
&& (strcmp(dev_name, "None")))
|
||||||
{
|
{
|
||||||
for (diff = TT_TECHDEPBASE; diff < TT_MAXTYPES; diff++)
|
for (ttype = TT_TECHDEPBASE; ttype < TT_MAXTYPES; ttype++)
|
||||||
{
|
{
|
||||||
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), diff)
|
for (i = 0; ; i++)
|
||||||
TTMaskSetType(&ResConnectWithSD[diff], dev);
|
{
|
||||||
|
if (TTMaskIsZero(&(devptr->exts_deviceSDTypes[i])))
|
||||||
|
break;
|
||||||
|
if TTMaskHasType(&(devptr->exts_deviceSDTypes[i]), ttype)
|
||||||
|
TTMaskSetType(&ResConnectWithSD[ttype], dev);
|
||||||
|
}
|
||||||
|
|
||||||
if TTMaskHasType(&(devptr->exts_deviceSubstrateTypes), diff)
|
if TTMaskHasType(&(devptr->exts_deviceSubstrateTypes), ttype)
|
||||||
TTMaskSetType(&ResConnectWithSD[diff], dev);
|
TTMaskSetType(&ResConnectWithSD[ttype], dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TTMaskSetMask(&ResConnectWithSD[dev], &DBConnectTbl[dev]);
|
TTMaskSetMask(&ResConnectWithSD[dev], &DBConnectTbl[dev]);
|
||||||
|
|
@ -410,6 +418,7 @@ ResFindNewContactTiles(contacts)
|
||||||
TxError("Error: setting contact tile to null\n");
|
TxError("Error: setting contact tile to null\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((IsSplit(tile) && TTMaskHasType(&mask, TiGetRightType(tile)))
|
if ((IsSplit(tile) && TTMaskHasType(&mask, TiGetRightType(tile)))
|
||||||
|| TTMaskHasType(&mask, TiGetType(tile)))
|
|| TTMaskHasType(&mask, TiGetType(tile)))
|
||||||
{
|
{
|
||||||
|
|
@ -423,6 +432,30 @@ ResFindNewContactTiles(contacts)
|
||||||
(contacts->cp_currentcontact) += 1;
|
(contacts->cp_currentcontact) += 1;
|
||||||
j->contactList = ce;
|
j->contactList = ce;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TileType ttype = TiGetTypeExact(tile);
|
||||||
|
if (DBIsContact(ttype))
|
||||||
|
{
|
||||||
|
/* Handle the exceptional case in which a contact
|
||||||
|
* type is its own residue. This can be used for
|
||||||
|
* devices whose terminals are always a contact
|
||||||
|
* and for which a non-contact type cannot be drawn.
|
||||||
|
*/
|
||||||
|
if (TTMaskIntersect(DBResidueMask(ttype), &mask))
|
||||||
|
{
|
||||||
|
tileJunk *j = (tileJunk *)tile->ti_client;
|
||||||
|
cElement *ce;
|
||||||
|
|
||||||
|
ce = (cElement *) mallocMagic((unsigned) (sizeof(cElement)));
|
||||||
|
contacts->cp_tile[contacts->cp_currentcontact] = tile;
|
||||||
|
ce->ce_thisc = contacts;
|
||||||
|
ce->ce_nextc = j->contactList;
|
||||||
|
(contacts->cp_currentcontact) += 1;
|
||||||
|
j->contactList = ce;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef PARANOID
|
#ifdef PARANOID
|
||||||
if (contacts->cp_currentcontact >= LAYERS_PER_CONTACT)
|
if (contacts->cp_currentcontact >= LAYERS_PER_CONTACT)
|
||||||
|
|
@ -1289,6 +1322,8 @@ FindStartTile(goodies, SourcePoint)
|
||||||
int pnum, t1, t2, i;
|
int pnum, t1, t2, i;
|
||||||
ExtDevice *devptr;
|
ExtDevice *devptr;
|
||||||
Rect r;
|
Rect r;
|
||||||
|
bool complex;
|
||||||
|
static Stack *devStack = NULL;
|
||||||
|
|
||||||
/* If the drive point is on a contact, check for the contact residues */
|
/* If the drive point is on a contact, check for the contact residues */
|
||||||
/* first, then the contact type itself. */
|
/* first, then the contact type itself. */
|
||||||
|
|
@ -1391,6 +1426,8 @@ FindStartTile(goodies, SourcePoint)
|
||||||
{
|
{
|
||||||
for (i = 0; i < devptr->exts_deviceSDCount; i++)
|
for (i = 0; i < devptr->exts_deviceSDCount; i++)
|
||||||
{
|
{
|
||||||
|
complex = FALSE; /* Assume device is a single tile */
|
||||||
|
|
||||||
/* left */
|
/* left */
|
||||||
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp))
|
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp))
|
||||||
{
|
{
|
||||||
|
|
@ -1403,6 +1440,9 @@ FindStartTile(goodies, SourcePoint)
|
||||||
MAX(BOTTOM(tile), BOTTOM(tp))) >> 1;
|
MAX(BOTTOM(tile), BOTTOM(tp))) >> 1;
|
||||||
return(tp);
|
return(tp);
|
||||||
}
|
}
|
||||||
|
else if (tp->ti_client != CLIENTDEFAULT)
|
||||||
|
if (((tileJunk *)tp->ti_client)->tj_status & RES_TILE_DEV)
|
||||||
|
complex = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* right */
|
/* right */
|
||||||
|
|
@ -1417,6 +1457,9 @@ FindStartTile(goodies, SourcePoint)
|
||||||
MAX(BOTTOM(tile), BOTTOM(tp))) >> 1;
|
MAX(BOTTOM(tile), BOTTOM(tp))) >> 1;
|
||||||
return(tp);
|
return(tp);
|
||||||
}
|
}
|
||||||
|
else if (tp->ti_client != CLIENTDEFAULT)
|
||||||
|
if (((tileJunk *)tp->ti_client)->tj_status & RES_TILE_DEV)
|
||||||
|
complex = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* top */
|
/* top */
|
||||||
|
|
@ -1431,6 +1474,9 @@ FindStartTile(goodies, SourcePoint)
|
||||||
MAX(LEFT(tile), LEFT(tp))) >> 1;
|
MAX(LEFT(tile), LEFT(tp))) >> 1;
|
||||||
return(tp);
|
return(tp);
|
||||||
}
|
}
|
||||||
|
else if (tp->ti_client != CLIENTDEFAULT)
|
||||||
|
if (((tileJunk *)tp->ti_client)->tj_status & RES_TILE_DEV)
|
||||||
|
complex = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bottom */
|
/* bottom */
|
||||||
|
|
@ -1445,6 +1491,149 @@ FindStartTile(goodies, SourcePoint)
|
||||||
MAX(LEFT(tile), LEFT(tp))) >> 1;
|
MAX(LEFT(tile), LEFT(tp))) >> 1;
|
||||||
return(tp);
|
return(tp);
|
||||||
}
|
}
|
||||||
|
else if (tp->ti_client != CLIENTDEFAULT)
|
||||||
|
if (((tileJunk *)tp->ti_client)->tj_status & RES_TILE_DEV)
|
||||||
|
complex = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (complex == TRUE)
|
||||||
|
{
|
||||||
|
/* Didn't find a terminal but device has multiple */
|
||||||
|
/* tiles, so make a secondary search looking at all */
|
||||||
|
/* tiles of the device. */
|
||||||
|
|
||||||
|
if (devStack == NULL) devStack = StackNew(8);
|
||||||
|
|
||||||
|
((tileJunk *)tile->ti_client)->tj_status |= RES_TILE_PUSHED;
|
||||||
|
STACKPUSH((ClientData)tile, devStack);
|
||||||
|
while (!StackEmpty(devStack))
|
||||||
|
{
|
||||||
|
tile = (Tile *)STACKPOP(devStack);
|
||||||
|
|
||||||
|
/* left */
|
||||||
|
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(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;
|
||||||
|
while (!StackEmpty(devStack))
|
||||||
|
{
|
||||||
|
STACKPOP(devStack);
|
||||||
|
}
|
||||||
|
return(tp);
|
||||||
|
}
|
||||||
|
else if (tp->ti_client != CLIENTDEFAULT)
|
||||||
|
{
|
||||||
|
if (((tileJunk *)tp->ti_client)->tj_status & RES_TILE_DEV)
|
||||||
|
{
|
||||||
|
if (!(((tileJunk *)tp->ti_client)->tj_status
|
||||||
|
& RES_TILE_PUSHED))
|
||||||
|
{
|
||||||
|
((tileJunk *)tp->ti_client)->tj_status
|
||||||
|
|= RES_TILE_PUSHED;
|
||||||
|
STACKPUSH((ClientData)tp, devStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* right */
|
||||||
|
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(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;
|
||||||
|
while (!StackEmpty(devStack))
|
||||||
|
{
|
||||||
|
STACKPOP(devStack);
|
||||||
|
}
|
||||||
|
return(tp);
|
||||||
|
}
|
||||||
|
else if (tp->ti_client != CLIENTDEFAULT)
|
||||||
|
{
|
||||||
|
if (((tileJunk *)tp->ti_client)->tj_status & RES_TILE_DEV)
|
||||||
|
{
|
||||||
|
if (!(((tileJunk *)tp->ti_client)->tj_status
|
||||||
|
& RES_TILE_PUSHED))
|
||||||
|
{
|
||||||
|
((tileJunk *)tp->ti_client)->tj_status
|
||||||
|
|= RES_TILE_PUSHED;
|
||||||
|
STACKPUSH((ClientData)tp, devStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
while (!StackEmpty(devStack))
|
||||||
|
{
|
||||||
|
STACKPOP(devStack);
|
||||||
|
}
|
||||||
|
return(tp);
|
||||||
|
}
|
||||||
|
else if (tp->ti_client != CLIENTDEFAULT)
|
||||||
|
{
|
||||||
|
if (((tileJunk *)tp->ti_client)->tj_status & RES_TILE_DEV)
|
||||||
|
{
|
||||||
|
if (!(((tileJunk *)tp->ti_client)->tj_status
|
||||||
|
& RES_TILE_PUSHED))
|
||||||
|
{
|
||||||
|
((tileJunk *)tp->ti_client)->tj_status
|
||||||
|
|= RES_TILE_PUSHED;
|
||||||
|
STACKPUSH((ClientData)tp, devStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
while (!StackEmpty(devStack))
|
||||||
|
{
|
||||||
|
STACKPOP(devStack);
|
||||||
|
}
|
||||||
|
return(tp);
|
||||||
|
}
|
||||||
|
else if (tp->ti_client != CLIENTDEFAULT)
|
||||||
|
{
|
||||||
|
if (((tileJunk *)tp->ti_client)->tj_status & RES_TILE_DEV)
|
||||||
|
{
|
||||||
|
if (!(((tileJunk *)tp->ti_client)->tj_status
|
||||||
|
& RES_TILE_PUSHED))
|
||||||
|
{
|
||||||
|
((tileJunk *)tp->ti_client)->tj_status
|
||||||
|
|= RES_TILE_PUSHED;
|
||||||
|
STACKPUSH((ClientData)tp, devStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -445,6 +445,16 @@ ResAddPlumbing(tile, arg)
|
||||||
Junk->deviceList = resDev;
|
Junk->deviceList = resDev;
|
||||||
Junk->tj_status |= RES_TILE_DEV;
|
Junk->tj_status |= RES_TILE_DEV;
|
||||||
|
|
||||||
|
/* Update device position to point to the lower-leftmost tile */
|
||||||
|
if ((tp2->ti_ll.p_x < resDev->rd_inside.r_ll.p_x) ||
|
||||||
|
((tp2->ti_ll.p_x == resDev->rd_inside.r_ll.p_x) &&
|
||||||
|
(tp2->ti_ll.p_y < resDev->rd_inside.r_ll.p_y)))
|
||||||
|
{
|
||||||
|
resDev->rd_inside.r_ll.p_x = LEFT(tp2);
|
||||||
|
resDev->rd_inside.r_ll.p_y = BOTTOM(tp2);
|
||||||
|
resDev->rd_inside.r_ur.p_x = RIGHT(tp2);
|
||||||
|
resDev->rd_inside.r_ur.p_y = TOP(tp2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||||
TiGetBottomType(tp2))
|
TiGetBottomType(tp2))
|
||||||
|
|
@ -464,6 +474,17 @@ ResAddPlumbing(tile, arg)
|
||||||
STACKPUSH((ClientData)tp2, resDevStack);
|
STACKPUSH((ClientData)tp2, resDevStack);
|
||||||
Junk->deviceList = resDev;
|
Junk->deviceList = resDev;
|
||||||
Junk->tj_status |= RES_TILE_DEV;
|
Junk->tj_status |= RES_TILE_DEV;
|
||||||
|
|
||||||
|
/* Update device position to point to the lower-leftmost tile */
|
||||||
|
if ((tp2->ti_ll.p_x < resDev->rd_inside.r_ll.p_x) ||
|
||||||
|
((tp2->ti_ll.p_x == resDev->rd_inside.r_ll.p_x) &&
|
||||||
|
(tp2->ti_ll.p_y < resDev->rd_inside.r_ll.p_y)))
|
||||||
|
{
|
||||||
|
resDev->rd_inside.r_ll.p_x = LEFT(tp2);
|
||||||
|
resDev->rd_inside.r_ll.p_y = BOTTOM(tp2);
|
||||||
|
resDev->rd_inside.r_ur.p_x = RIGHT(tp2);
|
||||||
|
resDev->rd_inside.r_ur.p_y = TOP(tp2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||||
TiGetTopType(tp2))
|
TiGetTopType(tp2))
|
||||||
|
|
@ -483,6 +504,17 @@ ResAddPlumbing(tile, arg)
|
||||||
STACKPUSH((ClientData)tp2, resDevStack);
|
STACKPUSH((ClientData)tp2, resDevStack);
|
||||||
Junk->deviceList = resDev;
|
Junk->deviceList = resDev;
|
||||||
Junk->tj_status |= RES_TILE_DEV;
|
Junk->tj_status |= RES_TILE_DEV;
|
||||||
|
|
||||||
|
/* Update device position to point to the lower-leftmost tile */
|
||||||
|
if ((tp2->ti_ll.p_x < resDev->rd_inside.r_ll.p_x) ||
|
||||||
|
((tp2->ti_ll.p_x == resDev->rd_inside.r_ll.p_x) &&
|
||||||
|
(tp2->ti_ll.p_y < resDev->rd_inside.r_ll.p_y)))
|
||||||
|
{
|
||||||
|
resDev->rd_inside.r_ll.p_x = LEFT(tp2);
|
||||||
|
resDev->rd_inside.r_ll.p_y = BOTTOM(tp2);
|
||||||
|
resDev->rd_inside.r_ur.p_x = RIGHT(tp2);
|
||||||
|
resDev->rd_inside.r_ur.p_y = TOP(tp2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||||
TiGetLeftType(tp2))
|
TiGetLeftType(tp2))
|
||||||
|
|
@ -502,6 +534,17 @@ ResAddPlumbing(tile, arg)
|
||||||
STACKPUSH((ClientData)tp2, resDevStack);
|
STACKPUSH((ClientData)tp2, resDevStack);
|
||||||
Junk->deviceList = resDev;
|
Junk->deviceList = resDev;
|
||||||
Junk->tj_status |= RES_TILE_DEV;
|
Junk->tj_status |= RES_TILE_DEV;
|
||||||
|
|
||||||
|
/* Update device position to point to the lower-leftmost tile */
|
||||||
|
if ((tp2->ti_ll.p_x < resDev->rd_inside.r_ll.p_x) ||
|
||||||
|
((tp2->ti_ll.p_x == resDev->rd_inside.r_ll.p_x) &&
|
||||||
|
(tp2->ti_ll.p_y < resDev->rd_inside.r_ll.p_y)))
|
||||||
|
{
|
||||||
|
resDev->rd_inside.r_ll.p_x = LEFT(tp2);
|
||||||
|
resDev->rd_inside.r_ll.p_y = BOTTOM(tp2);
|
||||||
|
resDev->rd_inside.r_ur.p_x = RIGHT(tp2);
|
||||||
|
resDev->rd_inside.r_ur.p_y = TOP(tp2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||||
TiGetRightType(tp2))
|
TiGetRightType(tp2))
|
||||||
|
|
|
||||||
|
|
@ -471,10 +471,12 @@ typedef struct capval
|
||||||
#define RES_TILE_DONE 0x08
|
#define RES_TILE_DONE 0x08
|
||||||
/*a temporary marking flag */
|
/*a temporary marking flag */
|
||||||
#define RES_TILE_MARK 0x10
|
#define RES_TILE_MARK 0x10
|
||||||
|
/*another temporary marking flag */
|
||||||
|
#define RES_TILE_PUSHED 0x20
|
||||||
/* indicates that tile has unidirectional current flow */
|
/* indicates that tile has unidirectional current flow */
|
||||||
#ifdef LAPLACE
|
#ifdef LAPLACE
|
||||||
#define RES_TILE_1D 0x20
|
#define RES_TILE_1D 0x40
|
||||||
#define RES_TILE_GDONE 0x40
|
#define RES_TILE_GDONE 0x80
|
||||||
#endif
|
#endif
|
||||||
/* tree walking flags */
|
/* tree walking flags */
|
||||||
#define RES_LOOP_OK 1
|
#define RES_LOOP_OK 1
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue