mif_inp2.c
来自「ngspice又一个电子CAD仿真软件代码.功能更全」· C语言 代码 · 共 966 行 · 第 1/3 页
C
966 行
should be the port type (MIF_STRING_TOK type). That is, we should be sitting righton the def of the port type (i.e. %vnam, %vd, %id, etc.) Note that the parsershould have stripped the % already.Upon return, this fcn should leave next_token holding the token *after* theport type (i.e. the thing after vnam, v, vd, id, etc). */static voidMIFget_port_type( void *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 { /* Fix by SDB so that the netlist parser uses the actual nature of the port instead of the default state to decide if it is an array. */ /* if ( (*port_type == MIF_DIFF_VOLTAGE) || (*port_type == MIF_DIFF_CURRENT) || (*port_type == MIF_DIFF_CONDUCTANCE) || (*port_type == MIF_DIFF_RESISTANCE) ) { conn_info->is_array = 1; } */ *status = MIF_OK; }}/* ********************************************************************* *//*MIFget_portThis function processes a port being parsed, either single ended,or both connections of a differential.When we call this fcn, next_token should be the *first* netname in the port net list. Depending upon the type of port, this fcn should eat the appropriatenumber of net tokens.When we leave this fcn, next_token should hold the next token after the last netname processed.*/static voidMIFget_port( void *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[1]; /* positive connection node */ CKTnode *neg_node[1]; /* negative connection node */ char *node; /* allocate space in the instance data struct for this port */ if(port_num == 0) { fast->conn[conn_num]->port = (void *) tmalloc(sizeof(void *)); fast->conn[conn_num]->port[0] = (void *) tmalloc(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 *) tmalloc(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,(void **)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[0]->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 */ // This don't work dickhead, INPtermInsert tries to FREE(&node) K.A. Feb 27, 2000 // which was not allocted node = (char*)malloc(2);// added by K.A. march 5th 2000 *node = '0'; // added by K.A. March 5th 2000 node[1] ='\0'; // added by K.A. March 5th 2000// node = "0"; // deleted by K.A. March 5th 2000, this is incorrect, it creates a new pointer // that cause a crash in INPtermInsert() INPtermInsert(ckt, &node, tab,(void **)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[0]->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,(void **)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[0]->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 + =
减小字号Ctrl + -
显示快捷键?