Corrected the "lef write -hide" method to keep a list of the areas

of the pin port geometry and using those areas to create the
spacing between them and the obstruction layer.  Otherwise, the
existing method used different databases (source vs. flattened) to
find the pin area, and they did not always agree on the exact
dimensions, leading to spacing errors within the LEF view.
This commit is contained in:
Tim Edwards 2020-03-20 21:29:29 -04:00
parent ad13e48a07
commit a1ee1720f1
1 changed files with 33 additions and 31 deletions

View File

@ -618,6 +618,14 @@ MakeLegalLEFSyntax(text)
return rstr; return rstr;
} }
/* Linked list structure for holding PIN PORT geometry areas */
typedef struct _labelLinkedList {
Label *lll_label;
Rect lll_area;
struct _labelLinkedList *lll_next;
} labelLinkedList;
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -657,6 +665,7 @@ lefWriteMacro(def, f, scale, hide)
char *LEFtext; char *LEFtext;
HashSearch hs; HashSearch hs;
HashEntry *he; HashEntry *he;
labelLinkedList *lll = NULL;
extern CellDef *SelectDef; extern CellDef *SelectDef;
@ -959,7 +968,11 @@ lefWriteMacro(def, f, scale, hide)
if (hide) if (hide)
{ {
SelectChunk(&scx, lab->lab_type, 0, NULL, FALSE); Rect carea;
labelLinkedList *newlll;
SelectChunk(&scx, lab->lab_type, 0, &carea, FALSE);
if (GEO_RECTNULL(&carea)) carea = lab->lab_rect;
/* Note that a sticky label could be placed over multiple */ /* Note that a sticky label could be placed over multiple */
/* tile types, which would cause SelectChunk to fail. So */ /* tile types, which would cause SelectChunk to fail. So */
@ -967,8 +980,15 @@ lefWriteMacro(def, f, scale, hide)
/* SelectDef. */ /* SelectDef. */
pNum = DBPlane(lab->lab_type); pNum = DBPlane(lab->lab_type);
DBPaintPlane(SelectDef->cd_planes[pNum], &lab->lab_rect, DBPaintPlane(SelectDef->cd_planes[pNum], &carea,
DBStdPaintTbl(lab->lab_type, pNum), (PaintUndoInfo *) NULL); DBStdPaintTbl(lab->lab_type, pNum), (PaintUndoInfo *) NULL);
/* Remember this area since it's going to get erased */
newlll = (labelLinkedList *)mallocMagic(sizeof(labelLinkedList));
newlll->lll_label = lab;
newlll->lll_area = carea;
newlll->lll_next = lll;
lll = newlll;
} }
else else
SelectNet(&scx, lab->lab_type, 0, NULL, FALSE); SelectNet(&scx, lab->lab_type, 0, NULL, FALSE);
@ -1064,6 +1084,7 @@ lefWriteMacro(def, f, scale, hide)
/* cell. Otherwise, this routine can block internal pins. */ /* cell. Otherwise, this routine can block internal pins. */
Rect layerBound; Rect layerBound;
labelLinkedList *thislll;
for (ttype = TT_TECHDEPBASE; ttype < DBNumTypes; ttype++) for (ttype = TT_TECHDEPBASE; ttype < DBNumTypes; ttype++)
if (TTMaskHasType(&lmask, ttype)) if (TTMaskHasType(&lmask, ttype))
@ -1080,39 +1101,20 @@ lefWriteMacro(def, f, scale, hide)
DBPaint(lc.lefYank, &layerBound, ttype); DBPaint(lc.lefYank, &layerBound, ttype);
} }
scx.scx_use = &lefSourceUse; for (thislll = lll; thislll; thislll = thislll->lll_next)
for (lab = def->cd_labels; lab != NULL; lab = lab->lab_next)
{ {
Rect carea;
int lspace; int lspace;
labr = lab->lab_rect; lab = thislll->lll_label;
/* Force label area to be non-degenerate */ lspace = DRCGetDefaultLayerSpacing(lab->lab_type, lab->lab_type);
if (labr.r_xbot >= labr.r_xtop) thislll->lll_area.r_xbot -= lspace;
{ thislll->lll_area.r_ybot -= lspace;
labr.r_xbot--; thislll->lll_area.r_xtop += lspace;
labr.r_xtop++; thislll->lll_area.r_ytop += lspace;
} DBErase(lc.lefYank, &thislll->lll_area, lab->lab_type);
if (labr.r_ybot >= labr.r_ytop)
{ freeMagic(thislll);
labr.r_ybot--;
labr.r_ytop++;
}
if (lab->lab_flags & PORT_DIR_MASK)
{
scx.scx_area = labr;
SelectClear();
SelectChunk(&scx, lab->lab_type, 0, &carea, FALSE);
if (GEO_RECTNULL(&carea)) carea = lab->lab_rect;
lspace = DRCGetDefaultLayerSpacing(lab->lab_type, lab->lab_type);
carea.r_xbot -= lspace;
carea.r_ybot -= lspace;
carea.r_xtop += lspace;
carea.r_ytop += lspace;
DBErase(lc.lefYank, &carea, lab->lab_type);
}
} }
} }
else else