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)
{
READI2(propAttrType);
if (propAttrType == CALMA_PROP_USENAME)
if (propAttrType == CALMA_PROP_USENAME ||
propAttrType == CALMA_PROP_USENAME_STD)
{
char *s;
@ -1262,7 +1263,19 @@ calmaFindCell(name, was_called, predefined)
if (was_called) *was_called = FALSE;
}
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);
}

View File

@ -46,6 +46,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "textio/textio.h"
#include "calma/calmaInt.h"
#include "commands/commands.h" /* for CmdGetRootPoint */
#include "utils/main.h" /* for EditCellUse */
#include "utils/undo.h"
/* Globals for Calma reading */
@ -164,6 +165,12 @@ CalmaReadFile(file, filename)
static int skipBeforeLib[] = { CALMA_LIBDIRSIZE, CALMA_SRFNAME,
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 */
CIFReadCellInit(0);

View File

@ -26,6 +26,7 @@ static char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic-8.0/c
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <arpa/inet.h> /* for htons() */
#ifdef SYSV
#include <time.h>
#else
@ -146,6 +147,7 @@ int calmaPaintLayerType;
*/
HashTable calmaLibHash;
HashTable calmaPrefixHash;
HashTable calmaUndefHash;
/* Imports */
extern time_t time();
@ -285,6 +287,8 @@ CalmaWrite(rootDef, f)
int oldCount = DBWFeedbackCount, problems;
bool good;
CellUse dummy;
HashEntry *he;
HashSearch hs;
/*
* Do not attempt to write anything if a CIF/GDS output style
@ -298,6 +302,7 @@ CalmaWrite(rootDef, f)
HashInit(&calmaLibHash, 32, 0);
HashInit(&calmaPrefixHash, 32, 0);
HashInit(&calmaUndefHash, 32, 0);
/*
* 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
* 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 */
calmaOutRH(4, CALMA_ENDLIB, CALMA_NODATA, f);
@ -355,6 +384,7 @@ CalmaWrite(rootDef, f)
HashFreeKill(&calmaLibHash);
HashKill(&calmaPrefixHash);
HashFreeKill(&calmaUndefHash);
return (good);
}
@ -409,14 +439,47 @@ calmaDumpStructure(def, outf, calmaDefHash, filename)
calmaOutDate(def->cd_timestamp, outf);
calmaOutDate(time((time_t *) 0), outf);
/* Find the structure's unique prefix, in case structure calls subcells */
/* that are not yet defined. */
/* Do a quick check of the calmaUndefHash table to see if this cell */
/* was previously used in a GDS file that does not define it (a GDS */
/* addendum library). */
he2 = HashFind(&calmaLibHash, filename);
if (he2 == NULL)
TxError("Fatal error: Library %s not recorded!\n", filename);
he = HashLookOnly(&calmaUndefHash, strname);
if (he != NULL)
{
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
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 */
he = HashFind(calmaDefHash, strname);
@ -456,16 +519,20 @@ calmaDumpStructure(def, outf, calmaDefHash, filename)
if (edef != NULL)
{
bool isAbstract, isReadOnly;
char *chklibname, *dotptr;
char *chklibname, *filenamesubbed = NULL;
/* Is view abstract? */
DBPropGet(edef, "LEFview", &isAbstract);
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 && !strcmp(filename, chklibname))
if (isAbstract && isReadOnly)
{
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 */
/* as having been written to GDS. */
@ -487,7 +554,7 @@ calmaDumpStructure(def, outf, calmaDefHash, filename)
HashSetValue(he, (char *)newnameptr);
}
}
if (dotptr) *dotptr = '.';
if (filenamesubbed) freeMagic(filenamesubbed);
}
else
{
@ -614,11 +681,12 @@ calmaFullDump(def, fi, outf, filename)
char *filename;
{
int version, rval;
char *libname = NULL, uniqlibname[4];
char *libname = NULL, *testlib, uniqlibname[4];
char *sptr, *viewopts;
bool isAbstract;
HashTable calmaDefHash;
HashEntry *he;
HashSearch hs;
HashEntry *he, *he2;
static int hdrSkip[] = { CALMA_FORMAT, CALMA_MASK, CALMA_ENDMASKS,
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.
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",
* then do not create a unique prefix for subcells. This is generally
@ -672,8 +745,6 @@ calmaFullDump(def, fi, outf, filename)
*/
while (TRUE)
{
HashEntry *he2;
rval = random() % 26;
rval = 'A' + rval;
uniqlibname[0] = (char)(rval & 127);
@ -700,6 +771,24 @@ calmaFullDump(def, fi, outf, filename)
calmaSkipExact(CALMA_ENDLIB);
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);
if (libname != NULL) freeMagic(libname);
return;
@ -1346,7 +1435,7 @@ calmaWriteUseFunc(use, f)
if (!calmaIsUseNameDefault(use->cu_def->cd_name, use->cu_id))
{
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);
}

View File

@ -99,6 +99,7 @@
#define CALMA_NUMRECORDTYPES 60 /* Number of above types */
/* 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_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);
break;
}
cifPlane = curPlane;
cifScale = (CIFCurStyle) ? CIFCurStyle->cs_scaleFactor : 1;
bbox.r_xbot *= cifScale;
bbox.r_xtop *= cifScale;
bbox.r_ybot *= cifScale;
bbox.r_ytop *= cifScale;
cifScale = 1;
DBNMPaintPlane(cifPlane, CIF_SOLIDTYPE, &bbox,
DBNMPaintPlane(curPlane, CIF_SOLIDTYPE, &bbox,
CIFPaintTable, (PaintUndoInfo *)NULL);
for (j = 0; j < 4; j++)
{

View File

@ -911,6 +911,52 @@ CIFGenSubcells(def, area, output)
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;
CellUse *use;
int radius, xsep, ysep, xsize, ysize, nx, ny, i, oldTileOps;
int xhi, yhi;
bool anyInteractions = FALSE;
use = scx->scx_use;
@ -1147,17 +1192,9 @@ cifHierArrayFunc(scx, output)
if ((use->cu_xlo == use->cu_xhi) && (use->cu_ylo == use->cu_yhi))
return 2;
/* We only want interactions between neighboring cells, so reduce */
/* the array size to at most 2x2, process, then restore the */
/* original array count. */
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);
/* We only want interactions between neighboring cells, so only */
/* look at the bottom-left 2x2 set when calculating A and B, and */
/* only look at the top-right 2x2 set when calculating C and D. */
/* Compute the sizes and separations of elements, in coordinates
* 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
* area than we check, in order to include material that will be
* 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 */
@ -1211,7 +1254,7 @@ cifHierArrayFunc(scx, output)
A.r_ybot = use->cu_bbox.r_ybot + ysep - radius;
A.r_ytop = use->cu_bbox.r_ybot + ysize + radius;
GEO_EXPAND(&A, CIFCurStyle->cs_radius, &expandedArea);
(void) DBArraySr(use, &expandedArea, cifHierElementFunc,
(void) DBArraySr(use, &expandedArea, cifHierElementFuncLow,
(ClientData) &A);
CIFErrorDef = use->cu_parent;
CIFGen(CIFTotalDef, use->cu_def, &A, CIFTotalPlanes,
@ -1220,24 +1263,6 @@ cifHierArrayFunc(scx, output)
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))
{
/* B */
@ -1247,31 +1272,16 @@ cifHierArrayFunc(scx, output)
B.r_ybot = use->cu_bbox.r_ybot - radius;
B.r_ytop = use->cu_bbox.r_ybot + ysep - radius;
GEO_EXPAND(&B, CIFCurStyle->cs_radius, &expandedArea);
(void) DBArraySr(use, &expandedArea, cifHierElementFunc,
(void) DBArraySr(use, &expandedArea, cifHierElementFuncLow,
(ClientData) &B);
CIFErrorDef = use->cu_parent;
CIFGen(CIFTotalDef, use->cu_def, &B, CIFTotalPlanes,
&CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE,
(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)
{
/* Remove redundant CIF that's already in the children, and
* make sure everything in the kids is in the parent too.
*/
@ -1308,6 +1318,155 @@ cifHierArrayFunc(scx, output)
(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). */
if ((nx > 1) && (xsep < xsize + radius))
@ -1325,17 +1484,6 @@ cifHierArrayFunc(scx, output)
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 right edge of the array (from D). */
cifHierXSpacing = 0;
@ -1346,36 +1494,12 @@ cifHierArrayFunc(scx, output)
(void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i],
&cifArea, &CIFSolidBits, cifHierPaintArrayFunc,
(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;
}
cifHierCleanup();
/* Restore the array bounds of the array */
use->cu_xhi = xhi;
use->cu_yhi = yhi;
return 2;
}

View File

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

View File

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

View File

@ -1612,8 +1612,9 @@ DBCellLookDef(cellName)
{
HashEntry *entry;
entry = HashFind(&dbCellDefTable, cellName);
return ((CellDef *) HashGetValue(entry));
entry = HashLookOnly(&dbCellDefTable, cellName);
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 DBTechFinalConnect();
extern void DBTechInitConnect();
extern bool DBIsContact();
/* Cell symbol table */
extern void DBCellInit();

View File

@ -326,6 +326,7 @@ DBWloadWindow(window, name, flags)
{
deleteDef = ((CellUse *)window->w_surfaceID)->cu_def;
if (strcmp(deleteDef->cd_name, "(UNNAMED)") ||
(GrDisplayStatus == DISPLAY_SUSPEND) ||
deleteDef->cd_flags & (CDMODIFIED|CDBOXESCHANGED|CDSTAMPSCHANGED))
deleteDef = NULL;
}
@ -497,7 +498,7 @@ DBWloadWindow(window, name, flags)
if (newEdit)
{
if (EditCellUse && EditRootDef)
if ((EditCellUse && EditRootDef) && (deleteDef == NULL))
{
DBWUndoOldEdit(EditCellUse, EditRootDef,
&EditToRootTransform, &RootToEditTransform);
@ -549,6 +550,11 @@ DBWloadWindow(window, name, flags)
/* If the cell before loading was (UNNAMED) and it was */
/* 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)
DBCellDelete(deleteDef->cd_name, TRUE);
}

View File

@ -613,6 +613,14 @@ drcCifTile (tile, arg)
if (SigInterruptPending) return 1;
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.
*
@ -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.

View File

@ -1836,6 +1836,7 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
bool needtrigger = FALSE;
bool touchingok = TRUE;
bool cornerok = FALSE;
bool surroundok = FALSE;
if (!strcmp(adjacency, "surround_ok"))
{
@ -1858,6 +1859,7 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
needtrigger = TRUE;
touchingok = FALSE;
needReverse = TRUE;
surroundok = TRUE;
}
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
* 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);

View File

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

View File

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

View File

@ -79,7 +79,7 @@ int esNoModelType; /* index for device type "None" (model-less device) */
HashTable subcktNameTable ; /* the hash table itself */
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 */
@ -90,7 +90,7 @@ typedef struct GLL {
char *gll_name;
} 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 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
the command line arguments */
for ( i = 0 ; i < MAXDEVTYPES ; i++ ) {
for ( i = 0 ; i < TT_MAXTYPES ; i++ ) {
esFetInfo[i].resClassSource = NO_RESCLASS;
esFetInfo[i].resClassDrain = NO_RESCLASS;
esFetInfo[i].resClassSub = NO_RESCLASS;
@ -743,12 +743,12 @@ runexttospice:
while (ExtGetDevInfo(idx++, &devname, &devtype, &s_rclass, &d_rclass,
&sub_rclass, &subname))
{
if (idx == MAXDEVTYPES)
if (idx == TT_MAXTYPES)
{
TxError("Error: Ran out of space for device types!\n");
break;
}
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, devname);
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, TT_MAXTYPES, devname);
if (!strcmp(devname, "None"))
esNoModelType = i;
if (EFStyle != NULL)
@ -908,7 +908,9 @@ runexttospice:
if (!esDoPorts)
EFVisitSubcircuits(subcktUndef, (ClientData) NULL);
initMask = ( esDistrJunct ) ? (unsigned long)0 : DEV_CONNECT_MASK;
TTMaskZero(&initMask);
if (!esDistrJunct)
TTMaskCom(&initMask);
if (esMergeDevsA || esMergeDevsC)
{
@ -924,7 +926,7 @@ runexttospice:
else if (esDistrJunct)
EFVisitDevs(devDistJunctVisit, (ClientData) NULL);
EFVisitDevs(spcdevVisit, (ClientData) NULL);
initMask = (unsigned long) 0;
TTMaskZero(&initMask);
if (flatFlags & EF_FLATCAPS)
{
(void) sprintf( esSpiceCapFormat, "C%%d %%s %%s %%.%dlffF\n",
@ -994,25 +996,25 @@ main(argc, argv)
EFResistThreshold = INFINITE_THRESHOLD ;
/* create default devinfo entries (MOSIS) which can be overriden by
the command line arguments */
for ( i = 0 ; i < MAXDEVTYPES ; i++ ) {
for ( i = 0 ; i < TT_MAXTYPES ; i++ ) {
esFetInfo[i].resClassSource = NO_RESCLASS;
esFetInfo[i].resClassDrain = NO_RESCLASS;
esFetInfo[i].resClassSub = NO_RESCLASS;
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].resClassSub = NO_RESCLASS ;
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].resClassSub = 8 ;
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].resClassSub = NO_RESCLASS ;
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].resClassSub = 8 ;
esFetInfo[i].defSubs = "Vdd!";
@ -1078,7 +1080,9 @@ main(argc, argv)
if (!esDoPorts)
EFVisitSubcircuits(subcktUndef, (ClientData) NULL);
initMask = ( esDistrJunct ) ? (unsigned long)0 : DEV_CONNECT_MASK ;
TTMaskZero(&initMask);
if (!esDistrJunct)
TTMaskCom(&initMask);
if ( esMergeDevsA || esMergeDevsC ) {
EFVisitDevs(devMergeVisit, (ClientData) NULL);
@ -1092,7 +1096,7 @@ main(argc, argv)
} else if ( esDistrJunct )
EFVisitDevs(devDistJunctVisit, (ClientData) NULL);
EFVisitDevs(spcdevVisit, (ClientData) NULL);
initMask = (unsigned long) 0;
TTMaskZero(&initMask);
if (flatFlags & EF_FLATCAPS) {
(void) sprintf( esSpiceCapFormat, "C%%d %%s %%s %%.%dlffF\n",esCapAccuracy);
EFVisitCaps(spccapVisit, (ClientData) NULL);
@ -1240,17 +1244,9 @@ spcmainArgs(pargc, pargv)
rClassSub = -1 ;
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].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));
strcpy(esFetInfo[ndx].defSubs,subsNode);
TxError("info: dev %s(%d) srcRclass=%d drnRclass=%d subRclass=%d dSub=%s\n",
@ -2910,8 +2906,10 @@ FILE *outf;
initNodeClientHier(nn->efnn_node);
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;
}
}
@ -3126,7 +3124,10 @@ spcdevOutNode(prefix, suffix, name, outf)
/* Mark node as visited */
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));
}
@ -3279,8 +3280,7 @@ spcnodeVisit(node, res, cap)
{
isConnected = (esDistrJunct) ?
(((nodeClient *)node->efnode_client)->m_w.widths != NULL) :
((((nodeClient *)node->efnode_client)->m_w.visitMask
& DEV_CONNECT_MASK) != 0);
(!TTMaskIsZero(&((nodeClient *)node->efnode_client)->m_w.visitMask));
}
if (!isConnected && esDevNodesOnly)
return 0;

View File

@ -60,7 +60,7 @@ extern FILE *esSpiceF;
extern float esScale; /* negative if hspice the EFScale/100 otherwise */
extern unsigned short esFormat;
extern unsigned long initMask;
extern TileTypeBitMask initMask;
extern int esCapNum, esDevNum, esResNum, esDiodeNum;
extern int esNodeNum; /* just in case we're extracting spice2 */
@ -96,19 +96,15 @@ typedef struct {
char *defSubs ; /* the default substrate node */
} fetInfoList;
extern fetInfoList esFetInfo[MAXDEVTYPES];
extern fetInfoList esFetInfo[TT_MAXTYPES];
#define MAX_STR_SIZE (1<<11) /* 2K should be enough for keeping temp
names even of the most complicated design */
/* 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 {
long visitMask; /* mask for normal visits */
TileTypeBitMask visitMask; /* mask for normal visits */
float *widths; /* width used for distributing area perim */
} maskOrWidth ;
@ -125,32 +121,27 @@ typedef struct {
#define NO_RESCLASS -1
#define markVisited(client, rclass) \
{ (client)->m_w.visitMask |= (1<<rclass); }
{ TTMaskSetType(&((client)->m_w.visitMask), rclass); }
#define clearVisited(client) \
{ (client)->m_w.visitMask = (long)0; }
{ TTMaskZero(&((client)->m_w.visitMask)); }
#define beenVisited(client, rclass) \
( (client)->m_w.visitMask & (1<<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))
( TTMaskHasType(&((client)->m_w.visitMask), rclass) )
#define initNodeClient(node) \
{ \
(node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClient))); \
(( nodeClient *)(node)->efnode_client)->spiceNodeName = NULL; \
(( nodeClient *)(node)->efnode_client)->m_w.visitMask = (unsigned long)initMask; \
(( nodeClient *)(node)->efnode_client)->spiceNodeName = NULL; \
TTMaskZero (&((nodeClient *) (node)->efnode_client)->m_w.visitMask); \
TTMaskSetMask(&(((nodeClient *)(node)->efnode_client)->m_w.visitMask), &initMask);\
}
#define initNodeClientHier(node) \
{ \
(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();
typedef struct {
long visitMask:MAXDEVTYPES;
TileTypeBitMask visitMask;
} nodeClient;
typedef struct {
HierName *lastPrefix;
long visitMask:MAXDEVTYPES;
TileTypeBitMask visitMask;
} nodeClientHier;
#define NO_RESCLASS -1
#define markVisited(client, rclass) \
{ (client)->visitMask |= (1<<rclass); }
{ TTMaskSetType(&((client)->visitMask), rclass); }
#define clearVisited(client) \
{ (client)->visitMask = (long)0; }
{ TTMaskZero(&((client)->visitMask); }
#define beenVisited(client, rclass) \
( (client)->visitMask & (1<<rclass))
( TTMaskHasType(&((client)->visitMask), rclass) )
#define initNodeClient(node) \
{ \
(node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClient))); \
(( nodeClient *)(node)->efnode_client)->visitMask = (long) 0; \
TTMaskZero(&(( nodeClient *)(node)->efnode_client)->visitMask); \
}
#define initNodeClientHier(node) \
{ \
(node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClientHier))); \
((nodeClientHier *) (node)->efnode_client)->visitMask = (long) 0; \
TTMaskZero(&(( nodeClientHier *)(node)->efnode_client)->visitMask); \
}
/* Diagnostic */
@ -228,9 +228,21 @@ runantennacheck:
TxPrintf("Building flattened netlist.\n");
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 */
EFDeviceTypes = (TileType *)mallocMagic(MAXDEVTYPES * sizeof(TileType));
for (i = 0; i < MAXDEVTYPES; i++)
EFDeviceTypes = (TileType *)mallocMagic(EFDevNumTypes * sizeof(TileType));
for (i = 0; i < EFDevNumTypes; i++)
if (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/utils.h"
#include "utils/malloc.h"
#include "tiles/tile.h"
#include "database/database.h" /* for TileType definition */
#include "extflat/extflat.h"
#include "extflat/EFint.h"
#include "tiles/tile.h"
#include "extract/extract.h" /* for device class list */
/*
@ -48,7 +49,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header$";
#define MAXTYPES 100
/* Table of transistor types */
char *EFDevTypes[MAXDEVTYPES];
char *EFDevTypes[TT_MAXTYPES];
int EFDevNumTypes;
/* Table of Magic layers */
@ -656,6 +657,8 @@ efBuildDevice(def, class, type, r, argc, argv)
DevTerm *term;
Dev *newdev, devtmp;
DevParam *newparm, *devp, *sparm;
TileType ttype;
int dev_type;
char ptype, *pptr, **av;
char devhash[64];
int argstart = 1; /* start of terminal list in argv[] */
@ -799,9 +802,18 @@ efBuildDevice(def, class, type, r, argc, argv)
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);
newdev = (Dev *)HashGetValue(he);
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
* 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) ||
(strcmp(EFDevTypes[newdev->dev_type], type)))
if ((newdev->dev_class != class) || ((newdev->dev_type != dev_type)
&& (ttype != extGetDevType(EFDevTypes[newdev->dev_type]))))
{
TxError("Device %s %s at (%d, %d) overlaps incompatible device %s %s!\n",
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_rect = *r;
newdev->dev_type = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, type);
newdev->dev_type = dev_type;
newdev->dev_class = class;
switch (class)

View File

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

View File

@ -342,9 +342,6 @@ extern char *EFHNToStr();
extern int EFGetPortMax();
/* ------------------------- 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

View File

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

View File

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

View File

@ -354,54 +354,63 @@ ExtGetDevInfo(idx, devnameptr, devtypeptr, s_rclassptr, d_rclassptr,
if (t == DBNumTypes) return FALSE;
if (devptr == NULL) return FALSE;
*devnameptr = locdname;
*subnameptr = devptr->exts_deviceSubstrateName;
*devtypeptr = t;
if (devnameptr) *devnameptr = locdname;
if (subnameptr) *subnameptr = devptr->exts_deviceSubstrateName;
if (devtypeptr) *devtypeptr = t;
tmask = &devptr->exts_deviceSDTypes[0];
*s_rclassptr = (short)(-1); /* NO_RESCLASS */
for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++)
if (s_rclassptr)
{
rmask = &ExtCurStyle->exts_typesByResistClass[n];
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 */
*s_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;
*s_rclassptr = (short)n;
break;
}
}
}
tmask = &devptr->exts_deviceSubstrateTypes;
*sub_rclassptr = (short)(-1); /* NO_RESCLASS */
for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++)
if (d_rclassptr)
{
rmask = &ExtCurStyle->exts_typesByResistClass[n];
if (TTMaskIntersect(rmask, tmask))
tmask = &devptr->exts_deviceSDTypes[1];
if (TTMaskIsZero(tmask))
{
*sub_rclassptr = (short)(n);
break;
/* 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++)
{
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
* in the list is the "official" node name.
*/
int node_len; /* Number of entries in node_names */
CapValue node_cap; /* Capacitance to substrate */
PerimArea node_pa[1]; /* Dummy; each node actually has
* ExtCurStyle->exts_numResistClasses

View File

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

View File

@ -5,7 +5,7 @@
MODULE = resis
MAGICDIR = ..
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
include ${MAGICDIR}/defs.mak

View File

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

View File

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

View File

@ -26,8 +26,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "textio/txcommands.h"
#include "resis/resis.h"
/*
*-------------------------------------------------------------------------
*
@ -45,56 +43,56 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
*/
void
ResNewSDDevice(tile,tp,xj,yj,direction,PendingList)
Tile *tile,*tp;
int xj,yj,direction;
resNode **PendingList;
ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
Tile *tile, *tp;
int xj, yj, direction;
resNode **PendingList;
{
resNode *resptr;
resDevice *resDev;
tElement *tcell;
int newnode;
tileJunk *j;
resNode *resptr;
resDevice *resDev;
tElement *tcell;
int newnode;
tileJunk *j;
newnode = FALSE;
j = (tileJunk *) tp->ti_client;
resDev = j->deviceList;
if ((j->sourceEdge & direction) != 0)
newnode = FALSE;
j = (tileJunk *) tp->ti_client;
resDev = j->deviceList;
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;
resDev->rd_fet_source = resptr;
}
else
{
resptr = resDev->rd_fet_source;
}
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
newnode = TRUE;
resDev->rd_fet_source = resptr;
}
else
{
if (resDev->rd_fet_drain == (resNode *) NULL)
{
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
newnode = TRUE;
resDev->rd_fet_drain = resptr;
}
else
{
resptr = resDev->rd_fet_drain;
}
resptr = resDev->rd_fet_source;
}
if (newnode)
}
else
{
if (resDev->rd_fet_drain == (resNode *) NULL)
{
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);
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
newnode = TRUE;
resDev->rd_fet_drain = resptr;
}
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
ResProcessJunction(tile, tp, xj, yj, NodeList)
Tile *tile, *tp;
int xj,yj;
resNode **NodeList;
Tile *tile, *tp;
int xj, yj;
resNode **NodeList;
{
ResJunction *junction;
resNode *resptr;
jElement *jcell;
tileJunk *j0 = (tileJunk *)tile->ti_client;
tileJunk *j2 = (tileJunk *)tp->ti_client;
ResJunction *junction;
resNode *resptr;
jElement *jcell;
tileJunk *j0 = (tileJunk *)tile->ti_client;
tileJunk *j2 = (tileJunk *)tp->ti_client;
#ifdef PARANOID
if (tile == tp)
{
TxError("Junction being made between tile and itself \n");
return;
}
if (tile == tp)
{
TxError("Junction being made between tile and itself \n");
return;
}
#endif
if (j2->tj_status & RES_TILE_DONE) return;
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
resptr->rn_te = (tElement *) NULL;
junction = (ResJunction *) mallocMagic((unsigned)(sizeof(ResJunction)));
jcell = (jElement *) mallocMagic((unsigned)(sizeof(jElement)));
InitializeNode(resptr,xj,yj,RES_NODE_JUNCTION);
resptr->rn_je = jcell;
ResAddToQueue(resptr,NodeList);
if (j2->tj_status & RES_TILE_DONE) return;
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
resptr->rn_te = (tElement *) NULL;
junction = (ResJunction *) mallocMagic((unsigned)(sizeof(ResJunction)));
jcell = (jElement *) mallocMagic((unsigned)(sizeof(jElement)));
InitializeNode(resptr, xj, yj, RES_NODE_JUNCTION);
resptr->rn_je = jcell;
ResAddToQueue(resptr, NodeList);
jcell->je_thisj = junction;
jcell->je_nextj = NULL;
junction->rj_status = FALSE;
junction->rj_jnode = resptr;
junction->rj_Tile[0] = tile;
junction->rj_Tile[1] = tp;
junction->rj_loc.p_x =xj;
junction->rj_loc.p_y =yj;
junction->rj_nextjunction[0] = j0->junctionList;
j0->junctionList = junction;
junction->rj_nextjunction[1] = j2->junctionList;
j2->junctionList = junction;
jcell->je_thisj = junction;
jcell->je_nextj = NULL;
junction->rj_status = FALSE;
junction->rj_jnode = resptr;
junction->rj_Tile[0] = tile;
junction->rj_Tile[1] = tp;
junction->rj_loc.p_x =xj;
junction->rj_loc.p_y =yj;
junction->rj_nextjunction[0] = j0->junctionList;
j0->junctionList = junction;
junction->rj_nextjunction[1] = j2->junctionList;
j2->junctionList = junction;
NEWBREAK(junction->rj_jnode,tile,
junction->rj_loc.p_x,junction->rj_loc.p_y,NULL);
NEWBREAK(junction->rj_jnode,tile, junction->rj_loc.p_x,
junction->rj_loc.p_y, NULL);
NEWBREAK(junction->rj_jnode,tp,
junction->rj_loc.p_x,junction->rj_loc.p_y,NULL);
NEWBREAK(junction->rj_jnode,tp, junction->rj_loc.p_x,
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 "dbwind/dbwind.h"
#include "utils/tech.h"
#include "select/select.h"
#include "textio/txcommands.h"
#include "resis/resis.h"
CellUse *ResUse=NULL; /* Our use and def */
CellDef *ResDef=NULL;
CellUse *ResUse = NULL; /* Our use and def */
CellDef *ResDef = NULL;
TileTypeBitMask ResConnectWithSD[NT]; /* A mask that goes from */
/* SD's to devices. */
TileTypeBitMask ResCopyMask[NT]; /* Indicates which tiles */
/* are to be copied. */
resResistor *ResResList=NULL; /* Resistor list */
resNode *ResNodeList=NULL; /* Processed Nodes */
resDevice *ResDevList=NULL; /* Devices */
ResContactPoint *ResContactList=NULL; /* Contacts */
resNode *ResNodeQueue=NULL; /* Pending nodes */
resNode *ResOriginNode=NULL; /* node where R=0 */
resResistor *ResResList = NULL; /* Resistor list */
resNode *ResNodeList = NULL; /* Processed Nodes */
resDevice *ResDevList = NULL; /* Devices */
ResContactPoint *ResContactList = NULL; /* Contacts */
resNode *ResNodeQueue = NULL; /* Pending nodes */
resNode *ResOriginNode = NULL; /* node where R=0 */
resNode *resCurrentNode;
int ResTileCount=0; /* Number of tiles rn_status */
int ResTileCount = 0; /* Number of tiles rn_status */
extern Region *ResFirst();
extern Tile *FindStartTile();
extern int ResEachTile();
@ -45,8 +46,6 @@ extern ResSimNode *ResInitializeNode();
extern HashTable ResNodeTable;
/*
*--------------------------------------------------------------------------
*
@ -78,13 +77,13 @@ ResInitializeConn()
for (diff = TT_TECHDEPBASE; diff < TT_MAXTYPES; diff++)
{
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), diff)
TTMaskSetType(&ResConnectWithSD[diff],dev);
TTMaskSetType(&ResConnectWithSD[diff], dev);
if TTMaskHasType(&(devptr->exts_deviceSubstrateTypes),diff)
TTMaskSetType(&ResConnectWithSD[diff],dev);
if TTMaskHasType(&(devptr->exts_deviceSubstrateTypes), diff)
TTMaskSetType(&ResConnectWithSD[diff], dev);
}
}
TTMaskSetMask(&ResConnectWithSD[dev],&DBConnectTbl[dev]);
TTMaskSetMask(&ResConnectWithSD[dev], &DBConnectTbl[dev]);
}
}
@ -121,7 +120,6 @@ ResGetReCell()
ResUse = DBCellNewUse(ResDef, (char *) NULL);
DBSetTrans(ResUse, &GeoIdentityTransform);
ResUse->cu_expandMask = CU_DESCEND_SPECIAL;
}
/*
@ -172,7 +170,7 @@ ResDissolveContacts(contacts)
}
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
if (TiGetTypeExact(tp) == contacts->cp_type)
{
@ -325,46 +323,46 @@ ResAddBreakpointFunc(tile, node)
void
ResFindNewContactTiles(contacts)
ResContactPoint *contacts;
ResContactPoint *contacts;
{
int pNum;
Tile *tile;
TileTypeBitMask mask;
int pNum;
Tile *tile;
TileTypeBitMask mask;
for (; contacts != (ResContactPoint *) NULL; contacts = contacts->cp_nextcontact)
{
DBFullResidueMask(contacts->cp_type, &mask);
for (pNum=PL_TECHDEPBASE; pNum<DBNumPlanes; pNum++)
{
tile = ResDef->cd_planes[pNum]->pl_hint;
GOTOPOINT(tile, &(contacts->cp_center));
for (; contacts != (ResContactPoint *) NULL; contacts = contacts->cp_nextcontact)
{
DBFullResidueMask(contacts->cp_type, &mask);
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
{
tile = ResDef->cd_planes[pNum]->pl_hint;
GOTOPOINT(tile, &(contacts->cp_center));
#ifdef PARANOID
if (tile == (Tile *) NULL)
{
TxError("Error: setting contact tile to null\n");
}
if (tile == (Tile *) NULL)
{
TxError("Error: setting contact tile to null\n");
}
#endif
if ((IsSplit(tile) && TTMaskHasType(&mask, TiGetRightType(tile)))
if ((IsSplit(tile) && TTMaskHasType(&mask, TiGetRightType(tile)))
|| TTMaskHasType(&mask, TiGetType(tile)))
{
tileJunk *j = (tileJunk *)tile->ti_client;
cElement *ce;
{
tileJunk *j = (tileJunk *)tile->ti_client;
cElement *ce;
ce = (cElement *) mallocMagic((unsigned) (sizeof(cElement)));
contacts->cp_tile[contacts->cp_currentcontact] = tile;
ce->ce_thisc = contacts;
ce->ce_nextc = j->contactList;
(contacts->cp_currentcontact) += 1;
j->contactList = ce;
}
}
ce = (cElement *) mallocMagic((unsigned) (sizeof(cElement)));
contacts->cp_tile[contacts->cp_currentcontact] = tile;
ce->ce_thisc = contacts;
ce->ce_nextc = j->contactList;
(contacts->cp_currentcontact) += 1;
j->contactList = ce;
}
}
#ifdef PARANOID
if (contacts->cp_currentcontact > LAYERS_PER_CONTACT)
{
TxError("Error: Not enough space allocated for contact nodes\n");
}
if (contacts->cp_currentcontact > LAYERS_PER_CONTACT)
{
TxError("Error: Not enough space allocated for contact nodes\n");
}
#endif
}
}
}
/*
@ -388,78 +386,77 @@ ResProcessTiles(goodies, origin)
ResGlobalParams *goodies;
{
Tile *startTile;
int tilenum,merged;
resNode *resptr2;
jElement *workingj;
cElement *workingc;
ResFixPoint *fix;
resNode *resptr;
int (*tilefunc)();
Tile *startTile;
int tilenum, merged;
resNode *resptr2;
jElement *workingj;
cElement *workingc;
ResFixPoint *fix;
resNode *resptr;
int (*tilefunc)();
#ifdef LAPLACE
tilefunc = (ResOptionsFlags & ResOpt_DoLaplace)?ResLaplaceTile:ResEachTile;
tilefunc = (ResOptionsFlags & ResOpt_DoLaplace) ? ResLaplaceTile : ResEachTile;
#else
tilefunc = ResEachTile;
tilefunc = ResEachTile;
#endif
if (ResOptionsFlags & ResOpt_Signal)
{
startTile = FindStartTile(goodies, origin);
if (startTile == NULL) return(1);
resCurrentNode = NULL;
(void) (*tilefunc)(startTile, origin);
startTile = FindStartTile(goodies, origin);
if (startTile == NULL) return(1);
resCurrentNode = NULL;
(void) (*tilefunc)(startTile, origin);
}
#ifdef ARIEL
else if (ResOptionsFlags & ResOpt_Power)
{
for (fix = ResFixList; fix != NULL;fix=fix->fp_next)
{
Tile *tile = fix->fp_tile;
if (tile == NULL)
{
for (fix = ResFixList; fix != NULL; fix = fix->fp_next)
{
Tile *tile = fix->fp_tile;
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;
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 &
if (tile != NULL && (((tileJunk *)tile->ti_client)->tj_status &
RES_TILE_DONE) == 0)
{
resCurrentNode = fix->fp_node;
(void) (*tilefunc)(tile, (Point *)NULL);
}
}
{
resCurrentNode = fix->fp_node;
(void) (*tilefunc)(tile, (Point *)NULL);
}
}
}
#endif
#ifdef PARANOID
else
{
TxError("Unknown analysis type in ResProcessTiles\n");
TxError("Unknown analysis type in ResProcessTiles\n");
}
#endif
@ -467,103 +464,199 @@ ResProcessTiles(goodies, origin)
while (ResNodeQueue != NULL)
{
/*
* merged keeps track of whether another node gets merged into
* the current one. If it does, then the node must be processed
* because additional junctions or contacts were added
*/
/*
* merged keeps track of whether another node gets merged into
* the current one. If it does, then the node must be processed
* because additional junctions or contacts were added
*/
resptr2 = ResNodeQueue;
merged = FALSE;
resptr2 = ResNodeQueue;
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)
{
ResJunction *rj = workingj->je_thisj;
if (rj->rj_status == FALSE)
{
for (tilenum = 0; tilenum < TILES_PER_JUNCTION; tilenum++)
{
Tile *tile = rj->rj_Tile[tilenum];
tileJunk *j = (tileJunk *) tile->ti_client;
for (workingj = resptr2->rn_je; workingj != NULL; workingj = workingj->je_nextj)
{
ResJunction *rj = workingj->je_thisj;
if (rj->rj_status == FALSE)
{
for (tilenum = 0; tilenum < TILES_PER_JUNCTION; tilenum++)
{
Tile *tile = rj->rj_Tile[tilenum];
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;
merged |= (*tilefunc)(tile,(Point *)NULL);
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)
else
{
if (cp->cp_cnode[tilenum] == resptr2)
{
resCurrentNode = resptr2;
merged |= (*tilefunc)(tile,(Point *)NULL);
}
else
{
newstatus = FALSE;
}
newstatus = FALSE;
}
if (merged & ORIGIN) break;
}
if (merged & ORIGIN) break;
cp->cp_status = newstatus;
}
}
}
if (merged & ORIGIN) break;
}
if (merged & ORIGIN) break;
cp->cp_status = newstatus;
}
}
/*
* If nothing new has been added via a merge, then the node is
* finished. It is removed from the pending queue, added to the
* done list, cleaned up, and passed to ResDoneWithNode
*/
/*
* If nothing new has been added via a merge, then the node is
* finished. It is removed from the pending queue, added to the
* done list, cleaned up, and passed to ResDoneWithNode
*/
if (merged == FALSE)
{
ResRemoveFromQueue(resptr2,&ResNodeQueue);
resptr2->rn_more = ResNodeList;
resptr2->rn_less = NULL;
resptr2->rn_status &= ~PENDING;
resptr2->rn_status |= FINISHED | MARKED;
if (ResNodeList != NULL)
{
ResNodeList->rn_less = resptr2;
}
if (resptr2->rn_noderes == 0)
{
ResOriginNode=resptr2;
}
ResNodeList = resptr2;
ResCleanNode(resptr2, FALSE, &ResNodeList, &ResNodeQueue);
ResDoneWithNode(resptr2);
}
}
return(0);
if (merged == FALSE)
{
ResRemoveFromQueue(resptr2, &ResNodeQueue);
resptr2->rn_more = ResNodeList;
resptr2->rn_less = NULL;
resptr2->rn_status &= ~PENDING;
resptr2->rn_status |= FINISHED | MARKED;
if (ResNodeList != NULL)
{
ResNodeList->rn_less = resptr2;
}
if (resptr2->rn_noderes == 0)
{
ResOriginNode=resptr2;
}
ResNodeList = resptr2;
ResCleanNode(resptr2, FALSE, &ResNodeList, &ResNodeQueue);
ResDoneWithNode(resptr2);
}
}
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
* rn_loc. If the resulting net is greater than the tolerance,
@ -577,18 +670,20 @@ ResProcessTiles(goodies, origin)
*/
bool
ResExtractNet(startlist, goodies, cellname)
ResFixPoint *startlist;
ResExtractNet(node, goodies, cellname)
ResSimNode *node;
ResGlobalParams *goodies;
char *cellname;
{
SearchContext scx;
int pNum;
ResDevTile *DevTiles, *lasttile;
TileTypeBitMask FirstTileMask;
Point startpoint;
ResFixPoint *fix;
static int first = 1;
ResDevTile *DevTiles, *thisDev;
ResFixPoint *fix;
devPtr *tptr;
int resMakeDevFunc();
/* Make sure all global network variables are reset */
@ -599,18 +694,18 @@ ResExtractNet(startlist, goodies, cellname)
ResContactList = NULL;
ResOriginNode = NULL;
/* Pass back network pointers */
/* Pass back network pointers */
goodies->rg_maxres = 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)
{
ResInitializeConn();
first = 0;
ResGetReCell();
ResInitializeConn();
first = 0;
ResGetReCell();
}
/* Initialize Cell */
@ -618,7 +713,7 @@ ResExtractNet(startlist, goodies, cellname)
if (cellname)
{
CellDef *def = DBCellLookDef(cellname);
if (def == (CellDef *) NULL)
if (def == (CellDef *)NULL)
{
TxError("Error: No such cell \"%s\"\n", cellname);
return TRUE;
@ -629,8 +724,8 @@ ResExtractNet(startlist, goodies, cellname)
}
else
{
MagWindow *w = ToolGetBoxWindow(&scx.scx_area, (int *) NULL);
if (w == (MagWindow *) NULL)
MagWindow *w = ToolGetBoxWindow(&scx.scx_area, (int *)NULL);
if (w == (MagWindow *)NULL)
{
TxError("Sorry, the box must appear in one of the windows.\n");
return TRUE;
@ -641,49 +736,59 @@ ResExtractNet(startlist, goodies, cellname)
DBCellClearDef(ResUse->cu_def);
/* Copy Paint */
DevTiles = NULL;
lasttile = NULL;
for (fix = startlist; fix != NULL; fix = fix->fp_next)
{
ResDevTile *newdevtiles, *tmp;
#ifdef ARIEL
if ((ResOptionsFlags & ResOpt_Power) &&
strcmp(fix->fp_name, goodies->rg_name) != 0) continue;
if ((ResOptionsFlags & ResOpt_Power) &&
strcmp(node->name, goodies->rg_name) != 0) continue;
#endif
scx.scx_area.r_ll.p_x = fix->fp_loc.p_x-2;
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;
/* Copy Paint */
/* Because fix->fp_ttype might come from a label with a sticky type
* that does not correspond exactly to the layer underneath, include
* all connecting types.
*/
TTMaskSetMask(&FirstTileMask, &DBConnectTbl[fix->fp_ttype]);
scx.scx_area.r_ll.p_x = node->location.p_x - 2;
scx.scx_area.r_ll.p_y = node->location.p_y - 2;
scx.scx_area.r_ur.p_x = node->location.p_x + 2;
scx.scx_area.r_ur.p_y = node->location.p_y + 2;
startpoint = node->location;
newdevtiles = DBTreeCopyConnectDCS(&scx, &FirstTileMask, 0,
ResCopyMask, &TiPlaneRect, ResUse);
/* Because node->type might come from a label with a sticky type
* 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);
if (newdevtiles)
{
if (DevTiles)
lasttile->nextDev = newdevtiles;
else
DevTiles = newdevtiles;
lasttile = tmp;
}
DBTreeCopyConnect(&scx, &FirstTileMask, 0, ResCopyMask, &TiPlaneRect,
SEL_DO_LABELS, ResUse);
/* Add devices to ResUse from list in node */
DevTiles = NULL;
for (tptr = node->firstDev; tptr; tptr = tptr->nextDev)
{
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);
/* 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),
&DBAllButSpaceAndDRCBits,
ResConnectWithSD, extUnInit, ResFirst,
@ -701,16 +806,16 @@ ResExtractNet(startlist, goodies, cellname)
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
{
Plane *plane = ResUse->cu_def->cd_planes[pNum];
Rect *rect = &ResUse->cu_def->cd_bbox;
ResFracture(plane, rect);
(void) DBSrPaintClient((Tile *) NULL,plane,rect,
Plane *plane = ResUse->cu_def->cd_planes[pNum];
Rect *rect = &ResUse->cu_def->cd_bbox;
ResFracture(plane, rect);
(void) DBSrPaintClient((Tile *) NULL, plane, rect,
&DBAllButSpaceAndDRCBits,
(ClientData) CLIENTDEFAULT, ResAddPlumbing,
(ClientData) &ResDevList);
}
/* Finish preprocessing. */
/* Finish preprocessing. */
ResMakePortBreakpoints(ResUse->cu_def);
ResMakeLabelBreakpoints(ResUse->cu_def);
@ -720,24 +825,24 @@ ResExtractNet(startlist, goodies, cellname)
#ifdef LAPLACE
if (ResOptionsFlags & ResOpt_DoLaplace)
{
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
{
Plane *plane = ResUse->cu_def->cd_planes[pNum];
Rect *rect = &ResUse->cu_def->cd_bbox;
Res1d(plane,rect);
}
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
{
Plane *plane = ResUse->cu_def->cd_planes[pNum];
Rect *rect = &ResUse->cu_def->cd_bbox;
Res1d(plane, rect);
}
}
#endif
#ifdef ARIEL
if (ResOptionsFlags & ResOpt_Power)
{
for (fix = startlist; fix != NULL;fix=fix->fp_next)
{
fix->fp_tile = ResUse->cu_def->cd_planes[DBPlane(fix->fp_ttype)]->pl_hint;
GOTOPOINT(fix->fp_tile,&fix->fp_loc);
if (TiGetTypeExact(fix->fp_tile) == TT_SPACE) fix->fp_tile = NULL;
}
for (fix = startlist; fix != NULL; fix = fix->fp_next)
{
fix->fp_tile = ResUse->cu_def->cd_planes[DBPlane(fix->fp_ttype)]->pl_hint;
GOTOPOINT(fix->fp_tile, &fix->fp_loc);
if (TiGetTypeExact(fix->fp_tile) == TT_SPACE) fix->fp_tile = NULL;
}
}
#endif
@ -765,25 +870,24 @@ void
ResCleanUpEverything()
{
int pNum;
resResistor *oldRes;
resDevice *oldDev;
ResContactPoint *oldCon;
int pNum;
resResistor *oldRes;
resDevice *oldDev;
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++)
{
(void) DBSrPaintClient((Tile *) NULL,ResUse->cu_def->cd_planes[pNum],
&(ResUse->cu_def->cd_bbox),&DBAllButSpaceAndDRCBits,
(ClientData) CLIENTDEFAULT,ResRemovePlumbing,
(ClientData) NULL);
(void) DBSrPaintClient((Tile *)NULL, ResUse->cu_def->cd_planes[pNum],
&(ResUse->cu_def->cd_bbox), &DBAllButSpaceAndDRCBits,
(ClientData)CLIENTDEFAULT, ResRemovePlumbing,
(ClientData)NULL);
}
while (ResNodeList != NULL)
{
ResCleanNode(ResNodeList,TRUE,&ResNodeList,&ResNodeQueue);
ResCleanNode(ResNodeList, TRUE, &ResNodeList, &ResNodeQueue);
}
while (ResContactList != NULL)
{
@ -807,12 +911,9 @@ ResCleanUpEverything()
freeMagic((char *)oldDev);
}
}
DBCellClearDef(ResUse->cu_def);
}
/*
*-------------------------------------------------------------------------
*
@ -849,10 +950,10 @@ FindStartTile(goodies, SourcePoint)
TileType savtype = goodies->rg_ttype;
TileType rtype;
savtype = goodies->rg_ttype;
for (rtype = TT_TECHDEPBASE; rtype < DBNumUserLayers; rtype++)
if (TTMaskHasType(rmask, rtype))
{
goodies->rg_ttype = rtype;
if ((tile = FindStartTile(goodies, SourcePoint)) != NULL)
{
goodies->rg_ttype = savtype;
@ -934,54 +1035,55 @@ FindStartTile(goodies, SourcePoint)
t1 = TiGetType(tile);
devptr = ExtCurStyle->exts_device[t1];
/* 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);
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2))
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2))
{
SourcePoint->p_x = LEFT(tile);
SourcePoint->p_y = (MIN(TOP(tile),TOP(tp))+
MAX(BOTTOM(tile),BOTTOM(tp)))>>1;
SourcePoint->p_y = (MIN(TOP(tile),TOP(tp)) +
MAX(BOTTOM(tile), BOTTOM(tp))) >> 1;
return(tp);
}
}
/* 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);
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2))
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2))
{
SourcePoint->p_x = RIGHT(tile);
SourcePoint->p_y = (MIN(TOP(tile),TOP(tp))+
MAX(BOTTOM(tile),BOTTOM(tp)))>>1;
SourcePoint->p_y = (MIN(TOP(tile), TOP(tp))+
MAX(BOTTOM(tile), BOTTOM(tp))) >> 1;
return(tp);
}
}
/* 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);
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2))
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2))
{
SourcePoint->p_y = TOP(tile);
SourcePoint->p_x = (MIN(RIGHT(tile),RIGHT(tp))+
MAX(LEFT(tile),LEFT(tp)))>>1;
SourcePoint->p_x = (MIN(RIGHT(tile),RIGHT(tp)) +
MAX(LEFT(tile), LEFT(tp))) >> 1;
return(tp);
}
}
/* 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);
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2))
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t2))
{
SourcePoint->p_y = BOTTOM(tile);
SourcePoint->p_x = (MIN(RIGHT(tile),RIGHT(tp))+
MAX(LEFT(tile),LEFT(tp)))>>1;
SourcePoint->p_x = (MIN(RIGHT(tile), RIGHT(tp)) +
MAX(LEFT(tile), LEFT(tp))) >> 1;
return(tp);
}
}
@ -1005,36 +1107,36 @@ FindStartTile(goodies, SourcePoint)
resDevice *
ResGetDevice(pt)
Point *pt;
Point *pt;
{
Point workingPoint;
Tile *tile;
int pnum;
Point workingPoint;
Tile *tile;
int pnum;
workingPoint.p_x = (*pt).p_x;
workingPoint.p_y = (*pt).p_y;
workingPoint.p_x = (*pt).p_x;
workingPoint.p_y = (*pt).p_y;
for (pnum= PL_TECHDEPBASE; pnum < DBNumPlanes; pnum++)
{
if (TTMaskIntersect(&ExtCurStyle->exts_deviceMask,&DBPlaneTypes[pnum]) == 0)
{
continue;
}
/*start at hint tile for device plane */
tile = ResUse->cu_def->cd_planes[pnum]->pl_hint;
GOTOPOINT(tile,&workingPoint);
for (pnum = PL_TECHDEPBASE; pnum < DBNumPlanes; pnum++)
{
if (TTMaskIntersect(&ExtCurStyle->exts_deviceMask, &DBPlaneTypes[pnum]) == 0)
continue;
if (IsSplit(tile))
{
if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetLeftType(tile))
/* Start at hint tile for device plane */
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)))
return(((tileJunk *)tile->ti_client)->deviceList);
}
else if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetType(tile)))
{
return(((tileJunk *)tile->ti_client)->deviceList);
}
}
return (NULL);
return (((tileJunk *)tile->ti_client)->deviceList);
}
else if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetType(tile)))
{
return (((tileJunk *)tile->ti_client)->deviceList);
}
}
return NULL;
}

View File

@ -311,7 +311,7 @@ ResCalcNorthSouth(tile, pendingList, doneList, resList)
*/
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));
freeMagic((char *)p1);

File diff suppressed because it is too large Load Diff

View File

@ -171,16 +171,25 @@ ResPrintExtDev(outextfile, devices)
else
fprintf(outextfile, " \"%s\"", subsName);
fprintf(outextfile, " \"%s\" %d %s \"%s\" %d %s \"%s\" %d %s\n",
devices->gate->name,
devices->layout->rd_length * 2,
devices->rs_gattr,
devices->source->name,
devices->layout->rd_width,
devices->rs_sattr,
devices->drain->name,
devices->layout->rd_width,
devices->rs_dattr);
if (devices->gate != NULL)
fprintf(outextfile, " \"%s\" %d %s",
devices->gate->name,
devices->layout->rd_length * 2,
devices->rs_gattr);
if (devices->source != NULL)
fprintf(outextfile, " \"%s\" %d %s",
devices->source->name,
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 "extract/extract.h"
#include "extract/extractInt.h"
#include "extflat/extflat.h"
#include "windows/windows.h"
#include "dbwind/dbwind.h"
#include "utils/utils.h"
@ -52,9 +53,10 @@ extern ResSimNode *ResOriginalNodes; /*Linked List of Nodes */
int resNodeNum;
#ifdef LAPLACE
int ResOptionsFlags = ResOpt_Simplify|ResOpt_Tdi|ResOpt_DoExtFile|ResOpt_CacheLaplace;
int ResOptionsFlags = ResOpt_Simplify | ResOpt_Tdi | ResOpt_DoExtFile
| ResOpt_CacheLaplace;
#else
int ResOptionsFlags = ResOpt_Simplify|ResOpt_Tdi|ResOpt_DoExtFile;
int ResOptionsFlags = ResOpt_Simplify | ResOpt_Tdi | ResOpt_DoExtFile;
#endif
char *ResCurrentNode;
@ -97,17 +99,34 @@ ExtResisForDef(celldef, resisdata)
HashEntry *entry;
devPtr *tptr,*oldtptr;
ResSimNode *node;
int result;
int result, idx;
char *devname;
ResRDevList = 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);
/* read in .sim file */
result = (ResReadSim(celldef->cd_name,
ResSimDevice, ResSimCapacitor, ResSimResistor,
ResSimAttribute, ResSimMerge, ResSimSubckt) == 0);
/* Clean up the EFDevTypes table */
for (idx = 0; idx < EFDevNumTypes; idx++) freeMagic(EFDevTypes[idx]);
EFDevNumTypes = 0;
if (result)
/* read in .nodes file */
result = (ResReadNode(celldef->cd_name) == 0);
@ -185,7 +204,7 @@ CmdExtResis(win, cmd)
TxCommand *cmd;
{
int i, j, k, option, value, saveFlags;
static int init=1;
static int init = 1;
static float tolerance, tdiTolerance, fhFrequency;
CellDef *mainDef;
CellUse *selectedUse;
@ -246,6 +265,17 @@ typedef enum {
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)
: RES_RUN;
@ -434,7 +464,7 @@ typedef enum {
CellDef *def;
Rect rect;
int oldoptions;
ResFixPoint fp;
ResSimNode lnode;
if (ToolGetBoxWindow((Rect *) NULL, (int *) NULL) == NULL)
{
@ -449,23 +479,23 @@ typedef enum {
gparams.rg_ttype = tt;
gparams.rg_status = DRIVEONLY;
oldoptions = ResOptionsFlags;
ResOptionsFlags = ResOpt_DoSubstrate|ResOpt_Signal|ResOpt_Box;
ResOptionsFlags = ResOpt_DoSubstrate | ResOpt_Signal | ResOpt_Box;
#ifdef LAPLACE
ResOptionsFlags |= (oldoptions & (ResOpt_CacheLaplace|ResOpt_DoLaplace));
ResOptionsFlags |= (oldoptions &
(ResOpt_CacheLaplace | ResOpt_DoLaplace));
LaplaceMatchCount = 0;
LaplaceMissCount = 0;
#endif
fp.fp_ttype = tt;
fp.fp_loc = rect.r_ll;
fp.fp_next = NULL;
if (ResExtractNet(&fp, &gparams, NULL) != 0) return;
ResPrintResistorList(stdout,ResResList);
ResPrintDeviceList(stdout,ResRDevList);
lnode.location = rect.r_ll;
lnode.type = tt;
if (ResExtractNet(&lnode, &gparams, NULL) != 0) return;
ResPrintResistorList(stdout, ResResList);
ResPrintDeviceList(stdout, ResRDevList);
#ifdef LAPLACE
if (ResOptionsFlags & ResOpt_DoLaplace)
{
TxPrintf("Laplace solved: %d matched %d\n",
LaplaceMissCount,LaplaceMatchCount);
LaplaceMissCount, LaplaceMatchCount);
}
#endif
@ -492,11 +522,11 @@ typedef enum {
return;
#endif
case RES_AMBIG:
TxPrintf("Ambiguous option: %s\n",cmd->tx_argv[1]);
TxPrintf("Ambiguous option: %s\n", cmd->tx_argv[1]);
TxFlushOut();
return;
case RES_BAD:
TxPrintf("Unknown option: %s\n",cmd->tx_argv[1]);
TxPrintf("Unknown option: %s\n", cmd->tx_argv[1]);
TxFlushOut();
return;
default:
@ -519,7 +549,7 @@ typedef enum {
}
ResOptionsFlags |= ResOpt_Signal;
#ifdef ARIEL
ResOptionsFlags &= ~ResOpt_Power;
ResOptionsFlags &= ~ResOpt_Power;
#endif
resisdata.tolerance = tolerance;
@ -581,8 +611,6 @@ resSubcircuitFunc(cellDef, rdata)
return 0;
}
/*
*-------------------------------------------------------------------------
*
@ -841,7 +869,7 @@ ResCheckSimNodes(celldef, resisdata)
}
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
{
@ -850,7 +878,7 @@ ResCheckSimNodes(celldef, resisdata)
if (ResOptionsFlags & ResOpt_FastHenry)
{
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);
ResPortIndex = 0;
}
@ -961,7 +989,7 @@ ResCheckSimNodes(celldef, resisdata)
t1->drain != t2->source)) break;
/* do parallel combination */
if (cumRes != 0.0 && t2->resistance != 0.0)
if ((cumRes != 0.0) && (t2->resistance != 0.0))
{
cumRes = (cumRes * t2->resistance) /
(cumRes + t2->resistance);
@ -998,32 +1026,32 @@ ResCheckSimNodes(celldef, resisdata)
gparams.rg_devloc = &node->drivepoint;
gparams.rg_status |= DRIVEONLY;
}
if (node->status & PORTNODE)
if (node->status & PORTNODE)
{
/* 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;
}
}
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 "
"driving device\n",node->name);
}
if (minRes == FLT_MAX || gparams.rg_devloc == NULL)
if ((minRes == FLT_MAX) || (gparams.rg_devloc == NULL))
{
continue;
}
gparams.rg_bigdevres = (int)minRes*OHMSTOMILLIOHMS;
if (rctol == 0.0 || tol == 0.0)
gparams.rg_bigdevres = (int)minRes * OHMSTOMILLIOHMS;
if ((rctol == 0.0) || (tol == 0.0))
{
ftolerance = 0.0;
rctolerance = 0.0;
}
else
{
ftolerance = minRes/tol;
rctolerance = minRes/rctol;
ftolerance = minRes / tol;
rctolerance = minRes / rctol;
}
/*
@ -1031,19 +1059,16 @@ ResCheckSimNodes(celldef, resisdata)
* resistance? If so, extract net.
*/
if (node->resistance > ftolerance || node->status & FORCE ||
if ((node->resistance > ftolerance) || (node->status & FORCE) ||
(ResOpt_ExtractAll & ResOptionsFlags))
{
ResFixPoint fp;
failed1++;
fp.fp_loc = node->location;
fp.fp_ttype = node->type;
fp.fp_next = NULL;
if (ResExtractNet(&fp, &gparams, outfile) != 0)
if (ResExtractNet(node, &gparams, outfile) != 0)
{
TxError("Error in extracting node %s\n",node->name);
// break; // Don't stop for one error. . .
/* On error, don't output this net, but keep going */
TxError("Error in extracting node %s\n", node->name);
}
else
{
@ -1062,7 +1087,7 @@ ResCheckSimNodes(celldef, resisdata)
}
}
#ifdef PARANOID
ResSanityChecks(node->name,ResResList,ResNodeList,ResDevList);
ResSanityChecks(node->name, ResResList, ResNodeList, ResDevList);
#endif
ResCleanUpEverything();
}
@ -1075,7 +1100,7 @@ ResCheckSimNodes(celldef, resisdata)
if (ResOptionsFlags & ResOpt_DoExtFile)
{
ResPrintExtDev(ResExtFile,ResRDevList);
ResPrintExtDev(ResExtFile, ResRDevList);
}
/*
@ -1182,7 +1207,7 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
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 */
/* name, the new one won't be used, so we decrement resNodeNum */
@ -1398,9 +1423,10 @@ void
ResSortByGate(DevpointerList)
devPtr **DevpointerList;
{
int changed=TRUE;
int localchange=TRUE;
devPtr *working, *last=NULL, *current, *gatelist=NULL;
int changed = TRUE;
int localchange = TRUE;
devPtr *working, *current;
devPtr *last = NULL, *gatelist = NULL;
working = *DevpointerList;
while (working != NULL)
@ -1526,7 +1552,7 @@ ResWriteLumpFile(node)
{
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))
{
reg = (ResContactPoint *) mallocMagic((unsigned) (sizeof(ResContactPoint)));
reg->cp_center.p_x = (LEFT(tile)+RIGHT(tile))>>1;
reg->cp_center.p_y = (TOP(tile)+BOTTOM(tile))>>1;
reg->cp_status = FALSE;
reg->cp_type = t;
reg->cp_width = RIGHT(tile)-LEFT(tile);
reg->cp_height = TOP(tile)-BOTTOM(tile);
for (i=0; i< LAYERS_PER_CONTACT; i++)
{
reg->cp_tile[i] = (Tile *) NULL;
reg->cp_cnode[i] = (resNode *) NULL;
}
reg->cp_currentcontact = 0;
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_ur.p_x = RIGHT(tile);
reg->cp_rect.r_ur.p_y = TOP(tile);
reg->cp_contactTile = tile;
/* Prepend it to the region list */
reg->cp_nextcontact = (ResContactPoint *) arg->fra_region;
arg->fra_region = (Region *) reg;
reg = (ResContactPoint *) mallocMagic((unsigned) (sizeof(ResContactPoint)));
reg->cp_center.p_x = (LEFT(tile) + RIGHT(tile)) >> 1;
reg->cp_center.p_y = (TOP(tile) + BOTTOM(tile)) >> 1;
reg->cp_status = FALSE;
reg->cp_type = t;
reg->cp_width = RIGHT(tile) - LEFT(tile);
reg->cp_height = TOP(tile) - BOTTOM(tile);
for (i = 0; i < LAYERS_PER_CONTACT; i++)
{
reg->cp_tile[i] = (Tile *) NULL;
reg->cp_cnode[i] = (resNode *) NULL;
}
reg->cp_currentcontact = 0;
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_ur.p_x = RIGHT(tile);
reg->cp_rect.r_ur.p_y = TOP(tile);
reg->cp_contactTile = tile;
/* Prepend it to the region list */
reg->cp_nextcontact = (ResContactPoint *) arg->fra_region;
arg->fra_region = (Region *) reg;
}
return((Region *) NULL);
}
@ -104,16 +104,16 @@ ResFirst(tile, arg)
int
ResEach(tile, pNum, arg)
Tile *tile;
int pNum;
FindRegion *arg;
Tile *tile;
int pNum;
FindRegion *arg;
{
if ( ((ResContactPoint *)(arg->fra_region))->cp_contactTile != tile)
{
(void) ResFirst(tile, arg);
}
return(0);
if (((ResContactPoint *)(arg->fra_region))->cp_contactTile != tile)
{
ResFirst(tile, arg);
}
return(0);
}
/*
@ -135,22 +135,21 @@ ResEach(tile, pNum, arg)
int
ResAddPlumbing(tile, arg)
Tile *tile;
ClientData *arg;
Tile *tile;
ClientData *arg;
{
tileJunk *Junk,*junk2;
static Stack *resDevStack=NULL;
TileType loctype, t1;
Tile *tp1,*tp2,*source;
resDevice *resDev;
ExtDevice *devptr;
tileJunk *Junk, *junk2;
static Stack *resDevStack = NULL;
TileType loctype, t1;
Tile *tp1, *tp2, *source;
resDevice *resDev;
ExtDevice *devptr;
if (resDevStack == NULL)
resDevStack = StackNew(64);
if (resDevStack == NULL)
resDevStack = StackNew(64);
if (tile->ti_client == (ClientData) CLIENTDEFAULT)
{
if (tile->ti_client == (ClientData) CLIENTDEFAULT)
{
if (IsSplit(tile))
loctype = (SplitSide(tile)) ? SplitRightType(tile) :
SplitLeftType(tile);
@ -165,7 +164,7 @@ ResAddPlumbing(tile, arg)
/* Count SD terminals of the device */
nterms = 0;
for (i = 0; ; i++)
for (i = 0;; i++)
{
if (TTMaskIsZero(&(devptr->exts_deviceSDTypes[i]))) break;
nterms++;
@ -181,7 +180,7 @@ ResAddPlumbing(tile, arg)
resDev = (resDevice *) mallocMagic((unsigned)(sizeof(resDevice)));
resDev->rd_nterms = nterms;
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_tile = tile;
@ -201,79 +200,91 @@ ResAddPlumbing(tile, arg)
junk2->deviceList = resDev;
junk2->tj_status |= RES_TILE_DEV;
source = NULL;
/* find diffusion (if present) to be source contact */
/* top */
for (tp2= RT(tile); RIGHT(tp2) > LEFT(tile); tp2 = BL(tp2))
for (i = 0; i < nterms - 2; i++)
{
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))
{
junk2->sourceEdge |= TOPEDGE;
source = tp2;
Junk = resAddField(source);
Junk->tj_status |= RES_TILE_SD;
break;
}
}
{
junk2->sourceEdge |= TOPEDGE;
source = tp2;
Junk = resAddField(source);
Junk->tj_status |= RES_TILE_SD;
break;
}
}
/*bottom*/
if (source == NULL)
for (tp2= LB(tile); LEFT(tp2) < RIGHT(tile); tp2 = TR(tp2))
{
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
/* bottom */
if (source == NULL)
for (tp2 = LB(tile); LEFT(tp2) < RIGHT(tile); tp2 = TR(tp2))
{
if TTMaskHasType(&(devptr->exts_deviceSDTypes[i]),
TiGetTopType(tp2))
{
junk2->sourceEdge |= BOTTOMEDGE;
source = tp2;
Junk = resAddField(source);
Junk->tj_status |= RES_TILE_SD;
break;
{
junk2->sourceEdge |= BOTTOMEDGE;
source = tp2;
Junk = resAddField(source);
Junk->tj_status |= RES_TILE_SD;
break;
}
}
}
/*right*/
if (source == NULL)
for (tp2= TR(tile); TOP(tp2) > BOTTOM(tile); tp2 = LB(tp2))
{
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
/* right */
if (source == NULL)
for (tp2 = TR(tile); TOP(tp2) > BOTTOM(tile); tp2 = LB(tp2))
{
if TTMaskHasType(&(devptr->exts_deviceSDTypes[i]),
TiGetLeftType(tp2))
{
junk2->sourceEdge |= RIGHTEDGE;
source = tp2;
Junk = resAddField(source);
Junk->tj_status |= RES_TILE_SD;
break;
{
junk2->sourceEdge |= RIGHTEDGE;
source = tp2;
Junk = resAddField(source);
Junk->tj_status |= RES_TILE_SD;
break;
}
}
}
/*left*/
if (source == NULL)
for (tp2= BL(tile); BOTTOM(tp2) < TOP(tile); tp2 = RT(tp2))
{
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
/* left */
if (source == NULL)
for (tp2 = BL(tile); BOTTOM(tp2) < TOP(tile); tp2 = RT(tp2))
{
if TTMaskHasType(&(devptr->exts_deviceSDTypes[i]),
TiGetRightType(tp2))
{
source = tp2;
Junk = resAddField(source);
Junk->tj_status |= RES_TILE_SD;
junk2->sourceEdge |= LEFTEDGE;
break;
{
source = tp2;
Junk = resAddField(source);
Junk->tj_status |= RES_TILE_SD;
junk2->sourceEdge |= LEFTEDGE;
break;
}
}
/* 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
* the source or to the drain of a device. A single
* diffusion tile is marked, and all connecting diffusion tiles
* are enumerated and called the source. Any other SD tiles
* are assumed to be the drain. BUG: this does not work
* correctly with multi SD structures.
*/
/* We need to know whether a given diffusion tile connects to
* the source or to the drain of a device. A single
* diffusion tile is marked, and all connecting diffusion tiles
* are enumerated and called the source. Any other SD tiles
* are assumed to be the drain. BUG: this does not work
* correctly with multi SD structures.
*/
if (source != (Tile *) NULL)
{
STACKPUSH((ClientData) (source),resDevStack);
if (source != (Tile *) NULL)
{
STACKPUSH((ClientData)source, resDevStack);
}
}
while (!StackEmpty(resDevStack))
{
@ -287,54 +298,54 @@ ResAddPlumbing(tile, arg)
t1 = TiGetTypeExact(tp1);
/* 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)
{
tileJunk *j= resAddField(tp2);
tileJunk *j = resAddField(tp2);
if ((j->tj_status & RES_TILE_SD) ==0)
{
j->tj_status |= RES_TILE_SD;
STACKPUSH((ClientData)tp2,resDevStack);
STACKPUSH((ClientData)tp2, resDevStack);
}
}
}
/*bottom*/
for (tp2= LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2))
/* bottom */
for (tp2 = LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2))
{
if (TiGetTopType(tp2) == t1)
{
tileJunk *j= resAddField(tp2);
tileJunk *j = resAddField(tp2);
if ((j->tj_status & RES_TILE_SD) == 0)
{
j->tj_status |= RES_TILE_SD;
STACKPUSH((ClientData) (tp2),resDevStack);
STACKPUSH((ClientData)tp2, resDevStack);
}
}
}
/*right*/
for (tp2= TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2))
/* right */
for (tp2 = TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2))
{
if (TiGetLeftType(tp2) == t1)
{
tileJunk *j= resAddField(tp2);
tileJunk *j = resAddField(tp2);
if ((j->tj_status & RES_TILE_SD) == 0)
{
j->tj_status |= RES_TILE_SD;
STACKPUSH((ClientData) (tp2),resDevStack);
STACKPUSH((ClientData)tp2, resDevStack);
}
}
}
/*left*/
for (tp2= BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2))
/* left */
for (tp2 = BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2))
{
if (TiGetRightType(tp2) == t1)
{
tileJunk *j= resAddField(tp2);
tileJunk *j = resAddField(tp2);
if ((j->tj_status & RES_TILE_SD) == 0)
{
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 */
STACKPUSH((ClientData) (tile), resDevStack);
STACKPUSH((ClientData)tile, resDevStack);
while (!StackEmpty(resDevStack))
{
tileJunk *j0;
tileJunk *j0;
tp1= (Tile *) STACKPOP(resDevStack);
tp1 = (Tile *) STACKPOP(resDevStack);
if (IsSplit(tp1))
{
t1 = (SplitSide(tp1)) ? SplitRightType(tp1) :
@ -359,14 +370,14 @@ ResAddPlumbing(tile, arg)
devptr = ExtCurStyle->exts_device[t1];
j0 = (tileJunk *) tp1->ti_client;
/* 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) &&
(tp2->ti_client == (ClientData) CLIENTDEFAULT))
{
Junk = resAddField(tp2);
STACKPUSH((ClientData)(tp2),resDevStack);
Junk->deviceList = resDev;
STACKPUSH((ClientData)tp2, resDevStack);
Junk->deviceList = resDev;
Junk->tj_status |= RES_TILE_DEV;
}
@ -378,14 +389,14 @@ ResAddPlumbing(tile, arg)
j0->sourceEdge |= TOPEDGE;
}
}
/*bottom*/
for (tp2= LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2))
/* bottom */
for (tp2 = LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2))
{
if ((TiGetTopType(tp2) == t1) &&
(tp2->ti_client == (ClientData) CLIENTDEFAULT))
{
Junk = resAddField(tp2);
STACKPUSH((ClientData)(tp2),resDevStack);
STACKPUSH((ClientData)tp2, resDevStack);
Junk->deviceList = resDev;
Junk->tj_status |= RES_TILE_DEV;
}
@ -397,33 +408,33 @@ ResAddPlumbing(tile, arg)
j0->sourceEdge |= BOTTOMEDGE;
}
}
/*right*/
for (tp2= TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2))
/* right */
for (tp2 = TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2))
{
if ((TiGetLeftType(tp2) == t1) &&
(tp2->ti_client == (ClientData) CLIENTDEFAULT))
{
Junk = resAddField(tp2);
STACKPUSH((ClientData)(tp2),resDevStack);
STACKPUSH((ClientData)tp2, resDevStack);
Junk->deviceList = resDev;
Junk->tj_status |= RES_TILE_DEV;
}
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
TiGetLeftType(tp2))
{
{
Junk = resAddField(tp2);
if (Junk->tj_status & RES_TILE_SD)
j0->sourceEdge |= RIGHTEDGE;
}
}
/*left*/
for (tp2= BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2))
/* left */
for (tp2 = BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2))
{
if ((TiGetRightType(tp2) == t1) &&
(tp2->ti_client == (ClientData) CLIENTDEFAULT))
{
Junk = resAddField(tp2);
STACKPUSH((ClientData)(tp2),resDevStack);
STACKPUSH((ClientData)tp2, resDevStack);
Junk->deviceList = resDev;
Junk->tj_status |= RES_TILE_DEV;
}
@ -441,9 +452,9 @@ ResAddPlumbing(tile, arg)
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;
}
while (!StackEmpty(resDevStack))
@ -458,54 +469,54 @@ ResAddPlumbing(tile, arg)
t1 = TiGetTypeExact(tp1);
/* 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 (j2->tj_status & RES_TILE_SD)
{
j2->tj_status &= ~RES_TILE_SD;
STACKPUSH((ClientData) tp2,resDevStack);
STACKPUSH((ClientData)tp2, resDevStack);
}
}
}
/*bottom*/
for(tp2= LB(tp1); LEFT(tp2) < RIGHT(tp1); tp2 = TR(tp2))
/* bottom */
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 (j2->tj_status & RES_TILE_SD)
{
j2->tj_status &= ~RES_TILE_SD;
STACKPUSH((ClientData) tp2,resDevStack);
STACKPUSH((ClientData)tp2, resDevStack);
}
}
}
/*right*/
for (tp2= TR(tp1); TOP(tp2) > BOTTOM(tp1); tp2 = LB(tp2))
/* right */
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 (j2->tj_status & RES_TILE_SD)
{
j2->tj_status &= ~RES_TILE_SD;
STACKPUSH((ClientData) tp2,resDevStack);
STACKPUSH((ClientData)tp2, resDevStack);
}
}
}
/*left*/
for (tp2= BL(tp1); BOTTOM(tp2) < TOP(tp1); tp2 = RT(tp2))
/* left */
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 (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
ResRemovePlumbing(tile, arg)
Tile *tile;
ClientData *arg;
Tile *tile;
ClientData *arg;
{
if (tile->ti_client != (ClientData) CLIENTDEFAULT)
{
freeMagic(((char *)(tile->ti_client)));
tile->ti_client = (ClientData) CLIENTDEFAULT;
}
return(0);
if (tile->ti_client != (ClientData) CLIENTDEFAULT)
{
freeMagic(((char *)(tile->ti_client)));
tile->ti_client = (ClientData) CLIENTDEFAULT;
}
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
* 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
@ -604,8 +615,9 @@ ResPreProcessDevices(TileList, DeviceList, Def)
tt = TiGetType(tile);
tstruct = (tileJunk *) tile->ti_client;
if (!TTMaskHasType(&ExtCurStyle->exts_deviceMask, tt) ||
tstruct->deviceList == NULL)
if ((tstruct == (tileJunk *)CLIENTDEFAULT) ||
(tstruct->deviceList == NULL) ||
!TTMaskHasType(&ExtCurStyle->exts_deviceMask, tt))
{
TxError("Bad Device Location at %d,%d\n",
TileList->area.r_ll.p_x,
@ -627,7 +639,7 @@ ResPreProcessDevices(TileList, DeviceList, Def)
freeMagic((char *)oldTile);
}
for(; DeviceList != NULL;DeviceList = DeviceList->rd_nextDev)
for (; DeviceList != NULL; DeviceList = DeviceList->rd_nextDev)
{
int width = DeviceList->rd_perim;
int length = DeviceList->rd_length;
@ -666,18 +678,17 @@ ResPreProcessDevices(TileList, DeviceList, Def)
*
*-------------------------------------------------------------------------
*/
void
ResAddToQueue(node,list)
resNode *node,**list;
ResAddToQueue(node, list)
resNode *node, **list;
{
node->rn_more = *list;
node->rn_less = NULL;
if (*list) (*list)->rn_less = node;
*list = node;
node->rn_more = *list;
node->rn_less = NULL;
if (*list) (*list)->rn_less = node;
*list = node;
}
/*
*-------------------------------------------------------------------------
*
@ -692,44 +703,42 @@ ResAddToQueue(node,list)
*/
void
ResRemoveFromQueue(node,list)
resNode *node,**list;
ResRemoveFromQueue(node, list)
resNode *node, **list;
{
if (node->rn_less != NULL)
{
node->rn_less->rn_more = node->rn_more;
}
else
{
if (node != (*list))
{
TxError("Error: Attempt to remove node from wrong list\n");
}
else
{
*list = node->rn_more;
}
}
if (node->rn_more != NULL)
{
node->rn_more->rn_less = node->rn_less;
}
node->rn_more = NULL;
node->rn_less = NULL;
if (node->rn_less != NULL)
{
node->rn_less->rn_more = node->rn_more;
}
else
{
if (node != (*list))
{
TxError("Error: Attempt to remove node from wrong list\n");
}
else
{
*list = node->rn_more;
}
}
if (node->rn_more != NULL)
{
node->rn_more->rn_less = node->rn_less;
}
node->rn_more = NULL;
node->rn_less = NULL;
}
tileJunk *
resAddField(tile)
Tile *tile;
Tile *tile;
{
tileJunk *Junk;
if ((Junk=(tileJunk *)tile->ti_client) == (tileJunk *) CLIENTDEFAULT)
{
Junk = (tileJunk *) mallocMagic((unsigned) (sizeof(tileJunk)));
ResJunkInit(Junk);
tile->ti_client = (ClientData) Junk;
}
return Junk;
tileJunk *Junk;
if ((Junk = (tileJunk *)tile->ti_client) == (tileJunk *) CLIENTDEFAULT)
{
Junk = (tileJunk *) mallocMagic((unsigned) (sizeof(tileJunk)));
ResJunkInit(Junk);
tile->ti_client = (ClientData) Junk;
}
return Junk;
}

View File

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

View File

@ -247,6 +247,7 @@ typedef struct resdevtile
struct resdevtile *nextDev;
Rect area;
TileType type;
ExtDevice *devptr;
int perim;
int overlap;
} ResDevTile;
@ -297,7 +298,8 @@ typedef struct rdev
Point location; /* Location of lower left point 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_sattr;
char *rs_dattr;
@ -512,6 +514,7 @@ typedef struct capval
#define RIGHTEDGE 4
#define TOPEDGE 8
#define BOTTOMEDGE 16
#define OTHERPLANE 32
#define RN_MAXTDI 0x00001000

View File

@ -190,7 +190,8 @@ extern int GeoRectPointSide(Rect *, Point *);
extern int GeoRectRectSide(Rect *, Rect *);
extern void GeoIncludePoint(Point *, Rect *);
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 */
cmp = i;
if (i & 1)
if ((i & 1) && (i != 1))
KEY_LE_COND(keyType, list, i, i-1, cmp = i-1);
/* Find parent. If 0 then at the root so quit */
if ((i >>= 1) == 0) return;
KEY_LE_COND(keyType, list, cmp, i, return);
list[0] = list[cmp]; list[cmp] = list[i]; list[i] = list[0];
heapify(heap, cmp);
@ -434,11 +435,12 @@ HeapAdd(heap, pKey, id)
{
/* If odd then new entry is the right half of a pair */
cmp = i;
if (i & 1)
if ((i & 1) && (i != 1))
KEY_GE_COND(keyType, list, i, i-1, cmp = i-1);
/* Find parent. If 0 then at the root so quit */
if ((i >>= 1) == 0) return;
KEY_GE_COND(keyType, list, cmp, i, return);
list[0] = list[cmp]; list[cmp] = list[i]; list[i] = list[0];
heapify(heap, cmp);

View File

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

View File

@ -149,7 +149,7 @@ TechSectionGetMask(sectionName, depend)
{
invid |= tsp->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;

View File

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