hsm1ld.c

来自「ngspice又一个电子CAD仿真软件代码.功能更全」· C语言 代码 · 共 1,380 行 · 第 1/4 页

C
1,380
字号
/*********************************************************************** HiSIM (Hiroshima University STARC IGFET Model) Copyright (C) 2003 STARC VERSION : HiSIM 1.2.0 FILE : hsm1ld.c of HiSIM 1.2.0 April 9, 2003 : released by STARC Physical Design Group***********************************************************************/#include "ngspice.h"#include "cktdefs.h"#include "hsm1def.h"#include "hisim.h"#include "trandefs.h"#include "const.h"#include "sperror.h"#include "devdefs.h"#include "suffix.h"#define SHOW_EPS_QUANT 1.0e-15static void ShowPhysVals(HSM1instance *here, HSM1model *model,int isFirst, double vds,              double vgs, double vbs, double vgd, double vbd, double vgb){  /* regard the epsilon-quantity as 0.0 */  vds = (fabs(vds) < SHOW_EPS_QUANT) ? 0.0 : vds;  vgs = (fabs(vgs) < SHOW_EPS_QUANT) ? 0.0 : vgs;  vbs = (fabs(vbs) < SHOW_EPS_QUANT) ? 0.0 : vbs;  vgb = (fabs(vgb) < SHOW_EPS_QUANT) ? 0.0 : vgb;  switch (model->HSM1_show) {  case 1:    if (isFirst) printf("Vds        Ids\n");    printf("%e %e\n", model->HSM1_type*vds, here->HSM1_mode*here->HSM1_ids);    break;  case 2:    if (isFirst) printf("Vgs        Ids\n");    printf("%e %e\n", model->HSM1_type*vgs, here->HSM1_mode*here->HSM1_ids);    break;  case 3:    if (isFirst) printf("Vgs        log10(|Ids|)\n");    printf("%e %e\n", model->HSM1_type*vgs, log10(here->HSM1_ids));    break;  case 4:    if (isFirst) printf("log10(|Ids|)    gm/|Ids|\n");    if (here->HSM1_ids == 0.0)      printf("I can't show gm/Ids - log10(Ids), because Ids = 0.\n");    else      printf("%e %e\n",  log10(here->HSM1_ids), here->HSM1_gm/here->HSM1_ids);    break;  case 5:    if (isFirst) printf("Vds        gds\n");    printf("%e %e\n", model->HSM1_type*vds, here->HSM1_gds);    break;  case 6:    if (isFirst) printf("Vgs        gm\n");    printf("%e %e\n", model->HSM1_type*vgs, here->HSM1_gm);    break;  case 7:    if (isFirst) printf("Vbs        gbs\n");    printf("%e %e\n", model->HSM1_type*vbs, here->HSM1_gmbs);    break;  case 8:    if (isFirst) printf("Vgs        Cgg\n");    printf("%e %e\n", model->HSM1_type*vgs, here->HSM1_cggb);    break;  case 9:    if (isFirst) printf("Vgs        Cgs\n");    printf("%e %e\n", model->HSM1_type*vgs, here->HSM1_cgsb);    break;  case 10:    if (isFirst) printf("Vgs        Cgd\n");    printf("%e %e\n", model->HSM1_type*vgs, here->HSM1_cgdb);    break;  case 11:    if (isFirst) printf("Vgs        Cgb\n");    printf("%e %e\n", model->HSM1_type*vgs, -(here->HSM1_cggb+here->HSM1_cgsb+here->HSM1_cgdb));    break;  case 12:    if (isFirst) printf("Vds        Csg\n");    printf("%e %e\n", model->HSM1_type*vds, -(here->HSM1_cggb+here->HSM1_cbgb+here->HSM1_cdgb));    break;  case 13:    if (isFirst) printf("Vds        Cdg\n");    printf("%e %e\n", model->HSM1_type*vds, here->HSM1_cdgb);    break;  case 14:    if (isFirst) printf("Vds        Cbg\n");    printf("%e %e\n", model->HSM1_type*vds, here->HSM1_cbgb);    break;  case 15:    if (isFirst) printf("Vds        Cgg\n");    printf("%e %e\n", model->HSM1_type*vds, here->HSM1_cggb);    break;  case 16:    if (isFirst) printf("Vds        Cgs\n");    printf("%e %e\n", model->HSM1_type*vds, here->HSM1_cgsb);    break;  case 17:    if (isFirst) printf("Vds        Cgd\n");    printf("%e %e\n", model->HSM1_type*vds, here->HSM1_cgdb);    break;  case 18:    if (isFirst) printf("Vds        Cgb\n");    printf("%e %e\n", model->HSM1_type*vds, -(here->HSM1_cggb+here->HSM1_cgsb+here->HSM1_cgdb));    break;  case 19:    if (isFirst) printf("Vgs        Csg\n");    printf("%e %e\n", model->HSM1_type*vgs, -(here->HSM1_cggb+here->HSM1_cbgb+here->HSM1_cdgb));    break;  case 20:    if (isFirst) printf("Vgs        Cdg\n");    printf("%e %e\n", model->HSM1_type*vgs, here->HSM1_cdgb);    break;  case 21:    if (isFirst) printf("Vgs        Cbg\n");    printf("%e %e\n", model->HSM1_type*vgs, here->HSM1_cbgb);    break;  case 22:    if (isFirst) printf("Vgb        Cgb\n");    printf("%e %e\n", model->HSM1_type*vgb, -(here->HSM1_cggb+here->HSM1_cgsb+here->HSM1_cgdb));    break;  case 50:    if (isFirst) printf("Vgs  Vds  Vbs  Vgb  Ids  log10(|Ids|)  gm/|Ids|  gm  gds  gbs  Cgg  Cgs  Cgb  Cgd  Csg  Cbg  Cdg\n");    printf("%e %e %e %e %e %e %e %e %e %e %e %e %e %e %e %e %e\n", model->HSM1_type*vgs, model->HSM1_type*vds, model->HSM1_type*vbs, model->HSM1_type*vgb, here->HSM1_mode*here->HSM1_ids, log10(here->HSM1_ids), here->HSM1_gm/here->HSM1_ids, here->HSM1_gm, here->HSM1_gds, here->HSM1_gmbs, here->HSM1_cggb, here->HSM1_cgsb, -(here->HSM1_cggb+here->HSM1_cgsb+here->HSM1_cgdb), here->HSM1_cgdb, -(here->HSM1_cggb+here->HSM1_cbgb+here->HSM1_cdgb), here->HSM1_cbgb, here->HSM1_cdgb);    break;  default:    /*    printf("There is no physical value corrsponding to %d\n", flag);    */    break;  }}int HSM1load(GENmodel *inModel, register CKTcircuit *ckt)     /* actually load the current value into the       * sparse matrix previously provided       */{  register HSM1model *model = (HSM1model*)inModel;  register HSM1instance *here;  HiSIM_input sIN;  HiSIM_output sOT;  HiSIM_messenger sMS;  double cbhat = 0.0, cdrain, cdhat = 0.0, cdreq;  double cgbhat = 0.0, cgshat = 0.0, cgdhat = 0.0;  double Ibtot = 0.0, Idtot, Igbtot = 0.0, Igstot = 0.0, Igdtot = 0.0;  double ceq, ceqbd, ceqbs, ceqqb, ceqqd, ceqqg;  double delvbd, delvbs, delvds, delvgd, delvgs;  double gcbdb, gcbgb, gcbsb, gcddb, gcdgb, gcdsb;  double gcgdb, gcggb, gcgsb, gcsdb, gcsgb, gcssb;  double geq, xfact;  double vbd, vbs, vcrit, vds, vgb, vgd, vgdo, vgs, von;  double qgd, qgs, qgb;  double gbbdp, gbbsp, gbspg, gbspdp, gbspb, gbspsp;  double qgate, qbulk, qdrn, qsrc;  double cqgate, cqbulk, cqdrn;  double gbdpdp, gbdpg, gbdpb, gbdpsp;   double cgdo, cgso, cgbo;  double gm, gmbs, FwdSum, RevSum;  double vt0, ag0;  double Ibtoteq, gIbtotg, gIbtotd, gIbtots, gIbtotb;  double Igtoteq, gIgtotg, gIgtotd, gIgtots, gIgtotb;  double Idtoteq, gIdtotg, gIdtotd, gIdtots, gIdtotb;  double Istoteq, gIstotg, gIstotd, gIstots, gIstotb;  int ByPass, Check, error;#ifndef NOBYPASS  double tempv;#endif /*NOBYPASS*/  double tmp;#ifndef NEWCONV  double tol, tol2, tol3, tol4;#endif  int ChargeComputationNeeded =      ((ckt->CKTmode & (MODEAC | MODETRAN | MODEINITSMSIG)) ||     ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)))    ? 1 : 0;  int showPhysVal;  int isConv;  double vds_pre = 0.0;  double m; /* Parallel multiplier */    /*  loop through all the HSM1 device models */  for ( ; model != NULL; model = model->HSM1nextModel ) {    /* loop through all the instances of the model */    for (here = model->HSM1instances; here != NULL ;	 here = here->HSM1nextInstance) {	       if (here->HSM1owner != ARCHme)              continue;	       showPhysVal = 0;      Check=1;      ByPass = 0;      if ( ckt->CKTmode & MODEINITSMSIG ) {	vbs= *(ckt->CKTstate0 + here->HSM1vbs);	vgs= *(ckt->CKTstate0 + here->HSM1vgs);	vds= *(ckt->CKTstate0 + here->HSM1vds);      }       else if ( ckt->CKTmode & MODEINITTRAN ) {	vbs= *(ckt->CKTstate1 + here->HSM1vbs);	vgs= *(ckt->CKTstate1 + here->HSM1vgs);	vds= *(ckt->CKTstate1 + here->HSM1vds);      }       else if ( (ckt->CKTmode & MODEINITJCT) && !here->HSM1_off ) {	vds= model->HSM1_type * here->HSM1_icVDS;	vgs= model->HSM1_type * here->HSM1_icVGS;	vbs= model->HSM1_type * here->HSM1_icVBS;	if ( (vds == 0.0) && (vgs == 0.0) && (vbs == 0.0) && 	     ( (ckt->CKTmode & (MODETRAN|MODEAC|MODEDCOP|MODEDCTRANCURVE)) ||	       !(ckt->CKTmode & MODEUIC) ) ) { 	  /* set biases for starting  analysis (same as BSIM3)*/	  vbs = 0.0;	  /*	  vt0 = model->HSM1_type * (-1.0 * model->HSM1_vfbc);*/	  vt0 = model->HSM1_type * model->HSM1_vfbc;	  vgs = vt0 + 0.1;	  vds = 0.1;	}      }       else if ( ( ckt->CKTmode & (MODEINITJCT | MODEINITFIX) ) && 		here->HSM1_off ) {	vbs = vgs = vds = 0.0;      }       else {#ifndef PREDICTOR /* BSIM3 style */	if (ckt->CKTmode & MODEINITPRED) {	  xfact = ckt->CKTdelta / ckt->CKTdeltaOld[1];	  *(ckt->CKTstate0 + here->HSM1vbs) = 	    *(ckt->CKTstate1 + here->HSM1vbs);	  vbs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->HSM1vbs))	    -(xfact * (*(ckt->CKTstate2 + here->HSM1vbs)));	  *(ckt->CKTstate0 + here->HSM1vgs) = 	    *(ckt->CKTstate1 + here->HSM1vgs);	  vgs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->HSM1vgs))	    -(xfact * (*(ckt->CKTstate2 + here->HSM1vgs)));	  *(ckt->CKTstate0 + here->HSM1vds) = 	    *(ckt->CKTstate1 + here->HSM1vds);	  vds = (1.0 + xfact)* (*(ckt->CKTstate1 + here->HSM1vds))	    -(xfact * (*(ckt->CKTstate2 + here->HSM1vds)));	  *(ckt->CKTstate0 + here->HSM1vbd) = 	    *(ckt->CKTstate0 + here->HSM1vbs)-	    *(ckt->CKTstate0 + here->HSM1vds);	} 	else {#endif /* PREDICTOR */	  /* get biases from CKT */	  vbs = model->HSM1_type * 	    (*(ckt->CKTrhsOld+here->HSM1bNode) -	     *(ckt->CKTrhsOld+here->HSM1sNodePrime));	  vgs = model->HSM1_type * 	    (*(ckt->CKTrhsOld+here->HSM1gNode) -	     *(ckt->CKTrhsOld+here->HSM1sNodePrime));	  vds = model->HSM1_type * 	    (*(ckt->CKTrhsOld+here->HSM1dNodePrime) -	     *(ckt->CKTrhsOld+here->HSM1sNodePrime));#ifndef PREDICTOR	}#endif /* PREDICTOR */	vbd = vbs - vds;	vgd = vgs - vds;	vgdo = *(ckt->CKTstate0 + here->HSM1vgs) - 	  *(ckt->CKTstate0 + here->HSM1vds);	delvbs = vbs - *(ckt->CKTstate0 + here->HSM1vbs);	delvbd = vbd - *(ckt->CKTstate0 + here->HSM1vbd);	delvgs = vgs - *(ckt->CKTstate0 + here->HSM1vgs);	delvds = vds - *(ckt->CKTstate0 + here->HSM1vds);	delvgd = vgd - vgdo;	  	if (here->HSM1_mode >= 0) {	  Idtot = here->HSM1_ids + here->HSM1_isub - here->HSM1_ibd	    + here->HSM1_igidl;	  cdhat = Idtot - here->HSM1_gbd * delvbd	    + (here->HSM1_gmbs + here->HSM1_gbbs + here->HSM1_gigidlbs) * delvbs 	    + (here->HSM1_gm + here->HSM1_gbgs + here->HSM1_gigidlgs) * delvgs	    + (here->HSM1_gds + here->HSM1_gbds + here->HSM1_gigidlds) * delvds;	  Ibtot = here->HSM1_ibs + here->HSM1_ibd - here->HSM1_isub	    - here->HSM1_igidl - here->HSM1_igisl;	  cbhat = Ibtot + here->HSM1_gbd * delvbd	    + (here->HSM1_gbs -  here->HSM1_gbbs - here->HSM1_gigidlbs) * delvbs	    - (here->HSM1_gbgs + here->HSM1_gigidlgs) * delvgs	    - (here->HSM1_gbds + here->HSM1_gigidlds) * delvds	    - here->HSM1_gigislgd * delvgd - here->HSM1_gigislbd * delvbd	    + here->HSM1_gigislsd * delvds;	  Igstot = here->HSM1_igs;	  cgshat = Igstot + here->HSM1_gigsg * delvgs + 	    here->HSM1_gigsd * delvds + here->HSM1_gigsb * delvbs;	  Igdtot = here->HSM1_igd;	  cgdhat = Igdtot + here->HSM1_gigdg * delvgs + 	    here->HSM1_gigdd * delvds + here->HSM1_gigdb * delvbs;	  Igbtot = here->HSM1_igb;	  cgbhat = Igbtot + here->HSM1_gigbg * delvgs + 	    here->HSM1_gigbd * delvds + here->HSM1_gigbb * delvbs;	} 	else {	  Idtot = here->HSM1_ids + here->HSM1_ibd - here->HSM1_igidl;	  cdhat = Idtot + (here->HSM1_gbd + here->HSM1_gmbs) * delvbd	    + here->HSM1_gm * delvgd - here->HSM1_gds * delvds	    - here->HSM1_gigidlgs * delvgd - here->HSM1_gigidlbs * delvbd 	    + here->HSM1_gigidlds * delvds ;	  Ibtot = here->HSM1_ibs + here->HSM1_ibd - here->HSM1_isub	    - here->HSM1_igidl - here->HSM1_igisl;	  cbhat = Ibtot + here->HSM1_gbs * delvbs	    + (here->HSM1_gbd - here->HSM1_gbbs - here->HSM1_gigidlbs) * delvbd	    - (here->HSM1_gbgs + here->HSM1_gigidlgs) * delvgd	    + (here->HSM1_gbds + here->HSM1_gigidlds) * delvds	    - here->HSM1_gigislgd * delvgd - here->HSM1_gigislbd * delvbd	    + here->HSM1_gigislsd * delvds;	  Igbtot = here->HSM1_igb;	  cgbhat = Igbtot + here->HSM1_gigbg * delvgd	    - here->HSM1_gigbs * delvds + here->HSM1_gigbb * delvbd;	  Igstot = here->HSM1_igs;	  cgshat = Igstot + here->HSM1_gigsg * delvgd	    - here->HSM1_gigss * delvds + here->HSM1_gigsb * delvbd;	  Igdtot = here->HSM1_igd;	  cgdhat = Igdtot + here->HSM1_gigdg * delvgd	    - here->HSM1_gigds * delvds + here->HSM1_gigdb * delvbd;	}	vds_pre = vds;#ifndef NOBYPASS /* BSIM3 style */	/* now lets see if we can bypass (ugh) */		/* following should be one big if connected by && all over	 * the place, but some C compilers can't handle that, so	 * we split it up here to let them digest it in stages	 */	if ( !(ckt->CKTmode & MODEINITPRED) && ckt->CKTbypass )	  if ( fabs(delvbs) < 	       ( ckt->CKTreltol * 		 MAX(fabs(vbs), fabs(*(ckt->CKTstate0+here->HSM1vbs))) + 		 ckt->CKTvoltTol ) )	    if ( fabs(delvbd) < 		 ( ckt->CKTreltol * 		   MAX(fabs(vbd), fabs(*(ckt->CKTstate0+here->HSM1vbd))) + 		   ckt->CKTvoltTol ) )	      if ( fabs(delvgs) < 		   ( ckt->CKTreltol * 		     MAX(fabs(vgs), fabs(*(ckt->CKTstate0+here->HSM1vgs))) +		     ckt->CKTvoltTol ) )		if ( fabs(delvds) < 		     ( ckt->CKTreltol * 

⌨️ 快捷键说明

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