OpenMP support for BSIM4, slight upgrade of OpenMP for BSIM3

This commit is contained in:
h_vogt 2010-06-28 17:51:55 +00:00
parent b1151b4934
commit a62db6942b
7 changed files with 689 additions and 65 deletions

View File

@ -1,8 +1,13 @@
2010-06-28 Holger Vogt
* bsim3/b3set.c b3ld.c bsim3def.h: new preproc flag USE_OMP3
* bsim4/b4set.c b4ld.c bsim4def.h: OpenMP support for BSIM4 model
2010-06-27 Robert Larice
* src/xspice/enh/enhtrans.c:
drop useless cast of a copy() return value
2010-06-23 Holger Vogt
2010-06-27 Holger Vogt
* numparam.h: short replaced by int
2010-06-27 Robert Larice

View File

@ -1,4 +1,5 @@
/**** BSIM3v3.3.0, Released by Xuemei Xi 07/29/2005 ****/
/**** OpenMP support for ngspice by Holger Vogt 06/28/2010 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
@ -31,7 +32,7 @@
#define DELTA_3 0.02
#define DELTA_4 0.02
#ifdef USE_OMP
#ifdef USE_OMP3
int BSIM3LoadOMP(BSIM3instance *here, CKTcircuit *ckt);
void BSIM3LoadRhsMat(GENmodel *inModel, CKTcircuit *ckt);
extern int nthreads;
@ -43,7 +44,7 @@ BSIM3load(
GENmodel *inModel,
CKTcircuit *ckt)
{
#ifdef USE_OMP
#ifdef USE_OMP3
int idx;
BSIM3model *model = (BSIM3model*)inModel;
int good = 0;
@ -166,7 +167,7 @@ struct bsim3SizeDependParam *pParam;
int ByPass, Check, ChargeComputationNeeded, error;
/* double junk[50]; */
#ifdef USE_OMP
#ifdef USE_OMP3
model = here->BSIM3modPtr;
#endif
@ -175,7 +176,7 @@ ChargeComputationNeeded =
((ckt->CKTmode & (MODEAC | MODETRAN | MODEINITSMSIG)) ||
((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)))
? 1 : 0;
#ifndef USE_OMP
#ifndef USE_OMP3
for (; model != NULL; model = model->BSIM3nextModel)
{ for (here = model->BSIM3instances; here != NULL;
here = here->BSIM3nextInstance)
@ -2925,7 +2926,7 @@ line900:
}
m = here->BSIM3m;
#ifdef USE_OMP
#ifdef USE_OMP3
here->BSIM3rhsG = m * ceqqg;
here->BSIM3rhsB = m * (ceqbs + ceqbd + ceqqb);
here->BSIM3rhsD = m * (ceqbd - cdreq - ceqqd);
@ -2947,7 +2948,7 @@ line900:
*/
T1 = qdef * here->BSIM3gtau;
#ifdef USE_OMP
#ifdef USE_OMP3
here->BSIM3DdPt = m * here->BSIM3drainConductance;
here->BSIM3GgPt = m * (gcggb - ggtg);
here->BSIM3SsPt = m * here->BSIM3sourceConductance;
@ -3051,14 +3052,14 @@ line900:
}
#endif
line1000: ;
#ifndef USE_OMP
#ifndef USE_OMP3
} /* End of Mosfet Instance */
} /* End of Model Instance */
#endif
return(OK);
}
#ifdef USE_OMP
#ifdef USE_OMP3
void BSIM3LoadRhsMat(GENmodel *inModel, CKTcircuit *ckt)
{
unsigned int InstCount, idx;

View File

@ -1,4 +1,5 @@
/**** BSIM3v3.3.0, Released by Xuemei Xi 07/29/2005 ****/
/**** OpenMP support for ngspice by Holger Vogt 06/28/2010 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
@ -15,7 +16,7 @@
#include "const.h"
#include "sperror.h"
#include "suffix.h"
#ifdef USE_OMP
#ifdef USE_OMP3
int nthreads;
extern bool cp_getvar(char *name, int type, void *retval);
#define VT_NUM 1
@ -45,7 +46,7 @@ CKTnode *tmp;
CKTnode *tmpNode;
IFuid tmpName;
#ifdef USE_OMP
#ifdef USE_OMP3
unsigned int idx, InstCount;
BSIM3instance **InstArray;
int nthreads;
@ -1009,9 +1010,9 @@ if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\
}
}
#ifdef USE_OMP
#ifdef USE_OMP3
if (!cp_getvar("num_threads", VT_NUM, (char *) &nthreads))
nthreads = 4;
nthreads = 2;
omp_set_num_threads(nthreads);
if (nthreads == 1)

View File

@ -3,6 +3,7 @@ Copyright 2004 Regents of the University of California. All rights reserved.
Author: 1995 Min-Chie Jeng and Mansun Chan.
Author: 1997-1999 Weidong Liu.
Author: 2001- Xuemei Xi
**** OpenMP support for ngspice by Holger Vogt 06/28/2010 ****
File: bsim3def.h
**********/
@ -15,9 +16,11 @@ File: bsim3def.h
#include "complex.h"
#include "noisedef.h"
//#define USE_OMP
#ifdef USE_OMP
#define USE_OMP3
#endif
#ifdef USE_OMP3
#include <omp.h>
#endif
@ -169,7 +172,7 @@ typedef struct sBSIM3instance
double *BSIM3SPqPtr;
double *BSIM3BqPtr;
#ifdef USE_OMP
#ifdef USE_OMP3
/* per instance storage of results, to update matrix at a later stge */
double BSIM3rhsG;
double BSIM3rhsB;
@ -844,7 +847,7 @@ typedef struct sBSIM3model
struct bsim3SizeDependParam *pSizeDependParamKnot;
#ifdef USE_OMP
#ifdef USE_OMP3
int BSIM3InstCount;
struct sBSIM3instance **BSIM3InstanceArray;
#endif

View File

@ -1,5 +1,6 @@
/**** BSIM4.6.2 Released by Wenwei Yang 07/31/2008****/
/**** BSIM4.6.5 Update ngspice 09/22/2009 ****/
/**** OpenMP support ngspice 06/28/2010 ****/
/**********
* Copyright 2006 Regents of the University of California. All rights reserved.
* File: b4ld.c of BSIM4.6.2.
@ -29,6 +30,7 @@
#include "sperror.h"
#include "devdefs.h"
#include "suffix.h"
/*
#define MAX_EXP 2.688117142e+43
#define MIN_EXP 3.720075976e-44
@ -58,6 +60,13 @@
} \
}
#ifdef USE_OMP4
int BSIM4LoadOMP(BSIM4instance *here, CKTcircuit *ckt);
void BSIM4LoadRhsMat(GENmodel *inModel, CKTcircuit *ckt);
extern int nthreads;
#endif
int BSIM4polyDepletion(double phi, double ngate,double epsgate, double coxe, double Vgs, double *Vgs_eff, double *dVgs_eff_dVg);
int
@ -65,9 +74,32 @@ BSIM4load(
GENmodel *inModel,
CKTcircuit *ckt)
{
#ifdef USE_OMP4
int idx;
BSIM4model *model = (BSIM4model*)inModel;
int good = 0;
BSIM4instance *here;
BSIM4instance **InstArray;
InstArray = model->BSIM4InstanceArray;
#pragma omp parallel for num_threads(nthreads) private(here)
for (idx = 0; idx < model->BSIM4InstCount; idx++) {
here = InstArray[idx];
good = BSIM4LoadOMP(here, ckt);
}
BSIM4LoadRhsMat(inModel, ckt);
return good;
}
int BSIM4LoadOMP(BSIM4instance *here, CKTcircuit *ckt) {
BSIM4model *model;
#else
BSIM4model *model = (BSIM4model*)inModel;
BSIM4instance *here;
#endif
double ceqgstot, dgstot_dvd, dgstot_dvg, dgstot_dvs, dgstot_dvb;
double ceqgdtot, dgdtot_dvd, dgdtot_dvg, dgdtot_dvs, dgdtot_dvb;
double gstot, gstotd, gstotg, gstots, gstotb, gspr, Rs, Rd;
@ -206,16 +238,23 @@ int ByPass, ChargeComputationNeeded, error, Check, Check1, Check2;
double m;
#ifdef USE_OMP4
model = here->BSIM4modPtr;
#endif
ScalingFactor = 1.0e-9;
ChargeComputationNeeded =
((ckt->CKTmode & (MODEAC | MODETRAN | MODEINITSMSIG)) ||
((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)))
? 1 : 0;
#ifndef USE_OMP4
for (; model != NULL; model = model->BSIM4nextModel)
{ for (here = model->BSIM4instances; here != NULL;
here = here->BSIM4nextInstance)
{ if (here->BSIM4owner != ARCHme) continue;
#endif
Check = Check1 = Check2 = 1;
ByPass = 0;
pParam = here->pParam;
@ -4708,6 +4747,38 @@ line900:
m = here->BSIM4m;
#ifdef USE_OMP4
here->BSIM4rhsdPrime = m * (ceqjd - ceqbd + ceqgdtot
- ceqdrn - ceqqd + Idtoteq);
here->BSIM4rhsgPrime = m * (ceqqg - ceqgcrg + Igtoteq);
if (here->BSIM4rgateMod == 2)
here->BSIM4rhsgExt = m * ceqgcrg;
else if (here->BSIM4rgateMod == 3)
here->BSIM4grhsMid = m * (ceqqgmid + ceqgcrg);
if (!here->BSIM4rbodyMod)
{ here->BSIM4rhsbPrime = m * (ceqbd + ceqbs - ceqjd
- ceqjs - ceqqb + Ibtoteq);
here->BSIM4rhssPrime = m * (ceqdrn - ceqbs + ceqjs
+ ceqqg + ceqqb + ceqqd + ceqqgmid - ceqgstot + Istoteq);
}
else
{ here->BSIM4rhsdb = m * (ceqjd + ceqqjd);
here->BSIM4rhsbPrime = m * (ceqbd + ceqbs - ceqqb + Ibtoteq);
here->BSIM4rhssb = m * (ceqjs + ceqqjs);
here->BSIM4rhssPrime = m * (ceqdrn - ceqbs + ceqjs + ceqqd
+ ceqqg + ceqqb + ceqqjd + ceqqjs + ceqqgmid - ceqgstot + Istoteq);
}
if (model->BSIM4rdsMod)
{ here->BSIM4rhsd = m * ceqgdtot;
here->BSIM4rhss = m * ceqgstot;
}
if (here->BSIM4trnqsMod)
here->BSIM4rhsq = m * (cqcheq - cqdef);
#else
(*(ckt->CKTrhs + here->BSIM4dNodePrime) += m * (ceqjd - ceqbd + ceqgdtot
- ceqdrn - ceqqd + Idtoteq));
(*(ckt->CKTrhs + here->BSIM4gNodePrime) -= m * (ceqqg - ceqgcrg + Igtoteq));
@ -4723,6 +4794,7 @@ line900:
(*(ckt->CKTrhs + here->BSIM4sNodePrime) += m * (ceqdrn - ceqbs + ceqjs
+ ceqqg + ceqqb + ceqqd + ceqqgmid - ceqgstot + Istoteq));
}
else
{ (*(ckt->CKTrhs + here->BSIM4dbNode) -= m * (ceqjd + ceqqjd));
(*(ckt->CKTrhs + here->BSIM4bNodePrime) += m * (ceqbd + ceqbs - ceqqb + Ibtoteq));
@ -4738,7 +4810,7 @@ line900:
if (here->BSIM4trnqsMod)
*(ckt->CKTrhs + here->BSIM4qNode) += m * (cqcheq - cqdef);
#endif
/*
* Loading matrix
@ -4761,7 +4833,167 @@ line900:
geltd = here->BSIM4grgeltd;
T1 = qdef * here->BSIM4gtau;
#ifdef USE_OMP4
if (here->BSIM4rgateMod == 1)
{ here->BSIM4_1 = m * geltd;
here->BSIM4_2 = m * geltd;
here->BSIM4_3 = m * geltd;
here->BSIM4_4 = m * (gcggb + geltd - ggtg + gIgtotg);
here->BSIM4_5 = m * (gcgdb - ggtd + gIgtotd);
here->BSIM4_6 = m * (gcgsb - ggts + gIgtots);
here->BSIM4_7 = m * (gcgbb - ggtb + gIgtotb);
} /* WDLiu: gcrg already subtracted from all gcrgg below */
else if (here->BSIM4rgateMod == 2)
{ here->BSIM4_8 = m * gcrg;
here->BSIM4_9 = m * gcrgg;
here->BSIM4_10 = m * gcrgd;
here->BSIM4_11 = m * gcrgs;
here->BSIM4_12 = m * gcrgb;
here->BSIM4_13 = m * gcrg;
here->BSIM4_14 = m * (gcggb - gcrgg - ggtg + gIgtotg);
here->BSIM4_15 = m * (gcgdb - gcrgd - ggtd + gIgtotd);
here->BSIM4_16 = m * (gcgsb - gcrgs - ggts + gIgtots);
here->BSIM4_17 = m * (gcgbb - gcrgb - ggtb + gIgtotb);
}
else if (here->BSIM4rgateMod == 3)
{ here->BSIM4_18 = m * geltd;
here->BSIM4_19 = m * geltd;
here->BSIM4_20 = m * geltd;
here->BSIM4_21 = m * (geltd + gcrg + gcgmgmb);
here->BSIM4_22 = m * (gcrgd + gcgmdb);
here->BSIM4_23 = m * gcrgg;
here->BSIM4_24 = m * (gcrgs + gcgmsb);
here->BSIM4_25 = m * (gcrgb + gcgmbb);
here->BSIM4_26 = m * gcdgmb;
here->BSIM4_26 = m * gcrg;
here->BSIM4_28 = m * gcsgmb;
here->BSIM4_29 = m * gcbgmb;
here->BSIM4_30 = m * (gcggb - gcrgg - ggtg + gIgtotg);
here->BSIM4_31 = m * (gcgdb - gcrgd - ggtd + gIgtotd);
here->BSIM4_32 = m * (gcgsb - gcrgs - ggts + gIgtots);
here->BSIM4_33 = m * (gcgbb - gcrgb - ggtb + gIgtotb);
}
else
{ here->BSIM4_34 = m * (gcggb - ggtg + gIgtotg);
here->BSIM4_35 = m * (gcgdb - ggtd + gIgtotd);
here->BSIM4_36 = m * (gcgsb - ggts + gIgtots);
here->BSIM4_37 = m * (gcgbb - ggtb + gIgtotb);
}
if (model->BSIM4rdsMod)
{ here->BSIM4_38 = m * gdtotg;
here->BSIM4_39 = m * gdtots;
here->BSIM4_40 = m * gdtotb;
here->BSIM4_41 = m * gstotd;
here->BSIM4_42 = m * gstotg;
here->BSIM4_43 = m * gstotb;
}
here->BSIM4_44 = m * (gdpr + here->BSIM4gds + here->BSIM4gbd + T1 * ddxpart_dVd
- gdtotd + RevSum + gcddb + gbdpdp + dxpart * ggtd - gIdtotd);
here->BSIM4_45 = m * (gdpr + gdtot);
here->BSIM4_46 = m * (Gm + gcdgb - gdtotg + gbdpg - gIdtotg
+ dxpart * ggtg + T1 * ddxpart_dVg);
here->BSIM4_47 = m * (here->BSIM4gds + gdtots - dxpart * ggts + gIdtots
- T1 * ddxpart_dVs + FwdSum - gcdsb - gbdpsp);
here->BSIM4_48 = m * (gjbd + gdtotb - Gmbs - gcdbb - gbdpb + gIdtotb
- T1 * ddxpart_dVb - dxpart * ggtb);
here->BSIM4_49 = m * (gdpr - gdtotd);
here->BSIM4_50 = m * (gdpr + gdtot);
here->BSIM4_51 = m * (here->BSIM4gds + gstotd + RevSum - gcsdb - gbspdp
- T1 * dsxpart_dVd - sxpart * ggtd + gIstotd);
here->BSIM4_52 = m * (gcsgb - Gm - gstotg + gbspg + sxpart * ggtg
+ T1 * dsxpart_dVg - gIstotg);
here->BSIM4_53 = m * (gspr + here->BSIM4gds + here->BSIM4gbs + T1 * dsxpart_dVs
- gstots + FwdSum + gcssb + gbspsp + sxpart * ggts - gIstots);
here->BSIM4_54 = m * (gspr + gstot);
here->BSIM4_55 = m * (gjbs + gstotb + Gmbs - gcsbb - gbspb - sxpart * ggtb
- T1 * dsxpart_dVb + gIstotb);
here->BSIM4_56 = m * (gspr - gstots);
here->BSIM4_57 = m * (gspr + gstot);
here->BSIM4_58 = m * (gcbdb - gjbd + gbbdp - gIbtotd);
here->BSIM4_59 = m * (gcbgb - here->BSIM4gbgs - gIbtotg);
here->BSIM4_60 = m * (gcbsb - gjbs + gbbsp - gIbtots);
here->BSIM4_61 = m * (gjbd + gjbs + gcbbb - here->BSIM4gbbs - gIbtotb);
ggidld = here->BSIM4ggidld;
ggidlg = here->BSIM4ggidlg;
ggidlb = here->BSIM4ggidlb;
ggislg = here->BSIM4ggislg;
ggisls = here->BSIM4ggisls;
ggislb = here->BSIM4ggislb;
/* stamp gidl */
here->BSIM4_62 = m * ggidld;
here->BSIM4_63 = m * ggidlg;
here->BSIM4_64 = m * (ggidlg + ggidld + ggidlb);
here->BSIM4_65 = m * ggidlb;
here->BSIM4_66 = m * ggidld;
here->BSIM4_67 = m * ggidlg;
here->BSIM4_68 = m * (ggidlg + ggidld + ggidlb);
here->BSIM4_69 = m * ggidlb;
/* stamp gisl */
here->BSIM4_70 = m * (ggisls + ggislg + ggislb);
here->BSIM4_71 = m * ggislg;
here->BSIM4_72 = m * ggisls;
here->BSIM4_73 = m * ggislb;
here->BSIM4_74 = m * (ggislg + ggisls + ggislb);
here->BSIM4_75 = m * ggislg;
here->BSIM4_76 = m * ggisls;
here->BSIM4_77 = m * ggislb;
if (here->BSIM4rbodyMod)
{ here->BSIM4_78 = m * (gcdbdb - here->BSIM4gbd);
here->BSIM4_79 = m * (here->BSIM4gbs - gcsbsb);
here->BSIM4_80 = m * (gcdbdb - here->BSIM4gbd);
here->BSIM4_81 = m * (here->BSIM4gbd - gcdbdb
+ here->BSIM4grbpd + here->BSIM4grbdb);
here->BSIM4_82 = m * here->BSIM4grbpd;
here->BSIM4_83 = m * here->BSIM4grbdb;
here->BSIM4_84 = m * here->BSIM4grbpd;
here->BSIM4_85 = m * here->BSIM4grbpb;
here->BSIM4_86 = m * here->BSIM4grbps;
here->BSIM4_87 = m * (here->BSIM4grbpd + here->BSIM4grbps
+ here->BSIM4grbpb);
/* WDLiu: (gcbbb - here->BSIM4gbbs) already added to BPbpPtr */
here->BSIM4_88 = m * (gcsbsb - here->BSIM4gbs);
here->BSIM4_89 = m * here->BSIM4grbps;
here->BSIM4_90 = m * here->BSIM4grbsb;
here->BSIM4_91 = m * (here->BSIM4gbs - gcsbsb
+ here->BSIM4grbps + here->BSIM4grbsb);
here->BSIM4_92 = m * here->BSIM4grbdb;
here->BSIM4_93 = m * here->BSIM4grbpb;
here->BSIM4_94 = m * here->BSIM4grbsb;
here->BSIM4_95 = m * (here->BSIM4grbsb + here->BSIM4grbdb
+ here->BSIM4grbpb);
}
if (here->BSIM4trnqsMod)
{ here->BSIM4_96 = m * (gqdef + here->BSIM4gtau);
here->BSIM4_97 = m * (ggtg - gcqgb);
here->BSIM4_98 = m * (ggtd - gcqdb);
here->BSIM4_99 = m * (ggts - gcqsb);
here->BSIM4_100 = m * (ggtb - gcqbb);
here->BSIM4_101 = m * dxpart * here->BSIM4gtau;
here->BSIM4_102 = m * sxpart * here->BSIM4gtau;
here->BSIM4_103 = m * here->BSIM4gtau;
}
#else
if (here->BSIM4rgateMod == 1)
{ (*(here->BSIM4GEgePtr) += m * geltd);
(*(here->BSIM4GPgePtr) -= m * geltd);
@ -4821,7 +5053,7 @@ line900:
(*(here->BSIM4SbpPtr) += m * gstotb);
}
(*(here->BSIM4DPdpPtr) += m * (gdpr + here->BSIM4gds + here->BSIM4gbd + T1 * ddxpart_dVd
(*(here->BSIM4DPdpPtr) = m * (gdpr + here->BSIM4gds + here->BSIM4gbd + T1 * ddxpart_dVd
- gdtotd + RevSum + gcddb + gbdpdp + dxpart * ggtd - gIdtotd));
(*(here->BSIM4DPdPtr) -= m * (gdpr + gdtot));
(*(here->BSIM4DPgpPtr) += m * (Gm + gcdgb - gdtotg + gbdpg - gIdtotg
@ -4921,11 +5153,14 @@ line900:
(*(here->BSIM4SPqPtr) += m * sxpart * here->BSIM4gtau);
(*(here->BSIM4GPqPtr) -= m * here->BSIM4gtau);
}
#endif
line1000: ;
#ifndef USE_OMP4
} /* End of MOSFET Instance */
} /* End of Model Instance */
#endif
return(OK);
}
@ -4963,3 +5198,192 @@ int BSIM4polyDepletion(
}
return(0);
}
#ifdef USE_OMP4
void BSIM4LoadRhsMat(GENmodel *inModel, CKTcircuit *ckt)
{
unsigned int InstCount, idx;
BSIM4instance **InstArray;
BSIM4instance *here;
BSIM4model *model = (BSIM4model*)inModel;
InstArray = model->BSIM4InstanceArray;
InstCount = model->BSIM4InstCount;
for(idx = 0; idx < InstCount; idx++) {
here = InstArray[idx];
/* Update b for Ax = b */
(*(ckt->CKTrhs + here->BSIM4dNodePrime) += here->BSIM4rhsdPrime);
(*(ckt->CKTrhs + here->BSIM4gNodePrime) -= here->BSIM4rhsgPrime);
if (here->BSIM4rgateMod == 2)
(*(ckt->CKTrhs + here->BSIM4gNodeExt) -= here->BSIM4rhsgExt);
else if (here->BSIM4rgateMod == 3)
(*(ckt->CKTrhs + here->BSIM4gNodeMid) -= here->BSIM4grhsMid);
if (!here->BSIM4rbodyMod)
{ (*(ckt->CKTrhs + here->BSIM4bNodePrime) += here->BSIM4rhsbPrime);
(*(ckt->CKTrhs + here->BSIM4sNodePrime) += here->BSIM4rhssPrime);
}
else
{ (*(ckt->CKTrhs + here->BSIM4dbNode) -= here->BSIM4rhsdb);
(*(ckt->CKTrhs + here->BSIM4bNodePrime) += here->BSIM4rhsbPrime);
(*(ckt->CKTrhs + here->BSIM4sbNode) -= here->BSIM4rhssb);
(*(ckt->CKTrhs + here->BSIM4sNodePrime) += here->BSIM4rhssPrime);
}
if (model->BSIM4rdsMod)
{ (*(ckt->CKTrhs + here->BSIM4dNode) -= here->BSIM4rhsd);
(*(ckt->CKTrhs + here->BSIM4sNode) += here->BSIM4rhss);
}
if (here->BSIM4trnqsMod)
*(ckt->CKTrhs + here->BSIM4qNode) += here->BSIM4rhsq;
/* Update A for Ax = b */
if (here->BSIM4rgateMod == 1)
{ (*(here->BSIM4GEgePtr) += here->BSIM4_1);
(*(here->BSIM4GPgePtr) -= here->BSIM4_2);
(*(here->BSIM4GEgpPtr) -= here->BSIM4_3);
(*(here->BSIM4GPgpPtr) += here->BSIM4_4);
(*(here->BSIM4GPdpPtr) += here->BSIM4_5);
(*(here->BSIM4GPspPtr) += here->BSIM4_6);
(*(here->BSIM4GPbpPtr) += here->BSIM4_7);
}
else if (here->BSIM4rgateMod == 2)
{ (*(here->BSIM4GEgePtr) += here->BSIM4_8);
(*(here->BSIM4GEgpPtr) += here->BSIM4_9);
(*(here->BSIM4GEdpPtr) += here->BSIM4_10);
(*(here->BSIM4GEspPtr) += here->BSIM4_11);
(*(here->BSIM4GEbpPtr) += here->BSIM4_12);
(*(here->BSIM4GPgePtr) -= here->BSIM4_13);
(*(here->BSIM4GPgpPtr) += here->BSIM4_14);
(*(here->BSIM4GPdpPtr) += here->BSIM4_15);
(*(here->BSIM4GPspPtr) += here->BSIM4_16);
(*(here->BSIM4GPbpPtr) += here->BSIM4_17);
}
else if (here->BSIM4rgateMod == 3)
{ (*(here->BSIM4GEgePtr) += here->BSIM4_18);
(*(here->BSIM4GEgmPtr) -= here->BSIM4_19);
(*(here->BSIM4GMgePtr) -= here->BSIM4_20);
(*(here->BSIM4GMgmPtr) += here->BSIM4_21);
(*(here->BSIM4GMdpPtr) += here->BSIM4_22);
(*(here->BSIM4GMgpPtr) += here->BSIM4_23);
(*(here->BSIM4GMspPtr) += here->BSIM4_24);
(*(here->BSIM4GMbpPtr) += here->BSIM4_25);
(*(here->BSIM4DPgmPtr) += here->BSIM4_26);
(*(here->BSIM4GPgmPtr) -= here->BSIM4_27);
(*(here->BSIM4SPgmPtr) += here->BSIM4_28);
(*(here->BSIM4BPgmPtr) += here->BSIM4_29);
(*(here->BSIM4GPgpPtr) += here->BSIM4_30);
(*(here->BSIM4GPdpPtr) += here->BSIM4_31);
(*(here->BSIM4GPspPtr) += here->BSIM4_32);
(*(here->BSIM4GPbpPtr) += here->BSIM4_33);
}
else
{ (*(here->BSIM4GPgpPtr) += here->BSIM4_34);
(*(here->BSIM4GPdpPtr) += here->BSIM4_35);
(*(here->BSIM4GPspPtr) += here->BSIM4_36);
(*(here->BSIM4GPbpPtr) += here->BSIM4_37);
}
if (model->BSIM4rdsMod)
{ (*(here->BSIM4DgpPtr) += here->BSIM4_38);
(*(here->BSIM4DspPtr) += here->BSIM4_39);
(*(here->BSIM4DbpPtr) += here->BSIM4_40);
(*(here->BSIM4SdpPtr) += here->BSIM4_41);
(*(here->BSIM4SgpPtr) += here->BSIM4_42);
(*(here->BSIM4SbpPtr) += here->BSIM4_43);
}
(*(here->BSIM4DPdpPtr) += here->BSIM4_44);
(*(here->BSIM4DPdPtr) -= here->BSIM4_45);
(*(here->BSIM4DPgpPtr) += here->BSIM4_46);
(*(here->BSIM4DPspPtr) -= here->BSIM4_47);
(*(here->BSIM4DPbpPtr) -= here->BSIM4_48);
(*(here->BSIM4DdpPtr) -= here->BSIM4_49);
(*(here->BSIM4DdPtr) += here->BSIM4_50);
(*(here->BSIM4SPdpPtr) -= here->BSIM4_51);
(*(here->BSIM4SPgpPtr) += here->BSIM4_52);
(*(here->BSIM4SPspPtr) += here->BSIM4_53);
(*(here->BSIM4SPsPtr) -= here->BSIM4_54);
(*(here->BSIM4SPbpPtr) -= here->BSIM4_55);
(*(here->BSIM4SspPtr) -= here->BSIM4_56);
(*(here->BSIM4SsPtr) += here->BSIM4_57);
(*(here->BSIM4BPdpPtr) += here->BSIM4_58);
(*(here->BSIM4BPgpPtr) += here->BSIM4_59);
(*(here->BSIM4BPspPtr) += here->BSIM4_60);
(*(here->BSIM4BPbpPtr) += here->BSIM4_61);
/* stamp gidl */
(*(here->BSIM4DPdpPtr) += here->BSIM4_62);
(*(here->BSIM4DPgpPtr) += here->BSIM4_63);
(*(here->BSIM4DPspPtr) -= here->BSIM4_64);
(*(here->BSIM4DPbpPtr) += here->BSIM4_65);
(*(here->BSIM4BPdpPtr) -= here->BSIM4_66);
(*(here->BSIM4BPgpPtr) -= here->BSIM4_67);
(*(here->BSIM4BPspPtr) += here->BSIM4_68);
(*(here->BSIM4BPbpPtr) -= here->BSIM4_69);
/* stamp gisl */
(*(here->BSIM4SPdpPtr) -= here->BSIM4_70);
(*(here->BSIM4SPgpPtr) += here->BSIM4_71);
(*(here->BSIM4SPspPtr) += here->BSIM4_72);
(*(here->BSIM4SPbpPtr) += here->BSIM4_73);
(*(here->BSIM4BPdpPtr) += here->BSIM4_74);
(*(here->BSIM4BPgpPtr) -= here->BSIM4_75);
(*(here->BSIM4BPspPtr) -= here->BSIM4_76);
(*(here->BSIM4BPbpPtr) -= here->BSIM4_77);
if (here->BSIM4rbodyMod)
{ (*(here->BSIM4DPdbPtr) += here->BSIM4_78);
(*(here->BSIM4SPsbPtr) -= here->BSIM4_79);
(*(here->BSIM4DBdpPtr) += here->BSIM4_80);
(*(here->BSIM4DBdbPtr) += here->BSIM4_81);
(*(here->BSIM4DBbpPtr) -= here->BSIM4_82);
(*(here->BSIM4DBbPtr) -= here->BSIM4_83);
(*(here->BSIM4BPdbPtr) -= here->BSIM4_84);
(*(here->BSIM4BPbPtr) -= here->BSIM4_85);
(*(here->BSIM4BPsbPtr) -= here->BSIM4_86);
(*(here->BSIM4BPbpPtr) += here->BSIM4_87);
(*(here->BSIM4SBspPtr) += here->BSIM4_88);
(*(here->BSIM4SBbpPtr) -= here->BSIM4_89);
(*(here->BSIM4SBbPtr) -= here->BSIM4_90);
(*(here->BSIM4SBsbPtr) += here->BSIM4_91);
(*(here->BSIM4BdbPtr) -= here->BSIM4_92);
(*(here->BSIM4BbpPtr) -= here->BSIM4_93);
(*(here->BSIM4BsbPtr) -= here->BSIM4_94);
(*(here->BSIM4BbPtr) += here->BSIM4_95);
}
if (here->BSIM4trnqsMod)
{ (*(here->BSIM4QqPtr) += here->BSIM4_96);
(*(here->BSIM4QgpPtr) += here->BSIM4_97);
(*(here->BSIM4QdpPtr) += here->BSIM4_98);
(*(here->BSIM4QspPtr) += here->BSIM4_99);
(*(here->BSIM4QbpPtr) += here->BSIM4_100);
(*(here->BSIM4DPqPtr) += here->BSIM4_101);
(*(here->BSIM4SPqPtr) += here->BSIM4_102);
(*(here->BSIM4GPqPtr) -= here->BSIM4_103);
}
}
}
#endif

View File

@ -1,5 +1,6 @@
/**** BSIM4.6.2 Released by Wenwei Yang 07/31/2008 ****/
/**** BSIM4.6.4 Update ngspice 08/22/2009 ****/
/**** OpenMP support ngspice 06/28/2010 ****/
/**********
* Copyright 2006 Regents of the University of California. All rights reserved.
* File: b4set.c of BSIM4.6.2.
@ -30,6 +31,12 @@
#include "sperror.h"
#include "suffix.h"
#ifdef USE_OMP4
int nthreads;
extern bool cp_getvar(char *name, int type, void *retval);
#define VT_NUM 1
#endif
#define MAX_EXP 5.834617425e14
#define MIN_EXP 1.713908431e-15
#define EXP_THRESHOLD 34.0
@ -58,6 +65,13 @@ int noiseAnalGiven = 0, createNode; /* Criteria for new node creation */
double Rtot, DMCGeff, DMCIeff, DMDGeff;
JOB *job;
#ifdef USE_OMP4
unsigned int idx, InstCount;
BSIM4instance **InstArray;
int nthreads;
#endif
/* Search for a noise analysis request */
for (job = ((TSKtask *)ft_curckt->ci_curTask)->jobs;job;job = job->JOBnextJob) {
if(strcmp(job->JOBname,"Noise Analysis")==0) {
@ -2375,7 +2389,49 @@ if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\
TSTALLOC(BSIM4SbpPtr, BSIM4sNode, BSIM4bNodePrime)
}
}
} /* end of loop through all the BSIM4 device models */
#ifdef USE_OMP4
if (!cp_getvar("num_threads", VT_NUM, (char *) &nthreads))
nthreads = 2;
omp_set_num_threads(nthreads);
if (nthreads == 1)
printf("OpenMP: %d thread is requested in BSIM4\n", nthreads);
else
printf("OpenMP: %d threads are requested in BSIM4\n", nthreads);
InstCount = 0;
model = (BSIM4model*)inModel;
/* loop through all the BSIM4 device models
to count the number of instances */
for( ; model != NULL; model = model->BSIM4nextModel )
{
/* loop through all the instances of the model */
for (here = model->BSIM4instances; here != NULL ;
here=here->BSIM4nextInstance)
{
InstCount++;
}
}
InstArray = (BSIM4instance**)tmalloc(InstCount*sizeof(BSIM4instance**));
model = (BSIM4model*)inModel;
idx = 0;
for( ; model != NULL; model = model->BSIM4nextModel )
{
/* loop through all the instances of the model */
for (here = model->BSIM4instances; here != NULL ;
here=here->BSIM4nextInstance)
{
InstArray[idx] = here;
idx++;
}
/* set the array pointer and instance count into each model */
model->BSIM4InstCount = InstCount;
model->BSIM4InstanceArray = InstArray;
}
#endif
return(OK);
}

View File

@ -1,5 +1,5 @@
/**** BSIM4.6.2 Released by Wenwei Yang 07/31/2008 ****/
/**** OpenMP support for ngspice by Holger Vogt 06/28/2010 ****/
/**********
Copyright 2006 Regents of the University of California. All rights reserved.
File: bsim4def.h
@ -27,6 +27,15 @@ Modified by Wenwei Yang, 07/31/2008.
#include "complex.h"
#include "noisedef.h"
#ifdef USE_OMP
#define USE_OMP4
#endif
#ifdef USE_OMP4
#include <omp.h>
#endif
typedef struct sBSIM4instance
{
struct sBSIM4model *BSIM4modPtr;
@ -386,6 +395,125 @@ typedef struct sBSIM4instance
double *BSIM4GPqPtr;
double *BSIM4SPqPtr;
#ifdef USE_OMP4
/* per instance storage of results, to update matrix at a later stge */
double BSIM4rhsdPrime;
double BSIM4rhsgPrime;
double BSIM4rhsgExt;
double BSIM4grhsMid;
double BSIM4rhsbPrime;
double BSIM4rhssPrime;
double BSIM4rhsdb;
double BSIM4rhssb;
double BSIM4rhsd;
double BSIM4rhss;
double BSIM4rhsq;
double BSIM4_1;
double BSIM4_2;
double BSIM4_3;
double BSIM4_4;
double BSIM4_5;
double BSIM4_6;
double BSIM4_7;
double BSIM4_8;
double BSIM4_9;
double BSIM4_10;
double BSIM4_11;
double BSIM4_12;
double BSIM4_13;
double BSIM4_14;
double BSIM4_15;
double BSIM4_16;
double BSIM4_17;
double BSIM4_18;
double BSIM4_19;
double BSIM4_20;
double BSIM4_21;
double BSIM4_22;
double BSIM4_23;
double BSIM4_24;
double BSIM4_25;
double BSIM4_26;
double BSIM4_27;
double BSIM4_28;
double BSIM4_29;
double BSIM4_30;
double BSIM4_31;
double BSIM4_32;
double BSIM4_33;
double BSIM4_34;
double BSIM4_35;
double BSIM4_36;
double BSIM4_37;
double BSIM4_38;
double BSIM4_39;
double BSIM4_40;
double BSIM4_41;
double BSIM4_42;
double BSIM4_43;
double BSIM4_44;
double BSIM4_45;
double BSIM4_46;
double BSIM4_47;
double BSIM4_48;
double BSIM4_49;
double BSIM4_50;
double BSIM4_51;
double BSIM4_52;
double BSIM4_53;
double BSIM4_54;
double BSIM4_55;
double BSIM4_56;
double BSIM4_57;
double BSIM4_58;
double BSIM4_59;
double BSIM4_60;
double BSIM4_61;
double BSIM4_62;
double BSIM4_63;
double BSIM4_64;
double BSIM4_65;
double BSIM4_66;
double BSIM4_67;
double BSIM4_68;
double BSIM4_69;
double BSIM4_70;
double BSIM4_71;
double BSIM4_72;
double BSIM4_73;
double BSIM4_74;
double BSIM4_75;
double BSIM4_76;
double BSIM4_77;
double BSIM4_78;
double BSIM4_79;
double BSIM4_80;
double BSIM4_81;
double BSIM4_82;
double BSIM4_83;
double BSIM4_84;
double BSIM4_85;
double BSIM4_86;
double BSIM4_87;
double BSIM4_88;
double BSIM4_89;
double BSIM4_90;
double BSIM4_91;
double BSIM4_92;
double BSIM4_93;
double BSIM4_94;
double BSIM4_95;
double BSIM4_96;
double BSIM4_97;
double BSIM4_98;
double BSIM4_99;
double BSIM4_100;
double BSIM4_101;
double BSIM4_102;
double BSIM4_103;
#endif
#define BSIM4vbd BSIM4states+ 0
#define BSIM4vbs BSIM4states+ 1
@ -1575,6 +1703,12 @@ typedef struct sBSIM4model
struct bsim4SizeDependParam *pSizeDependParamKnot;
#ifdef USE_OMP4
int BSIM4InstCount;
struct sBSIM4instance **BSIM4InstanceArray;
#endif
/* Flags */
unsigned BSIM4mobModGiven :1;
unsigned BSIM4binUnitGiven :1;