004_chebyshev_lpf : Chebyshev Low Pass Filter
Requires: SmartSpice & Smartview
Minimum Versions: SMARTSPICE 4.6.5.R
The input deck uses an Operational Amplifier with .AC analysis and a Verilog-A module. Rubberband the rbias[res] parameter.
Input Files
bsim4.va
/*****************************************************************/ /* Berkeley BSIM4.3.0 Verilog-A model */ /*****************************************************************/ // The terms under which the software is provided are as the following. // // Software is distributed as is, completely without warranty or service // support. The University of California and its employees are not liable // for the condition or performance of the software. // // The University owns the copyright but shall not be liable for any // infringement of copyright or other proprietary rights brought by third // parties against the users of the software. // // The University of California hereby disclaims all implied warranties. // // The University of California grants the users the right to modify, copy, // and redistribute the software and documentation, both within the user's // organization and externally, subject to the following restrictions: // // 1. The users agree not to charge for the University of California code // itself but may charge for additions, extensions, or support. // // 2. In any product based on the software, the users agree to acknowledge // the UC Berkeley BSIM Research Group that developed the software. This // acknowledgment shall appear in the product documentation. // // 3. The users agree to obey all U.S. Government restrictions governing // redistribution or export of the software. // // 4. The users agree to reproduce any copyright notice which appears on // the software on any copy or modification of such made available // to others. // // Chenming Hu, and Weidong Liu // Oct. 2000 // // UPDATED March 8,19 2004 // Contributed By: // Geoffrey Coram, Ph.D Senior CAD Engineer Analog Devices, Inc. //********************************************************************** `define VOLTAGE_MAXDELTA 0.3 `include "discipline.h" // The following line must be uncommented if RGATEMOD parameter is 3. //`define RGATE3 // The following line must be uncommented if RBODYMOD parameter is set to 1. //`define RBODY //****** Physical constants ******// `define EPS0 8.85418e-12 `define KboQ 8.617087e-5 `define EPSSI 1.03594e-10 `define Charge_q 1.60219e-19 `define Charge 1.6021918e-19 //****** Mathematical constants and constants of limitation ******// `define PI 3.141592654 `define EXP_THRESHOLD 34.0 `define MIN_EXP 1.713908431e-15 `define MAX_EXP 5.834617425e14 //****** Constants for the model ******// `define MM 3 `define DELTA 1.0e-9 `define DELTA_1 0.02 `define DELTA_3 0.02 `define DELTA_4 0.02 //****** Beginning of the model ******// module mosfet(drain, gate, source, bulk); inout drain, gate, source, bulk; electrical drain, gate, source, bulk; // External nodes electrical drainp, sourcep; // Internal nodes for rdsmod electrical gatep, gatem; // Internal nodes for rgatemod electrical drainb, sourceb, bulkp; // Internal nodes for rbodymod //****** Definition of all instance and model parameters *****// //****** To customize your model to fit your device, just*****// //****** modify those parameters in your modelcard *****// //****** -99.0 is used for parameters which are *****// //****** calculated if you don't determine them *****// //****** Minimum conductance ******// parameter GMIN = 1e-12; //****** Geometrical Parameters ******// parameter PS = 0.0; parameter PD = 0.0; parameter AS = 0.0; parameter AD = 0.0; //****** Overlap Capacitance Parameters ******// parameter CGBO = -99.0; // Gate-bulk overlap capacitance per length parameter CGDO = -99.0; // Gate-drain overlap capacitance per width parameter CGSO = -99.0; // Gate-source overlap capacitance per width //****** Mosfet type ******// parameter TYPE = 1; // Define the type of the mosfet (NMOS or PMOS) //****** Parameters L and W ******// parameter L = -1.0; // Length parameter W = -1.0; // Width //****** Model Selectors/Controllers ******// parameter MOBMOD = -99.0; // Mobility model selector parameter RDSMOD = -99.0; // Bias-dependent source/drain resistance model selector parameter IGCMOD = 0; // Gate-to-channel tunneling current model selector parameter IGBMOD = 0; // Gate-to-substrate tunneling current model selector parameter CAPMOD = 2; // Capacitance model selector parameter RGATEMOD = 2; // Gate resistance model selector parameter RBODYMOD = 0; // Substrate resistance network model selector parameter DIOMOD = 1; // Source/drain junction diode IV model selctor parameter TEMPMOD = -99.0; // Temperature mode selector parameter GEOMOD = 0; // Geometry-dependent parasitics model selector parameter RGEOMOD = 0; // Source/drain diffusion resistance and contact model selector parameter PERMOD = 1; // //****** Process Parameters ******// parameter EPSROX = 3.9; // Gate dielctric constant relative to vacuum parameter TOXE = -99.0; // Electrical gate equivalent oxide thickness parameter TOXP = TOXE; // Physical gate equivalent oxide thickness parameter TOXM = TOXE; // Tox at which parameters are extracted parameter DTOX = 0.0; // Defined as TOXE-TOXP parameter XJ = 1.5e-7; // S/D junction depth parameter GAMMA1 = -99.0; // Body-effect coefficient near the surface parameter GAMMA2 = -99.0; // Body-effect coefficient in the bulk parameter NDEP = -99.0; // Channel doping concentration at depletion edge for zero body bias parameter NSUB = 6.0e16; // Substrate doping concentration parameter NGATE = 0.0; // Poly Si gate doping concentration parameter NSD = 1.0e20; // S/D doping concentration parameter VBX = -99.0; // Vbs at which the depletion region width equals XT parameter XT = 1.55e-7; // Doping depth parameter RSH = 0.0; // S/D sheet resistance parameter RSHG = 0.0; // Gate electrode sheet resistance //****** Basic Parameters ******// parameter VTH0 = -99.0; // Long-channel threshold voltage at Vbs=0 parameter VFB = -99.0; // Flat-band voltage parameter PHIN = 0.0; // Non-uniform vertical doping effect on surface potential parameter K1 = -99.0; // First-order body bias coefficient parameter K2 = -99.0; // Second-order body bias coefficient parameter K3 = 80.0; // Narrow width coefficient parameter K3B = 0.0; // Body effect coefficient of K3 parameter W0 = 2.5e-6; // Narrow width parameter parameter LPE0 = 1.74e-7; // Lateral non-uniform doping parameter at Vbs=0 parameter LPEB = 0.0; // Lateral non-uniform doping effect on K1 parameter VBM = -3.0; // Maximum applied body bias in VTH0 calculation parameter DVT0 = 2.2; // First coefficient of short-channel effect on Vth parameter DVT1 = 0.53; // Second coefficient of short-channel effect on Vth parameter DVT2 = -0.032; // Body-bias coefficient of short-channel effect on Vth parameter DVTP0 = 0.0; // First coefficient of drain-induced Vth shift due to for long-channel pocket devices parameter DVTP1 = 0.0; // Second coefficient of drain-induced Vth shift due to for long-channel pocket devices parameter DVT0W = 0.0; // First coefficient of narrow width effect on Vth for small channel length parameter DVT1W = 5.3e6; // Second coefficient of narrow width effect on Vth for small channel length parameter DVT2W = -0.032; // Body-bias coefficient of narrow width effect on Vth for small channel length parameter U0 = -99.0; // Low-field mobility parameter UA = -99.0; // Coefficient of first-order mobility degradation due to vertical field parameter UB = 1.0e-19; // Coefficient of second-order mobility degradation due to vertical field parameter UC = -99.0; // Coefficient of mobility degradation due to body-bias effect parameter EU = -99.0; // Exponent for mobility degradation of MOBMOD=2 parameter VSAT = 8.0e4; // Saturation velocity parameter A0 = 1.0; // Coefficient of channel-length dependence of bulk charge effect parameter AGS = 0.0; // Coefficient of Vgs dependence of bulk charge effect parameter B0 = 0.0; // Bulk charge effect coefficient for channel width parameter B1 = 0.0; // Bulk charge effect width offset parameter KETA = -0.047; // Body-bias coefficient of bulk charge effect parameter A1 = 0.0; // First non-saturation effect parameter parameter A2 = 1.0; // Second non-saturation factor parameter WINT = 0.0; // Channel-width offset parameter parameter LINT = 0.0; // Channel-length offset parameter parameter DWG = 0.0; // Coefficient of gate bias dependence of Weff parameter DWB = 0.0; // Coefficient of body bias dependence of Weff parameter VOFF = -0.08; // Offset voltage in subthreshold region for large W and L parameter VOFFL = 0.0; // Channel-length dependence of VOFF parameter MINV = 0.0; // Vgsteff fitting parameter for moderate inversion condition parameter NFACTOR = 1.0; // Subthreshold swing factor parameter ETA0 = 0.08; // DIBL coefficient in subthreshold region parameter ETAB = -0.07; // Body-bias coefficient for the subthreshold DIBL effect parameter DROUT = 0.56; // Channel-length dependence of DIBL effect on Rout parameter DSUB = DROUT; // DIBL coefficient exponent in subthreshold region parameter CIT = 0.0; // Interface trap capacitance parameter CDSC = 2.4e-4; // Coupling cpacitance between S/D and channel parameter CDSCB = 0.0; // Body-bias sensivity of CDSC parameter CDSCD = 0.0; // Drain-bias sensivity of CDSC parameter PCLM = 1.3; // Channel-length modulation parameter parameter PDIBL1 = 0.39; // Parameter for DIBL effect on Rout parameter PDIBL2 = 0.0086; // Parameter for DIBL effect on Rout parameter PDIBLB = 0.0; // Body-bias coefficient of DIBL effect on Rout parameter PSCBE1 = 4.24e8; // First substrate current induced body-effect parameter parameter PSCBE2 = 1.0e-5; // Second substrate current induced body-effect parameter parameter PVAG = 0.0; // Gate-bias dependence of Early voltage parameter DELTA = 0.01; // Parameter for DC Vdseff parameter FPROUT = 0.0; // Effect of pocket implant on Rout degradation parameter PDITS = 0.0; // Impact of drain-induced Vth shift on Rout parameter PDITSD = 0.0; // Vds dependence of drain-induced Vth shift for Rout parameter PDITSL = 0.0; // Channel-length dependence of drain-induced Vth shift for Rout parameter LAMBDA = -99.0; // Velocity overshoot coefficient parameter VTL = -99.0; // Thermal velocity parameter LC = 5.0e-9; // Velocity back scattering coefficient parameter XN = 3.0; // Velocity back scattering coefficient //****** Assymetric and Bias-Dependent Rds Model Parameters ******// parameter RDSW = 200.0; // Zero bias LDD resistance per unit width for RDSMOD=0 parameter RDSWMIN = 0.0; // LDD resistance per unit width at high Vgs and zero Vbs for RDSMOD=0 parameter RDW = 100.0; // Zero bias lightly-doped drain resistance Rd per unit width for RDSMOD=1 parameter RDWMIN = 0.0; // Lightly-doped drain resistance Rd per unit width at high Vgs and zero Vbs for RDSMOD=1 parameter RSW = 100.0; // Zero bias lightly-doped source resistance Rd per unit width for RDSMOD=1 parameter RSWMIN = 0.0; // Lightly-doped source resistance Rd per unit width at high Vgs and zero Vbs for RDSMOD=1 parameter PRWG = 1.0; // Gate-bias dependence of LDD resistance parameter PRWB = 0.0; // Body-bias dependence of LDD resistance parameter WR = 1.0; // Channel-width dependence parameter of LDD resistance parameter NRS = -99.0; // Number of source diffusion squares parameter NRD = -99.0; // Number of drain diffusion squares //****** Impact Ionization Current Model Parameters ******// parameter ALPHA0 = 0.0; // First parameter of impact ionization current parameter ALPHA1 = 0.0; // Isub parameter length scaling parameter BETA0 = 30.0; // Second parameter of impact ionization current //****** Gate Induced Drain Leakage Model Parameters ******// parameter AGIDL = 0.0; // Pre-exponential coefficient for GIDL parameter BGIDL = 2.3e9; // Exponential coefficient for GIDL parameter CGIDL = 0.5; // Parameter for body-bias effect on GIDL parameter EGIDL = 0.8; // Fitting parameter for band bending for GIDL //****** Gate Dielectric Tunneling Current Model Parameters ******// parameter AIGBACC = 0.43; // Parameter for Igb in accumulation parameter BIGBACC = 0.054; // Parameter for Igb in accumulation parameter CIGBACC = 0.075; // Parameter for Igb in accumulation parameter NIGBACC = 1.0; // Parameter for Igb in accumulation parameter AIGBINV = 0.35; // Parameter for Igb in inversion parameter BIGBINV = 0.03; // Parameter for Igb in inversion parameter CIGBINV = 0.006; // Parameter for Igb in inversion parameter EIGBINV = 1.1; // Parameter for Igb in inversion parameter NIGBINV = 3.0; // Parameter for Igb in inversion parameter AIGC = -99.0; // Parameter for Igcs and Igcd parameter BIGC = -99.0; // Parameter for Igcs and Igcd parameter CIGC = -99.0; // Parameter for Igcs and Igcd parameter AIGSD = -99.0; // Parameter for Igs and Igd parameter BIGSD = -99.0; // Parameter for Igs and Igd parameter CIGSD = -99.0; // Parameter for Igs and Igd parameter DLCIG = LINT; // S/D overlap length for Igs and Igd parameter NIGC = 1.0; // Parameter for Igcs, Igcd, Igs and Igd parameter POXEDGE = 1.0; // Factor for the gate oxide thickness in S/D overlap regions parameter PIGCD = 1.0; // Vds dependence of Igcs and Igcd parameter NTOX = 1.0; // Exponent for the gate oxide ratio parameter TOXREF = 3.0e-9; // Nominal gate oxide thickness for gate dielectric tunneling current model only //****** Charge and Capacitance Model Parameters ******// parameter XPART = 0.0; // Charge partition parameter parameter CGS0 = 0.0; // Non LDD region source-gate overlap capacitance per unit channel width parameter CGD0 = 0.0; // Non LDD region drain-gate overlap capacitance per unit channel width parameter CGB0 = 0.0; // Gate-bulk overlap capcitance per unit channel length parameter CGSL = 0.0; // Overlap capacitance between gate and lightly-doped source region parameter CGDL = 0.0; // Overlap capacitance between gate and lightly-doped source region parameter CKAPPAS = 0.6; // Coefficient of bias-dependent overlap capacitance for the source side parameter CKAPPAD = CKAPPAS; // Coefficient of bias-dependent overlap capacitance for the drain side parameter CF = -99.0; // Fringing field capacitance parameter CLC = 1.0e-7; // Constant term for the short channel model parameter CLE = 0.6; // Exponential term for the short channel model parameter DLC = LINT; // Channel-length offset parameter for CV model parameter DWC = WINT; // Channel-width offset parameter for CV model parameter VFBCV = -1.0; // Flat-band voltage parameter parameter NOFF = 1.0; // CV parameter in Vgstett,CV for weak to strong inversion parameter VOFFCV = 0.0; // CV parameter in Vgstett,CV for weak to strong inversion parameter ACDE = 1.0; // Exponential coefficient for charge thickness in CAPMOD=2 for accumulation and depletion regions parameter MOIN = 15.0; // Coefficient for the gate-bias dependent surface potential //****** High-Speed/RF Model Parameters ******// parameter XRCRG1 = 12.0; // Parameter for distributed channel-resistance effect for intrinsic-input resistance parameter XRCRG2 = 1.0; // Parameter to account for the excess channel diffusion resistance parameter RBPB = 50.0; // Resistance connected between bNodePrime and bNode parameter RBPD = 50.0; // Resistance connected between bNodePrime and dbNode parameter RBPS = 50.0; // Resistance connected between bNodePrime and sbNode parameter RBDB = 50.0; // Resistance connected between dbNodePrime and bNode parameter RBSB = 50.0; // Resistance connected between sbNodePrime and bNode parameter GBMIN = 1.0e-12; // Conductance in parallel with each of the five substrate resistances to avoid potential numerical instability //****** Layout-Dependent Parasistics Model Parameters ******// parameter DMCG = 0.0; // Distance from S/D contact center to the gate edge parameter DMCI = DMCG; // Distance from S/D contact center to the isolation edge in the channel-length direction parameter DMDG = 0.0; // Same as DMCG but for merged device only parameter DMCGT = 0.0; // DMCG of test structures parameter NF = 1.0; // Number of device fingers parameter DWJ = DWC; // Offset of the S/D junction width parameter MIN = 0.0; // Whether to minimize the number of drain or source diffusions for even-number fingered device parameter XGW = 0.0; // Distance from the gate contact to the channel edge parameter XGL = 0.0; // Offset of the gate length due to variations in patterning parameter XL = 0.0; // Channel length offset due to mask/etch effect parameter XW = 0.0; // Channel width offset due to mask/etch effect parameter NGCON = 1.0; // Number of gate contacts //****** Assymetric Source/Drain Junction Diode Model Parameters ******// parameter IJTHSREV = 0.1; // Limiting current in reverse bias region parameter IJTHDREV = IJTHSREV; // Idem parameter IJTHSFWD = 0.1; // Limiting current in forward bias region parameter IJTHDFWD = IJTHSFWD; // Idem parameter XJBVS = 1.0; // Fitting parameter for diode breakdown parameter XJBVD = XJBVS; // Idem parameter BVS = 10.0; // Breakdown voltage parameter BVD = BVS; // Idem parameter JSS = 1.0e-4; // Bottom junction reverse saturation current density parameter JSD = JSS; // Idem parameter JSWS = 0.0; // Isolation-edge sidewall reverse saturation current density parameter JSWD = JSWS; // Idem parameter JSWGS = 0.0; // Gate-edge sidewall reverse saturation current density parameter JSWGD = JSWGS; // Idem parameter CJS = 5.0e-4; // Bottom junction capacitance per unit area at zero bias parameter CJD = CJS; // Idem parameter MJS = 0.5; // Bottom junction capacitance grating coefficient parameter MJD = MJS; // Idem parameter MJSWS = 0.33; // Isolation-edge sidewall junction capacitance grading coefficient parameter MJSWD = MJSWS; // Idem parameter CJSWS = 5.0e-10; // Isolation-edge sidewall junction capacitance per unit area parameter CJSWD = CJSWS; // Idem parameter CJSWGS = CJSWS; // Gate-edge sidewall junction capacitance per unit length parameter CJSWGD = CJSWS; // Idem parameter MJSWGS = MJSWS; // Gate-edge sidewall junction capacitance grading coefficient parameter MJSWGD = MJSWS; // Idem parameter PBS = 1.0; // Bottom junction built-in potential parameter PBD = PBS; // Idem parameter PBSWS = 1.0; // Isoaltion-edge sidewall junction built-in potential parameter PBSWD = PBSWS; // Idem parameter PBSWGS = PBSWS; // Gare-edge sidewall junction built-in potential parameter PBSWGD = PBSWS; // Idem //****** Temperature Dependence Parameters ******// parameter TNOM = 27; // Temperature at which parameters are extracted parameter UTE = -1.5; // Mobility temperature exponent parameter KT1 = -0.11; // Tempertature coefficient for threshold voltage parameter KT1L = 0.0; // Channel length dependence of the temperature coefficient for threshold voltage parameter KT2 = 0.022; // Body-bias coefficient of Vth temperature effect parameter UA1 = 1.0e-9; // Temperature coefficient for UA parameter UB1 = -1.0e-18; // Temperature coefficient for UB parameter UC1 = -99.0; // Temperature coefficient for UC parameter AT = 3.3e4; // Temperature coefficient for saturation velocity parameter PRT = 0.0; // Temperature coefficient for Rdsw parameter NJS = 1.0; // Emission coefficients of junction for drain and source jonctions parameter NJD = NJS; // Idem parameter XTIS = 3.0; // Junction current temperature exponents for source and drain junctions parameter XTID = XTIS; // Idem parameter TPB = 0.0; // Temperature coefficient of PB parameter TPBSW = 0.0; // Temperature coefficient of PBSW parameter TPBSWG = 0.0; // Temperature coefficient of PBSWG parameter TCJ = 0.0; // Temperature coefficient of CJ parameter TCJSW = 0.0; // Temperature coefficient of CJSW parameter TCJSWG = 0.0; // Temperature coefficient of CJSWG //****** Stress Effect Model Parameters ******// parameter SA = 0.0; // Distance between OD edge to poly from one side parameter SB = 0.0; // Distance between OD edge to poly from other side parameter SD = 0.0; // Distance between neighbouring fingers parameter SAREF = 1e-6; // Reference distance between OD and edge to poly of one side parameter SBREF = 1e-6; // Reference distance between OD and edge to poly of the other side parameter WLOD = 0.0; // Width parameter for stress effect parameter KU0 = 0.0; // Mobility degradation/enhancement coefficient for stress effect parameter KVSAT = 0.0; // Saturation velocity degradation/enhancement parameter for stress effect parameter TKU0 = 0.0; // Temperature coefficient of KU0 parameter LKU0 = 0.0; // Length dependence of KU0 parameter WKU0 = 0.0; // Width dependence of KU0 parameter PKU0 = 0.0; // parameter LLODKU0 = 0.0; // Length parameter for U0 stress effect parameter WLODKU0 = 0.0; // Width parameter for U0 stress effect parameter KVTH0 = 0.0; // Threshold shift parameter for stress effect parameter LKVTH0 = 0.0; // Length dependence of KVTH0 parameter WKVTH0 = 0.0; // Width dependence of KVTH0 parameter PKVTH0 = 0.0; // Cross-term dependence of KVTH0 parameter LLODVTH = 0.0; // Length parameter for Vth stress effect parameter WLODVTH = 0.0; // Width parameter for Vth stress effect parameter STK2 = 0.0; // K2 shift factor related to VTH0 change parameter LODK2 = 1.0; // K2 shift modification factor for stress effect parameter STETA0 = 0.0; // ETA0 shift factor related to VTH0 change parameter LODETA0 = 1.0; // ETA0 shift modification factor for stress effect //****** DW and DL Parameters ******// parameter WL = 0.0; // Coefficient of length dependence for width offset parameter WLN = 1.0; // Power of length dependence of width offset parameter WW = 0.0; // Coefficient of width dependence for width offset parameter WWN = 1.0; // Power of width dependence of width offset parameter WWL = 0.0; // Coefficient of length and width cross-term dependence for width parameter LL = 0.0; // Coefficient of length dependence for length offset parameter LLN = 1.0; // Power of length dependence of length offset parameter LW = 0.0; // Coefficient of width dependence for length offset parameter LWN = 1.0; // Power of width dependence of length offset parameter LWL = 0.0; // Coefficient of length and width cross-term dependence for length parameter LLC = LL; // Coefficient of length dependence for CV channel length offset parameter LWC = LW; // Coefficient of width dependence for CV channel length offset parameter LWLC = LWL; // Power of length and width cross-term dependence for CV channel length offset parameter WLC = WL; // Coefficient of length dependence for CV channel width offset parameter WWC = WW; // Coefficient of width dependence for CV channel width offset parameter WWLC = WWL; // Power of length and width cross-term dependence for CV channel width offset integer i; real type, mode, gmin; real t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13; real tmp, tmp1, tmp2, tmp3, tmp4; real mobmod, rdsmod, tempmod, rgatemod, permod, geomod, rgeomod; real igcmod, igbmod, diomod, capmod, rbodymod; real toxe, toxp, coxe, coxp, epsrox; real tnom, vtm0, vtm, eg0, eg, ni; real l, w, lnew, wnew, nf, xl, xw; real ll, lw, lwl, lln, lwn, lint, dl, leff; real wl, ww, wwl, wln, wwn, wint, dw, weff; real gamma1, gamma2, ndep, nsub; real phi, phin, sqrtphi, k3, vfbzb, w0, phis, sqrtphis; real xj, nsd, xdep0, litl, vbi, vfbsd, ngate, xdep; real cdep0, ntox, toxratio, toxratioedge, toxref, poxedge; real mstar, voff, voffl, voffcbn, minv, ldeb; real k1, k2, vbx, vbm, xt, vbsc, vfb, vth0, k1ox, k2ox, toxm; real vtfbphi1, vtfbphi2, thetarout, dsub, theta0vb0; real drout, pdibl1, pdibl2, factor1, dvt0w, dvt1w; real dvt1, dvt0, lpe0, lpeb, kt1, kt1l, tratio; real vgs, vds, vbs, Vds, Vbs, vses, vdes, vbd, vgd; real vsbs, vdbd, vgb, vded, vgeg, vgmg, vgegm, vgmb; real vbsb, vbdb, vbeb, vbes, vges, vgms, vdbs, vbesb, vbedb; real vbseff, v0, dvt2, dvt2w, lt1, ltw, theta0, thetavth; real delt_vth, kt2, vth_narroww, eta0, etab, ddibl_sft_dvd; real dibl_sft, lpe_vb, vth, k3b, dvtp0, dvtp1; real cit, nfactor, cdsc, cdscb, cdscd, n; real vgs_eff, vgd_eff, Vgs_eff, vgst, expvgst, vgsteff; real Weff, dwg, dwb, weffcj, powweffwr, wr, ua, ua1, ub, ub1, uc, uc1; real vsat, vsattemp, at, prt, rdw, rsw, rdwmin, rswmin; real rdsw, rdswmin, deltemp, u0, u0temp, ute, eu; real wlc, wwlc, wwc, dwj, rds0, rd0, rs0, rds; real prwb, prwg, a0, ags, b0, b1, ueff; real abulk, abulk0, dabulk_dvg, keta, denomi; real wvcox, wvcoxrds, esat, esatl, a1, a2, Lambda; real vgst2vtm, vdsat, delta, vdseff, diffvds; real lambda, vasat, tcen, coxeff, coxeffwovl, beta; real abovvgst2vtm, fgche1, fgche2, gche, idl; real fprout, fp, pvag, pvagterm, pclm, cclm, vaclm; real vadibl, pdiblb, pdits, pditsl, pditsd, vadits; real pscbe1, pscbe2, vascbe, idsa, ids; real alpha0, alpha1, beta0, isub, cdrain; real vtl, vs, lc, xn, tfactor, fsevl; real grgeltd, xgl, rshg, ngcon, xgw, xrcrg1, xrcrg2, gcrg; real llodku0, wlod, w_tmp, wlodku0, lku0, wku0, pku0, tku0; real llodvth, wlodvth, ku0, lkvth0, wkvth0, pkvth0, kvth0; real ku0temp, ldrn, inv_saref, inv_sbref, inv_od_ref, rho_ref; real sa, sb, saref, sbref, sd, lodk2, lodeta0, kvsat; real inv_sa, inv_sb, inv_odeff, rho, od_offset, stk2; real dvth0_lod, dk2_lod, steta0, deta0_lod; real pseff, pdeff, adeff, aseff, dmcg, dmcgt, dmcgeff; real dmcieff, dmci, dmdg, dmdgeff; real ps, pd, as, ad, imin; real nrs, nrd, rsh, gsdiff, gddiff, gstot, gdtot, rs, rd; real agidl, bgidl, cgidl, egidl, igidl, igisl; real v3, v4, vfbeff, voxacc, voxdepinv, vxnvt, expvxnvt, vaux; real dlc, dlcig, aechvb, bechvb, aechvbedge, bechvbedge; real aigc, bigc, cigc, aigsd, bigsd, cigsd, aigbacc, bigbacc; real cigbacc, nigbacc, aigbinv, bigbinv, cigbinv, nigbinv; real nigc, pigcd, eigbinv, igc, modif_pigcd, igcs, igcd; real igs, igd, igb, igbacc, igbinv; real llc, lwc, lwlc, pbs, pbsws, pbswgs, pbd, pbswd, pbswgd; real cgbo, param_cgdo, param_cgso, cgdo, cgso; real xtis, xtid, jss, jsd, jsws, jswd, jswgs, jswgd; real jss_temp, jsd_temp, jsws_temp, jswd_temp; real jswgs_temp, jswgd_temp, njs, njd, cgdl, cgsl; real dwc, tcj, tcjsw, tcjswg, cjs, cjd, cjsws, cjswd; real cjswgs, cjswgd, cjs_temp, cjd_temp, cjsws_temp, cjswd_temp; real cjswgs_temp, cjswgd_temp, tpb, tpbsw, tpbswg, phibs, phibd; real phibsws, phibswd, phibswgs, phibswgd; real ijthsfwd, ijthsrev, ijthdfwd, ijthdrev, xjbvd, bvd; real xjbvs, bvs, weffcv, leffcv, cf, acde; real gbmin, rbdb, grbdb, rbpb, grbpb, rbsb, grbsb, rbpd, grbpd; real rbps, grbps, nvtms, nvtmd, isbs, isbd, xexpbvs, xexpbvd; real vjsmfwd, vjdmfwd, ivjsmfwd, ivjdmfwd, sslpfwd, dslpfwd; real vjsmrev, vjdmrev, ivjsmrev, ivjdmrev, sslprev, dslprev; real cbs, cbd, evbs, evbd, vbs_jct, vbd_jct; real csub, clc, cle, abulkcvfactor, xpart, vfbcv; real coxwl, arg1, qdrn, qbulk, qgate, qsrc, ccn; real abulkcv, alphaz, vdsatcv, two_third_coxwl; real vbseffcv, noff, voffcv, vgstnvt, qac0, qsub0; real vdseffcv, tox, ccen, link, coxwlcen, moin, deltaphi; real arg, czbd, czbs, czbdsw, czbssw, czbdswg, czbsswg, sarg; real mjs, mjd, mjsws, mjswd, mjswgs, mjswgd; real ckappas, ckappad, qgso, qgdo, dt0_dvg; real qgmb, qgmid, qgb, qbd, qbs, qb, qd, qs; //****** Function to calculate geometrical parameters ******// //****** and intermediaries for rd an rs calculation ******// analog function real get_nuintd; input nf, minsd; real nf, minsd; begin if ((nf%2) != 0) get_nuintd = 2.0 * max((nf - 1.0) / 2.0, 0.0); else begin if (minsd == 1) /* minimize # of source */ get_nuintd = 2.0 * max((nf / 2.0 - 1.0), 0.0); else get_nuintd = nf; end end endfunction analog function real get_nuendd; input nf, minsd; real nf, minsd; begin if ((nf%2) != 0) get_nuendd = 1.0; else begin if (minsd == 1) /* minimize # of source */ get_nuendd = 2.0; else get_nuendd = 0.0; end end endfunction analog function real get_nuints; input nf, minsd; real nf, minsd; begin if ((nf%2) != 0) get_nuints= 2.0 * max((nf - 1.0) / 2.0, 0.0); else begin if (minsd == 1) /* minimize # of source */ get_nuints = nf; else get_nuints = 2.0 * max((nf / 2.0 - 1.0), 0.0); end end endfunction analog function real get_nuends; input nf, minsd; real nf, minsd; begin if ((nf%2) != 0) get_nuends = 1.0; else begin if (minsd == 1) /* minimize # of source */ get_nuends = 0.0; else get_nuends = 2.0; end end endfunction analog function real get_ps; input nf, geo, minsd, weffcj, dmcg, dmci, dmdg; real nf, geo, minsd, weffcj, dmcg, dmci, dmdg; real psiso, pssha, psmer; real t0, t1, t2; real nuints, nuends; begin nuints = 0.0; nuends = 0.0; if (geo < 9) begin nuints = get_nuints(nf, minsd); nuends = get_nuends(nf, minsd); end t0 = dmcg + dmci; t1 = dmcg + dmcg; t2 = dmdg + dmdg; psiso = t0 + t0 + weffcj; pssha = t1; psmer = t2; case(geo) 0: get_ps = nuends * psiso + nuints * pssha; 1: get_ps = nuends * psiso + nuints * pssha; 2: get_ps = (nuends + nuints) * pssha; 3: get_ps = (nuends + nuints) * pssha; 4: get_ps = nuends * psiso + nuints * pssha; 5: get_ps = (nuends + nuints) * pssha; 6: get_ps = nuends * psmer + nuints * pssha; 7: get_ps = nuends * psmer + nuints * pssha; 8: get_ps = nuends * psmer + nuints * pssha; 9: get_ps = psiso + (nf - 1.0) * pssha; 10: get_ps = nf * pssha; default: $strobe("Warning: Specified GEO = %d not matched", geo); endcase end endfunction analog function real get_pd; input nf, geo, minsd, weffcj, dmcg, dmci, dmdg; real nf, geo, minsd, weffcj, dmcg, dmci, dmdg; real pdiso, pdsha, pdmer; real t0, t1, t2; real nuintd, nuendd; begin nuintd = 0.0; nuendd = 0.0; if (geo < 9) begin nuintd = get_nuintd(nf, minsd); nuendd = get_nuendd(nf, minsd); end t0 = dmcg + dmci; t1 = dmcg + dmcg; t2 = dmdg + dmdg; pdiso = t0 + t0 + weffcj; pdsha = t1; pdmer = t2; case(geo) 0: get_pd = nuendd * pdiso + nuintd * pdsha; 1: get_pd = (nuendd + nuintd) * pdsha; 2: get_pd = nuendd * pdiso + nuintd * pdsha; 3: get_pd = (nuendd + nuintd) * pdsha; 4: get_pd = nuendd * pdmer + nuintd * pdsha; 5: get_pd = nuendd * pdmer + nuintd * pdsha; 6: get_pd = nuendd * pdiso + nuintd * pdsha; 7: get_pd = (nuendd + nuintd) * pdsha; 8: get_pd = nuendd * pdmer + nuintd * pdsha; 9: get_pd = nf * pdsha; 10: get_pd = pdiso + (nf - 1.0) * pdsha; default: $strobe("Warning: Specified GEO = %d not matched", geo); endcase end endfunction analog function real get_as; input nf, geo, minsd, weffcj, dmcg, dmci, dmdg; real nf, geo, minsd, weffcj, dmcg, dmci, dmdg; real asiso, assha, asmer; real t0; real nuints, nuends; begin nuints = 0.0; nuends = 0.0; if (geo < 9) begin nuints = get_nuints(nf, minsd); nuends = get_nuends(nf, minsd); end t0 = dmcg + dmci; asiso = t0 * weffcj; assha = dmcg * weffcj; asmer = dmdg * weffcj; case(geo) 0: get_as = nuends * asiso + nuints * assha; 1: get_as = nuends * asiso + nuints * assha; 2: get_as = (nuends + nuints) * assha; 3: get_as = (nuends + nuints) * assha; 4: get_as = nuends * asiso + nuints * assha; 5: get_as = (nuends + nuints) * assha; 6: get_as = nuends * asmer + nuints * assha; 7: get_as = nuends * asmer + nuints * assha; 8: get_as = nuends * asmer + nuints * assha; 9: get_as = asiso + (nf - 1.0) * assha; 10: get_as = nf * assha; default: $strobe("Warning: Specified GEO = %d not matched", geo); endcase end endfunction analog function real get_ad; input nf, geo, minsd, weffcj, dmcg, dmci, dmdg; real nf, geo, minsd, weffcj, dmcg, dmci, dmdg; real adiso, adsha, admer; real t0; real nuintd, nuendd; begin nuintd = 0.0; nuendd = 0.0; if (geo < 9) begin nuintd = get_nuintd(nf, minsd); nuendd = get_nuendd(nf, minsd); end t0 = dmcg + dmci; adiso = t0 * weffcj; adsha = dmcg * weffcj; admer = dmdg * weffcj; case(geo) 0: get_ad = nuendd * adiso + nuintd * adsha; 1: get_ad = (nuendd + nuintd) * adsha; 2: get_ad = nuendd * adiso + nuintd * adsha; 3: get_ad = (nuendd + nuintd) * adsha; 4: get_ad = nuendd * admer + nuintd * adsha; 5: get_ad = nuendd * admer + nuintd * adsha; 6: get_ad = nuendd * adiso + nuintd * adsha; 7: get_ad = (nuendd + nuintd) * adsha; 8: get_ad = nuendd * admer + nuintd * adsha; 9: get_ad = nf * adsha; 10: get_ad = adiso + (nf - 1.0) * adsha; default: $strobe("Warning: Specified GEO = %d not matched", geo); endcase end endfunction analog function real get_rendi; input weffcj, rsh, dmcg, dmci, dmdg, nuend, rgeo, type; real weffcj, rsh, dmcg, dmci, dmdg, nuend, rgeo, type; begin if (type == 1) begin case(rgeo) 1, 2, 5: begin if (nuend == 0.0) get_rendi = 0.0; else get_rendi = rsh * dmcg / (weffcj * nuend); end 3, 4, 6: begin if ((dmcg + dmci) == 0.0) $strobe("(dmcg + dmci) can not be equal to zero"); if (nuend == 0.0) get_rendi = 0.0; else get_rendi = rsh * weffcj / (3.0 * nuend * (dmcg + dmci)); end default: $strobe("warning: specified rgeo = %d not matched", rgeo); endcase end else begin case(rgeo) 1, 3, 7: begin if (nuend == 0.0) get_rendi = 0.0; else get_rendi = rsh * dmcg / (weffcj * nuend); end 2, 4, 8: begin if ((dmcg + dmci) == 0.0) $strobe("(dmcg + dmci) can not be equal to zero"); if (nuend == 0.0) get_rendi = 0.0; else get_rendi = rsh * weffcj / (3.0 * nuend * (dmcg + dmci)); end default: $strobe("warning: specified rgeo = %d not matched", rgeo); endcase end end endfunction analog function real get_renda; input weffcj, rsh, dmcg, dmci, dmdg, nuend, rgeo, type; real weffcj, rsh, dmcg, dmci, dmdg, nuend, rgeo, type; begin if (type == 1) begin case(rgeo) 1, 2, 5: begin if (nuend == 0.0) get_renda = 0.0; else get_renda = rsh * dmcg / (weffcj * nuend); end 3, 4, 6: begin if (dmcg == 0.0) $strobe("dmcg can not be equal to zero"); if (nuend == 0.0) get_renda = 0.0; else get_renda = rsh * weffcj / (6.0 * nuend * dmcg); end default: $strobe("warning: specified rgeo = %d not matched", rgeo); endcase end else begin case(rgeo) 1, 3, 7: begin if (nuend == 0.0) get_renda = 0.0; else get_renda = rsh * dmcg / (weffcj * nuend); end 2, 4, 8: begin if (dmcg == 0.0) $strobe("dmcg can not be equal to zero"); if (nuend == 0.0) get_renda = 0.0; else get_renda = rsh * weffcj / (6.0 * nuend * dmcg); end default: $strobe("warning: specified rgeo = %d not matched", rgeo); endcase end end endfunction analog function real get_rtot; input nf, geo, rgeo, minsd, weffcj, rsh, dmcg, dmci, dmdg, type; real nf, geo, rgeo, minsd, weffcj, rsh, dmcg, dmci, dmdg, type; real rint, rend; real nuintd, nuendd, nuints, nuends; begin rend = 0.0; nuintd = 0.0; nuendd = 0.0; nuints = 0.0; nuends = 0.0; if (geo < 9) /* since geo = 9 and 10 only happen when nf = even */ begin nuintd = get_nuintd(nf, minsd); nuints = get_nuints(nf, minsd); nuendd = get_nuendd(nf, minsd); nuends = get_nuends(nf, minsd); /* internal s/d resistance -- assume shared s or d and all wide contacts */ if (type == 1) begin if (nuints == 0.0) rint = 0.0; else rint = rsh * dmcg / ( weffcj * nuints); end else begin if (nuintd == 0.0) rint = 0.0; else rint = rsh * dmcg / ( weffcj * nuintd); end end /* end s/d resistance -- geo dependent */ case(geo) 0: begin if (type == 1) rend = get_rendi(weffcj, rsh, dmcg, dmci, dmdg, nuends, rgeo, 1); else rend = get_rendi(weffcj, rsh, dmcg, dmci, dmdg, nuendd, rgeo, 0); end 1: begin if (type == 1) rend = get_rendi(weffcj, rsh, dmcg, dmci, dmdg, nuends, rgeo, 1); else rend = get_renda(weffcj, rsh, dmcg, dmci, dmdg, nuendd, rgeo, 0); end 2: begin if (type == 1) rend = get_renda(weffcj, rsh, dmcg, dmci, dmdg, nuends, rgeo, 1); else rend = get_rendi(weffcj, rsh, dmcg, dmci, dmdg, nuendd, rgeo, 0); end 3: begin if (type == 1) rend = get_renda(weffcj, rsh, dmcg, dmci, dmdg, nuends, rgeo, 1); else rend = get_renda(weffcj, rsh, dmcg, dmci, dmdg, nuendd, rgeo, 0); end 4: begin if (type == 1) rend = get_rendi(weffcj, rsh, dmcg, dmci, dmdg, nuends, rgeo, 1); else rend = rsh * dmdg / weffcj; end 5: begin if (type == 1) rend = get_renda(weffcj, rsh, dmcg, dmci, dmdg, nuends, rgeo, 1); else rend = rsh * dmdg / (weffcj * nuendd); end 6: begin if (type == 1) rend = rsh * dmdg / weffcj; else rend = get_rendi(weffcj, rsh, dmcg, dmci, dmdg, nuendd, rgeo, 0); end 7: begin if (type == 1) rend = rsh * dmdg / (weffcj * nuends); else rend = get_renda(weffcj, rsh, dmcg, dmci, dmdg, nuendd, rgeo, 0); end 8: begin rend = rsh * dmdg / weffcj; end 9: /* all wide contacts assumed for geo = 9 and 10 */ begin if (type == 1) begin rend = 0.5 * rsh * dmcg / weffcj; if (nf == 2.0) rint = 0.0; else rint = rsh * dmcg / (weffcj * (nf - 2.0)); end else begin rend = 0.0; rint = rsh * dmcg / (weffcj * nf); end end 10: begin if (type == 1) begin rend = 0.0; rint = rsh * dmcg / (weffcj * nf); end else begin rend = 0.5 * rsh * dmcg / weffcj;; if (nf == 2.0) rint = 0.0; else rint = rsh * dmcg / (weffcj * (nf - 2.0)); end end default: $strobe("Warning: specified geo = %d not matched", geo); endcase if (rint <= 0.0) get_rtot = rend; else if (rend <= 0.0) get_rtot = rint; else get_rtot = rint * rend / (rint + rend); if(get_rtot==0.0) $strobe("Warning: zero resistance returned from get_rtot"); end endfunction analog function real get_vjm; input nvtm, ijth, isb, xexpbv; real nvtm, ijth, isb, xexpbv; real tb, tc, evjmovnv; begin tc = xexpbv; tb = 1.0 + ijth / isb - tc; evjmovnv = 0.5 * (tb + sqrt(tb * tb + 4.0 * tc)); get_vjm = nvtm * ln(evjmovnv); end endfunction analog begin @(initial_step) begin a0 = A0; a1 = A1; a2 = A2; acde = ACDE; ad = AD; agidl = AGIDL; ags = AGS; aigbacc = AIGBACC; aigbinv = AIGBINV; aigc = AIGC; aigsd = AIGSD; alpha0 = ALPHA0; alpha1 = ALPHA1; as = AS; at = AT; b0 = B0; b1 = B1; beta0 = BETA0; bgidl = BGIDL; bigbacc = BIGBACC; bigbinv = BIGBINV; bigc = BIGC; bigsd = BIGSD; bvd = BVD; bvs = BVS; capmod = CAPMOD; cdsc = CDSC; cdscb = CDSCB; cdscd = CDSCD; cf = CF; cgbo = CGBO; cgdl = CGDL; cgidl = CGIDL; cgsl = CGSL; cigbacc = CIGBACC; cigbinv = CIGBINV; cigc = CIGC; cigsd = CIGSD; cit = CIT; cjd = CJD; cjs = CJS; cjswd = CJSWD; cjswgd = CJSWGD; cjswgs = CJSWGS; cjsws = CJSWS; ckappad = CKAPPAD; ckappas = CKAPPAS; clc = CLC; cle = CLE; delta = DELTA; diomod = DIOMOD; dlc = DLC; dlcig = DLCIG; dmcg = DMCG; dmcgt = DMCGT; dmci = DMCI; dmdg = DMDG; drout = DROUT; dsub = DSUB; dvt0 = DVT0; dvt0w = DVT0W; dvt1 = DVT1; dvt1w = DVT1W; dvt2 = DVT2; dvt2w = DVT2W; dvtp0 = DVTP0; dvtp1 = DVTP1; dwb = DWB; dwc = DWC; dwg = DWG; dwj = DWJ; egidl = EGIDL; eigbinv = EIGBINV; epsrox = EPSROX; eta0 = ETA0; etab = ETAB; eu = EU; fprout = FPROUT; gamma1 = GAMMA1; gamma2 = GAMMA2; gbmin = GBMIN; geomod = GEOMOD; gmin = GMIN; igbmod = IGBMOD; igcmod = IGCMOD; ijthdfwd = IJTHDFWD; ijthdrev = IJTHDREV; ijthsfwd = IJTHSFWD; ijthsrev = IJTHSREV; imin = MIN; jsd = JSD; jss = JSS; jswd = JSWD; jswgd = JSWGD; jswgs = JSWGS; jsws = JSWS; k1 = K1; k2 = K2; k3 = K3; k3b = K3B; keta = KETA; kt1 = KT1; kt1l = KT1L; kt2 = KT2; ku0 = KU0; kvsat = KVSAT; kvth0 = KVTH0; l = L; lambda = LAMBDA; lc = LC; lint = LINT; lku0 = LKU0; lkvth0 = LKVTH0; ll = LL; llc = LLC; lln = LLN; llodku0 = LLODKU0; llodvth = LLODVTH; lodeta0 = LODETA0; lodk2 = LODK2; lpe0 = LPE0; lpeb = LPEB; lw = LW; lwc = LWC; lwl = LWL; lwn = LWN; lwlc = LWLC; minv = MINV; mjd = MJD; mjs = MJS; mjswd = MJSWD; mjswgd = MJSWGD; mjswgs = MJSWGS; mjsws = MJSWS; mobmod = MOBMOD; moin = MOIN; ndep = NDEP; nf = NF; nfactor = NFACTOR; ngate = NGATE; ngcon = NGCON; nigbacc = NIGBACC; nigbinv = NIGBINV; nigc = NIGC; njd = NJD; njs = NJS; noff = NOFF; nrd = NRD; nrs = NRS; nsd = NSD; nsub = NSUB; ntox = NTOX; param_cgdo = CGDO; param_cgso = CGSO; pbd = PBD; pbs = PBS; pbswd = PBSWD; pbswgd = PBSWGD; pbswgs = PBSWGS; pbsws = PBSWS; pclm = PCLM; pd = PD; pdibl1 = PDIBL1; pdibl2 = PDIBL2; pdiblb = PDIBLB; pdits = PDITS; pditsd = PDITSD; pditsl = PDITSL; permod = PERMOD; phin = PHIN; pigcd = PIGCD; pku0 = PKU0; pkvth0 = PKVTH0; poxedge = POXEDGE; prt = PRT; prwb = PRWB; prwg = PRWG; ps = PS; pscbe1 = PSCBE1; pscbe2 = PSCBE2; pvag = PVAG; rbdb = RBDB; rbodymod = RBODYMOD; rbpb = RBPB; rbpd = RBPD; rbps = RBPS; rbsb = RBSB; rdsmod = RDSMOD; rdsw = RDSW; rdswmin = RDSWMIN; rdw = RDW; rdwmin = RDWMIN; rgatemod = RGATEMOD; rgeomod = RGEOMOD; rsh = RSH; rshg = RSHG; rsw = RSW; rswmin = RSWMIN; sa = SA; saref = SAREF; sb = SB; sbref = SBREF; sd = SD; steta0 = STETA0; stk2 = STK2; tcj = TCJ; tcjsw = TCJSW; tcjswg = TCJSWG; tempmod = TEMPMOD; tku0 = TKU0; toxe = TOXE; toxm = TOXM; toxp = TOXP; toxref = TOXREF; tpb = TPB; tpbsw = TPBSW; tpbswg = TPBSWG; type = TYPE; u0 = U0; ua = UA; ua1 = UA1; ub = UB; ub1 = UB1; uc = UC; uc1 = UC1; ute = UTE; vbm = VBM; vbx = VBX; vfb = VFB; vfbcv = VFBCV; voff = VOFF; voffcv = VOFFCV; voffl = VOFFL; vsat = VSAT; vth0 = VTH0; vtl = VTL; w = W; w0 = W0; wint = WINT; wku0 = WKU0; wkvth0 = WKVTH0; wl = WL; wlc = WLC; wln = WLN; wlod = WLOD; wlodku0 = WLODKU0; wlodvth = WLODVTH; wr = WR; ww = WW; wwc = WWC; wwl = WWL; wwlc = WWLC; wwn = WWN; xgl = XGL; xgw = XGW; xj = XJ; xjbvd = XJBVD; xjbvs = XJBVS; xl = XL; xn = XN; xpart = XPART; xrcrg1 = XRCRG1; xrcrg2 = XRCRG2; xt = XT; xtid = XTID; xtis = XTIS; xw = XW; if (mobmod == -99.0) mobmod = 0; else if ((mobmod != 0) && (mobmod != 1) && (mobmod != 2)) begin mobmod = 0; $strobe("Warning: MOBMOD has been set to its default value: 0."); end if (rdsmod == -99.0) rdsmod = 0; else if ((rdsmod != 0) && (rdsmod != 1)) begin rdsmod = 0; $strobe("Warning: RDSMOD has been set to its default value: 0."); end if (tempmod == -99.0) tempmod = 0; else if ((tempmod != 0) && (tempmod != 1)) begin tempmod = 0; $strobe("Warning: TEMPMOD has been set to its default value: 0."); end if ((diomod != 0) && (diomod != 1) && (diomod != 2)) begin diomod = 1; $strobe("Warning: DIOMOD has been set to its default value: 1."); end if ((capmod != 0) && (capmod != 1) && (capmod != 2)) begin capmod = 2; $strobe("Warning: CAPMOD has been set to its default value: 2."); end if ((permod != 0) && (permod != 1)) begin permod = 1; $strobe("Warning: PERMOD has been set to its default value: 1."); end if ((igcmod != 0) && (igcmod != 1)) begin igcmod = 0; $strobe("Warning: IGCMOD has been set to its default value: 0."); end if ((igbmod != 0) && (igbmod != 1)) begin igbmod = 0; $strobe("Warning: IGBMOD has been set to its default value: 0."); end if ((rbodymod != 0) && (rbodymod != 1)) begin rbodymod = 0; $strobe("Warning: RBODYMOD has been set to its default value: 0."); end if (toxref <= 0.0) begin $strobe("Fatal: TOXREF = %e is not positive.", TOXREF); $finish(1); end if (toxe != -99.0 && toxp != -99.0 && DTOX != 0.0 && (toxe != (toxp + DTOX))) $strobe("Warning: TOXE, TOXP and DTOX all given and TOXE != TOXP + DTOX. DTOX ignored."); else if (toxe != -99.0 && toxp == -99.0) toxp = toxe - DTOX; else if (toxe == -99.0 && toxp != -99.0) toxe = toxp + DTOX; else if (toxp == -99.0 && toxe == -99.0) begin toxe = 3.0e-9; toxp = toxe; end if (toxe < 1.0e-10) $strobe("Warning: TOXE = %e is less than 1A. Recommended TOXE >= 5A", toxe); if (toxp < 1.0e-10) $strobe("Warning: TOXP = %e is less than 1A. Recommended TOXP >= 5A", toxp); if (toxm == -99.0) toxm = toxe; if (toxm <= 0.0) begin $strobe("Fatal: TOXM = %e is not positive.", toxm); $finish(1); end if (toxm < 1.0e-10) $strobe("Warning: TOXM = %e is less than 1A. Recommended TOXM >= 5A", toxm); if (epsrox <= 0.0) begin $strobe("Warning: EPSROX is not positive. Default value taken."); epsrox = 3.9; end if (TNOM < -273.15) begin $strobe("Warning: TNOM is not physically possible. Default value taken."); tnom = 300.15; end else tnom = TNOM + 273.15; if (l <= 0.0 ) begin $strobe("FATAL : L is not positive."); $finish(1); end if (w <= 0.0 ) begin $strobe("FATAL : W is not positive."); $finish(1); end if (nf < 1.0) begin $strobe("Warning : NF must be at least equal to 1.Default value taken"); nf = 1.0; end if (phin < -0.4) begin $strobe("Fatal: phin = %e is less than -0.4.", PHIN); $finish(1); end else if (nsub <= 0.0) begin $strobe("Fatal: NSUB = %e is not positive.", NSUB); $finish(1); end else if (NSUB <= 1.0e14) $strobe("Warning: NSUB = %e may be too small.", NSUB); else if (NSUB >= 1.0e21) $strobe("Warning: NSUB = %e may be too large.", NSUB); if (xj <= 0.0) $strobe("Fatal: XJ = %e is not positive.", XJ); if (ngate < 0.0) begin $strobe("Fatal: NGATE = %e is not positive.", NGATE); $finish(1); end if (ngate > 1.0e25) begin $strobe("Fatal: NGATE = %e is too high.", NGATE); $finish(1); end if ((ngate > 0.0) && (ngate <= 1.0e18)) $strobe("Warning: NGATE = %e is less than 1.E18cm^-3.", NGATE); if (poxedge <= 0.0) begin $strobe("Fatal: POXEDGE = %e is non-positive.", POXEDGE); $finish(1); end if (dsub < 0.0) begin $strobe("Fatal: DSUB = %e is negative.", DSUB); $finish(1); end if (drout < 0.0) begin $strobe("Fatal: DROUT = %e is negative.", DROUT); $finish(1); end if (pdibl1 < 0.0) $strobe("Warning: PDIBL1 = %e is negative.", PDIBL1); if (pdibl2 < 0.0) $strobe("Warning: PDIBL2 = %e is negative.", PDIBL2); if (dvt1w < 0.0) begin $strobe("Fatal: DVT1W = %e is negative.", DVT1W); $finish(1); end if (dvt1 < 0.0) begin $strobe("Fatal: DVT1 = %e is negative.", DVT1); $finish(1); end if (dvt0 < 0.0) $strobe("Warning: DVT0 = %e is negative.", DVT0); if (lpe0 < -leff) begin $strobe("Fatal: LPE0 = %e is less than -leff.", LPE0); $finish(1); end if (w0 == -weff) begin $strobe("Fatal: (W0 + Weff) = 0 causing divided-by-zero."); $finish(1); end if (abs(1.0e-6 / (w0 + weff)) > 10.0) $strobe("Warning: (W0 + Weff) may be too small."); if (eta0 < 0.0) $strobe("Warning: ETA0 = %e is negative.", ETA0); if (lpeb < -leff) begin $strobe("Fatal: LPEB = %e is less than -leff.", LPEB); $finish(1); end if (nfactor < 0.0) $strobe("Warning: NFACTOR = %e is negative.", NFACTOR); if (cdsc < 0.0) $strobe("Warning: CDSC = %e is negative.", CDSC); if (cdscd < 0.0) $strobe("Warning: CDSCD = %e is negative.", CDSCD); if (u0 == -99.0) u0 = (type == 1) ? 0.067 : 0.025; if (ua == -99.0) ua = (mobmod == 2) ? 1.0e-15 : 1.0e-9; if (uc == -99.0) uc = (mobmod == 1) ? -0.0465 : -0.0465e-9; if (uc1 == -99.0) uc1 = (mobmod == 1) ? -0.056 : -0.056e-9; if (eu == -99.0) eu = (type == 1) ? 1.67 : 1.0;; if (prwg < 0.0) begin $strobe("Warning: PRWG = %e is negative. Set to zero.", PRWG); prwg = 0.0; end if (a2 < 0.01) begin $strobe("Warning: A2 = %e is too small. Set to 0.01.", a2); a2 = 0.01; end else if (a2 > 1.0) begin $strobe("Warning: A2 = %e is larger than 1. A2 is set to 1 and A1 is set to 0.", a2); a2 = 1.0; a1 = 0.0; end if (delta < 0.0) begin $strobe("Fatal: DELTA = %e is less than zero.", delta); $finish(1); end if ((lambda != -99.0) && (lambda > 0.0)) begin if (lambda > 1.0e-9) $strobe("Warning: LAMBDA = %e may be too large.", LAMBDA); end if (fprout < 0.0) begin $strobe("Fatal: FPROUT = %e is negative.", FPROUT); $finish(1); end if (pclm <= 0.0) begin $strobe("Fatal: PCLM = %e is not positive.", PCLM); $finish(1); end if (pdits < 0.0) begin $strobe("Fatal: PDITS = %e is negative.", pdits); $finish(1); end if (pditsl < 0.0) begin $strobe("Fatal: PDITSL = %e is negative.", pditsl); $finish(1); end if (pscbe2 <= 0.0) $strobe("Warning: PSCBE2 = %e is not positive.", PSCBE2); if ((vtl != -99.0) && (vtl > 0.0)) begin if (vtl < 6.0e4) $strobe("Warning: Thermal velocity VTL = %e may be too small.", vtl); end if (xn < 3.0) begin $strobe("Warning: back scattering coeff XN = %e is too small. Reset to 3.0", xn); xn = 3.0; end if (rgatemod == 1) begin if (rshg <= 0.0) $strobe("Warning: RSHG should be positive for RGATEMOD = 1."); end else if (rgatemod == 2) begin if (rshg <= 0.0) $strobe("Warning: RSHG <= 0.0 for rgateMod = 2."); else if (xrcrg1 <= 0.0) $strobe("Warning: XRCRG1 <= 0.0 for rgateMod = 2."); end if (rgatemod == 3) begin if (rshg <= 0.0) $strobe("Warning: RSHG should be positive for RGATEMOD = 3."); else if (xrcrg1 <= 0.0) $strobe("Warning: XRCRG1 should be positive for RGATEMOD = 3."); end if (ngcon < 1.0) begin $strobe("Fatal: The parameter NGCON cannot be smaller than one."); $finish(1); end if ((l + xl) <= xgl) begin $strobe("Fatal: The parameter XGL must be smaller than Ldrawn+XL."); $finish(1); end if((sa > 0.0) && (sb > 0.0) && ((nf == 1.0) || ((nf > 1.0) && (sd > 0.0))) ) begin if (saref <= 0.0) begin $strobe("Fatal: SAREF = %e is not positive.",saref); $finish(1); end if (sbref <= 0.0) begin $strobe("Fatal: SBREF = %e is not positive.",sbref); $finish(1); end if (wlod < 0.0) begin $strobe("Warning: WLOD = %e is less than 0.",wlod); wlod = 0.0; end if (kvsat < -1.0 ) begin $strobe("Warning: KVSAT = %e is is too small; Reset to -1.0.",kvsat); kvsat = -1.0; end if (kvsat > 1.0) begin $strobe("Warning: KVSAT = %e is too big; Reset to 1.0.",kvsat); kvsat = 1.0; end if (lodk2 <= 0.0) $strobe("Warning: LODK2 = %e is not positive.",lodk2); if (lodeta0 <= 0.0) $strobe("Warning: LODETA0 = %e ih not positive.",lodeta0); end if (aigc == -99.0) aigc = (type == 1) ? 0.43 : 0.31; if (bigc == -99.0) bigc = (type == 1) ? 0.054 : 0.024; if (cigc == -99.0) cigc = (type == 1) ? 0.075 : 0.03; if (aigsd == -99.0) aigsd = (type == 1) ? 0.43 : 0.31; if (bigsd == -99.0) bigsd = (type == 1) ? 0.054 : 0.024; if (cigsd == -99.0) cigsd = (type == 1) ? 0.075 : 0.03; if (nigbinv <= 0.0) begin $strobe("Fatal: NIGBINV = %e is non-positive.", nigbinv); $finish(1); end if (nigbacc <= 0.0) begin $strobe("Fatal: NIGBACC = %e is non-positive.", nigbacc); $finish(1); end if (nigc <= 0.0) begin $strobe("Fatal: NIGC = %e is non-positive.", nigc); $finish(1); end if (pigcd <= 0.0) begin $strobe("Fatal: PIGCD = %e is non-positive.", pigcd); $finish(1); end if (pbs < 0.1) begin pbs = 0.1; $strobe("Given PBS is less than 0.1. PBS is set to 0.1."); end if (pbsws < 0.1) begin pbsws = 0.1; $strobe("Given PBSWS is less than 0.1. PBSWS is set to 0.1."); end if (pbswgs < 0.1) begin pbswgs = 0.1; $strobe("Given PBSWGS is less than 0.1. PBSWGS is set to 0.1."); end if (pbd < 0.1) begin pbd = 0.1; $strobe("Given PBD is less than 0.1. PBD is set to 0.1."); end if (pbswd < 0.1) begin pbswd = 0.1; $strobe("Given PBSWD is less than 0.1. PBSWD is set to 0.1."); end if (pbswgd < 0.1) begin pbswgd = 0.1; $strobe("Given PBSWGD is less than 0.1. PBSWGD is set to 0.1."); end if (ijthdfwd <= 0.0) begin ijthdfwd = 0.1; $strobe("IJTHDFWD reset to %e.", ijthdfwd); end if (ijthsfwd <= 0.0) begin ijthsfwd = 0.1; $strobe("IJTHSFWD reset to %e.", ijthsfwd); end if (ijthdrev <= 0.0) begin ijthdrev = 0.1; $strobe("IJTHDREV reset to %e.", ijthdrev); end if (ijthsrev <= 0.0) begin ijthsrev = 0.1; $strobe("IJTHSREV reset to %e.", ijthsrev); end if ((xjbvd <= 0.0) && (diomod == 2)) begin xjbvd = 1.0; $strobe("XJBVD reset to %e.", xjbvd); end else if ((xjbvd < 0.0) && (diomod == 0)) begin xjbvd = 1.0; $strobe("XJBVD reset to %e.", xjbvd); end if (bvd <= 0.0) begin bvd = 10.0; $strobe("BVD reset to %e.\n", bvd); end if ((xjbvs <= 0.0) && (diomod == 2)) begin xjbvs = 1.0; $strobe("XJBVS reset to %e.\n", xjbvs); end else if ((xjbvs < 0.0) && (diomod == 0)) begin xjbvs = 1.0; $strobe("XJBVS reset to %e.\n", xjbvs); end if (bvs <= 0.0) begin bvs = 10.0; $strobe("BVS reset to %g.\n", bvs); end if (gbmin < 1.0e-20) $strobe("Warning: GBMIN = %e is too small.", gbmin); if (clc < 0.0) begin $strobe("Fatal: CLC = %e is negative.", CLC); $finish(1); end if (noff < 0.1) $strobe("Warning: NOFF = %e is too small.", noff); if (voffcv < -0.5) $strobe("Warning: VOFFCV = %e is too small.", voffcv); if (moin < 5.0) $strobe("Warning: MOIN = %e is too small.", moin); if (moin > 25.0) $strobe("Warning: MOIN = %e is too large.", moin); if (ckappas < 0.02) begin $strobe("Warning: CKAPPAS = %e is too small.", ckappas); ckappas = 0.02; end if (ckappad < 0.02) begin $strobe("Warning: CKAPPAD = %e is too small.", ckappad); ckappad = 0.02; end //***** Oxide capacitances (line 110-111, file b4temp.c) *****// coxe = epsrox * `EPS0 / toxe; coxp = epsrox * `EPS0 / toxp; //***** Overlap capacitances (line 113-129, file b4temp.c) *****// if (param_cgdo == -99.0) begin if (dlc > 0.0) param_cgdo = dlc * coxe - cgdl ; else param_cgdo = 0.6 * xj * coxe; end if (param_cgso == -99.0) begin if (dlc > 0.0) param_cgso = dlc * coxe - cgsl ; else param_cgso = 0.6 * xj * coxe; end if (cgbo == -99.0) cgbo = 2.0 * dwc * coxe; tratio = $temperature / tnom; factor1 = sqrt(`EPSSI / (epsrox * `EPS0) * toxe); //***** Intrinsic carrier concentration (line 139-141, file b4temp.c) *****// vtm0 = `KboQ * tnom; eg0 = 1.16 - 7.02e-4 * tnom * tnom / (tnom + 1108.0); ni = 1.45e10 * (tnom / 300.15) * sqrt(tnom / 300.15) * exp(21.5565981 - eg0 / (2.0 * vtm0)); vtm = `KboQ * $temperature; //***** Energy gap (line 145, file b4temp.c) *****// eg = 1.16 - 7.02e-4 * $temperature * $temperature / ($temperature + 1108.0); //***** Temperture dependance of Junction diode IV (line 149-191, file b4temp.c) *****// if ($temperature != tnom) begin t0 = eg0 / vtm0 - eg / vtm; t1 = ln($temperature / tnom); t2 = t0 + xtis * t1; t3 = exp(t2 / njs); jss_temp = jss * t3; jsws_temp = jsws * t3; jswgs_temp = jswgs * t3; t2 = t0 + xtid * t1; t3 = exp(t2 / njd); jsd_temp = jsd * t3; jswd_temp = jswd * t3; jswgd_temp = jswgd * t3; end else begin jss_temp = jss; jsws_temp = jsws; jswgs_temp = jswgs; jsd_temp = jsd; jswd_temp = jswd; jswgd_temp = jswgd; end if (jss_temp < 0.0) jss_temp = 0.0; if (jsws_temp < 0.0) jsws_temp = 0.0; if (jswgs_temp < 0.0) jswgs_temp = 0.0; if (jsd_temp < 0.0) jsd_temp = 0.0; if (jswd_temp < 0.0) jswd_temp = 0.0; if (jswgd_temp < 0.0) jswgd_temp = 0.0; //***** Temperature dependence of D/B and S/B diode capacitance (line 193-278, file b4temp.c) *****// deltemp = $temperature - tnom; t0 = tcj * deltemp; if (t0 >= -1.0) begin cjs_temp = cjs *(1.0 + t0); cjd_temp = cjd *(1.0 + t0); end else begin if (cjs > 0.0) begin cjs_temp = 0.0; $strobe("Temperature effect has caused CJS to be negative. CJS is clamped to zero."); end if (cjd > 0.0) begin cjd_temp = 0.0; $strobe("Temperature effect has caused CJD to be negative. CJD is clamped to zero.\n"); end end t0 = tcjsw * deltemp; if (t0 >= -1.0) begin cjsws_temp = cjsws *(1.0 + t0); cjswd_temp = cjswd *(1.0 + t0); end else begin if (cjsws > 0.0) begin cjsws_temp = 0.0; $strobe("Temperature effect has caused CJSWS to be negative. CJSWS is clamped to zero."); end if (cjswd > 0.0) begin cjswd_temp = 0.0; $strobe("Temperature effect has caused CJSWD to be negative. CJSWD is clamped to zero."); end end t0 = tcjswg * deltemp; if (t0 >= -1.0) begin cjswgs_temp = cjswgs *(1.0 + t0); cjswgd_temp = cjswgd *(1.0 + t0); end else begin if (cjswgs > 0.0) begin cjswgs_temp = 0.0; $strobe("Temperature effect has caused CJSWGS to be negative. CJSWGS is clamped to zero."); end if (cjswgd > 0.0) begin cjswgd_temp = 0.0; $strobe("Temperature effect has caused CJSWGD to be negative. CJSWGD is clamped to zero."); end end phibs = pbs - tpb * deltemp; if (phibs < 0.01) begin phibs = 0.01; $strobe("Temperature effect has caused PBS to be less than 0.01. PBS is clamped to 0.01."); end phibd = pbd - tpb * deltemp; if (phibd < 0.01) begin phibd = 0.01; $strobe("Temperature effect has caused PBD to be less than 0.01. PBD is clamped to 0.01."); end phibsws = pbsws - tpbsw * deltemp; if (phibsws <= 0.01) begin phibsws = 0.01; $strobe("Temperature effect has caused PBSWS to be less than 0.01. PBSWS is clamped to 0.01."); end phibswd = pbswd - tpbsw * deltemp; if (phibswd <= 0.01) begin phibswd = 0.01; $strobe("Temperature effect has caused PBSWD to be less than 0.01. PBSWD is clamped to 0.01."); end phibswgs = pbswgs - tpbswg * deltemp; if (phibswgs <= 0.01) begin phibswgs = 0.01; $strobe("Temperature effect has caused PBSWGS to be less than 0.01. PBSWGS is clamped to 0.01."); end phibswgd = pbswgd - tpbswg * deltemp; if (phibswgd <= 0.01) begin phibswgd = 0.01; $strobe("Temperature effect has caused PBSWGD to be less than 0.01. PBSWGD is clamped to 0.01."); end //***** Effective length and width (line 362-396, file b4temp.c) *****// lnew = l + xl ; wnew = w / nf + xw; t0 = pow(lnew, lln); t1 = pow(wnew, lwn); tmp1 = ll / t0 + lw / t1 + lwl / (t0 * t1); dl = lint + tmp1; tmp2 = llc / t0 + lwc / t1 + lwlc / (t0 * t1); dlc = dlc + tmp2; dlcig = dlcig + tmp2; t2 = pow(lnew, wln); t3 = pow(wnew, wwn); tmp1 = wl / t2 + ww / t3 + wwl / (t2 * t3); dw = wint + tmp1; tmp2 = wlc / t2 + wwc / t3 + wwlc / (t2 * t3); dwj = dwj + tmp2; leff = lnew - 2.0 * dl; weff = wnew - 2.0 * dw; leffcv = lnew - 2.0 * dlc; if (leffcv <= 0.0) begin $strobe("Fatal: Effective channel length for C-V <= 0"); $finish(1); end weffcv = wnew - 2.0 * dwc; if (weffcv <= 0.0) begin $strobe("Fatal: Effective channel width for C-V <= 0"); $finish(1); end if (leff <= 1.0e-9) $strobe("Warning: leff = %e <= 1.0e-9. Recommended leff >= 1e-8.", leff); if (weff <= 1.0e-9) $strobe("Warning: weff = %e <= 1.0e-9. Recommended weff >= 1e-7.", weff); if (leffcv <= 1.0e-9) $strobe("warning: leff for CV = %e <= 1.0e-9. recommended leffcv >=1e-8 ", leffcv); if (weffcv <= 1.0e-9) $strobe("warning: weff for CV = %e <= 1.0e-9. recommended weffcv >= 1e-7 ", weffcv); //***** weffcj (line 429-437, file b4temp.c) *****// weffcj = wnew - 2.0 * dwj; if (weffcj <= 0.0) begin $strobe("Fatal: Effective channel width for S/D junctions <= 0."); $finish(1); end //***** Temperature model (line 955-1026, file b4temp.c) *****// abulkcvfactor = 1.0 + pow((clc / leffcv), cle); t0 = (tratio - 1.0); powweffwr = pow(weffcj * 1.0e6, wr) * nf; t1 = 0.0; t2 = 0.0; t3 = 0.0; t4 = 0.0; if (tempmod == 0) begin ua = ua + ua1 * t0; ub = ub + ub1 * t0; uc = uc + uc1 * t0; vsattemp = vsat - at * t0; t10 = prt * t0; if(rdsmod == 1) begin /* External Rd(V) */ t1 = rdw + t10; t2 = rdwmin + t10; /* External Rs(V) */ t3 = rsw + t10; t4 = rswmin + t10; end /* Internal Rds(V) in IV */ rds0 = (rdsw + t10) * nf / powweffwr; rdswmin = (rdswmin + t10) * nf / powweffwr; end else /* TEMPMOD = 1 */ begin ua = ua * (1.0 + ua1 * deltemp); ub = ub * (1.0 + ub1 * deltemp); uc = uc * (1.0 + uc1 * deltemp); vsattemp = vsat * (1.0 - at * deltemp); t10 = 1.0 + prt * deltemp; if(rdsmod == 1) begin /* External Rd(V) */ t1 = rdw * t10; t2 = rdwmin * t10; /* External Rs(V) */ t3 = rsw * t10; t4 = rswmin * t10; end /* Internal Rds(V) in IV */ rds0 = rdsw * t10 * nf / powweffwr; rdswmin = rdswmin * t10 * nf / powweffwr; end if (t1 < 0.0) begin t1 = 0.0; $strobe("Warning: rdw at current temperature is negative; set to 0."); end if (t2 < 0.0) begin t2 = 0.0; $strobe("Warning: rdwmin at current temperature is negative; set to 0."); end rd0 = t1 / powweffwr; rdwmin = t2 / powweffwr; if (t3 < 0.0) begin t3 = 0.0; $strobe("Warning: rsw at current temperature is negative; set to 0."); end if (t4 < 0.0) begin t4 = 0.0; $strobe("Warning: rswmin at current temperature is negative; set to 0."); end rs0 = t3 / powweffwr; rswmin = t4 / powweffwr; if (u0 > 1.0) u0 = u0 / 1.0e4; u0temp = u0 * pow(tratio, ute); if (u0temp <= 0.0) begin $strobe("Fatal: U0 at current temperature = %e is not positive.", u0temp); $finish(1); end if (eu < 0.0) begin eu = 0.0; $strobe("Warning: EU has been negative; reset to 0.0."); end if (vsattemp <= 0.0) begin $strobe("Fatal: VSAT at current temperature = %e is not positive.", vsattemp); $finish(1); end if (vsattemp < 1.0e3) $strobe("Warning: VSAT at current temperature = %e may be too small.", vsattemp); if (rds0 < 0.0) begin $strobe("Warning: Rds at current temperature = %e is negative. Set to zero.", rds0); rds0 = 0.0; end if (rdsw < 0.0) begin $strobe("Warning: rdsw = %e is negative. Set to zero.", rdsw); rdsw = 0.0; rds0 = 0.0; end if (rdswmin < 0.0) begin $strobe("Warning: rdswmin at current temperature = %e is negative. Set to zero.", rdswmin); rdswmin = 0.0; end if (b1 == -weff) begin $strobe("Fatal: (B1 + weff) = 0 causing divided-by-zero."); $finish(1); end if (abs(1.0e-6 / (b1 + weff)) > 10.0) $strobe("Warning: (B1 + weff) may be too small."); //***** Source End Velocity Limit (line 1024-1034, file b4temp.c) *****// if ((vtl != -99.0) && (vtl > 0.0)) begin if (lc < 0.0) lc = 0.0; t0 = leff / (xn * leff + lc); tfactor = (1.0 - t0) / (1.0 + t0 ); end //***** Overlap capacitances (line 1034-1040, file b4temp.c) *****// if (cf == -99.0) cf = 2.0 * epsrox * `EPS0 / `PI * ln(1.0 + 0.4e-6 / toxe); param_cgdo = (param_cgdo + cf) * weffcv; param_cgso = (param_cgso + cf) * weffcv; cgbo = cgbo * leffcv * nf; //***** Test on ndep and gamma1 (line 1043-1045, file b4temp.c) *****// if (ndep == -99.0 && gamma1 != -99.0) begin t0 = gamma1 * coxe; ndep = 3.01248e22 * t0 * t0; end else if (ndep != -99.0 && gamma1 == -99.0) gamma1 = 5.753e-12 * sqrt(ndep) / coxe; else if (ndep == -99.0 && gamma1 == -99.0) begin ndep = 1.0e17; gamma1 = 5.753e-12 * sqrt(ndep) / coxe; end if (ndep <= 0.0) begin $strobe("Fatal: NDEP = %e is not positive.", ndep); $finish(1); end if (ndep <= 1.0e12) $strobe("Warning: NDEP = %e may be too small.", ndep); else if (ndep >= 1.0e21) $strobe("Warning: NDEP = %e may be too large.", ndep); if (gamma2 == -99.0) gamma2 = 5.753e-12 * sqrt(nsub) / coxe; //***** Potential surface (line 1048-1049, file b4temp.c) *****// phi = vtm0 * ln(ndep / ni) + phin + 0.4; sqrtphi = sqrt(phi); //***** Calculation of some intermediaries (line 1054-1091, file b4temp.c) *****// xdep0 = sqrt(2.0 * `EPSSI / (`Charge_q * ndep * 1.0e6)) * sqrtphi; litl = sqrt(3.0 * xj * toxe); vbi = vtm0 * ln(nsd * ndep / (ni * ni)); if (ngate > 0.0) vfbsd = vtm0 * ln(ngate / nsd); else vfbsd = 0.0; cdep0 = sqrt(`Charge_q * `EPSSI * ndep * 1.0e6 / 2.0 / phi); toxratio = exp(ntox * ln(toxref / toxe)) / toxe / toxe; toxratioedge = exp(ntox * ln(toxref / (toxe * poxedge))) / toxe / toxe / poxedge / poxedge; mstar = 0.5 + atan(minv) / `PI; voffcbn = voff + voffl / leff; ldeb = sqrt(`EPSSI * vtm0 / (`Charge_q * ndep * 1.0e6)) / 3.0; acde = acde * pow((ndep / 2.0e16), -0.25); if (capmod ==2) begin if (acde < 0.1) $strobe("Warning: ACDE = %e is too small.", acde); if (acde > 1.6) $strobe("Warning: ACDE = %e is too large.", acde); end //***** Calculation of K1 and K2 (line 1101-1149, file b4temp.c) *****// if (k1 != -99.0 || k2 != -99.0) begin if (k1 == -99.0) begin $strobe("Warning: K1 should be specified with K2."); k1 = 0.53; end if (k2 == -99.0) begin $strobe("Warning: K2 should be specified with K1."); k2 = -0.0186; end end else begin if (vbx == -99.0) vbx = phi - 7.7348e-4 * ndep * xt * xt; if (vbx > 0.0) vbx = -vbx; if (vbm > 0.0) vbm = -vbm; t0 = gamma1 - gamma2; t1 = sqrt(phi - vbx) - sqrtphi; t2 = sqrt(phi * (phi - vbm)) - phi; k2 = t0 * t1 / (2.0 * t2 + vbm); k1 = gamma2 - 2.0 * k2 * sqrt(phi - vbm); end //***** Calculation of vbsc (line 1151-1161, file b4temp.c) *****// if (k2 < 0.0) begin t0 = 0.5 * k1 / k2; vbsc = 0.9 * (phi - t0 * t0); if (vbsc > -3.0) vbsc = -3.0; else if (vbsc < -30.0) vbsc = -30.0; end else vbsc = -30.0; if (vbsc > vbm) vbsc = vbm; //***** Flat-band voltage (line 1165-1179, file b4temp.c) *****// if (vfb == -99.0) begin if (vth0 != -99.0) vfb = type * vth0 - phi - k1 * sqrtphi; else vfb = -1.0; end //***** Flat-band voltage (line 1165-1179, file b4temp.c) *****// if (vth0 == -99.0) vth0 = type * (vfb + phi + k1 * sqrtphi); //***** Calculation of intermediaries (line 1181-1185, file b4temp.c) *****// k1ox = k1 * toxe / toxm; k2ox = k2 * toxe / toxm; //***** Calculation of vfbzb (line 1186-1265, file b4temp.c) *****// t3 = type * vth0 - vfb - phi; t4 = t3 + t3; t5 = 2.5 * t3; vtfbphi1 = (type == 1) ? t4 : t5; if (vtfbphi1 < 0.0) vtfbphi1 = 0.0; vtfbphi2 = 4.0 * t3; if (vtfbphi2 < 0.0) vtfbphi2 = 0.0; tmp = sqrt(`EPSSI / (epsrox * `EPS0) * toxe * xdep0); t0 = dsub * leff / tmp; if (t0 < `EXP_THRESHOLD) begin t1 = exp(t0); t2 = t1 - 1.0; t3 = t2 * t2; t4 = t3 + 2.0 * t1 * `MIN_EXP; theta0vb0 = t1 / t4; end else theta0vb0 = 1.0 / (`MAX_EXP - 2.0); t0 = drout * leff / tmp; if (t0 < `EXP_THRESHOLD) begin t1 = exp(t0); t2 = t1 - 1.0; t3 = t2 * t2; t4 = t3 + 2.0 * t1 * `MIN_EXP; t5 = t1 / t4; end else t5 = 1.0 / (`MAX_EXP - 2.0); /* 3.0 * `MIN_EXP omitted */ thetarout = pdibl1 * t5 + pdibl2; tmp = sqrt(xdep0); tmp1 = vbi - phi; tmp2 = factor1 * tmp; t0 = dvt1w * weff * leff / tmp2; if (t0 < `EXP_THRESHOLD) begin t1 = exp(t0); t2 = t1 - 1.0; t3 = t2 * t2; t4 = t3 + 2.0 * t1 * `MIN_EXP; t8 = t1 / t4; end else t8 = 1.0 / (`MAX_EXP - 2.0); t0 = dvt0w * t8; t8 = t0 * tmp1; t0 = dvt1 * leff / tmp2; if (t0 < `EXP_THRESHOLD) begin t1 = exp(t0); t2 = t1 - 1.0; t3 = t2 * t2; t4 = t3 + 2.0 * t1 * `MIN_EXP; t9 = t1 / t4; end else t9 = 1.0 / (`MAX_EXP - 2.0); t9 = dvt0 * t9 * tmp1; t4 = toxe * phi / (weff + w0); t0 = sqrt(1.0 + lpe0 / leff); t5 = k1ox * (t0 - 1.0) * sqrtphi + (kt1 + kt1l / leff) * (tratio - 1.0); tmp3 = type * vth0 - t8 - t9 + k3 * t4 + t5; vfbzb = tmp3 - phi - k1 * sqrtphi; //***** Stress Effect (line 1267-1366, file b4temp.c) *****// ldrn = l; t0 = pow(lnew, llodku0); w_tmp = wnew + wlod; t1 = pow(w_tmp, wlodku0); tmp1 = lku0 / t0 + wku0 / t1 + pku0 / (t0 * t1); ku0 = 1.0 + tmp1; t0 = pow(lnew, llodvth); t1 = pow(w_tmp, wlodvth); tmp1 = lkvth0 / t0 + wkvth0 / t1 + pkvth0 / (t0 * t1); kvth0 = 1.0 + tmp1; kvth0 = sqrt(kvth0*kvth0 + `DELTA); t0 = (tratio - 1.0); ku0temp = ku0 * (1.0 + tku0 *t0) + `DELTA; inv_saref = 1.0/(saref + 0.5 * ldrn); inv_sbref = 1.0/(sbref + 0.5 * ldrn); inv_od_ref = inv_saref + inv_sbref; rho_ref = KU0 / ku0temp * inv_od_ref; if ((sa > 0.0) && (sb > 0.0) && ((nf == 1.0) || ((nf > 1.0) && (sd > 0.0)))) begin inv_sa = 0; inv_sb = 0; for(i = 0; i < nf; i = i+1) begin t0 = 1.0 / nf / (sa + 0.5*ldrn + i * (sd +ldrn)); t1 = 1.0 / nf / (sb + 0.5*ldrn + i * (sd +ldrn)); inv_sa = inv_sa + t0; inv_sb = inv_sb + t1; end inv_odeff = inv_sa + inv_sb; rho = KU0 / ku0temp * inv_odeff; t0 = (1.0 + rho)/(1.0 + rho_ref); u0temp = u0temp * t0; t1 = (1.0 + kvsat * rho)/(1.0 + kvsat * rho_ref); vsattemp = vsattemp * t1; od_offset = inv_odeff - inv_od_ref; dvth0_lod = KVTH0 / kvth0 * od_offset; dk2_lod = stk2 / pow(kvth0, lodk2) * od_offset; deta0_lod = steta0 / pow(kvth0, lodeta0) * od_offset; vth0 = vth0 + dvth0_lod; if (VFB == -99.0 && VTH0 == -99.0) vfb = -1.0; else vfb = vfb + type * dvth0_lod; vfbzb = vfbzb + type * dvth0_lod; t3 = type * vth0 - vfb - phi; t4 = t3 + t3; t5 = 2.5 * t3; vtfbphi1 = (type == 1) ? t4 : t5; if (vtfbphi1 < 0.0) vtfbphi1 = 0.0; vtfbphi2 = 4.0 * t3; if (vtfbphi2 < 0.0) vtfbphi2 = 0.0; k2 = k2 + dk2_lod; if (k2 < 0.0) begin t0 = 0.5 * k1 / k2; vbsc = 0.9 * (phi - t0 * t0); if (vbsc > -3.0) vbsc = -3.0; else if (vbsc < -30.0) vbsc = -30.0; end else vbsc = -30.0; if (vbsc > vbm) vbsc = vbm; k2ox = k2 * toxe / toxm; eta0 = eta0 + deta0_lod; end //*********** HF model parameters (line 1371-1392, file b4temp.c) *****************// if (rbodymod == 1.0) begin if (rbdb < 1.0e-3) grbdb = 1.0e3; else grbdb = gbmin + 1.0 / rbdb; if (rbpb < 1.0e-3) grbpb = 1.0e3; else grbpb = gbmin + 1.0 / rbpb; if (rbps < 1.0e-3) grbps = 1.0e3; else grbps = gbmin + 1.0 / rbps; if (rbsb < 1.0e-3) grbsb = 1.0e3; else grbsb = gbmin + 1.0 / rbsb; if (rbpd < 1.0e-3) grbpd = 1.0e3; else grbpd = gbmin + 1.0 / rbpd; end //*********** Process geomertry dependent parasitics (line 1396-1452, file b4temp.c) *****************// grgeltd = rshg * (xgw + weffcj / 3.0 / ngcon) / (ngcon * nf * (lnew - xgl)); if (grgeltd > 0.0) grgeltd = 1.0 / grgeltd; else begin grgeltd = 1.0e3; if (rgatemod != 0) $strobe("Warning: The gate conductance reset to 1.0e3 ohms."); end dmcgeff = dmcg - dmcgt; dmcieff = dmci; dmdgeff = dmdg - dmcgt; if (ps > 0.0) begin if (permod == 0) pseff = ps; else pseff = ps - weffcj * nf; end else pseff = get_ps(nf, geomod, imin, weffcj, dmcgeff, dmcieff, dmdgeff); if (pd > 0.0) begin if (permod == 0) pdeff = pd; else pdeff = pd - weffcj * nf; end else pdeff = get_pd(nf, geomod, imin, weffcj, dmcgeff, dmcieff, dmdgeff); if (as > 0.0) aseff = as; else aseff = get_as(nf, geomod, imin, weffcj, dmcgeff, dmcieff, dmdgeff); if (ad > 0.0) adeff = ad; else adeff = get_ad(nf, geomod, imin, weffcj, dmcgeff, dmcieff, dmdgeff); //*********** Processing S/D resistance and conductance below (line 1453-1516, file b4temp.c) *****************// if (nrs != -99.0) gsdiff = rsh * nrs; else if (rgeomod > 0) gsdiff = get_rtot(nf, geomod, rgeomod, imin, weffcj, rsh, dmcgeff, dmcieff, dmdgeff, 1); else gsdiff = 0.0; if (gsdiff > 0.0) gsdiff = 1.0 / gsdiff; else begin gsdiff = 1.0e3; /* mho */ $strobe ("Warning: source conductance reset to 1.0e3 mho."); end if (nrd != -99.0) gddiff = rsh * nrd; else if (rgeomod > 0) gddiff = get_rtot(nf, geomod, rgeomod, imin, weffcj, rsh, dmcgeff, dmcieff, dmdgeff, 0); else gddiff = 0.0; if (gddiff > 0.0) gddiff = 1.0 / gddiff; else begin gddiff = 1.0e3; /* mho */ $strobe ("Warning: drain conductance reset to 1.0e3 mho."); end aechvb = (type == 1) ? 4.97232e-7 : 3.42537e-7; bechvb = (type == 1) ? 7.45669e11 : 1.16645e12; aechvbedge = aechvb * weff * dlcig * toxratioedge; bechvbedge = -bechvb * toxe * poxedge; aechvb = aechvb * weff * leff * toxratio; bechvb = bechvb * -toxe; //*********** Diode model intermediaries calculation (line 1519-1635, file b4temp.c) *****************// nvtms = vtm * njs; if ((aseff <= 0.0) && (pseff <= 0.0)) isbs = 1.0e-14; else isbs = aseff * jss_temp + pseff * jsws_temp + weffcj * nf * jswgs_temp; if (isbs > 0.0) begin case(diomod) 0: begin if ((bvs / nvtms) > `EXP_THRESHOLD) xexpbvs = xjbvs * `MIN_EXP; else xexpbvs = xjbvs * exp(-bvs / nvtms); end 1: begin vjsmfwd = get_vjm(nvtms, ijthsfwd, isbs, 0.0); ivjsmfwd = isbs * exp(vjsmfwd / nvtms); end 2: begin if ((bvs / nvtms) > `EXP_THRESHOLD) begin xexpbvs = xjbvs * `MIN_EXP; tmp = `MIN_EXP; end else begin xexpbvs = exp(-bvs / nvtms); tmp = xexpbvs; xexpbvs = xexpbvs * xjbvs; end vjsmfwd = get_vjm(nvtms, ijthsfwd, isbs, xexpbvs); t0 = exp(vjsmfwd / nvtms); ivjsmfwd = isbs * (t0 - xexpbvs / t0 + xexpbvs - 1.0); sslpfwd = isbs * (t0 + xexpbvs / t0) / nvtms; t2 = ijthsrev / isbs; if (t2 < 1.0) begin t2 = 10.0; $strobe("Warning: ijthsrev too small and set to 10 times isbsat.\n"); end vjsmrev = -bvs - nvtms * ln((t2 - 1.0) / xjbvs); t1 = xjbvs * exp(-(bvs + vjsmrev) / nvtms); ivjsmrev = isbs * (1.0 + t1); sslprev = -isbs * t1 / nvtms; end default: $strobe("Specified diomod = %d not matched", diomod); endcase end nvtmd = vtm * njd; if ((adeff <= 0.0) && (pdeff <= 0.0)) isbd = 1.0e-14; else isbd = adeff * jsd_temp + pdeff * jswd_temp + weffcj * nf * jswgd_temp; if (isbd > 0.0) begin case(diomod) 0: begin if ((bvd / nvtmd) > `EXP_THRESHOLD) xexpbvd = xjbvd * `MIN_EXP; else xexpbvd = xjbvd * exp(-bvd / nvtmd); end 1: begin vjdmfwd = get_vjm(nvtmd, ijthdfwd, isbd, 0.0); ivjdmfwd = isbd * exp(vjdmfwd / nvtmd); end 2: begin if ((bvd / nvtmd) > `EXP_THRESHOLD) begin xexpbvd = xjbvd * `MIN_EXP; tmp = `MIN_EXP; end else begin xexpbvd = exp(-bvd / nvtmd); tmp = xexpbvd; xexpbvd = xexpbvd * xjbvd; end vjsmfwd = get_vjm(nvtmd, ijthdfwd, isbd, xexpbvd); t0 = exp(vjdmfwd / nvtmd); ivjdmfwd = isbd * (t0 - xexpbvd / t0 + xexpbvd - 1.0); dslpfwd = isbd * (t0 + xexpbvd / t0) / nvtmd; t2 = ijthdrev / isbd; if (t2 < 1.0) begin t2 = 10.0; $strobe("Warning: ijthdrev too small and set to 10 times idbsat.\n"); end vjdmrev = -bvd - nvtmd * ln((t2 - 1.0) / xjbvd); t1 = xjbvd * exp(-(bvd + vjdmrev) / nvtmd); ivjdmrev = isbd * (1.0 + t1); dslprev = -isbd * t1 / nvtmd; end default: $strobe("Specified diomod = %d not matched", diomod); endcase end end //*********************************// //****** End of initial_step ******// //*********************************// //****** Calculation of all equations to define all currents ******// //****** Definition of the tensions ******// vds = type * V(drainp, sourcep); vgs = type * V(gatep, sourcep); vbs = type * V(bulkp, sourcep); vges = type * V(gate, sourcep); vgms = type * V(gatem, sourcep); vsbs = type * V(sourceb, sourcep); vdbs = type * V(drainb, sourcep); vses = type * V(source, sourcep); vdes = type * V(drain, sourcep); vbes = type * V(bulk, sourcep); vgd = vgs - vds; vbd = vbs - vds; vgb = vgs - vbs; vded = vdes - vds; vgeg = vges - vgs; vgmg = vgms - vgs; vgmb = vgms - vbs; vgegm = vgeg - vgmg; vbeb = vbes - vbs; vdbd = vdbs - vds; vbesb = vbes - vsbs; vbedb = vbes - vdbs; vbsb = vbs - vsbs; vbdb = vbs - vdbs; //***** Source/drain junction diode DC model (line 634-829, file b4ld.c) *****// vbs_jct = (rbodymod == 0) ? vbs : vsbs; vbd_jct = (rbodymod == 0) ? vbd : vdbd; nvtms = vtm * njs; if ((aseff <= 0.0) && (pseff <= 0.0)) isbs = 1.0e-14; else isbs = aseff * jss_temp + pseff * jsws_temp + weffcj * nf * jswgs_temp; if (isbs <= 0.0) cbs = gmin * vbs_jct; else begin case(diomod) 0: begin evbs = exp(vbs_jct / nvtms); t1 = xjbvs * exp(-(bvs + vbs_jct) / nvtms); cbs = isbs * (evbs + xexpbvs - t1 - 1.0) + gmin * vbs_jct; end 1: begin t2 = vbs_jct / nvtms; if (t2 < -`EXP_THRESHOLD) cbs = isbs * (`MIN_EXP - 1.0) + gmin * vbs_jct; else if (vbs_jct <= vjsmfwd) begin evbs = exp(t2); cbs = isbs * (evbs - 1.0) + gmin * vbs_jct; end else begin t0 = ivjsmfwd / nvtms; cbs = ivjsmfwd - isbs + t0 * (vbs_jct - vjsmfwd) + gmin * vbs_jct; end end 2: begin if (vbs_jct < vjsmrev) begin t0 = vbs_jct / nvtms; if (t0 < -`EXP_THRESHOLD) evbs = `MIN_EXP; else evbs = exp(t0); t1 = evbs - 1.0; t2 = ivjsmrev + sslprev * (vbs_jct - vjsmrev); cbs = t1 * t2 + gmin * vbs_jct; end else if (vbs_jct <= vjsmfwd) begin t0 = vbs_jct / nvtms; if (t0 < -`EXP_THRESHOLD) evbs = `MIN_EXP; else evbs = exp(t0); t3 = (bvs + vbs_jct) / nvtms; if (t1 > `EXP_THRESHOLD) t2 = `MIN_EXP; else t2 = exp(-t1); cbs = isbs * (evbs + xexpbvs - 1.0 - xjbvs * t2) + gmin * vbs_jct; end else cbs = ivjsmfwd + sslpfwd * (vbs_jct - vjsmfwd) + gmin * vbs_jct; end endcase end nvtmd = vtm * njd; if ((adeff <= 0.0) && (pdeff <= 0.0)) isbd = 1.0e-14; else isbd = adeff * jsd_temp + pdeff * jswd_temp + weffcj * nf * jswgd_temp; if (isbd <= 0.0) cbd = gmin * vbd_jct; else begin case(diomod) 0: begin evbd = exp(vbd_jct / nvtmd); t1 = xjbvd * exp(-(bvd + vbd_jct) / nvtmd); cbd = isbd * (evbd + xexpbvd - t1 - 1.0) + gmin * vbd_jct; end 1: begin t2 = vbd_jct / nvtmd; if (t2 < -`EXP_THRESHOLD) begin cbd = isbd * (`MIN_EXP - 1.0) + gmin * vbd_jct; end else if (vbd_jct <= vjdmfwd) begin evbd = exp(t2); cbd = isbd * (evbd - 1.0) + gmin * vbd_jct; end else begin t0 = ivjdmfwd / nvtmd; cbd = ivjdmfwd - isbd + t0 * (vbd_jct - vjdmfwd) + gmin * vbd_jct; end end 2: begin if (vbd_jct < vjdmrev) begin t0 = vbd_jct / nvtmd; if (t0 < -`EXP_THRESHOLD) evbd = `MIN_EXP; else evbd = exp(t0); t1 = evbd - 1.0; t2 = ivjdmrev + dslprev * (vbd_jct - vjdmrev); cbd = t1 * t2 + gmin * vbd_jct; end else if (vbd_jct <= vjdmfwd) begin t0 = vbd_jct / nvtmd; if (t0 < -`EXP_THRESHOLD) evbd = `MIN_EXP; else evbd = exp(t0); t1 = (bvd + vbd_jct) / nvtmd; if (t1 > `EXP_THRESHOLD) t2 = `MIN_EXP; else t2 = exp(-t1); cbd = isbd * (evbd + xexpbvd - 1.0 - xjbvd * t2) + gmin * vbd_jct; end else cbd = ivjdmfwd + dslpfwd * (vbd_jct - vjdmfwd) + gmin * vbd_jct; end endcase end //***** Mode choice (line 831-844, file b4ld.c) *****// if (vds >= 0.0) begin mode = 1; Vds = vds; Vbs = vbs; end else begin mode = -1; Vds = -vds; Vbs = vbd; end //***** Effective Vbs (line 846-863, file b4ld.c) *****// t0 = Vbs - vbsc - 0.001; t1 = sqrt(t0 * t0 - 0.004 * vbsc); if (t0 >= 0.0) vbseff = vbsc + 0.5 * (t0 + t1); else begin t2 = -0.002 / (t1 - t0); vbseff = vbsc * (1.0 + t2); end // Correction to forward body bias t9 = 0.95 * phi; t0 = t9 - vbseff - 0.001; t1 = sqrt(t0 * t0 + 0.004 * t9); vbseff = t9 - 0.5 * (t0 + t1); //***** Calculation of phis (line 865-867, file b4ld.c) *****// phis = phi - vbseff; sqrtphis = sqrt(phis); //***** Threshold Voltage (line 878-969, file b4ld.c) *****// xdep = xdep0 * sqrtphis / sqrt(phi); t3 = sqrt(xdep); v0 = vbi - phi; t0 = dvt2 * vbseff; if (t0 >= - 0.5) begin t1 = 1.0 + t0; t2 = dvt2; end else begin t4 = 1.0 / (3.0 + 8.0 * t0); t1 = (1.0 + 3.0 * t0) * t4; t2 = dvt2 * t4 * t4; end lt1 = factor1 * t3 * t1; t0 = dvt2w * vbseff; if (t0 >= - 0.5) begin t1 = 1.0 + t0; t2 = dvt2w; end else begin t4 = 1.0 / (3.0 + 8.0 * t0); t1 = (1.0 + 3.0 * t0) * t4; t2 = dvt2w * t4 * t4; end ltw = factor1 * t3 * t1; t0 = dvt1 * leff / lt1; if (t0 < `EXP_THRESHOLD) begin t1 = exp(t0); t2 = t1 - 1.0; t3 = t2 * t2; t4 = t3 + 2.0 * t1 * `MIN_EXP; theta0 = t1 / t4; end else theta0 = 1.0 / (`MAX_EXP - 2.0); /* 3.0 * `MIN_EXP omitted */ thetavth = dvt0 * theta0; delt_vth = thetavth * v0; t0 = dvt1w * weff * leff / ltw; if (t0 < `EXP_THRESHOLD) begin t1 = exp(t0); t2 = t1 - 1.0; t3 = t2 * t2; t4 = t3 + 2.0 * t1 * `MIN_EXP; t5 = t1 / t4; end else t5 = 1.0 / (`MAX_EXP - 2.0); /* 3.0 * `MIN_EXP omitted */ t0 = dvt0w * t5; t2 = t0 * v0; tratio = $temperature / tnom - 1.0; t0 = sqrt(1.0 + lpe0 / leff); t1 = k1ox * (t0 - 1.0) * sqrtphi + (kt1 + kt1l / leff + kt2 * vbseff) * tratio; vth_narroww = toxe * phi / (weff + w0); t3 = eta0 + etab * vbseff; if (t3 < 1.0e-4) begin t9 = 1.0 / (3.0 - 2.0e4 * t3); t3 = (2.0e-4 - t3) * t9; t4 = t9 * t9; end else t4 = 1.0; ddibl_sft_dvd = t3 * theta0vb0; dibl_sft = ddibl_sft_dvd * Vds; lpe_vb = sqrt(1.0 + lpeb / leff); vth = type * vth0 + (k1ox * sqrtphis - k1 * sqrt(phi)) * lpe_vb - k2ox * vbseff - delt_vth - t2 + (k3 + k3b * vbseff) * vth_narroww + t1 - dibl_sft; //***** Swing factor (line 978-998, file b4ld.c) *****// tmp1 = `EPSSI / xdep; tmp2 = nfactor * tmp1; tmp3 = cdsc + cdscb * vbseff + cdscd * Vds; tmp4 = (tmp2 + tmp3 * theta0 + cit) / coxe; if (tmp4 >= -0.5) n = 1.0 + tmp4; else begin t0 = 1.0 / (3.0 + 8.0 * tmp4); n = (1.0 + 3.0 * tmp4) * t0; end //***** Vth correction for Pocket Implant (line 1002-1024, file b4ld.c) *****// if (dvtp0 > 0.0) begin t0 = -dvtp1 * Vds; if (t0 < -`EXP_THRESHOLD) t2 = `MIN_EXP; else t2 = exp(t0); t3 = leff + dvtp0 * (1.0 + t2); t4 = vtm * ln(leff / t3); vth = vth - n * t4; end //***** Poly Gate Si Depletion Effect (line 1028 & 4584-4612, file b4ld.c) *****// t0 = vfb + phi; if ((ngate > 1.0e18) && (ngate < 1.0e25) && (vgs > t0)) begin t1 = 1.0e6 * `Charge * `EPSSI * ngate / (coxe * coxe); t8 = vgs - t0; t4 = sqrt(1.0 + 2.0 * t8 / t1); t2 = 2.0 * t8 / (t4 + 1.0); t3 = 0.5 * t2 * t2 / t1; t7 = 1.12 - t3 - 0.05; t6 = sqrt(t7 * t7 + 0.224); t5 = 1.12 - 0.5 * (t7 + t6); vgs_eff = vgs - t5; end else vgs_eff = vgs; if ((ngate > 1.0e18) && (ngate < 1.0e25) && (vgd > t0)) begin t1 = 1.0e6 * `Charge * `EPSSI * ngate / (coxe * coxe); t8 = vgd - t0; t4 = sqrt(1.0 + 2.0 * t8 / t1); t2 = 2.0 * t8 / (t4 + 1.0); t3 = 0.5 * t2 * t2 / t1; t7 = 1.12 - t3 - 0.05; t6 = sqrt(t7 * t7 + 0.224); t5 = 1.12 - 0.5 * (t7 + t6); vgd_eff = vgd - t5; end else vgd_eff = vgd; if(mode > 0) Vgs_eff = vgs_eff; else Vgs_eff = vgd_eff; vgst = Vgs_eff - vth; //***** Calculation of vgsteff (line 1051-1109, file b4ld.c) *****// t0 = n * vtm; t1 = mstar * vgst; t2 = t1 / t0; if (t2 > `EXP_THRESHOLD) t10 = t1; else if (t2 < -`EXP_THRESHOLD) begin t10 = vtm * ln(1.0 + `MIN_EXP); t10 = t10 * n; end else begin expvgst = exp(t2); t3 = vtm * ln(1.0 + expvgst); t10 = n * t3; end t1 = voffcbn - (1.0 - mstar) * vgst; t2 = t1 / t0; if (t2 < -`EXP_THRESHOLD) begin t3 = coxe * `MIN_EXP / cdep0; t9 = mstar + t3 * n; end else if (t2 > `EXP_THRESHOLD) begin t3 = coxe * `MAX_EXP / cdep0; t9 = mstar + t3 * n; end else begin expvgst = exp(t2); t3 = coxe / cdep0; t4 = t3 * expvgst; t5 = t1 * t4 / t0; t9 = mstar + n * t4; end vgsteff = t10 / t9; //***** Effective Channel Geometry (line 1111-1123, file b4ld.c) *****// t9 = sqrtphis - sqrt(phi); Weff = weff - 2.0 * (dwg * vgsteff + dwb * t9); if (Weff < 2.0e-8) /* to avoid the discontinuity problem due to Weff */ begin t0 = 1.0 / (6.0e-8 - 2.0 * Weff); Weff = 2.0e-8 * (4.0e-8 - Weff) * t0; end //***** Source/Drain Resistance (line 1126-1149, file b4ld.c) *****// if (rdsmod == 1) rds = 0.0; else begin t0 = 1.0 + prwg * vgsteff; t1 = prwb * t9; t2 = 1.0 / t0 + t1; t3 = t2 + sqrt(t2 * t2 + 0.01); t4 = rds0 * 0.5; rds = rdswmin + t3 * t4; end //***** Bulk Charge Effect (line 1151-1205, file b4ld.c) *****// t9 = 0.5 * k1ox * lpe_vb / sqrtphis; t1 = t9 + k2ox - k3b * vth_narroww; t9 = sqrt(xj * xdep); tmp1 = leff + 2.0 * t9; t5 = leff / tmp1; tmp2 = a0 * t5; tmp3 = weff + b1; tmp4 = b0 / tmp3; t2 = tmp2 + tmp4; t6 = t5 * t5; t7 = t5 * t6; abulk0 = 1.0 + t1 * t2; t8 = ags * a0 * t7; dabulk_dvg = -t1 * t8; abulk = abulk0 + dabulk_dvg * vgsteff; if (abulk0 < 0.1) /* added to avoid the problems caused by abulk0 */ begin t9 = 1.0 / (3.0 - 20.0 * abulk0); abulk0 = (0.2 - abulk0) * t9; end if (abulk < 0.1) begin t9 = 1.0 / (3.0 - 20.0 * abulk); abulk = (0.2 - abulk) * t9; end t2 = keta * vbseff; if (t2 >= -0.9) t0 = 1.0 / (1.0 + t2); else begin t1 = 1.0 / (0.8 + t2); t0 = (17.0 + 20.0 * t2) * t1; end abulk = abulk * t0; abulk0 = abulk0 * t0; //***** Effective Mobility (line 1207-1255, file b4ld.c) *****// if (mobmod == 0) begin t0 = vgsteff + vth + vth; t2 = ua + uc * vbseff; t3 = t0 / toxe; t5 = t3 * (t2 + ub * t3); end else if (mobmod == 1) begin t0 = vgsteff + vth + vth; t2 = 1.0 + uc * vbseff; t3 = t0 / toxe; t4 = t3 * (ua + ub * t3); t5 = t4 * t2; end else begin t0 = (vgsteff + vtfbphi1) / toxe; t1 = exp(eu * ln(t0)); t2 = ua + uc * vbseff; t5 = t1 * t2; end if (t5 >= -0.8) denomi = 1.0 + t5; else begin t9 = 1.0 / (7.0 + 10.0 * t5); denomi = (0.6 + t5) * t9; end ueff = u0temp / denomi; //***** Saturation Voltage (line 1257-1357, file b4ld.c) *****// wvcox = Weff * vsattemp * coxe; wvcoxrds = wvcox * rds; esat = 2.0 * vsattemp / ueff; esatl = esat * leff; t0 = -esatl /ueff; if (a1 == 0.0) Lambda = a2; else if (a1 > 0.0) begin t0 = 1.0 - a2; t1 = t0 - a1 * vgsteff - 0.0001; t2 = sqrt(t1 * t1 + 0.0004 * t0); Lambda = a2 + t0 - 0.5 * (t1 + t2); end else begin t1 = a2 + a1 * vgsteff - 0.0001; t2 = sqrt(t1 * t1 + 0.0004 * a2); Lambda = 0.5 * (t1 + t2); end vgst2vtm = vgsteff + 2.0 * vtm; if ((rds == 0.0) && (Lambda == 1.0)) begin t0 = 1.0 / (abulk * esatl + vgst2vtm); t1 = t0 * t0; t2 = vgst2vtm * t0; t3 = esatl * vgst2vtm; vdsat = t3 * t0; end else begin t9 = abulk * wvcoxrds; t8 = abulk * t9; t7 = vgst2vtm * t9; t6 = vgst2vtm * wvcoxrds; t0 = 2.0 * abulk * (t9 - 1.0 + 1.0 / Lambda); t1 = vgst2vtm * (2.0 / Lambda - 1.0) + abulk * esatl + 3.0 * t7; t2 = vgst2vtm * (esatl + 2.0 * t6); t3 = sqrt(t1 * t1 - 2.0 * t0 * t2); vdsat = (t1 - t3) / t0; end //***** Effective Vds (line 1359-1398, file b4ld.c) *****// t1 = vdsat - Vds - delta; t2 = sqrt(t1 * t1 + 4.0 * delta * vdsat); t0 = t1 / t2; t9 = 2.0 * delta; if (t1 >= 0.0) vdseff = vdsat - 0.5 * (t1 + t2); else begin t4 = t9 / (t2 - t1); t5 = 1.0 - t4; vdseff = vdsat * t5; end if (Vds == 0.0) vdseff = Vds; if (vdseff > Vds) vdseff = Vds; diffvds = Vds - vdseff; //***** Velocity Overshoot (line 1400-1439, file b4ld.c) *****// if((lambda != -99.0) && (lambda > 0.0) ) begin t1 = leff * ueff; t2 = lambda / t1; t5 = 1.0 / (esat * litl); t6 = 1.0 + diffvds * t5; t7 = 2.0 / (t6 * t6 + 1.0); t8 = 1.0 - t7; t10 = 1.0 + t2 * t8; esatl = esatl * t10; end //***** Early Voltage at vdsat (line 1441-1464 , file b4ld.c) *****// tmp4 = 1.0 - 0.5 * abulk * vdsat / vgst2vtm; t9 = wvcoxrds * vgsteff; t0 = esatl + vdsat + 2.0 * t9 * tmp4; t9 = wvcoxrds * abulk; t1 = 2.0 / Lambda - 1.0 + t9; vasat = t0 / t1; //***** Drain Current for Triode Region (line 1466-1523 , file b4ld.c) *****// tmp1 = vtfbphi2; tmp2 = 2.0e8 * toxp; dt0_dvg = 1.0 / tmp2; t0 = (vgsteff + tmp1) * dt0_dvg; tmp3 = exp(0.7 * ln(t0)); t1 = 1.0 + tmp3; tcen = 1.9e-9 / t1; coxeff = `EPSSI * coxp / (`EPSSI + coxp * tcen); coxeffwovl = coxeff * Weff / leff; beta = ueff * coxeffwovl; abovvgst2vtm = abulk / vgst2vtm; t0 = 1.0 - 0.5 * vdseff * abovvgst2vtm; fgche1 = vgsteff * t0; t9 = vdseff / esatl; fgche2 = 1.0 + t9; gche = beta * fgche1 / fgche2; t0 = 1.0 + gche * rds; idl = gche / t0; //***** Degradation Factor due to Pocket Implant (line 1525-1535 , file b4ld.c) *****// if (fprout <= 0.0) fp = 1.0; else begin t9 = fprout * sqrt(leff) / vgst2vtm; fp = 1.0 / (1.0 + t9); end //***** Early Voltage with Channel Length Modulatiom (line 1537-1585, file b4ld.c) *****// t8 = pvag / esatl; t9 = t8 * vgsteff; if (t9 > -0.9) pvagterm = 1.0 + t9; else begin t4 = 1.0 / (17.0 + 20.0 * t9); pvagterm = (0.8 + t9) * t4; end if ((pclm > 0.0) && (diffvds > 1.0e-10)) begin t0 = 1.0 + rds * idl; t2 = vdsat / esat; t1 = leff + t2; cclm = fp * pvagterm * t0 * t1 / (pclm * litl); vaclm = cclm * diffvds; end else begin vaclm = `MAX_EXP; cclm = `MAX_EXP; end //***** Early Voltage with Drain-INduced Barrier Lowering (line 1587-1635, file b4ld.c) *****// if (thetarout > 0.0) begin t8 = abulk * vdsat; t0 = vgst2vtm * t8; t1 = vgst2vtm + t8; t2 = thetarout; vadibl = (vgst2vtm - t0 / t1) / t2; t7 = pdiblb * vbseff; if (t7 >= -0.9) begin t3 = 1.0 / (1.0 + t7); vadibl = vadibl * t3; end else begin t4 = 1.0 / (0.8 + t7); t3 = (17.0 + 20.0 * t7) * t4; vadibl = vadibl * t3; end vadibl = vadibl * pvagterm; end else vadibl = `MAX_EXP; //***** Early Voltage with Drain-INduced Threshold Shift (line 1643-1664 , file b4ld.c) *****// if ((pditsd * Vds) > `EXP_THRESHOLD) t1 = `MAX_EXP; else t1 = exp(pditsd * Vds); if (pdits > 0.0) vadits = (1.0 + (1.0 + pditsl * leff) * t1) / pdits * fp; else vadits = `MAX_EXP; //***** Early Voltage with Substrate Current Induced Body Effect (line 1666-1685 , file b4.c) *****// if (pscbe2 > 0.0) begin if (diffvds > (pscbe1 * litl / `EXP_THRESHOLD)) begin t0 = pscbe1 * litl / diffvds; vascbe = leff * exp(t0) / pscbe2; end else vascbe = `MAX_EXP * leff/pscbe2; end else vascbe = `MAX_EXP; //***** Drain Current (line 1687-1719 , file b4ld.c) *****// t9 = diffvds / vadibl; t0 = 1.0 + t9; idsa = idl * t0; t9 = diffvds / vadits; t0 = 1.0 + t9; idsa = idsa * t0; t0 = ln((vasat + vaclm) / vasat); t1 = t0 / cclm; t9 = 1.0 + t1; idsa = idsa * t9; //***** Substrate current (line 1722-1760, file b4ld.c) *****// tmp = alpha0 + alpha1 * leff; if ((tmp <= 0.0) || (beta0 <= 0.0)) isub = 0.0; else begin t2 = tmp / leff; if (diffvds > beta0 / `EXP_THRESHOLD) begin t0 = -beta0 / diffvds; t1 = t2 * diffvds * exp(t0); end else begin t3 = t2 * `MIN_EXP; t1 = t3 * diffvds; end t4 = idsa * vdseff; isub = t1 * t4; end csub = isub; //***** Current Drain (line 1761-1785, file b4ld.c) *****// t9 = diffvds / vascbe; t0 = 1.0 + t9; ids = idsa * t0; cdrain = ids * vdseff; //***** Source End Velocity Limit (line 1787-1817, file b4ld.c) *****// if ((vtl != -99.0) && (vtl > 0.0)) begin t12 = 1.0 / leff / coxeffwovl; t11 = t12 / vgsteff; t10 = -t11 / vgsteff; vs = cdrain * t11; t0 = 2 * `MM; t1 = vs / (vtl * tfactor); if (t1 <= 0) t2 = 1.0; else t2 = 1.0 + exp(t0 * ln(t1)); fsevl = 1.0 / exp(ln(t2)/ t0); cdrain = cdrain * fsevl; end //***** Rg calculation (line 1824-1858, file b4ld.c) *****// if (rgatemod > 1) begin t9 = xrcrg2 * vtm; t0 = t9 * beta; gcrg = xrcrg1 * (t0 + ids); if (nf != 1.0) gcrg = gcrg * nf; if (rgatemod == 2) begin t10 = grgeltd * grgeltd; t11 = grgeltd + gcrg; gcrg = grgeltd * gcrg / t11; end end //*************** Calculate bias-dependent external S/D resistance (line 1861-1939, file b4ld.c) ****************// if (rdsmod == 1.0) begin /* rs(v) */ t0 = vgs - vfbsd; t1 = sqrt(t0 * t0 + 1.0e-4); vgs_eff = 0.5 * (t0 + t1); t0 = 1.0 + prwg * vgs_eff; t1 = -prwb * vbs; t2 = 1.0 / t0 + t1; t3 = t2 + sqrt(t2 * t2 + 0.01); t4 = rs0 * 0.5; rs = rswmin + t3 * t4; t0 = 1.0 + gsdiff * rs; gstot = gsdiff / t0; /* rd(v) */ t0 = vgd - vfbsd; t1 = sqrt(t0 * t0 + 1.0e-4); vgd_eff = 0.5 * (t0 + t1); t0 = 1.0 + prwg * vgd_eff; t1 = -prwb * vbd; t2 = 1.0 / t0 + t1; t3 = t2 + sqrt(t2 * t2 + 0.01); t4 = rd0 * 0.5; rd = rdwmin + t3 * t4; t0 = 1.0 + gddiff * rd; gdtot = gddiff / t0; end else begin gstot = 0.0; gdtot = 0.0; end //************** Calculate GIDL and GISL current (line 1941-2021, file b4ld.c) *******************// t0 = 3.0 * toxe; t1 = (vds - vgs_eff - egidl ) / t0; if ((agidl <= 0.0) || (bgidl <= 0.0) || (t1 <= 0.0) || (cgidl <= 0.0) || (vbd > 0.0)) igidl = 0.0; else begin t2 = bgidl / t1; if (t2 < 100.0) igidl = agidl * weffcj * t1 * exp(-t2); else begin igidl = agidl * weffcj * 3.720075976e-44; igidl = igidl * t1; end t4 = vbd * vbd; t5 = -vbd * t4; t6 = cgidl + t5; t7 = t5 / t6; t8 = 3.0 * cgidl * t4 / t6 / t6; igidl = igidl * t7; end t1 = (-vds - vgd_eff - egidl ) / t0; if ((agidl <= 0.0) || (bgidl <= 0.0) || (t1 <= 0.0) || (cgidl <= 0.0) || (vbs > 0.0)) igisl = 0.0; else begin t2 = bgidl / t1; if (t2 < 100.0) igisl = agidl * weffcj * t1 * exp(-t2); else begin igisl = agidl * weffcj * 3.720075976e-44; igisl = igisl * t1; end t4 = vbs * vbs; t5 = -vbs * t4; t6 = cgidl + t5; t7 = t5 / t6; t8 = 3.0 * cgidl * t4 / t6 / t6; igisl = igisl * t7; end //***************** Gate tunneling current (line 2024-2396, file b4ld.c) ****************// if ((igcmod != 0.0) || (igbmod != 0.0)) begin v3 = vfbzb - Vgs_eff + vbseff - `DELTA_3; if (vfbzb<= 0.0) t0 = sqrt(v3 * v3 - 4.0 * `DELTA_3 * vfbzb); else t0 = sqrt(v3 * v3 + 4.0 * `DELTA_3 * vfbzb); vfbeff = vfbzb- 0.5 * (v3 + t0); voxacc = vfbzb- vfbeff; if (voxacc < 0.0) voxacc = 0.0; t0 = 0.5 * k1ox; t3 = Vgs_eff - vfbeff - vbseff - vgsteff; if (k1ox == 0.0) voxdepinv = 0.0; else if (t3 < 0.0) voxdepinv = -t3; else begin t1 = sqrt(t0 * t0 + t3); t2 = t0 / t1; voxdepinv = k1ox * (t1 - t0); end voxdepinv = voxdepinv + vgsteff; end if (igcmod == 1.0) begin t0 = vtm * nigc; vxnvt = (Vgs_eff - type * vth0) / t0; if (vxnvt > `EXP_THRESHOLD) vaux = Vgs_eff - type * vth0; else if (vxnvt < -`EXP_THRESHOLD) vaux = t0 * ln(1.0 + `MIN_EXP); else begin expvxnvt = exp(vxnvt); vaux = t0 * ln(1.0 + expvxnvt); end t2 = Vgs_eff * vaux; t11 = aechvb; t12 = bechvb; t3 = aigc * cigc - bigc; t4 = bigc * cigc; t5 = t12 * (aigc + t3 * voxdepinv - t4 * voxdepinv * voxdepinv); if (t5 > `EXP_THRESHOLD) t6 = `MAX_EXP; else if (t5 < -`EXP_THRESHOLD) t6 = `MIN_EXP; else t6 = exp(t5); igc = t11 * t2 * t6; if (pigcd != -99.0) modif_pigcd = pigcd; else begin t11 = bechvb * toxe; t12 = vgsteff + 1.0e-20; t13 = t11 / t12 / t12; modif_pigcd = t13 * (1.0 - 0.5 * vdseff / t12); end t7 = -modif_pigcd * vdseff; t8 = t7 * t7 + 2.0e-4; if (t7 > `EXP_THRESHOLD) t9 = `MAX_EXP; else if (t7 < -`EXP_THRESHOLD) t9 = `MIN_EXP; else t9 = exp(t7); t0 = t8 * t8; t1 = t9 - 1.0 + 1.0e-4; t10 = (t1 - t7) / t8; igcs = igc * t10; t10 = (t7 * t9 - t1) / t8; igcd = igc * t10; t0 = vgs - vfbsd; vgs_eff = sqrt(t0 * t0 + 1.0e-4); t2 = vgs * vgs_eff; t11 = aechvbedge; t12 = bechvbedge; t3 = aigsd * cigsd - bigsd; t4 = bigsd * cigsd; t5 = t12 * (aigsd + t3 * vgs_eff - t4 * vgs_eff * vgs_eff); if (t5 > `EXP_THRESHOLD) t6 = `MAX_EXP; else if (t5 < -`EXP_THRESHOLD) t6 = `MIN_EXP; else t6 = exp(t5); igs = t11 * t2 * t6; t0 = vgd - vfbsd; vgd_eff = sqrt(t0 * t0 + 1.0e-4); t2 = vgd * vgd_eff; t5 = t12 * (aigsd + t3 * vgd_eff - t4 * vgd_eff * vgd_eff); if (t5 > `EXP_THRESHOLD) t6 = `MAX_EXP; else if (t5 < -`EXP_THRESHOLD) t6 = `MIN_EXP; else t6 = exp(t5); igd = t11 * t2 * t6; end else begin igcs = 0.0; igcd = 0.0; igs = 0.0; igd = 0.0; end if (igbmod == 1.0) begin t0 = vtm * nigbacc; t1 = -Vgs_eff + vbseff + vfbzb; vxnvt = t1 / t0; if (vxnvt > `EXP_THRESHOLD) vaux = t1; else if (vxnvt < -(`EXP_THRESHOLD)) begin vaux = t0 * ln(1.0 + `MIN_EXP); end else begin expvxnvt = exp(vxnvt); vaux = t0 * ln(1.0 + expvxnvt); end t2 = (Vgs_eff - vbseff) * vaux; t11 = 4.97232e-7 * weff * leff * toxratio; t12 = -7.45669e11 * toxe; t3 = aigbacc * cigbacc - bigbacc; t4 = bigbacc * cigbacc; t5 = t12 * (aigbacc + t3 * voxacc - t4 * voxacc * voxacc); if (t5 > `EXP_THRESHOLD) t6 = `MAX_EXP; else if (t5 < -`EXP_THRESHOLD) t6 = `MIN_EXP; else t6 = exp(t5); igbacc = t11 * t2 * t6; t0 = vtm * nigbinv; t1 = voxdepinv - eigbinv; vxnvt = t1 / t0; if (vxnvt > `EXP_THRESHOLD) vaux = t1; else if (vxnvt < -`EXP_THRESHOLD) vaux = t0 * ln(1.0 + `MIN_EXP); else begin expvxnvt = exp(vxnvt); vaux = t0 * ln(1.0 + expvxnvt); end t2 = (Vgs_eff - vbseff) * vaux; t11 = t11 * 0.75610; t12 = t12 * 1.31724; t3 = aigbinv * cigbinv - bigbinv; t4 = bigbinv * cigbinv; t5 = t12 * (aigbinv + t3 * voxdepinv - t4 * voxdepinv * voxdepinv); if (t5 > `EXP_THRESHOLD) t6 = `MAX_EXP; else if (t5 < -`EXP_THRESHOLD) t6 =`MIN_EXP; else t6 = exp(t5); igbinv = t11 * t2 * t6; igb = igbinv + igbacc; end else igb = 0.0; //***** Accounting of device fingers (line 2396-2452, file b4ld.c) *****// if (nf != 1.0) begin cdrain = cdrain * nf; csub = csub * nf; igidl = igidl * nf; igisl = igisl * nf; igcs = igcs * nf; igcd = igcd * nf; igs = igs * nf; igd = igd * nf; igb = igb * nf; end //***** CV model (line 2484-3288, file b4ld.c) *****// ccn = 1; if ((xpart < 0) || (ccn == 0)) begin qgate = 0.0; qdrn = 0.0; qsrc = 0.0; qbulk = 0.0; qgmid = 0.0; end else if (capmod == 0) begin if (vbseff < 0.0) vbseff = Vbs; else vbseff = phi - phis; vfb = vfbcv; vth = vfb + phi + k1ox * sqrtphis; vgst = Vgs_eff - vth; coxwl = coxe * weffcv * leffcv * nf; arg1 = Vgs_eff - vbseff - vfb; if (arg1 <= 0.0) begin qgate = coxwl * arg1; qbulk = -qgate; qdrn = 0.0; end else if (vgst <= 0.0) begin t1 = 0.5 * k1ox; t2 = sqrt(t1 * t1 + arg1); qgate = coxwl * k1ox * (t2 - t1); qbulk = -qgate; qdrn = 0.0; end else begin two_third_coxwl = 2.0 * (coxe * weffcv * leffcv * nf) / 3.0; abulkcv = abulk0 * abulkcvfactor; vdsat = vgst / abulkcv; if (xpart > 0.5) begin /* 0/100 Charge partition model */ if (vdsat <= Vds) begin /* saturation region */ t1 = vdsat / 3.0; qgate = coxwl * (Vgs_eff - vfb - phi - t1); t2 = -two_third_coxwl * vgst; qbulk = -(qgate + t2); qdrn = 0.0; end else begin /* linear region */ alphaz = vgst / vdsat; t1 = 2.0 * vdsat - Vds; t2 = Vds / (3.0 * t1); t3 = t2 * Vds; t9 = 0.25 * coxwl; t4 = t9 * alphaz; t7 = 2.0 * Vds - t1 - 3.0 * t3; t8 = t3 - t1 - 2.0 * Vds; qgate = coxwl * (Vgs_eff - vfb - phi - 0.5 * (Vds - t3)); t10 = t4 * t8; qdrn = t4 * t7; qbulk = -(qgate + qdrn + t10); end end else if (xpart < 0.5) begin /* 40/60 Charge partition model */ if (Vds >= vdsat) begin /* saturation region */ t1 = vdsat / 3.0; qgate = coxwl * (Vgs_eff - vfb - phi - t1); t2 = -two_third_coxwl * vgst; qbulk = -(qgate + t2); qdrn = 0.4 * t2; end else begin /* linear region */ alphaz = vgst / vdsat; t1 = 2.0 * vdsat - Vds; t2 = Vds / (3.0 * t1); t3 = t2 * Vds; t9 = 0.25 * coxwl; t4 = t9 * alphaz; qgate = coxwl * (Vgs_eff - vfb - phi - 0.5 * (Vds - t3)); t6 = 8.0 * vdsat * vdsat - 6.0 * vdsat * Vds + 1.2 * Vds * Vds; t8 = t2 / t1; t7 = Vds - t1 - t8 * t6; qdrn = t4 * t7; t7 = 2.0 * (t1 + t3); qbulk = -(qgate - t4 * t7); end end else begin /* 50/50 partitioning */ if (Vds >= vdsat) begin /* saturation region */ t1 = vdsat / 3.0; qgate = coxwl * (Vgs_eff - vfb - phi - t1); t2 = -two_third_coxwl * vgst; qbulk = -(qgate + t2); qdrn = 0.5 * t2; end else begin /* linear region */ alphaz = vgst / vdsat; t1 = 2.0 * vdsat - Vds; t2 = Vds / (3.0 * t1); t3 = t2 * Vds; t9 = 0.25 * coxwl; t4 = t9 * alphaz; qgate = coxwl * (Vgs_eff - vfb - phi - 0.5 * (Vds - t3)); t7 = t1 + t3; qdrn = -t4 * t7; qbulk = - (qgate + qdrn + qdrn); end end end end else begin if (vbseff < 0.0) vbseffcv = vbseff; else vbseffcv = phi - phis; coxwl = coxe * weffcv * leffcv * nf; t0 = vtm * n * noff; vgstnvt = (vgst - voffcv) / t0; if (vgstnvt > `EXP_THRESHOLD) vgsteff = vgst - voffcv; else if (vgstnvt < -`EXP_THRESHOLD) vgsteff = t0 * ln(1.0 + `MIN_EXP); else vgsteff = t0 * ln(1.0 + exp(vgstnvt)); if (capmod == 1) begin v3 = vfbzb - Vgs_eff + vbseffcv - `DELTA_3; if (vfbzb <= 0.0) t0 = sqrt(v3 * v3 - 4.0 * `DELTA_3 * vfbzb); else t0 = sqrt(v3 * v3 + 4.0 * `DELTA_3 * vfbzb); t1 = 0.5 * (1.0 + v3 / t0); vfbeff = vfbzb - 0.5 * (v3 + t0); qac0 = coxwl * (vfbeff - vfbzb); t0 = 0.5 * k1ox; t3 = Vgs_eff - vfbeff - vbseffcv - vgsteff; if (k1ox == 0.0) begin t1 = 0.0; t2 = 0.0; end else if (t3 < 0.0) begin t1 = t0 + t3 / k1ox; t2 = coxwl; end else begin t1 = sqrt(t0 * t0 + t3); t2 = coxwl * t0 / t1; end qsub0 = coxwl * k1ox * (t1 - t0); abulkcv = abulk0 * abulkcvfactor; vdsatcv = vgsteff / abulkcv; t0 = vdsatcv - Vds - `DELTA_4; t1 = sqrt(t0 * t0 + 4.0 * `DELTA_4 * vdsatcv); if (t0 >= 0.0) vdseffcv = vdsatcv - 0.5 * (t0 + t1); else begin t3 = (`DELTA_4 + `DELTA_4) / (t1 - t0); t4 = 1.0 - t3; t5 = vdsatcv * t3 / (t1 - t0); vdseffcv = vdsatcv * t4; end if (Vds == 0.0) vdseffcv = 0.0; t0 = abulkcv * vdseffcv; t1 = 12.0 * (vgsteff - 0.5 * t0 + 1.0e-20); t2 = t0 / t1; t3 = t0 * t2; qgate = coxwl * (vgsteff - 0.5 * t0 + t3); t7 = 1.0 - abulkcv; qbulk = coxwl * t7 * (0.5 * vdseffcv - t3); if (xpart > 0.5) begin /* 0/100 Charge petition model */ t1 = t1 + t1; qsrc = -coxwl * (0.5 * vgsteff + 0.25 * t0 - t0 * t0 / t1); end else if (xpart < 0.5) begin /* 40/60 Charge petition model */ t1 = t1 / 12.0; t2 = 0.5 * coxwl / (t1 * t1); t3 = vgsteff * (2.0 * t0 * t0 / 3.0 + vgsteff * (vgsteff - 4.0 * t0 / 3.0)) - 2.0 * t0 * t0 * t0 / 15.0; qsrc = -t2 * t3; end else /* 50/50 Charge petition model */ qsrc = -0.5 * (qgate + qbulk); qgate = qgate + qac0 + qsub0; qbulk = qbulk - (qac0 + qsub0); qdrn = -(qgate + qbulk + qsrc); end else if (capmod == 2) begin v3 = vfbzb - Vgs_eff + vbseffcv - `DELTA_3; if (vfbzb <= 0.0) t0 = sqrt(v3 * v3 - 4.0 * `DELTA_3 * vfbzb); else t0 = sqrt(v3 * v3 + 4.0 * `DELTA_3 * vfbzb); t1 = 0.5 * (1.0 + v3 / t0); vfbeff = vfbzb - 0.5 * (v3 + t0); tox = 1.0e8 * toxp; t0 = (Vgs_eff - vbseffcv - vfbzb) / tox; tmp = t0 * acde; if ((-`EXP_THRESHOLD < tmp) && (tmp < `EXP_THRESHOLD)) tcen = ldeb * exp(tmp); else if (tmp <= -`EXP_THRESHOLD) tcen = ldeb * `MIN_EXP; else tcen = ldeb * `MAX_EXP; link = 1.0e-3 * toxp; v3 = ldeb - tcen - link; v4 = sqrt(v3 * v3 + 4.0 * link * ldeb); tcen = ldeb - 0.5 * (v3 + v4); ccen = `EPSSI / tcen; t2 = coxp / (coxp + ccen); coxeff = t2 * ccen; coxwlcen = coxwl * coxeff / coxe; qac0 = coxwlcen * (vfbeff - vfbzb); t0 = 0.5 * k1ox; t3 = Vgs_eff - vfbeff - vbseffcv - vgsteff; if (k1ox == 0.0) begin t1 = 0.0; t2 = 0.0; end else if (t3 < 0.0) begin t1 = t0 + t3 / k1ox; t2 = coxwlcen; end else begin t1 = sqrt(t0 * t0 + t3); t2 = coxwlcen * t0 / t1; end qsub0 = coxwlcen * k1ox * (t1 - t0); if (k1ox <= 0.0) begin denomi = 0.25 * moin * vtm; t0 = 0.5 * sqrtphi; end else begin denomi = moin * vtm * k1ox * k1ox; t0 = k1ox * sqrtphi; end t1 = 2.0 * t0 + vgsteff; deltaphi = vtm * ln(1.0 + t1 * vgsteff / denomi); tox = tox + tox; t0 = (vgsteff + vtfbphi2) / tox; tmp = exp(0.7 * ln(t0)); t1 = 1.0 + tmp; tcen = 1.9e-9 / t1; ccen = `EPSSI / tcen; t0 = coxp / (coxp + ccen); coxeff = t0 * ccen; coxwlcen = coxwl * coxeff / coxe; abulkcv = abulk0 * abulkcvfactor; vdsatcv = (vgsteff - deltaphi) / abulkcv; t0 = vdsatcv - Vds - `DELTA_4; t1 = sqrt(t0 * t0 + 4.0 * `DELTA_4 * vdsatcv); if (t0 >= 0.0) vdseffcv = vdsatcv - 0.5 * (t0 + t1); else begin t3 = (`DELTA_4 + `DELTA_4) / (t1 - t0); t4 = 1.0 - t3; vdseffcv = vdsatcv * t4; end if (Vds == 0.0) vdseffcv = 0.0; t0 = abulkcv * vdseffcv; t1 = vgsteff - deltaphi; t2 = 12.0 * (t1 - 0.5 * t0 + 1.0e-20); t3 = t0 / t2; qgate = coxwlcen * (t1 - t0 * (0.5 - t3)); t7 = 1.0 - abulkcv; qbulk = coxwlcen * t7 * (0.5 * vdseffcv - t0 * vdseffcv / t2); if (xpart > 0.5) /* 0/100 partition */ qsrc = -coxwlcen * (t1 / 2.0 + t0 / 4.0 - 0.5 * t0 * t0 / t2); else if (xpart < 0.5) begin /* 40/60 partition */ t2 = t2 / 12.0; t3 = 0.5 * coxwlcen / (t2 * t2); t4 = t1 * (2.0 * t0 * t0 / 3.0 + t1 * (t1 - 4.0 * t0 / 3.0)) - 2.0 * t0 * t0 * t0 / 15.0; qsrc = -t3 * t4; end else /* 50/50 partition */ qsrc = -0.5 * qgate; qgate = qgate + qac0 + qsub0 - qbulk; qbulk = qbulk - (qac0 + qsub0); qdrn = -(qgate + qbulk + qsrc); end end if (ccn == 1) qsrc = -(qgate + qbulk + qdrn); //***** Junction Diode CV Model (line 3333-3450, file b4ld.c) *****// if (ccn == 1) begin czbd = cjd_temp * adeff; czbs = cjs_temp * aseff; czbdsw = cjswd_temp * pdeff; czbdswg = cjswgd_temp * weffcj * nf; czbssw = cjsws_temp * pseff; czbsswg = cjswgs_temp * weffcj * nf; /* Source Bulk Junction */ if (vbs_jct == 0.0) qbs = 0.0; else if (vbs_jct < 0.0) begin if (czbs > 0.0) begin arg = 1.0 - vbs_jct / phibs; if (mjs == 0.5) sarg = 1.0 / sqrt(arg); else sarg = exp(-mjs * ln(arg)); qbs = phibs * czbs * (1.0 - arg * sarg) / (1.0 - mjs); end else qbs = 0.0; if (czbssw > 0.0) begin arg = 1.0 - vbs_jct / phibsws; if (mjsws == 0.5) sarg = 1.0 / sqrt(arg); else sarg = exp(-mjsws * ln(arg)); qbs = qbs + phibsws * czbssw * (1.0 - arg * sarg) / (1.0 - mjsws); end if (czbsswg > 0.0) begin arg = 1.0 - vbs_jct / phibswgs; if (mjswgs == 0.5) sarg = 1.0 / sqrt(arg); else sarg = exp(-mjswgs * ln(arg)); qbs = qbs + phibswgs * czbsswg * (1.0 - arg * sarg) / (1.0 - mjswgs); end end else begin t0 = czbs + czbssw + czbsswg; t1 = vbs_jct * (czbs * mjs / phibs + czbssw * mjsws / phibsws + czbsswg * mjswgs / phibswgs); qbs = vbs_jct * (t0 + 0.5 * t1); end /* Drain Bulk Junction */ if (vbd_jct == 0.0) qbd = 0.0; else if (vbd_jct < 0.0) begin if (czbd > 0.0) begin arg = 1.0 - vbd_jct / phibd; if (mjd == 0.5) sarg = 1.0 / sqrt(arg); else sarg = exp(-mjd * ln(arg)); qbd = phibd * czbd * (1.0 - arg * sarg) / (1.0 - mjd); end else qbd = 0.0; if (czbdsw > 0.0) begin arg = 1.0 - vbd_jct / phibswd; if (mjswd == 0.5) sarg = 1.0 / sqrt(arg); else sarg = exp(-mjswd * ln(arg)); qbd = qbd + phibswd * czbdsw * (1.0 - arg * sarg) / (1.0 - mjswd); end if (czbdswg > 0.0) begin arg = 1.0 - vbd_jct / phibswgd; if (mjswgd == 0.5) sarg = 1.0 / sqrt(arg); else sarg = exp(-mjswgd * ln(arg)); qbd = qbd + phibswgd * czbdswg * (1.0 - arg * sarg) / (1.0 - mjswgd); end end else begin t0 = czbd + czbdsw + czbdswg; t1 = vbd_jct * (czbd * mjd / phibd + czbdsw * mjswd / phibswd + czbdswg * mjswgd / phibswgd); qbd = vbd_jct * (t0 + 0.5 * t1); end end //***** Overlap capacitances (line 3519-3558, file b4ld.c) *****// if (ccn == 1) begin if (capmod == 0) begin cgdo = param_cgdo; cgso = param_cgso; qgdo = param_cgdo * vgd; qgso = param_cgso * vgs; end else /* For both capMod == 1 and 2 */ begin t0 = vgd + `DELTA_1; t1 = sqrt(t0 * t0 + 4.0 * `DELTA_1); t2 = 0.5 * (t0 - t1); t3 = weffcv * cgdl; t4 = sqrt(1.0 - 4.0 * t2 / ckappad); cgdo = param_cgdo + t3 - t3 * (1.0 - 1.0 / t4) * (0.5 - 0.5 * t0 / t1); qgdo = (param_cgdo + t3) * vgd - t3 * (t2 + 0.5 * ckappad * (t4 - 1.0)); t0 = vgs + `DELTA_1; t1 = sqrt(t0 * t0 + 4.0 * `DELTA_1); t2 = 0.5 * (t0 - t1); t3 = weffcv * cgsl; t4 = sqrt(1.0 - 4.0 * t2 / ckappas); cgso = param_cgso + t3 - t3 * (1.0 - 1.0 / t4) * (0.5 - 0.5 * t0 / t1); qgso = (param_cgso + t3) * vgs - t3 * (t2 + 0.5 * ckappas * (t4 - 1.0)); end if (nf != 1.0) begin cgdo = cgdo * nf; cgso = cgso * nf; qgdo = qgdo * nf; qgso = qgso * nf; end if (mode > 0) begin qdrn = qdrn - qgdo; if (rgatemod == 3) begin qgmb = cgbo * vgmb; qgmid = qgdo + qgso + qgmb; qbulk = qbulk - qgmb; qsrc = -(qgate + qgmid + qbulk + qdrn); end else begin qgb = cgbo * vgb; qgate = qgate + qgdo + qgso + qgb; qbulk = qbulk - qgb; qsrc = -(qgate + qbulk + qdrn); end end else begin qsrc = qdrn - qgso; if (rgatemod == 3) begin qgmb = cgbo * vgmb; qgmid = qgdo + qgso + qgmb; qbulk = qbulk - qgmb; qdrn = -(qgate + qgmid + qbulk + qsrc); end else begin qgb = cgbo * vgb; qgate = qgate + qgdo + qgso + qgb; qbulk = qbulk - qgb; qdrn = -(qgate + qbulk + qsrc); end end qd = qdrn - qbd; qs = qsrc - qbs; if (rbodymod == 0) qb = qbulk + qbd + qbs; else qb = qbulk; end //****** Here all currents going through the device are taken in account ******// I(sourceb, sourcep) <+ type * cbs; I(drainb, drainp) <+ type * cbd; if (igbmod == 1) I(bulk, gatep) <+ -type * igb; if (igcmod == 1) begin I(source, gatep) <+ -type * (igs + igcs); I(drain, gatep) <+ -type * (igd + igcd); end if (mode == 1) begin I(drainp , sourcep) <+ type * cdrain; I(drainp , bulkp) <+ type * (csub + igidl); I(sourcep, bulkp) <+ type * igisl; end else begin I(drainp , sourcep) <+ -type * cdrain; I(drainp , bulkp) <+ type * (csub + igisl); I(sourcep, bulkp) <+ type * igidl; end if (rdsmod == 0) begin V(source, sourcep) <+ 0; V(drainp, drain) <+ 0; end else begin I(drain, drainp) <+ type * gdtot * vded; I(source, sourcep) <+ type * gstot * vses; end if (rgatemod == 0) begin V(gate, gatem) <+ 0; V(gatem, gatep) <+ 0; end else if (rgatemod == 1) begin V(gatep, gatem) <+ 0; I(gate, gatem) <+ type * grgeltd * vgeg; end else if (rgatemod == 2) begin V(gatep, gatem) <+ 0; I(gate, gatem) <+ type * gcrg * vgeg; end else begin I(gatem, gatep) <+ type * gcrg * vgmg; I(gate, gatem) <+ type * grgeltd * vgegm; `ifdef RGATE3 I(gatem, sourcep) <+ type * ddt(qgmid); `endif end if (rbodymod == 0) begin V(bulk, bulkp) <+ 0; V(bulkp, sourceb) <+ 0; V(bulkp, drainb) <+ 0; end else begin I(sourceb, bulkp) <+ -type * grbps * vbsb; I(drainb, bulkp) <+ -type * grbpd * vbdb; I(bulk, bulkp) <+ type * grbpb * vbeb; I(bulk, sourceb) <+ type * grbsb * vbesb; I(bulk, drainb) <+ type * grbdb * vbedb; end I(gatep, sourcep) <+ type * ddt(qgate); I(drainp, sourcep) <+ type * ddt(qd); I(bulkp, sourcep) <+ type * ddt(qb); `ifdef RBODY if (rbodymod == 1) begin I(drainb, sourcep) <+ type * ddt(qbd); I(sourceb, sourcep) <+ type * ddt(qbs); end `endif end endmodule
rubberband_example_04.in
* Operational Amplifier * Rubberband parameters * rbias[res] .verilog bsim4.va .options nomod + itl1 = 400 + itl4 = 100 YVLG1 bias1 1 cm cm N1 L=1u W=10u YVLG2 bias2 in2 cm cm N1 L=1u W=10u YVLG3 vdd bias1 bias1 vdd P1 L=1u W=2u YVLG4 bias2 bias1 vdd vdd P1 L=1u W=2u YVLG5 cm bias vss vss N1 L=1u W=2u YVLGbias bias bias vss vss N1 L=1u W=2u rbias 0 bias 195k YVLG6 8 bias vss vss N1 L=1u W=2u YVLG7 8 bias2 vdd 8 N1 L=1u W=2u Cfb bias2 8 2p Vid 1 c 0 ac 0.1 eid in2 c 1 c -1 vic c 0 dc 0 vss vss 0 -1.8 Vdd vdd 0 1.8 .ac dec 10 100 10G .save ac vdb(8) .include nmos.lib .include pmos.lib .end
Graphics