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

📄 nummload.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		    ig = *(ckt->CKTstate0 + inst->NUMOSig);		    g.dIdDVdb = *(ckt->CKTstate0 + inst->NUMOSdIdDVdb);		    g.dIdDVsb = *(ckt->CKTstate0 + inst->NUMOSdIdDVsb);		    g.dIdDVgb = *(ckt->CKTstate0 + inst->NUMOSdIdDVgb);		    g.dIsDVdb = *(ckt->CKTstate0 + inst->NUMOSdIsDVdb);		    g.dIsDVsb = *(ckt->CKTstate0 + inst->NUMOSdIsDVsb);		    g.dIsDVgb = *(ckt->CKTstate0 + inst->NUMOSdIsDVgb);		    g.dIgDVdb = *(ckt->CKTstate0 + inst->NUMOSdIgDVdb);		    g.dIgDVsb = *(ckt->CKTstate0 + inst->NUMOSdIgDVsb);		    g.dIgDVgb = *(ckt->CKTstate0 + inst->NUMOSdIgDVgb);		    goto load;		  }#endif				/* NOBYPASS */	/*	 * limit nonlinear branch voltages	 */	icheck1 = 1;	if (deviceType == OPTN_BIPOLAR) {	  double vbe, vbe0;	  double vce, vce0;	  vdb = -inst->NUMOStype * limitJunctionVoltage(-inst->NUMOStype * vdb,	      -inst->NUMOStype * *(ckt->CKTstate0 + inst->NUMOSvdb), &icheck);	  vce = vdb - vsb;	  vce0 = *(ckt->CKTstate0 + inst->NUMOSvdb) -	      *(ckt->CKTstate0 + inst->NUMOSvsb);	  vce = inst->NUMOStype * limitVce(inst->NUMOStype * vce,	      inst->NUMOStype * vce0, &icheck1);	  if (icheck1 == 1)	    icheck = 1;	  vsb = vdb - vce;	  vbe = vgb - vsb;	  vbe0 = *(ckt->CKTstate0 + inst->NUMOSvgb) -	      *(ckt->CKTstate0 + inst->NUMOSvsb);	  vbe = inst->NUMOStype * limitVbe(inst->NUMOStype * vbe,	      inst->NUMOStype * vbe0, &icheck1);	  if (icheck1 == 1)	    icheck = 1;	  vgb = vbe + vsb;	} else {	  vdb = -inst->NUMOStype * limitJunctionVoltage(-inst->NUMOStype * vdb,	      -inst->NUMOStype * *(ckt->CKTstate0 + inst->NUMOSvdb), &icheck);	  vsb = -inst->NUMOStype * limitJunctionVoltage(-inst->NUMOStype * vsb,	      -inst->NUMOStype * *(ckt->CKTstate0 + inst->NUMOSvsb), &icheck1);	  if (icheck1 == 1)	    icheck = 1;	  vgb = inst->NUMOStype * limitVgb(inst->NUMOStype * vgb,	      inst->NUMOStype * *(ckt->CKTstate0 + inst->NUMOSvgb), &icheck1);	  if (icheck1 == 1)	    icheck = 1;	}	delVdb = vdb - *(ckt->CKTstate0 + inst->NUMOSvdb);	delVsb = vsb - *(ckt->CKTstate0 + inst->NUMOSvsb);	delVgb = vgb - *(ckt->CKTstate0 + inst->NUMOSvgb);	NUMOSsetBCs(pDevice, vdb - delVdb, vsb - delVsb, vgb - delVgb);      }      if (doInitSolve) {	if (TWOdcDebug) {	  printVoltages(stdout, model->NUMOSmodName, inst->NUMOSname,	      deviceType, 3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);	}	startTime2 = SPfrontEnd->IFseconds();	TWOequilSolve(pDevice);	totalTime2 = SPfrontEnd->IFseconds() - startTime2;	pDevice->pStats->totalTime[STAT_SETUP] += totalTime2;	pDevice->pStats->totalTime[STAT_DC] -= totalTime2;	TWObiasSolve(pDevice, MaxIterations, FALSE, NULL);	*(ckt->CKTstate0 + inst->NUMOSvdb) = 0.0;	*(ckt->CKTstate0 + inst->NUMOSvsb) = 0.0;	*(ckt->CKTstate0 + inst->NUMOSvgb) = 0.0;	if (initStateName != NULL) {	  if (TWOreadState(pDevice, initStateName, 3, &vdb, &vgb, &vsb ) < 0) {	    fprintf(stderr,		"NUMOSload: trouble reading state-file %s\n", initStateName);	  } else {	    NUMOSsetBCs(pDevice, vdb, vsb, vgb);	    delVdb = delVsb = delVgb = 0.0;	  }	}      }      /*       * determine dc current and derivatives using the numerical routines       */      if (ckt->CKTmode & (MODEDCOP | MODETRANOP | MODEDCTRANCURVE | MODEINITSMSIG)) {	numDevNonCon = 0;	inst->NUMOSc11 = inst->NUMOSy11r = inst->NUMOSy11i = 0.0;	inst->NUMOSc12 = inst->NUMOSy12r = inst->NUMOSy12i = 0.0;	inst->NUMOSc13 = inst->NUMOSy13r = inst->NUMOSy13i = 0.0;	inst->NUMOSc21 = inst->NUMOSy21r = inst->NUMOSy21i = 0.0;	inst->NUMOSc22 = inst->NUMOSy22r = inst->NUMOSy22i = 0.0;	inst->NUMOSc23 = inst->NUMOSy23r = inst->NUMOSy23i = 0.0;	inst->NUMOSc31 = inst->NUMOSy31r = inst->NUMOSy31i = 0.0;	inst->NUMOSc32 = inst->NUMOSy32r = inst->NUMOSy32i = 0.0;	inst->NUMOSc33 = inst->NUMOSy33r = inst->NUMOSy33i = 0.0;	inst->NUMOSsmSigAvail = FALSE;    devNonCon:	NUMOSproject(pDevice, delVdb, delVsb, delVgb);	if (TWOdcDebug) {	  printVoltages(stdout, model->NUMOSmodName, inst->NUMOSname,	      deviceType, 3, vdb, delVdb, vgb, delVgb, vsb, delVsb);	}	TWObiasSolve(pDevice, MaxIterations, FALSE, model->NUMOSpInfo);	devConverged = pDevice->converged;	if (devConverged && finite(pDevice->rhsNorm)) {	  /* compute the currents */	  NUMOScurrent(pDevice, FALSE, (double *) NULL, &id, &is, &ig);	  NUMOSconductance(pDevice, FALSE, (double *) NULL, &g);	  /*	   * Add gmin to the gate conductance terms since they will be zero.	   * XXX This messes up the gXY output values, but we choose not to	   * correct this error, because it shouldn't cause practical problems.	   */	  g.dIgDVdb += ckt->CKTgmin;	  g.dIgDVsb += ckt->CKTgmin;	  g.dIgDVgb += ckt->CKTgmin;	} else {	  /* reduce the voltage step until converged */	  /* restore boundary nodes to previous potential */	  NUMOSsetBCs(pDevice,	      vdb - delVdb, vsb - delVsb, vgb - delVgb);	  TWOstoreInitialGuess(pDevice);	  TWOresetJacobian(pDevice);	  delVdb *= 0.5;	  delVsb *= 0.5;	  delVgb *= 0.5;	  vdb = delVdb + *(ckt->CKTstate0 + inst->NUMOSvdb);	  vsb = delVsb + *(ckt->CKTstate0 + inst->NUMOSvsb);	  vgb = delVgb + *(ckt->CKTstate0 + inst->NUMOSvgb);	  numDevNonCon++;	  icheck = 1;	  if (numDevNonCon > 10) {	    printVoltages(stderr, model->NUMOSmodName, inst->NUMOSname,		deviceType, 3, vdb, delVdb, vgb, delVgb, vsb, delVsb);	    fprintf(stderr, "*** Non-convergence during load ***\n");	    totalTime += SPfrontEnd->IFseconds() - startTime;	    pDevice->pStats->totalTime[STAT_DC] += totalTime;	    ckt->CKTtroubleElt = (GENinstance *) inst;	    return (E_BADMATRIX);	  } else {	    goto devNonCon;	  }	}      }      if ((ckt->CKTmode & (MODETRAN | MODEAC)) ||	  ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) ||	  (ckt->CKTmode & MODEINITSMSIG)) {	/*	 * store small-signal parameters	 */	if ((!(ckt->CKTmode & MODETRANOP)) ||	    (!(ckt->CKTmode & MODEUIC))) {	  if (ckt->CKTmode & MODEINITSMSIG) {	    totalTime += SPfrontEnd->IFseconds() - startTime;	    pDevice->pStats->totalTime[STAT_DC] += totalTime;	    startTime2 = SPfrontEnd->IFseconds();	    NUMOSinitSmSig(inst);	    pDevice->pStats->totalTime[STAT_AC] +=		SPfrontEnd->IFseconds() - startTime2;	    continue;	  } else {	    inst->NUMOSsmSigAvail = FALSE;	  }	  /*	   * transient analysis	   */	  if (ckt->CKTmode & MODEINITPRED) {	    NUMOSsetBCs(pDevice, vdb, vsb, vgb);	    TWOstoreInitialGuess(pDevice);	  } else {	    NUMOSupdate(pDevice, delVdb, delVsb, delVgb, TRUE);	  }	  if (TWOtranDebug) {	    printVoltages(stdout, model->NUMOSmodName, inst->NUMOSname,		deviceType, 3, vdb, delVdb, vgb, delVgb, vsb, delVsb);	  }	  TWObiasSolve(pDevice, 0, TRUE, model->NUMOSpInfo);	  if (!finite(pDevice->rhsNorm)) {	    totalTime += SPfrontEnd->IFseconds() - startTime;	    pDevice->pStats->totalTime[STAT_TRAN] += totalTime;	    ckt->CKTtroubleElt = (GENinstance *) inst;	    return (E_BADMATRIX);	  }	  devConverged = TWOdeviceConverged(pDevice);	  pDevice->converged = devConverged;	  /* compute the currents and conductances */	  NUMOScurrent(pDevice, TRUE, model->NUMOSpInfo->intCoeff,	      &id, &is, &ig);	  NUMOSconductance(pDevice, TRUE,	      model->NUMOSpInfo->intCoeff, &g);	}      }      /*       * check convergence       */      if ((!(ckt->CKTmode & MODEINITFIX)) || (!(inst->NUMOSoff))) {	if (icheck == 1 || !devConverged) {	  ckt->CKTnoncon++;	  ckt->CKTtroubleElt = (GENinstance *) inst;	} else {	  tol = ckt->CKTreltol * MAX(FABS(idhat), FABS(id)) + ckt->CKTabstol;	  if (FABS(idhat - id) > tol) {	    ckt->CKTnoncon++;	    ckt->CKTtroubleElt = (GENinstance *) inst;	  } else {	    tol = ckt->CKTreltol * MAX(FABS(ishat), FABS(is)) +		ckt->CKTabstol;	    if (FABS(ishat - is) > tol) {	      ckt->CKTnoncon++;	      ckt->CKTtroubleElt = (GENinstance *) inst;	    } else {	      tol = ckt->CKTreltol * MAX(FABS(ighat), FABS(ig)) +		  ckt->CKTabstol;	      if (FABS(ighat - ig) > tol) {		ckt->CKTnoncon++;		ckt->CKTtroubleElt = (GENinstance *) inst;	      }	    }	  }	}      }      *(ckt->CKTstate0 + inst->NUMOSvdb) = vdb;      *(ckt->CKTstate0 + inst->NUMOSvsb) = vsb;      *(ckt->CKTstate0 + inst->NUMOSvgb) = vgb;      *(ckt->CKTstate0 + inst->NUMOSid) = id;      *(ckt->CKTstate0 + inst->NUMOSis) = is;      *(ckt->CKTstate0 + inst->NUMOSig) = ig;      *(ckt->CKTstate0 + inst->NUMOSdIdDVdb) = g.dIdDVdb;      *(ckt->CKTstate0 + inst->NUMOSdIdDVsb) = g.dIdDVsb;      *(ckt->CKTstate0 + inst->NUMOSdIdDVgb) = g.dIdDVgb;      *(ckt->CKTstate0 + inst->NUMOSdIsDVdb) = g.dIsDVdb;      *(ckt->CKTstate0 + inst->NUMOSdIsDVsb) = g.dIsDVsb;      *(ckt->CKTstate0 + inst->NUMOSdIsDVgb) = g.dIsDVgb;      *(ckt->CKTstate0 + inst->NUMOSdIgDVdb) = g.dIgDVdb;      *(ckt->CKTstate0 + inst->NUMOSdIgDVsb) = g.dIgDVsb;      *(ckt->CKTstate0 + inst->NUMOSdIgDVgb) = g.dIgDVgb;  load:      /*       * load current excitation vector       */      ideq = id - g.dIdDVdb * vdb - g.dIdDVsb * vsb - g.dIdDVgb * vgb;      iseq = is - g.dIsDVdb * vdb - g.dIsDVsb * vsb - g.dIsDVgb * vgb;      igeq = ig - g.dIgDVdb * vdb - g.dIgDVsb * vsb - g.dIgDVgb * vgb;      *(ckt->CKTrhs + inst->NUMOSdrainNode) -= ideq;      *(ckt->CKTrhs + inst->NUMOSsourceNode) -= iseq;      *(ckt->CKTrhs + inst->NUMOSgateNode) -= igeq;      *(ckt->CKTrhs + inst->NUMOSbulkNode) += ideq + iseq + igeq;      /*       * load y matrix       */      *(inst->NUMOSdrainDrainPtr) += g.dIdDVdb;      *(inst->NUMOSdrainSourcePtr) += g.dIdDVsb;      *(inst->NUMOSdrainGatePtr) += g.dIdDVgb;      *(inst->NUMOSdrainBulkPtr) -= g.dIdDVdb + g.dIdDVsb + g.dIdDVgb;      *(inst->NUMOSsourceDrainPtr) += g.dIsDVdb;      *(inst->NUMOSsourceSourcePtr) += g.dIsDVsb;      *(inst->NUMOSsourceGatePtr) += g.dIsDVgb;      *(inst->NUMOSsourceBulkPtr) -= g.dIsDVdb + g.dIsDVsb + g.dIsDVgb;      *(inst->NUMOSgateDrainPtr) += g.dIgDVdb;      *(inst->NUMOSgateSourcePtr) += g.dIgDVsb;      *(inst->NUMOSgateGatePtr) += g.dIgDVgb;      *(inst->NUMOSgateBulkPtr) -= g.dIgDVdb + g.dIgDVsb + g.dIgDVgb;      *(inst->NUMOSbulkDrainPtr) -= g.dIdDVdb + g.dIsDVdb + g.dIgDVdb;      *(inst->NUMOSbulkSourcePtr) -= g.dIdDVsb + g.dIsDVsb + g.dIgDVsb;      *(inst->NUMOSbulkGatePtr) -= g.dIdDVgb + g.dIsDVgb + g.dIgDVgb;      *(inst->NUMOSbulkBulkPtr) += g.dIdDVdb + g.dIdDVsb + g.dIdDVgb	  + g.dIsDVdb + g.dIsDVsb + g.dIsDVgb	  + g.dIgDVdb + g.dIgDVsb + g.dIgDVgb;      totalTime += SPfrontEnd->IFseconds() - startTime;      if (ckt->CKTmode & MODETRAN) {	pDevice->pStats->totalTime[STAT_TRAN] += totalTime;      } else {	pDevice->pStats->totalTime[STAT_DC] += totalTime;      }    }  }  return (OK);}intNUMOSinitSmSig(inst)  NUMOSinstance *inst;{  struct mosAdmittances yAc;  double omega = inst->NUMOSmodPtr->NUMOSmethods->METHomega;  AcAnalysisMethod = SOR_ONLY;  (void) NUMOSadmittance(inst->NUMOSpDevice, omega, &yAc);  inst->NUMOSc11 = yAc.yIdVdb.imag / omega;  inst->NUMOSc12 = yAc.yIdVgb.imag / omega;  inst->NUMOSc13 = yAc.yIdVsb.imag / omega;  inst->NUMOSc21 = yAc.yIgVdb.imag / omega;  inst->NUMOSc22 = yAc.yIgVgb.imag / omega;  inst->NUMOSc23 = yAc.yIgVsb.imag / omega;  inst->NUMOSc31 = yAc.yIsVdb.imag / omega;  inst->NUMOSc32 = yAc.yIsVgb.imag / omega;  inst->NUMOSc33 = yAc.yIsVsb.imag / omega;  inst->NUMOSy11r = yAc.yIdVdb.real;  inst->NUMOSy11i = yAc.yIdVdb.imag;  inst->NUMOSy12r = yAc.yIdVgb.real;  inst->NUMOSy12i = yAc.yIdVgb.imag;  inst->NUMOSy13r = yAc.yIdVsb.real;  inst->NUMOSy13i = yAc.yIdVsb.imag;  inst->NUMOSy21r = yAc.yIgVdb.real;  inst->NUMOSy21i = yAc.yIgVdb.imag;  inst->NUMOSy22r = yAc.yIgVgb.real;  inst->NUMOSy22i = yAc.yIgVgb.imag;  inst->NUMOSy23r = yAc.yIgVsb.real;  inst->NUMOSy23i = yAc.yIgVsb.imag;  inst->NUMOSy31r = yAc.yIsVdb.real;  inst->NUMOSy31i = yAc.yIsVdb.imag;  inst->NUMOSy32r = yAc.yIsVgb.real;  inst->NUMOSy32i = yAc.yIsVgb.imag;  inst->NUMOSy33r = yAc.yIsVsb.real;  inst->NUMOSy33i = yAc.yIsVsb.imag;  inst->NUMOSsmSigAvail = TRUE;  return (OK);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -