Extended the use of "ext2spice resistor tee on" to include
DEV_RSUBCKT as well as (previously implemented) DEV_RES. The handling of DEV_RSUBCKT includes checking if the subcircuit has a substrate pin, and zeroing the capacitance to substrate for the resistor node, under the assumption that the parasitics are part of the resistor subcircuit model.
This commit is contained in:
parent
fa80458d80
commit
71fc835aee
|
|
@ -844,6 +844,8 @@ spcdevHierVisit(
|
||||||
case DEV_DSUBCKT:
|
case DEV_DSUBCKT:
|
||||||
case DEV_MSUBCKT:
|
case DEV_MSUBCKT:
|
||||||
fprintf(esSpiceF, "%d", esSbckNum++);
|
fprintf(esSpiceF, "%d", esSbckNum++);
|
||||||
|
if ((dev->dev_class == DEV_RSUBCKT) && esDoResistorTee)
|
||||||
|
fprintf(esSpiceF, "A");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(esSpiceF, "%d", esDevNum++);
|
fprintf(esSpiceF, "%d", esDevNum++);
|
||||||
|
|
@ -920,16 +922,27 @@ spcdevHierVisit(
|
||||||
else if (dev->dev_class != DEV_MSUBCKT)
|
else if (dev->dev_class != DEV_MSUBCKT)
|
||||||
{
|
{
|
||||||
if (dev->dev_nterm > 1)
|
if (dev->dev_nterm > 1)
|
||||||
spcdevOutNode(hc->hc_hierName, source->dterm_node->efnode_name->efnn_hier,
|
spcdevOutNode(hc->hc_hierName,
|
||||||
|
source->dterm_node->efnode_name->efnn_hier,
|
||||||
"subckt", esSpiceF);
|
"subckt", esSpiceF);
|
||||||
if (dev->dev_nterm > 2)
|
if ((dev->dev_class == DEV_RSUBCKT) && esDoResistorTee)
|
||||||
spcdevOutNode(hc->hc_hierName, drain->dterm_node->efnode_name->efnn_hier,
|
{
|
||||||
|
/* Handle resistor "tee" model */
|
||||||
|
spcdevOutNode(hc->hc_hierName,
|
||||||
|
gate->dterm_node->efnode_name->efnn_hier,
|
||||||
|
"subckt", esSpiceF);
|
||||||
|
l /= 2; /* Halve the resistor length for each side */
|
||||||
|
}
|
||||||
|
else if (dev->dev_nterm > 2)
|
||||||
|
spcdevOutNode(hc->hc_hierName,
|
||||||
|
drain->dterm_node->efnode_name->efnn_hier,
|
||||||
"subckt", esSpiceF);
|
"subckt", esSpiceF);
|
||||||
}
|
}
|
||||||
else /* class DEV_MSUBCKT */
|
else /* class DEV_MSUBCKT */
|
||||||
{
|
{
|
||||||
if (dev->dev_nterm > 2)
|
if (dev->dev_nterm > 2)
|
||||||
spcdevOutNode(hc->hc_hierName, source->dterm_node->efnode_name->efnn_hier,
|
spcdevOutNode(hc->hc_hierName,
|
||||||
|
source->dterm_node->efnode_name->efnn_hier,
|
||||||
"subckt", esSpiceF);
|
"subckt", esSpiceF);
|
||||||
}
|
}
|
||||||
/* The following only applies to DEV_SUBCKT and DEV_VERILOGA, which */
|
/* The following only applies to DEV_SUBCKT and DEV_VERILOGA, which */
|
||||||
|
|
@ -967,6 +980,54 @@ spcdevHierVisit(
|
||||||
spcHierWriteParams(hc, dev, scale, l, w, sdM, FALSE);
|
spcHierWriteParams(hc, dev, scale, l, w, sdM, FALSE);
|
||||||
if (sdM != 1.0)
|
if (sdM != 1.0)
|
||||||
fprintf(esSpiceF, " M=%g", sdM);
|
fprintf(esSpiceF, " M=%g", sdM);
|
||||||
|
|
||||||
|
if ((dev->dev_class == DEV_RSUBCKT) && esDoResistorTee)
|
||||||
|
{
|
||||||
|
/* Repeat everything above for the second half of the "tee" resistor */
|
||||||
|
fprintf(esSpiceF, "\n%c%dB", devchar, esSbckNum - 1);
|
||||||
|
|
||||||
|
spcdevOutNode(hc->hc_hierName,
|
||||||
|
gate->dterm_node->efnode_name->efnn_hier,
|
||||||
|
"subckt", esSpiceF);
|
||||||
|
spcdevOutNode(hc->hc_hierName,
|
||||||
|
drain->dterm_node->efnode_name->efnn_hier,
|
||||||
|
"subckt", esSpiceF);
|
||||||
|
|
||||||
|
/* Get the device parameters now, and check if the substrate is */
|
||||||
|
/* passed as a parameter rather than as a node. */
|
||||||
|
|
||||||
|
plist = efGetDeviceParams(EFDevTypes[dev->dev_type]);
|
||||||
|
for (pptr = plist; pptr != NULL; pptr = pptr->parm_next)
|
||||||
|
if (pptr->parm_type[0] == 's')
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ((pptr == NULL) && subnode)
|
||||||
|
{
|
||||||
|
EFNode *dnode;
|
||||||
|
|
||||||
|
fprintf(esSpiceF, " ");
|
||||||
|
subnodeFlat = spcdevSubstrate(hc->hc_hierName,
|
||||||
|
subnode->efnode_name->efnn_hier,
|
||||||
|
dev->dev_type, esSpiceF);
|
||||||
|
|
||||||
|
/* If a tee resistor subcircuit has a substrate pin, then the
|
||||||
|
* parasitic capacitance to substrate should be assumed to be
|
||||||
|
* part of the resistor subcircuit model, and so the parasitic
|
||||||
|
* to substrate on the "gate" node should be forced to zero.
|
||||||
|
*/
|
||||||
|
dnode = GetHierNode(hc, gate->dterm_node->efnode_name->efnn_hier);
|
||||||
|
dnode->efnode_cap = 0;
|
||||||
|
}
|
||||||
|
/* Support for CDL format */
|
||||||
|
if (esFormat == CDL) fprintf(esSpiceF, " /");
|
||||||
|
fprintf(esSpiceF, " %s", EFDevTypes[dev->dev_type]);
|
||||||
|
|
||||||
|
/* Write all requested parameters to the subcircuit call. */
|
||||||
|
sdM = getCurDevMult();
|
||||||
|
spcHierWriteParams(hc, dev, scale, l, w, sdM, FALSE);
|
||||||
|
if (sdM != 1.0)
|
||||||
|
fprintf(esSpiceF, " M=%g", sdM);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEV_RES:
|
case DEV_RES:
|
||||||
|
|
|
||||||
|
|
@ -2901,13 +2901,17 @@ spcdevVisit(
|
||||||
case DEV_VOLT:
|
case DEV_VOLT:
|
||||||
fprintf(esSpiceF, "%d", esVoltNum++);
|
fprintf(esSpiceF, "%d", esVoltNum++);
|
||||||
break;
|
break;
|
||||||
|
case DEV_RSUBCKT:
|
||||||
case DEV_SUBCKT:
|
case DEV_SUBCKT:
|
||||||
case DEV_VERILOGA:
|
case DEV_VERILOGA:
|
||||||
case DEV_RSUBCKT:
|
|
||||||
case DEV_CSUBCKT:
|
case DEV_CSUBCKT:
|
||||||
case DEV_DSUBCKT:
|
case DEV_DSUBCKT:
|
||||||
case DEV_MSUBCKT:
|
case DEV_MSUBCKT:
|
||||||
fprintf(esSpiceF, "%d", esSbckNum++);
|
fprintf(esSpiceF, "%d", esSbckNum++);
|
||||||
|
if ((dev->dev_class == DEV_RSUBCKT) && esDoResistorTee)
|
||||||
|
/* For resistor tee networks, use, e.g., */
|
||||||
|
/* "X1A" and "X1B", for clarity */
|
||||||
|
fprintf(esSpiceF, "A");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(esSpiceF, "%d", esDevNum++);
|
fprintf(esSpiceF, "%d", esDevNum++);
|
||||||
|
|
@ -2982,7 +2986,15 @@ spcdevVisit(
|
||||||
if (dev->dev_nterm > 1)
|
if (dev->dev_nterm > 1)
|
||||||
spcdevOutNode(hierName, source->dterm_node->efnode_name->efnn_hier,
|
spcdevOutNode(hierName, source->dterm_node->efnode_name->efnn_hier,
|
||||||
name, esSpiceF);
|
name, esSpiceF);
|
||||||
if (dev->dev_nterm > 2)
|
if ((dev->dev_class == DEV_RSUBCKT) && esDoResistorTee)
|
||||||
|
{
|
||||||
|
l /= 2; /* Halve the resistor. Note that this may introduce
|
||||||
|
* error if l is an odd value.
|
||||||
|
*/
|
||||||
|
spcdevOutNode(hierName, gate->dterm_node->efnode_name->efnn_hier,
|
||||||
|
name, esSpiceF);
|
||||||
|
}
|
||||||
|
else if (dev->dev_nterm > 2)
|
||||||
spcdevOutNode(hierName, drain->dterm_node->efnode_name->efnn_hier,
|
spcdevOutNode(hierName, drain->dterm_node->efnode_name->efnn_hier,
|
||||||
name, esSpiceF);
|
name, esSpiceF);
|
||||||
}
|
}
|
||||||
|
|
@ -3031,6 +3043,53 @@ spcdevVisit(
|
||||||
fprintf(esSpiceF, " M=%g", sdM);
|
fprintf(esSpiceF, " M=%g", sdM);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (dev->dev_class == DEV_RSUBCKT && esDoResistorTee)
|
||||||
|
{
|
||||||
|
/* Write the second half of the "Tee" resistor when
|
||||||
|
* the resistor is type DEV_RSUBCKT and not DEV_RES.
|
||||||
|
*/
|
||||||
|
fprintf(esSpiceF, "\n%c%dB", devchar, esSbckNum - 1);
|
||||||
|
|
||||||
|
spcdevOutNode(hierName, gate->dterm_node->efnode_name->efnn_hier,
|
||||||
|
name, esSpiceF);
|
||||||
|
spcdevOutNode(hierName, drain->dterm_node->efnode_name->efnn_hier,
|
||||||
|
name, esSpiceF);
|
||||||
|
|
||||||
|
/* Get the device parameters now, and check if the substrate is */
|
||||||
|
/* passed as a parameter rather than as a node. */
|
||||||
|
|
||||||
|
plist = efGetDeviceParams(EFDevTypes[dev->dev_type]);
|
||||||
|
for (pptr = plist; pptr != NULL; pptr = pptr->parm_next)
|
||||||
|
if (pptr->parm_type[0] == 's')
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ((pptr == NULL) && subnode)
|
||||||
|
{
|
||||||
|
fprintf(esSpiceF, " ");
|
||||||
|
subnodeFlat = spcdevSubstrate(hierName,
|
||||||
|
subnode->efnode_name->efnn_hier,
|
||||||
|
dev->dev_type, esSpiceF);
|
||||||
|
|
||||||
|
/* There is a substrate pin on the resistor subcircuit, so assume
|
||||||
|
* that the substrate cap is part of the subcircuit model, and
|
||||||
|
* zero it.
|
||||||
|
*/
|
||||||
|
gate->dterm_node->efnode_cap = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CDL format support: Output a slash followed by a space. */
|
||||||
|
if (esFormat == CDL) fprintf(esSpiceF, " /");
|
||||||
|
fprintf(esSpiceF, " %s", EFDevTypes[dev->dev_type]);
|
||||||
|
|
||||||
|
/* Write all requested parameters to the subcircuit call. */
|
||||||
|
|
||||||
|
sdM = getCurDevMult();
|
||||||
|
spcWriteParams(dev, hierName, scale, l, w, sdM, FALSE);
|
||||||
|
if (sdM != 1.0)
|
||||||
|
fprintf(esSpiceF, " M=%g", sdM);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case DEV_RES:
|
case DEV_RES:
|
||||||
if (esDoResistorTee)
|
if (esDoResistorTee)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue