Enable obtaining node info also for code models.
This commit is contained in:
parent
02c6478399
commit
08f4b56de5
|
|
@ -24,6 +24,10 @@ Author: 1985 Thomas L. Quarles
|
||||||
|
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
#include "ngspice/enh.h"
|
#include "ngspice/enh.h"
|
||||||
|
/* XSPICE code models store their terminals in the MIF conn/port tree, not in
|
||||||
|
* the generic GENnode() array, and report DEVpublic.terms == 0. CKTtopologyReduce()
|
||||||
|
* walks that tree explicitly so code-model nodes are counted. */
|
||||||
|
#include "ngspice/mifdefs.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_OMP
|
#ifdef USE_OMP
|
||||||
|
|
@ -49,9 +53,13 @@ Author: 1985 Thomas L. Quarles
|
||||||
*
|
*
|
||||||
* Node degree is counted GENERICALLY over every device type through the
|
* Node degree is counted GENERICALLY over every device type through the
|
||||||
* GENnode() terminal array, so no device family can be missed (which would
|
* GENnode() terminal array, so no device family can be missed (which would
|
||||||
* wrongly prune a live node). Only capacitors and resistors are ever removed.
|
* wrongly prune a live node). XSPICE code models are the one exception: they
|
||||||
* Disable with `set no_topo_reduce` in .spiceinit. It is disabled as well if
|
* report DEVpublic.terms == 0 and keep their node numbers in the MIF conn/port
|
||||||
* option rshunt=xx is selected.*/
|
* tree rather than in GENnode(), so they are walked separately below -- without
|
||||||
|
* that, a node touched only by a code model would look floating and its passive
|
||||||
|
* would be wrongly pruned. Only capacitors and resistors are ever removed.
|
||||||
|
* Disable with `set no_topo_reduce` in .spiceinit. It is disabled as well
|
||||||
|
* if option rshunt=xx is selected.*/
|
||||||
static void
|
static void
|
||||||
CKTtopologyReduce(CKTcircuit *ckt)
|
CKTtopologyReduce(CKTcircuit *ckt)
|
||||||
{
|
{
|
||||||
|
|
@ -81,7 +89,7 @@ CKTtopologyReduce(CKTcircuit *ckt)
|
||||||
|
|
||||||
/* complete, type-agnostic node degree over all device terminals */
|
/* complete, type-agnostic node degree over all device terminals */
|
||||||
for (i = 0; i < DEVmaxnum; i++) {
|
for (i = 0; i < DEVmaxnum; i++) {
|
||||||
if (!DEVices[i] || !ckt->CKThead[i] || !DEVices[i]->DEVpublic.terms)
|
if (!DEVices[i] || !ckt->CKThead[i])
|
||||||
continue;
|
continue;
|
||||||
nterm = *(DEVices[i]->DEVpublic.terms);
|
nterm = *(DEVices[i]->DEVpublic.terms);
|
||||||
if (DEVices[i]->DEVpublic.name) {
|
if (DEVices[i]->DEVpublic.name) {
|
||||||
|
|
@ -90,6 +98,49 @@ CKTtopologyReduce(CKTcircuit *ckt)
|
||||||
else if (!strcmp(DEVices[i]->DEVpublic.name, "Resistor"))
|
else if (!strcmp(DEVices[i]->DEVpublic.name, "Resistor"))
|
||||||
restype = i;
|
restype = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef XSPICE
|
||||||
|
/* XSPICE code models: DEVpublic.terms is 0 and GENnode() does not hold
|
||||||
|
* their nodes, so the generic walk below would count nothing for them.
|
||||||
|
* Walk the MIF conn/port tree and count every analog port's pos/neg node
|
||||||
|
* instead. Event-driven (digital) and vsource-current ports leave these
|
||||||
|
* at 0 (calloc'd) and are skipped by the nd > 0 test.
|
||||||
|
*
|
||||||
|
* A code-model instance IS a MIFinstance, so it is identified by its
|
||||||
|
* instance size -- a plain compile-time integer (sizeof(MIFinstance))
|
||||||
|
* that is identical across the .cm modules. A function-pointer test
|
||||||
|
* (DEVsetup == MIFsetup) is NOT reliable here: code models linked into
|
||||||
|
* separate .cm shared objects carry their own copy of MIFsetup, so the
|
||||||
|
* pointers differ from this translation unit's. */
|
||||||
|
if (DEVices[i]->DEVinstSize &&
|
||||||
|
*(DEVices[i]->DEVinstSize) == (int) sizeof(MIFinstance)) {
|
||||||
|
for (gmod = ckt->CKThead[i]; gmod; gmod = gmod->GENnextModel)
|
||||||
|
for (ginst = gmod->GENinstances; ginst; ginst = ginst->GENnextInstance) {
|
||||||
|
MIFinstance *mif = (MIFinstance *) ginst;
|
||||||
|
int c, p;
|
||||||
|
for (c = 0; c < mif->num_conn; c++) {
|
||||||
|
Mif_Conn_Data_t *conn = mif->conn[c];
|
||||||
|
if (!conn || conn->is_null)
|
||||||
|
continue;
|
||||||
|
for (p = 0; p < conn->size; p++) {
|
||||||
|
Mif_Port_Data_t *port = conn->port[p];
|
||||||
|
int nd;
|
||||||
|
if (!port || port->is_null)
|
||||||
|
continue;
|
||||||
|
nd = port->smp_data.pos_node;
|
||||||
|
if (nd > 0 && nd <= maxnode) degree[nd]++;
|
||||||
|
nd = port->smp_data.neg_node;
|
||||||
|
if (nd > 0 && nd <= maxnode) degree[nd]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue; /* code model handled; skip the generic terminal walk */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!DEVices[i]->DEVpublic.terms)
|
||||||
|
continue;
|
||||||
|
nterm = *(DEVices[i]->DEVpublic.terms);
|
||||||
for (gmod = ckt->CKThead[i]; gmod; gmod = gmod->GENnextModel)
|
for (gmod = ckt->CKThead[i]; gmod; gmod = gmod->GENnextModel)
|
||||||
for (ginst = gmod->GENinstances; ginst; ginst = ginst->GENnextInstance) {
|
for (ginst = gmod->GENinstances; ginst; ginst = ginst->GENnextInstance) {
|
||||||
int *nodes = GENnode(ginst);
|
int *nodes = GENnode(ginst);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue