Merge branch 'master' into magic-8.2
This commit is contained in:
commit
bc694cea43
75
cif/CIFgen.c
75
cif/CIFgen.c
|
|
@ -842,10 +842,21 @@ endbloat:
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define CIF_PENDING 0
|
||||
#define CIF_UNPROCESSED CLIENTDEFAULT
|
||||
#define CIF_PROCESSED 1
|
||||
#define CIF_IGNORE 2
|
||||
|
||||
#define PUSHTILE(tp, stack) \
|
||||
if ((tp)->ti_client == (ClientData) CIF_UNPROCESSED) { \
|
||||
(tp)->ti_client = (ClientData) CIF_PENDING; \
|
||||
STACKPUSH((ClientData) (tp), stack); \
|
||||
}
|
||||
|
||||
/*
|
||||
*-------------------------------------------------------
|
||||
*
|
||||
* cifFoundFun --
|
||||
* cifFoundFunc --
|
||||
*
|
||||
* Find the first tile in the given area.
|
||||
*
|
||||
|
|
@ -857,12 +868,12 @@ endbloat:
|
|||
*/
|
||||
|
||||
int
|
||||
cifFoundFunc(tile, treturn)
|
||||
cifFoundFunc(tile, BloatStackPtr)
|
||||
Tile *tile;
|
||||
Tile **treturn;
|
||||
Stack **BloatStackPtr;
|
||||
{
|
||||
*treturn = tile;
|
||||
return 1;
|
||||
PUSHTILE(tile, *BloatStackPtr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Data structure for bloat-all function */
|
||||
|
|
@ -890,17 +901,6 @@ typedef struct _bloatStruct {
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define CIF_PENDING 0
|
||||
#define CIF_UNPROCESSED CLIENTDEFAULT
|
||||
#define CIF_PROCESSED 1
|
||||
#define CIF_IGNORE 2
|
||||
|
||||
#define PUSHTILE(tp, stack) \
|
||||
if ((tp)->ti_client == (ClientData) CIF_UNPROCESSED) { \
|
||||
(tp)->ti_client = (ClientData) CIF_PENDING; \
|
||||
STACKPUSH((ClientData) (tp), stack); \
|
||||
}
|
||||
|
||||
int
|
||||
cifBloatAllFunc(tile, bls)
|
||||
Tile *tile; /* The tile to be processed. */
|
||||
|
|
@ -911,9 +911,8 @@ cifBloatAllFunc(tile, bls)
|
|||
Tile *t, *tp;
|
||||
TileType type;
|
||||
BloatData *bloats;
|
||||
int i;
|
||||
int i, locScale;
|
||||
PlaneMask pmask;
|
||||
int pNum;
|
||||
CIFOp *op;
|
||||
CellDef *def;
|
||||
static Stack *BloatStack = (Stack *)NULL;
|
||||
|
|
@ -944,17 +943,31 @@ cifBloatAllFunc(tile, bls)
|
|||
|
||||
t = tile;
|
||||
type = TiGetType(tile);
|
||||
pNum = DBPlane(type);
|
||||
pmask = CoincidentPlanes(&connect, PlaneNumToMaskBit(pNum));
|
||||
if (pmask == 0)
|
||||
if (type == CIF_SOLIDTYPE)
|
||||
{
|
||||
TiToRect(tile, &area);
|
||||
if (DBSrPaintArea((Tile *)NULL, def->cd_planes[bloats->bl_plane], &area,
|
||||
&connect, cifFoundFunc, (ClientData)(&t)) == 0)
|
||||
return 0; /* Nothing found here */
|
||||
}
|
||||
pmask = 0;
|
||||
locScale = (CIFCurStyle) ? CIFCurStyle->cs_scaleFactor : 1;
|
||||
|
||||
/* Get the tile into magic database coordinates if it's in CIF coords */
|
||||
TiToRect(tile, &area);
|
||||
area.r_xbot /= locScale;
|
||||
area.r_xtop /= locScale;
|
||||
area.r_ybot /= locScale;
|
||||
area.r_ytop /= locScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
int pNum = DBPlane(type);
|
||||
pmask = CoincidentPlanes(&connect, PlaneNumToMaskBit(pNum));
|
||||
if (pmask == 0) TiToRect(tile, &area);
|
||||
locScale = cifScale;
|
||||
}
|
||||
if (pmask == 0)
|
||||
DBSrPaintArea((Tile *)NULL, def->cd_planes[bloats->bl_plane], &area,
|
||||
&connect, cifFoundFunc, (ClientData)(&BloatStack));
|
||||
else
|
||||
PUSHTILE(t, BloatStack);
|
||||
|
||||
PUSHTILE(t, BloatStack);
|
||||
while (!StackEmpty(BloatStack))
|
||||
{
|
||||
t = (Tile *) STACKPOP(BloatStack);
|
||||
|
|
@ -964,10 +977,10 @@ cifBloatAllFunc(tile, bls)
|
|||
/* Get the tile into CIF coordinates. */
|
||||
|
||||
TiToRect(t, &area);
|
||||
area.r_xbot *= cifScale;
|
||||
area.r_ybot *= cifScale;
|
||||
area.r_xtop *= cifScale;
|
||||
area.r_ytop *= cifScale;
|
||||
area.r_xbot *= locScale;
|
||||
area.r_ybot *= locScale;
|
||||
area.r_xtop *= locScale;
|
||||
area.r_ytop *= locScale;
|
||||
|
||||
DBNMPaintPlane(cifPlane, TiGetTypeExact(t), &area,
|
||||
CIFPaintTable, (PaintUndoInfo *) NULL);
|
||||
|
|
|
|||
|
|
@ -1080,7 +1080,7 @@ CIFTechLine(sectionName, argc, argv)
|
|||
case CIFOP_BLOATALL:
|
||||
if (argc != 3) goto wrongNumArgs;
|
||||
cifParseLayers(argv[1], CIFCurStyle, &newOp->co_paintMask,
|
||||
(TileTypeBitMask *)NULL, FALSE);
|
||||
&newOp->co_cifMask, FALSE);
|
||||
bloats = (BloatData *)mallocMagic(sizeof(BloatData));
|
||||
for (i = 0; i < TT_MAXTYPES; i++)
|
||||
bloats->bl_distance[i] = 0;
|
||||
|
|
|
|||
|
|
@ -1882,8 +1882,16 @@ printPropertiesFunc(name, value)
|
|||
#ifdef MAGIC_WRAPPER
|
||||
char *keyvalue;
|
||||
|
||||
keyvalue = (char *)mallocMagic(strlen(name) + strlen((char *)value) + 2);
|
||||
sprintf(keyvalue, "%s %s", name, (char *)value);
|
||||
if (value == NULL)
|
||||
{
|
||||
keyvalue = (char *)mallocMagic(strlen(name) + 4);
|
||||
sprintf(keyvalue, "%s {}", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
keyvalue = (char *)mallocMagic(strlen(name) + strlen((char *)value) + 2);
|
||||
sprintf(keyvalue, "%s %s", name, (char *)value);
|
||||
}
|
||||
Tcl_AppendElement(magicinterp, keyvalue);
|
||||
freeMagic(keyvalue);
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,10 @@ DBPropPut(cellDef, name, value)
|
|||
entry = HashFind(htab, name);
|
||||
oldvalue = (char *)HashGetValue(entry);
|
||||
if (oldvalue != NULL) freeMagic(oldvalue);
|
||||
HashSetValue(entry, value);
|
||||
if (value == (ClientData)NULL)
|
||||
HashRemove(htab, name);
|
||||
else
|
||||
HashSetValue(entry, value);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1225,14 +1225,14 @@ efBuildResistor(def, nodeName1, nodeName2, resistance)
|
|||
Def *def; /* Def to which this connection is to be added */
|
||||
char *nodeName1; /* Name of first node in resistor */
|
||||
char *nodeName2; /* Name of second node in resistor */
|
||||
float resistance; /* Resistor value */
|
||||
int resistance; /* Resistor value */
|
||||
{
|
||||
Connection *conn;
|
||||
|
||||
conn = (Connection *) mallocMagic((unsigned)(sizeof (Connection)));
|
||||
if (efConnInitSubs(conn, nodeName1, nodeName2))
|
||||
{
|
||||
conn->conn_res = resistance;
|
||||
conn->conn_res = (float)resistance;
|
||||
conn->conn_next = def->def_resistors;
|
||||
def->def_resistors = conn;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -426,10 +426,8 @@ readfile:
|
|||
/* port name num xl yl xh yh type */
|
||||
case PORT:
|
||||
if (DoSubCircuit)
|
||||
{
|
||||
DoResist = FALSE;
|
||||
def->def_flags |= DEF_SUBCIRCUIT;
|
||||
}
|
||||
|
||||
efBuildPortNode(def, argv[1], atoi(argv[2]), atoi(argv[3]),
|
||||
atoi(argv[4]), argv[7], toplevel);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "textio/txcommands.h"
|
||||
#include "resis/resis.h"
|
||||
|
||||
int resSubTranFunc();
|
||||
int resSubDevFunc();
|
||||
|
||||
/*
|
||||
*--------------------------------------------------------------------------
|
||||
|
|
@ -113,13 +113,13 @@ resAllPortNodes(tile, list)
|
|||
*--------------------------------------------------------------------------
|
||||
*
|
||||
* ResEachTile--for each tile, make a list of all possible current sources/
|
||||
* sinks including contacts, transistors, and junctions. Once this
|
||||
* sinks including contacts, devices, and junctions. Once this
|
||||
* list is made, calculate the resistor nextwork for the tile.
|
||||
*
|
||||
* Results: returns TRUE or FALSE depending on whether a node was
|
||||
* involved in a merge.
|
||||
*
|
||||
* Side Effects: creates Nodes, transistors, junctions, and breakpoints.
|
||||
* Side Effects: creates Nodes, devices, junctions, and breakpoints.
|
||||
*
|
||||
*
|
||||
*--------------------------------------------------------------------------
|
||||
|
|
@ -169,21 +169,21 @@ ResEachTile(tile, startpoint)
|
|||
if TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t1)
|
||||
{
|
||||
/*
|
||||
* The transistor is put in the center of the tile. This is fine
|
||||
* for single tile transistors, but not as good for multiple ones.
|
||||
* The device is put in the center of the tile. This is fine
|
||||
* for single tile device, but not as good for multiple ones.
|
||||
*/
|
||||
|
||||
if (tstructs->tj_status & RES_TILE_TRAN)
|
||||
if (tstructs->tj_status & RES_TILE_DEV)
|
||||
{
|
||||
if (tstructs->transistorList->rt_gate == NULL)
|
||||
if (tstructs->deviceList->rd_fet_gate == NULL)
|
||||
{
|
||||
int x = (LEFT(tile) + RIGHT(tile)) >> 1;
|
||||
int y = (TOP(tile) + BOTTOM(tile)) >> 1;
|
||||
|
||||
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
|
||||
tstructs->transistorList->rt_gate = resptr;
|
||||
tstructs->deviceList->rd_fet_gate = resptr;
|
||||
tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement)));
|
||||
tcell->te_thist = tstructs->transistorList;
|
||||
tcell->te_thist = tstructs->deviceList;
|
||||
tcell->te_nextt = NULL;
|
||||
|
||||
InitializeNode(resptr, x, y, RES_NODE_JUNCTION);
|
||||
|
|
@ -220,7 +220,7 @@ ResEachTile(tile, startpoint)
|
|||
{
|
||||
(void)DBSrPaintArea((Tile *) NULL,
|
||||
ResUse->cu_def->cd_planes[pNum],
|
||||
&tileArea, mask, resSubTranFunc, (ClientData) tile);
|
||||
&tileArea, mask, resSubDevFunc, (ClientData) tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -254,11 +254,11 @@ ResEachTile(tile, startpoint)
|
|||
devptr = ExtCurStyle->exts_device[t2];
|
||||
if(TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
|
||||
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
|
||||
/* found transistor */
|
||||
/* found device */
|
||||
{
|
||||
xj = LEFT(tile);
|
||||
yj = (TOP(tp) + BOTTOM(tp)) >> 1;
|
||||
ResNewSDTransistor(tile, tp, xj, yj, RIGHTEDGE, &ResNodeQueue);
|
||||
ResNewSDDevice(tile, tp, xj, yj, RIGHTEDGE, &ResNodeQueue);
|
||||
}
|
||||
if TTMaskHasType(&(ExtCurStyle->exts_nodeConn[t1]), t2)
|
||||
/* tile is junction */
|
||||
|
|
@ -277,11 +277,11 @@ ResEachTile(tile, startpoint)
|
|||
devptr = ExtCurStyle->exts_device[t2];
|
||||
if(TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
|
||||
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
|
||||
/* found transistor */
|
||||
/* found device */
|
||||
{
|
||||
xj = RIGHT(tile);
|
||||
yj = (TOP(tp)+BOTTOM(tp))>>1;
|
||||
ResNewSDTransistor(tile, tp, xj, yj, LEFTEDGE, &ResNodeQueue);
|
||||
ResNewSDDevice(tile, tp, xj, yj, LEFTEDGE, &ResNodeQueue);
|
||||
}
|
||||
if TTMaskHasType(&ExtCurStyle->exts_nodeConn[t1], t2)
|
||||
/* tile is junction */
|
||||
|
|
@ -300,11 +300,11 @@ ResEachTile(tile, startpoint)
|
|||
devptr = ExtCurStyle->exts_device[t2];
|
||||
if(TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) &&
|
||||
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1))
|
||||
/* found transistor */
|
||||
/* found device */
|
||||
{
|
||||
yj = TOP(tile);
|
||||
xj = (LEFT(tp)+RIGHT(tp))>>1;
|
||||
ResNewSDTransistor(tile,tp,xj,yj,BOTTOMEDGE, &ResNodeQueue);
|
||||
ResNewSDDevice(tile,tp,xj,yj,BOTTOMEDGE, &ResNodeQueue);
|
||||
}
|
||||
if TTMaskHasType(&ExtCurStyle->exts_nodeConn[t1],t2)
|
||||
/* tile is junction */
|
||||
|
|
@ -322,11 +322,11 @@ ResEachTile(tile, startpoint)
|
|||
devptr = ExtCurStyle->exts_device[t2];
|
||||
if(TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
|
||||
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
|
||||
/* found transistor */
|
||||
/* found device */
|
||||
{
|
||||
yj = BOTTOM(tile);
|
||||
xj = (LEFT(tp) + RIGHT(tp)) >> 1;
|
||||
ResNewSDTransistor(tile, tp, xj, yj, TOPEDGE, &ResNodeQueue);
|
||||
ResNewSDDevice(tile, tp, xj, yj, TOPEDGE, &ResNodeQueue);
|
||||
}
|
||||
if TTMaskHasType(&(ExtCurStyle->exts_nodeConn[t1]), t2)
|
||||
/* tile is junction */
|
||||
|
|
@ -349,7 +349,7 @@ ResEachTile(tile, startpoint)
|
|||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* resSubTranFunc -- called when DBSrPaintArea finds a transistor within
|
||||
* resSubDevFunc -- called when DBSrPaintArea finds a device within
|
||||
* a substrate area.
|
||||
*
|
||||
* Results: always returns 0 to keep search going.
|
||||
|
|
@ -360,7 +360,7 @@ ResEachTile(tile, startpoint)
|
|||
*/
|
||||
|
||||
int
|
||||
resSubTranFunc(tile,tp)
|
||||
resSubDevFunc(tile,tp)
|
||||
Tile *tile,*tp;
|
||||
|
||||
|
||||
|
|
@ -370,13 +370,13 @@ resSubTranFunc(tile,tp)
|
|||
tElement *tcell;
|
||||
int x,y;
|
||||
|
||||
if (junk->transistorList->rt_subs== NULL)
|
||||
if (junk->deviceList->rd_fet_subs == NULL)
|
||||
{
|
||||
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
|
||||
junk->transistorList->rt_subs = resptr;
|
||||
junk->tj_status |= RES_TILE_TRAN;
|
||||
junk->deviceList->rd_fet_subs = resptr;
|
||||
junk->tj_status |= RES_TILE_DEV;
|
||||
tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement)));
|
||||
tcell->te_thist = junk->transistorList;
|
||||
tcell->te_thist = junk->deviceList;
|
||||
tcell->te_nextt = NULL;
|
||||
x = (LEFT(tile)+RIGHT(tile))>>1;
|
||||
y = (TOP(tile)+BOTTOM(tile))>>1;
|
||||
|
|
|
|||
|
|
@ -43,16 +43,16 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
*/
|
||||
|
||||
void
|
||||
ResSanityChecks(nodename,resistorList,nodeList,tranlist)
|
||||
ResSanityChecks(nodename,resistorList,nodeList,devlist)
|
||||
char *nodename;
|
||||
resResistor *resistorList;
|
||||
resNode *nodeList;
|
||||
resTransistor *tranlist;
|
||||
resDevice *devlist;
|
||||
|
||||
{
|
||||
resResistor *resistor;
|
||||
resNode *node;
|
||||
resTransistor *tran;
|
||||
resDevice *dev;
|
||||
resElement *rcell;
|
||||
static Stack *resSanityStack = NULL;
|
||||
int reached,foundorigin;
|
||||
|
|
@ -107,29 +107,29 @@ ResSanityChecks(nodename,resistorList,nodeList,tranlist)
|
|||
}
|
||||
resistor->rr_status &= ~RES_REACHED_RESISTOR;
|
||||
}
|
||||
for (tran = tranlist; tran != NULL; tran = tran->rt_nextTran)
|
||||
for (dev = devlist; dev != NULL; dev = dev->rd_nextDev)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (tran->rt_status & RES_TRAN_PLUG) continue;
|
||||
if (dev->rd_status & RES_DEV_PLUG) continue;
|
||||
reached = FALSE;
|
||||
for (i=0;i != RT_TERMCOUNT;i++)
|
||||
for (i=0;i != dev->rd_nterms;i++)
|
||||
{
|
||||
if (tran->rt_terminals[i] != NULL)
|
||||
if (dev->rd_terminals[i] != NULL)
|
||||
{
|
||||
reached = TRUE;
|
||||
if ((tran->rt_terminals[i]->rn_status & RES_REACHED_NODE) == 0)
|
||||
if ((dev->rd_terminals[i]->rn_status & RES_REACHED_NODE) == 0)
|
||||
{
|
||||
TxError("Transistor node %d unreached in %s\n",i,nodename);
|
||||
TxError("Device node %d unreached in %s\n",i,nodename);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (reached == 0)
|
||||
{
|
||||
TxError("Unreached transistor in %s at %d %d\n",
|
||||
TxError("Unreached device in %s at %d %d\n",
|
||||
nodename,
|
||||
tran->rt_inside.r_xbot,
|
||||
tran->rt_inside.r_ybot);
|
||||
dev->rd_inside.r_xbot,
|
||||
dev->rd_inside.r_ybot);
|
||||
}
|
||||
}
|
||||
foundorigin = 0;
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ extern int dbcConnectFuncDCS();
|
|||
extern int resSubSearchFunc();
|
||||
#endif
|
||||
|
||||
static ResTranTile *TransList = NULL;
|
||||
static ResDevTile *DevList = NULL;
|
||||
static TileTypeBitMask DiffTypeBitMask;
|
||||
TileTypeBitMask ResSubsTypeBitMask;
|
||||
|
||||
|
|
@ -73,14 +73,14 @@ extern void ResCalcPerimOverlap();
|
|||
*
|
||||
* dbcConnectFuncDCS -- the same as dbcConnectFunc, except that it does
|
||||
* some extra searching around diffusion tiles looking for
|
||||
* transistors.
|
||||
* devices.
|
||||
*
|
||||
* Results:
|
||||
* Always returns 0 to keep the search from aborting.
|
||||
*
|
||||
* Side effects:
|
||||
* Adds a new record to the current check list. May also add new
|
||||
* ResTranTile structures.
|
||||
* ResDevTile structures.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
|
@ -92,8 +92,8 @@ dbcConnectFuncDCS(tile, cx)
|
|||
|
||||
{
|
||||
struct conSrArg2 *csa2;
|
||||
Rect tileArea, *srArea, tranArea, newarea;
|
||||
ResTranTile *thisTran;
|
||||
Rect tileArea, *srArea, devArea, newarea;
|
||||
ResDevTile *thisDev;
|
||||
TileTypeBitMask notConnectMask, *connectMask;
|
||||
Tile *tp;
|
||||
TileType t2, t1, loctype, ctype;
|
||||
|
|
@ -126,13 +126,13 @@ dbcConnectFuncDCS(tile, cx)
|
|||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) &&
|
||||
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1))
|
||||
{
|
||||
TiToRect(tp, &tranArea);
|
||||
thisTran = (ResTranTile *) mallocMagic((unsigned)(sizeof(ResTranTile)));
|
||||
ResCalcPerimOverlap(thisTran,tp);
|
||||
GeoTransRect(&scx->scx_trans, &tranArea, &thisTran->area);
|
||||
thisTran->type = TiGetType(tp);
|
||||
thisTran->nextTran = TransList;
|
||||
TransList = thisTran;
|
||||
TiToRect(tp, &devArea);
|
||||
thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile)));
|
||||
ResCalcPerimOverlap(thisDev,tp);
|
||||
GeoTransRect(&scx->scx_trans, &devArea, &thisDev->area);
|
||||
thisDev->type = TiGetType(tp);
|
||||
thisDev->nextDev = DevList;
|
||||
DevList = thisDev;
|
||||
}
|
||||
}
|
||||
/*right*/
|
||||
|
|
@ -143,13 +143,13 @@ dbcConnectFuncDCS(tile, cx)
|
|||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) &&
|
||||
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1))
|
||||
{
|
||||
TiToRect(tp, &tranArea);
|
||||
thisTran = (ResTranTile *) mallocMagic((unsigned)(sizeof(ResTranTile)));
|
||||
GeoTransRect(&scx->scx_trans, &tranArea, &thisTran->area);
|
||||
thisTran->type = TiGetType(tp);
|
||||
thisTran->nextTran = TransList;
|
||||
TransList = thisTran;
|
||||
ResCalcPerimOverlap(thisTran,tp);
|
||||
TiToRect(tp, &devArea);
|
||||
thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile)));
|
||||
GeoTransRect(&scx->scx_trans, &devArea, &thisDev->area);
|
||||
thisDev->type = TiGetType(tp);
|
||||
thisDev->nextDev = DevList;
|
||||
DevList = thisDev;
|
||||
ResCalcPerimOverlap(thisDev,tp);
|
||||
}
|
||||
}
|
||||
/*top*/
|
||||
|
|
@ -160,13 +160,13 @@ dbcConnectFuncDCS(tile, cx)
|
|||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) &&
|
||||
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1))
|
||||
{
|
||||
TiToRect(tp, &tranArea);
|
||||
thisTran = (ResTranTile *) mallocMagic((unsigned)(sizeof(ResTranTile)));
|
||||
GeoTransRect(&scx->scx_trans, &tranArea, &thisTran->area);
|
||||
thisTran->type = TiGetType(tp);
|
||||
thisTran->nextTran = TransList;
|
||||
TransList = thisTran;
|
||||
ResCalcPerimOverlap(thisTran,tp);
|
||||
TiToRect(tp, &devArea);
|
||||
thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile)));
|
||||
GeoTransRect(&scx->scx_trans, &devArea, &thisDev->area);
|
||||
thisDev->type = TiGetType(tp);
|
||||
thisDev->nextDev = DevList;
|
||||
DevList = thisDev;
|
||||
ResCalcPerimOverlap(thisDev,tp);
|
||||
}
|
||||
}
|
||||
/*bottom */
|
||||
|
|
@ -177,28 +177,28 @@ dbcConnectFuncDCS(tile, cx)
|
|||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) &&
|
||||
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1))
|
||||
{
|
||||
TiToRect(tp, &tranArea);
|
||||
thisTran = (ResTranTile *) mallocMagic((unsigned)(sizeof(ResTranTile)));
|
||||
GeoTransRect(&scx->scx_trans, &tranArea, &thisTran->area);
|
||||
thisTran->type = TiGetType(tp);
|
||||
thisTran->nextTran = TransList;
|
||||
TransList = thisTran;
|
||||
ResCalcPerimOverlap(thisTran,tp);
|
||||
TiToRect(tp, &devArea);
|
||||
thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile)));
|
||||
GeoTransRect(&scx->scx_trans, &devArea, &thisDev->area);
|
||||
thisDev->type = TiGetType(tp);
|
||||
thisDev->nextDev = DevList;
|
||||
DevList = thisDev;
|
||||
ResCalcPerimOverlap(thisDev,tp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t1)
|
||||
{
|
||||
TiToRect(tile, &tranArea);
|
||||
thisTran = (ResTranTile *) mallocMagic((unsigned)(sizeof(ResTranTile)));
|
||||
ResCalcPerimOverlap(thisTran,tile);
|
||||
GeoTransRect(&scx->scx_trans, &tranArea, &thisTran->area);
|
||||
thisTran->type = TiGetType(tile);
|
||||
thisTran->nextTran = TransList;
|
||||
TransList = thisTran;
|
||||
TiToRect(tile, &devArea);
|
||||
thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile)));
|
||||
ResCalcPerimOverlap(thisDev,tile);
|
||||
GeoTransRect(&scx->scx_trans, &devArea, &thisDev->area);
|
||||
thisDev->type = TiGetType(tile);
|
||||
thisDev->nextDev = DevList;
|
||||
DevList = thisDev;
|
||||
}
|
||||
/* in some cases (primarily bipolar technology), we'll want to extract
|
||||
transistors whose substrate terminals are part of the given region.
|
||||
devices whose substrate terminals are part of the given region.
|
||||
The following does that check. (10-11-88)
|
||||
*/
|
||||
#ifdef ARIEL
|
||||
|
|
@ -338,8 +338,8 @@ dbcConnectFuncDCS(tile, cx)
|
|||
*/
|
||||
|
||||
void
|
||||
ResCalcPerimOverlap(trans, tile)
|
||||
ResTranTile *trans;
|
||||
ResCalcPerimOverlap(dev, tile)
|
||||
ResDevTile *dev;
|
||||
Tile *tile;
|
||||
|
||||
{
|
||||
|
|
@ -347,7 +347,7 @@ ResCalcPerimOverlap(trans, tile)
|
|||
int t1;
|
||||
int overlap;
|
||||
|
||||
trans->perim = (TOP(tile)-BOTTOM(tile)-LEFT(tile)+RIGHT(tile))<<1;
|
||||
dev->perim = (TOP(tile)-BOTTOM(tile)-LEFT(tile)+RIGHT(tile))<<1;
|
||||
overlap =0;
|
||||
|
||||
t1 = TiGetType(tile);
|
||||
|
|
@ -391,7 +391,7 @@ ResCalcPerimOverlap(trans, tile)
|
|||
}
|
||||
|
||||
}
|
||||
trans->overlap = overlap;
|
||||
dev->overlap = overlap;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -404,7 +404,7 @@ ResCalcPerimOverlap(trans, tile)
|
|||
* dbcConnectFuncDCS.
|
||||
*
|
||||
* Results:
|
||||
* Linked list of transistors.
|
||||
* Linked list of devices.
|
||||
*
|
||||
* Side effects:
|
||||
* The contents of the result cell are modified.
|
||||
|
|
@ -412,7 +412,7 @@ ResCalcPerimOverlap(trans, tile)
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
ResTranTile *
|
||||
ResDevTile *
|
||||
DBTreeCopyConnectDCS(scx, mask, xMask, connect, area, destUse)
|
||||
SearchContext *scx;
|
||||
TileTypeBitMask *mask;
|
||||
|
|
@ -424,10 +424,10 @@ DBTreeCopyConnectDCS(scx, mask, xMask, connect, area, destUse)
|
|||
{
|
||||
static int first = 1;
|
||||
struct conSrArg2 csa2;
|
||||
int tran, pNum;
|
||||
char *tran_name;
|
||||
int dev, pNum;
|
||||
char *dev_name;
|
||||
TileTypeBitMask *newmask;
|
||||
ResTranTile *CurrentT;
|
||||
ResDevTile *CurrentT;
|
||||
CellDef *def = destUse->cu_def;
|
||||
TileType newtype;
|
||||
ExtDevice *devptr;
|
||||
|
|
@ -447,11 +447,11 @@ DBTreeCopyConnectDCS(scx, mask, xMask, connect, area, destUse)
|
|||
{
|
||||
TTMaskZero(&DiffTypeBitMask);
|
||||
TTMaskZero(&ResSubsTypeBitMask);
|
||||
for (tran = TT_TECHDEPBASE; tran < TT_MAXTYPES; tran++)
|
||||
for (dev = TT_TECHDEPBASE; dev < TT_MAXTYPES; dev++)
|
||||
{
|
||||
devptr = ExtCurStyle->exts_device[tran];
|
||||
if ((devptr != NULL) && ((tran_name = devptr->exts_deviceName) != NULL)
|
||||
&& (strcmp(tran_name, "None")))
|
||||
devptr = ExtCurStyle->exts_device[dev];
|
||||
if ((devptr != NULL) && ((dev_name = devptr->exts_deviceName) != NULL)
|
||||
&& (strcmp(dev_name, "None")))
|
||||
{
|
||||
TTMaskSetMask(&DiffTypeBitMask,
|
||||
&(devptr->exts_deviceSDTypes[0]));
|
||||
|
|
@ -462,7 +462,7 @@ DBTreeCopyConnectDCS(scx, mask, xMask, connect, area, destUse)
|
|||
first = 0;
|
||||
}
|
||||
|
||||
TransList = NULL;
|
||||
DevList = NULL;
|
||||
DBTreeSrTiles(scx, mask, xMask, dbcConnectFuncDCS, (ClientData) &csa2);
|
||||
while (csa2.csa2_top >= 0)
|
||||
{
|
||||
|
|
@ -478,7 +478,7 @@ DBTreeCopyConnectDCS(scx, mask, xMask, connect, area, destUse)
|
|||
}
|
||||
freeMagic((char *)csa2.csa2_list);
|
||||
|
||||
for (CurrentT = TransList; CurrentT != NULL; CurrentT=CurrentT->nextTran)
|
||||
for (CurrentT = DevList; CurrentT != NULL; CurrentT=CurrentT->nextDev)
|
||||
{
|
||||
TileType t = CurrentT->type;
|
||||
TileType nt;
|
||||
|
|
@ -496,7 +496,7 @@ DBTreeCopyConnectDCS(scx, mask, xMask, connect, area, destUse)
|
|||
}
|
||||
|
||||
DBReComputeBbox(def);
|
||||
return(TransList);
|
||||
return(DevList);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -506,7 +506,7 @@ DBTreeCopyConnectDCS(scx, mask, xMask, connect, area, destUse)
|
|||
*
|
||||
* resSubSearchFunc --
|
||||
*
|
||||
* called when DBSrPaintArea finds a transistor within
|
||||
* called when DBSrPaintArea finds a device within
|
||||
* a substrate area.
|
||||
*
|
||||
* Results:
|
||||
|
|
@ -524,8 +524,8 @@ resSubSearchFunc(tile,cx)
|
|||
|
||||
|
||||
{
|
||||
ResTranTile *thisTran;
|
||||
Rect tranArea;
|
||||
ResDevTile *thisDev;
|
||||
Rect devArea;
|
||||
TileType t = TiGetType(tile);
|
||||
ExtDevice *devptr;
|
||||
|
||||
|
|
@ -535,13 +535,13 @@ resSubSearchFunc(tile,cx)
|
|||
*/
|
||||
devptr = ExtCurStyle->exts_device[t]
|
||||
if (devptr->exts_deviceSDCount >1) return 0;
|
||||
TiToRect(tile, &tranArea);
|
||||
thisTran = (ResTranTile *) mallocMagic((unsigned)(sizeof(ResTranTile)));
|
||||
GeoTransRect(&cx->tc_scx->scx_trans, &tranArea, &thisTran->area);
|
||||
thisTran->type = t;
|
||||
thisTran->nextTran = TransList;
|
||||
TransList = thisTran;
|
||||
ResCalcPerimOverlap(thisTran,tile);
|
||||
TiToRect(tile, &devArea);
|
||||
thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile)));
|
||||
GeoTransRect(&cx->tc_scx->scx_trans, &devArea, &thisDev->area);
|
||||
thisDev->type = t;
|
||||
thisDev->nextDev = DevList;
|
||||
DevList = thisDev;
|
||||
ResCalcPerimOverlap(thisDev,tile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,42 +101,42 @@ ResPrintResistorList(fp,list)
|
|||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ResPrintTransistorList--
|
||||
* ResPrintDeviceList--
|
||||
*
|
||||
*
|
||||
* Results: none
|
||||
*
|
||||
* Side effects: prints out transistors in list to file fp.
|
||||
* Side effects: prints out devices in list to file fp.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ResPrintTransistorList(fp,list)
|
||||
ResPrintDeviceList(fp,list)
|
||||
FILE *fp;
|
||||
resTransistor *list;
|
||||
resDevice *list;
|
||||
|
||||
{
|
||||
static char termtype[] = {'g','s','d','c'};
|
||||
int i;
|
||||
for (; list != NULL; list = list->rt_nextTran)
|
||||
for (; list != NULL; list = list->rd_nextDev)
|
||||
{
|
||||
if (list->rt_status & RES_TRAN_PLUG) continue;
|
||||
if (list->rd_status & RES_DEV_PLUG) continue;
|
||||
if (fp == stdout)
|
||||
TxPrintf("t w %d l %d ", list->rt_width, list->rt_length);
|
||||
TxPrintf("t w %d l %d ", list->rd_width, list->rd_length);
|
||||
else
|
||||
fprintf(fp, "t w %d l %d ", list->rt_width, list->rt_length);
|
||||
for (i=0; i!= RT_TERMCOUNT;i++)
|
||||
fprintf(fp, "t w %d l %d ", list->rd_width, list->rd_length);
|
||||
for (i = 0; i != list->rd_nterms; i++)
|
||||
{
|
||||
if (list->rt_terminals[i] == NULL) continue;
|
||||
if (list->rd_terminals[i] == NULL) continue;
|
||||
if (fp == stdout)
|
||||
TxPrintf("%c (%d,%d) ",termtype[i],
|
||||
list->rt_terminals[i]->rn_loc.p_x,
|
||||
list->rt_terminals[i]->rn_loc.p_y);
|
||||
list->rd_terminals[i]->rn_loc.p_x,
|
||||
list->rd_terminals[i]->rn_loc.p_y);
|
||||
else
|
||||
fprintf(fp, "%c (%d,%d) ",termtype[i],
|
||||
list->rt_terminals[i]->rn_loc.p_x,
|
||||
list->rt_terminals[i]->rn_loc.p_y);
|
||||
list->rd_terminals[i]->rn_loc.p_x,
|
||||
list->rd_terminals[i]->rn_loc.p_y);
|
||||
|
||||
}
|
||||
if (fp == stdout)
|
||||
|
|
|
|||
|
|
@ -31,66 +31,66 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ResNewSDTransistor-- called when a transistor is reached via a piece of
|
||||
* diffusion. (Transistors reached via poly, i.e.
|
||||
* ResNewSDDevice -- called when a device is reached via a piece of
|
||||
* diffusion. (Devices reached via poly, i.e.
|
||||
* gates, are handled by ResEachTile.)
|
||||
*
|
||||
* Results:none
|
||||
*
|
||||
* Side Effects: determines to which terminal (source or drain) node
|
||||
* is connected. Makes new node if node hasn't already been created .
|
||||
* Allocates breakpoint in current tile for transistor.
|
||||
* Allocates breakpoint in current tile for device.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ResNewSDTransistor(tile,tp,xj,yj,direction,PendingList)
|
||||
ResNewSDDevice(tile,tp,xj,yj,direction,PendingList)
|
||||
Tile *tile,*tp;
|
||||
int xj,yj,direction;
|
||||
resNode **PendingList;
|
||||
{
|
||||
resNode *resptr;
|
||||
resTransistor *resFet;
|
||||
resDevice *resDev;
|
||||
tElement *tcell;
|
||||
int newnode;
|
||||
tileJunk *j;
|
||||
|
||||
newnode = FALSE;
|
||||
j = (tileJunk *) tp->ti_client;
|
||||
resFet = j->transistorList;
|
||||
resDev = j->deviceList;
|
||||
if ((j->sourceEdge & direction) != 0)
|
||||
{
|
||||
if (resFet->rt_source == (resNode *) NULL)
|
||||
if (resDev->rd_fet_source == (resNode *) NULL)
|
||||
{
|
||||
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
|
||||
newnode = TRUE;
|
||||
resFet->rt_source = resptr;
|
||||
resDev->rd_fet_source = resptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
resptr = resFet->rt_source;
|
||||
resptr = resDev->rd_fet_source;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (resFet->rt_drain == (resNode *) NULL)
|
||||
if (resDev->rd_fet_drain == (resNode *) NULL)
|
||||
{
|
||||
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
|
||||
newnode = TRUE;
|
||||
resFet->rt_drain = resptr;
|
||||
resDev->rd_fet_drain = resptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
resptr = resFet->rt_drain;
|
||||
resptr = resDev->rd_fet_drain;
|
||||
}
|
||||
}
|
||||
if (newnode)
|
||||
{
|
||||
tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement)));
|
||||
tcell->te_nextt = NULL;
|
||||
tcell->te_thist = j->transistorList;
|
||||
InitializeNode(resptr,xj,yj,RES_NODE_TRANSISTOR);
|
||||
tcell->te_thist = j->deviceList;
|
||||
InitializeNode(resptr,xj,yj,RES_NODE_DEVICE);
|
||||
resptr->rn_te = tcell;
|
||||
ResAddToQueue(resptr,PendingList);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,12 +26,12 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
CellUse *ResUse=NULL; /* Our use and def */
|
||||
CellDef *ResDef=NULL;
|
||||
TileTypeBitMask ResConnectWithSD[NT]; /* A mask that goes from */
|
||||
/* SD's to transistors. */
|
||||
TileTypeBitMask ResCopyMask[NT]; /* Indicates which tiles */
|
||||
/* SD's to devices. */
|
||||
TileTypeBitMask ResCopyMask[NT]; /* Indicates which tiles */
|
||||
/* are to be copied. */
|
||||
resResistor *ResResList=NULL; /* Resistor list */
|
||||
resNode *ResNodeList=NULL; /* Processed Nodes */
|
||||
resTransistor *ResTransList=NULL; /* Transistors */
|
||||
resDevice *ResDevList=NULL; /* Devices */
|
||||
ResContactPoint *ResContactList=NULL; /* Contacts */
|
||||
resNode *ResNodeQueue=NULL; /* Pending nodes */
|
||||
resNode *ResOriginNode=NULL; /* node where R=0 */
|
||||
|
|
@ -52,7 +52,7 @@ extern HashTable ResNodeTable;
|
|||
*
|
||||
* ResInitializeConn--
|
||||
*
|
||||
* Sets up mask by Source/Drain type of transistors. This is
|
||||
* Sets up mask by Source/Drain type of devices. This is
|
||||
* exts_deviceSDtypes turned inside out.
|
||||
*
|
||||
* Results: none
|
||||
|
|
@ -65,26 +65,26 @@ extern HashTable ResNodeTable;
|
|||
void
|
||||
ResInitializeConn()
|
||||
{
|
||||
TileType tran, diff;
|
||||
char *tran_name;
|
||||
TileType dev, diff;
|
||||
char *dev_name;
|
||||
ExtDevice *devptr;
|
||||
|
||||
for (tran = TT_TECHDEPBASE; tran < TT_MAXTYPES; tran++)
|
||||
for (dev = TT_TECHDEPBASE; dev < TT_MAXTYPES; dev++)
|
||||
{
|
||||
devptr = ExtCurStyle->exts_device[tran];
|
||||
if ((devptr != NULL) && ((tran_name = devptr->exts_deviceName) != NULL)
|
||||
&& (strcmp(tran_name, "None")))
|
||||
devptr = ExtCurStyle->exts_device[dev];
|
||||
if ((devptr != NULL) && ((dev_name = devptr->exts_deviceName) != NULL)
|
||||
&& (strcmp(dev_name, "None")))
|
||||
{
|
||||
for (diff = TT_TECHDEPBASE; diff < TT_MAXTYPES; diff++)
|
||||
{
|
||||
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), diff)
|
||||
TTMaskSetType(&ResConnectWithSD[diff],tran);
|
||||
TTMaskSetType(&ResConnectWithSD[diff],dev);
|
||||
|
||||
if TTMaskHasType(&(devptr->exts_deviceSubstrateTypes),diff)
|
||||
TTMaskSetType(&ResConnectWithSD[diff],tran);
|
||||
TTMaskSetType(&ResConnectWithSD[diff],dev);
|
||||
}
|
||||
}
|
||||
TTMaskSetMask(&ResConnectWithSD[tran],&DBConnectTbl[tran]);
|
||||
TTMaskSetMask(&ResConnectWithSD[dev],&DBConnectTbl[dev]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -573,7 +573,7 @@ ResExtractNet(startlist,goodies,cellname)
|
|||
{
|
||||
SearchContext scx;
|
||||
int pNum;
|
||||
ResTranTile *TranTiles,*lasttile;
|
||||
ResDevTile *DevTiles,*lasttile;
|
||||
TileTypeBitMask FirstTileMask;
|
||||
Point startpoint;
|
||||
ResFixPoint *fix;
|
||||
|
|
@ -583,7 +583,7 @@ ResExtractNet(startlist,goodies,cellname)
|
|||
|
||||
ResResList=NULL;
|
||||
ResNodeList=NULL;
|
||||
ResTransList=NULL;
|
||||
ResDevList=NULL;
|
||||
ResNodeQueue=NULL;
|
||||
ResContactList = NULL;
|
||||
ResOriginNode = NULL;
|
||||
|
|
@ -632,11 +632,11 @@ ResExtractNet(startlist,goodies,cellname)
|
|||
|
||||
|
||||
/* Copy Paint */
|
||||
TranTiles = NULL;
|
||||
DevTiles = NULL;
|
||||
lasttile = NULL;
|
||||
for (fix = startlist; fix != NULL;fix=fix->fp_next)
|
||||
{
|
||||
ResTranTile *newtrantiles,*tmp;
|
||||
ResDevTile *newdevtiles,*tmp;
|
||||
|
||||
#ifdef ARIEL
|
||||
if ((ResOptionsFlags & ResOpt_Power) &&
|
||||
|
|
@ -650,19 +650,19 @@ ResExtractNet(startlist,goodies,cellname)
|
|||
startpoint = fix->fp_loc;
|
||||
TTMaskSetOnlyType(&FirstTileMask,fix->fp_ttype);
|
||||
|
||||
newtrantiles = DBTreeCopyConnectDCS(&scx, &FirstTileMask, 0,
|
||||
newdevtiles = DBTreeCopyConnectDCS(&scx, &FirstTileMask, 0,
|
||||
ResCopyMask, &TiPlaneRect, ResUse);
|
||||
|
||||
for (tmp = newtrantiles; tmp && tmp->nextTran; tmp = tmp->nextTran);
|
||||
if (newtrantiles)
|
||||
for (tmp = newdevtiles; tmp && tmp->nextDev; tmp = tmp->nextDev);
|
||||
if (newdevtiles)
|
||||
{
|
||||
if (TranTiles)
|
||||
if (DevTiles)
|
||||
{
|
||||
lasttile->nextTran = newtrantiles;
|
||||
lasttile->nextDev = newdevtiles;
|
||||
}
|
||||
else
|
||||
{
|
||||
TranTiles = newtrantiles;
|
||||
DevTiles = newdevtiles;
|
||||
}
|
||||
lasttile = tmp;
|
||||
}
|
||||
|
|
@ -696,7 +696,7 @@ ResExtractNet(startlist,goodies,cellname)
|
|||
(void) DBSrPaintClient((Tile *) NULL,plane,rect,
|
||||
&DBAllButSpaceAndDRCBits,
|
||||
(ClientData) CLIENTDEFAULT, ResAddPlumbing,
|
||||
(ClientData) &ResTransList);
|
||||
(ClientData) &ResDevList);
|
||||
}
|
||||
|
||||
/* Finish preprocessing. */
|
||||
|
|
@ -704,7 +704,7 @@ ResExtractNet(startlist,goodies,cellname)
|
|||
ResMakePortBreakpoints(ResUse->cu_def);
|
||||
ResMakeLabelBreakpoints(ResUse->cu_def);
|
||||
ResFindNewContactTiles(ResContactList);
|
||||
ResPreProcessTransistors(TranTiles, ResTransList, ResUse->cu_def);
|
||||
ResPreProcessDevices(DevTiles, ResDevList, ResUse->cu_def);
|
||||
|
||||
#ifdef LAPLACE
|
||||
if (ResOptionsFlags & ResOpt_DoLaplace)
|
||||
|
|
@ -756,7 +756,7 @@ ResCleanUpEverything()
|
|||
|
||||
int pNum;
|
||||
resResistor *oldRes;
|
||||
resTransistor *oldTran;
|
||||
resDevice *oldDev;
|
||||
ResContactPoint *oldCon;
|
||||
|
||||
/* check integrity of internal database. Free up lists. */
|
||||
|
|
@ -786,13 +786,14 @@ ResCleanUpEverything()
|
|||
ResResList = ResResList->rr_nextResistor;
|
||||
freeMagic((char *)oldRes);
|
||||
}
|
||||
while (ResTransList != NULL)
|
||||
while (ResDevList != NULL)
|
||||
{
|
||||
oldTran = ResTransList;
|
||||
ResTransList = ResTransList->rt_nextTran;
|
||||
if ((oldTran->rt_status & RES_TRAN_SAVE) == 0)
|
||||
oldDev = ResDevList;
|
||||
ResDevList = ResDevList->rd_nextDev;
|
||||
if ((oldDev->rd_status & RES_DEV_SAVE) == 0)
|
||||
{
|
||||
freeMagic((char *)oldTran);
|
||||
freeMagic((char *)oldDev->rd_terminals);
|
||||
freeMagic((char *)oldDev);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -806,7 +807,7 @@ ResCleanUpEverything()
|
|||
*
|
||||
* 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
|
||||
* unit) of the transistor. FindStartTile looks for the transistor, then
|
||||
* unit) of the device. FindStartTile looks for the device, then
|
||||
* for adjoining diffusion. The diffusion tile is returned.
|
||||
*
|
||||
* Results: returns source diffusion tile, if it exists. Otherwise, return
|
||||
|
|
@ -828,11 +829,11 @@ FindStartTile(goodies, SourcePoint)
|
|||
int pnum, t1, t2;
|
||||
ExtDevice *devptr;
|
||||
|
||||
workingPoint.p_x = goodies->rg_tranloc->p_x;
|
||||
workingPoint.p_y = goodies->rg_tranloc->p_y;
|
||||
workingPoint.p_x = goodies->rg_devloc->p_x;
|
||||
workingPoint.p_y = goodies->rg_devloc->p_y;
|
||||
pnum = DBPlane(goodies->rg_ttype);
|
||||
|
||||
/* for drivepoints, we don't have to find a transistor */
|
||||
/* for drivepoints, we don't have to find a device */
|
||||
if (goodies->rg_status & DRIVEONLY)
|
||||
{
|
||||
tile = ResUse->cu_def->cd_planes[pnum]->pl_hint;
|
||||
|
|
@ -862,7 +863,7 @@ FindStartTile(goodies, SourcePoint)
|
|||
}
|
||||
}
|
||||
TxError("Couldn't find wire at %d %d\n",
|
||||
goodies->rg_tranloc->p_x, goodies->rg_tranloc->p_y);
|
||||
goodies->rg_devloc->p_x, goodies->rg_devloc->p_y);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -883,15 +884,15 @@ FindStartTile(goodies, SourcePoint)
|
|||
}
|
||||
else
|
||||
{
|
||||
TxError("Couldn't find transistor at %d %d\n",
|
||||
goodies->rg_tranloc->p_x, goodies->rg_tranloc->p_y);
|
||||
TxError("Couldn't find device at %d %d\n",
|
||||
goodies->rg_devloc->p_x, goodies->rg_devloc->p_y);
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
else if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetType(tile)) == 0)
|
||||
{
|
||||
TxError("Couldn't find transistor at %d %d\n",
|
||||
goodies->rg_tranloc->p_x, goodies->rg_tranloc->p_y);
|
||||
TxError("Couldn't find device at %d %d\n",
|
||||
goodies->rg_devloc->p_x, goodies->rg_devloc->p_y);
|
||||
return(NULL);
|
||||
}
|
||||
else
|
||||
|
|
@ -955,11 +956,11 @@ FindStartTile(goodies, SourcePoint)
|
|||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ResGetTransistor-- Once the net is extracted, we still have to equate
|
||||
* the sim file transistors with the layout transistors. ResGetTransistor
|
||||
* looks for a transistor at the given location.
|
||||
* ResGetDevice -- Once the net is extracted, we still have to equate
|
||||
* the sim file devices with the layout devices. ResGetDevice
|
||||
* looks for a device at the given location.
|
||||
*
|
||||
* Results: returns transistor structure at location TransistorPoint, if it
|
||||
* Results: returns device structure at location DevicePoint, if it
|
||||
* exists.
|
||||
*
|
||||
* Side Effects: none
|
||||
|
|
@ -967,8 +968,8 @@ FindStartTile(goodies, SourcePoint)
|
|||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
resTransistor *
|
||||
ResGetTransistor(pt)
|
||||
resDevice *
|
||||
ResGetDevice(pt)
|
||||
Point *pt;
|
||||
|
||||
{
|
||||
|
|
@ -985,7 +986,7 @@ ResGetTransistor(pt)
|
|||
{
|
||||
continue;
|
||||
}
|
||||
/*start at hint tile for transistor plane */
|
||||
/*start at hint tile for device plane */
|
||||
tile = ResUse->cu_def->cd_planes[pnum]->pl_hint;
|
||||
GOTOPOINT(tile,&workingPoint);
|
||||
|
||||
|
|
@ -993,11 +994,11 @@ ResGetTransistor(pt)
|
|||
{
|
||||
if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetLeftType(tile))
|
||||
|| TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetRightType(tile)))
|
||||
return(((tileJunk *)tile->ti_client)->transistorList);
|
||||
return(((tileJunk *)tile->ti_client)->deviceList);
|
||||
}
|
||||
else if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetType(tile)))
|
||||
{
|
||||
return(((tileJunk *)tile->ti_client)->transistorList);
|
||||
return(((tileJunk *)tile->ti_client)->deviceList);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "cif/CIFint.h"
|
||||
|
||||
/* Forward declarations */
|
||||
bool ResCalcNearTransistor();
|
||||
bool ResCalcNearDevice();
|
||||
bool ResCalcNorthSouth();
|
||||
bool ResCalcEastWest();
|
||||
|
||||
|
|
@ -58,12 +58,12 @@ ResCalcTileResistance(tile, junk, pendingList, doneList)
|
|||
{
|
||||
int MaxX = MINFINITY, MinX = INFINITY;
|
||||
int MaxY = MINFINITY, MinY = INFINITY;
|
||||
int transistor;
|
||||
int device;
|
||||
bool merged;
|
||||
Breakpoint *p1;
|
||||
|
||||
merged = FALSE;
|
||||
transistor = FALSE;
|
||||
device = FALSE;
|
||||
|
||||
if ((p1 = junk->breakList) == NULL) return FALSE;
|
||||
for (; p1; p1 = p1->br_next)
|
||||
|
|
@ -74,18 +74,18 @@ ResCalcTileResistance(tile, junk, 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_TRANSISTOR)
|
||||
if (p1->br_this->rn_why == RES_NODE_DEVICE)
|
||||
{
|
||||
transistor = TRUE;
|
||||
device = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, produce resistors for partition. Keep track of */
|
||||
/* whether or not the node was involved in a merge. */
|
||||
|
||||
if (transistor)
|
||||
if (device)
|
||||
{
|
||||
merged |= ResCalcNearTransistor(tile, pendingList, doneList, &ResResList);
|
||||
merged |= ResCalcNearDevice(tile, pendingList, doneList, &ResResList);
|
||||
}
|
||||
else if (MaxY-MinY > MaxX-MinX)
|
||||
{
|
||||
|
|
@ -444,9 +444,9 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
|
|||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ResCalcNearTransistor-- Calculating the direction of current flow near
|
||||
* transistors is tricky because there are two adjoining regions with
|
||||
* vastly different sheet resistances. ResCalcNearTransistor is called
|
||||
* ResCalcNearDevice-- Calculating the direction of current flow near
|
||||
* devices is tricky because there are two adjoining regions with
|
||||
* vastly different sheet resistances. ResCalcNearDevice is called
|
||||
* whenever a diffusion tile adjoining a real tile is found. It makes
|
||||
* a guess at the correct direction of current flow, removes extra
|
||||
* breakpoints, and call either ResCalcEastWest or ResCalcNorthSouth
|
||||
|
|
@ -460,14 +460,14 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
|
|||
*/
|
||||
|
||||
bool
|
||||
ResCalcNearTransistor(tile, pendingList, doneList, resList)
|
||||
ResCalcNearDevice(tile, pendingList, doneList, resList)
|
||||
Tile *tile;
|
||||
resNode **pendingList, **doneList;
|
||||
resResistor **resList;
|
||||
|
||||
{
|
||||
bool merged;
|
||||
int trancount,tranedge,deltax,deltay;
|
||||
int devcount,devedge,deltax,deltay;
|
||||
Breakpoint *p1,*p2,*p3;
|
||||
tileJunk *junk = (tileJunk *)tile->ti_client;
|
||||
|
||||
|
|
@ -485,35 +485,35 @@ ResCalcNearTransistor(tile, pendingList, doneList, resList)
|
|||
junk->breakList = NULL;
|
||||
return(merged);
|
||||
}
|
||||
/* count the number of transistor breakpoints */
|
||||
/* count the number of device breakpoints */
|
||||
/* mark which edge they connect to */
|
||||
trancount = 0;
|
||||
tranedge = 0;
|
||||
devcount = 0;
|
||||
devedge = 0;
|
||||
for (p1=junk->breakList; p1 != NULL;p1 = p1->br_next)
|
||||
{
|
||||
if (p1->br_this->rn_why == RES_NODE_TRANSISTOR)
|
||||
if (p1->br_this->rn_why == RES_NODE_DEVICE)
|
||||
{
|
||||
trancount++;
|
||||
if (p1->br_loc.p_x == LEFT(tile)) tranedge |= LEFTEDGE;
|
||||
else if (p1->br_loc.p_x == RIGHT(tile)) tranedge |= RIGHTEDGE;
|
||||
else if (p1->br_loc.p_y == TOP(tile)) tranedge |= TOPEDGE;
|
||||
else if (p1->br_loc.p_y == BOTTOM(tile)) tranedge |= BOTTOMEDGE;
|
||||
devcount++;
|
||||
if (p1->br_loc.p_x == LEFT(tile)) devedge |= LEFTEDGE;
|
||||
else if (p1->br_loc.p_x == RIGHT(tile)) devedge |= RIGHTEDGE;
|
||||
else if (p1->br_loc.p_y == TOP(tile)) devedge |= TOPEDGE;
|
||||
else if (p1->br_loc.p_y == BOTTOM(tile)) devedge |= BOTTOMEDGE;
|
||||
}
|
||||
}
|
||||
/* use distance from transistor to next breakpoint as determinant */
|
||||
/* if there is only one transistor or if all the transitors are along */
|
||||
/* use distance from device to next breakpoint as determinant */
|
||||
/* if there is only one device or if all the devices are along */
|
||||
/* the same edge. */
|
||||
if (trancount == 1 ||
|
||||
(tranedge & LEFTEDGE) == tranedge ||
|
||||
(tranedge & RIGHTEDGE) == tranedge ||
|
||||
(tranedge & TOPEDGE) == tranedge ||
|
||||
(tranedge & BOTTOMEDGE) == tranedge)
|
||||
if (devcount == 1 ||
|
||||
(devedge & LEFTEDGE) == devedge ||
|
||||
(devedge & RIGHTEDGE) == devedge ||
|
||||
(devedge & TOPEDGE) == devedge ||
|
||||
(devedge & BOTTOMEDGE) == devedge)
|
||||
{
|
||||
ResSortBreaks(&junk->breakList,TRUE);
|
||||
p2 = NULL;
|
||||
for (p1=junk->breakList; p1 != NULL;p1 = p1->br_next)
|
||||
{
|
||||
if (p1->br_this->rn_why == RES_NODE_TRANSISTOR)
|
||||
if (p1->br_this->rn_why == RES_NODE_DEVICE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
@ -580,7 +580,7 @@ ResCalcNearTransistor(tile, pendingList, doneList, resList)
|
|||
p2 = NULL;
|
||||
for (p1=junk->breakList; p1 != NULL;p1 = p1->br_next)
|
||||
{
|
||||
if (p1->br_this->rn_why == RES_NODE_TRANSISTOR)
|
||||
if (p1->br_this->rn_why == RES_NODE_DEVICE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
@ -651,27 +651,27 @@ ResCalcNearTransistor(tile, pendingList, doneList, resList)
|
|||
}
|
||||
|
||||
}
|
||||
/* multiple transistors connected to the partition */
|
||||
/* multiple devices connected to the partition */
|
||||
else
|
||||
{
|
||||
if (tranedge == 0)
|
||||
if (devedge == 0)
|
||||
{
|
||||
TxError("Error in transistor current direction routine\n");
|
||||
TxError("Error in device current direction routine\n");
|
||||
return(merged);
|
||||
}
|
||||
/* check to see if the current flow is north-south */
|
||||
/* possible north-south conditions: */
|
||||
/* 1. there are transistors along the top and bottom edges */
|
||||
/* 1. there are devices along the top and bottom edges */
|
||||
/* but not along the left or right */
|
||||
/* 2. there are transistors along two sides at right angles, */
|
||||
/* 2. there are devices along two sides at right angles, */
|
||||
/* and the tile is wider than it is tall. */
|
||||
|
||||
if ((tranedge & TOPEDGE) &&
|
||||
(tranedge & BOTTOMEDGE) &&
|
||||
!(tranedge & LEFTEDGE) &&
|
||||
!(tranedge & RIGHTEDGE) ||
|
||||
(tranedge & TOPEDGE || tranedge & BOTTOMEDGE) &&
|
||||
(tranedge & LEFTEDGE || tranedge & RIGHTEDGE) &&
|
||||
if ((devedge & TOPEDGE) &&
|
||||
(devedge & BOTTOMEDGE) &&
|
||||
!(devedge & LEFTEDGE) &&
|
||||
!(devedge & RIGHTEDGE) ||
|
||||
(devedge & TOPEDGE || devedge & BOTTOMEDGE) &&
|
||||
(devedge & LEFTEDGE || devedge & RIGHTEDGE) &&
|
||||
RIGHT(tile)-LEFT(tile) > TOP(tile)-BOTTOM(tile))
|
||||
{
|
||||
/* re-sort nodes south to north. */
|
||||
|
|
@ -680,7 +680,7 @@ ResCalcNearTransistor(tile, pendingList, doneList, resList)
|
|||
/* eliminate duplicate S/D pointers */
|
||||
for (p1 = junk->breakList; p1 != NULL; p1 = p1->br_next)
|
||||
{
|
||||
if (p1->br_this->rn_why == RES_NODE_TRANSISTOR &&
|
||||
if (p1->br_this->rn_why == RES_NODE_DEVICE &&
|
||||
(p1->br_loc.p_y == BOTTOM(tile) ||
|
||||
p1->br_loc.p_y == TOP(tile)))
|
||||
{
|
||||
|
|
@ -721,7 +721,7 @@ ResCalcNearTransistor(tile, pendingList, doneList, resList)
|
|||
/* eliminate duplicate S/D pointers */
|
||||
for (p1 = junk->breakList; p1 != NULL; p1 = p1->br_next)
|
||||
{
|
||||
if (p1->br_this->rn_why == RES_NODE_TRANSISTOR &&
|
||||
if (p1->br_this->rn_why == RES_NODE_DEVICE &&
|
||||
(p1->br_loc.p_x == LEFT(tile) ||
|
||||
p1->br_loc.p_x == RIGHT(tile)))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ ResDoneWithNode(resptr)
|
|||
}
|
||||
}
|
||||
|
||||
/* Eliminations that can be only if there are no transistors connected */
|
||||
/* Eliminations that can be only if there are no devices connected */
|
||||
/* to node. Series and dangling connections fall in this group. */
|
||||
|
||||
if ((resptr->rn_te == NULL) && (resptr->rn_why != RES_NODE_ORIGIN)
|
||||
|
|
@ -219,7 +219,7 @@ ResFixParallel(elimResis,newResis)
|
|||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ResSeriesCheck -- for nodes with no transistors, sees if a series
|
||||
* ResSeriesCheck -- for nodes with no devices, sees if a series
|
||||
or loop combination is possible.
|
||||
*
|
||||
* Results: returns SINGLE,LOOP,or SERIES if succesful.
|
||||
|
|
@ -403,7 +403,7 @@ ResSeriesCheck(resptr)
|
|||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ResParallelCheck -- tries to do parallel combinations of transistors.
|
||||
* ResParallelCheck -- tries to do parallel combinations of devices.
|
||||
*
|
||||
* Results: returns PARALLEL if successful
|
||||
*
|
||||
|
|
@ -641,7 +641,7 @@ ResMergeNodes(node1,node2,pendingList,doneList)
|
|||
|
||||
{
|
||||
resElement *workingRes,*tRes;
|
||||
tElement *workingFet,*tFet;
|
||||
tElement *workingDev,*tDev;
|
||||
jElement *workingJunc,*tJunc;
|
||||
cElement *workingCon,*tCon;
|
||||
Tile *tile;
|
||||
|
|
@ -677,13 +677,13 @@ ResMergeNodes(node1,node2,pendingList,doneList)
|
|||
/* combine relevant flags */
|
||||
node1->rn_status |= (node2->rn_status & RN_MAXTDI);
|
||||
|
||||
/*merge transistor lists */
|
||||
workingFet = node2->rn_te;
|
||||
while (workingFet != NULL)
|
||||
/*merge device lists */
|
||||
workingDev = node2->rn_te;
|
||||
while (workingDev != NULL)
|
||||
{
|
||||
if (workingFet->te_thist->rt_status & RES_TRAN_PLUG)
|
||||
if (workingDev->te_thist->rd_status & RES_DEV_PLUG)
|
||||
{
|
||||
ResPlug *plug = (ResPlug *) workingFet->te_thist;
|
||||
ResPlug *plug = (ResPlug *) workingDev->te_thist;
|
||||
if (plug->rpl_node == node2)
|
||||
{
|
||||
plug->rpl_node = node1;
|
||||
|
|
@ -697,19 +697,18 @@ ResMergeNodes(node1,node2,pendingList,doneList)
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
int j;
|
||||
|
||||
for (j=0;j!= RT_TERMCOUNT;j++)
|
||||
if (workingFet->te_thist->rt_terminals[j] == node2)
|
||||
for (j = 0; j != workingDev->te_thist->rd_nterms; j++)
|
||||
if (workingDev->te_thist->rd_terminals[j] == node2)
|
||||
{
|
||||
workingFet->te_thist->rt_terminals[j] = node1;
|
||||
workingDev->te_thist->rd_terminals[j] = node1;
|
||||
}
|
||||
}
|
||||
tFet = workingFet;
|
||||
workingFet = workingFet->te_nextt;
|
||||
tFet->te_nextt = node1->rn_te;
|
||||
node1->rn_te = tFet;
|
||||
tDev = workingDev;
|
||||
workingDev = workingDev->te_nextt;
|
||||
tDev->te_nextt = node1->rn_te;
|
||||
node1->rn_te = tDev;
|
||||
}
|
||||
|
||||
/* append junction lists */
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ ResPrintExtRes(outextfile,resistors,nodename)
|
|||
{
|
||||
/*
|
||||
These names shouldn't be null; they should either be set by
|
||||
the transistor name or by the node printing routine. This
|
||||
the device name or by the node printing routine. This
|
||||
code is included in case the resistor network is printed
|
||||
before the nodes.
|
||||
*/
|
||||
|
|
@ -97,32 +97,32 @@ ResPrintExtRes(outextfile,resistors,nodename)
|
|||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ResPrintExtTran-- Print out all transistors that have had at least
|
||||
* ResPrintExtDev-- Print out all devices that have had at least
|
||||
* one terminal changed.
|
||||
*
|
||||
* Results:none
|
||||
*
|
||||
* Side Effects:prints transistor lines to output file
|
||||
* Side Effects:prints device lines to output file
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ResPrintExtTran(outextfile, transistors)
|
||||
ResPrintExtDev(outextfile, devices)
|
||||
FILE *outextfile;
|
||||
RTran *transistors;
|
||||
RDev *devices;
|
||||
{
|
||||
TileType t;
|
||||
char *subsName;
|
||||
ExtDevice *devptr;
|
||||
|
||||
for (; transistors != NULL; transistors = transistors->nextTran)
|
||||
for (; devices != NULL; devices = devices->nextDev)
|
||||
{
|
||||
if (transistors->status & TRUE)
|
||||
if (devices->status & TRUE)
|
||||
{
|
||||
if (ResOptionsFlags & ResOpt_DoExtFile)
|
||||
{
|
||||
t = transistors->layout->rt_trantype;
|
||||
t = devices->layout->rd_devtype;
|
||||
devptr = ExtCurStyle->exts_device[t];
|
||||
subsName = devptr->exts_deviceSubstrateName;
|
||||
|
||||
|
|
@ -142,22 +142,22 @@ ResPrintExtTran(outextfile, transistors)
|
|||
fprintf(outextfile,"fet %s %d %d %d %d %d %d "
|
||||
"%s \"%s\" %d %s \"%s\" %d %s \"%s\" %d %s\n",
|
||||
devptr->exts_deviceName,
|
||||
transistors->layout->rt_inside.r_ll.p_x,
|
||||
transistors->layout->rt_inside.r_ll.p_y,
|
||||
transistors->layout->rt_inside.r_ll.p_x + 1,
|
||||
transistors->layout->rt_inside.r_ll.p_y + 1,
|
||||
transistors->layout->rt_area,
|
||||
transistors->layout->rt_perim,
|
||||
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,
|
||||
transistors->gate->name,
|
||||
transistors->layout->rt_length * 2,
|
||||
transistors->rs_gattr,
|
||||
transistors->source->name,
|
||||
transistors->layout->rt_width,
|
||||
transistors->rs_sattr,
|
||||
transistors->drain->name,
|
||||
transistors->layout->rt_width,
|
||||
transistors->rs_dattr);
|
||||
devices->gate->name,
|
||||
devices->layout->rd_length * 2,
|
||||
devices->rs_gattr,
|
||||
devices->source->name,
|
||||
devices->layout->rd_width,
|
||||
devices->rs_sattr,
|
||||
devices->drain->name,
|
||||
devices->layout->rd_width,
|
||||
devices->rs_dattr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -244,7 +244,7 @@ ResPrintExtNode(outextfile, nodelist, nodename)
|
|||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ResPrintStats -- Prints out the node name, the number of transistors,
|
||||
* ResPrintStats -- Prints out the node name, the number of devices,
|
||||
* and the number of nodes for each net added. Also keeps a running
|
||||
* track of the totals.
|
||||
*
|
||||
|
|
@ -599,7 +599,7 @@ ResPrintFHRects(fp, reslist, nodename, eidx)
|
|||
* (FastHenry) file output.
|
||||
*
|
||||
* NOTE: For now, I am assuming that substrate = ground (GND).
|
||||
* However, a transistor list is passed, and it should be parsed
|
||||
* However, a device list is passed, and it should be parsed
|
||||
* for substrate devices, allowing the creation of VDD and GND
|
||||
* reference planes for both substrate and wells.
|
||||
*
|
||||
|
|
@ -614,9 +614,9 @@ ResPrintFHRects(fp, reslist, nodename, eidx)
|
|||
*/
|
||||
|
||||
void
|
||||
ResPrintReference(fp, transistors, cellDef)
|
||||
ResPrintReference(fp, devices, cellDef)
|
||||
FILE *fp;
|
||||
RTran *transistors;
|
||||
RDev *devices;
|
||||
CellDef *cellDef;
|
||||
{
|
||||
char *outfile = cellDef->cd_name;
|
||||
|
|
|
|||
|
|
@ -36,12 +36,12 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
|
||||
|
||||
/* constants defining where various fields can be found in .sim files. */
|
||||
#define RTRAN_LENGTH 4
|
||||
#define RTRAN_WIDTH 5
|
||||
#define RTRAN_TRANX 6
|
||||
#define RTRAN_TRANY 7
|
||||
#define RTRAN_ATTR 8
|
||||
#define RTRAN_NUM_ATTR 3
|
||||
#define RDEV_LENGTH 4
|
||||
#define RDEV_WIDTH 5
|
||||
#define RDEV_DEVX 6
|
||||
#define RDEV_DEVY 7
|
||||
#define RDEV_ATTR 8
|
||||
#define RDEV_NUM_ATTR 3
|
||||
#define RESNODENAME 1
|
||||
#define NODERESISTANCE 2
|
||||
#define COUPLETERMINAL1 1
|
||||
|
|
@ -80,7 +80,7 @@ ResSimNode *ResInitializeNode();
|
|||
|
||||
ResSimNode *ResOriginalNodes; /*Linked List of Nodes */
|
||||
static float lambda=1.0; /* Scale factor */
|
||||
char RTRAN_NOATTR[1]={'0'};
|
||||
char RDEV_NOATTR[1]={'0'};
|
||||
ResFixPoint *ResFixList;
|
||||
|
||||
#define nodeinit(n)\
|
||||
|
|
@ -185,7 +185,7 @@ ResReadSim(simfile,fetproc,capproc,resproc,attrproc,mergeproc)
|
|||
}
|
||||
if (fettype == -1)
|
||||
{
|
||||
TxError("Error in Reading tran line of sim file.\n");
|
||||
TxError("Error in Reading device line of sim file.\n");
|
||||
result = 1;
|
||||
}
|
||||
else if (fettype != MINFINITY)
|
||||
|
|
@ -320,29 +320,29 @@ gettokens(line,fp)
|
|||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ResSimTransistor-- Processes a transistor line from a sim file.
|
||||
* ResSimDevice-- Processes a device line from a sim file.
|
||||
*
|
||||
* Results: returns 0 if line was added correctly.
|
||||
*
|
||||
* Side Effects: Allocates transistors and adds nodes to the node hash table.
|
||||
* Side Effects: Allocates devices and adds nodes to the node hash table.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
ResSimTransistor(line,rpersquare,ttype)
|
||||
ResSimDevice(line,rpersquare,ttype)
|
||||
char line[][MAXTOKEN];
|
||||
float rpersquare;
|
||||
TileType ttype;
|
||||
|
||||
{
|
||||
RTran *transistor;
|
||||
RDev *device;
|
||||
int rvalue,i,j,k;
|
||||
char *newattr,tmpattr[MAXTOKEN];
|
||||
static int nowarning = TRUE;
|
||||
|
||||
transistor = (RTran *) mallocMagic((unsigned) (sizeof(RTran)));
|
||||
if ((line[RTRAN_WIDTH][0] == '\0') || (line[RTRAN_LENGTH][0] == '\0'))
|
||||
device = (RDev *) mallocMagic((unsigned) (sizeof(RDev)));
|
||||
if ((line[RDEV_WIDTH][0] == '\0') || (line[RDEV_LENGTH][0] == '\0'))
|
||||
{
|
||||
TxError("error in input file:\n");
|
||||
return(1);
|
||||
|
|
@ -355,23 +355,23 @@ ResSimTransistor(line,rpersquare,ttype)
|
|||
TxError("All driven nodes will be extracted\n");
|
||||
nowarning = FALSE;
|
||||
}
|
||||
transistor->resistance = MagAtof(line[RTRAN_LENGTH]) * rpersquare/MagAtof(line[RTRAN_WIDTH]);
|
||||
device->resistance = MagAtof(line[RDEV_LENGTH]) * rpersquare/MagAtof(line[RDEV_WIDTH]);
|
||||
}
|
||||
transistor->tnumber = ++Maxtnumber;
|
||||
transistor->status = FALSE;
|
||||
transistor->nextTran = ResTranList;
|
||||
transistor->location.p_x = atoi(line[RTRAN_TRANX]);
|
||||
transistor->location.p_y = atoi(line[RTRAN_TRANY]);
|
||||
transistor->rs_gattr=RTRAN_NOATTR;
|
||||
transistor->rs_sattr=RTRAN_NOATTR;
|
||||
transistor->rs_dattr=RTRAN_NOATTR;
|
||||
transistor->rs_ttype = ttype;
|
||||
device->tnumber = ++Maxtnumber;
|
||||
device->status = FALSE;
|
||||
device->nextDev = ResRDevList;
|
||||
device->location.p_x = atoi(line[RDEV_DEVX]);
|
||||
device->location.p_y = atoi(line[RDEV_DEVY]);
|
||||
device->rs_gattr=RDEV_NOATTR;
|
||||
device->rs_sattr=RDEV_NOATTR;
|
||||
device->rs_dattr=RDEV_NOATTR;
|
||||
device->rs_ttype = ttype;
|
||||
|
||||
/* sim attributes look like g=a1,a2 */
|
||||
/* ext attributes are "a1","a2" */
|
||||
/* do conversion from one to the other here */
|
||||
|
||||
for (i=RTRAN_ATTR;i < RTRAN_ATTR+RTRAN_NUM_ATTR;i++)
|
||||
for (i=RDEV_ATTR;i < RDEV_ATTR+RDEV_NUM_ATTR;i++)
|
||||
{
|
||||
if (line[i][0] == '\0') break;
|
||||
k=0;
|
||||
|
|
@ -395,18 +395,18 @@ ResSimTransistor(line,rpersquare,ttype)
|
|||
strncpy(newattr,tmpattr,k);
|
||||
switch (line[i][0])
|
||||
{
|
||||
case 'g': transistor->rs_gattr = newattr; break;
|
||||
case 's': transistor->rs_sattr = newattr; break;
|
||||
case 'd': transistor->rs_dattr = newattr; break;
|
||||
case 'g': device->rs_gattr = newattr; break;
|
||||
case 's': device->rs_sattr = newattr; break;
|
||||
case 'd': device->rs_dattr = newattr; break;
|
||||
default: TxError("Bad fet attribute\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
ResTranList = transistor;
|
||||
transistor->layout = NULL;
|
||||
rvalue = ResSimNewNode(line[GATE],GATE,transistor) +
|
||||
ResSimNewNode(line[SOURCE],SOURCE,transistor) +
|
||||
ResSimNewNode(line[DRAIN],DRAIN,transistor);
|
||||
ResRDevList = device;
|
||||
device->layout = NULL;
|
||||
rvalue = ResSimNewNode(line[GATE],GATE,device) +
|
||||
ResSimNewNode(line[SOURCE],SOURCE,device) +
|
||||
ResSimNewNode(line[DRAIN],DRAIN,device);
|
||||
|
||||
return(rvalue);
|
||||
}
|
||||
|
|
@ -425,35 +425,35 @@ ResSimTransistor(line,rpersquare,ttype)
|
|||
*/
|
||||
|
||||
int
|
||||
ResSimNewNode(line,type,transistor)
|
||||
ResSimNewNode(line,type,device)
|
||||
char line[];
|
||||
int type;
|
||||
RTran *transistor;
|
||||
RDev *device;
|
||||
|
||||
{
|
||||
HashEntry *entry;
|
||||
ResSimNode *node;
|
||||
tranPtr *tptr;
|
||||
devPtr *tptr;
|
||||
|
||||
if (line[0] == '\0')
|
||||
{
|
||||
TxError("Missing transistor connection\n");
|
||||
TxError("Missing device connection\n");
|
||||
return(1);
|
||||
}
|
||||
entry = HashFind(&ResNodeTable,line);
|
||||
node = ResInitializeNode(entry);
|
||||
tptr = (tranPtr *) mallocMagic((unsigned) (sizeof(tranPtr)));
|
||||
tptr->thisTran = transistor;
|
||||
tptr->nextTran = node->firstTran;
|
||||
node->firstTran = tptr;
|
||||
tptr = (devPtr *) mallocMagic((unsigned) (sizeof(devPtr)));
|
||||
tptr->thisDev = device;
|
||||
tptr->nextDev = node->firstDev;
|
||||
node->firstDev = tptr;
|
||||
tptr->terminal = type;
|
||||
switch(type)
|
||||
{
|
||||
case GATE: transistor->gate = node;
|
||||
case GATE: device->gate = node;
|
||||
break;
|
||||
case SOURCE: transistor->source = node;
|
||||
case SOURCE: device->source = node;
|
||||
break;
|
||||
case DRAIN: transistor->drain = node;
|
||||
case DRAIN: device->drain = node;
|
||||
break;
|
||||
default: TxError("Bad Terminal Specifier\n");
|
||||
break;
|
||||
|
|
@ -806,7 +806,7 @@ ResSimMerge(line)
|
|||
|
||||
{
|
||||
ResSimNode *node;
|
||||
tranPtr *ptr;
|
||||
devPtr *ptr;
|
||||
|
||||
if ((line[ALIASNAME][0] == '\0') || (line[REALNAME][0] == '\0'))
|
||||
{
|
||||
|
|
@ -818,12 +818,12 @@ ResSimMerge(line)
|
|||
node->forward = ResInitializeNode(HashFind(&ResNodeTable,line[REALNAME]));
|
||||
node->forward->resistance += node->resistance;
|
||||
node->forward->capacitance += node->capacitance;
|
||||
while (node->firstTran != NULL)
|
||||
while (node->firstDev != NULL)
|
||||
{
|
||||
ptr=node->firstTran;
|
||||
node->firstTran = node->firstTran->nextTran;
|
||||
ptr->nextTran = node->forward->firstTran;
|
||||
node->forward->firstTran = ptr;
|
||||
ptr=node->firstDev;
|
||||
node->firstDev = node->firstDev->nextDev;
|
||||
ptr->nextDev = node->forward->firstDev;
|
||||
node->forward->firstDev = ptr;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -860,7 +860,7 @@ ResInitializeNode(entry)
|
|||
node->cap_couple = 0;
|
||||
node->resistance = 0;
|
||||
node->type = 0;
|
||||
node->firstTran = NULL;
|
||||
node->firstDev = NULL;
|
||||
node->name = entry->h_key.h_name;
|
||||
node->oldname = NULL;
|
||||
node->drivepoint.p_x = INFINITY;
|
||||
|
|
|
|||
266
resis/ResRex.c
266
resis/ResRex.c
|
|
@ -45,11 +45,11 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
|
||||
|
||||
HashTable ResNodeTable; /* Hash table of sim file nodes */
|
||||
RTran *ResTranList; /* Linked list of Sim transistors */
|
||||
RDev *ResRDevList; /* Linked list of Sim devices */
|
||||
ResGlobalParams gparams; /* Junk passed between */
|
||||
/* ResCheckSimNodes and */
|
||||
/* ResExtractNet. */
|
||||
int Maxtnumber; /*maximum transistor number */
|
||||
int Maxtnumber; /*maximum device number */
|
||||
extern ResSimNode *ResOriginalNodes; /*Linked List of Nodes */
|
||||
int resNodeNum;
|
||||
|
||||
|
|
@ -94,21 +94,21 @@ ExtResisForDef(celldef, resisdata)
|
|||
CellDef *celldef;
|
||||
ResisData *resisdata;
|
||||
{
|
||||
RTran *oldTran;
|
||||
RDev *oldRDev;
|
||||
HashSearch hs;
|
||||
HashEntry *entry;
|
||||
tranPtr *tptr,*oldtptr;
|
||||
devPtr *tptr,*oldtptr;
|
||||
ResSimNode *node;
|
||||
int result;
|
||||
|
||||
ResTranList = NULL;
|
||||
ResRDevList = NULL;
|
||||
ResOriginalNodes = NULL;
|
||||
|
||||
Maxtnumber = 0;
|
||||
HashInit(&ResNodeTable, INITFLATSIZE, HT_STRINGKEYS);
|
||||
/* read in .sim file */
|
||||
result = (ResReadSim(celldef->cd_name,
|
||||
ResSimTransistor,ResSimCapacitor,ResSimResistor,
|
||||
ResSimDevice,ResSimCapacitor,ResSimResistor,
|
||||
ResSimAttribute,ResSimMerge) == 0);
|
||||
|
||||
if (result)
|
||||
|
|
@ -138,7 +138,7 @@ ExtResisForDef(celldef, resisdata)
|
|||
while((entry = HashNext(&ResNodeTable,&hs)) != NULL)
|
||||
{
|
||||
node=(ResSimNode *) HashGetValue(entry);
|
||||
tptr = node->firstTran;
|
||||
tptr = node->firstDev;
|
||||
if (node == NULL)
|
||||
{
|
||||
TxError("Error: NULL Hash entry!\n");
|
||||
|
|
@ -147,22 +147,22 @@ ExtResisForDef(celldef, resisdata)
|
|||
while (tptr != NULL)
|
||||
{
|
||||
oldtptr = tptr;
|
||||
tptr = tptr->nextTran;
|
||||
tptr = tptr->nextDev;
|
||||
freeMagic((char *)oldtptr);
|
||||
}
|
||||
freeMagic((char *) node);
|
||||
}
|
||||
HashKill(&ResNodeTable);
|
||||
while (ResTranList != NULL)
|
||||
while (ResRDevList != NULL)
|
||||
{
|
||||
oldTran = ResTranList;
|
||||
ResTranList = ResTranList->nextTran;
|
||||
if (oldTran->layout != NULL)
|
||||
oldRDev = ResRDevList;
|
||||
ResRDevList = ResRDevList->nextDev;
|
||||
if (oldRDev->layout != NULL)
|
||||
{
|
||||
freeMagic((char *)oldTran->layout);
|
||||
oldTran->layout = NULL;
|
||||
freeMagic((char *)oldRDev->layout);
|
||||
oldRDev->layout = NULL;
|
||||
}
|
||||
freeMagic((char *)oldTran);
|
||||
freeMagic((char *)oldRDev);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -206,7 +206,7 @@ CmdExtResis(win, cmd)
|
|||
|
||||
static char *cmdExtresisCmd[] =
|
||||
{
|
||||
"tolerance [value] set ratio between resistor and transistor tol.",
|
||||
"tolerance [value] set ratio between resistor and device tol.",
|
||||
"all extract all the nets",
|
||||
"simplify [on/off] turn on/off simplification of resistor nets",
|
||||
"extout [on/off] turn on/off writing of .res.ext file",
|
||||
|
|
@ -448,7 +448,7 @@ typedef enum {
|
|||
if (cmd->tx_argc != 3) return;
|
||||
tt = DBTechNoisyNameType(cmd->tx_argv[2]);
|
||||
if (tt <= 0 || ToolGetBox(&def, &rect)== FALSE) return;
|
||||
gparams.rg_tranloc = &rect.r_ll;
|
||||
gparams.rg_devloc = &rect.r_ll;
|
||||
gparams.rg_ttype = tt;
|
||||
gparams.rg_status = DRIVEONLY;
|
||||
oldoptions = ResOptionsFlags;
|
||||
|
|
@ -463,7 +463,7 @@ typedef enum {
|
|||
fp.fp_next = NULL;
|
||||
if (ResExtractNet(&fp, &gparams, NULL) != 0) return;
|
||||
ResPrintResistorList(stdout,ResResList);
|
||||
ResPrintTransistorList(stdout,ResTransList);
|
||||
ResPrintDeviceList(stdout,ResRDevList);
|
||||
#ifdef LAPLACE
|
||||
if (ResOptionsFlags & ResOpt_DoLaplace)
|
||||
{
|
||||
|
|
@ -722,7 +722,7 @@ ResCheckBlackbox(cellDef)
|
|||
*
|
||||
* Subcircuit boundaries mark an area which is to be checked
|
||||
* explicitly for geometry information. Because there may be
|
||||
* no transistors in the subcircuit cell, we must find the ports
|
||||
* no devices in the subcircuit cell, we must find the ports
|
||||
* into the subcircuit and declare them to be "driving" nodes so
|
||||
* the extresis algorithm will treat them as being part of valid
|
||||
* networks.
|
||||
|
|
@ -806,7 +806,7 @@ ResCheckPorts(cellDef)
|
|||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ResCheckSimNodes-- check to see if lumped resistance is greater than the
|
||||
* transistor resistance; if it is, Extract the net
|
||||
* device resistance; if it is, Extract the net
|
||||
* resistance. If the maximum point to point resistance
|
||||
* in the extracted net is still creater than the
|
||||
* tolerance, then output the extracted net.
|
||||
|
|
@ -824,7 +824,7 @@ ResCheckSimNodes(celldef, resisdata)
|
|||
ResisData *resisdata;
|
||||
{
|
||||
ResSimNode *node;
|
||||
tranPtr *ptr;
|
||||
devPtr *ptr;
|
||||
float ftolerance, rctolerance, minRes, cumRes;
|
||||
int failed1=0;
|
||||
int failed3=0;
|
||||
|
|
@ -876,7 +876,7 @@ ResCheckSimNodes(celldef, resisdata)
|
|||
*/
|
||||
if (ResOptionsFlags & ResOpt_FastHenry)
|
||||
{
|
||||
ResPrintReference(ResFHFile, ResTranList, celldef);
|
||||
ResPrintReference(ResFHFile, ResRDevList, celldef);
|
||||
}
|
||||
|
||||
for (node = ResOriginalNodes; node != NULL; node=node->nextnode)
|
||||
|
|
@ -913,11 +913,11 @@ ResCheckSimNodes(celldef, resisdata)
|
|||
continue;
|
||||
total++;
|
||||
|
||||
ResSortByGate(&node->firstTran);
|
||||
/* Find largest SD transistor connected to node. */
|
||||
ResSortByGate(&node->firstDev);
|
||||
/* Find largest SD device connected to node. */
|
||||
|
||||
minRes = FLT_MAX;
|
||||
gparams.rg_tranloc = (Point *) NULL;
|
||||
gparams.rg_devloc = (Point *) NULL;
|
||||
gparams.rg_status = FALSE;
|
||||
gparams.rg_nodecap = node->capacitance;
|
||||
|
||||
|
|
@ -925,10 +925,10 @@ ResCheckSimNodes(celldef, resisdata)
|
|||
/* to identify which tile the drivepoint is on. */
|
||||
gparams.rg_ttype = node->rs_ttype;
|
||||
|
||||
for (ptr = node->firstTran; ptr != NULL; ptr=ptr->nextTran)
|
||||
for (ptr = node->firstDev; ptr != NULL; ptr=ptr->nextDev)
|
||||
{
|
||||
RTran *t1;
|
||||
RTran *t2;
|
||||
RDev *t1;
|
||||
RDev *t2;
|
||||
|
||||
if (ptr->terminal == GATE)
|
||||
{
|
||||
|
|
@ -936,14 +936,14 @@ ResCheckSimNodes(celldef, resisdata)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* get cumulative resistance of all transistors */
|
||||
/* get cumulative resistance of all devices */
|
||||
/* with same connections. */
|
||||
cumRes = ptr->thisTran->resistance;
|
||||
t1 = ptr->thisTran;
|
||||
for (; ptr->nextTran != NULL; ptr = ptr->nextTran)
|
||||
cumRes = ptr->thisDev->resistance;
|
||||
t1 = ptr->thisDev;
|
||||
for (; ptr->nextDev != NULL; ptr = ptr->nextDev)
|
||||
{
|
||||
t1 = ptr->thisTran;
|
||||
t2 = ptr->nextTran->thisTran;
|
||||
t1 = ptr->thisDev;
|
||||
t2 = ptr->nextDev->thisDev;
|
||||
if (t1->gate != t2->gate) break;
|
||||
if ((t1->source != t2->source ||
|
||||
t1->drain != t2->drain) &&
|
||||
|
|
@ -964,7 +964,7 @@ ResCheckSimNodes(celldef, resisdata)
|
|||
if (minRes > cumRes)
|
||||
{
|
||||
minRes = cumRes;
|
||||
gparams.rg_tranloc = &t1->location;
|
||||
gparams.rg_devloc = &t1->location;
|
||||
gparams.rg_ttype = t1->rs_ttype;
|
||||
}
|
||||
}
|
||||
|
|
@ -985,26 +985,26 @@ ResCheckSimNodes(celldef, resisdata)
|
|||
}
|
||||
if (node->status & DRIVELOC)
|
||||
{
|
||||
gparams.rg_tranloc = &node->drivepoint;
|
||||
gparams.rg_devloc = &node->drivepoint;
|
||||
gparams.rg_status |= DRIVEONLY;
|
||||
}
|
||||
if (node->status & PORTNODE)
|
||||
{
|
||||
/* The node is a port, not a transistor, so make */
|
||||
/* The node is a port, not a device, so make */
|
||||
/* sure rg_ttype is set accordingly. */
|
||||
gparams.rg_ttype = node->rs_ttype;
|
||||
}
|
||||
}
|
||||
if (gparams.rg_tranloc == NULL && node->status & FORCE)
|
||||
if (gparams.rg_devloc == NULL && node->status & FORCE)
|
||||
{
|
||||
TxError("Node %s has force label but no drive point or "
|
||||
"driving transistor\n",node->name);
|
||||
"driving device\n",node->name);
|
||||
}
|
||||
if (minRes == FLT_MAX || gparams.rg_tranloc == NULL)
|
||||
if (minRes == FLT_MAX || gparams.rg_devloc == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
gparams.rg_bigtranres = (int)minRes*OHMSTOMILLIOHMS;
|
||||
gparams.rg_bigdevres = (int)minRes*OHMSTOMILLIOHMS;
|
||||
if (rctol == 0.0 || tol == 0.0)
|
||||
{
|
||||
ftolerance = 0.0;
|
||||
|
|
@ -1017,7 +1017,7 @@ ResCheckSimNodes(celldef, resisdata)
|
|||
}
|
||||
|
||||
/*
|
||||
* Is the transistor resistance greater than the lumped node
|
||||
* Is the device resistance greater than the lumped node
|
||||
* resistance? If so, extract net.
|
||||
*/
|
||||
|
||||
|
|
@ -1052,20 +1052,20 @@ ResCheckSimNodes(celldef, resisdata)
|
|||
}
|
||||
}
|
||||
#ifdef PARANOID
|
||||
ResSanityChecks(node->name,ResResList,ResNodeList,ResTransList);
|
||||
ResSanityChecks(node->name,ResResList,ResNodeList,ResDevList);
|
||||
#endif
|
||||
ResCleanUpEverything();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print out all transistors which have had at least one terminal changed
|
||||
* Print out all device which have had at least one terminal changed
|
||||
* by resistance extraction.
|
||||
*/
|
||||
|
||||
if (ResOptionsFlags & ResOpt_DoExtFile)
|
||||
{
|
||||
ResPrintExtTran(ResExtFile,ResTranList);
|
||||
ResPrintExtDev(ResExtFile,ResRDevList);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1132,21 +1132,21 @@ ResCheckSimNodes(celldef, resisdata)
|
|||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ResFixUpConnections-- Changes the connection to a terminal of the sim
|
||||
* transistor. The new name is formed by appending .t# to the old name.
|
||||
* device. The new name is formed by appending .t# to the old name.
|
||||
* The new name is added to the hash table of node names.
|
||||
*
|
||||
* Results:none
|
||||
*
|
||||
* Side Effects: Allocates new ResSimNodes. Modifies the terminal connections
|
||||
* of sim Transistors.
|
||||
* of sim Devices.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ResFixUpConnections(simTran, layoutTran, simNode, nodename)
|
||||
RTran *simTran;
|
||||
resTransistor *layoutTran;
|
||||
ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
||||
RDev *simDev;
|
||||
resDevice *layoutDev;
|
||||
ResSimNode *simNode;
|
||||
char *nodename;
|
||||
|
||||
|
|
@ -1162,12 +1162,12 @@ ResFixUpConnections(simTran, layoutTran, simNode, nodename)
|
|||
{
|
||||
return;
|
||||
}
|
||||
if (simTran->layout == NULL)
|
||||
if (simDev->layout == NULL)
|
||||
{
|
||||
layoutTran->rt_status |= RES_TRAN_SAVE;
|
||||
simTran->layout = layoutTran;
|
||||
layoutDev->rd_status |= RES_DEV_SAVE;
|
||||
simDev->layout = layoutDev;
|
||||
}
|
||||
simTran->status |= TRUE;
|
||||
simDev->status |= TRUE;
|
||||
if (strcmp(nodename,oldnodename) != 0)
|
||||
{
|
||||
strcpy(oldnodename,nodename);
|
||||
|
|
@ -1175,11 +1175,11 @@ ResFixUpConnections(simTran, layoutTran, simNode, nodename)
|
|||
(void)sprintf(newname,"%s%s%d",nodename,".t",resNodeNum++);
|
||||
notdecremented = TRUE;
|
||||
|
||||
if (simTran->gate == simNode)
|
||||
if (simDev->gate == simNode)
|
||||
{
|
||||
if ((gate=layoutTran->rt_gate) != NULL)
|
||||
if ((gate=layoutDev->rd_fet_gate) != NULL)
|
||||
{
|
||||
/* cosmetic addition: If the layout tran already has a */
|
||||
/* cosmetic addition: If the layout device already has a */
|
||||
/* name, the new one won't be used, so we decrement resNodeNum */
|
||||
if (gate->rn_name != NULL)
|
||||
{
|
||||
|
|
@ -1187,8 +1187,8 @@ ResFixUpConnections(simTran, layoutTran, simNode, nodename)
|
|||
notdecremented = FALSE;
|
||||
}
|
||||
|
||||
ResFixTranName(newname,GATE,simTran,gate);
|
||||
gate->rn_name = simTran->gate->name;
|
||||
ResFixDevName(newname,GATE,simDev,gate);
|
||||
gate->rn_name = simDev->gate->name;
|
||||
(void)sprintf(newname,"%s%s%d",nodename,".t",resNodeNum++);
|
||||
}
|
||||
else
|
||||
|
|
@ -1196,24 +1196,24 @@ ResFixUpConnections(simTran, layoutTran, simNode, nodename)
|
|||
TxError("Missing gate connection\n");
|
||||
}
|
||||
}
|
||||
if (simTran->source == simNode)
|
||||
if (simDev->source == simNode)
|
||||
{
|
||||
if (simTran->drain == simNode)
|
||||
if (simDev->drain == simNode)
|
||||
{
|
||||
if ((source=layoutTran->rt_source) &&
|
||||
(drain=layoutTran->rt_drain))
|
||||
if ((source=layoutDev->rd_fet_source) &&
|
||||
(drain=layoutDev->rd_fet_drain))
|
||||
{
|
||||
if (source->rn_name != NULL && notdecremented)
|
||||
{
|
||||
resNodeNum--;
|
||||
notdecremented = FALSE;
|
||||
}
|
||||
ResFixTranName(newname,SOURCE,simTran,source);
|
||||
source->rn_name = simTran->source->name;
|
||||
ResFixDevName(newname,SOURCE,simDev,source);
|
||||
source->rn_name = simDev->source->name;
|
||||
(void)sprintf(newname,"%s%s%d",nodename,".t",resNodeNum++);
|
||||
if (drain->rn_name != NULL) resNodeNum--;
|
||||
ResFixTranName(newname,DRAIN,simTran,drain);
|
||||
drain->rn_name = simTran->drain->name;
|
||||
ResFixDevName(newname,DRAIN,simDev,drain);
|
||||
drain->rn_name = simDev->drain->name;
|
||||
/* one to each */
|
||||
}
|
||||
else
|
||||
|
|
@ -1223,9 +1223,9 @@ ResFixUpConnections(simTran, layoutTran, simNode, nodename)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (source=layoutTran->rt_source)
|
||||
if (source=layoutDev->rd_fet_source)
|
||||
{
|
||||
if (drain=layoutTran->rt_drain)
|
||||
if (drain=layoutDev->rd_fet_drain)
|
||||
{
|
||||
if (source != drain)
|
||||
{
|
||||
|
|
@ -1244,10 +1244,10 @@ ResFixUpConnections(simTran, layoutTran, simNode, nodename)
|
|||
drain = source;
|
||||
}
|
||||
}
|
||||
layoutTran->rt_drain = (resNode *)NULL;
|
||||
layoutDev->rd_fet_drain = (resNode *)NULL;
|
||||
if (source->rn_name != NULL) resNodeNum--;
|
||||
ResFixTranName(newname,SOURCE,simTran,source);
|
||||
source->rn_name = simTran->source->name;
|
||||
ResFixDevName(newname,SOURCE,simDev,source);
|
||||
source->rn_name = simDev->source->name;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1256,8 +1256,8 @@ ResFixUpConnections(simTran, layoutTran, simNode, nodename)
|
|||
resNodeNum--;
|
||||
notdecremented = FALSE;
|
||||
}
|
||||
ResFixTranName(newname,SOURCE,simTran,source);
|
||||
source->rn_name = simTran->source->name;
|
||||
ResFixDevName(newname,SOURCE,simDev,source);
|
||||
source->rn_name = simDev->source->name;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1267,11 +1267,11 @@ ResFixUpConnections(simTran, layoutTran, simNode, nodename)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (simTran->drain == simNode)
|
||||
else if (simDev->drain == simNode)
|
||||
{
|
||||
if (source=layoutTran->rt_source)
|
||||
if (source=layoutDev->rd_fet_source)
|
||||
{
|
||||
if (drain=layoutTran->rt_drain)
|
||||
if (drain=layoutDev->rd_fet_drain)
|
||||
{
|
||||
if (drain != source)
|
||||
{
|
||||
|
|
@ -1290,14 +1290,14 @@ ResFixUpConnections(simTran, layoutTran, simNode, nodename)
|
|||
drain = source;
|
||||
}
|
||||
}
|
||||
layoutTran->rt_source = (resNode *) NULL;
|
||||
layoutDev->rd_fet_source = (resNode *) NULL;
|
||||
if (drain->rn_name != NULL)
|
||||
{
|
||||
resNodeNum--;
|
||||
notdecremented = FALSE;
|
||||
}
|
||||
ResFixTranName(newname, DRAIN, simTran, drain);
|
||||
drain->rn_name = simTran->drain->name;
|
||||
ResFixDevName(newname, DRAIN, simDev, drain);
|
||||
drain->rn_name = simDev->drain->name;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1306,8 +1306,8 @@ ResFixUpConnections(simTran, layoutTran, simNode, nodename)
|
|||
resNodeNum--;
|
||||
notdecremented = FALSE;
|
||||
}
|
||||
ResFixTranName(newname,DRAIN,simTran,source);
|
||||
source->rn_name = simTran->drain->name;
|
||||
ResFixDevName(newname,DRAIN,simDev,source);
|
||||
source->rn_name = simDev->drain->name;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1325,27 +1325,27 @@ ResFixUpConnections(simTran, layoutTran, simNode, nodename)
|
|||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ResFixTranName-- Moves transistor connection to new node.
|
||||
* ResFixDevName-- Moves device connection to new node.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side Effects: May create a new node. Creates a new transistor pointer.
|
||||
* Side Effects: May create a new node. Creates a new device pointer.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ResFixTranName(line,type,transistor,layoutnode)
|
||||
ResFixDevName(line,type,device,layoutnode)
|
||||
char line[];
|
||||
int type;
|
||||
RTran *transistor;
|
||||
RDev *device;
|
||||
resNode *layoutnode;
|
||||
|
||||
{
|
||||
HashEntry *entry;
|
||||
ResSimNode *node;
|
||||
tranPtr *tptr;
|
||||
devPtr *tptr;
|
||||
|
||||
if (layoutnode->rn_name != NULL)
|
||||
{
|
||||
|
|
@ -1358,24 +1358,24 @@ ResFixTranName(line,type,transistor,layoutnode)
|
|||
entry = HashFind(&ResNodeTable,line);
|
||||
node = ResInitializeNode(entry);
|
||||
}
|
||||
tptr = (tranPtr *) mallocMagic((unsigned) (sizeof(tranPtr)));
|
||||
tptr->thisTran = transistor;
|
||||
tptr->nextTran = node->firstTran;
|
||||
node->firstTran = tptr;
|
||||
tptr = (devPtr *) mallocMagic((unsigned) (sizeof(devPtr)));
|
||||
tptr->thisDev = device;
|
||||
tptr->nextDev = node->firstDev;
|
||||
node->firstDev = tptr;
|
||||
tptr->terminal = type;
|
||||
switch(type)
|
||||
{
|
||||
case GATE:
|
||||
node->oldname = transistor->gate->name;
|
||||
transistor->gate = node;
|
||||
node->oldname = device->gate->name;
|
||||
device->gate = node;
|
||||
break;
|
||||
case SOURCE:
|
||||
node->oldname = transistor->source->name;
|
||||
transistor->source = node;
|
||||
node->oldname = device->source->name;
|
||||
device->source = node;
|
||||
break;
|
||||
case DRAIN:
|
||||
node->oldname = transistor->drain->name;
|
||||
transistor->drain = node;
|
||||
node->oldname = device->drain->name;
|
||||
device->drain = node;
|
||||
break;
|
||||
default:
|
||||
TxError("Bad Terminal Specifier\n");
|
||||
|
|
@ -1387,59 +1387,59 @@ ResFixTranName(line,type,transistor,layoutnode)
|
|||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ResSortByGate--sorts transistor pointers whose terminal field is either
|
||||
* ResSortByGate--sorts device pointers whose terminal field is either
|
||||
* drain or source by gate node number, then by drain (source) number.
|
||||
* This places transistors with identical connections next to one
|
||||
* This places devices with identical connections next to one
|
||||
* another.
|
||||
*
|
||||
* Results: none
|
||||
*
|
||||
* Side Effects: modifies order of transistors
|
||||
* Side Effects: modifies order of devices
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ResSortByGate(TranpointerList)
|
||||
tranPtr **TranpointerList;
|
||||
ResSortByGate(DevpointerList)
|
||||
devPtr **DevpointerList;
|
||||
{
|
||||
int changed=TRUE;
|
||||
int localchange=TRUE;
|
||||
tranPtr *working, *last=NULL, *current, *gatelist=NULL;
|
||||
devPtr *working, *last=NULL, *current, *gatelist=NULL;
|
||||
|
||||
working = *TranpointerList;
|
||||
working = *DevpointerList;
|
||||
while (working != NULL)
|
||||
{
|
||||
if (working->terminal == GATE)
|
||||
{
|
||||
current = working;
|
||||
working = working->nextTran;
|
||||
working = working->nextDev;
|
||||
if (last == NULL)
|
||||
{
|
||||
*TranpointerList = working;
|
||||
*DevpointerList = working;
|
||||
}
|
||||
else
|
||||
{
|
||||
last->nextTran = working;
|
||||
last->nextDev = working;
|
||||
}
|
||||
current->nextTran = gatelist;
|
||||
current->nextDev = gatelist;
|
||||
gatelist = current;
|
||||
}
|
||||
else
|
||||
{
|
||||
last = working;
|
||||
working = working->nextTran;
|
||||
working = working->nextDev;
|
||||
}
|
||||
}
|
||||
while (changed == TRUE)
|
||||
{
|
||||
changed = localchange = FALSE;
|
||||
working = *TranpointerList;
|
||||
working = *DevpointerList;
|
||||
last = NULL;
|
||||
while (working != NULL && (current = working->nextTran) != NULL)
|
||||
while (working != NULL && (current = working->nextDev) != NULL)
|
||||
{
|
||||
RTran *w = working->thisTran;
|
||||
RTran *c = current->thisTran;
|
||||
RDev *w = working->thisDev;
|
||||
RDev *c = current->thisDev;
|
||||
|
||||
if (w->gate > c->gate)
|
||||
{
|
||||
|
|
@ -1466,7 +1466,7 @@ ResSortByGate(TranpointerList)
|
|||
else
|
||||
{
|
||||
last = working;
|
||||
working = working->nextTran;
|
||||
working = working->nextDev;
|
||||
continue;
|
||||
}
|
||||
if (localchange)
|
||||
|
|
@ -1474,31 +1474,31 @@ ResSortByGate(TranpointerList)
|
|||
localchange = FALSE;
|
||||
if (last == NULL)
|
||||
{
|
||||
*TranpointerList = current;
|
||||
*DevpointerList = current;
|
||||
}
|
||||
else
|
||||
{
|
||||
last->nextTran = current;
|
||||
last->nextDev = current;
|
||||
}
|
||||
working->nextTran = current->nextTran;
|
||||
current->nextTran = working;
|
||||
working->nextDev = current->nextDev;
|
||||
current->nextDev = working;
|
||||
last = current;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (working == NULL)
|
||||
{
|
||||
*TranpointerList = gatelist;
|
||||
*DevpointerList = gatelist;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (working->nextTran != NULL)
|
||||
if (working->nextDev != NULL)
|
||||
{
|
||||
TxError("Bad Transistor pointer in sort\n");
|
||||
TxError("Bad Device pointer in sort\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
working->nextTran = gatelist;
|
||||
working->nextDev = gatelist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1527,7 +1527,7 @@ ResWriteLumpFile(node)
|
|||
if (gparams.rg_nodecap != 0)
|
||||
{
|
||||
lumpedres = (int)((gparams.rg_Tdi/gparams.rg_nodecap
|
||||
-(float)(gparams.rg_bigtranres))/OHMSTOMILLIOHMS);
|
||||
-(float)(gparams.rg_bigdevres))/OHMSTOMILLIOHMS);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1619,36 +1619,36 @@ ResWriteExtFile(celldef, node, tol, rctol, nidx, eidx)
|
|||
float tol, rctol;
|
||||
int *nidx, *eidx;
|
||||
{
|
||||
float RCtran;
|
||||
float RCdev;
|
||||
char *cp, newname[MAXNAME];
|
||||
tranPtr *ptr;
|
||||
resTransistor *layoutFet, *ResGetTransistor();
|
||||
devPtr *ptr;
|
||||
resDevice *layoutDev, *ResGetDevice();
|
||||
|
||||
RCtran = gparams.rg_bigtranres * gparams.rg_nodecap;
|
||||
RCdev = gparams.rg_bigdevres * gparams.rg_nodecap;
|
||||
|
||||
if (tol == 0.0 ||(node->status & FORCE) ||
|
||||
(ResOptionsFlags & ResOpt_ExtractAll)||
|
||||
(ResOptionsFlags & ResOpt_Simplify)==0||
|
||||
(rctol+1)*RCtran < rctol*gparams.rg_Tdi)
|
||||
(rctol+1)*RCdev < rctol*gparams.rg_Tdi)
|
||||
{
|
||||
ASSERT(gparams.rg_Tdi != -1,"ResWriteExtFile");
|
||||
(void)sprintf(newname,"%s",node->name);
|
||||
cp = newname+strlen(newname)-1;
|
||||
if (*cp == '!' || *cp == '#') *cp = '\0';
|
||||
if ((rctol+1)*RCtran < rctol*gparams.rg_Tdi ||
|
||||
if ((rctol+1)*RCdev < rctol*gparams.rg_Tdi ||
|
||||
(ResOptionsFlags & ResOpt_Tdi) == 0)
|
||||
{
|
||||
if ((ResOptionsFlags & (ResOpt_RunSilent|ResOpt_Tdi)) == ResOpt_Tdi)
|
||||
{
|
||||
TxError("Adding %s; Tnew = %.2fns,Told = %.2fns\n",
|
||||
node->name,gparams.rg_Tdi/Z_TO_N, RCtran/Z_TO_N);
|
||||
node->name,gparams.rg_Tdi/Z_TO_N, RCdev/Z_TO_N);
|
||||
}
|
||||
}
|
||||
for (ptr = node->firstTran; ptr != NULL; ptr=ptr->nextTran)
|
||||
for (ptr = node->firstDev; ptr != NULL; ptr=ptr->nextDev)
|
||||
{
|
||||
if (layoutFet = ResGetTransistor(&ptr->thisTran->location))
|
||||
if (layoutDev = ResGetDevice(&ptr->thisDev->location))
|
||||
{
|
||||
ResFixUpConnections(ptr->thisTran,layoutFet,node,newname);
|
||||
ResFixUpConnections(ptr->thisDev,layoutDev,node,newname);
|
||||
}
|
||||
}
|
||||
if (ResOptionsFlags & ResOpt_DoExtFile)
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ int resRemoveLoops = FALSE;
|
|||
|
||||
/* Forward declarations */
|
||||
|
||||
extern void ResMoveTransistors();
|
||||
extern void ResMoveDevices();
|
||||
extern void ResAddResistorToList();
|
||||
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ extern void ResAddResistorToList();
|
|||
*
|
||||
* Results: none
|
||||
*
|
||||
* Side Effects: Can eliminate nodes and resistors, and move transistors from
|
||||
* Side Effects: Can eliminate nodes and resistors, and move devices from
|
||||
* one node to another.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
|
|
@ -233,7 +233,7 @@ ResSimplifyNet(nodelist,biglist,reslist,tolerance)
|
|||
|
||||
}
|
||||
/*
|
||||
Two resistors in series? Combine them and move transistors to
|
||||
Two resistors in series? Combine them and move devices to
|
||||
appropriate end.
|
||||
*/
|
||||
else if (numdrive+numreceive == 2 &&
|
||||
|
|
@ -260,10 +260,10 @@ ResSimplifyNet(nodelist,biglist,reslist,tolerance)
|
|||
|
||||
/*
|
||||
make one big resistor out of two little ones, eliminating
|
||||
the current node. Transistors connected to this node are
|
||||
the current node. Devices connected to this node are
|
||||
moved to either end depending on their resistance.
|
||||
*/
|
||||
ResMoveTransistors(node,otherNode);
|
||||
ResMoveDevices(node,otherNode);
|
||||
otherNode->rn_noderes = MIN(node->rn_noderes,otherNode->rn_noderes);
|
||||
node2->rn_float.rn_area += resistor1->rr_value*node->rn_float.rn_area/(resistor1->rr_value+resistor2->rr_value);
|
||||
node1->rn_float.rn_area += resistor2->rr_value*node->rn_float.rn_area/(resistor1->rr_value+resistor2->rr_value);
|
||||
|
|
@ -380,34 +380,34 @@ ResSimplifyNet(nodelist,biglist,reslist,tolerance)
|
|||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ResMoveTransistors-- move transistors from one node1 to node2
|
||||
* ResMoveDevices-- move devices from one node1 to node2
|
||||
*
|
||||
* Results: none
|
||||
*
|
||||
* Side Effects: Changes transistor connections and node tElements.
|
||||
* Side Effects: Changes device connections and node tElements.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ResMoveTransistors(node1,node2)
|
||||
ResMoveDevices(node1,node2)
|
||||
resNode *node1,*node2;
|
||||
|
||||
{
|
||||
tElement *tranptr,*oldptr;
|
||||
resTransistor *transistor;
|
||||
tElement *devptr,*oldptr;
|
||||
resDevice *device;
|
||||
|
||||
tranptr = node1->rn_te;
|
||||
while (tranptr != NULL)
|
||||
devptr = node1->rn_te;
|
||||
while (devptr != NULL)
|
||||
{
|
||||
transistor = tranptr->te_thist;
|
||||
oldptr = tranptr;
|
||||
tranptr = tranptr->te_nextt;
|
||||
if (transistor->rt_status & RES_TRAN_PLUG)
|
||||
device = devptr->te_thist;
|
||||
oldptr = devptr;
|
||||
devptr = devptr->te_nextt;
|
||||
if (device->rd_status & RES_DEV_PLUG)
|
||||
{
|
||||
if (((ResPlug *)(transistor))->rpl_node == node1)
|
||||
if (((ResPlug *)(device))->rpl_node == node1)
|
||||
{
|
||||
((ResPlug *)(transistor))->rpl_node = node2;
|
||||
((ResPlug *)(device))->rpl_node = node2;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -416,21 +416,21 @@ ResMoveTransistors(node1,node2)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (transistor->rt_gate == node1)
|
||||
if (device->rd_fet_gate == node1)
|
||||
{
|
||||
transistor->rt_gate = node2;
|
||||
device->rd_fet_gate = node2;
|
||||
}
|
||||
else if (transistor->rt_source == node1)
|
||||
else if (device->rd_fet_source == node1)
|
||||
{
|
||||
transistor->rt_source = node2;
|
||||
device->rd_fet_source = node2;
|
||||
}
|
||||
else if (transistor->rt_drain == node1)
|
||||
else if (device->rd_fet_drain == node1)
|
||||
{
|
||||
transistor->rt_drain = node2;
|
||||
device->rd_fet_drain = node2;
|
||||
}
|
||||
else
|
||||
{
|
||||
TxError("Missing Transistor connection in squish routines at %d, %d\n",node1->rn_loc.p_x,node1->rn_loc.p_y);
|
||||
TxError("Missing Device connection in squish routines at %d, %d\n",node1->rn_loc.p_x,node1->rn_loc.p_y);
|
||||
}
|
||||
}
|
||||
oldptr->te_nextt = node2->rn_te;
|
||||
|
|
@ -728,7 +728,7 @@ ResCalculateChildCapacitance(me)
|
|||
{
|
||||
RCDelayStuff *myC;
|
||||
resElement *workingRes;
|
||||
resTransistor *tran;
|
||||
resDevice *dev;
|
||||
float childcap;
|
||||
tElement *tptr;
|
||||
int t;
|
||||
|
|
@ -749,16 +749,16 @@ ResCalculateChildCapacitance(me)
|
|||
/* get capacitance for all connected gates */
|
||||
for (tptr = me->rn_te; tptr != NULL; tptr = tptr->te_nextt)
|
||||
{
|
||||
tran = tptr->te_thist;
|
||||
t = TiGetType(tran->rt_tile);
|
||||
if (tran->rt_gate == me)
|
||||
dev = tptr->te_thist;
|
||||
t = TiGetType(dev->rd_tile);
|
||||
if (dev->rd_fet_gate == me)
|
||||
{
|
||||
devptr = ExtCurStyle->exts_device[t];
|
||||
myC->rc_Cdownstream +=
|
||||
tran->rt_length*
|
||||
tran->rt_width*
|
||||
dev->rd_length*
|
||||
dev->rd_width*
|
||||
devptr->exts_deviceGateCap+
|
||||
(tran->rt_width+tran->rt_width)*
|
||||
(dev->rd_width+dev->rd_width)*
|
||||
devptr->exts_deviceSDCap;
|
||||
|
||||
}
|
||||
|
|
@ -917,7 +917,7 @@ ResDoSimplify(tolerance,rctol,goodies)
|
|||
goodies->rg_maxres = bigres;
|
||||
|
||||
#ifdef PARANOID
|
||||
ResSanityChecks("ExtractSingleNet",ResResList,ResNodeList,ResTransList);
|
||||
ResSanityChecks("ExtractSingleNet",ResResList,ResNodeList,ResDevList);
|
||||
#endif
|
||||
|
||||
/* Is extracted network still greater than the tolerance? */
|
||||
|
|
@ -958,7 +958,7 @@ ResDoSimplify(tolerance,rctol,goodies)
|
|||
{
|
||||
goodies->rg_nodecap = totalcap;
|
||||
ResCalculateTDi(ResOriginNode,(resResistor *)NULL,
|
||||
goodies->rg_bigtranres);
|
||||
goodies->rg_bigdevres);
|
||||
goodies->rg_Tdi = rc->rc_Tdi;
|
||||
slownode = ResNodeList;
|
||||
for (node = ResNodeList; node != NULL; node = node->rn_more)
|
||||
|
|
@ -984,7 +984,7 @@ ResDoSimplify(tolerance,rctol,goodies)
|
|||
{
|
||||
goodies->rg_Tdi = 0;
|
||||
}
|
||||
if ((rctol+1)*goodies->rg_bigtranres*goodies->rg_nodecap >
|
||||
if ((rctol+1)*goodies->rg_bigdevres*goodies->rg_nodecap >
|
||||
rctol*goodies->rg_Tdi &&
|
||||
(ResOptionsFlags & ResOpt_Tdi) &&
|
||||
goodies->rg_Tdi != -1)
|
||||
|
|
@ -1025,7 +1025,7 @@ ResDoSimplify(tolerance,rctol,goodies)
|
|||
rctol != 0)
|
||||
{
|
||||
ResPruneTree(ResOriginNode,
|
||||
(rctol+1)*goodies->rg_bigtranres*goodies->rg_nodecap/rctol,
|
||||
(rctol+1)*goodies->rg_bigdevres*goodies->rg_nodecap/rctol,
|
||||
&ResNodeList,&ResNodeQueue,&ResResList);
|
||||
}
|
||||
ResOriginNode->rn_status &= ~MARKED;
|
||||
|
|
@ -1089,8 +1089,8 @@ ResSetPathRes()
|
|||
}
|
||||
if (ResOriginNode == NULL)
|
||||
{
|
||||
resTransistor *res = ResGetTransistor(gparams.rg_tranloc);
|
||||
ResOriginNode = res->rt_source;
|
||||
resDevice *res = ResGetDevice(gparams.rg_devloc);
|
||||
ResOriginNode = res->rd_fet_source;
|
||||
ResOriginNode->rn_why = RES_NODE_ORIGIN;
|
||||
ResOriginNode->rn_noderes = 0;
|
||||
}
|
||||
|
|
|
|||
741
resis/ResUtils.c
741
resis/ResUtils.c
|
|
@ -122,8 +122,8 @@ ResEach(tile, pNum, arg)
|
|||
* ResAddPlumbing-- Each tile is a tileJunk structure associated with it
|
||||
* to keep track of various things used by the extractor. ResAddPlumbing
|
||||
* adds this structure and sets the tile's ClientData field to point to it.
|
||||
* If the tile is a transistor, then a transistor structure is also added;
|
||||
* all connected transistor tiles are enumerated and their transistorList
|
||||
* If the tile is a device, then a device structure is also added;
|
||||
* all connected device tiles are enumerated and their deviceList
|
||||
* fields set to the new structure.
|
||||
*
|
||||
* Results: always returns 0
|
||||
|
|
@ -140,372 +140,379 @@ ResAddPlumbing(tile, arg)
|
|||
|
||||
{
|
||||
tileJunk *Junk,*junk2;
|
||||
static Stack *resTransStack=NULL;
|
||||
static Stack *resDevStack=NULL;
|
||||
TileType loctype, t1;
|
||||
Tile *tp1,*tp2,*source;
|
||||
resTransistor *resFet;
|
||||
resDevice *resDev;
|
||||
ExtDevice *devptr;
|
||||
|
||||
if (resTransStack == NULL)
|
||||
{
|
||||
resTransStack = StackNew(64);
|
||||
}
|
||||
if (resDevStack == NULL)
|
||||
resDevStack = StackNew(64);
|
||||
|
||||
if (tile->ti_client == (ClientData) CLIENTDEFAULT)
|
||||
{
|
||||
if (IsSplit(tile))
|
||||
{
|
||||
loctype = (SplitSide(tile)) ? SplitRightType(tile) :
|
||||
SplitLeftType(tile);
|
||||
}
|
||||
else
|
||||
loctype = TiGetTypeExact(tile);
|
||||
|
||||
devptr = ExtCurStyle->exts_device[loctype];
|
||||
junk2 = resAddField(tile);
|
||||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), loctype))
|
||||
{
|
||||
resFet = (resTransistor *) mallocMagic((unsigned)(sizeof(resTransistor)));
|
||||
{
|
||||
int i;
|
||||
for (i=0; i != RT_TERMCOUNT;i++)
|
||||
resFet->rt_terminals[i] = (resNode *) NULL;
|
||||
}
|
||||
resFet->rt_tile = tile;
|
||||
resFet->rt_inside.r_ll.p_x = LEFT(tile);
|
||||
resFet->rt_inside.r_ll.p_y = BOTTOM(tile);
|
||||
resFet->rt_inside.r_ur.p_x = RIGHT(tile);
|
||||
resFet->rt_inside.r_ur.p_y = TOP(tile);
|
||||
resFet->rt_trantype = loctype;
|
||||
resFet->rt_tiles = 0;
|
||||
resFet->rt_length = 0;
|
||||
resFet->rt_width = 0;
|
||||
resFet->rt_perim = 0;
|
||||
resFet->rt_area = 0;
|
||||
resFet->rt_status = 0;
|
||||
resFet->rt_nextTran = (resTransistor *) *arg;
|
||||
*arg = (ClientData)resFet;
|
||||
junk2->transistorList = resFet;
|
||||
junk2->tj_status |= RES_TILE_TRAN;
|
||||
|
||||
source = NULL;
|
||||
/* find diffusion (if present) to be source contact */
|
||||
devptr = ExtCurStyle->exts_device[loctype];
|
||||
junk2 = resAddField(tile);
|
||||
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), loctype))
|
||||
{
|
||||
int i, nterms;
|
||||
|
||||
/* top */
|
||||
for (tp2= RT(tile); RIGHT(tp2) > LEFT(tile); tp2 = BL(tp2))
|
||||
{
|
||||
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||
/* Count SD terminals of the device */
|
||||
nterms = 0;
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
if (TTMaskIsZero(&(devptr->exts_deviceSDTypes[i]))) break;
|
||||
nterms++;
|
||||
}
|
||||
if (nterms < devptr->exts_deviceSDCount)
|
||||
nterms = devptr->exts_deviceSDCount;
|
||||
|
||||
/* resDev terminals includes device identifier (e.g., gate) and
|
||||
* substrate, so add two to nterms.
|
||||
*/
|
||||
nterms += 2;
|
||||
|
||||
resDev = (resDevice *) mallocMagic((unsigned)(sizeof(resDevice)));
|
||||
resDev->rd_nterms = nterms;
|
||||
resDev->rd_terminals = (resNode **) mallocMagic(nterms * sizeof(resNode *));
|
||||
for (i=0; i != nterms;i++)
|
||||
resDev->rd_terminals[i] = (resNode *) NULL;
|
||||
|
||||
resDev->rd_tile = tile;
|
||||
resDev->rd_inside.r_ll.p_x = LEFT(tile);
|
||||
resDev->rd_inside.r_ll.p_y = BOTTOM(tile);
|
||||
resDev->rd_inside.r_ur.p_x = RIGHT(tile);
|
||||
resDev->rd_inside.r_ur.p_y = TOP(tile);
|
||||
resDev->rd_devtype = loctype;
|
||||
resDev->rd_tiles = 0;
|
||||
resDev->rd_length = 0;
|
||||
resDev->rd_width = 0;
|
||||
resDev->rd_perim = 0;
|
||||
resDev->rd_area = 0;
|
||||
resDev->rd_status = 0;
|
||||
resDev->rd_nextDev = (resDevice *) *arg;
|
||||
*arg = (ClientData)resDev;
|
||||
junk2->deviceList = resDev;
|
||||
junk2->tj_status |= RES_TILE_DEV;
|
||||
|
||||
source = NULL;
|
||||
/* find diffusion (if present) to be source contact */
|
||||
|
||||
/* top */
|
||||
for (tp2= RT(tile); RIGHT(tp2) > LEFT(tile); tp2 = BL(tp2))
|
||||
{
|
||||
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||
TiGetBottomType(tp2))
|
||||
{
|
||||
junk2->sourceEdge |= TOPEDGE;
|
||||
source = tp2;
|
||||
Junk = resAddField(source);
|
||||
Junk->tj_status |= RES_TILE_SD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
junk2->sourceEdge |= TOPEDGE;
|
||||
source = tp2;
|
||||
Junk = resAddField(source);
|
||||
Junk->tj_status |= RES_TILE_SD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*bottom*/
|
||||
if (source == NULL)
|
||||
for (tp2= LB(tile); LEFT(tp2) < RIGHT(tile); tp2 = TR(tp2))
|
||||
{
|
||||
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||
/*bottom*/
|
||||
if (source == NULL)
|
||||
for (tp2= LB(tile); LEFT(tp2) < RIGHT(tile); tp2 = TR(tp2))
|
||||
{
|
||||
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||
TiGetTopType(tp2))
|
||||
{
|
||||
junk2->sourceEdge |= BOTTOMEDGE;
|
||||
source = tp2;
|
||||
Junk = resAddField(source);
|
||||
Junk->tj_status |= RES_TILE_SD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
junk2->sourceEdge |= BOTTOMEDGE;
|
||||
source = tp2;
|
||||
Junk = resAddField(source);
|
||||
Junk->tj_status |= RES_TILE_SD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*right*/
|
||||
if (source == NULL)
|
||||
for (tp2= TR(tile); TOP(tp2) > BOTTOM(tile); tp2 = LB(tp2))
|
||||
{
|
||||
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||
/*right*/
|
||||
if (source == NULL)
|
||||
for (tp2= TR(tile); TOP(tp2) > BOTTOM(tile); tp2 = LB(tp2))
|
||||
{
|
||||
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||
TiGetLeftType(tp2))
|
||||
{
|
||||
junk2->sourceEdge |= RIGHTEDGE;
|
||||
source = tp2;
|
||||
Junk = resAddField(source);
|
||||
Junk->tj_status |= RES_TILE_SD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
junk2->sourceEdge |= RIGHTEDGE;
|
||||
source = tp2;
|
||||
Junk = resAddField(source);
|
||||
Junk->tj_status |= RES_TILE_SD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*left*/
|
||||
if (source == NULL)
|
||||
for (tp2= BL(tile); BOTTOM(tp2) < TOP(tile); tp2 = RT(tp2))
|
||||
{
|
||||
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||
/*left*/
|
||||
if (source == NULL)
|
||||
for (tp2= BL(tile); BOTTOM(tp2) < TOP(tile); tp2 = RT(tp2))
|
||||
{
|
||||
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||
TiGetRightType(tp2))
|
||||
{
|
||||
source = tp2;
|
||||
Junk = resAddField(source);
|
||||
Junk->tj_status |= RES_TILE_SD;
|
||||
junk2->sourceEdge |= LEFTEDGE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
source = tp2;
|
||||
Junk = resAddField(source);
|
||||
Junk->tj_status |= RES_TILE_SD;
|
||||
junk2->sourceEdge |= LEFTEDGE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* We need to know whether a given diffusion tile connects to
|
||||
* the source or to the drain of a transistor. A single
|
||||
* diffusion tile is marked, and all connecting diffusion tiles
|
||||
* are enumerated and called the source. Any other SD tiles
|
||||
* are assumed to be the drain. BUG: this does not work
|
||||
* correctly with multi SD structures.
|
||||
*/
|
||||
/* We need to know whether a given diffusion tile connects to
|
||||
* the source or to the drain of a device. A single
|
||||
* diffusion tile is marked, and all connecting diffusion tiles
|
||||
* are enumerated and called the source. Any other SD tiles
|
||||
* are assumed to be the drain. BUG: this does not work
|
||||
* correctly with multi SD structures.
|
||||
*/
|
||||
|
||||
if (source != (Tile *) NULL)
|
||||
{
|
||||
STACKPUSH((ClientData) (source),resTransStack);
|
||||
}
|
||||
while (!StackEmpty(resTransStack))
|
||||
{
|
||||
tp1 = (Tile *) STACKPOP(resTransStack);
|
||||
if (IsSplit(tp1))
|
||||
{
|
||||
t1 = (SplitSide(tp1)) ? SplitRightType(tp1) :
|
||||
if (source != (Tile *) NULL)
|
||||
{
|
||||
STACKPUSH((ClientData) (source),resDevStack);
|
||||
}
|
||||
while (!StackEmpty(resDevStack))
|
||||
{
|
||||
tp1 = (Tile *) STACKPOP(resDevStack);
|
||||
if (IsSplit(tp1))
|
||||
{
|
||||
t1 = (SplitSide(tp1)) ? SplitRightType(tp1) :
|
||||
SplitLeftType(tp1);
|
||||
}
|
||||
else
|
||||
t1 = TiGetTypeExact(tp1);
|
||||
}
|
||||
else
|
||||
t1 = TiGetTypeExact(tp1);
|
||||
|
||||
/* top */
|
||||
for (tp2= RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2))
|
||||
{
|
||||
if (TiGetBottomType(tp2) == t1)
|
||||
{
|
||||
tileJunk *j= resAddField(tp2);
|
||||
if ((j->tj_status & RES_TILE_SD) ==0)
|
||||
{
|
||||
j->tj_status |= RES_TILE_SD;
|
||||
STACKPUSH((ClientData)tp2,resTransStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*bottom*/
|
||||
for (tp2= LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2))
|
||||
{
|
||||
if (TiGetTopType(tp2) == t1)
|
||||
{
|
||||
tileJunk *j= resAddField(tp2);
|
||||
if ((j->tj_status & RES_TILE_SD) == 0)
|
||||
{
|
||||
j->tj_status |= RES_TILE_SD;
|
||||
STACKPUSH((ClientData) (tp2),resTransStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*right*/
|
||||
for (tp2= TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2))
|
||||
{
|
||||
if (TiGetLeftType(tp2) == t1)
|
||||
{
|
||||
tileJunk *j= resAddField(tp2);
|
||||
if ((j->tj_status & RES_TILE_SD) == 0)
|
||||
{
|
||||
j->tj_status |= RES_TILE_SD;
|
||||
STACKPUSH((ClientData) (tp2),resTransStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*left*/
|
||||
for (tp2= BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2))
|
||||
{
|
||||
if (TiGetRightType(tp2) == t1)
|
||||
{
|
||||
tileJunk *j= resAddField(tp2);
|
||||
if ((j->tj_status & RES_TILE_SD) == 0)
|
||||
{
|
||||
j->tj_status |= RES_TILE_SD;
|
||||
STACKPUSH((ClientData) (tp2),resTransStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* find rest of transistor; search for source edges */
|
||||
|
||||
STACKPUSH((ClientData) (tile), resTransStack);
|
||||
while (!StackEmpty(resTransStack))
|
||||
{
|
||||
tileJunk *j0;
|
||||
|
||||
tp1= (Tile *) STACKPOP(resTransStack);
|
||||
if (IsSplit(tp1))
|
||||
/* top */
|
||||
for (tp2= RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2))
|
||||
{
|
||||
if (TiGetBottomType(tp2) == t1)
|
||||
{
|
||||
t1 = (SplitSide(tp1)) ? SplitRightType(tp1) :
|
||||
tileJunk *j= resAddField(tp2);
|
||||
if ((j->tj_status & RES_TILE_SD) ==0)
|
||||
{
|
||||
j->tj_status |= RES_TILE_SD;
|
||||
STACKPUSH((ClientData)tp2,resDevStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*bottom*/
|
||||
for (tp2= LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2))
|
||||
{
|
||||
if (TiGetTopType(tp2) == t1)
|
||||
{
|
||||
tileJunk *j= resAddField(tp2);
|
||||
if ((j->tj_status & RES_TILE_SD) == 0)
|
||||
{
|
||||
j->tj_status |= RES_TILE_SD;
|
||||
STACKPUSH((ClientData) (tp2),resDevStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*right*/
|
||||
for (tp2= TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2))
|
||||
{
|
||||
if (TiGetLeftType(tp2) == t1)
|
||||
{
|
||||
tileJunk *j= resAddField(tp2);
|
||||
if ((j->tj_status & RES_TILE_SD) == 0)
|
||||
{
|
||||
j->tj_status |= RES_TILE_SD;
|
||||
STACKPUSH((ClientData) (tp2),resDevStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*left*/
|
||||
for (tp2= BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2))
|
||||
{
|
||||
if (TiGetRightType(tp2) == t1)
|
||||
{
|
||||
tileJunk *j= resAddField(tp2);
|
||||
if ((j->tj_status & RES_TILE_SD) == 0)
|
||||
{
|
||||
j->tj_status |= RES_TILE_SD;
|
||||
STACKPUSH((ClientData) (tp2),resDevStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* find rest of device; search for source edges */
|
||||
|
||||
STACKPUSH((ClientData) (tile), resDevStack);
|
||||
while (!StackEmpty(resDevStack))
|
||||
{
|
||||
tileJunk *j0;
|
||||
|
||||
tp1= (Tile *) STACKPOP(resDevStack);
|
||||
if (IsSplit(tp1))
|
||||
{
|
||||
t1 = (SplitSide(tp1)) ? SplitRightType(tp1) :
|
||||
SplitLeftType(tp1);
|
||||
}
|
||||
else
|
||||
t1 = TiGetTypeExact(tp1);
|
||||
}
|
||||
else
|
||||
t1 = TiGetTypeExact(tp1);
|
||||
|
||||
devptr = ExtCurStyle->exts_device[t1];
|
||||
j0 = (tileJunk *) tp1->ti_client;
|
||||
/* top */
|
||||
for (tp2= RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2))
|
||||
{
|
||||
if ((TiGetBottomType(tp2) == t1) &&
|
||||
devptr = ExtCurStyle->exts_device[t1];
|
||||
j0 = (tileJunk *) tp1->ti_client;
|
||||
/* top */
|
||||
for (tp2= RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2))
|
||||
{
|
||||
if ((TiGetBottomType(tp2) == t1) &&
|
||||
(tp2->ti_client == (ClientData) CLIENTDEFAULT))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
STACKPUSH((ClientData)(tp2),resTransStack);
|
||||
Junk->transistorList = resFet;
|
||||
Junk->tj_status |= RES_TILE_TRAN;
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
STACKPUSH((ClientData)(tp2),resDevStack);
|
||||
Junk->deviceList = resDev;
|
||||
Junk->tj_status |= RES_TILE_DEV;
|
||||
|
||||
}
|
||||
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||
TiGetBottomType(tp2))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
if (Junk->tj_status & RES_TILE_SD)
|
||||
{
|
||||
j0->sourceEdge |= TOPEDGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*bottom*/
|
||||
for (tp2= LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2))
|
||||
{
|
||||
if ((TiGetTopType(tp2) == t1) &&
|
||||
(tp2->ti_client == (ClientData) CLIENTDEFAULT))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
STACKPUSH((ClientData)(tp2),resTransStack);
|
||||
Junk->transistorList = resFet;
|
||||
Junk->tj_status |= RES_TILE_TRAN;
|
||||
}
|
||||
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||
TiGetTopType(tp2))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
if (Junk->tj_status & RES_TILE_SD)
|
||||
{
|
||||
j0->sourceEdge |= BOTTOMEDGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*right*/
|
||||
for (tp2= TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2))
|
||||
{
|
||||
if ((TiGetLeftType(tp2) == t1) &&
|
||||
(tp2->ti_client == (ClientData) CLIENTDEFAULT))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
STACKPUSH((ClientData)(tp2),resTransStack);
|
||||
Junk->transistorList = resFet;
|
||||
Junk->tj_status |= RES_TILE_TRAN;
|
||||
}
|
||||
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||
TiGetLeftType(tp2))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
if (Junk->tj_status & RES_TILE_SD)
|
||||
{
|
||||
j0->sourceEdge |= RIGHTEDGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*left*/
|
||||
for (tp2= BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2))
|
||||
{
|
||||
if ((TiGetRightType(tp2) == t1) &&
|
||||
(tp2->ti_client == (ClientData) CLIENTDEFAULT))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
STACKPUSH((ClientData)(tp2),resTransStack);
|
||||
Junk->transistorList = resFet;
|
||||
Junk->tj_status |= RES_TILE_TRAN;
|
||||
}
|
||||
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||
TiGetRightType(tp2))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
if (Junk->tj_status & RES_TILE_SD)
|
||||
{
|
||||
j0->sourceEdge |= LEFTEDGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* unmark all tiles marked as being part of source */
|
||||
|
||||
if (source != (Tile *) NULL)
|
||||
{
|
||||
tileJunk *j = (tileJunk *) source->ti_client;
|
||||
|
||||
STACKPUSH((ClientData) (source),resTransStack);
|
||||
j->tj_status &= ~RES_TILE_SD;
|
||||
}
|
||||
while (!StackEmpty(resTransStack))
|
||||
{
|
||||
tp1 = (Tile *) STACKPOP(resTransStack);
|
||||
if (IsSplit(tp1))
|
||||
{
|
||||
t1 = (SplitSide(tp1)) ? SplitRightType(tp1) :
|
||||
SplitLeftType(tp1);
|
||||
}
|
||||
else
|
||||
t1 = TiGetTypeExact(tp1);
|
||||
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||
TiGetBottomType(tp2))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
if (Junk->tj_status & RES_TILE_SD)
|
||||
j0->sourceEdge |= TOPEDGE;
|
||||
}
|
||||
}
|
||||
/*bottom*/
|
||||
for (tp2= LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2))
|
||||
{
|
||||
if ((TiGetTopType(tp2) == t1) &&
|
||||
(tp2->ti_client == (ClientData) CLIENTDEFAULT))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
STACKPUSH((ClientData)(tp2),resDevStack);
|
||||
Junk->deviceList = resDev;
|
||||
Junk->tj_status |= RES_TILE_DEV;
|
||||
}
|
||||
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||
TiGetTopType(tp2))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
if (Junk->tj_status & RES_TILE_SD)
|
||||
j0->sourceEdge |= BOTTOMEDGE;
|
||||
}
|
||||
}
|
||||
/*right*/
|
||||
for (tp2= TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2))
|
||||
{
|
||||
if ((TiGetLeftType(tp2) == t1) &&
|
||||
(tp2->ti_client == (ClientData) CLIENTDEFAULT))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
STACKPUSH((ClientData)(tp2),resDevStack);
|
||||
Junk->deviceList = resDev;
|
||||
Junk->tj_status |= RES_TILE_DEV;
|
||||
}
|
||||
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||
TiGetLeftType(tp2))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
if (Junk->tj_status & RES_TILE_SD)
|
||||
j0->sourceEdge |= RIGHTEDGE;
|
||||
}
|
||||
}
|
||||
/*left*/
|
||||
for (tp2= BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2))
|
||||
{
|
||||
if ((TiGetRightType(tp2) == t1) &&
|
||||
(tp2->ti_client == (ClientData) CLIENTDEFAULT))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
STACKPUSH((ClientData)(tp2),resDevStack);
|
||||
Junk->deviceList = resDev;
|
||||
Junk->tj_status |= RES_TILE_DEV;
|
||||
}
|
||||
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
|
||||
TiGetRightType(tp2))
|
||||
{
|
||||
Junk = resAddField(tp2);
|
||||
if (Junk->tj_status & RES_TILE_SD)
|
||||
j0->sourceEdge |= LEFTEDGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* top */
|
||||
for (tp2= RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2))
|
||||
{
|
||||
tileJunk *j2 = (tileJunk *) tp2->ti_client;
|
||||
if (TiGetBottomType(tp2) == t1)
|
||||
{
|
||||
if (j2->tj_status & RES_TILE_SD)
|
||||
{
|
||||
j2->tj_status &= ~RES_TILE_SD;
|
||||
STACKPUSH((ClientData) tp2,resTransStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*bottom*/
|
||||
for(tp2= LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2))
|
||||
{
|
||||
tileJunk *j2 = (tileJunk *) tp2->ti_client;
|
||||
if (TiGetTopType(tp2) == t1)
|
||||
{
|
||||
if (j2->tj_status & RES_TILE_SD)
|
||||
{
|
||||
j2->tj_status &= ~RES_TILE_SD;
|
||||
STACKPUSH((ClientData) tp2,resTransStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*right*/
|
||||
for (tp2= TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2))
|
||||
{
|
||||
tileJunk *j2 = (tileJunk *) tp2->ti_client;
|
||||
if (TiGetLeftType(tp2) == t1)
|
||||
{
|
||||
if (j2->tj_status & RES_TILE_SD)
|
||||
{
|
||||
j2->tj_status &= ~RES_TILE_SD;
|
||||
STACKPUSH((ClientData) tp2,resTransStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*left*/
|
||||
for (tp2= BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2))
|
||||
{
|
||||
tileJunk *j2 = (tileJunk *) tp2->ti_client;
|
||||
if (TiGetRightType(tp2) == t1)
|
||||
{
|
||||
if (j2->tj_status & RES_TILE_SD)
|
||||
{
|
||||
j2->tj_status &= ~RES_TILE_SD;
|
||||
STACKPUSH((ClientData) tp2,resTransStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
/* unmark all tiles marked as being part of source */
|
||||
|
||||
if (source != (Tile *) NULL)
|
||||
{
|
||||
tileJunk *j = (tileJunk *) source->ti_client;
|
||||
|
||||
STACKPUSH((ClientData) (source),resDevStack);
|
||||
j->tj_status &= ~RES_TILE_SD;
|
||||
}
|
||||
while (!StackEmpty(resDevStack))
|
||||
{
|
||||
tp1 = (Tile *) STACKPOP(resDevStack);
|
||||
if (IsSplit(tp1))
|
||||
{
|
||||
t1 = (SplitSide(tp1)) ? SplitRightType(tp1) :
|
||||
SplitLeftType(tp1);
|
||||
}
|
||||
else
|
||||
t1 = TiGetTypeExact(tp1);
|
||||
|
||||
/* top */
|
||||
for (tp2= RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2))
|
||||
{
|
||||
tileJunk *j2 = (tileJunk *) tp2->ti_client;
|
||||
if (TiGetBottomType(tp2) == t1)
|
||||
{
|
||||
if (j2->tj_status & RES_TILE_SD)
|
||||
{
|
||||
j2->tj_status &= ~RES_TILE_SD;
|
||||
STACKPUSH((ClientData) tp2,resDevStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*bottom*/
|
||||
for(tp2= LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2))
|
||||
{
|
||||
tileJunk *j2 = (tileJunk *) tp2->ti_client;
|
||||
if (TiGetTopType(tp2) == t1)
|
||||
{
|
||||
if (j2->tj_status & RES_TILE_SD)
|
||||
{
|
||||
j2->tj_status &= ~RES_TILE_SD;
|
||||
STACKPUSH((ClientData) tp2,resDevStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*right*/
|
||||
for (tp2= TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2))
|
||||
{
|
||||
tileJunk *j2 = (tileJunk *) tp2->ti_client;
|
||||
if (TiGetLeftType(tp2) == t1)
|
||||
{
|
||||
if (j2->tj_status & RES_TILE_SD)
|
||||
{
|
||||
j2->tj_status &= ~RES_TILE_SD;
|
||||
STACKPUSH((ClientData) tp2,resDevStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*left*/
|
||||
for (tp2= BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2))
|
||||
{
|
||||
tileJunk *j2 = (tileJunk *) tp2->ti_client;
|
||||
if (TiGetRightType(tp2) == t1)
|
||||
{
|
||||
if (j2->tj_status & RES_TILE_SD)
|
||||
{
|
||||
j2->tj_status &= ~RES_TILE_SD;
|
||||
STACKPUSH((ClientData) tp2,resDevStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -539,39 +546,39 @@ ResRemovePlumbing(tile, arg)
|
|||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ResPreprocessTransistors-- Given a list of all the transistor tiles and
|
||||
* a list of all the transistors, this procedure calculates the width and
|
||||
* ResPreprocessDevices-- Given a list of all the device tiles and
|
||||
* a list of all the devices, this procedure calculates the width and
|
||||
* length. The width is set equal to the sum of all edges that touch
|
||||
* diffusion divided by 2. The length is the remaining perimeter divided by
|
||||
* 2*tiles. The perimeter and area fields of transistor structures are also
|
||||
* 2*tiles. The perimeter and area fields of device structures are also
|
||||
* fixed.
|
||||
*
|
||||
* Results: none
|
||||
*
|
||||
* Side Effects: sets length and width of transistors. "ResTransTile"
|
||||
* Side Effects: sets length and width of devices. "ResDevTile"
|
||||
* structures are freed.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ResPreProcessTransistors(TileList, TransistorList, Def)
|
||||
ResTranTile *TileList;
|
||||
resTransistor *TransistorList;
|
||||
ResPreProcessDevices(TileList, DeviceList, Def)
|
||||
ResDevTile *TileList;
|
||||
resDevice *DeviceList;
|
||||
CellDef *Def;
|
||||
{
|
||||
Tile *tile;
|
||||
ResTranTile *oldTile;
|
||||
ResDevTile *oldTile;
|
||||
tileJunk *tstruct;
|
||||
TileType tt, residue;
|
||||
int pNum;
|
||||
|
||||
while (TileList != (ResTranTile *) NULL)
|
||||
while (TileList != (ResDevTile *) NULL)
|
||||
{
|
||||
tt = TileList->type;
|
||||
if (DBIsContact(tt))
|
||||
{
|
||||
/* Find which residue of the contact is a transistor type. */
|
||||
/* Find which residue of the contact is a device. */
|
||||
TileTypeBitMask ttresidues;
|
||||
|
||||
DBFullResidueMask(tt, &ttresidues);
|
||||
|
|
@ -598,51 +605,51 @@ ResPreProcessTransistors(TileList, TransistorList, Def)
|
|||
tstruct = (tileJunk *) tile->ti_client;
|
||||
|
||||
if (!TTMaskHasType(&ExtCurStyle->exts_deviceMask, tt) ||
|
||||
tstruct->transistorList == NULL)
|
||||
tstruct->deviceList == NULL)
|
||||
{
|
||||
TxError("Bad Transistor Location at %d,%d\n",
|
||||
TxError("Bad Device Location at %d,%d\n",
|
||||
TileList->area.r_ll.p_x,
|
||||
TileList->area.r_ll.p_y);
|
||||
}
|
||||
else if ((tstruct->tj_status & RES_TILE_MARK) == 0)
|
||||
{
|
||||
resTransistor *rt = tstruct->transistorList;
|
||||
resDevice *rd = tstruct->deviceList;
|
||||
|
||||
tstruct->tj_status |= RES_TILE_MARK;
|
||||
rt->rt_perim += TileList->perim;
|
||||
rt->rt_length += TileList->overlap;
|
||||
rt->rt_area += (TileList->area.r_xtop - TileList->area.r_xbot)
|
||||
rd->rd_perim += TileList->perim;
|
||||
rd->rd_length += TileList->overlap;
|
||||
rd->rd_area += (TileList->area.r_xtop - TileList->area.r_xbot)
|
||||
* (TileList->area.r_ytop - TileList->area.r_ybot);
|
||||
rt->rt_tiles++;
|
||||
rd->rd_tiles++;
|
||||
}
|
||||
oldTile = TileList;
|
||||
TileList = TileList->nextTran;
|
||||
TileList = TileList->nextDev;
|
||||
freeMagic((char *)oldTile);
|
||||
}
|
||||
|
||||
for(; TransistorList != NULL;TransistorList = TransistorList->rt_nextTran)
|
||||
for(; DeviceList != NULL;DeviceList = DeviceList->rd_nextDev)
|
||||
{
|
||||
int width = TransistorList->rt_perim;
|
||||
int length = TransistorList->rt_length;
|
||||
if (TransistorList->rt_tiles != 0)
|
||||
int width = DeviceList->rd_perim;
|
||||
int length = DeviceList->rd_length;
|
||||
if (DeviceList->rd_tiles != 0)
|
||||
{
|
||||
if (length)
|
||||
{
|
||||
TransistorList->rt_length = (float) length /
|
||||
((float)((TransistorList->rt_tiles) << 1));
|
||||
TransistorList->rt_width = (width-length) >> 1;
|
||||
DeviceList->rd_length = (float) length /
|
||||
((float)((DeviceList->rd_tiles) << 1));
|
||||
DeviceList->rd_width = (width-length) >> 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
double perimeter = TransistorList->rt_perim;
|
||||
double area = TransistorList->rt_area;
|
||||
double perimeter = DeviceList->rd_perim;
|
||||
double area = DeviceList->rd_area;
|
||||
|
||||
perimeter /= 4.0;
|
||||
|
||||
TransistorList->rt_width = perimeter +
|
||||
DeviceList->rd_width = perimeter +
|
||||
sqrt(perimeter * perimeter-area);
|
||||
TransistorList->rt_length = (TransistorList->rt_perim
|
||||
- 2 * TransistorList->rt_width) >> 1;
|
||||
DeviceList->rd_length = (DeviceList->rd_perim
|
||||
- 2 * DeviceList->rd_width) >> 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ static char sccsid[] = "@(#)Write.c 4.10 MAGIC (Stanford Addition) 07/86";
|
|||
|
||||
#define RT_SIZE 0xf
|
||||
#define MAXTOKEN 256
|
||||
#define TRANFLATSIZE 1024
|
||||
#define DEVFLATSIZE 1024
|
||||
#define RESGROUPSIZE 256
|
||||
|
||||
void
|
||||
|
|
@ -136,15 +136,15 @@ resCurrentPrintFunc(node,resistor,filename)
|
|||
FILE *filename;
|
||||
|
||||
{
|
||||
tElement *workingTran;
|
||||
tElement *workingDev;
|
||||
float i_sum=0.0;
|
||||
|
||||
for (workingTran = node->rn_te; workingTran != NULL;
|
||||
workingTran=workingTran->te_nextt)
|
||||
for (workingDev = node->rn_te; workingDev != NULL;
|
||||
workingDev=workingDev->te_nextt)
|
||||
{
|
||||
if ((workingTran->te_thist->rt_status & RES_TRAN_PLUG) ||
|
||||
workingTran->te_thist->rt_gate != node)
|
||||
i_sum += workingTran->te_thist->rt_i;
|
||||
if ((workingDev->te_thist->rd_status & RES_DEV_PLUG) ||
|
||||
workingDev->te_thist->rd_gate != node)
|
||||
i_sum += workingDev->te_thist->rd_i;
|
||||
}
|
||||
if (i_sum != 0.0)
|
||||
{
|
||||
|
|
@ -167,11 +167,11 @@ ResDeviceCounts()
|
|||
{
|
||||
int i,j,k;
|
||||
resNode *n;
|
||||
resTransistor *t;
|
||||
resDevice *t;
|
||||
resResistor *r;
|
||||
|
||||
for (n=ResNodeList,i=0;n!=NULL;n=n->rn_more,i++);
|
||||
for (t=ResTransList,j=0;t!=NULL;t=t->rt_nextTran,j++);
|
||||
for (t=ResDevList,j=0;t!=NULL;t=t->rd_nextDev,j++);
|
||||
for (r=ResResList,k=0;r!=NULL;r=r->rr_nextResistor,k++);
|
||||
TxError("n=%d t=%d r=%d\n",i,j,k);
|
||||
TxFlushErr();
|
||||
|
|
|
|||
158
resis/resis.h
158
resis/resis.h
|
|
@ -66,35 +66,37 @@ typedef struct resistor
|
|||
#define rr_connection1 rr_node[0]
|
||||
#define rr_connection2 rr_node[1]
|
||||
|
||||
/* Definitions for old FET-style MOSFET devices */
|
||||
#define RT_GATE 0
|
||||
#define RT_SOURCE 1
|
||||
#define RT_DRAIN 2
|
||||
#define RT_SUBS 3
|
||||
#define RT_TERMCOUNT 4
|
||||
typedef struct transistor
|
||||
{
|
||||
int rt_status; /* status bits */
|
||||
struct transistor *rt_nextTran; /* next transistor in linked list */
|
||||
/* terminals of transistor */
|
||||
struct resnode *rt_terminals[RT_TERMCOUNT];
|
||||
int rt_perim; /* info about transistor */
|
||||
int rt_area; /* used in .ext and .sim file */
|
||||
int rt_length; /* patches. */
|
||||
int rt_width;
|
||||
int rt_tiles; /* number of tiles in transistor */
|
||||
int rt_trantype; /* tiletype of transistor. */
|
||||
Rect rt_inside; /* 1x1 rectangle inside transistor */
|
||||
Tile *rt_tile; /* pointer to a tile in transistor */
|
||||
#ifdef ARIEL
|
||||
float rt_i; /* Current injected from this tran */
|
||||
/* in milliamps */
|
||||
#endif
|
||||
} resTransistor;
|
||||
|
||||
#define rt_gate rt_terminals[RT_GATE]
|
||||
#define rt_source rt_terminals[RT_SOURCE]
|
||||
#define rt_drain rt_terminals[RT_DRAIN]
|
||||
#define rt_subs rt_terminals[RT_SUBS]
|
||||
#define rd_fet_gate rd_terminals[RT_GATE]
|
||||
#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
|
||||
{
|
||||
int rd_status; /* status bits */
|
||||
struct device *rd_nextDev; /* next device in linked list */
|
||||
/* terminals of device */
|
||||
struct resnode **rd_terminals;
|
||||
int rd_nterms; /* number of terminals in rt_terminals */
|
||||
int rd_perim; /* info about device */
|
||||
int rd_area; /* used in .ext and .sim file */
|
||||
int rd_length; /* patches. */
|
||||
int rd_width;
|
||||
int rd_tiles; /* number of tiles in device */
|
||||
int rd_devtype; /* tiletype of device. */
|
||||
Rect rd_inside; /* 1x1 rectangle inside device */
|
||||
Tile *rd_tile; /* pointer to a tile in device */
|
||||
#ifdef ARIEL
|
||||
float rd_i; /* Current injected from this device */
|
||||
/* in milliamps */
|
||||
#endif
|
||||
} resDevice;
|
||||
|
||||
/*
|
||||
a junction is formed when two tiles that connect are next to one another.
|
||||
|
|
@ -149,7 +151,7 @@ typedef struct jelement
|
|||
typedef struct telement
|
||||
{
|
||||
struct telement *te_nextt;
|
||||
resTransistor *te_thist;
|
||||
resDevice *te_thist;
|
||||
} tElement;
|
||||
|
||||
typedef struct celement
|
||||
|
|
@ -160,7 +162,7 @@ typedef struct celement
|
|||
|
||||
/*
|
||||
Nodes formed from network. These are linked both forwards and backwords
|
||||
to other nodes. Lists of transistors, resistors, junctions, and contacts
|
||||
to other nodes. Lists of devices, resistors, junctions, and contacts
|
||||
corresponding to this node are kept.
|
||||
*/
|
||||
typedef struct resnode
|
||||
|
|
@ -190,7 +192,7 @@ typedef struct resnode
|
|||
/* for this node. */
|
||||
ClientData rn_client; /* Random pointer */
|
||||
int rn_id;
|
||||
}resNode;
|
||||
} resNode;
|
||||
|
||||
typedef struct nelement
|
||||
{
|
||||
|
|
@ -222,32 +224,32 @@ typedef struct breakpoint
|
|||
typedef struct tilejunk
|
||||
{
|
||||
cElement *contactList; /*widgets connected to this tile */
|
||||
resTransistor *transistorList;
|
||||
resDevice *deviceList;
|
||||
resPort *portList;
|
||||
ResJunction *junctionList;
|
||||
Breakpoint *breakList;
|
||||
int sourceEdge; /* used in transistor tiles to keep
|
||||
of which diffusion edges are
|
||||
the transistor's source
|
||||
*/
|
||||
int sourceEdge; /* used in device tiles to keep
|
||||
* of which diffusion edges are
|
||||
* a transistor's source
|
||||
*/
|
||||
int tj_status; /* status of tile processing */
|
||||
} tileJunk;
|
||||
|
||||
/* ResTransTile keeps track of the location and type of transistors.
|
||||
/* ResDevTile keeps track of the location and type of devices.
|
||||
These areas are painted into our copied def after the tree is totally
|
||||
flattened. (They can't be painted right away becasue the copy routine
|
||||
uses the new def to keep track of where it is in the design. It is also
|
||||
used when transistors are preproceesed.
|
||||
used when devices are preproceesed.
|
||||
*/
|
||||
|
||||
typedef struct restrantile
|
||||
typedef struct resdevtile
|
||||
{
|
||||
struct restrantile *nextTran;
|
||||
struct resdevtile *nextDev;
|
||||
Rect area;
|
||||
TileType type;
|
||||
int perim;
|
||||
int overlap;
|
||||
} ResTranTile;
|
||||
} ResDevTile;
|
||||
|
||||
/*
|
||||
Goodies contains random stuff passed between the node extractor
|
||||
|
|
@ -261,10 +263,10 @@ typedef struct goodstuff
|
|||
float rg_maxres;
|
||||
float rg_nodecap;
|
||||
float rg_Tdi;
|
||||
int rg_bigtranres;
|
||||
int rg_bigdevres;
|
||||
int rg_tilecount;
|
||||
int rg_status;
|
||||
Point *rg_tranloc;
|
||||
Point *rg_devloc;
|
||||
char *rg_name;
|
||||
} ResGlobalParams;
|
||||
|
||||
|
|
@ -280,26 +282,26 @@ typedef struct rcdelaystuff
|
|||
|
||||
/* ResSim.c type declarations */
|
||||
|
||||
typedef struct rtran
|
||||
typedef struct rdev
|
||||
{
|
||||
struct rtran *nextTran; /* Next transistor in linked list */
|
||||
struct rtran *realTran; /* Single Lumped Transistor for */
|
||||
/* transistors connected in parallel */
|
||||
resTransistor *layout; /* pointer to resTransistor that */
|
||||
/* corresponds to RTran */
|
||||
struct rdev *nextDev; /* Next device in linked list */
|
||||
struct rdev *realDev; /* Single Lumped Device for */
|
||||
/* devices connected in parallel */
|
||||
resDevice *layout; /* pointer to resDevice that */
|
||||
/* corresponds to RDev */
|
||||
int status;
|
||||
struct ressimnode *gate; /* Terminals of transistor. */
|
||||
struct ressimnode *source;
|
||||
struct ressimnode *drain;
|
||||
Point location; /* Location of lower left point of */
|
||||
/* transistor. */
|
||||
float resistance; /* "Resistance" of transistor. */
|
||||
int tnumber; /* Transistor number */
|
||||
int rs_ttype; /* transistor type */
|
||||
/* 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;
|
||||
char *rs_dattr;
|
||||
} RTran;
|
||||
} RDev;
|
||||
|
||||
typedef struct ressimnode
|
||||
{
|
||||
|
|
@ -327,7 +329,7 @@ typedef struct ressimnode
|
|||
/* tile in the lowest numbered */
|
||||
/* plane contained in the node . */
|
||||
TileType type; /* Tile type of tile at location */
|
||||
struct tranptr *firstTran; /* linked list of transistors */
|
||||
struct devptr *firstDev; /* linked list of devices */
|
||||
/* connected to node. */
|
||||
char *name; /* Pointer to name of node stored */
|
||||
/* in hash table. */
|
||||
|
|
@ -341,15 +343,15 @@ typedef struct ressimnode
|
|||
#define RES_SUB_GND 0
|
||||
#define RES_SUB_VDD 1
|
||||
|
||||
/* `cons' cell for linked list of transistors connected to node */
|
||||
/* `cons' cell for linked list of devices connected to node */
|
||||
|
||||
typedef struct tranptr
|
||||
typedef struct devptr
|
||||
{
|
||||
struct tranptr *nextTran;
|
||||
struct rtran *thisTran;
|
||||
int terminal; /* which terminal of transistor */
|
||||
/* is connected to node. */
|
||||
} tranPtr;
|
||||
struct devptr *nextDev;
|
||||
struct rdev *thisDev;
|
||||
int terminal; /* which terminal of device */
|
||||
/* is connected to node. */
|
||||
} devPtr;
|
||||
|
||||
/* ResTime.c type declarations */
|
||||
|
||||
|
|
@ -360,7 +362,7 @@ typedef struct resevent /* Raw event list read in from rsim/tv */
|
|||
int rv_tmin; /* minimum event time in units of 100ps */
|
||||
int rv_tmax; /* maximum event time in units of 100ps */
|
||||
float rv_i; /* event current in milliamps */
|
||||
resTransistor *rv_tran; /* transistor where charge drains */
|
||||
resDevice *rv_dev; /* device where charge drains */
|
||||
} ResEvent;
|
||||
|
||||
typedef struct reseventcell
|
||||
|
|
@ -372,8 +374,8 @@ typedef struct reseventcell
|
|||
typedef struct rescurrentevent /* processed event used to feed relaxer */
|
||||
{
|
||||
struct rescurrentevent *ri_next;
|
||||
float ri_i;
|
||||
resTransistor *ri_tran;
|
||||
float ri_i;
|
||||
resDevice *ri_dev;
|
||||
} ResCurrentEvent;
|
||||
|
||||
typedef struct restimebin /* Holds one timestep's worth of Events */
|
||||
|
|
@ -406,7 +408,7 @@ typedef struct clump
|
|||
} ResClump;
|
||||
|
||||
/* the first two fields of this plug must be the the same as for
|
||||
resTransistor
|
||||
resDevice
|
||||
*/
|
||||
typedef struct plug
|
||||
{
|
||||
|
|
@ -437,7 +439,7 @@ typedef struct capval
|
|||
|
||||
/* type of node flags */
|
||||
#define RES_NODE_JUNCTION 0x00000001
|
||||
#define RES_NODE_TRANSISTOR 0x00000002
|
||||
#define RES_NODE_DEVICE 0x00000002
|
||||
#define RES_NODE_CONTACT 0x00000004
|
||||
#define RES_NODE_ORIGIN 0x00000008
|
||||
|
||||
|
|
@ -452,15 +454,15 @@ typedef struct capval
|
|||
#define RES_REACHED_RESISTOR 0x00100000
|
||||
#define RES_HEAP 0x00200000
|
||||
|
||||
/* transistor flags */
|
||||
#define RES_TRAN_SAVE 0x00000001
|
||||
#define RES_TRAN_PLUG 0x00000002
|
||||
/* device flags */
|
||||
#define RES_DEV_SAVE 0x00000001
|
||||
#define RES_DEV_PLUG 0x00000002
|
||||
|
||||
/* flags for tiles */
|
||||
/* A tile which is part of a source/drain region. */
|
||||
#define RES_TILE_SD 0x1
|
||||
/* A tile which is actually a transistor */
|
||||
#define RES_TILE_TRAN 0x2
|
||||
/* A tile which is actually a device */
|
||||
#define RES_TILE_DEV 0x2
|
||||
/* Indicates whether the tile has been processed or not */
|
||||
#define RES_TILE_DONE 0x4
|
||||
/*a temporary marking flag */
|
||||
|
|
@ -566,7 +568,7 @@ typedef struct capval
|
|||
|
||||
/* Assorted Variables */
|
||||
|
||||
extern RTran *ResTranList;
|
||||
extern RDev *ResRDevList;
|
||||
extern REcell *ResBigEventList;
|
||||
extern int ResOptionsFlags;
|
||||
extern char *ResCurrentNode;
|
||||
|
|
@ -587,24 +589,24 @@ extern TileTypeBitMask ResConnectWithSD[NT];
|
|||
extern TileTypeBitMask ResCopyMask[NT];
|
||||
extern resResistor *ResResList;
|
||||
extern resNode *ResNodeList;
|
||||
extern resTransistor *ResTransList;
|
||||
extern resDevice *ResDevList;
|
||||
extern ResContactPoint *ResContactList;
|
||||
extern resNode *ResNodeQueue;
|
||||
extern resNode *ResOriginNode;
|
||||
extern resNode *resCurrentNode;
|
||||
extern HashTable ResNodeTable;
|
||||
extern HashTable ResSimTranTable;
|
||||
extern HashTable ResSimDevTable;
|
||||
extern ResFixPoint *ResFixList;
|
||||
extern int ResTileCount;
|
||||
extern ResSimNode **ResNodeArray;
|
||||
extern CellDef *mainDef;
|
||||
extern TileTypeBitMask ResSubsTypeBitMask;
|
||||
extern HashTable ResTranTable;
|
||||
extern HashTable ResDevTable;
|
||||
extern TileTypeBitMask ResNoMergeMask[NT];
|
||||
extern ResGlobalParams gparams;
|
||||
extern int ResPortIndex;
|
||||
|
||||
extern int ResSimTransistor();
|
||||
extern int ResSimDevice();
|
||||
extern int ResSimCombineParallel();
|
||||
extern int ResSimCapacitor();
|
||||
extern int ResSimResistor();
|
||||
|
|
@ -613,16 +615,16 @@ extern int ResSimMerge();
|
|||
extern int dbSrConnectStartFunc();
|
||||
extern int ResEach(),ResAddPlumbing(),ResRemovePlumbing();
|
||||
extern float ResCalculateChildCapacitance();
|
||||
extern ResTranTile *DBTreeCopyConnectDCS();
|
||||
extern ResDevTile *DBTreeCopyConnectDCS();
|
||||
extern Tile *ResFindTile();
|
||||
extern resTransistor *ResImageAddPlug();
|
||||
extern resTransistor *ResGetTransistor();
|
||||
extern resDevice *ResImageAddPlug();
|
||||
extern resDevice *ResGetDevice();
|
||||
extern tileJunk *resAddField();
|
||||
extern int ResCheckPorts();
|
||||
extern int ResCheckBlackbox();
|
||||
extern void ResCheckSimNodes();
|
||||
extern void ResSortByGate();
|
||||
extern void ResFixTranName();
|
||||
extern void ResFixDevName();
|
||||
extern void ResWriteLumpFile();
|
||||
extern void ResSortBreaks();
|
||||
|
||||
|
|
@ -649,7 +651,7 @@ extern void ResSortBreaks();
|
|||
#define ResJunkInit(Junk) \
|
||||
{ \
|
||||
Junk->contactList = (cElement *) NULL; \
|
||||
Junk->transistorList = (resTransistor *) NULL; \
|
||||
Junk->deviceList = (resDevice *) NULL; \
|
||||
Junk->junctionList = (ResJunction *) NULL; \
|
||||
Junk->breakList = (Breakpoint *) NULL; \
|
||||
Junk->portList = (resPort *) NULL; \
|
||||
|
|
|
|||
45
utils/hash.c
45
utils/hash.c
|
|
@ -557,6 +557,51 @@ HashStats(table)
|
|||
printf("# of buckets with %d entries: %d.\n", i, count[i]);
|
||||
printf("# of buckets with >%d entries: %d.\n", MAXCOUNT-1, overflow);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------
|
||||
*
|
||||
* HashRemove --
|
||||
*
|
||||
* Remove an entry from the hash table. The entry
|
||||
* is assumed to have no data (NULL value). Only
|
||||
* use this routine on STRINGKEY type hash tables.
|
||||
* If the entry does not exist, then the routine
|
||||
* returns without doing anything.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*---------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
HashRemove(table, key)
|
||||
HashTable *table; /* Hash table to search. */
|
||||
char *key; /* Interpreted according to table->ht_ptrKeys
|
||||
* as described in HashInit()'s comments.
|
||||
*/
|
||||
{
|
||||
HashEntry *h, *hlast;
|
||||
int bucket;
|
||||
|
||||
bucket = hash(table, key);
|
||||
h = *(table->ht_table + bucket);
|
||||
hlast = NULL;
|
||||
while (h != NIL)
|
||||
{
|
||||
if (strcmp(h->h_key.h_name, key) == 0)
|
||||
{
|
||||
freeMagic((char *)h);
|
||||
if (hlast != NULL)
|
||||
hlast->h_next = h->h_next;
|
||||
else
|
||||
*(table->ht_table + bucket) = h->h_next;
|
||||
break;
|
||||
}
|
||||
hlast = h;
|
||||
h = h->h_next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------
|
||||
*
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ extern void HashInit(HashTable *, int, int), HashInitClient(), HashStats(), Hash
|
|||
HashFreeKill();
|
||||
extern HashEntry *HashFind(HashTable *, char *);
|
||||
extern HashEntry *HashLookOnly(HashTable *, char *);
|
||||
extern void HashRemove(HashTable *, char *);
|
||||
extern void HashStartSearch(HashSearch *);
|
||||
extern HashEntry *HashNext(HashTable *, HashSearch *);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue