From 7a42b5b6adf8f5a32634cc593a1b3d50cb774a47 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 23 Oct 2019 09:33:37 -0400 Subject: [PATCH 1/3] Fixed a long-standing error in which "ext2spice merge" fails when used with "ext2spice hierarchy on" because the device index is not reset between calls to output cells in the hierarchy, leading to a mismatch of the index for all cells after the first one output. --- cif/CIFrdtech.c | 4 +++- ext2spice/ext2hier.c | 3 +++ ext2spice/ext2spice.c | 53 ++++++++++++++++++++++++++++++++++++++++++- ext2spice/ext2spice.h | 30 +++++------------------- 4 files changed, 64 insertions(+), 26 deletions(-) diff --git a/cif/CIFrdtech.c b/cif/CIFrdtech.c index 297ad7b6..3777df9a 100644 --- a/cif/CIFrdtech.c +++ b/cif/CIFrdtech.c @@ -621,8 +621,10 @@ CIFReadTechLine(sectionName, argc, argv) if (argc >= 3) { - if(!strncmp(argv[argc - 1], "nanom", 5)) + if (!strncmp(argv[argc - 1], "nanom", 5)) cifCurReadStyle->crs_multiplier = 10; + else if (!strncmp(argv[argc - 1], "angstr", 6)) + cifCurReadStyle->crs_multiplier = 100; } if (cifCurReadStyle->crs_scaleFactor <= 0) diff --git a/ext2spice/ext2hier.c b/ext2spice/ext2hier.c index 07143cb0..c1afcb00 100644 --- a/ext2spice/ext2hier.c +++ b/ext2spice/ext2hier.c @@ -1883,6 +1883,9 @@ esHierVisit(hc, cdata) EFHierVisitNodes(hcf, spcnodeHierVisit, (ClientData) NULL); freeMagic(resstr); } + + /* Reset device merge index for next cell */ + if (esMergeDevsA || esMergeDevsC) esFMIndex = 0; } if ((def != topdef) || (def->def_flags & DEF_SUBCIRCUIT) || (locDoSubckt == TRUE)) diff --git a/ext2spice/ext2spice.c b/ext2spice/ext2spice.c index 8885bdce..e2e560f4 100644 --- a/ext2spice/ext2spice.c +++ b/ext2spice/ext2spice.c @@ -264,7 +264,8 @@ CmdExtToSpice(w, cmd) "extresist [on|off] incorporate information from extresist", "resistor tee [on|off] model resistor capacitance as a T-network", "scale [on|off] use .option card for scaling", - "subcircuits [on|off] standard cells become subcircuit calls", + "subcircuits [top|descend] [on|off|auto]\n" + " standard cells become subcircuit calls", "hierarchy [on|off] output hierarchical spice for LVS", "blackbox [on|off] output abstract views as black-box entries", "renumber [on|off] on = number instances X1, X2, etc.\n" @@ -2095,6 +2096,56 @@ esOutputResistor(dev, hierName, scale, term1, term2, has_model, l, w, dscale) } } +/* Report if device at index n has been deleted due to merging */ + +bool +devIsKilled(n) + int n; +{ + return (esFMult[(n)] <= (float)0.0) ? TRUE : FALSE; +} + +/* Add a dev's multiplier to the table and grow it if necessary */ + +void +addDevMult(f) + float f; +{ + int i; + float *op; + + if (esFMult == NULL) { + esFMult = (float *) mallocMagic((unsigned) (esFMSize*sizeof(float))); + } + else if (esFMIndex >= esFMSize) + { + op = esFMult; + esFMSize *= 2; + esFMult = (float *)mallocMagic((unsigned)(esFMSize * sizeof(float))); + for (i = 0; i < esFMSize / 2; i++) esFMult[i] = op[i]; + if (op) freeMagic(op); + } + esFMult[esFMIndex++] = f; +} + +/* Set the multiplier value f of device at index i */ + +void +setDevMult(i, f) + int i; + float f; +{ + esFMult[i] = f; +} + +/* Get the multiplier value of the device at the current index esFMIndex */ + +float +getCurDevMult() +{ + return (esFMult && (esFMIndex > 0)) ? esFMult[esFMIndex-1] : (float)1.0; +} + /* * ---------------------------------------------------------------------------- * diff --git a/ext2spice/ext2spice.h b/ext2spice/ext2spice.h index 4247d61e..065650d1 100644 --- a/ext2spice/ext2spice.h +++ b/ext2spice/ext2spice.h @@ -36,6 +36,11 @@ extern char *nodeSpiceHierName(); extern devMerge *mkDevMerge(); extern bool extHierSDAttr(); +extern bool devIsKilled(); +extern float getCurDevMult(); +extern void addDevMult(); +extern void setDevMult(); + /* Options specific to ext2spice */ extern bool esDoExtResis; extern bool esDoPorts; @@ -166,7 +171,7 @@ typedef struct { /* *--------------------------------------------------------- - * Variables & macros used for merging parallel devs + * Variables used for merging parallel devs * The merging of devs is based on the fact that spcdevVisit * visits the devs in the same order all the time so the * value of esFMult[i] keeps the multiplier for the ith dev @@ -174,31 +179,8 @@ typedef struct { */ #define DEV_KILLED ((float) -1.0) #define FMULT_SIZE (1<<10) - -#define devIsKilled(n) ( esFMult[(n)] <=(float)0.0 ) - #define DEV_KILLED ((float) -1.0) - -/* macro to add a dev's multiplier to the table and grow it if necessary */ -#define addDevMult(f) \ -{ \ - if ( esFMult == NULL ) { \ - esFMult = (float *) mallocMagic((unsigned) (esFMSize*sizeof(float))); \ - } else if ( esFMIndex >= esFMSize ) { \ - int i; \ - float *op = esFMult ; \ - esFMult = (float *) mallocMagic((unsigned) ((esFMSize = esFMSize*2)*sizeof(float))); \ - for ( i = 0 ; i < esFMSize/2 ; i++ ) esFMult[i] = op[i]; \ - if (op) freeMagic(op); \ - } \ - esFMult[esFMIndex++] = (float)(f); \ -} - -#define setDevMult(i,f) { esFMult[(i)] = (float)(f); } - -#define getCurDevMult() ((esFMult && (esFMIndex > 0)) ? esFMult[esFMIndex-1] : (float)1.0) - #ifdef MAGIC_WRAPPER #define atoCap(s) ((EFCapValue)atof(s)) #endif From 71108a88b4b273a7f04983a6fd100fde247de74e Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 23 Oct 2019 10:18:54 -0400 Subject: [PATCH 2/3] Corrected an error that prevented the "load" command from working with the simultaneous use of "scaled" and one of the options "-force" or "-nowindow", due to the use of a wrong index value. --- commands/CmdLQ.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/commands/CmdLQ.c b/commands/CmdLQ.c index 12250815..02c04b6f 100644 --- a/commands/CmdLQ.c +++ b/commands/CmdLQ.c @@ -318,7 +318,7 @@ CmdLabel(w, cmd) * Implement the "load" command. * * Usage: - * load [name [scaled n [d]]] [-force] + * load [name [scaled n [d]]] [-force] [-nowindow] * * If name is supplied, then the window containing the point tool is * remapped so as to edit the cell with the given name. @@ -364,15 +364,16 @@ CmdLoad(w, cmd) locargc--; ignoreTech = TRUE; } - if (locargc >= 4 && !strncmp(cmd->tx_argv[2], "scale", 5) && + if ((locargc >= 4) && !strncmp(cmd->tx_argv[2], "scale", 5) && StrIsInt(cmd->tx_argv[3])) { n = atoi(cmd->tx_argv[3]); - if (cmd->tx_argc == 5 && StrIsInt(cmd->tx_argv[4])) + if ((locargc == 5) && StrIsInt(cmd->tx_argv[4])) d = atoi(cmd->tx_argv[4]); else if (locargc != 4) { - TxError("Usage: %s name scaled n [d]\n", cmd->tx_argv[0]); + TxError("Usage: %s name scaled n [d] [-force] [-nowindow]\n", + cmd->tx_argv[0]); return; } DBLambda[0] *= d; @@ -381,7 +382,8 @@ CmdLoad(w, cmd) } else if (!ignoreTech && !noWindow) { - TxError("Usage: %s [name [scaled n [d]]]\n", cmd->tx_argv[0]); + TxError("Usage: %s name [scaled n [d]] [-force] [-nowindow]\n", + cmd->tx_argv[0]); return; } } From d9ccd711d908451945421b11f0fe8bdb0e5a88e4 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 23 Oct 2019 11:59:59 -0400 Subject: [PATCH 3/3] Realizing that the "no such node" messages were directly related to the below-threshold coupling caps being removed from the hierarchy, added code to suppress the error message when it is clearly related to a below-threshold cap that has been removed. --- ext2spice/ext2hier.c | 2 +- extflat/EFflat.c | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ext2spice/ext2hier.c b/ext2spice/ext2hier.c index c1afcb00..7348a0d6 100644 --- a/ext2spice/ext2hier.c +++ b/ext2spice/ext2hier.c @@ -1656,7 +1656,7 @@ esMakePorts(hc, cdata) // In particular, this keeps parasitics out of the netlist for // LVS purposes if "cthresh" is set to "infinite". - if (fabs((double)conn->conn_cap) < EFCapThreshold) continue; + if (fabs((double)conn->conn_cap / 1000) < EFCapThreshold) continue; portname = name; updef = def; diff --git a/extflat/EFflat.c b/extflat/EFflat.c index 9725def9..337c477e 100644 --- a/extflat/EFflat.c +++ b/extflat/EFflat.c @@ -1018,14 +1018,23 @@ efFlatSingleCap(hc, name1, name2, conn) EFNode *n1, *n2; HashEntry *he; EFCoupleKey ck; + static char msg0[] = "cap(1)"; + static char msg1[] = "cap(2)"; + char *msg; + + /* Connections that are below threshold (ext2spice hierarchy only) */ + /* will be missing. Do not generate errors for these. */ - if ((he = EFHNLook(hc->hc_hierName, name1, "cap(1)")) == NULL) + msg = (fabs((double)conn->conn_cap / 1000) < EFCapThreshold) ? NULL : msg0; + + if ((he = EFHNLook(hc->hc_hierName, name1, msg)) == NULL) return 0; n1 = ((EFNodeName *) HashGetValue(he))->efnn_node; if (n1->efnode_flags & EF_KILLED) return 0; - if ((he = EFHNLook(hc->hc_hierName, name2, "cap(2)")) == NULL) + if (msg) msg = msg1; + if ((he = EFHNLook(hc->hc_hierName, name2, msg)) == NULL) return 0; n2 = ((EFNodeName *) HashGetValue(he))->efnn_node; if (n2->efnode_flags & EF_KILLED)