Merge branch 'RTimothyEdwards:master' into spice_hier

This commit is contained in:
Dan Moore 2021-06-29 12:06:19 -07:00 committed by GitHub
commit f6b4671d96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 3944 additions and 4050 deletions

View File

@ -1 +1 @@
8.3.164 8.3.182

View File

@ -882,7 +882,8 @@ calmaElementSref(filename)
if (rtype == CALMA_PROPATTR) if (rtype == CALMA_PROPATTR)
{ {
READI2(propAttrType); READI2(propAttrType);
if (propAttrType == CALMA_PROP_USENAME) if (propAttrType == CALMA_PROP_USENAME ||
propAttrType == CALMA_PROP_USENAME_STD)
{ {
char *s; char *s;
@ -1262,7 +1263,19 @@ calmaFindCell(name, was_called, predefined)
if (was_called) *was_called = FALSE; if (was_called) *was_called = FALSE;
} }
else else
if (was_called) *was_called = TRUE; {
if (was_called)
{
if (*was_called == TRUE)
{
def = DBCellLookDef(name);
if ((def != NULL) && (def->cd_flags & CDAVAILABLE))
if (CalmaNoDuplicates)
if (predefined) *predefined = TRUE;
}
*was_called = TRUE;
}
}
return (CellDef *) HashGetValue(h); return (CellDef *) HashGetValue(h);
} }

View File

@ -46,6 +46,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "textio/textio.h" #include "textio/textio.h"
#include "calma/calmaInt.h" #include "calma/calmaInt.h"
#include "commands/commands.h" /* for CmdGetRootPoint */ #include "commands/commands.h" /* for CmdGetRootPoint */
#include "utils/main.h" /* for EditCellUse */
#include "utils/undo.h" #include "utils/undo.h"
/* Globals for Calma reading */ /* Globals for Calma reading */
@ -164,6 +165,12 @@ CalmaReadFile(file, filename)
static int skipBeforeLib[] = { CALMA_LIBDIRSIZE, CALMA_SRFNAME, static int skipBeforeLib[] = { CALMA_LIBDIRSIZE, CALMA_SRFNAME,
CALMA_LIBSECUR, -1 }; CALMA_LIBSECUR, -1 };
if (EditCellUse == (CellUse *)NULL)
{
TxError("Cannot read GDS: There is no edit cell.\n");
return;
}
/* We will use full cell names as keys in this hash table */ /* We will use full cell names as keys in this hash table */
CIFReadCellInit(0); CIFReadCellInit(0);

View File

@ -26,6 +26,7 @@ static char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic-8.0/c
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <sys/types.h> #include <sys/types.h>
#include <arpa/inet.h> /* for htons() */
#ifdef SYSV #ifdef SYSV
#include <time.h> #include <time.h>
#else #else
@ -146,6 +147,7 @@ int calmaPaintLayerType;
*/ */
HashTable calmaLibHash; HashTable calmaLibHash;
HashTable calmaPrefixHash; HashTable calmaPrefixHash;
HashTable calmaUndefHash;
/* Imports */ /* Imports */
extern time_t time(); extern time_t time();
@ -285,6 +287,8 @@ CalmaWrite(rootDef, f)
int oldCount = DBWFeedbackCount, problems; int oldCount = DBWFeedbackCount, problems;
bool good; bool good;
CellUse dummy; CellUse dummy;
HashEntry *he;
HashSearch hs;
/* /*
* Do not attempt to write anything if a CIF/GDS output style * Do not attempt to write anything if a CIF/GDS output style
@ -298,6 +302,7 @@ CalmaWrite(rootDef, f)
HashInit(&calmaLibHash, 32, 0); HashInit(&calmaLibHash, 32, 0);
HashInit(&calmaPrefixHash, 32, 0); HashInit(&calmaPrefixHash, 32, 0);
HashInit(&calmaUndefHash, 32, 0);
/* /*
* Make sure that the entire hierarchy rooted at rootDef is * Make sure that the entire hierarchy rooted at rootDef is
@ -337,7 +342,31 @@ CalmaWrite(rootDef, f)
* to insure that each child cell is output before it is used. The * to insure that each child cell is output before it is used. The
* root cell is output last. * root cell is output last.
*/ */
(void) calmaProcessDef(rootDef, f, CalmaDoLibrary); calmaProcessDef(rootDef, f, CalmaDoLibrary);
/*
* Check for any cells that were instanced in the output definition
* (by dumping a GDS file from a read-only view) but were never
* defined (because the dumped GDS contained undefined references).
* If these are in the database but were not part of the tree of
* rootDef, then output them at the end.
*/
HashStartSearch(&hs);
while ((he = HashNext(&calmaUndefHash, &hs)) != NULL)
{
char *refname = (char *)HashGetValue(he);
if (refname && (refname[0] == '0'))
{
CellDef *extraDef;
extraDef = DBCellLookDef((char *)he->h_key.h_name);
if (extraDef != NULL)
calmaProcessDef(extraDef, f, FALSE);
else
TxError("Error: Cell %s is not defined in the output file!\n",
refname + 1);
}
}
/* Finish up by outputting the end-of-library marker */ /* Finish up by outputting the end-of-library marker */
calmaOutRH(4, CALMA_ENDLIB, CALMA_NODATA, f); calmaOutRH(4, CALMA_ENDLIB, CALMA_NODATA, f);
@ -355,6 +384,7 @@ CalmaWrite(rootDef, f)
HashFreeKill(&calmaLibHash); HashFreeKill(&calmaLibHash);
HashKill(&calmaPrefixHash); HashKill(&calmaPrefixHash);
HashFreeKill(&calmaUndefHash);
return (good); return (good);
} }
@ -409,14 +439,47 @@ calmaDumpStructure(def, outf, calmaDefHash, filename)
calmaOutDate(def->cd_timestamp, outf); calmaOutDate(def->cd_timestamp, outf);
calmaOutDate(time((time_t *) 0), outf); calmaOutDate(time((time_t *) 0), outf);
/* Find the structure's unique prefix, in case structure calls subcells */ /* Do a quick check of the calmaUndefHash table to see if this cell */
/* that are not yet defined. */ /* was previously used in a GDS file that does not define it (a GDS */
/* addendum library). */
he2 = HashFind(&calmaLibHash, filename); he = HashLookOnly(&calmaUndefHash, strname);
if (he2 == NULL) if (he != NULL)
TxError("Fatal error: Library %s not recorded!\n", filename); {
HashSearch hs;
char *undefname = (char *)HashGetValue(he);
HashStartSearch(&hs);
while ((he2 = HashNext(&calmaLibHash, &hs)) != NULL)
{
prefix = (char *)HashGetValue(he2);
if (!strncmp(prefix, undefname + 1, strlen(prefix)))
break;
}
if (he2 == NULL)
{
prefix = (char *)NULL;
TxError("Error: Unreferenced cell %s prefix is unrecorded!\n",
undefname);
}
else
{
/* Remove this entry from the hash table */
freeMagic(undefname);
HashRemove(&calmaUndefHash, strname);
}
}
else else
prefix = (char *)HashGetValue(he2); {
/* Find the structure's unique prefix, in case structure calls */
/* subcells that are not yet defined. */
he2 = HashFind(&calmaLibHash, filename);
if (he2 == NULL)
TxError("Fatal error: Library %s not recorded!\n", filename);
else
prefix = (char *)HashGetValue(he2);
}
/* Prefix structure name with def name, and output new structure name */ /* Prefix structure name with def name, and output new structure name */
he = HashFind(calmaDefHash, strname); he = HashFind(calmaDefHash, strname);
@ -456,16 +519,20 @@ calmaDumpStructure(def, outf, calmaDefHash, filename)
if (edef != NULL) if (edef != NULL)
{ {
bool isAbstract, isReadOnly; bool isAbstract, isReadOnly;
char *chklibname, *dotptr; char *chklibname, *filenamesubbed = NULL;
/* Is view abstract? */ /* Is view abstract? */
DBPropGet(edef, "LEFview", &isAbstract); DBPropGet(edef, "LEFview", &isAbstract);
chklibname = (char *)DBPropGet(edef, "GDS_FILE", &isReadOnly); chklibname = (char *)DBPropGet(edef, "GDS_FILE", &isReadOnly);
dotptr = strrchr(filename, '.');
if (dotptr) *dotptr = '\0';
/* Is the library name the same as the filename (less extension)? */ if (isAbstract && isReadOnly)
if (isAbstract && isReadOnly && !strcmp(filename, chklibname)) {
filenamesubbed = StrDup(NULL, filename);
DBPathSubstitute(filename, filenamesubbed, edef);
}
/* Is the library name the same as the filename? */
if (isAbstract && isReadOnly && !strcmp(filenamesubbed, chklibname))
{ {
/* Same library, so keep the cellname and mark the cell */ /* Same library, so keep the cellname and mark the cell */
/* as having been written to GDS. */ /* as having been written to GDS. */
@ -487,7 +554,7 @@ calmaDumpStructure(def, outf, calmaDefHash, filename)
HashSetValue(he, (char *)newnameptr); HashSetValue(he, (char *)newnameptr);
} }
} }
if (dotptr) *dotptr = '.'; if (filenamesubbed) freeMagic(filenamesubbed);
} }
else else
{ {
@ -614,11 +681,12 @@ calmaFullDump(def, fi, outf, filename)
char *filename; char *filename;
{ {
int version, rval; int version, rval;
char *libname = NULL, uniqlibname[4]; char *libname = NULL, *testlib, uniqlibname[4];
char *sptr, *viewopts; char *sptr, *viewopts;
bool isAbstract; bool isAbstract;
HashTable calmaDefHash; HashTable calmaDefHash;
HashEntry *he; HashSearch hs;
HashEntry *he, *he2;
static int hdrSkip[] = { CALMA_FORMAT, CALMA_MASK, CALMA_ENDMASKS, static int hdrSkip[] = { CALMA_FORMAT, CALMA_MASK, CALMA_ENDMASKS,
CALMA_REFLIBS, CALMA_FONTS, CALMA_ATTRTABLE, CALMA_REFLIBS, CALMA_FONTS, CALMA_ATTRTABLE,
@ -645,6 +713,11 @@ calmaFullDump(def, fi, outf, filename)
// Record the GDS library so it will not be processed again. // Record the GDS library so it will not be processed again.
he = HashFind(&calmaLibHash, filename); he = HashFind(&calmaLibHash, filename);
if ((char *)HashGetValue(he) != NULL)
{
TxPrintf("Library %s has already been processed\n", libname);
return;
}
/* If property LEFview is defined as "no_prefix" instead of "TRUE", /* If property LEFview is defined as "no_prefix" instead of "TRUE",
* then do not create a unique prefix for subcells. This is generally * then do not create a unique prefix for subcells. This is generally
@ -672,8 +745,6 @@ calmaFullDump(def, fi, outf, filename)
*/ */
while (TRUE) while (TRUE)
{ {
HashEntry *he2;
rval = random() % 26; rval = random() % 26;
rval = 'A' + rval; rval = 'A' + rval;
uniqlibname[0] = (char)(rval & 127); uniqlibname[0] = (char)(rval & 127);
@ -700,6 +771,24 @@ calmaFullDump(def, fi, outf, filename)
calmaSkipExact(CALMA_ENDLIB); calmaSkipExact(CALMA_ENDLIB);
done: done:
/* Check that all references were resolved. If not, then it is
* probably because a library was an "addendum"-type library
* referencing things in other libraries. Move those cell
* references to the calmaUndefHash before killing calmaDefHash.
*/
HashStartSearch(&hs);
while ((he = HashNext(&calmaDefHash, &hs)) != NULL)
{
char *refname = (char *)HashGetValue(he);
if (refname[0] == '0')
{
he2 = HashFind(&calmaUndefHash, (char *)he->h_key.h_name);
HashSetValue(he2, StrDup(NULL, refname));
}
}
HashFreeKill(&calmaDefHash); HashFreeKill(&calmaDefHash);
if (libname != NULL) freeMagic(libname); if (libname != NULL) freeMagic(libname);
return; return;
@ -1346,7 +1435,7 @@ calmaWriteUseFunc(use, f)
if (!calmaIsUseNameDefault(use->cu_def->cd_name, use->cu_id)) if (!calmaIsUseNameDefault(use->cu_def->cd_name, use->cu_id))
{ {
calmaOutRH(6, CALMA_PROPATTR, CALMA_I2, f); calmaOutRH(6, CALMA_PROPATTR, CALMA_I2, f);
calmaOutI2(CALMA_PROP_USENAME, f); calmaOutI2(CALMA_PROP_USENAME_STD, f);
calmaOutStringRecord(CALMA_PROPVALUE, use->cu_id, f); calmaOutStringRecord(CALMA_PROPVALUE, use->cu_id, f);
} }

View File

@ -99,6 +99,7 @@
#define CALMA_NUMRECORDTYPES 60 /* Number of above types */ #define CALMA_NUMRECORDTYPES 60 /* Number of above types */
/* Property types defined for magic */ /* Property types defined for magic */
#define CALMA_PROP_USENAME_STD 61 /* To record non-default cell use ids */
#define CALMA_PROP_USENAME 98 /* To record non-default cell use ids */ #define CALMA_PROP_USENAME 98 /* To record non-default cell use ids */
#define CALMA_PROP_ARRAY_LIMITS 99 /* To record non-default array limits */ #define CALMA_PROP_ARRAY_LIMITS 99 /* To record non-default array limits */

View File

@ -4896,13 +4896,14 @@ CIFGenLayer(op, area, cellDef, origDef, temps, hier, clientdata)
TxError("%s: Cannot read rectangle values.\n", propname); TxError("%s: Cannot read rectangle values.\n", propname);
break; break;
} }
cifPlane = curPlane;
cifScale = (CIFCurStyle) ? CIFCurStyle->cs_scaleFactor : 1; cifScale = (CIFCurStyle) ? CIFCurStyle->cs_scaleFactor : 1;
bbox.r_xbot *= cifScale; bbox.r_xbot *= cifScale;
bbox.r_xtop *= cifScale; bbox.r_xtop *= cifScale;
bbox.r_ybot *= cifScale; bbox.r_ybot *= cifScale;
bbox.r_ytop *= cifScale; bbox.r_ytop *= cifScale;
cifScale = 1; cifScale = 1;
DBNMPaintPlane(cifPlane, CIF_SOLIDTYPE, &bbox, DBNMPaintPlane(curPlane, CIF_SOLIDTYPE, &bbox,
CIFPaintTable, (PaintUndoInfo *)NULL); CIFPaintTable, (PaintUndoInfo *)NULL);
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
{ {

View File

@ -911,6 +911,52 @@ CIFGenSubcells(def, area, output)
UndoEnable(); UndoEnable();
} }
/*
* ----------------------------------------------------------------------------
*
* ----------------------------------------------------------------------------
*/
int
cifHierElementFuncLow(use, transform, x, y, checkArea)
CellUse *use; /* CellUse being array-checked. */
Transform *transform; /* Transform from this instance to
* the parent.
*/
int x, y; /* Indices of this instance. */
Rect *checkArea; /* Area (in parent coords) to be
* CIF-generated.
*/
{
if (((x - use->cu_xlo) < 2) && ((y - use->cu_ylo) < 2))
return cifHierElementFunc(use, transform, x, y, checkArea);
else
return 0;
}
/*
* ----------------------------------------------------------------------------
*
* ----------------------------------------------------------------------------
*/
int
cifHierElementFuncHigh(use, transform, x, y, checkArea)
CellUse *use; /* CellUse being array-checked. */
Transform *transform; /* Transform from this instance to
* the parent.
*/
int x, y; /* Indices of this instance. */
Rect *checkArea; /* Area (in parent coords) to be
* CIF-generated.
*/
{
if (((use->cu_xhi - x) < 2) && ((use->cu_yhi - y) < 2))
return cifHierElementFunc(use, transform, x, y, checkArea);
else
return 0;
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1139,7 +1185,6 @@ cifHierArrayFunc(scx, output)
Rect childArea, parentArea, A, B, C, D, expandedArea; Rect childArea, parentArea, A, B, C, D, expandedArea;
CellUse *use; CellUse *use;
int radius, xsep, ysep, xsize, ysize, nx, ny, i, oldTileOps; int radius, xsep, ysep, xsize, ysize, nx, ny, i, oldTileOps;
int xhi, yhi;
bool anyInteractions = FALSE; bool anyInteractions = FALSE;
use = scx->scx_use; use = scx->scx_use;
@ -1147,17 +1192,9 @@ cifHierArrayFunc(scx, output)
if ((use->cu_xlo == use->cu_xhi) && (use->cu_ylo == use->cu_yhi)) if ((use->cu_xlo == use->cu_xhi) && (use->cu_ylo == use->cu_yhi))
return 2; return 2;
/* We only want interactions between neighboring cells, so reduce */ /* We only want interactions between neighboring cells, so only */
/* the array size to at most 2x2, process, then restore the */ /* look at the bottom-left 2x2 set when calculating A and B, and */
/* original array count. */ /* only look at the top-right 2x2 set when calculating C and D. */
xhi = use->cu_xhi;
yhi = use->cu_yhi;
if (use->cu_xlo != use->cu_xhi)
use->cu_xhi = use->cu_xlo + ((use->cu_xlo < use->cu_xhi) ? 1 : -1);
if (use->cu_ylo != use->cu_yhi)
use->cu_yhi = use->cu_ylo + ((use->cu_ylo < use->cu_yhi) ? 1 : -1);
/* Compute the sizes and separations of elements, in coordinates /* Compute the sizes and separations of elements, in coordinates
* of the parent. If the array is 1-dimensional, we set the * of the parent. If the array is 1-dimensional, we set the
@ -1200,6 +1237,12 @@ cifHierArrayFunc(scx, output)
* into CIFTotalPlanes. Note: in each case we have to yank a larger * into CIFTotalPlanes. Note: in each case we have to yank a larger
* area than we check, in order to include material that will be * area than we check, in order to include material that will be
* bloated or shrunk. * bloated or shrunk.
*
* (Updated 6/7/2021) A and B should be calculated and processed
* completely independently of C and D, or else if the array is
* small and the radius is large, then results from one will get
* picked up when making copies of the other, resulting in things
* getting painted out-of-bounds.
*/ */
/* A */ /* A */
@ -1211,7 +1254,7 @@ cifHierArrayFunc(scx, output)
A.r_ybot = use->cu_bbox.r_ybot + ysep - radius; A.r_ybot = use->cu_bbox.r_ybot + ysep - radius;
A.r_ytop = use->cu_bbox.r_ybot + ysize + radius; A.r_ytop = use->cu_bbox.r_ybot + ysize + radius;
GEO_EXPAND(&A, CIFCurStyle->cs_radius, &expandedArea); GEO_EXPAND(&A, CIFCurStyle->cs_radius, &expandedArea);
(void) DBArraySr(use, &expandedArea, cifHierElementFunc, (void) DBArraySr(use, &expandedArea, cifHierElementFuncLow,
(ClientData) &A); (ClientData) &A);
CIFErrorDef = use->cu_parent; CIFErrorDef = use->cu_parent;
CIFGen(CIFTotalDef, use->cu_def, &A, CIFTotalPlanes, CIFGen(CIFTotalDef, use->cu_def, &A, CIFTotalPlanes,
@ -1220,24 +1263,6 @@ cifHierArrayFunc(scx, output)
anyInteractions = TRUE; anyInteractions = TRUE;
} }
/* C */
if (xsep < xsize + radius)
{
C.r_xbot = use->cu_bbox.r_xtop - xsize - radius;
C.r_xtop = use->cu_bbox.r_xtop - xsep + radius;
C.r_ybot = use->cu_bbox.r_ytop - ysize - radius;
C.r_ytop = use->cu_bbox.r_ytop + radius;
GEO_EXPAND(&C, CIFCurStyle->cs_radius, &expandedArea);
(void) DBArraySr(use, &expandedArea, cifHierElementFunc,
(ClientData) &C);
CIFErrorDef = use->cu_parent;
CIFGen(CIFTotalDef, use->cu_def, &C, CIFTotalPlanes,
&CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE,
(ClientData)NULL);
anyInteractions = TRUE;
}
if ((xsep < xsize + radius) && (ysep < ysize + radius)) if ((xsep < xsize + radius) && (ysep < ysize + radius))
{ {
/* B */ /* B */
@ -1247,31 +1272,16 @@ cifHierArrayFunc(scx, output)
B.r_ybot = use->cu_bbox.r_ybot - radius; B.r_ybot = use->cu_bbox.r_ybot - radius;
B.r_ytop = use->cu_bbox.r_ybot + ysep - radius; B.r_ytop = use->cu_bbox.r_ybot + ysep - radius;
GEO_EXPAND(&B, CIFCurStyle->cs_radius, &expandedArea); GEO_EXPAND(&B, CIFCurStyle->cs_radius, &expandedArea);
(void) DBArraySr(use, &expandedArea, cifHierElementFunc, (void) DBArraySr(use, &expandedArea, cifHierElementFuncLow,
(ClientData) &B); (ClientData) &B);
CIFErrorDef = use->cu_parent; CIFErrorDef = use->cu_parent;
CIFGen(CIFTotalDef, use->cu_def, &B, CIFTotalPlanes, CIFGen(CIFTotalDef, use->cu_def, &B, CIFTotalPlanes,
&CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE,
(ClientData)NULL); (ClientData)NULL);
/* D */
D.r_xbot = use->cu_bbox.r_xtop - xsep + radius;
D.r_xtop = use->cu_bbox.r_xtop + radius;
D.r_ybot = use->cu_bbox.r_ytop - ysize - radius;
D.r_ytop = use->cu_bbox.r_ytop - ysep + radius;
GEO_EXPAND(&D, CIFCurStyle->cs_radius, &expandedArea);
(void) DBArraySr(use, &expandedArea, cifHierElementFunc,
(ClientData) &D);
CIFErrorDef = use->cu_parent;
CIFGen(CIFTotalDef, use->cu_def, &D, CIFTotalPlanes,
&CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE,
(ClientData)NULL);
} }
if (anyInteractions) if (anyInteractions)
{ {
/* Remove redundant CIF that's already in the children, and /* Remove redundant CIF that's already in the children, and
* make sure everything in the kids is in the parent too. * make sure everything in the kids is in the parent too.
*/ */
@ -1308,6 +1318,155 @@ cifHierArrayFunc(scx, output)
(ClientData) NULL); (ClientData) NULL);
} }
if ((nx > 1) && (ny > 1) && (xsep < xsize + radius)
&& (ysep < ysize + radius))
{
/* The bottom edge of the array (from B). */
cifHierXSpacing = xsep * scale;
cifHierYSpacing = 0;
cifHierXCount = nx-1;
cifHierYCount = 1;
SCALE(&B, scale, &cifArea);
(void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i],
&cifArea, &CIFSolidBits, cifHierPaintArrayFunc,
(ClientData) NULL);
/* The core of the array (copied from A and B). Copy area
* from A, but not to exceed 1/2 Y array separation, into the
* inside area of the array. If the expanded area is > 1/2
* the array separation, then there is no need to copy from
* area B. Otherwise, copy area from B, extending up to
* the bottom of the area just copied, and not to exceed
* 1/2 the X array separation.
*/
cifHierXSpacing = xsep * scale;
cifHierYSpacing = ysep * scale;
cifHierXCount = nx-1;
cifHierYCount = ny-1;
/* Find top edge of cell */
A.r_xbot = use->cu_bbox.r_xbot;
A.r_xtop = use->cu_bbox.r_xbot + xsep;
A.r_ybot = use->cu_bbox.r_ybot + ysep;
A.r_ytop = use->cu_bbox.r_ybot + ysize;
/* Expand up/down but not by more than 1/2 ysep */
if ((2 * radius) > ysep)
{
A.r_ybot -= (ysep >> 1);
A.r_ytop += (ysep >> 1);
}
else
{
A.r_ybot -= radius;
A.r_ytop += radius;
}
SCALE(&A, scale, &cifArea);
(void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i],
&cifArea, &CIFSolidBits, cifHierPaintArrayFunc,
(ClientData) NULL);
/* If the radius is more than half of ysep then there */
/* is nothing left that needs to be copied. */
if ((2 * radius) < ysep)
{
/* Find right edge of cell */
B.r_ybot = use->cu_bbox.r_ybot;
B.r_ytop = use->cu_bbox.r_ybot + ysep;
if (B.r_ytop > A.r_ybot) B.r_ytop = A.r_ybot;
B.r_xbot = use->cu_bbox.r_xbot + xsep;
B.r_xtop = use->cu_bbox.r_xbot + xsize;
/* Expand left/right but not by more than 1/2 xsep */
if ((2 * radius) > xsep)
{
B.r_xbot -= (xsep >> 1);
B.r_xtop += (xsep >> 1);
}
else
{
B.r_xbot -= radius;
B.r_xtop += radius;
}
SCALE(&B, scale, &cifArea);
(void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i],
&cifArea, &CIFSolidBits, cifHierPaintArrayFunc,
(ClientData) NULL);
}
}
}
CIFHierRects += CIFTileOps - oldTileOps;
}
/* Clean up from areas A and B */
cifHierCleanup();
anyInteractions = FALSE;
/* Now do areas C and D */
/* C */
if (xsep < xsize + radius)
{
C.r_xbot = use->cu_bbox.r_xtop - xsize - radius;
C.r_xtop = use->cu_bbox.r_xtop - xsep + radius;
C.r_ybot = use->cu_bbox.r_ytop - ysize - radius;
C.r_ytop = use->cu_bbox.r_ytop + radius;
GEO_EXPAND(&C, CIFCurStyle->cs_radius, &expandedArea);
(void) DBArraySr(use, &expandedArea, cifHierElementFuncHigh,
(ClientData) &C);
CIFErrorDef = use->cu_parent;
CIFGen(CIFTotalDef, use->cu_def, &C, CIFTotalPlanes,
&CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE,
(ClientData)NULL);
anyInteractions = TRUE;
}
if ((xsep < xsize + radius) && (ysep < ysize + radius))
{
/* D */
D.r_xbot = use->cu_bbox.r_xtop - xsep + radius;
D.r_xtop = use->cu_bbox.r_xtop + radius;
D.r_ybot = use->cu_bbox.r_ytop - ysize - radius;
D.r_ytop = use->cu_bbox.r_ytop - ysep + radius;
GEO_EXPAND(&D, CIFCurStyle->cs_radius, &expandedArea);
(void) DBArraySr(use, &expandedArea, cifHierElementFuncHigh,
(ClientData) &D);
CIFErrorDef = use->cu_parent;
CIFGen(CIFTotalDef, use->cu_def, &D, CIFTotalPlanes,
&CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE,
(ClientData)NULL);
}
if (anyInteractions)
{
/* Remove redundant CIF that's already in the children, and
* make sure everything in the kids is in the parent too.
*/
CIFErrorDef = use->cu_parent;
cifCheckAndErase(CIFCurStyle);
/* Lastly, paint everything back from our local planes into
* the planes of the caller. In doing this, stuff has to
* be replicated many times over to cover each of the array
* interaction areas.
*/
oldTileOps = CIFTileOps;
for (i=0; i<CIFCurStyle->cs_nLayers; i++)
{
int scale = CIFCurStyle->cs_scaleFactor;
Rect cifArea;
cifHierCurPlane = output[i];
CurCifLayer = CIFCurStyle->cs_layers[i]; /* for growSliver */
/* The top edge of the array (from C). */ /* The top edge of the array (from C). */
if ((nx > 1) && (xsep < xsize + radius)) if ((nx > 1) && (xsep < xsize + radius))
@ -1325,17 +1484,6 @@ cifHierArrayFunc(scx, output)
if ((nx > 1) && (ny > 1) && (xsep < xsize + radius) if ((nx > 1) && (ny > 1) && (xsep < xsize + radius)
&& (ysep < ysize + radius)) && (ysep < ysize + radius))
{ {
/* The bottom edge of the array (from B). */
cifHierXSpacing = xsep * scale;
cifHierYSpacing = 0;
cifHierXCount = nx-1;
cifHierYCount = 1;
SCALE(&B, scale, &cifArea);
(void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i],
&cifArea, &CIFSolidBits, cifHierPaintArrayFunc,
(ClientData) NULL);
/* The right edge of the array (from D). */ /* The right edge of the array (from D). */
cifHierXSpacing = 0; cifHierXSpacing = 0;
@ -1346,36 +1494,12 @@ cifHierArrayFunc(scx, output)
(void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i], (void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i],
&cifArea, &CIFSolidBits, cifHierPaintArrayFunc, &cifArea, &CIFSolidBits, cifHierPaintArrayFunc,
(ClientData) NULL); (ClientData) NULL);
/* The core of the array (from A and B). This code is a bit
* tricky in order to work correctly even for arrays where
* radius < ysep. The "if" statement handles this case.
*/
cifHierXSpacing = xsep * scale;
cifHierYSpacing = ysep * scale;
cifHierXCount = nx-1;
cifHierYCount = ny-1;
parentArea.r_xbot = A.r_xtop - xsep;
parentArea.r_ybot = A.r_ytop - ysep;
if (parentArea.r_ybot > B.r_ytop) parentArea.r_ybot = B.r_ytop;
parentArea.r_xtop = A.r_xtop;
parentArea.r_ytop = A.r_ytop;
SCALE(&parentArea, scale, &cifArea);
(void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i],
&cifArea, &CIFSolidBits, cifHierPaintArrayFunc,
(ClientData) NULL);
} }
} }
CIFHierRects += CIFTileOps - oldTileOps; CIFHierRects += CIFTileOps - oldTileOps;
} }
cifHierCleanup(); cifHierCleanup();
/* Restore the array bounds of the array */
use->cu_xhi = xhi;
use->cu_yhi = yhi;
return 2; return 2;
} }

View File

@ -4261,6 +4261,11 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx)
cellnameptr++; cellnameptr++;
fullpathname = (char *)mallocMagic(strlen(cmd->tx_argv[1]) + 2); fullpathname = (char *)mallocMagic(strlen(cmd->tx_argv[1]) + 2);
strcpy(fullpathname, cmd->tx_argv[1]); strcpy(fullpathname, cmd->tx_argv[1]);
/* If the name still has ".mag" attached, then strip it. */
clen = strlen(fullpathname);
if ((clen > 4) && !strcmp(fullpathname + clen - 4, ".mag"))
*(fullpathname + clen - 4) = '\0';
} }
else else
{ {
@ -4307,8 +4312,8 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx)
def = DBCellLookDef(newcellname); def = DBCellLookDef(newcellname);
uniqchar++; uniqchar++;
} }
TxError("Renaming cell to \"%s\" to avoid conflict.", newcellname); TxError("Renaming cell to \"%s\" to avoid conflict.\n", newcellname);
def = DBCellNewDef(cellnameptr); def = DBCellNewDef(newcellname);
StrDup(&def->cd_file, fullpathname); StrDup(&def->cd_file, fullpathname);
freeMagic(newcellname); freeMagic(newcellname);
} }
@ -4396,15 +4401,10 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx)
TxError("Keyword must be followed by a reference point\n"); TxError("Keyword must be followed by a reference point\n");
goto usage; goto usage;
} }
if (StrIsInt(av[1])) else if (ac == 3)
{ {
childPoint.p_x = atoi(av[1]); childPoint.p_x = cmdParseCoord(w, av[1], TRUE, TRUE);
if (ac < 3 || !StrIsInt(av[2])) childPoint.p_y = cmdParseCoord(w, av[2], TRUE, FALSE);
{
TxError("Must provide two coordinates\n");
goto usage;
}
childPoint.p_y = atoi(av[2]);
av += 3; av += 3;
ac -= 3; ac -= 3;
} }
@ -4455,15 +4455,10 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx)
TxError("Keyword must be followed by a reference point\n"); TxError("Keyword must be followed by a reference point\n");
goto usage; goto usage;
} }
if (StrIsInt(av[1])) else if (ac == 3)
{ {
editPoint.p_x = atoi(av[1]); editPoint.p_x = cmdParseCoord(w, av[1], TRUE, TRUE);
if (ac < 3 || !StrIsInt(av[2])) editPoint.p_y = cmdParseCoord(w, av[2], TRUE, FALSE);
{
TxError("Must provide two coordinates\n");
goto usage;
}
editPoint.p_y = atoi(av[2]);
av += 3; av += 3;
ac -= 3; ac -= 3;
GeoTransPoint(&EditToRootTransform, &editPoint, GeoTransPoint(&EditToRootTransform, &editPoint,

View File

@ -2008,14 +2008,18 @@ CmdFlatten(w, cmd)
return; return;
} }
/* create the new def */ /* create the new def */
if (newdef = DBCellLookDef(destname)) newdef = DBCellLookDef(destname);
if ((newdef != NULL) && (dobox == FALSE))
{ {
TxError("%s already exists\n",destname); TxError("%s already exists\n",destname);
return; return;
} }
newdef = DBCellNewDef(destname); else if (newdef == NULL)
ASSERT(newdef, "CmdFlatten"); {
DBCellSetAvail(newdef); newdef = DBCellNewDef(destname);
ASSERT(newdef, "CmdFlatten");
DBCellSetAvail(newdef);
}
newuse = DBCellNewUse(newdef, (char *) NULL); newuse = DBCellNewUse(newdef, (char *) NULL);
(void) StrDup(&(newuse->cu_id), "Flattened cell"); (void) StrDup(&(newuse->cu_id), "Flattened cell");
DBSetTrans(newuse, &GeoIdentityTransform); DBSetTrans(newuse, &GeoIdentityTransform);
@ -2063,5 +2067,6 @@ CmdFlatten(w, cmd)
if (xMask != CU_DESCEND_ALL) if (xMask != CU_DESCEND_ALL)
DBCellCopyAllCells(&scx, xMask, flatDestUse, (Rect *)NULL); DBCellCopyAllCells(&scx, xMask, flatDestUse, (Rect *)NULL);
DBCellDeleteUse(flatDestUse);
UndoEnable(); UndoEnable();
} }

View File

@ -1612,8 +1612,9 @@ DBCellLookDef(cellName)
{ {
HashEntry *entry; HashEntry *entry;
entry = HashFind(&dbCellDefTable, cellName); entry = HashLookOnly(&dbCellDefTable, cellName);
return ((CellDef *) HashGetValue(entry)); if (entry == (HashEntry *)NULL) return (CellDef *)NULL;
return (CellDef *)HashGetValue(entry);
} }

View File

@ -816,6 +816,7 @@ extern void DBTechInitContact();
extern void DBTechFinalContact(); extern void DBTechFinalContact();
extern void DBTechFinalConnect(); extern void DBTechFinalConnect();
extern void DBTechInitConnect(); extern void DBTechInitConnect();
extern bool DBIsContact();
/* Cell symbol table */ /* Cell symbol table */
extern void DBCellInit(); extern void DBCellInit();

View File

@ -326,6 +326,7 @@ DBWloadWindow(window, name, flags)
{ {
deleteDef = ((CellUse *)window->w_surfaceID)->cu_def; deleteDef = ((CellUse *)window->w_surfaceID)->cu_def;
if (strcmp(deleteDef->cd_name, "(UNNAMED)") || if (strcmp(deleteDef->cd_name, "(UNNAMED)") ||
(GrDisplayStatus == DISPLAY_SUSPEND) ||
deleteDef->cd_flags & (CDMODIFIED|CDBOXESCHANGED|CDSTAMPSCHANGED)) deleteDef->cd_flags & (CDMODIFIED|CDBOXESCHANGED|CDSTAMPSCHANGED))
deleteDef = NULL; deleteDef = NULL;
} }
@ -497,7 +498,7 @@ DBWloadWindow(window, name, flags)
if (newEdit) if (newEdit)
{ {
if (EditCellUse && EditRootDef) if ((EditCellUse && EditRootDef) && (deleteDef == NULL))
{ {
DBWUndoOldEdit(EditCellUse, EditRootDef, DBWUndoOldEdit(EditCellUse, EditRootDef,
&EditToRootTransform, &RootToEditTransform); &EditToRootTransform, &RootToEditTransform);
@ -549,6 +550,11 @@ DBWloadWindow(window, name, flags)
/* If the cell before loading was (UNNAMED) and it was */ /* If the cell before loading was (UNNAMED) and it was */
/* never modified, then delete it now. */ /* never modified, then delete it now. */
/* Caveat: The (UNNAMED) cell could be on a push stack; */
/* that is not fatal but should be avoided. Since the most */
/* common use is from the toolkit scripts, then make sure */
/* this doesn't happen within suspendall ... resumeall. */
if (deleteDef != NULL) if (deleteDef != NULL)
DBCellDelete(deleteDef->cd_name, TRUE); DBCellDelete(deleteDef->cd_name, TRUE);
} }

View File

@ -613,6 +613,14 @@ drcCifTile (tile, arg)
if (SigInterruptPending) return 1; if (SigInterruptPending) return 1;
DRCstatTiles++; DRCstatTiles++;
/* For non-Manhattan tiles, if the left side of tile is not the */
/* type that is declared by the rule, then skip the left-right */
/* check. */
if (IsSplit(tile))
if (SplitSide(tile))
goto tbcheck;
/* /*
* Check design rules along a vertical boundary between two tiles. * Check design rules along a vertical boundary between two tiles.
* *
@ -801,6 +809,15 @@ drcCifTile (tile, arg)
} }
} }
tbcheck:
/* For non-Manhattan tiles, if the bottom side of tile is not */
/* the type that is declared by the rule, then skip the top- */
/* bottom check. */
if (IsSplit(tile))
if (SplitSide(tile) == SplitDirection(tile))
return 0;
/* /*
* Check design rules along a horizontal boundary between two tiles. * Check design rules along a horizontal boundary between two tiles.

View File

@ -1836,6 +1836,7 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
bool needtrigger = FALSE; bool needtrigger = FALSE;
bool touchingok = TRUE; bool touchingok = TRUE;
bool cornerok = FALSE; bool cornerok = FALSE;
bool surroundok = FALSE;
if (!strcmp(adjacency, "surround_ok")) if (!strcmp(adjacency, "surround_ok"))
{ {
@ -1858,6 +1859,7 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
needtrigger = TRUE; needtrigger = TRUE;
touchingok = FALSE; touchingok = FALSE;
needReverse = TRUE; needReverse = TRUE;
surroundok = TRUE;
} }
else else
{ {
@ -2077,10 +2079,11 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
/* /*
* Now, if set1 and set2 are distinct apply the rule for LHS in set1 * Now, if set1 and set2 are distinct apply the rule for LHS in set1
* and RHS in set2. * and RHS in set2. HOWEVER, "surround_ok" rules are asymmetrically
* triggered and cannot be reversed between set1 and set2.
*/ */
if (pset = (DBTypesOnSamePlane(i, j) & pmask2)) if ((!surroundok) && (pset = (DBTypesOnSamePlane(i, j) & pmask2)))
{ {
plane = LowestMaskBit(pset); plane = LowestMaskBit(pset);

View File

@ -97,39 +97,39 @@ struct {
short resClassSub ; /* The resistance class of the substrate of the dev */ short resClassSub ; /* The resistance class of the substrate of the dev */
TileType devType ; /* Magic tile type of the device */ TileType devType ; /* Magic tile type of the device */
char *defSubs ; /* The default substrate node */ char *defSubs ; /* The default substrate node */
} fetInfo[MAXDEVTYPES]; } fetInfo[TT_MAXTYPES];
typedef struct { typedef struct {
long visitMask:MAXDEVTYPES; TileTypeBitMask visitMask;
} nodeClient; } nodeClient;
typedef struct { typedef struct {
HierName *lastPrefix; HierName *lastPrefix;
long visitMask:MAXDEVTYPES; TileTypeBitMask visitMask;
} nodeClientHier; } nodeClientHier;
#define NO_RESCLASS -1 #define NO_RESCLASS -1
#define markVisited(client, rclass) \ #define markVisited(client, rclass) \
{ (client)->visitMask |= (1<<rclass); } { TTMaskSetType(&((client)->visitMask), rclass); }
#define clearVisited(client) \ #define clearVisited(client) \
{ (client)->visitMask = (long)0; } { TTMaskZero(&((client)->visitMask)); }
#define beenVisited(client, rclass) \ #define beenVisited(client, rclass) \
( (client)->visitMask & (1<<rclass)) ( TTMaskHasType(&((client)->visitMask), rclass) )
#define initNodeClient(node) \ #define initNodeClient(node) \
{ \ { \
(node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClient))); \ (node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClient))); \
(( nodeClient *)(node)->efnode_client)->visitMask = (long) 0; \ TTMaskZero(&(( nodeClient *)(node)->efnode_client)->visitMask); \
} }
#define initNodeClientHier(node) \ #define initNodeClientHier(node) \
{ \ { \
(node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClientHier))); \ (node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClientHier))); \
((nodeClientHier *) (node)->efnode_client)->visitMask = (long) 0; \ TTMaskZero(&(( nodeClientHier *)(node)->efnode_client)->visitMask); \
} }
@ -572,7 +572,7 @@ runexttosim:
/* create default fetinfo entries (MOSIS) which can be overriden by /* create default fetinfo entries (MOSIS) which can be overriden by
the command line arguments */ the command line arguments */
for ( i = 0 ; i < MAXDEVTYPES ; i++ ) for ( i = 0 ; i < TT_MAXTYPES ; i++ )
{ {
fetInfo[i].resClassSource = NO_RESCLASS; fetInfo[i].resClassSource = NO_RESCLASS;
fetInfo[i].resClassDrain = NO_RESCLASS; fetInfo[i].resClassDrain = NO_RESCLASS;
@ -589,12 +589,12 @@ runexttosim:
while (ExtGetDevInfo(idx++, &devname, &devtype, &s_rclass, &d_rclass, while (ExtGetDevInfo(idx++, &devname, &devtype, &s_rclass, &d_rclass,
&sub_rclass, &subname)) &sub_rclass, &subname))
{ {
if (idx == MAXDEVTYPES) if (idx == TT_MAXTYPES)
{ {
TxError("Error: Ran out of space for device types!\n"); TxError("Error: Ran out of space for device types!\n");
break; break;
} }
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, devname); i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, devname);
if (EFStyle != NULL) if (EFStyle != NULL)
{ {
@ -676,26 +676,26 @@ main(argc, argv)
EFInit(); EFInit();
/* create default fetinfo entries (MOSIS) which can be overriden by /* create default fetinfo entries (MOSIS) which can be overriden by
the command line arguments */ the command line arguments */
for ( i = 0 ; i < MAXDEVTYPES ; i++ ) { for ( i = 0 ; i < TT_MAXTYPES ; i++ ) {
fetInfo[i].resClassSource = NO_RESCLASS; fetInfo[i].resClassSource = NO_RESCLASS;
fetInfo[i].resClassDrain = NO_RESCLASS; fetInfo[i].resClassDrain = NO_RESCLASS;
fetInfo[i].resClassSub = NO_RESCLASS; fetInfo[i].resClassSub = NO_RESCLASS;
fetInfo[i].defSubs = NULL; fetInfo[i].defSubs = NULL;
fetInfo[i].devType = TT_SPACE; fetInfo[i].devType = TT_SPACE;
} }
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "nfet"); i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, "nfet");
fetInfo[i].resClassSource = fetInfo[i].resClassDrain = 0 ; fetInfo[i].resClassSource = fetInfo[i].resClassDrain = 0 ;
fetInfo[i].resClassSub = NO_RESCLASS ; fetInfo[i].resClassSub = NO_RESCLASS ;
fetInfo[i].defSubs = "Gnd!"; fetInfo[i].defSubs = "Gnd!";
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "pfet"); i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, "pfet");
fetInfo[i].resClassSource = fetInfo[i].resClassDrain = 1 ; fetInfo[i].resClassSource = fetInfo[i].resClassDrain = 1 ;
fetInfo[i].resClassSub = 6 ; fetInfo[i].resClassSub = 6 ;
fetInfo[i].defSubs = "Vdd!"; fetInfo[i].defSubs = "Vdd!";
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "nmos"); i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, "nmos");
fetInfo[i].resClassSource = fetInfo[i].resClassDrain = 0 ; fetInfo[i].resClassSource = fetInfo[i].resClassDrain = 0 ;
fetInfo[i].resClassSub = NO_RESCLASS ; fetInfo[i].resClassSub = NO_RESCLASS ;
fetInfo[i].defSubs = "Gnd!"; fetInfo[i].defSubs = "Gnd!";
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "pmos"); i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, "pmos");
fetInfo[i].resClassSource = fetInfo[i].resClassDrain = 1 ; fetInfo[i].resClassSource = fetInfo[i].resClassDrain = 1 ;
fetInfo[i].resClassSub = 6 ; fetInfo[i].resClassSub = 6 ;
fetInfo[i].defSubs = "Vdd!"; fetInfo[i].defSubs = "Vdd!";
@ -896,7 +896,7 @@ simmainArgs(pargc, pargv)
rClassSub = NO_RESCLASS ; rClassSub = NO_RESCLASS ;
if ( sscanf(rp, "%d/%s", &rClass, subsNode) != 2 ) goto usage; if ( sscanf(rp, "%d/%s", &rClass, subsNode) != 2 ) goto usage;
} }
ndx = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, cp); ndx = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, cp);
fetInfo[ndx].resClassSource = rClass; fetInfo[ndx].resClassSource = rClass;
fetInfo[ndx].resClassDrain = rClass; fetInfo[ndx].resClassDrain = rClass;
fetInfo[ndx].resClassSub = rClassSub; fetInfo[ndx].resClassSub = rClassSub;
@ -1206,9 +1206,6 @@ simdevVisit(dev, hc, scale, trans)
/* Output length, width, and position as attributes */ /* Output length, width, and position as attributes */
fprintf(esSimF, " l=%g w=%g x=%g y=%g", fprintf(esSimF, " l=%g w=%g x=%g y=%g",
l * scale, w * scale, r.r_xbot * scale, r.r_ybot * scale); l * scale, w * scale, r.r_xbot * scale, r.r_ybot * scale);
/* Output tile type as an attribute for quick lookup by ResReadSim */
fprintf(esSimF, " t=%d", fetInfo[dev->dev_type].devType);
} }
else if ((dev->dev_class != DEV_DIODE) && (dev->dev_class != DEV_PDIODE) else if ((dev->dev_class != DEV_DIODE) && (dev->dev_class != DEV_PDIODE)
&& (dev->dev_class != DEV_NDIODE)) { && (dev->dev_class != DEV_NDIODE)) {
@ -1402,7 +1399,7 @@ bool simnAPHier(dterm, hierName, resClass, scale, outf)
initNodeClientHier(node); initNodeClientHier(node);
nc = (nodeClientHier *)node->efnode_client; nc = (nodeClientHier *)node->efnode_client;
if ( nc->lastPrefix != hierName ) { if ( nc->lastPrefix != hierName ) {
nc->visitMask = 0; TTMaskZero(&(nc->visitMask));
nc->lastPrefix = hierName; nc->lastPrefix = hierName;
} }
if ( resClass == NO_RESCLASS || if ( resClass == NO_RESCLASS ||

View File

@ -1264,10 +1264,10 @@ spcnodeHierVisit(hc, node, res, cap)
if (node->efnode_client) if (node->efnode_client)
{ {
isConnected = (esDistrJunct) ? if (esDistrJunct)
(((nodeClient *)node->efnode_client)->m_w.widths != NULL) : isConnected = (((nodeClient *)node->efnode_client)->m_w.widths != NULL);
((((nodeClient *)node->efnode_client)->m_w.visitMask else
& DEV_CONNECT_MASK) != 0); isConnected = !TTMaskIsZero(&((nodeClient *)node->efnode_client)->m_w.visitMask);
} }
if (!isConnected && esDevNodesOnly) if (!isConnected && esDevNodesOnly)
return 0; return 0;

View File

@ -79,7 +79,7 @@ int esNoModelType; /* index for device type "None" (model-less device) */
HashTable subcktNameTable ; /* the hash table itself */ HashTable subcktNameTable ; /* the hash table itself */
DQueue subcktNameQueue ; /* q used to print it sorted at the end*/ DQueue subcktNameQueue ; /* q used to print it sorted at the end*/
fetInfoList esFetInfo[MAXDEVTYPES]; fetInfoList esFetInfo[TT_MAXTYPES];
/* Record for keeping a list of global names */ /* Record for keeping a list of global names */
@ -90,7 +90,7 @@ typedef struct GLL {
char *gll_name; char *gll_name;
} globalList; } globalList;
unsigned long initMask = 0; TileTypeBitMask initMask; /* Used for device types, not tile types */
bool esMergeDevsA = FALSE; /* aggressive merging of devs L1=L2 merge them */ bool esMergeDevsA = FALSE; /* aggressive merging of devs L1=L2 merge them */
bool esMergeDevsC = FALSE; /* conservative merging of devs L1=L2 and W1=W2 */ bool esMergeDevsC = FALSE; /* conservative merging of devs L1=L2 and W1=W2 */
@ -728,7 +728,7 @@ runexttospice:
/* create default devinfo entries (MOSIS) which can be overridden by /* create default devinfo entries (MOSIS) which can be overridden by
the command line arguments */ the command line arguments */
for ( i = 0 ; i < MAXDEVTYPES ; i++ ) { for ( i = 0 ; i < TT_MAXTYPES ; i++ ) {
esFetInfo[i].resClassSource = NO_RESCLASS; esFetInfo[i].resClassSource = NO_RESCLASS;
esFetInfo[i].resClassDrain = NO_RESCLASS; esFetInfo[i].resClassDrain = NO_RESCLASS;
esFetInfo[i].resClassSub = NO_RESCLASS; esFetInfo[i].resClassSub = NO_RESCLASS;
@ -743,12 +743,12 @@ runexttospice:
while (ExtGetDevInfo(idx++, &devname, &devtype, &s_rclass, &d_rclass, while (ExtGetDevInfo(idx++, &devname, &devtype, &s_rclass, &d_rclass,
&sub_rclass, &subname)) &sub_rclass, &subname))
{ {
if (idx == MAXDEVTYPES) if (idx == TT_MAXTYPES)
{ {
TxError("Error: Ran out of space for device types!\n"); TxError("Error: Ran out of space for device types!\n");
break; break;
} }
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, devname); i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, devname);
if (!strcmp(devname, "None")) if (!strcmp(devname, "None"))
esNoModelType = i; esNoModelType = i;
if (EFStyle != NULL) if (EFStyle != NULL)
@ -908,7 +908,9 @@ runexttospice:
if (!esDoPorts) if (!esDoPorts)
EFVisitSubcircuits(subcktUndef, (ClientData) NULL); EFVisitSubcircuits(subcktUndef, (ClientData) NULL);
initMask = ( esDistrJunct ) ? (unsigned long)0 : DEV_CONNECT_MASK; TTMaskZero(&initMask);
if (!esDistrJunct)
TTMaskCom(&initMask);
if (esMergeDevsA || esMergeDevsC) if (esMergeDevsA || esMergeDevsC)
{ {
@ -924,7 +926,7 @@ runexttospice:
else if (esDistrJunct) else if (esDistrJunct)
EFVisitDevs(devDistJunctVisit, (ClientData) NULL); EFVisitDevs(devDistJunctVisit, (ClientData) NULL);
EFVisitDevs(spcdevVisit, (ClientData) NULL); EFVisitDevs(spcdevVisit, (ClientData) NULL);
initMask = (unsigned long) 0; TTMaskZero(&initMask);
if (flatFlags & EF_FLATCAPS) if (flatFlags & EF_FLATCAPS)
{ {
(void) sprintf( esSpiceCapFormat, "C%%d %%s %%s %%.%dlffF\n", (void) sprintf( esSpiceCapFormat, "C%%d %%s %%s %%.%dlffF\n",
@ -994,25 +996,25 @@ main(argc, argv)
EFResistThreshold = INFINITE_THRESHOLD ; EFResistThreshold = INFINITE_THRESHOLD ;
/* create default devinfo entries (MOSIS) which can be overriden by /* create default devinfo entries (MOSIS) which can be overriden by
the command line arguments */ the command line arguments */
for ( i = 0 ; i < MAXDEVTYPES ; i++ ) { for ( i = 0 ; i < TT_MAXTYPES ; i++ ) {
esFetInfo[i].resClassSource = NO_RESCLASS; esFetInfo[i].resClassSource = NO_RESCLASS;
esFetInfo[i].resClassDrain = NO_RESCLASS; esFetInfo[i].resClassDrain = NO_RESCLASS;
esFetInfo[i].resClassSub = NO_RESCLASS; esFetInfo[i].resClassSub = NO_RESCLASS;
esFetInfo[i].defSubs = NULL; esFetInfo[i].defSubs = NULL;
} }
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "ndev"); i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, "ndev");
esFetInfo[i].resClassSource = esFetInfo[i].resClassDrain = 0 ; esFetInfo[i].resClassSource = esFetInfo[i].resClassDrain = 0 ;
esFetInfo[i].resClassSub = NO_RESCLASS ; esFetInfo[i].resClassSub = NO_RESCLASS ;
esFetInfo[i].defSubs = "Gnd!"; esFetInfo[i].defSubs = "Gnd!";
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "pdev"); i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, "pdev");
esFetInfo[i].resClassSource = esFetInfo[i].resClassDrain = 1 ; esFetInfo[i].resClassSource = esFetInfo[i].resClassDrain = 1 ;
esFetInfo[i].resClassSub = 8 ; esFetInfo[i].resClassSub = 8 ;
esFetInfo[i].defSubs = "Vdd!"; esFetInfo[i].defSubs = "Vdd!";
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "nmos"); i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, "nmos");
esFetInfo[i].resClassSource = esFetInfo[i].resClassDrain = 0 ; esFetInfo[i].resClassSource = esFetInfo[i].resClassDrain = 0 ;
esFetInfo[i].resClassSub = NO_RESCLASS ; esFetInfo[i].resClassSub = NO_RESCLASS ;
esFetInfo[i].defSubs = "Gnd!"; esFetInfo[i].defSubs = "Gnd!";
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "pmos"); i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, "pmos");
esFetInfo[i].resClassSource = esFetInfo[i].resClassDrain = 1 ; esFetInfo[i].resClassSource = esFetInfo[i].resClassDrain = 1 ;
esFetInfo[i].resClassSub = 8 ; esFetInfo[i].resClassSub = 8 ;
esFetInfo[i].defSubs = "Vdd!"; esFetInfo[i].defSubs = "Vdd!";
@ -1078,7 +1080,9 @@ main(argc, argv)
if (!esDoPorts) if (!esDoPorts)
EFVisitSubcircuits(subcktUndef, (ClientData) NULL); EFVisitSubcircuits(subcktUndef, (ClientData) NULL);
initMask = ( esDistrJunct ) ? (unsigned long)0 : DEV_CONNECT_MASK ; TTMaskZero(&initMask);
if (!esDistrJunct)
TTMaskCom(&initMask);
if ( esMergeDevsA || esMergeDevsC ) { if ( esMergeDevsA || esMergeDevsC ) {
EFVisitDevs(devMergeVisit, (ClientData) NULL); EFVisitDevs(devMergeVisit, (ClientData) NULL);
@ -1092,7 +1096,7 @@ main(argc, argv)
} else if ( esDistrJunct ) } else if ( esDistrJunct )
EFVisitDevs(devDistJunctVisit, (ClientData) NULL); EFVisitDevs(devDistJunctVisit, (ClientData) NULL);
EFVisitDevs(spcdevVisit, (ClientData) NULL); EFVisitDevs(spcdevVisit, (ClientData) NULL);
initMask = (unsigned long) 0; TTMaskZero(&initMask);
if (flatFlags & EF_FLATCAPS) { if (flatFlags & EF_FLATCAPS) {
(void) sprintf( esSpiceCapFormat, "C%%d %%s %%s %%.%dlffF\n",esCapAccuracy); (void) sprintf( esSpiceCapFormat, "C%%d %%s %%s %%.%dlffF\n",esCapAccuracy);
EFVisitCaps(spccapVisit, (ClientData) NULL); EFVisitCaps(spccapVisit, (ClientData) NULL);
@ -1240,17 +1244,9 @@ spcmainArgs(pargc, pargv)
rClassSub = -1 ; rClassSub = -1 ;
if ( sscanf(rp, "%d/%s", &rClass, subsNode) != 2 ) goto usage; if ( sscanf(rp, "%d/%s", &rClass, subsNode) != 2 ) goto usage;
} }
ndx = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, cp); ndx = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, cp);
esFetInfo[ndx].resClassSource = esFetInfo[ndx].resClassDrain = rClass; esFetInfo[ndx].resClassSource = esFetInfo[ndx].resClassDrain = rClass;
esFetInfo[ndx].resClassSub = rClassSub; esFetInfo[ndx].resClassSub = rClassSub;
if ( ((1<<rClass) & DEV_CONNECT_MASK) ||
((1<<rClass) & DEV_CONNECT_MASK) ) {
TxError("Oops it seems that you have 31\n");
TxError("resistance classes. You will need to recompile");
TxError("the extflat package and change ext2sim/spice\n");
TxError("DEV_CONNECT_MASK and or nodeClient\n");
exit (1);
}
esFetInfo[ndx].defSubs = (char *)mallocMagic((unsigned)(strlen(subsNode)+1)); esFetInfo[ndx].defSubs = (char *)mallocMagic((unsigned)(strlen(subsNode)+1));
strcpy(esFetInfo[ndx].defSubs,subsNode); strcpy(esFetInfo[ndx].defSubs,subsNode);
TxError("info: dev %s(%d) srcRclass=%d drnRclass=%d subRclass=%d dSub=%s\n", TxError("info: dev %s(%d) srcRclass=%d drnRclass=%d subRclass=%d dSub=%s\n",
@ -2910,8 +2906,10 @@ FILE *outf;
initNodeClientHier(nn->efnn_node); initNodeClientHier(nn->efnn_node);
if (!esDistrJunct) if (!esDistrJunct)
((nodeClient *)nn->efnn_node->efnode_client)->m_w.visitMask |= {
DEV_CONNECT_MASK; TTMaskZero(&((nodeClient *)nn->efnn_node->efnode_client)->m_w.visitMask);
TTMaskCom(&((nodeClient *)nn->efnn_node->efnode_client)->m_w.visitMask);
}
return nn->efnn_node; return nn->efnn_node;
} }
} }
@ -3126,7 +3124,10 @@ spcdevOutNode(prefix, suffix, name, outf)
/* Mark node as visited */ /* Mark node as visited */
if (!esDistrJunct) if (!esDistrJunct)
((nodeClient *)nn->efnn_node->efnode_client)->m_w.visitMask |= DEV_CONNECT_MASK; {
TTMaskZero(&((nodeClient *)nn->efnn_node->efnode_client)->m_w.visitMask);
TTMaskCom(&((nodeClient *)nn->efnn_node->efnode_client)->m_w.visitMask);
}
return (1 + strlen(nname)); return (1 + strlen(nname));
} }
@ -3279,8 +3280,7 @@ spcnodeVisit(node, res, cap)
{ {
isConnected = (esDistrJunct) ? isConnected = (esDistrJunct) ?
(((nodeClient *)node->efnode_client)->m_w.widths != NULL) : (((nodeClient *)node->efnode_client)->m_w.widths != NULL) :
((((nodeClient *)node->efnode_client)->m_w.visitMask (!TTMaskIsZero(&((nodeClient *)node->efnode_client)->m_w.visitMask));
& DEV_CONNECT_MASK) != 0);
} }
if (!isConnected && esDevNodesOnly) if (!isConnected && esDevNodesOnly)
return 0; return 0;

View File

@ -60,7 +60,7 @@ extern FILE *esSpiceF;
extern float esScale; /* negative if hspice the EFScale/100 otherwise */ extern float esScale; /* negative if hspice the EFScale/100 otherwise */
extern unsigned short esFormat; extern unsigned short esFormat;
extern unsigned long initMask; extern TileTypeBitMask initMask;
extern int esCapNum, esDevNum, esResNum, esDiodeNum; extern int esCapNum, esDevNum, esResNum, esDiodeNum;
extern int esNodeNum; /* just in case we're extracting spice2 */ extern int esNodeNum; /* just in case we're extracting spice2 */
@ -96,19 +96,15 @@ typedef struct {
char *defSubs ; /* the default substrate node */ char *defSubs ; /* the default substrate node */
} fetInfoList; } fetInfoList;
extern fetInfoList esFetInfo[MAXDEVTYPES]; extern fetInfoList esFetInfo[TT_MAXTYPES];
#define MAX_STR_SIZE (1<<11) /* 2K should be enough for keeping temp #define MAX_STR_SIZE (1<<11) /* 2K should be enough for keeping temp
names even of the most complicated design */ names even of the most complicated design */
/* Node clients for figuring out areas and perimeters of sources and drains */ /* Node clients for figuring out areas and perimeters of sources and drains */
typedef struct {
long _duml:MAXDEVTYPES;
} _dum; /* if you get an error here you should change
the data structures and visitMask */
typedef union { typedef union {
long visitMask; /* mask for normal visits */ TileTypeBitMask visitMask; /* mask for normal visits */
float *widths; /* width used for distributing area perim */ float *widths; /* width used for distributing area perim */
} maskOrWidth ; } maskOrWidth ;
@ -125,32 +121,27 @@ typedef struct {
#define NO_RESCLASS -1 #define NO_RESCLASS -1
#define markVisited(client, rclass) \ #define markVisited(client, rclass) \
{ (client)->m_w.visitMask |= (1<<rclass); } { TTMaskSetType(&((client)->m_w.visitMask), rclass); }
#define clearVisited(client) \ #define clearVisited(client) \
{ (client)->m_w.visitMask = (long)0; } { TTMaskZero(&((client)->m_w.visitMask)); }
#define beenVisited(client, rclass) \ #define beenVisited(client, rclass) \
( (client)->m_w.visitMask & (1<<rclass)) ( TTMaskHasType(&((client)->m_w.visitMask), rclass) )
/*
* Used to mark the nodes which are connected to devs. initMask is set to
* DEV_CONNECT_MASK only when we are in visitDevs
*/
#define DEV_CONNECT_MASK ((unsigned long)1<<(sizeof(long)*BITSPERCHAR-1))
#define initNodeClient(node) \ #define initNodeClient(node) \
{ \ { \
(node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClient))); \ (node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClient))); \
(( nodeClient *)(node)->efnode_client)->spiceNodeName = NULL; \ (( nodeClient *)(node)->efnode_client)->spiceNodeName = NULL; \
(( nodeClient *)(node)->efnode_client)->m_w.visitMask = (unsigned long)initMask; \ TTMaskZero (&((nodeClient *) (node)->efnode_client)->m_w.visitMask); \
TTMaskSetMask(&(((nodeClient *)(node)->efnode_client)->m_w.visitMask), &initMask);\
} }
#define initNodeClientHier(node) \ #define initNodeClientHier(node) \
{ \ { \
(node)->efnode_client = (ClientData) mallocMagic((unsigned)(sizeof(nodeClientHier))); \ (node)->efnode_client = (ClientData) mallocMagic((unsigned)(sizeof(nodeClientHier))); \
((nodeClientHier *) (node)->efnode_client)->m_w.visitMask = (unsigned long) 0; \ TTMaskZero (&((nodeClientHier *) (node)->efnode_client)->m_w.visitMask); \
} }

View File

@ -42,36 +42,36 @@ int antennacheckArgs();
int antennacheckVisit(); int antennacheckVisit();
typedef struct { typedef struct {
long visitMask:MAXDEVTYPES; TileTypeBitMask visitMask;
} nodeClient; } nodeClient;
typedef struct { typedef struct {
HierName *lastPrefix; HierName *lastPrefix;
long visitMask:MAXDEVTYPES; TileTypeBitMask visitMask;
} nodeClientHier; } nodeClientHier;
#define NO_RESCLASS -1 #define NO_RESCLASS -1
#define markVisited(client, rclass) \ #define markVisited(client, rclass) \
{ (client)->visitMask |= (1<<rclass); } { TTMaskSetType(&((client)->visitMask), rclass); }
#define clearVisited(client) \ #define clearVisited(client) \
{ (client)->visitMask = (long)0; } { TTMaskZero(&((client)->visitMask); }
#define beenVisited(client, rclass) \ #define beenVisited(client, rclass) \
( (client)->visitMask & (1<<rclass)) ( TTMaskHasType(&((client)->visitMask), rclass) )
#define initNodeClient(node) \ #define initNodeClient(node) \
{ \ { \
(node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClient))); \ (node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClient))); \
(( nodeClient *)(node)->efnode_client)->visitMask = (long) 0; \ TTMaskZero(&(( nodeClient *)(node)->efnode_client)->visitMask); \
} }
#define initNodeClientHier(node) \ #define initNodeClientHier(node) \
{ \ { \
(node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClientHier))); \ (node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClientHier))); \
((nodeClientHier *) (node)->efnode_client)->visitMask = (long) 0; \ TTMaskZero(&(( nodeClientHier *)(node)->efnode_client)->visitMask); \
} }
/* Diagnostic */ /* Diagnostic */
@ -228,9 +228,21 @@ runantennacheck:
TxPrintf("Building flattened netlist.\n"); TxPrintf("Building flattened netlist.\n");
EFFlatBuild(inName, flatFlags); EFFlatBuild(inName, flatFlags);
/* Get device information from the current extraction style */
idx = 0;
while (ExtGetDevInfo(idx++, &devname, NULL, NULL, NULL, NULL, NULL))
{
if (idx == TT_MAXTYPES)
{
TxError("Error: Ran out of space for device types!\n");
break;
}
efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, devname);
}
/* Build device lookup table */ /* Build device lookup table */
EFDeviceTypes = (TileType *)mallocMagic(MAXDEVTYPES * sizeof(TileType)); EFDeviceTypes = (TileType *)mallocMagic(EFDevNumTypes * sizeof(TileType));
for (i = 0; i < MAXDEVTYPES; i++) for (i = 0; i < EFDevNumTypes; i++)
if (EFDevTypes[i]) if (EFDevTypes[i])
EFDeviceTypes[i] = extGetDevType(EFDevTypes[i]); EFDeviceTypes[i] = extGetDevType(EFDevTypes[i]);

View File

@ -30,9 +30,10 @@ static char rcsid[] __attribute__ ((unused)) = "$Header$";
#include "utils/hash.h" #include "utils/hash.h"
#include "utils/utils.h" #include "utils/utils.h"
#include "utils/malloc.h" #include "utils/malloc.h"
#include "tiles/tile.h"
#include "database/database.h" /* for TileType definition */
#include "extflat/extflat.h" #include "extflat/extflat.h"
#include "extflat/EFint.h" #include "extflat/EFint.h"
#include "tiles/tile.h"
#include "extract/extract.h" /* for device class list */ #include "extract/extract.h" /* for device class list */
/* /*
@ -48,7 +49,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header$";
#define MAXTYPES 100 #define MAXTYPES 100
/* Table of transistor types */ /* Table of transistor types */
char *EFDevTypes[MAXDEVTYPES]; char *EFDevTypes[TT_MAXTYPES];
int EFDevNumTypes; int EFDevNumTypes;
/* Table of Magic layers */ /* Table of Magic layers */
@ -656,6 +657,8 @@ efBuildDevice(def, class, type, r, argc, argv)
DevTerm *term; DevTerm *term;
Dev *newdev, devtmp; Dev *newdev, devtmp;
DevParam *newparm, *devp, *sparm; DevParam *newparm, *devp, *sparm;
TileType ttype;
int dev_type;
char ptype, *pptr, **av; char ptype, *pptr, **av;
char devhash[64]; char devhash[64];
int argstart = 1; /* start of terminal list in argv[] */ int argstart = 1; /* start of terminal list in argv[] */
@ -799,9 +802,18 @@ efBuildDevice(def, class, type, r, argc, argv)
nterminals = (argc - argstart) / 3; nterminals = (argc - argstart) / 3;
/* Determine if this device has been seen before */ dev_type = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, type);
sprintf(devhash, "%dx%d%s", r->r_xbot, r->r_ybot, type); /* Determine if this device has been seen before */
/* NOTE: This is done by tile type, not name, because the extresist
* device extraction is less sophisticated than the standard extraction
* and does not differentiate between different device names belonging
* to the same tile type. The extGetDevType() function is not efficient,
* and all of this needs to be done better.
*/
ttype = extGetDevType(type);
sprintf(devhash, "%dx%d_%d", r->r_xbot, r->r_ybot, ttype);
he = HashFind(&def->def_devs, devhash); he = HashFind(&def->def_devs, devhash);
newdev = (Dev *)HashGetValue(he); newdev = (Dev *)HashGetValue(he);
if (newdev) if (newdev)
@ -813,10 +825,14 @@ efBuildDevice(def, class, type, r, argc, argv)
* *
* Check that the device is actually the same device type and number * Check that the device is actually the same device type and number
* of terminals. If not, throw an error and abandon the new device. * of terminals. If not, throw an error and abandon the new device.
*
* NOTE: Quick check is made on dev_type, but for the reason stated
* above for the calculation of ttype, only the tile types need to
* match, so make an additional (expensive) check on tile type.
*/ */
if ((newdev->dev_class != class) || if ((newdev->dev_class != class) || ((newdev->dev_type != dev_type)
(strcmp(EFDevTypes[newdev->dev_type], type))) && (ttype != extGetDevType(EFDevTypes[newdev->dev_type]))))
{ {
TxError("Device %s %s at (%d, %d) overlaps incompatible device %s %s!\n", TxError("Device %s %s at (%d, %d) overlaps incompatible device %s %s!\n",
extDevTable[class], type, r->r_xbot, r->r_ybot, extDevTable[class], type, r->r_xbot, r->r_ybot,
@ -849,7 +865,7 @@ efBuildDevice(def, class, type, r, argc, argv)
newdev->dev_nterm = nterminals; newdev->dev_nterm = nterminals;
newdev->dev_rect = *r; newdev->dev_rect = *r;
newdev->dev_type = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, type); newdev->dev_type = dev_type;
newdev->dev_class = class; newdev->dev_class = class;
switch (class) switch (class)

View File

@ -135,6 +135,7 @@ EFDone()
/* Misc cleanup */ /* Misc cleanup */
for (n = 0; n < EFDevNumTypes; n++) freeMagic(EFDevTypes[n]); for (n = 0; n < EFDevNumTypes; n++) freeMagic(EFDevTypes[n]);
EFDevNumTypes = 0;
/* Changed from n = 0 to n = 1; First entry "space" is predefined, */ /* Changed from n = 0 to n = 1; First entry "space" is predefined, */
/* not malloc'd. ---Tim 9/3/02 */ /* not malloc'd. ---Tim 9/3/02 */

View File

@ -342,9 +342,6 @@ extern char *EFHNToStr();
extern int EFGetPortMax(); extern int EFGetPortMax();
/* ------------------------- constants used by clients -------------- */ /* ------------------------- constants used by clients -------------- */
/* This gives us a 32 or 64 dev types which should be ok */
#define BITSPERCHAR 8
#define MAXDEVTYPES (sizeof(long)*BITSPERCHAR)
/* /*
* ANSI C definitions of arguments to EFvisit procedures * ANSI C definitions of arguments to EFvisit procedures

View File

@ -112,7 +112,7 @@ ExtCell(def, outName, doLength)
TxError("Cannot open output file: "); TxError("Cannot open output file: ");
perror(filename); perror(filename);
#endif #endif
return; return NULL;
} }
extNumFatal = extNumWarnings = 0; extNumFatal = extNumWarnings = 0;

View File

@ -203,15 +203,32 @@ extHierSubstrate(ha, use, x, y)
if (node1 != node2) if (node1 != node2)
{ {
/* if (node1->node_len < node2->node_len)
* Both sets of names will now point to node1. {
*/ /*
for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next) * Both sets of names will now point to node2.
*/
for (nn = node1->node_names; nn->nn_next; nn = nn->nn_next)
nn->nn_node = node2;
nn->nn_node = node2;
nn->nn_next = node2->node_names->nn_next;
node2->node_names->nn_next = node1->node_names;
node2->node_len += node1->node_len;
freeMagic((char *)node1);
}
else
{
/*
* Both sets of names will now point to node1.
*/
for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next)
nn->nn_node = node1; nn->nn_node = node1;
nn->nn_node = node1; nn->nn_node = node1;
nn->nn_next = node1->node_names; nn->nn_next = node1->node_names;
node1->node_names = node2->node_names; node1->node_names = node2->node_names;
freeMagic((char *) node2); node1->node_len += node2->node_len;
freeMagic((char *)node2);
}
} }
freeMagic(nodeList); freeMagic(nodeList);
} }
@ -385,17 +402,36 @@ extHierConnectFunc1(oneTile, ha)
if (node1 != node2) if (node1 != node2)
{ {
/* if (node1->node_len < node2->node_len)
* Both sets of names will now point to node1. {
* We don't need to update node_cap since it /*
* hasn't been computed yet. * Both sets of names will now point to node2.
*/ * We don't need to update node_cap since it
for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next) * hasn't been computed yet.
nn->nn_node = node1; */
nn->nn_node = node1; for (nn = node1->node_names; nn->nn_next; nn = nn->nn_next)
nn->nn_next = node1->node_names; nn->nn_node = node2;
node1->node_names = node2->node_names; nn->nn_node = node2;
freeMagic((char *) node2); nn->nn_next = node2->node_names->nn_next;
node2->node_names->nn_next = node1->node_names;
node2->node_len += node1->node_len;
freeMagic((char *) node1);
}
else
{
/*
* Both sets of names will now point to node1.
* We don't need to update node_cap since it
* hasn't been computed yet.
*/
for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next)
nn->nn_node = node1;
nn->nn_node = node1;
nn->nn_next = node1->node_names;
node1->node_names = node2->node_names;
node1->node_len += node2->node_len;
freeMagic((char *) node2);
}
} }
} }
} }
@ -470,17 +506,36 @@ extHierConnectFunc2(cum, ha)
if (node1 != node2) if (node1 != node2)
{ {
/* if (node1->node_len < node2->node_len)
* Both sets of names will now point to node1. {
* We don't need to update node_cap since it /*
* hasn't been computed yet. * Both sets of names will now point to node2.
*/ * We don't need to update node_cap since it
for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next) * hasn't been computed yet.
nn->nn_node = node1; */
nn->nn_node = node1; for (nn = node1->node_names; nn->nn_next; nn = nn->nn_next)
nn->nn_next = node1->node_names; nn->nn_node = node2;
node1->node_names = node2->node_names; nn->nn_node = node2;
freeMagic((char *) node2); nn->nn_next = node2->node_names->nn_next;
node2->node_names->nn_next = node1->node_names;
node2->node_len += node1->node_len;
freeMagic((char *) node1);
}
else
{
/*
* Both sets of names will now point to node1.
* We don't need to update node_cap since it
* hasn't been computed yet.
*/
for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next)
nn->nn_node = node1;
nn->nn_node = node1;
nn->nn_next = node1->node_names;
node1->node_names = node2->node_names;
node1->node_len += node2->node_len;
freeMagic((char *) node2);
}
} }
} }
else if (r.r_xtop > r.r_xbot && r.r_ytop > r.r_ybot) else if (r.r_xtop > r.r_xbot && r.r_ytop > r.r_ybot)
@ -553,17 +608,36 @@ extHierConnectFunc3(cum, ha)
if (node1 != node2) if (node1 != node2)
{ {
/* if (node1->node_len < node2->node_len)
* Both sets of names will now point to node1. {
* We don't need to update node_cap since it /*
* hasn't been computed yet. * Both sets of names will now point to node2.
*/ * We don't need to update node_cap since it
for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next) * hasn't been computed yet.
nn->nn_node = node1; */
nn->nn_node = node1; for (nn = node1->node_names; nn->nn_next; nn = nn->nn_next)
nn->nn_next = node1->node_names; nn->nn_node = node2;
node1->node_names = node2->node_names; nn->nn_node = node2;
freeMagic((char *) node2); nn->nn_next = node2->node_names->nn_next;
node2->node_names->nn_next = node1->node_names;
node2->node_len += node1->node_len;
freeMagic((char *) node1);
}
else
{
/*
* Both sets of names will now point to node1.
* We don't need to update node_cap since it
* hasn't been computed yet.
*/
for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next)
nn->nn_node = node1;
nn->nn_node = node1;
nn->nn_next = node1->node_names;
node1->node_names = node2->node_names;
node1->node_len += node2->node_len;
freeMagic((char *) node2);
}
} }
} }
else if (r.r_xtop > r.r_xbot && r.r_ytop > r.r_ybot) else if (r.r_xtop > r.r_xbot && r.r_ytop > r.r_ybot)
@ -810,6 +884,7 @@ extHierNewNode(he)
nn->nn_name = he->h_key.h_name; nn->nn_name = he->h_key.h_name;
node->node_names = nn; node->node_names = nn;
node->node_cap = (CapValue) 0; node->node_cap = (CapValue) 0;
node->node_len = 1;
for (n = 0; n < nclasses; n++) for (n = 0; n < nclasses; n++)
node->node_pa[n].pa_perim = node->node_pa[n].pa_area = 0; node->node_pa[n].pa_perim = node->node_pa[n].pa_area = 0;
HashSetValue(he, (char *) nn); HashSetValue(he, (char *) nn);

View File

@ -354,54 +354,63 @@ ExtGetDevInfo(idx, devnameptr, devtypeptr, s_rclassptr, d_rclassptr,
if (t == DBNumTypes) return FALSE; if (t == DBNumTypes) return FALSE;
if (devptr == NULL) return FALSE; if (devptr == NULL) return FALSE;
*devnameptr = locdname; if (devnameptr) *devnameptr = locdname;
*subnameptr = devptr->exts_deviceSubstrateName; if (subnameptr) *subnameptr = devptr->exts_deviceSubstrateName;
*devtypeptr = t; if (devtypeptr) *devtypeptr = t;
tmask = &devptr->exts_deviceSDTypes[0]; tmask = &devptr->exts_deviceSDTypes[0];
*s_rclassptr = (short)(-1); /* NO_RESCLASS */ if (s_rclassptr)
for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++)
{ {
rmask = &ExtCurStyle->exts_typesByResistClass[n]; *s_rclassptr = (short)(-1); /* NO_RESCLASS */
if (TTMaskIntersect(rmask, tmask))
{
*s_rclassptr = (short)n;
break;
}
}
tmask = &devptr->exts_deviceSDTypes[1];
if (TTMaskIsZero(tmask))
{
/* Set source and drain resistance classes to be the same */
*d_rclassptr = (short)n;
}
else
{
*d_rclassptr = (short)(-1); /* NO_RESCLASS */
for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++)
{ {
rmask = &ExtCurStyle->exts_typesByResistClass[n]; rmask = &ExtCurStyle->exts_typesByResistClass[n];
if (TTMaskIntersect(rmask, tmask)) if (TTMaskIntersect(rmask, tmask))
{ {
*d_rclassptr = (short)n; *s_rclassptr = (short)n;
break; break;
} }
} }
} }
tmask = &devptr->exts_deviceSubstrateTypes; if (d_rclassptr)
*sub_rclassptr = (short)(-1); /* NO_RESCLASS */
for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++)
{ {
rmask = &ExtCurStyle->exts_typesByResistClass[n]; tmask = &devptr->exts_deviceSDTypes[1];
if (TTMaskIntersect(rmask, tmask)) if (TTMaskIsZero(tmask))
{ {
*sub_rclassptr = (short)(n); /* Set source and drain resistance classes to be the same */
break; *d_rclassptr = (short)n;
}
else
{
*d_rclassptr = (short)(-1); /* NO_RESCLASS */
for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++)
{
rmask = &ExtCurStyle->exts_typesByResistClass[n];
if (TTMaskIntersect(rmask, tmask))
{
*d_rclassptr = (short)n;
break;
}
}
}
}
if (sub_rclassptr)
{
tmask = &devptr->exts_deviceSubstrateTypes;
*sub_rclassptr = (short)(-1); /* NO_RESCLASS */
for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++)
{
rmask = &ExtCurStyle->exts_typesByResistClass[n];
if (TTMaskIntersect(rmask, tmask))
{
*sub_rclassptr = (short)(n);
break;
}
} }
} }

View File

@ -943,6 +943,7 @@ typedef struct node
NodeName *node_names; /* List of names for this node. The first name NodeName *node_names; /* List of names for this node. The first name
* in the list is the "official" node name. * in the list is the "official" node name.
*/ */
int node_len; /* Number of entries in node_names */
CapValue node_cap; /* Capacitance to substrate */ CapValue node_cap; /* Capacitance to substrate */
PerimArea node_pa[1]; /* Dummy; each node actually has PerimArea node_pa[1]; /* Dummy; each node actually has
* ExtCurStyle->exts_numResistClasses * ExtCurStyle->exts_numResistClasses

View File

@ -776,7 +776,7 @@ lefWriteGeometry(tile, cdata)
lefClient *lefdata = (lefClient *)cdata; lefClient *lefdata = (lefClient *)cdata;
FILE *f = lefdata->file; FILE *f = lefdata->file;
float scale = lefdata->oscale; float scale = lefdata->oscale;
char leffmt[6][10]; char leffmt[6][16];
TileType ttype, otype = TiGetTypeExact(tile); TileType ttype, otype = TiGetTypeExact(tile);
LefMapping *lefMagicToLefLayer = lefdata->lefMagicMap; LefMapping *lefMagicToLefLayer = lefdata->lefMagicMap;

View File

@ -5,7 +5,7 @@
MODULE = resis MODULE = resis
MAGICDIR = .. MAGICDIR = ..
SRCS = ResMain.c ResJunct.c ResMakeRes.c ResSimple.c ResPrint.c \ SRCS = ResMain.c ResJunct.c ResMakeRes.c ResSimple.c ResPrint.c \
ResReadSim.c ResConDCS.c ResRex.c ResBasic.c ResMerge.c ResChecks.c \ ResReadSim.c ResRex.c ResBasic.c ResMerge.c ResChecks.c \
ResFract.c ResUtils.c ResDebug.c ResFract.c ResUtils.c ResDebug.c
include ${MAGICDIR}/defs.mak include ${MAGICDIR}/defs.mak

View File

@ -43,111 +43,113 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
*/ */
void void
ResSanityChecks(nodename,resistorList,nodeList,devlist) ResSanityChecks(nodename, resistorList, nodeList, devlist)
char *nodename; char *nodename;
resResistor *resistorList; resResistor *resistorList;
resNode *nodeList; resNode *nodeList;
resDevice *devlist; resDevice *devlist;
{ {
resResistor *resistor; resResistor *resistor;
resNode *node; resNode *node;
resDevice *dev; resDevice *dev;
resElement *rcell; resElement *rcell;
static Stack *resSanityStack = NULL; static Stack *resSanityStack = NULL;
int reached,foundorigin; int reached, foundorigin;
if (resSanityStack == NULL) if (resSanityStack == NULL)
{ {
resSanityStack = StackNew(64); resSanityStack = StackNew(64);
} }
for (node = nodeList; node != NULL; node=node->rn_more) for (node = nodeList; node != NULL; node=node->rn_more)
{ {
node->rn_status &= ~RES_REACHED_NODE; node->rn_status &= ~RES_REACHED_NODE;
if (node->rn_why == RES_NODE_ORIGIN) if (node->rn_why == RES_NODE_ORIGIN)
STACKPUSH((ClientData) node, resSanityStack); STACKPUSH((ClientData) node, resSanityStack);
} }
for (resistor = resistorList; resistor != NULL; resistor = resistor->rr_nextResistor) for (resistor = resistorList; resistor != NULL; resistor = resistor->rr_nextResistor)
{ {
resistor->rr_status &= ~RES_REACHED_RESISTOR; resistor->rr_status &= ~RES_REACHED_RESISTOR;
} }
/* Check 1- Are the resistors and nodes all connected? */ /* Check: Are the resistors and nodes all connected? */
while (!StackEmpty(resSanityStack)) while (!StackEmpty(resSanityStack))
{ {
node = (resNode *)STACKPOP(resSanityStack); node = (resNode *)STACKPOP(resSanityStack);
if (node->rn_status & RES_REACHED_NODE) continue; if (node->rn_status & RES_REACHED_NODE) continue;
node->rn_status |= RES_REACHED_NODE; node->rn_status |= RES_REACHED_NODE;
for (rcell = node->rn_re; rcell != NULL; rcell=rcell->re_nextEl) for (rcell = node->rn_re; rcell != NULL; rcell = rcell->re_nextEl)
{ {
resistor = rcell->re_thisEl; resistor = rcell->re_thisEl;
if (resistor->rr_status & RES_REACHED_RESISTOR) continue; if (resistor->rr_status & RES_REACHED_RESISTOR) continue;
resistor->rr_status |= RES_REACHED_RESISTOR; resistor->rr_status |= RES_REACHED_RESISTOR;
if (resistor->rr_connection1 != node && if (resistor->rr_connection1 != node &&
resistor->rr_connection2 != node) resistor->rr_connection2 != node)
{ {
TxError("Stray resElement pointer- node %s, pointer %d\n",nodename,rcell); TxError("Stray resElement pointer- node %s, pointer %d\n",
continue; nodename, rcell);
} continue;
if ((resistor->rr_connection1->rn_status & RES_REACHED_NODE) == 0) }
{ if ((resistor->rr_connection1->rn_status & RES_REACHED_NODE) == 0)
STACKPUSH((ClientData)resistor->rr_connection1,resSanityStack); {
} STACKPUSH((ClientData)resistor->rr_connection1, resSanityStack);
if ((resistor->rr_connection2->rn_status & RES_REACHED_NODE) == 0) }
{ if ((resistor->rr_connection2->rn_status & RES_REACHED_NODE) == 0)
STACKPUSH((ClientData)resistor->rr_connection2,resSanityStack); {
} STACKPUSH((ClientData)resistor->rr_connection2, resSanityStack);
} }
} }
for (resistor = resistorList; resistor != NULL; resistor = resistor->rr_nextResistor) }
{ for (resistor = resistorList; resistor != NULL; resistor = resistor->rr_nextResistor)
if ((resistor->rr_status & RES_REACHED_RESISTOR) == 0) {
{ if ((resistor->rr_status & RES_REACHED_RESISTOR) == 0)
TxError("Unreached resistor in %s\n",nodename); {
} TxError("Unreached resistor in %s\n", nodename);
resistor->rr_status &= ~RES_REACHED_RESISTOR; }
resistor->rr_status &= ~RES_REACHED_RESISTOR;
} }
for (dev = devlist; dev != NULL; dev = dev->rd_nextDev) for (dev = devlist; dev != NULL; dev = dev->rd_nextDev)
{ {
int i; int i;
if (dev->rd_status & RES_DEV_PLUG) continue; if (dev->rd_status & RES_DEV_PLUG) continue;
reached = FALSE; reached = FALSE;
for (i=0;i != dev->rd_nterms;i++) for (i = 0; i != dev->rd_nterms; i++)
{ {
if (dev->rd_terminals[i] != NULL) if (dev->rd_terminals[i] != NULL)
{ {
reached = TRUE; reached = TRUE;
if ((dev->rd_terminals[i]->rn_status & RES_REACHED_NODE) == 0) if ((dev->rd_terminals[i]->rn_status & RES_REACHED_NODE) == 0)
{ {
TxError("Device 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 device in %s at %d %d\n", TxError("Unreached device in %s at %d %d\n",
nodename, nodename,
dev->rd_inside.r_xbot, dev->rd_inside.r_xbot,
dev->rd_inside.r_ybot); dev->rd_inside.r_ybot);
} }
} }
foundorigin = 0; foundorigin = 0;
for (node = nodeList; node != NULL; node=node->rn_more) for (node = nodeList; node != NULL; node=node->rn_more)
{ {
if ((node->rn_status & RES_REACHED_NODE) == 0) if ((node->rn_status & RES_REACHED_NODE) == 0)
{ {
TxError("Unreached node in %s at %d, %d\n",nodename,node->rn_loc.p_x,node->rn_loc.p_y); TxError("Unreached node in %s at %d, %d\n", nodename,
} node->rn_loc.p_x, node->rn_loc.p_y);
node->rn_status &= ~RES_REACHED_NODE; }
if (node->rn_why & RES_NODE_ORIGIN) node->rn_status &= ~RES_REACHED_NODE;
{ if (node->rn_why & RES_NODE_ORIGIN)
foundorigin = 1; {
} foundorigin = 1;
} }
if (foundorigin == 0) }
{ if (foundorigin == 0)
TxError("Starting node not found in %s\n",nodename); {
} TxError("Starting node not found in %s\n", nodename);
}
} }
#endif #endif

View File

@ -1,547 +0,0 @@
/* ResConnectDCS.c --
*
* This contains a slightly modified version of DBTreeCopyConnect.
*/
#ifndef lint
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/resis/ResConDCS.c,v 1.5 2010/06/24 12:37:56 tim Exp $";
#endif /* not lint */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include "utils/magic.h"
#include "utils/geometry.h"
#include "utils/geofast.h"
#include "tiles/tile.h"
#include "utils/hash.h"
#include "utils/stack.h"
#include "database/database.h"
#include "utils/malloc.h"
#include "textio/textio.h"
#include "extract/extract.h"
#include "extract/extractInt.h"
#include "utils/signals.h"
#include "windows/windows.h"
#include "dbwind/dbwind.h"
#include "utils/tech.h"
#include "textio/txcommands.h"
#include "resis/resis.h"
extern int dbcUnconnectFunc();
extern int dbcConnectLabelFunc();
extern int dbcConnectFuncDCS();
#ifdef ARIEL
extern int resSubSearchFunc();
#endif
static ResDevTile *DevList = NULL;
static TileTypeBitMask DiffTypeBitMask;
TileTypeBitMask ResSubsTypeBitMask;
/* Forward declarations */
extern void ResCalcPerimOverlap();
/*
* ----------------------------------------------------------------------------
*
* dbcConnectFuncDCS -- the same as dbcConnectFunc, except that it does
* some extra searching around diffusion tiles looking for
* devices.
*
* Results:
* Always returns 0 to keep the search from aborting.
*
* Side effects:
* Adds a new record to the current check list. May also add new
* ResDevTile structures.
*
* ----------------------------------------------------------------------------
*/
int
dbcConnectFuncDCS(tile, cx)
Tile *tile;
TreeContext *cx;
{
struct conSrArg2 *csa2;
Rect tileArea, *srArea, devArea, newarea;
ResDevTile *thisDev;
TileTypeBitMask notConnectMask, *connectMask;
Tile *tp;
TileType t2, t1, loctype, ctype;
TileType dinfo = 0;
SearchContext *scx = cx->tc_scx;
SearchContext scx2;
int i, pNum;
CellDef *def;
ExtDevice *devptr;
TerminalPath tpath;
char pathstring[FLATTERMSIZE];
TiToRect(tile, &tileArea);
srArea = &scx->scx_area;
if (((tileArea.r_xbot >= srArea->r_xtop-1) ||
(tileArea.r_xtop <= srArea->r_xbot+1)) &&
((tileArea.r_ybot >= srArea->r_ytop-1) ||
(tileArea.r_ytop <= srArea->r_ybot+1)))
return 0;
t1 = TiGetType(tile);
if TTMaskHasType(&DiffTypeBitMask,t1)
{
/* left */
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp=RT(tp))
{
t2 = TiGetType(tp);
devptr = ExtCurStyle->exts_device[t2];
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) &&
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1))
{
TiToRect(tp, &devArea);
thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile)));
ResCalcPerimOverlap(thisDev,tp);
GeoTransRect(&scx->scx_trans, &devArea, &thisDev->area);
thisDev->type = TiGetType(tp);
thisDev->nextDev = DevList;
DevList = thisDev;
}
}
/*right*/
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp=LB(tp))
{
t2 = TiGetType(tp);
devptr = ExtCurStyle->exts_device[t2];
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) &&
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1))
{
TiToRect(tp, &devArea);
thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile)));
GeoTransRect(&scx->scx_trans, &devArea, &thisDev->area);
thisDev->type = TiGetType(tp);
thisDev->nextDev = DevList;
DevList = thisDev;
ResCalcPerimOverlap(thisDev,tp);
}
}
/*top*/
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp=BL(tp))
{
t2 = TiGetType(tp);
devptr = ExtCurStyle->exts_device[t2];
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) &&
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1))
{
TiToRect(tp, &devArea);
thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile)));
GeoTransRect(&scx->scx_trans, &devArea, &thisDev->area);
thisDev->type = TiGetType(tp);
thisDev->nextDev = DevList;
DevList = thisDev;
ResCalcPerimOverlap(thisDev,tp);
}
}
/*bottom */
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp=TR(tp))
{
t2 = TiGetType(tp);
devptr = ExtCurStyle->exts_device[t2];
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) &&
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1))
{
TiToRect(tp, &devArea);
thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile)));
GeoTransRect(&scx->scx_trans, &devArea, &thisDev->area);
thisDev->type = TiGetType(tp);
thisDev->nextDev = DevList;
DevList = thisDev;
ResCalcPerimOverlap(thisDev,tp);
}
}
}
else if TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t1)
{
TiToRect(tile, &devArea);
thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile)));
ResCalcPerimOverlap(thisDev,tile);
GeoTransRect(&scx->scx_trans, &devArea, &thisDev->area);
thisDev->type = TiGetType(tile);
thisDev->nextDev = DevList;
DevList = thisDev;
}
/* in some cases (primarily bipolar technology), we'll want to extract
devices whose substrate terminals are part of the given region.
The following does that check. (10-11-88)
*/
#ifdef ARIEL
if (TTMaskHasType(&ResSubsTypeBitMask,t1) && (ResOptionsFlags & ResOpt_DoSubstrate))
{
TileTypeBitMask *mask = &ExtCurStyle->exts_subsTransistorTypes[t1];
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
{
if (TTMaskIntersect(&DBPlaneTypes[pNum], mask))
{
(void)DBSrPaintArea((Tile *) NULL,
scx->scx_use->cu_def->cd_planes[pNum],
&tileArea,mask,resSubSearchFunc, (ClientData) cx);
}
}
}
#endif
GeoTransRect(&scx->scx_trans, &tileArea, &newarea);
csa2 = (struct conSrArg2 *)cx->tc_filter->tf_arg;
GeoClip(&newarea, csa2->csa2_bounds);
if (GEO_RECTNULL(&newarea)) return 0;
loctype = TiGetTypeExact(tile);
/* Resolve geometric transformations on diagonally-split tiles */
if (IsSplit(tile))
{
dinfo = DBTransformDiagonal(loctype, &scx->scx_trans);
loctype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
}
pNum = cx->tc_plane;
connectMask = &csa2->csa2_connect[loctype];
if (DBIsContact(loctype))
{
/* The mask of contact types must include all stacked contacts */
TTMaskZero(&notConnectMask);
TTMaskSetMask(&notConnectMask, &DBNotConnectTbl[loctype]);
}
else
{
TTMaskCom2(&notConnectMask, connectMask);
}
def = csa2->csa2_use->cu_def;
if (DBSrPaintNMArea((Tile *) NULL, def->cd_planes[pNum],
dinfo, &newarea, &notConnectMask, dbcUnconnectFunc,
(ClientData)NULL) == 0)
return 0;
DBNMPaintPlane(def->cd_planes[pNum], dinfo,
&newarea, DBStdPaintTbl(loctype, pNum),
(PaintUndoInfo *) NULL);
/* Check the source def for any labels belonging to this */
/* tile area and plane, and add them to the destination */
scx2 = *csa2->csa2_topscx;
scx2.scx_area = newarea;
pathstring[0] = '\0';
tpath.tp_first = tpath.tp_next = pathstring;
tpath.tp_last = pathstring + FLATTERMSIZE;
DBTreeSrLabels(&scx2, connectMask, csa2->csa2_xMask, &tpath,
TF_LABEL_ATTACH, dbcConnectLabelFunc,
(ClientData)csa2);
// DBCellCopyLabels(&scx2, connectMask, csa2->csa2_xMask, csa2->csa2_use, NULL);
/* Only extend those sides bordering the diagonal tile */
if (dinfo & TT_DIAGONAL)
{
if (dinfo & TT_SIDE) /* right */
newarea.r_xtop += 1;
else /* left */
newarea.r_xbot -= 1;
if (((dinfo & TT_SIDE) >> 1)
== (dinfo & TT_DIRECTION)) /* top */
newarea.r_ytop += 1;
else /* bottom */
newarea.r_ybot -= 1;
}
else
{
newarea.r_xbot -= 1;
newarea.r_ybot -= 1;
newarea.r_xtop += 1;
newarea.r_ytop += 1;
}
/* Check if any of the last 5 entries has the same type and */
/* area. If so, don't duplicate the existing entry. */
/* (NOTE: Connect masks are all from the same table, so */
/* they can be compared by address, no need for TTMaskEqual)*/
for (i = csa2->csa2_lasttop; (i >= 0) && (i > csa2->csa2_lasttop - 5); i--)
if (connectMask == csa2->csa2_list[i].connectMask)
if (GEO_SURROUND(&csa2->csa2_list[i].area, &newarea))
return 0;
/* Register the area and connection mask as needing to be processed */
if (++csa2->csa2_top == CSA2_LIST_SIZE)
{
/* Reached list size limit---need to enlarge the list */
/* Double the size of the list every time we hit the limit */
conSrArea *newlist;
newlist = (conSrArea *)mallocMagic(CSA2_LIST_SIZE * sizeof(conSrArea));
StackPush((ClientData)csa2->csa2_list, csa2->csa2_stack);
csa2->csa2_list = newlist;
csa2->csa2_top = 0;
}
csa2->csa2_list[csa2->csa2_top].area = newarea;
csa2->csa2_list[csa2->csa2_top].connectMask = connectMask;
csa2->csa2_list[csa2->csa2_top].dinfo = dinfo;
return 0;
}
/*
*-------------------------------------------------------------------------
*
* ResCalcPerimOverlap--
*
* Results:
* None.
*
* Side Effects:
*
*-------------------------------------------------------------------------
*/
void
ResCalcPerimOverlap(dev, tile)
ResDevTile *dev;
Tile *tile;
{
Tile *tp;
int t1;
int overlap;
dev->perim = (TOP(tile)-BOTTOM(tile)-LEFT(tile)+RIGHT(tile))<<1;
overlap =0;
t1 = TiGetType(tile);
/* left */
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp=RT(tp))
{
if TTMaskHasType(&(ExtCurStyle->exts_nodeConn[t1]),TiGetType(tp))
{
overlap += MIN(TOP(tile),TOP(tp))-
MAX(BOTTOM(tile),BOTTOM(tp));
}
}
/*right*/
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp=LB(tp))
{
if TTMaskHasType(&(ExtCurStyle->exts_nodeConn[t1]),TiGetType(tp))
{
overlap += MIN(TOP(tile),TOP(tp))-
MAX(BOTTOM(tile),BOTTOM(tp));
}
}
/*top*/
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp=BL(tp))
{
if TTMaskHasType(&(ExtCurStyle->exts_nodeConn[t1]),TiGetType(tp))
{
overlap += MIN(RIGHT(tile),RIGHT(tp))-
MAX(LEFT(tile),LEFT(tp));
}
}
/*bottom */
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp=TR(tp))
{
if TTMaskHasType(&(ExtCurStyle->exts_nodeConn[t1]),TiGetType(tp))
{
overlap += MIN(RIGHT(tile),RIGHT(tp))-
MAX(LEFT(tile),LEFT(tp));
}
}
dev->overlap = overlap;
}
/*
* ----------------------------------------------------------------------------
*
* DBTreeCopyConnectDCS --
*
* Basically the same as DBTreeCopyConnect, except it calls
* dbcConnectFuncDCS.
*
* Results:
* Linked list of devices.
*
* Side effects:
* The contents of the result cell are modified.
*
* ----------------------------------------------------------------------------
*/
ResDevTile *
DBTreeCopyConnectDCS(scx, mask, xMask, connect, area, destUse)
SearchContext *scx;
TileTypeBitMask *mask;
int xMask;
TileTypeBitMask *connect;
Rect *area;
CellUse *destUse;
{
static int first = 1;
struct conSrArg2 csa2;
int dev, pNum;
char *dev_name;
TileTypeBitMask *newmask;
ResDevTile *CurrentT;
CellDef *def = destUse->cu_def;
TileType newtype;
ExtDevice *devptr;
csa2.csa2_use = destUse;
csa2.csa2_xMask = xMask;
csa2.csa2_bounds = area;
csa2.csa2_connect = connect;
csa2.csa2_topscx = scx;
csa2.csa2_list = (conSrArea *)mallocMagic(CSA2_LIST_SIZE * sizeof(conSrArea));
csa2.csa2_top = -1;
csa2.csa2_lasttop = -1;
csa2.csa2_stack = StackNew(100);
if (first)
{
TTMaskZero(&DiffTypeBitMask);
TTMaskZero(&ResSubsTypeBitMask);
for (dev = TT_TECHDEPBASE; dev < TT_MAXTYPES; dev++)
{
devptr = ExtCurStyle->exts_device[dev];
if ((devptr != NULL) && ((dev_name = devptr->exts_deviceName) != NULL)
&& (strcmp(dev_name, "None")))
{
TTMaskSetMask(&DiffTypeBitMask,
&(devptr->exts_deviceSDTypes[0]));
TTMaskSetMask(&ResSubsTypeBitMask,
&(devptr->exts_deviceSubstrateTypes));
}
}
first = 0;
}
DevList = NULL;
DBTreeSrTiles(scx, mask, xMask, dbcConnectFuncDCS, (ClientData) &csa2);
while (csa2.csa2_top >= 0)
{
newmask = csa2.csa2_list[csa2.csa2_top].connectMask;
scx->scx_area = csa2.csa2_list[csa2.csa2_top].area;
newtype = csa2.csa2_list[csa2.csa2_top].dinfo;
if (csa2.csa2_top == 0)
{
if (StackLook(csa2.csa2_stack) != (ClientData)NULL)
{
freeMagic(csa2.csa2_list);
csa2.csa2_list = (conSrArea *)StackPop(csa2.csa2_stack);
csa2.csa2_top = CSA2_LIST_SIZE - 1;
}
else
csa2.csa2_top--;
}
else
csa2.csa2_top--;
csa2.csa2_lasttop = csa2.csa2_top;
if (newtype & TT_DIAGONAL)
DBTreeSrNMTiles(scx, newtype, newmask, xMask, dbcConnectFuncDCS,
(ClientData) &csa2);
else
DBTreeSrTiles(scx, newmask, xMask, dbcConnectFuncDCS, (ClientData) &csa2);
}
freeMagic((char *)csa2.csa2_list);
StackFree(csa2.csa2_stack);
for (CurrentT = DevList; CurrentT != NULL; CurrentT=CurrentT->nextDev)
{
TileType t = CurrentT->type;
TileType nt;
TileTypeBitMask *residues = DBResidueMask(t);
for (nt = TT_TECHDEPBASE; nt < DBNumTypes; nt++)
{
if (TTMaskHasType(residues, nt))
{
pNum = DBPlane(nt);
DBPaintPlane(def->cd_planes[pNum], &CurrentT->area,
DBStdPaintTbl(nt, pNum), (PaintUndoInfo *) NULL);
}
}
}
DBReComputeBbox(def);
return(DevList);
}
#ifdef ARIEL
/*
*-------------------------------------------------------------------------
*
* resSubSearchFunc --
*
* called when DBSrPaintArea finds a device within
* a substrate area.
*
* Results:
* Always return 0 to keep the search alive.
*
* Side Effects:
*
*-------------------------------------------------------------------------
*/
int
resSubSearchFunc(tile,cx)
Tile *tile;
TreeContext *cx;
{
ResDevTile *thisDev;
Rect devArea;
TileType t = TiGetType(tile);
ExtDevice *devptr;
/* Right now, we're only going to extract substrate terminals for
devices with only one diffusion terminal, principally bipolar
devices.
*/
devptr = ExtCurStyle->exts_device[t]
if (devptr->exts_deviceSDCount >1) return 0;
TiToRect(tile, &devArea);
thisDev = (ResDevTile *) mallocMagic((unsigned)(sizeof(ResDevTile)));
GeoTransRect(&cx->tc_scx->scx_trans, &devArea, &thisDev->area);
thisDev->type = t;
thisDev->nextDev = DevList;
DevList = thisDev;
ResCalcPerimOverlap(thisDev,tile);
return 0;
}
#endif /* ARIEL */

View File

@ -46,17 +46,16 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
*/ */
void void
ResPrintNodeList(fp,list) ResPrintNodeList(fp, list)
FILE *fp; FILE *fp;
resNode *list; resNode *list;
{ {
for (; list != NULL; list = list->rn_more) for (; list != NULL; list = list->rn_more)
{ {
fprintf(fp, "node %p: (%d %d) r= %d\n", fprintf(fp, "node %p: (%d %d) r= %d\n",
list,list->rn_loc.p_x,list->rn_loc.p_y,list->rn_noderes); list, list->rn_loc.p_x, list->rn_loc.p_y, list->rn_noderes);
} }
} }
/* /*
@ -73,7 +72,7 @@ ResPrintNodeList(fp,list)
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
void void
ResPrintResistorList(fp,list) ResPrintResistorList(fp, list)
FILE *fp; FILE *fp;
resResistor *list; resResistor *list;
@ -112,9 +111,9 @@ ResPrintResistorList(fp,list)
*/ */
void void
ResPrintDeviceList(fp,list) ResPrintDeviceList(fp, list)
FILE *fp; FILE *fp;
resDevice *list; resDevice *list;
{ {
static char termtype[] = {'g','s','d','c'}; static char termtype[] = {'g','s','d','c'};

View File

@ -81,31 +81,30 @@ enumerate:
if (SigInterruptPending) if (SigInterruptPending)
return (1); return (1);
if ((tt=TiGetType(resSrTile)) != TT_SPACE) if ((tt = TiGetType(resSrTile)) != TT_SPACE)
{ {
resTopTile = RT(resSrTile); resTopTile = RT(resSrTile);
while (RIGHT(resTopTile) > LEFT(resSrTile)) while (RIGHT(resTopTile) > LEFT(resSrTile))
{ {
TileType ntt = TiGetType(resTopTile); TileType ntt = TiGetType(resTopTile);
if (ntt != tt)
{
resTopTile=BL(resTopTile);
continue;
}
/* ok, we may have found a concave corner */
ResCheckConcavity(resSrTile,resTopTile,tt);
if (resTopTile == NULL) break;
if (BOTTOM(resTopTile) != TOP(resSrTile))
{
resTopTile = RT(resSrTile);
}
else
{
resTopTile=BL(resTopTile);
}
}
if (ntt != tt)
{
resTopTile = BL(resTopTile);
continue;
}
/* ok, we may have found a concave corner */
ResCheckConcavity(resSrTile, resTopTile, tt);
if (resTopTile == NULL) break;
if (BOTTOM(resTopTile) != TOP(resSrTile))
{
resTopTile = RT(resSrTile);
}
else
{
resTopTile=BL(resTopTile);
}
}
} }
tpnew = TR(resSrTile); tpnew = TR(resSrTile);
@ -134,7 +133,8 @@ enumerate:
} }
/* At left edge -- walk down to next tile along the left edge */ /* At left edge -- walk down to next tile along the left edge */
for (resSrTile = LB(resSrTile); RIGHT(resSrTile) <= rect->r_xbot; resSrTile = TR(resSrTile)) for (resSrTile = LB(resSrTile); RIGHT(resSrTile) <= rect->r_xbot;
resSrTile = TR(resSrTile))
/* Nothing */; /* Nothing */;
} }
return (0); return (0);
@ -157,88 +157,96 @@ enumerate:
*/ */
void void
ResCheckConcavity(bot,top,tt) ResCheckConcavity(bot, top, tt)
Tile *bot,*top; Tile *bot, *top;
TileType tt; TileType tt;
{ {
Tile *tp; Tile *tp;
int xlen,ylen; int xlen, ylen;
/* corner #1:
XXXXXXX /* corner #1:
YYYYYYY * XXXXXXX
^--here * YYYYYYY
*/ * ^--here
if (RIGHT(top) > RIGHT(bot) && TiGetType(TR(bot)) != tt)
{
int xpos = RIGHT(bot);
int ypos = BOTTOM(top);
xlen = xpos - resWalkleft(top,tt,xpos,ypos,NULL);
ylen = resWalkup(top,tt,xpos,ypos,NULL) - ypos;
if (xlen > ylen)
{
(void) resWalkup(top,tt,xpos,ypos,ResSplitX);
}
}
if (resTopTile == NULL) return;
/* corner #2:
v--here
XXXXXXX
YYYYYYY
*/
if (RIGHT(top) < RIGHT(bot))
{
for (tp = TR(top);BOTTOM(tp) > BOTTOM(top);tp=LB(tp));
if (TiGetType(tp) != tt)
{
int xpos = RIGHT(top);
int ypos = BOTTOM(top);
xlen = xpos-resWalkleft(top,tt,xpos,ypos,NULL);
ylen = ypos-resWalkdown(bot,tt,xpos,ypos,NULL);
if (xlen > ylen)
{
(void) resWalkdown(bot,tt,xpos,ypos,ResSplitX);
}
}
}
if (resTopTile == NULL) return;
/* corner #3:
XXXXXXX
YYYYYYY
^--here
*/
if (LEFT(top) < LEFT(bot))
{
for (tp = BL(bot);TOP(tp) < TOP(bot);tp=RT(tp));
if (TiGetType(tp) != tt)
{
int xpos = LEFT(bot);
int ypos = BOTTOM(top);
xlen = resWalkright(top,tt,xpos,ypos,NULL)- xpos;
ylen = resWalkup(top,tt,xpos,ypos,NULL) - ypos;
if (xlen > ylen)
{
(void) resWalkup(top,tt,xpos,ypos,ResSplitX);
}
}
}
if (resTopTile == NULL) return;
/* corner #4:
v--here
XXXXXXX
YYYYYYY
*/ */
if (LEFT(top) > LEFT(bot) && TiGetType(BL(top)) != tt)
{ if (RIGHT(top) > RIGHT(bot) && TiGetType(TR(bot)) != tt)
int xpos = LEFT(top); {
int ypos = BOTTOM(top); int xpos = RIGHT(bot);
xlen = resWalkright(top,tt,xpos,ypos,NULL)- xpos; int ypos = BOTTOM(top);
ylen = ypos-resWalkdown(bot,tt,xpos,ypos,NULL); xlen = xpos - resWalkleft(top, tt, xpos, ypos, NULL);
if (xlen > ylen) ylen = resWalkup(top, tt, xpos, ypos, NULL) - ypos;
{ if (xlen > ylen)
(void) resWalkdown(bot,tt,xpos,ypos,ResSplitX); {
} (void) resWalkup(top, tt, xpos, ypos, ResSplitX);
} }
}
if (resTopTile == NULL) return;
/* corner #2:
* v--here
* XXXXXXX
* YYYYYYY
*/
if (RIGHT(top) < RIGHT(bot))
{
for (tp = TR(top); BOTTOM(tp) > BOTTOM(top); tp = LB(tp));
if (TiGetType(tp) != tt)
{
int xpos = RIGHT(top);
int ypos = BOTTOM(top);
xlen = xpos - resWalkleft(top, tt, xpos, ypos, NULL);
ylen = ypos - resWalkdown(bot, tt, xpos, ypos, NULL);
if (xlen > ylen)
{
(void) resWalkdown(bot,tt,xpos,ypos,ResSplitX);
}
}
}
if (resTopTile == NULL) return;
/* corner #3:
* XXXXXXX
* YYYYYYY
* ^--here
*/
if (LEFT(top) < LEFT(bot))
{
for (tp = BL(bot); TOP(tp) < TOP(bot); tp = RT(tp));
if (TiGetType(tp) != tt)
{
int xpos = LEFT(bot);
int ypos = BOTTOM(top);
xlen = resWalkright(top, tt, xpos, ypos, NULL) - xpos;
ylen = resWalkup(top, tt, xpos, ypos, NULL) - ypos;
if (xlen > ylen)
{
(void) resWalkup(top, tt, xpos, ypos, ResSplitX);
}
}
}
if (resTopTile == NULL) return;
/* corner #4:
* v--here
* XXXXXXX
* YYYYYYY
*/
if (LEFT(top) > LEFT(bot) && TiGetType(BL(top)) != tt)
{
int xpos = LEFT(top);
int ypos = BOTTOM(top);
xlen = resWalkright(top, tt, xpos, ypos, NULL) - xpos;
ylen = ypos - resWalkdown(bot, tt, xpos, ypos, NULL);
if (xlen > ylen)
{
(void) resWalkdown(bot, tt, xpos, ypos, ResSplitX);
}
}
} }
/* /*
@ -259,151 +267,151 @@ ResCheckConcavity(bot,top,tt)
*/ */
int int
resWalkup(tile,tt,xpos,ypos,func) resWalkup(tile, tt, xpos, ypos, func)
Tile *tile; Tile *tile;
TileType tt; TileType tt;
int xpos,ypos; int xpos,ypos;
Tile * (*func)(); Tile * (*func)();
{ {
Point pt; Point pt;
Tile *tp; Tile *tp;
pt.p_x = xpos; pt.p_x = xpos;
while (TiGetType(tile) == tt) while (TiGetType(tile) == tt)
{ {
if (xpos == LEFT(tile)) if (xpos == LEFT(tile))
{ {
/* walk up left edge */ /* walk up left edge */
for (tp = BL(tile);TOP(tp) <= ypos;tp=RT(tp)); for (tp = BL(tile); TOP(tp) <= ypos; tp = RT(tp));
for (;BOTTOM(tp) < TOP(tile);tp=RT(tp)) for (; BOTTOM(tp) < TOP(tile); tp = RT(tp))
{ {
if (TiGetType(tp) != tt) return(BOTTOM(tp)); if (TiGetType(tp) != tt) return(BOTTOM(tp));
} }
} }
else else
{ {
if (func) tile = (*func)(tile,xpos); if (func) tile = (*func)(tile,xpos);
} }
pt.p_y = TOP(tile); pt.p_y = TOP(tile);
GOTOPOINT(tile,&pt); GOTOPOINT(tile, &pt);
} }
return(BOTTOM(tile)); return(BOTTOM(tile));
} }
int int
resWalkdown(tile,tt,xpos,ypos,func) resWalkdown(tile, tt, xpos, ypos, func)
Tile *tile; Tile *tile;
TileType tt; TileType tt;
int xpos,ypos; int xpos, ypos;
Tile * (*func)(); Tile * (*func)();
{ {
Point pt; Point pt;
Tile *tp; Tile *tp;
Tile *endt; Tile *endt;
pt.p_x = xpos; pt.p_x = xpos;
while (TiGetType(tile) == tt) while (TiGetType(tile) == tt)
{ {
if (xpos == LEFT(tile)) if (xpos == LEFT(tile))
{ {
/* walk up left edge */ /* walk up left edge */
endt = NULL; endt = NULL;
for (tp = BL(tile);BOTTOM(tp) < TOP(tile);tp=RT(tp)) for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp))
{ {
if (TiGetType(tp) != tt) if (TiGetType(tp) != tt)
{ {
if (BOTTOM(tp) < ypos) endt = tp; if (BOTTOM(tp) < ypos) endt = tp;
} }
} }
if (endt) if (endt)
{ {
return TOP(endt); return TOP(endt);
} }
} }
else else
{ {
if (func) tile = (*func)(tile,xpos); if (func) tile = (*func)(tile, xpos);
} }
pt.p_y = BOTTOM(tile)-1; pt.p_y = BOTTOM(tile) - 1;
GOTOPOINT(tile,&pt); GOTOPOINT(tile, &pt);
} }
return(TOP(tile)); return(TOP(tile));
} }
int int
resWalkright(tile,tt,xpos,ypos,func) resWalkright(tile, tt, xpos, ypos, func)
Tile *tile; Tile *tile;
TileType tt; TileType tt;
int xpos,ypos; int xpos, ypos;
Tile * (*func)(); Tile * (*func)();
{ {
Point pt; Point pt;
Tile *tp; Tile *tp;
pt.p_y = ypos; pt.p_y = ypos;
while (TiGetType(tile) == tt) while (TiGetType(tile) == tt)
{ {
if (ypos == BOTTOM(tile)) if (ypos == BOTTOM(tile))
{ {
/* walk along bottom edge */ /* walk along bottom edge */
for (tp = LB(tile);LEFT(tp) < xpos;tp=TR(tp)); for (tp = LB(tile); LEFT(tp) < xpos; tp = TR(tp));
for (;LEFT(tp) < RIGHT(tile);tp=TR(tp)) for (; LEFT(tp) < RIGHT(tile); tp = TR(tp))
{ {
if (TiGetType(tp) != tt) return(LEFT(tp)); if (TiGetType(tp) != tt) return(LEFT(tp));
} }
} }
else else
{ {
if (func) tile = (*func)(tile,ypos); if (func) tile = (*func)(tile, ypos);
} }
pt.p_x = RIGHT(tile); pt.p_x = RIGHT(tile);
GOTOPOINT(tile,&pt); GOTOPOINT(tile, &pt);
} }
return(LEFT(tile)); return(LEFT(tile));
} }
int int
resWalkleft(tile,tt,xpos,ypos,func) resWalkleft(tile, tt, xpos, ypos, func)
Tile *tile; Tile *tile;
TileType tt; TileType tt;
int xpos,ypos; int xpos, ypos;
Tile * (*func)(); Tile * (*func)();
{ {
Point pt; Point pt;
Tile *tp; Tile *tp;
Tile *endt; Tile *endt;
pt.p_y = ypos; pt.p_y = ypos;
while (TiGetType(tile) == tt) while (TiGetType(tile) == tt)
{ {
if (ypos == BOTTOM(tile)) if (ypos == BOTTOM(tile))
{ {
/* walk along bottom edge */ /* walk along bottom edge */
endt = NULL; endt = NULL;
for (tp = LB(tile);LEFT(tp) < RIGHT(tile);tp=TR(tp)) for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp))
{ {
if (TiGetType(tp) != tt) if (TiGetType(tp) != tt)
{ {
if (LEFT(tp) < xpos) endt = tp; if (LEFT(tp) < xpos) endt = tp;
} }
} }
if (endt) if (endt)
{ {
return RIGHT(endt); return RIGHT(endt);
} }
} }
else else
{ {
if (func) tile = (*func)(tile,ypos); if (func) tile = (*func)(tile, ypos);
} }
pt.p_x = LEFT(tile)-1; pt.p_x = LEFT(tile) - 1;
GOTOPOINT(tile,&pt); GOTOPOINT(tile, &pt);
} }
return(RIGHT(tile)); return(RIGHT(tile));
} }
/* /*
@ -419,59 +427,60 @@ resWalkleft(tile,tt,xpos,ypos,func)
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
Tile * Tile *
ResSplitX(tile,x) ResSplitX(tile, x)
Tile *tile; Tile *tile;
int x; int x;
{ {
TileType tt = TiGetType(tile); TileType tt = TiGetType(tile);
Tile *tp = TiSplitX(tile,x); Tile *tp = TiSplitX(tile, x);
Tile *tp2; Tile *tp2;
TiSetBody(tp,tt); TiSetBody(tp,tt);
/* check to see if we can combine with the tiles above or below us */ /* check to see if we can combine with the tiles above or below us */
tp2 = RT(tile); tp2 = RT(tile);
if (TiGetType(tp2) == tt && LEFT(tp2) == LEFT(tile) && RIGHT(tp2) == RIGHT(tile)) if (TiGetType(tp2) == tt && LEFT(tp2) == LEFT(tile) && RIGHT(tp2) == RIGHT(tile))
{ {
if (tp2 == resSrTile) if (tp2 == resSrTile)
{ {
if (resTopTile == tile) resTopTile = NULL; if (resTopTile == tile) resTopTile = NULL;
TiJoinY(tp2,tile,resFracPlane); TiJoinY(tp2, tile, resFracPlane);
tile = tp2; tile = tp2;
} }
else else
{ {
if (resTopTile == tp2) resTopTile = NULL; if (resTopTile == tp2) resTopTile = NULL;
TiJoinY(tile,tp2,resFracPlane); TiJoinY(tile, tp2, resFracPlane);
} }
} }
tp2 = LB(tile); tp2 = LB(tile);
if (TiGetType(tp2) == tt && LEFT(tp2) == LEFT(tile) && RIGHT(tp2) == RIGHT(tile)) if (TiGetType(tp2) == tt && LEFT(tp2) == LEFT(tile) && RIGHT(tp2) == RIGHT(tile))
{ {
if (tp2 == resSrTile) if (tp2 == resSrTile)
{ {
if (resTopTile == tile) resTopTile = NULL; if (resTopTile == tile) resTopTile = NULL;
TiJoinY(tp2,tile,resFracPlane); TiJoinY(tp2, tile, resFracPlane);
tile = tp2; tile = tp2;
} }
else else
{ {
if (resTopTile == tp2) resTopTile = NULL; if (resTopTile == tp2) resTopTile = NULL;
TiJoinY(tile,tp2,resFracPlane); TiJoinY(tile, tp2, resFracPlane);
} }
} }
/* do the same checks with the newly created tile */ /* do the same checks with the newly created tile */
tp2 = RT(tp); tp2 = RT(tp);
if (TiGetType(tp2) == tt && LEFT(tp2) == LEFT(tp) && RIGHT(tp2) == RIGHT(tp)) if (TiGetType(tp2) == tt && LEFT(tp2) == LEFT(tp) && RIGHT(tp2) == RIGHT(tp))
{ {
TiJoinY(tp2,tp,resFracPlane); TiJoinY(tp2, tp, resFracPlane);
tp = tp2; tp = tp2;
} }
tp2 = LB(tp); tp2 = LB(tp);
if (TiGetType(tp2) == tt && LEFT(tp2) == LEFT(tp) && RIGHT(tp2) == RIGHT(tp)) if (TiGetType(tp2) == tt && LEFT(tp2) == LEFT(tp) && RIGHT(tp2) == RIGHT(tp))
{ {
TiJoinY(tp2,tp,resFracPlane); TiJoinY(tp2, tp, resFracPlane);
} }
return tile; return tile;
} }

View File

@ -26,8 +26,6 @@ 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"
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
@ -45,56 +43,56 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
*/ */
void void
ResNewSDDevice(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;
resDevice *resDev; 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;
resDev = j->deviceList; resDev = j->deviceList;
if ((j->sourceEdge & direction) != 0) if ((j->sourceEdge & direction) != 0)
{
if (resDev->rd_fet_source == (resNode *) NULL)
{ {
if (resDev->rd_fet_source == (resNode *) NULL) resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
{ newnode = TRUE;
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); resDev->rd_fet_source = resptr;
newnode = TRUE;
resDev->rd_fet_source = resptr;
}
else
{
resptr = resDev->rd_fet_source;
}
} }
else else
{ {
if (resDev->rd_fet_drain == (resNode *) NULL) resptr = resDev->rd_fet_source;
{
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
newnode = TRUE;
resDev->rd_fet_drain = resptr;
}
else
{
resptr = resDev->rd_fet_drain;
}
} }
if (newnode) }
else
{
if (resDev->rd_fet_drain == (resNode *) NULL)
{ {
tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement))); resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
tcell->te_nextt = NULL; newnode = TRUE;
tcell->te_thist = j->deviceList; resDev->rd_fet_drain = resptr;
InitializeNode(resptr,xj,yj,RES_NODE_DEVICE);
resptr->rn_te = tcell;
ResAddToQueue(resptr,PendingList);
} }
NEWBREAK(resptr,tile,xj,yj,NULL); else
{
resptr = resDev->rd_fet_drain;
}
}
if (newnode)
{
tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement)));
tcell->te_nextt = NULL;
tcell->te_thist = j->deviceList;
InitializeNode(resptr, xj, yj, RES_NODE_DEVICE);
resptr->rn_te = tcell;
ResAddToQueue(resptr, PendingList);
}
NEWBREAK(resptr, tile, xj, yj, NULL);
} }
/* /*
@ -113,49 +111,49 @@ ResNewSDDevice(tile,tp,xj,yj,direction,PendingList)
void void
ResProcessJunction(tile, tp, xj, yj, NodeList) ResProcessJunction(tile, tp, xj, yj, NodeList)
Tile *tile, *tp; Tile *tile, *tp;
int xj,yj; int xj, yj;
resNode **NodeList; resNode **NodeList;
{ {
ResJunction *junction; ResJunction *junction;
resNode *resptr; resNode *resptr;
jElement *jcell; jElement *jcell;
tileJunk *j0 = (tileJunk *)tile->ti_client; tileJunk *j0 = (tileJunk *)tile->ti_client;
tileJunk *j2 = (tileJunk *)tp->ti_client; tileJunk *j2 = (tileJunk *)tp->ti_client;
#ifdef PARANOID #ifdef PARANOID
if (tile == tp) if (tile == tp)
{ {
TxError("Junction being made between tile and itself \n"); TxError("Junction being made between tile and itself \n");
return; return;
} }
#endif #endif
if (j2->tj_status & RES_TILE_DONE) return; if (j2->tj_status & RES_TILE_DONE) return;
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode))); resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
resptr->rn_te = (tElement *) NULL; resptr->rn_te = (tElement *) NULL;
junction = (ResJunction *) mallocMagic((unsigned)(sizeof(ResJunction))); junction = (ResJunction *) mallocMagic((unsigned)(sizeof(ResJunction)));
jcell = (jElement *) mallocMagic((unsigned)(sizeof(jElement))); jcell = (jElement *) mallocMagic((unsigned)(sizeof(jElement)));
InitializeNode(resptr,xj,yj,RES_NODE_JUNCTION); InitializeNode(resptr, xj, yj, RES_NODE_JUNCTION);
resptr->rn_je = jcell; resptr->rn_je = jcell;
ResAddToQueue(resptr,NodeList); ResAddToQueue(resptr, NodeList);
jcell->je_thisj = junction; jcell->je_thisj = junction;
jcell->je_nextj = NULL; jcell->je_nextj = NULL;
junction->rj_status = FALSE; junction->rj_status = FALSE;
junction->rj_jnode = resptr; junction->rj_jnode = resptr;
junction->rj_Tile[0] = tile; junction->rj_Tile[0] = tile;
junction->rj_Tile[1] = tp; junction->rj_Tile[1] = tp;
junction->rj_loc.p_x =xj; junction->rj_loc.p_x =xj;
junction->rj_loc.p_y =yj; junction->rj_loc.p_y =yj;
junction->rj_nextjunction[0] = j0->junctionList; junction->rj_nextjunction[0] = j0->junctionList;
j0->junctionList = junction; j0->junctionList = junction;
junction->rj_nextjunction[1] = j2->junctionList; junction->rj_nextjunction[1] = j2->junctionList;
j2->junctionList = junction; j2->junctionList = junction;
NEWBREAK(junction->rj_jnode,tile, NEWBREAK(junction->rj_jnode,tile, junction->rj_loc.p_x,
junction->rj_loc.p_x,junction->rj_loc.p_y,NULL); junction->rj_loc.p_y, NULL);
NEWBREAK(junction->rj_jnode,tp, NEWBREAK(junction->rj_jnode,tp, junction->rj_loc.p_x,
junction->rj_loc.p_x,junction->rj_loc.p_y,NULL); junction->rj_loc.p_y, NULL);
} }

View File

@ -20,23 +20,24 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "windows/windows.h" #include "windows/windows.h"
#include "dbwind/dbwind.h" #include "dbwind/dbwind.h"
#include "utils/tech.h" #include "utils/tech.h"
#include "select/select.h"
#include "textio/txcommands.h" #include "textio/txcommands.h"
#include "resis/resis.h" #include "resis/resis.h"
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 devices. */ /* 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 */
resDevice *ResDevList=NULL; /* Devices */ 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 */
resNode *resCurrentNode; resNode *resCurrentNode;
int ResTileCount=0; /* Number of tiles rn_status */ int ResTileCount = 0; /* Number of tiles rn_status */
extern Region *ResFirst(); extern Region *ResFirst();
extern Tile *FindStartTile(); extern Tile *FindStartTile();
extern int ResEachTile(); extern int ResEachTile();
@ -45,8 +46,6 @@ extern ResSimNode *ResInitializeNode();
extern HashTable ResNodeTable; extern HashTable ResNodeTable;
/* /*
*-------------------------------------------------------------------------- *--------------------------------------------------------------------------
* *
@ -78,13 +77,13 @@ ResInitializeConn()
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],dev); TTMaskSetType(&ResConnectWithSD[diff], dev);
if TTMaskHasType(&(devptr->exts_deviceSubstrateTypes),diff) if TTMaskHasType(&(devptr->exts_deviceSubstrateTypes), diff)
TTMaskSetType(&ResConnectWithSD[diff],dev); TTMaskSetType(&ResConnectWithSD[diff], dev);
} }
} }
TTMaskSetMask(&ResConnectWithSD[dev],&DBConnectTbl[dev]); TTMaskSetMask(&ResConnectWithSD[dev], &DBConnectTbl[dev]);
} }
} }
@ -121,7 +120,6 @@ ResGetReCell()
ResUse = DBCellNewUse(ResDef, (char *) NULL); ResUse = DBCellNewUse(ResDef, (char *) NULL);
DBSetTrans(ResUse, &GeoIdentityTransform); DBSetTrans(ResUse, &GeoIdentityTransform);
ResUse->cu_expandMask = CU_DESCEND_SPECIAL; ResUse->cu_expandMask = CU_DESCEND_SPECIAL;
} }
/* /*
@ -172,7 +170,7 @@ ResDissolveContacts(contacts)
} }
tp = ResDef->cd_planes[DBPlane(contacts->cp_type)]->pl_hint; tp = ResDef->cd_planes[DBPlane(contacts->cp_type)]->pl_hint;
GOTOPOINT(tp,&(contacts->cp_rect.r_ll)); GOTOPOINT(tp, &(contacts->cp_rect.r_ll));
#ifdef PARANOID #ifdef PARANOID
if (TiGetTypeExact(tp) == contacts->cp_type) if (TiGetTypeExact(tp) == contacts->cp_type)
{ {
@ -325,46 +323,46 @@ ResAddBreakpointFunc(tile, node)
void void
ResFindNewContactTiles(contacts) ResFindNewContactTiles(contacts)
ResContactPoint *contacts; ResContactPoint *contacts;
{ {
int pNum; int pNum;
Tile *tile; Tile *tile;
TileTypeBitMask mask; TileTypeBitMask mask;
for (; contacts != (ResContactPoint *) NULL; contacts = contacts->cp_nextcontact) for (; contacts != (ResContactPoint *) NULL; contacts = contacts->cp_nextcontact)
{ {
DBFullResidueMask(contacts->cp_type, &mask); DBFullResidueMask(contacts->cp_type, &mask);
for (pNum=PL_TECHDEPBASE; pNum<DBNumPlanes; pNum++) for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
{ {
tile = ResDef->cd_planes[pNum]->pl_hint; tile = ResDef->cd_planes[pNum]->pl_hint;
GOTOPOINT(tile, &(contacts->cp_center)); GOTOPOINT(tile, &(contacts->cp_center));
#ifdef PARANOID #ifdef PARANOID
if (tile == (Tile *) NULL) if (tile == (Tile *) NULL)
{ {
TxError("Error: setting contact tile to null\n"); TxError("Error: setting contact tile to null\n");
} }
#endif #endif
if ((IsSplit(tile) && TTMaskHasType(&mask, TiGetRightType(tile))) if ((IsSplit(tile) && TTMaskHasType(&mask, TiGetRightType(tile)))
|| TTMaskHasType(&mask, TiGetType(tile))) || TTMaskHasType(&mask, TiGetType(tile)))
{ {
tileJunk *j = (tileJunk *)tile->ti_client; tileJunk *j = (tileJunk *)tile->ti_client;
cElement *ce; cElement *ce;
ce = (cElement *) mallocMagic((unsigned) (sizeof(cElement))); ce = (cElement *) mallocMagic((unsigned) (sizeof(cElement)));
contacts->cp_tile[contacts->cp_currentcontact] = tile; contacts->cp_tile[contacts->cp_currentcontact] = tile;
ce->ce_thisc = contacts; ce->ce_thisc = contacts;
ce->ce_nextc = j->contactList; ce->ce_nextc = j->contactList;
(contacts->cp_currentcontact) += 1; (contacts->cp_currentcontact) += 1;
j->contactList = ce; j->contactList = ce;
} }
} }
#ifdef PARANOID #ifdef PARANOID
if (contacts->cp_currentcontact > LAYERS_PER_CONTACT) if (contacts->cp_currentcontact > LAYERS_PER_CONTACT)
{ {
TxError("Error: Not enough space allocated for contact nodes\n"); TxError("Error: Not enough space allocated for contact nodes\n");
} }
#endif #endif
} }
} }
/* /*
@ -388,78 +386,77 @@ ResProcessTiles(goodies, origin)
ResGlobalParams *goodies; ResGlobalParams *goodies;
{ {
Tile *startTile; Tile *startTile;
int tilenum,merged; int tilenum, merged;
resNode *resptr2; resNode *resptr2;
jElement *workingj; jElement *workingj;
cElement *workingc; cElement *workingc;
ResFixPoint *fix; ResFixPoint *fix;
resNode *resptr; resNode *resptr;
int (*tilefunc)(); int (*tilefunc)();
#ifdef LAPLACE #ifdef LAPLACE
tilefunc = (ResOptionsFlags & ResOpt_DoLaplace)?ResLaplaceTile:ResEachTile; tilefunc = (ResOptionsFlags & ResOpt_DoLaplace) ? ResLaplaceTile : ResEachTile;
#else #else
tilefunc = ResEachTile; tilefunc = ResEachTile;
#endif #endif
if (ResOptionsFlags & ResOpt_Signal) if (ResOptionsFlags & ResOpt_Signal)
{ {
startTile = FindStartTile(goodies, origin); startTile = FindStartTile(goodies, origin);
if (startTile == NULL) return(1); if (startTile == NULL) return(1);
resCurrentNode = NULL; resCurrentNode = NULL;
(void) (*tilefunc)(startTile, origin); (void) (*tilefunc)(startTile, origin);
} }
#ifdef ARIEL #ifdef ARIEL
else if (ResOptionsFlags & ResOpt_Power) else if (ResOptionsFlags & ResOpt_Power)
{ {
for (fix = ResFixList; fix != NULL;fix=fix->fp_next) for (fix = ResFixList; fix != NULL; fix = fix->fp_next)
{ {
Tile *tile = fix->fp_tile; Tile *tile = fix->fp_tile;
if (tile == NULL) if (tile == NULL)
{ {
tile = ResDef->cd_planes[DBPlane(fix->fp_ttype)]->pl_hint;
GOTOPOINT(tile, &(fix->fp_loc));
if (TiGetTypeExact(tile) != TT_SPACE)
{
fix->fp_tile = tile;
}
else
{
tile = NULL;
}
}
if (tile != NULL)
{
int x = fix->fp_loc.p_x;
int y = fix->fp_loc.p_y;
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
InitializeNode(resptr, x, y, RES_NODE_ORIGIN);
resptr->rn_status = TRUE;
resptr->rn_noderes = 0;
ResAddToQueue(resptr, &ResNodeQueue);
fix->fp_node = resptr;
NEWBREAK(resptr, tile, x, y, NULL);
}
}
for (fix = ResFixList; fix != NULL; fix = fix->fp_next)
{
Tile *tile = fix->fp_tile;
tile = ResDef->cd_planes[DBPlane(fix->fp_ttype)]->pl_hint; if (tile != NULL && (((tileJunk *)tile->ti_client)->tj_status &
GOTOPOINT(tile, &(fix->fp_loc));
if (TiGetTypeExact(tile) != TT_SPACE)
{
fix->fp_tile = tile;
}
else
{
tile = NULL;
}
}
if (tile != NULL)
{
int x = fix->fp_loc.p_x;
int y = fix->fp_loc.p_y;
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
InitializeNode(resptr, x, y, RES_NODE_ORIGIN);
resptr->rn_status = TRUE;
resptr->rn_noderes = 0;
ResAddToQueue(resptr, &ResNodeQueue);
fix->fp_node = resptr;
NEWBREAK(resptr, tile, x, y, NULL);
}
}
for (fix = ResFixList; fix != NULL; fix = fix->fp_next)
{
Tile *tile = fix->fp_tile;
if (tile != NULL && (((tileJunk *)tile->ti_client)->tj_status &
RES_TILE_DONE) == 0) RES_TILE_DONE) == 0)
{ {
resCurrentNode = fix->fp_node; resCurrentNode = fix->fp_node;
(void) (*tilefunc)(tile, (Point *)NULL); (void) (*tilefunc)(tile, (Point *)NULL);
} }
} }
} }
#endif #endif
#ifdef PARANOID #ifdef PARANOID
else else
{ {
TxError("Unknown analysis type in ResProcessTiles\n"); TxError("Unknown analysis type in ResProcessTiles\n");
} }
#endif #endif
@ -467,103 +464,199 @@ ResProcessTiles(goodies, origin)
while (ResNodeQueue != NULL) while (ResNodeQueue != NULL)
{ {
/* /*
* merged keeps track of whether another node gets merged into * merged keeps track of whether another node gets merged into
* the current one. If it does, then the node must be processed * the current one. If it does, then the node must be processed
* because additional junctions or contacts were added * because additional junctions or contacts were added
*/ */
resptr2 = ResNodeQueue; resptr2 = ResNodeQueue;
merged = FALSE; merged = FALSE;
/* Process all junctions associated with node */ /* Process all junctions associated with node */
for (workingj = resptr2->rn_je; workingj != NULL; workingj = workingj->je_nextj) for (workingj = resptr2->rn_je; workingj != NULL; workingj = workingj->je_nextj)
{ {
ResJunction *rj = workingj->je_thisj; ResJunction *rj = workingj->je_thisj;
if (rj->rj_status == FALSE) if (rj->rj_status == FALSE)
{ {
for (tilenum = 0; tilenum < TILES_PER_JUNCTION; tilenum++) for (tilenum = 0; tilenum < TILES_PER_JUNCTION; tilenum++)
{ {
Tile *tile = rj->rj_Tile[tilenum]; Tile *tile = rj->rj_Tile[tilenum];
tileJunk *j = (tileJunk *) tile->ti_client; tileJunk *j = (tileJunk *)tile->ti_client;
if ((j->tj_status & RES_TILE_DONE) == 0) if ((j->tj_status & RES_TILE_DONE) == 0)
{
resCurrentNode = resptr2;
merged |= (*tilefunc)(tile,(Point *)NULL);
}
if (merged & ORIGIN) break;
}
if (merged & ORIGIN) break;
rj->rj_status = TRUE;
}
}
/* Next, Process all contacts. */
for (workingc = resptr2->rn_ce;workingc != NULL;workingc = workingc->ce_nextc)
{
ResContactPoint *cp = workingc->ce_thisc;
if (merged & ORIGIN) break;
if (cp->cp_status == FALSE)
{
int newstatus = TRUE;
for (tilenum = 0; tilenum < cp->cp_currentcontact; tilenum++)
{
Tile *tile = cp->cp_tile[tilenum];
tileJunk *j = (tileJunk *) tile->ti_client;
if ((j->tj_status & RES_TILE_DONE) == 0)
{
if (cp->cp_cnode[tilenum] == resptr2)
{ {
resCurrentNode = resptr2; resCurrentNode = resptr2;
merged |= (*tilefunc)(tile,(Point *)NULL); merged |= (*tilefunc)(tile,(Point *)NULL);
} }
if (merged & ORIGIN) break; else
}
if (merged & ORIGIN) break;
rj->rj_status = TRUE;
}
}
/* Next, Process all contacts. */
for (workingc = resptr2->rn_ce;workingc != NULL;workingc = workingc->ce_nextc)
{
ResContactPoint *cp = workingc->ce_thisc;
if (merged & ORIGIN) break;
if (cp->cp_status == FALSE)
{
int newstatus = TRUE;
for (tilenum = 0; tilenum < cp->cp_currentcontact; tilenum++)
{
Tile *tile = cp->cp_tile[tilenum];
tileJunk *j = (tileJunk *) tile->ti_client;
if ((j->tj_status & RES_TILE_DONE) == 0)
{ {
if (cp->cp_cnode[tilenum] == resptr2) newstatus = FALSE;
{
resCurrentNode = resptr2;
merged |= (*tilefunc)(tile,(Point *)NULL);
}
else
{
newstatus = FALSE;
}
} }
if (merged & ORIGIN) break; }
} if (merged & ORIGIN) break;
if (merged & ORIGIN) break; }
cp->cp_status = newstatus; if (merged & ORIGIN) break;
} cp->cp_status = newstatus;
} }
}
/* /*
* If nothing new has been added via a merge, then the node is * If nothing new has been added via a merge, then the node is
* finished. It is removed from the pending queue, added to the * finished. It is removed from the pending queue, added to the
* done list, cleaned up, and passed to ResDoneWithNode * done list, cleaned up, and passed to ResDoneWithNode
*/ */
if (merged == FALSE) if (merged == FALSE)
{ {
ResRemoveFromQueue(resptr2,&ResNodeQueue); ResRemoveFromQueue(resptr2, &ResNodeQueue);
resptr2->rn_more = ResNodeList; resptr2->rn_more = ResNodeList;
resptr2->rn_less = NULL; resptr2->rn_less = NULL;
resptr2->rn_status &= ~PENDING; resptr2->rn_status &= ~PENDING;
resptr2->rn_status |= FINISHED | MARKED; resptr2->rn_status |= FINISHED | MARKED;
if (ResNodeList != NULL) if (ResNodeList != NULL)
{ {
ResNodeList->rn_less = resptr2; ResNodeList->rn_less = resptr2;
} }
if (resptr2->rn_noderes == 0) if (resptr2->rn_noderes == 0)
{ {
ResOriginNode=resptr2; ResOriginNode=resptr2;
} }
ResNodeList = resptr2; ResNodeList = resptr2;
ResCleanNode(resptr2, FALSE, &ResNodeList, &ResNodeQueue); ResCleanNode(resptr2, FALSE, &ResNodeList, &ResNodeQueue);
ResDoneWithNode(resptr2); ResDoneWithNode(resptr2);
} }
} }
return(0); return(0);
} }
/*------------------------------------------------------------------------- /*
*-------------------------------------------------------------------------
*
* ResCalcPerimOverlap ---
*
* Given a device tile, compute simple perimeter and overlap of the device
* by the net under consideration.
*
* Results:
* None.
*
* Side Effects:
* The ResDevTile structure is updated with the overlap and perimeter
* values.
*
*-------------------------------------------------------------------------
*/
void
ResCalcPerimOverlap(tile, dev)
Tile *tile;
ResDevTile *dev;
{
Tile *tp;
int t1;
int overlap;
TileTypeBitMask *omask;
dev->perim = (TOP(tile) - BOTTOM(tile) - LEFT(tile) + RIGHT(tile)) << 1;
overlap = 0;
t1 = TiGetType(tile);
omask = &(ExtCurStyle->exts_nodeConn[t1]);
/* left */
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp))
{
if TTMaskHasType(omask, TiGetType(tp))
overlap += MIN(TOP(tile), TOP(tp)) - MAX(BOTTOM(tile), BOTTOM(tp));
}
/* right */
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp=LB(tp))
{
if TTMaskHasType(omask, TiGetType(tp))
overlap += MIN(TOP(tile), TOP(tp)) - MAX(BOTTOM(tile), BOTTOM(tp));
}
/* top */
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp))
{
if TTMaskHasType(omask, TiGetType(tp))
overlap += MIN(RIGHT(tile), RIGHT(tp)) - MAX(LEFT(tile), LEFT(tp));
}
/* bottom */
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp=TR(tp))
{
if TTMaskHasType(omask, TiGetType(tp))
overlap += MIN(RIGHT(tile), RIGHT(tp)) - MAX(LEFT(tile), LEFT(tp));
}
dev->overlap = overlap;
}
/*
*-------------------------------------------------------------------------
*
* resMakeDevFunc --
*
* Callback function from ResExtractNet. For each device in a node's
* device list pulled from the .sim file, find the tile corresponding
* to the device in the source tree, and fill out the complete device
* record (namely the full device area).
*
* Result:
* Return 1 to stop the search because the device has been found.
*
*-------------------------------------------------------------------------
*/
int
resMakeDevFunc(tile, cx)
Tile *tile;
TreeContext *cx;
{
ResDevTile *thisDev = (ResDevTile *)cx->tc_filter->tf_arg;
Rect devArea;
TiToRect(tile, &devArea);
GeoTransRect(&cx->tc_scx->scx_trans, &devArea, &thisDev->area);
ResCalcPerimOverlap(tile, thisDev);
return 1;
}
/*
*-------------------------------------------------------------------------
* *
* ResExtractNet-- extracts the resistance net at the specified * ResExtractNet-- extracts the resistance net at the specified
* rn_loc. If the resulting net is greater than the tolerance, * rn_loc. If the resulting net is greater than the tolerance,
@ -577,18 +670,20 @@ ResProcessTiles(goodies, origin)
*/ */
bool bool
ResExtractNet(startlist, goodies, cellname) ResExtractNet(node, goodies, cellname)
ResFixPoint *startlist; ResSimNode *node;
ResGlobalParams *goodies; ResGlobalParams *goodies;
char *cellname; char *cellname;
{ {
SearchContext scx; SearchContext scx;
int pNum; int pNum;
ResDevTile *DevTiles, *lasttile;
TileTypeBitMask FirstTileMask; TileTypeBitMask FirstTileMask;
Point startpoint; Point startpoint;
ResFixPoint *fix;
static int first = 1; static int first = 1;
ResDevTile *DevTiles, *thisDev;
ResFixPoint *fix;
devPtr *tptr;
int resMakeDevFunc();
/* Make sure all global network variables are reset */ /* Make sure all global network variables are reset */
@ -599,18 +694,18 @@ ResExtractNet(startlist, goodies, cellname)
ResContactList = NULL; ResContactList = NULL;
ResOriginNode = NULL; ResOriginNode = NULL;
/* Pass back network pointers */ /* Pass back network pointers */
goodies->rg_maxres = 0; goodies->rg_maxres = 0;
goodies->rg_tilecount = 0; goodies->rg_tilecount = 0;
/*set up internal stuff if this is the first time through */ /* Set up internal stuff if this is the first time through */
if (first) if (first)
{ {
ResInitializeConn(); ResInitializeConn();
first = 0; first = 0;
ResGetReCell(); ResGetReCell();
} }
/* Initialize Cell */ /* Initialize Cell */
@ -618,7 +713,7 @@ ResExtractNet(startlist, goodies, cellname)
if (cellname) if (cellname)
{ {
CellDef *def = DBCellLookDef(cellname); CellDef *def = DBCellLookDef(cellname);
if (def == (CellDef *) NULL) if (def == (CellDef *)NULL)
{ {
TxError("Error: No such cell \"%s\"\n", cellname); TxError("Error: No such cell \"%s\"\n", cellname);
return TRUE; return TRUE;
@ -629,8 +724,8 @@ ResExtractNet(startlist, goodies, cellname)
} }
else else
{ {
MagWindow *w = ToolGetBoxWindow(&scx.scx_area, (int *) NULL); MagWindow *w = ToolGetBoxWindow(&scx.scx_area, (int *)NULL);
if (w == (MagWindow *) NULL) if (w == (MagWindow *)NULL)
{ {
TxError("Sorry, the box must appear in one of the windows.\n"); TxError("Sorry, the box must appear in one of the windows.\n");
return TRUE; return TRUE;
@ -641,49 +736,59 @@ ResExtractNet(startlist, goodies, cellname)
DBCellClearDef(ResUse->cu_def); DBCellClearDef(ResUse->cu_def);
/* Copy Paint */
DevTiles = NULL;
lasttile = NULL;
for (fix = startlist; fix != NULL; fix = fix->fp_next)
{
ResDevTile *newdevtiles, *tmp;
#ifdef ARIEL #ifdef ARIEL
if ((ResOptionsFlags & ResOpt_Power) && if ((ResOptionsFlags & ResOpt_Power) &&
strcmp(fix->fp_name, goodies->rg_name) != 0) continue; strcmp(node->name, goodies->rg_name) != 0) continue;
#endif #endif
scx.scx_area.r_ll.p_x = fix->fp_loc.p_x-2; /* Copy Paint */
scx.scx_area.r_ll.p_y = fix->fp_loc.p_y-2;
scx.scx_area.r_ur.p_x = fix->fp_loc.p_x+2;
scx.scx_area.r_ur.p_y = fix->fp_loc.p_y+2;
startpoint = fix->fp_loc;
/* Because fix->fp_ttype might come from a label with a sticky type scx.scx_area.r_ll.p_x = node->location.p_x - 2;
* that does not correspond exactly to the layer underneath, include scx.scx_area.r_ll.p_y = node->location.p_y - 2;
* all connecting types. scx.scx_area.r_ur.p_x = node->location.p_x + 2;
*/ scx.scx_area.r_ur.p_y = node->location.p_y + 2;
TTMaskSetMask(&FirstTileMask, &DBConnectTbl[fix->fp_ttype]); startpoint = node->location;
newdevtiles = DBTreeCopyConnectDCS(&scx, &FirstTileMask, 0, /* Because node->type might come from a label with a sticky type
ResCopyMask, &TiPlaneRect, ResUse); * that does not correspond exactly to the layer underneath, include
* all connecting types.
*/
TTMaskZero(&FirstTileMask);
TTMaskSetMask(&FirstTileMask, &DBConnectTbl[node->type]);
for (tmp = newdevtiles; tmp && tmp->nextDev; tmp = tmp->nextDev); DBTreeCopyConnect(&scx, &FirstTileMask, 0, ResCopyMask, &TiPlaneRect,
if (newdevtiles) SEL_DO_LABELS, ResUse);
{
if (DevTiles) /* Add devices to ResUse from list in node */
lasttile->nextDev = newdevtiles; DevTiles = NULL;
else for (tptr = node->firstDev; tptr; tptr = tptr->nextDev)
DevTiles = newdevtiles; {
lasttile = tmp; TileTypeBitMask devMask;
}
TTMaskSetOnlyType(&devMask, tptr->thisDev->rs_ttype);
thisDev = (ResDevTile *)mallocMagic(sizeof(ResDevTile));
thisDev->devptr = tptr->thisDev->rs_devptr;
thisDev->type = tptr->thisDev->rs_ttype;
scx.scx_area.r_ll.p_x = tptr->thisDev->location.p_x;
scx.scx_area.r_ll.p_y = tptr->thisDev->location.p_y;
scx.scx_area.r_xtop = scx.scx_area.r_xbot + 1;
scx.scx_area.r_ytop = scx.scx_area.r_ybot + 1;
DBTreeSrTiles(&scx, &devMask, 0, resMakeDevFunc, (ClientData)thisDev);
thisDev->nextDev = DevTiles;
DevTiles = thisDev;
/* Paint the type into ResUse */
pNum = DBPlane(thisDev->type);
DBPaintPlane(ResUse->cu_def->cd_planes[pNum], &thisDev->area,
DBStdPaintTbl(thisDev->type, pNum), (PaintUndoInfo *)NULL);
} }
DBReComputeBbox(ResUse->cu_def);
ExtResetTiles(scx.scx_use->cu_def, extUnInit); ExtResetTiles(scx.scx_use->cu_def, extUnInit);
/* find all contacts in design and note their position */ /* Find all contacts in design and note their position */
ResContactList = (ResContactPoint *) ExtFindRegions(ResUse->cu_def, ResContactList = (ResContactPoint *)ExtFindRegions(ResUse->cu_def,
&(ResUse->cu_def->cd_bbox), &(ResUse->cu_def->cd_bbox),
&DBAllButSpaceAndDRCBits, &DBAllButSpaceAndDRCBits,
ResConnectWithSD, extUnInit, ResFirst, ResConnectWithSD, extUnInit, ResFirst,
@ -701,16 +806,16 @@ ResExtractNet(startlist, goodies, cellname)
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
{ {
Plane *plane = ResUse->cu_def->cd_planes[pNum]; Plane *plane = ResUse->cu_def->cd_planes[pNum];
Rect *rect = &ResUse->cu_def->cd_bbox; Rect *rect = &ResUse->cu_def->cd_bbox;
ResFracture(plane, rect); ResFracture(plane, rect);
(void) DBSrPaintClient((Tile *) NULL,plane,rect, (void) DBSrPaintClient((Tile *) NULL, plane, rect,
&DBAllButSpaceAndDRCBits, &DBAllButSpaceAndDRCBits,
(ClientData) CLIENTDEFAULT, ResAddPlumbing, (ClientData) CLIENTDEFAULT, ResAddPlumbing,
(ClientData) &ResDevList); (ClientData) &ResDevList);
} }
/* Finish preprocessing. */ /* Finish preprocessing. */
ResMakePortBreakpoints(ResUse->cu_def); ResMakePortBreakpoints(ResUse->cu_def);
ResMakeLabelBreakpoints(ResUse->cu_def); ResMakeLabelBreakpoints(ResUse->cu_def);
@ -720,24 +825,24 @@ ResExtractNet(startlist, goodies, cellname)
#ifdef LAPLACE #ifdef LAPLACE
if (ResOptionsFlags & ResOpt_DoLaplace) if (ResOptionsFlags & ResOpt_DoLaplace)
{ {
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
{ {
Plane *plane = ResUse->cu_def->cd_planes[pNum]; Plane *plane = ResUse->cu_def->cd_planes[pNum];
Rect *rect = &ResUse->cu_def->cd_bbox; Rect *rect = &ResUse->cu_def->cd_bbox;
Res1d(plane,rect); Res1d(plane, rect);
} }
} }
#endif #endif
#ifdef ARIEL #ifdef ARIEL
if (ResOptionsFlags & ResOpt_Power) if (ResOptionsFlags & ResOpt_Power)
{ {
for (fix = startlist; fix != NULL;fix=fix->fp_next) for (fix = startlist; fix != NULL; fix = fix->fp_next)
{ {
fix->fp_tile = ResUse->cu_def->cd_planes[DBPlane(fix->fp_ttype)]->pl_hint; fix->fp_tile = ResUse->cu_def->cd_planes[DBPlane(fix->fp_ttype)]->pl_hint;
GOTOPOINT(fix->fp_tile,&fix->fp_loc); GOTOPOINT(fix->fp_tile, &fix->fp_loc);
if (TiGetTypeExact(fix->fp_tile) == TT_SPACE) fix->fp_tile = NULL; if (TiGetTypeExact(fix->fp_tile) == TT_SPACE) fix->fp_tile = NULL;
} }
} }
#endif #endif
@ -765,25 +870,24 @@ void
ResCleanUpEverything() ResCleanUpEverything()
{ {
int pNum; int pNum;
resResistor *oldRes; resResistor *oldRes;
resDevice *oldDev; resDevice *oldDev;
ResContactPoint *oldCon; ResContactPoint *oldCon;
/* check integrity of internal database. Free up lists. */ /* Check integrity of internal database. Free up lists. */
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
{ {
(void) DBSrPaintClient((Tile *) NULL,ResUse->cu_def->cd_planes[pNum], (void) DBSrPaintClient((Tile *)NULL, ResUse->cu_def->cd_planes[pNum],
&(ResUse->cu_def->cd_bbox),&DBAllButSpaceAndDRCBits, &(ResUse->cu_def->cd_bbox), &DBAllButSpaceAndDRCBits,
(ClientData) CLIENTDEFAULT,ResRemovePlumbing, (ClientData)CLIENTDEFAULT, ResRemovePlumbing,
(ClientData) NULL); (ClientData)NULL);
} }
while (ResNodeList != NULL) while (ResNodeList != NULL)
{ {
ResCleanNode(ResNodeList,TRUE,&ResNodeList,&ResNodeQueue); ResCleanNode(ResNodeList, TRUE, &ResNodeList, &ResNodeQueue);
} }
while (ResContactList != NULL) while (ResContactList != NULL)
{ {
@ -807,12 +911,9 @@ ResCleanUpEverything()
freeMagic((char *)oldDev); freeMagic((char *)oldDev);
} }
} }
DBCellClearDef(ResUse->cu_def); DBCellClearDef(ResUse->cu_def);
} }
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
@ -849,10 +950,10 @@ FindStartTile(goodies, SourcePoint)
TileType savtype = goodies->rg_ttype; TileType savtype = goodies->rg_ttype;
TileType rtype; TileType rtype;
savtype = goodies->rg_ttype;
for (rtype = TT_TECHDEPBASE; rtype < DBNumUserLayers; rtype++) for (rtype = TT_TECHDEPBASE; rtype < DBNumUserLayers; rtype++)
if (TTMaskHasType(rmask, rtype)) if (TTMaskHasType(rmask, rtype))
{ {
goodies->rg_ttype = rtype;
if ((tile = FindStartTile(goodies, SourcePoint)) != NULL) if ((tile = FindStartTile(goodies, SourcePoint)) != NULL)
{ {
goodies->rg_ttype = savtype; goodies->rg_ttype = savtype;
@ -934,54 +1035,55 @@ FindStartTile(goodies, SourcePoint)
t1 = TiGetType(tile); t1 = TiGetType(tile);
devptr = ExtCurStyle->exts_device[t1]; devptr = ExtCurStyle->exts_device[t1];
/* left */ /* left */
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp=RT(tp)) for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp))
{ {
t2 = TiGetRightType(tp); t2 = TiGetRightType(tp);
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2)) if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2))
{ {
SourcePoint->p_x = LEFT(tile); SourcePoint->p_x = LEFT(tile);
SourcePoint->p_y = (MIN(TOP(tile),TOP(tp))+ SourcePoint->p_y = (MIN(TOP(tile),TOP(tp)) +
MAX(BOTTOM(tile),BOTTOM(tp)))>>1; MAX(BOTTOM(tile), BOTTOM(tp))) >> 1;
return(tp); return(tp);
} }
} }
/* right */ /* right */
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp=LB(tp)) for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp))
{ {
t2 = TiGetLeftType(tp); t2 = TiGetLeftType(tp);
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2)) if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2))
{ {
SourcePoint->p_x = RIGHT(tile); SourcePoint->p_x = RIGHT(tile);
SourcePoint->p_y = (MIN(TOP(tile),TOP(tp))+ SourcePoint->p_y = (MIN(TOP(tile), TOP(tp))+
MAX(BOTTOM(tile),BOTTOM(tp)))>>1; MAX(BOTTOM(tile), BOTTOM(tp))) >> 1;
return(tp); return(tp);
} }
} }
/* top */ /* top */
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp=BL(tp)) for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp))
{ {
t2 = TiGetBottomType(tp); t2 = TiGetBottomType(tp);
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2)) if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2))
{ {
SourcePoint->p_y = TOP(tile); SourcePoint->p_y = TOP(tile);
SourcePoint->p_x = (MIN(RIGHT(tile),RIGHT(tp))+ SourcePoint->p_x = (MIN(RIGHT(tile),RIGHT(tp)) +
MAX(LEFT(tile),LEFT(tp)))>>1; MAX(LEFT(tile), LEFT(tp))) >> 1;
return(tp); return(tp);
} }
} }
/* bottom */ /* bottom */
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp=TR(tp)) for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp))
{ {
t2 = TiGetTopType(tp); t2 = TiGetTopType(tp);
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2)) if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2))
{ {
SourcePoint->p_y = BOTTOM(tile); SourcePoint->p_y = BOTTOM(tile);
SourcePoint->p_x = (MIN(RIGHT(tile),RIGHT(tp))+ SourcePoint->p_x = (MIN(RIGHT(tile), RIGHT(tp)) +
MAX(LEFT(tile),LEFT(tp)))>>1; MAX(LEFT(tile), LEFT(tp))) >> 1;
return(tp); return(tp);
} }
} }
@ -1005,36 +1107,36 @@ FindStartTile(goodies, SourcePoint)
resDevice * resDevice *
ResGetDevice(pt) ResGetDevice(pt)
Point *pt; Point *pt;
{ {
Point workingPoint; Point workingPoint;
Tile *tile; Tile *tile;
int pnum; int pnum;
workingPoint.p_x = (*pt).p_x; workingPoint.p_x = (*pt).p_x;
workingPoint.p_y = (*pt).p_y; workingPoint.p_y = (*pt).p_y;
for (pnum= PL_TECHDEPBASE; pnum < DBNumPlanes; pnum++) for (pnum = PL_TECHDEPBASE; pnum < DBNumPlanes; pnum++)
{ {
if (TTMaskIntersect(&ExtCurStyle->exts_deviceMask,&DBPlaneTypes[pnum]) == 0) if (TTMaskIntersect(&ExtCurStyle->exts_deviceMask, &DBPlaneTypes[pnum]) == 0)
{ continue;
continue;
}
/*start at hint tile for device plane */
tile = ResUse->cu_def->cd_planes[pnum]->pl_hint;
GOTOPOINT(tile,&workingPoint);
if (IsSplit(tile)) /* Start at hint tile for device plane */
{
if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetLeftType(tile)) tile = ResUse->cu_def->cd_planes[pnum]->pl_hint;
GOTOPOINT(tile, &workingPoint);
if (IsSplit(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)->deviceList); 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)->deviceList); return (((tileJunk *)tile->ti_client)->deviceList);
} }
} }
return (NULL); return NULL;
} }

View File

@ -311,7 +311,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
*/ */
p1 = junk->breakList; p1 = junk->breakList;
if (p1->br_next == NULL) if (p1->br_next == NULL)
{ {
p1->br_this->rn_float.rn_area += width * (TOP(tile) - BOTTOM(tile)); p1->br_this->rn_float.rn_area += width * (TOP(tile) - BOTTOM(tile));
freeMagic((char *)p1); freeMagic((char *)p1);

File diff suppressed because it is too large Load Diff

View File

@ -171,16 +171,25 @@ ResPrintExtDev(outextfile, devices)
else else
fprintf(outextfile, " \"%s\"", subsName); fprintf(outextfile, " \"%s\"", subsName);
fprintf(outextfile, " \"%s\" %d %s \"%s\" %d %s \"%s\" %d %s\n", if (devices->gate != NULL)
devices->gate->name, fprintf(outextfile, " \"%s\" %d %s",
devices->layout->rd_length * 2, devices->gate->name,
devices->rs_gattr, devices->layout->rd_length * 2,
devices->source->name, devices->rs_gattr);
devices->layout->rd_width,
devices->rs_sattr, if (devices->source != NULL)
devices->drain->name, fprintf(outextfile, " \"%s\" %d %s",
devices->layout->rd_width, devices->source->name,
devices->rs_dattr); devices->layout->rd_width,
devices->rs_sattr);
if (devices->drain != NULL)
fprintf(outextfile, " \"%s\" %d %s",
devices->drain->name,
devices->layout->rd_width,
devices->rs_dattr);
fprintf(outextfile, "\n");
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "textio/textio.h" #include "textio/textio.h"
#include "extract/extract.h" #include "extract/extract.h"
#include "extract/extractInt.h" #include "extract/extractInt.h"
#include "extflat/extflat.h"
#include "windows/windows.h" #include "windows/windows.h"
#include "dbwind/dbwind.h" #include "dbwind/dbwind.h"
#include "utils/utils.h" #include "utils/utils.h"
@ -52,9 +53,10 @@ extern ResSimNode *ResOriginalNodes; /*Linked List of Nodes */
int resNodeNum; int resNodeNum;
#ifdef LAPLACE #ifdef LAPLACE
int ResOptionsFlags = ResOpt_Simplify|ResOpt_Tdi|ResOpt_DoExtFile|ResOpt_CacheLaplace; int ResOptionsFlags = ResOpt_Simplify | ResOpt_Tdi | ResOpt_DoExtFile
| ResOpt_CacheLaplace;
#else #else
int ResOptionsFlags = ResOpt_Simplify|ResOpt_Tdi|ResOpt_DoExtFile; int ResOptionsFlags = ResOpt_Simplify | ResOpt_Tdi | ResOpt_DoExtFile;
#endif #endif
char *ResCurrentNode; char *ResCurrentNode;
@ -97,17 +99,34 @@ ExtResisForDef(celldef, resisdata)
HashEntry *entry; HashEntry *entry;
devPtr *tptr,*oldtptr; devPtr *tptr,*oldtptr;
ResSimNode *node; ResSimNode *node;
int result; int result, idx;
char *devname;
ResRDevList = NULL; ResRDevList = NULL;
ResOriginalNodes = NULL; ResOriginalNodes = NULL;
/* Get device information from the current extraction style */
idx = 0;
while (ExtGetDevInfo(idx++, &devname, NULL, NULL, NULL, NULL, NULL))
{
if (idx == TT_MAXTYPES)
{
TxError("Error: Ran out of space for device types!\n");
break;
}
efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, devname);
}
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,
ResSimDevice, ResSimCapacitor, ResSimResistor, ResSimDevice, ResSimCapacitor, ResSimResistor,
ResSimAttribute, ResSimMerge, ResSimSubckt) == 0); ResSimAttribute, ResSimMerge, ResSimSubckt) == 0);
/* Clean up the EFDevTypes table */
for (idx = 0; idx < EFDevNumTypes; idx++) freeMagic(EFDevTypes[idx]);
EFDevNumTypes = 0;
if (result) if (result)
/* read in .nodes file */ /* read in .nodes file */
result = (ResReadNode(celldef->cd_name) == 0); result = (ResReadNode(celldef->cd_name) == 0);
@ -185,7 +204,7 @@ CmdExtResis(win, cmd)
TxCommand *cmd; TxCommand *cmd;
{ {
int i, j, k, option, value, saveFlags; int i, j, k, option, value, saveFlags;
static int init=1; static int init = 1;
static float tolerance, tdiTolerance, fhFrequency; static float tolerance, tdiTolerance, fhFrequency;
CellDef *mainDef; CellDef *mainDef;
CellUse *selectedUse; CellUse *selectedUse;
@ -246,6 +265,17 @@ typedef enum {
init = 0; init = 0;
} }
/* Initialize ResGlobalParams */
gparams.rg_ttype = TT_SPACE;
gparams.rg_Tdi = 0.0;
gparams.rg_nodecap = 0.0;
gparams.rg_maxres = 0.0;
gparams.rg_bigdevres = 0;
gparams.rg_tilecount = 0;
gparams.rg_status = 0;
gparams.rg_devloc = NULL;
gparams.rg_name = NULL;
option = (cmd->tx_argc > 1) ? Lookup(cmd->tx_argv[1], cmdExtresisCmd) option = (cmd->tx_argc > 1) ? Lookup(cmd->tx_argv[1], cmdExtresisCmd)
: RES_RUN; : RES_RUN;
@ -434,7 +464,7 @@ typedef enum {
CellDef *def; CellDef *def;
Rect rect; Rect rect;
int oldoptions; int oldoptions;
ResFixPoint fp; ResSimNode lnode;
if (ToolGetBoxWindow((Rect *) NULL, (int *) NULL) == NULL) if (ToolGetBoxWindow((Rect *) NULL, (int *) NULL) == NULL)
{ {
@ -449,23 +479,23 @@ typedef enum {
gparams.rg_ttype = tt; gparams.rg_ttype = tt;
gparams.rg_status = DRIVEONLY; gparams.rg_status = DRIVEONLY;
oldoptions = ResOptionsFlags; oldoptions = ResOptionsFlags;
ResOptionsFlags = ResOpt_DoSubstrate|ResOpt_Signal|ResOpt_Box; ResOptionsFlags = ResOpt_DoSubstrate | ResOpt_Signal | ResOpt_Box;
#ifdef LAPLACE #ifdef LAPLACE
ResOptionsFlags |= (oldoptions & (ResOpt_CacheLaplace|ResOpt_DoLaplace)); ResOptionsFlags |= (oldoptions &
(ResOpt_CacheLaplace | ResOpt_DoLaplace));
LaplaceMatchCount = 0; LaplaceMatchCount = 0;
LaplaceMissCount = 0; LaplaceMissCount = 0;
#endif #endif
fp.fp_ttype = tt; lnode.location = rect.r_ll;
fp.fp_loc = rect.r_ll; lnode.type = tt;
fp.fp_next = NULL; if (ResExtractNet(&lnode, &gparams, NULL) != 0) return;
if (ResExtractNet(&fp, &gparams, NULL) != 0) return; ResPrintResistorList(stdout, ResResList);
ResPrintResistorList(stdout,ResResList); ResPrintDeviceList(stdout, ResRDevList);
ResPrintDeviceList(stdout,ResRDevList);
#ifdef LAPLACE #ifdef LAPLACE
if (ResOptionsFlags & ResOpt_DoLaplace) if (ResOptionsFlags & ResOpt_DoLaplace)
{ {
TxPrintf("Laplace solved: %d matched %d\n", TxPrintf("Laplace solved: %d matched %d\n",
LaplaceMissCount,LaplaceMatchCount); LaplaceMissCount, LaplaceMatchCount);
} }
#endif #endif
@ -492,11 +522,11 @@ typedef enum {
return; return;
#endif #endif
case RES_AMBIG: case RES_AMBIG:
TxPrintf("Ambiguous option: %s\n",cmd->tx_argv[1]); TxPrintf("Ambiguous option: %s\n", cmd->tx_argv[1]);
TxFlushOut(); TxFlushOut();
return; return;
case RES_BAD: case RES_BAD:
TxPrintf("Unknown option: %s\n",cmd->tx_argv[1]); TxPrintf("Unknown option: %s\n", cmd->tx_argv[1]);
TxFlushOut(); TxFlushOut();
return; return;
default: default:
@ -519,7 +549,7 @@ typedef enum {
} }
ResOptionsFlags |= ResOpt_Signal; ResOptionsFlags |= ResOpt_Signal;
#ifdef ARIEL #ifdef ARIEL
ResOptionsFlags &= ~ResOpt_Power; ResOptionsFlags &= ~ResOpt_Power;
#endif #endif
resisdata.tolerance = tolerance; resisdata.tolerance = tolerance;
@ -581,8 +611,6 @@ resSubcircuitFunc(cellDef, rdata)
return 0; return 0;
} }
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
@ -841,7 +869,7 @@ ResCheckSimNodes(celldef, resisdata)
} }
if (ResOptionsFlags & ResOpt_DoLumpFile) if (ResOptionsFlags & ResOpt_DoLumpFile)
{ {
ResLumpFile = PaOpen(outfile,"w",".res.lump",".",(char *) NULL, (char **) NULL); ResLumpFile = PaOpen(outfile, "w", ".res.lump", ".", (char *)NULL, (char **)NULL);
} }
else else
{ {
@ -850,7 +878,7 @@ ResCheckSimNodes(celldef, resisdata)
if (ResOptionsFlags & ResOpt_FastHenry) if (ResOptionsFlags & ResOpt_FastHenry)
{ {
char *geofilename; char *geofilename;
ResFHFile = PaOpen(outfile,"w",".fh",".",(char *) NULL, &geofilename); ResFHFile = PaOpen(outfile, "w", ".fh", ".", (char *)NULL, &geofilename);
TxPrintf("Writing FastHenry-format geometry file \"%s\"\n", geofilename); TxPrintf("Writing FastHenry-format geometry file \"%s\"\n", geofilename);
ResPortIndex = 0; ResPortIndex = 0;
} }
@ -961,7 +989,7 @@ ResCheckSimNodes(celldef, resisdata)
t1->drain != t2->source)) break; t1->drain != t2->source)) break;
/* do parallel combination */ /* do parallel combination */
if (cumRes != 0.0 && t2->resistance != 0.0) if ((cumRes != 0.0) && (t2->resistance != 0.0))
{ {
cumRes = (cumRes * t2->resistance) / cumRes = (cumRes * t2->resistance) /
(cumRes + t2->resistance); (cumRes + t2->resistance);
@ -998,32 +1026,32 @@ ResCheckSimNodes(celldef, resisdata)
gparams.rg_devloc = &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 device, 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_devloc == 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 device\n",node->name); "driving device\n",node->name);
} }
if (minRes == FLT_MAX || gparams.rg_devloc == NULL) if ((minRes == FLT_MAX) || (gparams.rg_devloc == NULL))
{ {
continue; continue;
} }
gparams.rg_bigdevres = (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;
rctolerance = 0.0; rctolerance = 0.0;
} }
else else
{ {
ftolerance = minRes/tol; ftolerance = minRes / tol;
rctolerance = minRes/rctol; rctolerance = minRes / rctol;
} }
/* /*
@ -1031,19 +1059,16 @@ ResCheckSimNodes(celldef, resisdata)
* resistance? If so, extract net. * resistance? If so, extract net.
*/ */
if (node->resistance > ftolerance || node->status & FORCE || if ((node->resistance > ftolerance) || (node->status & FORCE) ||
(ResOpt_ExtractAll & ResOptionsFlags)) (ResOpt_ExtractAll & ResOptionsFlags))
{ {
ResFixPoint fp; ResFixPoint fp;
failed1++; failed1++;
fp.fp_loc = node->location; if (ResExtractNet(node, &gparams, outfile) != 0)
fp.fp_ttype = node->type;
fp.fp_next = NULL;
if (ResExtractNet(&fp, &gparams, outfile) != 0)
{ {
TxError("Error in extracting node %s\n",node->name); /* On error, don't output this net, but keep going */
// break; // Don't stop for one error. . . TxError("Error in extracting node %s\n", node->name);
} }
else else
{ {
@ -1062,7 +1087,7 @@ ResCheckSimNodes(celldef, resisdata)
} }
} }
#ifdef PARANOID #ifdef PARANOID
ResSanityChecks(node->name,ResResList,ResNodeList,ResDevList); ResSanityChecks(node->name, ResResList, ResNodeList, ResDevList);
#endif #endif
ResCleanUpEverything(); ResCleanUpEverything();
} }
@ -1075,7 +1100,7 @@ ResCheckSimNodes(celldef, resisdata)
if (ResOptionsFlags & ResOpt_DoExtFile) if (ResOptionsFlags & ResOpt_DoExtFile)
{ {
ResPrintExtDev(ResExtFile,ResRDevList); ResPrintExtDev(ResExtFile, ResRDevList);
} }
/* /*
@ -1182,7 +1207,7 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
if (simDev->gate == simNode) if (simDev->gate == simNode)
{ {
if ((gate=layoutDev->rd_fet_gate) != NULL) if ((gate = layoutDev->rd_fet_gate) != NULL)
{ {
/* Cosmetic addition: If the layout device 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 */
@ -1398,9 +1423,10 @@ void
ResSortByGate(DevpointerList) ResSortByGate(DevpointerList)
devPtr **DevpointerList; devPtr **DevpointerList;
{ {
int changed=TRUE; int changed = TRUE;
int localchange=TRUE; int localchange = TRUE;
devPtr *working, *last=NULL, *current, *gatelist=NULL; devPtr *working, *current;
devPtr *last = NULL, *gatelist = NULL;
working = *DevpointerList; working = *DevpointerList;
while (working != NULL) while (working != NULL)
@ -1526,7 +1552,7 @@ ResWriteLumpFile(node)
{ {
lumpedres = gparams.rg_maxres; lumpedres = gparams.rg_maxres;
} }
fprintf(ResLumpFile,"R %s %d\n", node->name, lumpedres); fprintf(ResLumpFile, "R %s %d\n", node->name, lumpedres);
} }

File diff suppressed because it is too large Load Diff

View File

@ -62,27 +62,27 @@ ResFirst(tile, arg)
if (DBIsContact(t)) if (DBIsContact(t))
{ {
reg = (ResContactPoint *) mallocMagic((unsigned) (sizeof(ResContactPoint))); reg = (ResContactPoint *) mallocMagic((unsigned) (sizeof(ResContactPoint)));
reg->cp_center.p_x = (LEFT(tile)+RIGHT(tile))>>1; reg->cp_center.p_x = (LEFT(tile) + RIGHT(tile)) >> 1;
reg->cp_center.p_y = (TOP(tile)+BOTTOM(tile))>>1; reg->cp_center.p_y = (TOP(tile) + BOTTOM(tile)) >> 1;
reg->cp_status = FALSE; reg->cp_status = FALSE;
reg->cp_type = t; reg->cp_type = t;
reg->cp_width = RIGHT(tile)-LEFT(tile); reg->cp_width = RIGHT(tile) - LEFT(tile);
reg->cp_height = TOP(tile)-BOTTOM(tile); reg->cp_height = TOP(tile) - BOTTOM(tile);
for (i=0; i< LAYERS_PER_CONTACT; i++) for (i = 0; i < LAYERS_PER_CONTACT; i++)
{ {
reg->cp_tile[i] = (Tile *) NULL; reg->cp_tile[i] = (Tile *) NULL;
reg->cp_cnode[i] = (resNode *) NULL; reg->cp_cnode[i] = (resNode *) NULL;
} }
reg->cp_currentcontact = 0; reg->cp_currentcontact = 0;
reg->cp_rect.r_ll.p_x = tile->ti_ll.p_x; reg->cp_rect.r_ll.p_x = tile->ti_ll.p_x;
reg->cp_rect.r_ll.p_y = tile->ti_ll.p_y; reg->cp_rect.r_ll.p_y = tile->ti_ll.p_y;
reg->cp_rect.r_ur.p_x = RIGHT(tile); reg->cp_rect.r_ur.p_x = RIGHT(tile);
reg->cp_rect.r_ur.p_y = TOP(tile); reg->cp_rect.r_ur.p_y = TOP(tile);
reg->cp_contactTile = tile; reg->cp_contactTile = tile;
/* Prepend it to the region list */ /* Prepend it to the region list */
reg->cp_nextcontact = (ResContactPoint *) arg->fra_region; reg->cp_nextcontact = (ResContactPoint *) arg->fra_region;
arg->fra_region = (Region *) reg; arg->fra_region = (Region *) reg;
} }
return((Region *) NULL); return((Region *) NULL);
} }
@ -104,16 +104,16 @@ ResFirst(tile, arg)
int int
ResEach(tile, pNum, arg) ResEach(tile, pNum, arg)
Tile *tile; Tile *tile;
int pNum; int pNum;
FindRegion *arg; FindRegion *arg;
{ {
if ( ((ResContactPoint *)(arg->fra_region))->cp_contactTile != tile) if (((ResContactPoint *)(arg->fra_region))->cp_contactTile != tile)
{ {
(void) ResFirst(tile, arg); ResFirst(tile, arg);
} }
return(0); return(0);
} }
/* /*
@ -135,22 +135,21 @@ ResEach(tile, pNum, arg)
int int
ResAddPlumbing(tile, arg) ResAddPlumbing(tile, arg)
Tile *tile; Tile *tile;
ClientData *arg; ClientData *arg;
{ {
tileJunk *Junk,*junk2; tileJunk *Junk, *junk2;
static Stack *resDevStack=NULL; static Stack *resDevStack = NULL;
TileType loctype, t1; TileType loctype, t1;
Tile *tp1,*tp2,*source; Tile *tp1, *tp2, *source;
resDevice *resDev; resDevice *resDev;
ExtDevice *devptr; ExtDevice *devptr;
if (resDevStack == NULL) if (resDevStack == NULL)
resDevStack = StackNew(64); resDevStack = 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);
@ -165,7 +164,7 @@ ResAddPlumbing(tile, arg)
/* Count SD terminals of the device */ /* Count SD terminals of the device */
nterms = 0; nterms = 0;
for (i = 0; ; i++) for (i = 0;; i++)
{ {
if (TTMaskIsZero(&(devptr->exts_deviceSDTypes[i]))) break; if (TTMaskIsZero(&(devptr->exts_deviceSDTypes[i]))) break;
nterms++; nterms++;
@ -181,7 +180,7 @@ ResAddPlumbing(tile, arg)
resDev = (resDevice *) mallocMagic((unsigned)(sizeof(resDevice))); resDev = (resDevice *) mallocMagic((unsigned)(sizeof(resDevice)));
resDev->rd_nterms = nterms; resDev->rd_nterms = nterms;
resDev->rd_terminals = (resNode **) mallocMagic(nterms * sizeof(resNode *)); resDev->rd_terminals = (resNode **) mallocMagic(nterms * sizeof(resNode *));
for (i=0; i != nterms;i++) for (i = 0; i != nterms; i++)
resDev->rd_terminals[i] = (resNode *) NULL; resDev->rd_terminals[i] = (resNode *) NULL;
resDev->rd_tile = tile; resDev->rd_tile = tile;
@ -201,79 +200,91 @@ ResAddPlumbing(tile, arg)
junk2->deviceList = resDev; junk2->deviceList = resDev;
junk2->tj_status |= RES_TILE_DEV; junk2->tj_status |= RES_TILE_DEV;
source = NULL; for (i = 0; i < nterms - 2; i++)
/* 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]), 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[i]),
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[i]),
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[i]),
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[i]),
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;
}
}
/* other plane (in ResUse) */
if (source == NULL)
{
int pNum;
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
{
/* XXX */
}
} }
}
/* 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 device. 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),resDevStack); STACKPUSH((ClientData)source, resDevStack);
}
} }
while (!StackEmpty(resDevStack)) while (!StackEmpty(resDevStack))
{ {
@ -287,54 +298,54 @@ ResAddPlumbing(tile, arg)
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); tileJunk *j = resAddField(tp2);
if ((j->tj_status & RES_TILE_SD) ==0) if ((j->tj_status & RES_TILE_SD) ==0)
{ {
j->tj_status |= RES_TILE_SD; j->tj_status |= RES_TILE_SD;
STACKPUSH((ClientData)tp2,resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
} }
} }
} }
/*bottom*/ /* bottom */
for (tp2= LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2)) for (tp2 = LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2))
{ {
if (TiGetTopType(tp2) == t1) if (TiGetTopType(tp2) == t1)
{ {
tileJunk *j= resAddField(tp2); tileJunk *j = resAddField(tp2);
if ((j->tj_status & RES_TILE_SD) == 0) if ((j->tj_status & RES_TILE_SD) == 0)
{ {
j->tj_status |= RES_TILE_SD; j->tj_status |= RES_TILE_SD;
STACKPUSH((ClientData) (tp2),resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
} }
} }
} }
/*right*/ /* right */
for (tp2= TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2)) for (tp2 = TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2))
{ {
if (TiGetLeftType(tp2) == t1) if (TiGetLeftType(tp2) == t1)
{ {
tileJunk *j= resAddField(tp2); tileJunk *j = resAddField(tp2);
if ((j->tj_status & RES_TILE_SD) == 0) if ((j->tj_status & RES_TILE_SD) == 0)
{ {
j->tj_status |= RES_TILE_SD; j->tj_status |= RES_TILE_SD;
STACKPUSH((ClientData) (tp2),resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
} }
} }
} }
/*left*/ /* left */
for (tp2= BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2)) for (tp2 = BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2))
{ {
if (TiGetRightType(tp2) == t1) if (TiGetRightType(tp2) == t1)
{ {
tileJunk *j= resAddField(tp2); tileJunk *j = resAddField(tp2);
if ((j->tj_status & RES_TILE_SD) == 0) if ((j->tj_status & RES_TILE_SD) == 0)
{ {
j->tj_status |= RES_TILE_SD; j->tj_status |= RES_TILE_SD;
STACKPUSH((ClientData) (tp2),resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
} }
} }
} }
@ -342,12 +353,12 @@ ResAddPlumbing(tile, arg)
/* find rest of device; search for source edges */ /* find rest of device; search for source edges */
STACKPUSH((ClientData) (tile), resDevStack); STACKPUSH((ClientData)tile, resDevStack);
while (!StackEmpty(resDevStack)) while (!StackEmpty(resDevStack))
{ {
tileJunk *j0; tileJunk *j0;
tp1= (Tile *) STACKPOP(resDevStack); tp1 = (Tile *) STACKPOP(resDevStack);
if (IsSplit(tp1)) if (IsSplit(tp1))
{ {
t1 = (SplitSide(tp1)) ? SplitRightType(tp1) : t1 = (SplitSide(tp1)) ? SplitRightType(tp1) :
@ -359,14 +370,14 @@ ResAddPlumbing(tile, arg)
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),resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
Junk->deviceList = resDev; Junk->deviceList = resDev;
Junk->tj_status |= RES_TILE_DEV; Junk->tj_status |= RES_TILE_DEV;
} }
@ -378,14 +389,14 @@ ResAddPlumbing(tile, arg)
j0->sourceEdge |= TOPEDGE; j0->sourceEdge |= TOPEDGE;
} }
} }
/*bottom*/ /* bottom */
for (tp2= LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2)) for (tp2 = LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2))
{ {
if ((TiGetTopType(tp2) == t1) && if ((TiGetTopType(tp2) == t1) &&
(tp2->ti_client == (ClientData) CLIENTDEFAULT)) (tp2->ti_client == (ClientData) CLIENTDEFAULT))
{ {
Junk = resAddField(tp2); Junk = resAddField(tp2);
STACKPUSH((ClientData)(tp2),resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
Junk->deviceList = resDev; Junk->deviceList = resDev;
Junk->tj_status |= RES_TILE_DEV; Junk->tj_status |= RES_TILE_DEV;
} }
@ -397,33 +408,33 @@ ResAddPlumbing(tile, arg)
j0->sourceEdge |= BOTTOMEDGE; j0->sourceEdge |= BOTTOMEDGE;
} }
} }
/*right*/ /* right */
for (tp2= TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2)) for (tp2 = TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2))
{ {
if ((TiGetLeftType(tp2) == t1) && if ((TiGetLeftType(tp2) == t1) &&
(tp2->ti_client == (ClientData) CLIENTDEFAULT)) (tp2->ti_client == (ClientData) CLIENTDEFAULT))
{ {
Junk = resAddField(tp2); Junk = resAddField(tp2);
STACKPUSH((ClientData)(tp2),resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
Junk->deviceList = resDev; Junk->deviceList = resDev;
Junk->tj_status |= RES_TILE_DEV; Junk->tj_status |= RES_TILE_DEV;
} }
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
TiGetLeftType(tp2)) TiGetLeftType(tp2))
{ {
Junk = resAddField(tp2); Junk = resAddField(tp2);
if (Junk->tj_status & RES_TILE_SD) if (Junk->tj_status & RES_TILE_SD)
j0->sourceEdge |= RIGHTEDGE; j0->sourceEdge |= RIGHTEDGE;
} }
} }
/*left*/ /* left */
for (tp2= BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2)) for (tp2 = BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2))
{ {
if ((TiGetRightType(tp2) == t1) && if ((TiGetRightType(tp2) == t1) &&
(tp2->ti_client == (ClientData) CLIENTDEFAULT)) (tp2->ti_client == (ClientData) CLIENTDEFAULT))
{ {
Junk = resAddField(tp2); Junk = resAddField(tp2);
STACKPUSH((ClientData)(tp2),resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
Junk->deviceList = resDev; Junk->deviceList = resDev;
Junk->tj_status |= RES_TILE_DEV; Junk->tj_status |= RES_TILE_DEV;
} }
@ -441,9 +452,9 @@ ResAddPlumbing(tile, arg)
if (source != (Tile *) NULL) if (source != (Tile *) NULL)
{ {
tileJunk *j = (tileJunk *) source->ti_client; tileJunk *j = (tileJunk *) source->ti_client;
STACKPUSH((ClientData) (source),resDevStack); STACKPUSH((ClientData)source, resDevStack);
j->tj_status &= ~RES_TILE_SD; j->tj_status &= ~RES_TILE_SD;
} }
while (!StackEmpty(resDevStack)) while (!StackEmpty(resDevStack))
@ -458,54 +469,54 @@ ResAddPlumbing(tile, arg)
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))
{ {
tileJunk *j2 = (tileJunk *) tp2->ti_client; tileJunk *j2 = (tileJunk *) tp2->ti_client;
if (TiGetBottomType(tp2) == t1) if (TiGetBottomType(tp2) == t1)
{ {
if (j2->tj_status & RES_TILE_SD) if (j2->tj_status & RES_TILE_SD)
{ {
j2->tj_status &= ~RES_TILE_SD; j2->tj_status &= ~RES_TILE_SD;
STACKPUSH((ClientData) tp2,resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
} }
} }
} }
/*bottom*/ /* bottom */
for(tp2= LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2)) for(tp2 = LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2))
{ {
tileJunk *j2 = (tileJunk *) tp2->ti_client; tileJunk *j2 = (tileJunk *) tp2->ti_client;
if (TiGetTopType(tp2) == t1) if (TiGetTopType(tp2) == t1)
{ {
if (j2->tj_status & RES_TILE_SD) if (j2->tj_status & RES_TILE_SD)
{ {
j2->tj_status &= ~RES_TILE_SD; j2->tj_status &= ~RES_TILE_SD;
STACKPUSH((ClientData) tp2,resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
} }
} }
} }
/*right*/ /* right */
for (tp2= TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2)) for (tp2 = TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2))
{ {
tileJunk *j2 = (tileJunk *) tp2->ti_client; tileJunk *j2 = (tileJunk *) tp2->ti_client;
if (TiGetLeftType(tp2) == t1) if (TiGetLeftType(tp2) == t1)
{ {
if (j2->tj_status & RES_TILE_SD) if (j2->tj_status & RES_TILE_SD)
{ {
j2->tj_status &= ~RES_TILE_SD; j2->tj_status &= ~RES_TILE_SD;
STACKPUSH((ClientData) tp2,resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
} }
} }
} }
/*left*/ /* left */
for (tp2= BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2)) for (tp2 = BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2))
{ {
tileJunk *j2 = (tileJunk *) tp2->ti_client; tileJunk *j2 = (tileJunk *) tp2->ti_client;
if (TiGetRightType(tp2) == t1) if (TiGetRightType(tp2) == t1)
{ {
if (j2->tj_status & RES_TILE_SD) if (j2->tj_status & RES_TILE_SD)
{ {
j2->tj_status &= ~RES_TILE_SD; j2->tj_status &= ~RES_TILE_SD;
STACKPUSH((ClientData) tp2,resDevStack); STACKPUSH((ClientData)tp2, resDevStack);
} }
} }
} }
@ -529,24 +540,24 @@ ResAddPlumbing(tile, arg)
int int
ResRemovePlumbing(tile, arg) ResRemovePlumbing(tile, arg)
Tile *tile; Tile *tile;
ClientData *arg; ClientData *arg;
{ {
if (tile->ti_client != (ClientData) CLIENTDEFAULT) if (tile->ti_client != (ClientData) CLIENTDEFAULT)
{ {
freeMagic(((char *)(tile->ti_client))); freeMagic(((char *)(tile->ti_client)));
tile->ti_client = (ClientData) CLIENTDEFAULT; tile->ti_client = (ClientData) CLIENTDEFAULT;
} }
return(0); return(0);
} }
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
* ResPreprocessDevices-- Given a list of all the device tiles and * ResPreProcessDevices-- Given a list of all the device tiles and
* a list of all the devices, 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
@ -604,8 +615,9 @@ ResPreProcessDevices(TileList, DeviceList, Def)
tt = TiGetType(tile); tt = TiGetType(tile);
tstruct = (tileJunk *) tile->ti_client; tstruct = (tileJunk *) tile->ti_client;
if (!TTMaskHasType(&ExtCurStyle->exts_deviceMask, tt) || if ((tstruct == (tileJunk *)CLIENTDEFAULT) ||
tstruct->deviceList == NULL) (tstruct->deviceList == NULL) ||
!TTMaskHasType(&ExtCurStyle->exts_deviceMask, tt))
{ {
TxError("Bad Device 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,
@ -627,7 +639,7 @@ ResPreProcessDevices(TileList, DeviceList, Def)
freeMagic((char *)oldTile); freeMagic((char *)oldTile);
} }
for(; DeviceList != NULL;DeviceList = DeviceList->rd_nextDev) for (; DeviceList != NULL; DeviceList = DeviceList->rd_nextDev)
{ {
int width = DeviceList->rd_perim; int width = DeviceList->rd_perim;
int length = DeviceList->rd_length; int length = DeviceList->rd_length;
@ -666,18 +678,17 @@ ResPreProcessDevices(TileList, DeviceList, Def)
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
void void
ResAddToQueue(node,list) ResAddToQueue(node, list)
resNode *node,**list; resNode *node, **list;
{ {
node->rn_more = *list;
node->rn_more = *list; node->rn_less = NULL;
node->rn_less = NULL; if (*list) (*list)->rn_less = node;
if (*list) (*list)->rn_less = node; *list = node;
*list = node;
} }
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
@ -692,44 +703,42 @@ ResAddToQueue(node,list)
*/ */
void void
ResRemoveFromQueue(node,list) ResRemoveFromQueue(node, list)
resNode *node,**list; resNode *node, **list;
{ {
if (node->rn_less != NULL)
if (node->rn_less != NULL) {
{ node->rn_less->rn_more = node->rn_more;
node->rn_less->rn_more = node->rn_more; }
} else
else {
{ if (node != (*list))
if (node != (*list)) {
{ TxError("Error: Attempt to remove node from wrong list\n");
TxError("Error: Attempt to remove node from wrong list\n"); }
} else
else {
{ *list = node->rn_more;
*list = node->rn_more; }
} }
} if (node->rn_more != NULL)
if (node->rn_more != NULL) {
{ node->rn_more->rn_less = node->rn_less;
node->rn_more->rn_less = node->rn_less; }
} node->rn_more = NULL;
node->rn_more = NULL; node->rn_less = NULL;
node->rn_less = NULL;
} }
tileJunk * tileJunk *
resAddField(tile) resAddField(tile)
Tile *tile; Tile *tile;
{ {
tileJunk *Junk; tileJunk *Junk;
if ((Junk=(tileJunk *)tile->ti_client) == (tileJunk *) CLIENTDEFAULT) if ((Junk = (tileJunk *)tile->ti_client) == (tileJunk *) CLIENTDEFAULT)
{ {
Junk = (tileJunk *) mallocMagic((unsigned) (sizeof(tileJunk))); Junk = (tileJunk *) mallocMagic((unsigned) (sizeof(tileJunk)));
ResJunkInit(Junk); ResJunkInit(Junk);
tile->ti_client = (ClientData) Junk; tile->ti_client = (ClientData) Junk;
} }
return Junk; return Junk;
} }

View File

@ -47,78 +47,76 @@ ResPrintNetwork(filename, reslist)
resResistor *reslist; resResistor *reslist;
{ {
char bigname[255],name1[255],name2[255]; char bigname[255], name1[255], name2[255];
FILE *fp; FILE *fp;
int i=1; int i = 1;
sprintf(bigname,"%s.%s",filename,"res"); sprintf(bigname, "%s.%s", filename, "res");
fp = fopen(bigname,"w"); fp = fopen(bigname, "w");
if (fp != NULL) if (fp != NULL)
{ {
for (;reslist;reslist=reslist->rr_nextResistor) for (; reslist; reslist = reslist->rr_nextResistor)
{ {
if (reslist->rr_connection1->rn_id == 0) if (reslist->rr_connection1->rn_id == 0)
{ {
reslist->rr_connection1->rn_id = i++; reslist->rr_connection1->rn_id = i++;
} }
if (reslist->rr_connection2->rn_id == 0) if (reslist->rr_connection2->rn_id == 0)
{ {
reslist->rr_connection2->rn_id = i++; reslist->rr_connection2->rn_id = i++;
} }
if (reslist->rr_connection1->rn_why == RES_NODE_ORIGIN) if (reslist->rr_connection1->rn_why == RES_NODE_ORIGIN)
{ {
sprintf(name1,"gnd"); sprintf(name1, "gnd");
} }
else else
{ {
sprintf(name1,"n%d_%d_%d", sprintf(name1, "n%d_%d_%d",
reslist->rr_connection1->rn_id, reslist->rr_connection1->rn_id,
reslist->rr_connection1->rn_loc.p_x, reslist->rr_connection1->rn_loc.p_x,
reslist->rr_connection1->rn_loc.p_y); reslist->rr_connection1->rn_loc.p_y);
} }
if (reslist->rr_connection2->rn_why == RES_NODE_ORIGIN) if (reslist->rr_connection2->rn_why == RES_NODE_ORIGIN)
{ {
sprintf(name2,"gnd"); sprintf(name2,"gnd");
} }
else else
{ {
sprintf(name2,"n%d_%d_%d", sprintf(name2, "n%d_%d_%d",
reslist->rr_connection2->rn_id, reslist->rr_connection2->rn_id,
reslist->rr_connection2->rn_loc.p_x, reslist->rr_connection2->rn_loc.p_x,
reslist->rr_connection2->rn_loc.p_y); reslist->rr_connection2->rn_loc.p_y);
} }
fprintf(fp,"r %s %s %f\n",name1,name2, fprintf(fp, "r %s %s %f\n", name1, name2,
(float)(reslist->rr_value)*MILLITOKILO); (float)(reslist->rr_value) * MILLITOKILO);
} }
} }
fclose(fp); fclose(fp);
} }
void void
ResPrintCurrents(filename,extension,node) ResPrintCurrents(filename, extension, node)
char *filename; char *filename;
float extension; float extension;
resNode *node; resNode *node;
{ {
char bigname[255]; char bigname[255];
FILE *fp; FILE *fp;
int resCurrentPrintFunc(); int resCurrentPrintFunc();
sprintf(bigname,"%s.%d",filename,abs((int)(extension))); sprintf(bigname, "%s.%d", filename, abs((int)(extension)));
fp = fopen(bigname,"w"); fp = fopen(bigname, "w");
if (fp != NULL) if (fp != NULL)
{ {
(void) ResTreeWalk(node,NULL,resCurrentPrintFunc, (void) ResTreeWalk(node, NULL, resCurrentPrintFunc,
RES_DO_FIRST,RES_NO_LOOP,RES_NO_FLAGS,fp); RES_DO_FIRST, RES_NO_LOOP, RES_NO_FLAGS, fp);
} }
fclose(fp); fclose(fp);
} }
/* /*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
* *
@ -130,100 +128,98 @@ ResPrintCurrents(filename,extension,node)
*/ */
void void
resCurrentPrintFunc(node,resistor,filename) resCurrentPrintFunc(node, resistor, filename)
resNode *node; resNode *node;
resResistor *resistor; resResistor *resistor;
FILE *filename; FILE *filename;
{ {
tElement *workingDev; tElement *workingDev;
float i_sum=0.0; float i_sum = 0.0;
for (workingDev = node->rn_te; workingDev != NULL; for (workingDev = node->rn_te; workingDev != NULL;
workingDev=workingDev->te_nextt) workingDev = workingDev->te_nextt)
{ {
if ((workingDev->te_thist->rd_status & RES_DEV_PLUG) || if ((workingDev->te_thist->rd_status & RES_DEV_PLUG) ||
workingDev->te_thist->rd_gate != node) workingDev->te_thist->rd_gate != node)
i_sum += workingDev->te_thist->rd_i; i_sum += workingDev->te_thist->rd_i;
} }
if (i_sum != 0.0) if (i_sum != 0.0)
{ {
if (node->rn_why == RES_NODE_ORIGIN) if (node->rn_why == RES_NODE_ORIGIN)
{ {
fprintf(filename,"i gnd %f\n",i_sum); fprintf(filename, "i gnd %f\n", i_sum);
}
} else
else {
{ fprintf(filename, "i n%d_%d %f\n", node->rn_loc.p_x,
fprintf(filename,"i n%d_%d %f\n",node->rn_loc.p_x, node->rn_loc.p_y, i_sum);
node->rn_loc.p_y,i_sum); }
} }
}
} }
void void
ResDeviceCounts() ResDeviceCounts()
{ {
int i,j,k; int i,j,k;
resNode *n; resNode *n;
resDevice *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=ResDevList,j=0;t!=NULL;t=t->rd_nextDev,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();
} }
void void
ResWriteECLFile(filename,reslist,nodelist) ResWriteECLFile(filename, reslist, nodelist)
char *filename; char *filename;
resResistor *reslist; resResistor *reslist;
resNode *nodelist; resNode *nodelist;
{ {
char newname[100],*tmpname,*per; char newname[100], *tmpname, *per;
FILE *fp; FILE *fp;
int nodenum = 0; int nodenum = 0;
strcpy(newname,filename); strcpy(newname, filename);
if (per = strrchr(newname,'.')) *per = '\0'; if (per = strrchr(newname,'.')) *per = '\0';
strcat(newname,".res"); strcat(newname, ".res");
if ((fp = fopen(newname,"w")) == NULL) if ((fp = fopen(newname, "w")) == NULL)
{ {
TxError("Can't open %s\n",newname); TxError("Can't open %s\n", newname);
return; return;
} }
for (;nodelist;nodelist=nodelist->rn_more) for (; nodelist; nodelist = nodelist->rn_more)
{ {
if (nodelist->rn_name == NULL) if (nodelist->rn_name == NULL)
{ {
if (nodelist->rn_noderes == 0) if (nodelist->rn_noderes == 0)
{ {
strcpy(newname,"gnd"); strcpy(newname, "gnd");
} }
else else
{ {
(void)sprintf(newname,"n%d_%d_%d",nodelist->rn_loc.p_x, (void)sprintf(newname, "n%d_%d_%d", nodelist->rn_loc.p_x,
nodelist->rn_loc.p_y,nodenum++); nodelist->rn_loc.p_y, nodenum++);
} }
tmpname = (char *) mallocMagic((unsigned) (strlen(newname)+1)); tmpname = (char *)mallocMagic((unsigned) (strlen(newname) + 1));
strcpy(tmpname,newname); strcpy(tmpname, newname);
nodelist->rn_name = tmpname; nodelist->rn_name = tmpname;
} }
} }
for (;reslist;reslist = reslist->rr_nextResistor) for (; reslist; reslist = reslist->rr_nextResistor)
{ {
fprintf(fp, "r %s %s %f %s %d\n",
fprintf(fp,"r %s %s %f %s %d\n", reslist->rr_node[0]->rn_name,
reslist->rr_node[0]->rn_name,reslist->rr_node[1]->rn_name, reslist->rr_node[1]->rn_name,
/* /1000.0 gets ohms from milliohms */ /* /1000.0 gets ohms from milliohms */
(float)(reslist->rr_value)/1000.0, (float)(reslist->rr_value) / 1000.0,
DBTypeShortName(reslist->rr_tt),reslist->rr_csArea); DBTypeShortName(reslist->rr_tt), reslist->rr_csArea);
} }
fclose(fp); fclose(fp);
} }

View File

@ -247,6 +247,7 @@ typedef struct resdevtile
struct resdevtile *nextDev; struct resdevtile *nextDev;
Rect area; Rect area;
TileType type; TileType type;
ExtDevice *devptr;
int perim; int perim;
int overlap; int overlap;
} ResDevTile; } ResDevTile;
@ -297,7 +298,8 @@ typedef struct rdev
Point location; /* Location of lower left point of */ Point location; /* Location of lower left point of */
/* device. */ /* device. */
float resistance; /* "Resistance" of device. */ float resistance; /* "Resistance" of device. */
int rs_ttype; /* device type */ TileType rs_ttype; /* tile type for device */
ExtDevice *rs_devptr; /* device extraction record */
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;
@ -512,6 +514,7 @@ typedef struct capval
#define RIGHTEDGE 4 #define RIGHTEDGE 4
#define TOPEDGE 8 #define TOPEDGE 8
#define BOTTOMEDGE 16 #define BOTTOMEDGE 16
#define OTHERPLANE 32
#define RN_MAXTDI 0x00001000 #define RN_MAXTDI 0x00001000

View File

@ -190,7 +190,8 @@ extern int GeoRectPointSide(Rect *, Point *);
extern int GeoRectRectSide(Rect *, Rect *); extern int GeoRectRectSide(Rect *, Rect *);
extern void GeoIncludePoint(Point *, Rect *); extern void GeoIncludePoint(Point *, Rect *);
extern void GeoDecomposeTransform(Transform *, bool *, int *); extern void GeoDecomposeTransform(Transform *, bool *, int *);
extern void GeoIncludeRectInBBox(Rect *, Rect *bbox); extern void GeoIncludeRectInBBox(Rect *, Rect *);
extern void GeoCanonicalRect(Rect *, Rect *);
/* /*
*------------------------------------------------------------------- *-------------------------------------------------------------------

View File

@ -417,11 +417,12 @@ HeapAdd(heap, pKey, id)
{ {
/* If odd then new entry is the right half of a pair */ /* If odd then new entry is the right half of a pair */
cmp = i; cmp = i;
if (i & 1) if ((i & 1) && (i != 1))
KEY_LE_COND(keyType, list, i, i-1, cmp = i-1); KEY_LE_COND(keyType, list, i, i-1, cmp = i-1);
/* Find parent. If 0 then at the root so quit */ /* Find parent. If 0 then at the root so quit */
if ((i >>= 1) == 0) return; if ((i >>= 1) == 0) return;
KEY_LE_COND(keyType, list, cmp, i, return); KEY_LE_COND(keyType, list, cmp, i, return);
list[0] = list[cmp]; list[cmp] = list[i]; list[i] = list[0]; list[0] = list[cmp]; list[cmp] = list[i]; list[i] = list[0];
heapify(heap, cmp); heapify(heap, cmp);
@ -434,11 +435,12 @@ HeapAdd(heap, pKey, id)
{ {
/* If odd then new entry is the right half of a pair */ /* If odd then new entry is the right half of a pair */
cmp = i; cmp = i;
if (i & 1) if ((i & 1) && (i != 1))
KEY_GE_COND(keyType, list, i, i-1, cmp = i-1); KEY_GE_COND(keyType, list, i, i-1, cmp = i-1);
/* Find parent. If 0 then at the root so quit */ /* Find parent. If 0 then at the root so quit */
if ((i >>= 1) == 0) return; if ((i >>= 1) == 0) return;
KEY_GE_COND(keyType, list, cmp, i, return); KEY_GE_COND(keyType, list, cmp, i, return);
list[0] = list[cmp]; list[cmp] = list[i]; list[i] = list[0]; list[0] = list[cmp]; list[cmp] = list[i]; list[i] = list[0];
heapify(heap, cmp); heapify(heap, cmp);

View File

@ -50,6 +50,7 @@ static __inline__ int IHashAlignedSize(int size)
int result; int result;
/* Expand size to be double-word (64 bit) aligned */ /* Expand size to be double-word (64 bit) aligned */
result = ((size + 7) / 8) * 8; result = ((size + 7) / 8) * 8;
return result;
} }
/* The IHashTable struct should not be manipulated directly by clients */ /* The IHashTable struct should not be manipulated directly by clients */

View File

@ -149,7 +149,7 @@ TechSectionGetMask(sectionName, depend)
{ {
invid |= tsp->ts_thisSect; invid |= tsp->ts_thisSect;
if (tsp->ts_prevSects & thissect->ts_thisSect) if (tsp->ts_prevSects & thissect->ts_thisSect)
if (depend != NULL) *depend != tsp->ts_thisSect; if (depend != NULL) *depend = tsp->ts_thisSect;
} }
} }
return invid; return invid;

View File

@ -49,6 +49,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header$";
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <ctype.h> /* for isalnum() */
#include "utils/magic.h" #include "utils/magic.h"
#include "utils/geometry.h" #include "utils/geometry.h"