diff --git a/ext2spice/ext2hier.c b/ext2spice/ext2hier.c index a6bfa79a..e0ab7dbf 100644 --- a/ext2spice/ext2hier.c +++ b/ext2spice/ext2hier.c @@ -1028,24 +1028,21 @@ spcdevHierVisit( if (sdM != 1.0) fprintf(esSpiceF, " M=%g", sdM); } + else + { + spcdevResPi(hc->hc_hierName, gate->dterm_node->efnode_name->efnn_hier, + source->dterm_node->efnode_name->efnn_hier, + drain->dterm_node->efnode_name->efnn_hier, + "subckt"); + } break; case DEV_RES: if (esDoResistorTee) { - /* There are three ways of handling capacitance */ - /* on resistor networks. One is to ignore it */ - /* (the default; generates "floating" nodes in */ - /* the SPICE output) which is okay for LVS. */ - /* Another way is the Pi network, in which the */ - /* capacitance is split evenly between the */ - /* terminals. Again, the resistor node is left */ - /* floating. The third is the Tee network, in */ - /* which the resistance is split in two parts, */ - /* connecting to a capacitor to ground in the */ - /* middle. This is the best solution but plays */ - /* havoc with LVS. So, the choice is a command */ - /* line option. */ + /* There are two ways of handling resistor */ + /* capacitance to substrate: The Pi model and */ + /* the Tee model (see ext2spice.c). */ esOutputHierResistor(hc, dev, scale, gate, source, has_model, l, w, 2); @@ -1061,6 +1058,11 @@ spcdevHierVisit( { esOutputHierResistor(hc, dev, scale, source, drain, has_model, l, w, 1); + + spcdevResPi(hc->hc_hierName, gate->dterm_node->efnode_name->efnn_hier, + source->dterm_node->efnode_name->efnn_hier, + drain->dterm_node->efnode_name->efnn_hier, + "subckt"); } break; diff --git a/ext2spice/ext2spice.c b/ext2spice/ext2spice.c index 0c3a0094..d048215f 100644 --- a/ext2spice/ext2spice.c +++ b/ext2spice/ext2spice.c @@ -2995,8 +2995,15 @@ spcdevVisit( name, esSpiceF); } else if (dev->dev_nterm > 2) + { spcdevOutNode(hierName, drain->dterm_node->efnode_name->efnn_hier, name, esSpiceF); + + spcdevResPi(hierName, gate->dterm_node->efnode_name->efnn_hier, + source->dterm_node->efnode_name->efnn_hier, + drain->dterm_node->efnode_name->efnn_hier, + name); + } } else /* class DEV_MSUBCKT */ { @@ -3093,19 +3100,15 @@ spcdevVisit( case DEV_RES: if (esDoResistorTee) { - /* There are three ways of handling capacitance */ - /* on resistor networks. One is to ignore it */ - /* (the default; generates "floating" nodes in */ - /* the SPICE output) which is okay for LVS. */ - /* Another way is the Pi network, in which the */ - /* capacitance is split evenly between the */ - /* terminals. Again, the resistor node is left */ - /* floating. The third is the Tee network, in */ - /* which the resistance is split in two parts, */ - /* connecting to a capacitor to ground in the */ - /* middle. This is the best solution but plays */ - /* havoc with LVS. So, the choice is a command */ - /* line option. */ + /* There are two ways of handling capacitance */ + /* on resistor networks. The default is the Pi */ + /* network, which splits the capacitance of the */ + /* resistor itself evenly between the two */ + /* terminals. The resistor itself is not */ + /* output as a node. The other is the Tee */ + /* network, in which the resistor is divided in */ + /* two, with the capacitance to substrate in */ + /* the middle. */ esOutputResistor(dev, hierName, scale, gate, source, has_model, l, w, 2); @@ -3121,6 +3124,11 @@ spcdevVisit( { esOutputResistor(dev, hierName, scale, source, drain, has_model, l, w, 1); + + spcdevResPi(hierName, gate->dterm_node->efnode_name->efnn_hier, + source->dterm_node->efnode_name->efnn_hier, + drain->dterm_node->efnode_name->efnn_hier, + name); } break; @@ -3851,6 +3859,55 @@ spcnAPHier( return 0; } +/* + * ---------------------------------------------------------------------------- + * + * spcdevResPi -- + * + * Handle a "pi" resistor model: Take the capacitance of the "gate" + * (resistor device layer) to substrate, and split it between the two + * resistor terminals. + * + * Results: + * None. + * + * Side effects: + * Modifies the capacitance values on the terminal and "gate" nodes + * of the resistor device. + * + * ---------------------------------------------------------------------------- + */ + +void +spcdevResPi( + const HierName *prefix, + const HierName *gate_suffix, + const HierName *source_suffix, + const HierName *drain_suffix, + const char *name) +{ + HashEntry *he; + EFNodeName *nngate, *nnsource, *nndrain; + EFCapValue rescap; + + he = EFHNConcatLook(prefix, gate_suffix, name); + if (he == NULL) return; + nngate = (EFNodeName *) HashGetValue(he); + + he = EFHNConcatLook(prefix, drain_suffix, name); + if (he == NULL) return; + nndrain = (EFNodeName *) HashGetValue(he); + + he = EFHNConcatLook(prefix, source_suffix, name); + if (he == NULL) return; + nnsource = (EFNodeName *) HashGetValue(he); + + rescap = nngate->efnn_node->efnode_cap / 2.0; + nnsource->efnn_node->efnode_cap += rescap; + nndrain->efnn_node->efnode_cap += rescap; + nngate->efnn_node->efnode_cap = 0; +} + /* * ---------------------------------------------------------------------------- * diff --git a/ext2spice/ext2spice.h b/ext2spice/ext2spice.h index 2284bfee..9e93c5dd 100644 --- a/ext2spice/ext2spice.h +++ b/ext2spice/ext2spice.h @@ -49,6 +49,7 @@ extern void setDevMult(int i, float f); extern int EFHNSprintf(char *str, HierName *hierName); extern int printSubcktDict(void); extern int spcdevOutNode(const HierName *prefix, const HierName *suffix, const char *name, FILE *outf); +extern void spcdevResPi(const HierName *prefix, const HierName *gate, const HierName *source, const HierName *drain, const char *name); extern int spcnAP(DevTerm *dterm, EFNode *node, int resClass, float scale, char *asterm, char *psterm, float m, FILE *outf, int w); extern int parallelDevs(const devMerge *f1, const devMerge *f2); extern int nodeHspiceName(char *s);