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:
|
* Usage:
|
||||||
* port make|makeall [num] [connect_direction(s)]
|
* port make|makeall [num] [connect_direction(s)]
|
||||||
* or
|
* 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
|
* 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
|
* 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_CLASS 0
|
||||||
#define PORT_USE 1
|
#define PORT_USE 1
|
||||||
#define PORT_INDEX 2
|
#define PORT_SHAPE 2
|
||||||
#define PORT_EQUIV 3
|
#define PORT_INDEX 3
|
||||||
#define PORT_EXISTS 4
|
#define PORT_EQUIV 4
|
||||||
#define PORT_CONNECT 5
|
#define PORT_EXISTS 5
|
||||||
#define PORT_LAST 6
|
#define PORT_CONNECT 6
|
||||||
#define PORT_MAKE 7
|
#define PORT_LAST 7
|
||||||
#define PORT_MAKEALL 8
|
#define PORT_MAKE 8
|
||||||
#define PORT_NAME 9
|
#define PORT_MAKEALL 9
|
||||||
#define PORT_REMOVE 10
|
#define PORT_NAME 10
|
||||||
#define PORT_HELP 11
|
#define PORT_REMOVE 11
|
||||||
|
#define PORT_HELP 12
|
||||||
|
|
||||||
void
|
void
|
||||||
CmdPort(w, cmd)
|
CmdPort(w, cmd)
|
||||||
|
|
@ -1268,6 +1269,7 @@ CmdPort(w, cmd)
|
||||||
{
|
{
|
||||||
"class [type] get [set] port class type",
|
"class [type] get [set] port class type",
|
||||||
"use [type] get [set] port use type",
|
"use [type] get [set] port use type",
|
||||||
|
"shape [type] get [set] port shape type",
|
||||||
"index [number] get [set] port number",
|
"index [number] get [set] port number",
|
||||||
"equivalent [number] make port equivalent to another port",
|
"equivalent [number] make port equivalent to another port",
|
||||||
"exists report if a label is a port or not",
|
"exists report if a label is a port or not",
|
||||||
|
|
@ -1329,6 +1331,25 @@ CmdPort(w, cmd)
|
||||||
PORT_USE_CLOCK
|
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;
|
argstart = 1;
|
||||||
argc = cmd->tx_argc;
|
argc = cmd->tx_argc;
|
||||||
if (argc > 6 || argc == 1)
|
if (argc > 6 || argc == 1)
|
||||||
|
|
@ -1601,6 +1622,51 @@ CmdPort(w, cmd)
|
||||||
goto portWrongNumArgs;
|
goto portWrongNumArgs;
|
||||||
break;
|
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:
|
case PORT_INDEX:
|
||||||
if (argc == 2)
|
if (argc == 2)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1873,7 +1873,7 @@ dbReadLabels(cellDef, line, len, f, scalen, scaled)
|
||||||
int scalen; /* Scale up by this factor */
|
int scalen; /* Scale up by this factor */
|
||||||
int scaled; /* Scale down 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;
|
TileType type;
|
||||||
int ntok, orient, size, rotate, font, flags;
|
int ntok, orient, size, rotate, font, flags;
|
||||||
Point offset;
|
Point offset;
|
||||||
|
|
@ -1982,9 +1982,9 @@ dbReadLabels(cellDef, line, len, f, scalen, scaled)
|
||||||
|
|
||||||
if (((lab = cellDef->cd_lastLabel) == NULL) ||
|
if (((lab = cellDef->cd_lastLabel) == NULL) ||
|
||||||
(lab->lab_flags & PORT_DIR_MASK) ||
|
(lab->lab_flags & PORT_DIR_MASK) ||
|
||||||
(((ntok = sscanf(line, "port %d %4s %49s %49s",
|
(((ntok = sscanf(line, "port %d %4s %49s %49s %49s",
|
||||||
&idx, ppos, port_use, port_class)) != 2) &&
|
&idx, ppos, port_use, port_class, port_shape)) != 2) &&
|
||||||
(ntok != 4)))
|
(ntok != 4) && (ntok != 5)))
|
||||||
{
|
{
|
||||||
TxError("Skipping bad \"port\" line: %s", line);
|
TxError("Skipping bad \"port\" line: %s", line);
|
||||||
goto nextlabel;
|
goto nextlabel;
|
||||||
|
|
@ -2009,7 +2009,7 @@ dbReadLabels(cellDef, line, len, f, scalen, scaled)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ntok == 4)
|
if (ntok >= 4)
|
||||||
{
|
{
|
||||||
switch(port_use[0])
|
switch(port_use[0])
|
||||||
{
|
{
|
||||||
|
|
@ -2060,7 +2060,26 @@ dbReadLabels(cellDef, line, len, f, scalen, scaled)
|
||||||
TxError("Ignoring unknown \"port\" use: %s", port_use);
|
TxError("Ignoring unknown \"port\" use: %s", port_use);
|
||||||
break;
|
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;
|
goto nextlabel;
|
||||||
}
|
}
|
||||||
|
|
@ -2505,7 +2524,7 @@ DBCellWriteFile(cellDef, f)
|
||||||
sprintf(lstring, "port %d %s", lab->lab_flags & PORT_NUM_MASK,
|
sprintf(lstring, "port %d %s", lab->lab_flags & PORT_NUM_MASK,
|
||||||
ppos);
|
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)
|
switch (lab->lab_flags & PORT_USE_MASK)
|
||||||
{
|
{
|
||||||
|
|
@ -2550,6 +2569,19 @@ DBCellWriteFile(cellDef, f)
|
||||||
strcat(lstring, " default");
|
strcat(lstring, " default");
|
||||||
break;
|
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");
|
strcat(lstring, "\n");
|
||||||
FPRINTF(f, lstring);
|
FPRINTF(f, lstring);
|
||||||
|
|
|
||||||
|
|
@ -283,19 +283,24 @@ typedef struct label
|
||||||
#define PORT_CLASS_FEEDTHROUGH 0x50000 /* Port touches no active */
|
#define PORT_CLASS_FEEDTHROUGH 0x50000 /* Port touches no active */
|
||||||
/* devices */
|
/* devices */
|
||||||
|
|
||||||
#define PORT_USE_MASK 0x700000 /* Mask of all port uses */
|
#define PORT_USE_MASK 0x0700000 /* Mask of all port uses */
|
||||||
#define PORT_USE_DEFAULT 0x000000 /* Port takes default use */
|
#define PORT_USE_DEFAULT 0x0000000 /* Port takes default use */
|
||||||
#define PORT_USE_SIGNAL 0x100000 /* Port is a digital signal */
|
#define PORT_USE_SIGNAL 0x0100000 /* Port is a digital signal */
|
||||||
#define PORT_USE_ANALOG 0x200000 /* Port is an analog signal */
|
#define PORT_USE_ANALOG 0x0200000 /* Port is an analog signal */
|
||||||
#define PORT_USE_POWER 0x300000 /* Port is a power rail */
|
#define PORT_USE_POWER 0x0300000 /* Port is a power rail */
|
||||||
#define PORT_USE_GROUND 0x400000 /* Port is a ground rail */
|
#define PORT_USE_GROUND 0x0400000 /* Port is a ground rail */
|
||||||
#define PORT_USE_CLOCK 0x500000 /* Port is a digital clock */
|
#define PORT_USE_CLOCK 0x0500000 /* Port is a digital clock */
|
||||||
/* signal */
|
/* 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. */
|
/* has been previously visited. */
|
||||||
|
|
||||||
#define LABEL_STICKY 0x1000000 /* Label does not change layers */
|
#define LABEL_STICKY 0x4000000 /* Label does not change layers */
|
||||||
#define LABEL_GENERATE 0x2000000 /* Auto-generated label */
|
#define LABEL_GENERATE 0x8000000 /* Auto-generated label */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macros for dealing with label rectangles.
|
* Macros for dealing with label rectangles.
|
||||||
|
|
|
||||||
|
|
@ -1269,11 +1269,11 @@ LefReadGeometry(lefMacro, f, oscale, do_list)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
LefReadPort(lefMacro, f, pinName, pinNum, pinDir, pinUse, oscale, lanno)
|
LefReadPort(lefMacro, f, pinName, pinNum, pinDir, pinUse, pinShape, oscale, lanno)
|
||||||
CellDef *lefMacro;
|
CellDef *lefMacro;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char *pinName;
|
char *pinName;
|
||||||
int pinNum, pinDir, pinUse;
|
int pinNum, pinDir, pinUse, pinShape;
|
||||||
float oscale;
|
float oscale;
|
||||||
Label *lanno;
|
Label *lanno;
|
||||||
{
|
{
|
||||||
|
|
@ -1333,8 +1333,8 @@ LefReadPort(lefMacro, f, pinName, pinNum, pinDir, pinUse, oscale, lanno)
|
||||||
else
|
else
|
||||||
/* Make this a port, and make it a sticky label so that */
|
/* 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 */
|
/* it is guaranteed to be on the layer on which it is defined */
|
||||||
newlab->lab_flags = pinNum | pinUse | pinDir | PORT_DIR_MASK |
|
newlab->lab_flags = pinNum | pinUse | pinDir | pinShape |
|
||||||
LABEL_STICKY;
|
PORT_DIR_MASK | LABEL_STICKY;
|
||||||
}
|
}
|
||||||
/* If lanno is non-NULL then the first rectangle in the LEF */
|
/* If lanno is non-NULL then the first rectangle in the LEF */
|
||||||
/* port list is used to modify it. All other LEF port geometry */
|
/* 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 keyword, subkey;
|
||||||
int pinDir = PORT_CLASS_DEFAULT;
|
int pinDir = PORT_CLASS_DEFAULT;
|
||||||
int pinUse = PORT_USE_DEFAULT;
|
int pinUse = PORT_USE_DEFAULT;
|
||||||
|
int pinShape = PORT_SHAPE_DEFAULT;
|
||||||
|
|
||||||
static char *pin_keys[] = {
|
static char *pin_keys[] = {
|
||||||
"DIRECTION",
|
"DIRECTION",
|
||||||
|
|
@ -1440,6 +1441,21 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
|
||||||
PORT_USE_CLOCK
|
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)
|
while ((token = LefNextToken(f, TRUE)) != NULL)
|
||||||
{
|
{
|
||||||
keyword = Lookup(token, pin_keys);
|
keyword = Lookup(token, pin_keys);
|
||||||
|
|
@ -1470,6 +1486,15 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
|
||||||
pinUse = lef_use_to_bitmask[subkey];
|
pinUse = lef_use_to_bitmask[subkey];
|
||||||
LefEndStatement(f);
|
LefEndStatement(f);
|
||||||
break;
|
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:
|
case LEF_PORT:
|
||||||
if (is_imported)
|
if (is_imported)
|
||||||
{
|
{
|
||||||
|
|
@ -1511,8 +1536,8 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
|
||||||
}
|
}
|
||||||
needRect = FALSE;
|
needRect = FALSE;
|
||||||
lab->lab_flags &= ~(PORT_USE_MASK | PORT_DIR_MASK |
|
lab->lab_flags &= ~(PORT_USE_MASK | PORT_DIR_MASK |
|
||||||
PORT_CLASS_MASK);
|
PORT_CLASS_MASK | PORT_SHAPE_MASK);
|
||||||
lab->lab_flags = pinNum | pinUse | pinDir |
|
lab->lab_flags = pinNum | pinUse | pinDir | pinShape |
|
||||||
PORT_DIR_MASK;
|
PORT_DIR_MASK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1522,14 +1547,14 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
|
||||||
if (lab == NULL)
|
if (lab == NULL)
|
||||||
DBEraseLabelsByContent(lefMacro, NULL, -1, pinname);
|
DBEraseLabelsByContent(lefMacro, NULL, -1, pinname);
|
||||||
LefReadPort(lefMacro, f, pinname, pinNum, pinDir, pinUse,
|
LefReadPort(lefMacro, f, pinname, pinNum, pinDir, pinUse,
|
||||||
oscale, lab);
|
pinShape, oscale, lab);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LefSkipSection(f, NULL);
|
LefSkipSection(f, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LefReadPort(lefMacro, f, pinname, pinNum, pinDir, pinUse, oscale,
|
LefReadPort(lefMacro, f, pinname, pinNum, pinDir, pinUse,
|
||||||
NULL);
|
pinShape, oscale, NULL);
|
||||||
break;
|
break;
|
||||||
case LEF_CAPACITANCE:
|
case LEF_CAPACITANCE:
|
||||||
case LEF_ANTENNADIFF:
|
case LEF_ANTENNADIFF:
|
||||||
|
|
@ -1540,7 +1565,6 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
|
||||||
case LEF_ANTENNAPARCUT:
|
case LEF_ANTENNAPARCUT:
|
||||||
case LEF_ANTENNAMAX:
|
case LEF_ANTENNAMAX:
|
||||||
case LEF_ANTENNAMAXSIDE:
|
case LEF_ANTENNAMAXSIDE:
|
||||||
case LEF_SHAPE:
|
|
||||||
case LEF_NETEXPR:
|
case LEF_NETEXPR:
|
||||||
LefEndStatement(f); /* Ignore. . . */
|
LefEndStatement(f); /* Ignore. . . */
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -833,6 +833,23 @@ LefWritePinHeader(f, lab)
|
||||||
}
|
}
|
||||||
fprintf(f, " ;\n");
|
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
|
#ifdef MAGIC_WRAPPER
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue