From f997203c6d071fb525dfd16424bcfc5427451f92 Mon Sep 17 00:00:00 2001 From: h_vogt Date: Fri, 10 Jun 2016 23:03:34 +0200 Subject: [PATCH] add OMP support to BSIM4.5 model --- src/spicelib/devices/bsim4v5/b4v5dest.c | 8 +- src/spicelib/devices/bsim4v5/b4v5ld.c | 419 ++++++++++++++++++++++ src/spicelib/devices/bsim4v5/b4v5set.c | 43 +++ src/spicelib/devices/bsim4v5/bsim4v5def.h | 124 +++++++ 4 files changed, 593 insertions(+), 1 deletion(-) diff --git a/src/spicelib/devices/bsim4v5/b4v5dest.c b/src/spicelib/devices/bsim4v5/b4v5dest.c index d62680e41..7eea05152 100644 --- a/src/spicelib/devices/bsim4v5/b4v5dest.c +++ b/src/spicelib/devices/bsim4v5/b4v5dest.c @@ -44,7 +44,13 @@ BSIM4v5destroy( } if(prev) FREE(prev); } - if(oldmod) FREE(oldmod); + if (oldmod) { +#ifdef USE_OMP + /* free just once for all models */ + FREE(oldmod->BSIM4v5InstanceArray); +#endif + FREE(oldmod); + } *model = NULL; return; } diff --git a/src/spicelib/devices/bsim4v5/b4v5ld.c b/src/spicelib/devices/bsim4v5/b4v5ld.c index cdb8bf55f..6e1549105 100644 --- a/src/spicelib/devices/bsim4v5/b4v5ld.c +++ b/src/spicelib/devices/bsim4v5/b4v5ld.c @@ -50,6 +50,11 @@ } \ } +#ifdef USE_OMP +int BSIM4v5LoadOMP(BSIM4v5instance *here, CKTcircuit *ckt); +void BSIM4v5LoadRhsMat(GENmodel *inModel, CKTcircuit *ckt); +#endif + int BSIM4v5polyDepletion(double phi, double ngate,double coxe, double Vgs, double *Vgs_eff, double *dVgs_eff_dVg); int @@ -57,8 +62,33 @@ BSIM4v5load( GENmodel *inModel, CKTcircuit *ckt) { +#ifdef USE_OMP + int idx; + BSIM4v5model *model = (BSIM4v5model*)inModel; + int error = 0; + BSIM4v5instance **InstArray; + InstArray = model->BSIM4v5InstanceArray; + +#pragma omp parallel for + for (idx = 0; idx < model->BSIM4v5InstCount; idx++) { + BSIM4v5instance *here = InstArray[idx]; + int local_error = BSIM4v5LoadOMP(here, ckt); + if (local_error) + error = local_error; + } + + BSIM4v5LoadRhsMat(inModel, ckt); + + return error; +} + + +int BSIM4v5LoadOMP(BSIM4v5instance *here, CKTcircuit *ckt) { +BSIM4v5model *model = here->BSIM4v5modPtr; +#else BSIM4v5model *model = (BSIM4v5model*)inModel; BSIM4v5instance *here; +#endif double ceqgstot, dgstot_dvd, dgstot_dvg, dgstot_dvs, dgstot_dvb; double ceqgdtot, dgdtot_dvd, dgdtot_dvg, dgdtot_dvs, dgdtot_dvb; @@ -206,10 +236,13 @@ ChargeComputationNeeded = ? 1 : 0; ChargeComputationNeeded = 1; +#ifndef USE_OMP for (; model != NULL; model = model->BSIM4v5nextModel) { for (here = model->BSIM4v5instances; here != NULL; here = here->BSIM4v5nextInstance) { +#endif + Check = Check1 = Check2 = 1; ByPass = 0; pParam = here->pParam; @@ -4534,6 +4567,38 @@ line900: m = here->BSIM4v5m; +#ifdef USE_OMP + here->BSIM4v5rhsdPrime = m * (ceqjd - ceqbd + ceqgdtot + - ceqdrn - ceqqd + Idtoteq); + here->BSIM4v5rhsgPrime = m * (ceqqg - ceqgcrg + Igtoteq); + + if (here->BSIM4v5rgateMod == 2) + here->BSIM4v5rhsgExt = m * ceqgcrg; + else if (here->BSIM4v5rgateMod == 3) + here->BSIM4v5grhsMid = m * (ceqqgmid + ceqgcrg); + + if (!here->BSIM4v5rbodyMod) + { here->BSIM4v5rhsbPrime = m * (ceqbd + ceqbs - ceqjd + - ceqjs - ceqqb + Ibtoteq); + here->BSIM4v5rhssPrime = m * (ceqdrn - ceqbs + ceqjs + + ceqqg + ceqqb + ceqqd + ceqqgmid - ceqgstot + Istoteq); + } + else + { here->BSIM4v5rhsdb = m * (ceqjd + ceqqjd); + here->BSIM4v5rhsbPrime = m * (ceqbd + ceqbs - ceqqb + Ibtoteq); + here->BSIM4v5rhssb = m * (ceqjs + ceqqjs); + here->BSIM4v5rhssPrime = m * (ceqdrn - ceqbs + ceqjs + ceqqd + + ceqqg + ceqqb + ceqqjd + ceqqjs + ceqqgmid - ceqgstot + Istoteq); + } + + if (model->BSIM4v5rdsMod) + { here->BSIM4v5rhsd = m * ceqgdtot; + here->BSIM4v5rhss = m * ceqgstot; + } + + if (here->BSIM4v5trnqsMod) + here->BSIM4v5rhsq = m * (cqcheq - cqdef); +#else (*(ckt->CKTrhs + here->BSIM4v5dNodePrime) += m * (ceqjd - ceqbd + ceqgdtot - ceqdrn - ceqqd + Idtoteq)); (*(ckt->CKTrhs + here->BSIM4v5gNodePrime) -= m * (ceqqg - ceqgcrg + Igtoteq)); @@ -4564,6 +4629,7 @@ line900: if (here->BSIM4v5trnqsMod) *(ckt->CKTrhs + here->BSIM4v5qNode) += m * (cqcheq - cqdef); +#endif /* @@ -4588,6 +4654,165 @@ line900: T1 = qdef * here->BSIM4v5gtau; +#ifdef USE_OMP + if (here->BSIM4v5rgateMod == 1) + { here->BSIM4v5_1 = m * geltd; + here->BSIM4v5_2 = m * geltd; + here->BSIM4v5_3 = m * geltd; + here->BSIM4v5_4 = m * (gcggb + geltd - ggtg + gIgtotg); + here->BSIM4v5_5 = m * (gcgdb - ggtd + gIgtotd); + here->BSIM4v5_6 = m * (gcgsb - ggts + gIgtots); + here->BSIM4v5_7 = m * (gcgbb - ggtb + gIgtotb); + } /* WDLiu: gcrg already subtracted from all gcrgg below */ + else if (here->BSIM4v5rgateMod == 2) + { here->BSIM4v5_8 = m * gcrg; + here->BSIM4v5_9 = m * gcrgg; + here->BSIM4v5_10 = m * gcrgd; + here->BSIM4v5_11 = m * gcrgs; + here->BSIM4v5_12 = m * gcrgb; + + here->BSIM4v5_13 = m * gcrg; + here->BSIM4v5_14 = m * (gcggb - gcrgg - ggtg + gIgtotg); + here->BSIM4v5_15 = m * (gcgdb - gcrgd - ggtd + gIgtotd); + here->BSIM4v5_16 = m * (gcgsb - gcrgs - ggts + gIgtots); + here->BSIM4v5_17 = m * (gcgbb - gcrgb - ggtb + gIgtotb); + } + else if (here->BSIM4v5rgateMod == 3) + { here->BSIM4v5_18 = m * geltd; + here->BSIM4v5_19 = m * geltd; + here->BSIM4v5_20 = m * geltd; + here->BSIM4v5_21 = m * (geltd + gcrg + gcgmgmb); + + here->BSIM4v5_22 = m * (gcrgd + gcgmdb); + here->BSIM4v5_23 = m * gcrgg; + here->BSIM4v5_24 = m * (gcrgs + gcgmsb); + here->BSIM4v5_25 = m * (gcrgb + gcgmbb); + + here->BSIM4v5_26 = m * gcdgmb; + here->BSIM4v5_26 = m * gcrg; + here->BSIM4v5_28 = m * gcsgmb; + here->BSIM4v5_29 = m * gcbgmb; + + here->BSIM4v5_30 = m * (gcggb - gcrgg - ggtg + gIgtotg); + here->BSIM4v5_31 = m * (gcgdb - gcrgd - ggtd + gIgtotd); + here->BSIM4v5_32 = m * (gcgsb - gcrgs - ggts + gIgtots); + here->BSIM4v5_33 = m * (gcgbb - gcrgb - ggtb + gIgtotb); + } + else + { here->BSIM4v5_34 = m * (gcggb - ggtg + gIgtotg); + here->BSIM4v5_35 = m * (gcgdb - ggtd + gIgtotd); + here->BSIM4v5_36 = m * (gcgsb - ggts + gIgtots); + here->BSIM4v5_37 = m * (gcgbb - ggtb + gIgtotb); + } + + if (model->BSIM4v5rdsMod) + { here->BSIM4v5_38 = m * gdtotg; + here->BSIM4v5_39 = m * gdtots; + here->BSIM4v5_40 = m * gdtotb; + here->BSIM4v5_41 = m * gstotd; + here->BSIM4v5_42 = m * gstotg; + here->BSIM4v5_43 = m * gstotb; + } + + here->BSIM4v5_44 = m * (gdpr + here->BSIM4v5gds + here->BSIM4v5gbd + T1 * ddxpart_dVd + - gdtotd + RevSum + gcddb + gbdpdp + dxpart * ggtd - gIdtotd); + here->BSIM4v5_45 = m * (gdpr + gdtot); + here->BSIM4v5_46 = m * (Gm + gcdgb - gdtotg + gbdpg - gIdtotg + + dxpart * ggtg + T1 * ddxpart_dVg); + here->BSIM4v5_47 = m * (here->BSIM4v5gds + gdtots - dxpart * ggts + gIdtots + - T1 * ddxpart_dVs + FwdSum - gcdsb - gbdpsp); + here->BSIM4v5_48 = m * (gjbd + gdtotb - Gmbs - gcdbb - gbdpb + gIdtotb + - T1 * ddxpart_dVb - dxpart * ggtb); + + here->BSIM4v5_49 = m * (gdpr - gdtotd); + here->BSIM4v5_50 = m * (gdpr + gdtot); + + here->BSIM4v5_51 = m * (here->BSIM4v5gds + gstotd + RevSum - gcsdb - gbspdp + - T1 * dsxpart_dVd - sxpart * ggtd + gIstotd); + here->BSIM4v5_52 = m * (gcsgb - Gm - gstotg + gbspg + sxpart * ggtg + + T1 * dsxpart_dVg - gIstotg); + here->BSIM4v5_53 = m * (gspr + here->BSIM4v5gds + here->BSIM4v5gbs + T1 * dsxpart_dVs + - gstots + FwdSum + gcssb + gbspsp + sxpart * ggts - gIstots); + here->BSIM4v5_54 = m * (gspr + gstot); + here->BSIM4v5_55 = m * (gjbs + gstotb + Gmbs - gcsbb - gbspb - sxpart * ggtb + - T1 * dsxpart_dVb + gIstotb); + + here->BSIM4v5_56 = m * (gspr - gstots); + here->BSIM4v5_57 = m * (gspr + gstot); + + here->BSIM4v5_58 = m * (gcbdb - gjbd + gbbdp - gIbtotd); + here->BSIM4v5_59 = m * (gcbgb - here->BSIM4v5gbgs - gIbtotg); + here->BSIM4v5_60 = m * (gcbsb - gjbs + gbbsp - gIbtots); + here->BSIM4v5_61 = m * (gjbd + gjbs + gcbbb - here->BSIM4v5gbbs - gIbtotb); + + ggidld = here->BSIM4v5ggidld; + ggidlg = here->BSIM4v5ggidlg; + ggidlb = here->BSIM4v5ggidlb; + ggislg = here->BSIM4v5ggislg; + ggisls = here->BSIM4v5ggisls; + ggislb = here->BSIM4v5ggislb; + + /* stamp gidl */ + here->BSIM4v5_62 = m * ggidld; + here->BSIM4v5_63 = m * ggidlg; + here->BSIM4v5_64 = m * (ggidlg + ggidld + ggidlb); + here->BSIM4v5_65 = m * ggidlb; + here->BSIM4v5_66 = m * ggidld; + here->BSIM4v5_67 = m * ggidlg; + here->BSIM4v5_68 = m * (ggidlg + ggidld + ggidlb); + here->BSIM4v5_69 = m * ggidlb; + /* stamp gisl */ + here->BSIM4v5_70 = m * (ggisls + ggislg + ggislb); + here->BSIM4v5_71 = m * ggislg; + here->BSIM4v5_72 = m * ggisls; + here->BSIM4v5_73 = m * ggislb; + here->BSIM4v5_74 = m * (ggislg + ggisls + ggislb); + here->BSIM4v5_75 = m * ggislg; + here->BSIM4v5_76 = m * ggisls; + here->BSIM4v5_77 = m * ggislb; + + if (here->BSIM4v5rbodyMod) + { here->BSIM4v5_78 = m * (gcdbdb - here->BSIM4v5gbd); + here->BSIM4v5_79 = m * (here->BSIM4v5gbs - gcsbsb); + + here->BSIM4v5_80 = m * (gcdbdb - here->BSIM4v5gbd); + here->BSIM4v5_81 = m * (here->BSIM4v5gbd - gcdbdb + + here->BSIM4v5grbpd + here->BSIM4v5grbdb); + here->BSIM4v5_82 = m * here->BSIM4v5grbpd; + here->BSIM4v5_83 = m * here->BSIM4v5grbdb; + + here->BSIM4v5_84 = m * here->BSIM4v5grbpd; + here->BSIM4v5_85 = m * here->BSIM4v5grbpb; + here->BSIM4v5_86 = m * here->BSIM4v5grbps; + here->BSIM4v5_87 = m * (here->BSIM4v5grbpd + here->BSIM4v5grbps + + here->BSIM4v5grbpb); + /* WDLiu: (gcbbb - here->BSIM4v5gbbs) already added to BPbpPtr */ + + here->BSIM4v5_88 = m * (gcsbsb - here->BSIM4v5gbs); + here->BSIM4v5_89 = m * here->BSIM4v5grbps; + here->BSIM4v5_90 = m * here->BSIM4v5grbsb; + here->BSIM4v5_91 = m * (here->BSIM4v5gbs - gcsbsb + + here->BSIM4v5grbps + here->BSIM4v5grbsb); + + here->BSIM4v5_92 = m * here->BSIM4v5grbdb; + here->BSIM4v5_93 = m * here->BSIM4v5grbpb; + here->BSIM4v5_94 = m * here->BSIM4v5grbsb; + here->BSIM4v5_95 = m * (here->BSIM4v5grbsb + here->BSIM4v5grbdb + + here->BSIM4v5grbpb); + } + + if (here->BSIM4v5trnqsMod) + { here->BSIM4v5_96 = m * (gqdef + here->BSIM4v5gtau); + here->BSIM4v5_97 = m * (ggtg - gcqgb); + here->BSIM4v5_98 = m * (ggtd - gcqdb); + here->BSIM4v5_99 = m * (ggts - gcqsb); + here->BSIM4v5_100 = m * (ggtb - gcqbb); + + here->BSIM4v5_101 = m * dxpart * here->BSIM4v5gtau; + here->BSIM4v5_102 = m * sxpart * here->BSIM4v5gtau; + here->BSIM4v5_103 = m * here->BSIM4v5gtau; + } +#else if (here->BSIM4v5rgateMod == 1) { (*(here->BSIM4v5GEgePtr) += m * geltd); (*(here->BSIM4v5GPgePtr) -= m * geltd); @@ -4747,15 +4972,209 @@ line900: (*(here->BSIM4v5SPqPtr) += m * sxpart * here->BSIM4v5gtau); (*(here->BSIM4v5GPqPtr) -= m * here->BSIM4v5gtau); } +#endif line1000: ; +#ifndef USE_OMP } /* End of MOSFET Instance */ } /* End of Model Instance */ +#endif return(OK); } + +#ifdef USE_OMP +void BSIM4v5LoadRhsMat(GENmodel *inModel, CKTcircuit *ckt) +{ + int InstCount, idx; + BSIM4v5instance **InstArray; + BSIM4v5instance *here; + BSIM4v5model *model = (BSIM4v5model*)inModel; + + InstArray = model->BSIM4v5InstanceArray; + InstCount = model->BSIM4v5InstCount; + + for(idx = 0; idx < InstCount; idx++) { + here = InstArray[idx]; + /* Update b for Ax = b */ + (*(ckt->CKTrhs + here->BSIM4v5dNodePrime) += here->BSIM4v5rhsdPrime); + (*(ckt->CKTrhs + here->BSIM4v5gNodePrime) -= here->BSIM4v5rhsgPrime); + + if (here->BSIM4v5rgateMod == 2) + (*(ckt->CKTrhs + here->BSIM4v5gNodeExt) -= here->BSIM4v5rhsgExt); + else if (here->BSIM4v5rgateMod == 3) + (*(ckt->CKTrhs + here->BSIM4v5gNodeMid) -= here->BSIM4v5grhsMid); + + if (!here->BSIM4v5rbodyMod) + { (*(ckt->CKTrhs + here->BSIM4v5bNodePrime) += here->BSIM4v5rhsbPrime); + (*(ckt->CKTrhs + here->BSIM4v5sNodePrime) += here->BSIM4v5rhssPrime); + } + else + { (*(ckt->CKTrhs + here->BSIM4v5dbNode) -= here->BSIM4v5rhsdb); + (*(ckt->CKTrhs + here->BSIM4v5bNodePrime) += here->BSIM4v5rhsbPrime); + (*(ckt->CKTrhs + here->BSIM4v5sbNode) -= here->BSIM4v5rhssb); + (*(ckt->CKTrhs + here->BSIM4v5sNodePrime) += here->BSIM4v5rhssPrime); + } + + if (model->BSIM4v5rdsMod) + { (*(ckt->CKTrhs + here->BSIM4v5dNode) -= here->BSIM4v5rhsd); + (*(ckt->CKTrhs + here->BSIM4v5sNode) += here->BSIM4v5rhss); + } + + if (here->BSIM4v5trnqsMod) + *(ckt->CKTrhs + here->BSIM4v5qNode) += here->BSIM4v5rhsq; + + + /* Update A for Ax = b */ + if (here->BSIM4v5rgateMod == 1) + { (*(here->BSIM4v5GEgePtr) += here->BSIM4v5_1); + (*(here->BSIM4v5GPgePtr) -= here->BSIM4v5_2); + (*(here->BSIM4v5GEgpPtr) -= here->BSIM4v5_3); + (*(here->BSIM4v5GPgpPtr) += here->BSIM4v5_4); + (*(here->BSIM4v5GPdpPtr) += here->BSIM4v5_5); + (*(here->BSIM4v5GPspPtr) += here->BSIM4v5_6); + (*(here->BSIM4v5GPbpPtr) += here->BSIM4v5_7); + } + else if (here->BSIM4v5rgateMod == 2) + { (*(here->BSIM4v5GEgePtr) += here->BSIM4v5_8); + (*(here->BSIM4v5GEgpPtr) += here->BSIM4v5_9); + (*(here->BSIM4v5GEdpPtr) += here->BSIM4v5_10); + (*(here->BSIM4v5GEspPtr) += here->BSIM4v5_11); + (*(here->BSIM4v5GEbpPtr) += here->BSIM4v5_12); + + (*(here->BSIM4v5GPgePtr) -= here->BSIM4v5_13); + (*(here->BSIM4v5GPgpPtr) += here->BSIM4v5_14); + (*(here->BSIM4v5GPdpPtr) += here->BSIM4v5_15); + (*(here->BSIM4v5GPspPtr) += here->BSIM4v5_16); + (*(here->BSIM4v5GPbpPtr) += here->BSIM4v5_17); + } + else if (here->BSIM4v5rgateMod == 3) + { (*(here->BSIM4v5GEgePtr) += here->BSIM4v5_18); + (*(here->BSIM4v5GEgmPtr) -= here->BSIM4v5_19); + (*(here->BSIM4v5GMgePtr) -= here->BSIM4v5_20); + (*(here->BSIM4v5GMgmPtr) += here->BSIM4v5_21); + + (*(here->BSIM4v5GMdpPtr) += here->BSIM4v5_22); + (*(here->BSIM4v5GMgpPtr) += here->BSIM4v5_23); + (*(here->BSIM4v5GMspPtr) += here->BSIM4v5_24); + (*(here->BSIM4v5GMbpPtr) += here->BSIM4v5_25); + + (*(here->BSIM4v5DPgmPtr) += here->BSIM4v5_26); + (*(here->BSIM4v5GPgmPtr) -= here->BSIM4v5_27); + (*(here->BSIM4v5SPgmPtr) += here->BSIM4v5_28); + (*(here->BSIM4v5BPgmPtr) += here->BSIM4v5_29); + + (*(here->BSIM4v5GPgpPtr) += here->BSIM4v5_30); + (*(here->BSIM4v5GPdpPtr) += here->BSIM4v5_31); + (*(here->BSIM4v5GPspPtr) += here->BSIM4v5_32); + (*(here->BSIM4v5GPbpPtr) += here->BSIM4v5_33); + } + + + else + { (*(here->BSIM4v5GPgpPtr) += here->BSIM4v5_34); + (*(here->BSIM4v5GPdpPtr) += here->BSIM4v5_35); + (*(here->BSIM4v5GPspPtr) += here->BSIM4v5_36); + (*(here->BSIM4v5GPbpPtr) += here->BSIM4v5_37); + } + + + if (model->BSIM4v5rdsMod) + { (*(here->BSIM4v5DgpPtr) += here->BSIM4v5_38); + (*(here->BSIM4v5DspPtr) += here->BSIM4v5_39); + (*(here->BSIM4v5DbpPtr) += here->BSIM4v5_40); + (*(here->BSIM4v5SdpPtr) += here->BSIM4v5_41); + (*(here->BSIM4v5SgpPtr) += here->BSIM4v5_42); + (*(here->BSIM4v5SbpPtr) += here->BSIM4v5_43); + } + + (*(here->BSIM4v5DPdpPtr) += here->BSIM4v5_44); + (*(here->BSIM4v5DPdPtr) -= here->BSIM4v5_45); + (*(here->BSIM4v5DPgpPtr) += here->BSIM4v5_46); + (*(here->BSIM4v5DPspPtr) -= here->BSIM4v5_47); + (*(here->BSIM4v5DPbpPtr) -= here->BSIM4v5_48); + + (*(here->BSIM4v5DdpPtr) -= here->BSIM4v5_49); + (*(here->BSIM4v5DdPtr) += here->BSIM4v5_50); + + (*(here->BSIM4v5SPdpPtr) -= here->BSIM4v5_51); + (*(here->BSIM4v5SPgpPtr) += here->BSIM4v5_52); + (*(here->BSIM4v5SPspPtr) += here->BSIM4v5_53); + (*(here->BSIM4v5SPsPtr) -= here->BSIM4v5_54); + (*(here->BSIM4v5SPbpPtr) -= here->BSIM4v5_55); + + (*(here->BSIM4v5SspPtr) -= here->BSIM4v5_56); + (*(here->BSIM4v5SsPtr) += here->BSIM4v5_57); + + (*(here->BSIM4v5BPdpPtr) += here->BSIM4v5_58); + (*(here->BSIM4v5BPgpPtr) += here->BSIM4v5_59); + (*(here->BSIM4v5BPspPtr) += here->BSIM4v5_60); + (*(here->BSIM4v5BPbpPtr) += here->BSIM4v5_61); + + /* stamp gidl */ + (*(here->BSIM4v5DPdpPtr) += here->BSIM4v5_62); + (*(here->BSIM4v5DPgpPtr) += here->BSIM4v5_63); + (*(here->BSIM4v5DPspPtr) -= here->BSIM4v5_64); + (*(here->BSIM4v5DPbpPtr) += here->BSIM4v5_65); + (*(here->BSIM4v5BPdpPtr) -= here->BSIM4v5_66); + (*(here->BSIM4v5BPgpPtr) -= here->BSIM4v5_67); + (*(here->BSIM4v5BPspPtr) += here->BSIM4v5_68); + (*(here->BSIM4v5BPbpPtr) -= here->BSIM4v5_69); + /* stamp gisl */ + (*(here->BSIM4v5SPdpPtr) -= here->BSIM4v5_70); + (*(here->BSIM4v5SPgpPtr) += here->BSIM4v5_71); + (*(here->BSIM4v5SPspPtr) += here->BSIM4v5_72); + (*(here->BSIM4v5SPbpPtr) += here->BSIM4v5_73); + (*(here->BSIM4v5BPdpPtr) += here->BSIM4v5_74); + (*(here->BSIM4v5BPgpPtr) -= here->BSIM4v5_75); + (*(here->BSIM4v5BPspPtr) -= here->BSIM4v5_76); + (*(here->BSIM4v5BPbpPtr) -= here->BSIM4v5_77); + + + if (here->BSIM4v5rbodyMod) + { (*(here->BSIM4v5DPdbPtr) += here->BSIM4v5_78); + (*(here->BSIM4v5SPsbPtr) -= here->BSIM4v5_79); + + (*(here->BSIM4v5DBdpPtr) += here->BSIM4v5_80); + (*(here->BSIM4v5DBdbPtr) += here->BSIM4v5_81); + (*(here->BSIM4v5DBbpPtr) -= here->BSIM4v5_82); + (*(here->BSIM4v5DBbPtr) -= here->BSIM4v5_83); + + (*(here->BSIM4v5BPdbPtr) -= here->BSIM4v5_84); + (*(here->BSIM4v5BPbPtr) -= here->BSIM4v5_85); + (*(here->BSIM4v5BPsbPtr) -= here->BSIM4v5_86); + (*(here->BSIM4v5BPbpPtr) += here->BSIM4v5_87); + + (*(here->BSIM4v5SBspPtr) += here->BSIM4v5_88); + (*(here->BSIM4v5SBbpPtr) -= here->BSIM4v5_89); + (*(here->BSIM4v5SBbPtr) -= here->BSIM4v5_90); + (*(here->BSIM4v5SBsbPtr) += here->BSIM4v5_91); + + (*(here->BSIM4v5BdbPtr) -= here->BSIM4v5_92); + (*(here->BSIM4v5BbpPtr) -= here->BSIM4v5_93); + (*(here->BSIM4v5BsbPtr) -= here->BSIM4v5_94); + (*(here->BSIM4v5BbPtr) += here->BSIM4v5_95); + } + + if (here->BSIM4v5trnqsMod) + { (*(here->BSIM4v5QqPtr) += here->BSIM4v5_96); + (*(here->BSIM4v5QgpPtr) += here->BSIM4v5_97); + (*(here->BSIM4v5QdpPtr) += here->BSIM4v5_98); + (*(here->BSIM4v5QspPtr) += here->BSIM4v5_99); + (*(here->BSIM4v5QbpPtr) += here->BSIM4v5_100); + + (*(here->BSIM4v5DPqPtr) += here->BSIM4v5_101); + (*(here->BSIM4v5SPqPtr) += here->BSIM4v5_102); + (*(here->BSIM4v5GPqPtr) -= here->BSIM4v5_103); + } + } +} + +#endif + + /* function to compute poly depletion effect */ int BSIM4v5polyDepletion( double phi, diff --git a/src/spicelib/devices/bsim4v5/b4v5set.c b/src/spicelib/devices/bsim4v5/b4v5set.c index bb3df430e..a803aa278 100644 --- a/src/spicelib/devices/bsim4v5/b4v5set.c +++ b/src/spicelib/devices/bsim4v5/b4v5set.c @@ -24,6 +24,10 @@ #include "ngspice/sperror.h" #include "ngspice/suffix.h" +#ifdef USE_OMP +#include "ngspice/cpextern.h" +#endif + #define MAX_EXP 5.834617425e14 #define MIN_EXP 1.713908431e-15 #define EXP_THRESHOLD 34.0 @@ -48,6 +52,11 @@ int noiseAnalGiven = 0, createNode; /* Criteria for new node creation */ double Rtot, DMCGeff, DMCIeff, DMDGeff; JOB *job; +#ifdef USE_OMP +int idx, InstCount; +BSIM4v5instance **InstArray; +#endif + /* Search for a noise analysis request */ for (job = ft_curckt->ci_curTask->jobs; job; job = job->JOBnextJob) { if(strcmp(job->JOBname,"Noise Analysis")==0) { @@ -2072,6 +2081,40 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ } } } + +#ifdef USE_OMP + InstCount = 0; + model = (BSIM4v5model*)inModel; + /* loop through all the BSIM4v6 device models + to count the number of instances */ + + for (; model != NULL; model = model->BSIM4v5nextModel) + { + /* loop through all the instances of the model */ + for (here = model->BSIM4v5instances; here != NULL; + here = here->BSIM4v5nextInstance) + { + InstCount++; + } + } + InstArray = TMALLOC(BSIM4v5instance*, InstCount); + model = (BSIM4v5model*)inModel; + idx = 0; + for (; model != NULL; model = model->BSIM4v5nextModel) + { + /* loop through all the instances of the model */ + for (here = model->BSIM4v5instances; here != NULL; + here = here->BSIM4v5nextInstance) + { + InstArray[idx] = here; + idx++; + } + /* set the array pointer and instance count into each model */ + model->BSIM4v5InstCount = InstCount; + model->BSIM4v5InstanceArray = InstArray; + } +#endif + return(OK); } diff --git a/src/spicelib/devices/bsim4v5/bsim4v5def.h b/src/spicelib/devices/bsim4v5/bsim4v5def.h index e20a53e67..b860ef18d 100644 --- a/src/spicelib/devices/bsim4v5/bsim4v5def.h +++ b/src/spicelib/devices/bsim4v5/bsim4v5def.h @@ -376,6 +376,125 @@ typedef struct sBSIM4v5instance double *BSIM4v5GPqPtr; double *BSIM4v5SPqPtr; +#ifdef USE_OMP + /* per instance storage of results, to update matrix at a later stge */ + double BSIM4v5rhsdPrime; + double BSIM4v5rhsgPrime; + double BSIM4v5rhsgExt; + double BSIM4v5grhsMid; + double BSIM4v5rhsbPrime; + double BSIM4v5rhssPrime; + double BSIM4v5rhsdb; + double BSIM4v5rhssb; + double BSIM4v5rhsd; + double BSIM4v5rhss; + double BSIM4v5rhsq; + + double BSIM4v5_1; + double BSIM4v5_2; + double BSIM4v5_3; + double BSIM4v5_4; + double BSIM4v5_5; + double BSIM4v5_6; + double BSIM4v5_7; + double BSIM4v5_8; + double BSIM4v5_9; + double BSIM4v5_10; + double BSIM4v5_11; + double BSIM4v5_12; + double BSIM4v5_13; + double BSIM4v5_14; + double BSIM4v5_15; + double BSIM4v5_16; + double BSIM4v5_17; + double BSIM4v5_18; + double BSIM4v5_19; + double BSIM4v5_20; + double BSIM4v5_21; + double BSIM4v5_22; + double BSIM4v5_23; + double BSIM4v5_24; + double BSIM4v5_25; + double BSIM4v5_26; + double BSIM4v5_27; + double BSIM4v5_28; + double BSIM4v5_29; + double BSIM4v5_30; + double BSIM4v5_31; + double BSIM4v5_32; + double BSIM4v5_33; + double BSIM4v5_34; + double BSIM4v5_35; + double BSIM4v5_36; + double BSIM4v5_37; + double BSIM4v5_38; + double BSIM4v5_39; + double BSIM4v5_40; + double BSIM4v5_41; + double BSIM4v5_42; + double BSIM4v5_43; + double BSIM4v5_44; + double BSIM4v5_45; + double BSIM4v5_46; + double BSIM4v5_47; + double BSIM4v5_48; + double BSIM4v5_49; + double BSIM4v5_50; + double BSIM4v5_51; + double BSIM4v5_52; + double BSIM4v5_53; + double BSIM4v5_54; + double BSIM4v5_55; + double BSIM4v5_56; + double BSIM4v5_57; + double BSIM4v5_58; + double BSIM4v5_59; + double BSIM4v5_60; + double BSIM4v5_61; + double BSIM4v5_62; + double BSIM4v5_63; + double BSIM4v5_64; + double BSIM4v5_65; + double BSIM4v5_66; + double BSIM4v5_67; + double BSIM4v5_68; + double BSIM4v5_69; + double BSIM4v5_70; + double BSIM4v5_71; + double BSIM4v5_72; + double BSIM4v5_73; + double BSIM4v5_74; + double BSIM4v5_75; + double BSIM4v5_76; + double BSIM4v5_77; + double BSIM4v5_78; + double BSIM4v5_79; + double BSIM4v5_80; + double BSIM4v5_81; + double BSIM4v5_82; + double BSIM4v5_83; + double BSIM4v5_84; + double BSIM4v5_85; + double BSIM4v5_86; + double BSIM4v5_87; + double BSIM4v5_88; + double BSIM4v5_89; + double BSIM4v5_90; + double BSIM4v5_91; + double BSIM4v5_92; + double BSIM4v5_93; + double BSIM4v5_94; + double BSIM4v5_95; + double BSIM4v5_96; + double BSIM4v5_97; + double BSIM4v5_98; + double BSIM4v5_99; + double BSIM4v5_100; + double BSIM4v5_101; + double BSIM4v5_102; + double BSIM4v5_103; + +#endif #define BSIM4v5vbd BSIM4v5states+ 0 #define BSIM4v5vbs BSIM4v5states+ 1 @@ -1482,6 +1601,11 @@ typedef struct sBSIM4v5model struct bsim4v5SizeDependParam *pSizeDependParamKnot; +#ifdef USE_OMP + int BSIM4v5InstCount; + struct sBSIM4v5instance **BSIM4v5InstanceArray; +#endif + /* Flags */ unsigned BSIM4v5rgeomodGiven :1; unsigned BSIM4v5stimodGiven :1;