From 31b3c0d8b4569b7b90b9bf7962f60c4de47310d8 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 13 Jun 2023 11:28:46 -0400 Subject: [PATCH] Extended the "lef" command to include a new option "lef nocheck" to create a list of net names to ignore for antenna gate and diffusion area checks. This allows the nets not to have to be selected in their entirity but selected by chunk only. This reduces the time to write LEF on a large layout back to approximately what it was before the change to include the hidden area from "-hide" in the antenna area checks. Plus, it greatly reduces the time to generate LEF for large layouts when not using the "-hide" option. --- VERSION | 2 +- lef/lefCmd.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++-- lef/lefInt.h | 7 +++++ lef/lefWrite.c | 41 +++++++++++++++++---------- 4 files changed, 109 insertions(+), 18 deletions(-) diff --git a/VERSION b/VERSION index 8a88198a..8606ed34 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.402 +8.3.403 diff --git a/lef/lefCmd.c b/lef/lefCmd.c index 66184559..3ae84132 100644 --- a/lef/lefCmd.c +++ b/lef/lefCmd.c @@ -24,6 +24,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "dbwind/dbwind.h" #include "utils/main.h" #include "utils/utils.h" +#include "utils/malloc.h" #include "textio/txcommands.h" #include "commands/commands.h" @@ -37,6 +38,9 @@ int lefDateStamp = -1; /* If not -1, defines the timestamp to use when creating * libraries to make sure that full and abstract views of * the same cell have matching timestamps. */ + +linkedNetName *lefIgnoreNets = NULL; /* Nets names to ignore for antenna area */ + /* * ---------------------------------------------------------------------------- * @@ -65,8 +69,9 @@ int lefDateStamp = -1; /* If not -1, defines the timestamp to use when creating #define LEF_READ 0 #define LEF_WRITE 1 #define LEF_WRITEALL 2 -#define LEF_DATESTAMP 3 -#define LEF_HELP 4 +#define LEF_NOCHECK 3 +#define LEF_DATESTAMP 4 +#define LEF_HELP 5 void CmdLef(w, cmd) @@ -155,6 +160,7 @@ CmdLef(w, cmd) " writeall -all recurse on all subcells of the top-level cell\n" " writeall -hide hide all details other than ports\n" " writeall -hide [dist] hide details in area set back distance dist", + "nocheck [netname ...] ignore antenna area checks on named net(s)", "datestamp [value] force the timestamp of cells read from LEF", "help print this help information", NULL @@ -463,6 +469,73 @@ CmdLef(w, cmd) } break; + case LEF_NOCHECK: + if (!is_lef) + { + TxPrintf("The \"nocheck\" option is only for LEF writes.\n"); + break; + } + if (cmd->tx_argc == 2) + { +#ifdef MAGIC_WRAPPER + if (lefIgnoreNets == NULL) + Tcl_SetObjResult(magicinterp, Tcl_NewStringObj("none", -1)); + else + { + Tcl_Obj *lobj; + linkedNetName *lnn; + + lobj = Tcl_NewListObj(0, NULL); + for (lnn = lefIgnoreNets; lnn; lnn = lnn->lnn_next) + Tcl_ListObjAppendElement(magicinterp, lobj, + Tcl_NewStringObj(lnn->lnn_name, -1)); + + Tcl_SetObjResult(magicinterp, lobj); + } +#else + if (lefIgnoreNets == NULL) + TxPrintf("There are no net names being ignored.\n"); + else + { + linkedNetName *lnn; + + for (lnn = lefIgnoreNets; lnn; lnn = lnn->lnn_next) + TxPrintf("%s ", lnn->lnn_name); + + TxPrintf("\n"); + } +#endif + } + else + { + int i; + char *inet; + linkedNetName *lnn; + + /* This is inefficient, but there should never be more than + * a few items in this list. + */ + for (i = 2; i < cmd->tx_argc; i++) + { + inet = cmd->tx_argv[i]; + if (!strcasecmp(inet, "none")) + { + /* Remove all net names from the list */ + for (lnn = lefIgnoreNets; lnn; lnn = lnn->lnn_next) + freeMagic(lnn); + lefIgnoreNets = NULL; + } + else + { + lnn = (linkedNetName *)mallocMagic(sizeof(linkedNetName)); + lnn->lnn_name = StrDup((char **)NULL, inet); + lnn->lnn_next = lefIgnoreNets; + lefIgnoreNets = lnn; + } + } + } + break; + case LEF_HELP: wrongNumArgs: TxPrintf("The \"%s\" options are:\n", cmd->tx_argv[0]); diff --git a/lef/lefInt.h b/lef/lefInt.h index 1e20f1b0..21e2c88b 100644 --- a/lef/lefInt.h +++ b/lef/lefInt.h @@ -127,10 +127,17 @@ typedef struct { bool has_nets; } NetCount; +/* Linked string structure used to maintain list of nets to ignore */ +typedef struct _linkedNetName { + char *lnn_name; + struct _linkedNetName *lnn_next; +} linkedNetName; + /* External declaration of global variables */ extern int lefCurrentLine; extern HashTable LefInfo; extern HashTable LefNonDefaultRules; +extern linkedNetName *lefIgnoreNets; /* Forward declarations */ diff --git a/lef/lefWrite.c b/lef/lefWrite.c index 88a45201..7dcc6388 100644 --- a/lef/lefWrite.c +++ b/lef/lefWrite.c @@ -1416,6 +1416,8 @@ lefWriteMacro(def, f, scale, setback, pinonly, toplayer, domaster) while (lab != NULL) { int antgatearea, antdiffarea; + linkedNetName *lnn; + bool ignored; labr = lab->lab_rect; @@ -1440,7 +1442,14 @@ lefWriteMacro(def, f, scale, setback, pinonly, toplayer, domaster) scx.scx_area = labr; SelectClear(); - SelectNet(&scx, lab->lab_type, 0, NULL, FALSE); + // Check for net names to ignore for antenna checks. + ignored = FALSE; + for (lnn = lefIgnoreNets; lnn; lnn = lnn->lnn_next) + if (!strcmp(lnn->lnn_name, lab->lab_text)) + ignored = TRUE; + + if (!ignored || (setback != 0)) + SelectNet(&scx, lab->lab_type, 0, NULL, FALSE); // Search for gate and diff types and accumulate antenna // areas. For gates, check for all gate types tied to @@ -1449,26 +1458,28 @@ lefWriteMacro(def, f, scale, setback, pinonly, toplayer, domaster) // statement in the extract section of the techfile. antgatearea = 0; - for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) - { - DBSrPaintArea((Tile *)NULL, SelectDef->cd_planes[pNum], + if (!ignored) + for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) + { + DBSrPaintArea((Tile *)NULL, SelectDef->cd_planes[pNum], &TiPlaneRect, &gatetypemask, lefAccumulateArea, (ClientData) &antgatearea); - // Stop after first plane with geometry to avoid double-counting - // contacts. - if (antgatearea > 0) break; - } + // Stop after first plane with geometry to avoid double-counting + // contacts. + if (antgatearea > 0) break; + } antdiffarea = 0; - for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) - { - DBSrPaintArea((Tile *)NULL, SelectDef->cd_planes[pNum], + if (!ignored) + for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) + { + DBSrPaintArea((Tile *)NULL, SelectDef->cd_planes[pNum], &TiPlaneRect, &difftypemask, lefAccumulateArea, (ClientData) &antdiffarea); - // Stop after first plane with geometry to avoid double-counting - // contacts. - if (antdiffarea > 0) break; - } + // Stop after first plane with geometry to avoid double-counting + // contacts. + if (antdiffarea > 0) break; + } if (setback == 0) {