diff --git a/ext2sim/ext2sim.c b/ext2sim/ext2sim.c index 0916d047..17277a91 100644 --- a/ext2sim/ext2sim.c +++ b/ext2sim/ext2sim.c @@ -62,7 +62,6 @@ bool esNoAttrs = FALSE; bool esHierAP = FALSE; bool esMergeDevsA = FALSE; /* merge devices of equal length */ bool esMergeDevsC = FALSE; /* merge devices of equal length & width */ -int esCapAccuracy = 1; #else extern bool esDevNodesOnly; @@ -70,7 +69,8 @@ extern bool esNoAttrs; extern bool esHierAP; extern bool esMergeDevsA; extern bool esMergeDevsC; -extern int esCapAccuracy; +extern char esSpiceDefaultGnd[]; +extern char *esSpiceCapNode; #endif bool esDoSimExtResis = FALSE; @@ -690,11 +690,10 @@ runexttosim: EFVisitDevs(simdevVisit, (ClientData)NULL); if (flatFlags & EF_FLATCAPS) { - (void) sprintf( esCapFormat, " %%.%dlf\n", esCapAccuracy); EFVisitCaps(simcapVisit, (ClientData) NULL); } EFVisitResists(simresistVisit, (ClientData) NULL); - (void) sprintf( esCapFormat, " GND %%.%dlf\n", esCapAccuracy); + esSpiceCapNode = esSpiceDefaultGnd; EFVisitNodes(simnodeVisit, (ClientData) NULL); EFFlatDone(NULL); @@ -817,12 +816,10 @@ main(argc, argv) } EFVisitDevs(simdevVisit, (ClientData) NULL); - if (flatFlags & EF_FLATCAPS) { - (void) sprintf( esCapFormat, " %%.%dlf\n", esCapAccuracy); + if (flatFlags & EF_FLATCAPS) EFVisitCaps(simcapVisit, (ClientData) NULL); - } EFVisitResists(simresistVisit, (ClientData) NULL); - (void) sprintf( esCapFormat, " GND %%.%dlf\n", esCapAccuracy); + esSpiceCapNode = esSpiceDefaultGnd; EFVisitNodes(simnodeVisit, (ClientData) NULL); EFFlatDone(NULL); @@ -922,7 +919,7 @@ simParseArgs(pargc, pargv) if (( t = ArgStr(&argc, &argv, "cap-accuracy") ) == NULL) goto usage; - esCapAccuracy = atoi(t); + TxPrintf("Cap accuracy option -y is deprecated.\n"); break; } case 'J': @@ -1535,7 +1532,7 @@ int simcapVisit(hierName1, hierName2, cap) EFHNOut(hierName1, esSimF); fprintf(esSimF, " "); EFHNOut(hierName2, esSimF); - fprintf(esSimF, esCapFormat, cap); + fprintf(esSimF, " %.1lf\n", cap); return 0; } @@ -1618,7 +1615,8 @@ int simnodeVisit(node, res, cap) { fprintf(esSimF, "C "); EFHNOut(hierName, esSimF); - fprintf(esSimF, esCapFormat, cap); + fprintf(esSimF, "%s ", esSpiceCapNode); + fprintf(esSimF, "%.1f\n", cap); } if (res > EFResistThreshold) { diff --git a/ext2spice/ext2hier.c b/ext2spice/ext2hier.c index 99a3c269..7ad50c99 100644 --- a/ext2spice/ext2hier.c +++ b/ext2spice/ext2hier.c @@ -902,7 +902,7 @@ spcdevHierVisit(hc, dev, scale) /* Capacitor is "Cnnn top bottom value" */ /* extraction sets top=gate bottom=source */ - /* extracted units are fF; output is in fF */ + /* extracted units are fF. */ spcdevOutNode(hc->hc_hierName, gate->dterm_node->efnode_name->efnn_hier, @@ -920,8 +920,7 @@ spcdevHierVisit(hc, dev, scale) if (!has_model) { - fprintf(esSpiceF, " %ffF", (double)sdM * - (double)(dev->dev_cap)); + esSIvalue(esSpiceF, 1.0E-15 * (double)sdM * (double)dev->dev_cap); spcHierWriteParams(hc, dev, scale, l, w, sdM); } else @@ -950,7 +949,7 @@ spcdevHierVisit(hc, dev, scale) /* Capacitor is "Cnnn bottom top value" */ /* extraction sets top=source bottom=gate */ - /* extracted units are fF; output is in fF */ + /* extracted units are fF. */ spcdevOutNode(hc->hc_hierName, gate->dterm_node->efnode_name->efnn_hier, @@ -968,8 +967,7 @@ spcdevHierVisit(hc, dev, scale) if (!has_model) { - fprintf(esSpiceF, " %ffF", (double)sdM * - (double)(dev->dev_cap)); + esSIvalue(esSpiceF, 1.0E-15 * (double)sdM * (double)dev->dev_cap); spcHierWriteParams(hc, dev, scale, l, w, sdM); } else @@ -1226,9 +1224,11 @@ spccapHierVisit(hc, hierName1, hierName2, cap) if (fabs(cap) <= EFCapThreshold) return 0; - fprintf(esSpiceF, esSpiceCapFormat, esCapNum++, + fprintf(esSpiceF, "C%d %s %s ", esCapNum++, nodeSpiceHierName(hc, hierName1), - nodeSpiceHierName(hc, hierName2), cap); + nodeSpiceHierName(hc, hierName2)); + esSIvalue(esSpiceF, 1.0E-15 *cap); + fprintf(esSpiceF, "\n"); return 0; } @@ -1397,10 +1397,14 @@ spcnodeHierVisit(hc, node, res, cap) cap = cap / 1000; if (fabs(cap) > EFCapThreshold) { - fprintf(esSpiceF, esSpiceCapFormat, esCapNum++, nsn, cap, - (isConnected) ? "" : - (esFormat == NGSPICE) ? " $ **FLOATING" : - " **FLOATING"); + fprintf(esSpiceF, "C%d %s %s ", esCapNum++, nsn, esSpiceCapNode); + esSIvalue(esSpiceF, 1.0E-15 * cap); + if (!isConnected) + { + if (esFormat == NGSPICE) fprintf(esSpiceF, " $"); + fprintf(esSpiceF, " **FLOATING"); + } + fprintf(esSpiceF, "\n"); } if (node->efnode_attrs && !esNoAttrs) { @@ -2121,18 +2125,17 @@ esHierVisit(hc, cdata) EFHierVisitResists(hcf, spcresistHierVisit, (ClientData)NULL); /* Output coupling capacitances */ - sprintf( esSpiceCapFormat, "C%%d %%s %%s %%.%dlffF\n", esCapAccuracy); EFHierVisitCaps(hcf, spccapHierVisit, (ClientData)NULL); if (EFCompat == FALSE) { /* Find the substrate node */ EFHierVisitNodes(hcf, spcsubHierVisit, (ClientData)&resstr); - if (resstr == NULL) resstr = StrDup((char **)NULL, "0"); + if (resstr == NULL) + resstr = esSpiceDefaultGnd; /* Output lumped capacitance and resistance to substrate */ - sprintf( esSpiceCapFormat, "C%%d %%s %s %%.%dlffF%%s\n", - resstr, esCapAccuracy); + esSpiceCapNode = resstr; EFHierVisitNodes(hcf, spcnodeHierVisit, (ClientData) NULL); freeMagic(resstr); } diff --git a/ext2spice/ext2spice.c b/ext2spice/ext2spice.c index 86da83a8..5ac9f116 100644 --- a/ext2spice/ext2spice.c +++ b/ext2spice/ext2spice.c @@ -56,8 +56,8 @@ bool esMergeNames = TRUE; bool esNoAttrs = FALSE; bool esHierAP = FALSE; char spcesDefaultOut[FNSIZE]; -int esCapAccuracy = 2; -char esSpiceCapFormat[FNSIZE]; +char *esSpiceCapNode; +char esSpiceDefaultGnd[] = "0"; char *spcesOutName = spcesDefaultOut; FILE *esSpiceF = NULL; float esScale = -1.0 ; /* negative if hspice the EFScale/100 otherwise */ @@ -1116,21 +1116,17 @@ runexttospice: EFVisitDevs(spcdevVisit, (ClientData) NULL); TTMaskZero(&initMask); if (flatFlags & EF_FLATCAPS) - { - (void) sprintf( esSpiceCapFormat, "C%%d %%s %%s %%.%dlffF\n", - esCapAccuracy); EFVisitCaps(spccapVisit, (ClientData) NULL); - } + EFVisitResists(spcresistVisit, (ClientData) NULL); EFVisitSubcircuits(subcktVisit, (ClientData) NULL); /* Visit nodes to find the substrate node */ EFVisitNodes(spcsubVisit, (ClientData)&substr); if (substr == NULL) - substr = StrDup((char **)NULL, "0"); + substr = esSpiceDefaultGnd; - (void) sprintf( esSpiceCapFormat, "C%%d %%s %s %%.%dlffF%%s", - substr, esCapAccuracy); + esSpiceCapNode = substr; EFVisitNodes(spcnodeVisit, (ClientData) NULL); if (EFCompat == FALSE) freeMagic(substr); @@ -1295,13 +1291,12 @@ main(argc, argv) EFVisitDevs(devDistJunctVisit, (ClientData) NULL); EFVisitDevs(spcdevVisit, (ClientData) NULL); TTMaskZero(&initMask); - if (flatFlags & EF_FLATCAPS) { - (void) sprintf( esSpiceCapFormat, "C%%d %%s %%s %%.%dlffF\n",esCapAccuracy); + if (flatFlags & EF_FLATCAPS) EFVisitCaps(spccapVisit, (ClientData) NULL); - } + EFVisitResists(spcresistVisit, (ClientData) NULL); EFVisitSubcircuits(subcktVisit, (ClientData) NULL); - (void) sprintf( esSpiceCapFormat, "C%%d %%s GND %%.%dlffF%%s", esCapAccuracy); + esSpiceCapNode = esSpiceDefaultGnd; EFVisitNodes(spcnodeVisit, (ClientData) NULL); if ((esDoSubckt == TRUE) || (locDoSubckt == TRUE)) @@ -1359,10 +1354,10 @@ spcParseArgs(pargc, pargv) { char **argv = *pargv, *cp; int argc = *pargc; + char *ftmp, *t; char usage_text[] = "Usage: ext2spice " - "[-B] [-o spicefile] [-M|-m] [-y cap_digits] " - "[-J flat|hier]\n" + "[-B] [-o spicefile] [-M|-m] [-J flat|hier]\n" "[-f spice2|spice3|hspice|ngspice] [-M] [-m] " "[file]\n"; @@ -1371,66 +1366,66 @@ spcParseArgs(pargc, pargv) case 'd': esDistrJunct = TRUE; break; + case 'M': esMergeDevsA = TRUE; break; + case 'm': esMergeDevsC = TRUE; break; + case 'B': esNoAttrs = TRUE; break; + case 'F': esDevNodesOnly = TRUE; break; + case 'o': if ((spcesOutName = ArgStr(&argc, &argv, "filename")) == NULL) goto usage; break; - case 'f': { - char *ftmp ; - if ((ftmp = ArgStr(&argc, &argv, "format")) == NULL) + case 'f': + if ((ftmp = ArgStr(&argc, &argv, "format")) == NULL) goto usage; - if (strcasecmp(ftmp, "SPICE2") == 0) + if (strcasecmp(ftmp, "SPICE2") == 0) esFormat = SPICE2; - else if (strcasecmp(ftmp, "SPICE3") == 0) + else if (strcasecmp(ftmp, "SPICE3") == 0) esFormat = SPICE3; - else if (strcasecmp(ftmp, "HSPICE") == 0) - { + else if (strcasecmp(ftmp, "HSPICE") == 0) + { esFormat = HSPICE; esScale = -1.0; - } - else if (strcasecmp(ftmp, "NGSPICE") == 0) + } + else if (strcasecmp(ftmp, "NGSPICE") == 0) esFormat = NGSPICE; - else goto usage; - break; - } + else goto usage; + break; + case 'J': - { - char *ftmp ; - - if ((ftmp = ArgStr(&argc, &argv, "hierAP_SD")) == NULL) + if ((ftmp = ArgStr(&argc, &argv, "hierAP_SD")) == NULL) goto usage; - if ( strcasecmp(ftmp, "HIER") == 0 ) + if ( strcasecmp(ftmp, "HIER") == 0 ) esHierAP = TRUE ; - else if ( strcasecmp(ftmp, "FLAT") == 0 ) + else if (strcasecmp(ftmp, "FLAT") == 0 ) esHierAP = FALSE ; - else goto usage; + else goto usage; - break; - } - case 'y': { - char *t; + break; - if (( t = ArgStr(&argc, &argv, "cap-accuracy") ) == NULL) + case 'y': + if ((t = ArgStr(&argc, &argv, "cap-accuracy")) == NULL) goto usage; - esCapAccuracy = atoi(t); - break; - } + TxPrintf("The cap accuracy flag 'y' is deprecated.\n"); + break; + case 'h': /* -h or -help, as suggested by "ext2spice help" */ TxPrintf(usage_text); break; + default: TxError("Unrecognized flag: %s\n", argv[0]); goto usage; @@ -2822,7 +2817,7 @@ spcdevVisit(dev, hc, scale, trans) /* Capacitor is "Cnnn top bottom value" */ /* extraction sets top=gate bottom=source */ - /* extracted units are fF; output is in fF */ + /* extracted units are fF. */ spcdevOutNode(hierName, gate->dterm_node->efnode_name->efnn_hier, name, esSpiceF); @@ -2838,8 +2833,7 @@ spcdevVisit(dev, hc, scale, trans) if (!has_model) { - fprintf(esSpiceF, " %ffF", (double)sdM * - (double)(dev->dev_cap)); + esSIvalue(esSpiceF, 1.0E-15 * (double)sdM * (double)dev->dev_cap); spcWriteParams(dev, hierName, scale, l, w, sdM); } else @@ -2866,7 +2860,7 @@ spcdevVisit(dev, hc, scale, trans) /* Capacitor is "Cnnn bottom top value" */ /* extraction sets top=source bottom=gate */ - /* extracted units are fF; output is in fF */ + /* extracted units are fF. */ spcdevOutNode(hierName, source->dterm_node->efnode_name->efnn_hier, name, esSpiceF); @@ -2882,8 +2876,7 @@ spcdevVisit(dev, hc, scale, trans) if (!has_model) { - fprintf(esSpiceF, " %ffF", (double)sdM * - (double)(dev->dev_cap)); + esSIvalue(esSpiceF, 1.0E-15 * (double)sdM * (double)dev->dev_cap); spcWriteParams(dev, hierName, scale, l, w, sdM); } else @@ -3113,13 +3106,9 @@ esSIvalue(file, value) { /* Do nothing---value is probably zero */ } - else if (avalue < 1.0E-15) - { - suffix = 'a'; - value *= 1.0E18; - } else if (avalue < 1.0E-12) { + /* NOTE: ngspice does not support "a" for "atto" */ suffix = 'f'; value *= 1.0E15; } @@ -3155,9 +3144,9 @@ esSIvalue(file, value) } if (suffix == '\0') - fprintf(file, "%g", value); + fprintf(file, "%.3g", value); else - fprintf(file, "%g%c", value, suffix); + fprintf(file, "%.3g%c", value, suffix); } /* @@ -3470,8 +3459,10 @@ spccapVisit(hierName1, hierName2, cap) if (cap <= EFCapThreshold) return 0; - fprintf(esSpiceF, esSpiceCapFormat ,esCapNum++,nodeSpiceName(hierName1, NULL), - nodeSpiceName(hierName2, NULL), cap); + fprintf(esSpiceF, "C%d %s %s ", esCapNum++, nodeSpiceName(hierName1, NULL), + nodeSpiceName(hierName2, NULL)); + esSIvalue(esSpiceF, 1.0E-15 * cap); + fprintf(esSpiceF, "\n"); return 0; } @@ -3638,10 +3629,14 @@ spcnodeVisit(node, res, cap) cap = cap / 1000; if (cap > EFCapThreshold) { - fprintf(esSpiceF, esSpiceCapFormat, esCapNum++, nsn, cap, - (isConnected) ? "\n" : - (esFormat == NGSPICE) ? " $ **FLOATING\n" : - " **FLOATING\n"); + fprintf(esSpiceF, "C%d %s %s ", esCapNum++, nsn, esSpiceCapNode); + esSIvalue(esSpiceF, 1.0E-15 * cap); + if (!isConnected) + { + if (esFormat == NGSPICE) fprintf(esSpiceF, " $"); + fprintf(esSpiceF, " **FLOATING"); + } + fprintf(esSpiceF, "\n"); } if (node->efnode_attrs && !esNoAttrs) { diff --git a/ext2spice/ext2spice.h b/ext2spice/ext2spice.h index 4ba9da2c..4f2fbaaa 100644 --- a/ext2spice/ext2spice.h +++ b/ext2spice/ext2spice.h @@ -65,8 +65,8 @@ extern bool esDevNodesOnly; extern bool esNoAttrs; extern bool esHierAP; extern char spcesDefaultOut[FNSIZE]; -extern int esCapAccuracy; -extern char esSpiceCapFormat[FNSIZE]; +extern char *esSpiceCapNode; +extern char esSpiceDefaultGnd[]; extern char *spcesOutName; extern FILE *esSpiceF; extern float esScale; /* negative if hspice the EFScale/100 otherwise */