/*ARGSUSED*/ int CCVSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) { CCVSmodel *model = (CCVSmodel*)inModel; CCVSinstance *here; int error; CKTnode *tmp; NG_IGNORE(states); /* loop through all the voltage source models */ for( ; model != NULL; model = model->CCVSnextModel ) { /* loop through all the instances of the model */ for (here = model->CCVSinstances; here != NULL ; here=here->CCVSnextInstance) { if(here->CCVSposNode == here->CCVSnegNode) { SPfrontEnd->IFerrorf (ERR_FATAL, "instance %s is a shorted CCVS", here->CCVSname); return(E_UNSUPP); } if(here->CCVSbranch==0) { error = CKTmkCur(ckt,&tmp,here->CCVSname, "branch"); if(error) return(error); here->CCVSbranch = tmp->number; } here->CCVScontBranch = CKTfndBranch(ckt,here->CCVScontName); if(here->CCVScontBranch == 0) { SPfrontEnd->IFerrorf (ERR_FATAL, "%s: unknown controlling source %s", here->CCVSname, here->CCVScontName); return(E_BADPARM); } /* macro to make elements with built in test for out of memory */ #define TSTALLOC(ptr,first,second) \ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ return(E_NOMEM);\ } } while(0) TSTALLOC(CCVSposIbrptr, CCVSposNode, CCVSbranch); TSTALLOC(CCVSnegIbrptr, CCVSnegNode, CCVSbranch); TSTALLOC(CCVSibrNegptr, CCVSbranch, CCVSnegNode); TSTALLOC(CCVSibrPosptr, CCVSbranch, CCVSposNode); TSTALLOC(CCVSibrContBrptr, CCVSbranch, CCVScontBranch); } } return(OK); }
/* ARGSUSED */ int VSRCsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *state) /* load the voltage source structure with those pointers needed later * for fast matrix loading */ { VSRCmodel *model = (VSRCmodel *)inModel; VSRCinstance *here; CKTnode *tmp; int error; NG_IGNORE(state); /* loop through all the voltage source models */ for( ; model != NULL; model = model->VSRCnextModel ) { /* loop through all the instances of the model */ for (here = model->VSRCinstances; here != NULL ; here=here->VSRCnextInstance) { if(here->VSRCposNode == here->VSRCnegNode) { SPfrontEnd->IFerror (ERR_FATAL, "instance %s is a shorted VSRC", &here->VSRCname); return(E_UNSUPP); } if(here->VSRCbranch == 0) { error = CKTmkCur(ckt,&tmp,here->VSRCname,"branch"); if(error) return(error); here->VSRCbranch = tmp->number; } /* macro to make elements with built in test for out of memory */ #define TSTALLOC(ptr,first,second) \ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ return(E_NOMEM);\ } } while(0) TSTALLOC(VSRCposIbrptr, VSRCposNode, VSRCbranch); TSTALLOC(VSRCnegIbrptr, VSRCnegNode, VSRCbranch); TSTALLOC(VSRCibrNegptr, VSRCbranch, VSRCnegNode); TSTALLOC(VSRCibrPosptr, VSRCbranch, VSRCposNode); } } return(OK); }
/* load the voltage source structure with those pointers needed later * for fast matrix loading */ int VSRCpzSetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *state) { VSRCmodel *model = (VSRCmodel *)inModel; VSRCinstance *here; CKTnode *tmp; int error; NG_IGNORE(state); /* loop through all the voltage source models */ for( ; model != NULL; model = VSRCnextModel(model)) { /* loop through all the instances of the model */ for (here = VSRCinstances(model); here != NULL ; here = VSRCnextInstance(here)) { if (here->VSRCbranch == 0) { error = CKTmkCur(ckt,&tmp,here->VSRCname,"branch"); if(error) return(error); here->VSRCbranch = tmp->number; } /* macro to make elements with built in test for out of memory */ #define TSTALLOC(ptr,first,second) \ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ return(E_NOMEM);\ } } while(0) TSTALLOC(VSRCposIbrPtr, VSRCposNode, VSRCbranch); TSTALLOC(VSRCnegIbrPtr, VSRCnegNode, VSRCbranch); TSTALLOC(VSRCibrNegPtr, VSRCbranch, VSRCnegNode); TSTALLOC(VSRCibrPosPtr, VSRCbranch, VSRCposNode); TSTALLOC(VSRCibrIbrPtr, VSRCbranch, VSRCbranch); } } return(OK); }
int TXLfindBr(CKTcircuit *ckt, GENmodel *inModel, IFuid name) { TXLmodel *model = (TXLmodel *)inModel; TXLinstance *here; int error; CKTnode *tmp; for( ; model != NULL; model = model->TXLnextModel) { for (here = model->TXLinstances; here != NULL; here = here->TXLnextInstance) { if(here->TXLname == name) { if(here->TXLbranch == 0) { error = CKTmkCur(ckt,&tmp,here->TXLname,"branch"); if(error) return(error); here->TXLbranch = tmp->number; } return(here->TXLbranch); } } } return(0); }
/*ARGSUSED*/ int ASRCsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) /* load the voltage source structure with those * pointers needed later for fast matrix loading */ { ASRCinstance *here; ASRCmodel *model = (ASRCmodel*)inModel; int error, i, j; int v_first; CKTnode *tmp; /* loop through all the user models*/ for( ; model != NULL; model = model->ASRCnextModel ) { /* loop through all the instances of the model */ for (here = model->ASRCinstances; here != NULL ; here=here->ASRCnextInstance) { here->ASRCposptr = (double **)MALLOC(0); j=0; /*strchr of the array holding ptrs to SMP */ v_first = 1; if( here->ASRCtype == ASRC_VOLTAGE){ if(here->ASRCbranch==0) { error = CKTmkCur(ckt,&tmp,here->ASRCname,"branch"); if(error) return(error); here->ASRCbranch = tmp->number; } } /* macro to make elements with built in test for out of memory */ #define TSTALLOC(ptr,first,second) \ if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ return(E_NOMEM);\ } #define MY_TSTALLOC(ptr,first,second) \ if((here->ptr = SMPmakeElt(matrix,here->first,((CKTnode*)(second))->number))\ ==(double *)NULL){\ return(E_NOMEM);\ } /* For each controlling variable set the entries in the vector of the positions of the SMP */ if (!here->ASRCtree) return E_PARMVAL; for( i=0; i < here->ASRCtree->numVars; i++){ switch(here->ASRCtree->varTypes[i]){ case IF_INSTANCE: here->ASRCcont_br = CKTfndBranch(ckt, here->ASRCtree->vars[i].uValue); if(here->ASRCcont_br == 0) { IFuid namarray[2]; namarray[0] = here->ASRCname; namarray[1] = here->ASRCtree->vars[i].uValue; (*(SPfrontEnd->IFerror))(ERR_FATAL, "%s: unknown controlling source %s",namarray); return(E_BADPARM); } if( here->ASRCtype == ASRC_VOLTAGE){ /* CCVS */ if(v_first){ here->ASRCposptr = (double **) REALLOC(here->ASRCposptr, (sizeof(double *)*(j+5))); TSTALLOC(ASRCposptr[j++],ASRCposNode,ASRCbranch); TSTALLOC(ASRCposptr[j++],ASRCnegNode,ASRCbranch); TSTALLOC(ASRCposptr[j++],ASRCbranch,ASRCnegNode); TSTALLOC(ASRCposptr[j++],ASRCbranch,ASRCposNode); TSTALLOC(ASRCposptr[j++],ASRCbranch,ASRCcont_br); v_first = 0; } else{ here->ASRCposptr = (double **) REALLOC(here->ASRCposptr, (sizeof(double *)*(j+1))); TSTALLOC(ASRCposptr[j++],ASRCbranch,ASRCcont_br); } } else if(here->ASRCtype == ASRC_CURRENT){ /* CCCS */ here->ASRCposptr = (double **) REALLOC(here->ASRCposptr, (sizeof(double *) * (j+2))); TSTALLOC(ASRCposptr[j++],ASRCposNode,ASRCcont_br); TSTALLOC(ASRCposptr[j++],ASRCnegNode,ASRCcont_br); } else{ return (E_BADPARM); } break; case IF_NODE: if( here->ASRCtype == ASRC_VOLTAGE){ /* VCVS */ if(v_first){ here->ASRCposptr = (double **) REALLOC(here->ASRCposptr, (sizeof(double *) * (j+5))); TSTALLOC(ASRCposptr[j++],ASRCposNode,ASRCbranch); TSTALLOC(ASRCposptr[j++],ASRCnegNode,ASRCbranch); TSTALLOC(ASRCposptr[j++],ASRCbranch,ASRCnegNode); TSTALLOC(ASRCposptr[j++],ASRCbranch,ASRCposNode); MY_TSTALLOC(ASRCposptr[j++],ASRCbranch,here->ASRCtree->vars[i].nValue); v_first = 0; } else{ here->ASRCposptr = (double **) REALLOC(here->ASRCposptr, (sizeof(double *) * (j+1))); MY_TSTALLOC(ASRCposptr[j++],ASRCbranch,here->ASRCtree->vars[i].nValue); } } else if(here->ASRCtype == ASRC_CURRENT){ /* VCCS */ here->ASRCposptr = (double **) REALLOC(here->ASRCposptr, (sizeof(double *) * (j+2))); MY_TSTALLOC(ASRCposptr[j++],ASRCposNode,here->ASRCtree->vars[i].nValue); MY_TSTALLOC(ASRCposptr[j++],ASRCnegNode,here->ASRCtree->vars[i].nValue); } else{ return (E_BADPARM); } break; default: break; } } } } return(OK); }
/* ARGSUSED */ int TXLsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit*ckt, int *state) { TXLmodel *model = (TXLmodel *)inModel; TXLinstance *here; CKTnode *tmp; int error; NG_IGNORE(state); /* loop through all the models */ for( ; model != NULL; model = model->TXLnextModel ) { if (!model->Rgiven) { SPfrontEnd->IFerrorf (ERR_FATAL, "model %s: lossy line series resistance not given", model->TXLmodName); return(E_BADPARM); } if (!model->Ggiven) { SPfrontEnd->IFerrorf (ERR_FATAL, "model %s: lossy line parallel conductance not given", model->TXLmodName); return(E_BADPARM); } if (!model->Lgiven) { SPfrontEnd->IFerrorf (ERR_FATAL, "model %s: lossy line series inductance not given", model->TXLmodName); return (E_BADPARM); } if (!model->Cgiven) { SPfrontEnd->IFerrorf (ERR_FATAL, "model %s: lossy line parallel capacitance not given", model->TXLmodName); return (E_BADPARM); } if (!model->lengthgiven) { SPfrontEnd->IFerrorf (ERR_FATAL, "model %s: lossy line length must be given", model->TXLmodName); return (E_BADPARM); } /* loop through all the instances of the model */ for (here = model->TXLinstances; here != NULL ; here=here->TXLnextInstance) { /* macro to make elements with built in test for out of memory */ #define TSTALLOC(ptr,first,second) \ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ return(E_NOMEM);\ } } while(0) if (! here->TXLibr1Given) { error = CKTmkCur(ckt, &tmp, here->TXLname, "branch1"); if (error) return (error); here->TXLibr1 = tmp->number; } if (! here->TXLibr2Given) { error = CKTmkCur(ckt, &tmp, here->TXLname, "branch2"); if (error) return (error); here->TXLibr2 = tmp->number; } TSTALLOC(TXLposPosptr, TXLposNode, TXLposNode); TSTALLOC(TXLposNegptr, TXLposNode, TXLnegNode); TSTALLOC(TXLnegPosptr, TXLnegNode, TXLposNode); TSTALLOC(TXLnegNegptr, TXLnegNode, TXLnegNode); TSTALLOC(TXLibr1Posptr, TXLibr1, TXLposNode); TSTALLOC(TXLibr2Negptr, TXLibr2, TXLnegNode); TSTALLOC(TXLnegIbr2ptr, TXLnegNode, TXLibr2); TSTALLOC(TXLposIbr1ptr, TXLposNode, TXLibr1); TSTALLOC(TXLibr1Ibr1ptr, TXLibr1, TXLibr1); TSTALLOC(TXLibr2Ibr2ptr, TXLibr2, TXLibr2); TSTALLOC(TXLibr1Negptr, TXLibr1, TXLnegNode); TSTALLOC(TXLibr2Posptr, TXLibr2, TXLposNode); TSTALLOC(TXLibr1Ibr2ptr, TXLibr1, TXLibr2); TSTALLOC(TXLibr2Ibr1ptr, TXLibr2, TXLibr1); here->in_node_name = CKTnodName(ckt,here->TXLposNode); here->out_node_name = CKTnodName(ckt,here->TXLnegNode); ReadTxL(here, ckt); } } return(OK); }
int MIFsetup( SMPmatrix *matrix, /* The analog simulation matrix structure */ GENmodel *inModel, /* The head of the model list */ CKTcircuit *ckt, /* The circuit structure */ int *states) /* The states vector */ { MIFmodel *model; MIFinstance *here; int mod_type; int max_size; int size; int error; int num_conn; int num_port; int num_port_k; int i; int j; int k; int l; Mif_Port_Type_t type; Mif_Port_Type_t in_type; Mif_Port_Type_t out_type; Mif_Cntl_Src_Type_t cntl_src_type; Mif_Smp_Ptr_t *smp_data_out; Mif_Smp_Ptr_t *smp_data_cntl; Mif_Param_Info_t *param_info; /* Mif_Conn_Info_t *conn_info;*/ Mif_Boolean_t is_input; Mif_Boolean_t is_output; char *suffix; CKTnode *tmp; /* Setup for access into MIF specific model data */ model = (MIFmodel *) inModel; mod_type = model->MIFmodType; /* loop through all models of this type */ for( ; model != NULL; model = model->MIFnextModel) { /* For each parameter not given explicitly on the .model */ /* card, default it */ for(i = 0; i < model->num_param; i++) { if(model->param[i]->is_null) { /* setup a pointer for quick access */ param_info = &(DEVices[mod_type]->DEVpublic.param[i]); /* determine the size and allocate the parameter element(s) */ if(! param_info->is_array) { model->param[i]->size = 1; model->param[i]->element = TMALLOC(Mif_Value_t, 1); } else { /* parameter is an array */ /* MIF_INP2A() parser assures that there is an associated array connection */ /* Since several instances may share this model, we have to create an array */ /* big enough for the instance with the biggest connection array */ max_size = 0; for(here = model->MIFinstances; here != NULL; here = here->MIFnextInstance) { size = here->conn[param_info->conn_ref]->size; if(size > max_size) max_size = size; } model->param[i]->size = max_size; model->param[i]->element = TMALLOC(Mif_Value_t, max_size); } /* end if parameter is an array */ /* set the parameter element(s) to default value */ for(j = 0; j < model->param[i]->size; j++) { switch(param_info->type) { case MIF_BOOLEAN: model->param[i]->element[j].bvalue = param_info->default_value.bvalue; break; case MIF_INTEGER: model->param[i]->element[j].ivalue = param_info->default_value.ivalue; break; case MIF_REAL: model->param[i]->element[j].rvalue = param_info->default_value.rvalue; break; case MIF_COMPLEX: model->param[i]->element[j].cvalue = param_info->default_value.cvalue; break; case MIF_STRING: model->param[i]->element[j].svalue = param_info->default_value.svalue; break; default: return(E_BADPARM); } } /* end for number of elements in param array */ } /* end if null */ } /* end for number of parameters */ /* For each instance, initialize stuff used by cm_... functions */ for(here = model->MIFinstances; here != NULL; here = here->MIFnextInstance) { here->num_state = 0; here->state = NULL; here->num_intgr = 0; here->intgr = NULL; here->num_conv = 0; here->conv = NULL; } /* For each instance, allocate runtime structs for output connections/ports */ /* and grab a place in the state vector for all input connections/ports */ for(here = model->MIFinstances; here != NULL; here = here->MIFnextInstance) { /* Skip these expensive allocations if the instance is not analog */ if(! here->analog) continue; num_conn = here->num_conn; for(i = 0; i < num_conn; i++) { if((here->conn[i]->is_null) || (! here->conn[i]->is_output) ) continue; num_port = here->conn[i]->size; for(j = 0; j < num_port; j++) { here->conn[i]->port[j]->partial = TMALLOC(Mif_Partial_t, num_conn); here->conn[i]->port[j]->ac_gain = TMALLOC(Mif_AC_Gain_t, num_conn); here->conn[i]->port[j]->smp_data.input = TMALLOC(Mif_Conn_Ptr_t, num_conn); for(k = 0; k < num_conn; k++) { if((here->conn[k]->is_null) || (! here->conn[k]->is_input) ) continue; num_port_k = here->conn[k]->size; here->conn[i]->port[j]->partial[k].port = TMALLOC(double, num_port_k); here->conn[i]->port[j]->ac_gain[k].port = TMALLOC(Mif_Complex_t, num_port_k); here->conn[i]->port[j]->smp_data.input[k].port = TMALLOC(Mif_Port_Ptr_t, num_port_k); } } } num_conn = here->num_conn; for(i = 0; i < num_conn; i++) { if((here->conn[i]->is_null) || (! here->conn[i]->is_input) ) continue; num_port = here->conn[i]->size; for(j = 0; j < num_port; j++) { here->conn[i]->port[j]->old_input = *states; (*states)++; } } } /* Loop through all instances of this model and for each port of each connection */ /* create current equations, matrix entries, and matrix pointers as necessary. */ for(here = model->MIFinstances; here != NULL; here = here->MIFnextInstance) { /* Skip these expensive allocations if the instance is not analog */ if(! here->analog) continue; num_conn = here->num_conn; /* loop through all connections on this instance */ /* and create matrix data needed for outputs and */ /* V sources associated with I inputs */ for(i = 0; i < num_conn; i++) { /* if the connection is null, skip to next connection */ if(here->conn[i]->is_null) continue; /* prepare things for convenient access later */ is_input = here->conn[i]->is_input; is_output = here->conn[i]->is_output; num_port = here->conn[i]->size; /* loop through all ports on this connection */ for(j = 0; j < num_port; j++) { /* if port is null, skip to next */ if(here->conn[i]->port[j]->is_null) continue; /* determine the type of this port */ type = here->conn[i]->port[j]->type; /* create a pointer to the smp data for quick access */ smp_data_out = &(here->conn[i]->port[j]->smp_data); /* if it has a voltage source output, */ /* create the matrix data needed */ if( (is_output && (type == MIF_VOLTAGE || type == MIF_DIFF_VOLTAGE)) || (type == MIF_RESISTANCE || type == MIF_DIFF_RESISTANCE) ) { /* first, make the current equation */ suffix = tprintf("branch_%d_%d", i, j); error = CKTmkCur(ckt, &tmp, here->MIFname, suffix); FREE(suffix); if(error) return(error); smp_data_out->branch = tmp->number; /* ibranch is needed to find the input equation for RESISTANCE type */ smp_data_out->ibranch = tmp->number; /* then make the matrix pointers */ TSTALLOC(pos_branch, pos_node, branch); TSTALLOC(neg_branch, neg_node, branch); TSTALLOC(branch_pos, branch, pos_node); TSTALLOC(branch_neg, branch, neg_node); } /* end if current input */ /* if it is a current input */ /* create the matrix data needed for the associated zero-valued V source */ if(is_input && (type == MIF_CURRENT || type == MIF_DIFF_CURRENT)) { /* first, make the current equation */ suffix = tprintf("ibranch_%d_%d", i, j); error = CKTmkCur(ckt, &tmp, here->MIFname, suffix); FREE(suffix); if(error) return(error); smp_data_out->ibranch = tmp->number; /* then make the matrix pointers */ TSTALLOC(pos_ibranch, pos_node, ibranch); TSTALLOC(neg_ibranch, neg_node, ibranch); TSTALLOC(ibranch_pos, ibranch, pos_node); TSTALLOC(ibranch_neg, ibranch, neg_node); } /* end if current input */ /* if it is a vsource current input (refers to a vsource elsewhere */ /* in the circuit), locate the source and get its equation number */ if(is_input && (type == MIF_VSOURCE_CURRENT)) { smp_data_out->ibranch = CKTfndBranch(ckt, here->conn[i]->port[j]->vsource_str); if(smp_data_out->ibranch == 0) { SPfrontEnd->IFerrorf (ERR_FATAL, "%s: unknown controlling source %s", here->MIFname, here->conn[i]->port[j]->vsource_str); return(E_BADPARM); } } /* end if vsource current input */ } /* end for number of ports */ } /* end for number of connections */ /* now loop through all connections on the instance and create */ /* matrix data needed for partial derivatives of outputs */ for(i = 0; i < num_conn; i++) { /* if the connection is null or is not an output */ /* skip to next connection */ if((here->conn[i]->is_null) || (! here->conn[i]->is_output)) continue; /* loop through all ports on this connection */ num_port = here->conn[i]->size; for(j = 0; j < num_port; j++) { /* if port is null, skip to next */ if(here->conn[i]->port[j]->is_null) continue; /* determine the type of this output port */ out_type = here->conn[i]->port[j]->type; /* create a pointer to the smp data for quick access */ smp_data_out = &(here->conn[i]->port[j]->smp_data); /* for this port, loop through all connections */ /* and all ports to touch on each possible input */ for(k = 0; k < num_conn; k++) { /* if the connection is null or is not an input */ /* skip to next connection */ if((here->conn[k]->is_null) || (! here->conn[k]->is_input)) continue; num_port_k = here->conn[k]->size; /* loop through all the ports of this connection */ for(l = 0; l < num_port_k; l++) { /* if port is null, skip to next */ if(here->conn[k]->port[l]->is_null) continue; /* determine the type of this input port */ in_type = here->conn[k]->port[l]->type; /* create a pointer to the smp data for quick access */ smp_data_cntl = &(here->conn[k]->port[l]->smp_data); /* determine type of controlled source according */ /* to input and output types */ cntl_src_type = MIFget_cntl_src_type(in_type, out_type); switch(cntl_src_type) { case MIF_VCVS: CTSTALLOC(e.branch_poscntl, branch, pos_node); CTSTALLOC(e.branch_negcntl, branch, neg_node); break; case MIF_ICIS: CTSTALLOC(f.pos_ibranchcntl, pos_node, ibranch); CTSTALLOC(f.neg_ibranchcntl, neg_node, ibranch); break; case MIF_VCIS: CTSTALLOC(g.pos_poscntl, pos_node, pos_node); CTSTALLOC(g.pos_negcntl, pos_node, neg_node); CTSTALLOC(g.neg_poscntl, neg_node, pos_node); CTSTALLOC(g.neg_negcntl, neg_node, neg_node); break; case MIF_ICVS: CTSTALLOC(h.branch_ibranchcntl, branch, ibranch); break; case MIF_minus_one: break; } /* end switch on controlled source type */ } /* end for number of input ports */ } /* end for number of input connections */ } /* end for number of output ports */ } /* end for number of output connections */ } /* end for all instances */ } /* end for all models of this type */ return(OK); }