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 + -
显示快捷键?