Added a "-pinonly" option to "lef write" to restrict the pin area
to what is defined by the label, and no additional surrounding geometry.
This commit is contained in:
parent
521baa91d9
commit
5b00ee7b83
19
lef/lefCmd.c
19
lef/lefCmd.c
|
|
@ -92,6 +92,9 @@ CmdLef(w, cmd)
|
||||||
* other than pin area surrounding labels,
|
* other than pin area surrounding labels,
|
||||||
* with the indicated setback distance.
|
* with the indicated setback distance.
|
||||||
*/
|
*/
|
||||||
|
bool lefPinOnly = FALSE; /* If TRUE, make pins only where labels
|
||||||
|
* are defined, not the whole net.
|
||||||
|
*/
|
||||||
bool lefTopLayer = FALSE; /* If TRUE, only output the topmost
|
bool lefTopLayer = FALSE; /* If TRUE, only output the topmost
|
||||||
* layer used by a pin, and make
|
* layer used by a pin, and make
|
||||||
* all layers below it obstructions.
|
* all layers below it obstructions.
|
||||||
|
|
@ -234,6 +237,8 @@ CmdLef(w, cmd)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!strncmp(cmd->tx_argv[i], "-pinonly", 8))
|
||||||
|
lefPinOnly = TRUE;
|
||||||
else if (!strncmp(cmd->tx_argv[i], "-toplayer", 9))
|
else if (!strncmp(cmd->tx_argv[i], "-toplayer", 9))
|
||||||
lefTopLayer = TRUE;
|
lefTopLayer = TRUE;
|
||||||
else if (!strncmp(cmd->tx_argv[i], "-nomaster", 9))
|
else if (!strncmp(cmd->tx_argv[i], "-nomaster", 9))
|
||||||
|
|
@ -244,8 +249,8 @@ CmdLef(w, cmd)
|
||||||
}
|
}
|
||||||
else goto wrongNumArgs;
|
else goto wrongNumArgs;
|
||||||
}
|
}
|
||||||
LefWriteAll(selectedUse, lefTopCell, lefTech, lefHide, lefTopLayer,
|
LefWriteAll(selectedUse, lefTopCell, lefTech, lefHide, lefPinOnly,
|
||||||
lefDoMaster, recurse);
|
lefTopLayer, lefDoMaster, recurse);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LEF_WRITE:
|
case LEF_WRITE:
|
||||||
|
|
@ -286,6 +291,13 @@ CmdLef(w, cmd)
|
||||||
else
|
else
|
||||||
TxPrintf("The \"-hide\" option is only for lef write\n");
|
TxPrintf("The \"-hide\" option is only for lef write\n");
|
||||||
}
|
}
|
||||||
|
else if (!strncmp(cmd->tx_argv[i], "-pinonly", 8))
|
||||||
|
{
|
||||||
|
if (is_lef)
|
||||||
|
lefPinOnly = TRUE;
|
||||||
|
else
|
||||||
|
TxPrintf("The \"-pinonly\" option is only for lef write\n");
|
||||||
|
}
|
||||||
else if (!strncmp(cmd->tx_argv[i], "-toplayer", 9))
|
else if (!strncmp(cmd->tx_argv[i], "-toplayer", 9))
|
||||||
{
|
{
|
||||||
if (is_lef)
|
if (is_lef)
|
||||||
|
|
@ -339,7 +351,8 @@ CmdLef(w, cmd)
|
||||||
DefWriteCell(selectedUse->cu_def, namep, allSpecial, units);
|
DefWriteCell(selectedUse->cu_def, namep, allSpecial, units);
|
||||||
else
|
else
|
||||||
LefWriteCell(selectedUse->cu_def, namep, selectedUse->cu_def
|
LefWriteCell(selectedUse->cu_def, namep, selectedUse->cu_def
|
||||||
== EditRootDef, lefTech, lefHide, lefTopLayer, lefDoMaster);
|
== EditRootDef, lefTech, lefHide, lefPinOnly,
|
||||||
|
lefTopLayer, lefDoMaster);
|
||||||
break;
|
break;
|
||||||
case LEF_HELP:
|
case LEF_HELP:
|
||||||
wrongNumArgs:
|
wrongNumArgs:
|
||||||
|
|
|
||||||
|
|
@ -1095,11 +1095,12 @@ LefWritePinHeader(f, lab)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
lefWriteMacro(def, f, scale, setback, toplayer, domaster)
|
lefWriteMacro(def, f, scale, setback, pinonly, toplayer, domaster)
|
||||||
CellDef *def; /* Def for which to generate LEF output */
|
CellDef *def; /* Def for which to generate LEF output */
|
||||||
FILE *f; /* Output to this file */
|
FILE *f; /* Output to this file */
|
||||||
float scale; /* Output distance units conversion factor */
|
float scale; /* Output distance units conversion factor */
|
||||||
int setback; /* If >= 0, hide all detail except pins inside setback */
|
int setback; /* If >= 0, hide all detail except pins inside setback */
|
||||||
|
bool pinonly; /* If TRUE, only place pins where labels are defined */
|
||||||
bool toplayer; /* If TRUE, only output topmost layer of pins */
|
bool toplayer; /* If TRUE, only output topmost layer of pins */
|
||||||
bool domaster; /* If TRUE, write masterslice layers */
|
bool domaster; /* If TRUE, write masterslice layers */
|
||||||
{
|
{
|
||||||
|
|
@ -1416,13 +1417,18 @@ lefWriteMacro(def, f, scale, setback, toplayer, domaster)
|
||||||
scx.scx_area = labr;
|
scx.scx_area = labr;
|
||||||
SelectClear();
|
SelectClear();
|
||||||
|
|
||||||
if (setback == 0)
|
if ((pinonly == TRUE) || (setback == 0))
|
||||||
{
|
{
|
||||||
Rect carea;
|
Rect carea;
|
||||||
labelLinkedList *newlll;
|
labelLinkedList *newlll;
|
||||||
|
|
||||||
SelectChunk(&scx, lab->lab_type, 0, &carea, FALSE);
|
if (pinonly == TRUE)
|
||||||
if (GEO_RECTNULL(&carea)) carea = labr;
|
carea = labr;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SelectChunk(&scx, lab->lab_type, 0, &carea, FALSE);
|
||||||
|
if (GEO_RECTNULL(&carea)) carea = labr;
|
||||||
|
}
|
||||||
|
|
||||||
/* 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 */
|
||||||
|
|
@ -1445,12 +1451,18 @@ lefWriteMacro(def, f, scale, setback, toplayer, domaster)
|
||||||
Rect carea;
|
Rect carea;
|
||||||
|
|
||||||
/* For -hide with setback, select the entire net and then */
|
/* For -hide with setback, select the entire net and then */
|
||||||
/* remove the part inside the setback area. Note that this */
|
/* remove the part inside the setback area. */
|
||||||
/* does not check if this causes the label to disappear. */
|
|
||||||
|
|
||||||
SelectNet(&scx, lab->lab_type, 0, NULL, FALSE);
|
SelectNet(&scx, lab->lab_type, 0, NULL, FALSE);
|
||||||
GEO_EXPAND(&boundary, -setback, &carea);
|
GEO_EXPAND(&boundary, -setback, &carea);
|
||||||
SelRemoveArea(&carea, &DBAllButSpaceAndDRCBits);
|
SelRemoveArea(&carea, &DBAllButSpaceAndDRCBits);
|
||||||
|
|
||||||
|
/* Paint over the label area so that labels do not simply */
|
||||||
|
/* disappear by being inside the setback area. */
|
||||||
|
|
||||||
|
pNum = DBPlane(lab->lab_type);
|
||||||
|
DBPaintPlane(SelectDef->cd_planes[pNum], &labr,
|
||||||
|
DBStdPaintTbl(lab->lab_type, pNum), (PaintUndoInfo *) NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SelectNet(&scx, lab->lab_type, 0, NULL, FALSE);
|
SelectNet(&scx, lab->lab_type, 0, NULL, FALSE);
|
||||||
|
|
@ -1964,11 +1976,13 @@ lefGetProperties(stackItem, i, clientData)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
LefWriteAll(rootUse, writeTopCell, lefTech, lefHide, lefTopLayer, lefDoMaster, recurse)
|
LefWriteAll(rootUse, writeTopCell, lefTech, lefHide, lefPinOnly, lefTopLayer,
|
||||||
|
lefDoMaster, recurse)
|
||||||
CellUse *rootUse;
|
CellUse *rootUse;
|
||||||
bool writeTopCell;
|
bool writeTopCell;
|
||||||
bool lefTech;
|
bool lefTech;
|
||||||
int lefHide;
|
int lefHide;
|
||||||
|
bool lefPinOnly;
|
||||||
bool lefTopLayer;
|
bool lefTopLayer;
|
||||||
bool lefDoMaster;
|
bool lefDoMaster;
|
||||||
bool recurse;
|
bool recurse;
|
||||||
|
|
@ -2040,7 +2054,7 @@ LefWriteAll(rootUse, writeTopCell, lefTech, lefHide, lefTopLayer, lefDoMaster, r
|
||||||
{
|
{
|
||||||
def->cd_client = (ClientData) 0;
|
def->cd_client = (ClientData) 0;
|
||||||
if (!SigInterruptPending)
|
if (!SigInterruptPending)
|
||||||
lefWriteMacro(def, f, scale, lefHide, lefTopLayer, lefDoMaster);
|
lefWriteMacro(def, f, scale, lefHide, lefPinOnly, lefTopLayer, lefDoMaster);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End the LEF file */
|
/* End the LEF file */
|
||||||
|
|
@ -2104,12 +2118,14 @@ lefDefPushFunc(use, recurse)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
LefWriteCell(def, outName, isRoot, lefTech, lefHide, lefTopLayer, lefDoMaster)
|
LefWriteCell(def, outName, isRoot, lefTech, lefHide, lefPinOnly, lefTopLayer,
|
||||||
|
lefDoMaster)
|
||||||
CellDef *def; /* Cell being written */
|
CellDef *def; /* Cell being written */
|
||||||
char *outName; /* Name of output file, or NULL. */
|
char *outName; /* Name of output file, or NULL. */
|
||||||
bool isRoot; /* Is this the root cell? */
|
bool isRoot; /* Is this the root cell? */
|
||||||
bool lefTech; /* Output layer information if TRUE */
|
bool lefTech; /* Output layer information if TRUE */
|
||||||
int lefHide; /* Hide detail other than pins if >= 0 */
|
int lefHide; /* Hide detail other than pins if >= 0 */
|
||||||
|
bool lefPinOnly; /* Only generate pins on label areas */
|
||||||
bool lefTopLayer; /* Use only topmost layer of pin if TRUE */
|
bool lefTopLayer; /* Use only topmost layer of pin if TRUE */
|
||||||
bool lefDoMaster; /* Write masterslice layers if TRUE */
|
bool lefDoMaster; /* Write masterslice layers if TRUE */
|
||||||
{
|
{
|
||||||
|
|
@ -2145,7 +2161,7 @@ LefWriteCell(def, outName, isRoot, lefTech, lefHide, lefTopLayer, lefDoMaster)
|
||||||
HashKill(&propHashTbl);
|
HashKill(&propHashTbl);
|
||||||
HashKill(&siteHashTbl);
|
HashKill(&siteHashTbl);
|
||||||
}
|
}
|
||||||
lefWriteMacro(def, f, scale, lefHide, lefTopLayer, lefDoMaster);
|
lefWriteMacro(def, f, scale, lefHide, lefPinOnly, lefTopLayer, lefDoMaster);
|
||||||
|
|
||||||
/* End the LEF file */
|
/* End the LEF file */
|
||||||
fprintf(f, "END LIBRARY\n\n");
|
fprintf(f, "END LIBRARY\n\n");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue