From 67d0d8c3f091f60b8a4f46c65cc33b30b610c6ee Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 7 Jan 2021 15:19:36 -0500 Subject: [PATCH] Corrected the use of the global substrate node name; this has been restricted to its original intent, which is to replace the long name formed from the plane short name and the "minfinity" coordinate. This avoids issues with conflicting substrate names derived from a real layer such as pwell. Also, the global substrate node name now returns the variable name without the "$" in front if the variable has not been set to anything. This avoids potential syntax errors in the netlist. --- VERSION | 2 +- commands/CmdFI.c | 4 +- extract/ExtBasic.c | 199 +++++++++++++++++++++++++++++-------------- extract/ExtHard.c | 17 +--- extract/ExtUnique.c | 2 +- extract/extractInt.h | 23 +---- 6 files changed, 140 insertions(+), 107 deletions(-) diff --git a/VERSION b/VERSION index f67731d6..e02f50e2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.111 +8.3.112 diff --git a/commands/CmdFI.c b/commands/CmdFI.c index ca4d60bd..04b5c4aa 100644 --- a/commands/CmdFI.c +++ b/commands/CmdFI.c @@ -1618,8 +1618,8 @@ CmdFindNetProc(nodename, use, rect, warn_not_found) /* go to that point (transformed to the top level of the design */ /* hierarchy). */ - /* see extract/extractInt.h for the format of the node, found in */ - /* extMakeNodeNumPrint(), which is a macro, not a subroutine. */ + /* see extract/extBasic.c for the format of the node, found */ + /* in extMakeNodeNumPrint(). */ locvalid = FALSE; if ((xstr = strchr(s, '_')) != NULL) diff --git a/extract/ExtBasic.c b/extract/ExtBasic.c index d835d185..41b33141 100644 --- a/extract/ExtBasic.c +++ b/extract/ExtBasic.c @@ -740,6 +740,139 @@ extOutputNodes(nodeList, outFile) } } +/* + * --------------------------------------------------------------------- + * + * extSubsName -- + * + * Return the name of the substrate node, if the node belongs to + * the substrate region and a global substrate node name has been + * specified by the tech file. If the substrate node name is a + * Tcl variable name, then perform the variable substitution. + * + * Results: + * Pointer to a character string. + * + * Side Effects: + * None. + * + * --------------------------------------------------------------------- + */ + +char * +extSubsName(node) + LabRegion *node; +{ + char *subsName; + + /* If the techfile specifies a global name for the substrate, use */ + /* that in preference to the default "p_x_y#" name. Use this name */ + /* only to substitute for nodes with tiles at -(infinity). */ + + if (ExtCurStyle->exts_globSubstrateName != NULL) + { + if (node->lreg_ll.p_x <= (MINFINITY + 3)) + { + if (ExtCurStyle->exts_globSubstrateName[0] == '$' && + ExtCurStyle->exts_globSubstrateName[1] != '$') + { + // If subsName is a Tcl variable (begins with "$"), make the + // variable substitution, if one exists. Ignore double-$. + // If the variable is undefined in the interpreter, then + // strip the "$" from the front as this is not legal in most + // netlist formats. + + char *varsub = (char *)Tcl_GetVar(magicinterp, + &ExtCurStyle->exts_globSubstrateName[1], + TCL_GLOBAL_ONLY); + return (varsub != NULL) ? varsub : ExtCurStyle->exts_globSubstrateName + + 1; + } + else + return ExtCurStyle->exts_globSubstrateName; + } + else return NULL; + } + return NULL; +} + +/* + * ---------------------------------------------------------------------------- + * + * extMakeNodeNumPrint -- + * + * Construct a node name from the plane number "plane" and lower left Point + * "coord", and place it in the string "buf" (which must be large enough). + * + * Results: + * None. + * + * Side Effects: + * Fills in string "buf". + * + * ---------------------------------------------------------------------------- + */ + +void +extMakeNodeNumPrint(buf, lreg) + char *buf; + LabRegion *lreg; +{ + int plane = lreg->lreg_pnum; + Point *p = &lreg->lreg_ll; + char *subsName; + + subsName = extSubsName(lreg); + if (subsName != NULL) + strcpy(buf, subsName); + else + sprintf(buf, "%s_%s%d_%s%d#", + DBPlaneShortName(plane), + (p->p_x < 0) ? "n": "", abs(p->p_x), + (p->p_y < 0) ? "n": "", abs(p->p_y)); +} + +/* + * ---------------------------------------------------------------------------- + * + * extNodeName -- + * + * Given a pointer to a LabRegion, return a pointer to a string + * that can be printed as the name of the node. If the LabRegion + * has a list of attached labels, use one of the labels; otherwise, + * use its node number. + * + * Results: + * Returns a pointer to a string. If the node had a label, this + * is a pointer to the lab_text field of the first label on the + * label list for the node; otherwise, it is a pointer to a static + * buffer into which we have printed the node number. + * + * Side effects: + * May overwrite the static buffer used to hold the printable + * version of a node number. + * + * ---------------------------------------------------------------------------- + */ + +char * +extNodeName(node) + LabRegion *node; +{ + static char namebuf[256]; /* Big enough to hold a generated nodename */ + LabelList *ll; + + if (node == (LabRegion *) NULL || SigInterruptPending) + return ("(none)"); + + for (ll = node->lreg_labels; ll; ll = ll->ll_next) + if (extLabType(ll->ll_label->lab_text, LABTYPE_NAME)) + return (ll->ll_label->lab_text); + + extMakeNodeNumPrint(namebuf, node); + return (namebuf); +} + /* * ---------------------------------------------------------------------------- * @@ -807,8 +940,7 @@ extFindDuplicateLabels(def, nreg) { r.r_ll = r.r_ur = ll2->ll_label->lab_rect.r_ll; r.r_xbot--, r.r_ybot--, r.r_xtop++, r.r_ytop++; - extMakeNodeNumPrint(name, - np2->nreg_pnum, np2->nreg_ll); + extMakeNodeNumPrint(name, np2); (void) sprintf(message, badmesg, text, name); DBWFeedbackAdd(&r, message, def, 1, STYLE_PALEHIGHLIGHTS); @@ -827,69 +959,6 @@ extFindDuplicateLabels(def, nreg) HashKill(&labelHash); } -/* - * ---------------------------------------------------------------------------- - * - * extNodeName -- - * - * Given a pointer to a LabRegion, return a pointer to a string - * that can be printed as the name of the node. If the LabRegion - * has a list of attached labels, use one of the labels; otherwise, - * use its node number. - * - * Results: - * Returns a pointer to a string. If the node had a label, this - * is a pointer to the lab_text field of the first label on the - * label list for the node; otherwise, it is a pointer to a static - * buffer into which we have printed the node number. - * - * Side effects: - * May overwrite the static buffer used to hold the printable - * version of a node number. - * - * ---------------------------------------------------------------------------- - */ - -char * -extNodeName(node) - LabRegion *node; -{ - static char namebuf[256]; /* Big enough to hold a generated nodename */ - LabelList *ll; - - if (node == (LabRegion *) NULL || SigInterruptPending) - return ("(none)"); - - for (ll = node->lreg_labels; ll; ll = ll->ll_next) - if (extLabType(ll->ll_label->lab_text, LABTYPE_NAME)) - return (ll->ll_label->lab_text); - - /* If the techfile specifies a global name for the substrate, use */ - /* that in preference to the default "p_x_y#" name. */ - - if (((NodeRegion *)node == glob_subsnode) || ((NodeRegion *)node == temp_subsnode)) - { - if (ExtCurStyle->exts_globSubstrateName != NULL) - { - if (ExtCurStyle->exts_globSubstrateName[0] == '$' && - ExtCurStyle->exts_globSubstrateName[1] != '$') - { - // If subsName is a Tcl variable (begins with "$"), make the - // variable substitution, if one exists. Ignore double-$. - - char *varsub = (char *)Tcl_GetVar(magicinterp, - &ExtCurStyle->exts_globSubstrateName[1], - TCL_GLOBAL_ONLY); - return (varsub != NULL) ? varsub : ExtCurStyle->exts_globSubstrateName; - } - else - return ExtCurStyle->exts_globSubstrateName; - } - } - extMakeNodeNumPrint(namebuf, node->lreg_pnum, node->lreg_ll); - return (namebuf); -} - /* * --------------------------------------------------------------------- * diff --git a/extract/ExtHard.c b/extract/ExtHard.c index 7d733caa..1cd48c57 100644 --- a/extract/ExtHard.c +++ b/extract/ExtHard.c @@ -406,22 +406,7 @@ extHardGenerateLabel(scx, reg, arg) Rect r; Point p; - // Modification 9/9/2014 by Tim: - // Convert the treg_ll value up to top-level coordinates. - // Otherwise you end up with a node that is apparently in - // "canonical coordinates", but if you try to find the - // location of the node using the name, you'll end up in - // a random place. It also allows the low-probability - // but possible conflict between this node and another with - // the same name in the parent cell. - // - // Reverted 10/30/2014: Apparently this causes worse - // problems. - // - // GeoTransPoint(&scx->scx_trans, ®->treg_ll, &r.r_ll); - // extMakeNodeNumPrint(gen, reg->treg_pnum, r.r_ll); - - extMakeNodeNumPrint(gen, reg->treg_pnum, reg->treg_ll); + extMakeNodeNumPrint(gen, (LabRegion *)reg); prefixlen = tpath->tp_next - tpath->tp_first; len = strlen(gen) + prefixlen; diff --git a/extract/ExtUnique.c b/extract/ExtUnique.c index accb53fa..f544fc26 100644 --- a/extract/ExtUnique.c +++ b/extract/ExtUnique.c @@ -207,7 +207,7 @@ extMakeUnique(def, ll, lreg, lregList, labelHash, option) nwarn++; r.r_ll = r.r_ur = ll2->ll_label->lab_rect.r_ll; GEO_EXPAND(&r, 1, &r); - extMakeNodeNumPrint(name, lp2->lreg_pnum, lp2->lreg_ll); + extMakeNodeNumPrint(name, lp2); (void) sprintf(message, badmesg, text, name); DBWFeedbackAdd(&r, message, def, 1, STYLE_MEDIUMHIGHLIGHTS); } diff --git a/extract/extractInt.h b/extract/extractInt.h index b6f49489..82d18d51 100644 --- a/extract/extractInt.h +++ b/extract/extractInt.h @@ -239,28 +239,6 @@ typedef struct { CapValue subcap_adjust; } SubCapAdjust; -/* - * The following constructs a node name from the plane number 'n' - * and lower left Point l, and places it in the string 's' (which must - * be large enough). - */ -#define extMakeNodeNumPrint(buf, plane, coord) \ - (void) sprintf((buf), "%s_%s%d_%s%d#", DBPlaneShortName(plane), \ - ((coord).p_x < 0) ? "n": "", abs((coord).p_x), \ - ((coord).p_y < 0) ? "n": "", abs((coord).p_y)) - -/* Old way: cryptic numbers, but a bit shorter - * - * #define extMakeNodeNumPrint(s, n, l) \ - * (void) sprintf((s), "%d_%d_%d#", (n), extCoord((l).p_x), extCoord((l).p_y)) - * - * The following is used to map the full coordinate space into - * the positive integers, for constructing internally generated - * node names. - * - * #define extCoord(x) (((x) < 0) ? (1 - ((x) << 1)) : ((x) << 1)) - */ - /* * Argument passed to filter functions for finding regions. */ @@ -1076,6 +1054,7 @@ extern NodeRegion *extFindNodes(); extern ExtTree *extHierNewOne(); extern int extNbrPushFunc(); extern TileType extGetDevType(); +extern void extMakeNodeNumPrint(); /* --------------------- Miscellaneous globals ------------------------ */