Separated drain and source records for the esFetInfo array, to
support asymmetric FETs and other devices like bipolars that have three distinct terminals. This does not go as far as it should to make the array independent of the number of declared terminals of the device. However, it suffices to make, e.g., parameter "a2=area" work for a bipolar device, and to generate the right drain and source areas and perimeters for asymmetric (e.g., extended-drain) devices.
This commit is contained in:
parent
ebe12fecfe
commit
32ec962535
|
|
@ -92,7 +92,8 @@ FILE *esLabF = NULL;
|
||||||
static unsigned short esFormat = MIT ;
|
static unsigned short esFormat = MIT ;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
short resClassSD ; /* the resistance class of the src/drn of the dev */
|
short resClassSource ; /* the resistance class of the source of the dev */
|
||||||
|
short resClassDrain ; /* the resistance class of the drain of the dev */
|
||||||
short resClassSub ; /* the resistance class of the substrate of the dev */
|
short resClassSub ; /* the resistance class of the substrate of the dev */
|
||||||
char *defSubs ; /* the default substrate node */
|
char *defSubs ; /* the default substrate node */
|
||||||
} fetInfo[MAXDEVTYPES];
|
} fetInfo[MAXDEVTYPES];
|
||||||
|
|
@ -262,8 +263,7 @@ CmdExtToSim(w, cmd)
|
||||||
char **msg;
|
char **msg;
|
||||||
bool err_result;
|
bool err_result;
|
||||||
|
|
||||||
short sd_rclass;
|
short s_rclass, d_rclass, sub_rclass;
|
||||||
short sub_rclass;
|
|
||||||
char *devname;
|
char *devname;
|
||||||
char *subname;
|
char *subname;
|
||||||
int idx;
|
int idx;
|
||||||
|
|
@ -572,7 +572,8 @@ runexttosim:
|
||||||
|
|
||||||
for ( i = 0 ; i < MAXDEVTYPES ; i++ )
|
for ( i = 0 ; i < MAXDEVTYPES ; i++ )
|
||||||
{
|
{
|
||||||
fetInfo[i].resClassSD = NO_RESCLASS;
|
fetInfo[i].resClassSource = NO_RESCLASS;
|
||||||
|
fetInfo[i].resClassDrain = NO_RESCLASS;
|
||||||
fetInfo[i].resClassSub = NO_RESCLASS;
|
fetInfo[i].resClassSub = NO_RESCLASS;
|
||||||
fetInfo[i].defSubs = NULL;
|
fetInfo[i].defSubs = NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -582,7 +583,7 @@ runexttosim:
|
||||||
/* command) */
|
/* command) */
|
||||||
|
|
||||||
idx = 0;
|
idx = 0;
|
||||||
while (ExtGetDevInfo(idx++, &devname, &sd_rclass, &sub_rclass, &subname))
|
while (ExtGetDevInfo(idx++, &devname, &s_rclass, &d_rclass, &sub_rclass, &subname))
|
||||||
{
|
{
|
||||||
if (idx == MAXDEVTYPES)
|
if (idx == MAXDEVTYPES)
|
||||||
{
|
{
|
||||||
|
|
@ -593,7 +594,8 @@ runexttosim:
|
||||||
|
|
||||||
if (EFStyle != NULL)
|
if (EFStyle != NULL)
|
||||||
{
|
{
|
||||||
fetInfo[i].resClassSD = sd_rclass;
|
fetInfo[i].resClassSource = s_rclass;
|
||||||
|
fetInfo[i].resClassDrain = d_rclass;
|
||||||
fetInfo[i].resClassSub = sub_rclass;
|
fetInfo[i].resClassSub = sub_rclass;
|
||||||
fetInfo[i].defSubs = subname;
|
fetInfo[i].defSubs = subname;
|
||||||
}
|
}
|
||||||
|
|
@ -670,24 +672,25 @@ main(argc, argv)
|
||||||
/* create default fetinfo entries (MOSIS) which can be overriden by
|
/* create default fetinfo entries (MOSIS) which can be overriden by
|
||||||
the command line arguments */
|
the command line arguments */
|
||||||
for ( i = 0 ; i < MAXDEVTYPES ; i++ ) {
|
for ( i = 0 ; i < MAXDEVTYPES ; i++ ) {
|
||||||
fetInfo[i].resClassSD = NO_RESCLASS;
|
fetInfo[i].resClassSource = NO_RESCLASS;
|
||||||
|
fetInfo[i].resClassDrain = NO_RESCLASS;
|
||||||
fetInfo[i].resClassSub = NO_RESCLASS;
|
fetInfo[i].resClassSub = NO_RESCLASS;
|
||||||
fetInfo[i].defSubs = NULL;
|
fetInfo[i].defSubs = NULL;
|
||||||
}
|
}
|
||||||
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "nfet");
|
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "nfet");
|
||||||
fetInfo[i].resClassSD = 0 ;
|
fetInfo[i].resClassSource = fetInfo[i].resClassDrain = 0 ;
|
||||||
fetInfo[i].resClassSub = NO_RESCLASS ;
|
fetInfo[i].resClassSub = NO_RESCLASS ;
|
||||||
fetInfo[i].defSubs = "Gnd!";
|
fetInfo[i].defSubs = "Gnd!";
|
||||||
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "pfet");
|
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "pfet");
|
||||||
fetInfo[i].resClassSD = 1 ;
|
fetInfo[i].resClassSource = fetInfo[i].resClassDrain = 1 ;
|
||||||
fetInfo[i].resClassSub = 6 ;
|
fetInfo[i].resClassSub = 6 ;
|
||||||
fetInfo[i].defSubs = "Vdd!";
|
fetInfo[i].defSubs = "Vdd!";
|
||||||
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "nmos");
|
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "nmos");
|
||||||
fetInfo[i].resClassSD = 0 ;
|
fetInfo[i].resClassSource = fetInfo[i].resClassDrain = 0 ;
|
||||||
fetInfo[i].resClassSub = NO_RESCLASS ;
|
fetInfo[i].resClassSub = NO_RESCLASS ;
|
||||||
fetInfo[i].defSubs = "Gnd!";
|
fetInfo[i].defSubs = "Gnd!";
|
||||||
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "pmos");
|
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "pmos");
|
||||||
fetInfo[i].resClassSD = 1 ;
|
fetInfo[i].resClassSource = fetInfo[i].resClassDrain = 1 ;
|
||||||
fetInfo[i].resClassSub = 6 ;
|
fetInfo[i].resClassSub = 6 ;
|
||||||
fetInfo[i].defSubs = "Vdd!";
|
fetInfo[i].defSubs = "Vdd!";
|
||||||
/* Process command line arguments */
|
/* Process command line arguments */
|
||||||
|
|
@ -888,7 +891,8 @@ simmainArgs(pargc, pargv)
|
||||||
if ( sscanf(rp, "%d/%s", &rClass, subsNode) != 2 ) goto usage;
|
if ( sscanf(rp, "%d/%s", &rClass, subsNode) != 2 ) goto usage;
|
||||||
}
|
}
|
||||||
ndx = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, cp);
|
ndx = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, cp);
|
||||||
fetInfo[ndx].resClassSD = rClass;
|
fetInfo[ndx].resClassSource = rClass;
|
||||||
|
fetInfo[ndx].resClassDrain = rClass;
|
||||||
fetInfo[ndx].resClassSub = rClassSub;
|
fetInfo[ndx].resClassSub = rClassSub;
|
||||||
fetInfo[ndx].defSubs = (char *) mallocMagic((unsigned) (strlen(subsNode)+1));
|
fetInfo[ndx].defSubs = (char *) mallocMagic((unsigned) (strlen(subsNode)+1));
|
||||||
strcpy(fetInfo[ndx].defSubs,subsNode);
|
strcpy(fetInfo[ndx].defSubs,subsNode);
|
||||||
|
|
@ -1160,12 +1164,12 @@ simdevVisit(dev, hc, scale, trans)
|
||||||
if ( esFormat == SU ) {
|
if ( esFormat == SU ) {
|
||||||
fprintf(esSimF, "%s", (source->dterm_attrs) ? "," : " s=" );
|
fprintf(esSimF, "%s", (source->dterm_attrs) ? "," : " s=" );
|
||||||
if (hierS)
|
if (hierS)
|
||||||
simnAPHier(source, hierName, fetInfo[dev->dev_type].resClassSD,
|
simnAPHier(source, hierName, fetInfo[dev->dev_type].resClassSource,
|
||||||
scale, esSimF);
|
scale, esSimF);
|
||||||
else {
|
else {
|
||||||
snode= SimGetNode(hierName,
|
snode= SimGetNode(hierName,
|
||||||
source->dterm_node->efnode_name->efnn_hier);
|
source->dterm_node->efnode_name->efnn_hier);
|
||||||
simnAP(snode, fetInfo[dev->dev_type].resClassSD, scale, esSimF);
|
simnAP(snode, fetInfo[dev->dev_type].resClassSource, scale, esSimF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (drain->dterm_attrs) {
|
if (drain->dterm_attrs) {
|
||||||
|
|
@ -1178,12 +1182,12 @@ simdevVisit(dev, hc, scale, trans)
|
||||||
if ( esFormat == SU ) {
|
if ( esFormat == SU ) {
|
||||||
fprintf(esSimF, "%s", (drain->dterm_attrs) ? "," : " d=" );
|
fprintf(esSimF, "%s", (drain->dterm_attrs) ? "," : " d=" );
|
||||||
if (hierD)
|
if (hierD)
|
||||||
simnAPHier(drain, hierName, fetInfo[dev->dev_type].resClassSD,
|
simnAPHier(drain, hierName, fetInfo[dev->dev_type].resClassDrain,
|
||||||
scale, esSimF);
|
scale, esSimF);
|
||||||
else {
|
else {
|
||||||
dnode = SimGetNode(hierName,
|
dnode = SimGetNode(hierName,
|
||||||
drain->dterm_node->efnode_name->efnn_hier);
|
drain->dterm_node->efnode_name->efnn_hier);
|
||||||
simnAP(dnode, fetInfo[dev->dev_type].resClassSD,
|
simnAP(dnode, fetInfo[dev->dev_type].resClassDrain,
|
||||||
scale, esSimF);
|
scale, esSimF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -172,9 +172,11 @@ spcHierWriteParams(hc, dev, scale, l, w, sdM)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int pn;
|
int pn, resclass;
|
||||||
pn = plist->parm_type[1] - '0';
|
pn = plist->parm_type[1] - '0';
|
||||||
if (pn >= dev->dev_nterm) pn = dev->dev_nterm - 1;
|
if (pn >= dev->dev_nterm) pn = dev->dev_nterm - 1;
|
||||||
|
resclass = (pn > 1) ? esFetInfo[dev->dev_type].resClassDrain :
|
||||||
|
esFetInfo[dev->dev_type].resClassSource;
|
||||||
|
|
||||||
dnode = GetHierNode(hc,
|
dnode = GetHierNode(hc,
|
||||||
dev->dev_terms[pn].dterm_node->efnode_name->efnn_hier);
|
dev->dev_terms[pn].dterm_node->efnode_name->efnn_hier);
|
||||||
|
|
@ -186,16 +188,14 @@ spcHierWriteParams(hc, dev, scale, l, w, sdM)
|
||||||
'p' && plist->parm_next->parm_type[1] ==
|
'p' && plist->parm_next->parm_type[1] ==
|
||||||
plist->parm_type[1])
|
plist->parm_type[1])
|
||||||
{
|
{
|
||||||
spcnAP(dnode, esFetInfo[dev->dev_type].resClassSD,
|
spcnAP(dnode, resclass, scale, plist->parm_name,
|
||||||
scale, plist->parm_name,
|
|
||||||
plist->parm_next->parm_name, sdM,
|
plist->parm_next->parm_name, sdM,
|
||||||
esSpiceF, w);
|
esSpiceF, w);
|
||||||
plist = plist->parm_next;
|
plist = plist->parm_next;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
spcnAP(dnode, esFetInfo[dev->dev_type].resClassSD,
|
spcnAP(dnode, resclass, scale, plist->parm_name, NULL, sdM,
|
||||||
scale, plist->parm_name, NULL, sdM,
|
|
||||||
esSpiceF, w);
|
esSpiceF, w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -218,9 +218,11 @@ spcHierWriteParams(hc, dev, scale, l, w, sdM)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int pn;
|
int pn, resclass;
|
||||||
pn = plist->parm_type[1] - '0';
|
pn = plist->parm_type[1] - '0';
|
||||||
if (pn >= dev->dev_nterm) pn = dev->dev_nterm - 1;
|
if (pn >= dev->dev_nterm) pn = dev->dev_nterm - 1;
|
||||||
|
resclass = (pn > 1) ? esFetInfo[dev->dev_type].resClassDrain :
|
||||||
|
esFetInfo[dev->dev_type].resClassSource;
|
||||||
|
|
||||||
dnode = GetHierNode(hc,
|
dnode = GetHierNode(hc,
|
||||||
dev->dev_terms[pn].dterm_node->efnode_name->efnn_hier);
|
dev->dev_terms[pn].dterm_node->efnode_name->efnn_hier);
|
||||||
|
|
@ -232,15 +234,13 @@ spcHierWriteParams(hc, dev, scale, l, w, sdM)
|
||||||
'a' && plist->parm_next->parm_type[1] ==
|
'a' && plist->parm_next->parm_type[1] ==
|
||||||
plist->parm_type[1])
|
plist->parm_type[1])
|
||||||
{
|
{
|
||||||
spcnAP(dnode, esFetInfo[dev->dev_type].resClassSD,
|
spcnAP(dnode, resclass, scale, plist->parm_next->parm_name,
|
||||||
scale, plist->parm_next->parm_name,
|
|
||||||
plist->parm_name, sdM, esSpiceF, w);
|
plist->parm_name, sdM, esSpiceF, w);
|
||||||
plist = plist->parm_next;
|
plist = plist->parm_next;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
spcnAP(dnode, esFetInfo[dev->dev_type].resClassSD,
|
spcnAP(dnode, resclass, scale, NULL, plist->parm_name, sdM,
|
||||||
scale, NULL, plist->parm_name, sdM,
|
|
||||||
esSpiceF, w);
|
esSpiceF, w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -965,10 +965,10 @@ spcdevHierVisit(hc, dev, scale)
|
||||||
|
|
||||||
fprintf(esSpiceF, "\n+ ");
|
fprintf(esSpiceF, "\n+ ");
|
||||||
dnode = GetHierNode(hc, drain->dterm_node->efnode_name->efnn_hier);
|
dnode = GetHierNode(hc, drain->dterm_node->efnode_name->efnn_hier);
|
||||||
spcnAP(dnode, esFetInfo[dev->dev_type].resClassSD, scale,
|
spcnAP(dnode, esFetInfo[dev->dev_type].resClassDrain, scale,
|
||||||
"ad", "pd", sdM, esSpiceF, w);
|
"ad", "pd", sdM, esSpiceF, w);
|
||||||
snode= GetHierNode(hc, source->dterm_node->efnode_name->efnn_hier);
|
snode= GetHierNode(hc, source->dterm_node->efnode_name->efnn_hier);
|
||||||
spcnAP(snode, esFetInfo[dev->dev_type].resClassSD, scale,
|
spcnAP(snode, esFetInfo[dev->dev_type].resClassSource, scale,
|
||||||
"as", "ps", sdM, esSpiceF, w);
|
"as", "ps", sdM, esSpiceF, w);
|
||||||
if (subAP)
|
if (subAP)
|
||||||
{
|
{
|
||||||
|
|
@ -1538,7 +1538,10 @@ devDistJunctHierVisit(hc, dev, scale)
|
||||||
for (i = 1; i<dev->dev_nterm; i++)
|
for (i = 1; i<dev->dev_nterm; i++)
|
||||||
{
|
{
|
||||||
n = GetHierNode(hc, dev->dev_terms[i].dterm_node->efnode_name->efnn_hier);
|
n = GetHierNode(hc, dev->dev_terms[i].dterm_node->efnode_name->efnn_hier);
|
||||||
update_w(esFetInfo[dev->dev_type].resClassSD, w, n);
|
if (i == 1)
|
||||||
|
update_w(esFetInfo[dev->dev_type].resClassSource, w, n);
|
||||||
|
else
|
||||||
|
update_w(esFetInfo[dev->dev_type].resClassDrain, w, n);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -239,8 +239,7 @@ CmdExtToSpice(w, cmd)
|
||||||
char *substr = NULL;
|
char *substr = NULL;
|
||||||
bool err_result, locDoSubckt;
|
bool err_result, locDoSubckt;
|
||||||
|
|
||||||
short sd_rclass;
|
short s_rclass, d_rclass, sub_rclass;
|
||||||
short sub_rclass;
|
|
||||||
char *devname;
|
char *devname;
|
||||||
char *subname;
|
char *subname;
|
||||||
int idx, idx2;
|
int idx, idx2;
|
||||||
|
|
@ -729,7 +728,8 @@ runexttospice:
|
||||||
the command line arguments */
|
the command line arguments */
|
||||||
|
|
||||||
for ( i = 0 ; i < MAXDEVTYPES ; i++ ) {
|
for ( i = 0 ; i < MAXDEVTYPES ; i++ ) {
|
||||||
esFetInfo[i].resClassSD = NO_RESCLASS;
|
esFetInfo[i].resClassSource = NO_RESCLASS;
|
||||||
|
esFetInfo[i].resClassDrain = NO_RESCLASS;
|
||||||
esFetInfo[i].resClassSub = NO_RESCLASS;
|
esFetInfo[i].resClassSub = NO_RESCLASS;
|
||||||
esFetInfo[i].defSubs = NULL;
|
esFetInfo[i].defSubs = NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -739,7 +739,7 @@ runexttospice:
|
||||||
/* command) */
|
/* command) */
|
||||||
|
|
||||||
idx = 0;
|
idx = 0;
|
||||||
while (ExtGetDevInfo(idx++, &devname, &sd_rclass, &sub_rclass, &subname))
|
while (ExtGetDevInfo(idx++, &devname, &s_rclass, &d_rclass, &sub_rclass, &subname))
|
||||||
{
|
{
|
||||||
if (idx == MAXDEVTYPES)
|
if (idx == MAXDEVTYPES)
|
||||||
{
|
{
|
||||||
|
|
@ -751,7 +751,8 @@ runexttospice:
|
||||||
esNoModelType = i;
|
esNoModelType = i;
|
||||||
if (EFStyle != NULL)
|
if (EFStyle != NULL)
|
||||||
{
|
{
|
||||||
esFetInfo[i].resClassSD = sd_rclass;
|
esFetInfo[i].resClassSource = s_rclass;
|
||||||
|
esFetInfo[i].resClassDrain = d_rclass;
|
||||||
esFetInfo[i].resClassSub = sub_rclass;
|
esFetInfo[i].resClassSub = sub_rclass;
|
||||||
esFetInfo[i].defSubs = subname;
|
esFetInfo[i].defSubs = subname;
|
||||||
}
|
}
|
||||||
|
|
@ -992,24 +993,25 @@ main(argc, argv)
|
||||||
/* create default devinfo entries (MOSIS) which can be overriden by
|
/* create default devinfo entries (MOSIS) which can be overriden by
|
||||||
the command line arguments */
|
the command line arguments */
|
||||||
for ( i = 0 ; i < MAXDEVTYPES ; i++ ) {
|
for ( i = 0 ; i < MAXDEVTYPES ; i++ ) {
|
||||||
esFetInfo[i].resClassSD = NO_RESCLASS;
|
esFetInfo[i].resClassSource = NO_RESCLASS;
|
||||||
|
esFetInfo[i].resClassDrain = NO_RESCLASS;
|
||||||
esFetInfo[i].resClassSub = NO_RESCLASS;
|
esFetInfo[i].resClassSub = NO_RESCLASS;
|
||||||
esFetInfo[i].defSubs = NULL;
|
esFetInfo[i].defSubs = NULL;
|
||||||
}
|
}
|
||||||
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "ndev");
|
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "ndev");
|
||||||
esFetInfo[i].resClassSD = 0 ;
|
esFetInfo[i].resClassSource = esFetInfo[i].resClassDrain = 0 ;
|
||||||
esFetInfo[i].resClassSub = NO_RESCLASS ;
|
esFetInfo[i].resClassSub = NO_RESCLASS ;
|
||||||
esFetInfo[i].defSubs = "Gnd!";
|
esFetInfo[i].defSubs = "Gnd!";
|
||||||
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "pdev");
|
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "pdev");
|
||||||
esFetInfo[i].resClassSD = 1 ;
|
esFetInfo[i].resClassSource = esFetInfo[i].resClassDrain = 1 ;
|
||||||
esFetInfo[i].resClassSub = 8 ;
|
esFetInfo[i].resClassSub = 8 ;
|
||||||
esFetInfo[i].defSubs = "Vdd!";
|
esFetInfo[i].defSubs = "Vdd!";
|
||||||
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "nmos");
|
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "nmos");
|
||||||
esFetInfo[i].resClassSD = 0 ;
|
esFetInfo[i].resClassSource = esFetInfo[i].resClassDrain = 0 ;
|
||||||
esFetInfo[i].resClassSub = NO_RESCLASS ;
|
esFetInfo[i].resClassSub = NO_RESCLASS ;
|
||||||
esFetInfo[i].defSubs = "Gnd!";
|
esFetInfo[i].defSubs = "Gnd!";
|
||||||
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "pmos");
|
i = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, "pmos");
|
||||||
esFetInfo[i].resClassSD = 1 ;
|
esFetInfo[i].resClassSource = esFetInfo[i].resClassDrain = 1 ;
|
||||||
esFetInfo[i].resClassSub = 8 ;
|
esFetInfo[i].resClassSub = 8 ;
|
||||||
esFetInfo[i].defSubs = "Vdd!";
|
esFetInfo[i].defSubs = "Vdd!";
|
||||||
/* Process command line arguments */
|
/* Process command line arguments */
|
||||||
|
|
@ -1237,7 +1239,7 @@ spcmainArgs(pargc, pargv)
|
||||||
if ( sscanf(rp, "%d/%s", &rClass, subsNode) != 2 ) goto usage;
|
if ( sscanf(rp, "%d/%s", &rClass, subsNode) != 2 ) goto usage;
|
||||||
}
|
}
|
||||||
ndx = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, cp);
|
ndx = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, cp);
|
||||||
esFetInfo[ndx].resClassSD = rClass;
|
esFetInfo[ndx].resClassSource = esFetInfo[ndx].resClassDrain = rClass;
|
||||||
esFetInfo[ndx].resClassSub = rClassSub;
|
esFetInfo[ndx].resClassSub = rClassSub;
|
||||||
if ( ((1<<rClass) & DEV_CONNECT_MASK) ||
|
if ( ((1<<rClass) & DEV_CONNECT_MASK) ||
|
||||||
((1<<rClass) & DEV_CONNECT_MASK) ) {
|
((1<<rClass) & DEV_CONNECT_MASK) ) {
|
||||||
|
|
@ -1249,9 +1251,9 @@ spcmainArgs(pargc, pargv)
|
||||||
}
|
}
|
||||||
esFetInfo[ndx].defSubs = (char *)mallocMagic((unsigned)(strlen(subsNode)+1));
|
esFetInfo[ndx].defSubs = (char *)mallocMagic((unsigned)(strlen(subsNode)+1));
|
||||||
strcpy(esFetInfo[ndx].defSubs,subsNode);
|
strcpy(esFetInfo[ndx].defSubs,subsNode);
|
||||||
TxError("info: dev %s(%d) sdRclass=%d subRclass=%d dSub=%s\n",
|
TxError("info: dev %s(%d) srcRclass=%d drnRclass=%d subRclass=%d dSub=%s\n",
|
||||||
cp, ndx, esFetInfo[ndx].resClassSD, esFetInfo[ndx].resClassSub,
|
cp, ndx, esFetInfo[ndx].resClassSource, esFetInfo[ndx].resClassDrain,
|
||||||
esFetInfo[ndx].defSubs);
|
esFetInfo[ndx].resClassSub, esFetInfo[ndx].defSubs);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* MAGIC_WRAPPER */
|
#endif /* MAGIC_WRAPPER */
|
||||||
|
|
@ -1882,13 +1884,16 @@ spcWriteParams(dev, hierName, scale, l, w, sdM)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int pn;
|
int pn, resclass;
|
||||||
|
|
||||||
pn = plist->parm_type[1] - '0';
|
pn = plist->parm_type[1] - '0';
|
||||||
if (pn >= dev->dev_nterm) pn = dev->dev_nterm - 1;
|
if (pn >= dev->dev_nterm) pn = dev->dev_nterm - 1;
|
||||||
|
|
||||||
hierD = extHierSDAttr(&dev->dev_terms[pn]);
|
hierD = extHierSDAttr(&dev->dev_terms[pn]);
|
||||||
|
|
||||||
|
resclass == (pn > 1) ? esFetInfo[dev->dev_type].resClassDrain :
|
||||||
|
esFetInfo[dev->dev_type].resClassSource;
|
||||||
|
|
||||||
// For parameter a<n> followed by parameter p<n>,
|
// For parameter a<n> followed by parameter p<n>,
|
||||||
// process both at the same time.
|
// process both at the same time.
|
||||||
|
|
||||||
|
|
@ -1898,16 +1903,14 @@ spcWriteParams(dev, hierName, scale, l, w, sdM)
|
||||||
{
|
{
|
||||||
if (hierD)
|
if (hierD)
|
||||||
spcnAPHier(&dev->dev_terms[pn], hierName,
|
spcnAPHier(&dev->dev_terms[pn], hierName,
|
||||||
esFetInfo[dev->dev_type].resClassSD,
|
resclass, scale, plist->parm_type,
|
||||||
scale, plist->parm_type,
|
|
||||||
plist->parm_next->parm_type,
|
plist->parm_next->parm_type,
|
||||||
sdM, esSpiceF);
|
sdM, esSpiceF);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dnode = SpiceGetNode(hierName,
|
dnode = SpiceGetNode(hierName,
|
||||||
dev->dev_terms[pn].dterm_node->efnode_name->efnn_hier);
|
dev->dev_terms[pn].dterm_node->efnode_name->efnn_hier);
|
||||||
spcnAP(dnode, esFetInfo[dev->dev_type].resClassSD,
|
spcnAP(dnode, resclass, scale, plist->parm_name,
|
||||||
scale, plist->parm_name,
|
|
||||||
plist->parm_next->parm_name,
|
plist->parm_next->parm_name,
|
||||||
sdM, esSpiceF, w);
|
sdM, esSpiceF, w);
|
||||||
}
|
}
|
||||||
|
|
@ -1917,15 +1920,13 @@ spcWriteParams(dev, hierName, scale, l, w, sdM)
|
||||||
{
|
{
|
||||||
if (hierD)
|
if (hierD)
|
||||||
spcnAPHier(&dev->dev_terms[pn], hierName,
|
spcnAPHier(&dev->dev_terms[pn], hierName,
|
||||||
esFetInfo[dev->dev_type].resClassSD,
|
resclass, scale, plist->parm_type, NULL,
|
||||||
scale, plist->parm_type, NULL,
|
|
||||||
sdM, esSpiceF);
|
sdM, esSpiceF);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dnode = SpiceGetNode(hierName,
|
dnode = SpiceGetNode(hierName,
|
||||||
dev->dev_terms[pn].dterm_node->efnode_name->efnn_hier);
|
dev->dev_terms[pn].dterm_node->efnode_name->efnn_hier);
|
||||||
spcnAP(dnode, esFetInfo[dev->dev_type].resClassSD,
|
spcnAP(dnode, resclass, scale, plist->parm_name, NULL,
|
||||||
scale, plist->parm_name, NULL,
|
|
||||||
sdM, esSpiceF, w);
|
sdM, esSpiceF, w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1948,11 +1949,14 @@ spcWriteParams(dev, hierName, scale, l, w, sdM)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int pn;
|
int pn, resclass;
|
||||||
|
|
||||||
pn = plist->parm_type[1] - '0';
|
pn = plist->parm_type[1] - '0';
|
||||||
if (pn >= dev->dev_nterm) pn = dev->dev_nterm - 1;
|
if (pn >= dev->dev_nterm) pn = dev->dev_nterm - 1;
|
||||||
|
|
||||||
|
resclass == (pn > 1) ? esFetInfo[dev->dev_type].resClassDrain :
|
||||||
|
esFetInfo[dev->dev_type].resClassSource;
|
||||||
|
|
||||||
hierD = extHierSDAttr(&dev->dev_terms[pn]);
|
hierD = extHierSDAttr(&dev->dev_terms[pn]);
|
||||||
|
|
||||||
// For parameter p<n> followed by parameter a<n>,
|
// For parameter p<n> followed by parameter a<n>,
|
||||||
|
|
@ -1964,15 +1968,13 @@ spcWriteParams(dev, hierName, scale, l, w, sdM)
|
||||||
{
|
{
|
||||||
if (hierD)
|
if (hierD)
|
||||||
spcnAPHier(&dev->dev_terms[pn], hierName,
|
spcnAPHier(&dev->dev_terms[pn], hierName,
|
||||||
esFetInfo[dev->dev_type].resClassSD,
|
resclass, scale, plist->parm_next->parm_type,
|
||||||
scale, plist->parm_next->parm_type,
|
|
||||||
plist->parm_type, sdM, esSpiceF);
|
plist->parm_type, sdM, esSpiceF);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dnode = SpiceGetNode(hierName,
|
dnode = SpiceGetNode(hierName,
|
||||||
dev->dev_terms[pn].dterm_node->efnode_name->efnn_hier);
|
dev->dev_terms[pn].dterm_node->efnode_name->efnn_hier);
|
||||||
spcnAP(dnode, esFetInfo[dev->dev_type].resClassSD,
|
spcnAP(dnode, resclass, scale, plist->parm_next->parm_name,
|
||||||
scale, plist->parm_next->parm_name,
|
|
||||||
plist->parm_name, sdM, esSpiceF, w);
|
plist->parm_name, sdM, esSpiceF, w);
|
||||||
}
|
}
|
||||||
plist = plist->parm_next;
|
plist = plist->parm_next;
|
||||||
|
|
@ -1981,15 +1983,13 @@ spcWriteParams(dev, hierName, scale, l, w, sdM)
|
||||||
{
|
{
|
||||||
if (hierD)
|
if (hierD)
|
||||||
spcnAPHier(&dev->dev_terms[pn], hierName,
|
spcnAPHier(&dev->dev_terms[pn], hierName,
|
||||||
esFetInfo[dev->dev_type].resClassSD,
|
resclass, scale, NULL, plist->parm_type,
|
||||||
scale, NULL, plist->parm_type,
|
|
||||||
sdM, esSpiceF);
|
sdM, esSpiceF);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dnode = SpiceGetNode(hierName,
|
dnode = SpiceGetNode(hierName,
|
||||||
dev->dev_terms[pn].dterm_node->efnode_name->efnn_hier);
|
dev->dev_terms[pn].dterm_node->efnode_name->efnn_hier);
|
||||||
spcnAP(dnode, esFetInfo[dev->dev_type].resClassSD,
|
spcnAP(dnode, resclass, scale, NULL, plist->parm_name,
|
||||||
scale, NULL, plist->parm_name,
|
|
||||||
sdM, esSpiceF, w);
|
sdM, esSpiceF, w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2771,20 +2771,20 @@ spcdevVisit(dev, hc, scale, trans)
|
||||||
|
|
||||||
fprintf(esSpiceF, "\n+ ");
|
fprintf(esSpiceF, "\n+ ");
|
||||||
if (hierD)
|
if (hierD)
|
||||||
spcnAPHier(drain, hierName, esFetInfo[dev->dev_type].resClassSD,
|
spcnAPHier(drain, hierName, esFetInfo[dev->dev_type].resClassDrain,
|
||||||
scale, "ad", "pd", sdM, esSpiceF);
|
scale, "ad", "pd", sdM, esSpiceF);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dnode = SpiceGetNode(hierName, drain->dterm_node->efnode_name->efnn_hier);
|
dnode = SpiceGetNode(hierName, drain->dterm_node->efnode_name->efnn_hier);
|
||||||
spcnAP(dnode, esFetInfo[dev->dev_type].resClassSD, scale,
|
spcnAP(dnode, esFetInfo[dev->dev_type].resClassDrain, scale,
|
||||||
"ad", "pd", sdM, esSpiceF, w);
|
"ad", "pd", sdM, esSpiceF, w);
|
||||||
}
|
}
|
||||||
if (hierS)
|
if (hierS)
|
||||||
spcnAPHier(source, hierName, esFetInfo[dev->dev_type].resClassSD,
|
spcnAPHier(source, hierName, esFetInfo[dev->dev_type].resClassSource,
|
||||||
scale, "as", "ps", sdM, esSpiceF);
|
scale, "as", "ps", sdM, esSpiceF);
|
||||||
else {
|
else {
|
||||||
snode= SpiceGetNode(hierName, source->dterm_node->efnode_name->efnn_hier);
|
snode= SpiceGetNode(hierName, source->dterm_node->efnode_name->efnn_hier);
|
||||||
spcnAP(snode, esFetInfo[dev->dev_type].resClassSD, scale,
|
spcnAP(snode, esFetInfo[dev->dev_type].resClassSource, scale,
|
||||||
"as", "ps", sdM, esSpiceF, w);
|
"as", "ps", sdM, esSpiceF, w);
|
||||||
}
|
}
|
||||||
if (subAP)
|
if (subAP)
|
||||||
|
|
@ -3998,7 +3998,10 @@ devDistJunctVisit(dev, hc, scale, trans)
|
||||||
{
|
{
|
||||||
n = SpiceGetNode(hierName,
|
n = SpiceGetNode(hierName,
|
||||||
dev->dev_terms[i].dterm_node->efnode_name->efnn_hier);
|
dev->dev_terms[i].dterm_node->efnode_name->efnn_hier);
|
||||||
update_w(esFetInfo[dev->dev_type].resClassSD, w, n);
|
if (i == 1)
|
||||||
|
update_w(esFetInfo[dev->dev_type].resClassSource, w, n);
|
||||||
|
else
|
||||||
|
update_w(esFetInfo[dev->dev_type].resClassDrain, w, n);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,8 @@ extern DQueue subcktNameQueue ; /* q used to print it sorted at the end*/
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
short resClassSD ; /* the resistance class of the src/drn of the dev */
|
short resClassSource ; /* the resistance class of the source of the dev */
|
||||||
|
short resClassDrain ; /* the resistance class of the drain of the dev */
|
||||||
short resClassSub ; /* the resistance class of the substrate of the dev */
|
short resClassSub ; /* the resistance class of the substrate of the dev */
|
||||||
char *defSubs ; /* the default substrate node */
|
char *defSubs ; /* the default substrate node */
|
||||||
} fetInfoList;
|
} fetInfoList;
|
||||||
|
|
|
||||||
|
|
@ -1743,7 +1743,7 @@ extOutputDevices(def, transList, outFile)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
extTransRec.tr_devmatch |= (MATCH_TERM << termcount);
|
extTransRec.tr_devmatch |= (MATCH_TERM << termcount);
|
||||||
extTransRec.tr_termnode[termcount++] = node;
|
extTransRec.tr_termnode[termcount] = node;
|
||||||
}
|
}
|
||||||
else if (TTMaskHasType(tmask, TT_SPACE)) {
|
else if (TTMaskHasType(tmask, TT_SPACE)) {
|
||||||
/* Device node is specified as being the substrate */
|
/* Device node is specified as being the substrate */
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include "tcltk/tclmagic.h"
|
#include "tcltk/tclmagic.h"
|
||||||
#include "utils/magic.h"
|
#include "utils/magic.h"
|
||||||
|
|
@ -42,6 +43,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
||||||
#include "debug/debug.h"
|
#include "debug/debug.h"
|
||||||
#include "extract/extract.h"
|
#include "extract/extract.h"
|
||||||
#include "extract/extractInt.h"
|
#include "extract/extractInt.h"
|
||||||
|
#include "graphics/graphics.h"
|
||||||
#include "utils/signals.h"
|
#include "utils/signals.h"
|
||||||
#include "windows/windows.h"
|
#include "windows/windows.h"
|
||||||
#include "dbwind/dbwind.h"
|
#include "dbwind/dbwind.h"
|
||||||
|
|
@ -168,6 +170,10 @@ extSubtree(parentUse, reg, f)
|
||||||
float pdone, plast;
|
float pdone, plast;
|
||||||
SearchContext scx;
|
SearchContext scx;
|
||||||
|
|
||||||
|
/* Use the display timer to force a 5-second progress check */
|
||||||
|
GrDisplayStatus = DISPLAY_IN_PROGRESS;
|
||||||
|
SigSetTimer(5); /* Print at 5-second intervals */
|
||||||
|
|
||||||
if ((ExtOptions & (EXT_DOCOUPLING|EXT_DOADJUST))
|
if ((ExtOptions & (EXT_DOCOUPLING|EXT_DOADJUST))
|
||||||
!= (EXT_DOCOUPLING|EXT_DOADJUST))
|
!= (EXT_DOCOUPLING|EXT_DOADJUST))
|
||||||
halo = 1;
|
halo = 1;
|
||||||
|
|
@ -264,9 +270,16 @@ extSubtree(parentUse, reg, f)
|
||||||
cuts++;
|
cuts++;
|
||||||
pdone = 100.0 * ((float)cuts / (float)totcuts);
|
pdone = 100.0 * ((float)cuts / (float)totcuts);
|
||||||
if ((((pdone - plast) > 5.0) || (cuts == totcuts)) && (cuts > 1)) {
|
if ((((pdone - plast) > 5.0) || (cuts == totcuts)) && (cuts > 1)) {
|
||||||
TxPrintf("Completed %d%%\n", (int)(pdone + 0.5));
|
/* Only print something if the 5-second timer has expired */
|
||||||
plast = pdone;
|
if (GrDisplayStatus == DISPLAY_BREAK_PENDING)
|
||||||
TxFlushOut();
|
{
|
||||||
|
TxPrintf("Completed %d%%\n", (int)(pdone + 0.5));
|
||||||
|
plast = pdone;
|
||||||
|
TxFlushOut();
|
||||||
|
|
||||||
|
GrDisplayStatus = DISPLAY_IN_PROGRESS;
|
||||||
|
SigSetTimer(5);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef MAGIC_WRAPPER
|
#ifdef MAGIC_WRAPPER
|
||||||
/* We need to let Tk paint the console display */
|
/* We need to let Tk paint the console display */
|
||||||
|
|
@ -313,6 +326,8 @@ done:
|
||||||
/* Output connections and node adjustments */
|
/* Output connections and node adjustments */
|
||||||
extOutputConns(&ha.ha_connHash, f);
|
extOutputConns(&ha.ha_connHash, f);
|
||||||
HashKill(&ha.ha_connHash);
|
HashKill(&ha.ha_connHash);
|
||||||
|
GrDisplayStatus = DISPLAY_IDLE;
|
||||||
|
SigRemoveTimer();
|
||||||
|
|
||||||
/* Clear the CU_SUB_EXTRACTED flag from all children instances */
|
/* Clear the CU_SUB_EXTRACTED flag from all children instances */
|
||||||
DBCellEnum(def, extClearUseFlags, (ClientData)NULL);
|
DBCellEnum(def, extClearUseFlags, (ClientData)NULL);
|
||||||
|
|
|
||||||
|
|
@ -293,14 +293,22 @@ ExtCompareStyle(stylename)
|
||||||
*
|
*
|
||||||
* Side Effects:
|
* Side Effects:
|
||||||
* Fills values in the argument list.
|
* Fills values in the argument list.
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
* The original sd_rclassptr has been expanded to s_rclassptr and
|
||||||
|
* d_rclassptr to capture asymmetric devices, bipolars, etc. Note
|
||||||
|
* that this is not a general-purpose method extending beyond two
|
||||||
|
* (non-gate) terminals, and should be updated.
|
||||||
|
*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ExtGetDevInfo(idx, devnameptr, sd_rclassptr, sub_rclassptr, subnameptr)
|
ExtGetDevInfo(idx, devnameptr, s_rclassptr, d_rclassptr, sub_rclassptr, subnameptr)
|
||||||
int idx;
|
int idx;
|
||||||
char **devnameptr;
|
char **devnameptr;
|
||||||
short *sd_rclassptr; /* First SD type only---needs to be updated! */
|
short *s_rclassptr; /* Source (1st terminal) type only */
|
||||||
|
short *d_rclassptr; /* Drain (2nd terminal) type only */
|
||||||
short *sub_rclassptr;
|
short *sub_rclassptr;
|
||||||
char **subnameptr;
|
char **subnameptr;
|
||||||
{
|
{
|
||||||
|
|
@ -348,18 +356,39 @@ ExtGetDevInfo(idx, devnameptr, sd_rclassptr, sub_rclassptr, subnameptr)
|
||||||
*subnameptr = devptr->exts_deviceSubstrateName;
|
*subnameptr = devptr->exts_deviceSubstrateName;
|
||||||
|
|
||||||
tmask = &devptr->exts_deviceSDTypes[0];
|
tmask = &devptr->exts_deviceSDTypes[0];
|
||||||
*sd_rclassptr = (short)(-1); /* NO_RESCLASS */
|
*s_rclassptr = (short)(-1); /* NO_RESCLASS */
|
||||||
|
|
||||||
for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++)
|
for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++)
|
||||||
{
|
{
|
||||||
rmask = &ExtCurStyle->exts_typesByResistClass[n];
|
rmask = &ExtCurStyle->exts_typesByResistClass[n];
|
||||||
if (TTMaskIntersect(rmask, tmask))
|
if (TTMaskIntersect(rmask, tmask))
|
||||||
{
|
{
|
||||||
*sd_rclassptr = (short)n;
|
*s_rclassptr = (short)n;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tmask = &devptr->exts_deviceSDTypes[1];
|
||||||
|
if (TTMaskIsZero(tmask))
|
||||||
|
{
|
||||||
|
/* Set source and drain resistance classes to be the same */
|
||||||
|
*d_rclassptr = (short)n;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*d_rclassptr = (short)(-1); /* NO_RESCLASS */
|
||||||
|
|
||||||
|
for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++)
|
||||||
|
{
|
||||||
|
rmask = &ExtCurStyle->exts_typesByResistClass[n];
|
||||||
|
if (TTMaskIntersect(rmask, tmask))
|
||||||
|
{
|
||||||
|
*d_rclassptr = (short)n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tmask = &devptr->exts_deviceSubstrateTypes;
|
tmask = &devptr->exts_deviceSubstrateTypes;
|
||||||
*sub_rclassptr = (short)(-1); /* NO_RESCLASS */
|
*sub_rclassptr = (short)(-1); /* NO_RESCLASS */
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue