/*ARGSUSED*/ int VCCSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) { VCCSmodel *model = (VCCSmodel *)inModel; VCCSinstance *here; NG_IGNORE(states); NG_IGNORE(ckt); /* loop through all the current source models */ for( ; model != NULL; model = model->VCCSnextModel ) { /* loop through all the instances of the model */ for (here = model->VCCSinstances; here != NULL ; here=here->VCCSnextInstance) { /* 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(VCCSposContPosptr, VCCSposNode, VCCScontPosNode); TSTALLOC(VCCSposContNegptr, VCCSposNode, VCCScontNegNode); TSTALLOC(VCCSnegContPosptr, VCCSnegNode, VCCScontPosNode); TSTALLOC(VCCSnegContNegptr, VCCSnegNode, VCCScontNegNode); } } return(OK); }
int CSWsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) /* load the switch conductance with those pointers needed later * for fast matrix loading */ { CSWmodel *model = (CSWmodel*)inModel; CSWinstance *here; /* loop through all the current source models */ for( ; model != NULL; model = model->CSWnextModel ) { /* Default Value Processing for Switch Model */ if (!model->CSWthreshGiven) { model->CSWiThreshold = 0; } if (!model->CSWhystGiven) { model->CSWiHysteresis = 0; } if (!model->CSWonGiven) { model->CSWonConduct = CSW_ON_CONDUCTANCE; model->CSWonResistance = 1.0/model->CSWonConduct; } if (!model->CSWoffGiven) { model->CSWoffConduct = CSW_OFF_CONDUCTANCE; model->CSWoffResistance = 1.0/model->CSWoffConduct; } /* loop through all the instances of the model */ for (here = model->CSWinstances; here != NULL ; here=here->CSWnextInstance) { /* Default Value Processing for Switch Instance */ here->CSWstate = *states; *states += CSW_NUM_STATES; here->CSWcontBranch = CKTfndBranch(ckt,here->CSWcontName); if(here->CSWcontBranch == 0) { IFuid namarray[2]; namarray[0] = here->CSWname; namarray[1] = here->CSWcontName; SPfrontEnd->IFerror (ERR_FATAL, "%s: unknown controlling source %s",namarray); 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(CSWposPosptr, CSWposNode, CSWposNode); TSTALLOC(CSWposNegptr, CSWposNode, CSWnegNode); TSTALLOC(CSWnegPosptr, CSWnegNode, CSWposNode); TSTALLOC(CSWnegNegptr, CSWnegNode, CSWnegNode); } } return(OK); }
/*ARGSUSED*/ int MUTsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) { MUTmodel *model = (MUTmodel*)inModel; MUTinstance *here; int ktype; NG_IGNORE(states); /* loop through all the inductor models */ for( ; model != NULL; model = model->MUTnextModel ) { /* loop through all the instances of the model */ for (here = model->MUTinstances; here != NULL ; here=here->MUTnextInstance) { ktype = CKTtypelook("Inductor"); if(ktype <= 0) { SPfrontEnd->IFerror (ERR_PANIC, "mutual inductor, but inductors not available!", NULL); return(E_INTERN); } if (!here->MUTind1) here->MUTind1 = (INDinstance *) CKTfndDev(ckt, here->MUTindName1); if (!here->MUTind1) { IFuid namarray[2]; namarray[0]=here->MUTname; namarray[1]=here->MUTindName1; SPfrontEnd->IFerror (ERR_WARNING, "%s: coupling to non-existant inductor %s.", namarray); } if (!here->MUTind2) here->MUTind2 = (INDinstance *) CKTfndDev(ckt, here->MUTindName2); if (!here->MUTind2) { IFuid namarray[2]; namarray[0]=here->MUTname; namarray[1]=here->MUTindName2; SPfrontEnd->IFerror (ERR_WARNING, "%s: coupling to non-existant inductor %s.", namarray); } /* 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(MUTbr1br2,MUTind1->INDbrEq,MUTind2->INDbrEq); TSTALLOC(MUTbr2br1,MUTind2->INDbrEq,MUTind1->INDbrEq); } } return(OK); }
int SWsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) /* load the switch conductance with those pointers needed later * for fast matrix loading */ { SWmodel *model = (SWmodel *)inModel; SWinstance *here; /* loop through all the current source models */ for( ; model != NULL; model = model->SWnextModel ) { /* Default Value Processing for Switch Model */ if (!model->SWthreshGiven) { model->SWvThreshold = 0; } if (!model->SWhystGiven) { model->SWvHysteresis = 0; } if (!model->SWonGiven) { model->SWonConduct = SW_ON_CONDUCTANCE; model->SWonResistance = 1.0/model->SWonConduct; } if (!model->SWoffGiven) { model->SWoffConduct = SW_OFF_CONDUCTANCE; model->SWoffResistance = 1.0/model->SWoffConduct; } /* loop through all the instances of the model */ for (here = model->SWinstances; here != NULL ; here=here->SWnextInstance) { here->SWstate = *states; *states += SW_NUM_STATES; /* Default Value Processing for Switch Instance */ /* none */ /* 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(SWposPosptr, SWposNode, SWposNode); TSTALLOC(SWposNegptr, SWposNode, SWnegNode); TSTALLOC(SWnegPosptr, SWnegNode, SWposNode); TSTALLOC(SWnegNegptr, SWnegNode, SWnegNode); } } return(OK); }
/*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); }
int CSWsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) { CSWmodel *model = (CSWmodel *) inModel; CSWinstance *here; for (; model; model = CSWnextModel(model)) { /* Default Value Processing for Switch Model */ if (!model->CSWthreshGiven) model->CSWiThreshold = 0; if (!model->CSWhystGiven) model->CSWiHysteresis = 0; if (!model->CSWonGiven) { model->CSWonConduct = CSW_ON_CONDUCTANCE; model->CSWonResistance = 1.0 / model->CSWonConduct; } if (!model->CSWoffGiven) { model->CSWoffConduct = CSW_OFF_CONDUCTANCE; model->CSWoffResistance = 1.0 / model->CSWoffConduct; } for (here = CSWinstances(model); here; here = CSWnextInstance(here)) { /* Default Value Processing for Switch Instance */ here->CSWstate = *states; *states += CSW_NUM_STATES; here->CSWcontBranch = CKTfndBranch(ckt, here->CSWcontName); if (here->CSWcontBranch == 0) { SPfrontEnd->IFerrorf(ERR_FATAL, "%s: unknown controlling source %s", here->CSWname, here->CSWcontName); return E_BADPARM; } TSTALLOC(CSWposPosPtr, CSWposNode, CSWposNode); TSTALLOC(CSWposNegPtr, CSWposNode, CSWnegNode); TSTALLOC(CSWnegPosPtr, CSWnegNode, CSWposNode); TSTALLOC(CSWnegNegPtr, CSWnegNode, CSWnegNode); } } return OK; }
int NDEVsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) /* * load the structure with those pointers needed later for fast matrix * loading */ { NDEVmodel *model = (NDEVmodel *)inModel; NDEVinstance *here; int i,j; CKTnode *node; NG_IGNORE(ckt); NG_IGNORE(states); /* loop through all the ndev models */ for( ; model != NULL; model = NDEVnextModel(model)) { /* connect to remote device simulator */ if(NDEVmodelConnect(model)) return E_PRIVATE; /* loop through all the instances of the model */ for (here = NDEVinstances(model); here != NULL ; here=NDEVnextInstance(here)) { here->Ndevinfo.term = here->term; strncpy(here->Ndevinfo.NDEVname, here->gen.GENname, 32); send(model->sock,&(here->Ndevinfo),sizeof(here->Ndevinfo),0); /* 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) for(i=0;i<here->term;i++) for(j=0;j<here->term;j++) { TSTALLOC(mat_pointer[i*here->term+j], pin[i], pin[j]); } for(i=0;i<here->term;i++) { node = here->node[i]; here->PINinfos[i].pin=node->number; strncpy(here->PINinfos[i].name,here->bname[i],32); here->PINinfos[i].V = 0.0; send(model->sock,&here->PINinfos[i],sizeof(here->PINinfos[i]),0); } } } 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 RESsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit*ckt, int *state) /* load the resistor structure with those pointers needed later * for fast matrix loading */ { RESmodel *model = (RESmodel *)inModel; RESinstance *here; NG_IGNORE(state); NG_IGNORE(ckt); /* loop through all the resistor models */ for( ; model != NULL; model = model->RESnextModel ) { /* Default Value Processing for Resistor Models */ if(!model->REStnomGiven) model->REStnom = ckt->CKTnomTemp; if(!model->RESsheetResGiven) model->RESsheetRes = 0.0; if(!model->RESdefWidthGiven) model->RESdefWidth = 10e-6; /*M*/ if(!model->RESdefLengthGiven) model->RESdefLength = 10e-6; if(!model->REStc1Given) model->REStempCoeff1 = 0.0; if(!model->REStc2Given) model->REStempCoeff2 = 0.0; if(!model->REStceGiven) model->REStempCoeffe = 0.0; if(!model->RESnarrowGiven) model->RESnarrow = 0.0; if(!model->RESshortGiven) model->RESshort = 0.0; if(!model->RESfNcoefGiven) model->RESfNcoef = 0.0; if(!model->RESfNexpGiven) model->RESfNexp = 1.0; if(!model->RESlfGiven) model->RESlf = 1.0; if(!model->RESwfGiven) model->RESwf = 1.0; if(!model->RESefGiven) model->RESef = 1.0; if(!model->RESbv_maxGiven) model->RESbv_max = 1e99; /* loop through all the instances of the model */ for (here = model->RESinstances; here != NULL ; here=here->RESnextInstance) { if(!here->RESwidthGiven) here->RESwidth = model->RESdefWidth; if(!here->RESlengthGiven) here->RESlength = model->RESdefLength; if(!here->RESscaleGiven) here->RESscale = 1.0; if(!here->RESmGiven) here->RESm = 1.0; if(!here->RESnoisyGiven) here->RESnoisy = 1; if(!here->RESbv_maxGiven) here->RESbv_max = model->RESbv_max; if((here->RESwidthGiven)||(here->RESlengthGiven)) here->RESeffNoiseArea = pow((here->RESlength-model->RESshort),model->RESlf) *pow((here->RESwidth-model->RESnarrow),model->RESwf); else here->RESeffNoiseArea = 1.0; /* 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(RESposPosptr, RESposNode, RESposNode); TSTALLOC(RESnegNegptr, RESnegNode, RESnegNode); TSTALLOC(RESposNegptr, RESposNode, RESnegNode); TSTALLOC(RESnegPosptr, RESnegNode, RESposNode); } } return(OK); }
int DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) { DIOmodel *model = (DIOmodel*)inModel; DIOinstance *here; int error; CKTnode *tmp; /* loop through all the diode models */ for( ; model != NULL; model = model->DIOnextModel ) { if(!model->DIOlevelGiven) { model->DIOlevel = 1; } if(!model->DIOemissionCoeffGiven) { model->DIOemissionCoeff = 1; } if(!model->DIOsatCurGiven) { model->DIOsatCur = 1e-14; } if(!model->DIOsatSWCurGiven) { model->DIOsatSWCur = 0.0; } if(!model->DIOswEmissionCoeffGiven) { model->DIOswEmissionCoeff = 1; } if(!model->DIObreakdownCurrentGiven) { model->DIObreakdownCurrent = 1e-3; } if(!model->DIOjunctionPotGiven){ model->DIOjunctionPot = 1; } if(!model->DIOgradingCoeffGiven) { model->DIOgradingCoeff = .5; } if(!model->DIOgradCoeffTemp1Given) { model->DIOgradCoeffTemp1 = 0.0; } if(!model->DIOgradCoeffTemp2Given) { model->DIOgradCoeffTemp2 = 0.0; } if(!model->DIOdepletionCapCoeffGiven) { model->DIOdepletionCapCoeff = .5; } if(!model->DIOdepletionSWcapCoeffGiven) { model->DIOdepletionSWcapCoeff = .5; } if(!model->DIOtransitTimeGiven) { model->DIOtransitTime = 0; } if(!model->DIOtranTimeTemp1Given) { model->DIOtranTimeTemp1 = 0.0; } if(!model->DIOtranTimeTemp2Given) { model->DIOtranTimeTemp2 = 0.0; } if(!model->DIOjunctionCapGiven) { model->DIOjunctionCap = 0; } if(!model->DIOjunctionSWCapGiven) { model->DIOjunctionSWCap = 0; } if(!model->DIOjunctionSWPotGiven){ model->DIOjunctionSWPot = 1; } if(!model->DIOgradingSWCoeffGiven) { model->DIOgradingSWCoeff = .33; } if(!model->DIOforwardKneeCurrentGiven) { model->DIOforwardKneeCurrent = 0.0; } if(!model->DIOreverseKneeCurrentGiven) { model->DIOreverseKneeCurrent = 0.0; } if(!model->DIObrkdEmissionCoeffGiven) { model->DIObrkdEmissionCoeff = model->DIOemissionCoeff; } if(!model->DIOtlevGiven) { model->DIOtlev = 0; } if(!model->DIOtlevcGiven) { model->DIOtlevc = 0; } if(!model->DIOactivationEnergyGiven) { model->DIOactivationEnergy = 1.11; } if(!model->DIOsaturationCurrentExpGiven) { model->DIOsaturationCurrentExp = 3; } if(!model->DIOctaGiven) { model->DIOcta = 0.0; } if(!model->DIOctpGiven) { model->DIOctp = 0.0; } if(!model->DIOtpbGiven) { model->DIOtpb = 0.0; } if(!model->DIOtphpGiven) { model->DIOtphp = 0.0; } if(!model->DIOfNcoefGiven) { model->DIOfNcoef = 0.0; } if(!model->DIOfNexpGiven) { model->DIOfNexp = 1.0; } if(!model->DIOresistTemp1Given) { model->DIOresistTemp1 = 0.0; } if(!model->DIOresistTemp2Given) { model->DIOresistTemp2 = 0.0; } if(!model->DIOtcvGiven) { model->DIOtcv = 0.0; } if(!model->DIOareaGiven) { model->DIOarea = 1.0; } if(!model->DIOpjGiven) { model->DIOpj = 0.0; } if(!model->DIOtunSatCurGiven) { model->DIOtunSatCur = 0.0; } if(!model->DIOtunSatSWCurGiven) { model->DIOtunSatSWCur = 0.0; } if(!model->DIOtunEmissionCoeffGiven) { model->DIOtunEmissionCoeff = 30.0; } if(!model->DIOtunSaturationCurrentExpGiven) { model->DIOtunSaturationCurrentExp = 3.0; } if(!model->DIOtunEGcorrectionFactorGiven) { model->DIOtunEGcorrectionFactor = 1.0; } if(!model->DIOfv_maxGiven) { model->DIOfv_max = 1e99; } if(!model->DIObv_maxGiven) { model->DIObv_max = 1e99; } /* loop through all the instances of the model */ for (here = model->DIOinstances; here != NULL ; here=here->DIOnextInstance) { if(!here->DIOareaGiven) { if((!here->DIOwGiven) && (!here->DIOlGiven)) { here->DIOarea = model->DIOarea; } else { here->DIOarea = 1; } } if(!here->DIOpjGiven) { if((!here->DIOwGiven) && (!here->DIOlGiven)) { here->DIOpj = model->DIOpj; } else { here->DIOpj = 0; } } if(!here->DIOmGiven) { here->DIOm = 1; } here->DIOarea = here->DIOarea * here->DIOm; here->DIOpj = here->DIOpj * here->DIOm; if (model->DIOlevel == 3) { if((here->DIOwGiven) && (here->DIOlGiven)) { here->DIOarea = here->DIOw * here->DIOl * here->DIOm; here->DIOpj = (2 * here->DIOw + 2 * here->DIOl) * here->DIOm; } } here->DIOforwardKneeCurrent = model->DIOforwardKneeCurrent * here->DIOarea; here->DIOreverseKneeCurrent = model->DIOreverseKneeCurrent * here->DIOarea; here->DIOjunctionCap = model->DIOjunctionCap * here->DIOarea; here->DIOjunctionSWCap = model->DIOjunctionSWCap * here->DIOpj; here->DIOstate = *states; *states += 5; if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN) ){ *states += 2 * (ckt->CKTsenInfo->SENparms); } if(model->DIOresist == 0) { here->DIOposPrimeNode = here->DIOposNode; } else if(here->DIOposPrimeNode == 0) { CKTnode *tmpNode; IFuid tmpName; error = CKTmkVolt(ckt,&tmp,here->DIOname,"internal"); if(error) return(error); here->DIOposPrimeNode = tmp->number; if (ckt->CKTcopyNodesets) { if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } /* 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(DIOposPosPrimePtr,DIOposNode,DIOposPrimeNode); TSTALLOC(DIOnegPosPrimePtr,DIOnegNode,DIOposPrimeNode); TSTALLOC(DIOposPrimePosPtr,DIOposPrimeNode,DIOposNode); TSTALLOC(DIOposPrimeNegPtr,DIOposPrimeNode,DIOnegNode); TSTALLOC(DIOposPosPtr,DIOposNode,DIOposNode); TSTALLOC(DIOnegNegPtr,DIOnegNode,DIOnegNode); TSTALLOC(DIOposPrimePosPrimePtr,DIOposPrimeNode,DIOposPrimeNode); } } return(OK); }
int BSIM3v32setup (SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) { BSIM3v32model *model = (BSIM3v32model*)inModel; BSIM3v32instance *here; int error; CKTnode *tmp; CKTnode *tmpNode; IFuid tmpName; #ifdef USE_OMP int idx, InstCount; BSIM3v32instance **InstArray; #endif /* loop through all the BSIM3v32 device models */ for( ; model != NULL; model = model->BSIM3v32nextModel ) { /* Default value Processing for BSIM3v32 MOSFET Models */ if (!model->BSIM3v32typeGiven) model->BSIM3v32type = NMOS; if (!model->BSIM3v32mobModGiven) model->BSIM3v32mobMod = 1; if (!model->BSIM3v32binUnitGiven) model->BSIM3v32binUnit = 1; if (!model->BSIM3v32paramChkGiven) model->BSIM3v32paramChk = 0; if (!model->BSIM3v32capModGiven) model->BSIM3v32capMod = 3; if (!model->BSIM3v32acmModGiven) model->BSIM3v32acmMod = 0; if (!model->BSIM3v32calcacmGiven) model->BSIM3v32calcacm = 0; if (!model->BSIM3v32noiModGiven) model->BSIM3v32noiMod = 1; if (!model->BSIM3v32nqsModGiven) model->BSIM3v32nqsMod = 0; else if ((model->BSIM3v32nqsMod != 0) && (model->BSIM3v32nqsMod != 1)) { model->BSIM3v32nqsMod = 0; printf("Warning: nqsMod has been set to its default value: 0.\n"); } /* If the user does not provide the model revision, * we always choose the most recent. */ if (!model->BSIM3v32versionGiven) model->BSIM3v32version = copy("3.2.4"); /* I have added below the code that translate model string * into an integer. This trick is meant to speed up the * revision testing instruction, since comparing integer * is faster than comparing strings. * Paolo Nenzi 2002 */ if ((!strcmp(model->BSIM3v32version, "3.2.4"))||(!strcmp(model->BSIM3v32version, "3.24"))) model->BSIM3v32intVersion = BSIM3v32V324; else if ((!strcmp(model->BSIM3v32version, "3.2.3"))||(!strcmp(model->BSIM3v32version, "3.23"))) model->BSIM3v32intVersion = BSIM3v32V323; else if ((!strcmp(model->BSIM3v32version, "3.2.2"))||(!strcmp(model->BSIM3v32version, "3.22"))) model->BSIM3v32intVersion = BSIM3v32V322; else if ((!strcmp(model->BSIM3v32version, "3.2"))||(!strcmp(model->BSIM3v32version, "3.20"))) model->BSIM3v32intVersion = BSIM3v32V32; else model->BSIM3v32intVersion = BSIM3v32V3OLD; /* BSIM3v32V3OLD is a placeholder for pre 3.2 revision * This model should not be used for pre 3.2 models. */ if (!model->BSIM3v32toxGiven) model->BSIM3v32tox = 150.0e-10; model->BSIM3v32cox = 3.453133e-11 / model->BSIM3v32tox; if (!model->BSIM3v32toxmGiven) model->BSIM3v32toxm = model->BSIM3v32tox; if (!model->BSIM3v32cdscGiven) model->BSIM3v32cdsc = 2.4e-4; /* unit Q/V/m^2 */ if (!model->BSIM3v32cdscbGiven) model->BSIM3v32cdscb = 0.0; /* unit Q/V/m^2 */ if (!model->BSIM3v32cdscdGiven) model->BSIM3v32cdscd = 0.0; /* unit Q/V/m^2 */ if (!model->BSIM3v32citGiven) model->BSIM3v32cit = 0.0; /* unit Q/V/m^2 */ if (!model->BSIM3v32nfactorGiven) model->BSIM3v32nfactor = 1; if (!model->BSIM3v32xjGiven) model->BSIM3v32xj = .15e-6; if (!model->BSIM3v32vsatGiven) model->BSIM3v32vsat = 8.0e4; /* unit m/s */ if (!model->BSIM3v32atGiven) model->BSIM3v32at = 3.3e4; /* unit m/s */ if (!model->BSIM3v32a0Given) model->BSIM3v32a0 = 1.0; if (!model->BSIM3v32agsGiven) model->BSIM3v32ags = 0.0; if (!model->BSIM3v32a1Given) model->BSIM3v32a1 = 0.0; if (!model->BSIM3v32a2Given) model->BSIM3v32a2 = 1.0; if (!model->BSIM3v32ketaGiven) model->BSIM3v32keta = -0.047; /* unit / V */ if (!model->BSIM3v32nsubGiven) model->BSIM3v32nsub = 6.0e16; /* unit 1/cm3 */ if (!model->BSIM3v32npeakGiven) model->BSIM3v32npeak = 1.7e17; /* unit 1/cm3 */ if (!model->BSIM3v32ngateGiven) model->BSIM3v32ngate = 0; /* unit 1/cm3 */ if (!model->BSIM3v32vbmGiven) model->BSIM3v32vbm = -3.0; if (!model->BSIM3v32xtGiven) model->BSIM3v32xt = 1.55e-7; if (!model->BSIM3v32kt1Given) model->BSIM3v32kt1 = -0.11; /* unit V */ if (!model->BSIM3v32kt1lGiven) model->BSIM3v32kt1l = 0.0; /* unit V*m */ if (!model->BSIM3v32kt2Given) model->BSIM3v32kt2 = 0.022; /* No unit */ if (!model->BSIM3v32k3Given) model->BSIM3v32k3 = 80.0; if (!model->BSIM3v32k3bGiven) model->BSIM3v32k3b = 0.0; if (!model->BSIM3v32w0Given) model->BSIM3v32w0 = 2.5e-6; if (!model->BSIM3v32nlxGiven) model->BSIM3v32nlx = 1.74e-7; if (!model->BSIM3v32dvt0Given) model->BSIM3v32dvt0 = 2.2; if (!model->BSIM3v32dvt1Given) model->BSIM3v32dvt1 = 0.53; if (!model->BSIM3v32dvt2Given) model->BSIM3v32dvt2 = -0.032; /* unit 1 / V */ if (!model->BSIM3v32dvt0wGiven) model->BSIM3v32dvt0w = 0.0; if (!model->BSIM3v32dvt1wGiven) model->BSIM3v32dvt1w = 5.3e6; if (!model->BSIM3v32dvt2wGiven) model->BSIM3v32dvt2w = -0.032; if (!model->BSIM3v32droutGiven) model->BSIM3v32drout = 0.56; if (!model->BSIM3v32dsubGiven) model->BSIM3v32dsub = model->BSIM3v32drout; if (!model->BSIM3v32vth0Given) model->BSIM3v32vth0 = (model->BSIM3v32type == NMOS) ? 0.7 : -0.7; if (!model->BSIM3v32uaGiven) model->BSIM3v32ua = 2.25e-9; /* unit m/V */ if (!model->BSIM3v32ua1Given) model->BSIM3v32ua1 = 4.31e-9; /* unit m/V */ if (!model->BSIM3v32ubGiven) model->BSIM3v32ub = 5.87e-19; /* unit (m/V)**2 */ if (!model->BSIM3v32ub1Given) model->BSIM3v32ub1 = -7.61e-18; /* unit (m/V)**2 */ if (!model->BSIM3v32ucGiven) model->BSIM3v32uc = (model->BSIM3v32mobMod == 3) ? -0.0465 : -0.0465e-9; if (!model->BSIM3v32uc1Given) model->BSIM3v32uc1 = (model->BSIM3v32mobMod == 3) ? -0.056 : -0.056e-9; if (!model->BSIM3v32u0Given) model->BSIM3v32u0 = (model->BSIM3v32type == NMOS) ? 0.067 : 0.025; if (!model->BSIM3v32uteGiven) model->BSIM3v32ute = -1.5; if (!model->BSIM3v32voffGiven) model->BSIM3v32voff = -0.08; if (!model->BSIM3v32deltaGiven) model->BSIM3v32delta = 0.01; if (!model->BSIM3v32rdswGiven) model->BSIM3v32rdsw = 0; if (!model->BSIM3v32prwgGiven) model->BSIM3v32prwg = 0.0; /* unit 1/V */ if (!model->BSIM3v32prwbGiven) model->BSIM3v32prwb = 0.0; if (!model->BSIM3v32prtGiven) model->BSIM3v32prt = 0.0; if (!model->BSIM3v32eta0Given) model->BSIM3v32eta0 = 0.08; /* no unit */ if (!model->BSIM3v32etabGiven) model->BSIM3v32etab = -0.07; /* unit 1/V */ if (!model->BSIM3v32pclmGiven) model->BSIM3v32pclm = 1.3; /* no unit */ if (!model->BSIM3v32pdibl1Given) model->BSIM3v32pdibl1 = .39; /* no unit */ if (!model->BSIM3v32pdibl2Given) model->BSIM3v32pdibl2 = 0.0086; /* no unit */ if (!model->BSIM3v32pdiblbGiven) model->BSIM3v32pdiblb = 0.0; /* 1/V */ if (!model->BSIM3v32pscbe1Given) model->BSIM3v32pscbe1 = 4.24e8; if (!model->BSIM3v32pscbe2Given) model->BSIM3v32pscbe2 = 1.0e-5; if (!model->BSIM3v32pvagGiven) model->BSIM3v32pvag = 0.0; if (!model->BSIM3v32wrGiven) model->BSIM3v32wr = 1.0; if (!model->BSIM3v32dwgGiven) model->BSIM3v32dwg = 0.0; if (!model->BSIM3v32dwbGiven) model->BSIM3v32dwb = 0.0; if (!model->BSIM3v32b0Given) model->BSIM3v32b0 = 0.0; if (!model->BSIM3v32b1Given) model->BSIM3v32b1 = 0.0; if (!model->BSIM3v32alpha0Given) model->BSIM3v32alpha0 = 0.0; if (!model->BSIM3v32alpha1Given) model->BSIM3v32alpha1 = 0.0; if (!model->BSIM3v32beta0Given) model->BSIM3v32beta0 = 30.0; if (!model->BSIM3v32ijthGiven) model->BSIM3v32ijth = 0.1; /* unit A */ if (!model->BSIM3v32elmGiven) model->BSIM3v32elm = 5.0; if (!model->BSIM3v32cgslGiven) model->BSIM3v32cgsl = 0.0; if (!model->BSIM3v32cgdlGiven) model->BSIM3v32cgdl = 0.0; if (!model->BSIM3v32ckappaGiven) model->BSIM3v32ckappa = 0.6; if (!model->BSIM3v32clcGiven) model->BSIM3v32clc = 0.1e-6; if (!model->BSIM3v32cleGiven) model->BSIM3v32cle = 0.6; if (!model->BSIM3v32vfbcvGiven) model->BSIM3v32vfbcv = -1.0; if (!model->BSIM3v32acdeGiven) model->BSIM3v32acde = 1.0; if (!model->BSIM3v32moinGiven) model->BSIM3v32moin = 15.0; if (!model->BSIM3v32noffGiven) model->BSIM3v32noff = 1.0; if (!model->BSIM3v32voffcvGiven) model->BSIM3v32voffcv = 0.0; if (!model->BSIM3v32tcjGiven) model->BSIM3v32tcj = 0.0; if (!model->BSIM3v32tpbGiven) model->BSIM3v32tpb = 0.0; if (!model->BSIM3v32tcjswGiven) model->BSIM3v32tcjsw = 0.0; if (!model->BSIM3v32tpbswGiven) model->BSIM3v32tpbsw = 0.0; if (!model->BSIM3v32tcjswgGiven) model->BSIM3v32tcjswg = 0.0; if (!model->BSIM3v32tpbswgGiven) model->BSIM3v32tpbswg = 0.0; /* ACM model */ if (!model->BSIM3v32hdifGiven) model->BSIM3v32hdif = 0.0; if (!model->BSIM3v32ldifGiven) model->BSIM3v32ldif = 0.0; if (!model->BSIM3v32ldGiven) model->BSIM3v32ld = 0.0; if (!model->BSIM3v32rdGiven) model->BSIM3v32rd = 0.0; if (!model->BSIM3v32rsGiven) model->BSIM3v32rs = 0.0; if (!model->BSIM3v32rdcGiven) model->BSIM3v32rdc = 0.0; if (!model->BSIM3v32rscGiven) model->BSIM3v32rsc = 0.0; if (!model->BSIM3v32wmltGiven) model->BSIM3v32wmlt = 1.0; if (!model->BSIM3v32lmltGiven) model->BSIM3v32lmlt = 1.0; /* Length dependence */ if (!model->BSIM3v32lcdscGiven) model->BSIM3v32lcdsc = 0.0; if (!model->BSIM3v32lcdscbGiven) model->BSIM3v32lcdscb = 0.0; if (!model->BSIM3v32lcdscdGiven) model->BSIM3v32lcdscd = 0.0; if (!model->BSIM3v32lcitGiven) model->BSIM3v32lcit = 0.0; if (!model->BSIM3v32lnfactorGiven) model->BSIM3v32lnfactor = 0.0; if (!model->BSIM3v32lxjGiven) model->BSIM3v32lxj = 0.0; if (!model->BSIM3v32lvsatGiven) model->BSIM3v32lvsat = 0.0; if (!model->BSIM3v32latGiven) model->BSIM3v32lat = 0.0; if (!model->BSIM3v32la0Given) model->BSIM3v32la0 = 0.0; if (!model->BSIM3v32lagsGiven) model->BSIM3v32lags = 0.0; if (!model->BSIM3v32la1Given) model->BSIM3v32la1 = 0.0; if (!model->BSIM3v32la2Given) model->BSIM3v32la2 = 0.0; if (!model->BSIM3v32lketaGiven) model->BSIM3v32lketa = 0.0; if (!model->BSIM3v32lnsubGiven) model->BSIM3v32lnsub = 0.0; if (!model->BSIM3v32lnpeakGiven) model->BSIM3v32lnpeak = 0.0; if (!model->BSIM3v32lngateGiven) model->BSIM3v32lngate = 0.0; if (!model->BSIM3v32lvbmGiven) model->BSIM3v32lvbm = 0.0; if (!model->BSIM3v32lxtGiven) model->BSIM3v32lxt = 0.0; if (!model->BSIM3v32lkt1Given) model->BSIM3v32lkt1 = 0.0; if (!model->BSIM3v32lkt1lGiven) model->BSIM3v32lkt1l = 0.0; if (!model->BSIM3v32lkt2Given) model->BSIM3v32lkt2 = 0.0; if (!model->BSIM3v32lk3Given) model->BSIM3v32lk3 = 0.0; if (!model->BSIM3v32lk3bGiven) model->BSIM3v32lk3b = 0.0; if (!model->BSIM3v32lw0Given) model->BSIM3v32lw0 = 0.0; if (!model->BSIM3v32lnlxGiven) model->BSIM3v32lnlx = 0.0; if (!model->BSIM3v32ldvt0Given) model->BSIM3v32ldvt0 = 0.0; if (!model->BSIM3v32ldvt1Given) model->BSIM3v32ldvt1 = 0.0; if (!model->BSIM3v32ldvt2Given) model->BSIM3v32ldvt2 = 0.0; if (!model->BSIM3v32ldvt0wGiven) model->BSIM3v32ldvt0w = 0.0; if (!model->BSIM3v32ldvt1wGiven) model->BSIM3v32ldvt1w = 0.0; if (!model->BSIM3v32ldvt2wGiven) model->BSIM3v32ldvt2w = 0.0; if (!model->BSIM3v32ldroutGiven) model->BSIM3v32ldrout = 0.0; if (!model->BSIM3v32ldsubGiven) model->BSIM3v32ldsub = 0.0; if (!model->BSIM3v32lvth0Given) model->BSIM3v32lvth0 = 0.0; if (!model->BSIM3v32luaGiven) model->BSIM3v32lua = 0.0; if (!model->BSIM3v32lua1Given) model->BSIM3v32lua1 = 0.0; if (!model->BSIM3v32lubGiven) model->BSIM3v32lub = 0.0; if (!model->BSIM3v32lub1Given) model->BSIM3v32lub1 = 0.0; if (!model->BSIM3v32lucGiven) model->BSIM3v32luc = 0.0; if (!model->BSIM3v32luc1Given) model->BSIM3v32luc1 = 0.0; if (!model->BSIM3v32lu0Given) model->BSIM3v32lu0 = 0.0; if (!model->BSIM3v32luteGiven) model->BSIM3v32lute = 0.0; if (!model->BSIM3v32lvoffGiven) model->BSIM3v32lvoff = 0.0; if (!model->BSIM3v32ldeltaGiven) model->BSIM3v32ldelta = 0.0; if (!model->BSIM3v32lrdswGiven) model->BSIM3v32lrdsw = 0.0; if (!model->BSIM3v32lprwbGiven) model->BSIM3v32lprwb = 0.0; if (!model->BSIM3v32lprwgGiven) model->BSIM3v32lprwg = 0.0; if (!model->BSIM3v32lprtGiven) model->BSIM3v32lprt = 0.0; if (!model->BSIM3v32leta0Given) model->BSIM3v32leta0 = 0.0; if (!model->BSIM3v32letabGiven) model->BSIM3v32letab = -0.0; if (!model->BSIM3v32lpclmGiven) model->BSIM3v32lpclm = 0.0; if (!model->BSIM3v32lpdibl1Given) model->BSIM3v32lpdibl1 = 0.0; if (!model->BSIM3v32lpdibl2Given) model->BSIM3v32lpdibl2 = 0.0; if (!model->BSIM3v32lpdiblbGiven) model->BSIM3v32lpdiblb = 0.0; if (!model->BSIM3v32lpscbe1Given) model->BSIM3v32lpscbe1 = 0.0; if (!model->BSIM3v32lpscbe2Given) model->BSIM3v32lpscbe2 = 0.0; if (!model->BSIM3v32lpvagGiven) model->BSIM3v32lpvag = 0.0; if (!model->BSIM3v32lwrGiven) model->BSIM3v32lwr = 0.0; if (!model->BSIM3v32ldwgGiven) model->BSIM3v32ldwg = 0.0; if (!model->BSIM3v32ldwbGiven) model->BSIM3v32ldwb = 0.0; if (!model->BSIM3v32lb0Given) model->BSIM3v32lb0 = 0.0; if (!model->BSIM3v32lb1Given) model->BSIM3v32lb1 = 0.0; if (!model->BSIM3v32lalpha0Given) model->BSIM3v32lalpha0 = 0.0; if (!model->BSIM3v32lalpha1Given) model->BSIM3v32lalpha1 = 0.0; if (!model->BSIM3v32lbeta0Given) model->BSIM3v32lbeta0 = 0.0; if (!model->BSIM3v32lvfbGiven) model->BSIM3v32lvfb = 0.0; if (!model->BSIM3v32lelmGiven) model->BSIM3v32lelm = 0.0; if (!model->BSIM3v32lcgslGiven) model->BSIM3v32lcgsl = 0.0; if (!model->BSIM3v32lcgdlGiven) model->BSIM3v32lcgdl = 0.0; if (!model->BSIM3v32lckappaGiven) model->BSIM3v32lckappa = 0.0; if (!model->BSIM3v32lclcGiven) model->BSIM3v32lclc = 0.0; if (!model->BSIM3v32lcleGiven) model->BSIM3v32lcle = 0.0; if (!model->BSIM3v32lcfGiven) model->BSIM3v32lcf = 0.0; if (!model->BSIM3v32lvfbcvGiven) model->BSIM3v32lvfbcv = 0.0; if (!model->BSIM3v32lacdeGiven) model->BSIM3v32lacde = 0.0; if (!model->BSIM3v32lmoinGiven) model->BSIM3v32lmoin = 0.0; if (!model->BSIM3v32lnoffGiven) model->BSIM3v32lnoff = 0.0; if (!model->BSIM3v32lvoffcvGiven) model->BSIM3v32lvoffcv = 0.0; /* Width dependence */ if (!model->BSIM3v32wcdscGiven) model->BSIM3v32wcdsc = 0.0; if (!model->BSIM3v32wcdscbGiven) model->BSIM3v32wcdscb = 0.0; if (!model->BSIM3v32wcdscdGiven) model->BSIM3v32wcdscd = 0.0; if (!model->BSIM3v32wcitGiven) model->BSIM3v32wcit = 0.0; if (!model->BSIM3v32wnfactorGiven) model->BSIM3v32wnfactor = 0.0; if (!model->BSIM3v32wxjGiven) model->BSIM3v32wxj = 0.0; if (!model->BSIM3v32wvsatGiven) model->BSIM3v32wvsat = 0.0; if (!model->BSIM3v32watGiven) model->BSIM3v32wat = 0.0; if (!model->BSIM3v32wa0Given) model->BSIM3v32wa0 = 0.0; if (!model->BSIM3v32wagsGiven) model->BSIM3v32wags = 0.0; if (!model->BSIM3v32wa1Given) model->BSIM3v32wa1 = 0.0; if (!model->BSIM3v32wa2Given) model->BSIM3v32wa2 = 0.0; if (!model->BSIM3v32wketaGiven) model->BSIM3v32wketa = 0.0; if (!model->BSIM3v32wnsubGiven) model->BSIM3v32wnsub = 0.0; if (!model->BSIM3v32wnpeakGiven) model->BSIM3v32wnpeak = 0.0; if (!model->BSIM3v32wngateGiven) model->BSIM3v32wngate = 0.0; if (!model->BSIM3v32wvbmGiven) model->BSIM3v32wvbm = 0.0; if (!model->BSIM3v32wxtGiven) model->BSIM3v32wxt = 0.0; if (!model->BSIM3v32wkt1Given) model->BSIM3v32wkt1 = 0.0; if (!model->BSIM3v32wkt1lGiven) model->BSIM3v32wkt1l = 0.0; if (!model->BSIM3v32wkt2Given) model->BSIM3v32wkt2 = 0.0; if (!model->BSIM3v32wk3Given) model->BSIM3v32wk3 = 0.0; if (!model->BSIM3v32wk3bGiven) model->BSIM3v32wk3b = 0.0; if (!model->BSIM3v32ww0Given) model->BSIM3v32ww0 = 0.0; if (!model->BSIM3v32wnlxGiven) model->BSIM3v32wnlx = 0.0; if (!model->BSIM3v32wdvt0Given) model->BSIM3v32wdvt0 = 0.0; if (!model->BSIM3v32wdvt1Given) model->BSIM3v32wdvt1 = 0.0; if (!model->BSIM3v32wdvt2Given) model->BSIM3v32wdvt2 = 0.0; if (!model->BSIM3v32wdvt0wGiven) model->BSIM3v32wdvt0w = 0.0; if (!model->BSIM3v32wdvt1wGiven) model->BSIM3v32wdvt1w = 0.0; if (!model->BSIM3v32wdvt2wGiven) model->BSIM3v32wdvt2w = 0.0; if (!model->BSIM3v32wdroutGiven) model->BSIM3v32wdrout = 0.0; if (!model->BSIM3v32wdsubGiven) model->BSIM3v32wdsub = 0.0; if (!model->BSIM3v32wvth0Given) model->BSIM3v32wvth0 = 0.0; if (!model->BSIM3v32wuaGiven) model->BSIM3v32wua = 0.0; if (!model->BSIM3v32wua1Given) model->BSIM3v32wua1 = 0.0; if (!model->BSIM3v32wubGiven) model->BSIM3v32wub = 0.0; if (!model->BSIM3v32wub1Given) model->BSIM3v32wub1 = 0.0; if (!model->BSIM3v32wucGiven) model->BSIM3v32wuc = 0.0; if (!model->BSIM3v32wuc1Given) model->BSIM3v32wuc1 = 0.0; if (!model->BSIM3v32wu0Given) model->BSIM3v32wu0 = 0.0; if (!model->BSIM3v32wuteGiven) model->BSIM3v32wute = 0.0; if (!model->BSIM3v32wvoffGiven) model->BSIM3v32wvoff = 0.0; if (!model->BSIM3v32wdeltaGiven) model->BSIM3v32wdelta = 0.0; if (!model->BSIM3v32wrdswGiven) model->BSIM3v32wrdsw = 0.0; if (!model->BSIM3v32wprwbGiven) model->BSIM3v32wprwb = 0.0; if (!model->BSIM3v32wprwgGiven) model->BSIM3v32wprwg = 0.0; if (!model->BSIM3v32wprtGiven) model->BSIM3v32wprt = 0.0; if (!model->BSIM3v32weta0Given) model->BSIM3v32weta0 = 0.0; if (!model->BSIM3v32wetabGiven) model->BSIM3v32wetab = 0.0; if (!model->BSIM3v32wpclmGiven) model->BSIM3v32wpclm = 0.0; if (!model->BSIM3v32wpdibl1Given) model->BSIM3v32wpdibl1 = 0.0; if (!model->BSIM3v32wpdibl2Given) model->BSIM3v32wpdibl2 = 0.0; if (!model->BSIM3v32wpdiblbGiven) model->BSIM3v32wpdiblb = 0.0; if (!model->BSIM3v32wpscbe1Given) model->BSIM3v32wpscbe1 = 0.0; if (!model->BSIM3v32wpscbe2Given) model->BSIM3v32wpscbe2 = 0.0; if (!model->BSIM3v32wpvagGiven) model->BSIM3v32wpvag = 0.0; if (!model->BSIM3v32wwrGiven) model->BSIM3v32wwr = 0.0; if (!model->BSIM3v32wdwgGiven) model->BSIM3v32wdwg = 0.0; if (!model->BSIM3v32wdwbGiven) model->BSIM3v32wdwb = 0.0; if (!model->BSIM3v32wb0Given) model->BSIM3v32wb0 = 0.0; if (!model->BSIM3v32wb1Given) model->BSIM3v32wb1 = 0.0; if (!model->BSIM3v32walpha0Given) model->BSIM3v32walpha0 = 0.0; if (!model->BSIM3v32walpha1Given) model->BSIM3v32walpha1 = 0.0; if (!model->BSIM3v32wbeta0Given) model->BSIM3v32wbeta0 = 0.0; if (!model->BSIM3v32wvfbGiven) model->BSIM3v32wvfb = 0.0; if (!model->BSIM3v32welmGiven) model->BSIM3v32welm = 0.0; if (!model->BSIM3v32wcgslGiven) model->BSIM3v32wcgsl = 0.0; if (!model->BSIM3v32wcgdlGiven) model->BSIM3v32wcgdl = 0.0; if (!model->BSIM3v32wckappaGiven) model->BSIM3v32wckappa = 0.0; if (!model->BSIM3v32wcfGiven) model->BSIM3v32wcf = 0.0; if (!model->BSIM3v32wclcGiven) model->BSIM3v32wclc = 0.0; if (!model->BSIM3v32wcleGiven) model->BSIM3v32wcle = 0.0; if (!model->BSIM3v32wvfbcvGiven) model->BSIM3v32wvfbcv = 0.0; if (!model->BSIM3v32wacdeGiven) model->BSIM3v32wacde = 0.0; if (!model->BSIM3v32wmoinGiven) model->BSIM3v32wmoin = 0.0; if (!model->BSIM3v32wnoffGiven) model->BSIM3v32wnoff = 0.0; if (!model->BSIM3v32wvoffcvGiven) model->BSIM3v32wvoffcv = 0.0; /* Cross-term dependence */ if (!model->BSIM3v32pcdscGiven) model->BSIM3v32pcdsc = 0.0; if (!model->BSIM3v32pcdscbGiven) model->BSIM3v32pcdscb = 0.0; if (!model->BSIM3v32pcdscdGiven) model->BSIM3v32pcdscd = 0.0; if (!model->BSIM3v32pcitGiven) model->BSIM3v32pcit = 0.0; if (!model->BSIM3v32pnfactorGiven) model->BSIM3v32pnfactor = 0.0; if (!model->BSIM3v32pxjGiven) model->BSIM3v32pxj = 0.0; if (!model->BSIM3v32pvsatGiven) model->BSIM3v32pvsat = 0.0; if (!model->BSIM3v32patGiven) model->BSIM3v32pat = 0.0; if (!model->BSIM3v32pa0Given) model->BSIM3v32pa0 = 0.0; if (!model->BSIM3v32pagsGiven) model->BSIM3v32pags = 0.0; if (!model->BSIM3v32pa1Given) model->BSIM3v32pa1 = 0.0; if (!model->BSIM3v32pa2Given) model->BSIM3v32pa2 = 0.0; if (!model->BSIM3v32pketaGiven) model->BSIM3v32pketa = 0.0; if (!model->BSIM3v32pnsubGiven) model->BSIM3v32pnsub = 0.0; if (!model->BSIM3v32pnpeakGiven) model->BSIM3v32pnpeak = 0.0; if (!model->BSIM3v32pngateGiven) model->BSIM3v32pngate = 0.0; if (!model->BSIM3v32pvbmGiven) model->BSIM3v32pvbm = 0.0; if (!model->BSIM3v32pxtGiven) model->BSIM3v32pxt = 0.0; if (!model->BSIM3v32pkt1Given) model->BSIM3v32pkt1 = 0.0; if (!model->BSIM3v32pkt1lGiven) model->BSIM3v32pkt1l = 0.0; if (!model->BSIM3v32pkt2Given) model->BSIM3v32pkt2 = 0.0; if (!model->BSIM3v32pk3Given) model->BSIM3v32pk3 = 0.0; if (!model->BSIM3v32pk3bGiven) model->BSIM3v32pk3b = 0.0; if (!model->BSIM3v32pw0Given) model->BSIM3v32pw0 = 0.0; if (!model->BSIM3v32pnlxGiven) model->BSIM3v32pnlx = 0.0; if (!model->BSIM3v32pdvt0Given) model->BSIM3v32pdvt0 = 0.0; if (!model->BSIM3v32pdvt1Given) model->BSIM3v32pdvt1 = 0.0; if (!model->BSIM3v32pdvt2Given) model->BSIM3v32pdvt2 = 0.0; if (!model->BSIM3v32pdvt0wGiven) model->BSIM3v32pdvt0w = 0.0; if (!model->BSIM3v32pdvt1wGiven) model->BSIM3v32pdvt1w = 0.0; if (!model->BSIM3v32pdvt2wGiven) model->BSIM3v32pdvt2w = 0.0; if (!model->BSIM3v32pdroutGiven) model->BSIM3v32pdrout = 0.0; if (!model->BSIM3v32pdsubGiven) model->BSIM3v32pdsub = 0.0; if (!model->BSIM3v32pvth0Given) model->BSIM3v32pvth0 = 0.0; if (!model->BSIM3v32puaGiven) model->BSIM3v32pua = 0.0; if (!model->BSIM3v32pua1Given) model->BSIM3v32pua1 = 0.0; if (!model->BSIM3v32pubGiven) model->BSIM3v32pub = 0.0; if (!model->BSIM3v32pub1Given) model->BSIM3v32pub1 = 0.0; if (!model->BSIM3v32pucGiven) model->BSIM3v32puc = 0.0; if (!model->BSIM3v32puc1Given) model->BSIM3v32puc1 = 0.0; if (!model->BSIM3v32pu0Given) model->BSIM3v32pu0 = 0.0; if (!model->BSIM3v32puteGiven) model->BSIM3v32pute = 0.0; if (!model->BSIM3v32pvoffGiven) model->BSIM3v32pvoff = 0.0; if (!model->BSIM3v32pdeltaGiven) model->BSIM3v32pdelta = 0.0; if (!model->BSIM3v32prdswGiven) model->BSIM3v32prdsw = 0.0; if (!model->BSIM3v32pprwbGiven) model->BSIM3v32pprwb = 0.0; if (!model->BSIM3v32pprwgGiven) model->BSIM3v32pprwg = 0.0; if (!model->BSIM3v32pprtGiven) model->BSIM3v32pprt = 0.0; if (!model->BSIM3v32peta0Given) model->BSIM3v32peta0 = 0.0; if (!model->BSIM3v32petabGiven) model->BSIM3v32petab = 0.0; if (!model->BSIM3v32ppclmGiven) model->BSIM3v32ppclm = 0.0; if (!model->BSIM3v32ppdibl1Given) model->BSIM3v32ppdibl1 = 0.0; if (!model->BSIM3v32ppdibl2Given) model->BSIM3v32ppdibl2 = 0.0; if (!model->BSIM3v32ppdiblbGiven) model->BSIM3v32ppdiblb = 0.0; if (!model->BSIM3v32ppscbe1Given) model->BSIM3v32ppscbe1 = 0.0; if (!model->BSIM3v32ppscbe2Given) model->BSIM3v32ppscbe2 = 0.0; if (!model->BSIM3v32ppvagGiven) model->BSIM3v32ppvag = 0.0; if (!model->BSIM3v32pwrGiven) model->BSIM3v32pwr = 0.0; if (!model->BSIM3v32pdwgGiven) model->BSIM3v32pdwg = 0.0; if (!model->BSIM3v32pdwbGiven) model->BSIM3v32pdwb = 0.0; if (!model->BSIM3v32pb0Given) model->BSIM3v32pb0 = 0.0; if (!model->BSIM3v32pb1Given) model->BSIM3v32pb1 = 0.0; if (!model->BSIM3v32palpha0Given) model->BSIM3v32palpha0 = 0.0; if (!model->BSIM3v32palpha1Given) model->BSIM3v32palpha1 = 0.0; if (!model->BSIM3v32pbeta0Given) model->BSIM3v32pbeta0 = 0.0; if (!model->BSIM3v32pvfbGiven) model->BSIM3v32pvfb = 0.0; if (!model->BSIM3v32pelmGiven) model->BSIM3v32pelm = 0.0; if (!model->BSIM3v32pcgslGiven) model->BSIM3v32pcgsl = 0.0; if (!model->BSIM3v32pcgdlGiven) model->BSIM3v32pcgdl = 0.0; if (!model->BSIM3v32pckappaGiven) model->BSIM3v32pckappa = 0.0; if (!model->BSIM3v32pcfGiven) model->BSIM3v32pcf = 0.0; if (!model->BSIM3v32pclcGiven) model->BSIM3v32pclc = 0.0; if (!model->BSIM3v32pcleGiven) model->BSIM3v32pcle = 0.0; if (!model->BSIM3v32pvfbcvGiven) model->BSIM3v32pvfbcv = 0.0; if (!model->BSIM3v32pacdeGiven) model->BSIM3v32pacde = 0.0; if (!model->BSIM3v32pmoinGiven) model->BSIM3v32pmoin = 0.0; if (!model->BSIM3v32pnoffGiven) model->BSIM3v32pnoff = 0.0; if (!model->BSIM3v32pvoffcvGiven) model->BSIM3v32pvoffcv = 0.0; /* unit degree celcius */ if (!model->BSIM3v32tnomGiven) model->BSIM3v32tnom = ckt->CKTnomTemp; /* else model->BSIM3v32tnom = model->BSIM3v32tnom + 273.15; we make this transform in b3v32mpar.c in the first run */ if (!model->BSIM3v32LintGiven) model->BSIM3v32Lint = 0.0; if (!model->BSIM3v32LlGiven) model->BSIM3v32Ll = 0.0; if (!model->BSIM3v32LlcGiven) model->BSIM3v32Llc = model->BSIM3v32Ll; if (!model->BSIM3v32LlnGiven) model->BSIM3v32Lln = 1.0; if (!model->BSIM3v32LwGiven) model->BSIM3v32Lw = 0.0; if (!model->BSIM3v32LwcGiven) model->BSIM3v32Lwc = model->BSIM3v32Lw; if (!model->BSIM3v32LwnGiven) model->BSIM3v32Lwn = 1.0; if (!model->BSIM3v32LwlGiven) model->BSIM3v32Lwl = 0.0; if (!model->BSIM3v32LwlcGiven) model->BSIM3v32Lwlc = model->BSIM3v32Lwl; if (!model->BSIM3v32LminGiven) model->BSIM3v32Lmin = 0.0; if (!model->BSIM3v32LmaxGiven) model->BSIM3v32Lmax = 1.0; if (!model->BSIM3v32WintGiven) model->BSIM3v32Wint = 0.0; if (!model->BSIM3v32WlGiven) model->BSIM3v32Wl = 0.0; if (!model->BSIM3v32WlcGiven) model->BSIM3v32Wlc = model->BSIM3v32Wl; if (!model->BSIM3v32WlnGiven) model->BSIM3v32Wln = 1.0; if (!model->BSIM3v32WwGiven) model->BSIM3v32Ww = 0.0; if (!model->BSIM3v32WwcGiven) model->BSIM3v32Wwc = model->BSIM3v32Ww; if (!model->BSIM3v32WwnGiven) model->BSIM3v32Wwn = 1.0; if (!model->BSIM3v32WwlGiven) model->BSIM3v32Wwl = 0.0; if (!model->BSIM3v32WwlcGiven) model->BSIM3v32Wwlc = model->BSIM3v32Wwl; if (!model->BSIM3v32WminGiven) model->BSIM3v32Wmin = 0.0; if (!model->BSIM3v32WmaxGiven) model->BSIM3v32Wmax = 1.0; if (!model->BSIM3v32dwcGiven) model->BSIM3v32dwc = model->BSIM3v32Wint; if (!model->BSIM3v32dlcGiven) model->BSIM3v32dlc = model->BSIM3v32Lint; if (!model->BSIM3v32xlGiven) model->BSIM3v32xl = 0.0; if (!model->BSIM3v32xwGiven) model->BSIM3v32xw = 0.0; if (!model->BSIM3v32cfGiven) model->BSIM3v32cf = 2.0 * EPSOX / PI * log(1.0 + 0.4e-6 / model->BSIM3v32tox); if (!model->BSIM3v32cgdoGiven) { if (model->BSIM3v32dlcGiven && (model->BSIM3v32dlc > 0.0)) { model->BSIM3v32cgdo = model->BSIM3v32dlc * model->BSIM3v32cox - model->BSIM3v32cgdl ; } else model->BSIM3v32cgdo = 0.6 * model->BSIM3v32xj * model->BSIM3v32cox; } if (!model->BSIM3v32cgsoGiven) { if (model->BSIM3v32dlcGiven && (model->BSIM3v32dlc > 0.0)) { model->BSIM3v32cgso = model->BSIM3v32dlc * model->BSIM3v32cox - model->BSIM3v32cgsl ; } else model->BSIM3v32cgso = 0.6 * model->BSIM3v32xj * model->BSIM3v32cox; } if (!model->BSIM3v32cgboGiven) { model->BSIM3v32cgbo = 2.0 * model->BSIM3v32dwc * model->BSIM3v32cox; } if (!model->BSIM3v32xpartGiven) model->BSIM3v32xpart = 0.0; if (!model->BSIM3v32sheetResistanceGiven) model->BSIM3v32sheetResistance = 0.0; if (!model->BSIM3v32unitAreaJctCapGiven) model->BSIM3v32unitAreaJctCap = 5.0E-4; if (!model->BSIM3v32unitLengthSidewallJctCapGiven) model->BSIM3v32unitLengthSidewallJctCap = 5.0E-10; if (!model->BSIM3v32unitLengthGateSidewallJctCapGiven) model->BSIM3v32unitLengthGateSidewallJctCap = model->BSIM3v32unitLengthSidewallJctCap ; if (!model->BSIM3v32jctSatCurDensityGiven) model->BSIM3v32jctSatCurDensity = 1.0E-4; if (!model->BSIM3v32jctSidewallSatCurDensityGiven) model->BSIM3v32jctSidewallSatCurDensity = 0.0; if (!model->BSIM3v32bulkJctPotentialGiven) model->BSIM3v32bulkJctPotential = 1.0; if (!model->BSIM3v32sidewallJctPotentialGiven) model->BSIM3v32sidewallJctPotential = 1.0; if (!model->BSIM3v32GatesidewallJctPotentialGiven) model->BSIM3v32GatesidewallJctPotential = model->BSIM3v32sidewallJctPotential; if (!model->BSIM3v32bulkJctBotGradingCoeffGiven) model->BSIM3v32bulkJctBotGradingCoeff = 0.5; if (!model->BSIM3v32bulkJctSideGradingCoeffGiven) model->BSIM3v32bulkJctSideGradingCoeff = 0.33; if (!model->BSIM3v32bulkJctGateSideGradingCoeffGiven) model->BSIM3v32bulkJctGateSideGradingCoeff = model->BSIM3v32bulkJctSideGradingCoeff; if (!model->BSIM3v32jctEmissionCoeffGiven) model->BSIM3v32jctEmissionCoeff = 1.0; if (!model->BSIM3v32jctTempExponentGiven) model->BSIM3v32jctTempExponent = 3.0; if (!model->BSIM3v32oxideTrapDensityAGiven) { if (model->BSIM3v32type == NMOS) model->BSIM3v32oxideTrapDensityA = 1e20; else model->BSIM3v32oxideTrapDensityA=9.9e18; } if (!model->BSIM3v32oxideTrapDensityBGiven) { if (model->BSIM3v32type == NMOS) model->BSIM3v32oxideTrapDensityB = 5e4; else model->BSIM3v32oxideTrapDensityB = 2.4e3; } if (!model->BSIM3v32oxideTrapDensityCGiven) { if (model->BSIM3v32type == NMOS) model->BSIM3v32oxideTrapDensityC = -1.4e-12; else model->BSIM3v32oxideTrapDensityC = 1.4e-12; } if (!model->BSIM3v32emGiven) model->BSIM3v32em = 4.1e7; /* V/m */ if (!model->BSIM3v32efGiven) model->BSIM3v32ef = 1.0; if (!model->BSIM3v32afGiven) model->BSIM3v32af = 1.0; if (!model->BSIM3v32kfGiven) model->BSIM3v32kf = 0.0; if (!model->BSIM3v32vgsMaxGiven) model->BSIM3v32vgsMax = 1e99; if (!model->BSIM3v32vgdMaxGiven) model->BSIM3v32vgdMax = 1e99; if (!model->BSIM3v32vgbMaxGiven) model->BSIM3v32vgbMax = 1e99; if (!model->BSIM3v32vdsMaxGiven) model->BSIM3v32vdsMax = 1e99; if (!model->BSIM3v32vbsMaxGiven) model->BSIM3v32vbsMax = 1e99; if (!model->BSIM3v32vbdMaxGiven) model->BSIM3v32vbdMax = 1e99; /* loop through all the instances of the model */ for (here = model->BSIM3v32instances; here != NULL ; here=here->BSIM3v32nextInstance) { /* allocate a chunk of the state vector */ here->BSIM3v32states = *states; *states += BSIM3v32numStates; /* perform the parameter defaulting */ if (!here->BSIM3v32drainAreaGiven) here->BSIM3v32drainArea = 0.0; if (!here->BSIM3v32drainPerimeterGiven) here->BSIM3v32drainPerimeter = 0.0; if (!here->BSIM3v32drainSquaresGiven) { if (model->BSIM3v32acmMod == 0) here->BSIM3v32drainSquares = 1.0; else here->BSIM3v32drainSquares = 0.0; } if (!here->BSIM3v32delvtoGiven) here->BSIM3v32delvto = 0.0; if (!here->BSIM3v32mulu0Given) here->BSIM3v32mulu0 = 1.0; if (!here->BSIM3v32icVBSGiven) here->BSIM3v32icVBS = 0.0; if (!here->BSIM3v32icVDSGiven) here->BSIM3v32icVDS = 0.0; if (!here->BSIM3v32icVGSGiven) here->BSIM3v32icVGS = 0.0; if (!here->BSIM3v32lGiven) here->BSIM3v32l = 5.0e-6; if (!here->BSIM3v32sourceAreaGiven) here->BSIM3v32sourceArea = 0.0; if (!here->BSIM3v32sourcePerimeterGiven) here->BSIM3v32sourcePerimeter = 0.0; if (!here->BSIM3v32sourceSquaresGiven) { if (model->BSIM3v32acmMod == 0) here->BSIM3v32sourceSquares = 1.0; else here->BSIM3v32sourceSquares = 0.0; } if (!here->BSIM3v32wGiven) here->BSIM3v32w = 5.0e-6; if (!here->BSIM3v32nqsModGiven) here->BSIM3v32nqsMod = model->BSIM3v32nqsMod; else if ((here->BSIM3v32nqsMod != 0) && (here->BSIM3v32nqsMod != 1)) { here->BSIM3v32nqsMod = model->BSIM3v32nqsMod; printf("Warning: nqsMod has been set to its global value %d.\n", model->BSIM3v32nqsMod); } if (!here->BSIM3v32geoGiven) here->BSIM3v32geo = 0; if (!here->BSIM3v32mGiven) here->BSIM3v32m = 1; /* process drain series resistance */ if ( ((model->BSIM3v32sheetResistance > 0.0) && (here->BSIM3v32drainSquares > 0.0)) ||((model->BSIM3v32sheetResistance > 0.0) && (model->BSIM3v32hdif > 0.0)) ||((model->BSIM3v32rd > 0.0) && (model->BSIM3v32ldif > 0.0)) ||((model->BSIM3v32rd > 0.0) && (model->BSIM3v32ld > 0.0)) ||((model->BSIM3v32rdc > 0.0)) ) { if(here->BSIM3v32dNodePrime == 0) { error = CKTmkVolt(ckt,&tmp,here->BSIM3v32name,"drain"); if(error) return(error); here->BSIM3v32dNodePrime = tmp->number; if (ckt->CKTcopyNodesets) { if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->BSIM3v32dNodePrime = here->BSIM3v32dNode; } /* process source series resistance */ if ( ((model->BSIM3v32sheetResistance > 0.0) && (here->BSIM3v32sourceSquares > 0.0)) ||((model->BSIM3v32sheetResistance > 0.0) && (model->BSIM3v32hdif > 0.0)) ||((model->BSIM3v32rs > 0.0) && (model->BSIM3v32ldif > 0.0)) ||((model->BSIM3v32rs > 0.0) && (model->BSIM3v32ld > 0.0)) ||((model->BSIM3v32rsc > 0.0)) ) { if(here->BSIM3v32sNodePrime == 0) { error = CKTmkVolt(ckt,&tmp,here->BSIM3v32name,"source"); if(error) return(error); here->BSIM3v32sNodePrime = tmp->number; if (ckt->CKTcopyNodesets) { if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->BSIM3v32sNodePrime = here->BSIM3v32sNode; } /* internal charge node */ if (here->BSIM3v32nqsMod) { if(here->BSIM3v32qNode == 0) { error = CKTmkVolt(ckt,&tmp,here->BSIM3v32name,"charge"); if(error) return(error); here->BSIM3v32qNode = tmp->number; } } else { here->BSIM3v32qNode = 0; } /* Channel length scaling with lmlt model parameter */ if (model->BSIM3v32lmltGiven) here->BSIM3v32l *= model->BSIM3v32lmlt; /* set Sparse Matrix Pointers */ /* 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(BSIM3v32DdPtr, BSIM3v32dNode, BSIM3v32dNode); TSTALLOC(BSIM3v32GgPtr, BSIM3v32gNode, BSIM3v32gNode); TSTALLOC(BSIM3v32SsPtr, BSIM3v32sNode, BSIM3v32sNode); TSTALLOC(BSIM3v32BbPtr, BSIM3v32bNode, BSIM3v32bNode); TSTALLOC(BSIM3v32DPdpPtr, BSIM3v32dNodePrime, BSIM3v32dNodePrime); TSTALLOC(BSIM3v32SPspPtr, BSIM3v32sNodePrime, BSIM3v32sNodePrime); TSTALLOC(BSIM3v32DdpPtr, BSIM3v32dNode, BSIM3v32dNodePrime); TSTALLOC(BSIM3v32GbPtr, BSIM3v32gNode, BSIM3v32bNode); TSTALLOC(BSIM3v32GdpPtr, BSIM3v32gNode, BSIM3v32dNodePrime); TSTALLOC(BSIM3v32GspPtr, BSIM3v32gNode, BSIM3v32sNodePrime); TSTALLOC(BSIM3v32SspPtr, BSIM3v32sNode, BSIM3v32sNodePrime); TSTALLOC(BSIM3v32BdpPtr, BSIM3v32bNode, BSIM3v32dNodePrime); TSTALLOC(BSIM3v32BspPtr, BSIM3v32bNode, BSIM3v32sNodePrime); TSTALLOC(BSIM3v32DPspPtr, BSIM3v32dNodePrime, BSIM3v32sNodePrime); TSTALLOC(BSIM3v32DPdPtr, BSIM3v32dNodePrime, BSIM3v32dNode); TSTALLOC(BSIM3v32BgPtr, BSIM3v32bNode, BSIM3v32gNode); TSTALLOC(BSIM3v32DPgPtr, BSIM3v32dNodePrime, BSIM3v32gNode); TSTALLOC(BSIM3v32SPgPtr, BSIM3v32sNodePrime, BSIM3v32gNode); TSTALLOC(BSIM3v32SPsPtr, BSIM3v32sNodePrime, BSIM3v32sNode); TSTALLOC(BSIM3v32DPbPtr, BSIM3v32dNodePrime, BSIM3v32bNode); TSTALLOC(BSIM3v32SPbPtr, BSIM3v32sNodePrime, BSIM3v32bNode); TSTALLOC(BSIM3v32SPdpPtr, BSIM3v32sNodePrime, BSIM3v32dNodePrime); TSTALLOC(BSIM3v32QqPtr, BSIM3v32qNode, BSIM3v32qNode); TSTALLOC(BSIM3v32QdpPtr, BSIM3v32qNode, BSIM3v32dNodePrime); TSTALLOC(BSIM3v32QspPtr, BSIM3v32qNode, BSIM3v32sNodePrime); TSTALLOC(BSIM3v32QgPtr, BSIM3v32qNode, BSIM3v32gNode); TSTALLOC(BSIM3v32QbPtr, BSIM3v32qNode, BSIM3v32bNode); TSTALLOC(BSIM3v32DPqPtr, BSIM3v32dNodePrime, BSIM3v32qNode); TSTALLOC(BSIM3v32SPqPtr, BSIM3v32sNodePrime, BSIM3v32qNode); TSTALLOC(BSIM3v32GqPtr, BSIM3v32gNode, BSIM3v32qNode); TSTALLOC(BSIM3v32BqPtr, BSIM3v32bNode, BSIM3v32qNode); } } #ifdef USE_OMP InstCount = 0; model = (BSIM3v32model*)inModel; /* loop through all the BSIM3 device models to count the number of instances */ for (; model != NULL; model = model->BSIM3v32nextModel) { /* loop through all the instances of the model */ for (here = model->BSIM3v32instances; here != NULL; here = here->BSIM3v32nextInstance) { InstCount++; } } InstArray = TMALLOC(BSIM3v32instance*, InstCount); model = (BSIM3v32model*)inModel; idx = 0; for (; model != NULL; model = model->BSIM3v32nextModel) { /* loop through all the instances of the model */ for (here = model->BSIM3v32instances; here != NULL; here = here->BSIM3v32nextInstance) { InstArray[idx] = here; idx++; } /* set the array pointer and instance count into each model */ model->BSIM3v32InstCount = InstCount; model->BSIM3v32InstanceArray = InstArray; } #endif return(OK); }
/*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); }
int HFETAsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) /* load the diode structure with those pointers needed later * for fast matrix loading */ { HFETAmodel *model = (HFETAmodel*)inModel; HFETAinstance *here; int error; CKTnode *tmp; /* loop through all the diode models */ for( ; model != NULL; model = model->HFETAnextModel ) { if( (model->HFETAtype != NHFET) && (model->HFETAtype != PHFET) ) { model->HFETAtype = NHFET; } if(!model->HFETAthresholdGiven) { if(model->HFETAtype == NHFET) model->HFETAthreshold = 0.15; else model->HFETAthreshold = -0.15; } if(!model->HFETAdiGiven) { model->HFETAdi = 0.04e-6; } if(!model->HFETAlambdaGiven) { model->HFETAlambda = 0.15; } if(!model->HFETAetaGiven) { if(model->HFETAtype == NHFET) model->HFETAeta = 1.28; else model->HFETAeta = 1.4; } if(!model->HFETAmGiven) { model->HFETAm = 3.0; } if(!model->HFETAmcGiven) { model->HFETAmc = 3.0; } if(!model->HFETAgammaGiven) { model->HFETAgamma = 3.0; } if(!model->HFETAsigma0Given) { model->HFETAsigma0 = 0.057; } if(!model->HFETAvsigmatGiven) { model->HFETAvsigmat = 0.3; } if(!model->HFETAvsigmaGiven) { model->HFETAvsigma = 0.1; } if(!model->HFETAmuGiven) { if(model->HFETAtype == NHFET) model->HFETAmu = 0.4; else model->HFETAmu = 0.03; } if(!model->HFETAdeltaGiven) { model->HFETAdelta = 3.0; } if(!model->HFETAvsGiven) { if(model->HFETAtype == NHFET) model->HFETAvs = 1.5e5; else model->HFETAvs = 0.8e5; } if(!model->HFETAnmaxGiven) { model->HFETAnmax = 2e16; } if(!model->HFETAdeltadGiven) { model->HFETAdeltad = 4.5e-9; } if(!model->HFETAjs1dGiven) { model->HFETAjs1d = 1.0; } if(!model->HFETAjs2dGiven) { model->HFETAjs2d = 1.15e6; } if(!model->HFETAjs1sGiven) { model->HFETAjs1s = 1.0; } if(!model->HFETAjs2sGiven) { model->HFETAjs2s = 1.15e6; } if(!model->HFETAm1dGiven) { model->HFETAm1d = 1.32; } if(!model->HFETAm2dGiven) { model->HFETAm2d = 6.9; } if(!model->HFETAm1sGiven) { model->HFETAm1s = 1.32; } if(!model->HFETAm2sGiven) { model->HFETAm2s = 6.9; } if(!model->HFETArdGiven) { model->HFETArd = 0; } if(!model->HFETArsGiven) { model->HFETArs = 0; } if(!model->HFETArdiGiven) { model->HFETArdi = 0; } if(!model->HFETArsiGiven) { model->HFETArsi = 0; } if(!model->HFETArgsGiven) { model->HFETArgs = 90; } if(!model->HFETArgdGiven) { model->HFETArgd = 90; } if(!model->HFETAriGiven) { model->HFETAri = 0; } if(!model->HFETArfGiven) { model->HFETArf = 0; } if(!model->HFETAepsiGiven) { model->HFETAepsi = 12.244*8.85418e-12; } if(!model->HFETAa1Given) { model->HFETAa1 = 0; } if(!model->HFETAa2Given) { model->HFETAa2 = 0; } if(!model->HFETAmv1Given) { model->HFETAmv1 = 3; } if(!model->HFETApGiven) { model->HFETAp = 1; } if(!model->HFETAkappaGiven) { model->HFETAkappa = 0; } if(!model->HFETAdelfGiven) { model->HFETAdelf = 0; } if(!model->HFETAfgdsGiven) { model->HFETAfgds = 0; } if(!model->HFETAtfGiven) { model->HFETAtf = ckt->CKTtemp; } if(!model->HFETAcdsGiven) { model->HFETAcds = 0; } if(!model->HFETAphibGiven) { model->HFETAphib = 0.5*CHARGE; } if(!model->HFETAtalphaGiven) { model->HFETAtalpha = 1200; } if(!model->HFETAmt1Given) { model->HFETAmt1 = 3.5; } if(!model->HFETAmt2Given) { model->HFETAmt2 = 9.9; } if(!model->HFETAck1Given) { model->HFETAck1 = 1; } if(!model->HFETAck2Given) { model->HFETAck2 = 0; } if(!model->HFETAcm1Given) { model->HFETAcm1 = 3; } if(!model->HFETAcm2Given) { model->HFETAcm2 = 0; } if(!model->HFETAcm3Given) { model->HFETAcm3 = 0.17; } if(!model->HFETAastarGiven) { model->HFETAastar = 4.0e4; } if(!model->HFETAeta1Given) { model->HFETAeta1 = 2; } if(!model->HFETAd1Given) { model->HFETAd1 = 0.03e-6; } if(!model->HFETAeta2Given) { model->HFETAeta2 = 2; } if(!model->HFETAd2Given) { model->HFETAd2 = 0.2e-6; } if(!model->HFETAvt2Given) { /* initialized in HFETAtemp */ model->HFETAvt2 = 0; } if(!model->HFETAggrGiven) { model->HFETAggr = 40; } if(!model->HFETAdelGiven) { model->HFETAdel = 0.04; } if(!model->HFETAklambdaGiven) KLAMBDA = 0; if(!model->HFETAkmuGiven) KMU = 0; if(!model->HFETAkvtoGiven) KVTO = 0; /* loop through all the instances of the model */ for (here = model->HFETAinstances; here != NULL ; here=here->HFETAnextInstance) { if(!here->HFETAlengthGiven) { here->HFETAlength = 1e-6; } if(!here->HFETAwidthGiven) { here->HFETAwidth = 20e-6; } if(!here->HFETAmGiven) { here->HFETAm = 1.0; } here->HFETAstate = *states; /* *states += 24; */ *states += HFETAnumStates; if(model->HFETArs != 0) { if(here->HFETAsourcePrimeNode == 0) { error = CKTmkVolt(ckt,&tmp,here->HFETAname,"source"); if(error) return(error); here->HFETAsourcePrimeNode = tmp->number; /* XXX: Applied AlansFixes */ if (ckt->CKTcopyNodesets) { CKTnode *tmpNode; IFuid tmpName; if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->HFETAsourcePrimeNode = here->HFETAsourceNode; } if(model->HFETArd != 0) { if(here->HFETAdrainPrimeNode == 0) { error = CKTmkVolt(ckt,&tmp,here->HFETAname,"drain"); if(error) return(error); here->HFETAdrainPrimeNode = tmp->number; if (ckt->CKTcopyNodesets) { CKTnode *tmpNode; IFuid tmpName; if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->HFETAdrainPrimeNode = here->HFETAdrainNode; } if(model->HFETArg != 0) { if(here->HFETAgatePrimeNode == 0) { error = CKTmkVolt(ckt,&tmp,here->HFETAname,"gate"); if(error) return(error); here->HFETAgatePrimeNode = tmp->number; if (ckt->CKTcopyNodesets) { CKTnode *tmpNode; IFuid tmpName; if (CKTinst2Node(ckt,here,2,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->HFETAgatePrimeNode = here->HFETAgateNode; } if(model->HFETArf != 0) { if(here->HFETAdrainPrmPrmNode == 0) { error = CKTmkVolt(ckt,&tmp,here->HFETAname,"gd"); if(error) return(error); here->HFETAdrainPrmPrmNode = tmp->number; if (ckt->CKTcopyNodesets) { CKTnode *tmpNode; IFuid tmpName; if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->HFETAdrainPrmPrmNode = here->HFETAdrainPrimeNode; } if(model->HFETAri != 0) { if(here->HFETAsourcePrmPrmNode == 0) { error = CKTmkVolt(ckt,&tmp,here->HFETAname,"gs"); if(error) return(error); here->HFETAsourcePrmPrmNode = tmp->number; if (ckt->CKTcopyNodesets) { CKTnode *tmpNode; IFuid tmpName; if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->HFETAsourcePrmPrmNode = here->HFETAsourcePrimeNode; } /* 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(HFETAdrainDrainPrimePtr,HFETAdrainNode,HFETAdrainPrimeNode); TSTALLOC(HFETAgatePrimeDrainPrimePtr,HFETAgatePrimeNode,HFETAdrainPrimeNode); TSTALLOC(HFETAgatePrimeSourcePrimePtr,HFETAgatePrimeNode,HFETAsourcePrimeNode); TSTALLOC(HFETAsourceSourcePrimePtr,HFETAsourceNode,HFETAsourcePrimeNode); TSTALLOC(HFETAdrainPrimeDrainPtr,HFETAdrainPrimeNode,HFETAdrainNode); TSTALLOC(HFETAdrainPrimeGatePrimePtr,HFETAdrainPrimeNode,HFETAgatePrimeNode); TSTALLOC(HFETAdrainPrimeSourcePrimePtr,HFETAdrainPrimeNode,HFETAsourcePrimeNode); TSTALLOC(HFETAsourcePrimeGatePrimePtr,HFETAsourcePrimeNode,HFETAgatePrimeNode); TSTALLOC(HFETAsourcePrimeSourcePtr,HFETAsourcePrimeNode,HFETAsourceNode); TSTALLOC(HFETAsourcePrimeDrainPrimePtr,HFETAsourcePrimeNode,HFETAdrainPrimeNode); TSTALLOC(HFETAdrainDrainPtr,HFETAdrainNode,HFETAdrainNode); TSTALLOC(HFETAgatePrimeGatePrimePtr,HFETAgatePrimeNode,HFETAgatePrimeNode); TSTALLOC(HFETAsourceSourcePtr,HFETAsourceNode,HFETAsourceNode); TSTALLOC(HFETAdrainPrimeDrainPrimePtr,HFETAdrainPrimeNode,HFETAdrainPrimeNode); TSTALLOC(HFETAsourcePrimeSourcePrimePtr,HFETAsourcePrimeNode,HFETAsourcePrimeNode); TSTALLOC(HFETAdrainPrimeDrainPrmPrmPtr,HFETAdrainPrimeNode,HFETAdrainPrmPrmNode); TSTALLOC(HFETAdrainPrmPrmDrainPrimePtr,HFETAdrainPrmPrmNode,HFETAdrainPrimeNode); TSTALLOC(HFETAdrainPrmPrmGatePrimePtr,HFETAdrainPrmPrmNode,HFETAgatePrimeNode); TSTALLOC(HFETAgatePrimeDrainPrmPrmPtr,HFETAgatePrimeNode,HFETAdrainPrmPrmNode); TSTALLOC(HFETAdrainPrmPrmDrainPrmPrmPtr,HFETAdrainPrmPrmNode,HFETAdrainPrmPrmNode); TSTALLOC(HFETAsourcePrimeSourcePrmPrmPtr,HFETAsourcePrimeNode,HFETAsourcePrmPrmNode); TSTALLOC(HFETAsourcePrmPrmSourcePrimePtr,HFETAsourcePrmPrmNode,HFETAsourcePrimeNode); TSTALLOC(HFETAsourcePrmPrmGatePrimePtr,HFETAsourcePrmPrmNode,HFETAgatePrimeNode); TSTALLOC(HFETAgatePrimeSourcePrmPrmPtr,HFETAgatePrimeNode,HFETAsourcePrmPrmNode); TSTALLOC(HFETAsourcePrmPrmSourcePrmPrmPtr,HFETAsourcePrmPrmNode,HFETAsourcePrmPrmNode); TSTALLOC(HFETAgateGatePtr,HFETAgateNode,HFETAgateNode); TSTALLOC(HFETAgateGatePrimePtr,HFETAgateNode,HFETAgatePrimeNode); TSTALLOC(HFETAgatePrimeGatePtr,HFETAgatePrimeNode,HFETAgateNode); } } return(OK); }
int MESAsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) /* load the diode structure with those pointers needed later * for fast matrix loading */ { MESAmodel *model = (MESAmodel*)inModel; MESAinstance *here; int error; CKTnode *tmp; /* loop through all the diode models */ for( ; model != NULL; model = model->MESAnextModel ) { if( (model->MESAtype != NMF) ) { fprintf(stderr, "Only nmf model type supported, set to nmf\n"); model->MESAtype = NMF; } if(!model->MESAthresholdGiven) { model->MESAthreshold = -1.26; } if(!model->MESAdGiven) { model->MESAd = 0.12e-6; } if(!model->MESAduGiven) { model->MESAdu = 0.035e-6; } if(!model->MESAlambdaGiven) { model->MESAlambda = 0.045; } if(!model->MESAvsGiven) { model->MESAvs = 1.5e5; } if(!model->MESAbetaGiven) { model->MESAbeta = 0.0085; } if(!model->MESAetaGiven) { model->MESAeta = 1.73; } if(!model->MESAmGiven) { model->MESAm = 2.5; } if(!model->MESAmcGiven) { model->MESAmc = 3.0; } if(!model->MESAalphaGiven) { model->MESAalpha = 0.0; } if(!model->MESAsigma0Given) { model->MESAsigma0 = 0.081; } if(!model->MESAvsigmatGiven) { model->MESAvsigmat = 1.01; } if(!model->MESAvsigmaGiven) { model->MESAvsigma = 0.1; } if(!model->MESAmuGiven) { model->MESAmu = 0.23; } if(!model->MESAthetaGiven) { model->MESAtheta = 0; } if(!model->MESAmu1Given) { model->MESAmu1 = 0; } if(!model->MESAmu2Given) { model->MESAmu2 = 0; } if(!model->MESAndGiven) { model->MESAnd = 2.0e23; } if(!model->MESAnduGiven) { model->MESAndu = 1e22; } if(!model->MESAndeltaGiven) { model->MESAndelta = 6e24; } if(!model->MESAthGiven) { model->MESAth = 0.01e-6; } if(!model->MESAdeltaGiven) { model->MESAdelta = 5.0; } if(!model->MESAtcGiven) { model->MESAtc = 0.0; } if(!model->MESAdrainResistGiven) { model->MESAdrainResist = 0; } if(!model->MESAsourceResistGiven) { model->MESAsourceResist = 0; } if(!model->MESAgateResistGiven) { model->MESAgateResist = 0; } if(!model->MESAriGiven) { model->MESAri = 0; } if(!model->MESArfGiven) { model->MESArf = 0; } if(!model->MESArdiGiven) { model->MESArdi = 0; } if(!model->MESArsiGiven) { model->MESArsi = 0; } if(!model->MESAphibGiven) { model->MESAphib = 0.5*CHARGE; } if(!model->MESAphib1Given) { model->MESAphib1 = 0; } if(!model->MESAastarGiven) { model->MESAastar = 4.0e4; } if(!model->MESAggrGiven) { model->MESAggr = 40; } if(!model->MESAdelGiven) { model->MESAdel = 0.04; } if(!model->MESAxchiGiven) { model->MESAxchi = 0.033; } if(!model->MESAnGiven) { model->MESAn = 1; } if(!model->MESAtvtoGiven) { model->MESAtvto = 0; } if(!model->MESAtlambdaGiven) { model->MESAtlambda = DBL_MAX; } if(!model->MESAteta0Given) { model->MESAteta0 = DBL_MAX; } if(!model->MESAteta1Given) { model->MESAteta1 = 0; } if(!model->MESAtmuGiven) { model->MESAtmu = 300.15; } if(!model->MESAxtm0Given) { model->MESAxtm0 = 0; } if(!model->MESAxtm1Given) { model->MESAxtm1 = 0; } if(!model->MESAxtm2Given) { model->MESAxtm2 = 0; } if(!model->MESAksGiven) { model->MESAks = 0; } if(!model->MESAvsgGiven) { model->MESAvsg = 0; } if(!model->MESAtfGiven) { model->MESAtf = ckt->CKTtemp; } if(!model->MESAfloGiven) { model->MESAflo = 0; } if(!model->MESAdelfoGiven) { model->MESAdelfo = 0; } if(!model->MESAagGiven) { model->MESAag = 0; } if(!model->MESAtc1Given) { model->MESAtc1 = 0; } if(!model->MESAtc2Given) { model->MESAtc2 = 0; } if(!model->MESAzetaGiven) { model->MESAzeta = 1; } if(!model->MESAlevelGiven) { model->MESAlevel = 2; } if(!model->MESAnmaxGiven) { model->MESAnmax = 2e16; } if(!model->MESAgammaGiven) { model->MESAgamma = 3.0; } if(!model->MESAepsiGiven) { model->MESAepsi = 12.244*8.85418e-12; } if(!model->MESAcasGiven) { model->MESAcas = 1; } if(!model->MESAcbsGiven) { model->MESAcbs = 1; } if(model->MESAdrainResist != 0) { model->MESAdrainConduct = 1./model->MESAdrainResist; } else { model->MESAdrainConduct = DBL_MAX; } if(model->MESAsourceResist != 0) { model->MESAsourceConduct = 1./model->MESAsourceResist; } else { model->MESAsourceConduct = DBL_MAX; } model->MESAvcrit = 0.; /* until model has changed */ /* loop through all the instances of the model */ for (here = model->MESAinstances; here != NULL ; here=here->MESAnextInstance) { if(!here->MESAlengthGiven) { here->MESAlength = 1e-6; } if(!here->MESAwidthGiven) { here->MESAwidth = 20e-6; } if(!here->MESAmGiven) { here->MESAm = 1.0; } if(!here->MESAdtempGiven) { here->MESAdtemp = 0.0; } if(!here->MESAtdGiven) { here->MESAtd = ckt->CKTtemp + here->MESAdtemp; } if(!here->MESAtsGiven) { here->MESAts = ckt->CKTtemp + here->MESAdtemp; } here->MESAstate = *states; *states += 20; if(model->MESAsourceResist != 0) { if(here->MESAsourcePrimeNode == 0) { error = CKTmkVolt(ckt,&tmp,here->MESAname,"source"); if(error) return(error); here->MESAsourcePrimeNode = tmp->number; if (ckt->CKTcopyNodesets) { CKTnode *tmpNode; IFuid tmpName; if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->MESAsourcePrimeNode = here->MESAsourceNode; } if(model->MESAdrainResist != 0) { if(here->MESAdrainPrimeNode == 0) { error = CKTmkVolt(ckt,&tmp,here->MESAname,"drain"); if(error) return(error); here->MESAdrainPrimeNode = tmp->number; if (ckt->CKTcopyNodesets) { CKTnode *tmpNode; IFuid tmpName; if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->MESAdrainPrimeNode = here->MESAdrainNode; } if(model->MESAgateResist != 0) { if(here->MESAgatePrimeNode == 0) { error = CKTmkVolt(ckt,&tmp,here->MESAname,"gate"); if(error) return(error); here->MESAgatePrimeNode = tmp->number; if (ckt->CKTcopyNodesets) { CKTnode *tmpNode; IFuid tmpName; if (CKTinst2Node(ckt,here,2,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->MESAgatePrimeNode = here->MESAgateNode; } if(model->MESAri != 0) { if(here->MESAsourcePrmPrmNode == 0) { error = CKTmkVolt(ckt,&tmp,here->MESAname,"gs"); if(error) return(error); here->MESAsourcePrmPrmNode = tmp->number; if (ckt->CKTcopyNodesets) { CKTnode *tmpNode; IFuid tmpName; if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->MESAsourcePrmPrmNode = here->MESAsourcePrimeNode; } if(model->MESArf != 0) { if(here->MESAdrainPrmPrmNode == 0) { error = CKTmkVolt(ckt,&tmp,here->MESAname,"gd"); if(error) return(error); here->MESAdrainPrmPrmNode = tmp->number; if (ckt->CKTcopyNodesets) { CKTnode *tmpNode; IFuid tmpName; if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->MESAdrainPrmPrmNode = here->MESAdrainPrimeNode; } #define TSTALLOC(ptr,first,second) \ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ return(E_NOMEM);\ } } while(0) TSTALLOC(MESAdrainDrainPtr,MESAdrainNode,MESAdrainNode); TSTALLOC(MESAdrainPrimeDrainPrimePtr,MESAdrainPrimeNode,MESAdrainPrimeNode); TSTALLOC(MESAdrainPrmPrmDrainPrmPrmPtr,MESAdrainPrmPrmNode,MESAdrainPrmPrmNode); TSTALLOC(MESAgateGatePtr,MESAgateNode,MESAgateNode); TSTALLOC(MESAgatePrimeGatePrimePtr,MESAgatePrimeNode,MESAgatePrimeNode); TSTALLOC(MESAsourceSourcePtr,MESAsourceNode,MESAsourceNode); TSTALLOC(MESAsourcePrimeSourcePrimePtr,MESAsourcePrimeNode,MESAsourcePrimeNode); TSTALLOC(MESAsourcePrmPrmSourcePrmPrmPtr,MESAsourcePrmPrmNode,MESAsourcePrmPrmNode); TSTALLOC(MESAdrainDrainPrimePtr,MESAdrainNode,MESAdrainPrimeNode); TSTALLOC(MESAdrainPrimeDrainPtr,MESAdrainPrimeNode,MESAdrainNode); TSTALLOC(MESAgatePrimeDrainPrimePtr,MESAgatePrimeNode,MESAdrainPrimeNode); TSTALLOC(MESAdrainPrimeGatePrimePtr,MESAdrainPrimeNode,MESAgatePrimeNode); TSTALLOC(MESAgatePrimeSourcePrimePtr,MESAgatePrimeNode,MESAsourcePrimeNode); TSTALLOC(MESAsourcePrimeGatePrimePtr,MESAsourcePrimeNode,MESAgatePrimeNode) ; TSTALLOC(MESAsourceSourcePrimePtr,MESAsourceNode,MESAsourcePrimeNode); TSTALLOC(MESAsourcePrimeSourcePtr,MESAsourcePrimeNode,MESAsourceNode); TSTALLOC(MESAdrainPrimeSourcePrimePtr,MESAdrainPrimeNode,MESAsourcePrimeNode); TSTALLOC(MESAsourcePrimeDrainPrimePtr,MESAsourcePrimeNode,MESAdrainPrimeNode); TSTALLOC(MESAgatePrimeGatePtr,MESAgatePrimeNode,MESAgateNode); TSTALLOC(MESAgateGatePrimePtr,MESAgateNode,MESAgatePrimeNode); TSTALLOC(MESAsourcePrmPrmSourcePrimePtr,MESAsourcePrmPrmNode,MESAsourcePrimeNode); TSTALLOC(MESAsourcePrimeSourcePrmPrmPtr,MESAsourcePrimeNode,MESAsourcePrmPrmNode); TSTALLOC(MESAsourcePrmPrmGatePrimePtr,MESAsourcePrmPrmNode,MESAgatePrimeNode); TSTALLOC(MESAgatePrimeSourcePrmPrmPtr,MESAgatePrimeNode,MESAsourcePrmPrmNode); TSTALLOC(MESAdrainPrmPrmDrainPrimePtr,MESAdrainPrmPrmNode,MESAdrainPrimeNode); TSTALLOC(MESAdrainPrimeDrainPrmPrmPtr,MESAdrainPrimeNode,MESAdrainPrmPrmNode); TSTALLOC(MESAdrainPrmPrmGatePrimePtr,MESAdrainPrmPrmNode,MESAgatePrimeNode); TSTALLOC(MESAgatePrimeDrainPrmPrmPtr,MESAgatePrimeNode,MESAdrainPrmPrmNode); } } 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); }
int NUMDsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) /* * load the structure with those pointers needed later for fast matrix * loading */ { register NUMDmodel *model = (NUMDmodel *) inModel; register NUMDinstance *inst; METHcard *methods; MODLcard *models; OPTNcard *options; OUTPcard *outputs; int error; int xMeshSize; ONEdevice *pDevice; ONEcoord *xCoordList = NULL; ONEdomain *domainList = NULL; ONEmaterial *pM, *pMaterial = NULL, *materialList = NULL; DOPprofile *profileList = NULL; DOPtable *dopTableList = NULL; double startTime; /* loop through all the models */ for (; model != NULL; model = model->NUMDnextModel) { if (!model->NUMDpInfo) { TSCALLOC(model->NUMDpInfo, 1, ONEtranInfo); } methods = model->NUMDmethods; if (!methods) { TSCALLOC(methods, 1, METHcard); model->NUMDmethods = methods; } models = model->NUMDmodels; if (!models) { TSCALLOC(models, 1, MODLcard); model->NUMDmodels = models; } options = model->NUMDoptions; if (!options) { TSCALLOC(options, 1, OPTNcard); model->NUMDoptions = options; } outputs = model->NUMDoutputs; if (!outputs) { TSCALLOC(outputs, 1, OUTPcard); model->NUMDoutputs = outputs; } if (!methods->METHvoltPredGiven) { methods->METHvoltPred = FALSE; } if (!methods->METHmobDerivGiven) { methods->METHmobDeriv = TRUE; } if (!methods->METHoneCarrierGiven) { methods->METHoneCarrier = FALSE; } if (!methods->METHacAnalysisMethodGiven) { methods->METHacAnalysisMethod = SOR; } if (!methods->METHdabstolGiven) { methods->METHdabstol = DABSTOL1D; } if (!methods->METHdreltolGiven) { methods->METHdreltol = ckt->CKTreltol; } if (!methods->METHitLimGiven) { methods->METHitLim = 20; } if (!methods->METHomegaGiven || methods->METHomega <= 0.0) { methods->METHomega = 2.0 * M_PI /* radians/sec */ ; } if (!options->OPTNdefaGiven || options->OPTNdefa <= 0.0) { options->OPTNdefa = 1.0e4 /* cm^2 */ ; } if (!options->OPTNdeviceTypeGiven) { options->OPTNdeviceType = OPTN_DIODE; } if (!options->OPTNicFileGiven) { options->OPTNicFile = NULL; options->OPTNunique = FALSE; /* Can't form a unique name. */ } if (!options->OPTNuniqueGiven) { options->OPTNunique = FALSE; } /* Set up the rest of the card lists */ if ((error = MODLsetup(model->NUMDmodels)) != 0) return (error); BandGapNarrowing = models->MODLbandGapNarrowing; ConcDepLifetime = models->MODLconcDepLifetime; TempDepMobility = models->MODLtempDepMobility; ConcDepMobility = models->MODLconcDepMobility; if ((error = OUTPsetup(model->NUMDoutputs)) != 0) return (error); if ((error = MATLsetup(model->NUMDmaterials, &materialList)) != 0) return (error); if ((error = MOBsetup(model->NUMDmobility, materialList)) != 0) return (error); if ((error = MESHsetup('x', model->NUMDxMeshes, &xCoordList, &xMeshSize)) != 0) return (error); if ((error = DOMNsetup(model->NUMDdomains, &domainList, xCoordList, NULL, materialList)) != 0) return (error); if ((error = BDRYsetup(model->NUMDboundaries, xCoordList, NULL, domainList)) != 0) return (error); if ((error = CONTsetup(model->NUMDcontacts, NULL)) != 0) return (error); if ((error = DOPsetup(model->NUMDdopings, &profileList, &dopTableList, xCoordList, NULL)) != 0) return (error); model->NUMDmatlInfo = materialList; model->NUMDprofiles = profileList; model->NUMDdopTables = dopTableList; /* loop through all the instances of the model */ for (inst = model->NUMDinstances; inst != NULL; inst = inst->NUMDnextInstance) { startTime = SPfrontEnd->IFseconds(); if ((!inst->NUMDprintGiven)) { inst->NUMDprint = 0; } else if (inst->NUMDprint <= 0) { inst->NUMDprint = 1; } if ((!inst->NUMDicFileGiven)) { if (options->OPTNunique) { inst->NUMDicFile = tprintf("%s.%s", options->OPTNicFile, inst->NUMDname); } else if (options->OPTNicFile != NULL) { inst->NUMDicFile = tprintf("%s", options->OPTNicFile); } else { inst->NUMDicFile = NULL; } } inst->NUMDstate = *states; *states += NUMDnumStates; if (!inst->NUMDpDevice) { /* Assign the mesh info to each instance. */ TSCALLOC(pDevice, 1, ONEdevice); TSCALLOC(pDevice->pStats, 1, ONEstats); pDevice->name = inst->NUMDname; pDevice->solverType = SLV_NONE; pDevice->numNodes = xMeshSize; pDevice->abstol = methods->METHdabstol; pDevice->reltol = methods->METHdreltol; pDevice->rhsImag = NULL; TSCALLOC(pDevice->elemArray, pDevice->numNodes, ONEelem *); /* Create a copy of material data that can change with temperature. */ pDevice->pMaterials = NULL; for (pM = materialList; pM != NULL; pM = pM->next) { if (pDevice->pMaterials == NULL) { TSCALLOC(pMaterial, 1, ONEmaterial); pDevice->pMaterials = pMaterial; } else { TSCALLOC(pMaterial->next, 1, ONEmaterial); pMaterial = pMaterial->next; } /* Copy everything, then fix the incorrect pointer. */ memcpy(pMaterial, pM, sizeof(ONEmaterial)); pMaterial->next = NULL; } /* generate the mesh structure for the device */ ONEbuildMesh(pDevice, xCoordList, domainList, pDevice->pMaterials); /* store the device info in the instance */ inst->NUMDpDevice = pDevice; } /* Now update the state pointers. */ ONEgetStatePointers(inst->NUMDpDevice, states); /* Wipe out statistics from previous runs (if any). */ memset(inst->NUMDpDevice->pStats, 0, sizeof(ONEstats)); inst->NUMDpDevice->pStats->totalTime[STAT_SETUP] += SPfrontEnd->IFseconds() - startTime; /* macro to make elements with built in test for out of memory */ #define TSTALLOC(ptr,first,second) \ do { if ((inst->ptr = SMPmakeElt(matrix, inst->first, inst->second)) == NULL){\ return(E_NOMEM);\ } } while(0) TSTALLOC(NUMDposPosPtr, NUMDposNode, NUMDposNode); TSTALLOC(NUMDnegNegPtr, NUMDnegNode, NUMDnegNode); TSTALLOC(NUMDnegPosPtr, NUMDnegNode, NUMDposNode); TSTALLOC(NUMDposNegPtr, NUMDposNode, NUMDnegNode); } /* Clean up lists */ killCoordInfo(xCoordList); killDomainInfo(domainList); }
/* 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); }
/* ARGSUSED */ int TRAsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *state) /* load the transmission line structure with those pointers needed later * for fast matrix loading */ { TRAmodel *model = (TRAmodel *)inModel; TRAinstance *here; int error; CKTnode *tmp; NG_IGNORE(state); /* loop through all the transmission line models */ for( ; model != NULL; model = model->TRAnextModel ) { /* loop through all the instances of the model */ for (here = model->TRAinstances; here != NULL ; here=here->TRAnextInstance) { if(here->TRAbrEq1==0) { error = CKTmkVolt(ckt,&tmp,here->TRAname,"i1"); if(error) return(error); here->TRAbrEq1 = tmp->number; } if(here->TRAbrEq2==0) { error = CKTmkVolt(ckt,&tmp,here->TRAname,"i2"); if(error) return(error); here->TRAbrEq2 = tmp->number; } if(here->TRAintNode1==0) { error = CKTmkVolt(ckt,&tmp,here->TRAname,"int1"); if(error) return(error); here->TRAintNode1 = tmp->number; } if(here->TRAintNode2==0) { error = CKTmkVolt(ckt,&tmp,here->TRAname,"int2"); if(error) return(error); here->TRAintNode2 = tmp->number; } /* allocate the delay table */ here->TRAdelays = TMALLOC(double, 15); here->TRAallocDelay = 4; /* 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(TRAibr1Ibr2Ptr, TRAbrEq1, TRAbrEq2); TSTALLOC(TRAibr1Int1Ptr, TRAbrEq1, TRAintNode1); TSTALLOC(TRAibr1Neg1Ptr, TRAbrEq1, TRAnegNode1); TSTALLOC(TRAibr1Neg2Ptr, TRAbrEq1, TRAnegNode2); TSTALLOC(TRAibr1Pos2Ptr, TRAbrEq1, TRAposNode2); TSTALLOC(TRAibr2Ibr1Ptr, TRAbrEq2, TRAbrEq1); TSTALLOC(TRAibr2Int2Ptr, TRAbrEq2, TRAintNode2); TSTALLOC(TRAibr2Neg1Ptr, TRAbrEq2, TRAnegNode1); TSTALLOC(TRAibr2Neg2Ptr, TRAbrEq2, TRAnegNode2); TSTALLOC(TRAibr2Pos1Ptr, TRAbrEq2, TRAposNode1); TSTALLOC(TRAint1Ibr1Ptr, TRAintNode1, TRAbrEq1); TSTALLOC(TRAint1Int1Ptr, TRAintNode1, TRAintNode1); TSTALLOC(TRAint1Pos1Ptr, TRAintNode1, TRAposNode1); TSTALLOC(TRAint2Ibr2Ptr, TRAintNode2, TRAbrEq2); TSTALLOC(TRAint2Int2Ptr, TRAintNode2, TRAintNode2); TSTALLOC(TRAint2Pos2Ptr, TRAintNode2, TRAposNode2); TSTALLOC(TRAneg1Ibr1Ptr, TRAnegNode1, TRAbrEq1); TSTALLOC(TRAneg2Ibr2Ptr, TRAnegNode2, TRAbrEq2); TSTALLOC(TRApos1Int1Ptr, TRAposNode1, TRAintNode1); TSTALLOC(TRApos1Pos1Ptr, TRAposNode1, TRAposNode1); TSTALLOC(TRApos2Int2Ptr, TRAposNode2, TRAintNode2); TSTALLOC(TRApos2Pos2Ptr, TRAposNode2, TRAposNode2); if(!here->TRAnlGiven) { here->TRAnl = .25; } if(!here->TRAfGiven) { here->TRAf = 1e9; } if(!here->TRAreltolGiven) { here->TRAreltol = 1; } if(!here->TRAabstolGiven) { here->TRAabstol = 1; } if(!here->TRAimpedGiven) { SPfrontEnd->IFerror (ERR_FATAL, "%s: transmission line z0 must be given", &(here->TRAname)); return(E_BADPARM); } } } return(OK); }
int JFET2setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) /* load the diode structure with those pointers needed later * for fast matrix loading */ { JFET2model *model = (JFET2model*)inModel; JFET2instance *here; int error; CKTnode *tmp; /* loop through all the diode models */ for( ; model != NULL; model = model->JFET2nextModel ) { if( (model->JFET2type != NJF) && (model->JFET2type != PJF) ) { model->JFET2type = NJF; } #define PARAM(code,id,flag,ref,default,descrip) \ if(!model->flag) {model->ref = default;} #include "jfet2parm.h" /* loop through all the instances of the model */ for (here = model->JFET2instances; here != NULL ; here=here->JFET2nextInstance) { if(!here->JFET2areaGiven) { here->JFET2area = 1; } if(!here->JFET2mGiven) { here->JFET2m = 1; } here->JFET2state = *states; *states += JFET2_STATE_COUNT + 1; if(model->JFET2rs != 0) { if(here->JFET2sourcePrimeNode == 0) { error = CKTmkVolt(ckt,&tmp,here->JFET2name,"source"); if(error) return(error); here->JFET2sourcePrimeNode = tmp->number; if (ckt->CKTcopyNodesets) { CKTnode *tmpNode; IFuid tmpName; if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->JFET2sourcePrimeNode = here->JFET2sourceNode; } if(model->JFET2rd != 0) { if(here->JFET2drainPrimeNode == 0) { error = CKTmkVolt(ckt,&tmp,here->JFET2name,"drain"); if(error) return(error); here->JFET2drainPrimeNode = tmp->number; if (ckt->CKTcopyNodesets) { CKTnode *tmpNode; IFuid tmpName; if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->JFET2drainPrimeNode = here->JFET2drainNode; } /* 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(JFET2drainDrainPrimePtr,JFET2drainNode,JFET2drainPrimeNode); TSTALLOC(JFET2gateDrainPrimePtr,JFET2gateNode,JFET2drainPrimeNode); TSTALLOC(JFET2gateSourcePrimePtr,JFET2gateNode,JFET2sourcePrimeNode); TSTALLOC(JFET2sourceSourcePrimePtr,JFET2sourceNode,JFET2sourcePrimeNode); TSTALLOC(JFET2drainPrimeDrainPtr,JFET2drainPrimeNode,JFET2drainNode); TSTALLOC(JFET2drainPrimeGatePtr,JFET2drainPrimeNode,JFET2gateNode); TSTALLOC(JFET2drainPrimeSourcePrimePtr,JFET2drainPrimeNode,JFET2sourcePrimeNode); TSTALLOC(JFET2sourcePrimeGatePtr,JFET2sourcePrimeNode,JFET2gateNode); TSTALLOC(JFET2sourcePrimeSourcePtr,JFET2sourcePrimeNode,JFET2sourceNode); TSTALLOC(JFET2sourcePrimeDrainPrimePtr,JFET2sourcePrimeNode,JFET2drainPrimeNode); TSTALLOC(JFET2drainDrainPtr,JFET2drainNode,JFET2drainNode); TSTALLOC(JFET2gateGatePtr,JFET2gateNode,JFET2gateNode); TSTALLOC(JFET2sourceSourcePtr,JFET2sourceNode,JFET2sourceNode); TSTALLOC(JFET2drainPrimeDrainPrimePtr,JFET2drainPrimeNode,JFET2drainPrimeNode); TSTALLOC(JFET2sourcePrimeSourcePrimePtr,JFET2sourcePrimeNode,JFET2sourcePrimeNode); } } return(OK); }
int LTRAsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *state) /* * load the transmission line structure with those pointers needed later for * fast matrix loading */ { LTRAmodel *model = (LTRAmodel *) inModel; LTRAinstance *here; int error; CKTnode *tmp; NG_IGNORE(state); /* loop through all the transmission line models */ for (; model != NULL; model = model->LTRAnextModel) { if (!model->LTRAnlGiven) { model->LTRAnl = .25; } if (!model->LTRAfGiven) { model->LTRAf = 1e9; } if (!model->LTRAreltolGiven) { model->LTRAreltol = 1; } if (!model->LTRAabstolGiven) { model->LTRAabstol = 1; } if (!model->LTRAresistGiven) { SPfrontEnd->IFerror (ERR_WARNING, "%s: lossy line series resistance not given, assumed zero", &(model->LTRAmodName)); model->LTRAresist = 0.0; /* return(E_BADPARM); */ } if (model->LTRAstLineReltol == 0.0) model->LTRAstLineReltol = ckt->CKTreltol; if (model->LTRAstLineAbstol == 0.0) model->LTRAstLineAbstol = ckt->CKTabstol; /* LTRAchopReltol and LTRAchopAbstol default zero */ if ((model->LTRAhowToInterp != LTRA_MOD_LININTERP) && (model->LTRAhowToInterp != LTRA_MOD_QUADINTERP) && (model->LTRAhowToInterp != LTRA_MOD_MIXEDINTERP)) { /* * SPfrontEnd->IFerror (ERR_FATAL, "%s: have to specify one of * lininterp, quadinterp or mixedinterp", &(model->LTRAmodName)); * return(E_BADPARM); */ if (ckt->CKTtryToCompact) { model->LTRAhowToInterp = LTRA_MOD_LININTERP; SPfrontEnd->IFerror (ERR_WARNING, "%s: using linear interpolation because trytocompact option specified", &(model->LTRAmodName)); } else { model->LTRAhowToInterp = LTRA_MOD_QUADINTERP; } } if ((model->LTRAstepLimit != LTRA_MOD_NOSTEPLIMIT)) model->LTRAstepLimit = LTRA_MOD_STEPLIMIT; if ((model->LTRAlteConType != LTRA_MOD_FULLCONTROL) && (model->LTRAlteConType != LTRA_MOD_HALFCONTROL)) model->LTRAlteConType = LTRA_MOD_NOCONTROL; if (!model->LTRAconductGiven) { /* * SPfrontEnd->IFerror (ERR_WARNING, "%s: lossy line parallel * conductance not given, assumed zero", &(model->LTRAmodName)); */ model->LTRAconduct = 0.0; /* return(E_BADPARM); */ } if (!model->LTRAinductGiven) { SPfrontEnd->IFerror (ERR_WARNING, "%s: lossy line series inductance not given, assumed zero", &(model->LTRAmodName)); model->LTRAinduct = 0.0; /* return(E_BADPARM); */ } if (!model->LTRAcapacGiven) { SPfrontEnd->IFerror (ERR_FATAL, "%s: lossy line parallel capacitance not given, assumed zero", &(model->LTRAmodName)); model->LTRAcapac = 0.0; /* return(E_BADPARM); */ } if (!model->LTRAlengthGiven) { SPfrontEnd->IFerror (ERR_FATAL, "%s: lossy line length must be given", &(model->LTRAmodName)); return (E_BADPARM); } if ((model->LTRAresist == 0) && (model->LTRAconduct == 0) && (model->LTRAcapac != 0) && (model->LTRAinduct != 0)) { model->LTRAspecialCase = LTRA_MOD_LC; #ifdef LTRADEBUG SPfrontEnd->IFerror (ERR_INFO, "%s: lossless line", &(model->LTRAmodName)); #endif } if ((model->LTRAresist != 0) && (model->LTRAconduct == 0) && (model->LTRAcapac != 0) && (model->LTRAinduct != 0)) { model->LTRAspecialCase = LTRA_MOD_RLC; #ifdef LTRADEBUG SPfrontEnd->IFerror (ERR_INFO, "%s: RLC line", &(model->LTRAmodName)); #endif } if ((model->LTRAresist != 0) && (model->LTRAconduct == 0) && (model->LTRAcapac != 0) && (model->LTRAinduct == 0)) { model->LTRAspecialCase = LTRA_MOD_RC; #ifdef LTRADEBUG SPfrontEnd->IFerror (ERR_INFO, "%s: RC line", &(model->LTRAmodName)); #endif } if ((model->LTRAresist != 0) && (model->LTRAconduct == 0) && (model->LTRAcapac == 0) && (model->LTRAinduct != 0)) { model->LTRAspecialCase = LTRA_MOD_RL; SPfrontEnd->IFerror (ERR_FATAL, "%s: RL line not supported yet", &(model->LTRAmodName)); return (E_BADPARM); #ifdef LTRADEBUG #endif } if ((model->LTRAresist != 0) && (model->LTRAconduct != 0) && (model->LTRAcapac == 0) && (model->LTRAinduct == 0)) { model->LTRAspecialCase = LTRA_MOD_RG; #ifdef LTRADEBUG SPfrontEnd->IFerror (ERR_INFO, "%s: RG line", &(model->LTRAmodName)); #endif } if ((model->LTRAconduct != 0) && ((model->LTRAcapac != 0) || (model->LTRAinduct != 0))) { model->LTRAspecialCase = LTRA_MOD_LTRA; SPfrontEnd->IFerror (ERR_FATAL, "%s: Nonzero G (except RG) line not supported yet", &(model->LTRAmodName)); return (E_BADPARM); #ifdef LTRADEBUG #endif } if ((model->LTRAresist == 0.0 ? 0 : 1) + (model->LTRAconduct == 0.0 ? 0 : 1) + (model->LTRAinduct == 0.0 ? 0 : 1) + (model->LTRAcapac == 0.0 ? 0 : 1) <= 1) { SPfrontEnd->IFerror (ERR_FATAL, "%s: At least two of R,L,G,C must be specified and nonzero", &(model->LTRAmodName)); return (E_BADPARM); } /* loop through all the instances of the model */ for (here = model->LTRAinstances; here != NULL; here = here->LTRAnextInstance) { if (here->LTRAbrEq1 == 0) { error = CKTmkVolt(ckt, &tmp, here->LTRAname, "i1"); if (error) return (error); here->LTRAbrEq1 = tmp->number; } if (here->LTRAbrEq2 == 0) { error = CKTmkVolt(ckt, &tmp, here->LTRAname, "i2"); if (error) return (error); here->LTRAbrEq2 = 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(LTRAibr1Pos1Ptr, LTRAbrEq1, LTRAposNode1); TSTALLOC(LTRAibr1Neg1Ptr, LTRAbrEq1, LTRAnegNode1); TSTALLOC(LTRAibr1Pos2Ptr, LTRAbrEq1, LTRAposNode2); TSTALLOC(LTRAibr1Neg2Ptr, LTRAbrEq1, LTRAnegNode2); TSTALLOC(LTRAibr1Ibr1Ptr, LTRAbrEq1, LTRAbrEq1); TSTALLOC(LTRAibr1Ibr2Ptr, LTRAbrEq1, LTRAbrEq2); TSTALLOC(LTRAibr2Pos1Ptr, LTRAbrEq2, LTRAposNode1); TSTALLOC(LTRAibr2Neg1Ptr, LTRAbrEq2, LTRAnegNode1); TSTALLOC(LTRAibr2Pos2Ptr, LTRAbrEq2, LTRAposNode2); TSTALLOC(LTRAibr2Neg2Ptr, LTRAbrEq2, LTRAnegNode2); TSTALLOC(LTRAibr2Ibr1Ptr, LTRAbrEq2, LTRAbrEq1); TSTALLOC(LTRAibr2Ibr2Ptr, LTRAbrEq2, LTRAbrEq2); TSTALLOC(LTRApos1Ibr1Ptr, LTRAposNode1, LTRAbrEq1); TSTALLOC(LTRAneg1Ibr1Ptr, LTRAnegNode1, LTRAbrEq1); TSTALLOC(LTRApos2Ibr2Ptr, LTRAposNode2, LTRAbrEq2); TSTALLOC(LTRAneg2Ibr2Ptr, LTRAnegNode2, LTRAbrEq2); /* * the following are done so that SMPpreOrder does not screw up on * occasion - for example, when one end of the lossy line is hanging */ TSTALLOC(LTRApos1Pos1Ptr, LTRAposNode1, LTRAposNode1); TSTALLOC(LTRAneg1Neg1Ptr, LTRAnegNode1, LTRAnegNode1); TSTALLOC(LTRApos2Pos2Ptr, LTRAposNode2, LTRAposNode2); TSTALLOC(LTRAneg2Neg2Ptr, LTRAnegNode2, LTRAnegNode2); } } return (OK); }
int HFET2setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) { HFET2model *model = (HFET2model*)inModel; HFET2instance *here; int error; CKTnode *tmp; for( ; model != NULL; model = model->HFET2nextModel ) { if((TYPE != NHFET) && (TYPE != PHFET) ) TYPE = NHFET; if(!model->HFET2cfGiven) CF = 0; if(!model->HFET2d1Given) D1 = 0.03e-6; if(!model->HFET2d2Given) D2 = 0.2e-6; if(!model->HFET2delGiven) DEL = 0.04; if(!model->HFET2deltaGiven) DELTA = 3.0; if(!model->HFET2deltadGiven) DELTAD = 4.5e-9; if(!model->HFET2diGiven) DI = 0.04e-6; if(!model->HFET2epsiGiven) EPSI = 12.244*8.85418e-12; if(!model->HFET2etaGiven) { if(TYPE == NHFET) ETA = 1.28; else ETA = 1.4; } if(!model->HFET2eta1Given) ETA1 = 2; if(!model->HFET2eta2Given) ETA2 = 2; if(!model->HFET2gammaGiven) GAMMA = 3.0; if(!model->HFET2ggrGiven) GGR = 0; if(!model->HFET2jsGiven) JS = 0; if(!model->HFET2klambdaGiven) KLAMBDA = 0; if(!model->HFET2kmuGiven) KMU = 0; if(!model->HFET2knmaxGiven) KNMAX = 0; if(!model->HFET2kvtoGiven) KVTO = 0; if(!model->HFET2lambdaGiven) LAMBDA = 0.15; if(!model->HFET2mGiven) M = 3.0; if(!model->HFET2mcGiven) MC = 3.0; if(!model->HFET2muGiven) { if(TYPE == NHFET) MU = 0.4; else MU = 0.03; } if(!model->HFET2nGiven) N = 5.0; if(!model->HFET2nmaxGiven) NMAX = 2e16; if(!model->HFET2pGiven) PP = 1; if(!model->HFET2rdGiven) RD = 0; if(!model->HFET2rdiGiven) RDI = 0; if(!model->HFET2rsGiven) RS = 0; if(!model->HFET2rsiGiven) RSI = 0; if(!model->HFET2sigma0Given) SIGMA0 = 0.057; if(!model->HFET2vsGiven) { if(TYPE == NHFET) VS = 1.5e5; else VS = 0.8e5; } if(!model->HFET2vsigmaGiven) VSIGMA = 0.1; if(!model->HFET2vsigmatGiven) VSIGMAT = 0.3; if(!model->HFET2vt1Given) /* initialized in HFET2temp */ HFET2_VT1 = 0; if(!model->HFET2vt2Given) /* initialized in HFET2temp */ VT2 = 0; if(!model->HFET2vtoGiven) { if(model->HFET2type == NHFET) VTO = 0.15; else VTO = -0.15; } /* loop through all the instances of the model */ for (here = model->HFET2instances; here != NULL; here=here->HFET2nextInstance) { CKTnode *tmpNode; IFuid tmpName; here->HFET2state = *states; *states += 13; if(!here->HFET2lengthGiven) L = 1e-6; if(!here->HFET2widthGiven) W = 20e-6; if(!here->HFET2mGiven) here->HFET2m = 1.0; if(model->HFET2rs != 0) { if(here->HFET2sourcePrimeNode == 0) { error = CKTmkVolt(ckt,&tmp,here->HFET2name,"source"); if(error) return(error); here->HFET2sourcePrimeNode = tmp->number; if (ckt->CKTcopyNodesets) { if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->HFET2sourcePrimeNode = here->HFET2sourceNode; } if(model->HFET2rd != 0) { if(here->HFET2drainPrimeNode == 0) { error = CKTmkVolt(ckt,&tmp,here->HFET2name,"drain"); if(error) return(error); here->HFET2drainPrimeNode = tmp->number; if (ckt->CKTcopyNodesets) { if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->HFET2drainPrimeNode = here->HFET2drainNode; } /* 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(HFET2drainDrainPrimePtr,HFET2drainNode,HFET2drainPrimeNode); TSTALLOC(HFET2gateDrainPrimePtr,HFET2gateNode,HFET2drainPrimeNode); TSTALLOC(HFET2gateSourcePrimePtr,HFET2gateNode,HFET2sourcePrimeNode); TSTALLOC(HFET2sourceSourcePrimePtr,HFET2sourceNode,HFET2sourcePrimeNode); TSTALLOC(HFET2drainPrimeDrainPtr,HFET2drainPrimeNode,HFET2drainNode); TSTALLOC(HFET2drainPrimeGatePtr,HFET2drainPrimeNode,HFET2gateNode); TSTALLOC(HFET2drainPriHFET2ourcePrimePtr,HFET2drainPrimeNode,HFET2sourcePrimeNode); TSTALLOC(HFET2sourcePrimeGatePtr,HFET2sourcePrimeNode,HFET2gateNode); TSTALLOC(HFET2sourcePriHFET2ourcePtr,HFET2sourcePrimeNode,HFET2sourceNode); TSTALLOC(HFET2sourcePrimeDrainPrimePtr,HFET2sourcePrimeNode,HFET2drainPrimeNode); TSTALLOC(HFET2drainDrainPtr,HFET2drainNode,HFET2drainNode); TSTALLOC(HFET2gateGatePtr,HFET2gateNode,HFET2gateNode); TSTALLOC(HFET2sourceSourcePtr,HFET2sourceNode,HFET2sourceNode); TSTALLOC(HFET2drainPrimeDrainPrimePtr,HFET2drainPrimeNode,HFET2drainPrimeNode); TSTALLOC(HFET2sourcePriHFET2ourcePrimePtr,HFET2sourcePrimeNode,HFET2sourcePrimeNode); } } return(OK); }
int NBJT2setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) /* * load the structure with those pointers needed later for fast matrix * loading */ { register NBJT2model *model = (NBJT2model *) inModel; register NBJT2instance *inst; METHcard *methods; MODLcard *models; OPTNcard *options; OUTPcard *outputs; int error, xIndex; int xMeshSize, yMeshSize; TWOdevice *pDevice; TWOcoord *xCoordList = NULL; TWOcoord *yCoordList = NULL; TWOdomain *domainList = NULL; TWOelectrode *electrodeList = NULL; TWOmaterial *pM, *pMaterial = NULL, *materialList = NULL; DOPprofile *profileList = NULL; DOPtable *dopTableList = NULL; double startTime; /* loop through all the models */ for (; model != NULL; model = model->NBJT2nextModel) { if (!model->NBJT2pInfo) { TSCALLOC(model->NBJT2pInfo, 1, TWOtranInfo); } methods = model->NBJT2methods; if (!methods) { TSCALLOC(methods, 1, METHcard); model->NBJT2methods = methods; } models = model->NBJT2models; if (!models) { TSCALLOC(models, 1, MODLcard); model->NBJT2models = models; } options = model->NBJT2options; if (!options) { TSCALLOC(options, 1, OPTNcard); model->NBJT2options = options; } outputs = model->NBJT2outputs; if (!outputs) { TSCALLOC(outputs, 1, OUTPcard); model->NBJT2outputs = outputs; } if (!methods->METHvoltPredGiven) { methods->METHvoltPred = FALSE; } if (!methods->METHmobDerivGiven) { methods->METHmobDeriv = TRUE; } if (!methods->METHoneCarrierGiven) { methods->METHoneCarrier = FALSE; } if (!methods->METHacAnalysisMethodGiven) { methods->METHacAnalysisMethod = SOR; } if (!methods->METHdabstolGiven) { methods->METHdabstol = DABSTOL2D; } if (!methods->METHdreltolGiven) { methods->METHdreltol = ckt->CKTreltol; } if (!methods->METHitLimGiven) { methods->METHitLim = 50; } if (!methods->METHomegaGiven || methods->METHomega <= 0.0) { methods->METHomega = 2.0 * M_PI /* radians/sec */ ; } if (!options->OPTNdefaGiven || options->OPTNdefa <= 0.0) { options->OPTNdefa = 1.0e4 /* cm^2 */ ; } if (!options->OPTNdeflGiven || options->OPTNdefl <= 0.0) { options->OPTNdefl = 1.0e2 /* cm */ ; } if (!options->OPTNdefwGiven && options->OPTNdefaGiven) { options->OPTNdefw = options->OPTNdefa / options->OPTNdefl; } else if (!options->OPTNdefwGiven || options->OPTNdefw <= 0.0) { options->OPTNdefw = 1.0e2 /* cm */ ; } if (!options->OPTNdeviceTypeGiven) { options->OPTNdeviceType = OPTN_BIPOLAR; } if (!options->OPTNicFileGiven) { options->OPTNicFile = NULL; options->OPTNunique = FALSE; /* Can't form a unique name. */ } if (!options->OPTNuniqueGiven) { options->OPTNunique = FALSE; } OneCarrier = methods->METHoneCarrier; /* Set up the rest of the card lists */ if ((error = MODLsetup(model->NBJT2models)) != 0) return (error); BandGapNarrowing = models->MODLbandGapNarrowing; ConcDepLifetime = models->MODLconcDepLifetime; TempDepMobility = models->MODLtempDepMobility; ConcDepMobility = models->MODLconcDepMobility; SurfaceMobility = models->MODLsurfaceMobility; if ((error = OUTPsetup(model->NBJT2outputs)) != 0) return (error); if ((error = MATLsetup(model->NBJT2materials, &materialList)) != 0) return (error); if ((error = MOBsetup(model->NBJT2mobility, materialList)) != 0) return (error); if ((error = MESHsetup('x', model->NBJT2xMeshes, &xCoordList, &xMeshSize)) != 0) return (error); if ((error = MESHsetup('y', model->NBJT2yMeshes, &yCoordList, &yMeshSize)) != 0) return (error); if ((error = DOMNsetup(model->NBJT2domains, &domainList, xCoordList, yCoordList, materialList)) != 0) return (error); if ((error = BDRYsetup(model->NBJT2boundaries, xCoordList, yCoordList, domainList)) != 0) return (error); if ((error = ELCTsetup(model->NBJT2electrodes, &electrodeList, xCoordList, yCoordList)) != 0) return (error); /* Make sure electrodes are OK. */ checkElectrodes(electrodeList, 3); /* NBJT2 has 3 electrodes */ if ((error = CONTsetup(model->NBJT2contacts, electrodeList)) != 0) return (error); if ((error = DOPsetup(model->NBJT2dopings, &profileList, &dopTableList, xCoordList, yCoordList)) != 0) return (error); model->NBJT2matlInfo = materialList; model->NBJT2profiles = profileList; model->NBJT2dopTables = dopTableList; /* loop through all the instances of the model */ for (inst = model->NBJT2instances; inst != NULL; inst = inst->NBJT2nextInstance) { startTime = SPfrontEnd->IFseconds(); if (!inst->NBJT2printGiven) { inst->NBJT2print = 0; } else if (inst->NBJT2print <= 0) { inst->NBJT2print = 1; } if (!inst->NBJT2icFileGiven) { if (options->OPTNunique) { inst->NBJT2icFile = tprintf("%s.%s", options->OPTNicFile, inst->NBJT2name); } else if (options->OPTNicFile != NULL) { inst->NBJT2icFile = tprintf("%s", options->OPTNicFile); } else { inst->NBJT2icFile = NULL; } } inst->NBJT2state = *states; *states += NBJT2numStates; if (!inst->NBJT2pDevice) { /* Assign the mesh and profile info to each instance. */ TSCALLOC(pDevice, 1, TWOdevice); TSCALLOC(pDevice->pStats, 1, TWOstats); pDevice->name = inst->NBJT2name; pDevice->solverType = SLV_NONE; pDevice->numXNodes = xMeshSize; pDevice->numYNodes = yMeshSize; pDevice->xScale = MESHmkArray(xCoordList, xMeshSize); pDevice->yScale = MESHmkArray(yCoordList, yMeshSize); pDevice->abstol = methods->METHdabstol; pDevice->reltol = methods->METHdreltol; pDevice->rhsImag = NULL; TSCALLOC(pDevice->elemArray, pDevice->numXNodes, TWOelem **); for (xIndex = 1; xIndex < pDevice->numXNodes; xIndex++) { TSCALLOC(pDevice->elemArray[xIndex], pDevice->numYNodes, TWOelem *); } /* Create a copy of material data that can change with temperature. */ pDevice->pMaterials = NULL; for (pM = materialList; pM != NULL; pM = pM->next) { if (pDevice->pMaterials == NULL) { TSCALLOC(pMaterial, 1, TWOmaterial); pDevice->pMaterials = pMaterial; } else { TSCALLOC(pMaterial->next, 1, TWOmaterial); pMaterial = pMaterial->next; } /* Copy everything, then fix the incorrect pointer. */ bcopy(pM, pMaterial, sizeof(TWOmaterial)); pMaterial->next = NULL; } /* Generate the mesh structure for the device. */ TWObuildMesh(pDevice, domainList, electrodeList, pDevice->pMaterials); /* Store the device info in the instance. */ inst->NBJT2pDevice = pDevice; } /* Now update the state pointers. */ TWOgetStatePointers(inst->NBJT2pDevice, states); /* Wipe out statistics from previous runs (if any). */ bzero(inst->NBJT2pDevice->pStats, sizeof(TWOstats)); inst->NBJT2pDevice->pStats->totalTime[STAT_SETUP] += SPfrontEnd->IFseconds() - startTime; /* macro to make elements with built in test for out of memory */ #define TSTALLOC(ptr,first,second) \ do { if ((inst->ptr = SMPmakeElt(matrix, inst->first, inst->second)) == NULL){\ return(E_NOMEM);\ } } while(0) TSTALLOC(NBJT2colColPtr, NBJT2colNode, NBJT2colNode); TSTALLOC(NBJT2colBasePtr, NBJT2colNode, NBJT2baseNode); TSTALLOC(NBJT2colEmitPtr, NBJT2colNode, NBJT2emitNode); TSTALLOC(NBJT2baseColPtr, NBJT2baseNode, NBJT2colNode); TSTALLOC(NBJT2baseBasePtr, NBJT2baseNode, NBJT2baseNode); TSTALLOC(NBJT2baseEmitPtr, NBJT2baseNode, NBJT2emitNode); TSTALLOC(NBJT2emitColPtr, NBJT2emitNode, NBJT2colNode); TSTALLOC(NBJT2emitBasePtr, NBJT2emitNode, NBJT2baseNode); TSTALLOC(NBJT2emitEmitPtr, NBJT2emitNode, NBJT2emitNode); } /* Clean up lists */ killCoordInfo(xCoordList); killCoordInfo(yCoordList); killDomainInfo(domainList); killElectrodeInfo(electrodeList); }
int BSIM3setup( SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) { BSIM3model *model = (BSIM3model*)inModel; BSIM3instance *here; int error; CKTnode *tmp; CKTnode *tmpNode; IFuid tmpName; #ifdef USE_OMP int idx, InstCount; BSIM3instance **InstArray; #endif /* loop through all the BSIM3 device models */ for( ; model != NULL; model = BSIM3nextModel(model)) { /* Default value Processing for BSIM3 MOSFET Models */ if (!model->BSIM3typeGiven) model->BSIM3type = NMOS; if (!model->BSIM3mobModGiven) model->BSIM3mobMod = 1; if (!model->BSIM3binUnitGiven) model->BSIM3binUnit = 1; if (!model->BSIM3paramChkGiven) model->BSIM3paramChk = 0; if (!model->BSIM3capModGiven) model->BSIM3capMod = 3; if (!model->BSIM3acmModGiven) model->BSIM3acmMod = 0; if (!model->BSIM3calcacmGiven) model->BSIM3calcacm = 0; if (!model->BSIM3noiModGiven) model->BSIM3noiMod = 1; if (!model->BSIM3nqsModGiven) model->BSIM3nqsMod = 0; else if ((model->BSIM3nqsMod != 0) && (model->BSIM3nqsMod != 1)) { model->BSIM3nqsMod = 0; printf("Warning: nqsMod has been set to its default value: 0.\n"); } if (!model->BSIM3acnqsModGiven) model->BSIM3acnqsMod = 0; else if ((model->BSIM3acnqsMod != 0) && (model->BSIM3acnqsMod != 1)) { model->BSIM3acnqsMod = 0; printf("Warning: acnqsMod has been set to its default value: 0.\n"); } if (!model->BSIM3versionGiven) model->BSIM3version = copy("3.3.0"); if (!model->BSIM3toxGiven) model->BSIM3tox = 150.0e-10; model->BSIM3cox = 3.453133e-11 / model->BSIM3tox; if (!model->BSIM3toxmGiven) model->BSIM3toxm = model->BSIM3tox; if (!model->BSIM3cdscGiven) model->BSIM3cdsc = 2.4e-4; /* unit Q/V/m^2 */ if (!model->BSIM3cdscbGiven) model->BSIM3cdscb = 0.0; /* unit Q/V/m^2 */ if (!model->BSIM3cdscdGiven) model->BSIM3cdscd = 0.0; /* unit Q/V/m^2 */ if (!model->BSIM3citGiven) model->BSIM3cit = 0.0; /* unit Q/V/m^2 */ if (!model->BSIM3nfactorGiven) model->BSIM3nfactor = 1; if (!model->BSIM3xjGiven) model->BSIM3xj = .15e-6; if (!model->BSIM3vsatGiven) model->BSIM3vsat = 8.0e4; /* unit m/s */ if (!model->BSIM3atGiven) model->BSIM3at = 3.3e4; /* unit m/s */ if (!model->BSIM3a0Given) model->BSIM3a0 = 1.0; if (!model->BSIM3agsGiven) model->BSIM3ags = 0.0; if (!model->BSIM3a1Given) model->BSIM3a1 = 0.0; if (!model->BSIM3a2Given) model->BSIM3a2 = 1.0; if (!model->BSIM3ketaGiven) model->BSIM3keta = -0.047; /* unit / V */ if (!model->BSIM3nsubGiven) model->BSIM3nsub = 6.0e16; /* unit 1/cm3 */ if (!model->BSIM3npeakGiven) model->BSIM3npeak = 1.7e17; /* unit 1/cm3 */ if (!model->BSIM3ngateGiven) model->BSIM3ngate = 0; /* unit 1/cm3 */ if (!model->BSIM3vbmGiven) model->BSIM3vbm = -3.0; if (!model->BSIM3xtGiven) model->BSIM3xt = 1.55e-7; if (!model->BSIM3kt1Given) model->BSIM3kt1 = -0.11; /* unit V */ if (!model->BSIM3kt1lGiven) model->BSIM3kt1l = 0.0; /* unit V*m */ if (!model->BSIM3kt2Given) model->BSIM3kt2 = 0.022; /* No unit */ if (!model->BSIM3k3Given) model->BSIM3k3 = 80.0; if (!model->BSIM3k3bGiven) model->BSIM3k3b = 0.0; if (!model->BSIM3w0Given) model->BSIM3w0 = 2.5e-6; if (!model->BSIM3nlxGiven) model->BSIM3nlx = 1.74e-7; if (!model->BSIM3dvt0Given) model->BSIM3dvt0 = 2.2; if (!model->BSIM3dvt1Given) model->BSIM3dvt1 = 0.53; if (!model->BSIM3dvt2Given) model->BSIM3dvt2 = -0.032; /* unit 1 / V */ if (!model->BSIM3dvt0wGiven) model->BSIM3dvt0w = 0.0; if (!model->BSIM3dvt1wGiven) model->BSIM3dvt1w = 5.3e6; if (!model->BSIM3dvt2wGiven) model->BSIM3dvt2w = -0.032; if (!model->BSIM3droutGiven) model->BSIM3drout = 0.56; if (!model->BSIM3dsubGiven) model->BSIM3dsub = model->BSIM3drout; if (!model->BSIM3vth0Given) model->BSIM3vth0 = (model->BSIM3type == NMOS) ? 0.7 : -0.7; if (!model->BSIM3uaGiven) model->BSIM3ua = 2.25e-9; /* unit m/V */ if (!model->BSIM3ua1Given) model->BSIM3ua1 = 4.31e-9; /* unit m/V */ if (!model->BSIM3ubGiven) model->BSIM3ub = 5.87e-19; /* unit (m/V)**2 */ if (!model->BSIM3ub1Given) model->BSIM3ub1 = -7.61e-18; /* unit (m/V)**2 */ if (!model->BSIM3ucGiven) model->BSIM3uc = (model->BSIM3mobMod == 3) ? -0.0465 : -0.0465e-9; if (!model->BSIM3uc1Given) model->BSIM3uc1 = (model->BSIM3mobMod == 3) ? -0.056 : -0.056e-9; if (!model->BSIM3u0Given) model->BSIM3u0 = (model->BSIM3type == NMOS) ? 0.067 : 0.025; if (!model->BSIM3uteGiven) model->BSIM3ute = -1.5; if (!model->BSIM3voffGiven) model->BSIM3voff = -0.08; if (!model->BSIM3deltaGiven) model->BSIM3delta = 0.01; if (!model->BSIM3rdswGiven) model->BSIM3rdsw = 0; if (!model->BSIM3prwgGiven) model->BSIM3prwg = 0.0; /* unit 1/V */ if (!model->BSIM3prwbGiven) model->BSIM3prwb = 0.0; if (!model->BSIM3prtGiven) model->BSIM3prt = 0.0; if (!model->BSIM3eta0Given) model->BSIM3eta0 = 0.08; /* no unit */ if (!model->BSIM3etabGiven) model->BSIM3etab = -0.07; /* unit 1/V */ if (!model->BSIM3pclmGiven) model->BSIM3pclm = 1.3; /* no unit */ if (!model->BSIM3pdibl1Given) model->BSIM3pdibl1 = .39; /* no unit */ if (!model->BSIM3pdibl2Given) model->BSIM3pdibl2 = 0.0086; /* no unit */ if (!model->BSIM3pdiblbGiven) model->BSIM3pdiblb = 0.0; /* 1/V */ if (!model->BSIM3pscbe1Given) model->BSIM3pscbe1 = 4.24e8; if (!model->BSIM3pscbe2Given) model->BSIM3pscbe2 = 1.0e-5; if (!model->BSIM3pvagGiven) model->BSIM3pvag = 0.0; if (!model->BSIM3wrGiven) model->BSIM3wr = 1.0; if (!model->BSIM3dwgGiven) model->BSIM3dwg = 0.0; if (!model->BSIM3dwbGiven) model->BSIM3dwb = 0.0; if (!model->BSIM3b0Given) model->BSIM3b0 = 0.0; if (!model->BSIM3b1Given) model->BSIM3b1 = 0.0; if (!model->BSIM3alpha0Given) model->BSIM3alpha0 = 0.0; if (!model->BSIM3alpha1Given) model->BSIM3alpha1 = 0.0; if (!model->BSIM3beta0Given) model->BSIM3beta0 = 30.0; if (!model->BSIM3ijthGiven) model->BSIM3ijth = 0.1; /* unit A */ if (!model->BSIM3elmGiven) model->BSIM3elm = 5.0; if (!model->BSIM3cgslGiven) model->BSIM3cgsl = 0.0; if (!model->BSIM3cgdlGiven) model->BSIM3cgdl = 0.0; if (!model->BSIM3ckappaGiven) model->BSIM3ckappa = 0.6; if (!model->BSIM3clcGiven) model->BSIM3clc = 0.1e-6; if (!model->BSIM3cleGiven) model->BSIM3cle = 0.6; if (!model->BSIM3vfbcvGiven) model->BSIM3vfbcv = -1.0; if (!model->BSIM3acdeGiven) model->BSIM3acde = 1.0; if (!model->BSIM3moinGiven) model->BSIM3moin = 15.0; if (!model->BSIM3noffGiven) model->BSIM3noff = 1.0; if (!model->BSIM3voffcvGiven) model->BSIM3voffcv = 0.0; if (!model->BSIM3tcjGiven) model->BSIM3tcj = 0.0; if (!model->BSIM3tpbGiven) model->BSIM3tpb = 0.0; if (!model->BSIM3tcjswGiven) model->BSIM3tcjsw = 0.0; if (!model->BSIM3tpbswGiven) model->BSIM3tpbsw = 0.0; if (!model->BSIM3tcjswgGiven) model->BSIM3tcjswg = 0.0; if (!model->BSIM3tpbswgGiven) model->BSIM3tpbswg = 0.0; /* ACM model */ if (!model->BSIM3hdifGiven) model->BSIM3hdif = 0.0; if (!model->BSIM3ldifGiven) model->BSIM3ldif = 0.0; if (!model->BSIM3ldGiven) model->BSIM3ld = 0.0; if (!model->BSIM3rdGiven) model->BSIM3rd = 0.0; if (!model->BSIM3rsGiven) model->BSIM3rs = 0.0; if (!model->BSIM3rdcGiven) model->BSIM3rdc = 0.0; if (!model->BSIM3rscGiven) model->BSIM3rsc = 0.0; if (!model->BSIM3wmltGiven) model->BSIM3wmlt = 1.0; /* Length dependence */ if (!model->BSIM3lcdscGiven) model->BSIM3lcdsc = 0.0; if (!model->BSIM3lcdscbGiven) model->BSIM3lcdscb = 0.0; if (!model->BSIM3lcdscdGiven) model->BSIM3lcdscd = 0.0; if (!model->BSIM3lcitGiven) model->BSIM3lcit = 0.0; if (!model->BSIM3lnfactorGiven) model->BSIM3lnfactor = 0.0; if (!model->BSIM3lxjGiven) model->BSIM3lxj = 0.0; if (!model->BSIM3lvsatGiven) model->BSIM3lvsat = 0.0; if (!model->BSIM3latGiven) model->BSIM3lat = 0.0; if (!model->BSIM3la0Given) model->BSIM3la0 = 0.0; if (!model->BSIM3lagsGiven) model->BSIM3lags = 0.0; if (!model->BSIM3la1Given) model->BSIM3la1 = 0.0; if (!model->BSIM3la2Given) model->BSIM3la2 = 0.0; if (!model->BSIM3lketaGiven) model->BSIM3lketa = 0.0; if (!model->BSIM3lnsubGiven) model->BSIM3lnsub = 0.0; if (!model->BSIM3lnpeakGiven) model->BSIM3lnpeak = 0.0; if (!model->BSIM3lngateGiven) model->BSIM3lngate = 0.0; if (!model->BSIM3lvbmGiven) model->BSIM3lvbm = 0.0; if (!model->BSIM3lxtGiven) model->BSIM3lxt = 0.0; if (!model->BSIM3lkt1Given) model->BSIM3lkt1 = 0.0; if (!model->BSIM3lkt1lGiven) model->BSIM3lkt1l = 0.0; if (!model->BSIM3lkt2Given) model->BSIM3lkt2 = 0.0; if (!model->BSIM3lk3Given) model->BSIM3lk3 = 0.0; if (!model->BSIM3lk3bGiven) model->BSIM3lk3b = 0.0; if (!model->BSIM3lw0Given) model->BSIM3lw0 = 0.0; if (!model->BSIM3lnlxGiven) model->BSIM3lnlx = 0.0; if (!model->BSIM3ldvt0Given) model->BSIM3ldvt0 = 0.0; if (!model->BSIM3ldvt1Given) model->BSIM3ldvt1 = 0.0; if (!model->BSIM3ldvt2Given) model->BSIM3ldvt2 = 0.0; if (!model->BSIM3ldvt0wGiven) model->BSIM3ldvt0w = 0.0; if (!model->BSIM3ldvt1wGiven) model->BSIM3ldvt1w = 0.0; if (!model->BSIM3ldvt2wGiven) model->BSIM3ldvt2w = 0.0; if (!model->BSIM3ldroutGiven) model->BSIM3ldrout = 0.0; if (!model->BSIM3ldsubGiven) model->BSIM3ldsub = 0.0; if (!model->BSIM3lvth0Given) model->BSIM3lvth0 = 0.0; if (!model->BSIM3luaGiven) model->BSIM3lua = 0.0; if (!model->BSIM3lua1Given) model->BSIM3lua1 = 0.0; if (!model->BSIM3lubGiven) model->BSIM3lub = 0.0; if (!model->BSIM3lub1Given) model->BSIM3lub1 = 0.0; if (!model->BSIM3lucGiven) model->BSIM3luc = 0.0; if (!model->BSIM3luc1Given) model->BSIM3luc1 = 0.0; if (!model->BSIM3lu0Given) model->BSIM3lu0 = 0.0; if (!model->BSIM3luteGiven) model->BSIM3lute = 0.0; if (!model->BSIM3lvoffGiven) model->BSIM3lvoff = 0.0; if (!model->BSIM3ldeltaGiven) model->BSIM3ldelta = 0.0; if (!model->BSIM3lrdswGiven) model->BSIM3lrdsw = 0.0; if (!model->BSIM3lprwbGiven) model->BSIM3lprwb = 0.0; if (!model->BSIM3lprwgGiven) model->BSIM3lprwg = 0.0; if (!model->BSIM3lprtGiven) model->BSIM3lprt = 0.0; if (!model->BSIM3leta0Given) model->BSIM3leta0 = 0.0; if (!model->BSIM3letabGiven) model->BSIM3letab = -0.0; if (!model->BSIM3lpclmGiven) model->BSIM3lpclm = 0.0; if (!model->BSIM3lpdibl1Given) model->BSIM3lpdibl1 = 0.0; if (!model->BSIM3lpdibl2Given) model->BSIM3lpdibl2 = 0.0; if (!model->BSIM3lpdiblbGiven) model->BSIM3lpdiblb = 0.0; if (!model->BSIM3lpscbe1Given) model->BSIM3lpscbe1 = 0.0; if (!model->BSIM3lpscbe2Given) model->BSIM3lpscbe2 = 0.0; if (!model->BSIM3lpvagGiven) model->BSIM3lpvag = 0.0; if (!model->BSIM3lwrGiven) model->BSIM3lwr = 0.0; if (!model->BSIM3ldwgGiven) model->BSIM3ldwg = 0.0; if (!model->BSIM3ldwbGiven) model->BSIM3ldwb = 0.0; if (!model->BSIM3lb0Given) model->BSIM3lb0 = 0.0; if (!model->BSIM3lb1Given) model->BSIM3lb1 = 0.0; if (!model->BSIM3lalpha0Given) model->BSIM3lalpha0 = 0.0; if (!model->BSIM3lalpha1Given) model->BSIM3lalpha1 = 0.0; if (!model->BSIM3lbeta0Given) model->BSIM3lbeta0 = 0.0; if (!model->BSIM3lvfbGiven) model->BSIM3lvfb = 0.0; if (!model->BSIM3lelmGiven) model->BSIM3lelm = 0.0; if (!model->BSIM3lcgslGiven) model->BSIM3lcgsl = 0.0; if (!model->BSIM3lcgdlGiven) model->BSIM3lcgdl = 0.0; if (!model->BSIM3lckappaGiven) model->BSIM3lckappa = 0.0; if (!model->BSIM3lclcGiven) model->BSIM3lclc = 0.0; if (!model->BSIM3lcleGiven) model->BSIM3lcle = 0.0; if (!model->BSIM3lcfGiven) model->BSIM3lcf = 0.0; if (!model->BSIM3lvfbcvGiven) model->BSIM3lvfbcv = 0.0; if (!model->BSIM3lacdeGiven) model->BSIM3lacde = 0.0; if (!model->BSIM3lmoinGiven) model->BSIM3lmoin = 0.0; if (!model->BSIM3lnoffGiven) model->BSIM3lnoff = 0.0; if (!model->BSIM3lvoffcvGiven) model->BSIM3lvoffcv = 0.0; /* Width dependence */ if (!model->BSIM3wcdscGiven) model->BSIM3wcdsc = 0.0; if (!model->BSIM3wcdscbGiven) model->BSIM3wcdscb = 0.0; if (!model->BSIM3wcdscdGiven) model->BSIM3wcdscd = 0.0; if (!model->BSIM3wcitGiven) model->BSIM3wcit = 0.0; if (!model->BSIM3wnfactorGiven) model->BSIM3wnfactor = 0.0; if (!model->BSIM3wxjGiven) model->BSIM3wxj = 0.0; if (!model->BSIM3wvsatGiven) model->BSIM3wvsat = 0.0; if (!model->BSIM3watGiven) model->BSIM3wat = 0.0; if (!model->BSIM3wa0Given) model->BSIM3wa0 = 0.0; if (!model->BSIM3wagsGiven) model->BSIM3wags = 0.0; if (!model->BSIM3wa1Given) model->BSIM3wa1 = 0.0; if (!model->BSIM3wa2Given) model->BSIM3wa2 = 0.0; if (!model->BSIM3wketaGiven) model->BSIM3wketa = 0.0; if (!model->BSIM3wnsubGiven) model->BSIM3wnsub = 0.0; if (!model->BSIM3wnpeakGiven) model->BSIM3wnpeak = 0.0; if (!model->BSIM3wngateGiven) model->BSIM3wngate = 0.0; if (!model->BSIM3wvbmGiven) model->BSIM3wvbm = 0.0; if (!model->BSIM3wxtGiven) model->BSIM3wxt = 0.0; if (!model->BSIM3wkt1Given) model->BSIM3wkt1 = 0.0; if (!model->BSIM3wkt1lGiven) model->BSIM3wkt1l = 0.0; if (!model->BSIM3wkt2Given) model->BSIM3wkt2 = 0.0; if (!model->BSIM3wk3Given) model->BSIM3wk3 = 0.0; if (!model->BSIM3wk3bGiven) model->BSIM3wk3b = 0.0; if (!model->BSIM3ww0Given) model->BSIM3ww0 = 0.0; if (!model->BSIM3wnlxGiven) model->BSIM3wnlx = 0.0; if (!model->BSIM3wdvt0Given) model->BSIM3wdvt0 = 0.0; if (!model->BSIM3wdvt1Given) model->BSIM3wdvt1 = 0.0; if (!model->BSIM3wdvt2Given) model->BSIM3wdvt2 = 0.0; if (!model->BSIM3wdvt0wGiven) model->BSIM3wdvt0w = 0.0; if (!model->BSIM3wdvt1wGiven) model->BSIM3wdvt1w = 0.0; if (!model->BSIM3wdvt2wGiven) model->BSIM3wdvt2w = 0.0; if (!model->BSIM3wdroutGiven) model->BSIM3wdrout = 0.0; if (!model->BSIM3wdsubGiven) model->BSIM3wdsub = 0.0; if (!model->BSIM3wvth0Given) model->BSIM3wvth0 = 0.0; if (!model->BSIM3wuaGiven) model->BSIM3wua = 0.0; if (!model->BSIM3wua1Given) model->BSIM3wua1 = 0.0; if (!model->BSIM3wubGiven) model->BSIM3wub = 0.0; if (!model->BSIM3wub1Given) model->BSIM3wub1 = 0.0; if (!model->BSIM3wucGiven) model->BSIM3wuc = 0.0; if (!model->BSIM3wuc1Given) model->BSIM3wuc1 = 0.0; if (!model->BSIM3wu0Given) model->BSIM3wu0 = 0.0; if (!model->BSIM3wuteGiven) model->BSIM3wute = 0.0; if (!model->BSIM3wvoffGiven) model->BSIM3wvoff = 0.0; if (!model->BSIM3wdeltaGiven) model->BSIM3wdelta = 0.0; if (!model->BSIM3wrdswGiven) model->BSIM3wrdsw = 0.0; if (!model->BSIM3wprwbGiven) model->BSIM3wprwb = 0.0; if (!model->BSIM3wprwgGiven) model->BSIM3wprwg = 0.0; if (!model->BSIM3wprtGiven) model->BSIM3wprt = 0.0; if (!model->BSIM3weta0Given) model->BSIM3weta0 = 0.0; if (!model->BSIM3wetabGiven) model->BSIM3wetab = 0.0; if (!model->BSIM3wpclmGiven) model->BSIM3wpclm = 0.0; if (!model->BSIM3wpdibl1Given) model->BSIM3wpdibl1 = 0.0; if (!model->BSIM3wpdibl2Given) model->BSIM3wpdibl2 = 0.0; if (!model->BSIM3wpdiblbGiven) model->BSIM3wpdiblb = 0.0; if (!model->BSIM3wpscbe1Given) model->BSIM3wpscbe1 = 0.0; if (!model->BSIM3wpscbe2Given) model->BSIM3wpscbe2 = 0.0; if (!model->BSIM3wpvagGiven) model->BSIM3wpvag = 0.0; if (!model->BSIM3wwrGiven) model->BSIM3wwr = 0.0; if (!model->BSIM3wdwgGiven) model->BSIM3wdwg = 0.0; if (!model->BSIM3wdwbGiven) model->BSIM3wdwb = 0.0; if (!model->BSIM3wb0Given) model->BSIM3wb0 = 0.0; if (!model->BSIM3wb1Given) model->BSIM3wb1 = 0.0; if (!model->BSIM3walpha0Given) model->BSIM3walpha0 = 0.0; if (!model->BSIM3walpha1Given) model->BSIM3walpha1 = 0.0; if (!model->BSIM3wbeta0Given) model->BSIM3wbeta0 = 0.0; if (!model->BSIM3wvfbGiven) model->BSIM3wvfb = 0.0; if (!model->BSIM3welmGiven) model->BSIM3welm = 0.0; if (!model->BSIM3wcgslGiven) model->BSIM3wcgsl = 0.0; if (!model->BSIM3wcgdlGiven) model->BSIM3wcgdl = 0.0; if (!model->BSIM3wckappaGiven) model->BSIM3wckappa = 0.0; if (!model->BSIM3wcfGiven) model->BSIM3wcf = 0.0; if (!model->BSIM3wclcGiven) model->BSIM3wclc = 0.0; if (!model->BSIM3wcleGiven) model->BSIM3wcle = 0.0; if (!model->BSIM3wvfbcvGiven) model->BSIM3wvfbcv = 0.0; if (!model->BSIM3wacdeGiven) model->BSIM3wacde = 0.0; if (!model->BSIM3wmoinGiven) model->BSIM3wmoin = 0.0; if (!model->BSIM3wnoffGiven) model->BSIM3wnoff = 0.0; if (!model->BSIM3wvoffcvGiven) model->BSIM3wvoffcv = 0.0; /* Cross-term dependence */ if (!model->BSIM3pcdscGiven) model->BSIM3pcdsc = 0.0; if (!model->BSIM3pcdscbGiven) model->BSIM3pcdscb = 0.0; if (!model->BSIM3pcdscdGiven) model->BSIM3pcdscd = 0.0; if (!model->BSIM3pcitGiven) model->BSIM3pcit = 0.0; if (!model->BSIM3pnfactorGiven) model->BSIM3pnfactor = 0.0; if (!model->BSIM3pxjGiven) model->BSIM3pxj = 0.0; if (!model->BSIM3pvsatGiven) model->BSIM3pvsat = 0.0; if (!model->BSIM3patGiven) model->BSIM3pat = 0.0; if (!model->BSIM3pa0Given) model->BSIM3pa0 = 0.0; if (!model->BSIM3pagsGiven) model->BSIM3pags = 0.0; if (!model->BSIM3pa1Given) model->BSIM3pa1 = 0.0; if (!model->BSIM3pa2Given) model->BSIM3pa2 = 0.0; if (!model->BSIM3pketaGiven) model->BSIM3pketa = 0.0; if (!model->BSIM3pnsubGiven) model->BSIM3pnsub = 0.0; if (!model->BSIM3pnpeakGiven) model->BSIM3pnpeak = 0.0; if (!model->BSIM3pngateGiven) model->BSIM3pngate = 0.0; if (!model->BSIM3pvbmGiven) model->BSIM3pvbm = 0.0; if (!model->BSIM3pxtGiven) model->BSIM3pxt = 0.0; if (!model->BSIM3pkt1Given) model->BSIM3pkt1 = 0.0; if (!model->BSIM3pkt1lGiven) model->BSIM3pkt1l = 0.0; if (!model->BSIM3pkt2Given) model->BSIM3pkt2 = 0.0; if (!model->BSIM3pk3Given) model->BSIM3pk3 = 0.0; if (!model->BSIM3pk3bGiven) model->BSIM3pk3b = 0.0; if (!model->BSIM3pw0Given) model->BSIM3pw0 = 0.0; if (!model->BSIM3pnlxGiven) model->BSIM3pnlx = 0.0; if (!model->BSIM3pdvt0Given) model->BSIM3pdvt0 = 0.0; if (!model->BSIM3pdvt1Given) model->BSIM3pdvt1 = 0.0; if (!model->BSIM3pdvt2Given) model->BSIM3pdvt2 = 0.0; if (!model->BSIM3pdvt0wGiven) model->BSIM3pdvt0w = 0.0; if (!model->BSIM3pdvt1wGiven) model->BSIM3pdvt1w = 0.0; if (!model->BSIM3pdvt2wGiven) model->BSIM3pdvt2w = 0.0; if (!model->BSIM3pdroutGiven) model->BSIM3pdrout = 0.0; if (!model->BSIM3pdsubGiven) model->BSIM3pdsub = 0.0; if (!model->BSIM3pvth0Given) model->BSIM3pvth0 = 0.0; if (!model->BSIM3puaGiven) model->BSIM3pua = 0.0; if (!model->BSIM3pua1Given) model->BSIM3pua1 = 0.0; if (!model->BSIM3pubGiven) model->BSIM3pub = 0.0; if (!model->BSIM3pub1Given) model->BSIM3pub1 = 0.0; if (!model->BSIM3pucGiven) model->BSIM3puc = 0.0; if (!model->BSIM3puc1Given) model->BSIM3puc1 = 0.0; if (!model->BSIM3pu0Given) model->BSIM3pu0 = 0.0; if (!model->BSIM3puteGiven) model->BSIM3pute = 0.0; if (!model->BSIM3pvoffGiven) model->BSIM3pvoff = 0.0; if (!model->BSIM3pdeltaGiven) model->BSIM3pdelta = 0.0; if (!model->BSIM3prdswGiven) model->BSIM3prdsw = 0.0; if (!model->BSIM3pprwbGiven) model->BSIM3pprwb = 0.0; if (!model->BSIM3pprwgGiven) model->BSIM3pprwg = 0.0; if (!model->BSIM3pprtGiven) model->BSIM3pprt = 0.0; if (!model->BSIM3peta0Given) model->BSIM3peta0 = 0.0; if (!model->BSIM3petabGiven) model->BSIM3petab = 0.0; if (!model->BSIM3ppclmGiven) model->BSIM3ppclm = 0.0; if (!model->BSIM3ppdibl1Given) model->BSIM3ppdibl1 = 0.0; if (!model->BSIM3ppdibl2Given) model->BSIM3ppdibl2 = 0.0; if (!model->BSIM3ppdiblbGiven) model->BSIM3ppdiblb = 0.0; if (!model->BSIM3ppscbe1Given) model->BSIM3ppscbe1 = 0.0; if (!model->BSIM3ppscbe2Given) model->BSIM3ppscbe2 = 0.0; if (!model->BSIM3ppvagGiven) model->BSIM3ppvag = 0.0; if (!model->BSIM3pwrGiven) model->BSIM3pwr = 0.0; if (!model->BSIM3pdwgGiven) model->BSIM3pdwg = 0.0; if (!model->BSIM3pdwbGiven) model->BSIM3pdwb = 0.0; if (!model->BSIM3pb0Given) model->BSIM3pb0 = 0.0; if (!model->BSIM3pb1Given) model->BSIM3pb1 = 0.0; if (!model->BSIM3palpha0Given) model->BSIM3palpha0 = 0.0; if (!model->BSIM3palpha1Given) model->BSIM3palpha1 = 0.0; if (!model->BSIM3pbeta0Given) model->BSIM3pbeta0 = 0.0; if (!model->BSIM3pvfbGiven) model->BSIM3pvfb = 0.0; if (!model->BSIM3pelmGiven) model->BSIM3pelm = 0.0; if (!model->BSIM3pcgslGiven) model->BSIM3pcgsl = 0.0; if (!model->BSIM3pcgdlGiven) model->BSIM3pcgdl = 0.0; if (!model->BSIM3pckappaGiven) model->BSIM3pckappa = 0.0; if (!model->BSIM3pcfGiven) model->BSIM3pcf = 0.0; if (!model->BSIM3pclcGiven) model->BSIM3pclc = 0.0; if (!model->BSIM3pcleGiven) model->BSIM3pcle = 0.0; if (!model->BSIM3pvfbcvGiven) model->BSIM3pvfbcv = 0.0; if (!model->BSIM3pacdeGiven) model->BSIM3pacde = 0.0; if (!model->BSIM3pmoinGiven) model->BSIM3pmoin = 0.0; if (!model->BSIM3pnoffGiven) model->BSIM3pnoff = 0.0; if (!model->BSIM3pvoffcvGiven) model->BSIM3pvoffcv = 0.0; /* unit degree celcius */ if (!model->BSIM3tnomGiven) model->BSIM3tnom = ckt->CKTnomTemp; /* else model->BSIM3tnom = model->BSIM3tnom + 273.15; we make this transform in b3mpar.c in the first run */ if (!model->BSIM3lintnoiGiven) model->BSIM3lintnoi = 0.0; /* unit m */ if (!model->BSIM3LintGiven) model->BSIM3Lint = 0.0; if (!model->BSIM3LlGiven) model->BSIM3Ll = 0.0; if (!model->BSIM3LlcGiven) model->BSIM3Llc = model->BSIM3Ll; if (!model->BSIM3LlnGiven) model->BSIM3Lln = 1.0; if (!model->BSIM3LwGiven) model->BSIM3Lw = 0.0; if (!model->BSIM3LwcGiven) model->BSIM3Lwc = model->BSIM3Lw; if (!model->BSIM3LwnGiven) model->BSIM3Lwn = 1.0; if (!model->BSIM3LwlGiven) model->BSIM3Lwl = 0.0; if (!model->BSIM3LwlcGiven) model->BSIM3Lwlc = model->BSIM3Lwl; if (!model->BSIM3LminGiven) model->BSIM3Lmin = 0.0; if (!model->BSIM3LmaxGiven) model->BSIM3Lmax = 1.0; if (!model->BSIM3WintGiven) model->BSIM3Wint = 0.0; if (!model->BSIM3WlGiven) model->BSIM3Wl = 0.0; if (!model->BSIM3WlcGiven) model->BSIM3Wlc = model->BSIM3Wl; if (!model->BSIM3WlnGiven) model->BSIM3Wln = 1.0; if (!model->BSIM3WwGiven) model->BSIM3Ww = 0.0; if (!model->BSIM3WwcGiven) model->BSIM3Wwc = model->BSIM3Ww; if (!model->BSIM3WwnGiven) model->BSIM3Wwn = 1.0; if (!model->BSIM3WwlGiven) model->BSIM3Wwl = 0.0; if (!model->BSIM3WwlcGiven) model->BSIM3Wwlc = model->BSIM3Wwl; if (!model->BSIM3WminGiven) model->BSIM3Wmin = 0.0; if (!model->BSIM3WmaxGiven) model->BSIM3Wmax = 1.0; if (!model->BSIM3dwcGiven) model->BSIM3dwc = model->BSIM3Wint; if (!model->BSIM3dlcGiven) model->BSIM3dlc = model->BSIM3Lint; if (!model->BSIM3xlGiven) model->BSIM3xl = 0.0; if (!model->BSIM3xwGiven) model->BSIM3xw = 0.0; if (!model->BSIM3cfGiven) model->BSIM3cf = 2.0 * EPSOX / PI * log(1.0 + 0.4e-6 / model->BSIM3tox); if (!model->BSIM3cgdoGiven) { if (model->BSIM3dlcGiven && (model->BSIM3dlc > 0.0)) { model->BSIM3cgdo = model->BSIM3dlc * model->BSIM3cox - model->BSIM3cgdl ; } else model->BSIM3cgdo = 0.6 * model->BSIM3xj * model->BSIM3cox; } if (!model->BSIM3cgsoGiven) { if (model->BSIM3dlcGiven && (model->BSIM3dlc > 0.0)) { model->BSIM3cgso = model->BSIM3dlc * model->BSIM3cox - model->BSIM3cgsl ; } else model->BSIM3cgso = 0.6 * model->BSIM3xj * model->BSIM3cox; } if (!model->BSIM3cgboGiven) { model->BSIM3cgbo = 2.0 * model->BSIM3dwc * model->BSIM3cox; } if (!model->BSIM3xpartGiven) model->BSIM3xpart = 0.0; if (!model->BSIM3sheetResistanceGiven) model->BSIM3sheetResistance = 0.0; if (!model->BSIM3unitAreaJctCapGiven) model->BSIM3unitAreaJctCap = 5.0E-4; if (!model->BSIM3unitLengthSidewallJctCapGiven) model->BSIM3unitLengthSidewallJctCap = 5.0E-10; if (!model->BSIM3unitLengthGateSidewallJctCapGiven) model->BSIM3unitLengthGateSidewallJctCap = model->BSIM3unitLengthSidewallJctCap ; if (!model->BSIM3jctSatCurDensityGiven) model->BSIM3jctSatCurDensity = 1.0E-4; if (!model->BSIM3jctSidewallSatCurDensityGiven) model->BSIM3jctSidewallSatCurDensity = 0.0; if (!model->BSIM3bulkJctPotentialGiven) model->BSIM3bulkJctPotential = 1.0; if (!model->BSIM3sidewallJctPotentialGiven) model->BSIM3sidewallJctPotential = 1.0; if (!model->BSIM3GatesidewallJctPotentialGiven) model->BSIM3GatesidewallJctPotential = model->BSIM3sidewallJctPotential; if (!model->BSIM3bulkJctBotGradingCoeffGiven) model->BSIM3bulkJctBotGradingCoeff = 0.5; if (!model->BSIM3bulkJctSideGradingCoeffGiven) model->BSIM3bulkJctSideGradingCoeff = 0.33; if (!model->BSIM3bulkJctGateSideGradingCoeffGiven) model->BSIM3bulkJctGateSideGradingCoeff = model->BSIM3bulkJctSideGradingCoeff; if (!model->BSIM3jctEmissionCoeffGiven) model->BSIM3jctEmissionCoeff = 1.0; if (!model->BSIM3jctTempExponentGiven) model->BSIM3jctTempExponent = 3.0; if (!model->BSIM3oxideTrapDensityAGiven) { if (model->BSIM3type == NMOS) model->BSIM3oxideTrapDensityA = 1e20; else model->BSIM3oxideTrapDensityA=9.9e18; } if (!model->BSIM3oxideTrapDensityBGiven) { if (model->BSIM3type == NMOS) model->BSIM3oxideTrapDensityB = 5e4; else model->BSIM3oxideTrapDensityB = 2.4e3; } if (!model->BSIM3oxideTrapDensityCGiven) { if (model->BSIM3type == NMOS) model->BSIM3oxideTrapDensityC = -1.4e-12; else model->BSIM3oxideTrapDensityC = 1.4e-12; } if (!model->BSIM3emGiven) model->BSIM3em = 4.1e7; /* V/m */ if (!model->BSIM3efGiven) model->BSIM3ef = 1.0; if (!model->BSIM3afGiven) model->BSIM3af = 1.0; if (!model->BSIM3kfGiven) model->BSIM3kf = 0.0; if (!model->BSIM3vgsMaxGiven) model->BSIM3vgsMax = 1e99; if (!model->BSIM3vgdMaxGiven) model->BSIM3vgdMax = 1e99; if (!model->BSIM3vgbMaxGiven) model->BSIM3vgbMax = 1e99; if (!model->BSIM3vdsMaxGiven) model->BSIM3vdsMax = 1e99; if (!model->BSIM3vbsMaxGiven) model->BSIM3vbsMax = 1e99; if (!model->BSIM3vbdMaxGiven) model->BSIM3vbdMax = 1e99; if (!model->BSIM3vgsrMaxGiven) model->BSIM3vgsrMax = 1e99; if (!model->BSIM3vgdrMaxGiven) model->BSIM3vgdrMax = 1e99; if (!model->BSIM3vgbrMaxGiven) model->BSIM3vgbrMax = 1e99; if (!model->BSIM3vbsrMaxGiven) model->BSIM3vbsrMax = 1e99; if (!model->BSIM3vbdrMaxGiven) model->BSIM3vbdrMax = 1e99; /* loop through all the instances of the model */ for (here = BSIM3instances(model); here != NULL ; here=BSIM3nextInstance(here)) { /* allocate a chunk of the state vector */ here->BSIM3states = *states; *states += BSIM3numStates; /* perform the parameter defaulting */ if (!here->BSIM3drainAreaGiven) here->BSIM3drainArea = 0.0; if (!here->BSIM3drainPerimeterGiven) here->BSIM3drainPerimeter = 0.0; if (!here->BSIM3drainSquaresGiven) { if (model->BSIM3acmMod == 0) here->BSIM3drainSquares = 1.0; else here->BSIM3drainSquares = 0.0; } if (!here->BSIM3delvtoGiven) here->BSIM3delvto = 0.0; if (!here->BSIM3mulu0Given) here->BSIM3mulu0 = 1.0; if (!here->BSIM3icVBSGiven) here->BSIM3icVBS = 0.0; if (!here->BSIM3icVDSGiven) here->BSIM3icVDS = 0.0; if (!here->BSIM3icVGSGiven) here->BSIM3icVGS = 0.0; if (!here->BSIM3lGiven) here->BSIM3l = 5.0e-6; if (!here->BSIM3sourceAreaGiven) here->BSIM3sourceArea = 0.0; if (!here->BSIM3sourcePerimeterGiven) here->BSIM3sourcePerimeter = 0.0; if (!here->BSIM3sourceSquaresGiven) { if (model->BSIM3acmMod == 0) here->BSIM3sourceSquares = 1.0; else here->BSIM3sourceSquares = 0.0; } if (!here->BSIM3wGiven) here->BSIM3w = 5.0e-6; if (!here->BSIM3nqsModGiven) here->BSIM3nqsMod = model->BSIM3nqsMod; else if ((here->BSIM3nqsMod != 0) && (here->BSIM3nqsMod != 1)) { here->BSIM3nqsMod = model->BSIM3nqsMod; printf("Warning: nqsMod has been set to its global value %d.\n", model->BSIM3nqsMod); } if (!here->BSIM3acnqsModGiven) here->BSIM3acnqsMod = model->BSIM3acnqsMod; else if ((here->BSIM3acnqsMod != 0) && (here->BSIM3acnqsMod != 1)) { here->BSIM3acnqsMod = model->BSIM3acnqsMod; printf("Warning: acnqsMod has been set to its global value %d.\n", model->BSIM3acnqsMod); } if (!here->BSIM3geoGiven) here->BSIM3geo = 0; if (!here->BSIM3mGiven) here->BSIM3m = 1; /* process source/drain series resistance */ /* ACM model */ double drainResistance, sourceResistance; if (model->BSIM3acmMod == 0) { drainResistance = model->BSIM3sheetResistance * here->BSIM3drainSquares; sourceResistance = model->BSIM3sheetResistance * here->BSIM3sourceSquares; } else /* ACM > 0 */ { error = ACM_SourceDrainResistances( model->BSIM3acmMod, model->BSIM3ld, model->BSIM3ldif, model->BSIM3hdif, model->BSIM3wmlt, here->BSIM3w, model->BSIM3xw, model->BSIM3sheetResistance, here->BSIM3drainSquaresGiven, model->BSIM3rd, model->BSIM3rdc, here->BSIM3drainSquares, here->BSIM3sourceSquaresGiven, model->BSIM3rs, model->BSIM3rsc, here->BSIM3sourceSquares, &drainResistance, &sourceResistance ); if (error) return(error); } /* process drain series resistance */ if (drainResistance != 0.0) { if(here->BSIM3dNodePrime == 0) { error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"drain"); if(error) return(error); here->BSIM3dNodePrime = tmp->number; if (ckt->CKTcopyNodesets) { if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->BSIM3dNodePrime = here->BSIM3dNode; } /* process source series resistance */ if (sourceResistance != 0.0) { if(here->BSIM3sNodePrime == 0) { error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"source"); if(error) return(error); here->BSIM3sNodePrime = tmp->number; if (ckt->CKTcopyNodesets) { if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { tmp->nodeset=tmpNode->nodeset; tmp->nsGiven=tmpNode->nsGiven; } } } } } else { here->BSIM3sNodePrime = here->BSIM3sNode; } /* internal charge node */ if (here->BSIM3nqsMod) { if (here->BSIM3qNode == 0) { error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"charge"); if(error) return(error); here->BSIM3qNode = tmp->number; } } else { here->BSIM3qNode = 0; } /* set Sparse Matrix Pointers */ /* 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(BSIM3DdPtr, BSIM3dNode, BSIM3dNode); TSTALLOC(BSIM3GgPtr, BSIM3gNode, BSIM3gNode); TSTALLOC(BSIM3SsPtr, BSIM3sNode, BSIM3sNode); TSTALLOC(BSIM3BbPtr, BSIM3bNode, BSIM3bNode); TSTALLOC(BSIM3DPdpPtr, BSIM3dNodePrime, BSIM3dNodePrime); TSTALLOC(BSIM3SPspPtr, BSIM3sNodePrime, BSIM3sNodePrime); TSTALLOC(BSIM3DdpPtr, BSIM3dNode, BSIM3dNodePrime); TSTALLOC(BSIM3GbPtr, BSIM3gNode, BSIM3bNode); TSTALLOC(BSIM3GdpPtr, BSIM3gNode, BSIM3dNodePrime); TSTALLOC(BSIM3GspPtr, BSIM3gNode, BSIM3sNodePrime); TSTALLOC(BSIM3SspPtr, BSIM3sNode, BSIM3sNodePrime); TSTALLOC(BSIM3BdpPtr, BSIM3bNode, BSIM3dNodePrime); TSTALLOC(BSIM3BspPtr, BSIM3bNode, BSIM3sNodePrime); TSTALLOC(BSIM3DPspPtr, BSIM3dNodePrime, BSIM3sNodePrime); TSTALLOC(BSIM3DPdPtr, BSIM3dNodePrime, BSIM3dNode); TSTALLOC(BSIM3BgPtr, BSIM3bNode, BSIM3gNode); TSTALLOC(BSIM3DPgPtr, BSIM3dNodePrime, BSIM3gNode); TSTALLOC(BSIM3SPgPtr, BSIM3sNodePrime, BSIM3gNode); TSTALLOC(BSIM3SPsPtr, BSIM3sNodePrime, BSIM3sNode); TSTALLOC(BSIM3DPbPtr, BSIM3dNodePrime, BSIM3bNode); TSTALLOC(BSIM3SPbPtr, BSIM3sNodePrime, BSIM3bNode); TSTALLOC(BSIM3SPdpPtr, BSIM3sNodePrime, BSIM3dNodePrime); TSTALLOC(BSIM3QqPtr, BSIM3qNode, BSIM3qNode); TSTALLOC(BSIM3QdpPtr, BSIM3qNode, BSIM3dNodePrime); TSTALLOC(BSIM3QspPtr, BSIM3qNode, BSIM3sNodePrime); TSTALLOC(BSIM3QgPtr, BSIM3qNode, BSIM3gNode); TSTALLOC(BSIM3QbPtr, BSIM3qNode, BSIM3bNode); TSTALLOC(BSIM3DPqPtr, BSIM3dNodePrime, BSIM3qNode); TSTALLOC(BSIM3SPqPtr, BSIM3sNodePrime, BSIM3qNode); TSTALLOC(BSIM3GqPtr, BSIM3gNode, BSIM3qNode); TSTALLOC(BSIM3BqPtr, BSIM3bNode, BSIM3qNode); } } #ifdef USE_OMP InstCount = 0; model = (BSIM3model*)inModel; /* loop through all the BSIM3 device models to count the number of instances */ for( ; model != NULL; model = BSIM3nextModel(model)) { /* loop through all the instances of the model */ for (here = BSIM3instances(model); here != NULL ; here=BSIM3nextInstance(here)) { InstCount++; } model->BSIM3InstCount = 0; model->BSIM3InstanceArray = NULL; } InstArray = TMALLOC(BSIM3instance*, InstCount); model = (BSIM3model*)inModel; /* store this in the first model only */ model->BSIM3InstCount = InstCount; model->BSIM3InstanceArray = InstArray; idx = 0; for( ; model != NULL; model = BSIM3nextModel(model)) { /* loop through all the instances of the model */ for (here = BSIM3instances(model); here != NULL ; here=BSIM3nextInstance(here)) { InstArray[idx] = here; idx++; } } #endif return(OK); }