📄 evtload.c
字号:
/*============================================================================FILE EVTload.cMEMBER OF process XSPICECopyright 1991Georgia Tech Research CorporationAtlanta, Georgia 30332All Rights ReservedPROJECT A-8503AUTHORS 9/12/91 Bill KuhnMODIFICATIONS <date> <person name> <nature of modifications>SUMMARY This file contains function EVTload which is used to call a specified event-driven or hybrid code model during an event-driven iteration. The 'CALL_TYPE' is set to 'EVENT_DRIVEN' when the model is called from this function.INTERFACES int EVTload(CKTcircuit *ckt, int inst_index)REFERENCED FILES None.NON-STANDARD FEATURES None.============================================================================*/#include <stdio.h>#include "ngspice.h"#include "cktdefs.h"//#include "util.h"#include "devdefs.h"#include "sperror.h"#include "mif.h"#include "evt.h"#include "evtudn.h"#include "mifproto.h"#include "evtproto.h"extern SPICEdev **DEVices;static void EVTcreate_state( CKTcircuit *ckt, int inst_index);static void EVTadd_msg( CKTcircuit *ckt, int port_index, char *msg_text);static void EVTcreate_output_event( CKTcircuit *ckt, int node_index, int output_index, void **value_ptr);static void EVTprocess_output( CKTcircuit *ckt, Mif_Boolean_t changed, int output_index, Mif_Boolean_t invert, double delay);/*EVTloadThis function calls the code model function for the specifiedinstance with CALL_TYPE set to EVENT_DRIVEN. Event outputs,messages, etc. are processed on return from the code model.Analog outputs, partials, etc. should not be computed by thecode model when the call type is event-driven and areignored.*/int EVTload( CKTcircuit *ckt, /* The circuit structure */ int inst_index) /* The instance to call code model for */{ int i; int j; int num_conn; int num_port; int mod_type; Mif_Conn_Data_t *conn; Mif_Port_Data_t *port; Mif_Private_t cm_data; MIFinstance *inst; Evt_Node_Data_t *node_data; void *value_ptr; /* ***************************** */ /* Prepare the code model inputs */ /* ***************************** */ /* Get pointer to instance data structure and other data */ /* needed for fast access */ inst = ckt->evt->info.inst_table[inst_index]->inst_ptr; node_data = ckt->evt->data.node; /* Setup circuit data in struct to be passed to code model function */ if(inst->initialized) cm_data.circuit.init = MIF_FALSE; else cm_data.circuit.init = MIF_TRUE; cm_data.circuit.anal_init = MIF_FALSE; cm_data.circuit.anal_type = g_mif_info.circuit.anal_type; if(g_mif_info.circuit.anal_type == MIF_TRAN) cm_data.circuit.time = g_mif_info.circuit.evt_step; else cm_data.circuit.time = 0.0; cm_data.circuit.call_type = MIF_EVENT_DRIVEN; cm_data.circuit.temperature = ckt->CKTtemp - 273.15; /* Setup data needed by cm_... functions */ g_mif_info.ckt = ckt; g_mif_info.instance = inst; g_mif_info.errmsg = ""; g_mif_info.circuit.call_type = MIF_EVENT_DRIVEN; if(inst->initialized) g_mif_info.circuit.init = MIF_FALSE; else g_mif_info.circuit.init = MIF_TRUE; /* If after initialization and in transient analysis mode */ /* create a new state for the instance */ if((g_mif_info.circuit.anal_type == MIF_TRAN) && inst->initialized) EVTcreate_state(ckt, inst_index); /* Loop through all connections on the instance and setup */ /* load, total_load, and msg on all ports, and changed flag */ /* and output pointer on all outputs */ num_conn = inst->num_conn; for(i = 0; i < num_conn; i++) { conn = inst->conn[i]; /* if connection is null, continue to next */ if(conn->is_null) continue; /* Loop through each port on the connection */ num_port = conn->size; for(j = 0; j < num_port; j++) { port = conn->port[j]; /* Skip if port is null */ if(port->is_null) continue; /* If port type is Digital or User-Defined */ if((port->type == MIF_DIGITAL) || (port->type == MIF_USER_DEFINED)) { /* Initialize the msg pointer on the port to NULL, */ /* initialize the load value to zero, and get the total load */ port->msg = NULL; port->load = 0.0; port->total_load = node_data->total_load[port->evt_data.node_index]; /* If connection is an output, initialize changed to true */ /* and create a new output event object in the free list */ /* if transient analysis mode */ if(conn->is_output) { port->changed = MIF_TRUE; if(g_mif_info.circuit.anal_type == MIF_TRAN) { EVTcreate_output_event(ckt, port->evt_data.node_index, port->evt_data.output_index, &value_ptr); port->output.pvalue = value_ptr; } } } else { /* Get the analog input value. All we need to do is */ /* set it to zero if mode is INITJCT. Otherwise, value */ /* should still be around from last successful analog call */ if(ckt->CKTmode & MODEINITJCT) port->input.rvalue = 0.0; } } /* end for number of ports */ } /* end for number of connections */ /* Prepare the structure to be passed to the code model */ cm_data.num_conn = inst->num_conn; cm_data.conn = inst->conn; cm_data.num_param = inst->num_param; cm_data.param = inst->param; cm_data.num_inst_var = inst->num_inst_var; cm_data.inst_var = inst->inst_var; /* ******************* */ /* Call the code model */ /* ******************* */ mod_type = inst->MIFmodPtr->MIFmodType; (*(DEVices[mod_type]->DEVpublic.cm_func)) (&cm_data); /* ****************************** */ /* Process the code model outputs */ /* ****************************** */ /* Loop through all connections and ports and process the msgs */ /* and event outputs */ num_conn = inst->num_conn; for(i = 0; i < num_conn; i++) { conn = inst->conn[i]; if(conn->is_null) continue; /* Loop through each port on the connection */ num_port = conn->size; for(j = 0; j < num_port; j++) { port = conn->port[j]; /* Skip if port is null */ if(port->is_null) continue; /* Process the message if any */ if(port->msg) EVTadd_msg(ckt, port->evt_data.port_index, port->msg); /* If this is the initialization pass, process the load factor */ if(! inst->initialized) { node_data->total_load[port->evt_data.node_index] += port->load; } /* If connection is not an event output, continue to next port */ if(! conn->is_output) continue; if((port->type != MIF_DIGITAL) && (port->type != MIF_USER_DEFINED)) continue; /* If output changed, process it */ EVTprocess_output(ckt, port->changed, port->evt_data.output_index, port->invert, port->delay); /* And prevent erroneous models from overwriting it during */ /* analog iterations */ if(g_mif_info.circuit.anal_type == MIF_TRAN) port->output.pvalue = NULL; } /* end for number of ports */ } /* end for number of connections */ /* Record statistics */ if(g_mif_info.circuit.anal_type == MIF_DC) (ckt->evt->data.statistics->op_load_calls)++; else if(g_mif_info.circuit.anal_type == MIF_TRAN) (ckt->evt->data.statistics->tran_load_calls)++; /* Mark that the instance has been called once */ inst->initialized = MIF_TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -