Added support for "PORT SHAPE" in LEF files.
This commit is contained in:
parent
d4c2b878f5
commit
483f15360a
|
|
@ -1209,7 +1209,7 @@ portFindLabel(editDef, port, unique, nonEdit)
|
|||
* Usage:
|
||||
* port make|makeall [num] [connect_direction(s)]
|
||||
* or
|
||||
* port [name|num] class|use|index [value]
|
||||
* port [name|num] class|use|shape|index [value]
|
||||
*
|
||||
* num is the index of the port, usually beginning with 1. This indicates
|
||||
* the order in which ports should be written to a subcircuit record
|
||||
|
|
@ -1238,16 +1238,17 @@ portFindLabel(editDef, port, unique, nonEdit)
|
|||
|
||||
#define PORT_CLASS 0
|
||||
#define PORT_USE 1
|
||||
#define PORT_INDEX 2
|
||||
#define PORT_EQUIV 3
|
||||
#define PORT_EXISTS 4
|
||||
#define PORT_CONNECT 5
|
||||
#define PORT_LAST 6
|
||||
#define PORT_MAKE 7
|
||||
#define PORT_MAKEALL 8
|
||||
#define PORT_NAME 9
|
||||
#define PORT_REMOVE 10
|
||||
#define PORT_HELP 11
|
||||
#define PORT_SHAPE 2
|
||||
#define PORT_INDEX 3
|
||||
#define PORT_EQUIV 4
|
||||
#define PORT_EXISTS 5
|
||||
#define PORT_CONNECT 6
|
||||
#define PORT_LAST 7
|
||||
#define PORT_MAKE 8
|
||||
#define PORT_MAKEALL 9
|
||||
#define PORT_NAME 10
|
||||
#define PORT_REMOVE 11
|
||||
#define PORT_HELP 12
|
||||
|
||||
void
|
||||
CmdPort(w, cmd)
|
||||
|
|
@ -1268,6 +1269,7 @@ CmdPort(w, cmd)
|
|||
{
|
||||
"class [type] get [set] port class type",
|
||||
"use [type] get [set] port use type",
|
||||
"shape [type] get [set] port shape type",
|
||||
"index [number] get [set] port number",
|
||||
"equivalent [number] make port equivalent to another port",
|
||||
"exists report if a label is a port or not",
|
||||
|
|
@ -1329,6 +1331,25 @@ CmdPort(w, cmd)
|
|||
PORT_USE_CLOCK
|
||||
};
|
||||
|
||||
static char *cmdPortShapeTypes[] =
|
||||
{
|
||||
"default",
|
||||
"abutment",
|
||||
"ring",
|
||||
"feedthrough",
|
||||
"feedthru",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int cmdShapeToBitmask[] =
|
||||
{
|
||||
PORT_SHAPE_DEFAULT,
|
||||
PORT_SHAPE_ABUT,
|
||||
PORT_SHAPE_RING,
|
||||
PORT_SHAPE_THRU,
|
||||
PORT_SHAPE_THRU
|
||||
};
|
||||
|
||||
argstart = 1;
|
||||
argc = cmd->tx_argc;
|
||||
if (argc > 6 || argc == 1)
|
||||
|
|
@ -1601,6 +1622,51 @@ CmdPort(w, cmd)
|
|||
goto portWrongNumArgs;
|
||||
break;
|
||||
|
||||
case PORT_SHAPE:
|
||||
if (argc == 2)
|
||||
{
|
||||
type = lab->lab_flags & PORT_SHAPE_MASK;
|
||||
for (idx = 0; cmdPortShapeTypes[idx] != NULL; idx++)
|
||||
if (cmdShapeToBitmask[idx] == type)
|
||||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_AppendResult(magicinterp, cmdPortShapeTypes[idx],
|
||||
NULL);
|
||||
#else
|
||||
TxPrintf("Shape = %s\n", cmdPortShapeTypes[idx]);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (argc == 3)
|
||||
{
|
||||
type = Lookup(cmd->tx_argv[argstart + 1], cmdPortShapeTypes);
|
||||
if (type < 0)
|
||||
{
|
||||
TxError("Usage: port shape <type>, where <type> is one of:\n");
|
||||
for (msg = &(cmdPortShapeTypes[0]); *msg != NULL; msg++)
|
||||
{
|
||||
TxError(" %s\n", *msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (sl = lab; sl; sl = sl->lab_next)
|
||||
{
|
||||
if (((sl->lab_flags & PORT_DIR_MASK) != 0) &&
|
||||
!strcmp(sl->lab_text, lab->lab_text))
|
||||
{
|
||||
sl->lab_flags &= (~PORT_SHAPE_MASK);
|
||||
sl->lab_flags |= (PORT_SHAPE_MASK & cmdShapeToBitmask[type]);
|
||||
}
|
||||
}
|
||||
editDef->cd_flags |= (CDMODIFIED | CDGETNEWSTAMP);
|
||||
}
|
||||
}
|
||||
else
|
||||
goto portWrongNumArgs;
|
||||
break;
|
||||
|
||||
case PORT_INDEX:
|
||||
if (argc == 2)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1873,7 +1873,7 @@ dbReadLabels(cellDef, line, len, f, scalen, scaled)
|
|||
int scalen; /* Scale up by this factor */
|
||||
int scaled; /* Scale down by this factor */
|
||||
{
|
||||
char layername[50], text[1024], port_use[50], port_class[50];
|
||||
char layername[50], text[1024], port_use[50], port_class[50], port_shape[50];
|
||||
TileType type;
|
||||
int ntok, orient, size, rotate, font, flags;
|
||||
Point offset;
|
||||
|
|
@ -1982,9 +1982,9 @@ dbReadLabels(cellDef, line, len, f, scalen, scaled)
|
|||
|
||||
if (((lab = cellDef->cd_lastLabel) == NULL) ||
|
||||
(lab->lab_flags & PORT_DIR_MASK) ||
|
||||
(((ntok = sscanf(line, "port %d %4s %49s %49s",
|
||||
&idx, ppos, port_use, port_class)) != 2) &&
|
||||
(ntok != 4)))
|
||||
(((ntok = sscanf(line, "port %d %4s %49s %49s %49s",
|
||||
&idx, ppos, port_use, port_class, port_shape)) != 2) &&
|
||||
(ntok != 4) && (ntok != 5)))
|
||||
{
|
||||
TxError("Skipping bad \"port\" line: %s", line);
|
||||
goto nextlabel;
|
||||
|
|
@ -2009,7 +2009,7 @@ dbReadLabels(cellDef, line, len, f, scalen, scaled)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (ntok == 4)
|
||||
if (ntok >= 4)
|
||||
{
|
||||
switch(port_use[0])
|
||||
{
|
||||
|
|
@ -2060,7 +2060,26 @@ dbReadLabels(cellDef, line, len, f, scalen, scaled)
|
|||
TxError("Ignoring unknown \"port\" use: %s", port_use);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ntok == 5) {
|
||||
switch(port_shape[0])
|
||||
{
|
||||
case 'a':
|
||||
lab->lab_flags |= PORT_SHAPE_ABUT;
|
||||
break;
|
||||
case 'r':
|
||||
lab->lab_flags |= PORT_SHAPE_RING;
|
||||
break;
|
||||
case 'f':
|
||||
lab->lab_flags |= PORT_SHAPE_THRU;
|
||||
break;
|
||||
case 'd':
|
||||
lab->lab_flags |= PORT_SHAPE_DEFAULT;
|
||||
break;
|
||||
default:
|
||||
TxError("Ignoring unknown \"port\" shape: %s", port_shape);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
goto nextlabel;
|
||||
}
|
||||
|
|
@ -2505,7 +2524,7 @@ DBCellWriteFile(cellDef, f)
|
|||
sprintf(lstring, "port %d %s", lab->lab_flags & PORT_NUM_MASK,
|
||||
ppos);
|
||||
|
||||
if (lab->lab_flags & (PORT_USE_MASK | PORT_CLASS_MASK))
|
||||
if (lab->lab_flags & (PORT_USE_MASK | PORT_CLASS_MASK | PORT_SHAPE_MASK))
|
||||
{
|
||||
switch (lab->lab_flags & PORT_USE_MASK)
|
||||
{
|
||||
|
|
@ -2550,6 +2569,19 @@ DBCellWriteFile(cellDef, f)
|
|||
strcat(lstring, " default");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (lab->lab_flags & PORT_SHAPE_MASK)
|
||||
{
|
||||
case PORT_SHAPE_ABUT:
|
||||
strcat(lstring, " abutment");
|
||||
break;
|
||||
case PORT_SHAPE_RING:
|
||||
strcat(lstring, " ring");
|
||||
break;
|
||||
case PORT_SHAPE_THRU:
|
||||
strcat(lstring, " feedthrough");
|
||||
break;
|
||||
}
|
||||
}
|
||||
strcat(lstring, "\n");
|
||||
FPRINTF(f, lstring);
|
||||
|
|
|
|||
|
|
@ -283,19 +283,24 @@ typedef struct label
|
|||
#define PORT_CLASS_FEEDTHROUGH 0x50000 /* Port touches no active */
|
||||
/* devices */
|
||||
|
||||
#define PORT_USE_MASK 0x700000 /* Mask of all port uses */
|
||||
#define PORT_USE_DEFAULT 0x000000 /* Port takes default use */
|
||||
#define PORT_USE_SIGNAL 0x100000 /* Port is a digital signal */
|
||||
#define PORT_USE_ANALOG 0x200000 /* Port is an analog signal */
|
||||
#define PORT_USE_POWER 0x300000 /* Port is a power rail */
|
||||
#define PORT_USE_GROUND 0x400000 /* Port is a ground rail */
|
||||
#define PORT_USE_CLOCK 0x500000 /* Port is a digital clock */
|
||||
#define PORT_USE_MASK 0x0700000 /* Mask of all port uses */
|
||||
#define PORT_USE_DEFAULT 0x0000000 /* Port takes default use */
|
||||
#define PORT_USE_SIGNAL 0x0100000 /* Port is a digital signal */
|
||||
#define PORT_USE_ANALOG 0x0200000 /* Port is an analog signal */
|
||||
#define PORT_USE_POWER 0x0300000 /* Port is a power rail */
|
||||
#define PORT_USE_GROUND 0x0400000 /* Port is a ground rail */
|
||||
#define PORT_USE_CLOCK 0x0500000 /* Port is a digital clock */
|
||||
/* signal */
|
||||
#define PORT_VISITED 0x800000 /* Bit for checking if a port */
|
||||
#define PORT_SHAPE_MASK 0x1800000 /* Mask of all port shapes */
|
||||
#define PORT_SHAPE_DEFAULT 0x0000000 /* Port takes default shape */
|
||||
#define PORT_SHAPE_ABUT 0x0800000 /* Port is an abutment shape */
|
||||
#define PORT_SHAPE_RING 0x1000000 /* Port is a ring shape */
|
||||
#define PORT_SHAPE_THRU 0x1800000 /* Port is a feedthrough shape */
|
||||
#define PORT_VISITED 0x2000000 /* Bit for checking if a port */
|
||||
/* has been previously visited. */
|
||||
|
||||
#define LABEL_STICKY 0x1000000 /* Label does not change layers */
|
||||
#define LABEL_GENERATE 0x2000000 /* Auto-generated label */
|
||||
#define LABEL_STICKY 0x4000000 /* Label does not change layers */
|
||||
#define LABEL_GENERATE 0x8000000 /* Auto-generated label */
|
||||
|
||||
/*
|
||||
* Macros for dealing with label rectangles.
|
||||
|
|
|
|||
|
|
@ -1269,11 +1269,11 @@ LefReadGeometry(lefMacro, f, oscale, do_list)
|
|||
*/
|
||||
|
||||
void
|
||||
LefReadPort(lefMacro, f, pinName, pinNum, pinDir, pinUse, oscale, lanno)
|
||||
LefReadPort(lefMacro, f, pinName, pinNum, pinDir, pinUse, pinShape, oscale, lanno)
|
||||
CellDef *lefMacro;
|
||||
FILE *f;
|
||||
char *pinName;
|
||||
int pinNum, pinDir, pinUse;
|
||||
int pinNum, pinDir, pinUse, pinShape;
|
||||
float oscale;
|
||||
Label *lanno;
|
||||
{
|
||||
|
|
@ -1333,8 +1333,8 @@ LefReadPort(lefMacro, f, pinName, pinNum, pinDir, pinUse, oscale, lanno)
|
|||
else
|
||||
/* Make this a port, and make it a sticky label so that */
|
||||
/* it is guaranteed to be on the layer on which it is defined */
|
||||
newlab->lab_flags = pinNum | pinUse | pinDir | PORT_DIR_MASK |
|
||||
LABEL_STICKY;
|
||||
newlab->lab_flags = pinNum | pinUse | pinDir | pinShape |
|
||||
PORT_DIR_MASK | LABEL_STICKY;
|
||||
}
|
||||
/* If lanno is non-NULL then the first rectangle in the LEF */
|
||||
/* port list is used to modify it. All other LEF port geometry */
|
||||
|
|
@ -1382,6 +1382,7 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
|
|||
int keyword, subkey;
|
||||
int pinDir = PORT_CLASS_DEFAULT;
|
||||
int pinUse = PORT_USE_DEFAULT;
|
||||
int pinShape = PORT_SHAPE_DEFAULT;
|
||||
|
||||
static char *pin_keys[] = {
|
||||
"DIRECTION",
|
||||
|
|
@ -1440,6 +1441,21 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
|
|||
PORT_USE_CLOCK
|
||||
};
|
||||
|
||||
static char *pin_shapes[] = {
|
||||
"DEFAULT",
|
||||
"ABUTMENT",
|
||||
"RING",
|
||||
"FEEDTHRU",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int lef_shape_to_bitmask[] = {
|
||||
PORT_SHAPE_DEFAULT,
|
||||
PORT_SHAPE_ABUT,
|
||||
PORT_SHAPE_RING,
|
||||
PORT_SHAPE_THRU
|
||||
};
|
||||
|
||||
while ((token = LefNextToken(f, TRUE)) != NULL)
|
||||
{
|
||||
keyword = Lookup(token, pin_keys);
|
||||
|
|
@ -1470,6 +1486,15 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
|
|||
pinUse = lef_use_to_bitmask[subkey];
|
||||
LefEndStatement(f);
|
||||
break;
|
||||
case LEF_SHAPE:
|
||||
token = LefNextToken(f, TRUE);
|
||||
subkey = Lookup(token, pin_shapes);
|
||||
if (subkey < 0)
|
||||
LefError(LEF_ERROR, "Improper SHAPE statement\n");
|
||||
else
|
||||
pinShape = lef_shape_to_bitmask[subkey];
|
||||
LefEndStatement(f);
|
||||
break;
|
||||
case LEF_PORT:
|
||||
if (is_imported)
|
||||
{
|
||||
|
|
@ -1511,8 +1536,8 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
|
|||
}
|
||||
needRect = FALSE;
|
||||
lab->lab_flags &= ~(PORT_USE_MASK | PORT_DIR_MASK |
|
||||
PORT_CLASS_MASK);
|
||||
lab->lab_flags = pinNum | pinUse | pinDir |
|
||||
PORT_CLASS_MASK | PORT_SHAPE_MASK);
|
||||
lab->lab_flags = pinNum | pinUse | pinDir | pinShape |
|
||||
PORT_DIR_MASK;
|
||||
}
|
||||
}
|
||||
|
|
@ -1522,14 +1547,14 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
|
|||
if (lab == NULL)
|
||||
DBEraseLabelsByContent(lefMacro, NULL, -1, pinname);
|
||||
LefReadPort(lefMacro, f, pinname, pinNum, pinDir, pinUse,
|
||||
oscale, lab);
|
||||
pinShape, oscale, lab);
|
||||
}
|
||||
else
|
||||
LefSkipSection(f, NULL);
|
||||
}
|
||||
else
|
||||
LefReadPort(lefMacro, f, pinname, pinNum, pinDir, pinUse, oscale,
|
||||
NULL);
|
||||
LefReadPort(lefMacro, f, pinname, pinNum, pinDir, pinUse,
|
||||
pinShape, oscale, NULL);
|
||||
break;
|
||||
case LEF_CAPACITANCE:
|
||||
case LEF_ANTENNADIFF:
|
||||
|
|
@ -1540,7 +1565,6 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
|
|||
case LEF_ANTENNAPARCUT:
|
||||
case LEF_ANTENNAMAX:
|
||||
case LEF_ANTENNAMAXSIDE:
|
||||
case LEF_SHAPE:
|
||||
case LEF_NETEXPR:
|
||||
LefEndStatement(f); /* Ignore. . . */
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -833,6 +833,23 @@ LefWritePinHeader(f, lab)
|
|||
}
|
||||
fprintf(f, " ;\n");
|
||||
}
|
||||
if (lab->lab_flags & PORT_SHAPE_MASK)
|
||||
{
|
||||
fprintf(f, IN1 "SHAPE ");
|
||||
switch(lab->lab_flags & PORT_SHAPE_MASK)
|
||||
{
|
||||
case PORT_SHAPE_ABUT:
|
||||
fprintf(f, "ABUTMENT");
|
||||
break;
|
||||
case PORT_SHAPE_RING:
|
||||
fprintf(f, "RING");
|
||||
break;
|
||||
case PORT_SHAPE_THRU:
|
||||
fprintf(f, "FEEDTHRU");
|
||||
break;
|
||||
}
|
||||
fprintf(f, " ;\n");
|
||||
}
|
||||
#ifdef MAGIC_WRAPPER
|
||||
else
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue