From a374230d88fc75dab144c3a6b51327f7abe609e4 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 26 Nov 2019 10:57:42 -0500 Subject: [PATCH] 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. --- lef/lefRead.c | 51 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/lef/lefRead.c b/lef/lefRead.c index 22978f7c..2a8e8ab4 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -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: