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) {