Corrected an issue with the limited bitfield dedicated to port numbers;

this limited ports to 16384, which seemed reasonable at the time.
However, the sky130_sram_macro layouts connect power and ground in a
way that when coupled with "extract unique" can generate tens of
thousands of ports and overrun the bit field, showing that automation
can do the unexpected.  The solution was to split out the port number
from the label record as its own 32-bit value.
This commit is contained in:
Tim Edwards 2021-12-12 22:09:31 -05:00
parent 552d6de0f7
commit 43bb499bcf
25 changed files with 136 additions and 119 deletions

View File

@ -1 +1 @@
8.3.239 8.3.240

View File

@ -316,7 +316,7 @@ calmaElementBoundary()
if (lab == NULL) if (lab == NULL)
{ {
/* There was no label in the area. Create a placeholder label */ /* There was no label in the area. Create a placeholder label */
DBPutLabel(cifReadCellDef, &rpc, GEO_CENTER, "", type, 0); DBPutLabel(cifReadCellDef, &rpc, GEO_CENTER, "", type, 0, 0);
} }
} }
} }
@ -970,10 +970,10 @@ calmaElementText()
} }
if (font < 0) if (font < 0)
lab = DBPutLabel(cifReadCellDef, &r, pos, textbody, type, flags); lab = DBPutLabel(cifReadCellDef, &r, pos, textbody, type, flags, 0);
else else
lab = DBPutFontLabel(cifReadCellDef, &r, font, size, angle, lab = DBPutFontLabel(cifReadCellDef, &r, font, size, angle,
&GeoOrigin, pos, textbody, type, flags); &GeoOrigin, pos, textbody, type, flags, 0);
if ((lab != NULL) && (cifnum >= 0) && if ((lab != NULL) && (cifnum >= 0) &&
(cifCurReadStyle->crs_labelSticky[cifnum] == LABEL_TYPE_PORT)) (cifCurReadStyle->crs_labelSticky[cifnum] == LABEL_TYPE_PORT))
@ -988,7 +988,7 @@ calmaElementText()
i = -1; i = -1;
for (sl = cifReadCellDef->cd_labels; sl != NULL; sl = sl->lab_next) for (sl = cifReadCellDef->cd_labels; sl != NULL; sl = sl->lab_next)
{ {
idx = sl->lab_flags & PORT_NUM_MASK; idx = sl->lab_port;
if (idx > i) i = idx; if (idx > i) i = idx;
if ((idx > 0) && (sl != lab) && !strcmp(sl->lab_text, textbody)) if ((idx > 0) && (sl != lab) && !strcmp(sl->lab_text, textbody))
{ {
@ -997,7 +997,7 @@ calmaElementText()
} }
} }
i++; i++;
lab->lab_flags |= (PORT_NUM_MASK & i); lab->lab_port = i;
lab->lab_flags |= PORT_DIR_NORTH | PORT_DIR_SOUTH | lab->lab_flags |= PORT_DIR_NORTH | PORT_DIR_SOUTH |
PORT_DIR_EAST | PORT_DIR_WEST; PORT_DIR_EAST | PORT_DIR_WEST;
} }

View File

@ -1262,8 +1262,8 @@ calmaOutFunc(def, f, cliprect)
} }
else else
{ {
if ((int)(lab->lab_flags & PORT_NUM_MASK) > maxport) if ((int)lab->lab_port > maxport)
maxport = (int)(lab->lab_flags & PORT_NUM_MASK); maxport = (int)lab->lab_port;
} }
} }
if (maxport >= 0) if (maxport >= 0)
@ -1272,7 +1272,7 @@ calmaOutFunc(def, f, cliprect)
{ {
type = CIFCurStyle->cs_portLayer[lab->lab_type]; type = CIFCurStyle->cs_portLayer[lab->lab_type];
if ((type >= 0) && ((lab->lab_flags & PORT_DIR_MASK) != 0) && if ((type >= 0) && ((lab->lab_flags & PORT_DIR_MASK) != 0) &&
((lab->lab_flags & PORT_NUM_MASK) == i)) (lab->lab_port == i))
{ {
calmaWriteLabelFunc(lab, type, f); calmaWriteLabelFunc(lab, type, f);
/* break; */ /* Do not limit to unique labels! */ /* break; */ /* Do not limit to unique labels! */

View File

@ -1183,7 +1183,7 @@ cifParseUser94()
flags = LABEL_STICKY; flags = LABEL_STICKY;
else else
flags = 0; flags = 0;
(void) DBPutLabel(cifReadCellDef, &rectangle, -1, name, type, flags); (void) DBPutLabel(cifReadCellDef, &rectangle, -1, name, type, flags, 0);
} }
freeMagic(name); freeMagic(name);
return TRUE; return TRUE;
@ -1344,7 +1344,7 @@ cifParseUser95()
flags = LABEL_STICKY; flags = LABEL_STICKY;
else else
flags = 0; flags = 0;
(void) DBPutLabel(cifReadCellDef, &rectangle, -1, name, type, flags); (void) DBPutLabel(cifReadCellDef, &rectangle, -1, name, type, flags, 0);
} }
freeMagic(name); freeMagic(name);

View File

@ -1872,7 +1872,8 @@ flatCopyAllLabels(scx, lab, tpath, targetUse)
{ {
Rect labTargetRect; Rect labTargetRect;
int targetPos; int targetPos;
int flags = 0; unsigned short flags = 0;
unsigned int port = 0;
CellDef *def; CellDef *def;
char labelname[1024]; char labelname[1024];
char *n, *f, c; char *n, *f, c;
@ -1903,7 +1904,10 @@ flatCopyAllLabels(scx, lab, tpath, targetUse)
* top level cell, but certainly not any others. * top level cell, but certainly not any others.
*/ */
if (tpath && (*tpath->tp_first) == '\0') if (tpath && (*tpath->tp_first) == '\0')
{
flags = lab->lab_flags; flags = lab->lab_flags;
port = lab->lab_port;
}
/* To-do Feb. 2008: Translate target rotation and offset */ /* To-do Feb. 2008: Translate target rotation and offset */
@ -1913,7 +1917,7 @@ flatCopyAllLabels(scx, lab, tpath, targetUse)
strcpy(n, lab->lab_text); strcpy(n, lab->lab_text);
DBPutFontLabel(def, &labTargetRect, lab->lab_font, lab->lab_size, DBPutFontLabel(def, &labTargetRect, lab->lab_font, lab->lab_size,
lab->lab_rotate, &lab->lab_offset, targetPos, lab->lab_rotate, &lab->lab_offset, targetPos,
f, lab->lab_type, flags); f, lab->lab_type, flags, port);
*n = c; *n = c;
return 0; return 0;

View File

@ -120,7 +120,7 @@ CmdLabelProc(text, font, size, rotate, offx, offy, pos, sticky, type)
offset.p_y = offy; offset.p_y = offy;
lab = DBPutFontLabel(EditCellUse->cu_def, &editBox, font, size, lab = DBPutFontLabel(EditCellUse->cu_def, &editBox, font, size,
rotate, &offset, pos, text, type, rotate, &offset, pos, text, type,
((sticky) ? LABEL_STICKY : 0)); ((sticky) ? LABEL_STICKY : 0), 0);
DBAdjustLabels(EditCellUse->cu_def, &editBox); DBAdjustLabels(EditCellUse->cu_def, &editBox);
DBReComputeBbox(EditCellUse->cu_def); DBReComputeBbox(EditCellUse->cu_def);
tmpArea = lab->lab_rect; tmpArea = lab->lab_rect;
@ -1503,7 +1503,7 @@ CmdPort(w, cmd)
int portidx = atoi(cmd->tx_argv[1]); int portidx = atoi(cmd->tx_argv[1]);
for (sl = editDef->cd_labels; sl != NULL; sl = sl->lab_next) for (sl = editDef->cd_labels; sl != NULL; sl = sl->lab_next)
if (sl && ((sl->lab_flags & PORT_DIR_MASK) != 0)) if (sl && ((sl->lab_flags & PORT_DIR_MASK) != 0))
if ((sl->lab_flags & PORT_NUM_MASK) == portidx) if ((int)sl->lab_port == portidx)
{ {
lab = sl; lab = sl;
break; break;
@ -1622,7 +1622,7 @@ CmdPort(w, cmd)
i = -1; i = -1;
for (sl = editDef->cd_labels; sl != NULL; sl = sl->lab_next) for (sl = editDef->cd_labels; sl != NULL; sl = sl->lab_next)
{ {
idx = sl->lab_flags & PORT_NUM_MASK; idx = (int)sl->lab_port;
if (idx > i) i = idx; if (idx > i) i = idx;
} }
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
@ -1633,16 +1633,15 @@ CmdPort(w, cmd)
break; break;
case PORT_FIRST: case PORT_FIRST:
i = PORT_NUM_MASK + 1; i = -1;
for (sl = editDef->cd_labels; sl != NULL; sl = sl->lab_next) for (sl = editDef->cd_labels; sl != NULL; sl = sl->lab_next)
{ {
if (sl->lab_flags & PORT_DIR_MASK) if (sl->lab_flags & PORT_DIR_MASK)
{ {
idx = sl->lab_flags & PORT_NUM_MASK; idx = (int)sl->lab_port;
if (idx < i) i = idx; if (idx < i) i = idx;
} }
} }
if (i == PORT_NUM_MASK + 1) i = -1;
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(i)); Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(i));
#else #else
@ -1651,18 +1650,17 @@ CmdPort(w, cmd)
break; break;
case PORT_NEXT: case PORT_NEXT:
refidx = lab->lab_flags & PORT_NUM_MASK; refidx = (int)lab->lab_port;
i = PORT_NUM_MASK + 1; i = -1;
for (sl = editDef->cd_labels; sl != NULL; sl = sl->lab_next) for (sl = editDef->cd_labels; sl != NULL; sl = sl->lab_next)
{ {
if (sl->lab_flags & PORT_DIR_MASK) if (sl->lab_flags & PORT_DIR_MASK)
{ {
idx = sl->lab_flags & PORT_NUM_MASK; idx = (int)sl->lab_port;
if (idx > refidx) if (idx > refidx)
if (idx < i) i = idx; if (idx < i) i = idx;
} }
} }
if (i == PORT_NUM_MASK + 1) i = -1;
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(i)); Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(i));
#else #else
@ -1705,7 +1703,7 @@ CmdPort(w, cmd)
lab->lab_size, lab->lab_rotate, lab->lab_size, lab->lab_rotate,
&lab->lab_offset, lab->lab_just, &lab->lab_offset, lab->lab_just,
cmd->tx_argv[argstart + 1], cmd->tx_argv[argstart + 1],
lab->lab_type, lab->lab_flags); lab->lab_type, lab->lab_flags, lab->lab_port);
DBEraseLabelsByContent(editDef, &lab->lab_rect, -1, DBEraseLabelsByContent(editDef, &lab->lab_rect, -1,
lab->lab_text); lab->lab_text);
DBWLabelChanged(editDef, sl, DBW_ALLWINDOWS); DBWLabelChanged(editDef, sl, DBW_ALLWINDOWS);
@ -1849,7 +1847,7 @@ CmdPort(w, cmd)
case PORT_INDEX: case PORT_INDEX:
if (argc == 2) if (argc == 2)
{ {
idx = lab->lab_flags & PORT_NUM_MASK; idx = (int)lab->lab_port;
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(idx)); Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(idx));
#else #else
@ -1867,8 +1865,7 @@ CmdPort(w, cmd)
if (((sl->lab_flags & PORT_DIR_MASK) != 0) && if (((sl->lab_flags & PORT_DIR_MASK) != 0) &&
!strcmp(sl->lab_text, lab->lab_text)) !strcmp(sl->lab_text, lab->lab_text))
{ {
sl->lab_flags &= (~PORT_NUM_MASK); sl->lab_port = (unsigned int)atoi(cmd->tx_argv[argstart + 1]);
sl->lab_flags |= atoi(cmd->tx_argv[argstart + 1]);
} }
} }
editDef->cd_flags |= (CDMODIFIED | CDGETNEWSTAMP); editDef->cd_flags |= (CDMODIFIED | CDGETNEWSTAMP);
@ -1950,8 +1947,7 @@ CmdPort(w, cmd)
if (!strcmp(lastlab->lab_text, tlab->lab_text)) if (!strcmp(lastlab->lab_text, tlab->lab_text))
p--; p--;
tlab->lab_flags &= ~PORT_NUM_MASK; tlab->lab_port = (unsigned int)p;
tlab->lab_flags |= p;
lastlab = tlab; lastlab = tlab;
p++; p++;
} }
@ -2019,7 +2015,7 @@ parseindex:
if (sl == lab) continue; /* don't consider self */ if (sl == lab) continue; /* don't consider self */
if (sl->lab_flags & PORT_DIR_MASK) if (sl->lab_flags & PORT_DIR_MASK)
{ {
if ((sl->lab_flags & PORT_NUM_MASK) == idx) if ((int)sl->lab_port == idx)
{ {
TxError("Port index %d is already used by port %s.\n" TxError("Port index %d is already used by port %s.\n"
"Use command \"port index %d\" to force " "Use command \"port index %d\" to force "
@ -2043,18 +2039,17 @@ parseindex:
// declared a port, then use its index. // declared a port, then use its index.
if (!strcmp(sl->lab_text, lab->lab_text)) if (!strcmp(sl->lab_text, lab->lab_text))
{ {
idx = (sl->lab_flags & PORT_NUM_MASK) - 1; idx = (int)sl->lab_port - 1;
break; break;
} }
else if ((sl->lab_flags & PORT_NUM_MASK) > idx) else if (sl->lab_port > idx)
idx = (sl->lab_flags & PORT_NUM_MASK); idx = sl->lab_port;
} }
} }
idx++; idx++;
} }
lab->lab_flags &= ~PORT_NUM_MASK; lab->lab_port = idx;
lab->lab_flags |= idx;
/* /*
* Find positions. * Find positions.

View File

@ -1633,7 +1633,8 @@ cmdLabelTextFunc(label, cellUse, transform, text)
{ {
newlab = DBPutFontLabel(cellDef, &label->lab_rect, label->lab_font, newlab = DBPutFontLabel(cellDef, &label->lab_rect, label->lab_font,
label->lab_size, label->lab_rotate, &label->lab_offset, label->lab_size, label->lab_rotate, &label->lab_offset,
label->lab_just, text, label->lab_type, label->lab_flags); label->lab_just, text, label->lab_type, label->lab_flags,
label->lab_port);
DBEraseLabelsByContent(cellDef, &label->lab_rect, -1, label->lab_text); DBEraseLabelsByContent(cellDef, &label->lab_rect, -1, label->lab_text);
DBWLabelChanged(cellDef, newlab, DBW_ALLWINDOWS); DBWLabelChanged(cellDef, newlab, DBW_ALLWINDOWS);
} }

View File

@ -641,7 +641,7 @@ dbCopyAllLabels(scx, lab, tpath, arg)
DBEraseLabelsByContent(def, &labTargetRect, -1, lab->lab_text); DBEraseLabelsByContent(def, &labTargetRect, -1, lab->lab_text);
DBPutFontLabel(def, &labTargetRect, lab->lab_font, DBPutFontLabel(def, &labTargetRect, lab->lab_font,
lab->lab_size, labRotate, &labOffset, targetPos, lab->lab_size, labRotate, &labOffset, targetPos,
lab->lab_text, lab->lab_type, lab->lab_flags); lab->lab_text, lab->lab_type, lab->lab_flags, lab->lab_port);
if (arg->cla_bbox != NULL) if (arg->cla_bbox != NULL)
{ {
GeoIncludeAll(&labTargetRect, arg->cla_bbox); GeoIncludeAll(&labTargetRect, arg->cla_bbox);
@ -849,7 +849,8 @@ DBCellCopyLabels(scx, mask, xMask, targetUse, pArea)
DBEraseLabelsByContent(def, &labTargetRect, -1, lab->lab_text); DBEraseLabelsByContent(def, &labTargetRect, -1, lab->lab_text);
DBPutFontLabel(def, &labTargetRect, lab->lab_font, DBPutFontLabel(def, &labTargetRect, lab->lab_font,
lab->lab_size, labRotate, &labOffset, targetPos, lab->lab_size, labRotate, &labOffset, targetPos,
lab->lab_text, lab->lab_type, lab->lab_flags); lab->lab_text, lab->lab_type, lab->lab_flags,
lab->lab_port);
if (pArea != NULL) if (pArea != NULL)
(void) GeoIncludeAll(&labTargetRect, pArea); (void) GeoIncludeAll(&labTargetRect, pArea);
} }

View File

@ -668,13 +668,13 @@ dbcConnectLabelFunc(scx, lab, tpath, csa2)
DBEraseLabelsByContent(def, &r, -1, lab->lab_text); DBEraseLabelsByContent(def, &r, -1, lab->lab_text);
DBPutFontLabel(def, &r, lab->lab_font, lab->lab_size, rotate, &offset, DBPutFontLabel(def, &r, lab->lab_font, lab->lab_size, rotate, &offset,
pos, newlabptr, lab->lab_type, lab->lab_flags); pos, newlabptr, lab->lab_type, lab->lab_flags, lab->lab_port);
if (lab->lab_flags & PORT_DIR_MASK) if (lab->lab_flags & PORT_DIR_MASK)
{ {
CellDef *orig_def = scx->scx_use->cu_def; CellDef *orig_def = scx->scx_use->cu_def;
Label *slab; Label *slab;
int lidx = lab->lab_flags & PORT_NUM_MASK; int lidx = lab->lab_port;
TileTypeBitMask *connectMask; TileTypeBitMask *connectMask;
/* Check for equivalent ports. For any found, call */ /* Check for equivalent ports. For any found, call */
@ -688,7 +688,7 @@ dbcConnectLabelFunc(scx, lab, tpath, csa2)
for (slab = orig_def->cd_labels; slab != NULL; slab = slab->lab_next) for (slab = orig_def->cd_labels; slab != NULL; slab = slab->lab_next)
if ((slab->lab_flags & PORT_DIR_MASK) && (slab != lab)) if ((slab->lab_flags & PORT_DIR_MASK) && (slab != lab))
if ((slab->lab_flags & PORT_NUM_MASK) == lidx) if (slab->lab_port == lidx)
{ {
Rect newarea; Rect newarea;
int i, pNum; int i, pNum;

View File

@ -2416,7 +2416,7 @@ dbReadLabels(cellDef, line, len, f, scalen, scaled)
goto nextlabel; goto nextlabel;
} }
/* lab->lab_flags &= ~LABEL_STICKY; */ /* lab->lab_flags &= ~LABEL_STICKY; */
lab->lab_flags |= idx; lab->lab_port = idx;
for (pptr = &ppos[0]; *pptr != '\0'; pptr++) for (pptr = &ppos[0]; *pptr != '\0'; pptr++)
{ {
switch(*pptr) switch(*pptr)
@ -2579,10 +2579,10 @@ dbReadLabels(cellDef, line, len, f, scalen, scaled)
type = rtype; type = rtype;
} }
if (font < 0) if (font < 0)
DBPutLabel(cellDef, &r, orient, text, type, flags); DBPutLabel(cellDef, &r, orient, text, type, flags, 0);
else else
DBPutFontLabel(cellDef, &r, font, size, rotate, &offset, DBPutFontLabel(cellDef, &r, font, size, rotate, &offset,
orient, text, type, flags); orient, text, type, flags, 0);
nextlabel: nextlabel:
if (dbFgets(line, len, f) == NULL) if (dbFgets(line, len, f) == NULL)
@ -2947,8 +2947,7 @@ DBCellWriteFile(cellDef, f)
if (lab->lab_flags & PORT_DIR_SOUTH) strcat(ppos, "s"); if (lab->lab_flags & PORT_DIR_SOUTH) strcat(ppos, "s");
if (lab->lab_flags & PORT_DIR_EAST) strcat(ppos, "e"); if (lab->lab_flags & PORT_DIR_EAST) strcat(ppos, "e");
if (lab->lab_flags & PORT_DIR_WEST) strcat(ppos, "w"); if (lab->lab_flags & PORT_DIR_WEST) strcat(ppos, "w");
sprintf(lstring, "port %d %s", lab->lab_flags & PORT_NUM_MASK, sprintf(lstring, "port %d %s", lab->lab_port, ppos);
ppos);
if (lab->lab_flags & (PORT_USE_MASK | PORT_CLASS_MASK | PORT_SHAPE_MASK)) if (lab->lab_flags & (PORT_USE_MASK | PORT_CLASS_MASK | PORT_SHAPE_MASK))
{ {

View File

@ -91,17 +91,18 @@ DBIsSubcircuit(cellDef)
*/ */
Label * Label *
DBPutLabel(cellDef, rect, align, text, type, flags) DBPutLabel(cellDef, rect, align, text, type, flags, port)
CellDef *cellDef; CellDef *cellDef;
Rect *rect; Rect *rect;
int align; int align;
char *text; char *text;
TileType type; TileType type;
int flags; unsigned short flags;
unsigned int port;
{ {
/* Draw text in a standard X11 font */ /* Draw text in a standard X11 font */
return DBPutFontLabel(cellDef, rect, -1, 0, 0, &GeoOrigin, return DBPutFontLabel(cellDef, rect, -1, 0, 0, &GeoOrigin,
align, text, type, flags); align, text, type, flags, port);
} }
/* /*
@ -128,7 +129,7 @@ DBPutLabel(cellDef, rect, align, text, type, flags)
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
Label * Label *
DBPutFontLabel(cellDef, rect, font, size, rot, offset, align, text, type, flags) DBPutFontLabel(cellDef, rect, font, size, rot, offset, align, text, type, flags, port)
CellDef *cellDef; /* Cell in which label is placed */ CellDef *cellDef; /* Cell in which label is placed */
Rect *rect; /* Location of label; see above for description */ Rect *rect; /* Location of label; see above for description */
int font; /* A vector outline font to use, or -1 for X11 font */ int font; /* A vector outline font to use, or -1 for X11 font */
@ -141,7 +142,8 @@ DBPutFontLabel(cellDef, rect, font, size, rot, offset, align, text, type, flags)
*/ */
char *text; /* Pointer to actual text of label */ char *text; /* Pointer to actual text of label */
TileType type; /* Type of tile to be labelled */ TileType type; /* Type of tile to be labelled */
int flags; /* Label flags */ unsigned short flags; /* Label flags */
unsigned int port; /* Port index (if label is a port, per the flags) */
{ {
Label *lab; Label *lab;
int len, x1, x2, y1, y2, tmp, labx, laby; int len, x1, x2, y1, y2, tmp, labx, laby;
@ -208,6 +210,7 @@ DBPutFontLabel(cellDef, rect, font, size, rot, offset, align, text, type, flags)
} }
lab->lab_type = type; lab->lab_type = type;
lab->lab_flags = flags; lab->lab_flags = flags;
lab->lab_port = port;
lab->lab_rect = *rect; lab->lab_rect = *rect;
lab->lab_next = NULL; lab->lab_next = NULL;
if (cellDef->cd_labels == NULL) if (cellDef->cd_labels == NULL)

View File

@ -434,6 +434,7 @@ typedef Label labelUE;
#define lue_offset lab_offset #define lue_offset lab_offset
#define lue_flags lab_flags #define lue_flags lab_flags
#define lue_text lab_text #define lue_text lab_text
#define lue_port lab_port
/* /*
* labelSize(n) is the size of a labelUE large enough to hold * labelSize(n) is the size of a labelUE large enough to hold
@ -556,7 +557,7 @@ dbUndoLabelForw(up)
lab = DBPutFontLabel(dbUndoLastCell, &up->lue_rect, lab = DBPutFontLabel(dbUndoLastCell, &up->lue_rect,
up->lue_font, up->lue_size, up->lue_rotate, up->lue_font, up->lue_size, up->lue_rotate,
&up->lue_offset, up->lue_just, up->lue_text, &up->lue_offset, up->lue_just, up->lue_text,
up->lue_type, up->lue_flags); up->lue_type, up->lue_flags, up->lue_port);
DBWLabelChanged(dbUndoLastCell, lab, DBW_ALLWINDOWS); DBWLabelChanged(dbUndoLastCell, lab, DBW_ALLWINDOWS);
/* /*

View File

@ -252,9 +252,10 @@ typedef struct label
Point lab_offset; /* Offset relative to origin point, in Point lab_offset; /* Offset relative to origin point, in
* units of (database units / 8) * units of (database units / 8)
*/ */
unsigned int lab_flags; /* Information, especially for unsigned short lab_flags; /* Information, especially for
* marking port labels * marking port labels
*/ */
unsigned int lab_port; /* Port number, if label is a port */
struct label *lab_next; /* Next label in list */ struct label *lab_next; /* Next label in list */
char lab_text[4]; /* Actual text of label. This field char lab_text[4]; /* Actual text of label. This field
* is just a place-holder: the actual * is just a place-holder: the actual
@ -269,46 +270,44 @@ typedef struct label
* Label flags bit fields * Label flags bit fields
*/ */
#define PORT_NUM_MASK 0x003fff /* Mask of port number (up to 16384) */ #define PORT_DIR_MASK 0x00000f /* Mask of all port directions */
#define PORT_DIR_NORTH 0x000001 /* Port allows connection to north */
#define PORT_DIR_EAST 0x000002 /* Port allows connection to east */
#define PORT_DIR_SOUTH 0x000004 /* Port allows connection to south */
#define PORT_DIR_WEST 0x000008 /* Port allows connection to west */
#define PORT_DIR_MASK 0x03c000 /* Mask of all port directions */ #define PORT_CLASS_MASK 0x070 /* Mask of all port classes */
#define PORT_DIR_NORTH 0x004000 /* Port allows connection to north */ #define PORT_CLASS_DEFAULT 0x000 /* Port takes default class */
#define PORT_DIR_EAST 0x008000 /* Port allows connection to east */ #define PORT_CLASS_INPUT 0x010 /* Port is a digital input */
#define PORT_DIR_SOUTH 0x010000 /* Port allows connection to south */ #define PORT_CLASS_OUTPUT 0x020 /* Port is a digital output */
#define PORT_DIR_WEST 0x020000 /* Port allows connection to west */ #define PORT_CLASS_TRISTATE 0x030 /* Port is a tri-state output */
#define PORT_CLASS_BIDIRECTIONAL 0x040 /* Port is analog or digital */
/* bidirectional */
#define PORT_CLASS_FEEDTHROUGH 0x050 /* Port touches no active */
/* devices */
#define PORT_CLASS_MASK 0x1c0000 /* Mask of all port classes */ #define PORT_USE_MASK 0x0780 /* Mask of all port uses */
#define PORT_CLASS_DEFAULT 0x000000 /* Port takes default class */ #define PORT_USE_DEFAULT 0x0000 /* Port takes default use */
#define PORT_CLASS_INPUT 0x040000 /* Port is a digital input */ #define PORT_USE_SIGNAL 0x0080 /* Port is a digital signal */
#define PORT_CLASS_OUTPUT 0x080000 /* Port is a digital output */ #define PORT_USE_ANALOG 0x0100 /* Port is an analog signal */
#define PORT_CLASS_TRISTATE 0x0c0000 /* Port is a tri-state output */ #define PORT_USE_POWER 0x0180 /* Port is a power rail */
#define PORT_CLASS_BIDIRECTIONAL 0x100000 /* Port is analog or digital */ #define PORT_USE_GROUND 0x0200 /* Port is a ground rail */
/* bidirectional */ #define PORT_USE_CLOCK 0x0280 /* Port is a digital clock */
#define PORT_CLASS_FEEDTHROUGH 0x140000 /* Port touches no active */ #define PORT_USE_RESET 0x0300 /* Port is a digital reset */
/* devices */ #define PORT_USE_SCAN 0x0380 /* Port is a digital scan */
#define PORT_USE_TIEOFF 0x0400 /* Port is a tie-off */
#define PORT_USE_MASK 0x03c00000 /* Mask of all port uses */ #define PORT_SHAPE_MASK 0x1800 /* Mask of all port shapes */
#define PORT_USE_DEFAULT 0x00000000 /* Port takes default use */ #define PORT_SHAPE_DEFAULT 0x0000 /* Port takes default shape */
#define PORT_USE_SIGNAL 0x00400000 /* Port is a digital signal */ #define PORT_SHAPE_ABUT 0x0800 /* Port is an abutment shape */
#define PORT_USE_ANALOG 0x00800000 /* Port is an analog signal */ #define PORT_SHAPE_RING 0x1000 /* Port is a ring shape */
#define PORT_USE_POWER 0x00c00000 /* Port is a power rail */ #define PORT_SHAPE_THRU 0x1800 /* Port is a feedthrough shape */
#define PORT_USE_GROUND 0x01000000 /* Port is a ground rail */
#define PORT_USE_CLOCK 0x01400000 /* Port is a digital clock */
#define PORT_USE_RESET 0x01800000 /* Port is a digital reset */
#define PORT_USE_SCAN 0x01c00000 /* Port is a digital scan */
#define PORT_USE_TIEOFF 0x02000000 /* Port is a tie-off */
#define PORT_SHAPE_MASK 0x0c000000 /* Mask of all port shapes */ #define PORT_VISITED 0x2000 /* Bit for checking if a port */
#define PORT_SHAPE_DEFAULT 0x00000000 /* Port takes default shape */
#define PORT_SHAPE_ABUT 0x04000000 /* Port is an abutment shape */
#define PORT_SHAPE_RING 0x08000000 /* Port is a ring shape */
#define PORT_SHAPE_THRU 0x0c000000 /* Port is a feedthrough shape */
#define PORT_VISITED 0x10000000 /* Bit for checking if a port */
/* has been previously visited. */ /* has been previously visited. */
#define LABEL_STICKY 0x20000000 /* Label does not change layers */ #define LABEL_STICKY 0x4000 /* Label does not change layers */
#define LABEL_GENERATE 0x40000000 /* Auto-generated label */ #define LABEL_GENERATE 0x8000 /* Auto-generated label */
/* /*
* Macros for dealing with label rectangles. * Macros for dealing with label rectangles.

View File

@ -1979,8 +1979,10 @@ esHierVisit(hc, cdata)
/* Reset the subcircuit hash table, if using HSPICE format */ /* Reset the subcircuit hash table, if using HSPICE format */
if (esFormat == HSPICE) if (esFormat == HSPICE)
{ {
HashKill(&subcktNameTable);
HashInit(&subcktNameTable, 32, HT_STRINGKEYS); HashInit(&subcktNameTable, 32, HT_STRINGKEYS);
#ifndef UNSORTED_SUBCKT #ifndef UNSORTED_SUBCKT
DQFree(&subcktNameQueue);
DQInit(&subcktNameQueue, 64); DQInit(&subcktNameQueue, 64);
#endif #endif
} }

View File

@ -77,7 +77,7 @@ int esNoModelType; /* index for device type "None" (model-less device) */
* which also are meaningful. * which also are meaningful.
*/ */
HashTable subcktNameTable ; /* the hash table itself */ HashTable subcktNameTable ; /* the hash table itself */
DQueue subcktNameQueue ; /* q used to print it sorted at the end*/ DQueue subcktNameQueue ; /* q used to print it sorted at the end */
fetInfoList esFetInfo[TT_MAXTYPES]; fetInfoList esFetInfo[TT_MAXTYPES];
@ -1005,6 +1005,12 @@ runexttospice:
EFFlatDone(); EFFlatDone();
} }
EFDone(); EFDone();
if (esFormat == HSPICE) {
HashKill(&subcktNameTable);
#ifndef UNSORTED_SUBCKT
DQFree(&subcktNameQueue);
#endif
}
if (esSpiceF) fclose(esSpiceF); if (esSpiceF) fclose(esSpiceF);
@ -1163,6 +1169,12 @@ main(argc, argv)
EFFlatDone(); EFFlatDone();
EFDone(); EFDone();
if (esFormat == HSPICE) {
HashKill(&subcktNameTable);
#ifndef UNSORTED_SUBCKT
DQFree(&subcktNameQueue);
#endif
}
if (esSpiceF) fclose(esSpiceF); if (esSpiceF) fclose(esSpiceF);

View File

@ -645,7 +645,7 @@ extOutputNodes(nodeList, outFile)
{ {
fprintf(outFile, "port \"%s\" %d %d %d %d %d %s\n", fprintf(outFile, "port \"%s\" %d %d %d %d %d %s\n",
ll->ll_label->lab_text, ll->ll_label->lab_text,
ll->ll_label->lab_flags & PORT_NUM_MASK, ll->ll_label->lab_port,
ll->ll_label->lab_rect.r_xbot, ll->ll_label->lab_rect.r_xbot,
ll->ll_label->lab_rect.r_ybot, ll->ll_label->lab_rect.r_ybot,
ll->ll_label->lab_rect.r_xtop, ll->ll_label->lab_rect.r_xtop,

View File

@ -186,7 +186,8 @@ extMakeUnique(def, ll, lreg, lregList, labelHash, option)
int nsuffix, nwarn; int nsuffix, nwarn;
Label saveLab, *lab; Label saveLab, *lab;
Rect r; Rect r;
int flags; unsigned short flags;
int portno;
/* /*
* Make a pass through all labels for all nodes. * Make a pass through all labels for all nodes.
@ -277,17 +278,17 @@ makeUnique:
flags = ll2->ll_label->lab_flags; flags = ll2->ll_label->lab_flags;
if (flags & PORT_DIR_MASK) { if (flags & PORT_DIR_MASK) {
int idx; int idx;
int portno = -1; portno = -1;
/* Find the last port index used in the cell def */ /* Find the last port index used in the cell def */
for (lab = def->cd_labels; lab != NULL; lab = lab->lab_next) for (lab = def->cd_labels; lab != NULL; lab = lab->lab_next)
{ {
idx = lab->lab_flags & PORT_NUM_MASK; idx = lab->lab_port;
if (idx > portno) portno = idx; if (idx > portno) portno = idx;
} }
portno++; portno++;
flags &= ~PORT_NUM_MASK;
flags |= portno;
} }
else
portno = 0;
lab = ll2->ll_label; lab = ll2->ll_label;
saveLab = *lab; saveLab = *lab;
@ -296,7 +297,7 @@ makeUnique:
(void) DBPutFontLabel(def, &saveLab.lab_rect, (void) DBPutFontLabel(def, &saveLab.lab_rect,
saveLab.lab_font, saveLab.lab_size, saveLab.lab_rotate, saveLab.lab_font, saveLab.lab_size, saveLab.lab_rotate,
&saveLab.lab_offset, saveLab.lab_just, name2, &saveLab.lab_offset, saveLab.lab_just, name2,
saveLab.lab_type, flags); saveLab.lab_type, flags, (unsigned int)portno);
ll2->ll_label = (Label *) NULL; ll2->ll_label = (Label *) NULL;
} }

View File

@ -616,7 +616,7 @@ endCoord:
Rect r; Rect r;
r.r_xbot = r.r_xtop = (routeTop->r_r.r_xbot + routeTop->r_r.r_xtop) / 2; r.r_xbot = r.r_xtop = (routeTop->r_r.r_xbot + routeTop->r_r.r_xtop) / 2;
r.r_ybot = r.r_ytop = (routeTop->r_r.r_ybot + routeTop->r_r.r_ytop) / 2; r.r_ybot = r.r_ytop = (routeTop->r_r.r_ybot + routeTop->r_r.r_ytop) / 2;
DBPutLabel(rootDef, &r, GEO_CENTER, netname, routeTop->r_type, 0); DBPutLabel(rootDef, &r, GEO_CENTER, netname, routeTop->r_type, 0, 0);
labeled = TRUE; labeled = TRUE;
} }
@ -1132,7 +1132,7 @@ DefReadPins(f, rootDef, sname, oscale, total)
DBPaint(rootDef, &topRect, rectList->r_type); DBPaint(rootDef, &topRect, rectList->r_type);
DBPutLabel(rootDef, &topRect, -1, pinname, DBPutLabel(rootDef, &topRect, -1, pinname,
rectList->r_type, rectList->r_type,
pinNum | pinDir | pinUse | flags); pinDir | pinUse | flags, pinNum);
freeMagic(rectList); freeMagic(rectList);
rectList = rectList->r_next; rectList = rectList->r_next;
} }
@ -1161,7 +1161,7 @@ DefReadPins(f, rootDef, sname, oscale, total)
DBPaint(rootDef, &topRect, rectList->r_type); DBPaint(rootDef, &topRect, rectList->r_type);
DBPutLabel(rootDef, &topRect, -1, pinname, DBPutLabel(rootDef, &topRect, -1, pinname,
rectList->r_type, rectList->r_type,
pinNum | pinDir | pinUse | flags); pinDir | pinUse | flags, pinNum);
freeMagic(rectList); freeMagic(rectList);
rectList = rectList->r_next; rectList = rectList->r_next;
} }

View File

@ -1299,7 +1299,7 @@ LefReadPort(lefMacro, f, pinName, pinNum, pinDir, pinUse, pinShape, oscale, lann
/* it. */ /* it. */
if (lanno->lab_flags & PORT_DIR_MASK) if (lanno->lab_flags & PORT_DIR_MASK)
pinNum = lanno->lab_flags & PORT_NUM_MASK; pinNum = lanno->lab_port;
else else
{ {
Label *sl; Label *sl;
@ -1310,7 +1310,7 @@ LefReadPort(lefMacro, f, pinName, pinNum, pinDir, pinUse, pinShape, oscale, lann
{ {
if (sl->lab_flags & PORT_DIR_MASK) if (sl->lab_flags & PORT_DIR_MASK)
{ {
idx = sl->lab_flags & PORT_NUM_MASK; idx = sl->lab_port;
if (idx > pinNum) pinNum = idx; if (idx > pinNum) pinNum = idx;
} }
} }
@ -1319,7 +1319,7 @@ LefReadPort(lefMacro, f, pinName, pinNum, pinDir, pinUse, pinShape, oscale, lann
} }
else else
/* Create a new label (non-rendered) */ /* Create a new label (non-rendered) */
DBPutLabel(lefMacro, &rectList->r_r, -1, pinName, rectList->r_type, 0); DBPutLabel(lefMacro, &rectList->r_r, -1, pinName, rectList->r_type, 0, 0);
/* Set this label to be a port */ /* Set this label to be a port */
@ -1607,7 +1607,7 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
else else
{ {
if (lab->lab_flags & PORT_DIR_MASK) if (lab->lab_flags & PORT_DIR_MASK)
pinNum = lab->lab_flags & PORT_NUM_MASK; pinNum = lab->lab_port;
else else
{ {
Label *sl; Label *sl;
@ -1619,7 +1619,7 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
{ {
if (sl->lab_flags & PORT_DIR_MASK) if (sl->lab_flags & PORT_DIR_MASK)
{ {
idx = sl->lab_flags & PORT_NUM_MASK; idx = sl->lab_port;
if (idx > pinNum) pinNum = idx; if (idx > pinNum) pinNum = idx;
} }
} }

View File

@ -1339,7 +1339,7 @@ lefWriteMacro(def, f, scale, setback, pinonly, toplayer, domaster)
if (lab->lab_flags & PORT_DIR_MASK) if (lab->lab_flags & PORT_DIR_MASK)
{ {
curport++; curport++;
idx = lab->lab_flags & PORT_NUM_MASK; idx = (int)lab->lab_port;
if (idx > maxport) if (idx > maxport)
maxport = idx; maxport = idx;
} }
@ -1356,7 +1356,7 @@ lefWriteMacro(def, f, scale, setback, pinonly, toplayer, domaster)
for (lab = def->cd_labels; lab != NULL; lab = lab->lab_next) for (lab = def->cd_labels; lab != NULL; lab = lab->lab_next)
if (lab->lab_flags & PORT_DIR_MASK) if (lab->lab_flags & PORT_DIR_MASK)
if (!(lab->lab_flags & PORT_VISITED)) if (!(lab->lab_flags & PORT_VISITED))
if ((lab->lab_flags & PORT_NUM_MASK) == idx) if (lab->lab_port == idx)
break; break;
} }
else else
@ -1610,7 +1610,7 @@ lefWriteMacro(def, f, scale, setback, pinonly, toplayer, domaster)
for (tlab = lab->lab_next; tlab != (Label *)NULL; tlab = tlab->lab_next) for (tlab = lab->lab_next; tlab != (Label *)NULL; tlab = tlab->lab_next)
if (tlab->lab_flags & PORT_DIR_MASK) if (tlab->lab_flags & PORT_DIR_MASK)
if (!(tlab->lab_flags & PORT_VISITED)) if (!(tlab->lab_flags & PORT_VISITED))
if ((tlab->lab_flags & PORT_NUM_MASK) == idx) if (tlab->lab_port == idx)
{ {
TileTypeBitMask lmask; TileTypeBitMask lmask;
TTMaskSetOnlyType(&lmask, tlab->lab_type); TTMaskSetOnlyType(&lmask, tlab->lab_type);
@ -1637,7 +1637,7 @@ lefWriteMacro(def, f, scale, setback, pinonly, toplayer, domaster)
for (; lab != NULL; lab = lab->lab_next) for (; lab != NULL; lab = lab->lab_next)
if (lab->lab_flags & PORT_DIR_MASK) if (lab->lab_flags & PORT_DIR_MASK)
if (!(lab->lab_flags & PORT_VISITED)) if (!(lab->lab_flags & PORT_VISITED))
if ((lab->lab_flags & PORT_NUM_MASK) == idx) if (lab->lab_port == idx)
break; break;
if (lc.numWrites > 0) if (lc.numWrites > 0)
@ -1660,7 +1660,7 @@ lefWriteMacro(def, f, scale, setback, pinonly, toplayer, domaster)
for (tlab = reflab->lab_next; tlab != NULL; tlab = tlab->lab_next) for (tlab = reflab->lab_next; tlab != NULL; tlab = tlab->lab_next)
{ {
if (tlab->lab_flags & PORT_DIR_MASK) if (tlab->lab_flags & PORT_DIR_MASK)
if ((tlab->lab_flags & PORT_NUM_MASK) == idx) if (tlab->lab_port == idx)
if (strcmp(reflab->lab_text, tlab->lab_text)) if (strcmp(reflab->lab_text, tlab->lab_text))
{ {
TxError("Index %d is used for ports \"%s\" and \"%s\"\n", TxError("Index %d is used for ports \"%s\" and \"%s\"\n",

View File

@ -154,7 +154,7 @@ PlowRandomTest(def)
#endif /* notdef */ #endif /* notdef */
/* Make sure there's always something to undo */ /* Make sure there's always something to undo */
DBPutLabel(def, &def->cd_bbox, -1, "dummylabel", TT_SPACE, 0); DBPutLabel(def, &def->cd_bbox, -1, "dummylabel", TT_SPACE, 0, 0);
/* Undo */ /* Undo */
UndoBackward(1); UndoBackward(1);

View File

@ -494,13 +494,11 @@ ResPrintFHNodes(fp, nodelist, nodename, nidx, celldef)
if (lab->lab_flags & PORT_DIR_MASK) if (lab->lab_flags & PORT_DIR_MASK)
if (!strcmp(lab->lab_text, nodeptr->rn_name)) if (!strcmp(lab->lab_text, nodeptr->rn_name))
{ {
if ((lab->lab_flags & PORT_NUM_MASK) != ResPortIndex) if (lab->lab_port != ResPortIndex)
{ {
lab->lab_flags &= (~(PORT_NUM_MASK)); lab->lab_port = ResPortIndex;
lab->lab_flags |= ResPortIndex;
TxPrintf("Port %s reassigned index %d\n", TxPrintf("Port %s reassigned index %d\n",
lab->lab_text, lab->lab_text, lab->lab_port);
lab->lab_flags & PORT_NUM_MASK);
celldef->cd_flags |= (CDMODIFIED | CDGETNEWSTAMP); celldef->cd_flags |= (CDMODIFIED | CDGETNEWSTAMP);
} }
ResPortIndex++; ResPortIndex++;

View File

@ -1200,8 +1200,7 @@ ResCheckSimNodes(celldef, resisdata)
fprintf(ResFHFile, "\n* Order of arguments to SPICE subcircuit call:\n"); fprintf(ResFHFile, "\n* Order of arguments to SPICE subcircuit call:\n");
for (lab = celldef->cd_labels; lab != NULL; lab = lab->lab_next) for (lab = celldef->cd_labels; lab != NULL; lab = lab->lab_next)
if (lab->lab_flags & PORT_DIR_MASK) if (lab->lab_flags & PORT_DIR_MASK)
fprintf(ResFHFile, "* %d %s\n", lab->lab_flags & PORT_NUM_MASK, fprintf(ResFHFile, "* %d %s\n", lab->lab_port, lab->lab_text);
lab->lab_text);
fprintf(ResFHFile, "\n.end\n"); fprintf(ResFHFile, "\n.end\n");
} }

View File

@ -941,7 +941,8 @@ selTransLabelFunc(label, cellUse, defTransform, transform)
(void) DBPutFontLabel(Select2Def, &finalArea, label->lab_font, (void) DBPutFontLabel(Select2Def, &finalArea, label->lab_font,
label->lab_size, finalRotate, &finalOffset, finalJust, label->lab_size, finalRotate, &finalOffset, finalJust,
label->lab_text, label->lab_type, label->lab_flags); label->lab_text, label->lab_type, label->lab_flags,
label->lab_port);
return 0; return 0;
} }
@ -1255,7 +1256,8 @@ selArrayLFunc(label, use, transform, arrayInfo)
DBEraseLabelsByContent(Select2Def, &current, -1, astr); DBEraseLabelsByContent(Select2Def, &current, -1, astr);
DBPutFontLabel(Select2Def, &current, label->lab_font, DBPutFontLabel(Select2Def, &current, label->lab_font,
label->lab_size, rootRotate, &rootOffset, label->lab_size, rootRotate, &rootOffset,
rootJust, astr, label->lab_type, label->lab_flags); rootJust, astr, label->lab_type,
label->lab_flags, label->lab_port);
current.r_ybot += arrayInfo->ar_ysep; current.r_ybot += arrayInfo->ar_ysep;
current.r_ytop += arrayInfo->ar_ysep; current.r_ytop += arrayInfo->ar_ysep;
xi += only1; xi += only1;

View File

@ -217,7 +217,7 @@ selRemoveLabelPaintFunc(tile, label)
(void) DBPutFontLabel(Select2Def, &label->lab_rect, label->lab_font, (void) DBPutFontLabel(Select2Def, &label->lab_rect, label->lab_font,
label->lab_size, label->lab_rotate, &label->lab_offset, label->lab_size, label->lab_rotate, &label->lab_offset,
label->lab_just, label->lab_text, label->lab_type, label->lab_just, label->lab_text, label->lab_type,
label->lab_flags); label->lab_flags, label->lab_port);
return 1; return 1;
} }