Changed the behavior of capacitance value output in ext2spice
and ext2sim to make use of the new esSIvalue() routine, so that it no longer depends on a preformatted string. Corrected an issue where the esSIvalue() routine would output "a" for "atto" which is not supported by ngspice.
This commit is contained in:
parent
c077e1acef
commit
a3f5f4db80
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,25 +1366,29 @@ 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 ;
|
||||
|
||||
case 'f':
|
||||
if ((ftmp = ArgStr(&argc, &argv, "format")) == NULL)
|
||||
goto usage;
|
||||
if (strcasecmp(ftmp, "SPICE2") == 0)
|
||||
|
|
@ -1405,32 +1404,28 @@ spcParseArgs(pargc, pargv)
|
|||
esFormat = NGSPICE;
|
||||
else goto usage;
|
||||
break;
|
||||
}
|
||||
case 'J':
|
||||
{
|
||||
char *ftmp ;
|
||||
|
||||
case 'J':
|
||||
if ((ftmp = ArgStr(&argc, &argv, "hierAP_SD")) == NULL)
|
||||
goto usage;
|
||||
if ( strcasecmp(ftmp, "HIER") == 0 )
|
||||
esHierAP = TRUE ;
|
||||
else if ( strcasecmp(ftmp, "FLAT") == 0 )
|
||||
else if (strcasecmp(ftmp, "FLAT") == 0 )
|
||||
esHierAP = FALSE ;
|
||||
else goto usage;
|
||||
|
||||
break;
|
||||
}
|
||||
case 'y': {
|
||||
char *t;
|
||||
|
||||
if (( t = ArgStr(&argc, &argv, "cap-accuracy") ) == NULL)
|
||||
case 'y':
|
||||
if ((t = ArgStr(&argc, &argv, "cap-accuracy")) == NULL)
|
||||
goto usage;
|
||||
esCapAccuracy = atoi(t);
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue