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