Corrected an issue that was caused by early work on extresist:
The original version of extresist only worked with 4-terminal FET devices, and handling of devices with fewer terminals was ignored, and never properly dealt with. This commit fixes the issues with devices such as diodes that have fewer terminals.
This commit is contained in:
parent
d8580be739
commit
d9e6c78adb
|
|
@ -48,7 +48,7 @@ ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
|
|||
int xj, yj, direction;
|
||||
resNode **PendingList;
|
||||
{
|
||||
resNode *resptr;
|
||||
resNode *resptr = NULL;
|
||||
resDevice *resDev;
|
||||
tElement *tcell;
|
||||
int newnode;
|
||||
|
|
@ -64,7 +64,8 @@ ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
|
|||
|
||||
ri = (resInfo *) TiGetClientPTR(tp);
|
||||
resDev = ri->deviceList;
|
||||
if ((ri->sourceEdge & direction) != 0)
|
||||
if ((((ri->sourceEdge & direction) != 0) && (resDev->rd_nterms == 4))
|
||||
|| (resDev->rd_nterms > 2))
|
||||
{
|
||||
if (resDev->rd_fet_source == (resNode *) NULL)
|
||||
{
|
||||
|
|
@ -73,11 +74,9 @@ ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
|
|||
resDev->rd_fet_source = resptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
resptr = resDev->rd_fet_source;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (resDev->rd_nterms > 3)
|
||||
{
|
||||
if (resDev->rd_fet_drain == (resNode *) NULL)
|
||||
{
|
||||
|
|
@ -86,9 +85,7 @@ ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
|
|||
resDev->rd_fet_drain = resptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
resptr = resDev->rd_fet_drain;
|
||||
}
|
||||
}
|
||||
if (newnode)
|
||||
{
|
||||
|
|
@ -99,7 +96,10 @@ ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
|
|||
resptr->rn_te = tcell;
|
||||
ResAddToQueue(resptr, PendingList);
|
||||
}
|
||||
NEWBREAK(resptr, tile, xj, yj, NULL);
|
||||
if (resptr != NULL)
|
||||
{
|
||||
NEWBREAK(resptr, tile, xj, yj, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -131,20 +131,14 @@ ResNewSubDevice(tile, tp, xj, yj, direction, PendingList)
|
|||
ri = (resInfo *) TiGetClientPTR(tp);
|
||||
resDev = ri->deviceList;
|
||||
|
||||
/* Arrived at a device that has a terminal connected to substrate */
|
||||
/* that is not a FET bulk terminal (e.g., varactor, diode). */
|
||||
if (resDev->rd_nterms < 4) return;
|
||||
|
||||
if (resDev->rd_fet_subs == (resNode *) NULL)
|
||||
if (resDev->rd_fet_subs == (resNode *)NULL)
|
||||
{
|
||||
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
|
||||
newnode = TRUE;
|
||||
resDev->rd_fet_subs = resptr;
|
||||
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
|
||||
newnode = TRUE;
|
||||
resDev->rd_fet_subs = resptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
resptr = resDev->rd_fet_subs;
|
||||
}
|
||||
resptr = resDev->rd_fet_subs;
|
||||
|
||||
if (newnode)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -76,10 +76,9 @@ ResCalcTileResistance(tile, info, pendingList, doneList)
|
|||
if (x < MinX) MinX = x;
|
||||
if (y > MaxY) MaxY = y;
|
||||
if (y < MinY) MinY = y;
|
||||
|
||||
if (p1->br_this->rn_why == RES_NODE_DEVICE)
|
||||
{
|
||||
device = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, produce resistors for partition. Keep track of */
|
||||
|
|
@ -248,7 +247,7 @@ ResCalcEastWest(tile, pendingList, doneList, resList)
|
|||
}
|
||||
else
|
||||
{
|
||||
p3 = p2->br_next;
|
||||
p3 = p2->br_next;
|
||||
while (p3 != NULL)
|
||||
{
|
||||
if (p3->br_this == currNode)
|
||||
|
|
@ -413,32 +412,32 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
|
|||
{
|
||||
if (p2->br_this == p1->br_this)
|
||||
{
|
||||
currNode = NULL;
|
||||
p1->br_next = p2->br_next;
|
||||
freeMagic((char *)p2);
|
||||
p2 = p1;
|
||||
currNode = NULL;
|
||||
p1->br_next = p2->br_next;
|
||||
freeMagic((char *)p2);
|
||||
p2 = p1;
|
||||
}
|
||||
else if (p2->br_this == resCurrentNode)
|
||||
{
|
||||
currNode = p1->br_this;
|
||||
ResMergeNodes(p2->br_this, p1->br_this, pendingList, doneList);
|
||||
freeMagic((char *)p1);
|
||||
merged = TRUE;
|
||||
currNode = p1->br_this;
|
||||
ResMergeNodes(p2->br_this, p1->br_this, pendingList, doneList);
|
||||
freeMagic((char *)p1);
|
||||
merged = TRUE;
|
||||
}
|
||||
else if (p1->br_this == resCurrentNode)
|
||||
{
|
||||
currNode = p2->br_this;
|
||||
p1->br_next = p2->br_next;
|
||||
ResMergeNodes(p1->br_this, p2->br_this, pendingList, doneList);
|
||||
merged = TRUE;
|
||||
freeMagic((char *)p2);
|
||||
p2 = p1;
|
||||
currNode = p2->br_this;
|
||||
p1->br_next = p2->br_next;
|
||||
ResMergeNodes(p1->br_this, p2->br_this, pendingList, doneList);
|
||||
merged = TRUE;
|
||||
freeMagic((char *)p2);
|
||||
p2 = p1;
|
||||
}
|
||||
else
|
||||
{
|
||||
currNode = p1->br_this;
|
||||
ResMergeNodes(p2->br_this, p1->br_this, pendingList, doneList);
|
||||
freeMagic((char *)p1);
|
||||
currNode = p1->br_this;
|
||||
ResMergeNodes(p2->br_this, p1->br_this, pendingList, doneList);
|
||||
freeMagic((char *)p1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -559,7 +558,7 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
|||
* breakpoint, then return.
|
||||
*/
|
||||
|
||||
if (info->breakList->br_next == NULL)
|
||||
if (info->breakList->br_next == NULL)
|
||||
{
|
||||
freeMagic((char *)info->breakList);
|
||||
info->breakList = NULL;
|
||||
|
|
|
|||
|
|
@ -839,9 +839,9 @@ ResTriangleCheck(resptr)
|
|||
*
|
||||
* ResMergeNodes--
|
||||
*
|
||||
* results: none
|
||||
* Results: none
|
||||
*
|
||||
* side effects: appends all the cElement, jElement, tElement and
|
||||
* Side Effects: appends all the cElement, jElement, tElement and
|
||||
* resElement structures from node 2 onto node 1. Node 2 is
|
||||
* then eliminated.
|
||||
*
|
||||
|
|
@ -1010,7 +1010,7 @@ ResMergeNodes(node1, node2, pendingList, doneList)
|
|||
* ResDeleteResPointer-- Deletes the pointer from a node to a resistor.
|
||||
* Used when a resistor is deleted.
|
||||
*
|
||||
* Results:none
|
||||
* Results: none
|
||||
*
|
||||
* Side Effects: Modifies a node's resistor list.
|
||||
*
|
||||
|
|
@ -1018,7 +1018,7 @@ ResMergeNodes(node1, node2, pendingList, doneList)
|
|||
*/
|
||||
|
||||
void
|
||||
ResDeleteResPointer(node,resistor)
|
||||
ResDeleteResPointer(node, resistor)
|
||||
resNode *node;
|
||||
resResistor *resistor;
|
||||
|
||||
|
|
@ -1059,7 +1059,7 @@ ResDeleteResPointer(node,resistor)
|
|||
*
|
||||
* ResEliminateResistor--
|
||||
*
|
||||
* Results:none
|
||||
* Results: none
|
||||
*
|
||||
* Side Effects: Deletes a resistor. Does not delete pointers from nodes to
|
||||
* resistor.
|
||||
|
|
@ -1097,8 +1097,7 @@ ResEliminateResistor(resistor, homelist)
|
|||
* they are no longer needed. If the 'info' option is used,
|
||||
* the node is eradicated.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
* Results: none.
|
||||
*
|
||||
* Side Effects: frees memory
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1356,7 +1356,7 @@ ResFixUpConnections(extDev, layoutDev, extNode, nodename)
|
|||
}
|
||||
if (extDev->subs == extNode)
|
||||
{
|
||||
if ((layoutDev->rd_nterms >= 4) && ((subs = layoutDev->rd_fet_subs) != NULL))
|
||||
if ((subs = layoutDev->rd_fet_subs) != NULL)
|
||||
{
|
||||
if (subs->rn_name != NULL && notdecremented)
|
||||
{
|
||||
|
|
@ -1422,7 +1422,7 @@ ResFixUpConnections(extDev, layoutDev, extNode, nodename)
|
|||
extNode->status |= DONTKILL;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (layoutDev->rd_nterms > 3)
|
||||
{
|
||||
if ((source = layoutDev->rd_fet_source) != NULL)
|
||||
{
|
||||
|
|
@ -1469,7 +1469,7 @@ ResFixUpConnections(extDev, layoutDev, extNode, nodename)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (extDev->drain == extNode)
|
||||
else if ((extDev->drain == extNode) && (layoutDev->rd_nterms > 3))
|
||||
{
|
||||
/* Check for devices with only one terminal. If it was cast as source, */
|
||||
/* then swap it with the drain so that the code below handles it */
|
||||
|
|
|
|||
|
|
@ -387,7 +387,7 @@ ResMoveDevices(node1, node2)
|
|||
devptr = devptr->te_nextt;
|
||||
if (device->rd_fet_gate == node1)
|
||||
device->rd_fet_gate = node2;
|
||||
else if ((device->rd_nterms >= 4) && (device->rd_fet_subs == node1))
|
||||
else if (device->rd_fet_subs == node1)
|
||||
device->rd_fet_subs = node2;
|
||||
else if (device->rd_fet_source == node1)
|
||||
device->rd_fet_source = node2;
|
||||
|
|
|
|||
|
|
@ -231,7 +231,8 @@ ResAddPlumbing(tile, dinfo, arg)
|
|||
|
||||
resDev = (resDevice *)mallocMagic((unsigned)(sizeof(resDevice)));
|
||||
resDev->rd_nterms = nterms;
|
||||
resDev->rd_terminals = (resNode **) mallocMagic(nterms * sizeof(resNode *));
|
||||
|
||||
resDev->rd_terminals = (resNode **)mallocMagic(nterms * sizeof(resNode *));
|
||||
for (i = 0; i != nterms; i++)
|
||||
resDev->rd_terminals[i] = (resNode *) NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -51,16 +51,24 @@ typedef struct resistor
|
|||
#define rr_connection1 rr_node[0]
|
||||
#define rr_connection2 rr_node[1]
|
||||
|
||||
/* Definitions for old FET-style MOSFET devices */
|
||||
/* Definitions for old FET-style MOSFET devices. Actual devices may have
|
||||
* any number of terminals. "GATE" is the identifying type; "SUBS" is
|
||||
* the substrate/well connection (if it exists), and the other terminals
|
||||
* make up the remaining entries. Memory will be allocated for the
|
||||
* substrate whether or not one is defined for the device. If the device
|
||||
* does not define a substrate connection, then this entry will remain
|
||||
* NULL.
|
||||
*/
|
||||
|
||||
#define RT_GATE 0
|
||||
#define RT_SOURCE 1
|
||||
#define RT_DRAIN 2
|
||||
#define RT_SUBS 3
|
||||
#define RT_SUBS 1
|
||||
#define RT_SOURCE 2
|
||||
#define RT_DRAIN 3
|
||||
|
||||
#define rd_fet_gate rd_terminals[RT_GATE]
|
||||
#define rd_fet_subs rd_terminals[RT_SUBS]
|
||||
#define rd_fet_source rd_terminals[RT_SOURCE]
|
||||
#define rd_fet_drain rd_terminals[RT_DRAIN]
|
||||
#define rd_fet_subs rd_terminals[RT_SUBS]
|
||||
|
||||
typedef struct device
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue