Modified the behavior of the LEF read routine when used to annotate

an existing cell.  If the existing cell has labels but the labels
are defined as point labels (no rectangle defined using specific
layer-purpose pairs), then the LEF macro's port geometry will be
used for the labels.  Because the GDS file can define label sizes
and fonts, which the LEF file cannot, but because the LEF file may
define multiple rectangles per port, the original point label is
given the first port rectangle from the LEF file, while the
remainder of the labels in the LEF file generate new non-rendered
labels in the cell.
This commit is contained in:
Tim Edwards 2019-11-26 10:57:42 -05:00
parent 46eefe8c33
commit a374230d88
1 changed files with 42 additions and 9 deletions

View File

@ -1212,18 +1212,21 @@ LefReadGeometry(lefMacro, f, oscale, do_list)
*
* Side Effects:
* Reads input from file f;
* Paints into the CellDef lefMacro.
* Generates a new label entry in the CellDef lefMacro.
* If "lanno" is not NULL, then the label pointed to by
* lanno is modified.
*
*------------------------------------------------------------
*/
void
LefReadPort(lefMacro, f, pinName, pinNum, pinDir, pinUse, oscale)
LefReadPort(lefMacro, f, pinName, pinNum, pinDir, pinUse, oscale, lanno)
CellDef *lefMacro;
FILE *f;
char *pinName;
int pinNum, pinDir, pinUse;
float oscale;
Label *lanno;
{
Label *newlab;
LinkedRect *rectList;
@ -1235,7 +1238,15 @@ LefReadPort(lefMacro, f, pinName, pinNum, pinDir, pinUse, oscale)
if (pinNum >= 0)
{
/* Label this area */
DBPutLabel(lefMacro, &rectList->r_r, -1, pinName, rectList->r_type, 0);
if (lanno != NULL)
{
/* Modify an existing label */
lanno->lab_rect = rectList->r_r;
lanno->lab_type = rectList->r_type;
}
else
/* Create a new label (non-rendered) */
DBPutLabel(lefMacro, &rectList->r_r, -1, pinName, rectList->r_type, 0);
/* Set this label to be a port */
@ -1243,13 +1254,16 @@ LefReadPort(lefMacro, f, pinName, pinNum, pinDir, pinUse, oscale)
LefError(LEF_ERROR, "Internal error: No labels in cell!\n");
else
{
newlab = lefMacro->cd_lastLabel;
newlab = (lanno != NULL) ? lanno : lefMacro->cd_lastLabel;
if (strcmp(newlab->lab_text, pinName))
LefError(LEF_ERROR, "Internal error: Can't find the label!\n");
else /* Make this a port */
newlab->lab_flags = pinNum | pinUse | pinDir | PORT_DIR_MASK;
}
/* DBAdjustLabels(lefMacro, &rectList->area); */
/* If lanno is non-NULL then the first rectangle in the LEF */
/* port list is used to modify it. All other LEF port geometry */
/* generates new labels in the CellDef. */
if (lanno != NULL) lanno = NULL;
}
freeMagic((char *)rectList);
@ -1383,24 +1397,43 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported)
case LEF_PORT:
if (is_imported)
{
bool needRect = TRUE;
Label *lab;
LefSkipSection(f, NULL);
/* Skip the port geometry but find the pin name and */
/* annotate with the use and direction. Note that */
/* there may be multiple instances of the label. */
/* However, if the label is a point label, then */
/* replace it with the geometry from the LEF file. */
for (lab = lefMacro->cd_labels; lab; lab = lab->lab_next)
{
if (!strcmp(lab->lab_text, pinname))
{
lab->lab_flags &= ~(PORT_USE_MASK | PORT_DIR_MASK |
if (GEO_RECTNULL(&lab->lab_rect))
break;
else
{
needRect = FALSE;
lab->lab_flags &= ~(PORT_USE_MASK | PORT_DIR_MASK |
PORT_CLASS_MASK);
lab->lab_flags = pinNum | pinUse | pinDir | PORT_DIR_MASK;
lab->lab_flags = pinNum | pinUse | pinDir |
PORT_DIR_MASK;
}
}
}
if (needRect)
{
if (lab == NULL)
DBEraseLabelsByContent(lefMacro, NULL, -1, pinname);
LefReadPort(lefMacro, f, pinname, pinNum, pinDir, pinUse,
oscale, lab);
}
else
LefSkipSection(f, NULL);
}
else
LefReadPort(lefMacro, f, pinname, pinNum, pinDir, pinUse, oscale);
LefReadPort(lefMacro, f, pinname, pinNum, pinDir, pinUse, oscale,
NULL);
break;
case LEF_CAPACITANCE:
case LEF_ANTENNADIFF: