From e80b724460429d1235b6720e696ee0fafb8445c3 Mon Sep 17 00:00:00 2001 From: Giles Atkinson <“gatk555@gmail.com”> Date: Fri, 20 May 2022 19:15:54 +0100 Subject: [PATCH] Add two functions to the Code Model Library: cm_get_node_name() makes circuit node names available to diagnostics, while cm_probe_node() is needed for a bidirectional A/D bridge. --- src/include/ngspice/cmproto.h | 3 ++ src/include/ngspice/dllitf.h | 3 ++ src/xspice/cm/cm.c | 80 +++++++++++++++++++++++++++++++++++ src/xspice/cm/cmexport.c | 2 + src/xspice/icm/dlmain.c | 10 +++++ 5 files changed, 98 insertions(+) diff --git a/src/include/ngspice/cmproto.h b/src/include/ngspice/cmproto.h index cee92fcae..0a117f561 100644 --- a/src/include/ngspice/cmproto.h +++ b/src/include/ngspice/cmproto.h @@ -96,6 +96,9 @@ int cm_message_printf(const char *fmt, ...); double cm_netlist_get_c(void); double cm_netlist_get_l(void); +const char *cm_get_node_name(const char *, unsigned int); +bool cm_probe_node(unsigned int, unsigned int, void *); + Complex_t cm_complex_set(double real, double imag); Complex_t cm_complex_add(Complex_t x, Complex_t y); Complex_t cm_complex_subtract(Complex_t x, Complex_t y); diff --git a/src/include/ngspice/dllitf.h b/src/include/ngspice/dllitf.h index 8bdbc2354..736111af8 100644 --- a/src/include/ngspice/dllitf.h +++ b/src/include/ngspice/dllitf.h @@ -58,6 +58,9 @@ struct coreInfo_t { int ((*dllitf_cm_message_send)(char *)); double ((*dllitf_cm_netlist_get_c)(void)); double ((*dllitf_cm_netlist_get_l)(void)); + const char * ((*dllitf_cm_get_node_name)(const char *, unsigned int)); + bool ((*dllitf_cm_probe_node)(unsigned int, unsigned int, + void *)); Complex_t ((*dllitf_cm_complex_set)(double, double)); Complex_t ((*dllitf_cm_complex_add)(Complex_t, Complex_t)); Complex_t ((*dllitf_cm_complex_subtract)(Complex_t, Complex_t)); diff --git a/src/xspice/cm/cm.c b/src/xspice/cm/cm.c index eea35d4c3..0b9626bd6 100644 --- a/src/xspice/cm/cm.c +++ b/src/xspice/cm/cm.c @@ -38,6 +38,9 @@ INTERFACES cm_get_path() cm_get_circuit() + cm_get_node_name() + cm_probe_node() + REFERENCED FILES None. @@ -49,6 +52,8 @@ NON-STANDARD FEATURES =========================================================================== */ #include "ngspice/ngspice.h" #include "ngspice/cm.h" +#include "ngspice/evt.h" +#include "ngspice/evtudn.h" #include "ngspice/enh.h" #include "ngspice/mif.h" #include "ngspice/cktdefs.h" @@ -722,3 +727,78 @@ CKTcircuit *cm_get_circuit(void) { return(g_mif_info.ckt); } + +/* Get the name of a circuit node connected to a port. */ + +const char *cm_get_node_name(const char *port_name, unsigned int index) +{ + MIFinstance *instance; + Mif_Conn_Data_t *conn; + Mif_Port_Data_t *port; + int i; + + instance = g_mif_info.instance; + for (i = 0; i < instance->num_conn; ++i) { + conn = instance->conn[i]; + if (!strcmp(port_name, conn->name)) { + if (index >= (unsigned int)conn->size) + return NULL; + port = conn->port[index]; + if (port->type == MIF_DIGITAL || port->type == MIF_USER_DEFINED) { + /* Event node, no name in port data. */ + + i = port->evt_data.node_index; + return g_mif_info.ckt->evt->info.node_table[i]->name; + } + return port->pos_node_str; + } + } + return NULL; +} + +/* Test the resolved value of a connected Digital/UDN node, given + * an assumed value for a particular port. + */ + +bool cm_probe_node(unsigned int conn_index, // Connection index + unsigned int port_index, // Port index within connection + void *value) // Inout UDN value +{ + MIFinstance *instance; + Mif_Conn_Data_t *conn; + Mif_Port_Data_t *port; + Mif_Evt_Data_t *edata; + Evt_Node_Info_t *node_info; + Evt_Node_t *this; + void *hold; + int num_outputs; + + instance = g_mif_info.instance; + if (conn_index >= (unsigned int)instance->num_conn) + return FALSE; + conn = instance->conn[conn_index]; + if (port_index >= (unsigned int)conn->size) + return FALSE; + port = conn->port[port_index]; + if (port->type != MIF_DIGITAL && port->type != MIF_USER_DEFINED) + return FALSE; + edata = &port->evt_data; + node_info = g_mif_info.ckt->evt->info.node_table[edata->node_index]; + num_outputs = node_info->num_outputs; + if (num_outputs <= 1) + return num_outputs == 1; // This should be the only output. + this = g_mif_info.ckt->evt->data.node->rhsold + edata->node_index; + + /* Replace the actual output with the test value and resolve. + * It is assumed that the resolve function will not use its output + * as a working variable. (True for digital, real and integer.) + */ + + hold = this->output_value[edata->output_subindex]; + this->output_value[edata->output_subindex] = value; + g_evt_udn_info[node_info->udn_index]->resolve(num_outputs, + this->output_value, + value); + this->output_value[edata->output_subindex] = hold; + return TRUE; +} diff --git a/src/xspice/cm/cmexport.c b/src/xspice/cm/cmexport.c index fa8e9199c..e0a98849d 100644 --- a/src/xspice/cm/cmexport.c +++ b/src/xspice/cm/cmexport.c @@ -58,6 +58,8 @@ struct coreInfo_t coreInfo = cm_message_send, cm_netlist_get_c, cm_netlist_get_l, + cm_get_node_name, + cm_probe_node, cm_complex_set, cm_complex_add, cm_complex_subtract, diff --git a/src/xspice/icm/dlmain.c b/src/xspice/icm/dlmain.c index be7533ce8..a62713fcd 100644 --- a/src/xspice/icm/dlmain.c +++ b/src/xspice/icm/dlmain.c @@ -338,6 +338,16 @@ double cm_netlist_get_l(void) { return (coreitf->dllitf_cm_netlist_get_l)(); } +const char *cm_get_node_name(const char *port, unsigned int index) { + return coreitf->dllitf_cm_get_node_name(port, index); +} + +bool cm_probe_node(unsigned int conn_index, + unsigned int port_index, + void *value) { + return coreitf->dllitf_cm_probe_node(conn_index, port_index, value); +} + Complex_t cm_complex_set(double real, double imag) { return (coreitf->dllitf_cm_complex_set)(real,imag); }