swapDrainSource moved into a function to encapsulate swap-related tasks; area parameters swapped according to the D/S attributes; SPICE attribute comment printf moved to the end of export function as it allows to add more device types
This commit is contained in:
parent
1ee9309d15
commit
6c508c25b9
|
|
@ -439,6 +439,8 @@ subcktHierVisit(use, hierName, is_top)
|
||||||
return subcktVisit(use, hierName, is_top);
|
return subcktVisit(use, hierName, is_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void swapDrainSource();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -516,8 +518,7 @@ spcdevHierVisit(hc, dev, scale)
|
||||||
(dev->dev_terms[2].dterm_attrs &&
|
(dev->dev_terms[2].dterm_attrs &&
|
||||||
!strcmp(dev->dev_terms[2].dterm_attrs, "S")))
|
!strcmp(dev->dev_terms[2].dterm_attrs, "S")))
|
||||||
{
|
{
|
||||||
drain = &dev->dev_terms[1];
|
swapDrainSource(dev, &source, &drain);
|
||||||
source = &dev->dev_terms[2];
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
drain = &dev->dev_terms[2];
|
drain = &dev->dev_terms[2];
|
||||||
|
|
@ -666,12 +667,12 @@ spcdevHierVisit(hc, dev, scale)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEV_MSUBCKT:
|
case DEV_MSUBCKT:
|
||||||
/* msubcircuit is "Xnnn source gate [drain [sub]]]" */
|
/* msubcircuit is "Xnnn drain gate [source [sub]]]" */
|
||||||
/* to more conveniently handle situations where MOSFETs */
|
/* to more conveniently handle situations where MOSFETs */
|
||||||
/* are modeled by subcircuits with the same pin ordering. */
|
/* are modeled by subcircuits with the same pin ordering. */
|
||||||
|
|
||||||
spcdevOutNode(hc->hc_hierName,
|
spcdevOutNode(hc->hc_hierName,
|
||||||
source->dterm_node->efnode_name->efnn_hier,
|
drain->dterm_node->efnode_name->efnn_hier,
|
||||||
"subckt", esSpiceF);
|
"subckt", esSpiceF);
|
||||||
|
|
||||||
/* Drop through to below (no break statement) */
|
/* Drop through to below (no break statement) */
|
||||||
|
|
@ -693,15 +694,21 @@ spcdevHierVisit(hc, dev, scale)
|
||||||
/* except that the "gate" node is treated as an identifier */
|
/* except that the "gate" node is treated as an identifier */
|
||||||
/* only and is not output. */
|
/* only and is not output. */
|
||||||
|
|
||||||
if ((dev->dev_nterm > 1) && (dev->dev_class != DEV_MSUBCKT))
|
if (dev->dev_class != DEV_MSUBCKT)
|
||||||
spcdevOutNode(hc->hc_hierName,
|
{
|
||||||
source->dterm_node->efnode_name->efnn_hier,
|
if (dev->dev_nterm > 1)
|
||||||
"subckt", esSpiceF);
|
spcdevOutNode(hc->hc_hierName, source->dterm_node->efnode_name->efnn_hier,
|
||||||
if (dev->dev_nterm > 2)
|
"subckt", esSpiceF);
|
||||||
spcdevOutNode(hc->hc_hierName,
|
if (dev->dev_nterm > 2)
|
||||||
drain->dterm_node->efnode_name->efnn_hier,
|
spcdevOutNode(hc->hc_hierName, drain->dterm_node->efnode_name->efnn_hier,
|
||||||
"subckt", esSpiceF);
|
"subckt", esSpiceF);
|
||||||
|
}
|
||||||
|
else /* class DEV_MSUBCKT */
|
||||||
|
{
|
||||||
|
if (dev->dev_nterm > 2)
|
||||||
|
spcdevOutNode(hc->hc_hierName, source->dterm_node->efnode_name->efnn_hier,
|
||||||
|
"subckt", esSpiceF);
|
||||||
|
}
|
||||||
/* The following only applies to DEV_SUBCKT*, which may define as */
|
/* The following only applies to DEV_SUBCKT*, which may define as */
|
||||||
/* many terminal types as it wants. */
|
/* many terminal types as it wants. */
|
||||||
|
|
||||||
|
|
@ -979,20 +986,27 @@ spcdevHierVisit(hc, dev, scale)
|
||||||
else
|
else
|
||||||
fprintf(esSpiceF, "asub=0 psub=0");
|
fprintf(esSpiceF, "asub=0 psub=0");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Now output attributes, if present */
|
/* Output attributes, if present - it looks more convenient here, as other device types may be added */
|
||||||
if (!esNoAttrs)
|
switch (dev->dev_class)
|
||||||
{
|
{
|
||||||
if (gate->dterm_attrs || source->dterm_attrs || drain->dterm_attrs)
|
case DEV_FET:
|
||||||
fprintf(esSpiceF,"\n**devattr");
|
case DEV_MOSFET:
|
||||||
if (gate->dterm_attrs)
|
case DEV_ASYMMETRIC:
|
||||||
fprintf(esSpiceF, " g=%s", gate->dterm_attrs);
|
case DEV_MSUBCKT:
|
||||||
if (source->dterm_attrs)
|
if (!esNoAttrs)
|
||||||
fprintf(esSpiceF, " s=%s", source->dterm_attrs);
|
{
|
||||||
if (drain->dterm_attrs)
|
if (gate->dterm_attrs || source->dterm_attrs || drain->dterm_attrs)
|
||||||
fprintf(esSpiceF, " d=%s", drain->dterm_attrs);
|
fprintf(esSpiceF,"\n**devattr");
|
||||||
}
|
if (gate->dterm_attrs)
|
||||||
break;
|
fprintf(esSpiceF, " g=%s", gate->dterm_attrs);
|
||||||
|
if (source->dterm_attrs)
|
||||||
|
fprintf(esSpiceF, " s=%s", source->dterm_attrs);
|
||||||
|
if (drain->dterm_attrs)
|
||||||
|
fprintf(esSpiceF, " d=%s", drain->dterm_attrs);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
fprintf(esSpiceF, "\n");
|
fprintf(esSpiceF, "\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -2184,6 +2184,51 @@ getCurDevMult()
|
||||||
return (esFMult && (esFMIndex > 0)) ? esFMult[esFMIndex-1] : (float)1.0;
|
return (esFMult && (esFMIndex > 0)) ? esFMult[esFMIndex-1] : (float)1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* swapDrainSource
|
||||||
|
*
|
||||||
|
* Swap drain and source ordering and the related stuff
|
||||||
|
* including the drain/source area parameters
|
||||||
|
*
|
||||||
|
* This is typycally called if any terminal is marked with attribute "D" or "S"
|
||||||
|
* (label "D$" or "S$" at poly-diffusion interface),
|
||||||
|
* then swap order of source and drain compared to the default ordering.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
swapDrainSource(dev, source, drain)
|
||||||
|
Dev *dev;
|
||||||
|
DevTerm **source, **drain;
|
||||||
|
{
|
||||||
|
DevParam *plist;
|
||||||
|
|
||||||
|
/* swap drain/source ordering */
|
||||||
|
*drain = &dev->dev_terms[1];
|
||||||
|
*source = &dev->dev_terms[2];
|
||||||
|
|
||||||
|
/* swap drain/source-related parameters */
|
||||||
|
plist = efGetDeviceParams(EFDevTypes[dev->dev_type]);
|
||||||
|
while (plist != NULL)
|
||||||
|
{
|
||||||
|
TxPrintf(" * param: %s; type: %c%c\n", plist->parm_name, plist->parm_type[0], plist->parm_type[1]);
|
||||||
|
|
||||||
|
/* swap drain/source parameters only */
|
||||||
|
if (!(strcmp(plist->parm_name, "as")) || !(strcmp(plist->parm_name, "ps")))
|
||||||
|
{
|
||||||
|
plist->parm_type[1] = '0' + 2;
|
||||||
|
}
|
||||||
|
else if (!(strcmp(plist->parm_name, "ad")) || !(strcmp(plist->parm_name, "pd")))
|
||||||
|
{
|
||||||
|
plist->parm_type[1] = '0' + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* move pointer */
|
||||||
|
plist = plist->parm_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -2263,8 +2308,8 @@ spcdevVisit(dev, hc, scale, trans)
|
||||||
(dev->dev_terms[2].dterm_attrs &&
|
(dev->dev_terms[2].dterm_attrs &&
|
||||||
!strcmp(dev->dev_terms[2].dterm_attrs, "S")))
|
!strcmp(dev->dev_terms[2].dterm_attrs, "S")))
|
||||||
{
|
{
|
||||||
drain = &dev->dev_terms[1];
|
/* If D/S should be swapped, also parameters must be swapped */
|
||||||
source = &dev->dev_terms[2];
|
swapDrainSource(dev, &source, &drain);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
drain = &dev->dev_terms[2];
|
drain = &dev->dev_terms[2];
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue