⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mif_inp2a.c

📁 支持数字元件仿真的SPICE插件
💻 C
📖 第 1 页 / 共 2 页
字号:
    }    /* 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 + -