📄 mif_inp2a.c
字号:
} /* check model parameter constraints */ /* some of these should probably be done in MIFgetMod() */ /* to prevent multiple error messages */ for(i = 0; i < DEVices[type]->DEVpublic.num_param; i++) { param_info = &(DEVices[type]->DEVpublic.param[i]); if(mdfast->param[i]->is_null) { if(! param_info->has_default) { LITERR("Parameter on model has no default"); return; } else if((param_info->is_array) && (! param_info->has_conn_ref)) { LITERR("Defaulted array parameter must have associated array connection"); return; } } if((! mdfast->param[i]->is_null) && (param_info->is_array)) { if(param_info->has_conn_ref) { if(fast->conn[param_info->conn_ref]->size != fast->param[i]->size) { LITERR("Array parameter size on model does not match connection size"); return; } } } }}/* ********************************************************************* *//*MIFinit_instThis function initializes the code model specific elements of the inst struct.*/static void MIFinit_inst( MIFmodel *mdfast, /* The model the instance is derived from */ MIFinstance *fast) /* The instance to initialize */{ int mod_type; /* type of this model */ Mif_Conn_Info_t *conn_info; int i; /* get an index into the DEVices information structure */ mod_type = mdfast->MIFmodType; /* allocate code model connector data in instance struct */ fast->num_conn = DEVices[mod_type]->DEVpublic.num_conn; fast->conn = (void *) MALLOC(fast->num_conn * sizeof(void *)); for(i = 0; i < fast->num_conn; i++) fast->conn[i] = (void *) MALLOC(sizeof(Mif_Conn_Data_t)); /* initialize code model connector data */ for(i = 0; i < fast->num_conn; i++) { conn_info = &(DEVices[mod_type]->DEVpublic.conn[i]); fast->conn[i]->name = conn_info->name; fast->conn[i]->description = conn_info->description; fast->conn[i]->is_null = MIF_TRUE; fast->conn[i]->size = 0; fast->conn[i]->port = NULL; switch(conn_info->direction) { case MIF_INOUT: fast->conn[i]->is_input = MIF_TRUE; fast->conn[i]->is_output = MIF_TRUE; break; case MIF_IN: fast->conn[i]->is_input = MIF_TRUE; fast->conn[i]->is_output = MIF_FALSE; break; case MIF_OUT: fast->conn[i]->is_input = MIF_FALSE; fast->conn[i]->is_output = MIF_TRUE; break; default: printf("\nERROR - Impossible direction type in MIFinit_inst\n"); exit(1); } } /* allocate and copy instance variable data to the instance */ fast->num_inst_var = DEVices[mod_type]->DEVpublic.num_inst_var; fast->inst_var = (void *) MALLOC(fast->num_inst_var * sizeof(void *)); for(i = 0; i < fast->num_inst_var; i++) { fast->inst_var[i] = (void *) MALLOC(sizeof(Mif_Inst_Var_Data_t)); if(DEVices[mod_type]->DEVpublic.inst_var[i].is_array) { fast->inst_var[i]->size = 0; fast->inst_var[i]->element = NULL; /* The code model allocates space for the data and sets the size */ } else { fast->inst_var[i]->size = 1; fast->inst_var[i]->element = (void *) MALLOC(sizeof(Mif_Value_t)); } } /* copy model parameter data to the instance */ fast->num_param = mdfast->num_param; fast->param = mdfast->param; /* initialize any additional instance data */ fast->initialized = MIF_FALSE; fast->analog = MIF_FALSE; fast->event_driven = MIF_FALSE; fast->inst_index = 0;}/* ********************************************************************* *//*MIFget_port_typeThis function gets the port type identifier and checks it for validity.*/static void MIFget_port_type( GENERIC *ckt, /* circuit structure to put mod/inst structs in */ INPtables *tab, /* symbol table for node names, etc. */ card *current, /* MUST be named 'current' for spice macros */ char **line, char **next_token, Mif_Token_Type_t *next_token_type, Mif_Port_Type_t *port_type, char **port_type_str, Mif_Conn_Info_t *conn_info, /* for faster access to conn info struct */ Mif_Status_t *status){ Mif_Boolean_t found_type; char *temp; int i; if(**line == '\0') { LITERR("Missing connections on A device"); *status = MIF_ERROR; return; } if(*next_token_type != MIF_STRING_TOK) { LITERR("Invalid port type specifier"); *status = MIF_ERROR; return; } /* OK, so get the port type string from the token and read next token */ temp = *next_token; *next_token = MIFget_token(line, next_token_type); /* check port type for validity */ found_type = MIF_FALSE; for(i = 0; i < conn_info->num_allowed_types; i++) { if(strcmp(temp, conn_info->allowed_type_str[i]) == 0) { found_type = MIF_TRUE; *port_type = conn_info->allowed_type[i]; *port_type_str = temp; break; } } if(! found_type) { LITERR("Port type is invalid"); *status = MIF_ERROR; } else *status = MIF_OK;}/* ********************************************************************* *//*MIFget_portThis function processes a port being parsed, either single ended,or both connections of a differential.*/static voidMIFget_port( GENERIC *ckt, /* circuit structure to put mod/inst structs in */ INPtables *tab, /* symbol table for node names, etc. */ card *current, /* MUST be named 'current' for spice macros */ MIFinstance *fast, /* pointer to instance struct */ char **line, char **next_token, Mif_Token_Type_t *next_token_type, Mif_Port_Type_t def_port_type, char *def_port_type_str, Mif_Conn_Info_t *conn_info, /* for faster access to conn info struct */ int conn_num, int port_num, Mif_Status_t *status){ CKTnode *pos_node; /* positive connection node */ CKTnode *neg_node; /* negative connection node */ char *node; /* get the leading port type if any */ if(*next_token_type == MIF_PERCENT_TOK) { /* get the port type identifier and check it for validity */ *next_token = MIFget_token(line, next_token_type); MIFget_port_type(ckt, tab, current, line, next_token, next_token_type, &def_port_type, &def_port_type_str, conn_info, status); if(*status == MIF_ERROR) { return; } } /* allocate space in the instance data struct for this port */ if(port_num == 0) { fast->conn[conn_num]->port = (void *) MALLOC(sizeof(void *)); fast->conn[conn_num]->port[0] = (void *) MALLOC(sizeof(Mif_Port_Data_t)); } else { fast->conn[conn_num]->port = (void *) REALLOC( fast->conn[conn_num]->port, ((port_num + 1) * sizeof(void *)) ); fast->conn[conn_num]->port[port_num] = (void *) MALLOC(sizeof(Mif_Port_Data_t)); } /* store the port type information in the instance struct */ fast->conn[conn_num]->port[port_num]->type = def_port_type; fast->conn[conn_num]->port[port_num]->type_str = def_port_type_str; /* check for a leading tilde on digital ports */ if(*next_token_type == MIF_TILDE_TOK) { if((def_port_type != MIF_DIGITAL) && (def_port_type != MIF_USER_DEFINED)) { LITERR("ERROR - Tilde not allowed on analog nodes"); *status = MIF_ERROR; return; } fast->conn[conn_num]->port[port_num]->invert = MIF_TRUE; /* eat the tilde and get the next token */ *next_token = MIFget_token(line, next_token_type); if(**line == '\0') { LITERR("ERROR - Not enough ports"); *status = MIF_ERROR; return; } } else fast->conn[conn_num]->port[port_num]->invert = MIF_FALSE; /* check for null port */ if(*next_token_type == MIF_NULL_TOK) { /* make sure null is allowed */ if(! conn_info->null_allowed) { LITERR("NULL connection found where not allowed"); *status = MIF_ERROR; return; } /* set the (port specific) null flag to true */ fast->conn[conn_num]->port[port_num]->is_null = MIF_TRUE; /* set input value to zero in case user code model refers to it */ fast->conn[conn_num]->port[port_num]->input.rvalue = 0.0; /* eat the null token and return */ *next_token = MIFget_token(line, next_token_type); *status = MIF_OK; return; } else { /* set the (port specific) null flag to false */ fast->conn[conn_num]->port[port_num]->is_null = MIF_FALSE; } /* next token must be a node/instance identifier ... */ if(*next_token_type != MIF_STRING_TOK) { LITERR("ERROR - Expected node/instance identifier"); *status = MIF_ERROR; return; } /* Get the first connection or the voltage source name */ switch(def_port_type) { case MIF_VOLTAGE: case MIF_DIFF_VOLTAGE: case MIF_CURRENT: case MIF_DIFF_CURRENT: case MIF_CONDUCTANCE: case MIF_DIFF_CONDUCTANCE: case MIF_RESISTANCE: case MIF_DIFF_RESISTANCE: /* Call the spice3c1 function to put this node in the node list in ckt */ INPtermInsert(ckt, next_token, tab, &pos_node); /* store the equation number and node identifier */ /* This is the equivalent of what CKTbindNode() does in 3C1 */ fast->conn[conn_num]->port[port_num]->pos_node_str = *next_token; fast->conn[conn_num]->port[port_num]->smp_data.pos_node = pos_node->number; break; case MIF_VSOURCE_CURRENT: /* Call the spice3c1 function to put this vsource instance name in */ /* the symbol table */ INPinsert(next_token, tab); /* Now record the name of the vsource instance for processing */ /* later by MIFsetup. This is equivalent to what INPpName */ /* does in 3C1. Checking to see if the source is present in */ /* the circuit is deferred to MIFsetup as is done in 3C1. */ fast->conn[conn_num]->port[port_num]->vsource_str = *next_token; break; case MIF_DIGITAL: case MIF_USER_DEFINED: /* Insert data into event-driven info structs */ EVTtermInsert(ckt, fast, *next_token, def_port_type_str, conn_num, port_num, &(current->error)); if(current->error) { *status = MIF_ERROR; return; } break; default: /* impossible connection type */ LITERR("INTERNAL ERROR - Impossible connection type"); *status = MIF_ERROR; return; } /* get the next token */ *next_token = MIFget_token(line, next_token_type); /* get other node if appropriate */ switch(def_port_type) { case MIF_VOLTAGE: case MIF_CURRENT: case MIF_CONDUCTANCE: case MIF_RESISTANCE: /* These are single ended types, so default other node to ground */ node = "0"; INPtermInsert(ckt, &node, tab, &neg_node); fast->conn[conn_num]->port[port_num]->neg_node_str = node; fast->conn[conn_num]->port[port_num]->smp_data.neg_node = neg_node->number; break; case MIF_DIFF_VOLTAGE: case MIF_DIFF_CURRENT: case MIF_DIFF_CONDUCTANCE: case MIF_DIFF_RESISTANCE: /* These are differential types, so get the other node */ if((**line == '\0') || (*next_token_type != MIF_STRING_TOK)) { LITERR("ERROR - Expected node identifier"); *status = MIF_ERROR; return; } INPtermInsert(ckt, next_token, tab, &neg_node); fast->conn[conn_num]->port[port_num]->neg_node_str = *next_token; fast->conn[conn_num]->port[port_num]->smp_data.neg_node = neg_node->number; *next_token = MIFget_token(line, next_token_type); break; default: /* must be vsource name, digital, or user defined, so there is no other node */ break; } *status = MIF_OK; return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -