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 + -
显示快捷键?