From 241be03cfa1b552edabf0a0863fb31fe3712c4e3 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Tue, 1 May 2018 11:39:29 +0200 Subject: [PATCH] Revert "verilog-a files in adms removed" This reverts commit 9c5a2d0810ee5e3529eaf71cd4f932272673f33f. --- .../devices/adms/badcode1/admsva/my.mak | 42 + .../devices/adms/badcode1/admsva/r2_cmc.va | 26 + .../devices/adms/bsimbulk/admsva/bsimbulk.va | 4399 +++++++++++++++++ .../devices/adms/bsimcmg/admsva/bsimcmg.va | 117 + .../admsva/bsimcmg_binning_parameters.include | 756 +++ .../adms/bsimcmg/admsva/bsimcmg_body.include | 4145 ++++++++++++++++ .../bsimcmg/admsva/bsimcmg_cfringe.include | 117 + .../admsva/bsimcmg_quasi_static_cv.include | 89 + .../bsimcmg/admsva/bsimcmg_rdsmod.include | 84 + .../adms/bsimcmg/admsva/common_defs.include | 185 + src/spicelib/devices/adms/ekv/admsva/ekv.va | 677 +++ .../devices/adms/ex-1/admsva/r2_cmc.va | 72 + .../devices/adms/hicum0/admsva/hicum0.va | 886 ++++ .../devices/adms/hicum2/admsva/hicum2.va | 1690 +++++++ .../admsva/IP_NOTICE_DISCLAIMER_LICENSE | 47 + .../devices/adms/mextram/admsva/bjt504t.va | 54 + .../devices/adms/mextram/admsva/evaluate.inc | 655 +++ .../devices/adms/mextram/admsva/frontdef.inc | 130 + .../adms/mextram/admsva/initialize.inc | 83 + .../devices/adms/mextram/admsva/noise.inc | 145 + .../devices/adms/mextram/admsva/opinfo.inc | 245 + .../devices/adms/mextram/admsva/opvars.inc | 156 + .../adms/mextram/admsva/parameters.inc | 115 + .../devices/adms/mextram/admsva/tscaling.inc | 262 + .../devices/adms/mextram/admsva/variables.inc | 198 + .../psp102/admsva/JUNCAP200_InitModel.include | 184 + .../psp102/admsva/JUNCAP200_macrodefs.include | 285 ++ .../psp102/admsva/JUNCAP200_parlist.include | 65 + .../psp102/admsva/JUNCAP200_varlist.include | 67 + .../psp102/admsva/PSP102_ChargesNQS.include | 303 ++ .../adms/psp102/admsva/PSP102_InitNQS.include | 190 + .../adms/psp102/admsva/PSP102_binning.include | 127 + .../adms/psp102/admsva/PSP102_binpars.include | 233 + .../psp102/admsva/PSP102_macrodefs.include | 250 + .../adms/psp102/admsva/PSP102_module.include | 2359 +++++++++ .../admsva/PSP102_nqs_macrodefs.include | 117 + .../psp102/admsva/SIMKIT_macrodefs.include | 122 + .../devices/adms/psp102/admsva/psp102.va | 48 + .../devices/adms/psp102/admsva/readme.ngspice | 8 + .../devices/adms/psp102/admsva/readme.txt | 120 + 40 files changed, 19853 insertions(+) create mode 100644 src/spicelib/devices/adms/badcode1/admsva/my.mak create mode 100755 src/spicelib/devices/adms/badcode1/admsva/r2_cmc.va create mode 100644 src/spicelib/devices/adms/bsimbulk/admsva/bsimbulk.va create mode 100644 src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg.va create mode 100644 src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_binning_parameters.include create mode 100644 src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_body.include create mode 100644 src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_cfringe.include create mode 100644 src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_quasi_static_cv.include create mode 100644 src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_rdsmod.include create mode 100644 src/spicelib/devices/adms/bsimcmg/admsva/common_defs.include create mode 100644 src/spicelib/devices/adms/ekv/admsva/ekv.va create mode 100644 src/spicelib/devices/adms/ex-1/admsva/r2_cmc.va create mode 100644 src/spicelib/devices/adms/hicum0/admsva/hicum0.va create mode 100644 src/spicelib/devices/adms/hicum2/admsva/hicum2.va create mode 100644 src/spicelib/devices/adms/mextram/admsva/IP_NOTICE_DISCLAIMER_LICENSE create mode 100644 src/spicelib/devices/adms/mextram/admsva/bjt504t.va create mode 100644 src/spicelib/devices/adms/mextram/admsva/evaluate.inc create mode 100644 src/spicelib/devices/adms/mextram/admsva/frontdef.inc create mode 100644 src/spicelib/devices/adms/mextram/admsva/initialize.inc create mode 100644 src/spicelib/devices/adms/mextram/admsva/noise.inc create mode 100644 src/spicelib/devices/adms/mextram/admsva/opinfo.inc create mode 100644 src/spicelib/devices/adms/mextram/admsva/opvars.inc create mode 100644 src/spicelib/devices/adms/mextram/admsva/parameters.inc create mode 100644 src/spicelib/devices/adms/mextram/admsva/tscaling.inc create mode 100644 src/spicelib/devices/adms/mextram/admsva/variables.inc create mode 100644 src/spicelib/devices/adms/psp102/admsva/JUNCAP200_InitModel.include create mode 100644 src/spicelib/devices/adms/psp102/admsva/JUNCAP200_macrodefs.include create mode 100644 src/spicelib/devices/adms/psp102/admsva/JUNCAP200_parlist.include create mode 100644 src/spicelib/devices/adms/psp102/admsva/JUNCAP200_varlist.include create mode 100644 src/spicelib/devices/adms/psp102/admsva/PSP102_ChargesNQS.include create mode 100644 src/spicelib/devices/adms/psp102/admsva/PSP102_InitNQS.include create mode 100644 src/spicelib/devices/adms/psp102/admsva/PSP102_binning.include create mode 100644 src/spicelib/devices/adms/psp102/admsva/PSP102_binpars.include create mode 100644 src/spicelib/devices/adms/psp102/admsva/PSP102_macrodefs.include create mode 100644 src/spicelib/devices/adms/psp102/admsva/PSP102_module.include create mode 100644 src/spicelib/devices/adms/psp102/admsva/PSP102_nqs_macrodefs.include create mode 100644 src/spicelib/devices/adms/psp102/admsva/SIMKIT_macrodefs.include create mode 100644 src/spicelib/devices/adms/psp102/admsva/psp102.va create mode 100644 src/spicelib/devices/adms/psp102/admsva/readme.ngspice create mode 100644 src/spicelib/devices/adms/psp102/admsva/readme.txt diff --git a/src/spicelib/devices/adms/badcode1/admsva/my.mak b/src/spicelib/devices/adms/badcode1/admsva/my.mak new file mode 100644 index 000000000..916175c0a --- /dev/null +++ b/src/spicelib/devices/adms/badcode1/admsva/my.mak @@ -0,0 +1,42 @@ +# -*- makefile -*- +# (compile "make -i -f my.mak to") + +CFLAGS=-I ../../../../../include -I ../../../../../../../w32/src/include + +SRCS = \ +r2_cmcacld.c r2_cmc.analogfunction.c r2_cmcask.c r2_cmc.c r2_cmcdel.c r2_cmcdest.c r2_cmcguesstopology.c r2_cmcinit.c r2_cmcload.c r2_cmcmask.c r2_cmcmdel.c r2_cmcmpar.c r2_cmcnoise.c r2_cmcpar.c r2_cmcpzld.c r2_cmcsetup.c r2_cmctemp.c r2_cmctrunc.c + +to : $(SRCS:%.c=%.o) + +scripts = \ + -x \ + -e ../../admst/adms.implicit.xml \ + -e ../../admst/ngspiceVersion.xml \ + -e ../../admst/analogfunction.xml \ + -e ../../admst/ngspiceMODULEitf.h.xml \ + -e ../../admst/ngspiceMODULEinit.c.xml \ + -e ../../admst/ngspiceMODULEinit.h.xml \ + -e ../../admst/ngspiceMODULEext.h.xml \ + -e ../../admst/ngspiceMODULEdefs.h.xml \ + -e ../../admst/ngspiceMODULEask.c.xml \ + -e ../../admst/ngspiceMODULEmask.c.xml \ + -e ../../admst/ngspiceMODULEpar.c.xml \ + -e ../../admst/ngspiceMODULEmpar.c.xml \ + -e ../../admst/ngspiceMODULEload.c.xml \ + -e ../../admst/ngspiceMODULEacld.c.xml \ + -e ../../admst/ngspiceMODULEpzld.c.xml \ + -e ../../admst/ngspiceMODULEtemp.c.xml \ + -e ../../admst/ngspiceMODULEtrunc.c.xml \ + -e ../../admst/ngspiceMODULEsetup.c.xml \ + -e ../../admst/ngspiceMODULEdel.c.xml \ + -e ../../admst/ngspiceMODULEmdel.c.xml \ + -e ../../admst/ngspiceMODULEdest.c.xml \ + -e ../../admst/ngspiceMODULEnoise.c.xml \ + -e ../../admst/ngspiceMODULEguesstopology.c.xml \ + -e ../../admst/ngspiceMODULE.hxx.xml \ + -e ../../admst/ngspiceMODULE.c.xml + +$(SRCS) : do + +do : r2_cmc.va + ../../../../../../adms/ADMS/admsXml/admsXml $(scripts) $< diff --git a/src/spicelib/devices/adms/badcode1/admsva/r2_cmc.va b/src/spicelib/devices/adms/badcode1/admsva/r2_cmc.va new file mode 100755 index 000000000..3cf3311a2 --- /dev/null +++ b/src/spicelib/devices/adms/badcode1/admsva/r2_cmc.va @@ -0,0 +1,26 @@ +`include "constants.vams" +`include "disciplines.vams" + +module r2_cmc(d, s); + inout d, s; + + electrical d, s; + + real Taa, Txx; + + analog begin + + Taa = 0; + + // Txx = 0; + Txx = Taa; + + Taa = V(d,s); + + Taa = Txx; + Taa = 0; + + I(d,s) <+ Taa; + end + +endmodule diff --git a/src/spicelib/devices/adms/bsimbulk/admsva/bsimbulk.va b/src/spicelib/devices/adms/bsimbulk/admsva/bsimbulk.va new file mode 100644 index 000000000..591daff4b --- /dev/null +++ b/src/spicelib/devices/adms/bsimbulk/admsva/bsimbulk.va @@ -0,0 +1,4399 @@ +// **************************************************************************** +// * BSIM-BULK 106.2.0 released by Chetan Gupta on 6/30/2017 * +// * BSIM Bulk MOSFET Model Equations (Verilog-A) * +// **************************************************************************** + +// **************************************************************************** +// * Copyright 2017 Regents of the University of California * +// * All rights reserved. * +// * * +// * Project director: Prof. Chenming Hu * +// * * +// * Current developers: Chetan Gupta (Ph.D. student, IIT Kanpur) * +// * Prof. Yogesh Chauhan (IIT Kanpur) * +// * Dr. Harshit Agarwal (Postdoc, UC Berkeley) * +// * Dr. Huan-Lin Chang (Postdoc, UC Berkeley) * +// * Dr. Pragya Kushwaha (Postdoc, UC Berkeley) * +// * Juan Duarte (Ph.D. student, UC Berkeley) * +// * Yen-Kai Lin (Ph.D. student, UC Berkeley) * +// **************************************************************************** + +// **************************************************************************** +// * 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 of California owns the copyright and grants users a * +// * perpetual, irrevocable, worldwide, non-exclusive, royalty-free license * +// * with respect to the software as set forth below. * +// * * +// * 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 University of California that developed the * +// * software. This acknowledgment shall appear in the product * +// * documentation. * +// * * +// * 3. Redistributions to others of source code and documentation must * +// * retain the copyright notice, disclaimer, and list of conditions. * +// * * +// * 4. Redistributions to others in binary form must reproduce the * +// * copyright notice, disclaimer, and list of conditions in the * +// * documentation and/or other materials provided with the * +// * distribution. * +// * * +// * Agreed to on _________Jun. 30, 2017__________ * +// * * +// * By: ____University of California, Berkeley___ * +// * ____Chenming Hu__________________________ * +// * ____Professor in Graduate School ________ * +// **************************************************************************** + +`include "constants.vams" +`include "disciplines.vams" + +// Disable strobe for improved performance speed +// To Use DISABLE_STROBE, Activate it here. Used Only at GEOMOD and RGEOMOD +// `define DISABLE_STROBE +`ifdef DISABLE_STROBE + `define STROBE(X) + `define STROBE2(X,Y) +`else + `define STROBE(X) $strobe(X) + `define STROBE2(X,Y) $strobe(X,Y) +`endif + +// Junction capacitance macro between S/D and bulk +`define JunCap(Czbx, Vbx_jct, PBX_t, MJX, czbx_p1, czbx_p2, Qbxj) \ + if (Czbx > 0.0) begin \ + T1 = Vbx_jct / PBX_t; \ + if (T1 < 0.9) begin \ + arg = 1.0 - T1; \ + if (MJX == 0.5) begin \ + sarg = 1.0 / sqrt(arg); \ + end else begin \ + sarg = lexp(-MJX * lln(arg)); \ + end \ + Qbxj = PBX_t * Czbx * (1.0 - arg * sarg) / (1.0 - MJX); \ + end else begin \ + T2 = czbx_p1 * (T1 - 1.0) * (5.0 * MJX * (T1 - 1.0) + (1.0 + MJX)); \ + Qbxj = PBX_t * Czbx * (T2 + czbx_p2); \ + end \ + end else begin \ + Qbxj = 0.0; \ + end \ + +// Normalized pinch-off voltage including PD +`define PO_psip(vg_vfb, gamma, DPD, phif, psip) \ + T1 = 1.0 + DPD; \ + vgfbPD = vg_vfb / T1; \ + gammaPD = gamma / T1; \ + T1 = 0.5 * vgfbPD - 3.0 * (1.0 + gammaPD / `M_SQRT2); \ + T2 = T1 + sqrt(T1 * T1 + 6.0 * vgfbPD); \ + if (vgfbPD < 0.0) begin \ + T3 = (vgfbPD - T2) / gammaPD; \ + psip = -lln(1.0 - T2 + T3 * T3); \ + end else begin \ + T3 = lexp(-T2); \ + T1 = 0.5 * gammaPD; \ + T2 = sqrt(vgfbPD - 1.0 + T3 + T1 * T1) - T1; \ + psip = T2 * T2 + 1.0 - T3; \ + end \ + +// Normalized charge-voltage relationship +`define BSIM_q(psip, phib, vch, gam, q) \ + T8 = 0.5 * (psip + 1.0 + sqrt((psip - 1.0) * (psip - 1.0) + 0.25 * 2.0 * 2.0)); \ + sqrtpsip = sqrt(T8); \ + T9 = 1.0 + gam / (2.0 * sqrtpsip); \ + T0 = (1.0 + (gam / (2.0 * sqrtpsip))) / gam; \ + T1 = psip - 2.0 * phib - vch; \ + T2 = T1 - lln(4.0 * T0 * sqrtpsip); \ + T8 = 0.5 * (T2 - 0.201491 - sqrt(T2 * (T2 + 0.402982) + 2.446562)); \ + sqrtpsisa = sqrtpsip; \ + if (T8 <= -68.0) begin \ + T4 = -100.0; \ + T5 = 20.0; \ + if (T8 < T4 - 0.5 * T5) \ + T3 = lexp(T4); \ + else begin \ + if (T8 > T4 + 0.5 * T5) \ + T3 = lexp(T8); \ + else begin \ + T2 = (T8 - T4) / T5; \ + T6 = T2 * T2; \ + T3 = lexp(T4 + T5 * ((5.0 / 64.0) + 0.5 * T2 + T6 * ((15.0 / 16.0) - T6 * (1.25 - T6)))); \ + end \ + end \ + q = T3 * (1.0 + T1 - T8 - lln(2.0 * T0 * (T3 * 2.0 * T0 + 2.0 * sqrtpsisa))); \ + end else begin \ + T3 = lexp(T8); \ + sqrtpsisainv = 1.0 / sqrtpsisa; \ + T4 = 2.0 * T3 + lln(T3 * 2.0 * T0 * (T3 * 2.0 * T0 + 2.0 * sqrtpsisa)) - T1; \ + T5 = 2.0 + (1.0 / T3) + (T0 + sqrtpsisainv) / (T0 * T3 + sqrtpsisa); \ + T3 = T3 - T4 / T5; \ + T4 = 2.0 * T3 + lln(T3 * 2.0 * T0 * (T3 * 2.0 * T0 + 2.0 * sqrtpsisa)) - T1; \ + T5 = 2.0 + (1.0 / T3) + (T0 + sqrtpsisainv) / (T0 * T3 + sqrtpsisa); \ + T6 = ((T0 + sqrtpsisainv) / (T0 * T3 + sqrtpsisa)) * ((T0 + sqrtpsisainv) / (T0 * T3 + sqrtpsisa)); \ + T7 = -((1.0 / T3) * (1.0 / T3)) - (1.0 / (sqrtpsisa * sqrtpsisa * sqrtpsisa * (T0 * T3 + sqrtpsisa))) - T6; \ + q = T3 - (T4 / T5) * (1.0 + T4 * T7 / (2.0 * T5 * T5)); \ + end \ + +// Smoothing function for (max of x, x0 with deltax) +`define Smooth(x, x0, deltax, xsmooth) \ + xsmooth = 0.5 * (x + x0 + sqrt((x - x0) * (x - x0) + 0.25 * deltax * deltax)); \ + +// Smoothing function for (max of x, x0 with deltax) +`define Smooth1(x, x0, deltax, xsmooth) \ + xsmooth = 0.5 * (x + x0 + sqrt((x - x0) * (x - x0) + 0.25 * deltax * deltax)) - 0.25 * deltax; \ + +// Smoothing function for (min of x, x0 with deltax) +`define Smooth2(x, x0, deltax, xsmooth) \ + xsmooth = 0.5 * (x + x0 - sqrt((x - x0) * (x - x0) + 0.25 * deltax * deltax)) + 0.25 * deltax; \ + +// Smoothing function for (min of x, x0 with deltax) +`define Min1(x, x0, deltax, xsmooth) \ + xsmooth = 0.5 * (x + x0 - sqrt((x - x0) * (x - x0) + 0.25 * deltax * deltax)); \ + + // These macros represent the subroutines to process the geometry dependent + // parasitics for BSIM-BULK, which calculates Ps, Pd, As, Ad, and Rs and Rd + // for multi-fingers and various GEO and RGEO options. + +// Define GEOMOD and RGEOMOD in the modelcard +`define BSIMBULKNumFingerDiff(nf, minSD, nuIntD, nuEndD, nuIntS, nuEndS) \ + if ((nf % 2) != 0) begin \ + nuEndD = 1.0; \ + nuEndS = 1.0; \ + nuIntD = 2.0 * max((nf - 1.0) / 2.0, 0.0); \ + nuIntS = nuIntD; \ + end else begin \ + if (minSD == 1) begin \ + nuEndD = 2.0; \ + nuIntD = 2.0 * max((nf / 2.0 - 1.0), 0.0); \ + nuEndS = 0.0; \ + nuIntS = nf; \ + end else begin \ + nuEndD = 0.0; \ + nuIntD = nf; \ + nuEndS = 2.0; \ + nuIntS = 2.0 * max((nf / 2.0 - 1.0), 0.0); \ + end \ + end + +`define BSIMBULKRdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEnd, rgeo, SRCFLAG, Rend) \ + if (SRCFLAG == 1) begin \ + case(rgeo) \ + 1, 2, 5: begin \ + if (nuEnd == 0.0) begin \ + Rend = 0.0; \ + end else begin \ + Rend = Rsh * DMCG / (Weffcj * nuEnd); \ + end \ + end \ + 3, 4, 6: begin \ + if ((DMCG + DMCI) == 0.0) begin \ + `STROBE("(DMCG + DMCI) can not be equal to zero"); \ + end \ + if (nuEnd == 0.0) begin \ + Rend = 0.0; \ + end else begin \ + Rend = Rsh * Weffcj / (3.0 * nuEnd * (DMCG + DMCI)); \ + end \ + end \ + default: begin \ + `STROBE2("Warning: (instance BSIMBULK) Specified RGEO = %d not matched (BSIMBULKRdsEndIso), Rend is set to zero.", rgeo); \ + Rend = 0.0; \ + end \ + endcase \ + end else begin \ + case(rgeo) \ + 1, 3, 7: begin \ + if (nuEnd == 0.0) begin \ + Rend = 0.0; \ + end else begin \ + Rend = Rsh * DMCG / (Weffcj * nuEnd); \ + end \ + end \ + 2, 4, 8: begin \ + if ((DMCG + DMCI) == 0.0) begin \ + `STROBE("(DMCG + DMCI) can not be equal to zero"); \ + end \ + if (nuEnd == 0.0) begin \ + Rend = 0.0; \ + end \ + else begin \ + Rend = Rsh * Weffcj / (3.0 * nuEnd * (DMCG + DMCI)); \ + end \ + end \ + default: begin \ + `STROBE2("Warning: (instance BSIMBULK) Specified RGEO=%d not matched (BSIMBULKRdsEndIso type 2), Rend is set to zero.", rgeo); \ + Rend = 0.0; \ + end \ + endcase \ + end + +`define BSIMBULKRdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEnd, rgeo, SRCFLAG, Rend) \ + begin \ + if (SRCFLAG == 1) begin \ + case(rgeo) \ + 1, 2, 5: begin \ + if (nuEnd == 0.0) begin \ + Rend = 0.0; \ + end else begin \ + Rend = Rsh * DMCG / (Weffcj * nuEnd); \ + end \ + end \ + 3, 4, 6: begin \ + if (DMCG == 0.0) begin \ + `STROBE("DMCG can not be equal to zero"); \ + end \ + if (nuEnd == 0.0) begin \ + Rend = 0.0; \ + end \ + else begin \ + Rend = Rsh * Weffcj / (6.0 * nuEnd * DMCG); \ + end \ + end \ + default: begin \ + `STROBE2("Warning: (instance BSIMBULK) Specified RGEO = %d not matched (BSIMBULKRdsEndSha), Rend is set to zero.", rgeo); \ + Rend = 0.0; \ + end \ + endcase \ + end else begin \ + case(rgeo) \ + 1, 3, 7: begin \ + if (nuEnd == 0.0) begin \ + Rend = 0.0; \ + end else begin \ + Rend = Rsh * DMCG / (Weffcj * nuEnd); \ + end \ + end \ + 2, 4, 8: begin \ + if (DMCG == 0.0) begin \ + `STROBE("DMCG can not be equal to zero"); \ + end \ + if (nuEnd == 0.0) begin \ + Rend = 0.0; \ + end \ + else begin \ + Rend = Rsh * Weffcj / (6.0 * nuEnd * DMCG); \ + end \ + end \ + default: begin \ + `STROBE2("Warning: (instance BSIMBULK) Specified RGEO=%d not matched (BSIMBULKRdsEndSha \ + type 2), Rend is set to zero.", rgeo); \ + Rend = 0.0; \ + end \ + endcase \ + end \ + end + +`define BSIMBULKRdseffGeo(nf, geo, rgeo, minSD, Weffcj, Rsh, DMCG, DMCI, DMDG, SRCFLAG, Rtot) \ + begin \ + if (geo < 9) begin \ + `BSIMBULKNumFingerDiff(nf, minSD, nuIntD, nuEndD, nuIntS, nuEndS) \ + if (SRCFLAG == 1) begin \ + if (nuIntS == 0.0) begin \ + Rint = 0.0; \ + end else begin \ + Rint = Rsh * DMCG / ( Weffcj * nuIntS); \ + end \ + end \ + else begin \ + if (nuIntD == 0.0) begin \ + Rint = 0.0; \ + end else begin \ + Rint = Rsh * DMCG / ( Weffcj * nuIntD); \ + end \ + end \ + end \ + case(geo) \ + 0: begin \ + if (SRCFLAG == 1) begin \ + `BSIMBULKRdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndS, \ + rgeo, 1, Rend) \ + end else begin \ + `BSIMBULKRdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndD, \ + rgeo, 0, Rend) \ + end \ + end \ + 1: begin \ + if (SRCFLAG == 1) begin \ + `BSIMBULKRdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndS, \ + rgeo, 1, Rend) \ + end else begin \ + `BSIMBULKRdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndD, \ + rgeo, 0, Rend) \ + end \ + end \ + 2: begin \ + if (SRCFLAG == 1) begin \ + `BSIMBULKRdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndS, \ + rgeo, 1, Rend) \ + end else begin \ + `BSIMBULKRdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndD, \ + rgeo, 0, Rend) \ + end \ + end \ + 3: begin \ + if (SRCFLAG == 1) begin \ + `BSIMBULKRdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndS, \ + rgeo, 1, Rend) \ + end else begin \ + `BSIMBULKRdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndD, \ + rgeo, 0, Rend) \ + end \ + end \ + 4: begin \ + if (SRCFLAG == 1) begin \ + `BSIMBULKRdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndS, \ + rgeo, 1, Rend) \ + end else begin \ + Rend = Rsh * DMDG / Weffcj; \ + end \ + end \ + 5: begin \ + if (SRCFLAG == 1) begin \ + `BSIMBULKRdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndS, \ + rgeo, 1, Rend) \ + end else begin \ + if (nuEndD==0) begin\ + Rend = 0;\ + end else begin \ + Rend = Rsh * DMDG / (Weffcj * nuEndD); \ + end \ + end\ + end \ + 6: begin \ + if (SRCFLAG == 1) begin \ + Rend = Rsh * DMDG / Weffcj; \ + end else begin \ + `BSIMBULKRdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndD, \ + rgeo, 0, Rend) \ + end \ + end \ + 7:begin \ + if (SRCFLAG == 1) begin \ + if (nuEndS == 0) begin \ + Rend = 0; \ + end else begin \ + Rend = Rsh * DMDG / (Weffcj * nuEndS); \ + end \ + end else \ + `BSIMBULKRdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndD, \ + rgeo, 0, Rend) \ + end \ + 8: begin \ + Rend = Rsh * DMDG / Weffcj; \ + end \ + 9: begin /* all wide contacts assumed for geo = 9 and 10 */\ + if (SRCFLAG == 1) begin \ + Rend = 0.5 * Rsh * DMCG / Weffcj; \ + if (nf == 2.0) begin \ + Rint = 0.0; \ + end else begin \ + Rint = Rsh * DMCG / (Weffcj * (nf - 2.0)); \ + end \ + end \ + else begin \ + Rend = 0.0; \ + Rint = Rsh * DMCG / (Weffcj * nf); \ + end \ + end \ + 10: begin \ + if (SRCFLAG == 1) begin \ + Rend = 0.0; \ + Rint = Rsh * DMCG / (Weffcj * nf); \ + end \ + else begin \ + Rend = 0.5 * Rsh * DMCG / Weffcj; \ + if (nf == 2.0) begin \ + Rint = 0.0; \ + end else begin \ + Rint = Rsh * DMCG / (Weffcj * (nf - 2.0)); \ + end \ + end \ + end \ + default: begin \ + `STROBE2("Warning: (instance BSIMBULK) Specified GEO=%d not matched (BSIMBULKRdseffGeo), Rint is set to zero.", geo); \ + Rint = 0.0; \ + end \ + endcase \ + if (Rint <= 0.0) begin \ + Rtot = Rend; \ + end else if (Rend <= 0.0) begin \ + Rtot = Rint; \ + end else begin \ + Rtot = Rint * Rend / (Rint + Rend); \ + end \ + if (Rtot==0.0) begin \ + `STROBE("Warning: (instance BSIMBULK) Zero resistance returned from RdseffGeo"); \ + end \ + end + +// Effective PS, PD, AS, AD calculation, Ref: BSIM4 +`define BSIMBULKPAeffGeo(nf, geo, minSD,Weffcj, DMCG, DMCI, DMDG, Ps, Pd, As, Ad) \ + begin if (geo < 9) \ + `BSIMBULKNumFingerDiff(nf, minSD, nuIntD, nuEndD, nuIntS, nuEndS) \ + T0 = DMCG + DMCI;\ + T1 = DMCG + DMCG;\ + T2y = DMDG + DMDG;\ + PSiso = T0 + T0 + Weffcj;\ + PDiso = T0 + T0 + Weffcj;\ + PSsha = T1;\ + PDsha = T1;\ + PSmer = T2y;\ + PDmer = T2y;\ + ASiso = T0 * Weffcj;\ + ADiso = T0 * Weffcj;\ + ASsha = DMCG * Weffcj;\ + ADsha = DMCG * Weffcj;\ + ASmer = DMDG * Weffcj; \ + ADmer = DMDG * Weffcj; \ + case(geo) \ + 0: begin \ + Ps = nuEndS * PSiso + nuIntS * PSsha;\ + Pd = nuEndD * PDiso + nuIntD * PDsha;\ + As = nuEndS * ASiso + nuIntS * ASsha;\ + Ad = nuEndD * ADiso + nuIntD * ADsha;\ + end \ + 1: begin \ + Ps = nuEndS * PSiso + nuIntS * PSsha;\ + Pd = (nuEndD + nuIntD) * PDsha;\ + As = nuEndS * ASiso + nuIntS * ASsha;\ + Ad = (nuEndD + nuIntD) * ADsha;\ + end \ + 2: begin \ + Ps = (nuEndS + nuIntS) * PSsha;\ + Pd = nuEndD * PDiso + nuIntD * PDsha;\ + As = (nuEndS + nuIntS) * ASsha;\ + Ad = nuEndD * ADiso + nuIntD * ADsha;\ + end \ + 3: begin \ + Ps = (nuEndS + nuIntS) * PSsha;\ + Pd = (nuEndD + nuIntD) * PDsha;\ + As = (nuEndS + nuIntS) * ASsha;\ + Ad = (nuEndD + nuIntD) * ADsha;\ + end \ + 4: begin \ + Ps = nuEndS * PSiso + nuIntS * PSsha;\ + Pd = nuEndD * PDmer + nuIntD * PDsha;\ + As = nuEndS * ASiso + nuIntS * ASsha;\ + Ad = nuEndD * ADmer + nuIntD * ADsha;\ + end \ + 5: begin \ + Ps = (nuEndS + nuIntS) * PSsha;\ + Pd = nuEndD * PDmer + nuIntD * PDsha;\ + As = (nuEndS + nuIntS) * ASsha;\ + Ad = nuEndD * ADmer + nuIntD * ADsha;\ + end \ + 6: begin \ + Ps = nuEndS * PSmer + nuIntS * PSsha;\ + Pd = nuEndD * PDiso + nuIntD * PDsha;\ + As = nuEndS * ASmer + nuIntS * ASsha;\ + Ad = nuEndD * ADiso + nuIntD * ADsha;\ + end \ + 7: begin \ + Ps = nuEndS * PSmer + nuIntS * PSsha;\ + Pd = (nuEndD + nuIntD) * PDsha;\ + As = nuEndS * ASmer + nuIntS * ASsha;\ + Ad = (nuEndD + nuIntD) * ADsha;\ + end \ + 8: begin \ + Ps = nuEndS * PSmer + nuIntS * PSsha;\ + Pd = nuEndD * PDmer + nuIntD * PDsha;\ + As = nuEndS * ASmer + nuIntS * ASsha;\ + Ad = nuEndD * ADmer + nuIntD * ADsha;\ + end \ + 9: begin \ + Ps = PSiso + (nf - 1.0) * PSsha;\ + Pd = nf * PDsha;\ + As = ASiso + (nf - 1.0) * ASsha;\ + Ad = nf * ADsha;\ + end \ + 10: begin \ + Ps = nf * PSsha;\ + Pd = PDiso + (nf - 1.0) * PDsha;\ + As = nf * ASsha;\ + Ad = ADiso + (nf - 1.0) * ADsha;\ + end \ + default: begin \ + `STROBE2("Warning: (instance BSIMBULK) Specified GEO=%d not matched (BSIMBULKPAeffGeo \ + ), PS,PD,AS,AD set to zero.", geo); \ + Ps = 0;\ + Pd = 0;\ + As = 0;\ + Ad = 0;\ + end \ + endcase \ + end \ + +// Numerical Constants +`define EXPL_THRESHOLD 80.0 +`define MAX_EXPL 5.540622384e34 +`define MIN_EXPL 1.804851387e-35 +`define N_MINLOG 1.0e-38 +`define DELTA_1 0.02 +`define Oneby3 0.33333333333333333 +`define REFTEMP 300.15 // 27 degrees C + +// Physical Constants +`define ntype 1 +`define ptype -1 +`define q 1.60219e-19 +`define EPS0 8.85418e-12 +`define KboQ 8.617087e-5 // Joule/degree + +// Macros for the model/instance parameters +// +// MPRxx model parameter real +// MPIxx model parameter integer +// IPRxx instance parameter real +// IPIxx instance parameter integer +// || +// cc closed lower bound, closed upper bound +// oo open lower bound, open upper bound +// co closed lower bound, open upper bound +// oc open lower bound, closed upper bound +// cz closed lower bound=0, open upper bound=inf +// oz open lower bound=0, open upper bound=inf +// nb no bounds +// ex no bounds with exclude +// sw switch(integer only, values 0=false and 1=true) +// ty switch(integer only, values -1=p-type and +1=n-type) +// +// IPM instance parameter mFactor(multiplicity, implicit for LRM 2.2) +// OPP operating point parameter, includes units and description for printing + +`define OPP(nam,uni,des) (* units=uni, desc=des *) real nam; +`define OPM(nam,uni,des) (* units=uni, desc=des, multiplicity="multiply" *) real nam; +`define OPD(nam,uni,des) (* units=uni, desc=des, multiplicity="divide" *) real nam; + +`define MPRnb(nam,def,uni, des) (* units=uni, desc=des *) parameter real nam=def; +`define MPRex(nam,def,uni,exc, des) (* units=uni, desc=des *) parameter real nam=def exclude exc; +`define MPRcc(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter real nam=def from[lwr:upr]; +`define MPRoo(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter real nam=def from(lwr:upr); +`define MPRco(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter real nam=def from[lwr:upr); +`define MPRoc(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter real nam=def from(lwr:upr]; +`define MPRcz(nam,def,uni, des) (* units=uni, desc=des *) parameter real nam=def from[ 0:inf); +`define MPRoz(nam,def,uni, des) (* units=uni, desc=des *) parameter real nam=def from( 0:inf); + +`define MPInb(nam,def,uni, des) (* units=uni, desc=des *) parameter integer nam=def; +`define MPIex(nam,def,uni,exc, des) (* units=uni, desc=des *) parameter integer nam=def exclude exc; +`define MPIcc(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter integer nam=def from[lwr:upr]; +`define MPIoo(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter integer nam=def from(lwr:upr); +`define MPIco(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter integer nam=def from[lwr:upr); +`define MPIoc(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter integer nam=def from(lwr:upr]; +`define MPIcz(nam,def,uni, des) (* units=uni, desc=des *) parameter integer nam=def from[ 0:inf); +`define MPIoz(nam,def,uni, des) (* units=uni, desc=des *) parameter integer nam=def from( 0:inf); +`define MPIsw(nam,def,uni, des) (* units=uni, desc=des *) parameter integer nam=def from[ 0: 1]; +`define MPIty(nam,def,uni, des) (* units=uni, desc=des *) parameter integer nam=def from[ -1: 1] exclude 0; +`define IPRnb(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter real nam=def; +`define IPRex(nam,def,uni,exc, des) (* units=uni, type = "instance", desc=des *) parameter real nam=def exclude exc; +`define IPRcc(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from[lwr:upr]; +`define IPRoo(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from(lwr:upr); +`define IPRco(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from[lwr:upr); +`define IPRoc(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from(lwr:upr]; +`define IPRcz(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from[ 0:inf); +`define IPRoz(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from( 0:inf); +`define IPInb(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def; +`define IPIex(nam,def,uni,exc, des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def exclude exc; +`define IPIcc(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from[lwr:upr]; +`define IPIoo(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from(lwr:upr); +`define IPIco(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from[lwr:upr); +`define IPIoc(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from(lwr:upr]; +`define IPIcz(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from[ 0:inf); +`define IPIoz(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from( 0:inf); +`define BPRco(nam, def, uni, lwr, upr, des) (* units = uni, type = "instance", desc = des *) parameter real nam = def from[lwr : upr); +`define BPRoz(nam, def, uni, des) (* units = uni, type = "instance", desc = des *) parameter real nam = def from(0.0 : inf); +`define BPRcz(nam, def, uni, des) (* units = uni, type = "instance", desc = des *) parameter real nam = def from[0.0 : inf); +`define BPIcc(nam, def, uni, lwr, upr, des) (* units = uni, type = "instance", desc = des *) parameter integer nam = def from[lwr : upr]; +`define BPInb(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def; +`define BPRnb(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter real nam=def; + + +module bsimbulk(d, g, s, b, t); +inout d, g, s, b, t; +electrical d, g, s, b, di, si, gi, gm, bi, sbulk, dbulk; +thermal t; + +// Extra internal nodes and branches (TNOIMOD=1) for correlated drain and gate noise +electrical N1, N2; +branch (N1) NI; +branch (N1) NR; +branch (N1) NC; + +// Clamped exponential function +analog function real lexp; + input x; + real x; + begin + if (x > `EXPL_THRESHOLD) begin + lexp = `MAX_EXPL * (1.0 + x - `EXPL_THRESHOLD); + end else if (x < -`EXPL_THRESHOLD) begin + lexp = `MIN_EXPL; + end else begin + lexp = exp(x); + end + end +endfunction + +// Clamped log function +analog function real lln; + input x; + real x; + begin + lln = ln(max(x, `N_MINLOG)); + end +endfunction + +// Hyperbolic smoothing function +analog function real hypsmooth; + input x, c; + real x, c; + begin + hypsmooth = 0.5 * (x + sqrt(x * x + 4.0 * c * c)); + end +endfunction + +// Pure instance parameters +`IPRoz( L ,1.0e-5 ,"m" ,"Length" ) +`IPRoz( W ,1.0e-5 ,"m" ,"Total width including fingers" ) +`IPIco( NF ,1 ,"" ,1 ,inf ,"Number of fingers" ) +`IPRcz( NRS ,1.0 ,"" ,"Number of squares in source" ) +`IPRcz( NRD ,1.0 ,"" ,"Number of squares in drain" ) +`IPRnb( VFBSDOFF ,0.0 ,"V" ,"Flat-band Voltage Offset Parameter" ) +`IPIcc( MINZ ,0 ,"" ,0 ,1 ,"Minimize either D or S" ) +`IPRnb( XGW ,0.0 ,"m" ,"Distance from gate contact centre to dev edge" ) +`IPIcc( NGCON ,1 ,"" ,1 ,2 ,"Number of gate contacts" ) +`IPIcc( RGATEMOD ,0 ,"" ,0 ,3 ,"Gate resistance model selector" ) +`IPIcc( RBODYMOD ,0 ,"" ,0 ,2 ,"Distributed body R model" ) +`IPIcc( GEOMOD ,0 ,"" ,0 ,10 ,"Geometry-dependent parasitics model" ) +`IPIcc( RGEOMOD ,0 ,"" ,0 ,8 ,"Geometry-dependent source/drain resistance, 0: RSH-based, 1: Holistic" ) +`IPIcc( EDGEFET ,0 ,"" ,0 ,1 ,"0: Edge FET Model Off, 1: Edge FET Model ON" ) +`IPIcc( SSLMOD ,0 ,"" ,0 ,1 ,"Sub-Surface Leakage Drain Current, 0: Turn off 1: Turn on" ) +`IPRcz( RBPB ,50.0 ,"ohm" ,"Resistance between bNodePrime and bNode" ) +`IPRcz( RBPD ,50.0 ,"ohm" ,"Resistance between bNodePrime and bNode " ) +`IPRcz( RBPS ,50.0 ,"ohm" ,"Resistance between bNodePrime and sbNode " ) +`IPRcz( RBDB ,50.0 ,"ohm" ,"Resistance between bNode and dbNode " ) +`IPRcz( RBSB ,50.0 ,"ohm" ,"Resistance between bNode and sbNode" ) +`IPRnb( SA ,0.0 ,"m" ,"Distance between OD edge from Poly from one side" ) +`IPRnb( SB ,0.0 ,"m" ,"Distance between OD edge from Poly from other side" ) +`IPRnb( SD ,0.0 ,"m" ,"Distance between neighbouring fingers" ) +`IPRoo( SCA ,0.0 ,"" ,-inf ,inf ,"Integral of the first distribution function for scattered well dopant" ) +`IPRoo( SCB ,0.0 ,"" ,-inf ,inf ,"Integral of second distribution function for scattered well dopant" ) +`IPRoo( SCC ,0.0 ,"" ,-inf ,inf ,"Integral of third distribution function for scattered well dopant" ) +`IPRoo( SC ,0.0 ,"m" ,-inf ,inf ,"Distance to a single well edge if <=0.0, turn off WPE" ) +`IPRcz( AS ,0.0 ,"m^2" ,"Source to Substrate Junction Area" ) +`IPRcz( AD ,0.0 ,"m^2" ,"Drain to Substrate Junction Area" ) +`IPRcz( PS ,0.0 ,"m" ,"Source to Substrate Junction Perimeter" ) +`IPRcz( PD ,0.0 ,"m" ,"Drain to Substrate Junction Perimeter" ) + +// Both model and instance parameters +`BPRnb( DTEMP ,0.0 ,"K" ,"Offset of Device Temperature" ) +`BPRnb( MULU0 ,1.0 ,"m^2/(V*s)" ,"Multiplication factor for low field mobility" ) +`BPRnb( DELVTO ,0.0 ,"V" ,"Zero bias threshold voltage variation" ) +`BPRcz( IDS0MULT ,1.0 ,"" ,"Variability in drain current for miscellaneous reasons" ) + +// Pure model parameters +`MPIty( TYPE ,`ntype ,"" ,"ntype=1, ptype=-1" ) +`MPIcc( CVMOD ,0 ,"" ,0 ,1 ,"0: Consistent IV-CV, 1: Different IV-CV" ) +`MPIcc( COVMOD ,0 ,"" ,0 ,1 ,"0: Use Bias-independent Overlap Capacitances, 1: Use Bias-dependent Overlap Capacitances" ) +`MPIcc( RDSMOD ,0 ,"" ,0 ,2 ,"0: Internal bias dependent and external bias independent s/d resistance model, 1: External s/d resistance model, 2: Internal s/d resistance model" ) +`MPIcc( WPEMOD ,0 ,"" ,0 ,1 ,"Model flag" ) +`MPIcc( ASYMMOD ,0 ,"" ,0 ,1 ,"0: Asymmetry Model turned off - forward mode parameters used, 1: Asymmetry Model turned on" ) +`MPIcc( GIDLMOD ,0 ,"" ,0 ,1 ,"0: Turn off GIDL Current, 1: Turn on GIDL Current" ) +`MPIcc( IGCMOD ,0 ,"" ,0 ,1 ,"0: Turn off Igc, Igs and Igd, 1: Turn on Igc, Igs and Igd" ) +`MPIcc( IGBMOD ,0 ,"" ,0 ,1 ,"0: Turn off Igb, 1: Turn on Igb" ) +`MPIcc( TNOIMOD ,0 ,"" ,0 ,1 ,"Thermal noise model selector" ) +`MPIcc( SHMOD ,0 ,"" ,0 ,1 ,"0 : Self heating model OFF, 1 : Self heating model ON" ) +`MPIcc( MOBSCALE ,0 ,"" ,0 ,1 ,"Mobility scaling model, 0: Old Model, 1: New Model" ) + +// Device parameters +`MPRoz( LLONG ,10u ,"m" ,"L of extracted Long channel device" ) +`MPRoz( LMLT ,1.0 ,"" ,"Length Shrinking Parameter" ) +`MPRoz( WMLT ,1.0 ,"" ,"Width Shrinking Parameter" ) +`MPRnb( XL ,0.0 ,"m" ,"L offset for channel length due to mask/etch effect" ) +`MPRoz( WWIDE ,10u ,"m" ,"W of extracted Wide channel device" ) +`MPRnb( XW ,0.0 ,"m" ,"W offset for channel width due to mask/etch effect" ) +`MPRnb( LINT ,0.0 ,"m" ,"Delta L for IV" ) +`MPRnb( LL ,0.0 ,"m^(1+LLN)" ,"Length reduction parameter" ) +`MPRnb( LW ,0.0 ,"m^(1+LWN)" ,"Length reduction parameter" ) +`MPRnb( LWL ,0.0 ,"m^(1+LLN+LWN)" ,"Length reduction parameter" ) +`MPRnb( LLN ,1.0 ,"" ,"Length reduction parameter" ) +`MPRnb( LWN ,1.0 ,"" ,"Length reduction parameter" ) +`MPRnb( WINT ,0.0 ,"m" ,"Delta W for IV" ) +`MPRnb( WL ,0.0 ,"m^(1+WLN)" ,"Width reduction parameter" ) +`MPRnb( WW ,0.0 ,"m^(1+WWN)" ,"Width reduction parameter" ) +`MPRnb( WWL ,0.0 ,"m^(1+WWN+WLN)" ,"Width reduction parameter" ) +`MPRnb( WLN ,1.0 ,"" ,"Width reduction parameter" ) +`MPRnb( WWN ,1.0 ,"" ,"Width reduction parameter" ) +`MPRnb( DLC ,0.0 ,"m" ,"Delta L for CV" ) +`MPRnb( LLC ,0.0 ,"m^(1+LLN)" ,"Length reduction parameter" ) +`MPRnb( LWC ,0.0 ,"m^(1+LWN)" ,"Length reduction parameter" ) +`MPRnb( LWLC ,0.0 ,"m^(1+LWN+LLN)" ,"Length reduction parameter" ) +`MPRnb( DWC ,0.0 ,"m" ,"Delta W for CV" ) +`MPRnb( WLC ,0.0 ,"m^(1+WLN)" ,"Width reduction parameter" ) +`MPRnb( WWC ,0.0 ,"m^(1+WWN)" ,"Width reduction parameter" ) +`MPRnb( WWLC ,0.0 ,"m^(1+WWN+WLN)" ,"Width reduction parameter" ) +`MPRoo( TOXE ,3.0e-9 ,"m" ,0 ,inf ,"Effective gate dielectric thickness relative to SiO2" ) +`MPRoo( TOXP ,TOXE ,"m" ,0 ,inf ,"Physical gate dielectric thickness. If not given, TOXP is calculated from TOXE and DTOX" ) +`MPRnb( DTOX ,0.0 ,"m" ,"Difference between effective dielectric thickness" ) +`MPRnb( NDEP ,1e24 ,"1/m^3" ,"Channel Doping Concentration for IV" ) +`MPRnb( NDEPL1 ,0.0 ,"m" ,"Length dependence coefficient of NDEP" ) +`MPRoz( NDEPLEXP1 ,1.0 ,"" ,"Length dependence exponent coefficient of NDEP" ) +`MPRnb( NDEPL2 ,0.0 ,"m" ,"Length dependence of NDEP - For Short Channel Devices" ) +`MPRoz( NDEPLEXP2 ,2.0 ,"" ,"Length dependence exponent coefficient of NDEP" ) +`MPRnb( NDEPW ,0.0 ,"m" ,"Width dependence coefficient of NDEP" ) +`MPRoz( NDEPWEXP ,1.0 ,"" ,"Width dependence exponent coefficient of NDEP" ) +`MPRnb( NDEPWL ,0.0 ,"m^2" ,"Width-Length dependence coefficient of NDEP" ) +`MPRoz( NDEPWLEXP ,1.0 ,"" ,"Width-Length dependence exponent coefficient of NDEP" ) +`MPRnb( LNDEP ,0.0 ,"1/m^2" ,"Length dependence of NDEP" ) +`MPRnb( WNDEP ,0.0 ,"1/m^2" ,"Width dependence of NDEP" ) +`MPRnb( PNDEP ,0.0 ,"1/m" ,"Area dependence of NDEP " ) +`MPRnb( NDEPCV ,NDEP ,"1/m^3" ,"Channel Doping Concentration for CV" ) +`MPRnb( NDEPCVL1 ,NDEPL1 ,"m" ,"Length dependence coefficient of NDEPCV" ) +`MPRoz( NDEPCVLEXP1 ,NDEPLEXP1 ,"" ,"Length dependence exponent coefficient of NDEPCV" ) +`MPRnb( NDEPCVL2 ,NDEPL2 ,"m" ,"Length dependence coefficient of NDEPCV - For Short Channel Devices" ) +`MPRoz( NDEPCVLEXP2 ,NDEPLEXP2 ,"" ,"Length dependence exponent coefficient of NDEPCV" ) +`MPRnb( NDEPCVW ,NDEPW ,"m" ,"Width dependence coefficient of NDEPCV" ) +`MPRoz( NDEPCVWEXP ,NDEPWEXP ,"" ,"Width dependence exponent coefficient of NDEPCV" ) +`MPRnb( NDEPCVWL ,NDEPWL ,"m^2" ,"Width-Length dependence coefficient of NDEPCV" ) +`MPRoz( NDEPCVWLEXP ,NDEPWLEXP ,"" ,"Width-Length dependence exponent coefficient of NDEPCV" ) +`MPRnb( LNDEPCV ,LNDEP ,"1/m^2" ,"Length dependence of NDEP for CV" ) +`MPRnb( WNDEPCV ,WNDEP ,"1/m^2" ,"Width dependence of NDEP for CV" ) +`MPRnb( PNDEPCV ,PNDEP ,"1/m" ,"Area dependence of NDEP for CV" ) +`MPRnb( NGATE ,5e25 ,"1/m^3" ,"Gate Doping Concentration" ) +`MPRnb( LNGATE ,0.0 ,"1/m^2" ,"Length dependence of NGATE" ) +`MPRnb( WNGATE ,0.0 ,"1/m^2" ,"Width dependence of NGATE" ) +`MPRnb( PNGATE ,0.0 ,"1/m" ,"Area dependence of NGATE" ) +`MPRnb( EASUB ,4.05 ,"eV" ,"Electron affinity of substrate" ) +`MPRoz( NI0SUB ,1.1e16 ,"1/m^3" ,"Intrinsic carrier concentration of the substrate at 300.15K" ) +`MPRoo( BG0SUB ,1.17 ,"eV" ,0 ,inf ,"Band gap of substrate at 300.15K" ) +`MPRoo( EPSRSUB ,11.9 ,"" ,0 ,inf ,"Relative dielectric constant of the channel material" ) +`MPRoo( EPSROX ,3.9 ,"" ,0 ,inf ,"Relative dielectric constant of the gate dielectric" ) +`MPRnb( XJ ,1.5e-7 ,"m" ,"S/D junction depth" ) +`MPRnb( LXJ ,0.0 ,"m^2" ,"Length dependence of XJ " ) +`MPRnb( WXJ ,0.0 ,"m^2" ,"Width dependence of XJ" ) +`MPRnb( PXJ ,0.0 ,"m^3" ,"Area dependence of XJ" ) +`MPRnb( VFB ,-0.5 ,"V" ,"Flat band voltage " ) +`MPRnb( LVFB ,0.0 ,"V*m" ,"Length dependence of VFB" ) +`MPRnb( WVFB ,0.0 ,"V*m" ,"Width dependence of VFB" ) +`MPRnb( PVFB ,0.0 ,"V*m^2" ,"Area dependence of VFB" ) +`MPRnb( VFBCV ,VFB ,"V" ,"Flat band voltage for CV" ) +`MPRnb( LVFBCV ,LVFB ,"V*m" ,"Length dependence of VFBCV" ) +`MPRnb( WVFBCV ,WVFB ,"V*m" ,"Width dependence of VFBCV" ) +`MPRnb( PVFBCV ,PVFB ,"V*m^2" ,"Area dependence of VFBCV" ) +`MPRnb( VFBCVL ,0.0 ,"m" ,"Length dependence coefficient of VFBCV" ) +`MPRoz( VFBCVLEXP ,1.0 ,"" ,"Length dependence exponent coefficient of VFBCV" ) +`MPRnb( VFBCVW ,0.0 ,"m" ,"Width dependence coefficient of VFBCV" ) +`MPRoz( VFBCVWEXP ,1.0 ,"" ,"Width dependence exponent coefficient of VFBCV" ) +`MPRnb( VFBCVWL ,0.0 ,"m^2" ,"Width-Length dependence coefficient of VFBCV" ) +`MPRoz( VFBCVWLEXP ,1.0 ,"" ,"Width-Length dependence coefficient of VFBCV" ) + +// Diode parameters +`MPIcc( PERMOD ,1 ,"" ,0 ,1 ,"Whether PS/PD (when given) include gate-edge perimeter" ) +`MPRnb( DWJ ,DWC ,"m" ,"delta W for S/D junctions" ) + +// Short channel effects +`MPRnb( NSD ,1e26 ,"1/m^3" ,"S/D Doping Concentration" ) +`MPRnb( LNSD ,0.0 ,"1/m^2" ,"Length dependence of NSD" ) +`MPRnb( WNSD ,0.0 ,"1/m^2" ,"Width dependence of NSD" ) +`MPRnb( PNSD ,0.0 ,"1/m" ,"Area dependence of NSD" ) +`MPRnb( DVTP0 ,0.0 ,"m" ,"DITS" ) +`MPRnb( LDVTP0 ,0 ,"m^2" ,"Length dependence of DVTP0" ) +`MPRnb( WDVTP0 ,0 ,"m^2" ,"Width dependence of DVTP0" ) +`MPRnb( PDVTP0 ,0 ,"m^3" ,"Area dependence of DVTP0" ) +`MPRnb( DVTP1 ,0.0 ,"1/V" ,"DITS" ) +`MPRnb( LDVTP1 ,0 ,"m/V" ,"Length dependence of DVTP1" ) +`MPRnb( WDVTP1 ,0 ,"m/V" ,"Width dependence of DVTP1" ) +`MPRnb( PDVTP1 ,0 ,"m^2/V" ,"Area dependence of DVTP1" ) +`MPRnb( DVTP2 ,0.0 ,"m*V" ,"DITS" ) +`MPRnb( LDVTP2 ,0 ,"m^2/V" ,"Length dependence of DVTP2" ) +`MPRnb( WDVTP2 ,0 ,"m^2/V" ,"Width dependence of DVTP2" ) +`MPRnb( PDVTP2 ,0 ,"m^3/V" ,"Area dependence of DVTP2" ) +`MPRnb( DVTP3 ,0.0 ,"" ,"DITS" ) +`MPRnb( LDVTP3 ,0 ,"m" ,"Length dependence of DVTP3" ) +`MPRnb( WDVTP3 ,0 ,"m" ,"Width dependence of DVTP3" ) +`MPRnb( PDVTP3 ,0 ,"m^2" ,"Area dependence of DVTP3" ) +`MPRnb( DVTP4 ,0.0 ,"1/V" ,"DITS" ) +`MPRnb( LDVTP4 ,0 ,"m/V" ,"Length dependence of DVTP4" ) +`MPRnb( WDVTP4 ,0 ,"m/V" ,"Width dependence of DVTP4" ) +`MPRnb( PDVTP4 ,0 ,"m^2/V" ,"Area dependence of DVTP4" ) +`MPRnb( DVTP5 ,0.0 ,"V" ,"DITS" ) +`MPRnb( LDVTP5 ,0 ,"m*V" ,"Length dependence of DVTP5" ) +`MPRnb( WDVTP5 ,0 ,"m*V" ,"Width dependence of DVTP5" ) +`MPRnb( PDVTP5 ,0 ,"m^2*V" ,"Area dependence of DVTP5" ) +`MPRnb( PHIN ,0.045 ,"V" ,"Non-uniform vertical doping effect on surface potential" ) +`MPRnb( LPHIN ,0.0 ,"m*V" ,"Length dependence of PHIN" ) +`MPRnb( WPHIN ,0.0 ,"m*V" ,"Width dependence of PHIN" ) +`MPRnb( PPHIN ,0.0 ,"m^2*V" ,"Area dependence of PHIN" ) +`MPRnb( ETA0 ,0.08 ,"" ,"DIBL coefficient" ) +`MPRnb( LETA0 ,0.0 ,"m" ,"Length dependence of ETA0" ) +`MPRnb( WETA0 ,0.0 ,"m" ,"Width dependence of ETA0" ) +`MPRnb( PETA0 ,0.0 ,"m^2" ,"Area dependence of ETA0" ) +`MPRnb( ETA0R ,ETA0 ,"" ,"DIBL coefficient" ) +`MPRnb( LETA0R ,LETA0 ,"m" ,"Length dependence of ETA0R" ) +`MPRnb( WETA0R ,WETA0 ,"m" ,"Width dependence of ETA0R" ) +`MPRnb( PETA0R ,PETA0 ,"m^2" ,"Area dependence of ETA0R" ) +`MPRnb( DSUB ,1.0 ,"" ,"Length scaling exponent for DIBL" ) +`MPRnb( ETAB ,-0.07 ,"1/V" ,"Body bias coefficient for sub-threshold DIBL effect" ) +`MPRoz( ETABEXP ,1.0 ,"" ,"Exponent coefficient of ETAB" ) +`MPRnb( LETAB ,0.0 ,"m/V" ,"Length dependence of ETAB" ) +`MPRnb( WETAB ,0.0 ,"m/V" ,"Width dependence of ETAB" ) +`MPRnb( PETAB ,0.0 ,"m^2/V" ,"Area dependence of ETAB" ) +`MPRnb( K1 ,0.0 ,"V^0.5" ,"First-order body-bias Vth shift due to Vertical Non-uniform doping" ) +`MPRnb( K1L ,0.0 ,"" ,"length dependence coefficient of K1" ) +`MPRoz( K1LEXP ,1.0 ,"" ,"Length dependence exponent coefficient of K1" ) +`MPRnb( K1W ,0.0 ,"" ,"Width dependence coefficient of K1" ) +`MPRoz( K1WEXP ,1.0 ,"" ,"Width dependence exponent coefficient of K1" ) +`MPRnb( K1WL ,0.0 ,"" ,"Width-Length dependence coefficient of K1" ) +`MPRoz( K1WLEXP ,1.0 ,"" ,"Width-Length dependence exponent coefficient of K1" ) +`MPRnb( LK1 ,0.0 ,"m*V^0.5" ,"Length dependence of K1" ) +`MPRnb( WK1 ,0.0 ,"m*V^0.5" ,"Width dependence of K1" ) +`MPRnb( PK1 ,0.0 ,"m^2*V^0.5" ,"Area dependence of K1" ) +`MPRnb( K2 ,0.0 ,"V" ,"Vth shift due to Vertical Non-uniform doping" ) +`MPRnb( K2L ,0.0 ,"m^K2LEXP" ,"Length dependence coefficient of K2" ) +`MPRoz( K2LEXP ,1.0 ,"" ,"Length dependence exponent coefficient of K2" ) +`MPRnb( K2W ,0.0 ,"m^K2WEXP" ,"Width dependence coefficient of K2" ) +`MPRoz( K2WEXP ,1.0 ,"" ,"Width dependence exponent coefficient of K2" ) +`MPRnb( K2WL ,0.0 ,"m^(2*K2WLEXP)" ,"Width-Length dependence coefficient of K2" ) +`MPRoz( K2WLEXP ,1.0 ,"" ,"Width-Length dependence exponent coefficient of K2" ) +`MPRnb( LK2 ,0.0 ,"m" ,"Length dependence of K2" ) +`MPRnb( WK2 ,0.0 ,"m" ,"Width dependence of K2" ) +`MPRnb( PK2 ,0.0 ,"m^2" ,"Area dependence of K2" ) + +// Quantum mechanical effects +`MPRcz( ADOS ,0.0 ,"" ,"Quantum mechanical effect pre-factor cum switch in inversion" ) +`MPRcz( BDOS ,1.0 ,"" ,"Charge centroid parameter - slope of CV curve under QME in inversion" ) +`MPRoz( QM0 ,1.0e-3 ,"" ,"Charge centroid parameter - starting point for QME in inversion" ) +`MPRcz( ETAQM ,0.54 ,"" ,"Bulk charge coefficient for charge centroid in inversion" ) + +// Sub-threshold swing factor +`MPRnb( CIT ,0.0 ,"F/m^2" ,"Parameter for interface trap" ) +`MPRnb( LCIT ,0.0 ,"F/m" ,"Length dependence of CIT" ) +`MPRnb( WCIT ,0.0 ,"F/m" ,"Width dependence of CIT" ) +`MPRnb( PCIT ,0.0 ,"F" ,"Area dependence of CIT" ) +`MPRnb( NFACTOR ,0.0 ,"" ,"Sub-threshold slope factor" ) +`MPRnb( NFACTORL ,0.0 ,"m^NFACTORLEXP" ,"Length dependence coefficient of NFACTOR" ) +`MPRoz( NFACTORLEXP ,1.0 ,"" ,"Length dependence exponent coefficient of NFACTOR" ) +`MPRnb( NFACTORW ,0.0 ,"m^NFACTORWEXP" ,"Width dependence coefficient of NFACTOR" ) +`MPRoz( NFACTORWEXP ,1.0 ,"" ,"Width dependence exponent coefficient of NFACTOR" ) +`MPRnb( NFACTORWL ,0.0 ,"m^(2*NFACTORWLEXP)" ,"Width-Length dependence coefficient of NFACTOR" ) +`MPRoz( NFACTORWLEXP ,1.0 ,"" ,"Width-Length dependence exponent coefficient of NFACTOR" ) +`MPRnb( LNFACTOR ,0.0 ,"m" ,"Length dependence of NFACTOR" ) +`MPRnb( WNFACTOR ,0.0 ,"m" ,"Width dependence of NFACTOR" ) +`MPRnb( PNFACTOR ,0.0 ,"m^2" ,"Area dependence of NFACTOR" ) +`MPRnb( CDSCD ,1e-9 ,"F/m^2/V" ,"Drain-bias sensitivity of sub-threshold slope" ) +`MPRnb( CDSCDL ,0.0 ,"m^CDSCDLEXP" ,"Length dependence coefficient of CDSCD" ) +`MPRoz( CDSCDLEXP ,1.0 ,"" ,"Length dependence exponent coefficient of CDSCD" ) +`MPRnb( LCDSCD ,0.0 ,"F/m/V" ,"Length dependence of CDSCD" ) +`MPRnb( WCDSCD ,0.0 ,"F/m/V" ,"Width dependence of CDSCD" ) +`MPRnb( PCDSCD ,0.0 ,"F/V" ,"Area dependence of CDSCD" ) +`MPRnb( CDSCDR ,CDSCD ,"F/m^2/V" ,"Drain-bias sensitivity of sub-threshold slope" ) +`MPRnb( CDSCDLR ,CDSCDL ,"m^CDSCDLEXP" ,"Length dependence coefficient of CDSCD" ) +`MPRnb( LCDSCDR ,LCDSCD ,"F/m/V" ,"Length dependence of CDSCDR" ) +`MPRnb( WCDSCDR ,WCDSCD ,"F/m/V" ,"Width dependence of CDSCDR" ) +`MPRnb( PCDSCDR ,PCDSCD ,"F/V" ,"Area dependence of CDSCDR" ) +`MPRnb( CDSCB ,0.0 ,"F/m^2/V" ,"Body-bias sensitivity of sub-threshold slope" ) +`MPRnb( CDSCBL ,0.0 ,"m^CDSCBLEXP" ,"Length dependence coefficient of CDSCB" ) +`MPRoz( CDSCBLEXP ,1.0 ,"" ,"Length dependence exponent coefficient of CDSCB" ) +`MPRnb( LCDSCB ,0.0 ,"F/m/V" ,"Length dependence of CDSCB" ) +`MPRnb( WCDSCB ,0.0 ,"F/m/V" ,"Width dependence of CDSCB" ) +`MPRnb( PCDSCB ,0.0 ,"F/V" ,"Area dependence of CDSCB" ) + +// Drain saturation voltage +`MPRnb( VSAT ,1e5 ,"m/s" ,"Saturation Velocity" ) +`MPRnb( LVSAT ,0.0 ,"m^2/s" ,"Length dependence of VSAT" ) +`MPRnb( WVSAT ,0.0 ,"m^2/s" ,"Width dependence of VSAT" ) +`MPRnb( PVSAT ,0.0 ,"m^3/s" ,"Area dependence of VSAT" ) +`MPRnb( VSATL ,0.0 ,"m^VSATLEXP" ,"Length dependence coefficient of of VSAT" ) +`MPRoz( VSATLEXP ,1.0 ,"" ,"Length dependence exponent coefficient of VSAT" ) +`MPRnb( VSATW ,0.0 ,"m^VSATWEXP" ,"Width dependence coefficient of of VSAT" ) +`MPRoz( VSATWEXP ,1.0 ,"" ,"Width dependence exponent coefficient of of VSAT" ) +`MPRnb( VSATWL ,0.0 ,"m^(2*VSATWLEXP)" ,"Width-Length dependence coefficient of of VSAT" ) +`MPRoz( VSATWLEXP ,1.0 ,"" ,"Width-Length dependence exponent coefficient of of VSAT" ) +`MPRnb( VSATR ,VSAT ,"m/s" ,"Saturation Velocity" ) +`MPRnb( LVSATR ,LVSAT ,"m^2/s" ,"Length dependence of VSATR" ) +`MPRnb( WVSATR ,WVSAT ,"m^2/s" ,"Width dependence of VSATR" ) +`MPRnb( PVSATR ,PVSAT ,"m^3/s" ,"Area dependence of VSATR" ) +`MPRnb( DELTA ,0.125 ,"" ,"Smoothing function factor for Vdsat" ) +`MPRnb( LDELTA ,0.0 ,"m" ,"Length dependence of DELTA" ) +`MPRnb( WDELTA ,0.0 ,"m" ,"Width dependence of DELTA" ) +`MPRnb( PDELTA ,0.0 ,"m^2" ,"Area dependence of DELTA" ) +`MPRnb( DELTAL ,0.0 ,"m^DELTALEXP" ,"Length dependence coefficient of DELTA" ) +`MPRoz( DELTALEXP ,1.0 ,"" ,"Length dependence exponent coefficient of DELTA" ) +`MPRnb( VSATCV ,VSAT ,"m/s" ,"VSAT parameter for CV" ) +`MPRnb( LVSATCV ,LVSAT ,"m^2/s" ,"Length dependence of VSATCV" ) +`MPRnb( WVSATCV ,WVSAT ,"m^2/s" ,"Width dependence of VSATCV" ) +`MPRnb( PVSATCV ,PVSAT ,"m^3/s" ,"Area dependence of VSATCV" ) +`MPRnb( VSATCVL ,VSATL ,"m^VSATCVLEXP" ,"Length dependence coefficient of VSATCV" ) +`MPRoz( VSATCVLEXP ,VSATLEXP ,"" ,"Length dependence exponent coefficient of VSATCV" ) +`MPRnb( VSATCVW ,VSATW ,"m^VSATCVWEXP" ,"Width dependence coefficient of VSATCV" ) +`MPRoz( VSATCVWEXP ,VSATWEXP ,"" ,"Width dependence exponent coefficient of VSATCV" ) +`MPRnb( VSATCVWL ,VSATWL ,"m^(2*VSATCVWLEXP)" ,"Width-Length dependence coefficient of VSATCV" ) +`MPRoz( VSATCVWLEXP ,VSATWLEXP ,"" ,"Width-Length dependence exponent coefficient of VSATCV" ) + +// Mobility degradation +`MPRoo( UP1 ,0.0 ,"" ,-inf ,inf ,"Mobility channel length coefficient" ) +`MPRex( LP1 ,1.0e-8 ,"m" ,0.0 ,"Mobility channel length exponential coefficient" ) +`MPRoo( UP2 ,0.0 ,"" ,-inf ,inf ,"Mobility channel length coefficient" ) +`MPRex( LP2 ,1.0e-8 ,"m" ,0.0 ,"Mobility channel length exponential coefficient" ) +`MPRnb( U0 ,67.0e-3 ,"m^2/V/s" ,"Low Field mobility." ) +`MPRnb( U0L ,0.0 ,"m^U0LEXP" ,"Length dependence coefficient of U0L" ) +`MPRoz( U0LEXP ,1.0 ,"" ,"Length dependence exponent coefficient of U0L" ) +`MPRnb( LU0 ,0.0 ,"m^3/V/s" ,"Length dependence of U0" ) +`MPRnb( WU0 ,0.0 ,"m^3/V/s" ,"Width dependence of U0" ) +`MPRnb( PU0 ,0.0 ,"m^4/V/s" ,"Area dependence of U0" ) +`MPRnb( U0R ,U0 ,"m2/V/s" ,"Reverse-mode Low Field mobility." ) +`MPRnb( LU0R ,LU0 ,"m^3/V/s" ,"Length dependence of U0R" ) +`MPRnb( WU0R ,WU0 ,"m^3/V/s" ,"Width dependence of U0R" ) +`MPRnb( PU0R ,PU0 ,"m^4/V/s" ,"Area dependence of U0R" ) +`MPRnb( ETAMOB ,1.0 ,"" ,"Effective field parameter (should be kept close to 1)" ) +`MPRnb( UA ,0.001 ,"(m/V)^EU" ,"Mobility reduction coefficient" ) +`MPRnb( UAL ,0.0 ,"m^UALEXP" ,"Length dependence coefficient of UA" ) +`MPRoz( UALEXP ,1.0 ,"" ,"Length dependence exponent coefficient of UA" ) +`MPRnb( UAW ,0.0 ,"m^UAWEXP" ,"Width dependence coefficient of UA" ) +`MPRoz( UAWEXP ,1.0 ,"" ,"Width dependence exponent coefficient of UA" ) +`MPRnb( UAWL ,0.0 ,"m^UAWLEXP" ,"Width-Length dependence coefficient of UA" ) +`MPRoz( UAWLEXP ,1.0 ,"" ,"Width-Length dependence coefficient of UA" ) +`MPRnb( LUA ,0.0 ,"m*(m/V)^EU" ,"Length dependence of UA" ) +`MPRnb( WUA ,0.0 ,"m*(m/V)^EU" ,"Width dependence of UA" ) +`MPRnb( PUA ,0.0 ,"m^2*(m/V)^EU" ,"Area dependence of UA" ) +`MPRnb( UAR ,UA ,"(m/V)^EU" ,"Reverse-mode Mobility reduction coefficient" ) +`MPRnb( LUAR ,LUA ,"m*(m/V)^EU" ,"Length dependence of UAR" ) +`MPRnb( WUAR ,WUA ,"m*(m/V)^EU" ,"Width dependence of UAR" ) +`MPRnb( PUAR ,PUA ,"m^2*(m/V)^EU" ,"Area dependence of UAR" ) +`MPRnb( EU ,1.5 ,"" ,"Mobility reduction exponent" ) +`MPRnb( LEU ,0.0 ,"m" ,"Length dependence of EU" ) +`MPRnb( WEU ,0.0 ,"m" ,"Width dependence of EU" ) +`MPRnb( PEU ,0.0 ,"m^2" ,"Area dependence of EU" ) +`MPRnb( EUL ,0.0 ,"m^EULEXP" ,"Length dependence coefficient of EU" ) +`MPRoz( EULEXP ,1.0 ,"" ,"Length dependence exponent coefficient of EU" ) +`MPRnb( EUW ,0.0 ,"m^EUWEXP" ,"Width dependence coefficient of EU" ) +`MPRoz( EUWEXP ,1.0 ,"" ,"Width dependence exponent coefficient of EU" ) +`MPRnb( EUWL ,0.0 ,"m^EUWLEXP" ,"Width-Length dependence coefficient of EU" ) +`MPRoz( EUWLEXP ,1.0 ,"" ,"Width-Length dependence coefficient of EU" ) +`MPRnb( UD ,0.001 ,"" ,"Coulomb scattering parameter" ) +`MPRnb( UDL ,0.0 ,"m^UDLEXP" ,"Length dependence coefficient of UD" ) +`MPRoz( UDLEXP ,1.0 ,"" ,"Length dependence exponent coefficient of UD" ) +`MPRnb( LUD ,0.0 ,"m" ,"Length dependence of UD" ) +`MPRnb( WUD ,0.0 ,"m" ,"Width dependence of UD" ) +`MPRnb( PUD ,0.0 ,"m^2" ,"Area dependence of UD" ) +`MPRnb( UDR ,UD ,"" ,"Reverse-mode Coulomb scattering parameter" ) +`MPRnb( LUDR ,LUD ,"m" ,"Length dependence of UDR" ) +`MPRnb( WUDR ,WUD ,"m" ,"Width dependence of UDR" ) +`MPRnb( PUDR ,PUD ,"m^2" ,"Area dependence of UDR" ) +`MPRnb( UCS ,2.0 ,"" ,"Coulomb scattering parameter" ) +`MPRnb( LUCS ,0.0 ,"m" ,"Length dependence of UCS" ) +`MPRnb( WUCS ,0.0 ,"m" ,"Width dependence of UCS" ) +`MPRnb( PUCS ,0.0 ,"m^2" ,"Area dependence of UCS" ) +`MPRnb( UCSR ,UCS ,"" ,"Reverse-mode Coulomb scattering parameter" ) +`MPRnb( LUCSR ,LUCS ,"m" ,"Length dependence of UCSR" ) +`MPRnb( WUCSR ,WUCS ,"m" ,"Width dependence of UCSR" ) +`MPRnb( PUCSR ,PUCS ,"m^2" ,"Area dependence of UCSR" ) +`MPRnb( UC ,0.0 ,"(m/V)^EU/V" ,"Mobility reduction with body bias" ) +`MPRnb( UCL ,0.0 ,"m^UCLEXP" ,"Length dependence coefficient of UC" ) +`MPRoz( UCLEXP ,1.0 ,"" ,"Length dependence exponent coefficient of UC" ) +`MPRnb( UCW ,0.0 ,"m^UCWEXP" ,"Width dependence coefficient of UC" ) +`MPRoz( UCWEXP ,1.0 ,"" ,"Width dependence exponent coefficient of UC" ) +`MPRnb( UCWL ,0.0 ,"m^(2*UCWLEXP)" ,"Width-Length dependence coefficient of UC" ) +`MPRoz( UCWLEXP ,1.0 ,"" ,"Width-Length dependence exponent coefficient of UC" ) +`MPRnb( LUC ,0.0 ,"m*(m/V)^EU/V" ,"Length dependence of UC" ) +`MPRnb( WUC ,0.0 ,"m*(m/V)^EU/V" ,"Width dependence of UC" ) +`MPRnb( PUC ,0.0 ,"m^2*(m/V)^EU/V" ,"Area dependence of UC" ) +`MPRnb( UCR ,UC ,"(m/V)^EU/V" ,"Reverse-mode Mobility reduction with body bias" ) +`MPRnb( LUCR ,LUC ,"m*(m/V)^EU/V" ,"Length dependence of UCR" ) +`MPRnb( WUCR ,WUC ,"m*(m/V)^EU/V" ,"Width dependence of UCR" ) +`MPRnb( PUCR ,PUC ,"m^2*(m/V)^EU/V" ,"Area dependence of UCR" ) + +// Channel length modulation +`MPRnb( PCLM ,0.0 ,"" ,"CLM pre-factor" ) +`MPRnb( PCLML ,0.0 ,"m^PCLMLEXP" ,"Length dependence coefficient of PCLM" ) +`MPRoz( PCLMLEXP ,1.0 ,"" ,"Length dependence exponent coefficient of PCLM" ) +`MPRnb( LPCLM ,0.0 ,"m" ,"Length dependence of PCLM" ) +`MPRnb( WPCLM ,0.0 ,"m" ,"Width dependence of PCLM" ) +`MPRnb( PPCLM ,0.0 ,"m^2" ,"Area dependence of PCLM" ) +`MPRnb( PCLMR ,PCLM ,"" ,"Reverse-mode CLM pre-factor" ) +`MPRnb( LPCLMR ,LPCLM ,"m" ,"Length dependence of PCLMR" ) +`MPRnb( WPCLMR ,WPCLM ,"m" ,"Width dependence of PCLMR" ) +`MPRnb( PPCLMR ,PPCLM ,"m^2" ,"Area dependence of PCLMR" ) +`MPRnb( PCLMG ,0.0 ,"V" ,"CLM pre-factor gate voltage dependence" ) +`MPRnb( PCLMCV ,PCLM ,"" ,"CLM parameter for CV" ) +`MPRnb( PCLMCVL ,PCLML ,"m^PCLMLEXP" ,"Length dependence coefficient of PCLMCV" ) +`MPRoz( PCLMCVLEXP ,PCLMLEXP ,"" ,"Length dependence exponent coefficient of PCLMCV" ) +`MPRnb( LPCLMCV ,LPCLM ,"m" ,"Length dependence of PCLMCV" ) +`MPRnb( WPCLMCV ,WPCLM ,"m" ,"Width dependence of PCLMCV" ) +`MPRnb( PPCLMCV ,PPCLM ,"m^2" ,"Area dependence of PCLMCV" ) +`MPRnb( PSCBE1 ,4.24e8 ,"V/m" ,"Substrate current body-effect coefficient" ) +`MPRnb( LPSCBE1 ,0.0 ,"V" ,"Length dependence of PSCBE1" ) +`MPRnb( WPSCBE1 ,0.0 ,"V" ,"Width dependence of PSCBE1" ) +`MPRnb( PPSCBE1 ,0.0 ,"V*m" ,"Area dependence of PSCBE1" ) +`MPRnb( PSCBE2 ,1.0e-8 ,"m/V" ,"Substrate current body-effect coefficient" ) +`MPRnb( LPSCBE2 ,0.0 ,"m^2/V" ,"Length dependence of PSCBE2" ) +`MPRnb( WPSCBE2 ,0.0 ,"m^2/V" ,"Width dependence of PSCBE2" ) +`MPRnb( PPSCBE2 ,0.0 ,"m^3/V" ,"Area dependence of PSCBE2" ) +`MPRnb( PDITS ,0.0 ,"1/V" ,"Coefficient for drain-induced Vth shift" ) +`MPRnb( LPDITS ,0.0 ,"m/V" ,"Length dependence of PDITS" ) +`MPRnb( WPDITS ,0.0 ,"m/V" ,"Width dependence of PDITS" ) +`MPRnb( PPDITS ,0.0 ,"m^2/V" ,"Area dependence of PDITS" ) +`MPRcz( PDITSL ,0.0 ,"1/m" ,"L dependence of drain-induced Vth shift" ) +`MPRnb( PDITSD ,0.0 ,"1/V" ,"Vds dependence of drain-induced Vth shift" ) +`MPRnb( LPDITSD ,0.0 ,"m/V" ,"Length dependence of PDITSD" ) +`MPRnb( WPDITSD ,0.0 ,"m/V" ,"Width dependence of PDITSD" ) +`MPRnb( PPDITSD ,0.0 ,"m^2/V" ,"Area dependence of PDITSD" ) + +// S/D series resistance +`MPRcz( RSH ,0.0 ,"ohm/square" ,"Source-drain sheet resistance" ) +`MPRnb( PRWG ,1.0 ,"1/V" ,"Gate bias dependence of S/D extension resistance" ) +`MPRnb( LPRWG ,0.0 ,"m/V" ,"Length dependence of PRWG" ) +`MPRnb( WPRWG ,0.0 ,"m/V" ,"Width dependence of PRWG" ) +`MPRnb( PPRWG ,0.0 ,"m^2/V" ,"Area dependence of PRWG" ) +`MPRnb( PRWB ,0.0 ,"1/V" ,"Body bias dependence of resistance" ) +`MPRnb( LPRWB ,0.0 ,"m/V" ,"Length dependence of PRWB" ) +`MPRnb( WPRWB ,0.0 ,"m/V" ,"Width dependence of PRWB" ) +`MPRnb( PPRWB ,0.0 ,"m^2/V" ,"Area dependence of PRWB" ) +`MPRnb( PRWBL ,0.0 ,"m^PRWBLEXP" ,"Length dependence coefficient of PPRWB" ) +`MPRoz( PRWBLEXP ,1.0 ,"" ,"Length dependence exponent coefficient of PPRWB" ) +`MPRnb( WR ,1.0 ,"" ,"W dependence parameter of S/D extension resistance" ) +`MPRnb( LWR ,0.0 ,"m" ,"Length dependence of WR" ) +`MPRnb( WWR ,0.0 ,"m" ,"Width dependence of WR" ) +`MPRnb( PWR ,0.0 ,"m^2" ,"Area dependence of WR" ) +`MPRnb( RSWMIN ,0.0 ,"ohm*m^WR" ,"Source Resistance per unit width at high Vgs (RDSMOD=1)" ) +`MPRnb( LRSWMIN ,0.0 ,"ohm*m^(2*WR)" ,"Length dependence of RSWMIN" ) +`MPRnb( WRSWMIN ,0.0 ,"ohm*m^(2*WR)" ,"Width dependence of RSWMIN" ) +`MPRnb( PRSWMIN ,0.0 ,"ohm*m^(3*WR)" ,"Area dependence of RSWMIN" ) +`MPRnb( RSW ,10.0 ,"ohm*m^WR" ,"Zero bias Source Resistance (RDSMOD=1)" ) +`MPRnb( LRSW ,0.0 ,"ohm*m^(2*WR)" ,"Length dependence of RSW" ) +`MPRnb( WRSW ,0.0 ,"ohm*m^(2*WR)" ,"Width dependence of RSW" ) +`MPRnb( PRSW ,0.0 ,"ohm*m^(3*WR)" ,"Area dependence of RSW" ) +`MPRnb( RSWL ,0.0 ,"m^RSWLEXP" ,"Geometrical scaling of RSW (RDSMOD=1)" ) +`MPRoz( RSWLEXP ,1.0 ,"" ,"Geometrical scaling of RSW (RDSMOD=1)" ) +`MPRnb( RDWMIN ,RSWMIN ,"ohm*m^WR" ,"Drain Resistance per unit width at high Vgs (RDSMOD=1)" ) +`MPRnb( LRDWMIN ,LRSWMIN ,"ohm*m^(2*WR)" ,"Length dependence of RDWMIN" ) +`MPRnb( WRDWMIN ,WRSWMIN ,"ohm*m^(2*WR)" ,"Width dependence of RDWMIN" ) +`MPRnb( PRDWMIN ,PRSWMIN ,"ohm*m^(3*WR)" ,"Area dependence of RDWMIN" ) +`MPRnb( RDW ,RSW ,"ohm*m^WR" ,"zero bias Drain Resistance (RDSMOD=1)" ) +`MPRnb( LRDW ,LRSW ,"ohm*m^(2*WR)" ,"Length dependence of RDW" ) +`MPRnb( WRDW ,WRSW ,"ohm*m^(2*WR)" ,"Width dependence of RDW" ) +`MPRnb( PRDW ,PRSW ,"ohm*m^(3*WR)" ,"Area dependence of RDW" ) +`MPRnb( RDWL ,RSWL ,"m^RDWLEXP" ,"Geometrical scaling of RDW (RDSMOD=1)" ) +`MPRoz( RDWLEXP ,RSWLEXP ,"" ,"Geometrical scaling of RDW (RDSMOD=1)" ) +`MPRnb( RDSWMIN ,0.0 ,"ohm*m^WR" ,"S/D Resistance per unit width at high Vgs (RDSMOD=0 and RDSMOD=2)" ) +`MPRnb( LRDSWMIN ,0.0 ,"ohm*m^(2*WR)" ,"Length dependence of RDSWMIN " ) +`MPRnb( WRDSWMIN ,0.0 ,"ohm*m^(2*WR)" ,"Width dependence of RDSWMIN " ) +`MPRnb( PRDSWMIN ,0.0 ,"ohm*m^(3*WR)" ,"Area dependence of RDSWMIN " ) +`MPRnb( RDSW ,20.0 ,"ohm*um^WR" ,"Zero bias Resistance (RDSMOD=0 and RDSMOD=2)" ) +`MPRnb( RDSWL ,0.0 ,"m^RDSWLEXP" ,"Geometrical scaling of RDSW (RDSMOD=0 and RDSMOD=2)" ) +`MPRoz( RDSWLEXP ,1.0 ,"" ,"Geometrical scaling of RDSW (RDSMOD=0 and RDSMOD=2)" ) +`MPRnb( LRDSW ,0.0 ,"ohm*m^(2*WR)" ,"Length dependence of RDSW" ) +`MPRnb( WRDSW ,0.0 ,"ohm*m^(2*WR)" ,"Width dependence of RDSW" ) +`MPRnb( PRDSW ,0.0 ,"ohm*m^(3*WR)" ,"Area dependence of RDSW " ) + +// Velocity saturation +`MPRnb( PSAT ,1.0 ,"" ,"Gmsat variation with gate bias" ) +`MPRnb( LPSAT ,0.0 ,"m" ,"Length dependence of PSAT" ) +`MPRnb( WPSAT ,0.0 ,"m" ,"Width dependence of PSAT" ) +`MPRnb( PPSAT ,0.0 ,"m^2" ,"Area dependence of PSAT" ) +`MPRnb( PSATL ,0.0 ,"m^PSATLEXP" ,"Length dependence coefficient of PSATL" ) +`MPRoz( PSATLEXP ,1.0 ,"" ,"Length dependence exponent coefficient of PSATLEXP" ) +`MPRnb( PSATB ,0.0 ,"1/V" ,"Body bias effect on Idsat" ) +`MPRnb( PSATR ,PSAT ,"" ,"Reverse-mode Gmsat variation with gate bias" ) +`MPRnb( LPSATR ,LPSAT ,"m" ,"Length dependence of PSATR" ) +`MPRnb( WPSATR ,WPSAT ,"m" ,"Width dependence of PSATR" ) +`MPRnb( PPSATR ,PPSAT ,"m^2" ,"Area dependence of PSATR" ) +`MPRnb( LPSATB ,0.0 ,"m/V" ,"Length dependence of PSATB" ) +`MPRnb( WPSATB ,0.0 ,"m/V" ,"Width dependence of PSATB" ) +`MPRnb( PPSATB ,0.0 ,"m^2/V" ,"Area dependence of PSATB" ) +`MPRoz( PSATX ,1.0 ,"" ,"Fine tuning of PTWG effect" ) +`MPRnb( PTWG ,0.0 ,"" ,"Idsat variation with gate bias" ) +`MPRnb( LPTWG ,0.0 ,"m" ,"Length dependence of PTWG" ) +`MPRnb( WPTWG ,0.0 ,"m" ,"Width dependence of PTWG" ) +`MPRnb( PPTWG ,0.0 ,"m^2" ,"Area dependence of PTWG" ) +`MPRnb( PTWGL ,0.0 ,"m^PTWGLEXP" ,"Length dependence coefficient of PTWG" ) +`MPRoz( PTWGLEXP ,1.0 ,"" ,"Length dependence exponent coefficient of PTWG" ) +`MPRnb( PTWGR ,PTWG ,"" ,"Reverse-mode Idsat variation with gate bias" ) +`MPRnb( LPTWGR ,LPTWG ,"m" ,"Length dependence of PTWGR" ) +`MPRnb( WPTWGR ,WPTWG ,"m" ,"Width dependence of PTWGR" ) +`MPRnb( PPTWGR ,PPTWG ,"m^2" ,"Area dependence of PTWGR" ) +`MPRnb( PTWGLR ,PTWGL ,"m^PTWGLEXPR" ,"Length dependence coefficient of PTWG" ) +`MPRoz( PTWGLEXPR ,PTWGLEXP ,"" ,"Length dependence exponent coefficient of PTWG" ) + +// Velocity non-saturation effect +`MPRnb( A1 ,0.0 ,"1/V^2" ,"Non-saturation effect parameter for strong inversion region" ) +`MPRnb( LA1 ,0.0 ,"m/V^2" ,"Length dependence of A1" ) +`MPRnb( WA1 ,0.0 ,"m/V^2" ,"Width dependence of A1" ) +`MPRnb( PA1 ,0.0 ,"m^2/V^2" ,"Area dependence of A1" ) +`MPRnb( A11 ,0.0 ,"" ,"Temperature dependence of A1" ) +`MPRnb( LA11 ,0.0 ,"m" ,"Length dependence of A11" ) +`MPRnb( WA11 ,0.0 ,"m" ,"Width dependence of A11" ) +`MPRnb( PA11 ,0.0 ,"m^2" ,"Area dependence of A11" ) +`MPRnb( A2 ,0.0 ,"1/V" ,"Non-saturation effect parameter for moderate inversion region" ) +`MPRnb( LA2 ,0.0 ,"m/V" ,"Length dependence of A2" ) +`MPRnb( WA2 ,0.0 ,"m/V" ,"Width dependence of A2" ) +`MPRnb( PA2 ,0.0 ,"m^2/V" ,"Area dependence of A2" ) +`MPRnb( A21 ,0.0 ,"" ,"Temperature dependence of A2" ) +`MPRnb( LA21 ,0.0 ,"m" ,"Length dependence of A21" ) +`MPRnb( WA21 ,0.0 ,"m" ,"Width dependence of A21" ) +`MPRnb( PA21 ,0.0 ,"m^2" ,"Area dependence of A21" ) + +// Output conductance +`MPRnb( PDIBLC ,0.0 ,"" ,"Parameter for DIBL effect on Rout" ) +`MPRnb( PDIBLCL ,0.0 ,"m^PDIBLCLEXP" ,"Length dependence coefficient of PDIBLC" ) +`MPRoz( PDIBLCLEXP ,1.0 ,"" ,"Length dependence exponent coefficient of PDIBLC" ) +`MPRnb( LPDIBLC ,0.0 ,"m" ,"Length dependence of PDIBLC" ) +`MPRnb( WPDIBLC ,0.0 ,"m" ,"Width dependence of PDIBLC" ) +`MPRnb( PPDIBLC ,0.0 ,"m^2" ,"Area dependence of PDIBLC" ) +`MPRnb( PDIBLCR ,PDIBLC ,"" ,"Reverse-mode Parameter for DIBL effect on Rout" ) +`MPRnb( PDIBLCLR ,PDIBLCL ,"m^PDIBLCLEXPR" ,"Length dependence coefficient of PDIBLC" ) +`MPRoz( PDIBLCLEXPR ,PDIBLCLEXP ,"" ,"Length dependence exponent coefficient of PDIBLC" ) +`MPRnb( LPDIBLCR ,LPDIBLC ,"m" ,"Length dependence of PDIBLCR" ) +`MPRnb( WPDIBLCR ,WPDIBLC ,"m" ,"Width dependence of PDIBLCR" ) +`MPRnb( PPDIBLCR ,PPDIBLC ,"m^2" ,"Area dependence of PDIBLCR" ) +`MPRnb( PDIBLCB ,0.0 ,"1/V" ,"Parameter for DIBL effect on Rout" ) +`MPRnb( LPDIBLCB ,0.0 ,"m/V" ,"Length dependence of PDIBLCB" ) +`MPRnb( WPDIBLCB ,0.0 ,"m/V" ,"Width dependence of PDIBLCB" ) +`MPRnb( PPDIBLCB ,0.0 ,"m^2/V" ,"Area dependence of PDIBLCB" ) +`MPRnb( PVAG ,1.0 ,"" ,"Vg dependence of early voltage" ) +`MPRnb( LPVAG ,0.0 ,"m" ,"Length dependence of PVAG" ) +`MPRnb( WPVAG ,0.0 ,"m" ,"Width dependence of PVAG" ) +`MPRnb( PPVAG ,0.0 ,"m^2" ,"Area dependence of PVAG" ) +`MPRnb( FPROUT ,0.0 ,"V/m^0.5" ,"gds degradation factor due to pocket implant." ) +`MPRnb( FPROUTL ,0.0 ,"m^FPROUTLEXP" ,"Length dependence coefficient of FPROUT" ) +`MPRoz( FPROUTLEXP ,1.0 ,"" ,"Length dependence exponent coefficient of FPROUT" ) +`MPRnb( LFPROUT ,0.0 ,"V*m^0.5" ,"Length dependence of FPROUT" ) +`MPRnb( WFPROUT ,0.0 ,"V*m^0.5" ,"Width dependence of FPROUT" ) +`MPRnb( PFPROUT ,0.0 ,"V*m^1.5" ,"Area dependence of FPROUT" ) + +// Impact ionization current +`MPRnb( ALPHA0 ,0.0 ,"m/V" ,"First parameter of Iii" ) +`MPRnb( ALPHA0L ,0.0 ,"m^ALPHA0LEXP" ,"Length dependence coefficient of ALPHA0" ) +`MPRoz( ALPHA0LEXP ,1.0 ,"" ,"Length dependence exponent coefficient of ALPHA0" ) +`MPRnb( LALPHA0 ,0.0 ,"m^2/V" ,"Length dependence of ALPHA0" ) +`MPRnb( WALPHA0 ,0.0 ,"m^2/V" ,"Width dependence of ALPHA0" ) +`MPRnb( PALPHA0 ,0.0 ,"m^3/V" ,"Area dependence of ALPHA0" ) +`MPRnb( BETA0 ,0.0 ,"1/V" ,"Vds dependent parameter of Iii" ) +`MPRnb( LBETA0 ,0.0 ,"m/V" ,"Length dependence of BETA0" ) +`MPRnb( WBETA0 ,0.0 ,"m/V" ,"Width dependence of BETA0" ) +`MPRnb( PBETA0 ,0.0 ,"m^2/V" ,"Area dependence of BETA0" ) + +// Gate dielectric tunnelling current model parameters +`MPRnb( AIGBACC ,1.36e-2 ,"(F*s^2/g)^0.5/m" ,"Parameter for Igb" ) +`MPRnb( BIGBACC ,1.71e-3 ,"(F*s^2/g)^0.5/m/V" ,"Parameter for Igb" ) +`MPRnb( CIGBACC ,0.075 ,"1/V" ,"Parameter for Igb" ) +`MPRnb( NIGBACC ,1.0 ,"" ,"Parameter for Igbacc slope" ) +`MPRnb( AIGBINV ,1.11e-2 ,"(F*s^2/g)^0.5/m" ,"Parameter for Igb" ) +`MPRnb( BIGBINV ,9.49e-4 ,"(F*s^2/g)^0.5/m/V" ,"Parameter for Igb" ) +`MPRnb( CIGBINV ,0.006 ,"1/V" ,"Parameter for Igb" ) +`MPRnb( EIGBINV ,1.1 ,"V" ,"Parameter for the Si band-gap for Igbinv" ) +`MPRnb( NIGBINV ,3.0 ,"" ,"Parameter for Igbinv slope" ) +`MPRnb( AIGC ,((TYPE == `ntype) ? 1.36e-2 : 9.8e-3) ,"(F*s^2/g)^0.5/m" ,"Parameter for Igc" ) +`MPRnb( BIGC ,((TYPE == `ntype) ? 1.71e-3 : 7.59e-4) ,"(F*s^2/g)^0.5/m/V" ,"Parameter for Igc" ) +`MPRnb( CIGC ,((TYPE == `ntype) ? 0.075 : 0.03) ,"1/V" ,"Parameter for Igc" ) +`MPRnb( AIGS ,((TYPE == `ntype) ? 1.36e-2 : 9.8e-3) ,"(F*s^2/g)^0.5/m" ,"Parameter for Igs d" ) +`MPRnb( BIGS ,((TYPE == `ntype) ? 1.71e-3 : 7.59e-4) ,"(F*s^2/g)^0.5/m/V" ,"Parameter for Igs d" ) +`MPRnb( CIGS ,((TYPE == `ntype) ? 0.075 : 0.03) ,"1/V" ,"Parameter for Igs d" ) +`MPRnb( AIGD ,((TYPE == `ntype) ? 1.36e-2 : 9.8e-3) ,"(F*s^2/g)^0.5/m" ,"Parameter for Igs d" ) +`MPRnb( BIGD ,((TYPE == `ntype) ? 1.71e-3 : 7.59e-4) ,"(F*s^2/g)^0.5/m/V" ,"Parameter for Igs d" ) +`MPRnb( CIGD ,((TYPE == `ntype) ? 0.075 : 0.03) ,"1/V" ,"Parameter for Igs d" ) +`MPRnb( DLCIG ,LINT ,"m" ,"Delta L for Ig model" ) +`MPRnb( DLCIGD ,DLCIG ,"m" ,"Delta L for Ig model" ) +`MPRnb( POXEDGE ,1.0 ,"" ,"Factor for the gate edge Tox" ) +`MPRnb( NTOX ,1.0 ,"" ,"Exponent for Tox ratio" ) +`MPRoz( TOXREF ,3.0e-9 ,"m" ,"Target tox value" ) +`MPRcc( PIGCD ,1.0 ,"" ,-50 ,50 ,"Igc, S/D partition parameter" ) +`MPRnb( AIGCL ,0.0 ,"m" ,"Length dependence coefficient of AIGC" ) +`MPRnb( AIGCW ,0.0 ,"m" ,"Width dependence coefficient of AIGC" ) +`MPRnb( AIGSL ,0.0 ,"m" ,"Length dependence coefficient of AIGS" ) +`MPRnb( AIGSW ,0.0 ,"m" ,"Width dependence coefficient of AIGS" ) +`MPRnb( AIGDL ,0.0 ,"m" ,"Length dependence coefficient of AIGD" ) +`MPRnb( AIGDW ,0.0 ,"m" ,"Width dependence coefficient of AIGD" ) +`MPRnb( PIGCDL ,0.0 ,"m" ,"Length dependence coefficient of PIGCD" ) +`MPRnb( LAIGBINV ,0.0 ,"(F*s^2/g)^0.5" ,"Length dependence of AIGBINV" ) +`MPRnb( WAIGBINV ,0.0 ,"(F*s^2/g)^0.5" ,"Width dependence of AIGBINV" ) +`MPRnb( PAIGBINV ,0.0 ,"m*(F*s^2/g)^0.5" ,"Area dependence of AIGBINV" ) +`MPRnb( LBIGBINV ,0.0 ,"(F*s^2/g)^0.5/V" ,"Length dependence of BIGBINV" ) +`MPRnb( WBIGBINV ,0.0 ,"(F*s^2/g)^0.5/V" ,"Width dependence of BIGBINV" ) +`MPRnb( PBIGBINV ,0.0 ,"m*(F*s^2/g)^0.5/V" ,"Area dependence of BIGBINV" ) +`MPRnb( LCIGBINV ,0.0 ,"m/V" ,"Length dependence of CIGBINV" ) +`MPRnb( WCIGBINV ,0.0 ,"m/V" ,"Width dependence of CIGBINV" ) +`MPRnb( PCIGBINV ,0.0 ,"m^2/V" ,"Area dependence of CIGBINV" ) +`MPRnb( LEIGBINV ,0.0 ,"m*V" ,"Length dependence of EIGBINV" ) +`MPRnb( WEIGBINV ,0.0 ,"m*V" ,"Width dependence of EIGBINV" ) +`MPRnb( PEIGBINV ,0.0 ,"m^2*V" ,"Area dependence of EIGBINV" ) +`MPRnb( LNIGBINV ,0.0 ,"m" ,"Length dependence of NIGBINV" ) +`MPRnb( WNIGBINV ,0.0 ,"m" ,"Width dependence of NIGBINV" ) +`MPRnb( PNIGBINV ,0.0 ,"m^2" ,"Area dependence of NIGBINV" ) +`MPRnb( LAIGBACC ,0.0 ,"(F*s^2/g)^0.5" ,"Length dependence of AIGBACC" ) +`MPRnb( WAIGBACC ,0.0 ,"(F*s^2/g)^0.5" ,"Width dependence of AIGBACC" ) +`MPRnb( PAIGBACC ,0.0 ,"m*(F*s^2/g)^0.5" ,"Area dependence of AIGBACC" ) +`MPRnb( LBIGBACC ,0.0 ,"(F*s^2/g)^0.5/V" ,"Length dependence of BIGBACC" ) +`MPRnb( WBIGBACC ,0.0 ,"(F*s^2/g)^0.5/V" ,"Width dependence of BIGBACC" ) +`MPRnb( PBIGBACC ,0.0 ,"m*(F*s^2/g)^0.5/V" ,"Area dependence of BIGBACC" ) +`MPRnb( LCIGBACC ,0.0 ,"m/V" ,"Length dependence of CIGBACC" ) +`MPRnb( WCIGBACC ,0.0 ,"m/V" ,"Width dependence of CIGBACC" ) +`MPRnb( PCIGBACC ,0.0 ,"m^2/V" ,"Area dependence of CIGBACC" ) +`MPRnb( LNIGBACC ,0.0 ,"m" ,"Length dependence of NIGBACC" ) +`MPRnb( WNIGBACC ,0.0 ,"m" ,"Width dependence of NIGBACC" ) +`MPRnb( PNIGBACC ,0.0 ,"m^2" ,"Area dependence of NIGBACC" ) +`MPRnb( LAIGC ,0.0 ,"(F*s^2/g)^0.5" ,"Length dependence of AIGC" ) +`MPRnb( WAIGC ,0.0 ,"(F*s^2/g)^0.5" ,"Width dependence of AIGC" ) +`MPRnb( PAIGC ,0.0 ,"m*(F*s^2/g)^0.5" ,"Area dependence of AIGC" ) +`MPRnb( LBIGC ,0.0 ,"(F*s^2/g)^0.5/V" ,"Length dependence of BIGC" ) +`MPRnb( WBIGC ,0.0 ,"(F*s^2/g)^0.5/V" ,"Width dependence of BIGC" ) +`MPRnb( PBIGC ,0.0 ,"m*(F*s^2/g)^0.5/V" ,"Area dependence of BIGC" ) +`MPRnb( LCIGC ,0.0 ,"m/V" ,"Length dependence of CIGC" ) +`MPRnb( WCIGC ,0.0 ,"m/V" ,"Width dependence of CIGC" ) +`MPRnb( PCIGC ,0.0 ,"m^2/V" ,"Area dependence of CIGC" ) +`MPRnb( LAIGS ,0.0 ,"(F*s^2/g)^0.5" ,"Length dependence of AIGS" ) +`MPRnb( WAIGS ,0.0 ,"(F*s^2/g)^0.5" ,"Width dependence of AIGS" ) +`MPRnb( PAIGS ,0.0 ,"m*(F*s^2/g)^0.5" ,"Area dependence of AIGS" ) +`MPRnb( LBIGS ,0.0 ,"(F*s^2/g)^0.5/V" ,"Length dependence of BIGS" ) +`MPRnb( WBIGS ,0.0 ,"(F*s^2/g)^0.5/V" ,"Width dependence of BIGS" ) +`MPRnb( PBIGS ,0.0 ,"m*(F*s^2/g)^0.5/V" ,"Area dependence of BIGS" ) +`MPRnb( LCIGS ,0.0 ,"m/V" ,"Length dependence of CIGS" ) +`MPRnb( WCIGS ,0.0 ,"m/V" ,"Width dependence of CIGS" ) +`MPRnb( PCIGS ,0.0 ,"m^2/V" ,"Area dependence of CIGS" ) +`MPRnb( LAIGD ,0.0 ,"(F*s^2/g)^0.5" ,"Length dependence of AIGD" ) +`MPRnb( WAIGD ,0.0 ,"(F*s^2/g)^0.5" ,"Width dependence of AIGD" ) +`MPRnb( PAIGD ,0.0 ,"m*(F*s^2/g)^0.5" ,"Area dependence of AIGD" ) +`MPRnb( LBIGD ,0.0 ,"(F*s^2/g)^0.5/V" ,"Length dependence of BIGD" ) +`MPRnb( WBIGD ,0.0 ,"(F*s^2/g)^0.5/V" ,"Width dependence of BIGD" ) +`MPRnb( PBIGD ,0.0 ,"m*(F*s^2/g)^0.5/V" ,"Area dependence of BIGD" ) +`MPRnb( LCIGD ,0.0 ,"m/V" ,"Length dependence of CIGD" ) +`MPRnb( WCIGD ,0.0 ,"m/V" ,"Width dependence of CIGD" ) +`MPRnb( PCIGD ,0.0 ,"m^2/V" ,"Area dependence of CIGD" ) +`MPRnb( LPOXEDGE ,0.0 ,"m" ,"Length dependence of POXEDGE" ) +`MPRnb( WPOXEDGE ,0.0 ,"m" ,"Width dependence of POXEDGE" ) +`MPRnb( PPOXEDGE ,0.0 ,"m^2" ,"Area dependence of POXEDGE" ) +`MPRnb( LDLCIG ,0.0 ,"m^2" ,"Length dependence of DLCIG" ) +`MPRnb( WDLCIG ,0.0 ,"m^2" ,"Width dependence of DLCIG" ) +`MPRnb( PDLCIG ,0.0 ,"m^3" ,"Area dependence of DLCIG" ) +`MPRnb( LDLCIGD ,0.0 ,"m^2" ,"Length dependence of DLCIGD" ) +`MPRnb( WDLCIGD ,0.0 ,"m^2" ,"Width dependence of DLCIGD" ) +`MPRnb( PDLCIGD ,0.0 ,"m^3" ,"Area dependence of DLCIGD" ) +`MPRnb( LNTOX ,0.0 ,"m" ,"Length dependence of NTOX" ) +`MPRnb( WNTOX ,0.0 ,"m" ,"Width dependence of NTOX" ) +`MPRnb( PNTOX ,0.0 ,"m^2" ,"Area dependence of NTOX" ) + +// GIDL and GISL currents +`MPRnb( AGIDL ,0.0 ,"V/m" ,"Pre-exponential coefficient for GIDL" ) +`MPRnb( AGIDLL ,0.0 ,"m" ,"Length dependence coefficient of AGIDL" ) +`MPRnb( AGIDLW ,0.0 ,"m" ,"Width dependence coefficient of AGIDL" ) +`MPRnb( LAGIDL ,0.0 ,"m^2" ,"Length dependence of AGIDL" ) +`MPRnb( WAGIDL ,0.0 ,"m^2" ,"Width dependence of AGIDL" ) +`MPRnb( PAGIDL ,0.0 ,"m^3" ,"Area dependence of AGIDL" ) +`MPRnb( BGIDL ,2.3e9 ,"V/m" ,"Exponential coefficient for GIDL" ) +`MPRnb( LBGIDL ,0.0 ,"V" ,"Length dependence of BGIDL" ) +`MPRnb( WBGIDL ,0.0 ,"V" ,"Width dependence of BGIDL" ) +`MPRnb( PBGIDL ,0.0 ,"V*m" ,"Area dependence of BGIDL" ) +`MPRnb( CGIDL ,0.5 ,"V/m" ,"Exponential coefficient for GIDL" ) +`MPRnb( LCGIDL ,0.0 ,"V" ,"Length dependence of CGIDL" ) +`MPRnb( WCGIDL ,0.0 ,"V" ,"Width dependence of CGIDL" ) +`MPRnb( PCGIDL ,0.0 ,"V*m" ,"Area dependence of CGIDL" ) +`MPRnb( EGIDL ,0.8 ,"V" ,"Band bending parameter for GIDL" ) +`MPRnb( LEGIDL ,0.0 ,"V*m" ,"Length dependence of EGIDL" ) +`MPRnb( WEGIDL ,0.0 ,"V*m" ,"Width dependence of EGIDL" ) +`MPRnb( PEGIDL ,0.0 ,"V*m^2" ,"Area dependence of EGIDL" ) +`MPRnb( AGISL ,AGIDL ,"V/m" ,"Pre-exponential coefficient for GISL" ) +`MPRnb( AGISLL ,AGIDLL ,"m" ,"Length dependence coefficient of AGISL" ) +`MPRnb( AGISLW ,AGIDLW ,"m" ,"Width dependence coefficient of AGISL" ) +`MPRnb( LAGISL ,LAGIDL ,"m^2" ,"Length dependence of AGISL" ) +`MPRnb( WAGISL ,WAGIDL ,"m^2" ,"Width dependence of AGISL" ) +`MPRnb( PAGISL ,PAGIDL ,"m^3" ,"Area dependence of AGISL" ) +`MPRnb( BGISL ,BGIDL ,"V/m" ,"Exponential coefficient for GISL" ) +`MPRnb( LBGISL ,LBGIDL ,"V" ,"Length dependence of BGISL" ) +`MPRnb( WBGISL ,WBGIDL ,"V" ,"Width dependence of BGISL" ) +`MPRnb( PBGISL ,PBGIDL ,"V*m" ,"Area dependence of BGISL" ) +`MPRnb( CGISL ,CGIDL ,"V/m" ,"Exponential coefficient for GISL" ) +`MPRnb( LCGISL ,LCGIDL ,"V" ,"Length dependence of CGISL" ) +`MPRnb( WCGISL ,WCGIDL ,"V" ,"Width dependence of CGISL" ) +`MPRnb( PCGISL ,PCGIDL ,"V*m" ,"Area dependence of CGISL" ) +`MPRnb( EGISL ,EGIDL ,"V" ,"Band bending parameter for GISL" ) +`MPRnb( LEGISL ,LEGIDL ,"V*m" ,"Length dependence of EGISL" ) +`MPRnb( WEGISL ,WEGIDL ,"V*m" ,"Width dependence of EGISL" ) +`MPRnb( PEGISL ,PEGIDL ,"V*m^2" ,"Area dependence of EGISL" ) + +// Overlap capacitance and fringing capacitance +`MPRnb( CF ,0.0 ,"F/m" ,"Outer Fringe capacitance" ) +`MPRnb( LCF ,0.0 ,"F" ,"Length dependence of CF" ) +`MPRnb( WCF ,0.0 ,"F" ,"Width dependence of CF" ) +`MPRnb( PCF ,0.0 ,"F*m" ,"Area dependence of CF" ) +`MPRco( CFRCOEFF ,1.0 ,"F/m" ,1.0 ,inf ,"Coefficient for Outer Fringe capacitance" ) +`MPRnb( CGSO ,0.0 ,"F/m" ,"Gate - Source overlap capacitance" ) +`MPRnb( CGDO ,0.0 ,"F/m" ,"Gate - Drain overlap capacitance" ) +`MPRnb( CGBO ,0.0 ,"F/m" ,"Gate - Body overlap capacitance" ) +`MPRnb( CGSL ,0.0 ,"F/m" ,"Overlap capacitance between gate and lightly-doped source region" ) +`MPRnb( LCGSL ,0.0 ,"" ,"Length dependence of CGSL" ) +`MPRnb( WCGSL ,0.0 ,"" ,"Width dependence of CGSL" ) +`MPRnb( PCGSL ,0.0 ,"" ,"Area dependence of CGSL" ) +`MPRnb( CGDL ,0.0 ,"F/m" ,"Overlap capacitance between gate and lightly-doped drain region" ) +`MPRnb( LCGDL ,0.0 ,"F" ,"Length dependence of CGDL" ) +`MPRnb( WCGDL ,0.0 ,"F" ,"Width dependence of CGDL" ) +`MPRnb( PCGDL ,0.0 ,"F*m" ,"Area dependence of CGDL" ) +`MPRnb( CKAPPAS ,0.6 ,"V" ,"Coefficient of bias-dependent overlap capacitance for the source side" ) +`MPRnb( LCKAPPAS ,0.0 ,"m*V" ,"Length dependence of CKAPPAS" ) +`MPRnb( WCKAPPAS ,0.0 ,"m*V" ,"Width dependence of CKAPPAS" ) +`MPRnb( PCKAPPAS ,0.0 ,"m^2*V" ,"Area dependence of CKAPPAS" ) +`MPRnb( CKAPPAD ,0.6 ,"V" ,"Coefficient of bias-dependent overlap capacitance for the drain side" ) +`MPRnb( LCKAPPAD ,0.0 ,"m*V" ,"Length dependence of CKAPPAD" ) +`MPRnb( WCKAPPAD ,0.0 ,"m*V" ,"Width dependence of CKAPPAD" ) +`MPRnb( PCKAPPAD ,0.0 ,"m^2*V" ,"Area dependence of CKAPPAD" ) + +// Layout-dependent parasitics model parameters (resistance only) +`MPRnb( DMCG ,0.0 ,"m" ,"Distance of Mid-Contact to Gate edge" ) +`MPRnb( DMCI ,DMCG ,"m" ,"Distance of Mid-Contact to Isolation" ) +`MPRnb( DMDG ,0.0 ,"m" ,"Distance of Mid-Diffusion to Gate edge" ) +`MPRnb( DMCGT ,0.0 ,"m" ,"Distance of Mid-Contact to Gate edge in Test" ) +`MPRoo( XGL ,0.0 ,"m" ,-inf ,L*LMLT+XL ,"Variation in Ldrawn" ) +`MPRcz( RSHG ,0.1 ,"ohm" ,"Gate sheet resistance" ) + +// Junction capacitance +`MPRnb( CJS ,5.0e-4 ,"F/m^2" ,"Unit area source-side junction capacitance at zero bias" ) +`MPRnb( CJD ,CJS ,"F/m^2" ,"Unit area drain-side junction capacitance at zero bias" ) +`MPRnb( CJSWS ,5.0e-10 ,"F/m" ,"Unit length source-side side-wall junction capacitance at zero bias" ) +`MPRnb( CJSWD ,CJSWS ,"F/m" ,"Unit length drain-side side-wall junction capacitance at zero bias" ) +`MPRnb( CJSWGS ,0.0 ,"F/m" ,"Unit length source-side gate side-wall junction capacitance at zero bias" ) +`MPRnb( CJSWGD ,CJSWGS ,"F/m" ,"Unit length drain-side gate side-wall junction capacitance at zero bias" ) +`MPRnb( PBS ,1.0 ,"V" ,"Source-side bulk junction built-in potential" ) +`MPRnb( PBD ,PBS ,"V" ,"Drain-side bulk junction built-in potential" ) +`MPRnb( PBSWS ,1.0 ,"V" ,"Built-in potential for Source-side side-wall junction capacitance" ) +`MPRnb( PBSWD ,PBSWS ,"V" ,"Built-in potential for Drain-side side-wall junction capacitance" ) +`MPRnb( PBSWGS ,PBSWS ,"V" ,"Built-in potential for Source-side gate side-wall junction capacitance" ) +`MPRnb( PBSWGD ,PBSWGS ,"V" ,"Built-in potential for Drain-side gate side-wall junction capacitance" ) +`MPRnb( MJS ,0.5 ,"" ,"Source bottom junction capacitance grading coefficient" ) +`MPRnb( MJD ,MJS ,"" ,"Drain bottom junction capacitance grading coefficient" ) +`MPRnb( MJSWS ,0.33 ,"" ,"Source side-wall junction capacitance grading coefficient" ) +`MPRnb( MJSWD ,MJSWS ,"" ,"Drain side-wall junction capacitance grading coefficient" ) +`MPRnb( MJSWGS ,MJSWS ,"" ,"Source-side gate side-wall junction capacitance grading coefficient" ) +`MPRnb( MJSWGD ,MJSWGS ,"" ,"Drain-side gate side-wall junction capacitance grading coefficient" ) + +// Junction current +`MPRnb( JSS ,1.0e-4 ,"A/m^2" ,"Bottom source junction reverse saturation current density" ) +`MPRnb( JSD ,JSS ,"A/m^2" ,"Bottom drain junction reverse saturation current density" ) +`MPRnb( JSWS ,0.0 ,"A/m" ,"Unit length reverse saturation current for side-wall source junction" ) +`MPRnb( JSWD ,JSWS ,"A/m" ,"Unit length reverse saturation current for side-wall drain junction" ) +`MPRnb( JSWGS ,0.0 ,"A/m" ,"Unit length reverse saturation current for gate-edge side-wall source junction" ) +`MPRnb( JSWGD ,JSWGS ,"A/m" ,"Unit length reverse saturation current for gate-edge side-wall drain junction" ) +`MPRoz( NJS ,1.0 ,"" ,"Source junction emission coefficient" ) +`MPRoz( NJD ,NJS ,"" ,"Drain junction emission coefficient" ) +`MPRnb( IJTHSFWD ,0.1 ,"A" ,"Forward source diode breakdown limiting current" ) +`MPRnb( IJTHDFWD ,IJTHSFWD ,"A" ,"Forward drain diode breakdown limiting current" ) +`MPRnb( IJTHSREV ,0.1 ,"A" ,"Reverse source diode breakdown limiting current" ) +`MPRnb( IJTHDREV ,IJTHSREV ,"A" ,"Reverse drain diode breakdown limiting current" ) +`MPRnb( BVS ,10.0 ,"V" ,"Source diode breakdown voltage" ) +`MPRnb( BVD ,BVS ,"V" ,"Drain diode breakdown voltage" ) +`MPRoz( XJBVS ,1.0 ,"" ,"Fitting parameter for source diode breakdown current" ) +`MPRoz( XJBVD ,XJBVS ,"" ,"Fitting parameter for drain diode breakdown current" ) + +// Tunneling component of junction current +`MPRnb( JTSS ,0.0 ,"A/m" ,"Bottom source junction trap-assisted saturation current density" ) +`MPRnb( JTSD ,JTSS ,"A/m" ,"Bottom drain junction trap-assisted saturation current density" ) +`MPRnb( JTSSWS ,0.0 ,"A/m^2" ,"Unit length trap-assisted saturation current for side-wall source junction" ) +`MPRnb( JTSSWD ,JTSSWS ,"A/m^2" ,"Unit length trap-assisted saturation current for side-wall drain junction" ) +`MPRnb( JTSSWGS ,0.0 ,"A/m" ,"Unit length trap-assisted saturation current for gate-edge side-wall source junction" ) +`MPRnb( JTSSWGD ,JTSSWGS ,"A/m" ,"Unit length trap-assisted saturation current for gate-edge side-wall drain junction" ) +`MPRcz( JTWEFF ,0.0 ,"" ,"Trap assisted tunnelling current width dependence" ) +`MPRnb( NJTS ,20.0 ,"" ,"Non-ideality factor for JTSS" ) +`MPRnb( NJTSD ,NJTS ,"" ,"Non-ideality factor for JTSD" ) +`MPRnb( NJTSSW ,20.0 ,"" ,"Non-ideality factor for JTSSWS" ) +`MPRnb( NJTSSWD ,NJTSSW ,"" ,"Non-ideality factor for JTSSWD" ) +`MPRnb( NJTSSWG ,20.0 ,"" ,"Non-ideality factor for JTSSWGS" ) +`MPRnb( NJTSSWGD ,NJTSSWG ,"" ,"Non-ideality factor for JTSSWGD" ) +`MPRnb( VTSS ,10.0 ,"V" ,"Bottom source junction trap-assisted current voltage dependent parameter" ) +`MPRnb( VTSD ,VTSS ,"V" ,"Bottom drain junction trap-assisted current voltage dependent parameter" ) +`MPRnb( VTSSWS ,10.0 ,"V" ,"Unit length trap-assisted current voltage dependent parameter for side-wall source junction" ) +`MPRnb( VTSSWD ,VTSSWS ,"V" ,"Unit length trap-assisted current voltage dependent parameter for side-wall drain junction" ) +`MPRnb( VTSSWGS ,10.0 ,"V" ,"Unit length trap-assisted current voltage dependent parameter for gate-edge side-wall source junction" ) +`MPRnb( VTSSWGD ,VTSSWGS ,"V" ,"Unit length trap-assisted current voltage dependent parameter for gate-edge side-wall drain junction" ) + +// High-speed/RF model parameters +`MPRnb( XRCRG1 ,12.0 ,"" ,"1st fitting parameter the bias-dependent Rg " ) +`MPRnb( XRCRG2 ,1.0 ,"" ,"2nd fitting parameter the bias-dependent Rg " ) +`MPRcz( GBMIN ,1.0e-12 ,"mho" ,"Minimum body conductance" ) +`MPRoz( RBPS0 ,50.0 ,"ohm" ,"Scaling pre-factor for RBPS" ) +`MPRcz( RBPSL ,0.0 ,"" ,"Length Scaling parameter for RBPS" ) +`MPRcz( RBPSW ,0.0 ,"" ,"Width Scaling parameter for RBPS" ) +`MPRcz( RBPSNF ,0.0 ,"" ,"Number of fingers Scaling parameter for RBPS" ) +`MPRoz( RBPD0 ,50.0 ,"ohm" ,"Scaling pre-factor for RBPD" ) +`MPRcz( RBPDL ,0.0 ,"" ,"Length Scaling parameter for RBPD" ) +`MPRcz( RBPDW ,0.0 ,"" ,"Width Scaling parameter for RBPD" ) +`MPRcz( RBPDNF ,0.0 ,"" ,"Number of fingers Scaling parameter for RBPD" ) +`MPRoz( RBPBX0 ,100.0 ,"ohm" ,"Scaling pre-factor for RBPBX" ) +`MPRcz( RBPBXL ,0.0 ,"" ,"Length Scaling parameter for RBPBX" ) +`MPRcz( RBPBXW ,0.0 ,"" ,"Width Scaling parameter for RBPBX" ) +`MPRcz( RBPBXNF ,0.0 ,"" ,"Number of fingers Scaling parameter for RBPBX" ) +`MPRoz( RBPBY0 ,100.0 ,"ohm" ,"Scaling pre-factor for RBPBY" ) +`MPRcz( RBPBYL ,0.0 ,"" ,"Length Scaling parameter for RBPBY" ) +`MPRcz( RBPBYW ,0.0 ,"" ,"Width Scaling parameter for RBPBY" ) +`MPRcz( RBPBYNF ,0.0 ,"" ,"Number of fingers Scaling parameter for RBPBY" ) +`MPRoz( RBSBX0 ,100.0 ,"ohm" ,"Scaling pre-factor for RBSBX" ) +`MPRoz( RBSBY0 ,100.0 ,"ohm" ,"Scaling pre-factor for RBSBY" ) +`MPRoz( RBDBX0 ,100.0 ,"ohm" ,"Scaling pre-factor for RBDBX" ) +`MPRoz( RBDBY0 ,100.0 ,"ohm" ,"Scaling pre-factor for RBDBY" ) +`MPRcz( RBSDBXL ,0.0 ,"" ,"Length Scaling parameter for RBSBX and RBDBX" ) +`MPRcz( RBSDBXW ,0.0 ,"" ,"Width Scaling parameter for RBSBX and RBDBX" ) +`MPRcz( RBSDBXNF ,0.0 ,"" ,"Number of fingers Scaling parameter for RBSBX and RBDBX" ) +`MPRcz( RBSDBYL ,0.0 ,"" ,"Length Scaling parameter for RBSBY and RBDBY" ) +`MPRcz( RBSDBYW ,0.0 ,"" ,"Width Scaling parameter for RBSBY and RBDBY" ) +`MPRcz( RBSDBYNF ,0.0 ,"" ,"Number of fingers Scaling parameter for RBSBY and RBDBY" ) + +// Flicker noise +`MPRoc( EF ,1.0 ,"" ,0 ,2 ,"Flicker Noise frequency exponent" ) +`MPRnb( EM ,4.1e7 ,"V/m" ,"Saturation Field" ) +`MPRnb( NOIA ,6.250e+40 ,"s^(1-EF)/(eV)^1/m^3" ,"Flicker noise parameter A" ) +`MPRnb( NOIB ,3.125e+25 ,"s^(1-EF)/(eV)^1/m" ,"Flicker noise parameter B" ) +`MPRnb( NOIC ,8.750e+8 ,"s^(1-EF)*m/(eV)^1" ,"Flicker noise parameter C" ) +`MPRnb( LINTNOI ,0.0 ,"m" ,"Length Reduction Parameter Offset" ) + +// Thermal noise +`MPRcz( NTNOI ,1.0 ,"" ,"Noise factor for short-channel devices for TNOIMOD=0 only" ) +`MPRnb( RNOIA ,0.577 ,"" ,"TNOIMOD = 1" ) +`MPRnb( RNOIB ,0.5164 ,"" ,"TNOIMOD = 1" ) +`MPRnb( RNOIC ,0.395 ,"" ,"TNOIMOD = 1" ) +`MPRoo( TNOIA ,0.0 ,"" ,-inf ,inf ,"TNOIMOD = 1" ) +`MPRoo( TNOIB ,0.0 ,"" ,-inf ,inf ,"TNOIMOD = 1" ) +`MPRoo( TNOIC ,0.0 ,"" ,-inf ,inf ,"Correlation coefficient" ) + +// Binning parameters +`MPIcc( BINUNIT ,1 ,"" ,0 ,1 ,"Unit of L and W for Binning, 1 : micro-meter, 0 : default" ) +`MPRnb( DLBIN ,0.0 ,"" ,"Length reduction parameter for binning" ) +`MPRnb( DWBIN ,0.0 ,"" ,"Width reduction parameter for binning" ) + +// Temperature dependence parameters +`MPRnb( TNOM ,27.0 ,"degC" ,"Temperature at which the model was extracted" ) +`MPRnb( TBGASUB ,4.73e-4 ,"eV/K" ,"Band-gap Temperature Coefficient" ) +`MPRnb( TBGBSUB ,636.0 ,"K" ,"Band-gap Temperature Coefficient" ) +`MPRnb( TNFACTOR ,0.0 ,"" ,"Temperature exponent for NFACTOR" ) +`MPRnb( UTE ,-1.5 ,"" ,"Mobility temperature exponent" ) +`MPRnb( LUTE ,0.0 ,"m" ,"Length dependence of UTE" ) +`MPRnb( WUTE ,0.0 ,"m" ,"Width dependence of UTE" ) +`MPRnb( PUTE ,0.0 ,"m^2" ,"Area dependence of UTE" ) +`MPRnb( UTEL ,0.0 ,"m" ,"Length Scaling parameter for UTE" ) +`MPRnb( UA1 ,1.0e-3 ,"m/V" ,"Temperature coefficient for UA" ) +`MPRnb( LUA1 ,0.0 ,"m^2/V" ,"Length dependence of UA1" ) +`MPRnb( WUA1 ,0.0 ,"m^2/V" ,"Width dependence of UA1" ) +`MPRnb( PUA1 ,0.0 ,"m^3/V" ,"Area dependence of UA1" ) +`MPRnb( UA1L ,0.0 ,"m" ,"Length Scaling parameter for UA1" ) +`MPRnb( UC1 ,0.056e-9 ,"1/K" ,"Temperature coefficient for UC" ) +`MPRnb( LUC1 ,0.0 ,"m/K" ,"Length dependence of UC1" ) +`MPRnb( WUC1 ,0.0 ,"m/K" ,"Width dependence of UC1" ) +`MPRnb( PUC1 ,0.0 ,"m^2/K" ,"Area dependence of UC1" ) +`MPRnb( UD1 ,0.0 ,"1/m^2" ,"Temperature coefficient for UD" ) +`MPRnb( LUD1 ,0.0 ,"1/m" ,"Length dependence of UD1" ) +`MPRnb( WUD1 ,0.0 ,"1/m" ,"Width dependence of UD1" ) +`MPRnb( PUD1 ,0.0 ,"" ,"Area dependence of UD1" ) +`MPRnb( UD1L ,0.0 ,"m" ,"Length Scaling parameter for UD1" ) +`MPRnb( UCSTE ,-4.775e-3 ,"" ,"Temperature coefficient for UCS" ) +`MPRnb( LUCSTE ,0.0 ,"m" ,"Length dependence of UCSTE" ) +`MPRnb( WUCSTE ,0.0 ,"m" ,"Width dependence of UCSTE" ) +`MPRnb( PUCSTE ,0.0 ,"m^2" ,"Area dependence of UCSTE" ) +`MPRnb( TETA0 ,0.0 ,"" ,"Temperature coefficient for ETA0" ) +`MPRnb( PRT ,0.0 ,"" ,"Temperature coefficient for resistance" ) +`MPRnb( LPRT ,0.0 ,"m" ,"Length dependence of PRT" ) +`MPRnb( WPRT ,0.0 ,"m" ,"Width dependence of PRT" ) +`MPRnb( PPRT ,0.0 ,"m^2" ,"Area dependence of PRT" ) +`MPRnb( AT ,-1.56e-3 ,"m/s" ,"Temperature coefficient for saturation velocity" ) +`MPRnb( LAT ,0.0 ,"m^2/s" ,"Length dependence of AT" ) +`MPRnb( WAT ,0.0 ,"m^2/s" ,"Width dependence of AT" ) +`MPRnb( PAT ,0.0 ,"m^3/s" ,"Area dependence of AT" ) +`MPRnb( ATL ,0.0 ,"m" ,"Length Scaling parameter for AT" ) +`MPRnb( TDELTA ,0.0 ,"1/K" ,"Temperature coefficient for DELTA" ) +`MPRnb( PTWGT ,0.0 ,"1/K" ,"Temperature coefficient for PTWG" ) +`MPRnb( LPTWGT ,0.0 ,"m/K" ,"Length dependence of PTWGT" ) +`MPRnb( WPTWGT ,0.0 ,"m/K" ,"Width dependence of PTWGT" ) +`MPRnb( PPTWGT ,0.0 ,"m^2/K" ,"Area dependence of PTWGT" ) +`MPRnb( PTWGTL ,0.0 ,"m" ,"Length Scaling parameter for PTWGT" ) +`MPRnb( KT1 ,-0.11 ,"V" ,"Temperature coefficient for Vth" ) +`MPRoz( KT1EXP ,1.0 ,"" ,"Temperature coefficient for Vth" ) +`MPRnb( KT1L ,0.0 ,"V*m" ,"Temperature coefficient for Vth" ) +`MPRnb( LKT1 ,0.0 ,"V*m" ,"Length dependence of KT1" ) +`MPRnb( WKT1 ,0.0 ,"V*m" ,"Width dependence of KT1" ) +`MPRnb( PKT1 ,0.0 ,"V*m^2" ,"Area dependence of KT1" ) +`MPRnb( KT2 ,0.022 ,"" ,"Temperature coefficient for Vth" ) +`MPRnb( LKT2 ,0.0 ,"m" ,"Length dependence of KT2" ) +`MPRnb( WKT2 ,0.0 ,"m" ,"Width dependence of KT2" ) +`MPRnb( PKT2 ,0.0 ,"m^2" ,"Area dependence of KT2" ) +`MPRnb( IIT ,0.0 ,"" ,"Temperature coefficient for BETA0" ) +`MPRnb( LIIT ,0.0 ,"m" ,"Length dependence of IIT" ) +`MPRnb( WIIT ,0.0 ,"m" ,"Width dependence of IIT" ) +`MPRnb( PIIT ,0.0 ,"m^2" ,"Area dependence of IIT" ) +`MPRnb( IGT ,2.5 ,"" ,"Gate Current Temperature Dependence" ) +`MPRnb( LIGT ,0.0 ,"m" ,"Length dependence of IGT" ) +`MPRnb( WIGT ,0.0 ,"m" ,"Width dependence of IGT" ) +`MPRnb( PIGT ,0.0 ,"m^2" ,"Area dependence of IGT" ) +`MPRnb( TGIDL ,0.0 ,"1/K" ,"Temperature coefficient for GIDL/GISL" ) +`MPRnb( LTGIDL ,0.0 ,"m/K" ,"Length dependence of TGIDL" ) +`MPRnb( WTGIDL ,0.0 ,"m/K" ,"Width dependence of TGIDL" ) +`MPRnb( PTGIDL ,0.0 ,"m^2/K" ,"Area dependence of TGIDL" ) +`MPRnb( TCJ ,0.0 ,"1/K" ,"Temperature coefficient for CJS/CJD" ) +`MPRnb( TCJSW ,0.0 ,"1/K" ,"Temperature coefficient for CJSWS/CJSWD" ) +`MPRnb( TCJSWG ,0.0 ,"1/K" ,"Temperature coefficient for CJSWGS/CJSWGD" ) +`MPRnb( TPB ,0.0 ,"V/K" ,"Temperature coefficient for PBS/PBD" ) +`MPRnb( TPBSW ,0.0 ,"V/K" ,"Temperature coefficient for PBSWS/PBSWD" ) +`MPRnb( TPBSWG ,0.0 ,"V/K" ,"Temperature coefficient for PBSWGS/PBSWGD" ) +`MPRnb( XTIS ,3.0 ,"" ,"Source junction current temperature exponent" ) +`MPRnb( XTID ,XTIS ,"" ,"Drain junction current temperature exponent" ) +`MPRnb( XTSS ,0.02 ,"" ,"Power dependence of JTSS on temperature" ) +`MPRnb( XTSD ,XTSS ,"" ,"Power dependence of JTSD on temperature" ) +`MPRnb( XTSSWS ,0.02 ,"" ,"Power dependence of JTSSWS on temperature" ) +`MPRnb( XTSSWD ,XTSSWS ,"" ,"Power dependence of JTSSWD on temperature" ) +`MPRnb( XTSSWGS ,0.02 ,"" ,"Power dependence of JTSSWGS on temperature" ) +`MPRnb( XTSSWGD ,XTSSWGS ,"" ,"Power dependence of JTSSWGD on temperature" ) +`MPRnb( TNJTS ,0.0 ,"" ,"Temperature coefficient for NJTS" ) +`MPRnb( TNJTSD ,TNJTS ,"" ,"Temperature coefficient for NJTSD" ) +`MPRnb( TNJTSSW ,0.0 ,"" ,"Temperature coefficient for NJTSSW" ) +`MPRnb( TNJTSSWD ,TNJTSSW ,"" ,"Temperature coefficient for NJTSSWD" ) +`MPRnb( TNJTSSWG ,0.0 ,"" ,"Temperature coefficient for NJTSSWG" ) +`MPRnb( TNJTSSWGD ,TNJTSSWG ,"" ,"Temperature coefficient for NJTSSWGD" ) + +// Self heating parameters +`MPRco( RTH0 ,0.0 ,"m*K/W" ,0 ,inf ,"Thermal resistance" ) +`MPRco( CTH0 ,1.0E-05 ,"s*W/(m*K)" ,0 ,inf ,"Thermal capacitance" ) +`MPRnb( WTH0 ,0.0 ,"m" ,"Width dependence coefficient for Rth and Cth" ) + +// Stress related parameters +`MPRoz( SAREF ,1.0e-6 ,"m" ,"Reference distance between OD edge from Poly from one side" ) +`MPRoz( SBREF ,1.0e-6 ,"m" ,"Reference distance between OD edge from Poly from other side" ) +`MPRcz( WLOD ,0.0 ,"m" ,"Width Parameter for Stress Effect" ) +`MPRnb( KU0 ,0.0 ,"m" ,"Mobility degradation/enhancement Parameter for Stress Effect" ) +`MPRnb( KVSAT ,0.0 ,"m" ,"Saturation Velocity degradation/enhancement Parameter for Stress Effect" ) +`MPRnb( TKU0 ,0.0 ,"" ,"Temperature Coefficient for KU0" ) +`MPRnb( LKU0 ,0.0 ,"m^LLODKU0" ,"Length Dependence of KU0" ) +`MPRnb( WKU0 ,0.0 ,"m^WLODKU0" ,"Width Dependence of KU0" ) +`MPRnb( PKU0 ,0.0 ,"m^(LLODKU0+WLODKU0)" ,"Cross Term Dependence of KU0" ) +`MPRnb( LLODKU0 ,0.0 ,"" ,"Length Parameter for U0 stress effect" ) +`MPRnb( WLODKU0 ,0.0 ,"" ,"Width Parameter for U0 stress effect" ) +`MPRnb( KVTH0 ,0.0 ,"V*m" ,"Threshold Shift parameter for stress effect" ) +`MPRnb( LKVTH0 ,0.0 ,"m^LLODKU0" ,"Length dependence of KVTH0" ) +`MPRnb( WKVTH0 ,0.0 ,"m^WLODKU0" ,"Width dependence of KVTH0" ) +`MPRnb( PKVTH0 ,0.0 ,"m^(LLODKU0+WLODKU0)" ,"Cross-term dependence of KVTH0" ) +`MPRnb( LLODVTH ,0.0 ,"" ,"Length Parameter for Vth stress effect" ) +`MPRnb( WLODVTH ,0.0 ,"" ,"Width Parameter for Vth stress effect" ) +`MPRnb( STK2 ,0.0 ,"m" ,"K2 shift factor related to Vth change" ) +`MPRnb( LODK2 ,0.0 ,"" ,"K2 shift modification factor for stress effect" ) +`MPRnb( STETA0 ,0.0 ,"m" ,"ETA0 shift related to Vth0 change" ) +`MPRnb( LODETA0 ,0.0 ,"" ,"ETA0 modification factor for stress effect" ) + +// Well proximity parameters +`MPRnb( WEB ,0.0 ,"" ,"Coefficient for SCB (>0.0)" ) +`MPRnb( WEC ,0.0 ,"" ,"Coefficient for SCC (>0.0)" ) +`MPRnb( KVTH0WE ,0.0 ,"" ,"Threshold shift factor for well proximity effect" ) +`MPRnb( LKVTH0WE ,0.0 ,"m" ,"Length dependence of KVTH0WE" ) +`MPRnb( WKVTH0WE ,0.0 ,"m" ,"Width dependence of KVTH0WE" ) +`MPRnb( PKVTH0WE ,0.0 ,"m^2" ,"Area dependence of KVTH0WE" ) +`MPRnb( K2WE ,0.0 ,"" ,"K2 shift factor for well proximity effect" ) +`MPRnb( LK2WE ,0.0 ,"m" ,"Length dependence of K2WE" ) +`MPRnb( WK2WE ,0.0 ,"m" ,"Width dependence of K2WE" ) +`MPRnb( PK2WE ,0.0 ,"m^2" ,"Area dependence of K2WE" ) +`MPRnb( KU0WE ,0.0 ,"" ,"Mobility degradation factor for well proximity effect" ) +`MPRnb( LKU0WE ,0.0 ,"m" ,"Length dependence of KU0WE" ) +`MPRnb( WKU0WE ,0.0 ,"m" ,"Width dependence of KU0WE" ) +`MPRnb( PKU0WE ,0.0 ,"m^2" ,"Area dependence of KU0WE" ) +`MPRoo( SCREF ,1.0e-6 ,"m" ,0 ,inf ,"Reference distance to calculate SCA,SCB and SCC (<0)" ) + +// Sub-surface leakage drain current +`MPRnb( SSL0 ,4.0e2 ,"A/m" ,"Temperature- and doping-independent parameter for sub-surface leakage drain current") +`MPRnb( SSL1 ,3.36e8 ,"1/m" ,"Temperature- and doping-independent parameter for gate length for sub-surface leakage drain current") +`MPRnb( SSL2 ,0.185 ,"" ,"Fitting parameter for sub-surface leakage drain current: barrier height") +`MPRnb( SSL3 ,0.3 ,"V" ,"Fitting parameter for sub-surface leakage drain current: gate voltage effect") +`MPRnb( SSL4 ,1.4 ,"1/V" ,"Fitting parameter for sub-surface leakage drain current: gate voltage effect") +`MPRnb( SSLEXP1 ,0.490 ,"" ,"Fitting exponent for ssl doping effect") +`MPRnb( SSLEXP2 ,1.42 ,"" ,"Fitting exponent for ssl temperature") + +// Vdsx smoothing +`MPRco( AVDSX ,20 ,"" ,5 ,100 ,"Smoothing parameter in Vdsx in Vbsx" ) + +// STI edge FET device parameters +`MPRco( WEDGE ,10.0e-9 ,"m" ,1.0e-9 ,inf ,"Edge FET Width" ) +`MPRoo( DGAMMAEDGE ,0.0 ,"" ,-inf ,inf ,"Different in body-bias coefficient between Edge-FET and Main-FET" ) +`MPRoo( DGAMMAEDGEL ,0.0 ,"" ,-inf ,inf ,"L dependence parameter for DGAMMA" ) +`MPRoo( DGAMMAEDGELEXP ,1.0 ,"" ,-inf ,inf ,"Exponent of L dependence parameter for DGAMMA" ) +`MPRoo( DVTEDGE ,0.0 ,"" ,-inf ,inf ,"Vth shift for Edge FET" ) +`MPRnb( NFACTOREDGE ,NFACTOR ,"" ,"NFACTOR for Edge FET" ) +`MPRnb( LNFACTOREDGE ,LNFACTOR ,"m" ,"Length dependence of NFACTOREDGE" ) +`MPRnb( WNFACTOREDGE ,WNFACTOR ,"m" ,"Width dependence of NFACTOREDGE" ) +`MPRnb( PNFACTOREDGE ,PNFACTOR ,"m^2" ,"Area dependence of NFACTOREDGE" ) +`MPRnb( CITEDGE ,CIT ,"F/m^2" ,"CIT for Edge FET" ) +`MPRnb( LCITEDGE ,LCIT ,"F/m" ,"Length dependence of CITEDGE" ) +`MPRnb( WCITEDGE ,WCIT ,"F/m" ,"Width dependence of CITEDGE" ) +`MPRnb( PCITEDGE ,PCIT ,"F" ,"Area dependence of CITEDGE" ) +`MPRnb( CDSCDEDGE ,CDSCD ,"F/m^2/V" ,"CDSCD for edge FET" ) +`MPRnb( LCDSCDEDGE ,LCDSCD ,"F/m/V" ,"Length dependence of CDSCDEDGE" ) +`MPRnb( WCDSCDEDGE ,WCDSCD ,"F/m/V" ,"Width dependence of CDSCDEDGE" ) +`MPRnb( PCDSCDEDGE ,PCDSCD ,"F/V" ,"Area dependence of CDSCDEDGE" ) +`MPRnb( CDSCBEDGE ,CDSCB ,"F/m^2/V" ,"CDSCB for edge FET" ) +`MPRnb( LCDSCBEDGE ,LCDSCB ,"F/m/V" ,"Length dependence of CDSCBEDGE" ) +`MPRnb( WCDSCBEDGE ,WCDSCB ,"F/m/V" ,"Width dependence of CDSCBEDGE" ) +`MPRnb( PCDSCBEDGE ,PCDSCB ,"F/V" ,"Area dependence of CDSCBEDGE" ) +`MPRnb( ETA0EDGE ,ETA0 ,"" ,"DIBL parameter for edge FET" ) +`MPRnb( LETA0EDGE ,LETA0 ,"m" ,"Length dependence of ETA0EDGE" ) +`MPRnb( WETA0EDGE ,WETA0 ,"m" ,"Width dependence of ETA0EDGE" ) +`MPRnb( PETA0EDGE ,PETA0 ,"m^2" ,"Area dependence of ETA0EDGE" ) +`MPRnb( ETABEDGE ,ETAB ,"1/V" ,"ETAB for edge FET" ) +`MPRnb( LETABEDGE ,LETAB ,"m/V" ,"Length dependence of ETABEDGE" ) +`MPRnb( WETABEDGE ,WETAB ,"m/V" ,"Width dependence of ETABEDGE" ) +`MPRnb( PETABEDGE ,PETAB ,"m^2/V" ,"Area dependence of ETABEDGE" ) +`MPRnb( KT1EDGE ,KT1 ,"V" ,"Temperature dependence parameter of threshold voltage for edge FET" ) +`MPRnb( LKT1EDGE ,LKT1 ,"V*m" ,"Length dependence of KT1EDGE" ) +`MPRnb( WKT1EDGE ,WKT1 ,"V*m" ,"Width dependence of KT1EDGE" ) +`MPRnb( PKT1EDGE ,PKT1 ,"V*m^2" ,"Area dependence of KT1EDGE" ) +`MPRnb( KT1LEDGE ,KT1L ,"V*m" ,"Temperature dependence parameter of threshold voltage for edge FET" ) +`MPRnb( LKT1LEDGE ,0.0 ,"V*m^2" ,"Length dependence of KT1LEDGE" ) +`MPRnb( WKT1LEDGE ,0.0 ,"V*m^2" ,"Width dependence of KT1LEDGE" ) +`MPRnb( PKT1LEDGE ,0.0 ,"V*m^3" ,"Area dependence of KT1LEDGE" ) +`MPRnb( KT2EDGE ,KT2 ,"" ,"Temperature dependence parameter of threshold voltage for edge FET" ) +`MPRnb( LKT2EDGE ,LKT2 ,"m" ,"Length dependence of KT2EDGE" ) +`MPRnb( WKT2EDGE ,WKT2 ,"m" ,"Width dependence of KT2EDGE" ) +`MPRnb( PKT2EDGE ,PKT2 ,"m^2" ,"Area dependence of KT2EDGE" ) +`MPRnb( KT1EXPEDGE ,KT1EXP ,"" ,"Temperature dependence parameter of threshold voltage for edge device" ) +`MPRnb( LKT1EXPEDGE ,0.0 ,"m" ,"Length dependence of KT1EXPEDGE" ) +`MPRnb( WKT1EXPEDGE ,0.0 ,"m" ,"Width dependence of KT1EXPEDGE" ) +`MPRnb( PKT1EXPEDGE ,0.0 ,"m^2" ,"Area dependence of KT1EXPEDGE" ) +`MPRnb( TNFACTOREDGE ,TNFACTOR ,"" ,"Temperature dependence parameter of sub-threshold slope factor for edge" ) +`MPRnb( LTNFACTOREDGE ,0.0 ,"m" ,"Length dependence of TNFACTOREDGE" ) +`MPRnb( WTNFACTOREDGE ,0.0 ,"m" ,"Width dependence of TNFACTOREDGE" ) +`MPRnb( PTNFACTOREDGE ,0.0 ,"m^2" ,"Area dependence of TNFACTOREDGE" ) +`MPRnb( TETA0EDGE ,TETA0 ,"" ,"Temperature dependence parameter of DIBL parameter for edge FET" ) +`MPRnb( LTETA0EDGE ,0.0 ,"m" ,"Length dependence of TETA0EDGE" ) +`MPRnb( WTETA0EDGE ,0.0 ,"m" ,"Width dependence of TETA0EDGE" ) +`MPRnb( PTETA0EDGE ,0.0 ,"m^2" ,"Area dependence of TETA0EDGE" ) +`MPRnb( DVT0EDGE ,2.2 ,"" ,"First coefficient of SCE effect on Vth for Edge FET" ) +`MPRnb( DVT1EDGE ,0.53 ,"" ,"Second coefficient of SCE effect on Vth for Edge FET" ) +`MPRnb( DVT2EDGE ,0.0 ,"1/V" ,"Body-bias coefficient for SCE effect for Edge FET" ) +`MPRnb( K2EDGE ,K2 ,"V" ,"Vth shift due to Vertical Non-uniform doping" ) +`MPRnb( LK2EDGE ,LK2 ,"m" ,"Length dependence of K2EDGE" ) +`MPRnb( WK2EDGE ,WK2 ,"m" ,"Width dependence of K2EDGE" ) +`MPRnb( PK2EDGE ,PK2 ,"m^2" ,"Area dependence of K2EDGE" ) +`MPRnb( KVTH0EDGE ,KVTH0 ,"V*m" ,"Threshold Shift parameter for stress effect" ) +`MPRnb( LKVTH0EDGE ,LKVTH0 ,"m^LLODKU0" ,"Length dependence of KVTH0EDGE" ) +`MPRnb( WKVTH0EDGE ,WKVTH0 ,"m^WLODKU0" ,"Width dependence of KVTH0EDGE" ) +`MPRnb( PKVTH0EDGE ,PKVTH0 ,"m^(LLODKU0+WLODKU0)" ,"Area dependence of KVTH0EDGE" ) +`MPRnb( STK2EDGE ,STK2 ,"m" ,"K2 shift factor related to Vth change" ) +`MPRnb( LSTK2EDGE ,0.0 ,"m^2" ,"Length dependence of STK2EDGE" ) +`MPRnb( WSTK2EDGE ,0.0 ,"m^2" ,"Width dependence of STK2EDGE" ) +`MPRnb( PSTK2EDGE ,0.0 ,"m^3" ,"Area dependence of STK2EDGE" ) +`MPRnb( STETA0EDGE ,STETA0 ,"m" ,"ETA0 shift related to Vth0 change" ) +`MPRnb( LSTETA0EDGE ,0.0 ,"m^2" ,"Length dependence of STETA0EDGE" ) +`MPRnb( WSTETA0EDGE ,0.0 ,"m^2" ,"Width dependence of STETA0EDGE" ) +`MPRnb( PSTETA0EDGE ,0.0 ,"m^3" ,"Area dependence of STETA0EDGE" ) +`MPIcc( IGCLAMP ,1 ,"" ,0 ,1 ,"Model flag" ) +`MPRoz( LP ,10u ,"m" ,"Length scaling parameter for thermal noise" ) +`MPRnb( RNOIK ,0.0 ,"" ,"Exponential coefficient for enhanced correlated thermal noise" ) +`MPRoo( TNOIK ,0.0 ,"1/m" ,-inf ,inf ,"Empirical parameter for Leff trend of Sid at low Ids" ) +`MPRcz( TNOIK2 ,0.1 ,"1/m" ,"Empirical parameter for sensitivity of RNOIK" ) +`MPRnb( K0 ,0.0 ,"" ,"Non-saturation effect parameter for strong inversion region" ) +`MPRnb( LK0 ,0.0 ,"m" ,"Length dependence of " ) +`MPRnb( WK0 ,0.0 ,"m" ,"Width dependence of " ) +`MPRnb( PK0 ,0.0 ,"m^2" ,"Area dependence of " ) +`MPRnb( K01 ,0.0 ,"1/K" ,"Temperature coefficient for K0" ) +`MPRnb( LK01 ,0.0 ,"m/K" ,"Length dependence of K0" ) +`MPRnb( WK01 ,0.0 ,"m/K" ,"Width dependence of K0" ) +`MPRnb( PK01 ,0.0 ,"m^2/K" ,"Area dependence of K0" ) +`MPRnb( M0 ,1.0 ,"" ,"offset of non-saturation effect parameter for strong inversion region" ) +`MPRnb( LM0 ,0.0 ,"m" ,"Length dependence of " ) +`MPRnb( WM0 ,0.0 ,"m" ,"Width dependence of " ) +`MPRnb( PM0 ,0.0 ,"m^2" ,"Area dependence of " ) +`MPRnb( M01 ,0.0 ,"1/K" ,"Temperature coefficient for M0" ) +`MPRnb( LM01 ,0.0 ,"m/K" ,"Length dependence of M0" ) +`MPRnb( WM01 ,0.0 ,"m/K" ,"Width dependence of M0" ) +`MPRnb( PM01 ,0.0 ,"m^2/K" ,"Area dependence of M0" ) +`MPIcc( FNOIMOD ,0 ,"" ,0 ,1 ,"Flicker noise model selector" ) +`MPRoo( LH ,30n ,"m" ,0 ,L ,"Length of Halo transistor" ) +`MPRnb( NOIA2 ,NOIA ,"s^(1-EF)/(eV)^1/m^3" ,"Flicker noise parameter A for Halo" ) +`MPRoz( HNDEP ,NDEP ,"1/m^3" ,"Halo Doping Concentration for IV" ) + +// Common variables +real PSiso, PDiso, PSsha, PDsha, PSmer, PDmer, ASiso, ADiso, ASsha, ADsha, ASmer, ADmer; +real T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12; +real T0y, T1y, T2y, T3y; +real Tb; +real epssi, epsox, ni, Weff, Leff, Weff1, Leff1, Wact, Lact, Weffcj, Eg, Eg0, Weff_SH; +real dLIV, dWIV, dLB, dWB, dLCV, dWCV, dWJ, Cox, epsratio; +real Vdb_noswap, Vsb_noswap, Vgs_noswap, Vgd_noswap, Vds_noswap; +real sigvds, vfb, vgfb, vgfbCV, Vbsx, Vfbsdr; +real Vg, vg, Vd, Vs, vs, Vds, Vdsx, Vgs_eff, Vgd_eff; +real Vth_shift; +real qia, qba, qiaCV, qbaCV, qbs, qbd, qb, dps, phib, phib_n; +real nq, psip, psiavg, psipclamp, sqrtpsisa, sqrtpsisainv, sqrtpsip; +real Cdep, Lnew, L_mult, Wnew, W_mult; +real wf, wr; + +// Short channel effects +real n, Fp, nVt, inv_nVt, Vt, inv_Vt; +real PhistVbs, sqrtPhistVbs, Xdep, cdsc; +real T1DEP; +real dVth_ldop, DVTP0_i, DVTP1_i, DVTP2_i, DVTP3_i, DVTP4_i, DVTP5_i; +real dVth_VNUD, dVth_dibl, dvth_temp; +real gam, inv_gam, Phist, sqrtPhist, litl; + +// Drain saturation voltage +real qis, qdsat, Eeffs, Dmobs, Esat, EsatL, Vdsat, LambdaC_by2, LambdaC; +real Vdseff, Vdssat, VdssatCV, vdeff, vdsat, qdeff, vdsatcv, VdsatCV; +real ln_T1_T2; +real A1_i, A11_i, A1_t, A2_i, A21_i, A2_t, Nsat; + +// Mobility degradation +real EeffFactor, Eeffm, ueff, eta_mu, Dmob, Dtot; + +// Velocity saturation +real zsat, Dvsat, Dptwg, PSAT_i, PSATR_i, PSAT_a; + +// Output conductance +real diffVds, VaDITS, VaSCBE, Vasat; +real DIBLfactor, PVAGfactor, VaDIBL, Vgst2Vtm, Moc, MdL, Mscbe; + +// Impact ionization and GIDL +real Iii, igidl, igisl; + +// I-V variables +integer devsign; +real ids; + +// C-V variables +real Qb, Qs, Qd1, Qd2, Qd, Qi, QBi, QSi, QDi, QGi, WLCOXVtinv; +real qs, qbeff, dqgeff; +real DPD, vgfbPD, gammaPD, gamg2; +real MdL_2, inv_MdL, inv_MdL_2, MdL_less_1; +real sis, sid, vgpqm, Temps, Tempd, DQSD, DQSD2, invgamg2; +real Vgsov, Vgdov, Qovb, Qovg, Qovs, Qovd, Cgsof, Cgdof; +real XDCinv, Coxeffinv, BSIMBULKTOXP; +real Vgd_ov_noswap, Vgs_ov_noswap; + +// S/D series resistance +real WeffWRFactor, DMCGeff, DMDGeff, DMCIeff; +real RSourceGeo, RDrainGeo, Rsource, Rdrain, Rdss, Rdsi, Dr; + +// S/D junction area and perimeter +real temp_ASeff, temp_ADeff, temp_PSeff, temp_PDeff; +real ASeff, ADeff; + +// Gate resistances +real Grgeltd, Gcrg, idsovvds; + +// Body resistance +real Lnl, Lnw, Lnnf, Bodymode, Rbpbx, Rbpby, Rbsbx, Rbsby, Rbdbx, Rbdby; +real Rbdb, Rbsb, Rbpb, Rbps, Rbpd; +real Grbsb, Grbdb, Grbpb, Grbps, Grbpd; + +// Gate current +real Voxm, Voxminv, Voxmacc, Vdseffx; +real Vaux_Igbinv, Vaux_Igbacc, igbinv, igbacc, igb; +real igcs, igcd, igc0, T1_exp; +real igs, igd, igs_mult, igd_mult; +real Aechvb, Bechvb, AechvbEdge, BechvbEdge, ToxRatio, ToxRatioEdge; + +// Junction current and capacitance +real PSeff, PDeff; +real Ibs, Ibd, Vbs_jct, Vbd_jct, arg, sarg; +real Czbs, czbs_p1, czbs_p2, Czbssw, czbssw_p1, czbssw_p2, Czbsswg, czbsswg_p1, czbsswg_p2; +real Czbd, czbd_p1, czbd_p2, Czbdsw, czbdsw_p1, czbdsw_p2, Czbdswg, czbdswg_p1, czbdswg_p2; +real Qbsj, Qbsj1, Qbsj2, Qbsj3; +real Qbdj, Qbdj1, Qbdj2, Qbdj3; +real Isbs, Isbd, Nvtms, Nvtmd; +real SslpRev, IVjsmRev, VjsmRev, SslpFwd, IVjsmFwd, VjsmFwd, XExpBVS; +real DslpRev, IVjdmRev, VjdmRev, DslpFwd, IVjdmFwd, VjdmFwd, XExpBVD; + +// Flicker noise +real LINTNOI_i; +real Esatnoi, Leffnoi, Leffnoisq, DelClm; +real N0, Nl, Nstar, Ssi, Swi, FNPowerAt1Hz; + +// Thermal noise +real gspr, gdpr; +real Gtnoi, sidn, Nt; +real mig, migid, mid, Lvsat, Vtn; +real cm_igid, sqid, sqig, ctnoi, betanoisq, thetanoisq, betaLowId; + +// Temperature effects +real delTemp1; +real DevTemp, Tnom, Vtm, Vtm0; +real TRatio, delTemp; +real U0_t, U0R_t, UA_t, UAR_t, UC_t, UCR_t, UD_t, UDR_t, UCS_t, UCSR_t, rdstemp, VSAT_t, VSATR_t, VSATCV_t; +real DELTA_t, PTWG_t, PTWGR_t, BETA0_t, BGIDL_t, BGISL_t; +real igtemp; +real ETA0_t, ETA0R_t, NFACTOR_t; + +//Diode temperature effects +real CJS_t, CJSWS_t, CJSWGD_t, CJD_t, CJSWD_t, CJSWGS_t; +real PBS_t, PBSWS_t, PBSWGS_t, PBD_t, PBSWD_t, PBSWGD_t; +real JSS_t, JSWS_t, JSWGS_t, JSD_t, JSWD_t, JSWGD_t; +real JTSS_t, JTSD_t, JTSSWS_t, JTSSWD_t, JTSSWGS_t, JTSSWGD_t; +real NJTS_t, NJTSD_t, NJTSSW_t, NJTSSWD_t, NJTSSWG_t, NJTSSWGD_t; + +// Binning +real PSATB_i; +real KT1_i, KT2_i; +real W_by_NF; +real L_LLN, W_LWN, LW_LLN_LWN, L_LLN1, W_LWN1, LW_LLN_LWN1; +real L_WLN, W_WWN, LW_WLN_WWN, L_WLN1, W_WWN1, LW_WLN_WWN1; +real Inv_L, Inv_W, Inv_WL, Inv_Lact, Inv_Wact, Inv_Llong, Inv_Wwide; +real BIN_L, BIN_W, BIN_WL; +real NGATE_i, NSD_i, NDEP_i, VFB_i; +real CIT_i, CDSCD_i, CDSCDR_i, CDSCD_a, CDSCB_i, NFACTOR_i; +real PHIN_i, ETA0_i, ETA0R_i, ETA0_a, ETAB_i, K2_i, K1_i; +real DELTA_i; +real U0_i, U0R_i, U0_a, VSAT_i, VSATR_i, VSAT_a, VSATCV_i, UA_i, UAR_i, UA_a, EU_i, UD_i, UDR_i, UD_a, UCS_i, UCSR_i, UCS_a, UC_i, UCR_i, UC_a; +real PDIBLC_i, PDIBLCR_i, PDIBLC_a, PDIBLCB_i, PSCBE1_i, PSCBE2_i, PDITS_i, PDITSD_i, FPROUT_i; +real PRWG_i, WR_i, RDWMIN_i, RSWMIN_i, RDW_i, RSW_i, RDSW_i, RDSWMIN_i; +real PTWG_i, PTWGR_i, PTWG_a, PVAG_i, XJ_i; +real PCLM_i, PCLMR_i, PCLM_a, PCLMCV_i, PRWB_i; +real CF_i, CGSL_i, CGDL_i, CKAPPAS_i, CKAPPAD_i; +real VFBCV_i, NDEPCV_i; +real ALPHA0_i, BETA0_i; +real AGIDL_i, BGIDL_i, CGIDL_i, EGIDL_i; +real AGISL_i, BGISL_i, CGISL_i, EGISL_i; +real UTE_i, UA1_i, UC1_i, UD1_i, UCSTE_i, PRT_i, AT_i, PTWGT_i, IIT_i, TGIDL_i; +real KVTH0WE_i, K2WE_i, KU0WE_i; +real AIGBINV_i, BIGBINV_i, CIGBINV_i, EIGBINV_i, NIGBINV_i; +real AIGBACC_i, BIGBACC_i, CIGBACC_i, NIGBACC_i; +real AIGC_i, BIGC_i, CIGC_i; +real AIGS_i, BIGS_i, CIGS_i, AIGD_i, BIGD_i, CIGD_i, POXEDGE_i, PIGCD_i; +real DLCIG_i, DLCIGD_i, NTOX_i; +real IGT_i; +real K0_i, M0_i; +real K01_i, M01_i; +real K0_t, M0_t; +real Mnud; +real NFACTOREDGE_i, CITEDGE_i, CDSCDEDGE_i, CDSCBEDGE_i, ETA0EDGE_i, ETABEDGE_i, KT1EDGE_i, KT1LEDGE_i, KT2EDGE_i, KT1EXPEDGE_i, TNFACTOREDGE_i, TETA0EDGE_i, K2EDGE_i, KVTH0EDGE_i, STK2EDGE_i, STETA0EDGE_i; + +// Stress effect +real W_tmp_stress, tmp1_stress, kstress_u0, tmp1_stress_vth, kstress_vth0, ku0_temp; +real Inv_sa, Inv_sb, Inv_saref, Inv_sbref, Inv_odref, rho_ref, Inv_od,rho; +real mu0_mult, vsat_mult, vth0_stress, k2_stress, eta_stress; +integer i; + +// Well Proximity effect +real vth0_well, k2_well, mu_well, Wdrn, local_sca, local_scb, local_scc; + +// Edge FET Model Variables +real ids_edge, ETA0EDGE_t, NFACTOREDGE_t, Vbi, theta_sce_edge, dvth_dibl, dvth_sce, litl_edge, DGAMMAEDGE_i, vdsatedge, Vdsatedge, Vdssate; +real vth0_stress_EDGE, k2_stress_EDGE, eta_stress_EDGE, K2_EDGE,ETA0_EDGE; + +// The following are used by the macro definitions (GEOMOD and RGEOMOD) +real nuIntD, nuEndD, nuIntS, nuEndS; +real Rint, Rend; + +// Sub-surface punchthrough +real Issl, SSL0_NT, SSL1_NT, PHIB_SSL; + +// VTH variables +real q_vth, psip_th; + +// 1/f Noise model for Halo +real vgfbh, gam_h, phib_h, psiph, qsh, nq_h, U0_i_h, i1, qdh, i2, qsch; +real Np2, beta_ch, beta_h, gds_h, gds_ch, gm_ch, R_ch, R_h, Ssi_ch; +real Swi_ch, FNPowerAt1Hz_ch, FNPowerAt1Hz_h; +real T0a, T0b, T0c, T0d, T0e, Swi_h, t_tot, CF_ch, CF_h, LeffnoiH; + +// Self Heating +real gth, cth; + +real Ggate, Gnoise; + + +// OPERATING POINT VARIABLES +`OPM( QBI, "C", "Intrinsic body charge") +`OPM( QSI, "C", "Intrinsic source charge") +`OPM( QDI, "C", "Intrinsic drain charge") +`OPM( QGI, "C", "Intrinsic gate charge") +`OPM( CGGI, "F", "Intrinsic g-g MOSFET capacitance") +`OPM( CGBI, "F", "Intrinsic g-b MOSFET capacitance") +`OPM( CGSI, "F", "Intrinsic g-s MOSFET capacitance") +`OPM( CGDI, "F", "Intrinsic g-d MOSFET capacitance") +`OPM( CSGI, "F", "Intrinsic s-g MOSFET capacitance") +`OPM( CSBI, "F", "Intrinsic s-b MOSFET capacitance") +`OPM( CSSI, "F", "Intrinsic s-s MOSFET capacitance") +`OPM( CSDI, "F", "Intrinsic s-d MOSFET capacitance") +`OPM( CDGI, "F", "Intrinsic d-g MOSFET capacitance") +`OPM( CDBI, "F", "Intrinsic d-b MOSFET capacitance") +`OPM( CDSI, "F", "Intrinsic d-s MOSFET capacitance") +`OPM( CDDI, "F", "Intrinsic d-d MOSFET capacitance") +`OPM( CBGI, "F", "Intrinsic b-g MOSFET capacitance") +`OPM( CBBI, "F", "Intrinsic b-b MOSFET capacitance") +`OPM( CBSI, "F", "Intrinsic b-s MOSFET capacitance") +`OPM( CBDI, "F", "Intrinsic b-d MOSFET capacitance") +`OPM( QB, "C", "Body charge") +`OPM( QS, "C", "Source charge") +`OPM( QD, "C", "Drain charge") +`OPM( QG, "C", "Gate charge") +`OPM( CGG, "F", "g-g MOSFET capacitance") +`OPM( CGB, "F", "g-b MOSFET capacitance") +`OPM( CGS, "F", "g-s MOSFET capacitance") +`OPM( CGD, "F", "g-d MOSFET capacitance") +`OPM( CSG, "F", "s-g MOSFET capacitance") +`OPM( CSB, "F", "s-b MOSFET capacitance") +`OPM( CSS, "F", "s-s MOSFET capacitance") +`OPM( CSD, "F", "s-d MOSFET capacitance") +`OPM( CDG, "F", "d-g MOSFET capacitance") +`OPM( CDB, "F", "d-b MOSFET capacitance") +`OPM( CDS, "F", "d-s MOSFET capacitance") +`OPM( CDD, "F", "d-d MOSFET capacitance") +`OPM( CBG, "F", "b-g MOSFET capacitance") +`OPM( CBB, "F", "b-b MOSFET capacitance") +`OPM( CBS, "F", "b-s MOSFET capacitance") +`OPM( CBD, "F", "b-d MOSFET capacitance") +`OPM( ISUB, "A", "Substrate current") +`OPM( IGIDL, "A", "") +`OPM( IGISL, "A", "") +`OPM( IGS, "A", "") +`OPM( IGD, "A", "") +`OPM( IGCS, "A", "") +`OPM( IGCD, "A", "") +`OPM( IGB, "A", "") +`OPM( CGSEXT, "F", "") +`OPM( CGDEXT, "F", "") +`OPM( CGBOV, "F", "Front gate charge") +`OPM( CAPBS, "F", "") +`OPM( CAPBD, "F", "") +`OPP( WEFF, "m", "") +`OPP( LEFF, "m", "") +`OPP( WEFFCV, "m", "") +`OPP( LEFFCV, "m", "") +`OPM( IDS, "A", "Drain-source current") +`OPM( IDEFF, "A", "Effective drain current") +`OPM( ISEFF, "A", "Effective source current") +`OPM( IGEFF, "A", "Effective gate current") +`OPM( IBS, "A", "") +`OPM( IBD, "A", "") +`OPP( VDS, "V", "Drain to source voltage") +`OPP( VGS, "V", "Gate to source voltage") +`OPP( VBS, "V", "Body to source voltage") +`OPP( VDSAT, "V", "") +`OPM( GM, "mho", "") +`OPM( GMBS, "mho", "") +`OPM( GDS, "mho", "") +`OPP( T_TOTAL_K, "K", "") +`OPP( T_TOTAL_C, "degC", "") +`OPP( T_DELTA_SH, "K", "") +`OPP( VTH, "V", "Threshold voltage") + +analog begin + // Variable initialization to prevent hidden states + CDSCDR_i = 0.0; ETA0R_i = 0.0; ETA0R_t = 0.0; L_LLN1 = 0.0; + L_WLN1 = 0.0; PCLMR_i = 0.0; PDIBLCR_i = 0.0; PSATR_i = 0.0; + PTWGR_i = 0.0; PTWGR_t = 0.0; U0R_i = 0.0; U0R_t = 0.0; + UAR_i = 0.0; UAR_t = 0.0; UCR_i = 0.0; UCR_t = 0.0; + UCSR_i = 0.0; UCSR_t = 0.0; UDR_i = 0.0; UDR_t = 0.0; + UD_a = 0.0; VSATR_i = 0.0; VSATR_t = 0.0; W_LWN1 = 0.0; + W_WWN1 = 0.0; local_sca = 0.0; local_scb = 0.0; local_scc = 0.0; + Inv_sa = 0.0; Inv_sb = 0.0; vth0_stress_EDGE = 0.0; k2_stress_EDGE = 0.0; + eta_stress = 0.0; K2_EDGE = 0.0; ETA0_EDGE = 0.0; eta_stress_EDGE = 0.0; + local_sca = 0.0; local_scb = 0.0; local_scc = 0.0; K0_i = 0.0; + M0_i = 0.0; K01_i = 0.0; M01_i = 0.0; K0_t = 0.0; + M0_t = 0.0; CITEDGE_i = 0.0; CDSCDEDGE_i = 0.0; CDSCBEDGE_i = 0.0; + ETA0EDGE_i = 0.0; ETABEDGE_i = 0.0; KT1EDGE_i = 0.0; KT1LEDGE_i = 0.0; + KT2EDGE_i = 0.0; KT1EXPEDGE_i = 0.0; TNFACTOREDGE_i = 0.0; TETA0EDGE_i = 0.0; + K2EDGE_i = 0.0; KVTH0EDGE_i = 0.0; STK2EDGE_i = 0.0; STETA0EDGE_i = 0.0; + + // Bias independent calculations + if (TYPE == `ntype) begin + devsign = 1; + end else begin + devsign = -1; + end + + // Constants + epssi = EPSRSUB * `EPS0; + epsox = EPSROX * `EPS0; + Cox = EPSROX * `EPS0 / TOXE; + epsratio = EPSRSUB / EPSROX; + + // Physical Oxide Thickness + if (!$param_given(TOXP)) begin + BSIMBULKTOXP = (TOXE * EPSROX / 3.9) - DTOX; + end else begin + BSIMBULKTOXP = TOXP; + end + L_mult = L * LMLT; + W_mult = W * WMLT; + Lnew = L_mult + XL; + if (Lnew <= 0.0) begin + $strobe("Fatal: Ldrawn * LMLT + XL = %e for BSIMBULK is non-positive", Lnew); + $finish(0); + end + W_by_NF = W_mult / NF; + Wnew = W_by_NF + XW; + if (Wnew <= 0.0) begin + $strobe("Fatal: W / NF * WMLT + XW = %e for BSIMBULK is non-positive", Wnew); + $finish(0); + end + + // Leff and Weff for I-V + L_LLN = pow(Lnew, -LLN); + W_LWN = pow(Wnew, -LWN); + LW_LLN_LWN = L_LLN * W_LWN; + dLIV = LINT + LL * L_LLN + LW * W_LWN + LWL * LW_LLN_LWN; + L_WLN = pow(Lnew, -WLN); + W_WWN = pow(Wnew, -WWN); + LW_WLN_WWN = L_WLN * W_WWN; + dWIV = WINT + WL * L_WLN + WW * W_WWN + WWL * LW_WLN_WWN; + Leff = Lnew - 2.0 * dLIV; + if (Leff <= 0.0) begin + $strobe("Fatal: Effective channel length = %e for BSIMBULK is non-positive", Leff); + $finish(0); + end else if (Leff <= 1.0e-9) begin + $strobe("Warning: Effective channel length = %e for BSIMBULK is <= 1.0e-9. Recommended Leff >= 1e-8", Leff); + end + Weff = Wnew - 2.0 * dWIV; + if (Weff <= 0.0) begin + $strobe("Fatal: Effective channel Width = %e for BSIMBULK is non-positive", Weff); + $finish(0); + end else if (Weff <= 1.0e-9) begin + $strobe("Warning: Effective channel width = %e for BSIMBULK is <= 1.0e-9. Recommended Weff >= 1e-8", Weff); + end + + // Leff and Weff for C-V + dLCV = DLC + LLC * L_LLN + LWC * W_LWN + LWLC * LW_LLN_LWN; + dWCV = DWC + WLC * L_WLN + WWC * W_WWN + WWLC * LW_WLN_WWN; + Lact = Lnew - 2.0 * dLCV; + if (Lact <= 0.0) begin + $strobe("Fatal: Effective channel length for CV = %e for BSIMBULK is non-positive", Lact); + $finish(0); + end else if (Lact <= 1.0e-9) begin + $strobe("Warning: Effective channel length for CV = %e for BSIMBULK is <= 1.0e-9. Recommended Lact >= 1e-8", Lact); + end + Wact = Wnew - 2.0 * dWCV; + if (Wact <= 0.0) begin + $strobe("Fatal: Effective channel width for CV = %e for BSIMBULK is non-positive", Wact); + $finish(0); + end else if (Wact <= 1.0e-9) begin + $strobe("Warning: Effective channel width for CV = %e for BSIMBULK is <= 1.0e-9. Recommended Wact >= 1e-8", Wact); + end + + // Weffcj for Diode, GIDL etc. + dWJ = DWJ + WLC / pow(Lnew, WLN) + WWC / pow(Wnew, WWN) + WWLC / pow(Lnew, WLN) / pow(Wnew, WWN); + Weffcj = Wnew - 2.0 * dWJ; + if (Weffcj <= 0.0) begin + $strobe("Fatal: Effective channel width for S/D junctions = %e for BSIMBULK is non-positive", Weffcj); + $finish(0); + end + Inv_L = 1.0e-6 / Leff; + Inv_W = 1.0e-6 / Weff; + Inv_Lact = 1.0e-6 / Lact; + Inv_Wact = 1.0e-6 / Wact; + Inv_Llong = 1.0e-6 / LLONG; + Inv_Wwide = 1.0e-6 / WWIDE; + Inv_WL = Inv_L * Inv_W; + + // Effective length and width for binning + L_LLN1 = L_LLN; + L_WLN1 = L_WLN; + if (DLBIN != 0.0) begin + if (DLBIN <= -Lnew) begin + $strobe("Fatal: DLBIN for BSIMBULK = %e is <= -Ldrawn * LMLT", DLBIN); + $finish(0); + end else begin + L_LLN1 = pow(Lnew + DLBIN, -LLN); + L_WLN1 = pow(Lnew + DLBIN, -WLN); + end + end + W_LWN1 = W_LWN; + W_WWN1 = W_WWN; + if (DWBIN != 0.0) begin + if (DWBIN <= -Wnew) begin + $strobe("Fatal: DWBIN for BSIMBULK = %e is <= -Wdrawn * WMLT", DWBIN); + $finish(0); + end else begin + W_LWN1 = pow(Wnew + DWBIN, -LWN); + W_WWN1 = pow(Wnew + DWBIN, -WWN); + end + end + LW_LLN_LWN1 = L_LLN1 * W_LWN1; + dLB = LINT + LL * L_LLN1 + LW * W_LWN1 + LWL * LW_LLN_LWN1; + LW_WLN_WWN1 = L_WLN1 * W_WWN1; + dWB = WINT + WL * L_WLN1 + WW * W_WWN1 + WWL * LW_WLN_WWN1; + Leff1 = Lnew - 2.0 * dLB + DLBIN; + if (Leff1 <= 0.0) begin + $strobe("Fatal: Effective channel length for binning = %e for BSIMBULK is non-positive", Leff1); + $finish(0); + end + Weff1 = Wnew - 2.0 * dWB + DWBIN; + if (Weff1 <= 0.0) begin + $strobe("Fatal: Effective channel width for binning = %e for BSIMBULK is non-positive", Weff1); + $finish(0); + end + if (BINUNIT == 1) begin + BIN_L = 1.0e-6 / Leff1; + BIN_W = 1.0e-6 / Weff1; + end else begin + BIN_L = 1.0 / Leff1; + BIN_W = 1.0 / Weff1; + end + BIN_WL = BIN_L * BIN_W; + VFB_i = VFB + BIN_L * LVFB + BIN_W * WVFB + BIN_WL * PVFB; + VFBCV_i = VFBCV + BIN_L * LVFBCV + BIN_W * WVFBCV + BIN_WL * PVFBCV; + NSD_i = NSD + BIN_L * LNSD + BIN_W * WNSD + BIN_WL * PNSD; + NDEP_i = NDEP + BIN_L * LNDEP + BIN_W * WNDEP + BIN_WL * PNDEP; + NDEPCV_i = NDEPCV + BIN_L * LNDEPCV + BIN_W * WNDEPCV + BIN_WL * PNDEPCV; + NGATE_i = NGATE + BIN_L * LNGATE + BIN_W * WNGATE + BIN_WL * PNGATE; + CIT_i = CIT + BIN_L * LCIT + BIN_W * WCIT + BIN_WL * PCIT; + NFACTOR_i = NFACTOR + BIN_L * LNFACTOR + BIN_W * WNFACTOR + BIN_WL * PNFACTOR; + CDSCD_i = CDSCD + BIN_L * LCDSCD + BIN_W * WCDSCD + BIN_WL * PCDSCD; + CDSCB_i = CDSCB + BIN_L * LCDSCB + BIN_W * WCDSCB + BIN_WL * PCDSCB; + DVTP0_i = DVTP0 + BIN_L * LDVTP0 + BIN_W * WDVTP0 + BIN_WL * PDVTP0; + DVTP1_i = DVTP1 + BIN_L * LDVTP1 + BIN_W * WDVTP1 + BIN_WL * PDVTP1; + DVTP2_i = DVTP2 + BIN_L * LDVTP2 + BIN_W * WDVTP2 + BIN_WL * PDVTP2; + DVTP3_i = DVTP3 + BIN_L * LDVTP3 + BIN_W * WDVTP3 + BIN_WL * PDVTP3; + DVTP4_i = DVTP4 + BIN_L * LDVTP4 + BIN_W * WDVTP4 + BIN_WL * PDVTP4; + DVTP5_i = DVTP5 + BIN_L * LDVTP5 + BIN_W * WDVTP5 + BIN_WL * PDVTP5; + K2_i = K2 + BIN_L * LK2 + BIN_W * WK2 + BIN_WL * PK2; + K1_i = K1 + BIN_L * LK1 + BIN_W * WK1 + BIN_WL * PK1; + XJ_i = XJ + BIN_L * LXJ + BIN_W * WXJ + BIN_WL * PXJ; + PHIN_i = PHIN + BIN_L * LPHIN + BIN_W * WPHIN + BIN_WL * PPHIN; + ETA0_i = ETA0 + BIN_L * LETA0 + BIN_W * WETA0 + BIN_WL * PETA0; + ETAB_i = ETAB + BIN_L * LETAB + BIN_W * WETAB + BIN_WL * PETAB; + DELTA_i = DELTA + BIN_L * LDELTA + BIN_W * WDELTA + BIN_WL * PDELTA; + U0_i = U0 + BIN_L * LU0 + BIN_W * WU0 + BIN_WL * PU0; + UA_i = UA + BIN_L * LUA + BIN_W * WUA + BIN_WL * PUA; + UD_i = UD + BIN_L * LUD + BIN_W * WUD + BIN_WL * PUD; + EU_i = EU + BIN_L * LEU + BIN_W * WEU + BIN_WL * PEU; + UCS_i = UCS + BIN_L * LUCS + BIN_W * WUCS + BIN_WL * PUCS; + UC_i = UC + BIN_L * LUC + BIN_W * WUC + BIN_WL * PUC; + PCLM_i = PCLM + BIN_L * LPCLM + BIN_W * WPCLM + BIN_WL * PPCLM; + PCLMCV_i = PCLMCV + BIN_L * LPCLMCV + BIN_W * WPCLMCV + BIN_WL * PPCLMCV; + RSW_i = RSW + BIN_L * LRSW + BIN_W * WRSW + BIN_WL * PRSW; + RDW_i = RDW + BIN_L * LRDW + BIN_W * WRDW + BIN_WL * PRDW; + PRWG_i = PRWG + BIN_L * LPRWG + BIN_W * WPRWG + BIN_WL * PPRWG; + PRWB_i = PRWB + BIN_L * LPRWB + BIN_W * WPRWB + BIN_WL * PPRWB; + WR_i = WR + BIN_L * LWR + BIN_W * WWR + BIN_WL * PWR; + RSWMIN_i = RSWMIN + BIN_L * LRSWMIN + BIN_W * WRSWMIN + BIN_WL * PRSWMIN; + RDWMIN_i = RDWMIN + BIN_L * LRDWMIN + BIN_W * WRDWMIN + BIN_WL * PRDWMIN; + RDSW_i = RDSW + BIN_L * LRDSW + BIN_W * WRDSW + BIN_WL * PRDSW; + RDSWMIN_i = RDSWMIN + BIN_L * LRDSWMIN + BIN_W * WRDSWMIN + BIN_WL * PRDSWMIN; + PTWG_i = PTWG + BIN_L * LPTWG + BIN_W * WPTWG + BIN_WL * PPTWG; + PDIBLC_i = PDIBLC + BIN_L * LPDIBLC + BIN_W * WPDIBLC + BIN_WL * PPDIBLC; + PDIBLCB_i = PDIBLCB + BIN_L * LPDIBLCB + BIN_W * WPDIBLCB + BIN_WL * PPDIBLCB; + PSCBE1_i = PSCBE1 + BIN_L * LPSCBE1 + BIN_W * WPSCBE1 + BIN_WL * PPSCBE1; + PSCBE2_i = PSCBE2 + BIN_L * LPSCBE2 + BIN_W * WPSCBE2 + BIN_WL * PPSCBE2; + PDITS_i = PDITS + BIN_L * LPDITS + BIN_W * WPDITS + BIN_WL * PPDITS; + PDITSD_i = PDITSD + BIN_L * LPDITSD + BIN_W * WPDITSD + BIN_WL * PPDITSD; + FPROUT_i = FPROUT + BIN_L * LFPROUT + BIN_W * WFPROUT + BIN_WL * PFPROUT; + PVAG_i = PVAG + BIN_L * LPVAG + BIN_W * WPVAG + BIN_WL * PPVAG; + VSAT_i = VSAT + BIN_L * LVSAT + BIN_W * WVSAT + BIN_WL * PVSAT; + PSAT_i = PSAT + BIN_L * LPSAT + BIN_W * WPSAT + BIN_WL * PPSAT; + VSATCV_i = VSATCV + BIN_L * LVSATCV + BIN_W * WVSATCV + BIN_WL * PVSATCV; + CF_i = CF + BIN_L * LCF + BIN_W * WCF + BIN_WL * PCF; + CGSL_i = CGSL + BIN_L * LCGSL + BIN_W * WCGSL + BIN_WL * PCGSL; + CGDL_i = CGDL + BIN_L * LCGDL + BIN_W * WCGDL + BIN_WL * PCGDL; + CKAPPAS_i = CKAPPAS + BIN_L * LCKAPPAS + BIN_W * WCKAPPAS + BIN_WL * PCKAPPAS; + CKAPPAD_i = CKAPPAD + BIN_L * LCKAPPAD + BIN_W * WCKAPPAD + BIN_WL * PCKAPPAD; + ALPHA0_i = ALPHA0 + BIN_L * LALPHA0 + BIN_W * WALPHA0 + BIN_WL * PALPHA0; + BETA0_i = BETA0 + BIN_L * LBETA0 + BIN_W * WBETA0 + BIN_WL * PBETA0; + KVTH0WE_i = KVTH0WE + BIN_L * LKVTH0WE + BIN_W * WKVTH0WE + BIN_WL * PKVTH0WE; + K2WE_i = K2WE + BIN_L * LK2WE + BIN_W * WK2WE + BIN_WL * PK2WE; + KU0WE_i = KU0WE + BIN_L * LKU0WE + BIN_W * WKU0WE + BIN_WL * PKU0WE; + AGIDL_i = AGIDL + BIN_L * LAGIDL + BIN_W * WAGIDL + BIN_WL * PAGIDL; + BGIDL_i = BGIDL + BIN_L * LBGIDL + BIN_W * WBGIDL + BIN_WL * PBGIDL; + CGIDL_i = CGIDL + BIN_L * LCGIDL + BIN_W * WCGIDL + BIN_WL * PCGIDL; + EGIDL_i = EGIDL + BIN_L * LEGIDL + BIN_W * WEGIDL + BIN_WL * PEGIDL; + AGISL_i = AGISL + BIN_L * LAGISL + BIN_W * WAGISL + BIN_WL * PAGISL; + BGISL_i = BGISL + BIN_L * LBGISL + BIN_W * WBGISL + BIN_WL * PBGISL; + CGISL_i = CGISL + BIN_L * LCGISL + BIN_W * WCGISL + BIN_WL * PCGISL; + EGISL_i = EGISL + BIN_L * LEGISL + BIN_W * WEGISL + BIN_WL * PEGISL; + UTE_i = UTE + BIN_L * LUTE + BIN_W * WUTE + BIN_WL * PUTE; + UA1_i = UA1 + BIN_L * LUA1 + BIN_W * WUA1 + BIN_WL * PUA1; + UC1_i = UC1 + BIN_L * LUC1 + BIN_W * WUC1 + BIN_WL * PUC1; + UD1_i = UD1 + BIN_L * LUD1 + BIN_W * WUD1 + BIN_WL * PUD1; + UCSTE_i = UCSTE + BIN_L * LUCSTE + BIN_W * WUCSTE + BIN_WL * PUCSTE; + PRT_i = PRT + BIN_L * LPRT + BIN_W * WPRT + BIN_WL * PPRT; + AT_i = AT + BIN_L * LAT + BIN_W * WAT + BIN_WL * PAT; + PTWGT_i = PTWGT + BIN_L * LPTWGT + BIN_W * WPTWGT + BIN_WL * PPTWGT; + IIT_i = IIT + BIN_L * LIIT + BIN_W * WIIT + BIN_WL * PIIT; + TGIDL_i = TGIDL + BIN_L * LTGIDL + BIN_W * WTGIDL + BIN_WL * PTGIDL; + IGT_i = IGT + BIN_L * LIGT + BIN_W * WIGT + BIN_WL * PIGT; + AIGBINV_i = AIGBINV + BIN_L * LAIGBINV + BIN_W * WAIGBINV + BIN_WL * PAIGBINV; + BIGBINV_i = BIGBINV + BIN_L * LBIGBINV + BIN_W * WBIGBINV + BIN_WL * PBIGBINV; + CIGBINV_i = CIGBINV + BIN_L * LCIGBINV + BIN_W * WCIGBINV + BIN_WL * PCIGBINV; + EIGBINV_i = EIGBINV + BIN_L * LEIGBINV + BIN_W * WEIGBINV + BIN_WL * PEIGBINV; + NIGBINV_i = NIGBINV + BIN_L * LNIGBINV + BIN_W * WNIGBINV + BIN_WL * PNIGBINV; + AIGBACC_i = AIGBACC + BIN_L * LAIGBACC + BIN_W * WAIGBACC + BIN_WL * PAIGBACC; + BIGBACC_i = BIGBACC + BIN_L * LBIGBACC + BIN_W * WBIGBACC + BIN_WL * PBIGBACC; + CIGBACC_i = CIGBACC + BIN_L * LCIGBACC + BIN_W * WCIGBACC + BIN_WL * PCIGBACC; + NIGBACC_i = NIGBACC + BIN_L * LNIGBACC + BIN_W * WNIGBACC + BIN_WL * PNIGBACC; + AIGC_i = AIGC + BIN_L * LAIGC + BIN_W * WAIGC + BIN_WL * PAIGC; + BIGC_i = BIGC + BIN_L * LBIGC + BIN_W * WBIGC + BIN_WL * PBIGC; + CIGC_i = CIGC + BIN_L * LCIGC + BIN_W * WCIGC + BIN_WL * PCIGC; + AIGS_i = AIGS + BIN_L * LAIGS + BIN_W * WAIGS + BIN_WL * PAIGS; + BIGS_i = BIGS + BIN_L * LBIGS + BIN_W * WBIGS + BIN_WL * PBIGS; + CIGS_i = CIGS + BIN_L * LCIGS + BIN_W * WCIGS + BIN_WL * PCIGS; + AIGD_i = AIGD + BIN_L * LAIGD + BIN_W * WAIGD + BIN_WL * PAIGD; + BIGD_i = BIGD + BIN_L * LBIGD + BIN_W * WBIGD + BIN_WL * PBIGD; + CIGD_i = CIGD + BIN_L * LCIGD + BIN_W * WCIGD + BIN_WL * PCIGD; + POXEDGE_i = POXEDGE + BIN_L * LPOXEDGE + BIN_W * WPOXEDGE + BIN_WL * PPOXEDGE; + DLCIG_i = DLCIG + BIN_L * LDLCIG + BIN_W * WDLCIG + BIN_WL * PDLCIG; + DLCIGD_i = DLCIGD + BIN_L * LDLCIGD + BIN_W * WDLCIGD + BIN_WL * PDLCIGD; + NTOX_i = NTOX + BIN_L * LNTOX + BIN_W * WNTOX + BIN_WL * PNTOX; + KT1_i = KT1 + BIN_L * LKT1 + BIN_W * WKT1 + BIN_WL * PKT1; + KT2_i = KT2 + BIN_L * LKT2 + BIN_W * WKT2 + BIN_WL * PKT2; + PSATB_i = PSATB + BIN_L * LPSATB + BIN_W * WPSATB + BIN_WL * PPSATB; + A1_i = A1 + BIN_L * LA1 + BIN_W * WA1 + BIN_WL * PA1; + A11_i = A11 + BIN_L * LA11 + BIN_W * WA11 + BIN_WL * PA11; + A2_i = A2 + BIN_L * LA2 + BIN_W * WA2 + BIN_WL * PA2; + A21_i = A21 + BIN_L * LA21 + BIN_W * WA21 + BIN_WL * PA21; + K0_i = K0 + BIN_L * LK0 + BIN_W * WK0 + BIN_WL * PK0; + M0_i = M0 + BIN_L * LM0 + BIN_W * WM0 + BIN_WL * PM0; + K01_i = K01 + BIN_L * LK01 + BIN_W * WK01 + BIN_WL * PK01; + M01_i = M01 + BIN_L * LM01 + BIN_W * WM01 + BIN_WL * PM01; + NFACTOREDGE_i = NFACTOREDGE + BIN_L * LNFACTOREDGE + BIN_W * WNFACTOREDGE + BIN_WL * PNFACTOREDGE; + CITEDGE_i = CITEDGE + BIN_L * LCITEDGE + BIN_W * WCITEDGE + BIN_WL * PCITEDGE; + CDSCDEDGE_i = CDSCDEDGE + BIN_L * LCDSCDEDGE + BIN_W * WCDSCDEDGE + BIN_WL * PCDSCDEDGE; + CDSCBEDGE_i = CDSCBEDGE + BIN_L * LCDSCBEDGE + BIN_W * WCDSCBEDGE + BIN_WL * PCDSCBEDGE; + ETA0EDGE_i = ETA0EDGE + BIN_L * LETA0EDGE + BIN_W * WETA0EDGE + BIN_WL * PETA0EDGE; + ETABEDGE_i = ETABEDGE + BIN_L * LETABEDGE + BIN_W * WETABEDGE + BIN_WL * PETABEDGE; + KT1EDGE_i = KT1EDGE + BIN_L * LKT1EDGE + BIN_W * WKT1EDGE + BIN_WL * PKT1EDGE; + KT1LEDGE_i = KT1LEDGE + BIN_L * LKT1LEDGE + BIN_W * WKT1LEDGE + BIN_WL * PKT1LEDGE; + KT2EDGE_i = KT2EDGE + BIN_L * LKT2EDGE + BIN_W * WKT2EDGE + BIN_WL * PKT2EDGE; + KT1EXPEDGE_i = KT1EXPEDGE + BIN_L * LKT1EXPEDGE + BIN_W * WKT1EXPEDGE + BIN_WL * PKT1EXPEDGE; + TNFACTOREDGE_i = TNFACTOREDGE + BIN_L * LTNFACTOREDGE + BIN_W * WTNFACTOREDGE + BIN_WL * PTNFACTOREDGE; + TETA0EDGE_i = TETA0EDGE + BIN_L * LTETA0EDGE + BIN_W * WTETA0EDGE + BIN_WL * PTETA0EDGE; + K2EDGE_i = K2EDGE + BIN_L * LK2EDGE + BIN_W * WK2EDGE + BIN_WL * PK2EDGE; + KVTH0EDGE_i = KVTH0EDGE + BIN_L * LKVTH0EDGE + BIN_W * WKVTH0EDGE + BIN_WL * PKVTH0EDGE; + STK2EDGE_i = STK2EDGE + BIN_L * LSTK2EDGE + BIN_W * WSTK2EDGE + BIN_WL * PSTK2EDGE; + STETA0EDGE_i = STETA0EDGE + BIN_L * LSTETA0EDGE + BIN_W * WSTETA0EDGE + BIN_WL * PSTETA0EDGE; + + if (ASYMMOD != 0) begin + CDSCDR_i = CDSCDR + BIN_L * LCDSCDR + BIN_W * WCDSCDR + BIN_WL * PCDSCDR; + ETA0R_i = ETA0R + BIN_L * LETA0R + BIN_W * WETA0R + BIN_WL * PETA0R; + U0R_i = U0R + BIN_L * LU0R + BIN_W * WU0R + BIN_WL * PU0R; + UAR_i = UAR + BIN_L * LUAR + BIN_W * WUAR + BIN_WL * PUAR; + UDR_i = UDR + BIN_L * LUDR + BIN_W * WUDR + BIN_WL * PUDR; + UCSR_i = UCSR + BIN_L * LUCSR + BIN_W * WUCSR + BIN_WL * PUCSR; + UCR_i = UCR + BIN_L * LUCR + BIN_W * WUCR + BIN_WL * PUCR; + PCLMR_i = PCLMR + BIN_L * LPCLMR + BIN_W * WPCLMR + BIN_WL * PPCLMR; + PDIBLCR_i = PDIBLCR + BIN_L * LPDIBLCR + BIN_W * WPDIBLCR + BIN_WL * PPDIBLCR; + VSATR_i = VSATR + BIN_L * LVSATR + BIN_W * WVSATR + BIN_WL * PVSATR; + PSATR_i = PSATR + BIN_L * LPSATR + BIN_W * WPSATR + BIN_WL * PPSATR; + PTWGR_i = PTWGR + BIN_L * LPTWGR + BIN_W * WPTWGR + BIN_WL * PPTWGR; + end + + // Geometrical scaling + T0y = NDEPL1 * max(pow(Inv_L, NDEPLEXP1) - pow(Inv_Llong, NDEPLEXP1), 0.0) + NDEPL2 * max(pow(Inv_L, NDEPLEXP2) - pow(Inv_Llong, NDEPLEXP2), 0.0); + T1y = NDEPW * max(pow(Inv_W, NDEPWEXP) - pow(Inv_Wwide, NDEPWEXP), 0.0) + NDEPWL * pow(Inv_W * Inv_L, NDEPWLEXP); + NDEP_i = NDEP_i * (1.0 + T0y + T1y); + T0y = NFACTORL * max( pow(Inv_L, NFACTORLEXP) - pow(Inv_Llong, NFACTORLEXP), 0.0); + T1y = NFACTORW * max( pow(Inv_W, NFACTORWEXP) - pow(Inv_Wwide, NFACTORWEXP), 0.0) + NFACTORWL * pow(Inv_WL, NFACTORWLEXP); + NFACTOR_i = NFACTOR_i * (1.0 + T0y + T1y); + T0y = (1.0 + CDSCDL * max(pow(Inv_L, CDSCDLEXP) - pow(Inv_Llong, CDSCDLEXP), 0.0)); + CDSCD_i = CDSCD_i * T0y; + if (ASYMMOD != 0) begin + CDSCDR_i = CDSCDR_i * T0y; + end + CDSCB_i = CDSCB_i * (1.0 + CDSCBL * max(pow(Inv_L, CDSCBLEXP) - pow(Inv_Llong, CDSCBLEXP), 0.0)); + U0_i = MULU0 * U0_i; + if (MOBSCALE != 1) begin + if (U0LEXP > 0.0) begin + U0_i = U0_i * (1.0 - U0L * max(pow(Inv_L, U0LEXP) - pow(Inv_Llong, U0LEXP), 0.0)); + if (ASYMMOD != 0) begin + U0R_i = U0R_i * (1.0 - U0L * max(pow(Inv_L, U0LEXP) - pow(Inv_Llong, U0LEXP), 0.0)); + end + end else begin + U0_i = U0_i * (1.0 - U0L); + if (ASYMMOD != 0) begin + U0R_i = U0R_i * (1.0 - U0L); + end + end + end else begin + U0_i = U0_i * (1.0 - (UP1 * lexp(-Leff / LP1)) - (UP2 * lexp(-Leff / LP2))); + if (ASYMMOD != 0) begin + U0R_i = U0R_i * (1.0 - (UP1 * lexp(-Leff / LP1)) - (UP2 * lexp(-Leff / LP2))); + end + end + T0y = UAL * max(pow(Inv_L, UALEXP) - pow(Inv_Llong, UALEXP), 0.0); + T1y = UAW * max(pow(Inv_W, UAWEXP) - pow(Inv_Wwide, UAWEXP), 0.0) + UAWL * pow(Inv_WL, UAWLEXP); + UA_i = UA_i * (1.0 + T0y + T1y); + if (ASYMMOD != 0) begin + UAR_i = UAR_i * (1.0 + T0y + T1y); + end + T0y = EUL * max(pow(Inv_L, EULEXP) - pow(Inv_Llong, EULEXP), 0.0); + T1y = EUW * max(pow(Inv_W, EUWEXP) - pow(Inv_Wwide, EUWEXP), 0.0) + EUWL * pow(Inv_WL, EUWLEXP); + EU_i = EU_i * (1.0 + T0y + T1y); + T0y = 1.0 + UDL * max(pow(Inv_L, UDLEXP) - pow(Inv_Llong, UDLEXP), 0.0); + UD_i = UD_i * T0y; + if (ASYMMOD != 0) begin + UDR_i = UDR_i * T0y; + end + T0y = UCL * max(pow(Inv_L, UCLEXP) - pow(Inv_Llong, UCLEXP), 0.0); + T1y = UCW * max(pow(Inv_W, UCWEXP) - pow(Inv_Wwide, UCWEXP), 0.0) + UCWL * pow(Inv_WL, UCWLEXP); + UC_i = UC_i * (1.0 + T0y + T1y); + if (ASYMMOD != 0) begin + UCR_i = UCR_i * (1.0 + T0y + T1y); + end + T0y = max(pow(Inv_L, DSUB) - pow(Inv_Llong, DSUB), 0.0); + ETA0_i = ETA0_i * T0y; + if (ASYMMOD != 0) begin + ETA0R_i = ETA0R_i * T0y; + end + ETAB_i = ETAB_i * max(pow(Inv_L, ETABEXP) - pow(Inv_Llong, ETABEXP), 0.0); + T0y = 1.0 + PDIBLCL * max(pow(Inv_L, PDIBLCLEXP) - pow(Inv_Llong, PDIBLCLEXP), 0.0); + PDIBLC_i = PDIBLC_i * T0y; + if (ASYMMOD != 0) begin + PDIBLCR_i = PDIBLCR_i * T0y; + end + T0y = DELTA_i * (1.0 + DELTAL * max(pow(Inv_L, DELTALEXP) - pow(Inv_Llong, DELTALEXP), 0.0)); + DELTA_i = min(T0y, 0.5); + FPROUT_i = FPROUT_i * (1.0 + FPROUTL * max(pow(Inv_L, FPROUTLEXP) - pow(Inv_Llong, FPROUTLEXP), 0.0)); + T0y = (1.0 + PCLML * max(pow(Inv_L, PCLMLEXP) - pow(Inv_Llong, PCLMLEXP), 0.0)); + PCLM_i = PCLM_i * T0y; + PCLM_i = max(PCLM_i, 0.0); + if (ASYMMOD != 0) begin + PCLMR_i = PCLMR_i * T0y; + PCLMR_i = max(PCLMR_i, 0.0); + end + T0y = VSATL * max(pow(Inv_L, VSATLEXP) - pow(Inv_Llong, VSATLEXP), 0.0); + T1y = VSATW * max(pow(Inv_W, VSATWEXP) - pow(Inv_Wwide, VSATWEXP), 0.0) + VSATWL * pow(Inv_WL, VSATWLEXP); + VSAT_i = VSAT_i * (1.0 + T0y + T1y); + if (ASYMMOD != 0) begin + VSATR_i = VSATR_i * (1.0 + T0y + T1y); + end + PSAT_i = max(PSAT_i * (1.0 + PSATL * max(pow(Inv_L, PSATLEXP) - pow(Inv_Llong, PSATLEXP), 0.0)), 0.25); + if (ASYMMOD != 0) begin + PSATR_i = max(PSATR_i * (1.0 + PSATL * max(pow(Inv_L, PSATLEXP) - pow(Inv_Llong, PSATLEXP), 0.0)), 0.25); + end + T0y = (1.0 + PTWGL * max(pow(Inv_L, PTWGLEXP) - pow(Inv_Llong, PTWGLEXP), 0.0)); + PTWG_i = PTWG_i * T0y; + if (ASYMMOD != 0) begin + PTWGR_i = PTWGR_i * T0y; + end + ALPHA0_i = ALPHA0_i * (1.0 + ALPHA0L * max(pow(Inv_L, ALPHA0LEXP) - pow(Inv_Llong, ALPHA0LEXP), 0.0)); + AGIDL_i = AGIDL_i * (1.0 + AGIDLL * Inv_L + AGIDLW * Inv_W); + AGISL_i = AGISL_i * (1.0 + AGISLL * Inv_L + AGISLW * Inv_W); + AIGC_i = AIGC_i * (1.0 + AIGCL * Inv_L + AIGCW * Inv_W); + AIGS_i = AIGS_i * (1.0 + AIGSL * Inv_L + AIGSW * Inv_W); + AIGD_i = AIGD_i * (1.0 + AIGDL * Inv_L + AIGDW * Inv_W); + PIGCD_i = PIGCD * (1.0 + PIGCDL * Inv_L); + T0y = NDEPCVL1 * max(pow(Inv_Lact, NDEPCVLEXP1) - pow(Inv_Llong, NDEPCVLEXP1), 0.0) + NDEPCVL2 * max( pow(Inv_Lact, NDEPCVLEXP2) - pow(Inv_Llong, NDEPCVLEXP2), 0.0); + T1y = NDEPCVW * max(pow(Inv_Wact, NDEPCVWEXP) - pow(Inv_Wwide, NDEPCVWEXP), 0.0) + NDEPCVWL * pow(Inv_Wact * Inv_Lact, NDEPCVWLEXP); + NDEPCV_i = NDEPCV_i * (1.0 + T0y + T1y); + T0y = VFBCVL * max(pow(Inv_Lact, VFBCVLEXP) - pow(Inv_Llong, VFBCVLEXP), 0.0); + T1y = VFBCVW * max(pow(Inv_Wact, VFBCVWEXP) - pow(Inv_Wwide, VFBCVWEXP), 0.0) + VFBCVWL * pow(Inv_WL, VFBCVWLEXP); + VFBCV_i = VFBCV_i * (1.0 + T0y + T1y); + T0y = VSATCVL * max(pow(Inv_Lact, VSATCVLEXP) - pow(Inv_Llong, VSATCVLEXP), 0.0); + T1y = VSATCVW * max(pow(Inv_W, VSATCVWEXP) - pow(Inv_Wwide, VSATCVWEXP), 0.0) + VSATCVWL * pow(Inv_WL, VSATCVWLEXP); + VSATCV_i = VSATCV_i * (1.0 + T0y + T1y); + PCLMCV_i = PCLMCV_i * (1.0 + PCLMCVL * max(pow(Inv_Lact, PCLMCVLEXP) - pow(Inv_Llong, PCLMCVLEXP), 0.0)); + PCLMCV_i = max(PCLMCV_i, 0.0); + T0y = K1L * max(pow(Inv_L, K1LEXP) - pow(Inv_Llong, K1LEXP), 0.0); + T1y = K1W * max(pow(Inv_W, K1WEXP) - pow(Inv_Wwide, K1WEXP), 0.0) + K1WL * pow(Inv_WL, K1WLEXP); + K1_i = K1_i * (1.0 + T0y + T1y); + T0y = K2L * max(pow(Inv_L, K2LEXP) - pow(Inv_Llong, K2LEXP), 0.0); + T1y = K2W * max(pow(Inv_W, K2WEXP) - pow(Inv_Wwide, K2WEXP), 0.0) + K2WL * pow(Inv_WL, K2WLEXP); + K2_i = K2_i * (1.0 + T0y + T1y); + PRWB_i = PRWB_i * (1.0 + PRWBL * max( pow(Inv_L, PRWBLEXP) - pow(Inv_Llong, PRWBLEXP), 0)); + + // Global scaling parameters for temperature + UTE_i = UTE_i * (1.0 + Inv_L * UTEL); + UA1_i = UA1_i * (1.0 + Inv_L * UA1L); + UD1_i = UD1_i * (1.0 + Inv_L * UD1L); + AT_i = AT_i * (1.0 + Inv_L * ATL); + PTWGT_i = PTWGT_i * (1.0 + Inv_L * PTWGTL); + if ($port_connected(t) == 0) begin + if (SHMOD == 0 || RTH0 == 0.0) begin + Temp(t) <+ 0.0; + end else begin + $strobe("5 terminal Module, while 't' node is not connected, SH is activated."); + end + end + if (RDSMOD == 1) begin + RSW_i = RSW_i * (1.0 + RSWL * max(pow(Inv_L, RSWLEXP) - pow(Inv_Llong, RSWLEXP), 0.0)); + RDW_i = RDW_i * (1.0 + RDWL * max(pow(Inv_L, RDWLEXP) - pow(Inv_Llong, RDWLEXP), 0.0)); + end else begin + RDSW_i = RDSW_i * (1.0 + RDSWL * max(pow(Inv_L, RDSWLEXP) - pow(Inv_Llong, RDSWLEXP), 0.0)); + end + + // Parameter checking + if (UCS_i < 1.0) begin + UCS_i = 1.0; + end else if (UCS_i > 2.0) begin + UCS_i = 2.0; + end + if (ASYMMOD != 0) begin + if (UCSR_i < 1.0) begin + UCSR_i = 1.0; + end else if (UCSR_i > 2.0) begin + UCSR_i = 2.0; + end + end + if (CGIDL_i < 0.0) begin + $strobe("Fatal: CGIDL_i = %e is negative.", CGIDL_i); + $finish(0); + end + if (CGISL_i < 0.0) begin + $strobe("Fatal: CGISL_i = %e is negative.", CGISL_i); + $finish(0); + end + if (CKAPPAD_i <= 0.0) begin + $strobe("Fatal: CKAPPAD_i = %e is non-positive.", CKAPPAD_i); + $finish(0); + end + if (CKAPPAS_i <= 0.0) begin + $strobe("Fatal: CKAPPAS_i = %e is non-positive.", CKAPPAS_i); + $finish(0); + end + if (PDITS_i < 0.0) begin + $strobe("Fatal: PDITS_i = %e is negative.", PDITS_i); + $finish(0); + end + if (CIT_i < 0.0) begin + $strobe("Fatal: CIT_i = %e is negative.", CIT_i); + $finish(0); + end + if (NFACTOR_i < 0.0) begin + $strobe("Fatal: NFACTOR_i = %e is negative.", NFACTOR_i); + $finish(0); + end + if (K1_i < 0.0) begin + $strobe("Fatal: K1_i = %e is negative.", K1_i); + $finish(0); + end + + if (NSD_i <= 0.0) begin + $strobe("Fatal: NSD_i = %e is non-positive.", NSD_i); + $finish(0); + end + if (NDEP_i <= 0.0) begin + $strobe("Fatal: NDEP_i = %e is non-positive.", NDEP_i); + $finish(0); + end + if (NDEPCV_i <= 0.0) begin + $strobe("Fatal: NDEPCV_i = %e is non-positive.", NDEPCV_i); + $finish(0); + end + if (IGBMOD != 0) begin + if (NIGBINV_i <= 0.0) begin + $strobe("Fatal: NIGBINV_i = %e is non-positive.", NIGBINV_i); + $finish(0); + end + if (NIGBACC_i <= 0.0) begin + $strobe("Fatal: NIGBACC_i = %e is non-positive.", NIGBACC_i); + $finish(0); + end + end + if (IGCMOD != 0) begin + if (POXEDGE_i <= 0.0) begin + $strobe("Fatal: POXEDGE_i = %e is non-positive.", POXEDGE_i); + $finish(0); + end + end + if (CDSCD_i < 0.0) begin + $strobe("Fatal: CDSCD_i = %e is negative.", CDSCD_i); + $finish(0); + end + if (ASYMMOD != 0) begin + if (CDSCDR_i < 0.0) begin + $strobe("Fatal: CDSCDR_i = %e is negative.", CDSCDR_i); + $finish(0); + end + end + if (DLCIG_i < 0.0) begin + $strobe("Warning: DLCIG = %e is negative, setting it to 0.", DLCIG_i); + DLCIG_i = 0.0; + end + if (DLCIGD_i < 0.0) begin + $strobe("Warning: DLCIGD = %e is negative, setting it to 0.", DLCIGD_i); + DLCIGD_i = 0.0; + end + if (M0_i < 0.0) begin + $strobe("Warning: M0_i = %e is negative, setting it to 0.", M0_i); + M0_i = 0.0; + end + + // Initialize variables used in geometry macros + nuEndD = 0.0; nuEndS = 0.0; nuIntD = 0.0; nuIntS = 0.0; Rend = 0.0; Rint = 0.0; + + // Process drain series resistance + DMCGeff = DMCG - DMCGT; + DMCIeff = DMCI; + DMDGeff = DMDG - DMCGT; + + // Processing S/D resistance and conductance below + if($param_given(NRS)) begin + RSourceGeo = RSH * NRS; + end else if (RGEOMOD > 0 && RSH > 0.0) begin + `BSIMBULKRdseffGeo(NF, GEOMOD, RGEOMOD, MINZ, Weff, RSH, DMCGeff, DMCIeff, DMDGeff, 1, RSourceGeo) + end else begin + RSourceGeo = 0.0; + end + + if ($param_given(NRD)) begin + RDrainGeo = RSH * NRD; + end else if (RGEOMOD > 0 && RSH > 0.0) begin + `BSIMBULKRdseffGeo(NF, GEOMOD, RGEOMOD, MINZ, Weff, RSH, DMCGeff, DMCIeff, DMDGeff, 0, RDrainGeo) + end else begin + RDrainGeo = 0.0; + end + + // Clamping of source/drain resistances + if (RSourceGeo <= 1.0e-3) begin + RSourceGeo = 1.0e-3; + end + if (RDrainGeo <= 1.0e-3) begin + RDrainGeo = 1.0e-3; + end + + if (RDSMOD == 1) begin + if (RSWMIN_i <= 0.0) begin + RSWMIN_i = 0.0; + end + if (RDWMIN_i <= 0.0) begin + RDWMIN_i = 0.0; + end + if (RSW_i <= 0.0) begin + RSW_i = 0.0; + end + if (RDW_i <= 0.0) begin + RDW_i = 0.0; + end + end else begin + if (RDSWMIN_i <= 0.0) begin + RDSWMIN_i = 0.0; + end + if (RDSW_i <= 0.0) begin + RDSW_i = 0.0; + end + end + + // Body resistance network + Grbsb = 0.0; + Grbdb = 0.0; + Grbpb = 0.0; + Grbps = 0.0; + Grbpd = 0.0; + if (RBODYMOD != 0) begin + Lnl = lln(Leff * 1.0e6); + Lnw = lln(Weff * 1.0e6); + Lnnf = lln(NF); + Bodymode = 5; + Rbpb = RBPB; + Rbpd = RBPD; + Rbps = RBPS; + Rbdb = RBDB; + Rbsb = RBSB; + if (!$param_given(RBPS0) || !$param_given(RBPD0)) begin + Bodymode = 1; + end + else if (!$param_given(RBSBX0) && !$param_given(RBSBY0) || !$param_given(RBDBX0) && !$param_given(RBDBY0)) begin + Bodymode = 3; + end + if (RBODYMOD == 2) begin + if (Bodymode == 5) begin + Rbsbx = RBSBX0 * lexp(RBSDBXL * Lnl + RBSDBXW * Lnw + RBSDBXNF * Lnnf); + Rbsby = RBSBY0 * lexp(RBSDBYL * Lnl + RBSDBYW * Lnw + RBSDBYNF * Lnnf); + Rbsb = Rbsbx * Rbsby / (Rbsbx + Rbsby); + Rbdbx = RBDBX0 * lexp(RBSDBXL * Lnl + RBSDBXW * Lnw + RBSDBXNF * Lnnf); + Rbdby = RBDBY0 * lexp(RBSDBYL * Lnl + RBSDBYW * Lnw + RBSDBYNF * Lnnf); + Rbdb = Rbdbx * Rbdby / (Rbdbx + Rbdby); + end + if (Bodymode == 3 || Bodymode == 5) begin + Rbps = RBPS0 * lexp(RBPSL * Lnl + RBPSW * Lnw + RBPSNF * Lnnf); + Rbpd = RBPD0 * lexp(RBPDL * Lnl + RBPDW * Lnw + RBPDNF * Lnnf); + end + Rbpbx = RBPBX0 * lexp(RBPBXL * Lnl + RBPBXW * Lnw + RBPBXNF * Lnnf); + Rbpby = RBPBY0 * lexp(RBPBYL * Lnl + RBPBYW * Lnw + RBPBYNF * Lnnf); + Rbpb = Rbpbx * Rbpby / (Rbpbx + Rbpby); + end + if (RBODYMOD == 1 || (RBODYMOD == 2 && Bodymode == 5)) begin + if (Rbdb < 1.0e-3) begin + Grbdb = 1.0e3; // in mho + end else begin + Grbdb = GBMIN + 1.0 / Rbdb; + end + if (Rbpb < 1.0e-3) begin + Grbpb = 1.0e3; + end else begin + Grbpb = GBMIN + 1.0 / Rbpb; + end + if (Rbps < 1.0e-3) begin + Grbps = 1.0e3; + end else begin + Grbps = GBMIN + 1.0 / Rbps; + end + if (Rbsb < 1.0e-3) begin + Grbsb = 1.0e3; + end else begin + Grbsb = GBMIN + 1.0 / Rbsb; + end + if (Rbpd < 1.0e-3) begin + Grbpd = 1.0e3; + end else begin + Grbpd = GBMIN + 1.0 / Rbpd; + end + end else if (RBODYMOD == 2 && Bodymode == 3) begin + Grbdb = GBMIN; + Grbsb = GBMIN; + if (Rbpb < 1.0e-3) begin + Grbpb = 1.0e3; + end else begin + Grbpb = GBMIN + 1.0 / Rbpb; + end + if (Rbps < 1.0e-3) begin + Grbps = 1.0e3; + end else begin + Grbps = GBMIN + 1.0 / Rbps; + end + if (Rbpd < 1.0e-3) begin + Grbpd = 1.0e3; + end else begin + Grbpd = GBMIN + 1.0 / Rbpd; + end + end else if (RBODYMOD == 2 && Bodymode == 1) begin + Grbdb = GBMIN; + Grbsb = GBMIN; + Grbps = 1.0e3; + Grbpd = 1.0e3; + if (Rbpb < 1.0e-3) begin + Grbpb = 1.0e3; + end else begin + Grbpb = GBMIN + 1.0 / Rbpb; + end + end + end + + // Gate process resistance + Grgeltd = RSHG * (XGW + Weffcj / 3.0 / NGCON) / (NGCON * NF * (Lnew - XGL)); + if (Grgeltd > 0.0) begin + Grgeltd = 1.0 / Grgeltd; + end else begin + Grgeltd = 1.0e3; + if (RGATEMOD != 0) begin + `STROBE("Warning: (instance BSIMBULK) The gate conductance reset to 1.0e3 mho."); + end + end + T0y = TOXE * TOXE; + T1y = TOXE * POXEDGE_i; + T2y = T1y * T1y; + ToxRatio = lexp(NTOX_i * lln(TOXREF / TOXE)) / T0y; + ToxRatioEdge = lexp(NTOX_i * lln(TOXREF / T1y)) / T2y; + Aechvb = (TYPE == `ntype) ? 4.97232e-7 : 3.42537e-7; + Bechvb = (TYPE == `ntype) ? 7.45669e11 : 1.16645e12; + AechvbEdge = Aechvb * Weff * ToxRatioEdge; + BechvbEdge = -Bechvb * TOXE * POXEDGE_i; + Aechvb = Aechvb * (Weff * Leff * ToxRatio); + Bechvb = -Bechvb * TOXE; + Weff_SH = WTH0 + Weff; + + // Parameters for self-heating + if((SHMOD != 0) && (RTH0 > 0.0) && (Weff_SH > 0.0)) begin + gth = Weff_SH * NF / RTH0; + cth = CTH0 * Weff_SH * NF; + end else begin + // set gth to some value to prevent a singular G matrix + gth = 1.0; + cth = 0.0; + end + + // Temperature Dependent Calculations Begin Here + if (TNOM <= -`P_CELSIUS0) begin + T0 = `REFTEMP - `P_CELSIUS0; + $strobe("Warning: TNOM = %e C <= %e C. Setting TNOM to %e C.", TNOM, -`P_CELSIUS0, T0); + Tnom = `REFTEMP; + end else begin + Tnom = TNOM + `P_CELSIUS0; + end + DevTemp = $temperature + DTEMP; + + // Calculate temperature dependent values for self-heating effect + if ((SHMOD != 0) && (RTH0 > 0.0) && (Weff_SH > 0.0)) begin + delTemp1 = Temp(t); + end else begin + delTemp1 = 0.0; + end + DevTemp = delTemp1 + DevTemp; + T_DELTA_SH = Temp(t); + T_TOTAL_K = DevTemp; + T_TOTAL_C = DevTemp - `P_CELSIUS0; + Vt = `KboQ * DevTemp; + inv_Vt = 1.0 / Vt; + TRatio = DevTemp / Tnom; + delTemp = DevTemp - Tnom; + Vtm = `KboQ * DevTemp; + Vtm0 = `KboQ * Tnom; + Eg = BG0SUB - TBGASUB * DevTemp * DevTemp / (DevTemp + TBGBSUB); + Eg0 = BG0SUB - TBGASUB * Tnom * Tnom / (Tnom + TBGBSUB); + T1 = (DevTemp / Tnom) * sqrt(DevTemp / Tnom); + ni = NI0SUB * T1 * lexp(Eg / (2.0 * Vtm0) - Eg / (2.0 * Vtm)); + if ((SHMOD != 0) && (RTH0 > 0.0) && (Weff_SH > 0.0)) begin + T0 = lln(NDEP_i / ni); + phib = sqrt(T0 * T0 + 1.0e-6); + end else begin + phib = lln(NDEP_i / ni); + end + if ((SHMOD != 0) && (RTH0 > 0.0) && (Weff_SH > 0.0)) begin + T0 = lln(NDEP_i * NSD_i / (ni * ni)); + Vbi = sqrt(T0 * T0 + 1.0e-6); + end else begin + Vbi = lln(NDEP_i * NSD_i / (ni * ni)); + end + if (NGATE_i > 0.0) begin + Vfbsdr = -devsign * Vt * lln(NGATE_i / NSD_i) + VFBSDOFF; + end else begin + Vfbsdr = 0.0; + end + + // Short channel effects + Phist = max(0.4 + Vt * phib + PHIN_i, 0.4); + sqrtPhist = sqrt(Phist); + T1DEP = sqrt(2.0 * epssi / (`q * NDEP_i)); + litl = sqrt((epssi / epsox) * TOXE * XJ_i); + NFACTOR_t = NFACTOR_i * hypsmooth((1.0 + TNFACTOR * (TRatio - 1.0)), 1e-3); + ETA0_t = ETA0_i * (1.0 + TETA0 * (TRatio - 1.0)); + if (ASYMMOD != 0) begin + ETA0R_t = ETA0R_i * (1.0 + TETA0 * (TRatio - 1.0)); + end + + // Mobility degradation + eta_mu = (TYPE != `ntype) ? (`Oneby3 * ETAMOB) : (0.5 * ETAMOB); + U0_t = U0_i * pow(TRatio, UTE_i); + UA_t = UA_i * hypsmooth(1.0 + UA1_i * delTemp - 1.0e-6, 1.0e-3); + UC_t = UC_i * hypsmooth(1.0 + UC1_i * delTemp - 1.0e-6, 1.0e-3); + UD_t = UD_i * pow(TRatio, UD1_i); + UCS_t = UCS_i * pow(TRatio, UCSTE_i); + if (ASYMMOD != 0) begin + U0R_t = U0R_i * pow(TRatio, UTE_i); + UAR_t = UAR_i * hypsmooth(1.0 + UA1_i * delTemp - 1.0e-6, 1.0e-3); + UCR_t = UCR_i * hypsmooth(1.0 + UC1_i * delTemp - 1.0e-6, 1.0e-3); + UDR_t = UDR_i * pow(TRatio, UD1_i); + UCSR_t = UCSR_i * pow(TRatio, UCSTE_i); + end + rdstemp = pow(TRatio, PRT_i); + VSAT_t = VSAT_i * pow(TRatio, -AT_i); + if (VSAT_t < 100.0) begin + $strobe("Warning: VSAT(%f) = %e is less than 100, setting it to 100.", DevTemp, VSAT_t); + VSAT_t = 100.0; + end + if (ASYMMOD != 0) begin + VSATR_t = VSATR_i * pow(TRatio, -AT_i); + if(VSATR_t < 100.0) begin + $strobe("Warning: VSATR(%f) = %e is less than 100, setting it to 100.", DevTemp, VSATR_t); + VSATR_t = 100.0; + end + end + VSATCV_t = VSATCV_i * pow(TRatio, -AT_i); + if (VSATCV_t < 100.0) begin + $strobe("Warning: VSATCV(%f) = %e is less than 100, setting it to 100.", DevTemp, VSATCV_t); + VSATCV_t = 100.0; + end + DELTA_t = 1.0 / ( hypsmooth((1.0 / DELTA_i) * (1.0 + TDELTA * delTemp) - 2.0 , 1.0e-3) + 2.0); + PTWG_t = PTWG_i * hypsmooth(1.0 - PTWGT_i * delTemp - 1.0e-6, 1.0e-3); + if (ASYMMOD != 0) begin + PTWGR_t = PTWGR_i * hypsmooth(1.0 - PTWGT_i * delTemp - 1.0e-6, 1.0e-3); + end + A1_t = A1_i * hypsmooth(1.0 + A11_i * delTemp - 1.0e-6, 1.0e-3); + A2_t = A2_i * hypsmooth(1.0 + A21_i * delTemp - 1.0e-6, 1.0e-3); + BETA0_t = BETA0_i * pow(TRatio, IIT_i); + BGIDL_t = BGIDL_i * hypsmooth(1.0 + TGIDL_i * delTemp - 1.0e-6, 1.0e-3); + BGISL_t = BGISL_i * hypsmooth(1.0 + TGIDL_i * delTemp - 1.0e-6, 1.0e-3); + igtemp = lexp(IGT_i * lln(TRatio)); + K0_t = K0_i * hypsmooth(1.0 + K01_i * delTemp - 1.0e-6, 1.0e-3); + M0_t = M0_i * hypsmooth(1.0 + M01_i * delTemp - 1.0e-6, 1.0e-3); + + // Diode Model temperature Code Start + CJS_t = CJS * hypsmooth(1.0 + TCJ * delTemp - 1.0e-6, 1.0e-3); + CJD_t = CJD * hypsmooth(1.0 + TCJ * delTemp - 1.0e-6, 1.0e-3); + CJSWS_t = CJSWS * hypsmooth(1.0 + TCJSW * delTemp - 1.0e-6, 1.0e-3); + CJSWD_t = CJSWD * hypsmooth(1.0 + TCJSW * delTemp - 1.0e-6, 1.0e-3); + CJSWGS_t = CJSWGS * hypsmooth(1.0 + TCJSWG * delTemp - 1.0e-6, 1.0e-3); + CJSWGD_t = CJSWGD * hypsmooth(1.0 + TCJSWG * delTemp - 1.0e-6, 1.0e-3); + PBS_t = hypsmooth(PBS - TPB * delTemp - 0.01, 1.0e-3) + 0.01; + PBD_t = hypsmooth(PBD - TPB * delTemp - 0.01, 1.0e-3) + 0.01; + PBSWS_t = hypsmooth(PBSWS - TPBSW * delTemp - 0.01, 1.0e-3) + 0.01; + PBSWD_t = hypsmooth(PBSWD - TPBSW * delTemp - 0.01, 1.0e-3) + 0.01; + PBSWGS_t = hypsmooth(PBSWGS - TPBSWG * delTemp - 0.01, 1.0e-3) + 0.01; + PBSWGD_t = hypsmooth(PBSWGD - TPBSWG * delTemp - 0.01, 1.0e-3) + 0.01; + T0 = Eg0 / Vtm0 - Eg / Vtm; + T1 = lln(TRatio); + T3 = lexp((T0 + XTIS * T1) / NJS); + JSS_t = JSS * T3; + JSWS_t = JSWS * T3; + JSWGS_t = JSWGS * T3; + T3 = lexp((T0 + XTID * T1) / NJD); + JSD_t = JSD * T3; + JSWD_t = JSWD * T3; + JSWGD_t = JSWGD * T3; + JTSS_t = JTSS * lexp(Eg0 * XTSS * (TRatio - 1.0) / Vtm); + JTSSWS_t = JTSSWS * lexp(Eg0 * XTSSWS * (TRatio - 1.0) / Vtm); + JTSSWGS_t = JTSSWGS * (sqrt(JTWEFF / Weffcj) + 1.0) * lexp(Eg0 * XTSSWGS * (TRatio - 1) / Vtm); + JTSD_t = JTSD * lexp(Eg0 * XTSD * (TRatio - 1.0) / Vtm); + JTSSWD_t = JTSSWD * lexp(Eg0 * XTSSWD * (TRatio - 1.0) / Vtm); + JTSSWGD_t = JTSSWGD * (sqrt(JTWEFF / Weffcj) + 1.0) * lexp(Eg0 * XTSSWGD * (TRatio - 1) / Vtm); + + // All NJT*'s smoothed to 0.01 to prevent divide by zero / negative values + NJTS_t = hypsmooth(NJTS * (1.0 + TNJTS * (TRatio - 1.0)) - 0.01, 1.0e-3) + 0.01; + NJTSSW_t = hypsmooth(NJTSSW * (1.0 + TNJTSSW * (TRatio - 1.0)) - 0.01, 1.0e-3) + 0.01; + NJTSSWG_t = hypsmooth(NJTSSWG * (1.0 + TNJTSSWG * (TRatio - 1.0)) - 0.01, 1.0e-3) + 0.01; + NJTSD_t = hypsmooth(NJTSD * (1.0 + TNJTSD * (TRatio - 1.0)) - 0.01, 1.0e-3) + 0.01; + NJTSSWD_t = hypsmooth(NJTSSWD * (1.0 + TNJTSSWD * (TRatio - 1.0)) - 0.01, 1.0e-3) + 0.01; + NJTSSWGD_t = hypsmooth(NJTSSWGD * (1.0 + TNJTSSWGD * (TRatio - 1.0)) - 0.01, 1.0e-3) + 0.01; + + // Effective Source/Drain junction area and perimeter + `BSIMBULKPAeffGeo(NF, GEOMOD, MINZ, Weffcj, DMCGeff, DMCIeff, DMDGeff, temp_PSeff, temp_PDeff, temp_ASeff, temp_ADeff) + if ($param_given(AS)) begin + ASeff = AS * WMLT * LMLT; + end else begin + ASeff = temp_ASeff; + end + if (ASeff < 0.0) begin + $strobe("Warning: (instance BSIMBULK) ASeff = %e is negative, set to zero.", ASeff); + ASeff = 0.0; + end + if ($param_given(AD)) begin + ADeff = AD * WMLT * LMLT; + end else begin + ADeff = temp_ADeff; + end + if (ADeff < 0.0) begin + $strobe("Warning: (instance BSIMBULK) ADeff = %e is negative, set to zero.", ADeff); + ADeff = 0.0; + end + if ($param_given(PS)) begin + if (PERMOD == 0) begin + // PS does not include gate-edge perimeter + PSeff = PS * WMLT; + end else begin + // PS includes gate-edge perimeter + PSeff = max(PS * WMLT - Weffcj * NF, 0.0); + end + end else begin + PSeff = temp_PSeff; + if (PSeff < 0.0) begin + $strobe("Warning: (instance BSIMBULK) PSeff = %e is negative.Set to 0.0", PSeff); + PSeff = 0.0; + end + end + if ($param_given(PD)) begin + if (PERMOD == 0) begin + // PD does not include gate-edge perimeter + PDeff = PD * WMLT; + end else begin + // PD includes gate-edge perimeter + PDeff = max(PD * WMLT - Weffcj * NF, 0.0); + end + end else begin + PDeff = temp_PDeff; + if (PDeff < 0.0) begin + $strobe("Warning: (instance BSIMBULK) PDeff = %e is negative.Set to 0.0", PDeff); + PDeff = 0.0; + end + end + Isbs = ASeff * JSS_t + PSeff * JSWS_t + Weffcj * NF * JSWGS_t; + if (Isbs > 0.0) begin + Nvtms = Vtm * NJS; + XExpBVS = lexp(-BVS / Nvtms) * XJBVS; + T2 = max(IJTHSFWD / Isbs, 10.0); + Tb = 1.0 + T2 - XExpBVS; + VjsmFwd = Nvtms * lln(0.5 * (Tb + sqrt(Tb * Tb + 4.0 * XExpBVS))); + T0 = lexp(VjsmFwd / Nvtms); + IVjsmFwd = Isbs * (T0 - XExpBVS / T0 + XExpBVS - 1.0); + SslpFwd = Isbs * (T0 + XExpBVS / T0) / Nvtms; + T2 = hypsmooth(IJTHSREV / Isbs - 10.0, 1.0e-3) + 10.0; + VjsmRev = -BVS - Nvtms * lln((T2 - 1.0) / XJBVS); + T1 = XJBVS * lexp(-(BVS + VjsmRev) / Nvtms); + IVjsmRev = Isbs * (1.0 + T1); + SslpRev = -Isbs * T1 / Nvtms; + end else begin + Nvtms = 0.0; + XExpBVS = 0.0; + VjsmFwd = 0.0; + IVjsmFwd = 0.0; + SslpFwd = 0.0; + VjsmRev = 0.0; + IVjsmRev = 0.0; + SslpRev = 0.0; + end + + // Drain-side junction current + Isbd = ADeff * JSD_t + PDeff * JSWD_t + Weffcj * NF * JSWGD_t; + if (Isbd > 0.0) begin + Nvtmd = Vtm * NJD; + XExpBVD = lexp(-BVD / Nvtmd) * XJBVD; + T2 = max(IJTHDFWD / Isbd, 10.0); + Tb = 1.0 + T2 - XExpBVD; + VjdmFwd = Nvtmd * lln(0.5 * (Tb + sqrt(Tb * Tb + 4.0 * XExpBVD))); + T0 = lexp(VjdmFwd / Nvtmd); + IVjdmFwd = Isbd * (T0 - XExpBVD / T0 + XExpBVD - 1.0); + DslpFwd = Isbd * (T0 + XExpBVD / T0) / Nvtmd; + T2 = hypsmooth(IJTHDREV / Isbd - 10.0, 1.0e-3) + 10.0; + VjdmRev = -BVD - Nvtmd * lln((T2 - 1.0) / XJBVD); + T1 = XJBVD * lexp(-(BVD + VjdmRev) / Nvtmd); + IVjdmRev = Isbd * (1.0 + T1); + DslpRev = -Isbd * T1 / Nvtmd; + end else begin + Nvtmd = 0.0; + XExpBVD = 0.0; + VjdmFwd = 0.0; + IVjdmFwd = 0.0; + DslpFwd = 0.0; + VjdmRev = 0.0; + IVjdmRev = 0.0; + DslpRev = 0.0; + end + + // STI stress equations + if((SA > 0.0) && (SB > 0.0) && ((NF == 1.0) || ((NF > 1.0) && (SD > 0.0)))) begin + T0 = pow(Lnew, LLODKU0); + W_tmp_stress = Wnew + WLOD; + T1 = pow(W_tmp_stress, WLODKU0); + tmp1_stress = LKU0 / T0 + WKU0 / T1 + PKU0 / (T0 * T1); + kstress_u0 = 1.0 + tmp1_stress; + T0 = pow(Lnew, LLODVTH); + T1 = pow(W_tmp_stress, WLODVTH); + tmp1_stress_vth = LKVTH0 / T0 + WKVTH0 / T1 + PKVTH0 / (T0 * T1); + kstress_vth0 = 1.0 + tmp1_stress_vth; + T0 = TRatio - 1.0; + ku0_temp = kstress_u0 * (1.0 + TKU0 * T0) + 1.0e-9; + i = 0; + while (i < NF) begin + T0 = 1.0 / NF / (SA + 0.5 * L_mult + i * (SD + L_mult)); + T1 = 1.0 / NF / (SB + 0.5 * L_mult + i * (SD + L_mult)); + Inv_sa = Inv_sa + T0; + Inv_sb = Inv_sb + T1; + i = i + 1; + end + Inv_saref = 1.0 / (SAREF + 0.5 * L_mult); + Inv_sbref = 1.0 / (SBREF + 0.5 * L_mult); + Inv_odref = Inv_saref + Inv_sbref; + rho_ref = (KU0 / ku0_temp) * Inv_odref; + Inv_od = Inv_sa + Inv_sb; + rho = (KU0 / ku0_temp) * Inv_od; + mu0_mult = (1.0 + rho) / (1.0 + rho_ref); + vsat_mult = (1.0 + rho * KVSAT) / (1.0 + rho_ref * KVSAT); + vth0_stress = (KVTH0 / kstress_vth0) * (Inv_od - Inv_odref); + k2_stress = (STK2 / pow(kstress_vth0, LODK2)) * (Inv_od - Inv_odref); + eta_stress = (STETA0 / pow(kstress_vth0, LODETA0)) * (Inv_od - Inv_odref); + U0_t = U0_t * mu0_mult; + VSAT_t = VSAT_t * vsat_mult; + K2_i = K2_i + k2_stress; + ETA0_t = ETA0_t + eta_stress; + if (EDGEFET == 1) begin + vth0_stress_EDGE = (KVTH0EDGE_i / kstress_vth0) * (Inv_od - Inv_odref); + k2_stress_EDGE = (STK2EDGE_i / pow(kstress_vth0, LODK2)) * (Inv_od - Inv_odref); + eta_stress_EDGE = (STETA0EDGE_i / pow(kstress_vth0, LODETA0)) * (Inv_od - Inv_odref); + end + K2_EDGE = K2EDGE_i + k2_stress_EDGE; + ETA0_EDGE = ETA0EDGE_i + eta_stress_EDGE; + end else begin + vth0_stress = 0.0; + vth0_stress_EDGE = 0.0; + end + + // Well proximity effect + if (WPEMOD == 1) begin + Wdrn = W / NF; + local_sca = SCA; + local_scb = SCB; + local_scc = SCC; + if (!$param_given(SCA) && !$param_given(SCB) && !$param_given(SCC)) begin + if($param_given(SC) && SC > 0.0) begin + T1 = SC + Wdrn; + T2 = 1.0 / SCREF; + local_sca = SCREF * SCREF / (SC * T1); + local_scb = ((0.1 * SC + 0.01 * SCREF) * lexp(-10.0 * SC * T2) - (0.1 * T1 + 0.01 * SCREF) * + lexp(-10.0 * T1 * T2)) / Wdrn; + local_scc = ((0.05 * SC + 0.0025 * SCREF) * lexp(-20.0 * SC * T2) - (0.05 * T1 + 0.0025 * SCREF) * + lexp(-20.0 * T1 * T2)) / Wdrn; + end else begin + `STROBE("Warning: (Instance BSIMBULK) No WPE as none of SCA, SCB, SCC, SC is given and/or SC not positive."); + end + end + end + vth0_well = KVTH0WE_i * (local_sca + WEB * local_scb + WEC * local_scc); + k2_well = K2WE_i * (local_sca + WEB * local_scb + WEC * local_scc); + mu_well = 1.0 + KU0WE_i * (local_sca + WEB * local_scb + WEC * local_scc); + U0_t = U0_t * mu_well; + K2_i = K2_i + k2_well; + + // Load Terminal Voltages + Vg = devsign * V(gi, bi); + Vd = devsign * V(di, bi); + Vs = devsign * V(si, bi); + Vds = Vd - Vs; + Vds_noswap = Vds; + Vsb_noswap = Vs; + Vdb_noswap = Vd; + Vbs_jct = devsign * V(sbulk, si); + Vbd_jct = devsign * V(dbulk, di); + Vgd_noswap = Vg - Vd; + Vgs_noswap = Vg - Vs; + Vgd_ov_noswap = devsign * V(gm, di); + Vgs_ov_noswap = devsign * V(gm, si); + + // Terminal voltage conditioning + // Source-drain interchange + sigvds = 1.0; + if (Vds < 0.0) begin + sigvds = -1.0; + Vd = devsign * V(si, bi); + Vs = devsign * V(di, bi); + end + Vds = Vd - Vs; + T0 = AVDSX * Vds; + if (T0 > `EXPL_THRESHOLD) begin + T1 = T0; + end else begin + T1 = ln(1.0 + exp(T0)); + end + Vdsx = ((2.0/AVDSX) * T1) - Vds - ((2.0/AVDSX) * ln(2.0)); + Vbsx = -(Vs + 0.5 * (Vds - Vdsx)); + + // Asymmetry model + T0 = tanh(0.6 * Vds_noswap / Vtm); + wf = 0.5 + 0.5 * T0; + wr = 1.0 - wf; + if (ASYMMOD != 0) begin + CDSCD_a = CDSCDR_i * wr + CDSCD_i * wf; + ETA0_a = ETA0R_t * wr + ETA0_t * wf; + PDIBLC_a = PDIBLCR_i * wr + PDIBLC_i * wf; + PCLM_a = PCLMR_i * wr + PCLM_i * wf; + PSAT_a = PSATR_i * wr + PSAT_i * wf; + VSAT_a = VSATR_t * wr + VSAT_t * wf; + PTWG_a = PTWGR_t * wr + PTWG_t * wf; + U0_a = U0R_t * wr + U0_t * wf; + UA_a = UAR_t * wr + UA_t * wf; + UC_a = UCR_t * wr + UC_t * wf; + UD_a = UDR_t * wr + UD_t * wf; + UCS_a = UCSR_t * wr + UCS_t * wf; + end else begin + CDSCD_a = CDSCD_i; + ETA0_a = ETA0_t; + PDIBLC_a = PDIBLC_i; + PCLM_a = PCLM_i; + PSAT_a = PSAT_i; + VSAT_a = VSAT_t; + PTWG_a = PTWG_t; + U0_a = U0_t; + UA_a = UA_t; + UC_a = UC_t; + UD_a = UD_t; + UCS_a = UCS_t; + end + + // SCE, DIBL, SS degradation effects, Ref: BSIM4 Model + `Smooth(Phist - Vbsx, 0.05, 0.1, PhistVbs) + sqrtPhistVbs = sqrt(PhistVbs); + Xdep = T1DEP * sqrtPhistVbs; + Cdep = epssi / Xdep; + cdsc = CIT_i + NFACTOR_t + CDSCD_a * Vdsx - CDSCB_i * Vbsx; + T1 = 1.0 + cdsc/Cox; + `Smooth(T1, 1, 0.05, n) + nVt = n * Vt; + inv_nVt = 1.0 / nVt; + + // Vth Shift for DIBL + dVth_dibl = -(ETA0_a + ETAB_i * Vbsx) * Vdsx; + + // Vth shift with temperature + dvth_temp = (KT1_i + KT1L / Leff + KT2_i * Vbsx) * (pow(TRatio, KT1EXP) - 1.0); + `Smooth2(dVth_dibl, 0.0, 5.0e-5, dVth_dibl) + + // Vth Correction for Pocket Implant + if (DVTP0_i > 0.0) begin + T0 = -DVTP1_i * Vdsx; + if (T0 < -`EXPL_THRESHOLD) begin + T2 = `MIN_EXPL; + end else begin + T2 = lexp(T0); + end + T3 = Leff + DVTP0_i * (1.0 + T2); + dVth_ldop = -nVt * lln(Leff / T3); + end else begin + dVth_ldop = 0.0; + end + T4 = DVTP5_i + DVTP2_i / pow(Leff, DVTP3_i); + dVth_ldop = dVth_ldop - T4 * tanh(DVTP4_i * Vdsx); + + // Normalization of terminal and flatband voltage by nVt + VFB_i = VFB_i + DELVTO; + vg = Vg * inv_nVt; + vs = Vs * inv_nVt; + vfb = VFB_i * inv_nVt; + + // Compute dVth_VNUD with "first-order" and "second-order" body-bias effect + dVth_VNUD = K1_i * (sqrtPhistVbs - sqrtPhist) - K2_i * Vbsx; + Vth_shift = dVth_dibl + dVth_ldop + dVth_VNUD - dvth_temp + vth0_stress + vth0_well; + vgfb = vg - vfb - Vth_shift * inv_nVt; + + // Threshold voltage for operating point information + gam = sqrt(2.0 * `q * epssi * NDEP_i * inv_Vt) / Cox; + q_vth = 0.5; + T0 = hypsmooth((2.0 * phib + Vs * inv_Vt), 1.0e-3); + nq = 1.0 + gam / (2.0 * sqrt(T0)); + psip_th = hypsmooth((Vs * inv_Vt + 2.0 * phib + lln(q_vth) + 2.0 * q_vth + lln(2.0 * nq / gam * (2.0 * q_vth * nq / gam + 2.0 * sqrt(T0)))), 1.0e-3); + VTH = devsign * (VFB_i + (psip_th - Vs * inv_Vt) * Vt + Vt * gam * sqrt(psip_th) + Vth_shift); + + // Normalized body factor + gam = sqrt(2.0 * `q * epssi * NDEP_i * inv_nVt) / Cox; + inv_gam = 1.0 / gam; + + // psip: pinch-off voltage + phib_n = phib / n; + `PO_psip(vgfb, gam, 0, phib_n, psip) + + // normalized inversion charge at source end of channel + `BSIM_q(psip, phib_n, vs, gam, qs) + + // average charge-surf. pot. slope, Ref: Charge-based MOS Transistor Modeling by C. Enz & E. Vittoz + `Smooth(psip, 1.0, 2.0, psipclamp) + sqrtpsip = sqrt(psipclamp); + + // source side surf pot. + psiavg = psip - 2.0 * qs; + `Smooth(psiavg, 1.0, 2.0, T0) + nq = 1.0 + gam / (sqrtpsip + sqrt(T0)); + + // Drain Saturation Voltage + EeffFactor = 1.0e-8 / (epsratio * TOXE); + T0 = nVt * (vgfb - psip - 2.0 * qs * (nq - 1.0)); + `Smooth(T0, 0, 0.1, qbs) + + // Source side qi and qb for Vdsat- normalized to Cox + qis = 2.0 * nq * nVt * qs; + Eeffs = EeffFactor * (qbs + eta_mu * qis); + + // Ref: BSIM4 Model mobility model + T2 = pow(0.5 * (1.0 + (qis / qbs)), UCS_a); + T3 = (UA_a + UC_a * Vbsx) * pow(Eeffs, EU_i) + UD_a / T2; + T4 = 1.0 + T3; + `Smooth(T4, 1.0, 0.0015, Dmobs) + WeffWRFactor = 1.0 / (pow(Weff * 1.0e6, WR_i) * NF); + + if (RDSMOD == 1) begin + Rdss = 0.0; + end else begin + T0 = 1.0 + PRWG_i * qis; + T1 = PRWB_i * (sqrtPhistVbs - sqrtPhist); + T2 = 1.0 / T0 + T1; + T3 = T2 + sqrt(T2 * T2 + 0.01); + Rdss = (RDSWMIN_i + RDSW_i * T3) * WeffWRFactor * NF * rdstemp; + if (RDSMOD == 2) begin + Rdss = (RSourceGeo + (RDSWMIN_i + RDSW_i * T3) * WeffWRFactor * NF + RDrainGeo) * rdstemp; + end + end + T0 = pow(Dmobs, 1.0 / PSAT_a); + if (PSATB_i < 0.0) begin + T1 = 1.0 / (1.0 + PSATB_i * Vbsx); + end else begin + T1 = 1.0 - PSATB_i * Vbsx; + end + T2 = 10.0 * PSATX * qs * T1 / (10.0 * PSATX + qs * T1); + if (PTWG_a < 0.0) begin + LambdaC = 2.0 * ((U0_a / T0) * nVt / (VSAT_a * Leff)) * (1.0 / (1.0 - PTWG_a * T2)); + end else begin + LambdaC = 2.0 * ((U0_a / T0) * nVt / (VSAT_a * Leff)) * (1.0 + PTWG_a * T2); + end + + // qdsat for external Rds + if (Rdss == 0) begin + // Accurate qdsat derived from consistent I-V + T0 = 0.5 * LambdaC * (qs * qs + qs) / (1.0 + 0.5 * LambdaC * (1.0 + qs)); + T1 = 2.0 * LambdaC * (qs - T0); + T2 = sqrt(1.0 + T1 * T1); + ln_T1_T2 = asinh(T1); + if (T1 != 0.0) begin + T3 = T2 + (1.0 / T1) * ln_T1_T2; + end else begin + T3 = T2 + (1.0 / T2); + end + T4 = T0 * T3 - LambdaC * ((qs * qs + qs) - (T0 * T0 + T0)); + if (T1 != 0.0) begin + T5 = -2.0 * LambdaC * (T1 * T2 - ln_T1_T2) / (T1 * T1); + end else begin + T5 = -2.0 * LambdaC * (T1/T2) * (T1/T2) *(T1/T2); + end + T6 = T0 * T5 + T3 + LambdaC * (2.0 * T0 + 1.0); + T0 = T0 - (T4 / T6); + T1 = 2.0 * LambdaC * (qs - T0); + T2 = sqrt(1.0 + T1 * T1); + ln_T1_T2 = asinh(T1); + if (T1 != 0.0) begin + T3 = T2 + (1.0 / T1) * ln_T1_T2; + end else begin + T3 = T2 + (1.0 / T2); + end + T4 = T0 * T3 - LambdaC * ((qs * qs + qs) - (T0 * T0 + T0)); + if (T1 != 0.0) begin + T5 = -2.0 * LambdaC * (T1 * T2 - ln_T1_T2) / (T1 * T1); + end else begin + T5 = (T1 / T2) * (T1 / T2) * (T1 / T2); + end + T6 = T0 * T5 + T3 + LambdaC * (2.0 * T0 + 1.0); + qdsat = T0 - (T4/T6); + // qdsat for internal Rds, Ref: BSIM4 Model + end else begin + // Accurate qdsat derived from consistent I-V + T11 = Weff * 2.0 * nq * Cox * nVt * VSAT_a; + T12 = T11 * LambdaC * Rdss / (2.0 * nVt); + T0 = 0.5 * LambdaC * (qs * qs + qs) / (1.0 + 0.5 * LambdaC * (1.0 + qs)); + T1 = 2.0 * LambdaC * (qs - T0); + T2 = sqrt(1.0 + T1 * T1); + ln_T1_T2 = asinh(T1); + if (T1 != 0.0) begin + T3 = T2 + (1.0 / T1) * ln_T1_T2; + end else begin + T3 = T2 + (1.0 / T2); + end + T4 = T0 * T3 + T12 * T0 * (qs + T0 + 1.0) - LambdaC * ((qs * qs + qs) - (T0 * T0 + T0)); + if (T1 != 0.0) begin + T5 = -2.0 * LambdaC * (T1 * T2 - ln_T1_T2) / (T1 * T1); + end else begin + T5 = -2.0 * LambdaC * (T1 / T2) * (T1 / T2) * (T1 / T2); + end + T6 = T0 * T5 + T3 + T12 * (qs + 2.0 * T0 + 1.0) + LambdaC * (2.0 * T0 + 1.0); + T0 = T0 - T4 / T6; + T1 = 2.0 * LambdaC * (qs - T0); + T2 = sqrt(1.0 + T1 * T1); + ln_T1_T2 = asinh(T1); + if (T1 != 0) begin + T3 = T2 + (1.0 / T1) * ln_T1_T2; + end else begin + T3 = T2 + (1.0 / T2); + end + T4 = T0 * T3 + T12 * T0 * (qs + T0 + 1.0) - LambdaC * ((qs * qs + qs) - (T0 * T0 + T0)); + if (T1 != 0.0) begin + T5 = -2.0 * LambdaC * (T1 * T2 - ln_T1_T2) / (T1 * T1); + end else begin + T5 = -2.0 * LambdaC * (T1 / T2) * (T1 / T2) * (T1 / T2); + end + T6 = T0 * T5 + T3 + T12 * (qs + 2.0 * T0 + 1.0) + LambdaC * (2.0 * T0 + 1.0); + qdsat = T0 - T4 / T6; + end + vdsat = psip - 2.0 * phib_n - (2.0 * qdsat + lln((qdsat * 2.0 * nq * inv_gam) * ((qdsat * 2.0 * nq * inv_gam) + (gam / (nq - 1.0))))); + Vdsat = vdsat * nVt; + + // normalized charge qdeff at drain end of channel + // Vdssat clamped to avoid negative values during transient simulation + `Smooth(Vdsat - Vs, 0.0, 1.0e-3, Vdssat) + T7 = pow(Vds / Vdssat , 1.0 / DELTA_t); + T8 = pow(1.0 + T7, -DELTA_t); + Vdseff = Vds * T8; + vdeff = (Vdseff + Vs) * inv_nVt; + `BSIM_q(psip, phib_n, vdeff, gam, qdeff) + + // Reevaluation of nq to include qdeff + psiavg = psip - qs - qdeff -1.0; + `Smooth(psiavg, 1.0, 2.0, T0) + T2 = sqrt(T0); + nq = 1.0 + gam / (sqrtpsip + T2); + + // Inversion and bulk charge + DQSD2 = (qs - qdeff) * (qs - qdeff); + T0 = 1.0 / (1.0 + qs + qdeff); + T1 = DQSD2 * T0; + Qb = vgfb - psip - (nq - 1.0) * (qs + qdeff + `Oneby3 * T1); + T2 = `Oneby3 * nq; + T3 = T1 * T0; + Qs = T2 * (2.0 * qs + qdeff + 0.5 * (1.0 + 0.8 * qs + 1.2 * qdeff) * T3); + Qd = T2 * (qs + 2.0 * qdeff + 0.5 * (1.0 + 1.2 * qs + 0.8 * qdeff) * T3); + + // Mobility degradation, Ref: BSIM4 + // Average charges (qba and qia) - normalized to Cox + `Smooth(nVt * Qb, 0, 0.1, qba) + qia = nVt * (Qs + Qd); + + Eeffm = EeffFactor * (qba + eta_mu * qia); + T2 = pow(0.5 * (1.0 + (qia / qba)), UCS_a); + T3 = (UA_a + UC_a * Vbsx) * pow(Eeffm, EU_i) + UD_a / T2; + T4 = 1.0 + T3; + `Smooth(T4, 1.0, 0.0015, Dmob) + + // Output conductance + Esat = 2.0 * VSAT_a / (U0_a / Dmob); + EsatL = Esat * Leff; + if (PVAG_i > 0.0) begin + PVAGfactor = 1.0 + PVAG_i * qia / EsatL; + end else begin + PVAGfactor = 1.0 / (1.0 - PVAG_i * qia / EsatL); + end + + // Output conductance due to DIBL, Ref: BSIM4 + DIBLfactor = PDIBLC_a; + diffVds = Vds - Vdseff; + Vgst2Vtm = qia + 2.0 * nVt; + if (DIBLfactor > 0.0) begin + T3 = Vgst2Vtm / (Vdssat + Vgst2Vtm); + T4 = hypsmooth((1.0 + PDIBLCB_i * Vbsx), 1.0e-3); + T5 = 1.0 / T4; + VaDIBL = Vgst2Vtm / DIBLfactor * T3 * PVAGfactor * T5; + Moc = 1.0 + diffVds / VaDIBL; + end else begin + Moc = 1.0; + end + + // Degradation factor due to pocket implant, Ref: BSIM4 Model + if (FPROUT_i <= 0.0) begin + Fp = 1.0; + end else begin + T9 = FPROUT_i * sqrt(Leff) / Vgst2Vtm; + Fp = 1.0 / (1.0 + T9); + end + + // Channel length modulation, Ref: BSIM4 Model + Vasat = Vdssat + EsatL; + if(PCLM_a != 0.0) begin + if (PCLMG < 0.0) begin + T1 = PCLM_a / (1.0 - PCLMG * qia / EsatL) / Fp; + end else begin + T1 = PCLM_a * (1.0 + PCLMG * qia / EsatL) / Fp; + end + MdL = 1.0 + T1 * lln(1.0 + diffVds / T1 / Vasat); + end else begin + MdL = 1.0; + end + Moc = Moc * MdL; + + // Calculate Va_DITS, Ref: BSIM4 + T1 = lexp(PDITSD_i * Vds); + if (PDITS_i > 0.0) begin + T2 = 1.0 + PDITSL * Leff; + VaDITS = (1.0 + T2 * T1) / PDITS_i; + VaDITS = VaDITS * Fp; + end else begin + VaDITS = `MAX_EXPL; + end + T4 = diffVds / VaDITS; + T0 = 1.0 + T4; + Moc = Moc * T0; + + // Calculate Vascbe, Ref: BSIM4 Model + if (PSCBE2_i > 0.0) begin + if (diffVds > PSCBE1_i * litl / `EXPL_THRESHOLD) begin + T0 = PSCBE1_i * litl / diffVds; + VaSCBE = Leff * lexp(T0) / PSCBE2_i; + end else begin + VaSCBE = `MAX_EXPL * Leff/PSCBE2_i; + end + end else begin + VaSCBE = `MAX_EXPL; + end + Mscbe = 1.0 + (diffVds / VaSCBE); + Moc = Moc * Mscbe; + + // Velocity saturation + T0 = pow(Dmob, 1.0 / PSAT_a); + if (PSATB_i < 0.0) begin + T1 = 1.0 / (1.0 + PSATB_i * Vbsx); + end else begin + T1 = 1.0 - PSATB_i * Vbsx; + end + T2 = 10.0 * PSATX * qia * T1 / (10.0 * PSATX + qia * T1); + if (PTWG_a < 0.0) begin + LambdaC = 2.0 * ((U0_a / T0) * nVt / (VSAT_a * Leff)) * (1.0 / (1.0 - PTWG_a * T2)); + end else begin + LambdaC = 2.0 * ((U0_a / T0) * nVt / (VSAT_a * Leff)) * (1.0 + PTWG_a * T2); + end + T1 = 2.0 * LambdaC * (qs - qdeff); + T2 = sqrt(1.0 + T1 * T1); + if (T1 != 0.0) begin + Dvsat = 0.5 * (T2 + (1.0 / T1) * asinh(T1)); + end else begin + Dvsat = 0.5 * (T2 + (1.0 / T2)); + end + Dptwg = Dvsat; + + // S/D Series Resistance, Ref: BSIM4 + Rsource = 0.0; + Rdrain = 0.0; + if (RDSMOD == 1) begin + Rdsi = 0.0; + Dr = 1.0; + // Rs (Source side resistance for all fingers) + T2 = Vgs_noswap - Vfbsdr; + T3 = sqrt(T2 * T2 + 0.01); + Vgs_eff = 0.5 * (T2 + T3); + T5 = 1.0 + PRWG_i * Vgs_eff; + T6 = (1.0 / T5) + PRWB_i * Vsb_noswap; + T4 = 0.5 * (T6 + sqrt(T6 * T6 + 0.01)); + Rsource = rdstemp * (RSourceGeo + (RSWMIN_i + RSW_i * T4) * WeffWRFactor); + // Rd (Drain side resistance for all fingers) + T2 = Vgd_noswap - Vfbsdr; + T3 = sqrt(T2 * T2 + 0.01); + Vgd_eff = 0.5 * (T2 + T3); + T5 = 1.0 + PRWG_i * Vgd_eff; + T6 = (1.0 / T5) + PRWB_i * Vdb_noswap; + T4 = 0.5 * (T6 + sqrt(T6 * T6 + 0.01)); + Rdrain = rdstemp * (RDrainGeo + (RDWMIN_i + RDW_i * T4) * WeffWRFactor); + end else begin + // Ref: (1) BSIM4 Model (2) "Operation and Modeling of the MOS Transistor" by Yannis Tsividis + T0 = 1.0 + PRWG_i * qia; + T1 = PRWB_i * (sqrtPhistVbs - sqrtPhist); + T2 = 1.0 / T0 + T1; + T3 = 0.5 * (T2 + sqrt(T2 * T2 + 0.01)); + Rdsi = rdstemp * (RDSWMIN_i + RDSW_i * T3) * WeffWRFactor * NF; + Rdrain = RDrainGeo; + Rsource = RSourceGeo; + Dr = 1.0 + U0_a /(Dvsat * Dmob) * Cox * Weff / Leff * qia * Rdsi; + if (RDSMOD == 2) begin + Rdsi = rdstemp * (RSourceGeo + (RDSWMIN_i + RDSW_i * T3) * WeffWRFactor * NF + RDrainGeo); + Rdrain = 0.0; + Rsource = 0.0; + Dr = 1.0 + U0_a /(Dvsat * Dmob) * Cox * Weff / Leff * qia * Rdsi; + end + end + + // Non-saturation effect + T0 = A1_t + A2_t / (qia + 2.0 * n * Vtm); + DQSD = qs - qdeff; + T1 = T0 * DQSD * DQSD; + T2 = T1 + 1.0 - 0.001; + T3 = -1.0 + 0.5 * (T2 + sqrt(T2 * T2 + 0.004)); + Nsat = 0.5 * (1.0 + sqrt(1.0 + T3)); + + // MNUD model to enhance Id-Vd fitting flexibility + T0 = (qs + qdeff); + T1 = (qs - qdeff); + T2 = T1 / (T0 + M0_t); + T3 = K0_t * T2 * T2; + Mnud = 1.0 + T3; + Dtot = Dmob * Dvsat * Dr; + + // Effective mobility including mobility degradation + ueff = U0_a / Dtot; + + // I-V + ids = 2.0 * NF * nq * ueff * Weff / Leff * Cox * nVt * nVt * ((qs - qdeff) * (1.0 + qs + qdeff)) * Moc / Nsat * Mnud; + ids = ids * IDS0MULT; + Gcrg = 0.0; + if (RGATEMOD > 1) begin + idsovvds = ueff * Weff / Leff * Cox * qia; + T9 = XRCRG2 * Vt; + T0 = T9 * ueff * Weff / Leff * Cox; + Gcrg = XRCRG1 * NF * (T0 + idsovvds); + if (RGATEMOD == 2) begin + T11 = Grgeltd + Gcrg; + Gcrg = Grgeltd * Gcrg / T11; + end + end + + // Impact ionization current, Ref: BSIM4 + if ((ALPHA0_i <= 0.0) || (BETA0_t <= 0.0)) begin + Iii = 0.0; + end else if (diffVds > BETA0_t / `EXPL_THRESHOLD) begin + T1 = -BETA0_t / diffVds; + Iii = ALPHA0_i * diffVds * ids * lexp(T1) / Mscbe; + end else begin + Iii = ALPHA0_i * diffVds * ids * `MIN_EXPL / Mscbe; + end + ISUB = Iii * devsign; + + // Gate Current, Ref: BSIM4 Model + igbinv = 0.0; + igbacc = 0.0; + igb = 0.0; + igcs = 0.0; + igcd = 0.0; + igs = 0.0; + igd = 0.0; + if ((IGCMOD != 0) || (IGBMOD != 0)) begin + Voxm = nVt * (vgfb - psip + qs + qdeff); + T1 = sqrt(Voxm * Voxm + 1.0e-4); + Voxmacc = 0.5 * (-Voxm + T1); + Voxminv = 0.5 * (Voxm + T1); + // Igbinv + if (IGBMOD != 0) begin + T1 = Voxmacc / NIGBACC_i / Vt; + Vaux_Igbacc = NIGBACC_i * Vt * lln(1.0 + lexp(-T1)); + T2 = AIGBACC_i - BIGBACC_i * Voxmacc; + T3 = 1.0 + CIGBACC_i * Voxmacc; + T4 = -7.45669e11 * TOXE * T2 * T3; + T5 = lexp(T4); + T6 = 4.97232e-7; + igbacc = NF * Weff * Leff * T6 * ToxRatio * Vg * Vaux_Igbacc * T5; + igbacc = igbacc * igtemp; + T1 = (Voxminv - EIGBINV_i) / NIGBINV_i / Vt; + Vaux_Igbinv = NIGBINV_i * Vt * lln(1.0 + lexp(T1)); + T2 = AIGBINV_i - BIGBINV_i * Voxminv; + T3 = 1.0 + CIGBINV_i * Voxminv; + T4 = -9.82222e11 * TOXE * T2 * T3; + T5 = lexp (T4); + T6 = 3.75956e-7; + igbinv = NF * Weff * Leff * T6 * ToxRatio * Vg * Vaux_Igbinv * T5; + igbinv = igbinv * igtemp; + igb = igbacc + igbinv; + end + + if (IGCMOD != 0) begin + // Igcinv + T1 = AIGC_i - BIGC_i * Voxminv; + T2 = 1.0 + CIGC_i * Voxminv; + T3 = Bechvb * T1 * T2; + T4 = nq * nVt * (qs + qdeff) * lexp(T3); + igc0 = NF * Aechvb * T4 * (Vg + 0.5 * Vdsx - 0.5 * (Vs + Vd)) * igtemp; + // Gate-current partitioning + Vdseffx = sqrt(Vdseff * Vdseff + 0.01) - 0.1; + T1 = PIGCD_i * Vdseffx; + T1_exp = lexp(-T1); + T3 = T1 + T1_exp -1.0 + 1.0e-4; + T4 = 1.0 - (T1 + 1.0) * T1_exp + 1.0e-4; + T5 = T1 * T1 + 2.0e-4; + if (sigvds > 0) begin + igcd = igc0 * T4 / T5; + igcs = igc0 * T3 / T5; + end else begin + igcs = igc0 * T4 / T5; + igcd = igc0 * T3 / T5; + end + // Igs + T2 = Vgs_noswap - Vfbsdr; + Vgs_eff = sqrt(T2 * T2 + 1.0e-4); + if (IGCLAMP == 1) begin + T1 = hypsmooth((AIGS_i - BIGS_i * Vgs_eff), 1.0e-6); + if (CIGS_i < 0.01) begin + CIGS_i = 0.01; + end + end else begin + T1 = AIGS_i - BIGS_i * Vgs_eff; + end + T2 = 1.0 + CIGS_i * Vgs_eff; + T3 = BechvbEdge * T1 * T2; + T4 = lexp(T3); + igs_mult = igtemp * NF * AechvbEdge * DLCIG_i; + igs = igs_mult * Vgs_noswap * Vgs_eff * T4; + // Igd + T2 = Vgd_noswap - Vfbsdr; + Vgd_eff = sqrt(T2 * T2 + 1.0e-4); + if (IGCLAMP == 1) begin + T1 = hypsmooth((AIGD_i - BIGD_i * Vgd_eff), 1.0e-6); + if (CIGD_i < 0.01) begin + CIGD_i = 0.01; + end + end else begin + T1 = AIGD_i - BIGD_i * Vgd_eff; + end + T2 = 1.0 + CIGD_i * Vgd_eff; + T3 = BechvbEdge * T1 * T2; + T4 = lexp(T3); + igd_mult = igtemp * NF * AechvbEdge * DLCIGD_i; + igd = igd_mult * Vgd_noswap * Vgd_eff * T4; + end + end + IGS = devsign * igs; + IGD = devsign * igd; + IGB = devsign * igb; + IGCS = devsign * igcs; + IGCD = devsign * igcd; + + // GIDL and GISL Currents , Ref: BSIM4 Model + igisl = 0.0; + igidl = 0.0; + if (GIDLMOD != 0) begin + T0 = epsratio * TOXE; + // GIDL + if ((AGIDL_i <= 0.0) || (BGIDL_t <= 0.0) || (CGIDL_i < 0.0)) begin + T6 = 0.0; + end else begin + T1 = (-Vgd_noswap - EGIDL_i + Vfbsdr) / T0; + T1 = hypsmooth(T1, 1.0e-2); + T2 = BGIDL_t / (T1 + 1.0e-3); + if (CGIDL_i != 0.0) begin + T3 = Vdb_noswap * Vdb_noswap * Vdb_noswap; + T4 = CGIDL_i + abs(T3) + 1.0e-4; + T5 = hypsmooth(T3 / T4, 1.0e-6) - 1.0e-6; + end else begin + T5 = 1.0; + end + T6 = AGIDL_i * Weff * T1 * lexp(-T2) * T5; + end + igidl = T6; + // GISL + if ((AGISL_i <= 0.0) || (BGISL_t <= 0.0) || (CGISL_i < 0.0)) begin + T6 = 0.0; + end else begin + T1 = (-Vgs_noswap - EGISL_i + Vfbsdr) / T0; + T1 = hypsmooth(T1, 1.0e-2); + T2 = BGISL_t / (T1 + 1.0e-3); + if (CGISL_i != 0.0) begin + T3 = Vsb_noswap * Vsb_noswap * Vsb_noswap; + T4 = CGISL_i + abs(T3) + 1.0e-4; + T5 = hypsmooth(T3 / T4, 1.0e-6) - 1.0e-6; + end else begin + T5 = 1.0; + end + T6 = AGISL_i * Weff * T1 * lexp(-T2) * T5; + end + igisl = T6; + end + IGIDL = devsign * NF * igidl; + IGISL = devsign * NF * igisl; + + // Junction current and capacitances + // Source-side junction current + if (Isbs > 0.0) begin + if (Vbs_jct < VjsmRev) begin + T0 = Vbs_jct / Nvtms; + T1 = lexp(T0) - 1.0; + T2 = IVjsmRev + SslpRev * (Vbs_jct - VjsmRev); + Ibs = T1 * T2; + end else if (Vbs_jct <= VjsmFwd) begin + T0 = Vbs_jct / Nvtms; + T1 = (BVS + Vbs_jct) / Nvtms; + T2 = lexp(-T1); + Ibs = Isbs * (lexp(T0) + XExpBVS - 1.0 - XJBVS * T2); + end else begin + Ibs = IVjsmFwd + SslpFwd * (Vbs_jct - VjsmFwd); + end + end else begin + Ibs = 0.0; + end + + //Source-side junction tunneling current + if (JTSS_t > 0.0) begin + if ((VTSS - Vbs_jct) < (VTSS * 1.0e-3)) begin + T0 = -Vbs_jct / Vtm0 / NJTS_t; + T1 = lexp(T0 * 1.0e3) - 1.0; + Ibs = Ibs - ASeff * JTSS_t * T1; + end else begin + T0 = -Vbs_jct / Vtm0 / NJTS_t; + T1 = lexp(T0 * VTSS / (VTSS - Vbs_jct)) - 1.0; + Ibs = Ibs - ASeff * JTSS_t * T1; + end + end + if (JTSSWS_t > 0.0) begin + if ((VTSSWS - Vbs_jct) < (VTSSWS * 1.0e-3)) begin + T0 = -Vbs_jct / Vtm0 / NJTSSW_t; + T1 = lexp(T0 * 1.0e3) - 1.0; + Ibs = Ibs - PSeff * JTSSWS_t * T1; + end else begin + T0 = -Vbs_jct / Vtm0 / NJTSSW_t; + T1 = lexp(T0 * VTSSWS / (VTSSWS - Vbs_jct)) - 1.0; + Ibs = Ibs - PSeff * JTSSWS_t * T1; + end + end + if (JTSSWGS_t > 0.0) begin + if((VTSSWGS - Vbs_jct) < (VTSSWGS * 1.0e-3)) begin + T0 = -Vbs_jct / Vtm0 / NJTSSWG_t; + T1 = lexp(T0 * 1.0e3) - 1.0; + Ibs = Ibs - Weffcj * NF * JTSSWGS_t * T1; + end else begin + T0 = -Vbs_jct / Vtm0 / NJTSSWG_t; + T1 = lexp(T0 * VTSSWGS / (VTSSWGS - Vbs_jct)) - 1.0; + Ibs = Ibs - Weffcj * NF * JTSSWGS_t * T1; + end + end + + // Drain-side Junction Current + if (Isbd > 0.0) begin + if (Vbd_jct < VjdmRev) begin + T0 = Vbd_jct / Nvtmd; + T1 = lexp(T0) - 1.0; + T2 = IVjdmRev + DslpRev * (Vbd_jct - VjdmRev); + Ibd = T1 * T2; + end else if (Vbd_jct <= VjdmFwd) begin + T0 = Vbd_jct / Nvtmd; + T1 = (BVD + Vbd_jct) / Nvtmd; + T2 = lexp(-T1); + Ibd = Isbd * (lexp(T0) + XExpBVD - 1.0 - XJBVD * T2); + end else begin + Ibd = IVjdmFwd + DslpFwd * (Vbd_jct - VjdmFwd); + end + end else begin + Ibd = 0.0; + end + + // Drain-side junction tunneling current + if (JTSD_t > 0.0) begin + if ((VTSD - Vbd_jct) < (VTSD * 1.0e-3)) begin + T0 = -Vbd_jct / Vtm0 / NJTSD_t; + T1 = lexp(T0 * 1.0e3) - 1.0; + Ibd = Ibd - ADeff * JTSD_t * T1; + end else begin + T0 = -Vbd_jct / Vtm0 / NJTSD_t; + T1 = lexp(T0 * VTSD/ (VTSD - Vbd_jct)) - 1.0; + Ibd = Ibd - ADeff * JTSD_t * T1; + end + end + if (JTSSWD_t > 0.0) begin + if ((VTSSWD - Vbd_jct) < (VTSSWD * 1.0e-3)) begin + T0 = -Vbd_jct / Vtm0 / NJTSSWD_t; + T1 = lexp(T0 * 1.0e3) - 1.0; + Ibd = Ibd - PDeff * JTSSWD_t * T1; + end else begin + T0 = -Vbd_jct / Vtm0 / NJTSSWD_t; + T1 = lexp(T0 * VTSSWD / (VTSSWD - Vbd_jct)) - 1.0; + Ibd = Ibd - PDeff * JTSSWD_t * T1; + end + end + if (JTSSWGD_t > 0.0) begin + if ((VTSSWGD - Vbd_jct) < (VTSSWGD * 1.0e-3)) begin + T0 = -Vbd_jct / Vtm0 / NJTSSWGD_t; + T1 = lexp(T0 * 1.0e3) - 1.0; + Ibd = Ibd - Weffcj * NF * JTSSWGD_t * T1; + end else begin + T0 = -Vbd_jct / Vtm0 / NJTSSWGD_t; + T1 = lexp(T0 * VTSSWGD / (VTSSWGD - Vbd_jct)) - 1.0; + Ibd = Ibd - Weffcj * NF * JTSSWGD_t * T1; + end + end + + // Junction capacitance (no swapping) + // Source Bulk Junction + Czbs = CJS_t * ASeff; + Czbssw = CJSWS_t * PSeff; + Czbsswg = CJSWGS_t * Weffcj * NF; + czbs_p1 = pow(0.1, -MJS); + czbs_p2 = 1.0 / (1.0 - MJS) * (1.0 - 0.05 * MJS * (1.0 + MJS) * czbs_p1); + czbssw_p1 = pow(0.1, -MJSWS); + czbssw_p2 = 1.0 / (1.0 - MJSWS) * (1.0 - 0.05 * MJSWS * (1.0 + MJSWS) * czbssw_p1); + czbsswg_p1 = pow(0.1, -MJSWGS); + czbsswg_p2 = 1.0 / (1.0 - MJSWGS) * (1.0 - 0.05 * MJSWGS * (1.0 + MJSWGS) * czbsswg_p1); + `JunCap(Czbs, Vbs_jct, PBS_t, MJS, czbs_p1, czbs_p2, Qbsj1) + `JunCap(Czbssw, Vbs_jct, PBSWS_t, MJSWS, czbssw_p1, czbssw_p2, Qbsj2) + `JunCap(Czbsswg, Vbs_jct, PBSWGS_t, MJSWGS, czbsswg_p1, czbsswg_p2, Qbsj3) + Qbsj = Qbsj1 + Qbsj2 + Qbsj3; + + // Drain Bulk Junction + Czbd = CJD_t * ADeff; + Czbdsw = CJSWD_t * PDeff; + Czbdswg = CJSWGD_t * Weffcj * NF; + czbd_p1 = pow(0.1, -MJD); + czbd_p2 = 1.0 / (1.0 - MJD) * (1.0 - 0.05 * MJD * (1.0 + MJD) * czbd_p1); + czbdsw_p1 = pow(0.1, -MJSWD); + czbdsw_p2 = 1.0 / (1.0 - MJSWD) * (1.0 - 0.05 * MJSWD * (1.0 + MJSWD) * czbdsw_p1); + czbdswg_p1 = pow(0.1, -MJSWGD); + czbdswg_p2 = 1.0 / (1.0 - MJSWGD) * (1.0 - 0.05 * MJSWGD * (1.0 + MJSWGD) * czbdswg_p1); + `JunCap(Czbd, Vbd_jct, PBD_t, MJD, czbd_p1, czbd_p2, Qbdj1) + `JunCap(Czbdsw, Vbd_jct, PBSWD_t, MJSWD, czbdsw_p1, czbdsw_p2, Qbdj2) + `JunCap(Czbdswg, Vbd_jct, PBSWGD_t, MJSWGD, czbdswg_p1, czbdswg_p2, Qbdj3) + Qbdj = Qbdj1 + Qbdj2 + Qbdj3; + + // Sub-Surface Leakage Drain Current + if (SSLMOD != 0) begin + T1 = pow(NDEP_i / 1.0e23, SSLEXP1); + T2 = pow(300.0 / DevTemp, SSLEXP2); + SSL0_NT = SSL0 * lexp(-T1 * T2); + SSL1_NT = SSL1 * T2 * T1; + PHIB_SSL = SSL3 * tanh(lexp(devsign * SSL4 * (V(g, b) - VTH))); + Issl = sigvds * NF * Weff * SSL0_NT * lexp(-SSL1_NT * Leff) * lexp(PHIB_SSL / Vt) * (lexp(SSL2 * Vdsx / Vt) - 1.0); + I(di, si) <+ Issl; + end + + // Harshit's New Flicker Noise Model, Ref : H. Agarwal et. al., IEEE JEDS,Vol. 3, Issue 4, April 2015. + Nt = 4.0 * Vt * `q; + Esatnoi = 2.0 * VSAT_a / ueff; + if (EM <= 0.0) begin + DelClm = 0.0; + end else begin + T0 = (diffVds / litl + EM) / Esatnoi; + DelClm = litl * lln(T0); + if (DelClm < 0.0) begin + DelClm = 0.0; + end + end + Nstar = Vt / `q * (Cox + Cdep + CIT_i); + Nl = 2.0 * nq * Cox * Vt * qdeff / `q; + T0a = `q * `q * `q * Vt * abs(ids) * ueff; + T0b = `q * Vt * ids * ids; + T0c = NOIA + NOIB * Nl + NOIC * Nl * Nl; + T0d = (Nl + Nstar) * (Nl + Nstar); + T0e = NOIA * `q * Vt; + if (FNOIMOD == 1) begin + if(LINTNOI >= (Leff - LH) / 2.0) begin + $strobe("Warning: LINTNOI = %e is too large - Leff for noise is negative. Re-setting LINTNOI = 0.", LINTNOI); + LINTNOI_i = 0.0; + end else begin + LINTNOI_i = LINTNOI; + end + LeffnoiH = Leff; + if (Leff < LH) begin + LeffnoiH = LH; + end + vgfbh = (Vg - VFB_i) / Vt; + gam_h = sqrt(2.0 * `q * epssi * HNDEP / Vt) / Cox; + phib_h = ln(HNDEP / ni); + + // Pinch-Off potential for halo region + `PO_psip(vgfbh, gam_h, 0, phib_h, psiph) + + // normalized inversion charge at source end of halo MOSFET + `BSIM_q(psiph, phib_h, vs, gam_h, qsh) + nq_h = 1.0 + gam_h / (2.0 * sqrt(psiph)); + + // Setting mobility of Halo region equal to the mobility of the channel. In general, U0H 0.0) begin + FNPowerAt1Hz_ch = (Ssi_ch * Swi_ch) / T7; + end else begin + FNPowerAt1Hz_ch = 0.0; + end + end else begin + FNPowerAt1Hz_ch = 0.0; + end + + // Halo transistor LNS + T8 = NOIA2 * `q * Vt; + T9 = Weff * NF * LH * 1.0e10 * Nstar * Nstar; + Swi_h = T8 / T9 * ids * ids; + T10 = Swi_h; + if (T10 > 0.0) begin + FNPowerAt1Hz_h = Swi_h; + end else begin + FNPowerAt1Hz_h = 0.0; + end + + // Overall noise + FNPowerAt1Hz = FNPowerAt1Hz_ch * CF_ch + FNPowerAt1Hz_h * CF_h; + I(di, si) <+ flicker_noise(FNPowerAt1Hz, EF, "1overf"); + end else begin + //Parameter checking + if (LINTNOI >= Leff/2.0) begin + $strobe("Warning: LINTNOI = %e is too large - Leff for noise is negative. Re-setting LINTNOI = 0.", LINTNOI); + LINTNOI_i = 0.0; + end else begin + LINTNOI_i = LINTNOI; + end + if (NOIA > 0 || NOIB > 0 || NOIC > 0) begin + Leffnoi = Leff - 2.0 * LINTNOI_i; + Leffnoisq = Leffnoi * Leffnoi; + T0 = 1.0e10 * Cox * Leffnoisq; + N0 = 2.0 * nq * Cox * Vt * qs / `q; + T1 = NOIA * lln((N0 + Nstar) / (Nl + Nstar)); + T2 = NOIB * (N0 - Nl); + T3 = 0.5 * NOIC * (N0 * N0 - Nl * Nl); + T4 = 1.0e10 * Leffnoisq * Weff * NF; + Ssi = T0a / T0 * (T1 + T2 + T3) + T0b / T4 * DelClm * T0c / T0d; + T5 = Weff * NF * Leffnoi * 1.0e10 * Nstar * Nstar; + Swi = T0e / T5 * ids * ids; + T6 = Swi + Ssi; + if (T6 > 0.0) begin + FNPowerAt1Hz = (Ssi * Swi) / T6; + end else begin + FNPowerAt1Hz = 0.0; + end + end else begin + FNPowerAt1Hz = 0.0; + end + I(di, si) <+ flicker_noise(FNPowerAt1Hz, EF, "1overf"); + end + T0 = qia / Esatnoi / Leff; + T1 = T0 * T0; + T3 = RNOIA * (1.0 + TNOIA * Leff * T1); + T4 = RNOIB * (1.0 + TNOIB * Leff * T1); + T5 = RNOIK * (1.0 + TNOIK * Leff * T1); + ctnoi = RNOIC * (1.0 + TNOIC * Leff * T1); + betanoisq = 3.0 * T3 * T3; + betanoisq = (betanoisq - 1.0) * exp(-Leff / LP) + 1.0; + betaLowId = T5 * T5; + thetanoisq = T4 * T4; + cm_igid = 0.0; + case (TNOIMOD) + 0: begin + QSi = -NF * Weff * Leff * Cox * Vt * Qs; + QDi = -NF * Weff * Leff * Cox * Vt * Qd; + T0 = ueff * abs(QSi + QDi); + T1 = T0 * Rdsi + Leff * Leff; + Gtnoi = (T0 / T1) * NTNOI; + sidn = Nt * Gtnoi; + I(di, si) <+ white_noise(sidn, "id"); + V(N1) <+ 0.0; + end + 1: begin + Vtn = 2.0 * nq * nVt; + T0 = ueff * Dptwg * Moc * Cox * Vtn; + T1 = 0.5 * (qs + qdeff); + T3 = T1 + 0.5; + T4 = T3 * T3; + T5 = T4 * T3; + T6 = qs - qdeff; + T7 = T6 * T6; + T8 = T7 * T6; + T9 = (6.0 * T1 + 0.5) * T7; + Lvsat = Leff * Dptwg; + T10 = Lvsat / Leff; + T12 = 1.0 + (betaLowId * (Vdseff / Vdssat) / (TNOIK2 + qia)); + T12 = ((T12 - 1.0) * exp(-Leff / LP)) + 1.0; + `Smooth(T12, 0, 1.0e-1, T12) + mid = T0 * NF * Weff / Lvsat * (T1 * T12 + T7 * betanoisq / (12.0 * T3)); + mig = Lvsat * T10 * T10 * (T1 / T4 - T9 / (60.0 * T4 * T4) + T7 * T7 / (144.0 * T4 * T5)) * 15.0 / 4.0 * thetanoisq / (NF * Weff * 12.0 * T0); + migid = T10 * (T6 / (12.0 * T3) - T8 / (144.0 * T5)) * ctnoi / 0.395; + sqid = sqrt(Nt * mid); + if (mig == 0.0) begin + sqig = 0.0; + cm_igid = 0.0; + end else begin + sqig = sqrt(Nt / mig); + if (sqid == 0.0) begin + cm_igid = 0.0; + end else begin + cm_igid = migid * sqig / sqid; + end + end + I(N2) <+ white_noise(cm_igid, "corl"); + I(NI) <+ white_noise(sqig * sqig * (1.0 - cm_igid), "corl"); + I(NI) <+ -sqig * V(N2); + I(NC) <+ ddt(mig * Cox * Weff * NF * Leff * V(NC)); + I(di, si) <+ white_noise(sqid * sqid * (1.0 - cm_igid), "id"); + I(di, si) <+ sqid * V(N2); + I(gi, si) <+ ddt(0.5 * ((1.0 + sigvds) * mig * Cox * Weff * NF * Leff * V(NC))); + I(gi, di) <+ ddt(0.5 * ((1.0 - sigvds) * mig * Cox * Weff * NF * Leff * V(NC))); + end + endcase + I(N2) <+ V(N2); + I(NR) <+ V(NR); + + // Gate current shot noise + if (IGCMOD != 0) begin + I(gi, si) <+ white_noise(2.0 * `q * abs(igcs + igs), "igs"); + I(gi, di) <+ white_noise(2.0 * `q * abs(igcd + igd), "igd"); + end + if (IGBMOD != 0) begin + I(gi, bi) <+ white_noise(2.0 * `q * abs(igb), "igb"); + end + + // C-V model + vgfbCV = vgfb; + gamg2 = (2.0 * `q * epssi * NGATE_i) / (Cox * Cox * Vt); + invgamg2 = (NGATE_i > 0.0) ? (1.0 / gamg2) : 0.0; + if (CVMOD == 1) begin + VFBCV_i = VFBCV_i + DELVTO; + vg = Vg * inv_Vt; + vs = Vs * inv_Vt; + vfb = VFBCV_i * inv_Vt; + vgfbCV = vg - vfb; + phib = lln(NDEPCV_i / ni); + // Normalized body factor + gam = sqrt(2.0 * `q * epssi * NDEPCV_i * inv_Vt) / Cox; + inv_gam = 1.0 / gam; + gamg2 = (2.0 * `q * epssi * NGATE_i) / (Cox * Cox * Vt); + invgamg2 = (NGATE_i > 0.0) ? (1.0 / gamg2) : 0.0; + DPD = (NGATE_i > 0.0) ? (NDEPCV_i / NGATE_i) : 0.0; + + // psip: pinch-off voltage + `PO_psip(vgfbCV, gam, DPD, phib, psip) + + // normalized inversion charge at source end of channel + `BSIM_q(psip, phib, vs, gam, qs) + `Smooth(psip, 1.0, 2.0, psipclamp) + sqrtpsip = sqrt(psipclamp); + + // source side surf pot. + psiavg = psip - 2.0 * qs; + `Smooth(psiavg, 1.0, 2.0, T0) + nq = 1.0 + gam / (sqrtpsip + sqrt(T0)); + + // Drain Saturation Voltage + T0 = Vt * (vgfbCV - psip - 2.0 * qs * (nq - 1.0)); + `Smooth(T0, 0, 0.1, qbs) + + // Source side qi and qb for Vdsat- normalized to Cox + qis = 2.0 * nq * Vt * qs; + Eeffs = EeffFactor * (qbs + eta_mu * qis); // in the unit of MV/cm + + // Ref: BSIM4 Model mobility model + T3 = (UA_a + UC_a * Vbsx) * pow(Eeffs, EU_i); + T4 = 1.0 + T3; + `Smooth(T4, 1.0, 0.0015, Dmobs) + LambdaC_by2 = (U0_a / Dmobs) * Vt / (VSATCV_t * Lact); + qdsat = LambdaC_by2 * (qs * qs + qs) / (1.0 + LambdaC_by2 * (1.0 + qs)); + vdsatcv = psip - 2.0 * phib - (2.0 * qdsat + lln((qdsat * 2.0 * nq * inv_gam) * ((qdsat * 2.0 * nq * inv_gam) + (gam / (nq - 1.0))))); + VdsatCV = vdsatcv * Vt; + + // Normalized charge qdeff at drain end of channel + `Smooth(VdsatCV - Vs, 0.0, 1e-3, VdssatCV) + T7 = pow(Vds / VdssatCV , 1.0 / DELTA_t); + T8 = pow(1.0 + T7, -DELTA_t); + Vdseff = Vds * T8; + vdeff = (Vdseff + Vs) * inv_Vt; + `BSIM_q(psip, phib, vdeff, gam, qdeff) + + // Reevaluation of nq to include qdeff needed for gummel symmetry + psiavg = psip - qs - qdeff - 1.0; + `Smooth(psiavg, 1.0, 2.0, T0) + T2 = sqrt(T0); + T3 = 1.0 + DPD + gam / (sqrtpsip + T2); + T4 = 0.5 + DPD * T2 * inv_gam; + T5 = sqrt(T4 * T4 + T3 * (qs + qdeff) * invgamg2); + nq = T3 / (T4 + T5); + + // CV Expressions including Velocity Saturation and CLM + // Velocity Saturation for CV + T0 = Vt * (vgfbCV - psip - 2.0 * qs * (nq - 1.0)); + `Smooth(T0, 0, 0.1, qbs) + T1 = Vt * (vgfbCV - psip - 2.0 * qdeff * (nq - 1.0)); + `Smooth(T1, 0, 0.1, qbd) + qb = 0.5 * (qbs + qbd); + qia = nq * Vt * (qs + qdeff); + Eeffm = EeffFactor * (qb + eta_mu * qia); + T3 = (UA_a + UC_a * Vbsx) * pow(Eeffm, EU_i); + T4 = 1.0 + T3; + `Smooth(T4, 1.0, 0.0015, Dmob) + LambdaC = 2.0 * (U0_a / Dmob) * Vt / (VSATCV_t * Lact); + dps = qs - qdeff; + T1 = 2.0 * (LambdaC * dps) * (LambdaC * dps); + zsat = sqrt(1.0 + T1); + Dvsat = 0.5 * (1.0 + zsat); + // CLM for CV + Esat = 2.0 * VSATCV_t / (U0_a / Dmob); + EsatL = Esat * Lact; + Vasat = VdssatCV + EsatL; + diffVds = Vds - Vdseff; + end + if (PCLMCV_i != 0.0) begin + MdL = 1.0 + PCLMCV_i * lln(1.0 + diffVds / PCLMCV_i / Vasat); + end else begin + MdL = 1.0; + end + MdL_2 = MdL * MdL; + inv_MdL = 1.0 / MdL; + inv_MdL_2 = 1.0 / MdL_2; + MdL_less_1 = MdL - 1.0; + vgpqm = vgfbCV - psip; + DQSD = (qs - qdeff); + DQSD2 = (qs - qdeff) * (qs - qdeff); + sis = vgpqm + 2.0 * qs; + sid = vgpqm + 2.0 * qdeff; + `Smooth(sis, 0.0, 0.5, T1) + `Smooth(sid, 0.0, 0.5, T2) + Temps = sqrt(0.25 + T1 * invgamg2); + Tempd = sqrt(0.25 + T2 * invgamg2); + T1 = sis / (1.0 + 2.0 * Temps); + T2 = sid / (1.0 + 2.0 * Tempd); + T3 = Temps + Tempd; + T4 = `Oneby3 * (DQSD2 / (T3 * T3 * T3)); + T5 = (Dvsat * inv_MdL) / (1.0 + qs + qdeff); + T6 = 0.8 * (T3 * T3 + Temps * Tempd) * T5; + T7 = T6 + (2.0 * invgamg2); + T8 = `Oneby3 * DQSD2 * T5; + dqgeff = sid * (2.0 * Tempd - 1.0) / (2.0 * Tempd + 1.0); + qbeff = vgpqm - 2.0 * (nq - 1.0) * qdeff + dqgeff; + Qb = inv_MdL * (T1 + T2 + (T4 * T7 - nq * (qs + qdeff + T8))) + MdL_less_1 * qbeff; + T9 = qs + qdeff; + T10 = DQSD2 * T5 * T5; + Qi = nq * inv_MdL * (T9 + `Oneby3 * DQSD2 * T5) + 2.0 * nq * MdL_less_1 * qdeff; + Qd1 = nq * inv_MdL_2 * (0.5 * T9 - (DQSD / 6.0) * (1.0 - DQSD * T5 - 0.2 * T10)); + Qd2 = nq * (MdL - inv_MdL) * qdeff; + Qd = Qd1 + Qd2; + Qs = Qi - Qd; + + // Quantum Mechanical Effect + `Smooth(Vt*Qb, 0, 0.1, qbaCV) + qiaCV = Vt *( Qs + Qd); + T0 = (qiaCV + ETAQM * qbaCV) / QM0; + T1 = 1.0 + pow(T0, 0.7 * BDOS); + XDCinv = ADOS * 1.9e-9 / T1; + Coxeffinv = 3.9 * `EPS0 / (BSIMBULKTOXP * 3.9 / EPSROX + XDCinv / epsratio); + QBi = -NF * Wact * Lact * (`EPS0 * EPSROX / BSIMBULKTOXP) * Vt * Qb; + WLCOXVtinv = NF * Wact * Lact * Coxeffinv * Vt; + QSi = -WLCOXVtinv * Qs; + QDi = -WLCOXVtinv * Qd; + QGi = -(QBi + QSi + QDi); + + // Outer fringing capacitance + if (!$param_given(CF)) begin + CF_i = 2.0 * EPSROX * `EPS0 / `M_PI * lln(CFRCOEFF * (1.0 + 0.4e-6 / TOXE)); + end + Cgsof = CGSO + CF_i; + Cgdof = CGDO + CF_i; + + // Overlap capacitance + if (COVMOD == 0) begin + Qovs = -Wact * NF * Cgsof * Vgs_ov_noswap; + Qovd = -Wact * NF * Cgdof * Vgd_ov_noswap; + end else begin + T0 = sqrt((Vgs_ov_noswap - Vfbsdr + `DELTA_1) * (Vgs_ov_noswap -Vfbsdr + `DELTA_1) + 4.0 * `DELTA_1); + Vgsov = 0.5 * (Vgs_ov_noswap - Vfbsdr + `DELTA_1 - T0); + T1 = sqrt(1.0 - 4.0 * Vgsov / CKAPPAS_i); + Qovs = -Wact * NF * (Cgsof * Vgs_ov_noswap + CGSL_i * (Vgs_ov_noswap -Vfbsdr - Vgsov - 0.5 * CKAPPAS_i * (-1.0 + T1))); + T0 = sqrt((Vgd_ov_noswap - Vfbsdr + `DELTA_1) * (Vgd_ov_noswap - Vfbsdr + `DELTA_1) + 4.0 * `DELTA_1); + Vgdov = 0.5 * (Vgd_ov_noswap - Vfbsdr + `DELTA_1 - T0); + T2 = sqrt(1.0 - 4.0 * Vgdov / CKAPPAD_i); + Qovd = -Wact * NF * (Cgdof * Vgd_ov_noswap + CGDL_i * (Vgd_ov_noswap - Vfbsdr - Vgdov - 0.5 * CKAPPAD_i * (-1.0 + T2))); + end + Qovb = -devsign * NF * Lact * CGBO * V(gm, bi); + Qovg = -(Qovs + Qovd + Qovb); + + // Edge FET model + if (EDGEFET == 1) begin + NFACTOREDGE_t = NFACTOREDGE_i * hypsmooth((1.0 + TNFACTOREDGE_i * (TRatio - 1.0)), 1e-3); + ETA0EDGE_t = ETA0_EDGE * (1.0 + TETA0EDGE_i * (TRatio - 1.0)); + cdsc = CITEDGE_i + NFACTOREDGE_t + CDSCDEDGE_i * Vdsx - CDSCBEDGE_i * Vbsx; + T1 = 1.0 + cdsc/Cox; + `Smooth(T1, 1.0, 0.05, n) + nVt = n * Vt; + inv_nVt = 1.0 / nVt; + vg = Vg * inv_nVt; + vs = Vs * inv_nVt; + vfb = VFB_i * inv_nVt; + dvth_dibl = -(ETA0EDGE_t + ETABEDGE_i * Vbsx) * Vdsx; + dvth_temp = (KT1EDGE_i + KT1LEDGE_i / Leff + KT2EDGE_i * Vbsx) * (pow(TRatio, KT1EXPEDGE_i) - 1.0); + litl_edge = litl * (1.0 + DVT2EDGE * Vbsx); + T0 = DVT1EDGE * Leff / litl_edge; + if (T0 < 40.0) begin + theta_sce_edge = 0.5 * DVT0EDGE / (cosh(T0) - 1.0); + end else begin + theta_sce_edge = DVT0EDGE * lexp(-T0); + end + dvth_sce = theta_sce_edge * (Vbi - Phist); + Vth_shift = dvth_dibl - dvth_temp + dvth_sce + DVTEDGE + vth0_stress_EDGE - K2_EDGE * Vbsx; + vgfb = vg - vfb - Vth_shift * inv_nVt; + + // Normalized body factor + DGAMMAEDGE_i = DGAMMAEDGE * (1.0 + DGAMMAEDGEL * pow(Leff, -DGAMMAEDGELEXP)); + gam = sqrt(2.0 * `q * epssi * NDEP_i * inv_nVt) / Cox; + gam = gam * (1.0 + DGAMMAEDGE_i); + inv_gam = 1.0 / gam; + phib_n = phib / n; + `PO_psip(vgfb, gam, 0, phib_n, psip) + `BSIM_q(psip, phib_n, vs, gam, qs) + + // Approximate Pinch Off voltage + vdsatedge = 2.0 * nVt * qs + 2.0 * nVt; + Vdsatedge = vdsatedge; + Vdsatedge = Vdsatedge + Vs; + + // Vdssat clamped to avoid negative values during transient simulation + `Smooth(Vdsatedge - Vs, 0.0, 1.0e-3, Vdssate) + T7 = pow(Vds / Vdssate , 1.0 / DELTA_t); + T8 = pow(1.0 + T7, -DELTA_t); + Vdseff = Vds * T8; + vdeff = (Vdseff + Vs) * inv_nVt; + `BSIM_q(psip, phib_n, vdeff, gam, qdeff) + + // Nq calculation for Edge FET + `Smooth(psip, 1.0, 2.0, psipclamp) + sqrtpsip = sqrt(psipclamp); + psiavg = psip - qs - qdeff -1.0; + `Smooth(psiavg, 1.0, 2.0, T0) + T2 = sqrt(T0); + nq = 1.0 + gam / (sqrtpsip + T2); + ids_edge = 2.0 * NF * nq * ueff * WEDGE / Leff * Cox * nVt * nVt *((qs - qdeff)*(1.0 + qs + qdeff)) *Moc; + ids = ids_edge + ids; + end + + // Edge FET Parasitic Device Drain Current Model Ends + // Charge expressions including fringing and overlap capacitance + QB = devsign * (QBi + Qovb + Qbsj + Qbdj); + if (sigvds > 0) begin + QSI = devsign * QSi; + QDI = devsign * QDi; + QS = devsign * (QSi + Qovs - Qbsj); + QD = devsign * (QDi + Qovd - Qbdj); + end else begin + QSI = devsign * QDi; + QDI = devsign * QSi; + QS = devsign * (QDi + Qovs - Qbsj); + QD = devsign * (QSi + Qovd - Qbdj); + end + QG = devsign * (QGi + Qovg); + + // Output + // Intrinsic Charges + QBI = devsign * QBi; + QGI = devsign * QGi; + + // QSI and QDI are defined above + // Intrinsic Capacitances + CGSI = -ddx(QGI,V(si)); + CGDI = -ddx(QGI,V(di)); + CGBI = -ddx(QGI,V(bi)); + CGGI = ddx(QGI,V(gi)); + CSSI = ddx(QSI,V(si)); + CSDI = -ddx(QSI,V(di)); + CSBI = -ddx(QSI,V(bi)); + CSGI = -ddx(QSI,V(gi)); + CDSI = -ddx(QDI,V(si)); + CDDI = ddx(QDI,V(di)); + CDBI = -ddx(QDI,V(bi)); + CDGI = -ddx(QDI,V(gi)); + CBSI = -ddx(QBI,V(si)); + CBDI = -ddx(QBI,V(di)); + CBBI = ddx(QBI,V(bi)); + CBGI = -ddx(QBI,V(gi)); + + // Total Capacitances + CGS = -ddx(QG, V(si)); + CGD = -ddx(QG, V(di)); + CGB = -ddx(QG, V(bi)); + CGG = CGGI + ddx(devsign * Qovg, V(gm)); + CSS = ddx(QS, V(si)); + CSD = -ddx(QS, V(di)); + CSB = CSBI - ddx((QS - QSI), V(sbulk)); + CSG = CSGI - ddx((QS - QSI), V(gm)); + CDS = -ddx(QD, V(si)); + CDD = ddx(QD, V(di)); + CDB = CDBI - ddx((QD - QDI), V(dbulk)); + CDG = CDGI - ddx((QD - QDI), V(gm)); + CBS = -ddx(QB, V(si)); + CBD = -ddx(QB, V(di)); + CBB = CBBI + ddx(QB, V(sbulk)) + ddx(QB, V(dbulk)) + ddx((devsign * Qovb), V(bi)); + CBG = -ddx(QB, V(gi)) - ddx((devsign * Qovb), V(gm)); + + // Total extrinsic capacitance + CGSEXT = -devsign * ddx(Qovg, V(si)); // Gate-Source Overlap + outer fringing + CGDEXT = -devsign * ddx(Qovg, V(di)); // Gate-Drain Overlap + outer fringing + CGBOV = -devsign * ddx(Qovg, V(bi)); // Gate-Body Overlap + + // Total Source/Drain Junction Capacitances + CAPBS = -devsign * ddx(Qbsj, V(si)); + CAPBD = -devsign * ddx(Qbdj, V(di)); + + // W & L + WEFF = Weff; // Effective width for IV + LEFF = Leff; // Effective length for IV + WEFFCV = Wact; // Effective width for CV + LEFFCV = Lact; // Effective length for CV + + // Currents and derivatives + if (sigvds > 0) begin + IDS = devsign * ids; // Intrinsic drain to source current + IDEFF = IDS - (IGD + IGCD) + ISUB + IGIDL; // Total drain current + ISEFF = -IDS - (IGS + IGCS) + IGISL; // Total source current + end else begin + IDS = -devsign * ids; // Intrinsic drain to source current + IDEFF = IDS - (IGD + IGCD) + IGIDL; // Total drain current + ISEFF = -IDS - (IGS + IGCS) + ISUB + IGISL; // Total source current + end + IGEFF = IGB + IGS + IGCS + IGD + IGCD;//Total gate tunneling current + IBS = -devsign * Ibs; // Source junction current + IBD = -devsign * Ibd; // Source junction current + VDS = V(di, si); // Drain-Source Voltage + VGS = V(gi, si); + VBS = -V(si, bi); // Source-body Voltage + VDSAT = Vdssat; // Drain-Source saturation Voltage + GM = ddx(IDS, V(gi)); // Transconductance + GMBS = ddx(IDS, V(bi)); // Body transconductance + GDS = ddx(IDS, V(di)); // Output conductance + + // Loading variables + I(gi, bi) <+ ddt(QGI); + I(si, bi) <+ ddt(QSI); + I(di, bi) <+ ddt(QDI); + I(gm, si) <+ ddt(-devsign * Qovs); + I(gm, di) <+ ddt(-devsign * Qovd); + I(gm, bi) <+ ddt(-devsign * Qovb); + + // Drain to source current + I(di, si) <+ devsign * sigvds * ids; + + if (IGBMOD != 0) begin + I(gi, bi) <+ IGB; + end + if (IGCMOD != 0) begin + I(gi, si) <+ (IGS + IGCS); + I(gi, di) <+ (IGD + IGCD); + end + if (sigvds > 0) begin + I(di, bi) <+ ISUB + IGIDL; + I(si, bi) <+ IGISL; + end else begin + I(di, bi) <+ IGIDL; + I(si, bi) <+ ISUB + IGISL; + end + + // External S/D Resistance + if (RDSMOD != 2) begin + gdpr = 1.0 / Rdrain; // Note: gdpr considers all fingers + gspr = 1.0 / Rsource; // Note: gspr considers all fingers + I(d, di) <+ V(d, di) * gdpr; + I(s, si) <+ V(s, si) * gspr; + I(d, di) <+ white_noise(Nt * gdpr, "rd"); + I(s, si) <+ white_noise(Nt * gspr, "rs"); + end else begin + V(d, di) <+ 0.0; + V(s, si) <+ 0.0; + end + if (RGATEMOD == 0) begin + V(g, gm) <+ 0.0; + end else begin: rgate + if (RGATEMOD == 2) begin + Ggate = Gcrg; + Gnoise = Gcrg * Gcrg / Grgeltd; + end else begin + Ggate = Grgeltd; + Gnoise = Grgeltd; + end + I(g, gm) <+ V(g, gm) * Ggate; + I(g, gm) <+ white_noise(Nt * Gnoise, "rg"); + end + if (RGATEMOD == 3) begin + I(gm, gi) <+ V(gm, gi) * Gcrg; + end else begin + V(gm, gi) <+ 0; + end + if ((SHMOD != 0) && (RTH0 > 0.0)) begin + if (RDSMOD != 2) begin + Pwr(t) <+ -(devsign * sigvds * ids * V(di, si) + V(d,di) * V(d,di) / Rdrain + V(s,si) * V(s,si) / Rsource) + delTemp1 * gth; + end else begin + Pwr(t) <+ -(devsign * sigvds * ids * V(di, si)) + delTemp1 * gth; + end + Pwr(t) <+ ddt(delTemp1 * cth); + end else begin + Temp(t) <+ 0.0; + end + if (RBODYMOD != 0) begin + I(bi, sbulk) <+ V(bi, sbulk) * Grbps; + I(b, sbulk) <+ V(b, sbulk) * Grbsb; + I(b, bi) <+ V(b, bi) * Grbpb; + I(b, dbulk) <+ V(b, dbulk) * Grbdb; + I(bi, dbulk) <+ V(bi, dbulk) * Grbpd; + I(sbulk, bi) <+ white_noise(Nt * Grbps, "rbps"); + I(sbulk, b) <+ white_noise(Nt * Grbsb, "rbsb"); + I(b, bi) <+ white_noise(Nt * Grbpb, "rbpb"); + I(dbulk, bi) <+ white_noise(Nt * Grbpd, "rbpd"); + I(dbulk, b) <+ white_noise(Nt * Grbdb, "rbdb"); + end else begin + V(b, sbulk) <+ 0.0; + V(b, bi) <+ 0.0; + V(b, dbulk) <+ 0.0; + end + + // Diode Current and Capacitance + if (RBODYMOD != 0) begin + I(sbulk, si) <+ devsign * Ibs; + I(dbulk, di) <+ devsign * Ibd; + I(sbulk, si) <+ devsign * ddt(Qbsj); + I(dbulk, di) <+ devsign * ddt(Qbdj); + end else begin + I(bi, si) <+ devsign * Ibs; + I(bi, di) <+ devsign * Ibd; + I(bi, si) <+ devsign * ddt(Qbsj); + I(bi, di) <+ devsign * ddt(Qbdj); + end +end +endmodule diff --git a/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg.va b/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg.va new file mode 100644 index 000000000..5f15f3875 --- /dev/null +++ b/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg.va @@ -0,0 +1,117 @@ +// ******************************************************** +// **** BSIM-CMG 110.0.0 released by Sourabh Khandelwal on 01/01/2016 *****/ +// * BSIM Common Multi-Gate Model Equations (Verilog-A) +// ******************************************************** +// +// ******************************************************** +// * Copyright 2016 Regents of the University of California. +// * All rights reserved. +// * +// * Project Director: Prof. Chenming Hu. +// * Authors: Sriramkumar V., Navid Paydavosi, Juan Duarte, Darsen Lu, Sourabh Khandelwal +// * Chung-Hsun Lin, Mohan Dunga, Shijing Yao, +// * Ali Niknejad, Chenming Hu +// ******************************************************** +// ******************************************************** +// * NONDISCLOSURE STATEMENT +// 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 of California owns the copyright and grants users a perpetual, +// irrevocable, worldwide, non-exclusive, royalty-free license with +// respect to the software as set forth below. +// 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 University of California 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 +// Agreed to on __Jan 01, 2016__________________ +// By: ___University of California, Berkeley____ +// ___Chenming Hu_____________________ +// ___Professor in Graduate School _______ +// ******************************************************** + + +`include "constants.vams" +`include "disciplines.vams" + +/**************************************************************/ +/* SHMOD is a model parameter */ +/* SHMOD = 1 : Self-heating turned on */ +/* SHMOD = 0 : Self-heating turned off */ +/* */ +/* RDSMOD is a model parameter */ +/* RDSMOD = 1 : External source/drain resistance model */ +/* RDSMOD = 0 : Internal source/drain resistance model */ +/* RDSMOD = 2 : Internal Bias Dependent and Bias Independent part of source/drain resistance */ +/* */ +/* NQSMOD is a model parameter */ +/* NQSMOD = 1 : NQS Resistance / gi node turned on */ +/* NQSMOD = 0 : NQS Resistance / gi node turned off */ +/* */ +/* RGATEMOD is a model parameter */ +/* RGATEMOD = 1 : Gate Resistance / ge node turned on */ +/* RGATEMOD = 0 : Gate Resistance / ge node turned off */ +/**************************************************************/ +// +// In Verilog-A the number of internal nodes cannot be controlled by +// a model parameter. Therefore we use `define statements +// to control it. Comment the following lines whenever +// possible for best computational efficiency. +`define __OPINFO__ +`define __DEBUG__ +`define __SHMOD__ +`define __RDSMOD__ +//`define __NQSMOD1__ +//`define __NQSMOD2__ +`define __RGATEMOD__ +`define __TNOIMOD1__ //Correlated Thermal Noise Switch + +`include "common_defs.include" +`include "bsimcmg_cfringe.include" + + +module bsimcmg(d, g, s, e, t); + inout g, d, s, e, t; + electrical g, d, s, e; + electrical si, di; + +`ifdef __NQSMOD1__ + electrical gi; +`endif + +`ifdef __NQSMOD2__ + electrical q; +`endif + +`ifdef __RGATEMOD__ + electrical ge; +`endif + +`ifdef __SHMOD__ + thermal t; + branch (t) rth_branch; + branch (t) ith_branch; +`else + thermal t; +`endif + +// Internal node controlled by Correlated Thermal Noise Switch +`ifdef __TNOIMOD1__ + electrical N; +`endif + +`include "bsimcmg_body.include" + + +endmodule + diff --git a/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_binning_parameters.include b/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_binning_parameters.include new file mode 100644 index 000000000..f55c5d9ed --- /dev/null +++ b/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_binning_parameters.include @@ -0,0 +1,756 @@ +// ******************************************************** +// **** BSIM-CMG 110.0.0 released by Sourabh Khandelwal on 01/01/2016 ****/ +// * BSIM Common Multi-Gate Model Equations (Verilog-A) +// ******************************************************** +// +// ******************************************************** +// * Copyright 2016 Regents of the University of California. +// * All rights reserved. +// * +// * Project Director: Prof. Chenming Hu. +// * Authors: Sriramkumar V., Navid Paydavosi, Juan Duarte, Darsen Lu, Sourabh Khandelwal +// * Chung-Hsun Lin, Mohan Dunga, Shijing Yao, +// * Ali Niknejad, Chenming Hu +// ******************************************************** +// ******************************************************** +// * NONDISCLOSURE STATEMENT +// 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 of California owns the copyright and grants users a perpetual, +// irrevocable, worldwide, non-exclusive, royalty-free license with +// respect to the software as set forth below. +// 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 University of California 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 +// Agreed to on __Jan 01, 2016_________________ +// By: ___University of California, Berkeley____ +// ___Chenming Hu_____________________ +// ___Professor in Graduate School _______ +// ******************************************************** +`MPRnb( LNBODY ,0.0 ,"m^-2" ,"" ) +`MPRnb( NNBODY ,0.0 ,"m^-2" ,"" ) +`MPRnb( PNBODY ,0.0 ,"m^-1" ,"" ) + +`MPRnb( LPHIG ,0.0 ,"m*eV" ,"" ) +`MPRnb( NPHIG ,0.0 ,"m*eV" ,"" ) +`MPRnb( PPHIG ,0.0 ,"(m^2)*eV" ,"" ) + +`MPRnb( LNGATE ,0.0 ,"m^-2" ,"" ) +`MPRnb( NNGATE ,0.0 ,"m^-2" ,"" ) +`MPRnb( PNGATE ,0.0 ,"m^-1" ,"" ) + +`MPRnb( LCIT ,0.0 ,"F/m" ,"" ) +`MPRnb( NCIT ,0.0 ,"F/m" ,"" ) +`MPRnb( PCIT ,0.0 ,"F" ,"" ) + +`MPRnb( LCITR ,LCIT ,"" ,"" ) +`MPRnb( NCITR ,NCIT ,"" ,"" ) +`MPRnb( PCITR ,PCIT ,"" ,"" ) + +`MPRnb( LCDSC ,0.0 ,"F/m" ,"" ) +`MPRnb( NCDSC ,0.0 ,"F/m" ,"" ) +`MPRnb( PCDSC ,0.0 ,"F" ,"" ) + +`MPRnb( LCDSCD ,0.0 ,"F/m" ,"" ) +`MPRnb( NCDSCD ,0.0 ,"F/m" ,"" ) +`MPRnb( PCDSCD ,0.0 ,"F" ,"" ) + +`MPRnb( LCDSCDR ,LCDSCD ,"F/m" ,"" ) +`MPRnb( NCDSCDR ,NCDSCD ,"F/m" ,"" ) +`MPRnb( PCDSCDR ,PCDSCD ,"F" ,"" ) + +`MPRnb( LDVT0 ,0.0 ,"" ,"" ) +`MPRnb( NDVT0 ,0.0 ,"" ,"" ) +`MPRnb( PDVT0 ,0.0 ,"" ,"" ) + +`MPRnb( LDVT1 ,0.0 ,"" ,"" ) +`MPRnb( NDVT1 ,0.0 ,"" ,"" ) +`MPRnb( PDVT1 ,0.0 ,"" ,"" ) + +`MPRnb( LDVT1SS ,LDVT1 ,"" ,"" ) +`MPRnb( NDVT1SS ,NDVT1 ,"" ,"" ) +`MPRnb( PDVT1SS ,PDVT1 ,"" ,"" ) + +`MPRnb( LPHIN ,0.0 ,"m*V" ,"" ) +`MPRnb( NPHIN ,0.0 ,"m*V" ,"" ) +`MPRnb( PPHIN ,0.0 ,"(m^2)*V" ,"" ) + +`MPRnb( LETA0 ,0.0 ,"" ,"" ) +`MPRnb( NETA0 ,0.0 ,"" ,"" ) +`MPRnb( PETA0 ,0.0 ,"" ,"" ) + +`MPRnb( LETA0R ,LETA0 ,"" ,"" ) +`MPRnb( NETA0R ,NETA0 ,"" ,"" ) +`MPRnb( PETA0R ,PETA0 ,"" ,"" ) + +`MPRnb( LDSUB ,0.0 ,"" ,"" ) +`MPRnb( NDSUB ,0.0 ,"" ,"" ) +`MPRnb( PDSUB ,0.0 ,"" ,"" ) + +`MPRnb( LK1RSCE ,0.0 ,"m*V^(1/2)" ,"" ) +`MPRnb( NK1RSCE ,0.0 ,"m*V^(1/2)" ,"" ) +`MPRnb( PK1RSCE ,0.0 ,"(m^2)*V^(1/2)" ,"" ) + +`MPRnb( LLPE0 ,0.0 ,"m^2" ,"" ) +`MPRnb( NLPE0 ,0.0 ,"m^2" ,"" ) +`MPRnb( PLPE0 ,0.0 ,"m^3" ,"" ) + +`MPRnb( LDVTSHIFT ,0.0 ,"m*V" ,"" ) +`MPRnb( NDVTSHIFT ,0.0 ,"m*V" ,"" ) +`MPRnb( PDVTSHIFT ,0.0 ,"(m^2)*V" ,"" ) + +`MPRnb( LDVTSHIFTR ,LDVTSHIFT ,"" ,"" ) +`MPRnb( NDVTSHIFTR ,NDVTSHIFT ,"" ,"" ) +`MPRnb( PDVTSHIFTR ,PDVTSHIFT ,"" ,"" ) + +`MPRnb( LPHIBE ,0.0 ,"m*V" ,"" ) +`MPRnb( NPHIBE ,0.0 ,"m*V" ,"" ) +`MPRnb( PPHIBE ,0.0 ,"(m^2)*V" ,"" ) + +`MPRnb( LK0 ,0.0 ,"m*V" ,"" ) +`MPRnb( NK0 ,0.0 ,"m*V" ,"" ) +`MPRnb( PK0 ,0.0 ,"(m^2)*V" ,"" ) + +`MPRnb( LK01 ,0.0 ,"(m*V)/K" ,"" ) +`MPRnb( NK01 ,0.0 ,"(m*V)/K" ,"" ) +`MPRnb( PK01 ,0.0 ,"(m^2*V)/K" ,"" ) + +`MPRnb( LK0SI ,0.0 ,"" ,"" ) +`MPRnb( NK0SI ,0.0 ,"" ,"" ) +`MPRnb( PK0SI ,0.0 ,"" ,"" ) + +`MPRnb( LK0SI1 ,0.0 ,"m/K" ,"" ) +`MPRnb( NK0SI1 ,0.0 ,"m/K" ,"" ) +`MPRnb( PK0SI1 ,0.0 ,"(m^2)/K" ,"" ) + +`MPRnb( LK1 ,0.0 ,"m*V^(1/2)" ,"" ) +`MPRnb( NK1 ,0.0 ,"m*V^(1/2)" ,"" ) +`MPRnb( PK1 ,0.0 ,"(m^2)*V^(1/2)" ,"" ) + +`MPRnb( LK11 ,0.0 ,"(m*V^(-1/2))/K" ,"" ) +`MPRnb( NK11 ,0.0 ,"(m*V^(-1/2))/K" ,"" ) +`MPRnb( PK11 ,0.0 ,"(m^2*V^(-1/2))/K" ,"" ) + +`MPRnb( LK2SI ,LK0SI ,"" ,"" ) +`MPRnb( NK2SI ,NK0SI ,"" ,"" ) +`MPRnb( PK2SI ,PK0SI ,"" ,"" ) + +`MPRnb( LK2SI1 ,LK0SI1 ,"" ,"" ) +`MPRnb( NK2SI1 ,NK0SI1 ,"" ,"" ) +`MPRnb( PK2SI1 ,PK0SI1 ,"" ,"" ) + +`MPRnb( LK0SISAT ,0.0 ,"" ,"" ) +`MPRnb( NK0SISAT ,0.0 ,"" ,"" ) +`MPRnb( PK0SISAT ,0.0 ,"" ,"" ) + +`MPRnb( LK0SISAT1 ,0.0 ,"" ,"" ) +`MPRnb( NK0SISAT1 ,0.0 ,"" ,"" ) +`MPRnb( PK0SISAT1 ,0.0 ,"" ,"" ) + +`MPRnb( LK2SISAT ,LK0SISAT ,"" ,"" ) +`MPRnb( NK2SISAT ,NK0SISAT ,"" ,"" ) +`MPRnb( PK2SISAT ,PK0SISAT ,"" ,"" ) + +`MPRnb( LK2SISAT1 ,LK0SISAT1 ,"" ,"" ) +`MPRnb( NK2SISAT1 ,NK0SISAT1 ,"" ,"" ) +`MPRnb( PK2SISAT1 ,PK0SISAT1 ,"" ,"" ) + +`MPRnb( LK2SAT ,0.0 ,"" ,"" ) +`MPRnb( NK2SAT ,0.0 ,"" ,"" ) +`MPRnb( PK2SAT ,0.0 ,"" ,"" ) + +`MPRnb( LK2SAT1 ,0.0 ,"" ,"" ) +`MPRnb( NK2SAT1 ,0.0 ,"" ,"" ) +`MPRnb( PK2SAT1 ,0.0 ,"" ,"" ) + +`MPRnb( LK2 ,0.0 ,"" ,"" ) +`MPRnb( NK2 ,0.0 ,"" ,"" ) +`MPRnb( PK2 ,0.0 ,"" ,"" ) + +`MPRnb( LK21 ,0.0 ,"" ,"" ) +`MPRnb( NK21 ,0.0 ,"" ,"" ) +`MPRnb( PK21 ,0.0 ,"" ,"" ) + +`MPRnb( LDVTB ,0.0 ,"" ,"" ) +`MPRnb( NDVTB ,0.0 ,"" ,"" ) +`MPRnb( PDVTB ,0.0 ,"" ,"" ) + +`MPRnb( LLPEB ,0.0 ,"" ,"" ) +`MPRnb( NLPEB ,0.0 ,"" ,"" ) +`MPRnb( PLPEB ,0.0 ,"" ,"" ) + +`MPRnb( LQMFACTOR ,0.0 ,"" ,"" ) +`MPRnb( NQMFACTOR ,0.0 ,"" ,"" ) +`MPRnb( PQMFACTOR ,0.0 ,"" ,"" ) + +`MPRnb( LQMTCENCV ,0.0 ,"" ,"" ) +`MPRnb( NQMTCENCV ,0.0 ,"" ,"" ) +`MPRnb( PQMTCENCV ,0.0 ,"" ,"" ) + +`MPRnb( LQMTCENCVA ,0.0 ,"" ,"" ) +`MPRnb( NQMTCENCVA ,0.0 ,"" ,"" ) +`MPRnb( PQMTCENCVA ,0.0 ,"" ,"" ) + +`MPRnb( LVSAT ,0.0 ,"(m^2)/s" ,"" ) +`MPRnb( NVSAT ,0.0 ,"(m^2)/s" ,"" ) +`MPRnb( PVSAT ,0.0 ,"(m^3)/s" ,"" ) + +`MPRnb( LVSATR ,LVSAT ,"" ,"" ) +`MPRnb( NVSATR ,NVSAT ,"" ,"" ) +`MPRnb( PVSATR ,PVSAT ,"" ,"" ) + +`MPRnb( LVSAT1 ,LVSAT ,"" ,"" ) +`MPRnb( NVSAT1 ,NVSAT ,"" ,"" ) +`MPRnb( PVSAT1 ,PVSAT ,"" ,"" ) + +`MPRnb( LVSAT1R ,LVSAT1 ,"(m^2)/s" ,"" ) +`MPRnb( NVSAT1R ,NVSAT1 ,"(m^2)/s" ,"" ) +`MPRnb( PVSAT1R ,PVSAT1 ,"(m^3)/s" ,"" ) + +`MPRnb( LPSAT ,0.0 ,"" ,"" ) +`MPRnb( NPSAT ,0.0 ,"" ,"" ) +`MPRnb( PPSAT ,0.0 ,"" ,"" ) + +`MPRnb( LDELTAVSAT ,0.0 ,"" ,"" ) +`MPRnb( NDELTAVSAT ,0.0 ,"" ,"" ) +`MPRnb( PDELTAVSAT ,0.0 ,"" ,"" ) + +`MPRnb( LKSATIV ,0.0 ,"" ,"" ) +`MPRnb( NKSATIV ,0.0 ,"" ,"" ) +`MPRnb( PKSATIV ,0.0 ,"" ,"" ) + +`MPRnb( LKSATIVR ,LKSATIV ,"" ,"" ) +`MPRnb( NKSATIVR ,NKSATIV ,"" ,"" ) +`MPRnb( PKSATIVR ,PKSATIV ,"" ,"" ) + +`MPRnb( LVSATCV ,0.0 ,"(m^2)/s" ,"" ) +`MPRnb( NVSATCV ,0.0 ,"(m^2)/s" ,"" ) +`MPRnb( PVSATCV ,0.0 ,"(m^3)/s" ,"" ) + +`MPRnb( LPSATCV ,0.0 ,"" ,"" ) +`MPRnb( NPSATCV ,0.0 ,"" ,"" ) +`MPRnb( PPSATCV ,0.0 ,"" ,"" ) + +`MPRnb( LDELTAVSATCV ,0.0 ,"" ,"" ) +`MPRnb( NDELTAVSATCV ,0.0 ,"" ,"" ) +`MPRnb( PDELTAVSATCV ,0.0 ,"" ,"" ) + +`MPRnb( LMEXP ,0.0 ,"" ,"" ) +`MPRnb( NMEXP ,0.0 ,"" ,"" ) +`MPRnb( PMEXP ,0.0 ,"" ,"" ) + +`MPRnb( LMEXPR ,LMEXP ,"" ,"" ) +`MPRnb( NMEXPR ,NMEXP ,"" ,"" ) +`MPRnb( PMEXPR ,PMEXP ,"" ,"" ) + +`MPRnb( LPTWG ,0.0 ,"m*(V^-2)" ,"" ) +`MPRnb( NPTWG ,0.0 ,"m*(V^-2)" ,"" ) +`MPRnb( PPTWG ,0.0 ,"m^2*(V^-2)" ,"" ) + +`MPRnb( LPTWGR ,LPTWG ,"m*(V^-2)" ,"" ) +`MPRnb( NPTWGR ,NPTWG ,"m*(V^-2)" ,"" ) +`MPRnb( PPTWGR ,PPTWG ,"m^2*(V^-2)" ,"" ) + +`MPRnb( LU0 ,0.0 ,"(m^3)/V*s" ,"" ) +`MPRnb( NU0 ,0.0 ,"(m^3)/V*s" ,"" ) +`MPRnb( PU0 ,0.0 ,"(m^4)/V*s" ,"" ) + +`MPRnb( LU0R ,LU0 ,"" ,"" ) +`MPRnb( NU0R ,NU0 ,"" ,"" ) +`MPRnb( PU0R ,PU0 ,"" ,"" ) + +`MPRnb( LETAMOB ,0.0 ,"" ,"" ) +`MPRnb( NETAMOB ,0.0 ,"" ,"" ) +`MPRnb( PETAMOB ,0.0 ,"" ,"" ) + +`MPRnb( LUP ,0.0 ,"m*(um^LPA)" ,"" ) +`MPRnb( NUP ,0.0 ,"m*(um^LPA)" ,"" ) +`MPRnb( PUP ,0.0 ,"m^2*(um^LPA)" ,"" ) + +`MPRnb( LUPR ,LUP ,"" ,"" ) +`MPRnb( NUPR ,NUP ,"" ,"" ) +`MPRnb( PUPR ,PUP ,"" ,"" ) + +`MPRnb( LUA ,0.0 ,"m*((cm/MV)^EU)" ,"" ) +`MPRnb( NUA ,0.0 ,"m*((cm/MV)^EU)" ,"" ) +`MPRnb( PUA ,0.0 ,"m^2*((cm/MV)^EU)" ,"" ) + +`MPRnb( LUAR ,LUA ,"" ,"" ) +`MPRnb( NUAR ,NUA ,"" ,"" ) +`MPRnb( PUAR ,PUA ,"" ,"" ) + +`MPRnb( LUC ,0.0 ,"" ,"" ) +`MPRnb( NUC ,0.0 ,"" ,"" ) +`MPRnb( PUC ,0.0 ,"" ,"" ) + +`MPRnb( LUCR ,LUC ,"" ,"" ) +`MPRnb( NUCR ,NUC ,"" ,"" ) +`MPRnb( PUCR ,PUC ,"" ,"" ) + +`MPRnb( LEU ,0.0 ,"m*(cm/MV)" ,"" ) +`MPRnb( NEU ,0.0 ,"m*(cm/MV)" ,"" ) +`MPRnb( PEU ,0.0 ,"m^2*(cm/MV)" ,"" ) + +`MPRnb( LEUR ,LEU ,"" ,"" ) +`MPRnb( NEUR ,NEU ,"" ,"" ) +`MPRnb( PEUR ,PEU ,"" ,"" ) + +`MPRnb( LUD ,0.0 ,"m*(cm/MV)" ,"" ) +`MPRnb( NUD ,0.0 ,"m*(cm/MV)" ,"" ) +`MPRnb( PUD ,0.0 ,"m^2*(cm/MV)" ,"" ) + +`MPRnb( LUDR ,LUD ,"" ,"" ) +`MPRnb( NUDR ,NUD ,"" ,"" ) +`MPRnb( PUDR ,PUD ,"" ,"" ) + +`MPRnb( LUCS ,0.0 ,"" ,"" ) +`MPRnb( NUCS ,0.0 ,"" ,"" ) +`MPRnb( PUCS ,0.0 ,"" ,"" ) + +`MPRnb( LPCLM ,0.0 ,"" ,"" ) +`MPRnb( NPCLM ,0.0 ,"" ,"" ) +`MPRnb( PPCLM ,0.0 ,"" ,"" ) + +`MPRnb( LPCLMR ,LPCLM ,"" ,"" ) +`MPRnb( NPCLMR ,NPCLM ,"" ,"" ) +`MPRnb( PPCLMR ,PPCLM ,"" ,"" ) + +`MPRnb( LPCLMG ,0.0 ,"" ,"" ) +`MPRnb( NPCLMG ,0.0 ,"" ,"" ) +`MPRnb( PPCLMG ,0.0 ,"" ,"" ) + +`MPRnb( LPCLMCV ,LPCLM ,"" ,"" ) +`MPRnb( NPCLMCV ,NPCLM ,"" ,"" ) +`MPRnb( PPCLMCV ,PPCLM ,"" ,"" ) + +`MPRnb( LA1 ,0.0 ,"m*(V^-2)" ,"" ) +`MPRnb( NA1 ,0.0 ,"m*(V^-2)" ,"" ) +`MPRnb( PA1 ,0.0 ,"m^2*(V^-2)" ,"" ) + +`MPRnb( LA11 ,0.0 ,"m*(V^-2/K)" ,"" ) +`MPRnb( NA11 ,0.0 ,"m*(V^-2/K)" ,"" ) +`MPRnb( PA11 ,0.0 ,"m^2*(V^-2/K)" ,"" ) + +`MPRnb( LA2 ,0.0 ,"m*(V^-1)" ,"" ) +`MPRnb( NA2 ,0.0 ,"m*(V^-1)" ,"" ) +`MPRnb( PA2 ,0.0 ,"m^2*(V^-1)" ,"" ) + +`MPRnb( LA21 ,0.0 ,"m*(V^-1/K)" ,"" ) +`MPRnb( NA21 ,0.0 ,"m*(V^-1/K)" ,"" ) +`MPRnb( PA21 ,0.0 ,"m^2*(V^-1/K)" ,"" ) + +`MPRnb( LRDSW ,0.0 ,"m*(ohm-um^WR)" ,"" ) +`MPRnb( NRDSW ,0.0 ,"m*(ohm-um^WR)" ,"" ) +`MPRnb( PRDSW ,0.0 ,"(m^2)*(ohm-um^WR)" ,"" ) + +`MPRnb( LRSW ,0.0 ,"m*(ohm-um^WR)" ,"" ) +`MPRnb( NRSW ,0.0 ,"m*(ohm-um^WR)" ,"" ) +`MPRnb( PRSW ,0.0 ,"(m^2)*(ohm-um^WR)" ,"" ) + +`MPRnb( LRDW ,0.0 ,"m*(ohm-um^WR)" ,"" ) +`MPRnb( NRDW ,0.0 ,"m*(ohm-um^WR)" ,"" ) +`MPRnb( PRDW ,0.0 ,"(m^2)*(ohm-um^WR)" ,"" ) + +`MPRnb( LPRWGS ,0.0 ,"m/V" ,"" ) +`MPRnb( NPRWGS ,0.0 ,"m/V" ,"" ) +`MPRnb( PPRWGS ,0.0 ,"(m^2)/V" ,"" ) + +`MPRnb( LPRWGD ,0.0 ,"m/V" ,"" ) +`MPRnb( NPRWGD ,0.0 ,"m/V" ,"" ) +`MPRnb( PPRWGD ,0.0 ,"(m^2)/V" ,"" ) + +`MPRnb( LWR ,0.0 ,"" ,"" ) +`MPRnb( NWR ,0.0 ,"" ,"" ) +`MPRnb( PWR ,0.0 ,"" ,"" ) + +`MPRnb( LPDIBL1 ,0.0 ,"" ,"" ) +`MPRnb( NPDIBL1 ,0.0 ,"" ,"" ) +`MPRnb( PPDIBL1 ,0.0 ,"" ,"" ) + +`MPRnb( LPDIBL1R ,LPDIBL1 ,"" ,"" ) +`MPRnb( NPDIBL1R ,NPDIBL1 ,"" ,"" ) +`MPRnb( PPDIBL1R ,PPDIBL1 ,"" ,"" ) + +`MPRnb( LPDIBL2 ,0.0 ,"" ,"" ) +`MPRnb( NPDIBL2 ,0.0 ,"" ,"" ) +`MPRnb( PPDIBL2 ,0.0 ,"" ,"" ) + +`MPRnb( LPDIBL2R ,LPDIBL2 ,"" ,"" ) +`MPRnb( NPDIBL2R ,NPDIBL2 ,"" ,"" ) +`MPRnb( PPDIBL2R ,PPDIBL2 ,"" ,"" ) + +`MPRnb( LDROUT ,0.0 ,"" ,"" ) +`MPRnb( NDROUT ,0.0 ,"" ,"" ) +`MPRnb( PDROUT ,0.0 ,"" ,"" ) + +`MPRnb( LPVAG ,0.0 ,"" ,"" ) +`MPRnb( NPVAG ,0.0 ,"" ,"" ) +`MPRnb( PPVAG ,0.0 ,"" ,"" ) + +`MPRnb( LAIGBINV ,0.0 ,"(F*s^2/g)^0.5" ,"" ) +`MPRnb( NAIGBINV ,0.0 ,"(F*s^2/g)^0.5" ,"" ) +`MPRnb( PAIGBINV ,0.0 ,"((F*s^2/g)^0.5)*m" ,"" ) + +`MPRnb( LAIGBINV1 ,0.0 ,"((F*s^2/g)^0.5)/K" ,"" ) +`MPRnb( NAIGBINV1 ,0.0 ,"((F*s^2/g)^0.5)/K" ,"" ) +`MPRnb( PAIGBINV1 ,0.0 ,"((F*s^2/g)^0.5)*(m/K)" ,"" ) + +`MPRnb( LBIGBINV ,0.0 ,"((F*s^2/g)^0.5)/V" ,"" ) +`MPRnb( NBIGBINV ,0.0 ,"((F*s^2/g)^0.5)/V" ,"" ) +`MPRnb( PBIGBINV ,0.0 ,"((F*s^2/g)^0.5)*(m/V)" ,"" ) + +`MPRnb( LCIGBINV ,0.0 ,"m/V" ,"" ) +`MPRnb( NCIGBINV ,0.0 ,"m/V" ,"" ) +`MPRnb( PCIGBINV ,0.0 ,"(m^2)/V" ,"" ) + +`MPRnb( LEIGBINV ,0.0 ,"m*V" ,"" ) +`MPRnb( NEIGBINV ,0.0 ,"m*V" ,"" ) +`MPRnb( PEIGBINV ,0.0 ,"(m^2)*V" ,"" ) + +`MPRnb( LNIGBINV ,0.0 ,"" ,"" ) +`MPRnb( NNIGBINV ,0.0 ,"" ,"" ) +`MPRnb( PNIGBINV ,0.0 ,"" ,"" ) + +`MPRnb( LAIGBACC ,0.0 ,"(F*s^2/g)^0.5" ,"" ) +`MPRnb( NAIGBACC ,0.0 ,"(F*s^2/g)^0.5" ,"" ) +`MPRnb( PAIGBACC ,0.0 ,"((F*s^2/g)^0.5)*m" ,"" ) + +`MPRnb( LAIGBACC1 ,0.0 ,"((F*s^2/g)^0.5)/K" ,"" ) +`MPRnb( NAIGBACC1 ,0.0 ,"((F*s^2/g)^0.5)/K" ,"" ) +`MPRnb( PAIGBACC1 ,0.0 ,"((F*s^2/g)^0.5)*(m/K)" ,"" ) + +`MPRnb( LBIGBACC ,0.0 ,"((F*s^2/g)^0.5)/V" ,"" ) +`MPRnb( NBIGBACC ,0.0 ,"((F*s^2/g)^0.5)/V" ,"" ) +`MPRnb( PBIGBACC ,0.0 ,"((F*s^2/g)^0.5)*(m/V)" ,"" ) + +`MPRnb( LCIGBACC ,0.0 ,"m/V" ,"" ) +`MPRnb( NCIGBACC ,0.0 ,"m/V" ,"" ) +`MPRnb( PCIGBACC ,0.0 ,"(m^2)/V" ,"" ) + +`MPRnb( LNIGBACC ,0.0 ,"" ,"" ) +`MPRnb( NNIGBACC ,0.0 ,"" ,"" ) +`MPRnb( PNIGBACC ,0.0 ,"" ,"" ) + +`MPRnb( LAIGC ,0.0 ,"(F*s^2/g)^0.5" ,"" ) +`MPRnb( NAIGC ,0.0 ,"(F*s^2/g)^0.5" ,"" ) +`MPRnb( PAIGC ,0.0 ,"((F*s^2/g)^0.5)*m" ,"" ) + +`MPRnb( LAIGC1 ,0.0 ,"((F*s^2/g)^0.5)/K" ,"" ) +`MPRnb( NAIGC1 ,0.0 ,"((F*s^2/g)^0.5)/K" ,"" ) +`MPRnb( PAIGC1 ,0.0 ,"((F*s^2/g)^0.5)*(m/K)" ,"" ) + +`MPRnb( LBIGC ,0.0 ,"((F*s^2/g)^0.5)/V" ,"" ) +`MPRnb( NBIGC ,0.0 ,"((F*s^2/g)^0.5)/V" ,"" ) +`MPRnb( PBIGC ,0.0 ,"((F*s^2/g)^0.5)*(m/V)" ,"" ) + +`MPRnb( LCIGC ,0.0 ,"m/V" ,"" ) +`MPRnb( NCIGC ,0.0 ,"m/V" ,"" ) +`MPRnb( PCIGC ,0.0 ,"(m^2)/V" ,"" ) + +`MPRnb( LPIGCD ,0.0 ,"" ,"" ) +`MPRnb( NPIGCD ,0.0 ,"" ,"" ) +`MPRnb( PPIGCD ,0.0 ,"" ,"" ) + +`MPRnb( LAIGS ,0.0 ,"(F*s^2/g)^0.5" ,"" ) +`MPRnb( NAIGS ,0.0 ,"(F*s^2/g)^0.5" ,"" ) +`MPRnb( PAIGS ,0.0 ,"((F*s^2/g)^0.5)*m" ,"" ) + +`MPRnb( LAIGS1 ,0.0 ,"((F*s^2/g)^0.5)/K" ,"" ) +`MPRnb( NAIGS1 ,0.0 ,"((F*s^2/g)^0.5)/K" ,"" ) +`MPRnb( PAIGS1 ,0.0 ,"((F*s^2/g)^0.5)*(m/K)" ,"" ) + +`MPRnb( LBIGS ,0.0 ,"((F*s^2/g)^0.5)/V" ,"" ) +`MPRnb( NBIGS ,0.0 ,"((F*s^2/g)^0.5)/V" ,"" ) +`MPRnb( PBIGS ,0.0 ,"((F*s^2/g)^0.5)*(m/V)" ,"" ) + +`MPRnb( LCIGS ,0.0 ,"m/V" ,"" ) +`MPRnb( NCIGS ,0.0 ,"m/V" ,"" ) +`MPRnb( PCIGS ,0.0 ,"(m^2)/V" ,"" ) + +`MPRnb( LAIGD ,LAIGS ,"(F*s^2/g)^0.5" ,"" ) +`MPRnb( NAIGD ,NAIGS ,"(F*s^2/g)^0.5" ,"" ) +`MPRnb( PAIGD ,PAIGS ,"((F*s^2/g)^0.5)*m" ,"" ) + +`MPRnb( LAIGD1 ,LAIGS1 ,"((F*s^2/g)^0.5)/K" ,"" ) +`MPRnb( NAIGD1 ,NAIGS1 ,"((F*s^2/g)^0.5)/K" ,"" ) +`MPRnb( PAIGD1 ,PAIGS1 ,"((F*s^2/g)^0.5)*(m/K)" ,"" ) + +`MPRnb( LBIGD ,LBIGS ,"((F*s^2/g)^0.5)/V" ,"" ) +`MPRnb( NBIGD ,NBIGS ,"((F*s^2/g)^0.5)/V" ,"" ) +`MPRnb( PBIGD ,PBIGS ,"((F*s^2/g)^0.5)*(m/V)" ,"" ) + +`MPRnb( LCIGD ,LCIGS ,"m/V" ,"" ) +`MPRnb( NCIGD ,NCIGS ,"m/V" ,"" ) +`MPRnb( PCIGD ,PCIGS ,"(m^2)/V" ,"" ) + +`MPRnb( LNTOX ,0.0 ,"" ,"" ) +`MPRnb( NNTOX ,0.0 ,"" ,"" ) +`MPRnb( PNTOX ,0.0 ,"" ,"" ) + +`MPRnb( LPOXEDGE ,0.0 ,"" ,"" ) +`MPRnb( NPOXEDGE ,0.0 ,"" ,"" ) +`MPRnb( PPOXEDGE ,0.0 ,"" ,"" ) + +`MPRnb( LAGISL ,0.0 ,"m/ohm" ,"" ) +`MPRnb( NAGISL ,0.0 ,"m/ohm" ,"" ) +`MPRnb( PAGISL ,0.0 ,"(m^2)/ohm" ,"" ) + +`MPRnb( LBGISL ,0.0 ,"V" ,"" ) +`MPRnb( NBGISL ,0.0 ,"V" ,"" ) +`MPRnb( PBGISL ,0.0 ,"m*V" ,"" ) + +`MPRnb( LCGISL ,0.0 ,"m*(V^3)" ,"" ) +`MPRnb( NCGISL ,0.0 ,"m*(V^3)" ,"" ) +`MPRnb( PCGISL ,0.0 ,"(m^2)*(V^3)" ,"" ) + +`MPRnb( LEGISL ,0.0 ,"m*V" ,"" ) +`MPRnb( NEGISL ,0.0 ,"m*V" ,"" ) +`MPRnb( PEGISL ,0.0 ,"(m^2)*V" ,"" ) + +`MPRnb( LPGISL ,0.0 ,"" ,"" ) +`MPRnb( NPGISL ,0.0 ,"" ,"" ) +`MPRnb( PPGISL ,0.0 ,"" ,"" ) + +`MPRnb( LAGIDL ,LAGISL ,"m/ohm" ,"" ) +`MPRnb( NAGIDL ,NAGISL ,"m/ohm" ,"" ) +`MPRnb( PAGIDL ,PAGISL ,"(m^2)/ohm" ,"" ) + +`MPRnb( LBGIDL ,LBGISL ,"V" ,"" ) +`MPRnb( NBGIDL ,NBGISL ,"V" ,"" ) +`MPRnb( PBGIDL ,PBGISL ,"m*V" ,"" ) + +`MPRnb( LCGIDL ,LCGISL ,"m*(V^3)" ,"" ) +`MPRnb( NCGIDL ,NCGISL ,"m*(V^3)" ,"" ) +`MPRnb( PCGIDL ,PCGISL ,"(m^2)*(V^3)" ,"" ) + +`MPRnb( LEGIDL ,LEGISL ,"m*V" ,"" ) +`MPRnb( NEGIDL ,NEGISL ,"m*V" ,"" ) +`MPRnb( PEGIDL ,PEGISL ,"(m^2)*V" ,"" ) + +`MPRnb( LPGIDL ,LPGISL ,"" ,"" ) +`MPRnb( NPGIDL ,NPGISL ,"" ,"" ) +`MPRnb( PPGIDL ,PPGISL ,"" ,"" ) + +`MPRnb( LALPHA0 ,0.0 ,"(m^2)/V" ,"" ) +`MPRnb( NALPHA0 ,0.0 ,"(m^2)/V" ,"" ) +`MPRnb( PALPHA0 ,0.0 ,"(m^3)/V" ,"" ) + +`MPRnb( LALPHA1 ,0.0 ,"m/V" ,"" ) +`MPRnb( NALPHA1 ,0.0 ,"m/V" ,"" ) +`MPRnb( PALPHA1 ,0.0 ,"(m^2)/V" ,"" ) + +`MPRnb( LALPHAII0 ,0.0 ,"(m^2)/V" ,"" ) +`MPRnb( NALPHAII0 ,0.0 ,"(m^2)/V" ,"" ) +`MPRnb( PALPHAII0 ,0.0 ,"(m^3)/V" ,"" ) + +`MPRnb( LALPHAII1 ,0.0 ,"m/V" ,"" ) +`MPRnb( NALPHAII1 ,0.0 ,"m/V" ,"" ) +`MPRnb( PALPHAII1 ,0.0 ,"(m^2)/V" ,"" ) + +`MPRnb( LBETA0 ,0.0 ,"m/V" ,"" ) +`MPRnb( NBETA0 ,0.0 ,"m/V" ,"" ) +`MPRnb( PBETA0 ,0.0 ,"(m^2)/V" ,"" ) + +`MPRnb( LBETAII0 ,0.0 ,"m/V" ,"" ) +`MPRnb( NBETAII0 ,0.0 ,"m/V" ,"" ) +`MPRnb( PBETAII0 ,0.0 ,"(m^2)/V" ,"" ) + +`MPRnb( LBETAII1 ,0.0 ,"" ,"" ) +`MPRnb( NBETAII1 ,0.0 ,"" ,"" ) +`MPRnb( PBETAII1 ,0.0 ,"" ,"" ) + +`MPRnb( LBETAII2 ,0.0 ,"m*V" ,"" ) +`MPRnb( NBETAII2 ,0.0 ,"m*V" ,"" ) +`MPRnb( PBETAII2 ,0.0 ,"(m^2)*V" ,"" ) + +`MPRnb( LESATII ,0.0 ,"V" ,"" ) +`MPRnb( NESATII ,0.0 ,"V" ,"" ) +`MPRnb( PESATII ,0.0 ,"m*V" ,"" ) + +`MPRnb( LLII ,0.0 ,"(m^2)*V" ,"" ) +`MPRnb( NLII ,0.0 ,"(m^2)*V" ,"" ) +`MPRnb( PLII ,0.0 ,"(m^3)*V" ,"" ) + +`MPRnb( LSII0 ,0.0 ,"m/V" ,"" ) +`MPRnb( NSII0 ,0.0 ,"m/V" ,"" ) +`MPRnb( PSII0 ,0.0 ,"(m^2)/V" ,"" ) + +`MPRnb( LSII1 ,0.0 ,"" ,"" ) +`MPRnb( NSII1 ,0.0 ,"" ,"" ) +`MPRnb( PSII1 ,0.0 ,"" ,"" ) + +`MPRnb( LSII2 ,0.0 ,"m*V" ,"" ) +`MPRnb( NSII2 ,0.0 ,"m*V" ,"" ) +`MPRnb( PSII2 ,0.0 ,"(m^2)*V" ,"" ) + +`MPRnb( LSIID ,0.0 ,"m*V" ,"" ) +`MPRnb( NSIID ,0.0 ,"m*V" ,"" ) +`MPRnb( PSIID ,0.0 ,"(m^2)*V" ,"" ) + +`MPRnb( LCFS ,0.0 ,"F" ,"" ) +`MPRnb( NCFS ,0.0 ,"F" ,"" ) +`MPRnb( PCFS ,0.0 ,"F*m" ,"" ) + +`MPRnb( LCFD ,LCFS ,"F" ,"" ) +`MPRnb( NCFD ,NCFS ,"F" ,"" ) +`MPRnb( PCFD ,PCFS ,"F*m" ,"" ) + +`MPRnb( LCOVS ,0.0 ,"F" ,"" ) +`MPRnb( NCOVS ,0.0 ,"F" ,"" ) +`MPRnb( PCOVS ,0.0 ,"F*m" ,"" ) + +`MPRnb( LCOVD ,LCOVS ,"F" ,"" ) +`MPRnb( NCOVD ,NCOVS ,"F" ,"" ) +`MPRnb( PCOVD ,PCOVS ,"F*m" ,"" ) + +`MPRnb( LCGSL ,0.0 ,"F" ,"" ) +`MPRnb( NCGSL ,0.0 ,"F" ,"" ) +`MPRnb( PCGSL ,0.0 ,"F*m" ,"" ) + +`MPRnb( LCGDL ,LCGSL ,"F" ,"" ) +`MPRnb( NCGDL ,NCGSL ,"F" ,"" ) +`MPRnb( PCGDL ,PCGSL ,"F*m" ,"" ) + +`MPRnb( LCKAPPAS ,0.0 ,"m*V" ,"" ) +`MPRnb( NCKAPPAS ,0.0 ,"m*V" ,"" ) +`MPRnb( PCKAPPAS ,0.0 ,"(m^2)*V" ,"" ) + +`MPRnb( LCKAPPAD ,LCKAPPAS ,"m*V" ,"" ) +`MPRnb( NCKAPPAD ,NCKAPPAS ,"m*V" ,"" ) +`MPRnb( PCKAPPAD ,PCKAPPAS ,"(m^2)*V" ,"" ) + +`MPRnb( LCGBL ,0.0 ,"F" ,"" ) +`MPRnb( NCGBL ,0.0 ,"F" ,"" ) +`MPRnb( PCGBL ,0.0 ,"F*m" ,"" ) + +`MPRnb( LCKAPPAB ,0.0 ,"m*V" ,"" ) +`MPRnb( NCKAPPAB ,0.0 ,"m*V" ,"" ) +`MPRnb( PCKAPPAB ,0.0 ,"(m^2)*V" ,"" ) + +`MPRnb( LNTGEN ,0.0 ,"" ,"" ) +`MPRnb( NNTGEN ,0.0 ,"" ,"" ) +`MPRnb( PNTGEN ,0.0 ,"" ,"" ) + +`MPRnb( LAIGEN ,0.0 ,"(m^-2)*(V^-1)" ,"" ) +`MPRnb( NAIGEN ,0.0 ,"(m^-2)*(V^-1)" ,"" ) +`MPRnb( PAIGEN ,0.0 ,"(m^-1)*(V^-1)" ,"" ) + +`MPRnb( LBIGEN ,0.0 ,"(m^-2)*(V^-3)" ,"" ) +`MPRnb( NBIGEN ,0.0 ,"(m^-2)*(V^-3)" ,"" ) +`MPRnb( PBIGEN ,0.0 ,"(m^-1)*(V^-3)" ,"" ) + +`MPRnb( LXRCRG1 ,0.0 ,"" ,"" ) +`MPRnb( NXRCRG1 ,0.0 ,"" ,"" ) +`MPRnb( PXRCRG1 ,0.0 ,"" ,"" ) + +`MPRnb( LXRCRG2 ,0.0 ,"" ,"" ) +`MPRnb( NXRCRG2 ,0.0 ,"" ,"" ) +`MPRnb( PXRCRG2 ,0.0 ,"" ,"" ) + +`MPRnb( LUTE ,0.0 ,"" ,"" ) +`MPRnb( NUTE ,0.0 ,"" ,"" ) +`MPRnb( PUTE ,0.0 ,"" ,"" ) + +`MPRnb( LUTER ,LUTE ,"" ,"" ) +`MPRnb( NUTER ,NUTE ,"" ,"" ) +`MPRnb( PUTER ,PUTE ,"" ,"" ) + +`MPRnb( LUTL ,0.0 ,"" ,"" ) +`MPRnb( NUTL ,0.0 ,"" ,"" ) +`MPRnb( PUTL ,0.0 ,"" ,"" ) + +`MPRnb( LUTLR ,LUTL ,"" ,"" ) +`MPRnb( NUTLR ,NUTL ,"" ,"" ) +`MPRnb( PUTLR ,PUTL ,"" ,"" ) + +`MPRnb( LEMOBT ,0.0 ,"" ,"" ) +`MPRnb( NEMOBT ,0.0 ,"" ,"" ) +`MPRnb( PEMOBT ,0.0 ,"" ,"" ) + +`MPRnb( LUA1 ,0.0 ,"" ,"" ) +`MPRnb( NUA1 ,0.0 ,"" ,"" ) +`MPRnb( PUA1 ,0.0 ,"" ,"" ) + +`MPRnb( LUA1R ,LUA1 ,"" ,"" ) +`MPRnb( NUA1R ,NUA1 ,"" ,"" ) +`MPRnb( PUA1R ,PUA1 ,"" ,"" ) + +`MPRnb( LUC1 ,0.0 ,"" ,"" ) +`MPRnb( NUC1 ,0.0 ,"" ,"" ) +`MPRnb( PUC1 ,0.0 ,"" ,"" ) + +`MPRnb( LUC1R ,LUC1 ,"" ,"" ) +`MPRnb( NUC1R ,NUC1 ,"" ,"" ) +`MPRnb( PUC1R ,PUC1 ,"" ,"" ) + +`MPRnb( LUD1 ,0.0 ,"" ,"" ) +`MPRnb( NUD1 ,0.0 ,"" ,"" ) +`MPRnb( PUD1 ,0.0 ,"" ,"" ) + +`MPRnb( LUD1R ,LUD1 ,"" ,"" ) +`MPRnb( NUD1R ,NUD1 ,"" ,"" ) +`MPRnb( PUD1R ,PUD1 ,"" ,"" ) + +`MPRnb( LUCSTE ,0.0 ,"" ,"" ) +`MPRnb( NUCSTE ,0.0 ,"" ,"" ) +`MPRnb( PUCSTE ,0.0 ,"" ,"" ) + +`MPRnb( LPTWGT ,0.0 ,"m/K" ,"" ) +`MPRnb( NPTWGT ,0.0 ,"m/K" ,"" ) +`MPRnb( PPTWGT ,0.0 ,"(m^2)/K" ,"" ) + +`MPRnb( LAT ,0.0 ,"m/K" ,"" ) +`MPRnb( NAT ,0.0 ,"m/K" ,"" ) +`MPRnb( PAT ,0.0 ,"(m^2)/K" ,"" ) + +`MPRnb( LATR ,LAT ,"" ,"" ) +`MPRnb( NATR ,NAT ,"" ,"" ) +`MPRnb( PATR ,PAT ,"" ,"" ) + +`MPRnb( LATCV ,0.0 ,"m/K" ,"" ) +`MPRnb( NATCV ,0.0 ,"m/K" ,"" ) +`MPRnb( PATCV ,0.0 ,"(m^2)/K" ,"" ) + +`MPRnb( LSTTHETASAT ,0.0 ,"" ,"" ) +`MPRnb( NSTTHETASAT ,0.0 ,"" ,"" ) +`MPRnb( PSTTHETASAT ,0.0 ,"" ,"" ) + +`MPRnb( LPRT ,0.0 ,"m/K" ,"" ) +`MPRnb( NPRT ,0.0 ,"m/K" ,"" ) +`MPRnb( PPRT ,0.0 ,"(m^2)/K" ,"" ) + +`MPRnb( LKT1 ,0.0 ,"m*V" ,"" ) +`MPRnb( NKT1 ,0.0 ,"m*V" ,"" ) +`MPRnb( PKT1 ,0.0 ,"(m^2)*V" ,"" ) + +`MPRnb( LTSS ,0.0 ,"" ,"" ) +`MPRnb( NTSS ,0.0 ,"" ,"" ) +`MPRnb( PTSS ,0.0 ,"" ,"" ) + +`MPRnb( LIIT ,0.0 ,"" ,"" ) +`MPRnb( NIIT ,0.0 ,"" ,"" ) +`MPRnb( PIIT ,0.0 ,"" ,"" ) + +`MPRnb( LTII ,0.0 ,"" ,"" ) +`MPRnb( NTII ,0.0 ,"" ,"" ) +`MPRnb( PTII ,0.0 ,"" ,"" ) + +`MPRnb( LTGIDL ,0.0 ,"m/K" ,"" ) +`MPRnb( NTGIDL ,0.0 ,"m/K" ,"" ) +`MPRnb( PTGIDL ,0.0 ,"(m^2)/K" ,"" ) + +`MPRnb( LIGT ,0.0 ,"" ,"" ) +`MPRnb( NIGT ,0.0 ,"" ,"" ) +`MPRnb( PIGT ,0.0 ,"" ,"" ) diff --git a/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_body.include b/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_body.include new file mode 100644 index 000000000..6d47e3a5a --- /dev/null +++ b/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_body.include @@ -0,0 +1,4145 @@ +// ******************************************************** +// ******************************************************** +// *** BSIM-CMG 110.0.0 released by Sourabh Khandelwal on 01/01/2016 ****/ +// * BSIM Common Multi-Gate Model Equations (Verilog-A) +// ******************************************************** +// +// ******************************************************** +// * Copyright 2016 Regents of the University of California. +// * All rights reserved. +// * +// * Project Director: Prof. Chenming Hu. +// * Authors: Sriramkumar V., Navid Paydavosi, Juan Duarte, Sourabh Khandelwal, Darsen Lu, +// * Chung-Hsun Lin, Mohan Dunga, Shijing Yao, +// * Ali Niknejad, Chenming Hu +// ******************************************************** +// ******************************************************** +// * NONDISCLOSURE STATEMENT +// 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 of California owns the copyright and grants users a perpetual, +// irrevocable, worldwide, non-exclusive, royalty-free license with +// respect to the software as set forth below. +// 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 University of California 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 +// Agreed to on __Jan 01, 2016__________________ +// By: ___University of California, Berkeley____ +// ___Chenming Hu_____________________ +// ___Professor in Graduate School _______ +// ******************************************************** + +// Clamped Exponential Function +analog function real lexp; + input x; + real x; + + begin + if (x > `EXPL_THRESHOLD) begin + lexp = `MAX_EXPL * (1.0 + x - `EXPL_THRESHOLD); + end else if (x < -`EXPL_THRESHOLD) begin + lexp = `MIN_EXPL; + end else begin + lexp = exp(x); + end + end +endfunction + +// Clamped log Function +analog function real lln; + input x; + real x; + + begin + lln = ln(max(x, `N_MINLOG)); + end +endfunction + +// Hyperbolic Smoothing Function +analog function real hypsmooth; + input x, c; + real x, c; + + begin + hypsmooth = 0.5 * (x + sqrt(x * x + 4.0 * c * c)); + end +endfunction + +// Hyperbolic Smoothing max Function +analog function real hypmax; + input x, xmin, c; + real x, xmin, c; + + begin + hypmax = xmin + 0.5 * (x - xmin - c + sqrt((x - xmin - c) * (x - xmin - c) - 4.0 * xmin * c)); + end +endfunction + +// Temperature Dependence Type +analog function real Tempdep; + input PARAML, PARAMT, DELTEMP, TEMPMOD; + real PARAML, PARAMT, DELTEMP, TEMPMOD; + + begin + if (TEMPMOD != 0) begin + Tempdep = PARAML + hypmax(PARAMT * DELTEMP, -PARAML, 1.0e-6); + end else begin + Tempdep = PARAML * hypsmooth(1.0 + PARAMT * DELTEMP - 1.0e-6, 1.0e-3); + end + end +endfunction + +// Node Definitions +`ifdef __RGATEMOD__ + `define GateEdgeNode ge +`else + `define GateEdgeNode g +`endif +`ifdef __NQSMOD1__ + `define IntrinsicGate gi +`else + `define IntrinsicGate `GateEdgeNode +`endif + +// *************************** +// * Instance Parameters * +// *************************** + +// Note: Some instance parameters are also model parameters. Please refer to the technical note for details. +`IPRco( L ,3.0e-8 ,"m" ,1.0e-9 ,inf ,"Designed gate length" ) +`IPRco( D ,4.0e-8 ,"m" ,1.0e-9 ,inf ,"Diameter of the cylinder (GEOMOD=3)" ) +`IPRco( TFIN ,1.5e-8 ,"m" ,1.0e-9 ,inf ,"Body (fin) thickness" ) +`IPRco( FPITCH ,8.0e-8 ,"m" ,TFIN ,inf ,"Fin pitch" ) +`IPIco( NF ,1 ,"" ,1 ,inf ,"Number of fingers" ) +`IPRoz( NFIN ,1.0 ,"" ,"Number of fins per finger (real number enables optimization)" ) +`IPIcc( NGCON ,1 ,"" ,1 ,2 ,"Number of gate contact (1 or 2 sided)" ) +`IPRcz( ASEO ,0.0 ,"m^2" ,"Source-to-substrate overlap area through oxide" ) +`IPRcz( ADEO ,0.0 ,"m^2" ,"Drain-to-substrate overlap area through oxide" ) +`IPRcz( PSEO ,0.0 ,"m" ,"Perimeter of source-to-substrate overlap region through oxide" ) +`IPRcz( PDEO ,0.0 ,"m" ,"Perimeter of drain-to-substrate overlap region through oxide" ) +`IPRcz( ASEJ ,0.0 ,"m^2" ,"Source junction area (BULKMOD=1 or 2)" ) +`IPRcz( ADEJ ,0.0 ,"m^2" ,"Drain junction area (BULKMOD=1 or 2)" ) +`IPRcz( PSEJ ,0.0 ,"m" ,"Source-to-substrate PN junction perimeter (BULKMOD=1 or 2)" ) +`IPRcz( PDEJ ,0.0 ,"m" ,"Drain-to-substrate PN junction perimeter (BULKMOD=1 or 2)" ) +`IPRcz( COVS ,0.0 ,"F/m" ,"Constant gate-to-source overlap capacitance (CGEOMOD=1)" ) +`IPRcz( COVD ,COVS ,"F/m" ,"Constant gate-to-drain overlap capacitance (CGEOMOD=1)" ) +`IPRcz( CGSP ,0.0 ,"F/m" ,"Constant gate-to-source fringe capacitance (CGEOMOD=1)" ) +`IPRcz( CGDP ,0.0 ,"F/m" ,"Constant gate-to-drain fringe capacitance (CGEOMOD=1)" ) +`IPRcz( CDSP ,0.0 ,"F" ,"Constant drain-to-source fringe capacitance (all CGEOMOD)" ) +`IPRcz( NRS ,0.0 ,"" ,"Number of source diffusion squares" ) +`IPRcz( NRD ,0.0 ,"" ,"Number of source diffusion squares" ) +`IPRoz( LRSD ,L ,"m" ,"Length of the source/drain" ) +`IPRoz( NFINNOM ,1.0 ,"" ,"Nominal number of fins per finger" ) + +// Variability Handles +`MPRnb( XL ,0.0 ,"m" ,"L offset for channel length due to mask/etch effect" ) +`MPRnb( DTEMP ,0.0 ,"Celsius" ,"Variability in device temperature" ) +`MPRnb( DELVTRAND ,0.0 ,"V" ,"Variability in Vth" ) +`MPRcz( U0MULT ,1.0 ,"" ,"Variability in carrier mobility" ) +`MPRcz( IDS0MULT ,1.0 ,"" ,"Variability in drain current for miscellaneous reasons" ) + +// ************************ +// * Model Parameters * +// ************************ +`MPIcc( DEVTYPE ,`ntype ,"" ,`ptype ,`ntype ,"0: PMOS; 1: NMOS" ) +`MPIcc( TYPE ,DEVTYPE ,"" ,`ptype ,`ntype ,"0: PMOS; 1: NMOS" ) +`MPIcc( BULKMOD ,0 ,"" ,0 ,2 ,"0: SOI multi-gate; 1: Bulk multi-gate; 2: for decoupled bulk multi-gate" ) +`MPIcc( GEOMOD ,0 ,"" ,0 ,4 ,"0: Double gate; 1: Triple gate; 2: Quadruple gate; 3: Cylindrical gate; 4: Unified fin Shape" ) +`MPIcc( CGEO1SW ,0 ,"" ,0 ,1 ,"For CGEOMOD=1 only, this switch enables the parameters COVS, COVD, CGSP, and CGDP to be in F per fin, per gate-finger, per unit channel width" ) +`MPIcc( RDSMOD ,0 ,"" ,0 ,2 ,"0: Internal S/D resistance model; 1: External S/D resistance model; 2: Both bias dependent and independent part of S/D resistance internal" ) +`MPIcc( ASYMMOD ,0 ,"" ,0 ,1 ,"0: Turn off asymmetry model - forward mode parameters used; 1: Turn on asymmetry model" ) +`MPIcc( IGCMOD ,0 ,"" ,0 ,1 ,"0: Turn off Igc, Igs and Igd; 1: Turn on Igc, Igs and Igd" ) +`MPIcc( IGBMOD ,0 ,"" ,0 ,1 ,"0: Turn off Igb; 1: Turn on Igb" ) +`MPIcc( GIDLMOD ,0 ,"" ,0 ,1 ,"0: Turn off GIDL/GISL current; 1: Turn on GIDL/GISL current" ) +`MPIcc( IIMOD ,0 ,"" ,0 ,2 ,"0: Turn off impact ionization current; 1: BSIM4-based model; 2: BSIMSOI-based model" ) +`MPIcc( TNOIMOD ,0 ,"" ,0 ,1 ,"0: Charge-based, 1: Correlated thermal noise model" ) +`MPIcc( NQSMOD ,0 ,"" ,0 ,2 ,"0: Turn off NQS model; 1: NQS gate resistance (with gi node); 2: NQS charge deficit model from BSIM4 (with q node)" ) +`MPIcc( SHMOD ,0 ,"" ,0 ,1 ,"0: Turn off self-heating; 1: Turn on self-heating" ) +`MPIcc( TEMPMOD ,0 ,"" ,0 ,1 ,"1: Change temperature dependence of specific parameters" ) +`MPIcc( RGATEMOD ,0 ,"" ,0 ,1 ,"0: Turn off gate electrode resistance (without ge node); 1: Turn on gate electrode resistance (with ge node)" ) +`MPIcc( RGEOMOD ,0 ,"" ,0 ,1 ,"Geometry-dependent source/drain resistance; 0: RSH-based; 1: Holistic" ) +`MPIcc( CGEOMOD ,0 ,"" ,0 ,2 ,"Geometry-dependent parasitic capacitance model selector" ) +`MPIcc( SH_WARN ,0 ,"" ,0 ,1 ,"0: Disable self-heating warnings; 1: Enable self-heating warnings" ) +`MPIcc( IGCLAMP ,1 ,"" ,0 ,1 ,"0: Disable gate current clamps; 1: Enable gate current clamps" ) +`MPRnb( LINT ,0.0 ,"m" ,"Length reduction parameter (dopant diffusion effect)" ) +`MPRnb( LL ,0.0 ,"m^(LLN+1)" ,"Length reduction parameter (dopant diffusion effect)" ) +`MPRnb( LLN ,1.0 ,"" ,"Length reduction parameter (dopant diffusion effect)" ) +`MPRnb( DLC ,0.0 ,"m" ,"Delta L for C-V model" ) +`MPRnb( DLCACC ,0.0 ,"m" ,"Delta L for C-V model in accumulation region (BULKMOD=1 or 2)" ) +`MPRnb( DLBIN ,0.0 ,"m" ,"Delta L for binning" ) +`MPRnb( LLC ,0.0 ,"m^(LLN+1)" ,"Length reduction parameter (dopant diffusion effect)" ) +`MPRco( EOT ,1.0e-9 ,"m" ,1.0e-10 ,inf ,"Equivalent oxide thickness" ) +`MPRco( TOXP ,1.2e-9 ,"m" ,1.0e-10 ,inf ,"Physical oxide thickness" ) +`MPRco( EOTBOX ,1.4e-7 ,"m" ,1.0e-9 ,inf ,"Equivalent oxide thickness of the buried oxide (SOI FinFET)" ) +`MPRco( HFIN ,3.0e-8 ,"m" ,1.0e-9 ,inf ,"Fin height" ) +`MPRcz( FECH ,1.0 ,"" ,"End-channel factor for different orientation/shape" ) +`MPRnb( DELTAW ,0.0 ,"m" ,"Change of effective width due to shape of fin/cylinder" ) +`MPRcz( FECHCV ,1.0 ,"" ,"CV end-channel factor for different orientation/shape" ) +`MPRnb( DELTAWCV ,0.0 ,"m" ,"CV change of effective width due to shape of fin/cylinder" ) +`MPRnb( NBODY ,1.0e22 ,"/m^3" ,"Channel (body) doping" ) +`MPRnb( NBODYN1 ,0.0 ,"" ,"NFIN dependence of channel (body) doping" ) +`MPRex( NBODYN2 ,1.0e5 ,"" ,0.0 ,"NFIN dependence of channel (body) doping" ) +`MPRcc( NSD ,2.0e26 ,"/m^3" ,2.0e25 ,1.0e27 ,"Source/drain active doping concentration" ) +`MPRcz( PHIG ,4.61 ,"eV" ,"Gate workfunction" ) +`MPRnb( PHIGL ,0.0 ,"eV/m" ,"Length dependence of gate workfunction" ) +`MPRnb( PHIGLT ,0.0 ,"/m" ,"Coupled NFIN and length dependence of gate workfunction" ) +`MPRnb( PHIGN1 ,0.0 ,"" ,"NFIN dependence of gate workfunction" ) +`MPRex( PHIGN2 ,1.0e5 ,"" ,0.0 ,"NFIN dependence of gate workfunction" ) +`MPRco( EPSROX ,3.9 ,"" ,1.0 ,inf ,"Relative dielectric constant of the gate dielectric" ) +`MPRco( EPSRSUB ,11.9 ,"" ,1.0 ,inf ,"Relative dielectric constant of the channel material" ) +`MPRcz( EASUB ,4.05 ,"eV" ,"Electron affinity of substrate" ) +`MPRnb( NI0SUB ,1.1e16 ,"/m^3" ,"Intrinsic carrier constant at 300.15K" ) +`MPRnb( BG0SUB ,1.12 ,"eV" ,"Bandgap of substrate at 300.15K" ) +`MPRnb( NC0SUB ,2.86e25 ,"/m^3" ,"Conduction band density of states" ) +`MPRnb( NGATE ,0.0 ,"/m^3" ,"Parameter for poly gate doping. For metal gate please set NGATE = 0" ) +`MPRnb( Imin ,1.0e-15 ,"A/m^2" ,"Parameter for Vgs clamping for inversion region calculation in accumulation" ) + +// Short Channel Effects +`MPRnb( CIT ,0.0 ,"F/m^2" ,"Parameter for interface trap" ) +`MPRnb( CITR ,CIT ,"" ,"Parameter for interface trap in reverse mode for asymmetric model" ) +`MPRnb( CDSC ,7.0e-3 ,"F/m^2" ,"Coupling capacitance between S/D and channel" ) +`MPRnb( CDSCN1 ,0.0 ,"" ,"NFIN dependence of CDSC" ) +`MPRnb( CDSCN2 ,1.0e5 ,"" ,"NFIN dependence of CDSC" ) +`MPRnb( CDSCD ,7.0e-3 ,"F/m^2" ,"Drain-bias sensitivity of CDSC" ) +`MPRnb( CDSCDN1 ,0.0 ,"" ,"NFIN dependence of CDSCD" ) +`MPRex( CDSCDN2 ,1.0e5 ,"" ,0.0 ,"NFIN dependence of CDSCD" ) +`MPRnb( CDSCDR ,CDSCD ,"F/m^2" ,"Reverse-mode drain-bias sensitivity of CDSC" ) +`MPRnb( CDSCDRN1 ,CDSCDN1 ,"" ,"NFIN dependence of CDSCD" ) +`MPRex( CDSCDRN2 ,CDSCDN2 ,"" ,0.0 ,"NFIN dependence of CDSCD" ) +`MPRnb( DVT0 ,0.0 ,"" ,"SCE coefficient" ) +`MPRnb( DVT1 ,0.6 ,"" ,"SCE exponent coefficient. After binning it should be within (0:inf)" ) +`MPRnb( DVT1SS ,DVT1 ,"" ,"Subthreshold swing exponent coefficient. After binning it should be within (0:inf)" ) +`MPRnb( PHIN ,0.05 ,"V" ,"Nonuniform vertical doping effect on surface potential" ) +`MPRnb( ETA0 ,0.6 ,"" ,"DIBL coefficient" ) +`MPRnb( ETA0N1 ,0.0 ,"" ,"NFIN dependence of ETA0" ) +`MPRco( ETA0N2 ,1.0e5 ,"" ,1.0e-5 ,inf ,"NFIN dependence of ETA0" ) +`MPRnb( ETA0LT ,0.0 ,"/m" ,"Coupled NFIN and length dependence of ETA0" ) +`MPRnb( TETA0 ,0.0 ,"/K" ,"Temperature dependence of DIBL coefficient" ) +`MPRnb( ETA0R ,ETA0 ,"" ,"Reverse-mode DIBL coefficient" ) +`MPRnb( TETA0R ,TETA0 ,"/K" ,"Temperature dependence of reverse-mode DIBL coefficient" ) +`MPRnb( DSUB ,1.06 ,"" ,"DIBL exponent coefficient" ) +`MPRnb( DVTP0 ,0.0 ,"" ,"Coefficient for drain-induced Vth shift (DITS)" ) +`MPRnb( DVTP1 ,0.0 ,"" ,"DITS exponent coefficient" ) +`MPRnb( ADVTP0 ,0.0 ,"" ,"Pre-exponential coefficient for DITS" ) +`MPRex( BDVTP0 ,1.0e-7 ,"" ,0.0 ,"Exponential coefficient for DITS" ) +`MPRnb( ADVTP1 ,0.0 ,"" ,"Pre-exponential coefficient for DVTP1" ) +`MPRex( BDVTP1 ,1.0e-7 ,"" ,0.0 ,"Exponential coefficient for DVTP1" ) +`MPRnb( DVTP2 ,0.0 ,"" ,"DITS model parameter" ) +`MPRnb( K1RSCE ,0.0 ,"/V^(0.5)" ,"K1 for reverse short channel effect calculation" ) +`MPRnb( LPE0 ,5.0e-9 ,"m" ,"Equivalent length of pocket region at zero bias" ) +`MPRnb( DVTSHIFT ,0.0 ,"V" ,"Vth shift handle" ) +`MPRnb( DVTSHIFTR ,DVTSHIFT ,"" ,"Vth shift handle for asymmetric mode" ) +`MPRnb( THETASCE ,0.0 ,"" ,"Vth roll-off length dependence. If defined by user, it will overwrite Theta_SCE in the code") +`MPRnb( THETADIBL ,0.0 ,"" ,"DIBL length dependence. If defined by user, will overwrite Theta_DIBL in the code" ) +`MPRnb( THETASW ,0.0 ,"" ,"Subthreshold swing length dependence. If defined by user, it will overwrite Theta_SW in the code" ) +`MPRnb( NVTM ,0.0 ,"V" ,"Subthreshold swing factor multiplied by Vtm. If defined by user, it will overwrite nVtm in the code" ) + +// Lateral non-uniform doping effect (IV-CV Vth shift) +`MPRnb( K0 ,0.0 ,"V" ,"Lateral NUD voltage parameter" ) +`MPRnb( K01 ,0.0 ,"V/K" ,"Temperature dependence of lateral NUD voltage parameter" ) +`MPRnb( K0SI ,1.0 ,"" ,"Correction factor for strong inversion used in Mnud. After binning it should be within (0:inf)" ) +`MPRnb( K0SI1 ,0.0 ,"/K" ,"Temperature dependence of K0SI" ) +`MPRnb( K2SI ,K0SI ,"" ,"Correction factor for strong inversion used in Mob" ) +`MPRnb( K2SI1 ,K0SI1 ,"" ,"Temperature dependence of K2SI" ) +`MPRnb( K0SISAT ,0.0 ,"" ,"Correction factor for strong inversion used in Mnud" ) +`MPRnb( K0SISAT1 ,0.0 ,"" ,"Temperature dependence of K0SISAT" ) +`MPRnb( K2SISAT ,K0SISAT ,"" ,"Correction factor for strong inversion used in Mob" ) +`MPRnb( K2SISAT1 ,K0SISAT1 ,"" ,"Temperature dependence of K2SISAT" ) + +// Body Effect for MG Devices on Bulk Substrate (ex: FinFETs on BULK) +`MPRnb( PHIBE ,0.7 ,"V" ,"Body effect voltage parameter. After binning it should be within [0.2:1.2]" ) +`MPRco( K1 ,1.0e-6 ,"V^(0.5)" ,1.0e-6 ,inf ,"Body effect coefficient for subthreshold region" ) +`MPRnb( K11 ,0.0 ,"V^(0.5)/K" ,"Temperature dependence of K1" ) +`MPRnb( K2SAT ,0.0 ,"" ,"Correction factor for K2 in saturation (high Vds)" ) +`MPRnb( K2SAT1 ,0.0 ,"" ,"Temperature dependence of K2SAT" ) +`MPRnb( K2 ,0.0 ,"" ,"Body effect coefficient for BULKMOD==2" ) +`MPRnb( K21 ,0.0 ,"" ,"Temperature dependence of K2" ) + +// Quantum Mechanical Effect +`MPRnb( QMFACTOR ,0.0 ,"" ,"Prefactor + switch for QM Vth correction" ) +`MPRnb( QMTCENCV ,0.0 ,"" ,"Prefactor + switch for QM Width and Toxeff correction for CV" ) +`MPRnb( QMTCENCVA ,0.0 ,"" ,"Prefactor + switch for QM Width and Toxeff correction for CV (accumulation region)" ) +`MPRnb( AQMTCEN ,0.0 ,"" ,"Parameter for geometric dependence of Tcen on R/TFIN/HFIN" ) +`MPRex( BQMTCEN ,1.2e-8 ,"" ,0.0 ,"Parameter for geometric dependence of Tcen on R/TFIN/HFIN" ) +`MPRnb( ETAQM ,0.54 ,"" ,"Bulk charge coefficient for Tcen" ) +`MPRnb( QM0 ,1.0e-3 ,"V" ,"Knee-point for Tcen in inversion (Charge normalized to Cox)" ) +`MPRnb( PQM ,0.66 ,"" ,"Slope of normalized Tcen in inversion" ) +`MPRnb( QM0ACC ,1.0e-3 ,"V" ,"Knee-point for Tcen in accumulation (Charge normalized to Cox)" ) +`MPRnb( PQMACC ,0.66 ,"" ,"Slope of normalized Tcen in accumulation" ) + +// Velocity Saturation Model +`MPRnb( VSAT ,8.5e4 ,"m/s" ,"Saturation velocity for the saturation region" ) +`MPRnb( VSATR ,VSAT ,"m/s" ,"Saturation velocity for the saturation region in the reverse mode" ) +`MPRnb( VSATN1 ,0.0 ,"" ,"NFIN dependence of VSAT" ) +`MPRex( VSATN2 ,1.0e5 ,"" ,0.0 ,"NFIN dependence of VSAT" ) +`MPRnb( VSATRN1 ,VSATN1 ,"" ,"NFIN dependence of VSATR" ) +`MPRex( VSATRN2 ,VSATN2 ,"" ,0.0 ,"NFIN dependence of VSATR" ) +`MPRnb( AVSAT ,0.0 ,"" ,"Pre-exponential coefficient for VSAT" ) +`MPRex( BVSAT ,1.0e-7 ,"" ,0.0 ,"Exponential coefficient for VSAT" ) +`MPRnb( VSAT1 ,VSAT ,"m/s" ,"Velocity saturation parameter for Ion degradation - forward mode" ) +`MPRnb( VSAT1N1 ,VSATN1 ,"" ,"NFIN dependence of VSAT1" ) +`MPRex( VSAT1N2 ,VSATN2 ,"" ,0.0 ,"NFIN dependence of VSAT1" ) +`MPRnb( VSAT1R ,VSAT1 ,"m/s" ,"Velocity saturation parameter for Ion degradation - reverse mode" ) +`MPRnb( VSAT1RN1 ,VSAT1N1 ,"" ,"NFIN dependence of VSAT1R" ) +`MPRex( VSAT1RN2 ,VSAT1N2 ,"" ,0.0 ,"NFIN dependence of VSAT1R" ) +`MPRnb( AVSAT1 ,AVSAT ,"" ,"Pre-exponential coefficient for VSAT1" ) +`MPRex( BVSAT1 ,BVSAT ,"" ,0.0 ,"Exponential coefficient for VSAT1" ) +`MPRnb( DELTAVSAT ,1.0 ,"" ,"velocity saturation parameter in the linear region" ) +`MPRnb( PSAT ,2.0 ,"" ,"Velocity saturation exponent, after binnig should be from [2.0:inf)" ) +`MPRnb( APSAT ,0.0 ,"" ,"Pre-exponential coefficient for PSAT" ) +`MPRex( BPSAT ,1.0 ,"" ,0.0 ,"Exponential coefficient for PSAT" ) +`MPRnb( KSATIV ,1.0 ,"" ,"Parameter for long channel Vdsat" ) +`MPRnb( KSATIVR ,KSATIV ,"" ,"KSATIV in asymmetric mode" ) +`MPRnb( VSATCV ,VSAT ,"m/s" ,"Velocity saturation parameter for CV" ) +`MPRnb( AVSATCV ,AVSAT ,"" ,"Pre-exponential coefficient for VSATCV" ) +`MPRex( BVSATCV ,BVSAT ,"" ,0.0 ,"Exponential coefficient for VSATCV" ) +`MPRnb( DELTAVSATCV ,DELTAVSAT ,"" ,"Velocity saturation parameter in the linear region for the capacitance model" ) +`MPRnb( PSATCV ,PSAT ,"" ,"Velocity saturation exponent for C-V" ) +`MPRnb( APSATCV ,APSAT ,"" ,"Pre-exponential coefficient for PSATCV" ) +`MPRex( BPSATCV ,BPSAT ,"" ,0.0 ,"Exponential coefficient for PSATCV" ) +`MPRnb( MEXP ,4.0 ,"" ,"Smoothing function factor for Vdsat" ) +`MPRnb( AMEXP ,0.0 ,"" ,"Pre-exponential coefficient for MEXP" ) +`MPRnb( BMEXP ,1.0 ,"" ,"Exponential coefficient for MEXP" ) +`MPRnb( MEXPR ,MEXP ,"" ,"Reverse-mode smoothing function factor for Vdsat" ) +`MPRnb( AMEXPR ,AMEXP ,"" ,"Pre-exponential coefficient for MEXPR" ) +`MPRnb( BMEXPR ,BMEXP ,"" ,"Exponential coefficient for MEXPR" ) +`MPRnb( PTWG ,0.0 ,"/V^2" ,"Gmsat degradation parameter - forward mode" ) +`MPRnb( PTWGR ,PTWG ,"/V^2" ,"Gmsat degradation parameter - reverse mode" ) +`MPRnb( APTWG ,0.0 ,"" ,"Pre-exponential coefficient for PTWG" ) +`MPRex( BPTWG ,1.0e-7 ,"" ,0.0 ,"Exponential coefficient for PTWG" ) +`MPRnb( AT ,-1.56e-3 ,"/K" ,"Saturation velocity temperature coefficient" ) +`MPRnb( ATR ,AT ,"" ,"Reverse-mode saturation velocity temperature coefficient" ) +`MPRnb( ATCV ,AT ,"/K" ,"Saturation velocity temperature coefficient for CV" ) +`MPRnb( TMEXP ,0.0 ,"/K" ,"Temperature coefficient for Vdseff smoothing" ) +`MPRnb( TMEXPR ,TMEXP ,"/K" ,"Reverse-mode temperature coefficient for Vdseff smoothing" ) +`MPRnb( PTWGT ,4.0e-3 ,"/K" ,"PTWG temperature coefficient" ) + +// Mobility Model +`MPRnb( U0 ,3.0e-2 ,"m^2/(V*s)" ,"Low-field mobility" ) +`MPRnb( U0R ,U0 ,"m^2/(V*s)" ,"Reverse-mode low-field mobility" ) +`MPRnb( U0N1 ,0.0 ,"" ,"NFIN dependence of U0" ) +`MPRnb( U0N1R ,U0N1 ,"" ,"Reverse-mode NFIN dependence of U0" ) +`MPRex( U0N2 ,1.0e5 ,"" ,0.0 ,"NFIN dependence of U0" ) +`MPRex( U0N2R ,U0N2 ,"" ,0.0 ,"Reverse-mode NFIN dependence of U0" ) +`MPRnb( U0LT ,0.0 ,"/m" ,"Coupled NFIN and length dependence of U0" ) +`MPRnb( ETAMOB ,2.0 ,"" ,"Effective field parameter" ) +`MPRnb( UP ,0.0 ,"um^LPA" ,"Mobility L coefficient" ) +`MPRnb( LPA ,1.0 ,"" ,"Mobility L power coefficient" ) +`MPRnb( UPR ,UP ,"um^LPA" ,"Reverse-mode mobility L coefficient" ) +`MPRnb( LPAR ,LPA ,"" ,"Reverse-mode mobility L power coefficient" ) +`MPRnb( UA ,0.3 ,"(cm/MV)^EU" ,"Phonon/surface roughness scattering parameter" ) +`MPRnb( UAR ,UA ,"(cm/MV)^EU" ,"Reverse-mode phonon/surface roughness scattering parameter" ) +`MPRnb( AUA ,0.0 ,"" ,"Pre-exponential coefficient for UA" ) +`MPRnb( AUAR ,AUA ,"" ,"Reverse-mode pre-exponential coefficient for UA" ) +`MPRex( BUA ,1.0e-7 ,"" ,0.0 ,"Exponential coefficient for UA" ) +`MPRex( BUAR ,BUA ,"" ,0.0 ,"Reverse-mode exponential coefficient for UAR" ) +`MPRnb( UC ,0.0 ,"(1e-6*cm/MV^2)^EU" ,"Body effect for mobility degradation parameter - BULKMOD=1 or 2" ) +`MPRnb( UCR ,UC ,"" ,"Reverse-mode body effect for mobility degradation parameter - BULKMOD=1 or 2" ) +`MPRnb( EU ,2.5 ,"cm/MV" ,"Phonon/surface roughness scattering parameter" ) +`MPRnb( EUR ,EU ,"cm/MV" ,"Reverse-mode phonon/surface roughness scattering parameter" ) +`MPRnb( AEU ,0.0 ,"" ,"Pre-exponential coefficient for EU" ) +`MPRnb( AEUR ,AEU ,"" ,"Reverse-mode pre-exponential coefficient for EU" ) +`MPRex( BEU ,1.0e-7 ,"" ,0.0 ,"Exponential coefficient for EU" ) +`MPRex( BEUR ,BEU ,"" ,0.0 ,"Reverse-mode exponential coefficient for EU" ) +`MPRnb( UD ,0.0 ,"cm/MV" ,"Columbic scattering parameter" ) +`MPRnb( UDR ,UD ,"cm/MV" ,"Reverse-mode columbic scattering parameter" ) +`MPRnb( AUD ,0.0 ,"" ,"Pre-exponential coefficient for UD" ) +`MPRnb( AUDR ,AUD ,"" ,"Reverse-mode pre-exponential coefficient for UD" ) +`MPRex( BUD ,5.0e-8 ,"" ,0.0 ,"Exponential coefficient for UD" ) +`MPRex( BUDR ,BUD ,"" ,0.0 ,"Reverse-mode exponential coefficient for UD" ) +`MPRnb( UCS ,1.0 ,"" ,"Columbic scattering parameter" ) +`MPRnb( UTE ,0.0 ,"" ,"Mobility temperature coefficient" ) +`MPRnb( UTER ,UTE ,"" ,"Reverse-mode for mobility temperature coefficient" ) +`MPRnb( UTL ,-1.5e-3 ,"" ,"Mobility temperature coefficient" ) +`MPRnb( UTLR ,UTL ,"" ,"Reverse-mode for mobility temperature coefficient" ) +`MPRnb( EMOBT ,0.0 ,"" ,"Temperature coefficient of ETAMOB" ) +`MPRnb( UA1 ,1.032e-3 ,"" ,"Mobility temperature coefficient for UA" ) +`MPRnb( UA1R ,UA1 ,"" ,"Reverse-mode mobility temperature coefficient for UA" ) +`MPRnb( UC1 ,5.6e-11 ,"" ,"Mobility temperature coefficient for UC" ) +`MPRnb( UC1R ,UC1 ,"" ,"Reverse-mode mobility temperature coefficient for UC" ) +`MPRnb( UD1 ,0.0 ,"" ,"Mobility temperature coefficient for UC" ) +`MPRnb( UD1R ,UD1 ,"" ,"Reverse-mode mobility temperature coefficient for UD" ) +`MPRnb( UCSTE ,-4.775e-3 ,"" ,"Mobility temperature coefficient" ) +`MPRcc( CHARGEWF ,0.0 ,"" ,-1.0 ,1.0 ,"Average channel charge weighting factor, +1: source-side, 0: middle, -1: drain-side" ) + +// Access Resistance Model +`MPRnb( RDSWMIN ,0.0 ,"ohm*(um^(WR))" ,"RDSMOD = 0 S/D extension resistance per unit width at high Vgs" ) +`MPRnb( RDSW ,1.0e2 ,"ohm*(um^(WR))" ,"RDSMOD = 0 zero bias S/D extension resistance per unit width" ) +`MPRnb( ARDSW ,0.0 ,"" ,"Pre-exponential coefficient for RDSW" ) +`MPRex( BRDSW ,1.0e-7 ,"" ,0.0 ,"exponential coefficient for RDSW" ) +`MPRnb( RSWMIN ,0.0 ,"ohm*(um^(WR))" ,"RDSMOD = 1 source extension resistance per unit width at high Vgs" ) +`MPRnb( RSW ,5.0e1 ,"ohm*(um^(WR))" ,"RDSMOD = 1 zero bias source extension resistance per unit width" ) +`MPRnb( ARSW ,0.0 ,"" ,"Pre-exponential coefficient for RSW" ) +`MPRex( BRSW ,1.0e-7 ,"" ,0.0 ,"Exponential coefficient for RSW" ) +`MPRnb( RDWMIN ,0.0 ,"ohm*(um^(WR))" ,"RDSMOD = 1 drain extension resistance per unit width at high Vgs" ) +`MPRnb( RDW ,5.0e1 ,"" ,"RDSMOD = 1 zero bias drain extension resistance per unit width" ) +`MPRnb( ARDW ,0.0 ,"" ,"Pre-exponential coefficient for RDW" ) +`MPRex( BRDW ,1.0e-7 ,"" ,0.0 ,"Exponential coefficient for RDW" ) +`MPRcz( RSDR ,0.0 ,"V^(-PRSDR)" ,"Source-side drift resistance parameter - forward mode" ) +`MPRcz( RSDRR ,RSDR ,"V^(-PRSDR)" ,"Source-side drift resistance parameter - reverse mode" ) +`MPRcz( RDDR ,RSDR ,"V^(-PRDDR)" ,"Drain-side drift resistance parameter - forward mode" ) +`MPRcz( RDDRR ,RDDR ,"V^(-PRDDR)" ,"Drain-side drift resistance parameter - reverse mode" ) +`MPRnb( PRSDR ,1.0 ,"" ,"Source-side quasi-saturation parameter" ) +`MPRnb( PRDDR ,PRSDR ,"" ,"Drain-side quasi-saturation parameter" ) +`MPRnb( PRWGS ,0.0 ,"/V" ,"Gate bias dependence of source extension resistance" ) +`MPRnb( PRWGD ,PRWGS ,"/V" ,"Gate bias dependence of drain extension resistance" ) +`MPRnb( WR ,1.0 ,"" ,"W dependence parameter of S/D extension resistance" ) +`MPRnb( PRT ,1.0e-3 ,"/K" ,"Series resistance temperature coefficient" ) +`MPRnb( TRSDR ,0.0 ,"/K" ,"Source-side drift resistance temperature coefficient" ) +`MPRnb( TRDDR ,TRSDR ,"/K" ,"Drain-side drift resistance temperature coefficient" ) + +// DIBL Model +`MPRnb( PDIBL1 ,1.3 ,"" ,"DIBL output conductance parameter - forward mode" ) +`MPRnb( PDIBL1R ,PDIBL1 ,"" ,"DIBL output conductance parameter - reverse mode" ) +`MPRnb( PDIBL2 ,2.0e-4 ,"" ,"DIBL output conductance parameter" ) +`MPRnb( PDIBL2R ,PDIBL2 ,"" ,"DIBL output conductance parameter - reverse mode" ) +`MPRnb( DROUT ,1.06 ,"" ,"L dependence of DIBL effect on Rout" ) +`MPRnb( PVAG ,1.0 ,"" ,"Vgs dependence on early voltage" ) + +// Channel Length Modulation Effect +`MPRnb( PCLM ,1.3e-2 ,"" ,"Channel length modulation (CLM) parameter" ) +`MPRnb( PCLMR ,PCLM ,"" ,"Reverse model PCLM parameter" ) +`MPRnb( APCLM ,0.0 ,"" ,"Pre-exponential coefficient for PCLM" ) +`MPRnb( APCLMR ,APCLM ,"" ,"Reverse-mode pre-exponential coefficient for PCLM" ) +`MPRex( BPCLM ,1.0e-7 ,"" ,0.0 ,"Exponential coefficient for PCLM" ) +`MPRex( BPCLMR ,BPCLM ,"" ,0.0 ,"Reverse-mode exponential coefficient for PCLM" ) +`MPRnb( PCLMG ,0.0 ,"" ,"Gate bias dependence parameter for CLM" ) +`MPRnb( PCLMCV ,PCLM ,"" ,"CLM parameter for short-channel CV" ) + +// Non-Saturation Effect +`MPRnb( A1 ,0.0 ,"" ,"Non-saturation effect parameter for strong inversion Region" ) +`MPRnb( A11 ,0.0 ,"(V^-2)/K" ,"Temperature dependence of A1" ) +`MPRnb( A2 ,0.0 ,"" ,"Non-saturation effect parameter for moderate Inversion Region" ) +`MPRnb( A21 ,0.0 ,"(V^-1)/K" ,"Temperature dependence of A2" ) + +// Gate Electrode Resistance +`MPRcz( RGEXT ,0.0 ,"ohm" ,"Effective gate electrode external resistance" ) +`MPRco( RGFIN ,1.0e-3 ,"ohm" ,1.0e-3 ,inf ,"Effective gate electrode per finger per fin resistance" ) + +// Geometry Dependent Source/Drain Resistance of RGEOMOD = 0 +`MPRnb( RSHS ,0.0 ,"ohm" ,"Source-side sheet resistance" ) +`MPRnb( RSHD ,RSHS ,"ohm" ,"Drain-side sheet resistance" ) + +// Geometry Dependent Source/Drain Resistance of RGEOMOD = 1 for variability modeling +// These parameters are shared with CGEOMOD = 2 +`MPRnb( HEPI ,1.0e-8 ,"m" ,"Height of the raised source/drain on top of the fin" ) +`MPRnb( TSILI ,1.0e-8 ,"m" ,"Thickness of the silicide on top of the raised source/drain" ) +`MPRcc( RHOC ,1.0e-12 ,"ohm*(m^2)" ,1.0e-18 ,1.0e-9 ,"Contact resistivity at the silicon/silicide interface" ) +`MPRoz( RHORSD ,1.0 ,"ohm*(m)" ,"Average resistivity of silicon in the raised source/drain region" ) +`MPRcc( CRATIO ,0.5 ,"" ,0.0 ,1.0 ,"Ratio of the corner area filled with silicon to the total corner area" ) +`MPRoo( DELTAPRSD ,0.0 ,"m" ,-FPITCH ,inf ,"Change in silicon/silicide interface length due to non-rectangular epi" ) +`MPIcc( SDTERM ,0 ,"" ,0 ,1 ,"Indicator of whether the source/drain are terminated with silicide" ) +`MPRnb( LSP ,-1 ,"m" ,"Thickness of the gate sidewall spacer" ) +`MPRco( EPSRSP ,3.9 ,"" ,1.0 ,inf ,"Relative dielectric constant of the spacer" ) +`MPRoz( TGATE ,3.0e-8 ,"m" ,"Gate height on top of the hard mask" ) +`MPRcz( TMASK ,3.0e-8 ,"m" ,"Height of hard mask on top of the fin" ) +`MPRcz( ASILIEND ,0.0 ,"m^2" ,"Extra silicide cross sectional area at the two ends of the FinFET" ) +`MPRcz( ARSDEND ,0.0 ,"m^2" ,"Extra raised source/drain cross sectional areaat the two ends of the FinFET" ) +`MPRcz( PRSDEND ,0.0 ,"m" ,"Extra silicon/silicide interface perimeter at the two ends of the FinFET" ) +`MPRcc( NSDE ,2.0e25 ,"/(m^3)" ,1.0e25 ,1.0e26 ,"Source/drain active doping concentration at Leff edge" ) +`MPRnb( RGEOA ,1.0 ,"" ,"Fitting parameter for RGEOMOD=1" ) +`MPRnb( RGEOB ,0.0 ,"/m" ,"Fitting parameter for RGEOMOD=1" ) +`MPRnb( RGEOC ,0.0 ,"/m" ,"Fitting parameter for RGEOMOD=1" ) +`MPRnb( RGEOD ,0.0 ,"/m" ,"Fitting parameter for RGEOMOD=1" ) +`MPRnb( RGEOE ,0.0 ,"/m" ,"Fitting parameter for RGEOMOD=1" ) +`MPRnb( CGEOA ,1.0 ,"" ,"Fitting parameter for CGEOMOD=2" ) +`MPRnb( CGEOB ,0.0 ,"/m" ,"Fitting parameter for CGEOMOD=2" ) +`MPRnb( CGEOC ,0.0 ,"/m" ,"Fitting parameter for CGEOMOD=2" ) +`MPRnb( CGEOD ,0.0 ,"/m" ,"Fitting parameter for CGEOMOD=2" ) +`MPRcz( CGEOE ,1.0 ,"" ,"Fitting parameter for CGEOMOD=2" ) + +// Gate Current +`MPRnb( AIGBINV ,1.11e-2 ,"((F*s^2/g)^0.5)*m^-1" ,"Parameter for Igb in inversion" ) +`MPRnb( AIGBINV1 ,0.0 ,"((F*s^2/g)^0.5)*m^-1/K" ,"Parameter for Igb in inversion" ) +`MPRnb( BIGBINV ,9.49e-4 ,"((F*s^2/g)^0.5)*(m*V)^-1" ,"Parameter for Igb in inversion" ) +`MPRnb( CIGBINV ,6.0e-3 ,"/V" ,"Parameter for Igb in inversion" ) +`MPRnb( EIGBINV ,1.1 ,"V" ,"Parameter for Igb in inversion" ) +`MPRnb( NIGBINV ,3.0 ,"" ,"Parameter for Igb in inversion" ) +`MPRnb( AIGBACC ,1.36e-2 ,"((F*s^2/g)^0.5)*m^-1" ,"Parameter for Igb in accumulation" ) +`MPRnb( AIGBACC1 ,0.0 ,"((F*s^2/g)^0.5)*m^-1/K" ,"Parameter for Igb in accumulation" ) +`MPRnb( BIGBACC ,1.71e-3 ,"((F*s^2/g)^0.5)*(m*V)^-1" ,"Parameter for Igb in accumulation" ) +`MPRnb( CIGBACC ,7.5e-2 ,"/V" ,"Parameter for Igb in accumulation" ) +`MPRnb( NIGBACC ,1.0 ,"" ,"Parameter for Igb in accumulation" ) +`MPRnb( AIGC ,1.36e-2 ,"((F*s^2/g)^0.5)*m^-1" ,"Parameter for Igc in inversion" ) +`MPRnb( AIGC1 ,0.0 ,"((F*s^2/g)^0.5)*m^-1/K" ,"Parameter for Igc in inversion" ) +`MPRnb( BIGC ,1.71e-3 ,"((F*s^2/g)^0.5)*(m*V)^-1" ,"Parameter for Igc in inversion" ) +`MPRnb( CIGC ,7.5e-2 ,"/V" ,"Parameter for Igc in inversion" ) +`MPRnb( PIGCD ,1.0 ,"" ,"Parameter for Igc partition" ) +`MPRnb( DLCIGS ,0.0 ,"m" ,"Delta L for Igs model" ) +`MPRnb( AIGS ,1.36e-2 ,"((F*s^2/g)^0.5)*m^-1" ,"Parameter for Igs in inversion" ) +`MPRnb( AIGS1 ,0.0 ,"((F*s^2/g)^0.5)*m^-1/K" ,"Parameter for Igs in inversion" ) +`MPRnb( BIGS ,1.71e-3 ,"((F*s^2/g)^0.5)*(m*V)^-1" ,"Parameter for Igs in inversion" ) +`MPRnb( CIGS ,7.5e-2 ,"/V" ,"Parameter for Igs in inversion" ) +`MPRnb( DLCIGD ,DLCIGS ,"m" ,"Delta L for Igd model" ) +`MPRnb( AIGD ,AIGS ,"((F*s^2/g)^0.5)*m^-1" ,"Parameter for Igd in inversion" ) +`MPRnb( AIGD1 ,AIGS1 ,"((F*s^2/g)^0.5)*m^-1/K" ,"Parameter for Igd in inversion" ) +`MPRnb( BIGD ,BIGS ,"((F*s^2/g)^0.5)*(m*V)^-1" ,"Parameter for Igd in inversion" ) +`MPRnb( CIGD ,CIGS ,"/V" ,"Parameter for Igd in inversion" ) +`MPRnb( VFBSD ,0.0 ,"V" ,"Flatband voltage for S/D region" ) +`MPRnb( VFBSDCV ,VFBSD ,"V" ,"Flatband voltage for S/D region for C-V calculations" ) +`MPRoz( TOXREF ,1.2e-9 ,"m" ,"Target tox value" ) +`MPRnb( TOXG ,TOXP ,"m" ,"Oxide thickness for gate current model" ) +`MPRnb( NTOX ,1.0 ,"" ,"Exponent for Tox ratio" ) +`MPRnb( POXEDGE ,1.0 ,"" ,"Factor for the gate edge Tox" ) + +// GIDL/GISL Current +`MPRnb( AGISL ,6.055e-12 ,"mho" ,"Pre-exponential coefficient for GISL" ) +`MPRnb( BGISL ,3.0e8 ,"V/m" ,"Exponential coefficient for GISL" ) +`MPRnb( CGISL ,0.5 ,"V^3" ,"Parameter for body-effect of GISL" ) +`MPRnb( EGISL ,0.2 ,"V" ,"Band bending parameter for GISL" ) +`MPRnb( PGISL ,1.0 ,"" ,"Parameter for body-bias effect on GISL" ) +`MPRnb( AGIDL ,AGISL ,"mho" ,"Pre-exponential coefficient for GIDL" ) +`MPRnb( BGIDL ,BGISL ,"V/m" ,"Exponential coefficient for GIDL" ) +`MPRnb( CGIDL ,CGISL ,"V^3" ,"Parameter for body-effect of GIDL" ) +`MPRnb( EGIDL ,EGISL ,"V" ,"Band bending parameter for GIDL" ) +`MPRnb( PGIDL ,PGISL ,"" ,"Parameter for body-bias effect on GIDL" ) + +// Impact Ionization Current +// IIMOD = 1 +`MPRnb( ALPHA0 ,0.0 ,"m/V" ,"First parameter of Iii" ) +`MPRnb( ALPHA01 ,0.0 ,"m/V/K" ,"Temperature dependence of ALPHA0" ) +`MPRnb( ALPHA1 ,0.0 ,"/V" ,"L scaling parameter of Iii" ) +`MPRnb( ALPHA11 ,0.0 ,"/V/K" ,"Temperature dependence ALPHA1" ) +`MPRnb( BETA0 ,0.0 ,"/V" ,"Vds dependence parameter of Iii" ) + +// IIMOD = 2 +`MPRnb( ALPHAII0 ,0.0 ,"m/V" ,"First parameter of Iii for IIMOD=2" ) +`MPRnb( ALPHAII01 ,0.0 ,"m/V/K" ,"Temperature dependence of ALPHAII0" ) +`MPRnb( ALPHAII1 ,0.0 ,"/V" ,"L scaling parameter of Iii for IIMOD=2" ) +`MPRnb( ALPHAII11 ,0.0 ,"m/V/K" ,"Temperature dependence of ALPHAII1" ) +`MPRnb( BETAII0 ,0.0 ,"/V" ,"Vds dependence parameter of Iii" ) +`MPRnb( BETAII1 ,0.0 ,"" ,"Vds dependence parameter of Iii" ) +`MPRnb( BETAII2 ,0.1 ,"V" ,"Vds dependence parameter of Iii" ) +`MPRnb( ESATII ,1.0e7 ,"V/m" ,"Saturation channel E-field for Iii" ) +`MPRnb( LII ,0.5e-9 ,"V*m" ,"Channel length dependence parameter of Iii" ) +`MPRnb( SII0 ,0.5 ,"/V" ,"Vgs dependence parameter of Iii" ) +`MPRnb( SII1 ,0.1 ,"" ,"1st Vgs dependence parameter of Iii" ) +`MPRnb( SII2 ,0.0 ,"V" ,"2nd Vgs dependence parameter of Iii" ) +`MPRnb( SIID ,0.0 ,"V" ,"3rd Vds dependence parameter of Iii" ) +`MPRoo( IIMOD2CLAMP1 ,0.1 ,"V" ,0.0 ,inf ,"Clamp1 of SII1*Vg term in IIMOD=2 model" ) +`MPRoo( IIMOD2CLAMP2 ,0.1 ,"V" ,0.0 ,inf ,"Clamp2 of SII0*Vg term in IIMOD=2 model" ) +`MPRoo( IIMOD2CLAMP3 ,0.1 ,"V" ,0.0 ,inf ,"Clamp3 of Ratio term in IIMOD=2 model" ) + +// Accumulation Capacitance +`MPRco( EOTACC ,EOT ,"m" ,1.0e-10 ,inf ,"Equivalent oxide thickness for accumulation region" ) +`MPRnb( DELVFBACC ,0.0 ,"V" ,"Change in flatband voltage: Vfb_accumulation - Vfb_inversion" ) + +// Fringe Capacitance +// CGEOMOD=0 +`MPRcz( CFS ,2.5e-11 ,"F/m" ,"Outer fringe capacitance at source side" ) +`MPRcz( CFD ,CFS ,"F/m" ,"Outer fringe capacitance at drain side" ) + +// Overlap Capacitance for CGEOMOD = 0 and 2 +`MPRcz( CGSO ,0.0 ,"F/m" ,"Non LDD region source-gate overlap capacitance per unit channel width" ) +`MPRcz( CGDO ,CGSO ,"F/m" ,"Non LDD region drain-gate overlap capacitance per unit channel width" ) +`MPRcz( CGSL ,0.0 ,"F/m" ,"Overlap capacitance between gate and lightly-doped source region (for CGEOMOD = 0, 2)" ) +`MPRcz( CGDL ,CGSL ,"F/m" ,"Overlap capacitance between gate and lightly-doped drain region (for CGEOMOD = 0, 2)" ) +`MPRco( CKAPPAS ,0.6 ,"V" ,2.0e-2 ,inf ,"Coefficient of bias-dependent overlap capacitance for the source side (for CGEOMOD = 0, 2)" ) +`MPRco( CKAPPAD ,CKAPPAS ,"V" ,2.0e-2 ,inf ,"Coefficient of bias-dependent overlap capacitance for the drain side (for CGEOMOD = 0, 2)" ) +`MPRcz( CGBO ,0.0 ,"F/m" ,"Gate-to-substrate overlap capacitance per unit channel length per finger per NGCON" ) +`MPRcz( CGBN ,0.0 ,"F/m" ,"Gate-to-substrate overlap capacitance per unit channel length per fin per finger" ) +`MPRcz( CGBL ,0.0 ,"F/m" ,"Bias dependent component of gate-to-substrate overlap capacitance per unit channel length per fin per finger" ) +`MPRco( CKAPPAB ,0.6 ,"" ,2.0e-2 ,inf ,"Bias dependent gate-to-substrate parasitic capacitance" ) + +// Source/Drain-to-Substrate Sidewall Capacitance +`MPRcz( CSDESW ,0.0 ,"F/m" ,"Coefficient for source/drain-to-substrate sidewall capacitance" ) + +// Junction Current and Capacitance +// Junction Capacitance +`MPRnb( CJS ,5.0e-4 ,"F/m^2" ,"Unit area source-side junction capacitance at zero bias" ) +`MPRnb( CJD ,CJS ,"F/m^2" ,"Unit area drain-side junction capacitance at zero bias" ) +`MPRnb( CJSWS ,5.0e-10 ,"F/m" ,"Unit length source-side sidewall junction capacitance at zero bias" ) +`MPRnb( CJSWD ,CJSWS ,"F/m" ,"Unit length drain-side sidewall junction capacitance at zero bias" ) +`MPRnb( CJSWGS ,0.0 ,"F/m" ,"Unit length source-side gate sidewall junction capacitance at zero bias" ) +`MPRnb( CJSWGD ,CJSWGS ,"F/m" ,"Unit length drain-side gate sidewall junction capacitance at zero bias" ) +`MPRnb( PBS ,1.0 ,"V" ,"Source-side bulk junction built-in potential" ) +`MPRnb( PBD ,PBS ,"V" ,"Drain-side bulk junction built-in potential" ) +`MPRnb( PBSWS ,1.0 ,"V" ,"Built-in potential for Source-side sidewall junction capacitance" ) +`MPRnb( PBSWD ,PBSWS ,"V" ,"Built-in potential for Drain-side sidewall junction capacitance" ) +`MPRnb( PBSWGS ,PBSWS ,"V" ,"Built-in potential for Source-side gate sidewall junction capacitance" ) +`MPRnb( PBSWGD ,PBSWGS ,"V" ,"Built-in potential for Drain-side gate sidewall junction capacitance" ) +`MPRnb( MJS ,0.5 ,"" ,"Source bottom junction capacitance grading coefficient" ) +`MPRnb( MJD ,MJS ,"" ,"Drain bottom junction capacitance grading coefficient" ) +`MPRnb( MJSWS ,0.33 ,"" ,"Source sidewall junction capacitance grading coefficient" ) +`MPRnb( MJSWD ,MJSWS ,"" ,"Drain sidewall junction capacitance grading coefficient" ) +`MPRnb( MJSWGS ,MJSWS ,"" ,"Source-side gate sidewall junction capacitance grading coefficient" ) +`MPRnb( MJSWGD ,MJSWGS ,"" ,"Drain-side gate sidewall junction capacitance grading coefficient" ) + +// Second Junction for Two-Step Junction Capacitance +`MPRcz( SJS ,0.0 ,"" ,"Constant for source-side two-step second junction" ) +`MPRcz( SJD ,SJS ,"" ,"Constant for drain-side two-step second junction" ) +`MPRcz( SJSWS ,0.0 ,"" ,"Constant for source-side sidewall two-step second junction" ) +`MPRcz( SJSWD ,SJSWS ,"" ,"Constant for drain-side sidewall two-step second junction" ) +`MPRcz( SJSWGS ,0.0 ,"" ,"Constant for source-side gate sidewall two-step second junction" ) +`MPRcz( SJSWGD ,SJSWGS ,"" ,"Constant for source-side gate sidewall two-step second junction" ) +`MPRnb( MJS2 ,1.25e-1 ,"" ,"Source bottom two-step second junction capacitance grading coefficient" ) +`MPRnb( MJD2 ,MJS2 ,"" ,"Drain bottom two-step second junction capacitance grading coefficient" ) +`MPRnb( MJSWS2 ,8.3e-2 ,"" ,"Source sidewall two-step second junction capacitance grading coefficient" ) +`MPRnb( MJSWD2 ,MJSWS2 ,"" ,"Drain sidewall two-step second junction capacitance grading coefficient" ) +`MPRnb( MJSWGS2 ,MJSWS2 ,"" ,"Source-side gate sidewall two-step second junction capacitance grading coefficient" ) +`MPRnb( MJSWGD2 ,MJSWGS2 ,"" ,"Drain-side gate sidewall two-step second junction capacitance grading coefficient" ) + +// Junction Current +`MPRnb( JSS ,1.0e-4 ,"A/m^2" ,"Bottom source junction reverse saturation current density" ) +`MPRnb( JSD ,JSS ,"A/m^2" ,"Bottom drain junction reverse saturation current density" ) +`MPRnb( JSWS ,0.0 ,"A/m" ,"Unit length reverse saturation current for sidewall source junction" ) +`MPRnb( JSWD ,JSWS ,"A/m" ,"Unit length reverse saturation current for sidewall drain junction" ) +`MPRnb( JSWGS ,0.0 ,"A/m" ,"Unit length reverse saturation current for gate-edge sidewall source junction" ) +`MPRnb( JSWGD ,JSWGS ,"A/m" ,"Unit length reverse saturation current for gate-edge sidewall drain junction" ) +`MPRex( NJS ,1.0 ,"" ,0.0 ,"Source junction emission coefficient" ) +`MPRex( NJD ,NJS ,"" ,0.0 ,"Drain junction emission coefficient" ) +`MPRnb( IJTHSFWD ,0.1 ,"A" ,"Forward source diode breakdown limiting current" ) +`MPRnb( IJTHDFWD ,IJTHSFWD ,"A" ,"Forward drain diode breakdown limiting current" ) +`MPRnb( IJTHSREV ,0.1 ,"A" ,"Reverse source diode breakdown limiting current" ) +`MPRnb( IJTHDREV ,IJTHSREV ,"A" ,"Reverse drain diode breakdown limiting current" ) +`MPRnb( BVS ,1.0e1 ,"V" ,"Source diode breakdown voltage" ) +`MPRnb( BVD ,BVS ,"V" ,"Drain diode breakdown voltage" ) +`MPRnb( XJBVS ,1.0 ,"" ,"Fitting parameter for source diode breakdown current" ) +`MPRnb( XJBVD ,XJBVS ,"" ,"Fitting parameter for drain diode breakdown current" ) + +// Tunneling Component of Junction Current +`MPRnb( JTSS ,0.0 ,"A/m^2" ,"Bottom source junction trap-assisted saturation current density" ) +`MPRnb( JTSD ,JTSS ,"A/m^2" ,"Bottom drain junction trap-assisted saturation current density" ) +`MPRnb( JTSSWS ,0.0 ,"A/m" ,"Unit length trap-assisted saturation current for sidewall source junction" ) +`MPRnb( JTSSWD ,JTSSWS ,"A/m" ,"Unit length trap-assisted saturation current for sidewall drain junction" ) +`MPRnb( JTSSWGS ,0.0 ,"A/m" ,"Unit length trap-assisted saturation current for gate-edge sidewall source junction" ) +`MPRnb( JTSSWGD ,JTSSWGS ,"A/m" ,"Unit length trap-assisted saturation current for gate-edge sidewall drain junction" ) +`MPRnb( JTWEFF ,0.0 ,"m" ,"Trap-assisted tunneling current width dependence" ) +`MPRnb( NJTS ,2.0e1 ,"" ,"Non-ideality factor for JTSS" ) +`MPRnb( NJTSD ,NJTS ,"" ,"Non-ideality factor for JTSD" ) +`MPRnb( NJTSSW ,2.0e1 ,"" ,"Non-ideality factor for JTSSWS" ) +`MPRnb( NJTSSWD ,NJTSSW ,"" ,"Non-ideality factor for JTSSWD" ) +`MPRnb( NJTSSWG ,2.0e1 ,"" ,"Non-ideality factor for JTSSWGS" ) +`MPRnb( NJTSSWGD ,NJTSSWG ,"" ,"Non-ideality factor for JTSSWGD" ) +`MPRnb( VTSS ,1.0e1 ,"V" ,"Bottom source junction trap-assisted current voltage dependent parameter" ) +`MPRnb( VTSD ,VTSS ,"V" ,"Bottom drain junction trap-assisted current voltage dependent parameter" ) +`MPRnb( VTSSWS ,1.0e1 ,"V" ,"Unit length trap-assisted current voltage dependent parameter for sidewall source junction" ) +`MPRnb( VTSSWD ,VTSSWS ,"V" ,"Unit length trap-assisted current voltage dependent parameter for sidewall drain junction" ) +`MPRnb( VTSSWGS ,1.0e1 ,"V" ,"Unit length trap-assisted current voltage dependent parameter for gate-edge sidewall source junction" ) +`MPRnb( VTSSWGD ,VTSSWGS ,"V" ,"Unit length trap-assisted current voltage dependent parameter for gate-edge sidewall drain junction" ) + +// Recombination-Generation Current +`MPRnb( LINTIGEN ,0.0 ,"m" ,"Lint for thermal generation current" ) +`MPRnb( NTGEN ,1.0 ,"" ,"Thermal generation current parameter" ) +`MPRnb( AIGEN ,0.0 ,"(m^-3)*(V^-1)" ,"Thermal generation current parameter" ) +`MPRnb( BIGEN ,0.0 ,"(m^-3)*(V^-3)" ,"Thermal generation current parameter" ) + +// NQS Gate Resistance Model & NQS Charge Deficit Model +// For NQSMOD=1, Set XRCRG1=0 to turn off NQS gate resistance +`MPRnb( XRCRG1 ,1.2e1 ,"" ,"Parameter for non-quasistatic gate resistance (NQSMOD = 1) and NQSMOD = 2" ) +`MPRnb( XRCRG2 ,1.0 ,"" ,"Parameter for non-quasistatic gate resistance (NQSMOD = 1) and NQSMOD = 2" ) + +// NQS Charge Segmentation Model +`MPIcc( NSEG ,4 ,"" ,4 ,10 ,"Number of segments for NQSMOD=3 (3, 5 & 10 supported)" ) + +// Flicker Noise +`MPRnb( EF ,1.0 ,"" ,"Flicker noise frequency exponent" ) +`MPRnb( EM ,4.1e7 ,"V/m" ,"Flicker noise parameter" ) +`MPRnb( NOIA ,6.25e39 ,"(eV^-1)*(s^(1-EF))*(m^-3)" ,"Flicker noise parameter" ) +`MPRnb( NOIB ,3.125e24 ,"(eV^-1)*(s^(1-EF))*(m^-1)" ,"Flicker noise parameter" ) +`MPRnb( NOIC ,8.75e7 ,"(eV^-1)*(s^(1-EF))*(m)" ,"Flicker noise parameter" ) +`MPRnb( LINTNOI ,0.0 ,"m^2" ,"L offset for flicker noise calculation" ) + +// Thermal Noise +`MPRcz( NTNOI ,1.0 ,"" ,"Thermal noise parameter" ) +`MPRnb( TNOIA ,1.5 ,"/m" ,"Thermal noise parameter" ) +`MPRnb( TNOIB ,3.5 ,"/m" ,"Thermal noise parameter" ) +`MPRnb( RNOIA ,5.77e-1 ,"" ,"Thermal noise coefficient" ) +`MPRnb( RNOIB ,3.7e-1 ,"" ,"Thermal noise coefficient" ) + +// Parameters Controlled by Correlated Thermal Noise Switch +`ifdef __TNOIMOD1__ +`MPRnb( TNOIC ,3.5 ,"" ,"Thermal noise parameter for TNOIMOD=1" ) +`MPRnb( RNOIC ,3.95e-1 ,"" ,"Thermal noise coefficient for TNOIMOD=1" ) +`MPRex( SCALEN ,1.0e5 ,"" ,0.0 ,"Noise scaling parameter for TNOIMOD=1" ) +`endif + +// Temperature Effects +`MPRco( TNOM ,27.0 ,"Celsius" ,-`P_CELSIUS0,inf ,"Temperature at which the model is extracted" ) +`MPRnb( TBGASUB ,7.02e-4 ,"eV/K" ,"Bandgap temperature coefficient" ) +`MPRnb( TBGBSUB ,1.108e3 ,"K" ,"Bandgap temperature coefficient" ) +`MPRnb( KT1 ,0.0 ,"V" ,"Vth temperature coefficient" ) +`MPRnb( KT1L ,0.0 ,"V*m" ,"Vth temperature L coefficient" ) +`MPRnb( TSS ,0.0 ,"/K" ,"Swing temperature coefficient" ) +`MPRnb( IIT ,-0.5 ,"" ,"Impact ionization temperature dependence for IIMOD = 1" ) +`MPRnb( TII ,0.0 ,"" ,"Impact ionization temperature dependence for IIMOD = 2" ) +`MPRnb( TGIDL ,-3.0e-3 ,"/K" ,"GIDL/GISL temperature dependence" ) +`MPRnb( IGT ,2.5 ,"" ,"Gate current temperature dependence" ) +`MPRnb( TCJ ,0.0 ,"/K" ,"Temperature coefficient for CJS/CJD" ) +`MPRnb( TCJSW ,0.0 ,"/K" ,"Temperature coefficient for CJSWS/CJSWD" ) +`MPRnb( TCJSWG ,0.0 ,"/K" ,"Temperature coefficient for CJSWGS/CJSWGD" ) +`MPRnb( TPB ,0.0 ,"/K" ,"Temperature coefficient for PBS/PBD" ) +`MPRnb( TPBSW ,0.0 ,"/K" ,"Temperature coefficient for PBSWS/PBSWD" ) +`MPRnb( TPBSWG ,0.0 ,"/K" ,"Temperature coefficient for PBSWGS/PBSWGD" ) +`MPRnb( XTIS ,3.0 ,"" ,"Source junction current temperature exponent" ) +`MPRnb( XTID ,XTIS ,"" ,"Drain junction current temperature exponent" ) +`MPRnb( XTSS ,2.0e-2 ,"" ,"Power dependence of JTSS on temperature" ) +`MPRnb( XTSD ,XTSS ,"" ,"Power dependence of JTSD on temperature" ) +`MPRnb( XTSSWS ,2.0e-2 ,"" ,"Power dependence of JTSSWS on temperature" ) +`MPRnb( XTSSWD ,XTSSWS ,"" ,"Power dependence of JTSSWD on temperature" ) +`MPRnb( XTSSWGS ,2.0e-2 ,"" ,"Power dependence of JTSSWGS on temperature" ) +`MPRnb( XTSSWGD ,XTSSWGS ,"" ,"Power dependence of JTSSWGD on temperature" ) +`MPRnb( TNJTS ,0.0 ,"" ,"Temperature coefficient for NJTS" ) +`MPRnb( TNJTSD ,TNJTS ,"" ,"Temperature coefficient for NJTSD" ) +`MPRnb( TNJTSSW ,0.0 ,"" ,"Temperature coefficient for NJTSSW" ) +`MPRnb( TNJTSSWD ,TNJTSSW ,"" ,"Temperature coefficient for NJTSSWD" ) +`MPRnb( TNJTSSWG ,0.0 ,"" ,"Temperature coefficient for NJTSSWG" ) +`MPRnb( TNJTSSWGD ,TNJTSSWG ,"" ,"Temperature coefficient for NJTSSWGD" ) + +// Self Heating +`MPRcz( RTH0 ,1.0e-2 ,"ohm*m*K/W" ,"Thermal resistance" ) +`MPRcz( CTH0 ,1.0e-5 ,"W*s/m/K" ,"Thermal capacitance" ) +`MPRcz( WTH0 ,0.0 ,"m" ,"Width dependence coefficient for Rth and Cth" ) +`MPRcz( ASHEXP ,1.0 ,"" ,"Exponent to tune RTH dependence of NFINTOTAL" ) +`MPRcz( BSHEXP ,1.0 ,"" ,"Exponent to tune RTH dependence of NF" ) + +// Unified Model +`MPRoz( ACH_UFCM ,1.0 ,"m^2" ,"Area of the channel for the unified Model" ) +`MPRoz( CINS_UFCM ,1.0 ,"F/m" ,"Insulator capacitance for the unified Model" ) +`MPRoz( W_UFCM ,1.0 ,"m" ,"Effective channel width for the unified Model" ) +`MPRcz( TFIN_TOP ,1.5e-8 ,"m" ,"Top body (fin) thickness for trapezoidal triple gate" ) +`MPRco( TFIN_BASE ,1.5e-8 ,"m" ,1.0e-9 ,inf ,"Base body (fin) thickness for trapezoidal triple gate" ) +`MPRcz( QMFACTORCV ,0.0 ,"" ,"Charge dependence taking QM effects into account" ) +`MPRcz( ALPHA_UFCM ,0.5556 ,"" ,"Mobile charge scaling term taking QM effects into account" ) + +// Binning Parameters +`include "bsimcmg_binning_parameters.include" + +// Output Variables +`ifdef __OPINFO__ + (* desc= "WEFF" *) real WEFF; + (* desc= "LEFF" *) real LEFF; + (* desc= "WEFFCV" *) real WEFFCV; + (* desc= "LEFFCV" *) real LEFFCV; + (* desc= "IDS" *) real IDS; + (* desc= "IDEFF" *) real IDEFF; + (* desc= "ISEFF" *) real ISEFF; + (* desc= "IGTOT" *) real IGTOT; + (* desc= "IDSGEN" *) real IDSGEN; + (* desc= "III" *) real III; + (* desc= "IGS" *) real IGS; + (* desc= "IGD" *) real IGD; + (* desc= "IGCS" *) real IGCS; + (* desc= "IGCD" *) real IGCD; + (* desc= "IGBS" *) real IGBS; + (* desc= "IGBD" *) real IGBD; + (* desc= "IGIDL" *) real IGIDL; + (* desc= "IGISL" *) real IGISL; + (* desc= "IJSB" *) real IJSB; + (* desc= "IJDB" *) real IJDB; + (* desc= "ISUB" *) real ISUB; + (* desc= "BETA" *) real BETA; + (* desc= "VTH" *) real VTH; + (* desc= "VDSSAT" *) real VDSSAT; + (* desc= "VFB" *) real VFB; + (* desc= "GM" *) real GM; + (* desc= "GDS" *) real GDS; + (* desc= "GMBS" *) real GMBS; + (* desc= "QGI" *) real QGI; + (* desc= "QDI" *) real QDI; + (* desc= "QSI" *) real QSI; + (* desc= "QBI" *) real QBI; + (* desc= "QG" *) real QG; + (* desc= "QD" *) real QD; + (* desc= "QS" *) real QS; + (* desc= "QB" *) real QB; + (* desc= "CGGI" *) real CGGI; + (* desc= "CGSI" *) real CGSI; + (* desc= "CGDI" *) real CGDI; + (* desc= "CGEI" *) real CGEI; + (* desc= "CDGI" *) real CDGI; + (* desc= "CDDI" *) real CDDI; + (* desc= "CDSI" *) real CDSI; + (* desc= "CDEI" *) real CDEI; + (* desc= "CSGI" *) real CSGI; + (* desc= "CSDI" *) real CSDI; + (* desc= "CSSI" *) real CSSI; + (* desc= "CSEI" *) real CSEI; + (* desc= "CEGI" *) real CEGI; + (* desc= "CEDI" *) real CEDI; + (* desc= "CESI" *) real CESI; + (* desc= "CEEI" *) real CEEI; + (* desc= "CGG" *) real CGG; + (* desc= "CGS" *) real CGS; + (* desc= "CGD" *) real CGD; + (* desc= "CGE" *) real CGE; + (* desc= "CDG" *) real CDG; + (* desc= "CDD" *) real CDD; + (* desc= "CDS" *) real CDS; + (* desc= "CDE" *) real CDE; + (* desc= "CSG" *) real CSG; + (* desc= "CSD" *) real CSD; + (* desc= "CSS" *) real CSS; + (* desc= "CSE" *) real CSE; + (* desc= "CEG" *) real CEG; + (* desc= "CED" *) real CED; + (* desc= "CES" *) real CES; + (* desc= "CEE" *) real CEE; + (* desc= "CGSEXT" *) real CGSEXT; + (* desc= "CGDEXT" *) real CGDEXT; + (* desc= "CGBOV" *) real CGBOV; + (* desc= "CJST" *) real CJST; + (* desc= "CJDT" *) real CJDT; + (* desc= "RSGEO" *) real RSGEO; + (* desc= "RDGEO" *) real RDGEO; + (* desc= "CFGEO" *) real CFGEO; + (* desc= "T_TOTAL_K" *) real T_TOTAL_K; + (* desc= "T_TOTAL_C" *) real T_TOTAL_C; + (* desc= "T_DELTA_SH" *) real T_DELTA_SH; + + `ifdef __DEBUG__ + (* desc= "IGBACC" *) real IGBACC; + (* desc= "IGBINV" *) real IGBINV; + (* desc= "DIDSDVG" *) real DIDSDVG; + (* desc= "DIDSDVS" *) real DIDSDVS; + (* desc= "DIDSDVD" *) real DIDSDVD; + (* desc= "DIGSDVG" *) real DIGSDVG; + (* desc= "DIGSDVS" *) real DIGSDVS; + (* desc= "DIGSDVD" *) real DIGSDVD; + (* desc= "DIGDDVG" *) real DIGDDVG; + (* desc= "DIGDDVS" *) real DIGDDVS; + (* desc= "DIGDDVD" *) real DIGDDVD; + (* desc= "DIIIDVG" *) real DIIIDVG; + (* desc= "DIIIDVS" *) real DIIIDVS; + (* desc= "DIIIDVD" *) real DIIIDVD; + (* desc= "DIGIDLDVG" *) real DIGIDLDVG; + (* desc= "DIGIDLDVS" *) real DIGIDLDVS; + (* desc= "DIGIDLDVD" *) real DIGIDLDVD; + (* desc= "DIGISLDVG" *) real DIGISLDVG; + (* desc= "DIGISLDVS" *) real DIGISLDVS; + (* desc= "DIGISLDVD" *) real DIGISLDVD; + + `ifdef __SHMOD__ + (* desc= "CGT" *) real CGT; + (* desc= "CST" *) real CST; + (* desc= "CDT" *) real CDT; + (* desc= "DIDSDVTH" *) real DIDSDVTH; + (* desc= "DIGSDVTH" *) real DIGSDVTH; + (* desc= "DIGDDVTH" *) real DIGDDVTH; + (* desc= "DIIIDVTH" *) real DIIIDVTH; + (* desc= "DIGIDLDVTH" *) real DIGIDLDVTH; + (* desc= "DIGISLDVTH" *) real DIGISLDVTH; + (* desc= "DITHDVTH" *) real DITHDVTH; + `endif + + (* desc= "ITH" *) real ITH; + (* desc= "DITHDVG" *) real DITHDVG; + (* desc= "DITHDVS" *) real DITHDVS; + (* desc= "DITHDVD" *) real DITHDVD; + `endif +`endif + +// Variables Inside the Model +integer devsign; + +real NFINtotal; +real DevTemp; +real ids0, ids0_ov_dqi, ids, vgs, vds, vdsx, sigvds, vch, etaiv; +real vgs_noswap, vds_noswap, vgd_noswap; +real qd, qg, qs, qb; +real ni, epssub, epssp, epsratio, Eg, Eg0, Nc; +real Lg, deltaL, deltaL1, deltaLCV, Leff, Leff1, LeffCV, LeffCV_acc, Weff0, WeffCV0; +real cox, cdsc, cbox; +real nbody, phib, deltaPhi; +real T0, T0y, T1, T1y, T2, T2y, T3, T3y, T4, T4a, T5, T6, T7, T8, T9; +real Vtm, Vtm0, nVtm; +real beta, beta0 ; +real wf, wr; + +// Temperature Effects +real Tnom, TRatio, dvth_temp, delTemp, ThetaSS; +real K0_t, K0SI_t, K2SI_t, K1_t, K2SAT_t, A1_t, A2_t; +real AIGBINV_t, AIGBACC_t, AIGC_t, AIGS_t, AIGD_t; +real BETA0_t, SII0_t, BGISL_t, BGIDL_t, igtemp, PTWG_t, PTWGR_t; +real ALPHA0_t, ALPHA1_t, ALPHAII0_t, ALPHAII1_t; +real CJS_t, CJSWS_t, CJSWGD_t, CJD_t, CJSWD_t, CJSWGS_t; +real PBS_t, PBSWS_t, PBSWGS_t, PBD_t, PBSWD_t, PBSWGD_t; +real JSS_t, JSWS_t, JSWGS_t, JSD_t, JSWD_t, JSWGD_t; +real JTSS_t, JTSD_t, JTSSWS_t, JTSSWD_t, JTSSWGS_t, JTSSWGD_t; +real NJTS_t, NJTSD_t, NJTSSW_t, NJTSSWD_t, NJTSSWG_t, NJTSSWGD_t; +real K2_t; +real K0SISAT_t, K2SISAT_t; + +// Variables for analytical surface potential +real q0; +real T10, T11, T12; +real e0, e1, e2; + +// Accumulation Model +real vgsfb, vgsfbeff; + +// Short Channel Effect +real ETA0_t, ETA0R_t; +real scl, vbi, phist, dvth_vtroll, dvth_dibl, dvth_rsce, dvth_all; +real tmp, Theta_SCE, Theta_SW, Theta_DIBL, Theta_RSCE, Theta_DITS; + +// Lateral Non-uniform Doping Effect +real Mnud; + +// Body Effect for BULKMOD=1 +real ves, vesx, vesmax, veseff; +real Mob; + +// Quantum mechanical correction [units are MKS] +real coxeff, Tcen0, Tcen, dvch_qm, MTcen; +real E0, E0prime, E1, E1prime, mx, mxprime, md, mdprime; +real gprime, gfactor, gam0, gam1, kT; + +// Drain Saturation Voltage +real Vdseff, qis, qid, qbs, Dmobs; + +// Midpoint Potential and Charge +real qia, qia2, qba, dqi; +real qb0; +real eta_mu, eta_mu_cv, Eeffm, Eeffm_cv, Dmob, Dmob_cv, u0, ueff, u0_a, u0r; +real UA_t, UAR_t, UC_t, UCR_t, UCS_t, UD_t, UDR_t, U0_t, U0R_t, ETAMOB_t, Eeffs, EeffFactor; + +real Dr, WeffWRFactor; +real RSourceGeo, RDrainGeo; +real RDSWMIN_i, RDWMIN_i, RSWMIN_i; +real Rdrain, Rsource; + +real rdstemp, Rdsi, Rdss; +real RSDR_t, RSDRR_t, RDDR_t, RDDRR_t; + +real DIBLfactor, PVAGfactor, diffVds, VaDIBL, Vgst2Vtm, Moc, Mclm; +real MclmCV, inv_MclmCV; + +real Dvsat, Vdsat, inv_MEXP, DvsatCV, Nsat; +real VSAT_t, VSAT1_t, VSAT1R_t, VSATCV_t, MEXP_t, MEXPR_t, Esat, EsatL, Esat1, Esat1L, EsatCV, EsatCVL; +real WVCox, Ta, Tb, Tc; + +// Asymmetry Model +real VSAT1_a, MEXP_a, PTWG_a, RSDR_a, RDDR_a, PDIBL1_a, VSAT_a; + +// Geometry dependent Source/Drain Resistance +real mu_max, mu_rsd, rhorsd, afin, thetarsp; +real Rsp, lt, arsd_total, prsd_total, alpha; +real eta, RrsdTML, Rrsdside, Rrsd; +real Rdsgeo, Arsd, Prsd; + +// Geometry dependent fringing capacitance +real Hg, Wg, Trsd, Hrsd, Cgg_top, Cgg_side, Cfr_geo, Acorner, Ccorner; + +// Gate Electrode Resistance +`ifdef __RGATEMOD__ + real ggeltd, Rgeltd; +`endif + +// Gate Current +real Vaux_Igbinv, igbinv, igsd_mult, igsd_mult0, igbs, igbd; +real Voxacc, Vaux_Igbacc, vfbzb, igbacc; +real igcs, igcd, igc0, Vdseffx, T1_exp; +real igisl, igidl, vfbsd, igs, igd, vgs_eff, vgd_eff; +real Aechvb, Bechvb, Toxratio, Toxratioedge; + +// Impact Ionization current +real Iii, Vdiff, Vdsatii, VgsStep, Ratio, ALPHAII; + +// Accumulation Capacitance +real cox_acc; +real qg_acc, qb_acc; +real vge; + +// Parasitic Capacitance +real qgs_ov, qgd_ov, qgs_fr, qgd_fr, qds_fr; +real qgs_parasitic, qgd_parasitic, Qes, Qed, Qeg; +real vgs_overlap, vgd_overlap, vge_overlap; +real cgsp, cgdp, csbox, cdbox, cgbox, vfbsdcv; + +// Junction Current and Capacitance +real Ies, Ied, ves_jct, ved_jct, vec; +real Czbs, Czbssw, Czbsswg, Czbd, Czbdsw, Czbdswg; +real pb2, arg, sarg, Qec; +real Qesj, Qesj1, Qesj2, Qesj3, Qedj, Qedj1, Qedj2, Qedj3; +real Isbs, Isbd, Nvtms, Nvtmd; +real SslpRev, IVjsmRev, VjsmRev, SslpFwd, IVjsmFwd, VjsmFwd, XExpBVS; +real DslpRev, IVjdmRev, VjdmRev, DslpFwd, IVjdmFwd, VjdmFwd, XExpBVD; +real igentemp, idsgen, LINTIGEN_i; + +// NQS Gate Resistance +`ifdef __NQSMOD1__ + real gcrg, XRCRG1_i, XRCRG2_i; + real IdovVds; +`endif + +// NQS Charge Deficit Model +`ifdef __NQSMOD2__ + real xdpart, gtau, gcrg, XRCRG1_i, XRCRG2_i; + real IdovVds; +`endif + +// Flicker Noise +real LINTNOI_i; +real litl, Esatnoi, Leffnoi, Leffnoisq, DelClm; +real N0, Nl, Nstar, Ssi, Swi, FNPowerAt1Hz; + +// Thermal Noise +real NTNOI_i, qinv; +real Gtnoi, sid; +real gspr, gdpr; + +// Variables Controlled by Correlated Thermal Noise Switch +`ifdef __TNOIMOD1__ + real Abulk, etaa, gamma, delta, epsilon, gche; + real npart_beta, npart_theta, ctnoi, npart_c; + real noiGd0, GammaGd0, C0, sf; +`endif + +// Self Heating +`ifdef __SHMOD__ + real gth, cth; +`endif + +// Binning +real Inv_L, Inv_NFIN, Inv_LNFIN; +real NBODY_i, PHIG_i, CFD_i, CFS_i, COVS_i, COVD_i, CGSO_i, CGDO_i; +real CGSL_i, CGDL_i, CGBL_i, CKAPPAS_i, CKAPPAD_i, CKAPPAB_i; +real QMFACTOR_i, QMTCENCV_i, QMTCENCVA_i, KSATIV_i, KSATIVR_i, KSATIV_a; +real CDSC_i, CDSCD_i, CDSCD_a, CDSCDR_i, CIT_i, DVT0_i, CITR_i, CIT_a; +real DVT1_i, DVT1SS_i, PHIN_i, ETA0_i, ETA0_a, ETA0R_i, DSUB_i, VSAT_i, VSATR_i, VSATR_t; +real DVTP0_i, DVTP1_i ; +real K0_i, K01_i, K0SI_i, K0SI1_i, K2SI_i, K2SI1_i, PHIBE_i, K1_i, K11_i, K2SAT_i, K2SAT1_i; +real DELTAVSAT_i, PSAT_i, DELTAVSATCV_i, PSATCV_i, VSAT1_i, VSAT1R_i, PTWG_i, PTWGR_i, VSATCV_i; +real UP_i, U0_i, U0R_i, ETAMOB_i, NGATE_i, RDSW_i, UPR_i; +real PRWGS_i, PRWGD_i, WR_i, PDIBL1_i, PDIBL1R_i, PDIBL2_i,PDIBL2R_i, PDIBL2_a ; +real DROUT_i, PVAG_i; +real AIGBINV_i, AIGBINV1_i, BIGBINV_i, CIGBINV_i, EIGBINV_i, NIGBINV_i; +real AIGBACC_i, AIGBACC1_i, BIGBACC_i, CIGBACC_i, NIGBACC_i; +real AIGC_i, AIGC1_i, BIGC_i, CIGC_i, PIGCD_i; +real AIGS_i, AIGS1_i, BIGS_i, CIGS_i, NTOX_i, POXEDGE_i; +real AIGD_i, AIGD1_i, BIGD_i, CIGD_i; +real AGIDL_i, BGIDL_i, CGIDL_i, EGIDL_i, PGIDL_i; +real AGISL_i, BGISL_i, CGISL_i, EGISL_i, PGISL_i; +real ALPHA0_i, ALPHA1_i, ALPHAII0_i, ALPHAII1_i, BETA0_i; +real BETAII0_i, BETAII1_i, BETAII2_i, ESATII_i; +real LII_i, SII0_i, SII1_i, SII2_i, SIID_i, TII_i; +real MEXP_i, MEXPR_i; +real PCLM_i, PCLMG_i, PCLMCV_i, PCLM_a, PCLMR_i; +real A1_i, A2_i, A11_i, A21_i; +real K1RSCE_i, LPE0_i, DVTSHIFT_i, DVTSHIFT_a, DVTSHIFTR_i ; +real UA_i, UC_i, EU_i, UD_i, UCS_i, UAR_i, EUR_i, UCR_i, UDR_i, UA_a, UD_a, UC_a, EU_a; +real UA1_i, UA1R_i, UC1_i, UD1_i, UCSTE_i, UTE_i, UTL_i, EMOBT_i, UC1R_i, UD1R_i, UTER_i, UTLR_i; +real PTWGT_i; +real AT_i, ATCV_i, ATR_i; +real RDW_i, RSW_i; +real PRT_i, KT1_i, TSS_i, IIT_i, IGT_i, TGIDL_i; +real NTGEN_i, AIGEN_i, BIGEN_i; +real K0SISAT_i, K0SISAT1_i; +real K2SISAT_i, K2SISAT1_i; +real K2_i, K21_i; + +// Variables of Unified Finfet Compact Model +real Cins, Ach, Weff_UFCM, qdep,rc, vth_fixed_factor_Sub, vth_fixed_factor_SI, qm, Qdep_ov_Cins, qi_acc_for_QM; +real fieldnormalizationfactor, auxQMfact, QMFACTORCVfinal; +real psipclamp, sqrtpsip, nq, F0; + +real LSP_i; + +`Cfringe_2d_vars(); + +//=================================================== +// analog block begins +//=================================================== +analog begin + + // ************************************************ + // * Geometry dependent calculations * + // ************************************************ + begin : CMGBiasIndepCalc + + // Variable Initialization to Prevent Hidden States + qid = 0.0; + qis = 0.0; + qba = 0.0; + T11 = 0.0; + T12 = 0.0; + ids = 0.0; + sigvds = 0.0; + Iii = 0.0; + qd = 0.0; + qg = 0.0; + qs = 0.0; + qb = 0.0; + Weff0 = 0.0; + WeffCV0 = 0.0; + CJS_t = 0.0; + CJSWS_t = 0.0; + CJSWGS_t = 0.0; + CJD_t = 0.0; + CJSWD_t = 0.0; + CJSWGD_t = 0.0; + PBS_t = 0.0; + PBSWS_t = 0.0; + PBSWGS_t = 0.0; + PBD_t = 0.0; + PBSWD_t = 0.0; + PBSWGD_t = 0.0; + JSS_t = 0.0; + JSWS_t = 0.0; + JSWGS_t = 0.0; + JSD_t = 0.0; + JSWD_t = 0.0; + JSWGD_t = 0.0; + JTSS_t = 0.0; + JTSSWS_t = 0.0; + JTSSWGS_t = 0.0; + JTSD_t = 0.0; + JTSSWD_t = 0.0; + JTSSWGD_t = 0.0; + NJTS_t = 0.0; + NJTSSW_t = 0.0; + NJTSSWG_t = 0.0; + NJTSD_t = 0.0; + NJTSSWD_t = 0.0; + NJTSSWGD_t = 0.0; + Ies = 0.0; + Ied = 0.0; + Czbs = 0.0; + Czbssw = 0.0; + Czbsswg = 0.0; + Czbd = 0.0; + Czbdsw = 0.0; + Czbdswg = 0.0; + Qes = 0.0; + Qed = 0.0; + Qeg = 0.0; + Isbs = 0.0; + Isbd = 0.0; + Nvtms = 0.0; + Nvtmd = 0.0; + SslpRev = 0.0; + IVjsmRev = 0.0; + VjsmRev = 0.0; + SslpFwd = 0.0; + IVjsmFwd = 0.0; + VjsmFwd = 0.0; + DslpRev = 0.0; + IVjdmRev = 0.0; + VjdmRev = 0.0; + DslpFwd = 0.0; + IVjdmFwd = 0.0; + VjdmFwd = 0.0; + XExpBVS = 0.0; + XExpBVD = 0.0; + idsgen = 0.0; + q0 = 0.0; + Tcen = 0.0; + MTcen = 0.0; + Rdrain = 0.0; + Rsource = 0.0; + Cfr_geo = 0.0; + igbinv = 0.0; + igbs = 0.0; + igbd = 0.0; + igbacc = 0.0; + igcs = 0.0; + igcd = 0.0; + igidl = 0.0; + igisl = 0.0; + igs = 0.0; + igd = 0.0; + cox_acc = 0.0; + CGSO_i = 0.0; + CGDO_i = 0.0; + qb_acc = 0.0; + qg_acc = 0.0; + qgs_fr = 0.0; + qgd_fr = 0.0; + qds_fr = 0.0; + qgs_parasitic = 0.0; + qgd_parasitic = 0.0; + FNPowerAt1Hz = 0.0; + Gtnoi = 0.0; + gspr = 0.0; + gdpr = 0.0; + Dr = 1.0; + CDSCDR_i = 0.0; + ETA0R_i = 0.0; + VSAT1R_i = 0.0; + VSAT1R_t = 0.0; + MEXPR_i = 0.0; + MEXPR_t = 0.0; + PTWGR_i = 0.0; + PTWGR_t = 0.0; + PDIBL1R_i = 0.0; + PDIBL2R_i = 0.0; + PHIBE_i = 0.0; + K1_i = 0.0; + K11_i = 0.0; + K2SAT_i = 0.0; + K2SAT1_i = 0.0; + KSATIVR_i = 0.0; + K2_i = 0.0; + K21_i = 0.0; + UC_i = 0.0; + UC1_i = 0.0; + UC_t = 0.0; + U0R_i = 0.0; + UPR_i = 0.0; + EUR_i = 0.0; + ATR_i = 0.0; + CITR_i = 0.0; + ETA0R_i = 0.0; + DVTP0_i = 0.0; + DVTP1_i = 0.0; + PDIBL2R_i = 0.0; + PCLMR_i = 0.0; + LeffCV_acc = 0.0; + RDDRR_t = 0.0; + RSDRR_t = 0.0; + Rdsi = 0.0; + T3y = 0.0; + Tcen0 = 0.0; + veseff = 0.0; + U0R_t = 0.0; + UAR_t = 0.0; + UCR_t = 0.0; + UDR_t = 0.0; + VSAT_a = 0.0; + DVTSHIFTR_i = 0.0; + UA1R_i = 0.0; + UAR_i = 0.0; + UC1R_i = 0.0; + UCR_i = 0.0; + UD1R_i = 0.0; + UDR_i = 0.0; + UTER_i = 0.0; + UTLR_i = 0.0; + VSATR_i = 0.0; + VSATR_t = 0.0; + u0r = 0.0; + + // Thermal Noise + sid = 0.0; + + `ifdef __TNOIMOD1__ + ctnoi = 0.0; + sf = 0.0; + C0 = 0.0; + gamma = 0.0; + delta = 0.0; + `endif + + `ifdef __RGATEMOD__ + ggeltd = 0.0; + `endif + + // Unified FinFET Model + qm = 1.0; + Cins = 1.0; + Ach = 1.0; + Weff_UFCM = 1.0; + qdep = -1.0; + rc = 1.0; + vth_fixed_factor_Sub = 1.0; + vth_fixed_factor_SI = 1.0; + qi_acc_for_QM = 0.0; + fieldnormalizationfactor = 0.0; + auxQMfact = 0.0; + QMFACTORCVfinal = 0.0; + psipclamp = 1.0; + sqrtpsip = 1.0; + nq = 1.0; + F0 = 0.0; + e0 = 0.0; + e1 = 0.0; + e2 = 0.0; + Qdep_ov_Cins = 0.0; + + // Constants + if ( TYPE == `ntype ) begin + devsign = 1; + end else begin + devsign = -1; + end + + epssub = EPSRSUB * `EPS0; + epssp = EPSRSP * `EPS0; + cbox = EPSROX * `EPS0 / EOTBOX; + epsratio = EPSRSUB / EPSROX; + + if ($port_connected(t) == 1) begin + `ifdef __SHMOD__ + if (SHMOD == 0) begin + if (SH_WARN == 1) begin + $strobe("The optional 5th terminal is present but not active because SHMOD=0."); + end + end + `else + Temp(t) <+ 0.0; + if (SH_WARN == 1) begin + $strobe("The optional 5th terminal is present but not active because the model was not compiled with self-heating enabled (__SHMOD__ was not activated)."); + end + `endif + end + + // Constants for Quantum Mechanical Effects + mx = 0.916 * `MEL; + mxprime = 0.190 * `MEL; + md = 0.190 * `MEL; + mdprime = 0.417 * `MEL; + gprime = 4.0; + gfactor = 2.0; + + // Effective Channel Length for I-V / C-V + Lg = L + XL; + deltaL = LINT + LL * pow(Lg, -LLN); + deltaL1 = LINT + LL * pow(Lg+DLBIN, -LLN); + deltaLCV = DLC + LLC * pow(Lg, -LLN); + Leff = Lg - 2.0 * deltaL; + Leff1 = Lg + DLBIN - 2.0 * deltaL1; //Used in the binning equations only + LeffCV = Lg - 2.0 * deltaLCV; + if (BULKMOD != 0) LeffCV_acc = LeffCV - DLCACC; + + // Total Fins + NFINtotal = NFIN * NF; + + // Range Checking on Leff and Leff1 + if (Leff <= 0.0) begin + $strobe("Fatal: Leff = %e is not positive.", Leff); + $finish(0); + end else if (Leff <= 1.0e-9) begin + $strobe("Warning: Leff = %e <= 1.0e-9.", Leff); + end + + if (Leff1 <= 0.0) begin + $strobe("Fatal: Leff1 = %e is not positive.", Leff1); + $finish(0); + end else if (Leff1 <= 1.0e-9) begin + $strobe("Warning: Leff1 = %e <= 1.0e-9.", Leff1); + end + + // Binning + Inv_L = 1.0e-6 / (Leff1); + Inv_NFIN = 1.0 / NFIN; + Inv_LNFIN = 1.0e-6 / (Leff1 * NFIN); + + // Nbody Binning Equation for UFCM Parameters + NBODY_i = NBODY + Inv_L * LNBODY + Inv_NFIN * NNBODY + Inv_LNFIN * PNBODY; + + if (NBODYN1 != 0.0) begin + NBODY_i = NBODY_i * (1.0 + NBODYN1/NFIN * lln(1.0 + NFIN/NBODYN2)); + end + + // Model Parameters for Unified FinFET Compact Model by Juan Duarte 10/2013 + case (GEOMOD) + 0: begin // Double Gate + if (!$param_given(TFIN_TOP) || !$param_given(TFIN_BASE)) begin + Weff_UFCM = 2.0 * HFIN; + Cins = Weff_UFCM * EPSROX * `EPS0 / EOT; + Ach = HFIN * TFIN; + rc = (2.0 * Cins / (Weff_UFCM * Weff_UFCM * epssub / Ach)); + Qdep_ov_Cins = -`q * NBODY_i * Ach / Cins; + end else begin + Weff_UFCM = 2.0 * sqrt( HFIN * HFIN + (TFIN_TOP - TFIN_BASE) * (TFIN_TOP - TFIN_BASE) / 4.0); + Cins = Weff_UFCM * EPSROX * `EPS0 / EOT; + Ach = HFIN * (TFIN_TOP + TFIN_BASE) / 2.0; + rc = (2.0 * Cins / (Weff_UFCM * Weff_UFCM * epssub / Ach)); + Qdep_ov_Cins = -`q * NBODY_i * Ach / Cins; + end + end + 1: begin // Triple Gate + if (!$param_given(TFIN_TOP) || !$param_given(TFIN_BASE)) begin + Weff_UFCM = 2.0 * HFIN + TFIN; + Cins = Weff_UFCM * EPSROX * `EPS0 / EOT; + Ach = HFIN * TFIN; + rc = (2.0 * Cins / (Weff_UFCM * Weff_UFCM * epssub / Ach)); + Qdep_ov_Cins = -`q * NBODY_i * Ach / Cins; + end else begin + Weff_UFCM = 2.0 * sqrt(HFIN * HFIN + (TFIN_TOP - TFIN_BASE) * (TFIN_TOP - TFIN_BASE) / 4.0) + TFIN_TOP; + Cins = Weff_UFCM * EPSROX * `EPS0 / EOT; + Ach = HFIN * (TFIN_TOP + TFIN_BASE) / 2.0; + rc = (2.0 * Cins /(Weff_UFCM * Weff_UFCM * epssub / Ach)); + Qdep_ov_Cins = -`q * NBODY_i * Ach / Cins; + end + end + 2: begin // Quadruple Gate + if (!$param_given(TFIN_TOP) || !$param_given(TFIN_BASE)) begin + Weff_UFCM = 2.0 * HFIN + 2.0 * TFIN; + Cins = Weff_UFCM * EPSROX * `EPS0 / EOT; + Ach = HFIN * TFIN; + rc = (2.0 * Cins / (Weff_UFCM * Weff_UFCM * epssub / Ach)); + Qdep_ov_Cins = -`q * NBODY_i * Ach / Cins; + end else begin + Weff_UFCM = 2.0 * sqrt(HFIN * HFIN + (TFIN_TOP - TFIN_BASE) * (TFIN_TOP - TFIN_BASE) / 4.0) + TFIN_TOP + TFIN_BASE; + Cins = Weff_UFCM * EPSROX * `EPS0 / EOT; + Ach = HFIN * (TFIN_TOP + TFIN_BASE) / 2.0; + rc = (2.0 * Cins / (Weff_UFCM * Weff_UFCM * epssub / Ach)); + Qdep_ov_Cins = -`q * NBODY_i * Ach / Cins; + end + end + 3: begin // Cylindrical Gate + Weff_UFCM = `M_PI * D; + Cins = 2.0 * `M_PI * EPSROX * `EPS0 / ln(1.0 + 2.0 * EOT / D); + Ach = `M_PI * D * D / 4.0; + rc = (2.0 * Cins / (Weff_UFCM * Weff_UFCM * epssub / Ach)); + Qdep_ov_Cins = -`q * NBODY_i * Ach / Cins; + end + 4: begin // Unified Model + Weff_UFCM = W_UFCM; + Cins = CINS_UFCM; + Ach = ACH_UFCM; + rc = (2.0 * Cins / (Weff_UFCM * Weff_UFCM * epssub / Ach)); + Qdep_ov_Cins = -`q * NBODY_i * Ach / Cins; + end + endcase + + // Cox Definition + cox = Cins / Weff_UFCM; + if (BULKMOD != 0) begin + cox_acc = cox * EOT / EOTACC; + end + + // Effective Width Calculation + Weff0 = Weff_UFCM - DELTAW; + WeffCV0 = Weff_UFCM - DELTAWCV; + + // SCE Scaling Length + scl = sqrt((epssub * Ach / Cins) * (1.0 + Ach * Cins / (2.0 * epssub * Weff_UFCM * Weff_UFCM))); + + // Binning Equations (Process Parameters) + PHIG_i = PHIG + Inv_L * LPHIG + Inv_NFIN * NPHIG + Inv_LNFIN * PPHIG; + NGATE_i = NGATE + Inv_L * LNGATE + Inv_NFIN * NNGATE + Inv_LNFIN * PNGATE; + + // Binning Equations (Model Parameters) + CIT_i = CIT + Inv_L * LCIT + Inv_NFIN * NCIT + Inv_LNFIN * PCIT; + CDSC_i = CDSC + Inv_L * LCDSC + Inv_NFIN * NCDSC + Inv_LNFIN * PCDSC; + CDSCD_i = CDSCD + Inv_L * LCDSCD + Inv_NFIN * NCDSCD + Inv_LNFIN * PCDSCD; + DVT0_i = DVT0 + Inv_L * LDVT0 + Inv_NFIN * NDVT0 + Inv_LNFIN * PDVT0; + DVT1_i = DVT1 + Inv_L * LDVT1 + Inv_NFIN * NDVT1 + Inv_LNFIN * PDVT1; + DVT1SS_i = DVT1SS + Inv_L * LDVT1SS + Inv_NFIN * NDVT1SS + Inv_LNFIN * PDVT1SS; + PHIN_i = PHIN + Inv_L * LPHIN + Inv_NFIN * NPHIN + Inv_LNFIN * PPHIN; + ETA0_i = ETA0 + Inv_L * LETA0 + Inv_NFIN * NETA0 + Inv_LNFIN * PETA0; + DSUB_i = DSUB + Inv_L * LDSUB + Inv_NFIN * NDSUB + Inv_LNFIN * PDSUB; + K1RSCE_i = K1RSCE + Inv_L * LK1RSCE + Inv_NFIN * NK1RSCE + Inv_LNFIN * PK1RSCE; + LPE0_i = LPE0 + Inv_L * LLPE0 + Inv_NFIN * NLPE0 + Inv_LNFIN * PLPE0; + DVTSHIFT_i = DVTSHIFT + Inv_L * LDVTSHIFT + Inv_NFIN * NDVTSHIFT + Inv_LNFIN * PDVTSHIFT; + K0_i = K0 + Inv_L * LK0 + Inv_NFIN * NK0 + Inv_LNFIN * PK0; + K01_i = K01 + Inv_L * LK01 + Inv_NFIN * NK01 + Inv_LNFIN * PK01; + K0SI_i = K0SI + Inv_L * LK0SI + Inv_NFIN * NK0SI + Inv_LNFIN * PK0SI; + K0SI1_i = K0SI1 + Inv_L * LK0SI1 + Inv_NFIN * NK0SI1 + Inv_LNFIN * PK0SI1; + K2SI_i = K2SI + Inv_L * LK2SI + Inv_NFIN * NK2SI + Inv_LNFIN * PK2SI; + K2SI1_i = K2SI1 + Inv_L * LK2SI1 + Inv_NFIN * NK2SI1 + Inv_LNFIN * PK2SI1; + K0SISAT_i = K0SISAT + Inv_L * LK0SISAT + Inv_NFIN * NK0SISAT + Inv_LNFIN * PK0SISAT; + K0SISAT1_i = K0SISAT1 + Inv_L * LK0SISAT1 + Inv_NFIN * NK0SISAT1 + Inv_LNFIN * PK0SISAT1; + K2SISAT_i = K2SISAT + Inv_L * LK2SISAT + Inv_NFIN * NK2SISAT + Inv_LNFIN * PK2SISAT; + K2SISAT1_i = K2SISAT1 + Inv_L * LK2SISAT1 + Inv_NFIN * NK2SISAT1 + Inv_LNFIN * PK2SISAT1; + + if (BULKMOD != 0) begin + if (BULKMOD == 2) begin + K2_i = K2 + Inv_L * LK2 + Inv_NFIN * NK2 + Inv_LNFIN * PK2; + K21_i = K21 + Inv_L * LK21 + Inv_NFIN * NK21 + Inv_LNFIN * PK21; + K2SAT_i = K2SAT + Inv_L * LK2SAT + Inv_NFIN * NK2SAT + Inv_LNFIN * PK2SAT; + K2SAT1_i = K2SAT1 + Inv_L * LK2SAT1 + Inv_NFIN * NK2SAT1 + Inv_LNFIN * PK2SAT1; + end + PHIBE_i = PHIBE + Inv_L * LPHIBE + Inv_NFIN * NPHIBE + Inv_LNFIN * PPHIBE; + K1_i = K1 + Inv_L * LK1 + Inv_NFIN * NK1 + Inv_LNFIN * PK1; + K11_i = K11 + Inv_L * LK11 + Inv_NFIN * NK11 + Inv_LNFIN * PK11; + end + QMFACTOR_i = QMFACTOR + Inv_L * LQMFACTOR + Inv_NFIN * NQMFACTOR + Inv_LNFIN * PQMFACTOR; + QMTCENCV_i = QMTCENCV + Inv_L * LQMTCENCV + Inv_NFIN * NQMTCENCV + Inv_LNFIN * PQMTCENCV; + QMTCENCVA_i = QMTCENCVA + Inv_L * LQMTCENCVA + Inv_NFIN * NQMTCENCVA + Inv_LNFIN * PQMTCENCVA; + VSAT_i = VSAT + Inv_L * LVSAT + Inv_NFIN * NVSAT + Inv_LNFIN * PVSAT; + VSAT1_i = VSAT1 + Inv_L * LVSAT1 + Inv_NFIN * NVSAT1 + Inv_LNFIN * PVSAT1; + VSATCV_i = VSATCV + Inv_L * LVSATCV + Inv_NFIN * NVSATCV + Inv_LNFIN * PVSATCV; + DELTAVSAT_i = DELTAVSAT + Inv_L * LDELTAVSAT + Inv_NFIN * NDELTAVSAT + Inv_LNFIN * PDELTAVSAT; + PSAT_i = PSAT + Inv_L * LPSAT + Inv_NFIN * NPSAT + Inv_LNFIN * PPSAT; + DELTAVSATCV_i = DELTAVSATCV + Inv_L * LDELTAVSATCV + Inv_NFIN * NDELTAVSATCV + Inv_LNFIN * PDELTAVSATCV; + PSATCV_i = PSATCV + Inv_L * LPSATCV + Inv_NFIN * NPSATCV + Inv_LNFIN * PPSATCV; + KSATIV_i = KSATIV + Inv_L * LKSATIV + Inv_NFIN * NKSATIV + Inv_LNFIN * PKSATIV; + MEXP_i = MEXP + Inv_L * LMEXP + Inv_NFIN * NMEXP + Inv_LNFIN * PMEXP; + PTWG_i = PTWG + Inv_L * LPTWG + Inv_NFIN * NPTWG + Inv_LNFIN * PPTWG; + U0_i = U0 + Inv_L * LU0 + Inv_NFIN * NU0 + Inv_LNFIN * PU0; + ETAMOB_i = ETAMOB + Inv_L * LETAMOB + Inv_NFIN * NETAMOB + Inv_LNFIN * PETAMOB; + UP_i = UP + Inv_L * LUP + Inv_NFIN * NUP + Inv_LNFIN * PUP; + UA_i = UA + Inv_L * LUA + Inv_NFIN * NUA + Inv_LNFIN * PUA; + if (BULKMOD != 0) begin + UC_i = UC + Inv_L * LUC + Inv_NFIN * NUC + Inv_LNFIN * PUC; + end + EU_i = EU + Inv_L * LEU + Inv_NFIN * NEU + Inv_LNFIN * PEU; + UD_i = UD + Inv_L * LUD + Inv_NFIN * NUD + Inv_LNFIN * PUD; + UCS_i = UCS + Inv_L * LUCS + Inv_NFIN * NUCS + Inv_LNFIN * PUCS; + PCLM_i = PCLM + Inv_L * LPCLM + Inv_NFIN * NPCLM + Inv_LNFIN * PPCLM; + PCLMG_i = PCLMG + Inv_L * LPCLMG + Inv_NFIN * NPCLMG + Inv_LNFIN * PPCLMG; + PCLMCV_i = PCLMCV + Inv_L * LPCLMCV + Inv_NFIN * NPCLMCV + Inv_LNFIN * PPCLMCV; + A1_i = A1 + Inv_L * LA1 + Inv_NFIN * NA1 + Inv_LNFIN * PA1; + A11_i = A11 + Inv_L * LA11 + Inv_NFIN * NA11 + Inv_LNFIN * PA11; + A2_i = A2 + Inv_L * LA2 + Inv_NFIN * NA2 + Inv_LNFIN * PA2; + A21_i = A21 + Inv_L * LA21 + Inv_NFIN * NA21 + Inv_LNFIN * PA21; + RDSW_i = RDSW + Inv_L * LRDSW + Inv_NFIN * NRDSW + Inv_LNFIN * PRDSW; + RSW_i = RSW + Inv_L * LRSW + Inv_NFIN * NRSW + Inv_LNFIN * PRSW; + RDW_i = RDW + Inv_L * LRDW + Inv_NFIN * NRDW + Inv_LNFIN * PRDW; + PRWGD_i = PRWGD + Inv_L * LPRWGD + Inv_NFIN * NPRWGD + Inv_LNFIN * PPRWGD; + PRWGS_i = PRWGS + Inv_L * LPRWGS + Inv_NFIN * NPRWGS + Inv_LNFIN * PPRWGS; + WR_i = WR + Inv_L * LWR + Inv_NFIN * NWR + Inv_LNFIN * PWR; + PDIBL1_i = PDIBL1 + Inv_L * LPDIBL1 + Inv_NFIN * NPDIBL1 + Inv_LNFIN * PPDIBL1; + PDIBL2_i = PDIBL2 + Inv_L * LPDIBL2 + Inv_NFIN * NPDIBL2 + Inv_LNFIN * PPDIBL2; + DROUT_i = DROUT + Inv_L * LDROUT + Inv_NFIN * NDROUT + Inv_LNFIN * PDROUT; + PVAG_i = PVAG + Inv_L * LPVAG + Inv_NFIN * NPVAG + Inv_LNFIN * PPVAG; + AIGBINV_i = AIGBINV + Inv_L * LAIGBINV + Inv_NFIN * NAIGBINV + Inv_LNFIN * PAIGBINV; + AIGBINV1_i = AIGBINV1 + Inv_L * LAIGBINV1 + Inv_NFIN * NAIGBINV1 + Inv_LNFIN * PAIGBINV1; + BIGBINV_i = BIGBINV + Inv_L * LBIGBINV + Inv_NFIN * NBIGBINV + Inv_LNFIN * PBIGBINV; + CIGBINV_i = CIGBINV + Inv_L * LCIGBINV + Inv_NFIN * NCIGBINV + Inv_LNFIN * PCIGBINV; + EIGBINV_i = EIGBINV + Inv_L * LEIGBINV + Inv_NFIN * NEIGBINV + Inv_LNFIN * PEIGBINV; + NIGBINV_i = NIGBINV + Inv_L * LNIGBINV + Inv_NFIN * NNIGBINV + Inv_LNFIN * PNIGBINV; + AIGBACC_i = AIGBACC + Inv_L * LAIGBACC + Inv_NFIN * NAIGBACC + Inv_LNFIN * PAIGBACC; + AIGBACC1_i = AIGBACC1 + Inv_L * LAIGBACC1 + Inv_NFIN * NAIGBACC1 + Inv_LNFIN * PAIGBACC1; + BIGBACC_i = BIGBACC + Inv_L * LBIGBACC + Inv_NFIN * NBIGBACC + Inv_LNFIN * PBIGBACC; + CIGBACC_i = CIGBACC + Inv_L * LCIGBACC + Inv_NFIN * NCIGBACC + Inv_LNFIN * PCIGBACC; + NIGBACC_i = NIGBACC + Inv_L * LNIGBACC + Inv_NFIN * NNIGBACC + Inv_LNFIN * PNIGBACC; + AIGC_i = AIGC + Inv_L * LAIGC + Inv_NFIN * NAIGC + Inv_LNFIN * PAIGC; + AIGC1_i = AIGC1 + Inv_L * LAIGC1 + Inv_NFIN * NAIGC1 + Inv_LNFIN * PAIGC1; + BIGC_i = BIGC + Inv_L * LBIGC + Inv_NFIN * NBIGC + Inv_LNFIN * PBIGC; + CIGC_i = CIGC + Inv_L * LCIGC + Inv_NFIN * NCIGC + Inv_LNFIN * PCIGC; + PIGCD_i = PIGCD + Inv_L * LPIGCD + Inv_NFIN * NPIGCD + Inv_LNFIN * PPIGCD; + AIGS_i = AIGS + Inv_L * LAIGS + Inv_NFIN * NAIGS + Inv_LNFIN * PAIGS; + AIGS1_i = AIGS1 + Inv_L * LAIGS1 + Inv_NFIN * NAIGS1 + Inv_LNFIN * PAIGS1; + BIGS_i = BIGS + Inv_L * LBIGS + Inv_NFIN * NBIGS + Inv_LNFIN * PBIGS; + CIGS_i = CIGS + Inv_L * LCIGS + Inv_NFIN * NCIGS + Inv_LNFIN * PCIGS; + AIGD_i = AIGD + Inv_L * LAIGD + Inv_NFIN * NAIGD + Inv_LNFIN * PAIGD; + AIGD1_i = AIGD1 + Inv_L * LAIGD1 + Inv_NFIN * NAIGD1 + Inv_LNFIN * PAIGD1; + BIGD_i = BIGD + Inv_L * LBIGD + Inv_NFIN * NBIGD + Inv_LNFIN * PBIGD; + CIGD_i = CIGD + Inv_L * LCIGD + Inv_NFIN * NCIGD + Inv_LNFIN * PCIGD; + NTOX_i = NTOX + Inv_L * LNTOX + Inv_NFIN * NNTOX + Inv_LNFIN * PNTOX; + POXEDGE_i = POXEDGE + Inv_L * LPOXEDGE + Inv_NFIN * NPOXEDGE + Inv_LNFIN * PPOXEDGE; + AGIDL_i = AGIDL + Inv_L * LAGIDL + Inv_NFIN * NAGIDL + Inv_LNFIN * PAGIDL; + BGIDL_i = BGIDL + Inv_L * LBGIDL + Inv_NFIN * NBGIDL + Inv_LNFIN * PBGIDL; + CGIDL_i = CGIDL + Inv_L * LCGIDL + Inv_NFIN * NCGIDL + Inv_LNFIN * PCGIDL; + EGIDL_i = EGIDL + Inv_L * LEGIDL + Inv_NFIN * NEGIDL + Inv_LNFIN * PEGIDL; + PGIDL_i = PGIDL + Inv_L * LPGIDL + Inv_NFIN * NPGIDL + Inv_LNFIN * PPGIDL; + AGISL_i = AGISL + Inv_L * LAGISL + Inv_NFIN * NAGISL + Inv_LNFIN * PAGISL; + BGISL_i = BGISL + Inv_L * LBGISL + Inv_NFIN * NBGISL + Inv_LNFIN * PBGISL; + CGISL_i = CGISL + Inv_L * LCGISL + Inv_NFIN * NCGISL + Inv_LNFIN * PCGISL; + EGISL_i = EGISL + Inv_L * LEGISL + Inv_NFIN * NEGISL + Inv_LNFIN * PEGISL; + PGISL_i = PGISL + Inv_L * LPGISL + Inv_NFIN * NPGISL + Inv_LNFIN * PPGISL; + ALPHA0_i = ALPHA0 + Inv_L * LALPHA0 + Inv_NFIN * NALPHA0 + Inv_LNFIN * PALPHA0; + ALPHA1_i = ALPHA1 + Inv_L * LALPHA1 + Inv_NFIN * NALPHA1 + Inv_LNFIN * PALPHA1; + ALPHAII0_i = ALPHAII0 + Inv_L * LALPHAII0 + Inv_NFIN * NALPHAII0 + Inv_LNFIN * PALPHAII0; + ALPHAII1_i = ALPHAII1 + Inv_L * LALPHAII1 + Inv_NFIN * NALPHAII1 + Inv_LNFIN * PALPHAII1; + BETA0_i = BETA0 + Inv_L * LBETA0 + Inv_NFIN * NBETA0 + Inv_LNFIN * PBETA0; + BETAII0_i = BETAII0 + Inv_L * LBETAII0 + Inv_NFIN * NBETAII0 + Inv_LNFIN * PBETAII0; + BETAII1_i = BETAII1 + Inv_L * LBETAII1 + Inv_NFIN * NBETAII1 + Inv_LNFIN * PBETAII1; + BETAII2_i = BETAII2 + Inv_L * LBETAII2 + Inv_NFIN * NBETAII2 + Inv_LNFIN * PBETAII2; + ESATII_i = ESATII + Inv_L * LESATII + Inv_NFIN * NESATII + Inv_LNFIN * PESATII; + LII_i = LII + Inv_L * LLII + Inv_NFIN * NLII + Inv_LNFIN * PLII; + SII0_i = SII0 + Inv_L * LSII0 + Inv_NFIN * NSII0 + Inv_LNFIN * PSII0; + SII1_i = SII1 + Inv_L * LSII1 + Inv_NFIN * NSII1 + Inv_LNFIN * PSII1; + SII2_i = SII2 + Inv_L * LSII2 + Inv_NFIN * NSII2 + Inv_LNFIN * PSII2; + SIID_i = SIID + Inv_L * LSIID + Inv_NFIN * NSIID + Inv_LNFIN * PSIID; + TII_i = TII + Inv_L * LTII + Inv_NFIN * NTII + Inv_LNFIN * PTII; + CFS_i = CFS + Inv_L * LCFS + Inv_NFIN * NCFS + Inv_LNFIN * PCFS; + CFD_i = CFD + Inv_L * LCFD + Inv_NFIN * NCFD + Inv_LNFIN * PCFD; + COVS_i = COVS + Inv_L * LCOVS + Inv_NFIN * NCOVS + Inv_LNFIN * PCOVS; + COVD_i = COVD + Inv_L * LCOVD + Inv_NFIN * NCOVD + Inv_LNFIN * PCOVD; + CGSL_i = CGSL + Inv_L * LCGSL + Inv_NFIN * NCGSL + Inv_LNFIN * PCGSL; + CGDL_i = CGDL + Inv_L * LCGDL + Inv_NFIN * NCGDL + Inv_LNFIN * PCGDL; + CGBL_i = CGBL + Inv_L * LCGBL + Inv_NFIN * NCGBL + Inv_LNFIN * PCGBL; + CKAPPAS_i = CKAPPAS + Inv_L * LCKAPPAS + Inv_NFIN * NCKAPPAS + Inv_LNFIN * PCKAPPAS; + CKAPPAD_i = CKAPPAD + Inv_L * LCKAPPAD + Inv_NFIN * NCKAPPAD + Inv_LNFIN * PCKAPPAD; + CKAPPAB_i = CKAPPAB + Inv_L * LCKAPPAB + Inv_NFIN * NCKAPPAB + Inv_LNFIN * PCKAPPAB; + NTGEN_i = NTGEN + Inv_L * LNTGEN + Inv_NFIN * NNTGEN + Inv_LNFIN * PNTGEN; + AIGEN_i = AIGEN + Inv_L * LAIGEN + Inv_NFIN * NAIGEN + Inv_LNFIN * PAIGEN; + BIGEN_i = BIGEN + Inv_L * LBIGEN + Inv_NFIN * NBIGEN + Inv_LNFIN * PBIGEN; + + if (ASYMMOD != 0) begin + CDSCDR_i = CDSCDR + Inv_L * LCDSCDR + Inv_NFIN * NCDSCDR + Inv_LNFIN * PCDSCDR; + CITR_i = CITR + Inv_L * LCITR + Inv_NFIN * NCITR + Inv_LNFIN * PCITR; + ETA0R_i = ETA0R + Inv_L * LETA0R + Inv_NFIN * NETA0R + Inv_LNFIN * PETA0R; + VSAT1R_i = VSAT1R + Inv_L * LVSAT1R + Inv_NFIN * NVSAT1R + Inv_LNFIN * PVSAT1R; + MEXPR_i = MEXPR + Inv_L * LMEXPR + Inv_NFIN * NMEXPR + Inv_LNFIN * PMEXPR; + PTWGR_i = PTWGR + Inv_L * LPTWGR + Inv_NFIN * NPTWGR + Inv_LNFIN * PPTWGR; + PDIBL1R_i = PDIBL1R + Inv_L * LPDIBL1R + Inv_NFIN * NPDIBL1R + Inv_LNFIN * PPDIBL1R; + PDIBL2R_i = PDIBL2R + Inv_L * LPDIBL2R + Inv_NFIN * NPDIBL2R + Inv_LNFIN * PPDIBL2R; + PCLMR_i = PCLMR + Inv_L * LPCLMR + Inv_NFIN * NPCLMR + Inv_LNFIN * PPCLMR; + DVTSHIFTR_i = DVTSHIFTR + Inv_L * LDVTSHIFTR + Inv_NFIN * NDVTSHIFTR + Inv_LNFIN * PDVTSHIFTR; + VSATR_i = VSATR + Inv_L * LVSATR + Inv_NFIN * NVSATR + Inv_LNFIN * PVSATR; + KSATIVR_i = KSATIVR + Inv_L * LKSATIVR + Inv_NFIN * NKSATIVR + Inv_LNFIN * PKSATIVR; + U0R_i = U0R + Inv_L * LU0R + Inv_NFIN * NU0R + Inv_LNFIN * PU0R; + UAR_i = UAR + Inv_L * LUAR + Inv_NFIN * NUAR + Inv_LNFIN * PUAR; + UPR_i = UPR + Inv_L * LUPR + Inv_NFIN * NUPR + Inv_LNFIN * PUPR; + if (BULKMOD != 0) begin + UCR_i = UCR + Inv_L * LUCR + Inv_NFIN * NUCR + Inv_LNFIN * PUCR; + end + EUR_i = EUR + Inv_L * LEUR + Inv_NFIN * NEUR + Inv_LNFIN * PEUR; + UDR_i = UDR + Inv_L * LUDR + Inv_NFIN * NUDR + Inv_LNFIN * PUDR; + end + + `ifdef __NQSMOD1__ + if (NQSMOD == 1 && XRCRG1 != 0.0) begin + XRCRG1_i = XRCRG1 + Inv_L * LXRCRG1 + Inv_NFIN * NXRCRG1 + Inv_LNFIN * PXRCRG1; + XRCRG2_i = XRCRG2 + Inv_L * LXRCRG2 + Inv_NFIN * NXRCRG2 + Inv_LNFIN * PXRCRG2; + end else begin + XRCRG1_i = 0.0; + XRCRG2_i = 0.0; + end + `else + if (NQSMOD == 1) begin + $strobe(" Although the model selector NQSMOD is set to 1, the NQS gate resistance model is not activated in the Verilog-A code. Please uncomment \"`define __NQSMOD1__\" in bsimcmg.va to activate it."); + end + `endif + + `ifdef __NQSMOD2__ + if (NQSMOD == 2 && XRCRG1 != 0.0) begin + XRCRG1_i = XRCRG1 + Inv_L * LXRCRG1 + Inv_NFIN * NXRCRG1 + Inv_LNFIN * PXRCRG1; + XRCRG2_i = XRCRG2 + Inv_L * LXRCRG2 + Inv_NFIN * NXRCRG2 + Inv_LNFIN * PXRCRG2; + end else begin + XRCRG1_i = 0.0; + XRCRG2_i = 0.0; + end + `else + if (NQSMOD == 2) begin + $strobe(" Although the model selector NQSMOD is set to 2, the NQS gate resistance model is not activated in the Verilog-A code. Please uncomment \"`define __NQSMOD2__\" in bsimcmg.va to activate it."); + end + `endif + + UTE_i = UTE + Inv_L * LUTE + Inv_NFIN * NUTE + Inv_LNFIN * PUTE; + UTL_i = UTL + Inv_L * LUTL + Inv_NFIN * NUTL + Inv_LNFIN * PUTL; + EMOBT_i = EMOBT + Inv_L * LEMOBT + Inv_NFIN * NEMOBT + Inv_LNFIN * PEMOBT; + UA1_i = UA1 + Inv_L * LUA1 + Inv_NFIN * NUA1 + Inv_LNFIN * PUA1; + + if (BULKMOD != 0) begin + UC1_i = UC1 + Inv_L * LUC1 + Inv_NFIN * NUC1 + Inv_LNFIN * PUC1; + end + UD1_i = UD1 + Inv_L * LUD1 + Inv_NFIN * NUD1 + Inv_LNFIN * PUD1; + UCSTE_i = UCSTE + Inv_L * LUCSTE + Inv_NFIN * NUCSTE + Inv_LNFIN * PUCSTE; + PTWGT_i = PTWGT + Inv_L * LPTWGT + Inv_NFIN * NPTWGT + Inv_LNFIN * PPTWGT; + AT_i = AT + Inv_L * LAT + Inv_NFIN * NAT + Inv_LNFIN * PAT; + ATCV_i = ATCV + Inv_L * LATCV + Inv_NFIN * NATCV + Inv_LNFIN * PATCV; + PRT_i = PRT + Inv_L * LPRT + Inv_NFIN * NPRT + Inv_LNFIN * PPRT; + KT1_i = KT1 + Inv_L * LKT1 + Inv_NFIN * NKT1 + Inv_LNFIN * PKT1; + TSS_i = TSS + Inv_L * LTSS + Inv_NFIN * NTSS + Inv_LNFIN * PTSS; + IIT_i = IIT + Inv_L * LIIT + Inv_NFIN * NIIT + Inv_LNFIN * PIIT; + TGIDL_i = TGIDL + Inv_L * LTGIDL + Inv_NFIN * NTGIDL + Inv_LNFIN * PTGIDL; + IGT_i = IGT + Inv_L * LIGT + Inv_NFIN * NIGT + Inv_LNFIN * PIGT; + + if (ASYMMOD != 0) begin + UTER_i = UTER + Inv_L * LUTER + Inv_NFIN * NUTER + Inv_LNFIN * PUTER; + UTLR_i = UTLR + Inv_L * LUTLR + Inv_NFIN * NUTLR + Inv_LNFIN * PUTLR; + UA1R_i = UA1R + Inv_L * LUA1R + Inv_NFIN * NUA1R + Inv_LNFIN * PUA1R; + UD1R_i = UD1R + Inv_L * LUD1R + Inv_NFIN * NUD1R + Inv_LNFIN * PUD1R; + ATR_i = ATR + Inv_L * LATR + Inv_NFIN * NATR + Inv_LNFIN * PATR; + if (BULKMOD != 0) begin + UC1R_i = UC1R + Inv_L * LUC1R + Inv_NFIN * NUC1R + Inv_LNFIN * PUC1R; + end + end + + // Geometrical Scaling + // NFIN Scaling + if (PHIGN1 != 0.0) begin + PHIG_i = PHIG_i * (1.0 + PHIGN1 / NFIN * lln(1.0 + NFIN / PHIGN2)); + end + + if (ETA0N1 != 0.0) begin + ETA0_i = ETA0_i * (1.0 + ETA0N1 / NFIN * lln(1.0 + NFIN / ETA0N2)); + end + + if (CDSCN1 != 0.0) begin + CDSC_i = CDSC_i * (1.0 + CDSCN1 / NFIN * lln(1.0 + NFIN / CDSCN2)); + end + + if (CDSCDN1 != 0.0) begin + CDSCD_i = CDSCD_i * (1.0 + CDSCDN1 / NFIN * lln(1.0 + NFIN / CDSCDN2)); + end + + if (CDSCDRN1 != 0.0) begin + CDSCDR_i = CDSCDR_i * (1.0 + CDSCDRN1 / NFIN * lln(1.0 + NFIN / CDSCDRN2)); + end + + if (VSATN1 != 0.0) begin + VSAT_i = VSAT_i * (1.0 + VSATN1 / NFIN * lln(1.0 + NFIN / VSATN2)); + end + + if (VSAT1N1 != 0.0) begin + VSAT1_i = VSAT1_i * (1.0 + VSAT1N1 / NFIN * lln(1.0 + NFIN / VSAT1N2)); + end + + if (VSAT1RN1 != 0.0) begin + VSAT1R_i = VSAT1R_i * (1.0 + VSAT1RN1 / NFIN * lln(1.0 + NFIN / VSAT1RN2)); + end + + if (U0N1 != 0.0) begin + U0_i = U0_i * (1.0 + U0N1 / NFIN * lln(1.0 + NFIN / U0N2)); + end + + if ($param_given(NFINNOM)) begin + PHIG_i = PHIG_i * (1.0 + (NFIN - NFINNOM) * PHIGLT * Leff) ; + ETA0_i = ETA0_i * (1.0 + (NFIN - NFINNOM) * ETA0LT * Leff); + U0_i = U0_i * (1.0 + (NFIN - NFINNOM) * U0LT * Leff); + end + + if (U0N1R != 0.0) begin + U0R_i = U0R_i * (1.0 + U0N1R / NFIN * lln(1.0 + NFIN / U0N2R)); + end + + // Length Scaling + PHIG_i = PHIG_i + PHIGL * Leff; + if (LPA > 0.0) begin + U0_i = U0_i * (1.0 - UP_i * pow(Leff, -LPA)); + end else begin + U0_i = U0_i * (1.0 - UP_i); + end + UA_i = UA_i + AUA * lexp(-Leff / BUA); + UD_i = UD_i + AUD * lexp(-Leff / BUD); + EU_i = EU_i + AEU * lexp(-Leff / BEU); + + if (ASYMMOD != 0) begin + if (LPAR > 0.0) begin + U0R_i = U0R_i * (1.0 - UPR_i * pow(Leff, -LPAR)); + end else begin + U0R_i = U0R_i * (1.0 - UPR_i); + end + UAR_i = UAR_i + AUAR * lexp(-Leff / BUAR); + UDR_i = UDR_i + AUDR * lexp(-Leff / BUDR); + EUR_i = EUR_i + AEUR * lexp(-Leff / BEUR); + end + + if (RDSMOD == 1) begin + RSW_i = RSW_i + ARSW * lexp(-Leff / BRSW); + RDW_i = RDW_i + ARDW * lexp(-Leff / BRDW); + end else begin + RDSW_i = RDSW_i + ARDSW * lexp(-Leff / BRDSW); + end + + PCLM_i = PCLM_i + APCLM * lexp(-Leff / BPCLM); + if (ASYMMOD != 0) begin + PCLMR_i = PCLMR_i + APCLMR * pow(Leff, -BPCLMR); + end + + MEXP_i = MEXP_i + AMEXP * pow(Leff, -BMEXP); + if (ASYMMOD != 0) begin + MEXPR_i = MEXPR_i + AMEXPR * pow(Leff, -BMEXPR); + end + + PTWG_i = PTWG_i + APTWG * lexp(-Leff / BPTWG); + if (ASYMMOD != 0) begin + PTWGR_i = PTWGR_i + APTWG * lexp(-Leff / BPTWG); + end + + VSAT_i = VSAT_i + AVSAT * lexp(-Leff / BVSAT); + VSAT1_i = VSAT1_i + AVSAT1 * lexp(-Leff / BVSAT1); + if (ASYMMOD != 0) begin + VSAT1R_i = VSAT1R_i + AVSAT1 * lexp(-Leff / BVSAT1); + end + + PSAT_i = PSAT_i + APSAT * lexp(-Leff / BPSAT); + PSATCV_i = PSATCV_i + APSATCV * lexp(-Leff / BPSATCV); + VSATCV_i = VSATCV_i + AVSATCV * lexp(-LeffCV / BVSATCV); + + // Scaling for DITS Parameters + DVTP0_i = DVTP0 + ADVTP0 * lexp(-Leff / BDVTP0); + DVTP1_i = DVTP1 + ADVTP1 * lexp(-Leff / BDVTP1); + + // Geometrical Scaling for Toxeff / Charge Centroid Tcen + if (QMTCENCV_i > 0.0 || QMTCENCVA_i > 0.0) begin + MTcen = 1.0 + AQMTCEN * lexp(- (2.0 * Ach / Weff_UFCM) / BQMTCEN); + Tcen0 = (2.0 * Ach / Weff_UFCM ) * MTcen; + end + + // ************************************** + // * Parameter Checking * + // ************************************** + + if (LeffCV <= 1.0e-9) begin + $strobe("Warning: LeffCV = %e <= 1.0e-9.", LeffCV); + end + + if (BULKMOD != 0) begin + if (LeffCV_acc <= 1.0e-9) begin + $strobe("Warning: LeffCV_acc = %e <= 1.0e-9.", LeffCV_acc); + end + end + + if (Weff0 <= 1.0e-9) begin + $strobe("Warning: Weff0 = %e <= 1.0e-9.", Weff0); + end + + if (WeffCV0 <= 1.0e-9) begin + $strobe("Warning: WeffCV0 = %e <= 1.0e-9.", WeffCV0); + end + + if (NBODY_i <= 0.0) begin + $strobe("Fatal: NBODY_i = %e is not positive.", NBODY_i); + $finish(0); + end else if (NBODY_i <= 1.0e18) begin + $strobe("Warning: NBODY_i = %e m^-3 may be too small.", NBODY_i); + end + + if (NGATE_i < 0.0) begin + $strobe("Fatal: NGATE_i = %e is negative.", NGATE_i); + $finish(0); + end else if (NGATE_i != 0.0 && NGATE_i <= 1.0e24) begin + $strobe("Warning: NGATE_i = %e may be too small.", NGATE_i); + end else if (NGATE_i > 1.0e31) begin + $strobe("Fatal: NGATE_i = %e is too high.", NGATE_i); + $finish(0); + end + + if (DVT0_i < 0.0) begin + $strobe("Warning: DVT0_i = %e is negative.", DVT0_i); + end + + if (PHIG_i <= 0.0) begin + $strobe("Fatal: PHIG_i = %e is not positive.", PHIG_i); + $finish(0); + end + + if (VSAT_i <= 0.0) begin + $strobe("Fatal: VSAT_i = %e is not positive.", VSAT_i); + $finish(0); + end + + if (VSAT1_i <= 0.0) begin + $strobe("Fatal: VSAT1_i = %e is not positive.", VSAT1_i); + $finish(0); + end + + if (ASYMMOD != 0 && VSAT1R_i <= 0.0) begin + $strobe("Fatal: VSAT1R_i = %e is not positive.", VSAT1R_i); + $finish(0); + end + + if (DVT1_i <= 0.0) begin + $strobe("Fatal: DVT1_i = %e is not positive.", DVT1_i); + $finish(0); + end + + if (DVT1SS_i <= 0.0) begin + $strobe("Fatal: DVT1SS_i = %e is not positive.", DVT1SS_i); + $finish(0); + end + + if (CDSC_i < 0.0) begin + $strobe("Warning: CDSC_i = %e is negative.", CDSC_i); + end + + if (CDSCD_i < 0.0) begin + $strobe("Warning: CDSCD_i = %e is negative.", CDSCD_i); + end + + if (ASYMMOD != 0 && CDSCDR_i < 0.0) begin + $strobe("Warning: CDSCDR_i = %e is negative.", CDSCDR_i); + end + + if (DSUB_i <= 0.0) begin + $strobe("Fatal: DSUB_i = %e is not positive.", DSUB_i); + $finish(0); + end + + if (ETA0_i < 0.0) begin + $strobe("Warning: ETA0_i = %e is negative, setting it to 0", ETA0_i); + ETA0_i = 0.0; + end + + if (ETA0R_i < 0.0) begin + $strobe("Warning: ETA0R_i = %e is negative, setting it to 0", ETA0R_i); + ETA0R_i = 0.0; + end + + if (LPE0_i < -Leff) begin + $strobe("Warning: LPE0_i = %e is less than -Leff. Clipping LPE0_i to 0", LPE0_i); + LPE0_i = 0.0; + end + + if (K0SI_i <= 0.0) begin + $strobe("Warning: K0SI_i = %e is not positive, setting it to 0.", K0SI_i); + K0SI_i = 0.0; + end + + if (K2SI_i <= 0.0) begin + $strobe("Warning: K2SI_i = %e is not positive, setting it to 0.", K2SI_i); + K2SI_i = 0.0; + end + + if (PHIBE_i < 0.2 && BULKMOD != 0) begin + $strobe("Warning: PHIBE_i = %e is less than 0.2, setting it to 0.2.", PHIBE_i); + PHIBE_i = 0.2; + end + + if (PHIBE_i > 1.2 && BULKMOD != 0) begin + $strobe("Warning: PHIBE_i = %e is larger than 1.2, setting it to 1.2.", PHIBE_i); + PHIBE_i = 1.2; + end + + if (PSAT_i < 2.0) begin + $strobe("Warning: PSAT_i = %e is less than 2.0, setting it to 2.0.", PSAT_i); + PSAT_i = 2.0; + end + + if (PSATCV_i < 2.0) begin + $strobe("Warning: PSATCV_i = %e is less than 2.0, setting it to 2.0.", PSATCV_i); + PSATCV_i = 2.0; + end + + if (U0_i < 0.0) begin + $strobe("Warning: U0_i = %e is negative, setting it to the default value.", U0_i); + U0_i = 0.03; + end + + if (UA_i < 0.0) begin + $strobe("Warning: UA_i = %e is negative, setting it to 0.", UA_i); + UA_i = 0.0; + end + + if (EU_i < 0.0) begin + $strobe("Warning: EU_i = %e is negative, setting it to 0.", EU_i); + EU_i = 0.0; + end + + if (UD_i < 0.0) begin + $strobe("Warning: UD_i = %e is negative, setting it to 0.", UD_i); + UD_i = 0.0; + end + + if (UCS_i < 0.0) begin + $strobe("Warning: UCS_i = %e is negative, setting it to 0.", UCS_i); + UCS_i = 0.0; + end + + if (ETAMOB_i < 0.0) begin + $strobe("Warning: ETAMOB_i = %e is negative, setting it to 0", ETAMOB_i); + ETAMOB_i = 0.0; + end + + RDSWMIN_i = RDSWMIN; + if (RDSWMIN_i < 0.0) begin + $strobe("Warning: RDSWMIN = %e is negative. Set to zero", RDSWMIN_i); + RDSWMIN_i = 0.0; + end + + if (RDSW_i < 0.0) begin + $strobe("Warning: RDSW_i = %e is negative. Set to zero", RDSW_i); + RDSW_i = 0.0; + end + + RSWMIN_i = RSWMIN; + if (RSWMIN_i < 0.0) begin + $strobe("Warning: RSWMIN = %e is negative. Set to zero", RSWMIN_i); + RSWMIN_i = 0.0; + end + + if (RSW_i < 0.0) begin + $strobe("Warning: RSW_i = %e is negative. Set to zero", RSW_i); + RSW_i = 0.0; + end + + RDWMIN_i = RDWMIN; + if (RDWMIN_i < 0.0) begin + $strobe("Warning: RDWMIN = %e is negative. Set to zero", RDWMIN_i); + RDWMIN_i = 0.0; + end + + if (RDW_i < 0) begin + $strobe("Warning: RDW_i = %e is negative. Set to zero", RDW_i); + RDW_i = 0.0; + end + + if (PRWGD_i < 0.0) begin + $strobe("Warning: PRWGD_i = %e is negative. Set to zero", PRWGD_i); + PRWGD_i = 0.0; + end + + if (PRWGS_i < 0.0) begin + $strobe("Warning: PRWGS_i = %e is negative. Set to zero", PRWGS_i); + PRWGS_i = 0.0; + end + + if (PCLM_i < 0) begin + $strobe("Warning: PCLM_i = %e is negative.", PCLM_i); + end + + if (PDIBL1_i < 0.0) begin + $strobe("Warning: PDIBL1_i = %e is negative.", PDIBL1_i); + end + + if (ASYMMOD != 0) begin + if (PDIBL1R_i < 0.0) begin + $strobe("Warning: PDIBL1R_i = %e is negative.", PDIBL1R_i); + end + if (PDIBL2R_i < 0.0) begin + $strobe("Warning: PDIBL2R_i = %e is negative.", PDIBL2R_i); + end + if (U0R_i < 0) begin + $strobe("Warning: U0R_i = %e is negative, setting it to 0.", U0R_i); + U0R_i = 0.0; + end + if (UAR_i < 0.0) begin + $strobe("Warning: UAR_i = %e is negative, setting it to 0.", UAR_i); + UAR_i = 0.0; + end + if (EUR_i < 0.0) begin + $strobe("Warning: EUR_i = %e is negative, setting it to 0.", EUR_i); + EUR_i = 0.0; + end + if (UDR_i < 0.0) begin + $strobe("Warning: UDR_i = %e is negative, setting it to 0.", UDR_i); + UDR_i = 0.0; + end + end + + if (PDIBL2_i < 0.0) begin + $strobe("Warning: PDIBL2_i = %e is negative.", PDIBL2_i); + end + + if (DROUT_i <= 0.0) begin + $strobe("Fatal: DROUT_i = %e is non-positive.", DROUT_i); + $finish(0); + end + + if (MEXP_i < 2.0) begin + $strobe("Warning: MEXP_i = %e < 2. Setting MEXP_i = 2.", MEXP_i); + MEXP_i = 2.0; + end + + if (ASYMMOD != 0) begin + if (MEXPR_i < 2.0) begin + $strobe("Warning: MEXPR_i = %e < 2. Setting MEXPR_i = 2.", MEXPR_i); + MEXPR_i = 2.0; + end + end + + if (PTWG_i < 0) begin + $strobe("Warning: PTWG_i = %e is negative, setting it to 0.", PTWG_i ); + PTWG_i = 0.0; + end + + if (QMTCENCV_i > 0.0) begin + if (QM0 <= 0.0) begin + $strobe("Fatal: QM0 = %e is non-positive.", QM0); + $finish(0); + end + end + + if (BULKMOD != 0 && QMTCENCVA_i > 0.0) begin + if (QM0ACC <= 0.0) begin + $strobe("Fatal: QM0ACC = %e is non-positive.", QM0ACC); + $finish(0); + end + end + + if (CGIDL_i < 0.0) begin + $strobe("Warning: CGIDL_i = %e < 0. Setting CGIDL_i = 0.", CGIDL_i); + CGIDL_i = 0.0; + end + + if (CGISL_i < 0.0) begin + $strobe("Warning: CGISL_i = %e < 0. Setting CGISL_i = 0.", CGISL_i); + CGISL_i = 0.0; + end + + if (IGBMOD != 0) begin + if (NIGBINV_i <= 0.0) begin + $strobe("Fatal: NIGBINV_i = %e is non-positive.", NIGBINV_i); + $finish(0); + end + if (NIGBACC_i <= 0.0) begin + $strobe("Fatal: NIGBACC_i = %e is non-positive.", NIGBACC_i); + $finish(0); + end + end + + if (IGCMOD != 0) begin + if (POXEDGE_i <= 0.0) begin + $strobe("Fatal: POXEDGE_i = %e is non-positive.", POXEDGE_i); + $finish(0); + end + if (PIGCD_i <= 0.0) begin + $strobe("Fatal: PIGCD_i = %e is non-positive.", PIGCD_i); + $finish(0); + end + end + + if (IGCMOD != 0 || IGBMOD != 0) begin + if (TOXREF <= 0) begin + $strobe("Fatal: TOXREF = %e is non-positive.", TOXREF); + $finish(0); + end + end + + if (LINTIGEN >= (Leff / 2.0)) begin + $strobe("Warning: LINTIGEN = %e is too large - Leff for r/g current is negative. Re-setting LINTIGEN = 0.", LINTIGEN); + LINTIGEN_i = 0.0; + end else begin + LINTIGEN_i = LINTIGEN; + end + + if (NTGEN_i <= 0.0) begin + $strobe("Fatal: NTGEN_i = %e is non-positive.", NTGEN_i); + $finish(0); + end + + `ifdef __NQSMOD1__ + if (NQSMOD == 1 && XRCRG1_i != 0.0 && XRCRG1_i < 1.0e-3) begin + $strobe("Warning: XRCRG1_i = %e. Gate resistance may be too large. Disabling NQS Gate Resistance.", XRCRG1_i); + XRCRG1_i = 0.0; + end + `endif + + if (IIMOD == 2) begin + if (BETAII0_i < 0.0) begin + $strobe("Warning: BETAII0_i = %e is negative.",BETAII0_i); + end + if (BETAII1_i < 0.0) begin + $strobe("Warning: BETAII1_i = %e is negative.", BETAII1_i); + end + if (BETAII2_i < 0.0) begin + $strobe("Warning: BETAII2_i = %e is negative.", BETAII2_i); + end + if (ESATII_i < 0.0) begin + $strobe("Warning: ESATII_i = %e is negative.", ESATII_i); + end + if (LII_i < 0.0) begin + $strobe("Warning: LII_i = %e is negative.", LII_i); + end + if (SII1_i < 0.0) begin + $strobe("Warning: SII1_i = %e is negative.", SII1); + end + if (SII2_i < 0.0) begin + $strobe("Warning: SII2_i = %e is negative.", SII2_i); + end + if (SIID_i < 0.0) begin + $strobe("Warning: SIID_i = %e is negative.", SIID_i); + end + end + + if (EF <= 0.0) begin + $strobe("Fatal: EF = %e is non-positive.", EF); + $finish(0); + end else if (EF > 2.0) begin + $strobe("Fatal: EF = %e > 2.0.", EF); + $finish(0); + end + + if (LINTNOI >= (Leff / 2.0)) begin + $strobe("Warning: LINTNOI = %e is too large - Leff for noise is negative. Re-setting LINTNOI = 0.", LINTNOI); + LINTNOI_i = 0.0; + end else begin + LINTNOI_i = LINTNOI; + end + + if (NTNOI < 0) begin + $strobe("Warning: NTNOI = %e is negative. Set to zero.", NTNOI); + NTNOI_i = 0.0; + end else begin + NTNOI_i = NTNOI; + end + + // Self-Heating + `ifdef __SHMOD__ + if (SHMOD != 0 && RTH0 > 0.0) begin + T1y = WTH0; + if (BSHEXP != 0.0) begin + T1y = WTH0 * pow(NF, BSHEXP); + end + T2y = FPITCH; + if (ASHEXP != 0.0) begin + T2y = FPITCH * pow(NFINtotal, ASHEXP); + end + gth = (T1y + T2y)/ RTH0; + cth = CTH0 * (T1y + T2y); + end else begin + gth = 1.0; + cth = 0.0; + end + `else + if (SHMOD != 0) begin + $strobe("Although the model selector SHMOD is set to 1, the self heating model is not activated in the Verilog-A code. Please uncomment \"`define __SHMOD__\" in bsimcmg.va to activate it."); + end + `endif + + // Gate Electrode Resistance + `ifdef __RGATEMOD__ + if (RGATEMOD != 0) begin + Rgeltd = (RGEXT / NGCON + (RGFIN * NFIN) / (NGCON == 2 ? 12.0 : 3.0)) / NF; + ggeltd = 1.0 / max(1.0e-3, Rgeltd); + end + `else + if (RGATEMOD != 0) + $strobe("Although the model selector RGATEMOD is set to 1, the gate electrode resistance model is not activated in the Verilog-A code. Please uncomment \"`define __RGATEMOD__\" in bsimcmg.va to activate it."); + `endif + + // Geometry-Dependent Source/Drain Resistance + if (RGEOMOD == 0) begin + RSourceGeo = RSHS * NRS; + RDrainGeo = RSHD * NRD; + end else begin + // Area and perimeter calculation + if (HEPI > 0.0) begin + Arsd = FPITCH * HFIN + (TFIN + (FPITCH - TFIN) * CRATIO) * HEPI; + end else begin + Arsd = FPITCH * max(1.0e-9, HFIN + HEPI); + end + Prsd = FPITCH + DELTAPRSD; + + // Resistivity Calculation + if ($param_given(RHORSD)) begin + rhorsd = RHORSD; + end else begin + mu_max = (TYPE == `ntype) ? 1417.0 : 470.5; + if (TYPE == `ntype) begin + mu_rsd = (52.2 + (mu_max - 52.2) / (1.0 + pow(NSD / 9.68e22, 0.680)) - 43.4 / (1.0 + pow(3.43e26 / NSD, 2.0))) * 1.0e-4; + end else begin + mu_rsd = (44.9 + (mu_max - 44.9) / (1.0 + pow(NSD / 2.23e22, 0.719)) - 29.0 / (1.0 + pow(6.10e26 / NSD, 2.0))) * 1.0e-4; + end + rhorsd = 1.0 / (`q * NSD * mu_rsd); + end + + // Component: Spreading Resistance (extension -> hdd) + thetarsp = 55.0 * `M_PI / 180.0; + afin = min(Arsd, max(1.0e-18, TFIN * (HFIN + min(0.0, HEPI)))); + T1y = `COT(thetarsp); + Rsp = rhorsd * T1y / (sqrt(`M_PI) * NFIN) * (1.0 / sqrt(afin) - 2.0 / sqrt(Arsd) + sqrt(afin / (Arsd*Arsd))); + + // Component: Contact Resistance + arsd_total = Arsd * NFIN + ARSDEND; + prsd_total = Prsd * NFIN + PRSDEND; + lt = sqrt(RHOC * arsd_total / (rhorsd * prsd_total)); + alpha = LRSD / lt; + T0y = lexp(alpha + alpha); + + if (SDTERM == 1.0) begin + eta = rhorsd * lt / RHOC; + T1y = T0y * (1.0 + eta); + T2y = T1y + 1.0 - eta; + T3y = T1y - 1.0 + eta; + end else begin + T2y = T0y + 1.0; + T3y = T0y - 1.0; + end + RrsdTML = rhorsd * lt * T2y / (arsd_total * T3y); + + if (HEPI < -1.0e-10) begin + Rrsdside = RHOC / (-HEPI * TFIN * NFIN); + Rrsd = (RrsdTML + Rsp) * Rrsdside / ((RrsdTML + Rsp) + Rrsdside); + end else begin + Rrsd = RrsdTML + Rsp; + end + + Rdsgeo = Rrsd / NF * max(0.0, RGEOA + RGEOB * TFIN + RGEOC * FPITCH + RGEOD * LRSD + RGEOE * HEPI); + RSourceGeo = Rdsgeo; + RDrainGeo = Rdsgeo; + end + + // Clamping of Source/Drain Resistances + if (RSourceGeo <= 1.0e-3) begin + RSourceGeo = 1.0e-3; + end + + if (RDrainGeo <= 1.0e-3) begin + RDrainGeo = 1.0e-3; + end + + if (RDSMOD == 1) begin + if (RSWMIN_i <= 0.0) begin + RSWMIN_i = 0.0; + end + if (RDWMIN_i <= 0.0) begin + RDWMIN_i = 0.0; + end + if (RSW_i <= 0.0) begin + RSW_i = 0.0; + end + if (RDW_i <= 0.0) begin + RDW_i = 0.0; + end + end else begin + if (RDSWMIN_i <= 0.0) begin + RDSWMIN_i = 0.0; + end + if (RDSW_i <= 0.0) begin + RDSW_i = 0.0; + end + end // End of Clamping of Source/Drain Resistances + + if (CGEOMOD != 1) begin + if ($param_given(CGSO)) begin + CGSO_i = CGSO; + end else begin + if ($param_given(DLC) && DLC > 0.0) begin + CGSO_i = max(0.0, DLC * cox - CGSL_i); + end else begin + CGSO_i = 0.3 * TFIN * cox; + end + end + if ($param_given(CGDO)) begin + CGDO_i = CGDO; + end else begin + if ($param_given(DLC) && DLC > 0.0) begin + CGDO_i = max(0.0, DLC * cox - CGDL_i); + end else begin + CGDO_i = 0.3 * TFIN * cox; + end + end + end + + // Parasitic Source/Drain to Gate Fringe Capacitance Model + if (CGEOMOD == 2) begin + if ($param_given(LSP)) + LSP_i = LSP; + else + LSP_i = 0.2*(L + XL); + Hg = TGATE + TMASK; + Trsd = 0.5 * (FPITCH - TFIN); + Wg = max(0.0, Trsd - TOXP); + Hrsd = max(0.0, HEPI + TSILI); + + // Top Component + if (TMASK > 0.0) begin + // Capacitance Model by Chung-Hsun Lin (IBM) + T0y = 3.467e-11 * lln(1.0e-7 * EPSRSP / (3.9 * LSP_i)); + T1y = 0.942 * Hrsd * epssp / LSP_i; + Cgg_top = (T0y + T1y) * (TFIN + (FPITCH - TFIN) * CRATIO); + end else begin + `Cfringe_2d(cfr_top_trigate, Hg, Hrsd, LSP_i, TFIN, LRSD, Lg, TOXP, 0.85, Cgg_top) + end + + // Side Component + if (TMASK > 0) begin + `Cfringe_2d(cfr_side_dblgate, Wg, Trsd, LSP_i, HFIN, LRSD, Lg, TOXP, 0.70, Cgg_side) + end else begin + `Cfringe_2d(cfr_side_trigate, Wg, Trsd, LSP_i, HFIN, LRSD, Lg, TOXP, 0.85, Cgg_side) + end + + // Corner Component + if (TMASK > 0.0) begin + Acorner = 0.0; + end else begin + if (HEPI > 0.0) begin + Acorner = (FPITCH - TFIN) * (HEPI * CRATIO + TSILI); + end else begin + Acorner = (FPITCH - TFIN) * Hrsd; + end + end + Ccorner = (NFIN * Acorner + ARSDEND + ASILIEND) * epssp / LSP_i; + Cfr_geo = (Ccorner + Cgg_top * NFIN + CGEOE * Cgg_side * NFIN * 2.0) * NF; + Cfr_geo = Cfr_geo * max(0.0, CGEOA + CGEOB * TFIN + CGEOC * FPITCH + CGEOD * LRSD); + end + + // Source/Gate/Drain-to-Substrate Parasitic Capacitances + T0y = CSDESW * lln(1.0 + HFIN / EOTBOX); + csbox = cbox * ASEO + T0y * max(0.0, PSEO - FPITCH * NFINtotal); + cdbox = cbox * ADEO + T0y * max(0.0, PDEO - FPITCH * NFINtotal); + cgbox = (CGBO * NF * NGCON + CGBN * NFINtotal) * Lg; + + // Mobility Degradation + EeffFactor = 1.0e-8 / (epsratio * (EOT)); + WeffWRFactor = 1.0 / (pow((Weff0) * 1.0e6, WR_i) * NFINtotal); + litl = sqrt(epsratio * EOT * 0.5 * TFIN); + + if (!$param_given(THETASCE)) begin + tmp = DVT1_i * Leff / scl + 1.0e-6; + if (tmp < 40.0) begin + Theta_SCE = 0.5 / (cosh(tmp) - 1.0); + end else begin + Theta_SCE = exp(-tmp); + end + end else begin + Theta_SCE = THETASCE; + end + + if (!$param_given(THETASW)) begin + tmp = DVT1SS_i * Leff / scl + 1.0e-6; + if (tmp < 40.0) begin + Theta_SW = 0.5 / (cosh(tmp) - 1.0); + end else begin + Theta_SW = exp(-tmp); + end + end else begin + Theta_SW = THETASW; + end + + if (!$param_given(THETADIBL)) begin + tmp = DSUB_i * Leff / scl + 1.0e-6; + if (tmp < 40.0) begin + Theta_DIBL = 0.5 / (cosh(tmp) - 1.0); + end else begin + Theta_DIBL = exp(-tmp); + end + end else begin + Theta_DIBL = THETADIBL; + end + + Theta_RSCE = sqrt(1.0 + LPE0_i / Leff) - 1.0; + + tmp = DSUB_i * Leff / scl + 1.0e-6; + if (tmp < 40.0) begin + T0y = 1.0 / max((1.0 + DVTP2 * (cosh(tmp) - 2.0)), 1.0e-6); + end else begin + T0y = exp(-tmp) / max((exp(-tmp) + DVTP2), 1.0e-6); + end + + Theta_DITS = T0y; + nbody = NBODY_i; + qbs = `q * nbody * Ach / Cins; + + // Gate Current + if (TYPE == `ntype) begin + Aechvb = 4.97232e-7; // NMOS + Bechvb = 7.45669e11; // NMOS + end else begin + Aechvb = 3.42537e-7; // PMOS + Bechvb = 1.16645e12; // PMOS + end + + T0y = TOXG * TOXG; + T1y = TOXG * POXEDGE_i; + T2y = T1y * T1y; + Toxratio = lexp(NTOX_i * lln(TOXREF / TOXG)) / T0y; + Toxratioedge = lexp(NTOX_i * lln(TOXREF / T1y)) / T2y; + igsd_mult0 = Weff0 * Aechvb * Toxratioedge; + + if (TNOM < -`P_CELSIUS0) begin + $strobe("Warning: (TNOM=%e) < -`P_CELSIUS0. Set to 27 C.", TNOM); + Tnom = `REFTEMP; + end else begin + Tnom = TNOM + `CONSTCtoK; + end + end // initial_step + + // ************************************************ + // * Temperature Dependence Calculations * + // ************************************************ + `ifdef __SHMOD__ + if (SHMOD != 0 && RTH0 > 0.0) begin + DevTemp = $temperature + Temp(rth_branch) + DTEMP; + end else begin + `endif + DevTemp = $temperature + DTEMP; + `ifdef __SHMOD__ + end + `endif + + begin : CMGTempDepCalc + TRatio = DevTemp / Tnom; + delTemp = DevTemp - Tnom; + Vtm = `KboQ * DevTemp; + Vtm0 = `KboQ * Tnom; + Eg = BG0SUB - TBGASUB * DevTemp * DevTemp / (DevTemp + TBGBSUB); + Eg0 = BG0SUB - TBGASUB * Tnom * Tnom / (Tnom + TBGBSUB); + T1 = (DevTemp / 300.15) * sqrt(DevTemp / 300.15); + ni = NI0SUB * T1 * lexp(BG0SUB / (2.0 * `KboQ * 300.15) - Eg / (2.0 * Vtm)); + Nc = NC0SUB * T1; + ThetaSS = hypsmooth(1.0 + TSS_i * delTemp - 1.0e-6, 1.0e-3); + + // Quantum Mechanical Vth Correction (Ref: Trivedi et al., EDL 2005) + kT = Vtm * `q; + T0y = `HBAR * `M_PI / (2*Ach/Weff_UFCM ); + E0 = T0y * T0y / (2.0 * mx); + E0prime = T0y * T0y / (2.0 * mxprime); + E1 = 4.0 * E0; + E1prime = 4.0 * E0prime; + T1 = gprime * mdprime / (gfactor * md); + gam0 = 1.0 + T1 * lexp((E0 - E0prime) / kT); + gam1 = gam0 + lexp((E0 - E1) / kT) + T1 * lexp((E0 - E1prime) / kT); + T2 = -Vtm * lln(gfactor * md / (`M_PI * `HBAR * `HBAR * Nc) * kT / (2.0 * Ach / Weff_UFCM) * gam1); + dvch_qm = QMFACTOR_i * (E0 / `q + T2); + + // Temperature Dependence + ETA0_t = Tempdep(ETA0_i, TETA0, delTemp, TEMPMOD); + ETA0R_t = Tempdep(ETA0R_i, TETA0R, delTemp, TEMPMOD); + T1 = U0_i * pow(TRatio, UTE_i); + U0_t = T1 + hypmax(UTL_i * delTemp, -0.9 * T1, 1.0e-4); + u0 = U0_t; + if (ASYMMOD == 1) begin + T1 = U0R_i * pow(TRatio, UTER_i); + U0R_t = T1 + hypmax(UTLR_i * delTemp, -0.9 * T1, 1.0e-4); + u0r = U0R_t; + end + + ETAMOB_t = Tempdep(ETAMOB_i, EMOBT_i, delTemp, TEMPMOD); + UA_t = UA_i + hypmax(UA1_i*delTemp, -UA_i, 1.0e-6); + if (ASYMMOD != 0) begin + UAR_t = UAR_i + hypmax(UA1R_i * delTemp, -UAR_i, 1.0e-6); + end + + if (BULKMOD != 0) begin + if (TEMPMOD == 0) begin + UC_t = Tempdep(UC_i, UC1_i, delTemp, 0); + if (ASYMMOD != 0) begin + UCR_t = Tempdep(UCR_i, UC1R_i, delTemp, 0); + end + end else begin + UC_t = UC_i + UC1_i * delTemp; + if (ASYMMOD != 0) begin + UCR_t = UCR_i + UC1R_i * delTemp; + end + end + end + + UD_t = UD_i * pow(TRatio, UD1_i); + if (ASYMMOD != 0) begin + UDR_t = UDR_i * pow(TRatio, UD1R_i); + end + + UCS_t = UCS_i * pow(TRatio, UCSTE_i); + + rdstemp = hypsmooth(1.0 + PRT_i * delTemp - 1.0e-6, 1.0e-3); + RSDR_t = Tempdep(RSDR, TRSDR, delTemp, TEMPMOD); + if (ASYMMOD != 0) begin + RSDRR_t = Tempdep(RSDRR, TRSDR, delTemp, TEMPMOD); + end + + RDDR_t = Tempdep(RDDR, TRDDR, delTemp, TEMPMOD); + if (ASYMMOD != 0) begin + RDDRR_t = Tempdep(RDDRR, TRDDR, delTemp, TEMPMOD); + end + + VSAT_t = Tempdep(VSAT_i, -AT_i, delTemp, TEMPMOD); + if (VSAT_t < 1000) begin + $strobe("Warning: VSAT(%f) = %e is less than 1K, setting it to 1K.", DevTemp, VSAT_t); + VSAT_t = 1000; + end + + if (ASYMMOD != 0) begin + VSATR_t = Tempdep(VSATR_i, -ATR_i, delTemp, TEMPMOD); + if (VSATR_t < 1000) begin + $strobe("Warning: VSATR(%f) = %e is less than 1K, setting it to 1K.", DevTemp, VSATR_t); + VSATR_t = 1000; + end + end + + VSAT1_t = Tempdep(VSAT1_i, -AT_i, delTemp, TEMPMOD); + if (VSAT1_t < 1000) begin + $strobe("Warning: VSAT1(%f) = %e is less than 1K, setting it to 1K.", DevTemp, VSAT1_t); + VSAT1_t = 1000; + end + + if (ASYMMOD != 0) begin + VSAT1R_t = Tempdep(VSAT1R_i, -AT_i, delTemp, TEMPMOD); + if (VSAT1R_t < 1000) begin + $strobe("Warning: VSAT1R(%f) = %e is less than 1K, setting it to 1K.", DevTemp, VSAT1R_t); + VSAT1R_t = 1000; + end + end + + VSATCV_t = Tempdep(VSATCV_i, -ATCV_i, delTemp, TEMPMOD); + if (VSATCV_t < 1000) begin + $strobe("Warning: VSATCV(%f) = %e is less than 1K, setting it to 1K.", DevTemp, VSATCV_t); + VSATCV_t = 1000; + end + + MEXP_t = hypsmooth(MEXP_i * (1.0 + TMEXP * delTemp) - 2.0, 1.0e-3) + 2.0; + if (ASYMMOD != 0) begin + MEXPR_t = hypsmooth(MEXPR_i * (1.0 + TMEXPR * delTemp) - 2.0, 1.0e-3) + 2.0; + end + + PTWG_t = Tempdep(PTWG_i, -PTWGT_i, delTemp, TEMPMOD); + if (ASYMMOD != 0) begin + PTWGR_t = Tempdep(PTWGR_i, -PTWGT_i, delTemp, TEMPMOD); + end + + dvth_temp = (KT1_i + KT1L / Leff) * (TRatio - 1.0); + BETA0_t = BETA0_i * pow(TRatio, IIT_i); + SII0_t = SII0_i * (hypsmooth(1.0 + TII_i * (TRatio - 1.0) - 0.01, 1.0e-3) + 0.01); + + K0_t = K0_i + K01_i * delTemp; + K0SI_t = K0SI_i + hypmax(K0SI1_i * delTemp, -K0SI_i, 1.0e-6); + K2SI_t = K2SI_i + hypmax(K2SI1_i * delTemp, -K2SI_i, 1.0e-6); + K1_t = K1_i + hypmax(K11_i * delTemp, -K1_i, 1.0e-6); + K2SAT_t = K2SAT_i + K2SAT1_i * delTemp; + A1_t = A1_i + A11_i * delTemp; + A2_t = A2_i + A21_i * delTemp; + K2_t = K2_i + hypmax(K21_i * delTemp, -K2_i, 1.0e-6); + K0SISAT_t = K0SISAT_i + K0SISAT1_i * delTemp; + K2SISAT_t = K2SISAT_i + K2SISAT1_i * delTemp; + AIGBINV_t = AIGBINV_i + hypmax(AIGBINV1_i * delTemp, -AIGBINV_i, 1.0e-6); + AIGBACC_t = AIGBACC_i + hypmax(AIGBACC1_i * delTemp, -AIGBACC_i, 1.0e-6); + AIGC_t = AIGC_i + hypmax(AIGC1_i * delTemp, -AIGC_i, 1.0e-6); + AIGS_t = AIGS_i + hypmax(AIGS1_i * delTemp, -AIGS_i, 1.0e-6); + AIGD_t = AIGD_i + hypmax(AIGD1_i * delTemp, -AIGD_i, 1.0e-6); + BGIDL_t = BGIDL_i * hypsmooth(1.0 + TGIDL_i * delTemp - 1.0e-6, 1.0e-3); + BGISL_t = BGISL_i * hypsmooth(1.0 + TGIDL_i * delTemp - 1.0e-6, 1.0e-3); + ALPHA0_t = ALPHA0_i + hypmax(ALPHA01 * delTemp, -ALPHA0_i, 1.0e-6); + ALPHA1_t = ALPHA1_i + hypmax(ALPHA11 * delTemp, -ALPHA1_i, 1.0e-6); + ALPHAII0_t = ALPHAII0_i + hypmax(ALPHAII01 * delTemp, -ALPHAII0_i, 1.0e-25); + ALPHAII1_t = ALPHAII1_i + hypmax(ALPHAII11 * delTemp, -ALPHAII1_i, 1.0e-20); + igtemp = lexp(IGT_i * lln(TRatio)); + igsd_mult = igsd_mult0 * igtemp; + + if (BULKMOD != 0) begin + CJS_t = Tempdep(CJS, TCJ, delTemp, TEMPMOD); + CJD_t = Tempdep(CJD, TCJ, delTemp, TEMPMOD); + CJSWS_t = Tempdep(CJSWS, TCJSW, delTemp, TEMPMOD); + CJSWD_t = Tempdep(CJSWD, TCJSW, delTemp, TEMPMOD); + CJSWGS_t = Tempdep(CJSWGS, TCJSWG, delTemp, TEMPMOD); + CJSWGD_t = Tempdep(CJSWGD, TCJSWG, delTemp, TEMPMOD); + + PBS_t = hypsmooth(PBS - TPB * delTemp - 0.01, 1.0e-3) + 0.01; + PBD_t = hypsmooth(PBD - TPB * delTemp - 0.01, 1.0e-3) + 0.01; + PBSWS_t = hypsmooth(PBSWS - TPBSW * delTemp - 0.01, 1.0e-3) + 0.01; + PBSWD_t = hypsmooth(PBSWD - TPBSW * delTemp - 0.01, 1.0e-3) + 0.01; + PBSWGS_t = hypsmooth(PBSWGS - TPBSWG * delTemp - 0.01, 1.0e-3) + 0.01; + PBSWGD_t = hypsmooth(PBSWGD - TPBSWG * delTemp - 0.01, 1.0e-3) + 0.01; + + T0 = Eg0 / Vtm0 - Eg / Vtm; + T1 = lln(TRatio); + T3 = lexp((T0 + XTIS * T1) / NJS); + JSS_t = JSS * T3; + JSWS_t = JSWS * T3; + JSWGS_t = JSWGS * T3; + + T3 = lexp((T0 + XTID * T1) / NJD); + JSD_t = JSD * T3; + JSWD_t = JSWD * T3; + JSWGD_t = JSWGD * T3; + + JTSS_t = JTSS * lexp(Eg0 * XTSS * (TRatio - 1.0) / Vtm); + JTSD_t = JTSD * lexp(Eg0 * XTSD * (TRatio - 1.0) / Vtm); + JTSSWS_t = JTSSWS * lexp(Eg0 * XTSSWS * (TRatio - 1.0) / Vtm); + JTSSWD_t = JTSSWD * lexp(Eg0 * XTSSWD * (TRatio - 1.0) / Vtm); + JTSSWGS_t = JTSSWGS * (sqrt(JTWEFF / Weff0) + 1.0) * lexp(Eg0 * XTSSWGS * (TRatio - 1.0) / Vtm); + JTSSWGD_t = JTSSWGD * (sqrt(JTWEFF / Weff0) + 1.0) * lexp(Eg0 * XTSSWGD * (TRatio - 1.0) / Vtm); + + // All NJT's Smoothed to 0.01 to Prevent Divide-by-zero / Negative Values + NJTS_t = hypsmooth(NJTS * (1.0 + TNJTS * (TRatio-1.0)) - 0.01, 1.0e-3) + 0.01; + NJTSD_t = hypsmooth(NJTSD * (1.0 + TNJTSD * (TRatio-1.0)) - 0.01, 1.0e-3) + 0.01; + NJTSSW_t = hypsmooth(NJTSSW * (1.0 + TNJTSSW * (TRatio-1.0)) - 0.01, 1.0e-3) + 0.01; + NJTSSWD_t = hypsmooth(NJTSSWD * (1.0 + TNJTSSWD * (TRatio-1.0)) - 0.01, 1.0e-3) + 0.01; + NJTSSWG_t = hypsmooth(NJTSSWG * (1.0 + TNJTSSWG * (TRatio-1.0)) - 0.01, 1.0e-3) + 0.01; + NJTSSWGD_t = hypsmooth(NJTSSWGD * (1.0 + TNJTSSWGD * (TRatio-1.0)) - 0.01, 1.0e-3) + 0.01; + end + + if (!$param_given(VFBSD)) begin + if (NGATE > 0.0) begin + vfbsd = devsign * (hypsmooth(0.5 * Eg - Vtm * lln(NGATE / ni), 1.0e-4) - (0.5 * Eg - devsign * (0.5 * Eg - hypsmooth(0.5 * Eg - Vtm * lln(NSD / ni), 1.0e-4)))); + end else begin + vfbsd = devsign * (PHIG_i - (EASUB + 0.5 * Eg - devsign * (0.5 * Eg - hypsmooth(0.5 * Eg - Vtm * lln(NSD / ni), 1.0e-4)))); + end + end else begin + vfbsd = VFBSD; + end + + if (!$param_given(VFBSDCV)) begin + vfbsdcv = vfbsd; + end else begin + vfbsdcv = VFBSDCV; + end + + `ifdef __SHMOD__ + if (SHMOD != 0 && RTH0 > 0.0) begin + T0 = Vtm * lln(nbody / ni); + phib = sqrt(T0 * T0 + 1.0e-6); + end else begin + phib = Vtm * lln(nbody / ni); + end + `else + phib = Vtm * lln(nbody/ni); + `endif + + `ifdef __SHMOD__ + if (SHMOD != 0 && RTH0 > 0.0) begin + T0 = Vtm * lln(nbody * NSD / (ni * ni)); + vbi = sqrt(T0 * T0 + 1.0e-6); + end else begin + vbi = Vtm * lln(nbody * NSD / (ni * ni)); + end + `else + vbi = Vtm * lln(nbody * NSD / (ni * ni)); + `endif + + // deltaPhi definition and Polysilicon Depletion + // deltaPhi: workfunction difference between the gate and the n+ source. + deltaPhi = devsign*(PHIG_i - (EASUB + (TYPE == `ntype ? 0 : Eg))); + + // Mobility Degradation + eta_mu = 0.5 * ETAMOB_t; + eta_mu_cv = 0.5; + if ( TYPE != `ntype ) begin + eta_mu = 1.0 / 3.0 * ETAMOB_t; + eta_mu_cv = 1.0 / 3.0; + end + + // Junction Current and Capacitance + if (BULKMOD != 0) begin + // Source-Side Junction Current + Isbs = ASEJ * JSS_t + PSEJ * JSWS_t + TFIN * NFINtotal * JSWGS_t; + if (Isbs > 0.0) begin + Nvtms = Vtm * NJS; + XExpBVS = lexp(-BVS / Nvtms) * XJBVS; + T2 = max(IJTHSFWD / Isbs, 10.0); + Tb = 1.0 + T2 - XExpBVS; + VjsmFwd = Nvtms * lln(0.5 * (Tb + sqrt(Tb * Tb + 4.0 * XExpBVS))); + T0 = lexp(VjsmFwd / Nvtms); + IVjsmFwd = Isbs * (T0 - XExpBVS / T0 + XExpBVS - 1.0); + SslpFwd = Isbs * (T0 + XExpBVS / T0) / Nvtms; + T2 = hypsmooth(IJTHSREV / Isbs - 10.0, 1.0e-3) + 10.0; + VjsmRev = -BVS - Nvtms * lln((T2 - 1.0) / XJBVS); + T1 = XJBVS * lexp(-(BVS + VjsmRev) / Nvtms); + IVjsmRev = Isbs * (1.0 + T1); + SslpRev = -Isbs * T1 / Nvtms; + end + + // Drain-Side Junction Current + Isbd = ADEJ * JSD_t + PDEJ * JSWD_t + TFIN * NFINtotal * JSWGD_t; + if (Isbd > 0.0) begin + Nvtmd = Vtm * NJD; + XExpBVD = lexp(-BVD / Nvtmd) * XJBVD; + T2 = max(IJTHDFWD / Isbd, 10.0); + Tb = 1.0 + T2 - XExpBVD; + VjdmFwd = Nvtmd * lln(0.5 * (Tb + sqrt(Tb * Tb + 4.0 * XExpBVD))); + T0 = lexp(VjdmFwd / Nvtmd); + IVjdmFwd = Isbd * (T0 - XExpBVD / T0 + XExpBVD - 1.0); + DslpFwd = Isbd * (T0 + XExpBVD / T0) / Nvtmd; + T2 = hypsmooth(IJTHDREV / Isbd - 10.0, 1.0e-3) + 10.0; + VjdmRev = -BVD - Nvtmd * lln((T2 - 1.0) / XJBVD); + T1 = XJBVD * lexp(-(BVD + VjdmRev) / Nvtmd); + IVjdmRev = Isbd * (1.0 + T1); + DslpRev = -Isbd * T1 / Nvtmd; + end + + // Junction Capacitance + Czbs = CJS_t * ASEJ; + Czbssw = CJSWS_t * PSEJ; + Czbsswg = CJSWGS_t * Weff0 * NFINtotal; + Czbd = CJD_t * ADEJ; + Czbdsw = CJSWD_t * PDEJ; + Czbdswg = CJSWGD_t * Weff0 * NFINtotal; + end + + // Generation-Recombination Current + T0 = Eg / Vtm * (TRatio - 1.0); + T1 = T0 / NTGEN_i; + igentemp = lexp(T1); + + end // End of temperature dependent calculations + + // ************************************************ + // * Bias dependent calculations follow * + // ************************************************ + + // Load Terminal Voltages + vgs_noswap = devsign * V(`IntrinsicGate, si); + vds_noswap = devsign * V(di, si); + vgd_noswap = devsign * V(`IntrinsicGate, di); + ves_jct = devsign * V(e, si); + ved_jct = devsign * V(e, di); + vge = devsign * V(`IntrinsicGate, e); + + // Source-Drain Interchange + sigvds = 1.0; + if (vds_noswap < 0.0) begin + sigvds = -1.0; + vgs = vgs_noswap - vds_noswap; + vds = -1.0 * vds_noswap; + ves = ved_jct; + end else begin + vgs = vgs_noswap; + vds = vds_noswap; + ves = ves_jct; + end + vgsfb = vgs - deltaPhi; + + // Initialize Certain Variables to Zero to Prevent Unnecessary Update + etaiv = 0.0; + Qes = 0.0; + Qesj = 0.0; + Qeg = 0.0; + Qed = 0.0; + Qedj = 0.0; + + // Vds Smoothing + vdsx = sqrt (vds * vds + 0.01) - 0.1; + + // Ves Smoothing + if (BULKMOD != 0) begin + vesx = ves - 0.5 * (vds - vdsx); + vesmax = 0.95 * PHIBE_i; + T2 = vesmax - vesx - 1.0e-3; + veseff = vesmax - 0.5 * (T2 + sqrt(T2 * T2 + 0.004 * vesmax)); + end + + // Asymmetry Model + T0 = tanh(0.6 * vds_noswap / Vtm); + wf = 0.5 + 0.5 * T0; + wr = 1.0 - wf; + if (ASYMMOD != 0) begin + CDSCD_a = CDSCDR_i * wr + CDSCD_i * wf; + ETA0_a = ETA0R_t * wr + ETA0_t * wf; + PDIBL1_a = PDIBL1R_i * wr + PDIBL1_i * wf; + PDIBL2_a = PDIBL2R_i * wr + PDIBL2_i * wf; + MEXP_a = MEXPR_t * wr + MEXP_t * wf; + PTWG_a = PTWGR_t * wr + PTWG_t * wf; + VSAT1_a = VSAT1R_t * wr + VSAT1_t * wf; + RSDR_a = RSDRR_t * wr + RSDR_t * wf; + RDDR_a = RDDRR_t * wr + RDDR_t * wf; + PCLM_a = PCLMR_i * wr + PCLM_i * wf; + VSAT_a = VSATR_t * wr + VSAT_t * wf; + KSATIV_a = KSATIVR_i * wr + KSATIV_i * wf; + DVTSHIFT_a = DVTSHIFTR_i * wr + DVTSHIFT_i * wf; + CIT_a = CITR_i * wr + CIT_i * wf; + u0_a = u0r * wr + u0 * wf; + UA_a = UAR_t*wr + UA_t * wf; + UD_a = UDR_t * wr + UD_t * wf; + UC_a = UCR_t * wr + UC_t * wf; + EU_a = EUR_i * wr + EU_i * wf; + end else begin + CDSCD_a = CDSCD_i; + ETA0_a = ETA0_t; + PDIBL1_a = PDIBL1_i; + PDIBL2_a = PDIBL2_i; + MEXP_a = MEXP_t; + PTWG_a = PTWG_t; + VSAT1_a = VSAT1_t; + RSDR_a = RSDR_t; + RDDR_a = RDDR_t; + PCLM_a = PCLM_i; + VSAT_a = VSAT_t; + KSATIV_a = KSATIV_i; + DVTSHIFT_a = DVTSHIFT_i; + CIT_a = CIT_i; + u0_a = u0; + UA_a = UA_t; + UD_a = UD_t; + UC_a = UC_t; + EU_a = EU_i; + end + + // Drain Saturation Voltage + inv_MEXP = 1.0 / MEXP_a; + + // SCE, DIBL, SS Degradation Effects (Ref: BSIM4 Model) + phist = 0.4 + phib + PHIN_i; + T1 = 2.0 * (Cins / Weff_UFCM) / (rc + 2.0); + cdsc = Theta_SW * (CDSC_i + CDSCD_a * vdsx); + + if (!$param_given(NVTM)) + nVtm = Vtm * ThetaSS * (1.0 + (CIT_a + cdsc) / T1); + else nVtm = NVTM; + + // temp deped UFCM + qdep = Qdep_ov_Cins / nVtm; + vth_fixed_factor_SI = ln(Cins * nVtm/(`q * Nc * 2.0 * Ach)); + vth_fixed_factor_Sub = ln((qdep * rc) * (qdep * rc) / ((exp(qdep * rc) - qdep * rc - 1.0))) + vth_fixed_factor_SI; + q0 = 10.0 * nVtm / rc + 2.0 * qbs; + + // New QM parameter calculation: fieldnormalizationfactor, auxQMfact, QMFACTORCVfinal + fieldnormalizationfactor = Vtm * Cins / (Weff_UFCM * epssub); + auxQMfact = pow(((3.0 / 4.0) * 3.0 * `HBAR * 2.0 * `M_PI * `q / (4.0 * sqrt(2.0 * mx))), 2.0 / 3.0); + QMFACTORCVfinal = QMFACTORCV * auxQMfact * pow(fieldnormalizationfactor, 2.0 / 3.0) * (1/(`q * Vtm)); + + dvth_vtroll = -DVT0_i * Theta_SCE * (vbi - phist); + dvth_dibl = -ETA0_a * Theta_DIBL * vdsx + (DVTP0_i * Theta_DITS * pow(vdsx, DVTP1_i)); + dvth_rsce = K1RSCE_i * Theta_RSCE * sqrt(phist); + dvth_all = dvth_vtroll + dvth_dibl + dvth_rsce + dvth_temp + DVTSHIFT_a; + vgsfb = vgsfb - dvth_all; + + // Vgs Clamping for Inversion Region Calculation in Accumulation + beta0 = u0_a * cox * Weff0 / Leff; + T0 = -(dvch_qm + nVtm * lln(2.0 * cox * Imin / (beta0 * nVtm * `q * Nc * TFIN))); + T1 = vgsfb + T0 + DELVTRAND; + vgsfbeff = hypsmooth(T1 , 1.0e-4) - T0; + + // Core Model Calculation at Source Side + vch = 0.0 + dvch_qm; + + if (BULKMOD != 0) begin + T1 = hypsmooth(2.0 * phib + vch - ves, 0.1); + T3 = (-K1_t / (2.0 * nVtm)) * (sqrt(T1) - sqrt(2.0 * phib)); + T0 = -qdep - T3 + vth_fixed_factor_Sub + QMFACTORCVfinal * pow(-qdep, 2.0/3.0); + T1 = -qdep - T3 + vth_fixed_factor_SI; + end else begin + T0 = -qdep + vth_fixed_factor_Sub + QMFACTORCVfinal * pow(-qdep, 2.0/3.0); + T1 = -qdep + vth_fixed_factor_SI; + end + T2 = (vgsfbeff - vch) / nVtm; + F0 = -T2 + T1; + T3 = 0.5 * (T2 - T0); + qm = exp(T3); + if (qm > 1.0e-7) begin + T7 = ln(1.0 + qm); + qm = 2.0 * (1.0 - sqrt(1.0 + T7 * T7)); + T8 = (qm * ALPHA_UFCM + qdep) * rc; + T4 = T8 / (exp(T8) - T8 - 1.0); + T5 = T8 * T4; + e0 = F0 - qm + ln(-qm) + ln(T5) + QMFACTORCVfinal * pow(-(qm + qdep), 2.0 / 3.0); + e1 = -1.0 + 1.0 / qm + (2.0 / T8 - T4 - 1.0) * rc - (2.0 / 3.0) * QMFACTORCVfinal * pow(-(qm + qdep), -1.0 / 3.0); + e2 = -1.0 / (qm * qm) - (2.0 / 9.0) * QMFACTORCVfinal * pow(-(qm + qdep), -4.0/3.0); + qm = qm - (e0 / e1) * (1.0 + (e0 * e2) / (2.0 * e1 * e1)); + T8 = (qm * ALPHA_UFCM + qdep) * rc; + T4 = T8 / (exp(T8) - T8 - 1.0); + T5 = T8 * T4; + e0 = F0 - qm + ln(-qm) + ln(T5) + QMFACTORCVfinal * pow(-(qm + qdep), 2.0 / 3.0); + e1 = -1.0 + 1.0 / qm + (2.0 / T8 - T4 - 1.0) * rc - (2.0 / 3.0) * QMFACTORCVfinal * pow(-(qm + qdep), -1.0/3.0); + e2 = -1.0 / (qm * qm) - (2.0 / 9.0) * QMFACTORCVfinal * pow(-(qm + qdep), -4.0/3.0); + qm = qm - (e0 / e1) * (1.0 + (e0 * e2) / (2.0 * e1 * e1)); + end else begin + qm = -qm * qm; + end + qis = -qm * nVtm; + + // Drain Saturation Voltage + Eeffs = EeffFactor * (qbs + eta_mu * qis); + qb0 = 1.0e-2 / cox; + T2 = pow(0.5 * (1.0 + abs((qis) / qb0)), UCS_t); + if (BULKMOD != 0) begin + T3 = (UA_a + UC_a * veseff) * pow(abs(Eeffs), EU_a) + UD_a / T2; + end else begin + T3 = UA_a * pow(abs(Eeffs), EU_a) + UD_a / T2; + end + Dmobs = 1.0 + T3; + Dmobs = Dmobs / U0MULT; + + if (RDSMOD == 1) begin + Rdss = 0.0; + end else if (RDSMOD == 0) begin + T4 = 1.0 + PRWGS_i * qis; + T1 = 1.0 / T4; + T0 = 0.5 * (T1 + sqrt(T1 * T1 + 0.01)); + Rdss = (RDSWMIN_i + RDSW_i * T0) * WeffWRFactor * NFINtotal * rdstemp; + end else begin + T4 = 1.0 + PRWGS_i * qis; + T1 = 1.0 / T4; + T0 = 0.5 * (T1 + sqrt(T1 * T1 + 0.01)); + Rdss = (RSourceGeo + RDrainGeo + RDSWMIN_i + RDSW_i * T0) * WeffWRFactor * NFINtotal * rdstemp; + end + + Esat = 2.0 * VSAT_a / u0_a * Dmobs; + EsatL = Esat * Leff; + T6 = KSATIV_a * (qis + 2 * Vtm); + + if (Rdss == 0.0) begin + Vdsat = EsatL * T6 / (EsatL + T6); + end else begin + WVCox = Weff0 * VSAT_a * cox; + T0 = WVCox * Rdss; + Ta = 2.0 * T0; + Tb = T6 + EsatL + 3.0 * T6 * T0; + Tc = T6 * (EsatL + 2.0 * T6 * T0); + Vdsat = (Tb - sqrt(Tb * Tb - 2.0 * Ta * Tc)) / Ta; + end + Vdsat = hypsmooth(Vdsat - 1.0e-3, 1.0e-5) + 1.0e-3; + T7 = pow(vds / Vdsat , MEXP_a); + T8 = pow(1.0 + T7, inv_MEXP); + Vdseff = vds / T8; + + if (Vdseff > vds) begin + Vdseff = vds; + end + + // Core Model Calculation at Drain Side + vch = Vdseff + dvch_qm; + + if (BULKMOD != 0) begin + T1 = hypsmooth(2.0 * phib + vch - ves, 0.1); + T3 = (-K1_t / (2.0 * nVtm)) * (sqrt(T1) - sqrt(2.0 * phib)); + T0 = -qdep - T3 + vth_fixed_factor_Sub + QMFACTORCVfinal * pow(-qdep, 2.0 / 3.0); + T1 = -qdep - T3 + vth_fixed_factor_SI; + end else begin + T0 = -qdep + vth_fixed_factor_Sub + QMFACTORCVfinal * pow(-qdep, 2.0 / 3.0); + T1 = -qdep + vth_fixed_factor_SI; + end + T2 = (vgsfbeff - vch) / nVtm; + F0 = -T2 + T1; + T3 = (T2 - T0) * 0.5; + qm = exp(T3); + if (qm > 1.0e-7) begin + T7 = ln(1.0 + qm); + qm = 2.0 * (1.0 - sqrt(1.0 + T7 * T7)); + T8 = (qm * ALPHA_UFCM + qdep) * rc; + T4 = T8 / (exp(T8) - T8 - 1.0); + T5 = T8 * T4; + e0 = F0 - qm + ln(-qm) + ln(T5) + QMFACTORCVfinal * pow(-(qm + qdep), 2.0 / 3.0); + e1 = -1.0 + (1.0 / qm) + (2.0 / T8 - T4 - 1.0) * rc - (2.0 / 3.0) * QMFACTORCVfinal * pow(-(qm + qdep), -1.0 / 3.0); + e2 = -1.0 / (qm * qm) - (2.0 / 9.0) * QMFACTORCVfinal * pow(-(qm + qdep), -4.0 / 3.0); + qm = qm - (e0 / e1)*(1.0 + (e0 * e2) / (2.0 * e1 * e1)); + T8 = (qm * ALPHA_UFCM + qdep) * rc; + T4 = T8 / (exp(T8) - T8 - 1.0); + T5 = T8 * T4; + e0 = F0 - qm + ln(-qm) + ln(T5) + QMFACTORCVfinal * pow(-(qm + qdep), 2.0/3.0); + e1 = -1.0 + (1.0 / qm) + (2.0 / T8 - T4 - 1.0) * rc - (2.0 / 3.0) * QMFACTORCVfinal * pow(-(qm + qdep), -1.0 / 3.0); + e2 = -1.0 / (qm * qm) - (2.0 / 9.0) * QMFACTORCVfinal * pow(-(qm + qdep), -4.0 / 3.0); + qm = qm - (e0 / e1) * (1.0 + (e0 * e2) / (2.0 * e1 * e1)); + end else begin + qm = -qm * qm; + end + qid = -qm * nVtm; + + if (BULKMOD != 0) begin + T9 = (K1_t / (2.0 * nVtm)) * sqrt(Vtm); + T0 = T9 / 2.0; + T2 = (vge - (deltaPhi - Eg - Vtm * ln(NBODY / Nc) + DELVFBACC)) / Vtm; + if ((T2 * Vtm) > phib + T9 * sqrt(phib * Vtm)) begin + T1 = sqrt(T2 - 1.0 + T0 * T0) - T0; + T10 = 1.0 + T1 * T1; + end else begin + T3 = T2 * 0.5 - 3.0 * (1.0 + T9 / sqrt(2.0)); + T10 = T3 + sqrt(T3 * T3 + 6.0 * T2); + if (T2 < 0.0) begin + T4 = (T2 - T10) / T9; + T10 = -ln(1.0 - T10 + T4 * T4 ); + end else begin + T11 = exp(-T10); + T4 = sqrt(T2 - 1.0 + T11 + T0 * T0) - T0; + T10 = 1.0 - T11 + T4 * T4; + end + end + T6 = exp(-T10) - 1.0; + T7 = sqrt(T6 + T10); + if (T10 > 1.0e-15) begin + e0 = -(T2 - T10) + T9 * T7; + e1 = 1.0 - T9 * 0.5 * T6 / T7; + T8 = T10 - (e0 / e1); + T11 = exp(-T8) - 1.0; + T12 = sqrt(T11 + T8); + qba = -T9 * T12 * Vtm; + end else begin + if (T10 < -1.0e-15) begin + e0 = -(T2 - T10) - T9 * T7; + e1 = 1.0 + T9 * 0.5 * T6 / T7; + T8 = T10 - e0 / e1; + T12 = T9 * sqrt(exp(-T8) + T8 - 1.0); + end else begin + T12 = 0.0; + T8 = 0.0; + end + qba = T12 * Vtm; + end + qi_acc_for_QM = T9 * exp(-T8 / 2.0) * Vtm; + + psipclamp = 0.5 * (T8 + 1.0 + sqrt((T8 - 1.0) * (T8 - 1.0) + 0.25 * 2.0 * 2.0)); + sqrtpsip = sqrt(psipclamp); + nq = 1.0 + T9 / sqrtpsip; + end + + // Drain Side and Average Potential / Charge + qia = 0.5 * (qis + qid); + dqi = qis - qid; + + T0 = pow(Vdseff, 2.0) / 6.25e-4; // pow(Vdseff,2.0) / pow(25e-3, 2.0) + if (CHARGEWF != 0.0) + qia2 = 0.5 * (qis + qid) + CHARGEWF * (1.0 - lexp(-T0)) * 0.5 * dqi; + else + qia2 = 0.5 * (qis + qid); + + `ifdef __DEBUG__ + if (qis < 0.0) $strobe("Warning: negative source-side inversion carrier density. Vgs=%f Vds=%f Vbs=%f qis=%e", V(g, s), V(d, s), V(e, s), qis); + if (qid < 0.0) $strobe("Warning: negative drain-side inversion carrier density. Vgs=%f Vds=%f Vbs=%f qid=%e", V(g, s), V(d, s), V(e, s), qid); + `endif + + // Toxeff model for quantum mechanical effects + // Normal operation (Vgs > Vfb) + if (QMTCENCV_i > 0.0) begin + T4 = qia / QM0; + T5 = 1.0 + pow(T4, PQM); + Tcen = Tcen0 / T5; + coxeff = 1.0 / (1.0 / (cox * EOT / TOXP) + Tcen * QMTCENCV_i / epssub); + end else begin + coxeff = cox; + end + + // Quantum Mechanical Effect Correction for Accumulation Side Cap (Vgs < Vfb) + if (BULKMOD != 0 && QMTCENCVA_i != 0.0) begin + T6 = 1.0 + pow(qi_acc_for_QM / QM0ACC, PQMACC); + Tcen = Tcen0 / T6; + cox_acc = 1.0 / (1.0 / cox_acc + Tcen * QMTCENCVA_i / epssub); + end + + // Multiplication Factor for I-V + beta = u0_a * cox * Weff0 / Leff; + + // Mobility Degradation + Eeffm = EeffFactor * (qba + eta_mu * qia2); + T2 = pow(0.5 * (1.0 + abs((qia2) / qb0)), UCS_t); + if (BULKMOD != 0) begin + T3 = (UA_a + UC_a * veseff) * pow(abs(Eeffm), EU_a) + UD_a / T2; + end else begin + T3 = UA_a * pow(abs(Eeffm), EU_a) + UD_a / T2; + end + Dmob = 1.0 + T3; + Dmob = Dmob / U0MULT; + ueff = u0_a / Dmob; + + // Mobility Degradation for C-V + Eeffm_cv = EeffFactor * (qba + eta_mu_cv * qia2); + T3 = UA_a * pow(abs(Eeffm_cv), EU_a) + UD_a / T2; + Dmob_cv = 1.0 + T3; + Dmob_cv = Dmob_cv / U0MULT; + + // Calculate current and capacitance enhancement factors due to CLM and DIBL + tmp = DROUT_i * Leff / scl + 1.0e-6; + + if (tmp < 40.0) begin + DIBLfactor = 0.5 * PDIBL1_a / (cosh(tmp) - 1.0) + PDIBL2_a; + end else begin + DIBLfactor = PDIBL1_a * exp(-tmp) + PDIBL2_a; + end + + if (PVAG_i > 0.0) begin + PVAGfactor = 1.0 + PVAG_i * qia / EsatL; + end else begin + PVAGfactor = 1.0 / (1.0 - PVAG_i * qia / EsatL); + end + + if (Vdseff > vds) begin + Vdseff = vds; + end + diffVds = vds - Vdseff; + Vgst2Vtm = qia + 2.0 * Vtm; + if (DIBLfactor > 0) begin + T1 = Vgst2Vtm; + T3 = T1 / (Vdsat + T1); + VaDIBL = T1 / DIBLfactor * T3 * PVAGfactor; + Moc = 1.0 + diffVds / VaDIBL; + end else begin + Moc = 1.0; + end + + if (PCLM_a > 0.0) begin + if (PCLMG_i < 0.0) begin + T1 = 1.0 / (1.0 / PCLM_a - PCLMG_i * qia); + end else begin + T1 = PCLM_a + PCLMG_i * qia; + end + Mclm = 1.0 + T1 * lln(1.0 + (vds - Vdseff) / T1 / (Vdsat + EsatL)); + end else begin + Mclm = 1.0; + end + + Moc = Moc * Mclm; + + // Current Degradation Factor Due to Velocity Saturation + Esat1 = 2.0 * VSAT1_a / ueff; + Esat1L = Esat1 * Leff; + T0 = lexp(PSAT_i * lln(dqi / Esat1L)); + Ta = (1.0 + lexp(1.0 / PSAT_i * lln(DELTAVSAT_i))); + Dvsat = (1.0 + lexp(1.0 / PSAT_i * lln(DELTAVSAT_i + T0))) / Ta; + Dvsat = Dvsat + 0.5 * PTWG_a * qia * dqi * dqi; + + // Non-Saturation Effect + T0 = A1_t + A2_t / (qia + 2.0 * nVtm); + T1 = T0 * dqi * dqi; + T2 = T1 + 1.0 - 0.001; + T3 = -1.0 + 0.5 * (T2 + sqrt(T2 * T2 + 0.004)); // max(T1, -1.0) + Nsat = 0.5 * (1.0 + sqrt(1.0 + T3)); + Dvsat = Dvsat * Nsat; + + // Lateral Non-uniform doping effect (IV-CV Vth shift) factor + if (K0_t != 0) begin + T1 = K0_t / (max(0, K0SI_t + K0SISAT_t * dqi * dqi) * qia + 2.0 * nVtm); + Mnud = lexp(-T1); + end else begin + Mnud = 1.0; + end + + // Body-Effect Factor for BULKMOD = 2 + if (BULKMOD == 2) begin + T0 = hypsmooth((K2_t + K2SAT_t * vdsx), 1.0e-6); + T1 = T0 / (max(0, K2SI_t + K2SISAT_t * dqi * dqi) * qia + 2.0 * nVtm); + T3 = sqrt(PHIBE_i - veseff) - sqrt(PHIBE_i); + Mob = lexp(- T1 * T3); + end else + Mob = 1.0; + + // Velocity Saturation Factor for C-V + EsatCV = 2.0 * VSATCV_t * Dmob_cv / u0_a; + EsatCVL = EsatCV * LeffCV; + T0 = lexp(PSATCV_i * lln(dqi / EsatCVL)); + Ta = (1.0 + lexp(1.0 / PSATCV_i * lln(DELTAVSATCV_i))); + DvsatCV = (1.0 + lexp(1.0 / PSATCV_i * lln(DELTAVSATCV_i + T0))) / Ta; + + // Channel Length Modulation factor for C-V + if (PCLMCV_i != 0) begin + MclmCV = 1.0 + PCLMCV_i * lln(1.0 + (vds - Vdseff) / PCLMCV_i / (Vdsat + EsatCVL)); + end else begin + MclmCV = 1.0; + end + + // Calculating fixed body charge qb with sign (Here to avoid multiple calculation in NQSMOD=3 case) + qb = -`q * nbody * Ach * LeffCV; + + // ************************************************ + // * Current and Charges Calculations * + // ************************************************ + // Quasi Static I-V Model + T1 = qia; + etaiv = q0 / (q0 + qia); + T2 = (2.0 - etaiv) * nVtm; + ids0_ov_dqi = T1 + T2; + ids0 = ids0_ov_dqi * dqi; + + // S/D Series Resistance + `include "bsimcmg_rdsmod.include" + + ids = NFINtotal * beta * ids0 * Moc * Mnud * Mob / (Dmob * Dvsat * Dr); + ids = ids * IDS0MULT; + + // Quasi Static C-V Model + `include "bsimcmg_quasi_static_cv.include" + + // Parasitic Capacitances + // Bias-dependent overlap capacitances (CGEOMOD = 0 and 2) + qgs_ov = 0.0; + qgd_ov = 0.0; + if (CGEOMOD != 1) begin + T1 = NFINtotal * WeffCV0 * devsign; + T2 = devsign * V(`GateEdgeNode, si); + T0 = T2 - vfbsdcv + `DELTA_1; + vgs_overlap = 0.5 * (T0 - sqrt(T0 * T0 + 4.0 * `DELTA_1)); + qgs_ov = T1 * (CGSL_i * (T2 - vfbsdcv - vgs_overlap - 0.5 * CKAPPAS_i * (sqrt(1.0 - 4.0 * vgs_overlap / CKAPPAS_i) - 1.0)) + CGSO_i * T2); + T2 = devsign * V(`GateEdgeNode, di); + T0 = T2 - vfbsdcv + `DELTA_1; + vgd_overlap = 0.5 * (T0 - sqrt(T0 * T0 + 4.0 * `DELTA_1)); + qgd_ov = T1 * (CGDL_i * (T2 - vfbsdcv - vgd_overlap - 0.5 * CKAPPAD_i * (sqrt(1.0 - 4.0 * vgd_overlap / CKAPPAD_i) - 1.0)) + CGDO_i * T2); + end + + if (CGEOMOD == 0) begin + T1 = NFINtotal * WeffCV0; // Fringe caps dont see QM effects + qgs_fr = T1 * CFS_i * V(`GateEdgeNode, si); + qgd_fr = T1 * CFD_i * V(`GateEdgeNode, di); + qgs_parasitic = qgs_ov + qgs_fr; + qgd_parasitic = qgd_ov + qgd_fr; + end else if (CGEOMOD == 1) begin // CGEO1SW=1 enables parameters to be in F per fin, per gate-finger, per unit channel width + if (CGEO1SW == 1) begin + T0 = NFINtotal * WeffCV0; + COVS_i = T0 * COVS_i; + COVD_i = T0 * COVD_i; + cgsp = T0 * CGSP; + cgdp = T0 * CGDP; + end else begin + cgsp = CGSP; + cgdp = CGDP; + end + qgs_ov = COVS_i * V(`GateEdgeNode, si); + qgd_ov = COVD_i * V(`GateEdgeNode, di); + qgs_parasitic = qgs_ov; + qgd_parasitic = qgd_ov; + qgs_fr = cgsp * V(`GateEdgeNode, s); + qgd_fr = cgdp * V(`GateEdgeNode, d); + end else begin + qgs_fr = Cfr_geo * V(`GateEdgeNode, si); + qgd_fr = Cfr_geo * V(`GateEdgeNode, di); + qgs_parasitic = qgs_ov + qgs_fr; + qgd_parasitic = qgd_ov + qgd_fr; + end + + // Drain-to-Source Fringe Capacitance Available for all CGEOMOD + qds_fr = CDSP * V(d, s); + + // Impact Ionization Current (Ref: IIMOD = 1 from BSIM4 Model, IIMOD = 2 from BSIMSOI Model) + Iii = 0.0; + if (IIMOD == 1) begin + T0 = (ALPHA0_t + ALPHA1_t * Leff) / Leff; + if ((T0 <= 0.0) || (BETA0_t <= 0.0)) + Iii = 0.0; + else begin + T1 = -BETA0_t / (diffVds + 1.0e-30); + Iii = T0 * diffVds * ids * lexp(T1); + end + end else if (IIMOD == 2) begin //End of IIMOD=1 + ALPHAII = (ALPHAII0_t + ALPHAII1_t * Leff) / Leff; + if (ALPHAII <= 0.0) begin + Iii = 0.0; + end else begin + T0 = ESATII_i * Leff; + T1 = SII0_t * T0 / (1.0 + T0); + T0 = 1.0 / (1.0 + hypsmooth(SII1_i * vgsfbeff, IIMOD2CLAMP1)); // T0 = 1 / (1 + SII1_i * vgsfbeff) + T3 = T0 + SII2_i; + T2 = hypsmooth(vgsfbeff * T3, IIMOD2CLAMP2); // T2 = vgsfbeff * T3 + T3 = 1.0 / (1.0 + SIID_i * vds); + VgsStep = T1 * T2 * T3; + Vdsatii = VgsStep * (1.0 - LII_i / Leff); + Vdiff = vds - Vdsatii; + T0 = BETAII2_i + BETAII1_i * Vdiff + BETAII0_i * Vdiff * Vdiff; + T1 = sqrt(T0 * T0 + 1.0e-10); + Ratio = -hypmax( -ALPHAII * lexp(Vdiff / T1), -10.0, IIMOD2CLAMP3); + Iii = Ratio * ids; + end + end // End of IIMOD=2 + + // Gate Current (Ref: BSIM4 Model) + igbinv = 0.0; + igbacc = 0.0; + igcs = 0.0; + igcd = 0.0; + igs = 0.0; + igd = 0.0; + + // Igb + if (IGBMOD != 0) begin + // Igbinv + T1 = (qia - EIGBINV_i) / NIGBINV_i / Vtm; + Vaux_Igbinv = NIGBINV_i * Vtm * lln(1.0 + lexp(T1)); + T2 = AIGBINV_t - BIGBINV_i * qia; + T3 = 1.0 + CIGBINV_i * qia; + T4 = -9.82222e11 * TOXG * T2 * T3; + T5 = lexp(T4); + T6 = 3.75956e-7; + igbinv = Weff0 * Leff * T6 * Toxratio * vge * Vaux_Igbinv * T5; + igbinv = igbinv * igtemp; + + // Igbacc + vfbzb = deltaPhi - (Eg / 2.0) - phib; + T0 = vfbzb - vge; + T1 = T0 / NIGBACC_i / Vtm; + Vaux_Igbacc = NIGBACC_i * Vtm * lln(1.0 + lexp(T1)); + if (BULKMOD != 0) begin + Voxacc = qi_acc_for_QM; + end else begin + if (vfbzb <= 0) + Voxacc = 0.5 * (T0 - 0.02 + sqrt((T0 - 0.02) * (T0 - 0.02) - 0.08 * vfbzb)); + else + Voxacc = 0.5 * (T0 - 0.02 + sqrt((T0 - 0.02) * (T0 - 0.02) + 0.08 * vfbzb)); + end + T2 = AIGBACC_t - BIGBACC_i * Voxacc; + T3 = 1.0 + CIGBACC_i * Voxacc; + T4 = -7.45669e11 * TOXG * T2 * T3; + T5 = lexp(T4); + T6 = 4.97232e-7; + igbacc = Weff0 * Leff * T6 * Toxratio * vge * Vaux_Igbacc * T5; + igbacc = igbacc * igtemp; + + end + + if (IGCMOD != 0) begin + // Igcinv + T1 = AIGC_t - BIGC_i * qia; + T2 = 1.0 + CIGC_i * qia; + T3 = -Bechvb * TOXG * T1 * T2; + T4 = qia * lexp(T3); + T5 = (vge + 0.5 * vdsx + 0.5 * (ves_jct + ved_jct)); + igc0 = Weff0 * Leff * Aechvb * Toxratio * T4 * T5 * igtemp; + + // Gate-Current Partitioning + Vdseffx = sqrt(Vdseff * Vdseff + 0.01) - 0.1; + T1 = PIGCD_i * Vdseffx; + T1_exp = lexp(-T1); + T3 = T1 + T1_exp - 1.0 + 1.0e-4; + T4 = 1.0 - (T1 + 1.0) * T1_exp + 1.0e-4; + T5 = T1 * T1 + 2.0e-4; + igcd = igc0 * T4 / T5; + igcs = igc0 * T3 / T5; + + // Igs + T0 = vgs_noswap - vfbsd; + vgs_eff = sqrt(T0 * T0 + 1.0e-4); + if (IGCLAMP == 1) begin + T1 = hypsmooth((AIGS_t - BIGS_i * vgs_eff), 1.0e-6); + if (CIGS_i < 0.01) begin + CIGS_i = 0.01; + end + end else begin + T1 = AIGS_t - BIGS_i * vgs_eff; + end + T2 = 1.0 + CIGS_i * vgs_eff; + T3 = -Bechvb * TOXG * POXEDGE_i * T1 * T2; + T4 = lexp(T3); + if (sigvds > 0.0) begin + igs = igsd_mult * DLCIGS * vgs_noswap * vgs_eff * T4; + end else begin + igd = igsd_mult * DLCIGS * vgs_noswap * vgs_eff * T4; + end + + // Igd + T0 = vgd_noswap - vfbsd; + vgd_eff = sqrt(T0 * T0 + 1.0e-4); + if (IGCLAMP == 1) begin + T1 = hypsmooth((AIGD_t - BIGD_i * vgd_eff), 1.0e-6); + if (CIGD_i < 0.01) begin + CIGD_i = 0.01; + end + end else begin + T1 = AIGD_t - BIGD_i * vgd_eff; + end + T2 = 1.0 + CIGD_i * vgd_eff; + T3 = -Bechvb * TOXG * POXEDGE_i * T1 * T2; + T4 = lexp(T3); + + if (sigvds > 0.0) begin + igd = igsd_mult * DLCIGD * vgd_noswap * vgd_eff * T4; + end else begin + igs = igsd_mult * DLCIGD * vgd_noswap * vgd_eff * T4; + end + end + + // GIDL/GISL Current (Ref: BSIM4 Model) + igisl = 0.0; + igidl = 0.0; + + if (GIDLMOD != 0) begin + T0 = epsratio * EOT; + // GIDL + if ((AGIDL_i <= 0.0) || (BGIDL_t <= 0.0)) begin + T6 = 0.0; + end else begin + T1 = (-vgd_noswap - EGIDL_i + vfbsd) / T0; + T1 = hypsmooth(T1, 1.0e-2); + T2 = BGIDL_t / (T1 + 1.0e-3); + T3 = lexp(PGIDL_i * lln(T1)); + if (BULKMOD != 0) begin + T4 = -ved_jct*ved_jct*ved_jct; + T4a = CGIDL_i + abs(T4) + 1.0e-5; + T5 = hypsmooth(T4/T4a, 1.0e-6) - 1.0e-6; + T6 = AGIDL_i * Weff0 * T3 * lexp(-T2) * T5; + end else begin + T6 = AGIDL_i * Weff0 * T3 * lexp(-T2) * vds_noswap; + end + end + + if (sigvds > 0.0) begin + igidl = T6; + end else begin + igisl = T6; + end + + // GISL + if ((AGISL_i <= 0.0) || (BGISL_t <= 0.0)) begin + T6 = 0.0; + end else begin + T1 = (-vgs_noswap - EGISL_i + vfbsd) / T0; + T1 = hypsmooth(T1, 1.0e-2); + T2 = BGISL_t / (T1 + 1.0e-3); + T3 = lexp(PGISL_i * lln(T1)); + if (BULKMOD != 0) begin + T4 = -ves_jct * ves_jct * ves_jct; + T4a = CGISL_i + abs(T4) + 1.0e-5; + T5 = hypsmooth(T4/T4a, 1.0e-6) - 1.0e-6; + T6 = AGISL_i * Weff0 * T3 * lexp(-T2) * T5; + end else + T6 = AGISL_i * Weff0 * T3 * lexp(-T2) * (-vds_noswap); + end + + if (sigvds > 0.0) begin + igisl = T6; + end else begin + igidl = T6; + end + + end // End of GIDLMOD + + // Junction Current + if (BULKMOD != 0) begin + // Source-Side Junction Current + if (Isbs > 0.0) begin + if (ves_jct < VjsmRev) begin + T0 = ves_jct / Nvtms; + T1 = lexp(T0) - 1.0; + T2 = IVjsmRev + SslpRev * (ves_jct - VjsmRev); + Ies = T1 * T2; + end else if (ves_jct <= VjsmFwd) begin + T0 = ves_jct / Nvtms; + T1 = (BVS + ves_jct) / Nvtms; + T2 = lexp(-T1); + Ies = Isbs * (lexp(T0) + XExpBVS - 1.0 - XJBVS * T2); + end else begin + Ies = IVjsmFwd + SslpFwd * (ves_jct - VjsmFwd); + end + end else begin + Ies = 0.0; + end + + // Source-Side Junction Tunneling Current + if (JTSS_t > 0.0) begin + if ((VTSS - ves_jct) < (VTSS * 1.0e-3)) begin + T0 = -ves_jct / Vtm0 / NJTS_t; + T1 = lexp(T0 * 1.0e3) - 1.0; + Ies = Ies - ASEJ * JTSS_t * T1; + end else begin + T0 = -ves_jct / Vtm0 / NJTS_t; + T1 = lexp(T0 * VTSS / (VTSS - ves_jct)) - 1.0; + Ies = Ies - ASEJ * JTSS_t * T1; + end + end + + if (JTSSWS_t > 0.0) begin + if ((VTSSWS - ves_jct) < (VTSSWS * 1.0e-3)) begin + T0 = -ves_jct / Vtm0 / NJTSSW_t; + T1 = lexp(T0 * 1.0e3) - 1.0; + Ies = Ies - PSEJ * JTSSWS_t * T1; + end else begin + T0 = -ves_jct / Vtm0 / NJTSSW_t; + T1 = lexp(T0 * VTSSWS / (VTSSWS - ves_jct)) - 1.0; + Ies = Ies - PSEJ * JTSSWS_t * T1; + end + end + + if (JTSSWGS_t > 0.0) begin + if ((VTSSWGS - ves_jct) < (VTSSWGS * 1.0e-3)) begin + T0 = -ves_jct / Vtm0 / NJTSSWG_t; + T1 = lexp(T0 * 1.0e3) - 1.0; + Ies = Ies - Weff0 * NFINtotal * JTSSWGS_t * T1; + end else begin + T0 = -ves_jct / Vtm0 / NJTSSWG_t; + T1 = lexp(T0 * VTSSWGS / (VTSSWGS - ves_jct)) - 1.0; + Ies = Ies - Weff0 * NFINtotal * JTSSWGS_t * T1; + end + end + + // Drain-Side Junction Current + if (Isbd > 0.0) begin + if (ved_jct < VjdmRev) begin + T0 = ved_jct / Nvtmd; + T1 = lexp(T0) - 1.0; + T2 = IVjdmRev + DslpRev * (ved_jct - VjdmRev); + Ied = T1 * T2; + end else if (ved_jct <= VjdmFwd) begin + T0 = ved_jct / Nvtmd; + T1 = (BVD + ved_jct) / Nvtmd; + T2 = lexp(-T1); + Ied = Isbd * (lexp(T0) + XExpBVD - 1.0 - XJBVD * T2); + end else + Ied = IVjdmFwd + DslpFwd * (ved_jct - VjdmFwd); + end else + Ied = 0.0; + + // Drain-Side Junction Tunneling Current + if (JTSD_t > 0.0) begin + if ((VTSD - ved_jct) < (VTSD * 1.0e-3)) begin + T0 = -ved_jct / Vtm0 / NJTSD_t; + T1 = lexp(T0 * 1.0e3) - 1.0; + Ied = Ied - ADEJ * JTSD_t * T1; + end else begin + T0 = -ved_jct / Vtm0 / NJTSD_t; + T1 = lexp(T0 * VTSD/ (VTSD - ved_jct)) - 1.0; + Ied = Ied - ADEJ * JTSD_t * T1; + end + end + if (JTSSWD_t > 0.0) begin + if ((VTSSWD - ved_jct) < (VTSSWD * 1.0e-3)) begin + T0 = -ved_jct / Vtm0 / NJTSSWD_t; + T1 = lexp(T0 * 1.0e3) - 1.0; + Ied = Ied - PDEJ * JTSSWD_t * T1; + end else begin + T0 = -ved_jct / Vtm0 / NJTSSWD_t; + T1 = lexp(T0 * VTSSWD / (VTSSWD - ved_jct)) - 1.0; + Ied = Ied - PDEJ * JTSSWD_t * T1; + end + end + if (JTSSWGD_t > 0.0) begin + if ((VTSSWGD - ved_jct) < (VTSSWGD * 1.0e-3)) begin + T0 = -ved_jct / Vtm0 / NJTSSWGD_t; + T1 = lexp(T0 * 1.0e3) - 1.0; + Ied = Ied - Weff0 * NFINtotal * JTSSWGD_t * T1; + end else begin + T0 = -ved_jct / Vtm0 / NJTSSWGD_t; + T1 = lexp(T0 * VTSSWGD / (VTSSWGD - ved_jct)) - 1.0; + Ied = Ied - Weff0 * NFINtotal * JTSSWGD_t * T1; + end + end + + // Junction Capacitance (No Swapping) + // Source-Substrate Junction + `BSIM6JunctnCap(ves_jct, Czbs, PBS_t, SJS, MJS, MJS2, Qesj1) + `BSIM6JunctnCap(ves_jct, Czbssw, PBSWS_t, SJSWS, MJSWS, MJSWS2, Qesj2) + `BSIM6JunctnCap(ves_jct, Czbsswg, PBSWGS_t, SJSWGS, MJSWGS, MJSWGS2, Qesj3) + Qesj = Qesj1 + Qesj2 + Qesj3; + + // Drain-Substrate Junction + `BSIM6JunctnCap(ved_jct, Czbd, PBD_t, SJD, MJD, MJD2, Qedj1) + `BSIM6JunctnCap(ved_jct, Czbdsw, PBSWD_t, SJSWD, MJSWD, MJSWD2, Qedj2) + `BSIM6JunctnCap(ved_jct, Czbdswg, PBSWGD_t, SJSWGD, MJSWGD, MJSWGD2, Qedj3) + Qedj = Qedj1 + Qedj2 + Qedj3; + + end // BULKMOD=0 + + Qes = Qesj + csbox * ves_jct; + Qed = Qedj + cdbox * ved_jct; + + // Gate-to-Substrate Parasitic Capacitance + // Bias Independent Component + Qeg = cgbox * devsign * V(e, `GateEdgeNode); + if (BULKMOD != 0) begin + // Bias Dependent Component + T2 = devsign * V(`GateEdgeNode, e); + T3 = T2 - deltaPhi + Eg / 2.0 + phib - DELVFBACC; + T0 = T3 + `DELTA_1; + vge_overlap = 0.5 * (T0 + sqrt(T0 * T0 + 4.0 * `DELTA_1)); + Qeg = Qeg - NFINtotal * LeffCV * (CGBL_i * (T3 - vge_overlap + 0.5 * CKAPPAB_i * ( sqrt(1.0 + 4.0 * vge_overlap / CKAPPAB_i) - 1.0 ))); + end + + // Generation-Recombination Component + T0 = vds; + T1 = T0 * (AIGEN_i + BIGEN_i * T0 * T0); + idsgen = HFIN * TFIN * (Leff - 2.0 * LINTIGEN_i) * igentemp * T1; + + // NQS Gate Resistance (Ref: BSIM4 Model) + T0 = ueff * coxeff * Weff0 / Leff; + + `ifdef __NQSMOD1__ + if (NQSMOD == 1 && XRCRG1_i != 0) begin + IdovVds = beta * ids0_ov_dqi * Moc / (Dmob * Dvsat * Dr); + gcrg = NFINtotal * XRCRG1_i * (IdovVds + XRCRG2_i * Vtm * T0); + end + `endif + + `ifdef __NQSMOD2__ + if (NQSMOD == 2) begin + IdovVds = beta * ids0_ov_dqi * Moc / (Dmob * Dvsat * Dr); + gcrg = NFINtotal * XRCRG1_i * (IdovVds + XRCRG2_i * Vtm * T0); + gtau = gcrg / (cox * Weff0 * Leff); + end + `endif + + // *** Multiply all current and charge components by NFINtotal *** + // Note: Do not multiply ids, qg, qs, qd, qb, Ies, Ied, Qbs, Qbd with NFINtotal + // since it is already considered. + + igidl = NFINtotal * igidl; + igisl = NFINtotal * igisl; + igcd = NFINtotal * igcd; + igcs = NFINtotal * igcs; + igs = NFINtotal * igs; + igd = NFINtotal * igd; + igbinv = NFINtotal * igbinv; + igbacc = NFINtotal * igbacc; + idsgen = NFINtotal * idsgen; + + // Gate to Body Tunneling Current Empirical Partition for BULKMOD = 0 + igbs = 0.0; + igbd = 0.0; + if (BULKMOD == 0) begin + igbs = (igbinv + igbacc) * wf; + igbd = (igbinv + igbacc) * wr; + end + + // Noise Models + Esatnoi = 2.0 * VSAT_a / ueff; // Thermal noise and flicker noise + + // Flicker Noise (Ref: BSIM4 Model from K. K. Hung et al. TED 1990) + if (NOIA > 0.0 || NOIB > 0.0 || NOIC > 0.0) begin + Leffnoi = Leff - 2.0 * LINTNOI_i; + Leffnoisq = Leffnoi * Leffnoi; + if (EM <= 0.0) begin + DelClm = 0.0; + end else begin + T0 = (diffVds / litl + EM) / Esatnoi; + DelClm = litl * lln(T0); + if (DelClm < 0.0) begin + DelClm = 0.0; + end + end + T1 = `q * `q * `q * Vtm * abs(ids) * ueff; + T2 = 1.0e10 * coxeff * Leffnoisq; + N0 = coxeff * qis / `q; + Nl = coxeff * qid / `q; + Nstar = Vtm / `q * (coxeff + CIT_a); + T3 = NOIA * lln((N0 + Nstar) / (Nl + Nstar)); + T4 = NOIB * (N0 - Nl); + T5 = 0.5 * NOIC * (N0 * N0 - Nl * Nl); + T6 = `q * Vtm * ids * ids; + T7 = 1.0e10 * Leffnoisq * Weff0 * NFINtotal; + T8 = NOIA + NOIB * Nl + NOIC * Nl * Nl; + T9 = (Nl + Nstar) * (Nl + Nstar); + Ssi = T1 / T2 * (T3 + T4 + T5) + T6 / T7 * DelClm * T8 / T9; + T10 = NOIA * `q * Vtm; + T11 = Weff0 * NFINtotal * Leffnoi * 1.0e10 * Nstar * Nstar; + Swi = T10 / T11 * ids * ids; + T1 = Swi + Ssi; + if (T1 > 0.0) begin + FNPowerAt1Hz = (Ssi * Swi) / T1; + end else begin + FNPowerAt1Hz = 0.0; + end + end else begin + FNPowerAt1Hz = 0.0; + end + + // Thermal Noise + case (TNOIMOD) + 0 : begin // Charge-based model (BSIM4 - TNOIMOD=0) + T0 = ueff * qinv; + T1 = T0 * Rdsi + Leff * Leff; + Gtnoi = (T0 / T1) * NTNOI_i; + sid = 4.0 * Vtm * `q * Gtnoi; + end + 1: begin // Correlated Thermal Noise by Navid, November 2013, Reference BSIMSOI4.5.0 + `ifdef __TNOIMOD1__ + Abulk = 1.0; + Vgst2Vtm = KSATIV_a * (qis + 2.0 * Vtm); + etaa = 1.0 - Vdseff * Abulk / Vgst2Vtm ; + T0 = 1.0 - etaa; + T1 = 1.0 + etaa; + T2 = T1 + 2.0 * Abulk * Vtm / (qia + 1.0e-10); + T3 = T2 * T2; + T4 = T0 * T0; + T5 = T3 * T3; + T6 = 1.0 / (1.0 + Vdseff / EsatL) ; + gamma = T6 * (0.5 * T1 + T0 * T0 / (6.0 * T2)); + delta = ((T1 / T3) - (5.0 * T1 + T2) * T4 / (15.0 * T5) + T4 * T4 / (9.0 * T5 * T2)) / (6.0 * T6 * T6 * T6); + T7 = T0 / T2; + epsilon = (T7 + T7 * T7 * T7 / 3.0) / (6.0 * T6); + T8 = qia / EsatL; + T8 = T8 * T8; + npart_c = RNOIC * (1.0 + T8 * TNOIC * Leff); + T9 = gamma * delta ; + if (T9 > 0.0) begin + ctnoi = epsilon / sqrt( gamma * delta) * (2.5316 * npart_c); + end else begin + ctnoi = 1.0; + end + if (ctnoi > 1) begin + ctnoi = 1.0; + end + if (ctnoi < 0) begin + ctnoi = 0.0; + end + npart_beta = RNOIA * (1.0 + T8 * TNOIA * Leff); + npart_theta = RNOIB * (1.0 + T8 * TNOIB * Leff); + gamma = gamma * (3.0 * npart_beta * npart_beta); + delta = delta * (3.75 * npart_theta * npart_theta); + T9 = qia * 0.5 * T1; + gche = beta * T9 * T6; + noiGd0 = NFINtotal * beta * qia / (1.0 + gche * Rdsi); + GammaGd0 = gamma * noiGd0; + sid = 4.0 * Vtm * `q * GammaGd0; + C0 = NFINtotal * coxeff * WeffCV0 * LeffCV; + if (gamma > 0.0 && delta > 0.0) begin + sf = (noiGd0 + 1.0e-15) / sqrt(delta / gamma); + end else begin + sf = 0.0; + end + `else + $strobe("[Warning!] Although the model selector TNOIMOD is set to 1, the new correlated thermal noise model is not activated. Please uncomment \"`define __TNOIMOD1__\" in the bsimcmg.va."); + `endif + end + endcase + + // Source and Drain Conductance for Thermal Noise Contribution + if (RDSMOD != 2) begin + gspr = 1.0 / Rsource; // Note: gspr considers all fins + gdpr = 1.0 / Rdrain; // Note: gdpr considers all fins + end + + // Loading Ids, Gate and Drain charges + `ifdef __NQSMOD2__ + if (sigvds > 0.0) begin + I(di, si) <+ devsign * ids; + end else begin + I(si, di) <+ devsign * ids; + end + + if (NQSMOD == 2) begin + I(`IntrinsicGate, si) <+ devsign * gtau * -V(q); + I(di, si) <+ devsign * xdpart * gtau * V(q); + end else begin // Quasi-static Stamping (Normal case) + I(di, si) <+ devsign * ddt(qd); + I(`IntrinsicGate, si) <+ devsign * ddt(qg); + end + `else + if (sigvds > 0.0) begin + I(di, si) <+ devsign * ids; + end else begin + I(si, di) <+ devsign * ids; + end + I(di, si) <+ devsign * ddt(qd); + I(`IntrinsicGate, si) <+ devsign * ddt(qg); + `endif + + // Loading Other Currents + if (sigvds > 0.0) begin + I(di, si) <+ devsign * idsgen; + I(`IntrinsicGate, si) <+ devsign * (igcs + igs); + I(`IntrinsicGate, di) <+ devsign * (igcd + igd); + if (BULKMOD != 0) begin + I(di, e) <+ devsign * (igidl + Iii); + I(si, e) <+ devsign * igisl; + I(`IntrinsicGate, e) <+ devsign * (igbinv + igbacc); + end else begin + I(di, si) <+ devsign * (igidl + Iii); + I(si, di) <+ devsign * igisl; + end + end else begin + I(si, di) <+ devsign * idsgen; + I(`IntrinsicGate, di) <+ devsign * (igcs + igs); + I(`IntrinsicGate, si) <+ devsign * (igcd + igd); + if (BULKMOD != 0) begin + I(si, e) <+ devsign * (igidl + Iii); + I(di, e) <+ devsign * igisl; + I(`IntrinsicGate, e) <+ devsign * (igbinv + igbacc); + end else begin + I(si, di) <+ devsign * (igidl + Iii); + I(di, si) <+ devsign * igisl; + end + end + if (BULKMOD == 0) begin + I(`IntrinsicGate, si) <+ devsign * igbs; + I(`IntrinsicGate, di) <+ devsign * igbd; + end + + if (BULKMOD != 0) begin + I(e, si) <+ devsign * Ies; + I(e, di) <+ devsign * Ied; + end + I(e, si) <+ devsign * ddt(Qes); + I(e, di) <+ devsign * ddt(Qed); + I(e, `GateEdgeNode) <+ devsign * ddt(Qeg); + + // Loading other charges + I(`GateEdgeNode, si) <+ ddt(qgs_parasitic); + I(`GateEdgeNode, di) <+ ddt(qgd_parasitic); + I(d, s) <+ ddt(qds_fr); + if (CGEOMOD == 1) begin + I(`GateEdgeNode, s) <+ ddt(qgs_fr); + I(`GateEdgeNode, d) <+ ddt(qgd_fr); + end + + // Accumulation Charge for Bulk FET + if (BULKMOD != 0) begin + I(`IntrinsicGate, si) <+ devsign * ddt(qg_acc); + I(e, si) <+ devsign * ddt(qb_acc); + end + + // External S/D Resistance + if (RDSMOD == 2) begin + V(d, di) <+ 0.0; + V(s, si) <+ 0.0; + end else begin + I(d, di) <+ V(d, di) / Rdrain; + I(s, si) <+ V(s, si) / Rsource; + end + + // NQSMOD1 Gate Resistance Model + `ifdef __NQSMOD1__ + if (NQSMOD == 1 && XRCRG1_i != 0) + I(`GateEdgeNode, gi) <+ V(`GateEdgeNode, gi) * gcrg; + else + V(`GateEdgeNode, gi) <+ 0.0; + `endif + + // NQSMOD2 BSIM4 Charge Deficit Model + `ifdef __NQSMOD2__ + if (NQSMOD ==2) begin + I(q) <+ ddt(qg - qb); + I(q) <+ V(q) * gtau; + I(q) <+ ddt(V(q)); + end else + V(q) <+ 0.0; + `endif + + // Gate Electrode Resistance + `ifdef __RGATEMOD__ + if (RGATEMOD != 0) + I(g, ge) <+ V(g, ge) * ggeltd; + else + V(g, ge) <+ 0.0; + `endif + + // Flicker Noise + I(di,si) <+ flicker_noise(FNPowerAt1Hz, EF, "flicker"); + + // Thermal noise for parasitics + if (RDSMOD != 2) begin + I(d, di) <+ white_noise(4.0 * Vtm * `q * gdpr, "thermal"); + I(s, si) <+ white_noise(4.0 * Vtm * `q * gspr, "thermal"); + end + + `ifdef __RGATEMOD__ + if (RGATEMOD != 0) + I(g, ge) <+ white_noise(4.0 * Vtm * `q * ggeltd, "thermal"); + `endif + + // Channel thermal noise and induced gate noise stamping + // Implementation of correlated noise follows C. C. McAndrew, WCM 2005 + if (TNOIMOD == 0) begin + I(di, si) <+ white_noise(sid, "thermal"); + `ifdef __TNOIMOD1__ + V(N) <+ 0.0; + `endif + end else begin + `ifdef __TNOIMOD1__ + I(di,si) <+ white_noise(sid * abs(1.0 - ctnoi * ctnoi), "thermal"); + I(di,si) <+ ctnoi * V(N) * sf * SCALEN ; + if (gamma > 0 && delta > 0) begin + I(N) <+ V(N) * sf * SCALEN; + I(N) <+ white_noise(sid/(sf*sf*SCALEN*SCALEN)); + end else begin + I(N) <+ V(N) ; + end + I(`IntrinsicGate,si) <+ ddt(0.5 * C0 * SCALEN * V(N)); + I(`IntrinsicGate,di) <+ ddt(0.5 * C0 * SCALEN * V(N)); + `else + $strobe("[Warning!] Although the model selector TNOIMOD is set to 1, the new correlated thermal noise model is not activated. Please uncomment \"`define __TNOIMOD1__\" in the bsimcmg.va."); + `endif + end + + // Gate Current Shot Noise + if (IGCMOD != 0) begin + if (sigvds > 0) begin + I(`IntrinsicGate, si) <+ white_noise(2.0 * `q * abs(igcs + igs), "shot"); + I(`IntrinsicGate, di) <+ white_noise(2.0 * `q * abs(igcd + igd), "shot"); + end else begin + I(`IntrinsicGate, di) <+ white_noise(2.0 * `q * abs(igcs + igs), "shot"); + I(`IntrinsicGate, si) <+ white_noise(2.0 * `q * abs(igcd + igd), "shot"); + end + end + + if (IGBMOD != 0) begin + if (BULKMOD != 0) begin + I(`IntrinsicGate, e) <+ white_noise(2.0 * `q * abs(igbinv + igbacc), "shot"); + end else begin + I(`IntrinsicGate, si) <+ white_noise(2.0 * `q * abs(igbs), "shot"); + I(`IntrinsicGate, di) <+ white_noise(2.0 * `q * abs(igbd), "shot"); + end + end + + // Self Heating + `ifdef __SHMOD__ + if (SHMOD != 0 && RTH0 > 0) begin + if (RDSMOD != 2) begin + Pwr(ith_branch) <+ -(devsign * sigvds * V(di,si) * ids + V(d,di) * V(d,di) / Rdrain + V(s,si) * V(s,si) / Rsource); + end else begin + Pwr(ith_branch) <+ -(devsign * sigvds * V(di,si) * ids ); + end + end + Pwr(rth_branch) <+ Temp(rth_branch) * gth; + Pwr(rth_branch) <+ ddt(Temp(rth_branch) * cth); + `endif + + // Operating-Point information + `ifdef __OPINFO__ + // W & L + WEFF = Weff0; // Effective width for IV + LEFF = Leff; // Effective length for IV + WEFFCV = WeffCV0; // Effective width for CV + LEFFCV = LeffCV; // Effective length for CV + + // Currents + IDS = devsign * ids; // Intrinsic Drain Current (Electrical) + if (sigvds > 0) begin // Total Source/Drain Currents (Physical) + if (BULKMOD != 0) begin + IDEFF = IDS + devsign * idsgen - devsign * (igd + igcd) + devsign * (Iii + igidl) - devsign * Ied; + ISEFF = -IDS - devsign * idsgen - devsign * (igs + igcs) + devsign * (igisl) - devsign * Ies; + end else begin + IDEFF = IDS + devsign * idsgen - devsign * (igd + igcd + igbd) + devsign * (Iii + igidl - igisl); + ISEFF = -IDS - devsign * idsgen - devsign * (igs + igcs + igbs) + devsign* (igisl - igidl); + end + end else begin + if (BULKMOD != 0) begin + IDEFF = -IDS - devsign * idsgen - devsign * (igs + igcs) + devsign * (igisl) - devsign * Ied; + ISEFF = IDS + devsign * idsgen - devsign * (igd + igcd) + devsign * (Iii + igidl) - devsign * Ies; + end else begin + IDEFF = -IDS - devsign * idsgen - devsign * (igs + igcs + igbd) + devsign * (igisl - igidl); + ISEFF = IDS + devsign * idsgen - devsign * (igd + igcd + igbs) + devsign * (Iii + igidl - igisl); + end + end + + if (BULKMOD == 0) begin // Total Gate Current + IGTOT = devsign * (igs + igd + igcs + igcd + igbs + igbd); + end else begin + IGTOT = devsign * (igs + igd + igcs + igcd + igbacc + igbinv); + end + + IDSGEN = sigvds * devsign * idsgen; // Generation-Recombination Current (Physical) + III = devsign * Iii; // Impact Ionization Current + if (sigvds > 0) begin + IGIDL = devsign * igidl; // GIDL Current (Physical) + IGISL = devsign * igisl; // GISL Current (Physical) + end else begin + IGIDL = devsign * igisl; // GIDL Current (Physical) + IGISL = devsign * igidl; // GISL Current (Physical) + end + + if (BULKMOD != 0) begin + IJSB = -devsign * Ies; // Source-Body Junction Current (Physical) + IJDB = -devsign * Ied; // Drain-Body Junction Current (Physical) + end else begin + IJSB = 0.0; + IJDB = 0.0; + end + + if (BULKMOD != 0) begin + ISUB = -III - IGIDL - IGISL - IJSB - IJDB - devsign * (igbinv + igbacc); // Substrate Current + end else begin + ISUB = 0.0; + end + + // Misc Variables + BETA = beta; // Drain Current prefactor per fin per finger + VDSSAT = Vdsat; // Drain-Source saturation Voltage + if (NGATE_i > 0) // Flatband Voltage + VFB = -devsign * (phib + Vtm * lln(NGATE_i / ni)); + else + VFB = PHIG_i - (EASUB + 0.5 * Eg + devsign * phib); + + // Threshold Voltage Calculation + q0 = 10.0 * Vtm / rc + 2.0 * qbs; + T1 = Vtm * (Vtm + q0); + T2 = cox * cox * T1; + T3 = 2.0 * `q * ni * epssub * Vtm; + VTH = VFB + devsign * (Vtm * lln(T2 / T3) + dvch_qm + phib + qbs + Vtm + dvth_all - DELVTRAND); + + // Conductances + GM = ddx(devsign * ids,V(`IntrinsicGate)); // Transconductance + GDS = ddx(devsign * ids,V(di)); // Output Conductance + if (BULKMOD != 0) + GMBS = ddx(devsign * ids,V(e)); // Body Transconductance + else + GMBS = 0.0; + + // Intrinsic Charges (Physical) (Sriram: Not accurate for NQSMOD= 2 and 3) + QGI = devsign * qg + devsign * qg_acc; + QDI = devsign * qd; + QSI = devsign * qs; + QBI = devsign * (qb + qb_acc); + + // Total Charges (Sriram: Not accurate for NQSMOD= 2 and 3) + QG = devsign * qg + qgs_parasitic + qgd_parasitic + (CGEOMOD == 1 ? qgs_fr + qgd_fr : 0) + devsign * qg_acc - devsign * Qeg; + QD = devsign * qd - qgd_parasitic - (CGEOMOD == 1 ? qgd_fr : 0) - devsign * Qed; + QS = devsign * qs - qgs_parasitic - (CGEOMOD == 1 ? qgs_fr : 0) - devsign * Qes; + QB = devsign * (qb + qb_acc) + devsign * (Qeg + Qes + Qed); + + // Intrinsic Capacitances (Physical) + CGGI = ddx(QGI, V(`IntrinsicGate)); + CGSI = ddx(-QGI, V(si)); + CGDI = ddx(-QGI, V(di)); + CGEI = ddx(-QGI, V(e)); + + CSGI = ddx(-QSI, V(`IntrinsicGate)); + CSDI = ddx(-QSI, V(di)); + CSSI = ddx(QSI, V(si)); + CSEI = ddx(-QSI, V(e)); // Should be zero everywhere + + CDGI = ddx(-QDI, V(`IntrinsicGate)); + CDDI = ddx(QDI, V(di)); + CDSI = ddx(-QDI, V(si)); + CDEI = ddx(-QDI, V(e)); + + CEGI = ddx(-QBI, V(`IntrinsicGate)); + CEDI = ddx(-QBI, V(di)); // Should be zero everywhere + CESI = ddx(-QBI, V(si)); // Should be zero everywhere + CEEI = ddx(QBI, V(e)); + + // Total Capacitances + CGG = ddx(QG, V(`IntrinsicGate)); + CGS = ddx(-QG, V(si)); + CGD = ddx(-QG, V(di)); + CGE = ddx(-QG, V(e)); + + CSG = ddx(-QS, V(`IntrinsicGate)); + CSD = ddx(-QS, V(di)); + CSS = ddx(QS, V(si)); + CSE = ddx(-QS, V(e)); + + CDG = ddx(-QD, V(`IntrinsicGate)); + CDD = ddx(QD, V(di)); + CDS = ddx(-QD, V(si)); + CDE = ddx(-QD, V(e)); + + CEG = ddx(-QB, V(`IntrinsicGate)); + CED = ddx(-QB, V(di)); + CES = ddx(-QB, V(si)); + CEE = ddx(QB, V(e)); + + // Total extrinsic capacitance + CGSEXT = ddx(-(qgs_parasitic + (CGEOMOD == 1 ? qgs_fr : 0)),V(si)); // Gate-Source Overlap + outer fringing + CGDEXT = ddx(-(qgd_parasitic + (CGEOMOD == 1 ? qgd_fr : 0)),V(di)); // Gate-Drain Overlap + outer fringing + CGBOV = ddx(Qeg,V(e)); // Gate-Body Overlap + CGBOV = -devsign * CGBOV; + + // Total of Junction Capacitance and Source/Drain-Body Overlap Capacitance + CJST = ddx(Qes, V(si)); + CJST = -devsign * CJST; + CJDT = ddx(Qed, V(di)); + CJDT = -devsign * CJDT; + + RSGEO = RSourceGeo; // External bias independent Source Resistance + RDGEO = RDrainGeo; // External bias independent Drain Resistance + CFGEO = Cfr_geo; // Geometric Parasitic Cap for CGEOMOD=1 + + // Output for Self-Heating Temperature + T_TOTAL_K = DevTemp; + T_TOTAL_C = DevTemp - `P_CELSIUS0; + T_DELTA_SH = Temp(t); + + `ifdef __DEBUG__ + // Individual Gate Current Components + IGS = devsign * igs; + IGD = devsign * igd; + IGCS = devsign * igcs; + IGCD = devsign * igcd; + if (BULKMOD == 0) begin + IGBS = devsign * igbs; + IGBD = devsign * igbd; + end else begin + IGBINV = devsign * igbinv; + IGBACC = devsign * igbacc; + end + + DIDSDVG = ddx(ids, V(`IntrinsicGate)); + DIDSDVG = devsign * sigvds * DIDSDVG; + DIDSDVS = ddx(ids, V(si)); + DIDSDVS = devsign * sigvds * DIDSDVS; + DIDSDVD = ddx(ids, V(di)); + DIDSDVD = devsign * sigvds * DIDSDVD; + `ifdef __SHMOD__ + DIDSDVTH = ddx(ids, Temp(t)); + DIDSDVTH = devsign * sigvds * DIDSDVTH; + `endif + DIGSDVG = ddx(igs + igcs, V(`IntrinsicGate)); + DIGSDVG = devsign * DIGSDVG; + DIGSDVS = ddx(igs + igcs, V(si)); + DIGSDVS = devsign * DIGSDVS; + DIGSDVD = ddx(igs + igcs, V(di)); + DIGSDVD = devsign * DIGSDVD; + `ifdef __SHMOD__ + DIGSDVTH = ddx(igs + igcs, Temp(t)); + DIGSDVTH = devsign * DIGSDVTH; + `endif + DIGDDVG = ddx(igd + igcd, V(`IntrinsicGate)); + DIGDDVG = devsign * DIGDDVG; + DIGDDVS = ddx(igd + igcd, V(si)); + DIGDDVS = devsign * DIGDDVS; + DIGDDVD = ddx(igd + igcd, V(di)); + DIGDDVD = devsign * DIGDDVD; + `ifdef __SHMOD__ + DIGDDVTH = ddx(igd + igcd, Temp(t)); + DIGDDVTH = devsign * DIGDDVTH; + `endif + DIIIDVG = ddx(Iii, V(`IntrinsicGate)); + DIIIDVG = devsign * DIIIDVG; + DIIIDVS = ddx(Iii, V(si)); + DIIIDVS = devsign * DIIIDVS; + DIIIDVD = ddx(Iii, V(di)); + DIIIDVD = devsign * DIIIDVD; + `ifdef __SHMOD__ + DIIIDVTH = ddx(Iii, Temp(t)); + DIIIDVTH = devsign * DIIIDVTH; + `endif + DIGIDLDVG = ddx(igidl, V(`IntrinsicGate)); + DIGIDLDVG = devsign * DIGIDLDVG; + DIGIDLDVS = ddx(igidl, V(si)); + DIGIDLDVS = devsign * DIGIDLDVS; + DIGIDLDVD = ddx(igidl, V(di)); + DIGIDLDVD = devsign * DIGIDLDVD; + `ifdef __SHMOD__ + DIGIDLDVTH = ddx(igidl, Temp(t)); + DIGIDLDVTH = devsign * DIGIDLDVTH; + `endif + DIGISLDVG = ddx(igisl, V(`IntrinsicGate)); + DIGISLDVG = devsign * DIGISLDVG; + DIGISLDVS = ddx(igisl, V(si)); + DIGISLDVS = devsign * DIGISLDVS; + DIGISLDVD = ddx(igisl, V(di)); + DIGISLDVD = devsign * DIGISLDVD; + `ifdef __SHMOD__ + DIGISLDVTH = ddx(igisl, Temp(t)); + DIGISLDVTH = devsign * DIGISLDVTH; + `endif + + `ifdef __SHMOD__ + CGT = ddx(QG, Temp(t)); + CST = ddx(QS, Temp(t)); + CDT = ddx(QD, Temp(t)); + `endif + ITH = ids * vds; + `ifdef __SHMOD__ + DITHDVTH = ddx(ITH, Temp(t)); + `endif + DITHDVG = ddx(ITH, V(`IntrinsicGate)); + DITHDVS = ddx(ITH, V(si)); + DITHDVD = ddx(ITH, V(di)); + `endif // __DEBUG__ + `endif // __OPINFO__ +end // analog block ends +//================================================ diff --git a/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_cfringe.include b/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_cfringe.include new file mode 100644 index 000000000..f4e211f77 --- /dev/null +++ b/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_cfringe.include @@ -0,0 +1,117 @@ +// ******************************************************** +// **** BSIM-CMG 110.0.0 released by Sourabh Khandelwal on 01/01/2016****/ +// * BSIM Common Multi-Gate Model Equations (Verilog-A) +// ******************************************************** +// +// ******************************************************** +// * Copyright 2016 Regents of the University of California. +// * All rights reserved. +// * +// * Project Director: Prof. Chenming Hu. +// * Authors: Sriramkumar V., Navid Paydavosi, Juan Duarte, Darsen Lu, Sourabh Khandelwal, +// * Chung-Hsun Lin, Mohan Dunga, Shijing Yao, +// * Ali Niknejad, Chenming Hu +// ******************************************************** +// ******************************************************** +// * NONDISCLOSURE STATEMENT +// 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 of California owns the copyright and grants users a perpetual, +// irrevocable, worldwide, non-exclusive, royalty-free license with +// respect to the software as set forth below. +// 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 University of California 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 +// Agreed to on __Jan 01, 2016__________________ +// By: ___University of California, Berkeley____ +// ___Chenming Hu_____________________ +// ___Professor in Graduate School _______ +// ******************************************************** + +// ******************************************************** +// Macro for the geometry-dependent fringing capacitance +// model +// ******************************************************** + +/* + (while (re-search-forward + (rx bow + (or "Hr" "Lr" "Hgdelta" "Lmax" "y" "x" + "CcgSat" "Cnon" "TT1" "Ccg1" "r1cf" "Rcf" "Ccg2" + "Ccg" "C1" "C2" "C3" "Cfglog" "dcf" "TT0" + "TT2" "Cfgsat" "delta" "xCfg") + eow) + nil t) + (replace-match "x42_\\&" t)) +*/ + +`define Cfringe_2d_vars() \ + real x42_Hr, x42_Lr, x42_Hgdelta, x42_Lmax, x42_y, x42_x; \ + real x42_CcgSat, x42_Cnon, x42_TT1, x42_Ccg1, x42_r1cf, x42_Rcf, x42_Ccg2; \ + real x42_Ccg, x42_C1, x42_C2, x42_C3, x42_Cfglog, x42_dcf, x42_TT0; \ + real x42_TT2, x42_Cfgsat, x42_delta, Cfg; + +`define Cfringe_2d(block_name, Hg, Hc, Lext, Wfin, Lc, Lg, Tox, Cf1, Cgg) \ +begin : block_name \ + x42_Hr = 2.3 + 0.2 * ((Hg) + (Tox)) / (Hc); \ + x42_Lr = 1.05; \ + x42_Hgdelta = abs((Hg) + (Tox) - (Hc)); \ + x42_Lmax = (Lext) * x42_Lr; \ + \ + x42_y = min((Hc), (Hg) + (Tox)); \ + x42_x = (Lext) / (x42_Hr + 1.0); \ + x42_Cnon = 1.7e12; \ + x42_CcgSat = epssp * (x42_y - x42_x) / (Lext); \ + x42_TT1 = x42_Cnon * x42_CcgSat; \ + if(x42_TT1 > `EXPL_THRESHOLD) \ + x42_Ccg1 = x42_CcgSat; \ + else \ + x42_Ccg1 = 1.0 / x42_Cnon * ln(1.0 + lexp(x42_TT1)); \ + \ + x42_r1cf = 0.5 * \ + min((Hc) / ((Hg) + (Tox)), ((Hg) + (Tox)) / (Hc)); \ + x42_Rcf = x42_Hgdelta * x42_r1cf; \ + x42_Ccg2 = epssp * 2 / `M_PI * \ + ln(((Lext) + 0.5 * `M_PI * x42_Rcf) / (Lext)); \ + \ + x42_Ccg = (Wfin) * (x42_Ccg1 + x42_Ccg2); \ + \ + x42_x = x42_Lmax / (Hg); \ + x42_C1 = 4.0 / (sqrt(2.0 * (x42_x + 1)) * `M_PI); \ + x42_C2 = sqrt((Tox) * (Tox) + 2.0 * (Hg) * (Tox) + \ + (Hg) * (Hg) * (x42_x + 1)) * sqrt(x42_x + 1) + (Tox) + \ + (Hg) * x42_x + (Hg); \ + x42_C3 = (Tox) * sqrt((x42_x + 1) * (x42_x + 4)) + Tox * (x42_x + 2); \ + x42_Cfglog = epssp * (x42_C1 * ln(x42_C2 / x42_C3) + 12.27); \ + \ + x42_dcf = x42_Hr * x42_Lr; \ + x42_TT0 = sqrt(x42_dcf * x42_dcf + 1.0); \ + x42_TT1 = sqrt((x42_dcf * x42_dcf + 1) * ((x42_dcf * (Tox)) * (x42_dcf * (Tox)) + \ + 2 * x42_dcf * x42_Lmax * (Tox) + (x42_dcf * x42_dcf + 1) * x42_Lmax * x42_Lmax)) \ + + x42_dcf * (Tox) + x42_dcf * x42_dcf * x42_Lmax + x42_Lmax; \ + x42_TT2 = (x42_TT0 + 1.0) * (x42_dcf * (Tox)); \ + x42_Cfgsat = 2.0 * epssp * sqrt(2) / `M_PI * (Cf1) * x42_dcf \ + / x42_TT0 * ln(x42_TT1 / x42_TT2); \ + \ + x42_delta = 1.2e-12; \ + x42_TT1 = x42_Cfgsat - x42_Cfglog - x42_delta; \ + Cfg = (Wfin) * (x42_Cfgsat - 0.5 * (x42_TT1 + \ + sqrt(x42_TT1 * x42_TT1 + 4 * x42_delta * x42_Cfgsat))); \ + Cgg = x42_Ccg + Cfg; \ +end + + + + diff --git a/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_quasi_static_cv.include b/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_quasi_static_cv.include new file mode 100644 index 000000000..a0210a4f9 --- /dev/null +++ b/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_quasi_static_cv.include @@ -0,0 +1,89 @@ +// ******************************************************** +// **** BSIM-CMG 110.0.0 released by Sourabh Khandelwal on 01/01/2016 ****/ +// * BSIM Common Multi-Gate Model Equations (Verilog-A) +// ******************************************************** +// +// ******************************************************** +// * Copyright 2016 Regents of the University of California. +// * All rights reserved. +// * +// * Project Director: Prof. Chenming Hu. +// * Authors: Sriramkumar V., Navid Paydavosi, Juan Duarte, Darsen Lu, +// * Chung-Hsun Lin, Mohan Dunga, Shijing Yao, +// * Ali Niknejad, Chenming Hu +// ******************************************************** +// ******************************************************** +// * NONDISCLOSURE STATEMENT +// 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 of California owns the copyright and grants users a perpetual, +// irrevocable, worldwide, non-exclusive, royalty-free license with +// respect to the software as set forth below. +// 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 University of California 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 +// Agreed to on __Jan 01, 2016_________________ +// By: ___University of California, Berkeley____ +// ___Chenming Hu_____________________ +// ___Professor in Graduate School _______ +// ******************************************************** +// *** Quasi Static CV Model *** + + T11 = (2.0*qia+nVtm)/DvsatCV;//G + qg = qia+dqi*dqi/(6.0*T11);//qc + qd = -0.5*(qia-(dqi/(6.0))*(1.0-(dqi/T11)*(1+dqi/(5.0*T11))));//qd + // Including CLM in qg and qd + inv_MclmCV = 1.0 / MclmCV; + qg = inv_MclmCV * qg + (MclmCV - 1.0) * qid; + qd = inv_MclmCV * inv_MclmCV * qd + 0.5 * (MclmCV - inv_MclmCV) * qid; + +//Calculating partition for NQSMOD2 +`ifdef __NQSMOD2__ + if(NQSMOD == 2) xdpart = qd / qg; + else xdpart = 0; +`endif + + qs = -qg-qd; //from charge conservation qs = -qg-qd; + T6 = NFINtotal*WeffCV0 * LeffCV * coxeff; + + qg = T6*qg; + qd = T6*qd; + qs = T6*qs; + qinv = qg ; + if(BULKMOD != 0) begin + T1 = NFINtotal * WeffCV0 * LeffCV_acc * cox_acc; + T7 = qi_acc_for_QM;//qbulk + T10 = T7 * T1; + qg_acc = - T10; + qb_acc = T10; + T1 = NFINtotal * WeffCV0 * LeffCV * cox; + T2 = qba - qi_acc_for_QM; + T10 = T1*T2; + qg_acc = qg_acc - T10; + qb_acc = qb_acc + T10; + T1 = NFINtotal * WeffCV0 * LeffCV * cox; + T2 = (nq-1.0)*0.5*(qia+(dqi*dqi/(6.0*T11))); + T10 = T1*T2; + qg_acc = qg_acc - T10; + qb_acc = qb_acc + T10; + end + +// if vds is negative, physical charge on qd is qs + if (sigvds < 0) begin + T1 = qd; + qd = qs; + qs = T1; + end + diff --git a/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_rdsmod.include b/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_rdsmod.include new file mode 100644 index 000000000..892a126cc --- /dev/null +++ b/src/spicelib/devices/adms/bsimcmg/admsva/bsimcmg_rdsmod.include @@ -0,0 +1,84 @@ +// ******************************************************* +// **** BSIM-CMG 110.0.0 released by Sourabh Khandelwal on 01/01/2016 ****/ +// * BSIM Common Multi-Gate Model Equations (Verilog-A) +// ******************************************************** +// +// ******************************************************** +// * Copyright 2016 Regents of the University of California. +// * All rights reserved. +// * +// * Project Director: Prof. Chenming Hu. +// * Authors: Sriramkumar V., Navid Paydavosi, Juan Duarte, Darsen Lu, Sourabh Khandelwal +// * Chung-Hsun Lin, Mohan Dunga, Shijing Yao, +// * Ali Niknejad, Chenming Hu +// ******************************************************** +// ******************************************************** +// * NONDISCLOSURE STATEMENT +// 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 of California owns the copyright and grants users a perpetual, +// irrevocable, worldwide, non-exclusive, royalty-free license with +// respect to the software as set forth below. +// 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 University of California 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 +// Agreed to on __Jan 01, 2016_________________ +// By: ___University of California, Berkeley____ +// ___Chenming Hu_____________________ +// ___Professor in Graduate School _______ +// ******************************************************** +// Source-Drain Resistance Model +case(RDSMOD) + 1: begin + Rdsi = 0.0; + Dr = 1.0; + + T2 = vgs_noswap - vfbsd; + T3 = sqrt(T2 * T2 + 1.0e-1); + vgs_eff = 0.5 * (T2 + T3); + T4 = 1.0 + PRWGS_i * vgs_eff; + T1 = 1.0 / T4; + T0 = 0.5 * (T1 + sqrt(T1 * T1 + 0.01)); + T5 = RSW_i * (1.0 + RSDR_a * lexp(0.5 * PRSDR * lln(V(si,s) * V(si,s) + 1.0E-6))); + Rsource = rdstemp * (RSourceGeo + (RSWMIN_i + T5 * T0) * WeffWRFactor); + + T2 = vgd_noswap - vfbsd; + T3 = sqrt(T2 * T2 + 1.0e-1); + vgd_eff = 0.5 * (T2 + T3); + T4 = 1.0 + PRWGD_i * vgd_eff; + T1 = 1.0 / T4; + T0 = 0.5 * (T1 + sqrt(T1 * T1 + 0.01)); + T5 = RDW_i * (1.0 + RDDR_a * lexp(0.5 * PRDDR * lln(V(di,d) * V(di,d) + 1.0E-6))); + Rdrain = rdstemp * (RDrainGeo + (RDWMIN_i + T5 * T0) * WeffWRFactor); + end + 0: begin + Rsource = RSourceGeo; + Rdrain = RDrainGeo; + T4 = 1.0 + PRWGS_i * qia; + T1 = 1.0 / T4; + T0 = 0.5 * (T1 + sqrt(T1 * T1 + 0.01)); + Rdsi = rdstemp * (RDSWMIN_i + RDSW_i * T0) * WeffWRFactor; + Dr = 1.0 + (NFINtotal) * beta * ids0_ov_dqi / (Dmob * Dvsat) * Rdsi; + end + 2: begin + T4 = 1.0 + PRWGS_i * qia; + T1 = 1.0 / T4; + T0 = 0.5 * (T1 + sqrt(T1 * T1 + 0.01)); + Rdsi = rdstemp * (RSourceGeo + RDrainGeo + RDSWMIN_i + RDSW_i * T0) * WeffWRFactor; + Dr = 1.0 + (NFINtotal) * beta * ids0_ov_dqi / (Dmob * Dvsat) * Rdsi; + Rsource = 0.0; + Rdrain = 0.0; + end +endcase diff --git a/src/spicelib/devices/adms/bsimcmg/admsva/common_defs.include b/src/spicelib/devices/adms/bsimcmg/admsva/common_defs.include new file mode 100644 index 000000000..0d1ec67e5 --- /dev/null +++ b/src/spicelib/devices/adms/bsimcmg/admsva/common_defs.include @@ -0,0 +1,185 @@ +// ******************************************************** +// **** BSIM-CMG 110.0.0 released by Sourabh Khandelwal on 01/01/2016 ****/ +// * BSIM Common Multi-Gate Model Equations (Verilog-A) +// ******************************************************** +// +// ******************************************************** +// * Copyright 2016 Regents of the University of California. +// * All rights reserved. +// * +// * Project Director: Prof. Chenming Hu. +// * Authors: Sriramkumar V., Navid Paydavosi, Juan Duarte, Darsen Lu, Sourabh Khandelwal +// * Chung-Hsun Lin, Mohan Dunga, Shijing Yao, +// * Ali Niknejad, Chenming Hu +// ******************************************************** +// ******************************************************** +// * NONDISCLOSURE STATEMENT +// 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 of California owns the copyright and grants users a perpetual, +// irrevocable, worldwide, non-exclusive, royalty-free license with +// respect to the software as set forth below. +// 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 University of California 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 +// Agreed to on __Jan 01, 2016__________________ +// By: ___University of California, Berkeley____ +// ___Chenming Hu_____________________ +// ___Professor in Graduate School _______ +// ******************************************************** + +// Numerical Constants +`define EXPL_THRESHOLD 80.0 +`define MAX_EXPL 5.540622384e34 +`define MIN_EXPL 1.804851387e-35 +`define N_MINLOG 1.0e-38 +`define MEXPQM 4 +`define DELTA_1 0.02 +`define DELTA_ASYMM 0.04 +`define CONSTCtoK (273.15) +`define REFTEMP (300.15) /* 27 degrees C */ + + +// Model type definitions +`define ntype 1 +`define ptype 0 + +// Physical Constants +`define q 1.60219e-19 // Coul +`define EPS0 8.8542e-12 // F/m +`define HBAR 1.05457e-34 // Joule-sec +`define MEL 9.11e-31 // kg +`define KboQ 8.617087e-5 // Joule / degree + +// Mathematical functions +//`define SINH(x) (0.5 * (lexp(x) - lexp(-(x)))) +`define COSH(x) (0.5 * (lexp(x) + lexp(-(x)))) +//`define TANH(x) ((lexp(x) - lexp(-(x))) / (lexp(x) + lexp(-(x)))) +`define COT(x) ((x)>=`M_PI/2 ? 0 : ((x)<=-`M_PI/2 ? 0 : 1.0/tan(x))) + +// Junction capacitance +//ex:(ves_jct, Czbs, PBS_t, SBS, MJS, MJS2, Qes1) +`define BSIM6JunctnCap(vex, Cz, PB, SJ, MJ, MJ2, Qej) \ + begin \ + if (Cz > 0.0) begin \ + T1 = vex / PB; \ + if (T1 < 0.9) begin \ + if (SJ > 0.0) begin /*second-step junction*/ \ + vec = PB * (1.0 - lexp((1.0 / MJ) * lln(1.0/SJ))); /*Switch over voltage*/\ + pb2 = PB * SJ * MJ2 / MJ / lexp(- (1.0 + MJ) * lln(1.0 - vec / PB)); /*PB for second doping region*/\ + if (vex > vec) begin \ + arg = 1.0 - T1; \ + if (MJ == 0.5) sarg = 1.0 / sqrt(arg); \ + else sarg = lexp(-MJ * lln(arg)); \ + Qej = PB * Cz * (1.0 - arg * sarg) / (1.0 - MJ); \ + end else begin /*vex < vec*/ \ + arg = 1.0 - vec / PB; \ + if (MJ == 0.5) sarg = 1.0 / sqrt(arg); \ + else sarg = lexp(-MJ * lln(arg)); \ + Qec = PB * Cz * (1.0 - arg * sarg) / (1.0 - MJ); \ + arg = 1.0 - (vex - vec) / pb2; \ + if (MJ2 == 0.5) sarg = 1.0 / sqrt(arg); \ + else sarg = lexp(-MJ2 * lln(arg)); \ + Qej = Qec + SJ * pb2 * Cz * (1.0 - arg * sarg) / (1.0 - MJ2); \ + end \ + end else begin /*single junction*/ \ + arg = 1.0 - T1; \ + if (MJ == 0.5) sarg = 1.0 / sqrt(arg); \ + else sarg = lexp(-MJ * lln(arg)); \ + Qej = PB * Cz * (1.0 - arg * sarg) / (1.0 - MJ); \ + end \ + end else begin /*vex/PB>=0.9*/ \ + T2 = lexp(-MJ * lln(0.1)); \ + T3 = 1.0 / (1.0-MJ); \ + T4 = T2 * (T1 - 1.0) * (5.0 * MJ * (T1-1.0) + (1.0 + MJ) ); \ + T5 = T3 * (1.0 - 0.05 * MJ * (1.0 + MJ) * T2 ); \ + Qej = PB * Cz * (T4 + T5); /*Quadratic equation for Qej when vex/PB>=0.9*/\ + end \ + end else begin \ + Qej = 0.0; \ + end \ + end + +// +// Macros for the model/instance parameters +// +// MPRxx model parameter real +// MPIxx model parameter integer +// IPRxx instance parameter real +// IPIxx instance parameter integer +// || +// cc closed lower bound, closed upper bound +// oo open lower bound, open upper bound +// co closed lower bound, open upper bound +// oc open lower bound, closed upper bound +// cz closed lower bound=0, open upper bound=inf +// oz open lower bound=0, open upper bound=inf +// nb no bounds +// ex no bounds with exclude +// sw switch(integer only, values 0=false and 1=true) +// ty switch(integer only, values -1=p-type and +1=n-type) +// +// IPM instance parameter mFactor(multiplicity, implicit for LRM2.2) +// OPP operating point parameter, includes units and description for printing +// +`define ALIAS(alias,paramName) aliasparam alias = paramName ; +`define OPP(nam,uni,des) (*units=uni, desc=des*) real nam ; + +`define MPRnb(nam,def,uni, des) (*units=uni, desc=des*) parameter real nam=def ; +`define MPRex(nam,def,uni,exc, des) (*units=uni, desc=des*) parameter real nam=def exclude exc ; +`define MPRcc(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter real nam=def from[lwr:upr] ; +`define MPRoo(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter real nam=def from(lwr:upr) ; +`define MPRco(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter real nam=def from[lwr:upr) ; +`define MPRoc(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter real nam=def from(lwr:upr] ; +`define MPRcz(nam,def,uni, des) (*units=uni, desc=des*) parameter real nam=def from[ 0:inf); +`define MPRoz(nam,def,uni, des) (*units=uni, desc=des*) parameter real nam=def from( 0:inf); + +`define MPInb(nam,def,uni, des) (*units=uni, desc=des*) parameter integer nam=def ; +`define MPIex(nam,def,uni,exc, des) (*units=uni, desc=des*) parameter integer nam=def exclude exc ; +`define MPIcc(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter integer nam=def from[lwr:upr] ; +`define MPIoo(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter integer nam=def from(lwr:upr) ; +`define MPIco(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter integer nam=def from[lwr:upr) ; +`define MPIoc(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter integer nam=def from(lwr:upr] ; +`define MPIcz(nam,def,uni, des) (*units=uni, desc=des*) parameter integer nam=def from[ 0:inf); +`define MPIoz(nam,def,uni, des) (*units=uni, desc=des*) parameter integer nam=def from( 0:inf); + +`define MPIsw(nam,def,uni, des) (*units=uni, desc=des*) parameter integer nam=def from[ 0: 1] ; +`define MPIty(nam,def,uni, des) (*units=uni, desc=des*) parameter integer nam=def from[ -1: 1] exclude 0 ; + +`define IPRnb(nam,def,uni, des) (*units=uni, type="instance", desc=des*) parameter real nam=def ; +`define IPRex(nam,def,uni,exc, des) (*units=uni, type="instance", desc=des*) parameter real nam=def exclude exc ; +`define IPRcc(nam,def,uni,lwr,upr,des) (*units=uni, type="instance", desc=des*) parameter real nam=def from[lwr:upr] ; +`define IPRoo(nam,def,uni,lwr,upr,des) (*units=uni, type="instance", desc=des*) parameter real nam=def from(lwr:upr) ; +`define IPRco(nam,def,uni,lwr,upr,des) (*units=uni, type="instance", desc=des*) parameter real nam=def from[lwr:upr) ; +`define IPRoc(nam,def,uni,lwr,upr,des) (*units=uni, type="instance", desc=des*) parameter real nam=def from(lwr:upr] ; +`define IPRcz(nam,def,uni, des) (*units=uni, type="instance", desc=des*) parameter real nam=def from[ 0:inf); +`define IPRoz(nam,def,uni, des) (*units=uni, type="instance", desc=des*) parameter real nam=def from( 0:inf); + +`define IPInb(nam,def,uni, des) (*units=uni, type="instance", desc=des*) parameter integer nam=def ; +`define IPIex(nam,def,uni,exc, des) (*units=uni, type="instance", desc=des*) parameter integer nam=def exclude exc ; +`define IPIcc(nam,def,uni,lwr,upr,des) (*units=uni, type="instance", desc=des*) parameter integer nam=def from[lwr:upr] ; +`define IPIoo(nam,def,uni,lwr,upr,des) (*units=uni, type="instance", desc=des*) parameter integer nam=def from(lwr:upr) ; +`define IPIco(nam,def,uni,lwr,upr,des) (*units=uni, type="instance", desc=des*) parameter integer nam=def from[lwr:upr) ; +`define IPIoc(nam,def,uni,lwr,upr,des) (*units=uni, type="instance", desc=des*) parameter integer nam=def from(lwr:upr] ; +`define IPIcz(nam,def,uni, des) (*units=uni, type="instance", desc=des*) parameter integer nam=def from[ 0:inf); +`define IPIoz(nam,def,uni, des) (*units=uni, type="instance", desc=des*) parameter integer nam=def from( 0:inf); + +`ifdef EXPLICIT_MFACTOR + `define IPM (*units="" , type="instance", desc="multiplicity factor"*) parameter real m=1.0 from(0.0:inf) ; + `define MFACTOR_USE m +`else // + `define IPM + `define MFACTOR_USE 1.0 +`endif diff --git a/src/spicelib/devices/adms/ekv/admsva/ekv.va b/src/spicelib/devices/adms/ekv/admsva/ekv.va new file mode 100644 index 000000000..093035968 --- /dev/null +++ b/src/spicelib/devices/adms/ekv/admsva/ekv.va @@ -0,0 +1,677 @@ +// EPFL-EKV version 2.6: A Verilog-A description. +// The intrinsic device is coded according to the official manual +// (revision II) available at https://ekv.epfl.ch/model. + +// License information for this implementation: + +// Copyright Ivan Riis Nielsen 2006, Dietmar Warning 2009 + +// This model implementation is licensed according to the modified (3-clause) BSD license: +/* +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +//Default simulator: Spectre + +`ifdef insideADMS + `define P(txt) (*txt*) + `define PGIVEN(p) $given(p) + `define INITIAL_MODEL @(initial_model) + `define INSTANCE @(initial_instance) + `define NOISE @(noise) +`else + `define P(txt) (txt) + `define PGIVEN(p) p + `define INITIAL_MODEL + `define INSTANCE + `define NOISE +`endif + +//ADS +//`include "constants.vams" +//`include "disciplines.vams" +//`include "compact.vams" + +//Spectre +`include "constants.h" +`include "discipline.h" + +`define NMOS 1 +`define PMOS -1 + +`define EPSSI `P_EPS0*11.7 +`define EPSOX `P_EPS0*3.9 +`define TREF 300.15 + +`define SQR(x) ((x)*(x)) + +`define VT(temp) (`P_K*temp/`P_Q) +`define EG(temp) (1.16-0.000702*`SQR(temp)/(temp+1108)) +`define NI(temp) (1.45e16*(temp/`TREF)*exp(`EG(`TREF)/(2*`VT(`TREF))-`EG(temp)/(2*`VT(temp)))) + + +`define oneThird 3.3333333333333333e-01 + +// Constants needed in safe exponential function (called "expl") +`define se05 2.3025850929940458e+02 +`define ke05 1.0e-100 +`define ke05inv 1.0e100 + +// P3 3rd order polynomial expansion of exp() +`define P3(u) (1.0 + (u) * (1.0 + 0.5 * ((u) * (1.0 + (u) * `oneThird)))) + +// expl exp() with 3rd order polynomial extrapolation +// to avoid overflows and underflows and retain C-3 continuity +`define expl(x, res) \ +if (abs(x) < `se05) begin\ + res = exp(x); \ +end else begin \ + if ((x) < -`se05) begin\ + res = `ke05 / `P3(-`se05 - (x)); \ + end else begin\ + res = `ke05inv * `P3((x) - `se05); \ + end \ +end + + +module ekv (d,g,s,b); + + // Node definitions + + inout d,g,s,b; + electrical d,g,s,b,di,si; + + // Model parameters + + parameter integer nmos=1 from [0:1] `P(desc="MOS type : nmos:0"); + parameter integer pmos=1 from [0:1] `P(desc="MOS type : pmos:0"); + parameter integer MTYPE=(nmos==0 ? (pmos==0 ? 0 : 1) : (pmos==0 ? -1 : 1)); + parameter real TNOM=27 from (-273.15:inf) + `P(desc="Nominal temperature [degC]"); + parameter real IMAX=1 from (0:inf) + `P(desc="Maximum forward junction current before linearization [A]"); + + // - intrinsic model (optional, section 4.2.1) + parameter real TOX=0 from [0:inf) + `P(desc="Oxide thickness [m]"); + parameter real NSUB=0 from [0:inf) + `P(desc="Channel doping [cm^-3]"); + parameter real VFB=1001.0 from (-inf:inf) // use 1001V as "not specified" + `P(desc="Flat-band voltage [V]"); + parameter real UO=0 from [0:inf) + `P(desc="Low-field mobility [cm^2/Vs]"); + parameter real VMAX=0 from [0:inf) + `P(desc="Saturation velocity [m/s]"); + parameter real THETA=0 from [0:inf) + `P(desc="Mobility reduction coefficient [V^-1]"); + + // - intrinsic model (process related, section 4.1) + parameter real COX=((TOX>0) ? (`EPSOX/TOX) : 0.7m) from [0:inf) + `P(desc="Oxide capacitance [F/m^2]"); + parameter real XJ=0.1u from [1n:inf) + `P(desc="Junction depth [m]"); + parameter real DL=0 from (-inf:inf) + `P(desc="Length correction [m]"); + parameter real DW=0 from (-inf:inf) + `P(desc="Width correction [m]"); + + // - intrinsic model (basic, section 4.2) + parameter real GAMMA=((NSUB>0) ? (sqrt(2*`P_Q*`EPSSI*NSUB*1e6)/COX) : 1) from [0:inf) + `P(desc="Body effect parameter [V^0.5]"); + parameter real PHI=((NSUB>0) ? (2*`VT((TNOM+273.15))*ln(max(NSUB,1)*1e6/`NI((TNOM+273.15)))) : 0.7) from [0.1:inf) + `P(desc="Bulk Fermi potential (*2) [V]"); + parameter real VTO=((VFB<1000.0) ? (VFB+MTYPE*(PHI+GAMMA*sqrt(PHI))) : 0.5) from (-inf:inf) + `P(desc="Long-channel threshold voltage [V]"); + parameter real KP=((UO>0) ? (UO*1e-4*COX) : 50u) from (0:inf) + `P(desc="Transconductance parameter [A/V^2]"); + parameter real UCRIT=(((VMAX>0) && (UO>0)) ? (VMAX/(UO*1e-4)) : 2e6 ) from [100k:inf) + `P(desc="Longitudinal critical field [V/m]"); + parameter real E0=((THETA>0) ? 0 : 1e12) from [100k:inf) + `P(desc="Mobility reduction coefficient [V/m]"); + + // - intrinsic model (channel length modulation and charge sharing, section 4.3) + parameter real LAMBDA=0.5 from [0:inf) + `P(desc="Depletion length coefficient (CLM)"); + parameter real WETA=0.25 from (-inf:inf) + `P(desc="Narrow-channel effect coefficient"); + parameter real LETA=0.1 from (-inf:inf) + `P(desc="Short-channel effect coefficient"); + + // - intrinsic model (reverse short channel effect, section 4.4) + parameter real Q0=0 from (-inf:inf) + `P(desc="RSCE peak charge density [C/m^2]"); + parameter real LK=0.29u from [10n:inf) + `P(desc="RSCE characteristic length [m]"); + + // - intrinsic model (impact ionization, section 4.5) + parameter real IBA=0 from (-inf:inf) + `P(desc="First impact ionization coefficient [m^-1]"); + parameter real IBB=3e8 from [1e8:inf) + `P(desc="Second impact ionization coefficient [V/m]"); + parameter real IBN=1 from [0.1:inf) + `P(desc="Saturation voltage factor for impact ionization"); + + // - intrinsic model (temperature, section 4.6) + parameter real TCV=1m from (-inf:inf) + `P(desc="Threshold voltage TC [V/K]"); + parameter real BEX=-1.5 from (-inf:inf) + `P(desc="Mobility temperature exponent"); + parameter real UCEX=0.8 from (-inf:inf) + `P(desc="Longitudinal critical field temperature exponent"); + parameter real IBBT=9e-4 from (-inf:inf) + `P(desc="Temperature coefficient for IBB [K^-1]"); + + // - intrinsic model (matching, section 4.7) + parameter real AVTO=0 from (-inf:inf) + `P(desc="Area related VTO mismatch parameter [Vm]"); + parameter real AKP=0 from (-inf:inf) + `P(desc="Area related KP mismatch parameter [m]"); + parameter real AGAMMA=0 from (-inf:inf) + `P(desc="Area related GAMMA mismatch parameter [V^0.5*m]"); + + // - intrinsic model (flicker noise, section 4.8) + parameter real KF=0 from [0:inf) + `P(desc="Flicker noise coefficient"); + parameter real AF=1 from (-inf:inf) + `P(desc="Flicker noise exponent"); + + // - intrinsic model (setup, section 4.9) + parameter real NQS=0 from [0:1] + `P(desc="Non-quasi-static operation switch"); + parameter real SATLIM=exp(4) from (0:inf) + `P(desc="Saturation limit (if/ir)"); + parameter real XQC=0.4 from [0:1] + `P(desc="Charge/capacitance model selector"); + + // - external parasitic parameters + parameter real HDIF=0 from [0:inf) + `P(desc="S/D diffusion length (/2) [m]"); + parameter real RSH=0 from [0:inf) + `P(desc="S/D sheet resistance [ohm]"); + parameter real JS=0 from [0:inf) + `P(desc="S/D junction saturation current density [A/m^2]"); + parameter real JSW=0 from [0:inf) + `P(desc="S/D junction sidewall saturation current density [A/m]"); + parameter real XTI=0 from [0:inf) + `P(desc="S/D diode saturation current temperature exponent"); + parameter real N=1 from [0.5:10] + `P(desc="S/D diode emission coefficient"); + parameter real CJ=0 from [0:inf) + `P(desc="S/D zero-bias junction capacitance per area [F/m^2]"); + parameter real CJSW=0 from [0:inf) + `P(desc="S/D zero-bias junction capacitance per perimeter [F/m]"); + parameter real PB=0.8 from (0:inf) + `P(desc="S/D bottom junction builtin potential [V]"); + parameter real PBSW=PB from (0:inf) + `P(desc="S/D sidewall junction builtin potential [V]"); + parameter real MJ=0.5 from (0:inf) + `P(desc="S/D bottom junction grading coefficient"); + parameter real MJSW=0.333 from (0:inf) + `P(desc="S/D sidewall junction grading coefficient"); + parameter real FC=0.5 from (0:inf) + `P(desc="S/D bottom junction forward-bias threshold"); + parameter real FCSW=FC from (0:inf) + `P(desc="S/D sidewall junction forward-bias threshold"); + parameter real CGSO=0 from [0:inf) + `P(desc="Gate-source overlap capacitance per width [F/m]"); + parameter real CGDO=0 from [0:inf) + `P(desc="Gate-drain overlap capacitance per width [F/m]"); + parameter real CGBO=0 from [0:inf) + `P(desc="Gate-bulk overlap capacitance per length [F/m]"); + + + // Instance parameters + + // - intrinsic model + parameter real L=10u from [0:inf] + `P(type="instance" desc="Drawn length [m]" unit="m"); + parameter real W=10u from [0:inf] + `P(type="instance" desc="Drawn width [m]" unit="m"); + parameter real M=1 from [0:inf] + `P(type="instance" desc="Parallel multiplier" unit="m"); +// parameter real N=1 from [0:inf] +// `P(type="instance" desc="Series multiplier" unit="m"); + + // - external parasitics + parameter real AD=((HDIF>0) ? (2*HDIF*W) : 0) from [0:inf) + `P(desc="Drain area [m^2]" type="instance"); + parameter real AS=((HDIF>0) ? (2*HDIF*W) : 0) from [0:inf) + `P(desc="Source area [m^2]" type="instance"); + parameter real PD=((HDIF>0) ? (4*HDIF+2*W) : 0) from [0:inf) + `P(desc="Drain perimeter [m]" type="instance"); + parameter real PS=((HDIF>0) ? (4*HDIF+2*W) : 0) from [0:inf) + `P(desc="Source perimeter [m]" type="instance"); + parameter real NRD=((HDIF>0) ? (HDIF/W) : 0) from [0:inf) + `P(desc="Drain no. squares" type="instance"); + parameter real NRS=((HDIF>0) ? (HDIF/W) : 0) from [0:inf) + `P(desc="Source no. squares" type="instance"); + parameter real RS=((RSH>0) ? (RSH*NRS) : 0) from [0:inf) + `P(desc="Source resistance [ohms]" type="instance"); + parameter real RD=((RSH>0) ? (RSH*NRD) : 0) from [0:inf) + `P(desc="Drain resistance [ohms]" type="instance"); + + + // Declaration of variables + integer mode; + real lc,isat_s,vexp_s,gexp_s,isat_d,vexp_d,gexp_d,fact, + weff,leff,np,ns,lmin,rd,rs,ceps,ca,xsi,dvrsce, + tempk,vt,sqrt_A,vto_a,kp_a,gamma_a,ucrit,phi,ibb,vc,qb0, + vg,vd,vs,tmp,vgprime,vp0,vsprime,vdprime,gamma0,gammaprime,vp,n,ifwd, + vdss,vdssprime,dv,vds,vip,dl,lprime,leq,irprime,irev,beta0,nau, + nq,xf,xr,qd,qs,qi,qb,qg,beta0prime,beta,vpprime,is,ids,vib, + idb,ibdj,ibsj,coxt,qdt,qst,qgt,qbt, + cbs0,cbs0sw,cbs,cbd0,cbd0sw,cbd, + fv,z0,z1,y; + + real cgso,cgdo,cgbo; + + + analog begin + + `INITIAL_MODEL begin // Model Initialization + + lc = sqrt(`EPSSI/COX*XJ); + + end // INITIAL_MODEL + + `INSTANCE begin // temperature independent device initialization + + weff = W+DW; + leff = L+DL; + + np = M; + ns = 1; + + // eq. 54 + lmin = 0.1*ns*leff; + + rs = ns/np*RS; + rd = ns/np*RD; + + ceps = 4*22e-3*22e-3; + ca = 0.028; + xsi = ca*(10*leff/LK-1); + dvrsce = 2*Q0/COX/`SQR(1+0.5*(xsi+sqrt(xsi*xsi+ceps))); + + coxt = np*ns*COX*weff*leff; + + end // temperature independent + + `INSTANCE begin // temperature dependent device initialization + tempk = $temperature; + vt = `VT(tempk); + + sqrt_A = sqrt(np*weff*ns*leff); + + vto_a = MTYPE*(VTO+TCV*(tempk-(TNOM+273.15)))+AVTO/sqrt_A; + kp_a = KP*pow(tempk/(TNOM+273.15),BEX)*(1+AKP/sqrt_A); + gamma_a = GAMMA+AGAMMA/sqrt_A; + ucrit = UCRIT*pow(tempk/(TNOM+273.15),UCEX); + phi = PHI*tempk/(TNOM+273.15)-3*vt*ln(tempk/(TNOM+273.15))-`EG(TNOM+273.15)*tempk/(TNOM+273.15)+`EG(tempk); + ibb = IBB*(1+IBBT*(tempk-(TNOM+273.15))); + + vc = ucrit*ns*leff; + + // eq. 60 + qb0 = gamma_a*sqrt(phi); + + fact = (`EG(TNOM+273.15)/`VT(TNOM+273.15)-`EG(tempk)/vt) * pow(tempk/(TNOM+273.15),XTI); + `expl(fact,tmp) + isat_s = np*ns*(JS*AS+JSW*PS)*tmp; + isat_d = np*ns*(JS*AD+JSW*PD)*tmp; + + if (isat_s>0) begin + vexp_s = vt*ln(IMAX/isat_s+1); + gexp_s = (IMAX+isat_s)/vt; + end else begin + vexp_s = -1e9; + gexp_s = 0; + end + + if (isat_d>0) begin + vexp_d = vt*ln(IMAX/isat_d+1); + gexp_d = (IMAX+isat_d)/vt; + end else begin + vexp_d = -1e9; + gexp_d = 0; + end + + cbs0 = np*ns*CJ*AS; + cbd0 = np*ns*CJ*AD; + cbs0sw = np*ns*CJSW*PS; + cbd0sw = np*ns*CJSW*PD; + + cgso = np*ns*CGSO*weff; + cgdo = np*ns*CGDO*weff; + cgbo = np*ns*CGBO*leff; + + end // temperature dependent + + + begin //Bias-dependent model evaluation + + vg = MTYPE*V(g,b); + vd = MTYPE*V(di,b); + vs = MTYPE*V(si,b); + // $strobe("vg=%e vd=%e vs=%e",vg,vd,vs); + + if (vd>=vs) + mode = 1; + else begin + mode = -1; + tmp = vs; + vs = vd; + vd = tmp; + end + + // eq. 33 + vgprime = vg-vto_a-dvrsce+phi+gamma_a*sqrt(phi); + // eq. 35 + vsprime = 0.5*(vs+phi+sqrt(`SQR(vs+phi)+16*`SQR(vt))); + vdprime = 0.5*(vd+phi+sqrt(`SQR(vd+phi)+16*`SQR(vt))); + // $strobe("vgprime=%e vdprime=%e vsprime=%e",vgprime,vdprime,vsprime); + // eq. 34 + if (vgprime>=0) begin + vp0 = vgprime-phi-gamma_a*(sqrt(vgprime+0.25*`SQR(gamma_a))-0.5*gamma_a); + // eq. 36 + gamma0 = gamma_a-`EPSSI/COX*(LETA/leff*(sqrt(vsprime)+sqrt(vdprime))-3*WETA/weff*sqrt(vp0+phi)); + end else begin + vp0 = -phi; + // eq. 36 - skipped sqrt(vp0+phi) here, it produces inf on derivative + gamma0 = gamma_a-`EPSSI/COX*(LETA/leff*(sqrt(vsprime)+sqrt(vdprime)) ); + end + // eq. 37 + gammaprime = 0.5*(gamma0+sqrt(`SQR(gamma0)+0.1*vt)); + // eq. 38 + if (vgprime>=0) + vp = vgprime-phi-gammaprime*(sqrt(vgprime+0.25*`SQR(gammaprime))-0.5*gammaprime); + else + vp = -phi; + // $strobe("vp0=%e vp=%e gamma0=%e gammaprime=%e",vp0,vp,gamma0,gammaprime); + // eq. 39 + n = 1+gamma_a*0.5/sqrt(vp+phi+4*vt); + + // Forward current (43-44) + fv=(vp-vs)/vt; + + if (fv > -0.35) begin + z0 = 2.0/(1.3 + fv - ln(fv+1.6)); + z1 = (2.0 + z0) / (1.0 + fv + ln(z0)); + y = (1.0 + fv + ln(z1)) / (2.0 + z1); + end + else if (fv > -15) begin + `expl(-fv,tmp) + z0 = 1.55 + tmp; + z1 = (2.0 + z0) / (1.0 + fv + ln(z0)); + y = (1.0 + fv + ln(z1)) / (2.0 + z1); + end + else if (fv > -23.0) begin + `expl(-fv,tmp) + y = 1.0 / (2.0 + tmp); + end + else begin + `expl(fv,tmp) + y = tmp + 1.0e-64; + end + + ifwd = y*(1.0 + y); + z0 = 1; + z1 = 1; + + // eq. 46 + vdss = vc*(sqrt(0.25+vt/vc*sqrt(ifwd))-0.5); + // eq. 47 + vdssprime = vc*(sqrt(0.25+vt/vc*(sqrt(ifwd)-0.75*ln(ifwd)))-0.5)+vt*(ln(0.5*vc/vt)-0.6); + // $strobe("ifwd=%e vdss=%e vdssprime=%e",ifwd,vdss,vdssprime); + // eq. 48 + dv = 4*vt*sqrt(LAMBDA*(sqrt(ifwd)-vdss/vt)+1.0/64); + // eq. 49 + vds = 0.5*(vd-vs); + // eq. 50 + vip = sqrt(`SQR(vdss)+`SQR(dv))-sqrt(`SQR(vds-vdss)+`SQR(dv)); + // eq. 52 + dl = LAMBDA*lc*ln(1+(vds-vip)/(lc*ucrit)); + + // eq. 53 + lprime = ns*leff-dl+(vds+vip)/ucrit; + // eq. 55 + leq = 0.5*(lprime+sqrt(`SQR(lprime)+`SQR(lmin))); + + // eq. 56 + fv=(vp-vds-vs-sqrt(`SQR(vdssprime)+`SQR(dv))+sqrt(`SQR(vds-vdssprime)+`SQR(dv)))/vt; + + if (fv > -0.35) begin + z0 = 2.0/(1.3 + fv - ln(fv+1.6)); + z1 = (2.0 + z0) / (1.0 + fv + ln(z0)); + y = (1.0 + fv + ln(z1)) / (2.0 + z1); + end + else if (fv > -15) begin + `expl(-fv,tmp) + z0 = 1.55 + tmp; + z1 = (2.0 + z0) / (1.0 + fv + ln(z0)); + y = (1.0 + fv + ln(z1)) / (2.0 + z1); + end + else if (fv > -23.0) begin + `expl(-fv,tmp) + y = 1.0 / (2.0 + tmp); + end + else begin + `expl(fv,tmp) + y = tmp + 1.0e-64; + end + + irprime = y*(1.0 + y); + z0 = 1; + z1 = 1; + + // eq. 57 + fv=(vp-vd)/vt; + + if (fv > -0.35) begin + z0 = 2.0/(1.3 + fv - ln(fv+1.6)); + z1 = (2.0 + z0) / (1.0 + fv + ln(z0)); + y = (1.0 + fv + ln(z1)) / (2.0 + z1); + end + else if (fv > -15) begin + `expl(-fv,tmp) + z0 = 1.55 + tmp; + z1 = (2.0 + z0) / (1.0 + fv + ln(z0)); + y = (1.0 + fv + ln(z1)) / (2.0 + z1); + end + else if (fv > -23.0) begin + `expl(-fv,tmp) + y = 1.0 / (2.0 + tmp); + end + else begin + `expl(fv,tmp) + y = tmp + 1.0e-64; + end + + irev = y*(1.0 + y); + + // eq. 58 + beta0 = kp_a*np*weff/leq; + // eq. 59 + nau = (5+MTYPE)/12.0; + + // eq. 69 + nq = 1+0.5*gamma_a/sqrt(vp+phi+1e-6); + + // eq. 70 + xf = sqrt(0.25+ifwd); + // eq. 71 + xr = sqrt(0.25+irev); + // eq. 72 + qd = -nq*(4.0/15*(3*`SQR(xr)*(xr+2*xf)+2*`SQR(xf)*(xf+2*xr))/`SQR(xf+xr)-0.5); + // eq. 73 + qs = -nq*(4.0/15*(3*`SQR(xf)*(xf+2*xr)+2*`SQR(xr)*(xr+2*xf))/`SQR(xf+xr)-0.5); + // eq. 74 + qi = qs+qd; + // eq. 75 + if (vgprime>=0) + qb = (-gamma_a*sqrt(vp+phi+1e-6))/vt-(nq-1)/nq*qi; + else + qb = -vgprime/vt; + // eq. 76 (qox removed since it is assumed to be zero) + qg = -qi-qb; + + if (E0!=0) begin + // eq. 61 + beta0prime = beta0*(1+COX/(E0*`EPSSI)*qb0); + // eq. 62 + beta = beta0prime/(1+COX/(E0*`EPSSI)*vt*abs(qb+nau*qi)); + end else begin + // eq. 63 + vpprime = 0.5*(vp+sqrt(`SQR(vp)+2*`SQR(vt))); + // eq. 64 + beta = beta0/(1+THETA*vpprime); + end // else: !if(e0!=0) + // eq. 65 + is = 2*n*beta*`SQR(vt); + // $strobe("beta0=%e beta0prime=%e beta=%e E0=%e qb0=%e qb=%e qi=%e",beta0,beta0prime,beta,E0,qb0,qb,qi); + // eq. 66 + ids = is*(ifwd-irprime); + // eq. 67 + vib = vd-vs-IBN*2*vdss; + // eq. 68 + if (vib>0) begin + `expl((-ibb*lc)/vib,tmp) + idb = ids*IBA/ibb*vib*tmp; + end else + idb = 0; + // $strobe("ids=%e idb=%e",ids,idb); + + if (mode>1) begin + if (isat_s>0) begin + if (-vs>vexp_s) + ibsj = IMAX+gexp_s*(-vs-vexp_s); + else begin + `expl(-vs/(N*vt),tmp) + ibsj = isat_s*(tmp-1); + end + end else + ibsj = 0; + + if (isat_d>0) begin + if (-vd>vexp_d) + ibdj = IMAX+gexp_d*(-vd-vexp_d); + else begin + `expl(-vd/(N*vt),tmp) + ibdj = isat_d*(tmp-1); + end + end else + ibdj = 0; + + end else begin // if (mode>1) + if (isat_s>0) begin + if (-vd>vexp_s) + ibsj = IMAX+gexp_s*(-vd-vexp_s); + else begin + `expl(-vd/(N*vt),tmp) + ibsj = isat_s*(tmp-1); + end + end else + ibsj = 0; + + if (isat_d>0) begin + if (-vs>vexp_d) + ibdj = IMAX+gexp_d*(-vs-vexp_d); + else begin + `expl(-vs/(N*vt),tmp) + ibdj = isat_d*(tmp-1); + end + end else + ibdj = 0; + + end // else: !if(mode>1) + + qdt = coxt*vt*qd; + qst = coxt*vt*qs; + qgt = coxt*vt*qg; + qbt = coxt*vt*qb; + + cbs = 0; + cbd = 0; + + if (cbs0>0) begin + if (MTYPE*V(b,si)>FC*PB) + cbs = cbs+cbs0/pow(1-FC,MJ)*(1+MJ*(MTYPE*V(b,si)-PB*FC))/(PB*(1-FC)); + else + cbs = cbs+cbs0/pow(1-MTYPE*V(b,si),MJ); + end + if (cbd0>0) begin + if (MTYPE*V(b,di)>FC*PB) + cbd = cbd+cbd0/pow(1-FC,MJ)*(1+MJ*(MTYPE*V(b,di)-PB*FC))/(PB*(1-FC)); + else + cbd = cbd+cbd0/pow(1-MTYPE*V(b,di),MJ); + end + if (cbs0sw>0) begin + if (MTYPE*V(b,si)>FCSW*PBSW) + cbs = cbs+cbs0sw/pow(1-FCSW,MJSW)*(1+MJSW*(MTYPE*V(b,si)-PBSW*FCSW))/(PBSW*(1-FCSW)); + else + cbs = cbs+cbs0sw/pow(1-MTYPE*V(b,si),MJSW); + end + if (cbd0sw>0) begin + if (MTYPE*V(b,di)>FCSW*PBSW) + cbd = cbd+cbd0sw/pow(1-FCSW,MJSW)*(1+MJSW*(MTYPE*V(b,di)-PBSW*FCSW))/(PBSW*(1-FCSW)); + else + cbd = cbd+cbd0sw/pow(1-MTYPE*V(b,di),MJSW); + end + + end //Bias-dependent model evaluation + + begin //Define branch sources + + I(di,si) <+ MTYPE*mode*ids; + if (mode>0) begin + I(di,b) <+ MTYPE*idb; + + I(di,g) <+ MTYPE*ddt(qdt); + I(si,g) <+ MTYPE*ddt(qst); + + end else begin + I(si,b) <+ MTYPE*idb; + + I(si,g) <+ MTYPE*ddt(qdt); + I(di,g) <+ MTYPE*ddt(qst); + + end // else: !if(mode>0) + + I(b,si) <+ MTYPE*ibsj; + I(b,di) <+ MTYPE*ibdj; + + I(b,g) <+ MTYPE*ddt(qbt); + + I(g,si) <+ cgso*ddt(V(g,si)); + I(g,di) <+ cgdo*ddt(V(g,di)); + I(g,b) <+ cgbo*ddt(V(g,b)); + + if (RD>0) + I(d,di) <+ V(d,di)/rd; + else + V(d,di) <+ 0.0; + if (RS>0) + I(s,si) <+ V(s,si)/rs; + else + V(s,si) <+ 0.0; + + I(b,si) <+ cbs*ddt(V(b,si)); + I(b,di) <+ cbd*ddt(V(b,di)); + + end // begin + +// `NOISE begin //Define noise sources +// +// end // noise + + end //analog + +endmodule diff --git a/src/spicelib/devices/adms/ex-1/admsva/r2_cmc.va b/src/spicelib/devices/adms/ex-1/admsva/r2_cmc.va new file mode 100644 index 000000000..6ef800311 --- /dev/null +++ b/src/spicelib/devices/adms/ex-1/admsva/r2_cmc.va @@ -0,0 +1,72 @@ +// +// simple capacitor model +// t R i C b +// o——/\/\/——o——| |——o +// + +`include "constants.h" +`include "discipline.h" + +`define P_CELCIUS0 273.15 +`define TNOM (`P_CELCIUS0 + 27.0) + +module r2_cmc(t, b); + inout t, b; + electrical t, b; + electrical i; + branch (t, i) R; + branch (i, b) C; + parameter real w = 1u from (0.1u : +inf); + parameter real l = 1u from (0.1u : +inf); + parameter real nc = 1 from [1:2]; + parameter real rsh = 1 from (0 : +inf); + parameter real ca = 1f from (0 : +inf); + parameter real tcr = 0; + parameter real vc1 = 0; + parameter real vc2 = 0; + parameter real type = 0; // 0=n, 1=p + real dT, rsh_t, c, r, Ir, Qc, Ceff, pwrR; + analog begin : L + if ($port_connected(b) == 0) + $finish(113); + if ($param_given(tcr)) + $finish(4); + if ($param_given(tcr)) + $finish(4); + if (nc > 2) + $finish(0); + begin : initializeModel + dT = $temperature - `TNOM; + rsh_t = rsh*(1.0+tcr*dT); + end + begin : initializeInstance + c = w*l*ca*1e12; // unit conversion + if (nc > 1.5) + r = rsh_t*(w/l)/12; + else + r = rsh_t*(w/l)/3; + end + begin : evaluateStatic + Ir = V(R)/r; + end + begin : evaluateDynamic + if (type > 0.5) // inelegant + Qc = c*V(C)*(1-V(C)*(vc1/2-V(C)*vc2/3)); + else + Qc = c*V(C)*(1+V(C)*(vc1/2+V(C)*vc2/3)); + end + begin : loadStatic + I(R) <+ Ir; + end + begin : loadDynamic + I(C) <+ ddt(Qc); + end + begin : postProcess + if (type > 0.5) + Ceff = c*(1.0-V(C)*(vc1/2-V(C)/3));//error! + else + Ceff = c*(1.0+V(C)*(vc1/2+V(C)/3));//error! + pwrR = V(R)*Ir; + end + end // analog +endmodule diff --git a/src/spicelib/devices/adms/hicum0/admsva/hicum0.va b/src/spicelib/devices/adms/hicum0/admsva/hicum0.va new file mode 100644 index 000000000..81910a8be --- /dev/null +++ b/src/spicelib/devices/adms/hicum0/admsva/hicum0.va @@ -0,0 +1,886 @@ +/* COPYRIGHT NOTE for HICUM Models +downloaded 17.03.2018 from +https://www.iee.et.tu-dresden.de/iee/eb/hic_new/hic_source.html + +The terms under which the HICUM software is provided are as follows: + +Software is distributed as is, completely without warranty or service support. +The Model Owner and his team members are not liable for the condition or +performance of the software. + +Michael Schroter (Model Owner) 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 Model Owner hereby disclaims all implied warranties. + +The Model Owner 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: + + The users agree not to charge for the HICUM code itself but may charge + for additions, extensions, or support. + + In any product based on the software, the users agree to acknowledge + the Model Owner that developed the software. This acknowledgment + shall appear in the product documentation. + + The users agree to reproduce any copyright notice which appears on + the software on any copy or modification of such made available to + others. +*/ + +// HICUM Level_0 Version_1.12: A Verilog-A description +// (A simplified version of HICUM Level2 model for BJT) +// ## It is modified after the first version of HICUM/L0 code ## + +// 12/08: Modifications for ngspice and adms2.2.7 DW +// Changed VT0 in Vt0 to prevent conflict in compiled C version. +// Made a temporary variable cjei_i for cjei output purpose only. + +// Minor code related changes +// 03/08: Quick Fix: Default value of TFH has been changed from infinity to zero and modified the default value limits to [0, inf) to include zero +// 12/06: Upper limit of FGEO is changed to infinity +// 06/06: Thermal node "tnode" set as external +// Flag FLSH introduced for controlling Self-heating calculation +// all if-else blocks marked with begin-end +// all series resistors and RTH are allowed to have a minimum value MIN_R +// 07/06: QCJMOD deleted, QJMODF introduced along with with HICJQ +// ddx() operator used with QJMOD and QJMODF wherever needed +// aj is kept at 2.4 except BE depletion charge +// Substrate transistor transfer current added. +// Gmin added to (bi,ei) and (bi,ci) branches. +// hyperbolic smoothing used in rbi computation to avoid devide-by-zero. + +// ********************************************************************************* +// 06/06: Comment on NODE COLLAPSING: +// Presently this verilog code permits a minimum of 1 milli-Ohm resistance for any +// series resistance as well as for thermal resistance RTH. If any of the resistance +// values drops below this minimum value, the corresponding nodes are shorted with +// zero voltage contribution. We want the model compilers/simulators deal this +// situation in such a manner that the corresponding node is COLLAPSED. +// We expect that the simulators should permit current contribution statement +// for any branch with resistance value more than (or equal to) 1 milli-Ohm without +// any convergence problem. In fact, we wish NOT to have to use a voltage contribution +// statement in our Verilog code, except as an indication for the model compiler/simulator +// to interprete a zero branch voltage as NODE-COLLAPSING action. +// ********************************************************************************** + + +//Default simulator: Spectre + +`ifdef insideADMS + `define P(p) (*p*) + `define PGIVEN(p) $given(p) + `define INITIAL_MODEL @(initial_model) +`else + `define P(p) + `define PGIVEN(p) p + `define INITIAL_MODEL @(initial_step) +`endif + + +//ADS +//`include "constants.vams" +//`include "disciplines.vams" +//`include "compact.vams" + +//Spectre +`include "constants.h" +`include "discipline.h" + + +`define NPN +1 +`define PNP -1 + +`define VPT_thresh 1.0e2 +`define EXPLIM 80.0 +`define INF 1.0e6 +`define TMAX 326.85 +`define TMIN -100.0 +`define MIN_R 0.001 +//`define Gmin 1.0e-12 + +`define QCMODF(vj,cj0,vd,z,aj,cjf)\ + if(cj0 > 0.0) begin\ + vf = vd*(1.0-exp(-ln(aj)/z));\ + xvf = (vf-vj)/VT;\ + xvf2 = sqrt(xvf*xvf+1.921812);\ + v_j = vf-VT*(xvf+xvf2)*0.5;\ + dvj = 0.5*(xvf+xvf2)/xvf2;\ + cjf = cj0*exp(-z*ln(1-v_j/vd))*dvj+aj*cj0*(1-dvj);\ + end else begin\ + cjf = 0.0;\ + end + +// DEPLETION CHARGE CALCULATION +// Hyperbolic smoothing used; no punch-through +`define QJMODF(vj,cj0,vd,z,aj,qjf)\ + if(cj0 > 0.0) begin\ + vf = vd*(1.0-exp(-ln(aj)/z));\ + xvf = (vf-vj)/VT;\ + xvf2 = sqrt(xvf*xvf+1.921812);\ + v_j = vf-VT*(xvf+xvf2)*0.5;\ + x = 1.0-z;\ + y = 1.0-exp(x*ln(1.0-v_j/vd));\ + qjf = cj0*vd*y/x+aj*cj0*(vj-v_j);\ + end else begin\ + qjf = 0.0;\ + end + + +// Depletion Charge : with punch through +`define QJMOD(vj,cj0,vd,z,vpt,aj,qjf)\ + if(cj0 > 0.0) begin\ + zr = z/4.0;\ + vp = vpt-vd;\ + vf = vd*(1.0-exp(-ln(aj)/z));\ + cmax = aj*cj0;\ + cr = cj0*exp((z-zr)*ln(vd/vpt));\ + a = VT;\ + ve = (vf-vj)/a;\ + if (ve <= `EXPLIM) begin\ + ex1 = exp(ve);\ + ee1 = 1.0+ex1;\ + vj1 = vf-a*ln(ee1);\ + end else begin\ + vj1 = vj;\ + end\ + a = 0.1*vp+4.0*VT;\ + vr = (vp+vj1)/a;\ + if (vr <= `EXPLIM) begin\ + ex1 = exp(vr);\ + ee1 = 1.0+ex1;\ + vj2 = -vp+a*ln(ee1);\ + end else begin\ + vj2 = vj1;\ + end\ + vj4 = vj-vj1;\ + ez = 1.0-z;\ + ezr = 1.0-zr;\ + vdj1 = ln(1.0-vj1/vd);\ + vdj2 = ln(1.0-vj2/vd);\ + qj1 = cj0*(1.0-exp(vdj2*ez))/ez;\ + qj2 = cr*(1.0-exp(vdj1*ezr))/ezr;\ + qj3 = cr*(1.0-exp(vdj2*ezr))/ezr;\ + qjf = (qj1+qj2-qj3)*vd+cmax*vj4;\ + end else begin\ + qjf = 0.0;\ + end + + +// DEPLETION CHARGE CALCULATION SELECTOR: +// Dependent on junction punch-through voltage +// Important for collector related junctions +`define HICJQ(vj,cj0,vd,z,vpt,qjf)\ + if(vpt < `VPT_thresh) begin\ + `QJMOD(vj,cj0,vd,z,vpt,2.4,qjf)\ + end else begin\ + `QJMODF(vj,cj0,vd,z,2.4,qjf)\ + end + +//Temperature dependence of depletion capacitance parameters +`define TMPHICJ(cj0,vd,z,vg,cj0_t,vd_t)\ + arg = 0.5*vd/Vt0;\ + vdj0 = 2*Vt0*ln(exp(arg)-exp(-arg));\ + vdjt = vdj0*qtt0+vg*(1-qtt0)-mg*VT*ln_qtt0;\ + vd_t = vdjt+2*VT*ln(0.5*(1+sqrt(1+4*exp(-vdjt/VT))));\ + cj0_t = cj0*exp(z*ln(vd/vd_t)); + + +//Limiting exponential +`define LIN_EXP(le, arg)\ + if(arg > 80) begin\ + le = (1 + ((arg) - 80));\ + arg = 80;\ + end else begin\ + le=1;\ + end\ + le = le*limexp(arg); + +// IDEAL DIODE (WITHOUT CAPACITANCE): +// conductance not calculated +// INPUT: +// IS, IST : saturation currents (model parameter related) +// UM1 : ideality factor +// U : branch voltage +// IMPLICIT INPUT: +// VT : thermal voltage +// OUTPUT: +// Iz : diode current +`define HICDIO(IS,IST,UM1,U,Iz)\ + DIOY = U/(UM1*VT);\ + if (IS > 0.0) begin\ + if (DIOY > 80) begin\ + le = (1 + ((DIOY) - 80));\ + DIOY = 80;\ + end else begin\ + le = 1;\ + end\ + le = le*limexp(DIOY);\ + Iz = IST*(le-1.0);\ + if(DIOY <= -14.0) begin\ + Iz = -IST;\ + end\ + end else begin\ + Iz = 0.0;\ + end + + +module hic0_full (c,b,e,s,tnode); + + +//Node definitions + + inout c,b,e,s,tnode; + electrical c `P(desc="external collector node"); + electrical b `P(desc="external base node"); + electrical e `P(desc="external emitter node"); + electrical s `P(desc="external substrate node"); + electrical ci `P(desc="internal collector node"); + electrical bi `P(desc="internal base node"); + electrical ei `P(desc="internal emitter node"); + electrical tnode `P(desc="local temperature rise node"); + + + //Branch definitions + branch (ci,c) br_cic_i; + branch (ci,c) br_cic_v; + branch (ei,e) br_eie_i; + branch (ei,e) br_eie_v; + branch (bi,ei) br_biei; + branch (bi,ci) br_bici; + branch (ci,ei) br_ciei; + branch (b,bi) br_bbi_i; + branch (b,bi) br_bbi_v; + branch (b,e) br_be; + branch (b,ci) br_bci; + branch (b,s) br_bs; + branch (s,ci) br_sci; + branch (tnode ) br_sht; + +// +// Parameter initialization with default values + +// Collector current + parameter real is = 1.0e-16 from [0:1] `P(spice:name="is" desc="(Modified) saturation current" m:factor="yes" unit="A"); + parameter real mcf = 1.00 from (0:10] `P(spice:name="mcf" desc="Non-ideality coefficient of forward collector current"); + parameter real mcr = 1.00 from (0:10] `P(spice:name="mcr" desc="Non-ideality coefficient of reverse collector current"); + parameter real vef = `INF from (0:`INF] `P(spice:name="vef" desc="forward Early voltage (normalization volt.)" unit="V" default:value="infinity"); + parameter real iqf = `INF from (0:`INF] `P(spice:name="iqf" desc="forward d.c. high-injection toll-off current" unit="A" m:factor="yes" default:value="infinity"); + parameter real iqr = `INF from (0:`INF] `P(spice:name="iqr" desc="inverse d.c. high-injection roll-off current" unit="A" m:factor="yes" default:value="infinity"); + parameter real iqfh = `INF from (0:`INF] `P(spice:name="iqfh" desc="high-injection correction current" unit="A" m:factor="yes"); + parameter real tfh = 0.0 from [0:`INF) `P(spice:name="tfh" desc="high-injection correction factor" test:value="2e-9" m:factor="yes"); + +// Base current + parameter real ibes = 1e-18 from [0:1] `P(spice:name="ibes" desc="BE saturation current" unit="A" m:factor="yes"); + parameter real mbe = 1.0 from (0:10] `P(spice:name="mbe" desc="BE non-ideality factor"); + parameter real ires = 0.0 from [0:1] `P(spice:name="ires" desc="BE recombination saturation current" test:value="1e-16" unit="A" m:factor="yes"); + parameter real mre = 2.0 from (0:10] `P(spice:name="mre" desc="BE recombination non-ideality factor"); + parameter real ibcs = 0.0 from [0:1] `P(spice:name="ibcs" desc="BC saturation current" test:value="1e-16" unit="A" m:factor="yes"); + parameter real mbc = 1.0 from (0:10] `P(spice:name="mbc" desc="BC non-ideality factor"); + +// BE depletion cap + parameter real cje0 = 1.0e-20 from (0:`INF) `P(spice:name="cje0" desc="Zero-bias BE depletion capacitance" unit="F" test:value="2e-14" m:factor="yes"); + parameter real vde = 0.9 from (0:10] `P(spice:name="vde" desc="BE built-in voltage" unit="V"); + parameter real ze = 0.5 from (0:1] `P(spice:name="ze" desc="BE exponent factor"); + parameter real aje = 2.5 from [1:`INF) `P(spice:name="aje" desc="Ratio of maximum to zero-bias value"); + +// Transit time + parameter real t0 = 0.0 from [0:`INF) `P(spice:name="t0" desc="low current transit time at Vbici=0" test:value="5e-12" unit="s"); + parameter real dt0h = 0.0; // from [0:`INF) `P(spice:name="dt0h" desc="Base width modulation contribution" test:value="2e-12" unit="s"); + parameter real tbvl = 0.0 from [0:`INF) `P(spice:name="tbvl" desc="SCR width modulation contribution" test:value="4e-12" unit="s"); + parameter real tef0 = 0.0 from [0:`INF) `P(spice:name="tef0" desc="Storage time in neutral emitter" test:value="1e-12" unit="s"); + parameter real gte = 1.0 from (0:10] `P(spice:name="gte" desc="Exponent factor for emmiter transit time"); + parameter real thcs = 0.0 from [0:`INF) `P(spice:name="thcs" desc="Saturation time at high current densities" test:value="3e-11" unit="s"); + parameter real ahc = 0.1 from (0:10] `P(spice:name="ahc" desc="Smoothing facor for current dependence"); + parameter real tr = 0.0 from [0:`INF) `P(spice:name="tr" desc="Storage time at inverse operation" unit="s"); + +// Critical current + parameter real rci0 = 150 from (0:`INF) `P(spice:name="rci0" desc="Low-field collector resistance under emitter" test:value="50" unit="Ohm" m:inverse_factor="yes"); + parameter real vlim = 0.5 from (0:10] `P(spice:name="vlim" desc="Voltage dividing ohmic and satur.region" unit="V"); + parameter real vpt = 100 from (0:100] `P(spice:name="vpt" desc="Punch-through voltage" test:value="10" unit="V" default="infinity"); + parameter real vces = 0.1 from [0:1] `P(spice:name="vces" desc="Saturation voltage" unit="V"); + +// BC depletion cap intern + parameter real cjci0 = 1.0e-20 from (0:`INF) `P(spice:name="cjci0" desc="Total zero-bias BC depletion capacitance" test:value="1e-15" unit="F" m:factor="yes"); + parameter real vdci = 0.7 from (0:10] `P(spice:name="vdci" desc="BC built-in voltage" test:value="0.7" unit="V"); + parameter real zci = 0.333 from (0:1] `P(spice:name="zci" desc="BC exponent factor" test:value="0.4"); + parameter real vptci = 100 from (0:100] `P(spice:name="vptci" desc="Punch-through voltage of BC junction" test:value="50" unit="V"); + +// BC depletion cap extern + parameter real cjcx0 = 1.0e-20 from [0:`INF) `P(spice:name="cjcx0" desc="Zero-bias external BC depletion capacitance" unit="F" test:value="1e-15" m:factor="yes"); + parameter real vdcx = 0.7 from (0:10] `P(spice:name="vdcx" desc="External BC built-in voltage" unit="V"); + parameter real zcx = 0.333 from (0:1] `P(spice:name="zcx" desc="External BC exponent factor"); + parameter real vptcx = 100 from (0:100] `P(spice:name="vptcx" desc="Punch-through voltage" unit="V" test:value="5.0" default="infinity"); + parameter real fbc = 1.0 from [0:1] `P(spice:name="fbc" desc="Split factor = Cjci0/Cjc0" test:value="0.5"); + +// Base resistance + parameter real rbi0 = 0.0 from [0:`INF) `P(spice:name="rbi0" desc="Internal base resistance at zero-bias" test:value="100" unit="Ohm" m:inverse_factor="yes"); + parameter real vr0e = 2.5 from (0:`INF] `P(spice:name="vr0e" desc="forward Early voltage (normalization volt.)" unit="V"); + parameter real vr0c = `INF from (0:`INF] `P(spice:name="vr0c" desc="forward Early voltage (normalization volt.)" unit="V" default="infinity" test:value="25.0"); + parameter real fgeo = 0.656 from [0:`INF] `P(spice:name="fgeo" desc="Geometry factor" test:value="0.73"); + +// Series resistances + parameter real rbx = 0.0 from [0:`INF) `P(spice:name="rbx" desc="External base series resistance" test:value="8.8" unit="Ohm" m:inverse_factor="yes"); + parameter real rcx = 0.0 from [0:`INF) `P(spice:name="rcx" desc="Emitter series resistance" test:value="12.5" unit="Ohm" m:inverse_factor="yes"); + parameter real re = 0.0 from [0:`INF) `P(spice:name="re" desc="External collector series resistance" test:value="9.16" unit="Ohm" m:inverse_factor="yes"); + +// Substrate transfer current, diode current and cap + parameter real itss = 0.0 from [0:1.0] `P(spice:name="itss" desc="Substrate transistor transfer saturation current" unit="A" test:value="1e-17" m:factor="yes"); + parameter real msf = 1.0 from (0:10] `P(spice:name="msf" desc="Substrate transistor transfer current non-ideality factor"); + parameter real iscs = 0.0 from [0:1.0] `P(spice:name="iscs" desc="SC saturation current" unit="A" test:value="1e-17" m:factor="yes"); + parameter real msc = 1.0 from (0:10] `P(spice:name="msc" desc="SC non-ideality factor"); + parameter real cjs0 = 1.0e-20 from [0:`INF) `P(spice:name="cjs0" desc="Zero-bias SC depletion capacitance" unit="F" test:value="1e-15" m:factor="yes"); + parameter real vds = 0.3 from (0:10] `P(spice:name="vds" desc="SC built-in voltage" unit="V"); + parameter real zs = 0.3 from (0:1] `P(spice:name="zs" desc="External SC exponent factor"); + parameter real vpts = 100 from (0:100] `P(spice:name="vpts" desc="SC punch-through voltage" unit="V" test:value="5.0" default="infinity"); + +// Parasitic caps + parameter real cbcpar = 0.0 from [0:`INF) `P(spice:name="cbcpar" desc="Collector-base isolation (overlap) capacitance" unit="F" m:factor="yes" test:value="1e-15"); + parameter real cbepar = 0.0 from [0:`INF) `P(spice:name="cbepar" desc="Emitter-base oxide capacitance" unit="F" m:factor="yes" test:value="2e-15"); + +// BC avalanche current + parameter real eavl = 0.0 from [0:inf) `P(spice:name="eavl" desc="Exponent factor" test:value="1e-14"); + parameter real kavl = 0.0 from [0:`INF) `P(spice:name="kavl" desc="Prefactor" test:value="1.19"); + +// Flicker noise + parameter real kf = 0.0 from [0:`INF) `P(spice:name="kf" desc="flicker noise coefficient" unit="M^(1-AF)"); + parameter real af = 2.0 from (0:10] `P(spice:name="af" desc="flicker noise exponent factor"); + +// Temperature dependance + parameter real vgb = 1.2 from (0:10] `P(spice:name="vgb" desc="Bandgap-voltage" unit="V" test:value="1.17"); + parameter real vge = 1.17 from (0:10] `P(spice:name="vge" desc="Effective emitter bandgap-voltage" unit="V" test:value="1.07"); + parameter real vgc = 1.17 from (0:10] `P(spice:name="vgc" desc="Effective collector bandgap-voltage" unit="V" test:value="1.14"); + parameter real vgs = 1.17 from (0:10] `P(spice:name="vgs" desc="Effective substrate bandgap-voltage" unit="V" test:value="1.17"); + parameter real f1vg =-1.02377e-4 `P(spice:name="f1vg" desc="Coefficient K1 in T-dependent bandgap equation" unit="V/K"); + parameter real f2vg = 4.3215e-4 `P(spice:name="f2vg" desc="Coefficient K2 in T-dependent bandgap equation" unit="V/K"); + parameter real alt0 = 0.0 `P(spice:name="alt0" desc="Frist-order TC of tf0" unit="1/K"); + parameter real kt0 = 0.0 `P(spice:name="kt0" desc="Second-order TC of tf0" unit="1/K^2"); + parameter real zetact = 3.0 `P(spice:name="zetact" desc="Exponent coefficient in transfer current temperature dependence" test:value="3.5"); + parameter real zetabet = 3.5 `P(spice:name="zetabet" desc="Exponent coefficient in BE junction current temperature dependence" test:value="4.0"); + parameter real zetaci = 0.0 `P(spice:name="zetaci" desc="TC of epi-collector diffusivity" test:value="1.6"); + parameter real alvs = 0.0 `P(spice:name="alvs" desc="Relative TC of satur.drift velocity" unit="1/K" test:value="1e-3"); + parameter real alces = 0.0 `P(spice:name="alces" desc="Relative TC of vces" unit="1/K" test:value="4e-4"); + parameter real zetarbi = 0.0 `P(spice:name="zetarbi" desc="TC of internal base resistance" test:value="0.6"); + parameter real zetarbx = 0.0 `P(spice:name="zetarbx" desc="TC of external base resistance" test:value="0.2"); + parameter real zetarcx = 0.0 `P(spice:name="zetarcx" desc="TC of external collector resistance" test:value="0.2"); + parameter real zetare = 0.0 `P(spice:name="zetare" desc="TC of emitter resistances"); + parameter real alkav = 0.0 `P(spice:name="alkav" desc="TC of avalanche prefactor" unit="1/K"); + parameter real aleav = 0.0 `P(spice:name="aleav" desc="TC of avalanche exponential factor" unit="1/K"); + +// Self-heating + parameter integer flsh = 0 from [0:2] `P(spice:name="flsh" desc="Flag for self-heating calculation" test:value="2"); + parameter real rth = 0.0 from [0:`INF) `P(spice:name="rth" desc="Thermal resistance" test:value="200.0" unit="K/W" m:inverse_factor="yes"); + parameter real cth = 0.0 from [0:`INF) `P(spice:name="cth" desc="Thermal capacitance" test:value="0.1" unit="Ws/K" m:factor="yes"); + +// Transistor type + parameter integer npn = 1 from [0:1] `P(spice:isflag="yes" desc="model type flag for npn" ); + parameter integer pnp = 0 from [0:1] `P(desc="model type flag for pnp" ); + +//Circuit simulator specific parameters + parameter real tnom = 27 `P(spice:name="tnom" desc="Temperature for which parameters are valid" unit="C"); + parameter real dt = 0.0 `P(spice:name="dt" type="instance" desc="Temperature change for particular transistor" unit="K"); + + +// Declaration of the variables: begin + + real HICUMtype `P(spice:name="type" /* desc="Device type from npn or pnp flags" unit="no" */); + + // QCJMOD + real cj0,vd,z,aj; + real zr,vp; + real cmax,cr,ve; + real ee1,ez,ezr,vdj1,vdj2,ex1,vr,vj1,vj2,vj4; + real qj1,qj2,qj3,qjf; + + + //Cjfun *** VT, removed: BA + real cj1,cj2,cj3,cjf; + + + //cjtfun *** tnom,VT,mg,Vt0, removed: BA + real vg; + real vdj0,vdjt,cj0_t,vd_t,aj_t; + + + // temperature and drift + real VT,Tamb,Tdev,Tnom,dT,qtt0,ln_qtt0; + real vde_t,vdci_t,vdcx_t,vds_t; + real is_t,ires_t,ibes_t,ibcs_t; + real itss_t,iscs_t,cje0_t,cjci0_t,cjcx0_t; + real cjs0_t,rci0_t,vlim_t; + real vces_t,thcs_t,tef0_t,rbi0_t; + real rbx_t,rcx_t,re_t,t0_t,eavl_t,kavl_t; + real aje_t; + + // bc charge and cap + real qjci `P(desc="B-C internal junction charge" unit="C"); + real qjcx,qjcii,cjcii,qjcxi,qjciii; //cjcx + real cjci0_t_ii,cjcx0_t_ii,cjcx0_t_i,v_j; + + // be junction + real qjei `P(desc="B-E internal junction charge" unit="C"); + real cjei_i `P(desc="B-E internal junction capacitance" unit="F"); // dw: adms2.2.7 problem + real cjei,vf,vj,x,y,e1,e2; + + // transfer and internal base current + real cc,qj_2,facl; + real tf0,ickf,ickr,itfi,itri,qm; + real qpt,itf,itr; + real it `P(desc="Transfer Current" unit="A"); + real ibe,ire,ibi; + real itfl,itrl,al,s3l,wl,d_qfh; + + // be diffusion charge + real qf,qf0,dqfh,dqef; + real dtef,dtfh,tf,ick; + real vc,vceff,s3,w,a,tww; + + // bc diffusion charge + real qr; + + // avalanche current source + real v_bord,a_iavl,lncc; + + // base resistance + real rb,eta,rbi,qje,Qz_nom,fQz; + + // substrate transistor, diode and cap + real qjs,HSa,HSb,HSI_Tsu,HSUM; + + // self heating + real pterm; + + // new for temperature dependence + real mg,zetabci,zetasct,zetatef,avs; + real k1,k2,vgbe,vgbc,vgsc,dvg; + real xvf,xvf2,dvj,uvc,Vt0; + + // noise + real flicker_Pwr,fourkt,twoq; + + // LIN_EXP + real le,arg,le1,arg1,le2,arg2; + + //HICDIO + real IS,IST,UM1,U,Iz,DIOY; + + // branch voltages + real Vbci,Vbici,Vbiei,Vciei,Vsci,Veie,Vbbi,Vcic,Vbe,Vrth; + + //Output to be seen + real ijbc `P(desc="Base-collector diode current" unit="A"); + real iavl `P(desc="Avalanche current" unit="A"); + real ijsc `P(desc="Substrate-collector diode current" unit="A"); + real Ieei `P(desc="Current through external to internal emitter node" unit="A"); + real Icci `P(desc="Current through external to internal collector node" unit="A"); + real Ibbi `P(desc="Current through external to internal base node" unit="A"); + real Ibici `P(desc="Base-collector diode current minus the avalanche current" unit="A"); + real ijbe `P(desc="Base-emitter diode current" unit="A"); + + real Qbci,Qbe,Qbici,Qbiei; +//Declaration of the variables: end + + +// +//======================== calculation of the transistor =================== +// + +analog begin + +// assign voltages with regard to transistor type + + `INITIAL_MODEL + begin + if (`PGIVEN(npn)) + HICUMtype = `NPN; + else if (`PGIVEN(pnp)) + HICUMtype = `PNP; + else + HICUMtype = `NPN; + end + + Vbci = HICUMtype*V(br_bci); + Vbici = HICUMtype*V(br_bici); + Vbiei = HICUMtype*V(br_biei); + Vciei = HICUMtype*V(br_ciei); + Vsci = HICUMtype*V(br_sci); + Veie = V(br_eie_v); + Vcic = V(br_cic_v); + Vbbi = V(br_bbi_v); + Vbe = HICUMtype*V(br_be); + Vrth = V(br_sht); + + + +// +// temperature and resulting parameter drift +// + + Tnom = tnom+273.15; + Tamb = $temperature; + Tdev = Tamb+dt+Vrth; + +// Limit temperature to avoid FPE's in equations + if(Tdev < `TMIN + 273.15) begin + Tdev = `TMIN + 273.15; + end else begin + if (Tdev > `TMAX + 273.15) begin + Tdev = `TMAX + 273.15; + end + end + + Vt0 = `P_K*Tnom /`P_Q; + VT = `P_K*Tdev /`P_Q; + dT = Tdev-Tnom; + qtt0 = Tdev/Tnom; + ln_qtt0 = ln(qtt0); + k1 = f1vg*Tnom; + k2 = f2vg*Tnom+k1*ln(Tnom); + avs = alvs*Tnom; + vgbe = (vgb+vge)/2; + vgbc = (vgb+vgc)/2; + vgsc = (vgs+vgc)/2; + mg = 3-`P_Q*f1vg/`P_K; + zetabci = mg+1-zetaci; + zetasct = mg-1.5; //+1-m_upS with m_upS=2.5 + is_t = is*exp(zetact*ln_qtt0+vgb/VT*(qtt0-1)); + ibes_t = ibes*exp(zetabet*ln_qtt0+vge/VT*(qtt0-1)); + ires_t = ires*exp(0.5*mg*ln_qtt0+0.5*vgbe/VT*(qtt0-1)); + ibcs_t = ibcs*exp(zetabci*ln_qtt0+vgc/VT*(qtt0-1)); + itss_t = itss*exp(zetasct*ln_qtt0+vgc/VT*(qtt0-1)); + iscs_t = iscs*exp(zetasct*ln_qtt0+vgs/VT*(qtt0-1)); + `TMPHICJ(cje0,vde,ze,vgbe,cje0_t,vde_t) + aje_t = aje*vde_t/vde; + `TMPHICJ(cjci0,vdci,zci,vgbc,cjci0_t,vdci_t) + `TMPHICJ(cjcx0,vdcx,zcx,vgbc,cjcx0_t,vdcx_t) + `TMPHICJ(cjs0,vds,zs,vgsc,cjs0_t,vds_t) + rci0_t = rci0*exp(zetaci*ln_qtt0); + vlim_t = vlim*exp((zetaci-avs)*ln_qtt0); + vces_t = vces*(1+alces*dT); + t0_t = t0*(1+alt0*dT+kt0*dT*dT); + thcs_t = thcs*exp((zetaci-1)*ln_qtt0); + zetatef = zetabet-zetact-0.5; + dvg = vgb-vge; + tef0_t = tef0*exp(zetatef*ln_qtt0-dvg/VT*(qtt0-1)); + rbx_t = rbx*exp(zetarbx*ln_qtt0); + rcx_t = rcx*exp(zetarcx*ln_qtt0); + rbi0_t = rbi0*exp(zetarbi*ln_qtt0); + re_t = re*exp(zetare*ln_qtt0); + eavl_t = eavl*exp(aleav*dT); + kavl_t = kavl*exp(alkav*dT); + + +// +// Calculation of intrinsic transistor elements +// + +// BC charge and cap (internal and external) + +// The cjcx0 value is used to switch between one (cjcx0=0) and two bc parameter sets +// 1. For one parameter set only the internal bc set is partitioned by fbc +// 2. For two independent sets only the external set is partitioned by fbc + + if (cjcx0_t==0) begin + cjci0_t_ii = cjci0_t*fbc; // zero bias internal portion + qjcxi = 0; + cjcx0_t_i = cjci0_t*(1-fbc); // zero bias external portion + `HICJQ(Vbci,cjcx0_t_i,vdci_t,zci,vptci,qjcx) + end else begin + cjci0_t_ii = cjci0_t; // zero bias internal portion + cjcx0_t_ii = cjcx0_t*fbc; + `HICJQ(Vbici,cjcx0_t_ii,vdcx_t,zcx,vptcx,qjcxi) + cjcx0_t_i = cjcx0_t*(1-fbc); // zero bias external portion + `HICJQ(Vbci,cjcx0_t_i,vdcx_t,zcx,vptcx,qjcx) + end + `HICJQ(Vbici,cjci0_t_ii,vdci_t,zci,vptci,qjci) + qjcii = qjci+qjcxi; + +//Internal bc cap without punch through for cc + + //`HICJQ(Vbici,cjci0_t_ii,vdci_t,zci,100,qjciii) + `QCMODF(Vbici,cjci0_t_ii,vdci_t,zci,2.4,cjcii) + //cjcii = ddx(qjciii,V(bi)); + +//Internal be cap and charge + + `QJMODF(Vbiei,cje0_t,vde_t,ze,aje_t,qjei) + cjei = ddx(qjei,V(bi)); + cjei_i = cjei; // dw: adms2.2.7 problem + +// Critical current: ick + vc = Vciei-vces_t; + uvc = vc/VT-1; + vceff = VT*(1+0.5*(uvc+sqrt(uvc*uvc+1.921812))); + x = (vceff-vlim_t)/vpt; + ick = vceff*(1+0.5*(x+sqrt(x*x+1e-3)))/rci0_t/sqrt(1+vceff*vceff/vlim_t/vlim_t); + +// Transfer current + +// Normalized BC cap and carge + cc = cjci0_t_ii/cjcii; + qjci = qjci/cjci0_t_ii; + qj_2 = (1+qjci/vef)/2; + +// Minority charge transit time + tf0 = t0_t+dt0h*(cc-1)+tbvl*(1/cc-1); + +// DC critical currents + ickf = iqf; + ickr = iqr; + +// Ideal transfer currents + arg1 = Vbiei/(mcf*VT); + `LIN_EXP(le1,arg1) + itfi=is_t*le1; + + arg2 = Vbici/(mcr*VT); + `LIN_EXP(le2,arg2) + itri=is_t*le2; + + +// Normalized minority charge + qm = (itfi/ickf+itri/ickr); + +// Normalized total hole charge + qpt = qj_2+sqrt((qj_2)*(qj_2)+qm); + if (qpt<=1e-20) begin + qpt=1e-20; + end + +// Low transfer current + itfl = itfi/qpt; + itrl = itri/qpt; + +// Normalized injection width with low transfer current +// and normalized charge component + if (itfl<=1e-20) begin + itfl = 1e-20; + end + al = 1-ick/itfl; + s3l = sqrt(al*al+ahc); + wl = (al+s3l)/(1+sqrt(1+ahc)); + d_qfh = (wl*wl+tfh*itfl/ick)*itfl/iqfh; + +// Transfer current + facl = 1/(1+d_qfh/qpt); + itf = itfl*facl; + itr = itrl*facl; + if (itf<=1e-20) begin + itf = 1e-20; + end + it = itf-itr; + +// BE diffusion charge + +// Calculation of low-current portion + qf0 = tf0*itf; + +// Current dependent component + a = 1-ick/itf; + s3 = sqrt(a*a+ahc); + w = (a+s3)/(1+sqrt(1+ahc)); + tww = thcs_t*w*w; + dqfh = tww*itf; + dtfh = tww*(1+2*ick/itf/s3); + +// Emitter component + dtef = tef0_t*exp(gte*ln(itf/ick)); + dqef = dtef*itf/(gte+1.0); + +// Total minority charge and transit time + qf = qf0+dqef+dqfh; + tf = tf0+dtfh+dtef; + +// BC diffusion charge + qr = tr*itr; + +// Internal base current + +// BE diode + `HICDIO(ibes,ibes_t,mbe,Vbiei,ibe) + `HICDIO(ires,ires_t,mre,Vbiei,ire) + ijbe = ibe+ire; + +// BC diode + `HICDIO(ibcs,ibcs_t,mbc,Vbici,ijbc) + +// Total base current + ibi = ijbe+ijbc; + +// Avalanche current + + if (Vbici < 0) begin : HICAVL + v_bord = eavl_t*vdci_t; + if (vdci_t-Vbici>v_bord) begin + a_iavl = kavl_t/vdci_t*exp(-cc); + iavl = itf*a_iavl*(v_bord+(1+cc)*(vdci_t-Vbici-v_bord)); + end else begin + lncc = ln(1/cc); + iavl = kavl_t*itf*exp(-1/zci*lncc-eavl_t*exp((1/zci-1)*lncc)); + end + end else begin + iavl = 0; + end + +// +// Additional elements for external transistor +// + +// Base resistance + if(rbi0_t > 0.0) begin : HICRBI + // Conductivity modulation with hyperbolic smoothing + qje = qjei/cje0_t; + Qz_nom = 1+qje/vr0e+qjci/vr0c+itf/ickf+itr/ickr; + fQz = 0.5*(Qz_nom+sqrt(Qz_nom*Qz_nom+0.01));; + rbi = rbi0_t/fQz; + // Emitter current crowding + if (ibi > 0.0) begin + eta = fgeo*rbi*ibi/VT; + if (eta < 1e-6) begin + rbi = rbi*(1-0.5*eta); + end else begin + rbi = rbi*ln(eta+1)/eta; + end + end + end else begin + rbi = 0.0; + end + // Total base resistance + rb = rbi+rbx_t; + +// Parasitic substrate transistor transfer current + if(itss > 0.0) begin : Sub_Transfer + HSUM = msf*VT; + HSa = limexp(Vbci/HSUM); + HSb = limexp(Vsci/HSUM); + HSI_Tsu = itss_t*(HSa-HSb); + end else begin + HSI_Tsu = 0.0; + end + +// Substrate diode and cap and charge + + `HICDIO(iscs,iscs_t,msc,Vsci,ijsc) + + `HICJQ(Vsci,cjs0_t,vds_t,zs,vpts,qjs) + +// Self heating + + if (flsh == 1 && rth >= `MIN_R) begin + pterm = it*Vciei+iavl*(vdci_t-Vbici); + end else if (flsh == 2 && rth >= `MIN_R) begin + pterm = Vciei*it + (vdci_t-Vbici)*iavl + ijbe*Vbiei + ijbc*Vbici + ijsc*Vsci; + if (rb >= `MIN_R) begin + pterm = pterm + Vbbi*Vbbi/rb; + end + if (re_t >= `MIN_R) begin + pterm = pterm + Veie*Veie/re_t; + end + if (rcx_t >= `MIN_R) begin + pterm = pterm + Vcic*Vcic/rcx_t; + end + end + +// +// Compute branch sources +// + + Ibici = ijbc - iavl; + + Qbci = cbcpar*Vbci; + Qbe = cbepar*Vbe; + Qbici = qjcii+qr; + Qbiei = qjei+qf; + + ijsc = HICUMtype*ijsc; + qjs = HICUMtype*qjs; + qjcx = HICUMtype*qjcx; + Qbci = HICUMtype*Qbci; + Qbe = HICUMtype*Qbe; + + Ibici = HICUMtype*Ibici; + Qbici = HICUMtype*Qbici; + ijbe = HICUMtype*ijbe; + Qbiei = HICUMtype*Qbiei; + it = HICUMtype*it; + +// +// Define branch sources +// + I(br_biei) <+ $simparam("gmin")*V(br_biei); + I(br_bici) <+ $simparam("gmin")*V(br_bici); + + I(br_bs) <+ HSI_Tsu; + I(br_sci) <+ ijsc + $simparam("gmin")*V(br_sci); //`P(spectre:gmin="add" spectre:pwl_passive="1e10"); + I(br_sci) <+ ddt(qjs); + I(br_bci) <+ ddt(qjcx); + I(br_bci) <+ ddt(Qbci); + I(br_be) <+ ddt(Qbe); + if (re >= `MIN_R) begin + I(br_eie_i) <+ Veie/re_t + $simparam("gmin")*V(br_eie_i);//`P(spectre:gmin="add"); + end else begin + V(br_eie_v) <+ 0.0; + end + if (rcx >= `MIN_R) begin + I(br_cic_i) <+ Vcic/rcx_t + $simparam("gmin")*V(br_cic_i);//`P(spectre:gmin="add"); + end else begin + V(br_cic_v) <+ 0.0; + end + if (rbi0 >= `MIN_R || rbx >= `MIN_R) begin + I(br_bbi_i) <+ Vbbi/rb + $simparam("gmin")*V(br_bbi_i); //`P(spectre:gmin="add"); + end else begin + V(br_bbi_v) <+ 0.0; + end + I(br_bici) <+ Ibici + $simparam("gmin")*V(br_bici); //`P(spectre:gmin="add" spectre:pwl_sat_current="IMAX" spectre:pwl_sat_cond="imax/0.025" spectre:pwl_rev_current="imax" spectre:pwl_rev_cond="IMAX/0.025"); + I(br_bici) <+ ddt(Qbici); + I(br_biei) <+ ijbe + $simparam("gmin")*V(br_biei); //`P(spectre:gmin="add" spectre:pwl_fwd_current="IBEIS*exp(25.0)" spectre:pwl_fwd_node="bi" spectre:pwl_fwd_cond="IBEIS*exp(25.0)/0.025" spectre:pwl_sat_current="IMAX" spectre:pwl_sat_cond="IMAX/0.025" spectre:pwl_passive="1e10"); + I(br_biei) <+ ddt(Qbiei); + I(br_ciei) <+ it `P(spectre:pwl_fwd_current="IS*exp(25.0)" spectre:pwl_fwd_node="bi" spectre:pwl_fwd_cond="IS*exp(25.0)/0.025" spectre:pwl_rev_current="IMAX" spectre:pwl_rev_cond="IMAX/0.025" spectre:pwl_passive="1e10"); + + // Following code is an intermediate solution: + // ****************************************** + if(flsh == 0 || rth < `MIN_R) begin + I(br_sht) <+ Vrth/`MIN_R; + end else begin + I(br_sht) <+ Vrth/rth-pterm + $simparam("gmin")*V(br_sht);//`P(spectre:gmin="add"); + I(br_sht) <+ ddt(cth*Vrth); + end + // ****************************************** + // For simulators having no problem with V(br_sht) <+ 0.0 + // with external thermal node, follwing code may be used. + // This external thermal node should remain accessible. + // ******************************************** + //if(flsh == 0 || rth < `MIN_R) begin + // V(br_sht) <+ 0.0; + //end else begin + // I(br_sht) <+ Vrth/rth-pterm `P(spectre:gmin="add"); + // I(br_sht) <+ ddt(cth*Vrth); + //end + // ******************************************** + +// Noise sources +// Thermal noise + fourkt = 4.0 * `P_K * Tdev; + if(rbx >= `MIN_R || rbi0 >= `MIN_R) begin + I(br_bbi_i) <+ white_noise(fourkt/rb); + end + if(rcx >= `MIN_R) begin + I(br_cic_i) <+ white_noise(fourkt/rcx_t); + end + if(re >= `MIN_R) begin + I(br_eie_i) <+ white_noise(fourkt/re_t); + end + +// Shot noise + twoq = 2.0 * `P_Q; + I(br_biei) <+ white_noise(twoq*ijbe); + I(br_ciei) <+ white_noise(twoq*it); + +// Flicker noise + flicker_Pwr = kf*pow(ijbe,af); + I(br_biei) <+ flicker_noise(flicker_Pwr,1.0); + +end // analog +endmodule diff --git a/src/spicelib/devices/adms/hicum2/admsva/hicum2.va b/src/spicelib/devices/adms/hicum2/admsva/hicum2.va new file mode 100644 index 000000000..5edd78e67 --- /dev/null +++ b/src/spicelib/devices/adms/hicum2/admsva/hicum2.va @@ -0,0 +1,1690 @@ +/* COPYRIGHT NOTE for HICUM Models +downloaded 17.03.2018 from +https://www.iee.et.tu-dresden.de/iee/eb/hic_new/hic_source.html + +The terms under which the HICUM software is provided are as follows: + +Software is distributed as is, completely without warranty or service support. +The Model Owner and his team members are not liable for the condition or +performance of the software. + +Michael Schroter (Model Owner) 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 Model Owner hereby disclaims all implied warranties. + +The Model Owner 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: + + The users agree not to charge for the HICUM code itself but may charge + for additions, extensions, or support. + + In any product based on the software, the users agree to acknowledge + the Model Owner that developed the software. This acknowledgment + shall appear in the product documentation. + + The users agree to reproduce any copyright notice which appears on + the software on any copy or modification of such made available to + others. +*/ + + + +//HICUM Level_2 Version_2.24: A Verilog-A Description + +//dw 09/10: Modifications for ngspice and adms: +// backup to ddx for capacitance calculation +// all V(...) <+ 0.0; are replaced by I(...) < V(...)/`MIN_R; +// using GMIN from ngspice: $simparam("gmin") +// switch of section for correlated noise (see below) +// removed obsolete variables S_avl, f_p +// don't like internal variable declaration + +//**************New Implementations***************** + +//****************************************************************************** +//This code contains a Verilog-A implementation of Vertical Non-Quasi-Static(NQS) +//Effects using adjunct gyrator networks. To turn on this effect please set FLNQS=1. +//Although Vertical NQS effects have been taken into account in HICUM from the very +//beginning (see original FTN code and built-in v2.1 HICUM model inside most of the +//existing circuit simulators) their implementation has been based on Weil's approach. +//However, using Verilog, it is presently not possible to implement Weil's approach, +//since there does not exist access to previous time-steps of the simulatior. +//The nearly available Verilog-A solution reproduces the results of previous +//HICUM versions (cf. documentation). +//****************************************************************************** + +//****************************************************************************** +// Implementation of noise correlation +// Please turn-off (by front slash “//”) the noise correlation code section for simulation with Spectre +//****************************************************************************** + +// ***************Bug fix and optimization************* +// 12/09: Elimination of 'ddx' operator for internal capacitance determination +// Capacitances will be calculated by Analytical Equations +// 10/09: Temperature coefficient (ZETAxyz) range modified to [-10:10] +// 09/09: VPT ranges modified from [0:inf] to (0:inf] +// 07/09: DT0H rabge modified from no range to (-inf:inf) +// 03/09: Simplified input NQS adjacent circuit (RC network) +// 04/08: New range has been defined for FDQR0. +// 11/07: Bugs have been fixed in macro HICFCI and HICQFC +// 10/06: in @(initial_model), external if-block for HICTUN_T removed +// 11/06: within HICQFC, minor changes made for LATB<=0.01; +// also HICFCI and HICFCT are changed accordingly +// to ensure correct derivatives +// Upper limit of FGEO parameter was changed to infinity. +// 12/06: expressions for Cdei and Cdci are corrected not to include +// Ccdei and Cbdci respectively (used in Crbi expression). + +// 01/06: FCdf1_dw assigned expression (missing in v2.21) +// FCa and FCa1 are found to have same expression: FCa is omitted in those cases +// FCa1 written instead of FCa in the expression for FCf_ci +// Thermal node "tnode" set as external +// zetasct = mg+1-2.5 changed to zetasct = mg-1.5; +// Code optimization: Temperature dependent parts are moduled in two separate blocks: +// within @(initial_model) when self-heating is OFF +// outside @(initial_model) when self-heating is ON +// 03/06 : Further fix +// vlim_t,ibcis_t,ibcxs_t,itss_t,iscs_t considered in compatibility block +// ddt() operators are separated in contribution expressions. +// FLCOMP parameter is given different values +// 05/06: +// all if-else blocks marked with begin-end +// unused variables deleted +// all series resistors and RTH are allowed to have a minimum value MIN_R +// only tunelling current source contribution within if-then-else +// 06/06: HICRBI deleted and instead the code changed (hyperbolic smoothing in +// conductivity modulation part) and put in relevant portion of the code. +// 07/06: ddx() operator used to find out capacitances from charges: +// QJMODF,QJMOD,HICJQ changed accordingly +// Lateral NQS effect modified with ddx() operator. +// HICFCT included for downward compatibility reason. +// Few macros are taken inside the code: HICICK, HICAVL, HICTUN (more optimized), +// internal base resistance (Qjci included under conductivity modulation, hyperbolic smoothing used) +// Gmin added at (bi,ei) and (bi,ci) branches. +// 08/06: Units added in the parameter descriptions. + +// ********************************************************************************* +// 06/06: Comment on NODE COLLAPSING: +// Presently this verilog code permits a minimum of 1 milli-Ohm resistance for any +// series resistance as well as for thermal resistance RTH. If any of the resistance +// values drops below this minimum value, the corresponding nodes are shorted with +// zero voltage contribution. We want the model compilers/simulators deal this +// situation in such a manner that the corresponding node is COLLAPSED. +// We expect that the simulators should permit current contribution statement +// for any branch with resistance value more than (or equal to) 1 milli-Ohm without +// any convergence problem. In fact, we wish NOT to have to use a voltage contribution +// statement in our Verilog code, except as an indication for the model compiler/simulator +// to interprete a zero branch voltage as NODE-COLLAPSING action. +// ********************************************************************************** + + +//Default simulator: Spectre + +`ifdef insideADMS + `define MODEL @(initial_model) + `define NOISE @(noise) + `define ATTR(txt) (*txt*) +`else + `define MODEL + `define NOISE + `define ATTR(txt) +`endif + + +`define VPT_thresh 1.0e2 +`define Dexp_lim 80.0 +`define Cexp_lim 80.0 +`define DFa_fj 1.921812 +`define RTOLC 1.0e-5 +`define l_itmax 100 +`define TMAX 326.85 +`define TMIN -100.0 +`define LN_EXP_LIMIT 11.0 +`define MIN_R 0.001 +//`define Gmin 1.0e-12 +//`define Gmin $simparam("gmin",1e-12) //suggested by L.L + +//ADS +//`include "constants.vams" +//`include "disciplines.vams" +//`include "compact.vams" + +//Spectre +`include "constants.h" +`include "discipline.h" + +//////////////Explicit Capacitance and Charge Expression/////////////// + +// DEPLETION CHARGE CALCULATION +// Hyperbolic smoothing used; no punch-through +// INPUT: +// c_0 : zero-bias capacitance +// u_d : built-in voltage +// z : exponent coefficient +// a_j : control parameter for C peak value at high forward bias +// U_cap : voltage across junction +// IMPLICIT INPUT: +// VT : thermal voltage +// OUTPUT: +// Qz : depletion Charge +// C : depletion capacitance +`define QJMODF(c_0,u_d,z,a_j,U_cap,C,Qz)\ + if(c_0 > 0.0) begin\ + DFV_f = u_d*(1.0-exp(-ln(a_j)/z));\ + DFv_e = (DFV_f-U_cap)/VT;\ + DFs_q = sqrt(DFv_e*DFv_e+`DFa_fj);\ + DFs_q2 = (DFv_e+DFs_q)*0.5;\ + DFv_j = DFV_f-VT*DFs_q2;\ + DFdvj_dv = DFs_q2/DFs_q;\ + DFb = ln(1.0-DFv_j/u_d);\ + DFC_j1 = c_0*exp(-z*DFb)*DFdvj_dv;\ + C = DFC_j1+a_j*c_0*(1.0-DFdvj_dv);\ + DFQ_j = c_0*u_d*(1.0-exp(DFb*(1.0-z)))/(1.0-z);\ + Qz = DFQ_j+a_j*c_0*(U_cap-DFv_j);\ + end else begin\ + C = 0.0;\ + Qz = 0.0;\ + end + +//////////////////////////////////////////////////////////////// + + +//////////////Explicit Capacitance and Charge Expression/////////////// + + +// DEPLETION CHARGE CALCULATION CONSIDERING PUNCH THROUGH +// smoothing of reverse bias region (punch-through) +// and limiting to a_j=Cj,max/Cj0 for forward bias. +// Important for base-collector and collector-substrate junction +// INPUT: +// c_0 : zero-bias capacitance +// u_d : built-in voltage +// z : exponent coefficient +// a_j : control parameter for C peak value at high forward bias +// v_pt : punch-through voltage (defined as qNw^2/2e) +// U_cap : voltage across junction +// IMPLICIT INPUT: +// VT : thermal voltage +// OUTPUT: +// Qz : depletion charge +// C : depletion capacitance +`define QJMOD(c_0,u_d,z,a_j,v_pt,U_cap,C,Qz)\ + if(c_0 > 0.0) begin\ + Dz_r = z/4.0;\ + Dv_p = v_pt-u_d;\ + DV_f = u_d*(1.0-exp(-ln(a_j)/z));\ + DC_max = a_j*c_0;\ + DC_c = c_0*exp((Dz_r-z)*ln(v_pt/u_d));\ + Dv_e = (DV_f-U_cap)/VT;\ + if(Dv_e < `Cexp_lim) begin\ + De = exp(Dv_e);\ + De_1 = De/(1.0+De);\ + Dv_j1 = DV_f-VT*ln(1.0+De);\ + end else begin\ + De_1 = 1.0;\ + Dv_j1 = U_cap;\ + end\ + Da = 0.1*Dv_p+4.0*VT;\ + Dv_r = (Dv_p+Dv_j1)/Da;\ + if(Dv_r < `Cexp_lim) begin\ + De = exp(Dv_r);\ + De_2 = De/(1.0+De);\ + Dv_j2 = -Dv_p+Da*ln(1.0+De);\ + end else begin\ + De_2 = 1.0;\ + Dv_j2 = Dv_j1;\ + end\ + Dv_j4 = U_cap-Dv_j1;\ + DCln1 = ln(1.0-Dv_j1/u_d);\ + DCln2 = ln(1.0-Dv_j2/u_d);\ + Dz1 = 1.0-z;\ + Dzr1 = 1.0-Dz_r;\ + DC_j1 = c_0*exp(DCln2*(-z))*De_1*De_2;\ + DC_j2 = DC_c*exp(DCln1*(-Dz_r))*(1.0-De_2);\ + DC_j3 = DC_max*(1.0-De_1);\ + C = DC_j1+DC_j2+DC_j3;\ + DQ_j1 = c_0*(1.0-exp(DCln2*Dz1))/Dz1;\ + DQ_j2 = DC_c*(1.0-exp(DCln1*Dzr1))/Dzr1;\ + DQ_j3 = DC_c*(1.0-exp(DCln2*Dzr1))/Dzr1;\ + Qz = (DQ_j1+DQ_j2-DQ_j3)*u_d+DC_max*Dv_j4;\ + end else begin\ + C = 0.0;\ + Qz = 0.0;\ + end + + +// DEPLETION CHARGE & CAPACITANCE CALCULATION SELECTOR +// Dependent on junction punch-through voltage +// Important for collector related junctions +`define HICJQ(c_0,u_d,z,v_pt,U_cap,C,Qz)\ + if(v_pt < `VPT_thresh) begin\ + `QJMOD(c_0,u_d,z,2.4,v_pt,U_cap,C,Qz)\ + end else begin\ + `QJMODF(c_0,u_d,z,2.4,U_cap,C,Qz)\ + end + + +// A CALCULATION NEEDED FOR COLLECTOR MINORITY CHARGE FORMULATION +// INPUT: +// zb,zl : zeta_b and zeta_l (model parameters, TED 10/96) +// w : normalized injection width +// OUTPUT: +// hicfcio : function of equation (2.1.17-10) +`define HICFCI(zb,zl,w,hicfcio,dhicfcio_dw)\ + z = zb*w;\ + lnzb = ln(1+zb*w);\ + if(z > 1.0e-6) begin\ + x = 1.0+z;\ + a = x*x;\ + a2 = 0.250*(a*(2.0*lnzb-1.0)+1.0);\ + a3 = (a*x*(3.0*lnzb-1.0)+1.0)/9.0;\ + r = zl/zb;\ + hicfcio = ((1.0-r)*a2+r*a3)/zb;\ + dhicfcio_dw = ((1.0-r)*x+r*a)*lnzb;\ + end else begin\ + a = z*z;\ + a2 = 3.0+z-0.25*a+0.10*z*a;\ + a3 = 2.0*z+0.75*a-0.20*a*z;\ + hicfcio = (zb*a2+zl*a3)*w*w/6.0;\ + dhicfcio_dw = (1+zl*w)*(1+z)*lnzb;\ + end + + +// NEEDED TO CALCULATE WEIGHTED ICCR COLLECTOR MINORITY CHARGE +// INPUT: +// z : zeta_b or zeta_l +// w : normalized injection width +// OUTPUT: +// hicfcto : output +// dhicfcto_dw : derivative of output wrt w +`define HICFCT(z,w,hicfcto,dhicfcto_dw)\ + a = z*w;\ + lnz = ln(1+z*w);\ + if (a > 1.0e-6) begin\ + hicfcto = (a - lnz)/z;\ + dhicfcto_dw = a / (1.0 + a);\ + end else begin\ + hicfcto = 0.5 * a * w;\ + dhicfcto_dw = a;\ + end + + +// COLLECTOR CURRENT SPREADING CALCULATION +// collector minority charge incl. 2D/3D current spreading (TED 10/96) +// INPUT: +// Ix : forward transport current component (itf) +// I_CK : critical current +// FFT_pcS : dependent on fthc and thcs (parameters) +// IMPLICIT INPUT: +// ahc, latl, latb : model parameters +// VT : thermal voltage +// OUTPUT: +// Q_fC, Q_CT: actual and ICCR (weighted) hole charge +// T_fC, T_cT: actual and ICCR (weighted) transit time +// Derivative dfCT_ditf not properly implemented yet +`define HICQFC(Ix,I_CK,FFT_pcS,Q_fC,Q_CT,T_fC,T_cT)\ + Q_fC = FFT_pcS*Ix;\ + FCa = 1.0-I_CK/Ix;\ + FCrt = sqrt(FCa*FCa+ahc);\ + FCa_ck = 1.0-(FCa+FCrt)/(1.0+sqrt(1.0+ahc));\ + FCdaick_ditf = (FCa_ck-1.0)*(1-FCa)/(FCrt*Ix);\ + if(latb > latl) begin\ + FCz = latb-latl;\ + FCxl = 1.0+latl;\ + FCxb = 1.0+latb;\ + if(latb > 0.01) begin\ + FCln = ln(FCxb/FCxl);\ + FCa1 = exp((FCa_ck-1.0)*FCln);\ + FCd_a = 1.0/(latl-FCa1*latb);\ + FCw = (FCa1-1.0)*FCd_a;\ + FCdw_daick = -FCz*FCa1*FCln*FCd_a*FCd_a;\ + FCa1 = ln((1.0+latb*FCw)/(1.0+latl*FCw));\ + FCda1_dw = latb/(1.0+latb*FCw) - latl/(1.0+latl*FCw);\ + end else begin\ + FCf1 = 1.0-FCa_ck;\ + FCd_a = 1.0/(1.0+FCa_ck*latb);\ + FCw = FCf1*FCd_a;\ + FCdw_daick = -1.0*FCd_a*FCd_a*FCxb*FCd_a;\ + FCa1 = FCz*FCw;\ + FCda1_dw = FCz;\ + end\ + FCf_CT = 2.0/FCz;\ + FCw2 = FCw*FCw;\ + FCf1 = latb*latl*FCw*FCw2/3.0+(latb+latl)*FCw2/2.0+FCw;\ + FCdf1_dw = latb*latl*FCw2 + (latb+latl)*FCw + 1.0;\ + `HICFCI(latb,latl,FCw,FCf2,FCdf2_dw)\ + `HICFCI(latl,latb,FCw,FCf3,FCdf3_dw)\ + FCf_ci = FCf_CT*(FCa1*FCf1-FCf2+FCf3);\ + FCdfc_dw = FCf_CT*(FCa1*FCdf1_dw+FCda1_dw*FCf1-FCdf2_dw+FCdf3_dw);\ + FCdw_ditf = FCdw_daick*FCdaick_ditf;\ + FCdfc_ditf = FCdfc_dw*FCdw_ditf;\ + if(flcomp == 0.0 || flcomp == 2.1) begin\ + `HICFCT(latb,FCw,FCf2,FCdf2_dw)\ + `HICFCT(latl,FCw,FCf3,FCdf3_dw)\ + FCf_CT = FCf_CT*(FCf2-FCf3);\ + FCdfCT_dw = FCf_CT*(FCdf2_dw-FCdf3_dw);\ + FCdfCT_ditf = FCdfCT_dw*FCdw_ditf;\ + end else begin\ + FCf_CT = FCf_ci;\ + FCdfCT_ditf = FCdfc_ditf;\ + end\ + end else begin\ + if(latb > 0.01) begin\ + FCd_a = 1.0/(1.0+FCa_ck*latb);\ + FCw = (1.0-FCa_ck)*FCd_a;\ + FCdw_daick = -(1.0+latb)*FCd_a*FCd_a;\ + end else begin\ + FCw = 1.0-FCa_ck-FCa_ck*latb;\ + FCdw_daick = -(1.0+latb);\ + end\ + FCw2 = FCw*FCw;\ + FCz = latb*FCw;\ + FCz_1 = 1.0+FCz;\ + FCd_f = 1.0/(FCz_1);\ + FCf_ci = FCw2*(1.0+FCz/3.0)*FCd_f;\ + FCdfc_dw = 2.0*FCw*(FCz_1+FCz*FCz/3.0)*FCd_f*FCd_f;\ + FCdw_ditf = FCdw_daick*FCdaick_ditf;\ + FCdfc_ditf = FCdfc_dw*FCdw_ditf;\ + if(flcomp == 0.0 || flcomp == 2.1) begin\ + if (FCz > 0.001) begin\ + FCf_CT = 2.0*(FCz_1*ln(FCz_1)-FCz)/(latb*latb*FCz_1);\ + FCdfCT_dw = 2.0*FCw*FCd_f*FCd_f;\ + end else begin\ + FCf_CT = FCw2*(1.0-FCz/3.0)*FCd_f;\ + FCdfCT_dw = 2.0*FCw*(1.0-FCz*FCz/3.0)*FCd_f*FCd_f;\ + end\ + FCdfCT_ditf = FCdfCT_dw*FCdw_ditf;\ + end else begin\ + FCf_CT = FCf_ci;\ + FCdfCT_ditf = FCdfc_ditf;\ + end\ + end\ + Q_CT = Q_fC*FCf_CT;\ + Q_fC = Q_fC*FCf_ci;\ + T_fC = FFT_pcS*(FCf_ci+Ix*FCdfc_ditf);\ + T_cT = FFT_pcS*(FCf_CT+Ix*FCdfCT_ditf); + +// TRANSIT-TIME AND STORED MINORITY CHARGE +// INPUT: +// itf : forward transport current +// I_CK : critical current +// T_f : transit time \ +// Q_f : minority charge / for low current +// IMPLICIT INPUT: +// tef0, gtfe, fthc, thcs, ahc, latl, latb : model parameters +// OUTPUT: +// T_f : transit time \ +// Q_f : minority charge / transient analysis +// T_fT : transit time \ +// Q_fT : minority charge / ICCR (transfer current) +// Q_bf : excess base charge +`define HICQFF(itf,I_CK,T_f,Q_f,T_fT,Q_fT,Q_bf)\ + if(itf < 1.0e-6*I_CK) begin\ + Q_fT = Q_f;\ + T_fT = T_f;\ + end else begin\ + FFa = I_CK/itf;\ + FFd_TfE = tef0_t*exp(-gtfe*ln(FFa));\ + FFd_QfE = FFd_TfE*itf/(gtfe+1.0);\ + FFT_fbS = (1.0-fthc)*thcs_t;\ + FFx = 1.0-FFa;\ + FFs = sqrt(FFx*FFx+ahc);\ + FFw = (FFx+FFs)/(1.0+sqrt(1.0+ahc));\ + FFw_2 = FFw*FFw;\ + FFd_QfB = FFT_fbS*itf*FFw_2;\ + Q_bf = FFd_QfB;\ + FFa_w = FFw_2*(1.0+2.0*FFa/FFs);\ + FFd_TfB = FFT_fbS*FFa_w;\ + FFT_pcS = fthc*thcs_t;\ + if(latb <= 0.0 && latl <= 0.0) begin\ + FFQ_fC = FFT_pcS*itf*FFw_2;\ + FFT_fC = FFT_pcS*FFa_w;\ + FFQ_cT = FFQ_fC;\ + FFT_cT = FFT_fC;\ + end else begin\ + `HICQFC(itf,I_CK,FFT_pcS,FFQ_fC,FFQ_cT,FFT_fC,FFT_cT)\ + end\ + Q_f = Q_f+FFd_QfB;\ + T_f = T_f+FFd_TfB;\ + Q_fT = Q_f+hfe*FFd_QfE+hfc*FFQ_cT;\ + T_fT = T_f+hfe*FFd_TfE+hfc*FFT_cT;\ + Q_f = Q_f+FFd_QfE+FFQ_fC;\ + T_f = T_f+FFd_TfE+FFT_fC;\ + end + + + + +// IDEAL DIODE (WITHOUT CAPACITANCE): +// conductance calculation not required +// INPUT: +// IS, IST : saturation currents (model parameter related) +// UM1 : ideality factor +// U : branch voltage +// IMPLICIT INPUT: +// VT : thermal voltage +// OUTPUT: +// Iz : diode current +`define HICDIO(IS,IST,UM1,U,Iz)\ + DIOY = U/(UM1*VT);\ + if (IS > 0.0) begin\ + if (DIOY > `Dexp_lim) begin\ + le = (1 + (DIOY - `Dexp_lim));\ + DIOY = `Dexp_lim;\ + end else begin\ + le = 1;\ + end\ + le = le*limexp(DIOY);\ + Iz = IST*(le-1.0);\ + if(DIOY <= -14.0) begin\ + Iz = -IST;\ + end\ + end else begin\ + Iz = 0.0;\ + end + + + +// TEMPERATURE UPDATE OF JUNCTION CAPACITANCE RELATED PARAMETERS +// INPUT: +// mostly model parameters +// x : zero bias junction capacitance +// y : junction built-in potencial +// z : grading co-efficient +// w : ratio of maximum to zero-bias value of capacitance or punch-through voltage +// is_al : condition factor to check what "w" stands for +// vgeff : band-gap voltage +// IMPLICIT INPUT: +// VT : thermal voltage +// vt0,qtt0,ln_qtt0,mg : other model variables +// OUTPUT: +// c_j_t : temperature update of "c_j" +// vd_t : temperature update of "vd0" +// w_t : temperature update of "w" +`define TMPHICJ(c_j,vd0,z,w,is_al,vgeff,c_j_t,vd_t,w_t)\ + if (c_j > 0.0) begin\ + vdj0 = 2*vt0*ln(exp(vd0*0.5/vt0)-exp(-0.5*vd0/vt0));\ + vdjt = vdj0*qtt0+vgeff*(1-qtt0)-mg*VT*ln_qtt0;\ + vdt = vdjt+2*VT*ln(0.5*(1+sqrt(1+4*exp(-vdjt/VT))));\ + vd_t = vdt;\ + c_j_t = c_j*exp(z*ln(vd0/vd_t));\ + if (is_al == 1) begin\ + w_t = w*vd_t/vd0;\ + end else begin\ + w_t = w;\ + end\ + end else begin\ + c_j_t = c_j;\ + vd_t = vd0;\ + w_t = w;\ + end + + + +module hic2_full (c,b,e,s,tnode); + +//Node definitions + +inout c,b,e,s,tnode; +electrical c,b,e,s,ci,ei,bp,bi,si; +electrical xf1,xf2; +electrical xf; //RC nw + +electrical tnode; +electrical n1,n2; + +//Branch definitions +branch (b,bp) br_bbp_i; +branch (b,bp) br_bbp_v; +branch (ci,c) br_cic_i; +branch (ci,c) br_cic_v; +branch (ei,e) br_eie_i; +branch (ei,e) br_eie_v; +branch (bp,bi) br_bpbi_i; +branch (bp,bi) br_bpbi_v; +branch (si,s) br_sis_i; +branch (si,s) br_sis_v; +branch (bi,ei) br_biei; +branch (bi,ci) br_bici; +branch (ci,bi) br_cibi; +branch (ci,ei) br_ciei; +branch (ei,ci) br_eici; +branch (bp,e) br_bpe; +branch (b,e) br_be; +branch (bp,ei) br_bpei; +branch (bp,ci) br_bpci; +branch (b,ci) br_bci; +branch (si,ci) br_sici; +branch (bp,si) br_bpsi; +branch (tnode ) br_sht; + +//Phase network for ITF +branch (xf1 ) br_bxf1; +branch (xf1 ) br_cxf1; +branch (xf2 ) br_bxf2; +branch (xf2 ) br_cxf2; + +//Phase network for QF + +branch (xf ) br_bxf; //for RC nw +branch (xf ) br_cxf; //for RC nw + +//Noise + +branch (n1 ) b_n1; +branch (n2 ) b_n2; + + + +// -- ########################################################### +// -- ########### Parameters initialization ################ +// -- ########################################################### + + +//Transfer current +parameter real c10 = 2.0E-30 from [0:1] `ATTR(desc="GICCR constant" unit="A^2s"); +parameter real qp0 = 2.0E-14 from (0:1] `ATTR(desc="Zero-bias hole charge" unit="Coul"); +parameter real ich = 0.0 from [0:inf) `ATTR(desc="High-current correction for 2D and 3D effects" unit="A"); //`0' signifies infinity +parameter real hfe = 1.0 from [0:inf] `ATTR(desc="Emitter minority charge weighting factor in HBTs"); +parameter real hfc = 1.0 from [0:inf] `ATTR(desc="Collector minority charge weighting factor in HBTs"); +parameter real hjei = 1.0 from [0:100] `ATTR(desc="B-E depletion charge weighting factor in HBTs"); +parameter real hjci = 1.0 from [0:100] `ATTR(desc="B-C depletion charge weighting factor in HBTs"); + +//Base-Emitter diode currents +parameter real ibeis = 1.0E-18 from [0:1] `ATTR(desc="Internal B-E saturation current" unit="A"); +parameter real mbei = 1.0 from (0:10] `ATTR(desc="Internal B-E current ideality factor"); +parameter real ireis = 0.0 from [0:1] `ATTR(desc="Internal B-E recombination saturation current" unit="A"); +parameter real mrei = 2.0 from (0:10] `ATTR(desc="Internal B-E recombination current ideality factor"); +parameter real ibeps = 0.0 from [0:1] `ATTR(desc="Peripheral B-E saturation current" unit="A"); +parameter real mbep = 1.0 from (0:10] `ATTR(desc="Peripheral B-E current ideality factor"); +parameter real ireps = 0.0 from [0:1] `ATTR(desc="Peripheral B-E recombination saturation current" unit="A"); +parameter real mrep = 2.0 from (0:10] `ATTR(desc="Peripheral B-E recombination current ideality factor"); +parameter real mcf = 1.0 from (0:10] `ATTR(desc="Non-ideality factor for III-V HBTs"); + +//Transit time for excess recombination current at b-c barrier +parameter real tbhrec = 0.0 from [0:inf) `ATTR(desc="Base current recombination time constant at B-C barrier for high forward injection" unit="s"); + +//Base-Collector diode currents +parameter real ibcis = 1.0E-16 from [0:1.0] `ATTR(desc="Internal B-C saturation current" unit="A"); +parameter real mbci = 1.0 from (0:10] `ATTR(desc="Internal B-C current ideality factor"); +parameter real ibcxs = 0.0 from [0:1.0] `ATTR(desc="External B-C saturation current" unit="A"); +parameter real mbcx = 1.0 from (0:10] `ATTR(desc="External B-C current ideality factor"); + +//Base-Emitter tunneling current +parameter real ibets = 0.0 from [0:1] `ATTR(desc="B-E tunneling saturation current" unit="A"); +parameter real abet = 40 from [0:inf) `ATTR(desc="Exponent factor for tunneling current"); +parameter integer tunode= 1 from [0:1] `ATTR(desc="Specifies the base node connection for the tunneling current"); // =1 signifies perimeter node + +//Base-Collector avalanche current +parameter real favl = 0.0 from [0:inf) `ATTR(desc="Avalanche current factor" unit="1/V"); +parameter real qavl = 0.0 from [0:inf) `ATTR(desc="Exponent factor for avalanche current" unit="Coul"); +parameter real alfav = 0.0 `ATTR(desc="Relative TC for FAVL" unit="1/K"); +parameter real alqav = 0.0 `ATTR(desc="Relative TC for QAVL" unit="1/K"); + +//Series resistances +parameter real rbi0 = 0.0 from [0:inf) `ATTR(desc="Zero bias internal base resistance" unit="Ohm"); +parameter real rbx = 0.0 from [0:inf) `ATTR(desc="External base series resistance" unit="Ohm"); +parameter real fgeo = 0.6557 from [0:inf] `ATTR(desc="Factor for geometry dependence of emitter current crowding"); +parameter real fdqr0 = 0.0 from [-0.5:100] `ATTR(desc="Correction factor for modulation by B-E and B-C space charge layer"); +parameter real fcrbi = 0.0 from [0:1] `ATTR(desc="Ratio of HF shunt to total internal capacitance (lateral NQS effect)"); +parameter real fqi = 1.0 from [0:1] `ATTR(desc="Ration of internal to total minority charge"); +parameter real re = 0.0 from [0:inf) `ATTR(desc="Emitter series resistance" unit="Ohm"); +parameter real rcx = 0.0 from [0:inf) `ATTR(desc="External collector series resistance" unit="Ohm"); + +//Substrate transistor +parameter real itss = 0.0 from [0:1.0] `ATTR(desc="Substrate transistor transfer saturation current" unit="A"); +parameter real msf = 1.0 from (0:10] `ATTR(desc="Forward ideality factor of substrate transfer current"); +parameter real iscs = 0.0 from [0:1.0] `ATTR(desc="C-S diode saturation current" unit="A"); +parameter real msc = 1.0 from (0:10] `ATTR(desc="Ideality factor of C-S diode current"); +parameter real tsf = 0.0 from [0:inf) `ATTR(desc="Transit time for forward operation of substrate transistor" unit="s"); + +//Intra-device substrate coupling +parameter real rsu = 0.0 from [0:inf) `ATTR(desc="Substrate series resistance" unit="Ohm"); +parameter real csu = 0.0 from [0:inf) `ATTR(desc="Substrate shunt capacitance" unit="F"); + +//Depletion Capacitances +parameter real cjei0 = 1.0E-20 from [0:inf) `ATTR(desc="Internal B-E zero-bias depletion capacitance" unit="F"); +parameter real vdei = 0.9 from (0:10] `ATTR(desc="Internal B-E built-in potential" unit="V"); +parameter real zei = 0.5 from (0:1] `ATTR(desc="Internal B-E grading coefficient"); +parameter real ajei = 2.5 from [1:inf) `ATTR(desc="Ratio of maximum to zero-bias value of internal B-E capacitance"); +parameter real cjep0 = 1.0E-20 from [0:inf) `ATTR(desc="Peripheral B-E zero-bias depletion capacitance" unit="F"); +parameter real vdep = 0.9 from (0:10] `ATTR(desc="Peripheral B-E built-in potential" unit="V"); +parameter real zep = 0.5 from (0:1] `ATTR(desc="Peripheral B-E grading coefficient"); +parameter real ajep = 2.5 from [1:inf) `ATTR(desc="Ratio of maximum to zero-bias value of peripheral B-E capacitance"); +parameter real cjci0 = 1.0E-20 from [0:inf) `ATTR(desc="Internal B-C zero-bias depletion capacitance" unit="F"); +parameter real vdci = 0.7 from (0:10] `ATTR(desc="Internal B-C built-in potential" unit="V"); +parameter real zci = 0.4 from (0:1] `ATTR(desc="Internal B-C grading coefficient"); +parameter real vptci = 100 from (0:100] `ATTR(desc="Internal B-C punch-through voltage" unit="V"); +parameter real cjcx0 = 1.0E-20 from [0:inf) `ATTR(desc="External B-C zero-bias depletion capacitance" unit="F"); +parameter real vdcx = 0.7 from (0:10] `ATTR(desc="External B-C built-in potential" unit="V"); +parameter real zcx = 0.4 from (0:1] `ATTR(desc="External B-C grading coefficient"); +parameter real vptcx = 100 from (0:100] `ATTR(desc="External B-C punch-through voltage" unit="V"); +parameter real fbcpar = 0.0 from [0:1] `ATTR(desc="Partitioning factor of parasitic B-C cap"); +parameter real fbepar = 1.0 from [0:1] `ATTR(desc="Partitioning factor of parasitic B-E cap"); +parameter real cjs0 = 0.0 from [0:inf) `ATTR(desc="C-S zero-bias depletion capacitance" unit="F"); +parameter real vds = 0.6 from (0:10] `ATTR(desc="C-S built-in potential" unit="V"); +parameter real zs = 0.5 from (0:1] `ATTR(desc="C-S grading coefficient"); +parameter real vpts = 100 from (0:100] `ATTR(desc="C-S punch-through voltage" unit="V"); + +//Diffusion Capacitances +parameter real t0 = 0.0 from [0:inf) `ATTR(desc="Low current forward transit time at VBC=0V" unit="s"); +parameter real dt0h = 0.0 from (-inf:inf) `ATTR(desc="Time constant for base and B-C space charge layer width modulation" unit="s"); +parameter real tbvl = 0.0 from [0:inf) `ATTR(desc="Time constant for modelling carrier jam at low VCE" unit="s"); +parameter real tef0 = 0.0 from [0:inf) `ATTR(desc="Neutral emitter storage time" unit="s"); +parameter real gtfe = 1.0 from (0:10] `ATTR(desc="Exponent factor for current dependence of neutral emitter storage time"); +parameter real thcs = 0.0 from [0:inf) `ATTR(desc="Saturation time constant at high current densities" unit="s"); +parameter real ahc = 0.1 from (0:10] `ATTR(desc="Smoothing factor for current dependence of base and collector transit time"); +parameter real fthc = 0.0 from [0:1] `ATTR(desc="Partitioning factor for base and collector portion"); +parameter real rci0 = 150 from (0:inf) `ATTR(desc="Internal collector resistance at low electric field" unit="Ohm"); +parameter real vlim = 0.5 from (0:10] `ATTR(desc="Voltage separating ohmic and saturation velocity regime" unit="V"); +parameter real vces = 0.1 from [0:1] `ATTR(desc="Internal C-E saturation voltage" unit="V"); +parameter real vpt = 100.0 from (0:inf] `ATTR(desc="Collector punch-through voltage" unit="V"); // `0' signifies infinity +parameter real tr = 0.0 from [0:inf) `ATTR(desc="Storage time for inverse operation" unit="s"); + +//Isolation Capacitances +parameter real cbepar = 0.0 from [0:inf) `ATTR(desc="Total parasitic B-E capacitance" unit="F"); +parameter real cbcpar = 0.0 from [0:inf) `ATTR(desc="Total parasitic B-C capacitance" unit="F"); + +//Non-quasi-static Effect +parameter real alqf = 0.0 from [0:1] `ATTR(desc="Factor for additional delay time of minority charge"); +parameter real alit = 0.0 from [0:1] `ATTR(desc="Factor for additional delay time of transfer current"); +parameter integer flnqs = 0 from [0:1] `ATTR(desc="Flag for turning on and off of vertical NQS effect"); + +//Noise +parameter real kf = 0.0 from [0:inf) `ATTR(desc="Flicker noise coefficient"); +parameter real af = 2.0 from (0:10] `ATTR(desc="Flicker noise exponent factor"); +parameter integer cfbe = -1 from [-2:-1] `ATTR(desc="Flag for determining where to tag the flicker noise source"); + + +//Lateral Geometry Scaling (at high current densities) +parameter real latb = 0.0 from [0:inf) `ATTR(desc="Scaling factor for collector minority charge in direction of emitter width"); +parameter real latl = 0.0 from [0:inf) `ATTR(desc="Scaling factor for collector minority charge in direction of emitter length"); + +//Temperature dependence +parameter real vgb = 1.17 from (0:10] `ATTR(desc="Bandgap voltage extrapolated to 0 K" unit="V"); +parameter real alt0 = 0.0 `ATTR(desc="First order relative TC of parameter T0" unit="1/K"); +parameter real kt0 = 0.0 `ATTR(desc="Second order relative TC of parameter T0"); +parameter real zetaci = 0.0 from [-10:10] `ATTR(desc="Temperature exponent for RCI0"); +parameter real alvs = 0.0 `ATTR(desc="Relative TC of saturation drift velocity" unit="1/K"); +parameter real alces = 0.0 `ATTR(desc="Relative TC of VCES" unit="1/K"); +parameter real zetarbi = 0.0 from [-10:10] `ATTR(desc="Temperature exponent of internal base resistance"); +parameter real zetarbx = 0.0 from [-10:10] `ATTR(desc="Temperature exponent of external base resistance"); +parameter real zetarcx = 0.0 from [-10:10] `ATTR(desc="Temperature exponent of external collector resistance"); +parameter real zetare = 0.0 from [-10:10] `ATTR(desc="Temperature exponent of emitter resistance"); +parameter real zetacx = 1.0 from [-10:10] `ATTR(desc="Temperature exponent of mobility in substrate transistor transit time"); +parameter real vge = 1.17 from (0:10] `ATTR(desc="Effective emitter bandgap voltage" unit="V"); +parameter real vgc = 1.17 from (0:10] `ATTR(desc="Effective collector bandgap voltage" unit="V"); +parameter real vgs = 1.17 from (0:10] `ATTR(desc="Effective substrate bandgap voltage" unit="V"); +parameter real f1vg =-1.02377e-4 `ATTR(desc="Coefficient K1 in T-dependent band-gap equation"); +parameter real f2vg = 4.3215e-4 `ATTR(desc="Coefficient K2 in T-dependent band-gap equation"); +parameter real zetact = 3.0 from [-10:10] `ATTR(desc="Exponent coefficient in transfer current temperature dependence"); +parameter real zetabet = 3.5 from [-10:10] `ATTR(desc="Exponent coefficient in B-E junction current temperature dependence"); +parameter real alb = 0.0 `ATTR(desc="Relative TC of forward current gain for V2.1 model" unit="1/K"); + +//Self-Heating +parameter integer flsh = 0 from [0:2] `ATTR(desc="Flag for turning on and off self-heating effect"); +parameter real rth = 0.0 from [0:inf) `ATTR(desc="Thermal resistance" unit="K/W"); +parameter real cth = 0.0 from [0:inf) `ATTR(desc="Thermal capacitance" unit="J/W"); + +//Compatibility with V2.1 +parameter real flcomp = 0.0 from [0:inf) `ATTR(desc="Flag for compatibility with v2.1 model (0=v2.1)"); + +//Circuit simulator specific parameters +parameter real tnom = 27.0 `ATTR(desc="Temperature at which parameters are specified" unit="C"); +parameter real dt = 0.0 `ATTR(desc="Temperature change w.r.t. chip temperature for particular transistor" unit="K"); + + +// +//======================== Transistor model formulation =================== +// + + //Declaration of variables + + //Temperature and drift + real VT,Tdev,qtt0,ln_qtt0,r_VgVT,V_gT,dT,k; + real ireis_t,ibeis_t,ibcxs_t,ibcis_t,iscs_t,cjci0_t; + real cjs0_t,rci0_t,vlim_t,vces_t,thcs_t,tef0_t,rbi0_t; + real rbx_t,rcx_t,re_t,t0_t,vdei_t,vdci_t,vpts_t,itss_t,tsf_t; + real c10_t,cjei0_t,qp0_t,vdcx_t,vptcx_t,cjcx01_t,cjcx02_t; + real qjcx0_t_i,qjcx0_t_ii,cratio_t,c_dummy; + real ibeps_t,ireps_t,cjep0_t; + real ajei_t,qavl_t,favl_t,ibets_t,abet_t,vptci_t,vdep_t,ajep_t,zetatef; + real k1,k2,dvg0,vge_t,vgb_t,vgbe_t,vds_t,vt0,Tnom,Tamb,a,avs; + real zetabci,zetabcxt,zetasct,vgbe0,mg,vgb_t0,vge_t0,vgbe_t0,vgbc0,vgsc0; + real cbcpar1,cbcpar2,cbepar2,cbepar1,Oich,Ovpt,Otbhrec; + + //Charges, capacitances and currents + real Qjci,Qjei,Qjep; + real it,ibei,irei,ibci,ibep,irep,ibh_rec; + real Qdei,Qdci,qrbi; + real ibet,iavl; + real ijbcx,ijsc,Qjs,HSUM,HSI_Tsu,Qdsu; + + //Base resistance and self-heating power + real rbi,pterm; + + //Variables for macro TMPHICJ + real vdj0,vdjt,vdt; + + //Model initialization + real k10,k20,C_1; + + //Model evaluation + real Cjci,Cjcit,cc,Cjei,Cjep; + real itf,itr,Tf,Tr,VT_f,i_0f,i_0r,a_bpt,Q_0,Q_p,Q_bpt; + real Orci0_t,b_q,Q_fC,T_fC,T_cT,I_Tf1,T_f0,Q_fT,T_fT,Q_bf; + real ICKa,d1; + real A,a_h,Q_pT,d_Q,d_Q0; + real Qf,Cdei,Qr,Cdci,Crbi; + real ick,vc,vceff,cjcx01,cjcx02,HSa,HSb; + integer l_it; + + //Variables for macros + real DIOY,le;//HICDIO + real FFT_fbS,FFa,FFx,FFs,FFw,FFw_2,FFd_QfB,FFd_TfB,FFT_pcS,FFQ_fC,FFT_fC,FFQ_cT,FFT_cT,FFd_TfE,FFd_QfE,FFa_w;//HICQFF + real FCz,FCw2,FCf1,FCf2,FCf3,FCf_ci,FCz_1,FCa1,FCa_ck,FCxl,FCxb;//HICQFC + real FCd_a,FCdaick_ditf,FCa,FCw,FCdw_daick,FCdfc_dw,FCdw_ditf,FCdfc_ditf,FCf_CT,FCdfCT_ditf,FCrt,FCln,lnz,FCda1_dw,FCdf1_dw,FCdf2_dw,FCdf3_dw,FCd_f,FCdfCT_dw;//HICQFC + real Dz_r,Dv_p,DV_f,DC_max,DC_c,Da,Dv_e,De,De_1,Dv_j1,Dv_r,De_2,Dv_j2,Dv_j4,DQ_j1,DQ_j2,DQ_j3,DCln1,DCln2,Dz1,Dzr1,DC_j1,DC_j2,DC_j3;//QJMOD + real DFV_f,DFv_e,DFv_j,DFb,DFQ_j,DFs_q,DFs_q2,DFdvj_dv,DFC_j1;//QJMODF + real z,a2,a3,r,x;//HICFCI + real zb,zl,lnzb,w,hicfcio,dhicfcio_dw; //HICFCT + + //Noise + real fourkt,twoq,flicker_Pwr; + real thermal_Rbx,thermal_Rbi,thermal_Rcx,thermal_Re,betad,betan,betadin,betadc,icn,icn1,icn2; + + //NQS + real Ixf1,Ixf2,Qxf1,Qxf2,Vxf1,Vxf2,Itxf,TD1,Qdeix; + real T, Vxf, Ixf, Qxf,fact; + + real pocce,czz; + real Qz_nom,f_QR,ETA,Qz0,fQz; + real v_bord,v_q,U0,av,avl; + real cV_f,cv_e,cs_q,cs_q2,cv_j,cdvj_dv; + real a_eg,ab,aa; + + //end of variables + +analog begin + +`MODEL begin : Model_initialization + + Tnom = tnom+`P_CELSIUS0; + Tamb = $temperature; + vt0 = `P_K*Tnom /`P_Q; + k10 = f1vg*Tnom*ln(Tnom); + k20 = f2vg*Tnom; + avs = alvs*Tnom; + vgb_t0 = vgb+k10+k20; + vge_t0 = vge+k10+k20; + vgbe_t0 = (vgb_t0+vge_t0)/2; + vgbe0 = (vgb+vge)/2; + vgbc0 = (vgb+vgc)/2; + vgsc0 = (vgs+vgc)/2; + mg = 3-`P_Q*f1vg/`P_K; + zetabci = mg+1-zetaci; + zetabcxt= mg+1-zetacx; + zetasct = mg-1.5; + + //Depletion capacitance splitting at b-c junction + //Capacitances at peripheral and external base node + C_1 = (1.0-fbcpar)*(cjcx0+cbcpar); + if (C_1 >= cbcpar) begin + cbcpar1 = cbcpar; + cbcpar2 = 0.0; + cjcx01 = C_1-cbcpar; + cjcx02 = cjcx0-cjcx01; + end else begin + cbcpar1 = C_1; + cbcpar2 = cbcpar-cbcpar1; + cjcx01 = 0.0; + cjcx02 = cjcx0; + end + + //Parasitic b-e capacitance partitioning: No temperature dependence + cbepar2 = fbepar*cbepar; + cbepar1 = cbepar-cbepar2; + + //Avoid devide-by-zero and define infinity other way + //High current correction for 2D and 3D effects + if (ich != 0.0) begin + Oich = 1.0/ich; + end else begin + Oich = 0.0; + end + + //Base current recombination time constant at b-c barrier + if (tbhrec != 0.0) begin + Otbhrec = 1.0/tbhrec; + end else begin + Otbhrec = 0.0; + end + + // Temperature and resulting parameter drift + if (flsh==0 || rth < `MIN_R) begin : Thermal_updat_without_self_heating + Tdev = Tamb+dt; + if(Tdev < `TMIN + 273.15) begin + Tdev = `TMIN + 273.15; + end else begin + if (Tdev > `TMAX + 273.15) begin + Tdev = `TMAX + 273.15; + end + end + VT = `P_K*Tdev /`P_Q; + dT = Tdev-Tnom; + qtt0 = Tdev/Tnom; + ln_qtt0 = ln(qtt0); + k1 = f1vg*Tdev*ln(Tdev); + k2 = f2vg*Tdev; + vgb_t = vgb+k1+k2; + vge_t = vge+k1+k2; + vgbe_t = (vgb_t+vge_t)/2; + + //Internal b-e junction capacitance + `TMPHICJ(cjei0,vdei,zei,ajei,1,vgbe0,cjei0_t,vdei_t,ajei_t) + + if (flcomp == 0.0 || flcomp == 2.1) begin + V_gT = 3.0*VT*ln_qtt0 + vgb*(qtt0-1.0); + r_VgVT = V_gT/VT; + //Internal b-e diode saturation currents + a = mcf*r_VgVT/mbei - alb*dT; + ibeis_t = ibeis*exp(a); + a = mcf*r_VgVT/mrei - alb*dT; + ireis_t = ireis*exp(a); + a = mcf*r_VgVT/mbep - alb*dT; + //Peripheral b-e diode saturation currents + ibeps_t = ibeps*exp(a); + a = mcf*r_VgVT/mrep - alb*dT; + ireps_t = ireps*exp(a); + //Internal b-c diode saturation current + a = r_VgVT/mbci; + ibcis_t = ibcis*exp(a); + //External b-c diode saturation currents + a = r_VgVT/mbcx; + ibcxs_t = ibcxs*exp(a); + //Saturation transfer current for substrate transistor + a = r_VgVT/msf; + itss_t = itss*exp(a); + //Saturation current for c-s diode + a = r_VgVT/msc; + iscs_t = iscs*exp(a); + //Zero bias hole charge + a = vdei_t/vdei; + qp0_t = qp0*(1.0+0.5*zei*(1.0-a)); + //Voltage separating ohmic and saturation velocity regime + a = vlim*(1.0-alvs*dT)*exp(zetaci*ln_qtt0); + k = (a-VT)/VT; + if (k < `LN_EXP_LIMIT) begin + vlim_t = VT + VT*ln(1.0+exp(k)); + end else begin + vlim_t = a; + end + //Neutral emitter storage time + a = 1.0+alb*dT; + k = 0.5*(a+sqrt(a*a+0.01)); + tef0_t = tef0*qtt0/k; + end else begin + //Internal b-e diode saturation currents + ibeis_t = ibeis*exp(zetabet*ln_qtt0+vge/VT*(qtt0-1)); + ireis_t = ireis*exp(0.5*mg*ln_qtt0+0.5*vgbe0/VT*(qtt0-1)); + //Peripheral b-e diode saturation currents + ibeps_t = ibeps*exp(zetabet*ln_qtt0+vge/VT*(qtt0-1)); + ireps_t = ireps*exp(0.5*mg*ln_qtt0+0.5*vgbe0/VT*(qtt0-1)); + //Internal b-c diode saturation currents + ibcis_t = ibcis*exp(zetabci*ln_qtt0+vgc/VT*(qtt0-1)); + //External b-c diode saturation currents + ibcxs_t = ibcxs*exp(zetabcxt*ln_qtt0+vgc/VT*(qtt0-1)); + //Saturation transfer current for substrate transistor + itss_t = itss*exp(zetasct*ln_qtt0+vgc/VT*(qtt0-1)); + //Saturation current for c-s diode + iscs_t = iscs*exp(zetasct*ln_qtt0+vgs/VT*(qtt0-1)); + //Zero bias hole charge + a = exp(zei*ln(vdei_t/vdei)); + qp0_t = qp0*(2.0-a); + //Voltage separating ohmic and saturation velocity regime + vlim_t = vlim*exp((zetaci-avs)*ln_qtt0); + //Neutral emitter storage time + zetatef = zetabet-zetact-0.5; + dvg0 = vgb-vge; + tef0_t = tef0*exp(zetatef*ln_qtt0-dvg0/VT*(qtt0-1)); + end + + //GICCR prefactor + c10_t = c10*exp(zetact*ln_qtt0+vgb/VT*(qtt0-1)); + + // Low-field internal collector resistance + rci0_t = rci0*exp(zetaci*ln_qtt0); + + //Voltage separating ohmic and saturation velocity regime + //vlim_t = vlim*exp((zetaci-avs)*ln_qtt0); + + //Internal c-e saturation voltage + vces_t = vces*(1+alces*dT); + + + //Internal b-c diode saturation current + //ibcis_t = ibcis*exp(zetabci*ln_qtt0+vgc/VT*(qtt0-1)); + + //Internal b-c junction capacitance + `TMPHICJ(cjci0,vdci,zci,vptci,0,vgbc0,cjci0_t,vdci_t,vptci_t) + + //Low-current forward transit time + t0_t = t0*(1+alt0*dT+kt0*dT*dT); + + //Saturation time constant at high current densities + thcs_t = thcs*exp((zetaci-1)*ln_qtt0); + + + //Avalanche caurrent factors + favl_t = favl*exp(alfav*dT); + qavl_t = qavl*exp(alqav*dT); + + //Zero bias internal base resistance + rbi0_t = rbi0*exp(zetarbi*ln_qtt0); + + + //Peripheral b-e junction capacitance + `TMPHICJ(cjep0,vdep,zep,ajep,1,vgbe0,cjep0_t,vdep_t,ajep_t) + + //Tunneling current factors + begin : HICTUN_T +// real a_eg,ab,aa; + ab = 1.0; + aa = 1.0; + a_eg=vgbe_t0/vgbe_t; + if(tunode==1 && cjep0 > 0.0 && vdep >0.0) begin + ab = (cjep0_t/cjep0)*sqrt(a_eg)*vdep_t*vdep_t/(vdep*vdep); + aa = (vdep/vdep_t)*(cjep0/cjep0_t)*pow(a_eg,-1.5); + end else if (tunode==0 && cjei0 > 0.0 && vdei >0.0) begin + ab = (cjei0_t/cjei0)*sqrt(a_eg)*vdei_t*vdei_t/(vdei*vdei); + aa = (vdei/vdei_t)*(cjei0/cjei0_t)*pow(a_eg,-1.5); + end + ibets_t = ibets*ab; + abet_t = abet*aa; + end + + + //Temperature mapping for tunneling current is done inside HICTUN + + `TMPHICJ(1.0,vdcx,zcx,vptcx,0,vgbc0,cratio_t,vdcx_t,vptcx_t) + cjcx01_t=cratio_t*cjcx01; + cjcx02_t=cratio_t*cjcx02; + + + //External b-c diode saturation currents + //ibcxs_t = ibcxs*exp(zetabcxt*ln_qtt0+vgc/VT*(qtt0-1)); + + + //Constant external series resistances + rcx_t = rcx*exp(zetarcx*ln_qtt0); + rbx_t = rbx*exp(zetarbx*ln_qtt0); + re_t = re*exp(zetare*ln_qtt0); + + //Forward transit time in substrate transistor + tsf_t = tsf*exp((zetacx-1.0)*ln_qtt0); + + //Capacitance for c-s junction + `TMPHICJ(cjs0,vds,zs,vpts,0,vgsc0,cjs0_t,vds_t,vpts_t) + + end // of Thermal_update_without_self_heating + +end //of Model_initialization + +if (flsh!=0 && rth >= `MIN_R) begin : Thermal_update_with_self_heating + Tdev = Tamb+dt+V(br_sht); + // Limit temperature to avoid FPEs in equations + if(Tdev < `TMIN + 273.15) begin + Tdev = `TMIN + 273.15; + end else begin + if (Tdev > `TMAX + 273.15) begin + Tdev = `TMAX + 273.15; + end + end + VT = `P_K*Tdev /`P_Q; + dT = Tdev-Tnom; + qtt0 = Tdev/Tnom; + ln_qtt0 = ln(qtt0); + k1 = f1vg*Tdev*ln(Tdev); + k2 = f2vg*Tdev; + vgb_t = vgb+k1+k2; + vge_t = vge+k1+k2; + vgbe_t = (vgb_t+vge_t)/2; + + //Internal b-e junction capacitance + `TMPHICJ(cjei0,vdei,zei,ajei,1,vgbe0,cjei0_t,vdei_t,ajei_t) + + if (flcomp == 0.0 || flcomp == 2.1) begin + V_gT = 3.0*VT*ln_qtt0 + vgb*(qtt0-1.0); + r_VgVT = V_gT/VT; + //Internal b-e diode saturation currents + a = mcf*r_VgVT/mbei - alb*dT; + ibeis_t = ibeis*exp(a); + a = mcf*r_VgVT/mrei - alb*dT; + ireis_t = ireis*exp(a); + a = mcf*r_VgVT/mbep - alb*dT; + //Peripheral b-e diode saturation currents + ibeps_t = ibeps*exp(a); + a = mcf*r_VgVT/mrep - alb*dT; + ireps_t = ireps*exp(a); + //Internal b-c diode saturation current + a = r_VgVT/mbci; + ibcis_t = ibcis*exp(a); + //External b-c diode saturation currents + a = r_VgVT/mbcx; + ibcxs_t = ibcxs*exp(a); + //Saturation transfer current for substrate transistor + a = r_VgVT/msf; + itss_t = itss*exp(a); + //Saturation current for c-s diode + a = r_VgVT/msc; + iscs_t = iscs*exp(a); + //Zero bias hole charge + a = vdei_t/vdei; + qp0_t = qp0*(1.0+0.5*zei*(1.0-a)); + //Voltage separating ohmic and saturation velocity regime + a = vlim*(1.0-alvs*dT)*exp(zetaci*ln_qtt0); + k = (a-VT)/VT; + if (k < `LN_EXP_LIMIT) begin + vlim_t = VT + VT*ln(1.0+exp(k)); + end else begin + vlim_t = a; + end + //Neutral emitter storage time + a = 1.0+alb*dT; + k = 0.5*(a+sqrt(a*a+0.01)); + tef0_t = tef0*qtt0/k; + end else begin + //Internal b-e diode saturation currents + ibeis_t = ibeis*exp(zetabet*ln_qtt0+vge/VT*(qtt0-1)); + ireis_t = ireis*exp(0.5*mg*ln_qtt0+0.5*vgbe0/VT*(qtt0-1)); + //Peripheral b-e diode saturation currents + ibeps_t = ibeps*exp(zetabet*ln_qtt0+vge/VT*(qtt0-1)); + ireps_t = ireps*exp(0.5*mg*ln_qtt0+0.5*vgbe0/VT*(qtt0-1)); + //Internal b-c diode saturation currents + ibcis_t = ibcis*exp(zetabci*ln_qtt0+vgc/VT*(qtt0-1)); + //External b-c diode saturation currents + ibcxs_t = ibcxs*exp(zetabcxt*ln_qtt0+vgc/VT*(qtt0-1)); + //Saturation transfer current for substrate transistor + itss_t = itss*exp(zetasct*ln_qtt0+vgc/VT*(qtt0-1)); + //Saturation current for c-s diode + iscs_t = iscs*exp(zetasct*ln_qtt0+vgs/VT*(qtt0-1)); + //Zero bias hole charge + a = exp(zei*ln(vdei_t/vdei)); + qp0_t = qp0*(2.0-a); + //Voltage separating ohmic and saturation velocity regime + vlim_t = vlim*exp((zetaci-avs)*ln_qtt0); + //Neutral emitter storage time + zetatef = zetabet-zetact-0.5; + dvg0 = vgb-vge; + tef0_t = tef0*exp(zetatef*ln_qtt0-dvg0/VT*(qtt0-1)); + end + + //GICCR prefactor + c10_t = c10*exp(zetact*ln_qtt0+vgb/VT*(qtt0-1)); + + // Low-field internal collector resistance + rci0_t = rci0*exp(zetaci*ln_qtt0); + + //Voltage separating ohmic and saturation velocity regime + //vlim_t = vlim*exp((zetaci-avs)*ln_qtt0); + + //Internal c-e saturation voltage + vces_t = vces*(1+alces*dT); + + + //Internal b-c diode saturation current + //ibcis_t = ibcis*exp(zetabci*ln_qtt0+vgc/VT*(qtt0-1)); + + //Internal b-c junction capacitance + `TMPHICJ(cjci0,vdci,zci,vptci,0,vgbc0,cjci0_t,vdci_t,vptci_t) + + //Low-current forward transit time + t0_t = t0*(1+alt0*dT+kt0*dT*dT); + + //Saturation time constant at high current densities + thcs_t = thcs*exp((zetaci-1)*ln_qtt0); + + + //Avalanche caurrent factors + favl_t = favl*exp(alfav*dT); + qavl_t = qavl*exp(alqav*dT); + + //Zero bias internal base resistance + rbi0_t = rbi0*exp(zetarbi*ln_qtt0); + + + //Peripheral b-e junction capacitance + `TMPHICJ(cjep0,vdep,zep,ajep,1,vgbe0,cjep0_t,vdep_t,ajep_t) + + //Tunneling current factors + if (V(br_bpei) < 0.0 || V(br_biei) < 0.0) begin : HICTUN_T +// real a_eg,ab,aa; + ab = 1.0; + aa = 1.0; + a_eg=vgbe_t0/vgbe_t; + if(tunode==1 && cjep0 > 0.0 && vdep >0.0) begin + ab = (cjep0_t/cjep0)*sqrt(a_eg)*vdep_t*vdep_t/(vdep*vdep); + aa = (vdep/vdep_t)*(cjep0/cjep0_t)*pow(a_eg,-1.5); + end else if (tunode==0 && cjei0 > 0.0 && vdei >0.0) begin + ab = (cjei0_t/cjei0)*sqrt(a_eg)*vdei_t*vdei_t/(vdei*vdei); + aa = (vdei/vdei_t)*(cjei0/cjei0_t)*pow(a_eg,-1.5); + end + ibets_t = ibets*ab; + abet_t = abet*aa; + end + + + //Temperature mapping for tunneling current is done inside HICTUN + + `TMPHICJ(1.0,vdcx,zcx,vptcx,0,vgbc0,cratio_t,vdcx_t,vptcx_t) + cjcx01_t=cratio_t*cjcx01; + cjcx02_t=cratio_t*cjcx02; + + + //External b-c diode saturation currents + //ibcxs_t = ibcxs*exp(zetabcxt*ln_qtt0+vgc/VT*(qtt0-1)); + + + //Constant external series resistances + rcx_t = rcx*exp(zetarcx*ln_qtt0); + rbx_t = rbx*exp(zetarbx*ln_qtt0); + re_t = re*exp(zetare*ln_qtt0); + + //Forward transit time in substrate transistor + tsf_t = tsf*exp((zetacx-1.0)*ln_qtt0); + + //Capacitance for c-s junction + `TMPHICJ(cjs0,vds,zs,vpts,0,vgsc0,cjs0_t,vds_t,vpts_t) + +end //of Thermal_update_with_self_heating + + +begin : Model_evaluation + + //Intrinsic transistor + //Internal base currents across b-e junction + `HICDIO(ibeis,ibeis_t,mbei,V(br_biei),ibei) + `HICDIO(ireis,ireis_t,mrei,V(br_biei),irei) + + //HICCR: begin + + //Inverse of low-field internal collector resistance: needed in HICICK + Orci0_t = 1.0/rci0_t; + + //Initialization + //Transfer current, minority charges and transit times + + Tr = tr; + VT_f = mcf*VT; + i_0f = c10_t * limexp(V(br_biei)/VT_f); + i_0r = c10_t * limexp(V(br_bici)/VT); + + //Internal b-e and b-c junction capacitances and charges + //`QJMODF(cjei0_t,vdei_t,zei,ajei_t,V(br_biei),Qjei) + //Cjei = ddx(Qjei,V(bi)); + `QJMODF(cjei0_t,vdei_t,zei,ajei_t,V(br_biei),Cjei,Qjei) + + //`HICJQ(cjci0_t,vdci_t,zci,vptci_t,V(br_bici),Qjci) + //Cjci = ddx(Qjci,V(bi)); + `HICJQ(cjci0_t,vdci_t,zci,vptci_t,V(br_bici),Cjci,Qjci) + + //Hole charge at low bias + a_bpt = 0.05; + Q_0 = qp0_t + hjei*Qjei + hjci*Qjci; + Q_bpt = a_bpt*qp0_t; + b_q = Q_0/Q_bpt-1; + Q_0 = Q_bpt*(1+(b_q +sqrt(b_q*b_q+1.921812))/2); + + //Transit time calculation at low current density + if(cjci0_t > 0.0) begin : CJMODF +// real cV_f,cv_e,cs_q,cs_q2,cv_j,cdvj_dv; + cV_f = vdci_t*(1.0-exp(-ln(2.4)/zci)); + cv_e = (cV_f-V(br_bici))/VT; + cs_q = sqrt(cv_e*cv_e+1.921812); + cs_q2 = (cv_e+cs_q)*0.5; + cv_j = cV_f-VT*cs_q2; + cdvj_dv = cs_q2/cs_q; + Cjcit = cjci0_t*exp(-zci*ln(1.0-cv_j/vdci_t))*cdvj_dv+2.4*cjci0_t*(1.0-cdvj_dv); + end else begin + Cjcit = 0.0; + end + if(Cjcit > 0.0) begin + cc = cjci0_t/Cjcit; + end else begin + cc = 1.0; + end + T_f0 = t0_t+dt0h*(cc-1.0)+tbvl*(1/cc-1.0); + + //Effective collector voltage + vc = V(br_ciei)-vces_t; + + //Critical current for onset of high-current effects + begin : HICICK + Ovpt = 1.0/vpt; + a = vc/VT; + d1 = a-1; + vceff = (1.0+((d1+sqrt(d1*d1+1.921812))/2))*VT; + a = vceff/vlim_t; + ick = vceff*Orci0_t/sqrt(1.0+a*a); + ICKa = (vceff-vlim_t)*Ovpt; + ick = ick*(1.0+0.5*(ICKa+sqrt(ICKa*ICKa+1.0e-3))); + end + + //Initial formulation of forward and reverse component of transfer current + Q_p = Q_0; + if (T_f0 > 0.0 || Tr > 0.0) begin + A = 0.5*Q_0; + Q_p = A+sqrt(A*A+T_f0*i_0f+Tr*i_0r); + end + I_Tf1 =i_0f/Q_p; + a_h = Oich*I_Tf1; + itf = I_Tf1*(1.0+a_h); + itr = i_0r/Q_p; + + //Initial formulation of forward transit time, diffusion, GICCR and excess b-c charge + Q_bf = 0.0; + Tf = T_f0; + Qf = T_f0*itf; + `HICQFF(itf,ick,Tf,Qf,T_fT,Q_fT,Q_bf) + + //Initial formulation of reverse diffusion charge + Qr = Tr*itr; + + //Preparation for iteration to get total hole charge and related variables + l_it = 0; + if(Qf > `RTOLC*Q_p || a_h > `RTOLC) begin + //Iteration for Q_pT is required for improved initial solution + Qf = sqrt(T_f0*itf*Q_fT); + Q_pT = Q_0+Qf+Qr; + d_Q = Q_pT; + while (abs(d_Q) >= `RTOLC*abs(Q_pT) && l_it <= `l_itmax) begin + d_Q0 = d_Q; + I_Tf1 = i_0f/Q_pT; + a_h = Oich*I_Tf1; + itf = I_Tf1*(1.0+a_h); + itr = i_0r/Q_pT; + Tf = T_f0; + Qf = T_f0*itf; + `HICQFF(itf,ick,Tf,Qf,T_fT,Q_fT,Q_bf) + Qr = Tr*itr; + if(Oich == 0.0) begin + a = 1.0+(T_fT*itf+Qr)/Q_pT; + end else begin + a = 1.0+(T_fT*I_Tf1*(1.0+2.0*a_h)+Qr)/Q_pT; + end + d_Q = -(Q_pT-(Q_0+Q_fT+Qr))/a; + //Limit maximum change of Q_pT + a = abs(0.3*Q_pT); + if(abs(d_Q) > a) begin + if (d_Q>=0) begin + d_Q = a; + end else begin + d_Q = -a; + end + end + Q_pT = Q_pT+d_Q; + l_it = l_it+1; + end //while + + I_Tf1 = i_0f/Q_pT; + a_h = Oich*I_Tf1; + itf = I_Tf1*(1.0+a_h); + itr = i_0r/Q_pT; + + //Final transit times, charges and transport current components + Tf = T_f0; + Qf = T_f0*itf; + `HICQFF(itf,ick,Tf,Qf,T_fT,Q_fT,Q_bf) + Qr = Tr*itr; + + end //if + + //NQS effect implemented with LCR networks + //Once the delay in ITF is considered, IT_NQS is calculated afterwards + + it = itf-itr; + + //Diffusion charges for further use + Qdei = Qf; + Qdci = Qr; + + + //High-frequency emitter current crowding (lateral NQS) + Cdei = -1*ddx(Qdei,V(ei)); + Cdci = -1*ddx(Qdci,V(ci)); + Crbi = fcrbi*(Cjei+Cjci+Cdei+Cdci); + qrbi = Crbi*V(br_bpbi_v); + +// qrbi = fcrbi*(Qjei+Qjci+Qdei+Qdci); + + //HICCR: end + + //Internal base current across b-c junction + `HICDIO(ibcis,ibcis_t,mbci,V(br_bici),ibci) + + //Avalanche current + if((V(br_bici) < 0.0) && (favl_t > 0.0) && (cjci0_t > 0.0)) begin : HICAVL +// real v_bord,v_q,U0,av,avl; + v_bord = vdci_t-V(br_bici); + v_q = qavl_t/Cjci; + U0 = qavl_t/cjci0_t; + if(v_bord > U0) begin + av = favl_t*exp(-v_q/U0); + avl = av*(U0+(1.0+v_q/U0)*(v_bord-U0)); + end else begin + avl = favl_t*v_bord*exp(-v_q/v_bord); + end + iavl = itf*avl; + end else begin + iavl = 0.0; + end + + //Excess base current from recombination at the b-c barrier + ibh_rec = Q_bf*Otbhrec; + + //Internal base resistance + if(rbi0_t > 0.0) begin : HICRBI +// real Qz_nom,f_QR,ETA,Qz0,fQz; + // Consideration of conductivity modulation + // To avoid convergence problem hyperbolic smoothing used + f_QR = (1+fdqr0)*qp0_t; + Qz0 = Qjei+Qjci+Qf; + Qz_nom = 1+Qz0/f_QR; + fQz = 0.5*(Qz_nom+sqrt(Qz_nom*Qz_nom+0.01)); + rbi = rbi0_t/fQz; + // Consideration of emitter current crowding + if( ibei > 0.0) begin + ETA = rbi*ibei*fgeo/VT; + if(ETA < 1.0e-6) begin + rbi = rbi*(1.0-0.5*ETA); + end else begin + rbi = rbi*ln(1.0+ETA)/ETA; + end + end + // Consideration of peripheral charge + if(Qf > 0.0) begin + rbi = rbi*(Qjei+Qf*fqi)/(Qjei+Qf); + end + end else begin + rbi = 0.0; + end + + //Base currents across peripheral b-e junction + `HICDIO(ibeps,ibeps_t,mbep,V(br_bpei),ibep) + `HICDIO(ireps,ireps_t,mrep,V(br_bpei),irep) + + //Peripheral b-e junction capacitance and charge + `QJMODF(cjep0_t,vdep_t,zep,ajep_t,V(br_bpei),Cjep,Qjep) + + //Tunelling current + if (V(br_bpei) <0.0 || V(br_biei) < 0.0) begin : HICTUN +// real pocce,czz; + if(tunode==1 && cjep0_t > 0.0 && vdep_t >0.0) begin + pocce = exp((1-1/zep)*ln(Cjep/cjep0_t)); + czz = -(V(br_bpei)/vdep_t)*ibets_t*pocce; + ibet = czz*exp(-abet_t/pocce); + end else if (tunode==0 && cjei0_t > 0.0 && vdei_t >0.0) begin + pocce = exp((1-1/zei)*ln(Cjei/cjei0_t)); + czz = -(V(br_biei)/vdei_t)*ibets_t*pocce; + ibet = czz*exp(-abet_t/pocce); + end else begin + ibet = 0.0; + end + end else begin + ibet = 0.0; + end + + + //Depletion capacitance and charge at peripheral b-c junction (bp,ci) + `HICJQ(cjcx02_t,vdcx_t,zcx,vptcx_t,V(br_bpci),c_dummy,qjcx0_t_ii) + + //Base currents across peripheral b-c junction (bp,ci) + `HICDIO(ibcxs,ibcxs_t,mbcx,V(br_bpci),ijbcx) + + //Depletion capacitance and charge at external b-c junction (b,ci) + `HICJQ(cjcx01_t,vdcx_t,zcx,vptcx_t,V(br_bci),c_dummy,qjcx0_t_i) + + //Depletion substrate capacitance and charge at s-c junction (si,ci) + `HICJQ(cjs0_t,vds_t,zs,vpts_t,V(br_sici),c_dummy,Qjs) + + //Parasitic substrate transistor transfer current and diffusion charge + if(itss > 0.0) begin : Sub_Transfer + HSUM = msf*VT; + HSa = limexp(V(br_bpci)/HSUM); + HSb = limexp(V(br_sici)/HSUM); + HSI_Tsu = itss_t*(HSa-HSb); + if(tsf > 0.0) begin + Qdsu = tsf_t*itss_t*HSa; + end else begin + Qdsu = 0.0; + end + end else begin + HSI_Tsu = 0.0; + Qdsu = 0.0; + end + + // Current gain computation for correlated noise implementation + betad=ibei; + if (betad > 0.0) begin + betadin=betad; + betan=it; + betadc=betan/betad; + end else begin + betadc=0.0; + end + + //Diode current for s-c junction (si,ci) + `HICDIO(iscs,iscs_t,msc,V(br_sici),ijsc) + + //Self-heating calculation + if (flsh == 1 && rth >= `MIN_R) begin + pterm = V(br_ciei)*it + (vdci_t-V(br_bici))*iavl; + end else if (flsh == 2 && rth >= `MIN_R) begin + pterm = V(br_ciei)*it + (vdci_t-V(br_bici))*iavl + ibei*V(br_biei) + ibci*V(br_bici) + ibep*V(br_bpei) + ijbcx*V(br_bpci) + ijsc*V(br_sici); + if (rbi >= `MIN_R) begin + pterm = pterm + V(br_bpbi_i)*V(br_bpbi_i)/rbi; + end + if (re_t >= `MIN_R) begin + pterm = pterm + V(br_eie_i)*V(br_eie_i)/re_t; + end + if (rcx_t >= `MIN_R) begin + pterm = pterm + V(br_cic_i)*V(br_cic_i)/rcx_t; + end + if (rbx_t >= `MIN_R) begin + pterm = pterm + V(br_bbp_i)*V(br_bbp_i)/rbx_t; + end + end + + Itxf = itf; + Qdeix = Qdei; + // Excess Phase calculation + + if (flnqs != 0 && Tf != 0) begin + Vxf1 = V(br_bxf1); + Vxf2 = V(br_bxf2); + + Ixf1 = (Vxf2-itf)/Tf*t0; + Ixf2 = (Vxf2-Vxf1)/Tf*t0; + Qxf1 = alit*Vxf1*t0; + Qxf2 = alit*Vxf2/3*t0; + Itxf = Vxf2; + + Vxf = V(br_bxf); //for RC nw + fact = t0/Tf; //for RC nw + Ixf = (Vxf - Qdei)*fact; //for RC nw + Qxf = alqf*Vxf*t0; //for RC nw + Qdeix = Vxf; //for RC nw + end else begin + Ixf1 = V(br_bxf1); + Ixf2 = V(br_bxf2); + Qxf1 = 0; + Qxf2 = 0; + + Ixf = V(br_bxf); + Qxf = 0; + end + +end //of Model_evaluation + +begin : Load_sources + + I(br_biei) <+ $simparam("gmin")*V(br_biei); + I(br_bici) <+ $simparam("gmin")*V(br_bici); + + I(br_bci) <+ ddt(qjcx0_t_i); + I(br_bci) <+ ddt(cbcpar1*V(br_bci)); + I(br_bpci) <+ ddt(cbcpar2*V(br_bpci)); + if (rbx >= `MIN_R) begin + I(br_bbp_i) <+ V(br_bbp_i)/rbx_t; + end else begin +// V(br_bbp_v) <+ 0.0; + I(br_bbp_i) <+ V(br_bbp_i)/`MIN_R; + end + if(rbi0 >= `MIN_R) begin + I(br_bpbi_i) <+ V(br_bpbi_i)/rbi; + I(br_bpbi_i) <+ ddt(qrbi); + end else begin +// V(br_bpbi_v) <+ 0.0; + I(br_bpbi_i) <+ V(br_bpbi_i)/`MIN_R; + end + if (tunode==1.0) begin + I(br_bpei) <+ -ibet; + end else begin + I(br_biei) <+ -ibet; + end + I(br_bpei) <+ ibep; + I(br_bpei) <+ irep; + I(br_bpei) <+ ddt(Qjep); + I(br_biei) <+ ibei; + I(br_biei) <+ irei; + I(br_biei) <+ ibh_rec; + I(br_biei) <+ ddt(Qdeix+Qjei); + I(br_bpsi) <+ HSI_Tsu; + I(br_bpci) <+ ijbcx; + I(br_bpci) <+ ddt(qjcx0_t_ii+Qdsu); + I(br_be) <+ ddt(cbepar1*V(br_be)); + I(br_bpe) <+ ddt(cbepar2*V(br_bpe)); + I(br_bici) <+ ibci-iavl; + I(br_bici) <+ ddt(Qdci+Qjci); + I(br_sici) <+ ijsc; + I(br_sici) <+ ddt(Qjs); + I(br_ciei) <+ Itxf; + I(br_eici) <+ itr; + if (rcx >= `MIN_R) begin + I(br_cic_i) <+ V(br_cic_i)/rcx_t; + end else begin +// V(br_cic_v) <+ 0.0; + I(br_cic_i) <+ V(br_cic_i)/`MIN_R; + end + if (re >= `MIN_R) begin + I(br_eie_i) <+ V(br_eie_i)/re_t; + end else begin +// V(br_eie_v) <+ 0.0; + I(br_eie_i) <+ V(br_eie_i)/`MIN_R; + end + if(rsu >= `MIN_R) begin + I(br_sis_i) <+ V(br_sis_i)/rsu; + I(br_sis_i) <+ ddt(csu*V(br_sis_i)); + end else begin +// V(br_sis_v) <+ 0.0; + I(br_sis_i) <+ V(br_sis_i)/`MIN_R; + end + + // Following code is an intermediate solution (if branch contribution is not supported): + // ****************************************** + if(flsh == 0 || rth < `MIN_R) begin + I(br_sht) <+ V(br_sht)/`MIN_R; + end else begin + I(br_sht) <+ V(br_sht)/rth-pterm; + I(br_sht) <+ ddt(cth*V(br_sht)); + end + + // ****************************************** + + // For simulators having no problem with V(br_sht) <+ 0.0 + // with external thermal node, follwing code may be used. + // Note that external thermal node should remain accessible + // even without self-heating. + // ******************************************** + //if(flsh == 0 || rth < `MIN_R) begin + // V(br_sht) <+ 0.0; + //end else begin + // I(br_sht) <+ V(br_sht)/rth-pterm; + // I(br_sht) <+ ddt(cth*V(br_sht)); + //end + // ******************************************** + + // NQS effect + I(br_bxf1) <+ Ixf1; + I(br_cxf1) <+ ddt(Qxf1); + I(br_bxf2) <+ Ixf2; + I(br_cxf2) <+ ddt(Qxf2); + + I(br_bxf) <+ Ixf; //for RC nw + I(br_cxf) <+ ddt(Qxf); //for RC nw + +end //of Load_sources + + +`NOISE begin : Noise_sources + + //Thermal noise + fourkt = 4.0 * `P_K * Tdev; + if(rbx >= `MIN_R) begin + I(br_bbp_i) <+ white_noise(fourkt/rbx_t, "thermal"); + end + if(rbi0 >= `MIN_R) begin + I(br_bpbi_i) <+ white_noise(fourkt/rbi, "thermal"); + end + if(rcx >= `MIN_R) begin + I(br_cic_i) <+ white_noise(fourkt/rcx_t, "thermal"); + end + if(re >= `MIN_R) begin + I(br_eie_i) <+ white_noise(fourkt/re_t, "thermal"); + end + if(rsu >= `MIN_R) begin + I(br_sis_i) <+ white_noise(fourkt/rsu, "thermal"); + end + + //Flicker noise : Fully correlated between the perimeter and internal base-node + flicker_Pwr = kf*pow((ibei+ibep),af); + if (cfbe == -1) begin + I(br_biei) <+ flicker_noise(flicker_Pwr,1.0); + end else begin + I(br_bpei) <+ flicker_noise(flicker_Pwr,1.0); + end + + //Shot noise + + twoq = 2.0 * `P_Q; + // I(br_ciei) <+ white_noise(twoq*it, "shot"); + I(br_cibi) <+ white_noise(twoq*iavl, "shot"); + + // I(br_biei) <+ white_noise(twoq*ibei, "shot"); + + I(br_bici) <+ white_noise(twoq*abs(ibci), "shot"); + + I(br_bpei) <+ white_noise(twoq*ibep, "shot"); + + I(br_bpci) <+ white_noise(twoq*abs(ijbcx), "shot"); + + I(br_sici) <+ white_noise(twoq*abs(ijsc), "shot"); + + // Code section for correlated noise + // Please turn-off this code section by "//" in order to run the code with Spectre + +// I(b_n1) <+ white_noise(2 * `P_Q * ibei, "shot"); +// I(b_n1) <+ V(b_n1); +// I(b_n2) <+ white_noise(2 * `P_Q * it, "shot"); +// I(b_n2) <+ V(b_n2); +// +// I(bi,ei) <+ V(b_n1); +// I(ci,ei) <+ V(b_n2)+ddt((betadc/2)*alit*Tf*alit*Tf*ddt(V(b_n2))); +// I(ci,ei) <+ betadc*ddt(-(Tf*alit)*V(b_n1)); +end //of Noise_sources + +end //analog +endmodule diff --git a/src/spicelib/devices/adms/mextram/admsva/IP_NOTICE_DISCLAIMER_LICENSE b/src/spicelib/devices/adms/mextram/admsva/IP_NOTICE_DISCLAIMER_LICENSE new file mode 100644 index 000000000..9f542f722 --- /dev/null +++ b/src/spicelib/devices/adms/mextram/admsva/IP_NOTICE_DISCLAIMER_LICENSE @@ -0,0 +1,47 @@ +// Copyright (c) 2000-2007, NXP Semiconductors +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University + +INTELLECTUAL PROPERTY NOTICE, DISCLAIMER AND LICENSE + +The Mextram model and documentation presented at this website, +denoted as the Model, +has been developed by NXP Semiconductors until 2007, +Delft University of Technology from 2007 to 2014, +and Auburn University since April 2015. + +The Model is distributed as is, completely without any expressed +or implied warranty or service support. +NXP Semiconductors, Delft University of Technology, +Auburn University and their employees are not liable for +the condition or performance of the Model. + +NXP Semiconductors, Delft University of Technology, +Auburn University own +the copyright and grant users a perpetual, +irrevocable, worldwide, non-exclusive, royalty-free +license with respect to the Model as set forth below. + +NXP Semiconductors, Delft University of Technology, Auburn University +hereby disclaim all implied warranties. + +NXP Semiconductors, Delft University of Technology, Auburn University +grant the users the right to modify, copy, and +redistribute the Model and documentation, +both within the user's organization and externally, +subject to the following restrictions + +1. The users agree not to charge for the code +itself but may charge for additions, extensions, or support. + +2. In any product based on the Model, the users agree to acknowledge +NXP Semiconductors, Delft University of Technology, Auburn University +that developed the Model. This acknowledgment +shall appear in the product documentation. + +3. The users agree to obey all restrictions governing redistribution +or export of the Model. + +4. The users agree to reproduce any copyright notice which appears +on the Model on any copy or modification of such made available +to others. diff --git a/src/spicelib/devices/adms/mextram/admsva/bjt504t.va b/src/spicelib/devices/adms/mextram/admsva/bjt504t.va new file mode 100644 index 000000000..6acf64b19 --- /dev/null +++ b/src/spicelib/devices/adms/mextram/admsva/bjt504t.va @@ -0,0 +1,54 @@ +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. + +`include "frontdef.inc" +`define SELFHEATING +`define SUBSTRATE + +module bjt504tva (c, b, e, s, dt); + +`ifdef insideADMS + `define P(p) (*p*) +`else + `define P(p) +`endif + + // External ports + inout c, b, e, s, dt; + + electrical c `P(desc="external collector node"); + electrical b `P(desc="external base node"); + electrical e `P(desc="external emitter node"); + electrical s `P(desc="external substrate node"); + electrical dt `P(desc="external thermal node"); + + // Internal nodes + electrical c1 `P(desc="internal collector node 1"); + electrical e1 `P(desc="internal emitter node"); + electrical b1 `P(desc="internal base node 1"); + electrical b2 `P(desc="internal base node 2"); + electrical c2 `P(desc="internal collector node 2"); + electrical c3 `P(desc="internal collector node 3"); + electrical c4 `P(desc="internal collector node 4"); + // For correlated noise implementation + electrical noi `P(desc="internal noise node"); + +`include "parameters.inc" +`include "variables.inc" +//`include "opvars.inc" + +analog begin +`include "initialize.inc" +`include "tscaling.inc" +`include "evaluate.inc" +`include "noise.inc" +//`include "opinfo.inc" + +// The following can be used to print OP-info to std out: +// `include "op_print.inc" + +end // analog +endmodule + diff --git a/src/spicelib/devices/adms/mextram/admsva/evaluate.inc b/src/spicelib/devices/adms/mextram/admsva/evaluate.inc new file mode 100644 index 000000000..f67486930 --- /dev/null +++ b/src/spicelib/devices/adms/mextram/admsva/evaluate.inc @@ -0,0 +1,655 @@ +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. + +// Evaluate model equations + +begin // Currents and charges +// Nodal biases + + Vb2c1 = TYPE * V(b2, c1); + Vb2c2 = TYPE * V(b2, c2); + Vb2e1 = TYPE * V(b2, e1); + Vb1e1 = TYPE * V(b1, e1); + Vb1b2 = TYPE * V(b1, b2); +`ifdef SUBSTRATE + Vsc1 = TYPE * V(s, c1); +`endif + Vc1c2 = TYPE * V(c1, c2); + Vee1 = TYPE * V(e, e1); + Vbb1 = TYPE * V(b, b1); + Vbe = TYPE * V(b, e); + Vbc = TYPE * V(b, c); + +/* RvdT, 03-12-2007, voltage differences + associated with distributed parasitic collector. + Evaluated taking values of resistances into account: + in case of vanishing resistance corresponding node + is not addressed: */ + +`ifdef insideADMS +//dw we have limited all the RCXXX to MIN_R + Vc4c1 = TYPE * V(c4, c1); + Vc3c4 = TYPE * V(c3, c4); +`else + if (RCBLX > 0.0) + begin + if (RCBLI > 0.0) + begin + Vc4c1 = TYPE * V(c4, c1); + Vc3c4 = TYPE * V(c3, c4); + end + else + begin + Vc4c1 = 0 ; + Vc3c4 = TYPE * V(c3, c1); + end + end + else + begin + if (RCBLI > 0.0) + begin + Vc4c1 = TYPE * V(c4, c1); + Vc3c4 = 0 ; + end + else + begin + Vc4c1 = 0 ; + Vc3c4 = 0 ; + end + end +`endif + + Vb1c4 = Vb1b2 + Vb2c2 - Vc1c2 - Vc4c1 ; + Vcc3 = - Vbc + Vbb1 + Vb1c4 - Vc3c4 ; + Vbc3 = Vbc + Vcc3 ; + +`ifdef SUBSTRATE +Vsc4 = Vsc1 - Vc4c1 ; +Vsc3 = Vsc4 - Vc3c4 ; +`endif + + +// Exponential bias terms + + `expLin(eVb2c2,Vb2c2 * VtINV) + `expLin(eVb2e1,Vb2e1 * VtINV) + `expLin(eVb1e1,Vb1e1 * VtINV) + `expLin(eVb1c4,Vb1c4 * VtINV) + `expLin(eVb1b2,Vb1b2 * VtINV) + `expLin(eVbc3,Vbc3 * VtINV) +`ifdef SUBSTRATE + `expLin(eVsc1,Vsc1 * VtINV) +// RvdT MXT504.10, new: eVsc3, eVsc4 + `expLin(eVsc3,Vsc3 * VtINV) + `expLin(eVsc4,Vsc4 * VtINV) +`endif + + `expLin(eVbc3VDC,(Vbc3 - VDC_T) * VtINV) + `expLin(eVb1c4VDC,(Vb1c4 - VDC_T) * VtINV) + `expLin(eVb2c2VDC,(Vb2c2 - VDC_T) * VtINV) + `expLin(eVb2c1VDC,(Vb2c1 - VDC_T) * VtINV) + +// Governing equations + + // Epilayer model + + K0 = sqrt(1.0 + 4.0 * eVb2c2VDC); + Kw = sqrt(1.0 + 4.0 * eVb2c1VDC); + pW = 2.0 * eVb2c1VDC / (1.0 + Kw); +// if (pW < `TEN_M40) pW = 0; + Ec = Vt * (K0 - Kw - ln((K0 + 1.0) / (Kw + 1.0)) ); + Ic1c2 = (Ec + Vc1c2) / RCV_TM; + + if (Ic1c2 > 0.0) begin + + `linLog(tmpV,Vb2c1,100.0); + Vqs_th = VDC_T + 2.0 * Vt * + ln(0.5 * Ic1c2 * RCV_TM * VtINV + 1.0) - tmpV; + eps_VDC = 0.2 * VDC_T; + `max_hyp0(Vqs, Vqs_th, eps_VDC); + Iqs = Vqs * (Vqs + IHC_M * SCRCV_M) / (SCRCV_M * (Vqs + IHC_M * RCV_TM)); + + Ic1c2_Iqs = Ic1c2 / Iqs; + `max_logexp(alpha1, Ic1c2_Iqs, 1.0, AXI); + alpha = alpha1 / (1.0 + AXI * ln(1.0 + exp(-1.0 / AXI))); + vyi = Vqs / (IHC_M * SCRCV_M); + yi = (1.0 + sqrt(1.0 + 4.0 * alpha * vyi * (1.0 + vyi))) / + (2.0 * alpha * (1.0 + vyi)); + + //xi_w = 1.0 - yi / (1.0 + pW * yi); + // Niu 5/23/2015, fixes numerical discontinuity at forward/reverse transition, see "Epi layer model improvement of smoothness at I=0" + xi_w = (1.0 - yi + pW * yi) / (1.0 + pW * yi); + gp0 = 0.5 * Ic1c2 * RCV_TM * xi_w * VtINV; + + gp0_help = 2.0 * gp0 + pW * (pW + gp0 + 1.0); + gp02 = 0.5 * (gp0 - 1.0); + sqr_arg = gp02 * gp02 + gp0_help; + if (gp0 >= 1.0) + p0star = gp02 + sqrt(sqr_arg); + else + p0star = gp0_help / (sqrt(sqr_arg) - gp02); +// if (p0star < `TEN_M40) p0star = 0.0; + + + eVb2c2star = p0star * (p0star + 1.0) * exp(VDC_T * VtINV); + B1 = 0.5 * SCRCV_M * (Ic1c2 - IHC_M); + B2 = SCRCV_M * RCV_TM * IHC_M * Ic1c2; + Vxi0 = B1 + sqrt(B1 * B1 + B2); + Vch = VDC_T * (0.1 + 2.0 * Ic1c2 / (Ic1c2 + Iqs)); + Icap = IHC_M * Ic1c2 / (IHC_M + Ic1c2); + Icap_IHC = IHC_M / (IHC_M + Ic1c2); + + end else begin + + Iqs = 0.0 ; + p0star = 2.0 * eVb2c2VDC / (1.0 + K0); + eVb2c2star = eVb2c2; + if ((abs(Vc1c2) < 1.0e-5 * Vt) || + (abs(Ec) < `TEN_M40 * Vt * (K0 + Kw))) + begin + pav = 0.5 * (p0star + pW); + xi_w = pav / (pav + 1.0); + end + + else + begin + xi_w = Ec / (Ec + Vb2c2 - Vb2c1); + end + + Vxi0 = Vc1c2; + Vch = 0.1 * VDC_T; + Icap = Ic1c2; + Icap_IHC = 1.0 - Icap / IHC_M; + + end + + // Effective emitter junction capacitance bias + + Vfe = VDE_T * (1.0 - pow(`AJE , -1.0 / PE)); + a_VDE = 0.1 * VDE_T; + `min_logexp(Vje, Vb2e1, Vfe, a_VDE); + +// RvdT, November 2008, E0BE to be re-used in EB- Zener tunnel model: + E0BE = pow(1.0 - Vje * inv_VDE_T, 1.0 - PE) ; + Vte = VDE_T / (1.0 - PE) * (1.0 - E0BE) + + `AJE * (Vb2e1 - Vje); + + // Effective collector junction capacitance bias + + Vjunc = Vb2c1 + Vxi0; + bjc = (`AJC - XP_T) / (1.0 - XP_T); + Vfc = VDC_T * (1.0 - pow(bjc, -1.0 / PC)); + `min_logexp(Vjc, Vjunc, Vfc, Vch); + fI = pow(Icap_IHC, MC); + Vcv = VDC_T / (1.0 - PC) * (1.0 - fI * pow(1.0 - Vjc / VDC_T, 1.0 - PC)) + + fI * bjc * (Vjunc - Vjc); + Vtc = (1.0 - XP_T) * Vcv + XP_T * Vb2c1; + + // Transfer current + + If0 = 4.0 * IS_TM / IK_TM; + f1 = If0 * eVb2e1; + n0 = f1 / (1.0 + sqrt(1.0 + f1)); + f2 = If0 * eVb2c2star; + nB = f2 / (1.0 + sqrt(1.0 + f2)); + + if (DEG == 0.0) + q0I = 1.0 + Vte / VER_T + Vtc / VEF_T; + else + begin + termE = (Vte / VER_T + 1.0) * DEG_T * VtINV; + termC = -Vtc / VEF_T * DEG_T * VtINV; + q0I = (exp(termE) - exp(termC)) / + (exp(DEG_T * VtINV) - 1.0); + end + + `max_hyp0(q1I, q0I, 0.1); + qBI = q1I * (1.0 + 0.5 * (n0 + nB)); + + Ir = IS_TM * eVb2c2star; + If = IS_TM * eVb2e1; + In = (If - Ir) / qBI; + + // Base and substrate current(s) + + Ibf0 = IS_TM / BF_T; + if (XREC == 0.0) + Ib1 = (1.0 - XIBI) * Ibf0 * (eVb2e1 - 1.0); + else + Ib1 = (1.0 - XIBI) * Ibf0 * ((1.0 - XREC) * (eVb2e1 - 1.0) + + XREC * (eVb2e1 + eVb2c2star - 2.0) * (1.0 + Vtc / VEF_T)); + + Ib1_s = XIBI * Ibf0 * (eVb1e1 - 1.0); + `expLin(tmpExp,Vb2e1 * VtINV / MLF) + Ib2 = IBF_TM * (tmpExp - 1.0) + $simparam("gmin") * Vb2e1; + `expLin(tmpExp,0.5 * Vb1c4 * VtINV) + Ib3 = IBR_TM * (eVb1c4 - 1.0) / + (tmpExp + exp(0.5 * VLR * VtINV)) + + $simparam("gmin") * Vb1c4; + +// begin RvdT, November 2008, MXT504.8_alpha + +// Base-emitter tunneling current +// max E-field E0BE calculated in BE depletion charge model: + + if (IZEB > 0.0 && NZEB > 0.0 && Vb2e1 < 0) + begin + + `expLin(eZEB, nZEB_T * (1 - (pow2_2mPE/(2.0*E0BE)))) +// Force all derivatives at Vb2e1=0 to zero by using in DZEB a +// modified dE0BE expression for E0BE: + x = Vb2e1 * inv_VDE_T ; + dE0BE = pow(- x, -2.0-PE)*(PE*(1-PE*PE-3*x*(PE-1))-6*x*x*(PE-1+x)) * `one_sixth ; + `expLin(edZEB, Vb2e1 * pow2_2mPE * nZEB_T / (VGZEB_T * dE0BE )) + DZEB = - Vb2e1 - VGZEB_T * dE0BE * (1 - edZEB) / (pow2_2mPE * nZEB_T) ; + Izteb = 2.0 * IZEB_TM * DZEB * E0BE * eZEB * inv_VDE_T * pow2_PEm2 ; + end + else + begin + DZEB = 0 ; + Izteb = 0 ; + end + +// end RvdT, November 2008, MXT504.8_alpha + + // Iex, Isub (XIex, XIsub) + g1 = If0 * eVb1c4; + g2 = 4.0 * eVb1c4VDC; + +// nBex until and including MXT 504.9: +// nBex = g1 / (1.0 + sqrt(1.0 + g1)); +// nBex since MXT 504.10.1: Ackn. Jos Peters, Geoffrey Coram + nBex = (g1 - If0) / (1.0 + sqrt(1.0 + g1)); + pWex = g2 / (1.0 + sqrt(1.0 + g2)); +// Iex until and including MXT 504.9: +// Iex = (1.0 / BRI_T) * (0.5 * IK_TM * nBex - IS_TM); +// +// Iex since MXT 504.10: RvdT@TUDelft Q1, 2011: + Iex = IK_TM * nBex / (2.0 * BRI_T) ; + +`ifdef SUBSTRATE +// RvdT MXT504.10, new term: eVsc4 + if (EXSUB == 1.0) + Isub = 2.0 * ISS_TM * (eVb1c4 - eVsc4) / + (1.0 + sqrt(1.0 + 4.0 * (IS_TM / IKS_TM) * eVb1c4)); + else + Isub = 2.0 * ISS_TM * (eVb1c4 - 1.0) / + (1.0 + sqrt(1.0 + 4.0 * (IS_TM / IKS_TM) * eVb1c4)); + +// until504.8: Isf = ISS_TM * (eVsc1 - 1.0); +// New 504.9: + +if (ICSS < 0.0) +// this clause is to implement backwards compatibility + begin + Isf = ISS_TM * (eVsc1 - 1.0); + end + else + begin + Isf = ICSS_TM * (eVsc1 - 1.0); + end + +// End: New 504.9. + +`endif + + XIex =0.0; + +`ifdef SUBSTRATE + XIsub = 0.0; +`endif + +// begin: RvdT, Q4 2012, Mextram 504.11: added EXMOD=2 option: + if (EXMOD == 1 || EXMOD == 2) + begin + + Iex = Iex * Xext1; + +`ifdef SUBSTRATE + Isub = Isub * Xext1; +`endif + + Xg1 = If0 * eVbc3; +// XnBex until and including MXT 504.9: +// XnBex = Xg1 / (1.0 + sqrt(1.0 + Xg1)); +// XnBex in MXT 504.10.1: Ackn. Jos Peters, Geoffrey Coram: + XnBex = (Xg1 - If0) / (1.0 + sqrt(1.0 + Xg1)); +// XIMex until and including MXT 504.9: +// XIMex = XEXT * (0.5 * IK_TM * XnBex - IS_TM) / BRI_T; +// +// XIMex in MXT 504.10: RvdT@TUDelft Q1, 2011: + XIMex = XEXT * 0.5 * IK_TM * XnBex / BRI_T; + +`ifdef SUBSTRATE +// RvdT MXT504.10, new term: eVsc3 + if (EXSUB == 1.0) + XIMsub = XEXT * 2.0 * ISS_TM * (eVbc3 - eVsc3) / + (1.0 + sqrt(1.0 + 4.0 * IS_T / IKS_T * eVbc3)); + else + XIMsub = XEXT * 2.0 * ISS_TM * (eVbc3 - 1.0) / + (1.0 + sqrt(1.0 + 4.0 * IS_T / IKS_T * eVbc3)); +`else + XIMsub = 0.0; +`endif + + if (EXMOD == 1) + begin +`ifdef SUBSTRATE + Vex_bias = XEXT * (IS_TM / BRI_T + ISS_TM) * RCCxx_TM; +`else + Vex_bias = XEXT * (IS_TM / BRI_T) * RCCxx_TM; +`endif + Vex = Vt * (2.0 - ln( Vex_bias * VtINV)); + vdif = Vbc3 - Vex; + `max_hyp0(VBex, vdif, 0.11); + Fex = VBex /(Vex_bias + (XIMex + XIMsub) * RCCxx_TM + VBex); + end + else + begin + Vex = 0.0 ; + vdif = 0.0 ; + VBex = 0.0 ; + Fex = 1.0 ; + end + +/* end: RvdT, Q4, 2012, Mextram 504.11: added EXMOD=2 option: */ + + XIex = Fex * XIMex; + +`ifdef SUBSTRATE + XIsub = Fex * XIMsub; +`endif + end + else + begin + Fex = 0; + XnBex = 0 ; + end + + // Variable base resistance + + q0Q = 1.0 + Vte / VER_T + Vtc / VEF_T; + `max_hyp0(q1Q, q0Q, 0.1); + qBQ = q1Q * (1.0 + 0.5 * (n0 + nB)); + + Rb2 = 3.0 * RBV_TM / qBQ; + Ib1b2 = (2.0 * Vt * (eVb1b2 - 1.0) + Vb1b2) / Rb2; + + // Weak-avalanche current + + Iavl = 0.0; + Gem = 0.0; + if ((Ic1c2 > 0.0) && (Vb2c1 < VDC_T)) begin + + dEdx0 = 2.0 * VAVL / (WAVL * WAVL); + sqr_arg = (VDC_T - Vb2c1) / Icap_IHC; + xd = sqrt(2.0 * sqr_arg / dEdx0); + if (EXAVL == 0.0) + Weff = WAVL; + else + begin + xi_w1 = 1.0 - 0.5 * xi_w; + Weff = WAVL * xi_w1 * xi_w1; + end + Wd = xd * Weff / sqrt(xd * xd + Weff * Weff); + Eav = (VDC_T - Vb2c1) / Wd; + E0 = Eav + 0.5 * Wd * dEdx0 * Icap_IHC; + + if (EXAVL == 0) + Em = E0; + else + begin + SHw = 1.0 + 2.0 * SFH * (1.0 + 2.0 * xi_w); + Efi = (1.0 + SFH) / (1.0 + 2.0 * SFH); + Ew = Eav - 0.5 * Wd * dEdx0 * (Efi - Ic1c2 / (IHC_M * SHw)); + sqr_arg = (Ew - E0) * (Ew - E0) + 0.1 * Eav * Eav * Icap / IHC_M; + Em = 0.5 * (Ew + E0 + sqrt(sqr_arg)); + end + + EmEav_Em = (Em - Eav) / Em; + if (abs(EmEav_Em) > `TEN_M07) + begin + lambda = 0.5 * Wd / EmEav_Em; + Gem = An / BnT * Em * lambda * + (exp(-BnT / Em) - exp(-BnT / Em * (1.0 + Weff / lambda)) ); + end + else + Gem = An * Weff * exp(-BnT / Em); + + Gmax = Vt / (Ic1c2 * (RBC_TM + Rb2)) + qBI / BF_T + + RE_TM / (RBC_TM + Rb2); + Iavl = Ic1c2 * Gem / (Gem +Gem / Gmax + 1.0); + end + + if (eVb2c2star > 0.0) + Vb2c2star = Vt * ln(eVb2c2star); + else + Vb2c2star = Vb2c2; + +`ifdef SELFHEATING + // Power dissipation + +// RvdT 03-12-2007, modified power equation due to distribution collector resistance + + power = In * (Vb2e1 - Vb2c2star) + + Ic1c2 * (Vb2c2star - Vb2c1) - + Iavl * Vb2c2star + + Vee1 * Vee1 / RE_TM + + Vcc3 * Vcc3 * GCCxx_TM + + Vc3c4 * Vc3c4 * GCCex_TM + + Vc4c1 * Vc4c1 * GCCin_TM + + Vbb1 * Vbb1 / RBC_TM + + Ib1b2 * Vb1b2 + +// 504.8: Nov. 2008, RvdT, TU_Delft: Zener current contribution added: +// Izteb > 0 for Vb2e1 < 0, hence the minus sign: + (Ib1 + Ib2 - Izteb) * Vb2e1 + + Ib1_s * Vb1e1 + +`ifdef SUBSTRATE + (Iex + Ib3) * Vb1c4 + XIex * Vbc3 + + Isub * (Vb1c4 - Vsc4) + + XIsub * (Vbc3 - Vsc3) + + Isf * Vsc1; +`else + (Iex + Ib3) * Vb1c4 + XIex * Vbc3; +`endif + +`endif + + + // Charges + + Qte = (1.0 - XCJE) * CJE_TM * Vte; + `min_logexp(Vje_s, Vb1e1, Vfe, a_VDE); + Qte_s = XCJE * CJE_TM * (VDE_T / (1.0 - PE) * + (1.0 - pow(1.0 - Vje_s * inv_VDE_T, 1.0 - PE)) + + `AJE * (Vb1e1 - Vje_s)); + + Qtc = XCJC * CJC_TM * Vtc; + Qb0 = TAUB_T * IK_TM; + Qbe_qs = 0.5 * Qb0 * n0 * q1Q; + Qbc_qs = 0.5 * Qb0 * nB * q1Q; + + a_VDC = 0.1 * VDC_T; + `min_logexp(Vjcex, Vb1c4, Vfc, a_VDC); + Vtexv = VDC_T / (1.0 - PC) * (1.0 - pow(1.0 - Vjcex / VDC_T, 1.0 - PC)) + + bjc * (Vb1c4 - Vjcex); + Qtex = CJC_TM * ((1.0 - XP_T) * Vtexv + XP_T * Vb1c4) * + (1.0 - XCJC) * (1.0 - XEXT); + + `min_logexp(XVjcex, Vbc3, Vfc, a_VDC); + XVtexv = VDC_T / (1.0 - PC) * (1.0 - pow(1.0 - XVjcex / VDC_T, 1.0 - PC)) + + bjc * (Vbc3 - XVjcex); + XQtex = CJC_TM * ((1.0 - XP_T) * XVtexv + XP_T * Vbc3) * + (1.0 - XCJC) * XEXT; + +`ifdef SUBSTRATE + a_VDS = 0.1 * VDS_T; + Vfs = VDS_T * (1.0 - pow(`AJS , -1.0 / PS)); + `min_logexp(Vjs, Vsc1, Vfs, a_VDS); + Qts = CJS_TM * (VDS_T / (1.0 - PS) * + (1.0 - pow(1.0 - Vjs / VDS_T, 1.0 - PS)) + `AJS * (Vsc1 - Vjs)); +`endif + + Qe0 = TAUE_T * IK_TM * pow(IS_TM / IK_TM, 1.0 / MTAU); + `expLin(tmpExp,Vb2e1 / (MTAU * Vt)) + + // Niu Q2, 2016, for fixing reverse VBE noise when KE=1, KC=1, + // Previous Qe_qs causes unphysically large noise correlation time constant tau_n + Qe_qs = Qe0 * tmpExp; + + Qepi0 = 4.0 * TEPI_T * Vt / RCV_TM; + Qepi = 0.5 * Qepi0 * xi_w * (p0star + pW + 2.0); + + Qex = TAUR_T * 0.5 * (Qb0 * nBex + Qepi0 * pWex) / (TAUB_T + TEPI_T); + XQex = 0.0; + + if (EXMOD == 1) begin + + Qex = Qex * (1.0 - XEXT); + Xg2 = 4.0 * eVbc3VDC; + XpWex = Xg2 / (1.0 + sqrt(1.0 + Xg2)); + XQex = 0.5 * Fex * XEXT * TAUR_T * + (Qb0 * XnBex + Qepi0 * XpWex) / (TAUB_T + TEPI_T); + + end + + Qb1b2 = 0.0; + if (EXPHI == 1) + begin + dVteVje = pow(1.0 - Vje * inv_VDE_T, -PE) - `AJE; + Vb2e1Vfe = (Vb2e1 - Vfe) / a_VDE; + if (Vb2e1Vfe < 0.0) + dVjeVb2e1 = 1.0 / (1.0 + exp(Vb2e1Vfe)); + else + dVjeVb2e1 = exp(- Vb2e1Vfe) / (1.0 + exp(- Vb2e1Vfe)); + + dVteVb2e1 = dVteVje * dVjeVb2e1 + `AJE; + dQteVb2e1 = (1.0 - XCJE) * CJE_TM * dVteVb2e1; + + dn0Vb2e1 = If0 * eVb2e1 * VtINV * (0.5 / sqrt(1.0 + f1)); + dQbeVb2e1 = 0.5 * Qb0 * q1Q * dn0Vb2e1; + + // Niu, Q2 2016. Modified to fix reverse VBE noise problem. + dQeVb2e1 = Qe_qs / (MTAU * Vt); + + Qb1b2 = 0.2 * Vb1b2 * (dQteVb2e1 + dQbeVb2e1 + dQeVb2e1); + + Qe = (1 - KE) * Qe_qs; + Qbe_qs_eff = Qbe_qs + KE * Qe_qs; + Qbc = XQB * Qbe_qs_eff + Qbc_qs; + Qbe = (1 - XQB) * Qbe_qs_eff; + + end + else + begin + Qbe = Qbe_qs; + Qbc = Qbc_qs; + Qe = Qe_qs; + end + + +// Add branch current contributions + + // Static currents + I(c1, c2) <+ TYPE * Ic1c2; + I(c2, e1) <+ TYPE * In; + I(b1, e1) <+ TYPE * Ib1_s; +// begin RvdT, 28-10-2008, MXT504.8_alpha +// contribution tunnel current added + I(b2, e1) <+ TYPE * (Ib1 + Ib2 - Izteb); + +`ifdef SUBSTRATE + I(b1, s) <+ TYPE * Isub; + I(b, s) <+ TYPE * XIsub; + I(s, c1) <+ TYPE * Isf; +`endif + I(b1, b2) <+ TYPE * Ib1b2; + I(b2, c2) <+ TYPE * (-1.0 * Iavl); + I(e, e1) <+ TYPE * Vee1 / RE_TM; + I(b, b1) <+ TYPE * Vbb1 / RBC_TM; + +`ifdef SELFHEATING + // Electrical equivalent for the thermal network + I(dt) <+ V(dt) / RTH_Tamb_M; + I(dt) <+ ddt(CTH_M * V(dt)); + I(dt) <+ -1.0 * power; +`endif + + + // Dynamic currents + I(b2, e1) <+ ddt(TYPE * (Qte + Qbe + Qe)); + I(b1, e1) <+ ddt(TYPE * (Qte_s)); + I(b2, c2) <+ ddt(TYPE * (Qtc + Qbc + Qepi)); +`ifdef SUBSTRATE + I(s, c1) <+ ddt(TYPE * Qts); +`endif + I(b1, b2) <+ ddt(TYPE * Qb1b2); + I(b, e) <+ ddt(TYPE * CBEO_M * Vbe); + I(b, c) <+ ddt(TYPE * CBCO_M * Vbc); + + end // Currents and charges + + +/* RvdT, Delft Univ. Tech. 03-12-2007. +Distribution of parasitic collector resistance. +This construct supports the case +RCBLI = 0.0 and or RCBLX = 0.0 . +It is up to the compiler to adjust the circuit topology +and perform a node-collapse in such cases. */ +`ifdef insideADMS +//dw we have limited all the RCXXX to MIN_R + I(b, c3) <+ TYPE * XIex; + I(c, c3) <+ TYPE * Vcc3 * GCCxx_TM ; + I(b, c3) <+ ddt(TYPE * (XQtex + XQex)); + I(c4, c1) <+ TYPE * Vc4c1 * GCCin_TM; + I(b1, c4) <+ TYPE * (Ib3 + Iex); + I(c3, c4) <+ TYPE * Vc3c4 * GCCex_TM ; + I(b1, c4) <+ ddt(TYPE * (Qtex + Qex)); +`else + if (RCBLX > 0.0) + begin + I(b, c3) <+ TYPE * XIex; + I(c, c3) <+ TYPE * Vcc3 * GCCxx_TM ; + I(b, c3) <+ ddt(TYPE * (XQtex + XQex)); + if (RCBLI > 0.0) + begin + I(c4, c1) <+ TYPE * Vc4c1 * GCCin_TM; + I(b1, c4) <+ TYPE * (Ib3 + Iex); + I(c3, c4) <+ TYPE * Vc3c4 * GCCex_TM ; + I(b1, c4) <+ ddt(TYPE * (Qtex + Qex)); + end + else + begin + V(c4, c1) <+ 0.0 ; + I(b1, c1) <+ TYPE * (Ib3 + Iex); + I(b1, c1) <+ ddt(TYPE * (Qtex + Qex)); + I(c3, c1) <+ TYPE * Vc3c4 * GCCex_TM ; + end + end + else + begin + V(c3, c4) <+ 0 ; + if (RCBLI > 0.0) + begin + I(b, c4) <+ TYPE * XIex; + I(c, c4) <+ TYPE * Vcc3 * GCCxx_TM ; + I(c4, c1) <+ TYPE * Vc4c1 * GCCin_TM; + I(b1, c4) <+ TYPE * (Ib3 + Iex); + I(b1, c4) <+ ddt(TYPE * (Qtex + Qex)); + I(b, c4) <+ ddt(TYPE * (XQtex + XQex)); + end + else + begin + I(b, c1) <+ TYPE * XIex; + I(c, c1) <+ TYPE * Vcc3 * GCCxx_TM ; + V(c4, c1) <+ 0.0 ; + I(b1, c1) <+ TYPE * (Ib3 + Iex); + I(b1, c1) <+ ddt(TYPE * (Qtex + Qex)); + I(b, c1) <+ ddt(TYPE * (XQtex + XQex)); + I(c3, c1) <+ TYPE * Vc3c4 * GCCex_TM ; + end + end +`endif + diff --git a/src/spicelib/devices/adms/mextram/admsva/frontdef.inc b/src/spicelib/devices/adms/mextram/admsva/frontdef.inc new file mode 100644 index 000000000..b2136db5e --- /dev/null +++ b/src/spicelib/devices/adms/mextram/admsva/frontdef.inc @@ -0,0 +1,130 @@ +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. + +// Front definitions + +`include "discipline.h" + +// Numerical, physical and model constants +`define TEN_M40 1.0e-40 +`define TEN_M07 1.0e-7 +`define C2K 273.15 +`define KB 1.3806226e-23 +`define QQ 1.6021918e-19 +`define KBdivQQ 8.61708691805812512584e-5 +`define one_third 0.33333333333333333333 +`define one_sixth 0.16666666666666666667 +`define VDLOW 0.05 +`define AJE 3.0 +`define AJC 2.0 +`define AJS 2.0 +`define VEXLIM 400.0 +`define PI 3.1415926 +`ifdef insideADMS +//dw needed for RCXXX limiting + `define MIN_R 0.001 +`endif + +// Desriptions and units +`ifdef __VAMS_COMPACT_MODELING__ + `define OPP(nam,uni,des) (* desc="des", units="uni" *) real nam; + `define PAR(des,uni) (* desc="des", units="uni" *) parameter real + `define PAI(des,uni) (* desc="des", units="uni" *) parameter integer +`else + `define OPP(nam,uni,des) + `define PAR(des,uni) parameter real + `define PAI(des,uni) parameter integer +`endif + +// ADMS specific definitions +`ifdef insideADMS + `define MODEL @(initial_model) + `define INSTANCE @(initial_instance) + `define NOISE @(noise) +`else + `define MODEL + `define INSTANCE + `define NOISE +`endif + +// Smooth limitting functions +`define max_hyp0(result, x, epsilon)\ + eps2 = epsilon * epsilon;\ + x2 = x * x;\ + if (x < 0.0)\ + result = 0.5 * eps2 / (sqrt(x2 + eps2) - x);\ + else\ + result = 0.5 * (sqrt(x2 + eps2) + x);\ + result=result + +`define min_logexp(result, x, x0, a)\ + dxa = (x - x0) / (a);\ + if (x < x0)\ + result = x - a * ln(1.0 + exp(dxa));\ + else\ + result = x0 - a * ln(1.0 + exp(-dxa));\ + result=result + +`define max_logexp(result, x, x0, a)\ + dxa = (x - x0) / (a);\ + if (x < x0)\ + result = x0 + a * ln(1.0 + exp(dxa));\ + else\ + result = x + a * ln(1.0 + exp(-dxa));\ + result=result + +`define expLin(result, x)\ + if (x < `VEXLIM)\ + result = exp(x);\ + else begin\ + expl = exp(`VEXLIM);\ + result = expl * (1.0 + (x - `VEXLIM));\ + end + +`define linLog(result, x, vlim)\ + if (x < vlim)\ + result = x;\ + else\ + result = vlim + ln(1.0 + (x - vlim));\ + result=result + +// Macros for the model/instance parameters +// +// MPRxx model parameter real +// MPIxx model parameter integer +// || +// cc closed lower bound, closed upper bound +// oo open lower bound, open upper bound +// co closed lower bound, open upper bound +// oc open lower bound, closed upper bound +// cz closed lower bound=0, open upper bound=inf +// oz open lower bound=0, open upper bound=inf +// nb no bounds +// ex no bounds with exclude +// sw switch(integer only, values 0=false and 1=true) +// ty switch(integer only, values -1=p-type and +1=n-type) +// +// +`define MPRnb(nam,def,uni, des) (*units=uni, desc=des*) parameter real nam=def ; +`define MPRex(nam,def,uni,exc, des) (*units=uni, desc=des*) parameter real nam=def exclude exc ; +`define MPRcc(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter real nam=def from[lwr:upr] ; +`define MPRoo(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter real nam=def from(lwr:upr) ; +`define MPRco(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter real nam=def from[lwr:upr) ; +`define MPRoc(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter real nam=def from(lwr:upr] ; +`define MPRcz(nam,def,uni, des) (*units=uni, desc=des*) parameter real nam=def from[ 0:inf); +`define MPRoz(nam,def,uni, des) (*units=uni, desc=des*) parameter real nam=def from( 0:inf); + +`define MPInb(nam,def,uni, des) (*units=uni, desc=des*) parameter integer nam=def ; +`define MPIex(nam,def,uni,exc, des) (*units=uni, desc=des*) parameter integer nam=def exclude exc ; +`define MPIcc(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter integer nam=def from[lwr:upr] ; +`define MPIoo(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter integer nam=def from(lwr:upr) ; +`define MPIco(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter integer nam=def from[lwr:upr) ; +`define MPIoc(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter integer nam=def from(lwr:upr] ; +`define MPIcz(nam,def,uni, des) (*units=uni, desc=des*) parameter integer nam=def from[ 0:inf); +`define MPIoz(nam,def,uni, des) (*units=uni, desc=des*) parameter integer nam=def from( 0:inf); + +`define MPIsw(nam,def,uni, des) (*units=uni, desc=des*) parameter integer nam=def from[ 0: 1] ; +`define MPIty(nam,def,uni, des) (*units=uni, desc=des*) parameter integer nam=def from[ -1: 1] exclude 0 ; + diff --git a/src/spicelib/devices/adms/mextram/admsva/initialize.inc b/src/spicelib/devices/adms/mextram/admsva/initialize.inc new file mode 100644 index 000000000..2eba1e368 --- /dev/null +++ b/src/spicelib/devices/adms/mextram/admsva/initialize.inc @@ -0,0 +1,83 @@ +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. + +// Initialize model constants + + // Impact ionization constants (NPN - PNP) + +if (TYPE == 1) begin + + An = 7.03e7; + Bn = 1.23e8; + +end else begin + + An = 1.58e8; + Bn = 2.04e8; + +end + +Xext1 = 1.0 - XEXT; + + // Temperature independent MULT scaling + +`ifdef SELFHEATING + CTH_M = CTH * MULT; +`endif + + CBEO_M = CBEO * MULT; + CBCO_M = CBCO * MULT; + + invMULT = 1.0 / MULT; + SCRCV_M = SCRCV * invMULT; + + KF_M = KF * pow(MULT, 1.0 - AF); + KFN_M = KFN * pow(MULT, 1.0 - (2.0 * (MLF - 1.0) + AF * (2.0 - MLF))); + +// begin: RvdT, November 2008; Zener tunneling current model + + pow2_2mPE = pow(2.0, 2.0 - PE) ; + pow2_PEm2 = 1.0 / pow2_2mPE ; + +// Reference Temperature expressed in Kelvin: + Trk = TREF + `C2K; +// Ambient Temperature expressed in Kelvin: + Tamb = $temperature + DTA; + + +// begin: RvdT, November 2008; Zener tunneling current model +// +// Comment added March 2009: this assumes VGZEBOK as a model parameter. +// +// Bandgap for Zener tunnel current model at reference temperature in eV: +// VGZEB_Tr = VGZEBOK - AVGEB*Trk*Trk / (Trk + TVGEB) ; +// `max_logexp(VGZEB_Tr, VGZEBOK - AVGEB*Trk*Trk / (Trk + TVGEB), 0.05, 0.1) ; +// end: RvdT, November 2008 + +// begin: RvdT March 2009: +// to decrease parameter interdependency, +// use VGZEB as a parameter, instead of VGZEBOK: +// VGZEB : bandgap for Zener tunneling at T = Tref, +// VGZEBOK : bandgap for Zener tunneling at T = 0 K. +// `max_logexp(VGZEBOK, VGZEB + AVGEB*Trk*Trk / (Trk + TVGEB), 0.05, 0.1) ; +//dw adms can't expand the macro `max_logexp here - using the code + _x = VGZEB + AVGEB*Trk*Trk / (Trk + TVGEB); + _x0 = 0.05; + _a = 0.1; + _dxa = (_x - _x0) / (_a); + if (_x < _x0) + VGZEBOK = _x0 + _a * ln(1.0 + exp(_dxa)); + else + VGZEBOK = _x + _a * ln(1.0 + exp(-_dxa)); + + VGZEB_Tr = VGZEB ; +// end: RvdT March 2009: use VGZEB as a parameter, instead of VGZEBOK: + + inv_VGZEB_Tr = 1.0 / VGZEB_Tr ; + + inv_VDE = 1.0 / VDE ; + +// end: RvdT, November 2008; Zener tunneling current model + diff --git a/src/spicelib/devices/adms/mextram/admsva/noise.inc b/src/spicelib/devices/adms/mextram/admsva/noise.inc new file mode 100644 index 000000000..035705124 --- /dev/null +++ b/src/spicelib/devices/adms/mextram/admsva/noise.inc @@ -0,0 +1,145 @@ +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. + +// Noise sources + +`NOISE begin + + // Thermal noise + common = 4.0 * `KB * Tk; + powerREC = common / RE_TM; // Emitter resistance + powerRBC = common / RBC_TM; // Base resistance + powerRCCxx = common * GCCxx_TM; // Collector resistance + powerRCCex = common * GCCex_TM; // Collector resistance + powerRCCin = common * GCCin_TM; // Collector resistance + powerRBV = common / Rb2 * (4.0 * eVb1b2 + 5.0) * `one_third ; // Variable base resistance + + // Main current shot noise + In_N = (If + Ir) / qBI; + powerCCS = 2.0 * `QQ * abs(In_N); + + // Weak-avalanche current shot noise + if (KAVL > 0) begin + Gem_N = abs(Iavl / In_N); + end else begin + Gem_N = 0.0; + end + + powerIIS = 2.0 * `QQ * Iavl * (Gem_N + 1); + + // Transit time for noise + if (In_N > 0.0) begin + Taub_N = (Qbe + Qbc) / In_N; + end else begin + Taub_N = TAUB_T * q1Q * qBI; + end + + // RF correlation noise model switch + if (KC == 1) begin + // use charge partition for noise transit time + taun = XQB * Taub_N; + end else if (KC == 2) begin + // use fraction of transit time for noise transit time + taun = FTAUN * Taub_N; + end else begin // KC == 0 + // no correlation noise + taun = 0; + end + + // Forward base current shot noise and 1/f noise + powerFBCS = 2.0 * `QQ * (abs(Ib1) + abs(Ib2) + abs(Izteb)); + powerFBC1fB1 = (1.0 - XIBI) * pow((abs(Ib1) / (1 - XIBI)), AF) * KF_M; + exponentFBC1fB2 = (2.0 * (MLF - 1.0)) + (AF * (2.0 - MLF)); + powerFBC1fB2 = KFN_M * pow(abs(Ib2), exponentFBC1fB2); + + // Emitter-base sidewall current shot and 1/f noise + powerEBSCS = 2.0 * `QQ * abs(Ib1_s); + if (XIBI == 0) + powerEBSC1f = 0.0; + else + powerEBSC1f = KF_M * XIBI * pow((abs(Ib1_s / XIBI)), AF); + + // Reverse base current shot noise and 1/f noise + powerRBCS = 2.0 * `QQ * abs(Ib3); + powerRBC1f = KF_M * pow(abs(Ib3), AF); + + // Extrinsic current shot noise and 1/f noise + powerExCS = 2.0 * `QQ * abs(Iex); + powerExC1f = KF_M * (1 - (EXMOD * XEXT)) * + pow((abs(Iex) / (1 - (EXMOD * XEXT))), AF); + powerExCSMOD = 2.0 * `QQ * abs(XIex) * EXMOD; + if (XEXT == 0.0) + powerExC1fMOD = 0.0; + else + powerExC1fMOD = KF_M * EXMOD * XEXT * pow((abs(XIex) / XEXT), AF); + +`ifdef SUBSTRATE + // Substrate current shot noise (between nodes B1 and S, resp. B and S) + powerSubsCS_B1S = 2.0 * `QQ * abs(Isub); + powerSubsCS_BS = 2.0 * `QQ * abs(XIsub); +`endif + + // Reference un-correlated current shot noise sources + I(noi) <+ white_noise(powerCCS); + I(noi) <+ V(noi); + + // Implementing correlated noise sources + I(b2, e1) <+ taun * ddt(V(noi)); + I(c2, b2) <+ Gem_N * V(noi); + I(c2, e1) <+ V(noi); + + // Implementing un-correlated noise sources + I(c2, b2) <+ white_noise(powerIIS); + I(b2, e1) <+ white_noise(powerFBCS); + + // Add noise sources + I(e, e1) <+ white_noise(powerREC); // "emitter resistance" + I(b, b1) <+ white_noise(powerRBC); // "base resistance" + I(b1, b2) <+ white_noise(powerRBV); // "variable base resistance" + I(b2, e1) <+ flicker_noise(powerFBC1fB1, 1); // "bas_emi_forw" + I(b2, e1) <+ flicker_noise(powerFBC1fB2, 1); // "bas_emi_forw" + I(e1, b1) <+ white_noise(powerEBSCS); // "emi_bas_side" + I(e1, b1) <+ flicker_noise(powerEBSC1f, 1); // "emi_bas_side" + I(b1, c4) <+ white_noise(powerRBCS); // "bas_col_reve" + I(b1, c4) <+ flicker_noise(powerRBC1f, 1); // "bas_col_reve" + I(b1, c4) <+ white_noise(powerExCS); // "Ext_bas_col" + I(b1, c4) <+ flicker_noise(powerExC1f, 1); // "Ext_bas_col" + I(b, c3) <+ white_noise(powerExCSMOD); // "Ext_bas_col" + I(b, c3) <+ flicker_noise(powerExC1fMOD, 1); // "Ext_bas_col" + +`ifdef SUBSTRATE + I(b1, s) <+ white_noise(powerSubsCS_B1S); // "bas_sub_current" + I(b, s) <+ white_noise(powerSubsCS_BS); // "bas_sub_current" +`endif + + if (RCBLX > 0.0) + begin + if (RCBLI > 0.0) + begin /* all branches exist */ + I(c, c3) <+ white_noise(powerRCCxx); // "collector plug resistance" + I(c3, c4) <+ white_noise(powerRCCex); // "extrinsic collector BL resistance" + I(c4, c1) <+ white_noise(powerRCCin); // "intrinsic collector BL resistance" + end + else + begin /* only Rcblx exists */ + I(c, c3) <+ white_noise(powerRCCxx); // "collector plug resistance" + I(c3, c1) <+ white_noise(powerRCCex); // "extrinsic collector BL resistance" + end + end + else + begin + if (RCBLI > 0.0) + begin /* only Rcbli exists */ + I(c, c4) <+ white_noise(powerRCCxx); // "collector plug resistance" + I(c4, c1) <+ white_noise(powerRCCin); // "intrinsic collector BL resistance" + end + else + begin /* neither Rcblx nor Rcbli exists */ + I(c, c1) <+ white_noise(powerRCCxx); // "collector plug resistance" + end + end + +end // Noise + diff --git a/src/spicelib/devices/adms/mextram/admsva/opinfo.inc b/src/spicelib/devices/adms/mextram/admsva/opinfo.inc new file mode 100644 index 000000000..14182e5e5 --- /dev/null +++ b/src/spicelib/devices/adms/mextram/admsva/opinfo.inc @@ -0,0 +1,245 @@ +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. + +// Evaluate the operating point (output) variables +begin + +`ifdef __VAMS_COMPACT_MODELING__ + + +// The external currents and the current gain +OP_ic = I(); // External DC collector current +OP_ib = I(); // External DC base Current + +if (OP_ib == 0) + begin + OP_betadc = 0.0 ; + end +else + begin + OP_betadc = OP_ic / OP_ib; // External DC Current gain + end + +// begin added in MXT 504.9: +OP_ie = I(); // External DC emitter current +OP_vbe = V(b, e); // External base-emitter bias +OP_vce = V(c, e); // External collector-emitter bias +OP_vbc = V(b, c); // External base-collector bias + +`ifdef SUBSTRATE +OP_is = I(); // External DC emitter current +OP_vse = V(s, e); // External substrate-emitter bias +OP_vbs = V(b, s); // External base-substrate bias +OP_vsc = V(s, c); // External substrate-collector bias +`endif + +// end added in MXT 504.9: + +// The internal voltage differences +OP_vb2e1 = Vb2e1; // Internal base-emiter bias +OP_vb2c2 = Vb2c2; // Internal base-emiter bias +OP_vb2c1 = Vb2c1; // Internal base-collector bias including epilayer + +OP_vb1c1 = Vb1b2 + Vb2c1; // External base-collector bias without contact resistances + +OP_vc4c1 = Vc4c1; // Bias over intrinsic buried layer +OP_vc3c4 = Vc3c4; // Bias over extrinsic buried layer + +OP_ve1e = - Vee1; // Bias over emiter resistance + +// The branch currents +OP_in = In; // Main current +OP_ic1c2 = Ic1c2; // Epilayer current +OP_ib1b2 = Ib1b2; // Pinched-base current +OP_ib1 = Ib1; // Ideal forward base current +OP_sib1 = Ib1_s; // Ideal side-wall base current +// +// 504.8, RvdT, TU-Delft April. 2009: +// +OP_izteb = Izteb ; // Zener tunneling current +// +OP_ib2 = Ib2; // Non-ideal forward base current +OP_ib3 = Ib3; // Non-ideal reverse base current +OP_iavl = Iavl; // Avalanche current +OP_iex = Iex; // Extrinsic reverse base current +OP_xiex = XIex; // Extrinsic reverse base current +`ifdef SUBSTRATE +OP_isub = Isub; // Substrate current +OP_xisub = XIsub; // Substrate current +OP_isf = Isf; // Substrate-collector current +`endif +OP_ire = - Vee1 / RE_TM; // Current through emiter resistance +OP_irbc = Vbb1 / RBC_TM; // Current through constant base resistance + +OP_ircc = Vcc3 * GCCxx_TM; // Current through collector contact resistance +OP_ircblx = Vc3c4 * GCCex_TM; // Current through extrinsic buried layer resistance +OP_ircbli = Vc4c1 * GCCin_TM; // Current through extrinsic buried layer resistance + +// The branch charges +OP_qe = Qe; // Emitter charge or emitter neutral charge +OP_qte = Qte; // Base-emiter depletion charge +OP_sqte = Qte_s; // Sidewall base-emiter depletion charge +OP_qbe = Qbe; // Base-emiter diffusion charge +OP_qbc = Qbc; // Base-collector diffusion charge +OP_qtc = Qtc; // Base-colector depletion charge +OP_qepi = Qepi; // Epilayer diffusion charge +OP_qb1b2 = Qb1b2; // AC current crowding charge +OP_qtex = Qtex; // Extrinsic base-collector depletion charge +OP_xqtex = XQtex; // Extrinsic base-collector depletion charge +OP_qex = Qex; // Extrinsic base-collector diffusion charge +OP_xqex = XQex; // Extrinsic base-collector diffusion charge +`ifdef SUBSTRATE +OP_qts = Qts; // Collector substrate depletion charge +`endif + +// Small signal equivalent circuit conductances and resistances + +OP_gx = - ddx(In, V(e1)); // Forward transconductance +OP_gy = - ddx(In, V(c2)); // Reverse transconductance + +OP_gz = - ddx(In, V(c1)); // Reverse transconductance + +OP_sgpi = - ddx(Ib1_s, V(e)) + - ddx(Ib1_s, V(e1)); // Conductance sidewal b-e junction +OP_gpix = - ddx(Ib1+Ib2, V(e1)); // Conductance floor b-e junction + +OP_gpiy = - ddx(Ib1, V(c2)); // Early effect on recombination base current +OP_gpiz = - ddx(Ib1, V(c1)); // Early effect on recombination base current + +OP_gmux = ddx( Iavl, V(e1)); // Early effect on avalanche current limitting +OP_gmuy = ddx( Iavl, V(c2)); // Conductance of avalanche current +OP_gmuz = - ddx(- Iavl, V(c1)); // Conductance of avalanche current + +// Conductance extrinsic b-c current : +OP_gmuex = ddx(Iex+Ib3, V(e)) + + ddx(Iex+Ib3, V(b1)) + + ddx(Iex+Ib3, V(b2)) + + ddx(Iex+Ib3, V(e1)) + + ddx(Iex+Ib3, V(c2)); + +OP_xgmuex = ddx(XIex, V(b)) ; // Conductance extrinsic b-c current + +OP_grcvy = - ddx(Ic1c2, V(c2)); // Conductance of epilayer current +OP_grcvz = - ddx(Ic1c2, V(c1)); // Conductance of epilayer current + +OP_rbv = 1.0 / (- ddx(Ib1b2, V(b2)) - ddx(Ib1b2, V(c2))); // Base resistance + +OP_grbvx = - ddx(Ib1b2, V(e)) - ddx(Ib1b2, V(e1)); // Early effect on base resistance +OP_grbvy = - ddx(Ib1b2, V(c2)); // Early effect on base resistance + +OP_grbvz = - ddx(Ib1b2, V(c1)); // Early effect on base resistance + +OP_re = RE_TM; // Emiter resistance +OP_rbc = RBC_TM; // Constant base resistance +OP_rcc = RCCxx_TM; // Collector Contact resistance +OP_rcblx = RCCex_TM; // Extrinsic buried layer resistance +OP_rcbli = RCCin_TM; // Extrinsic buried layer resistance + + +`ifdef SUBSTRATE +OP_gs = ddx(Isub, V(b)) + ddx(Isub, V(b1)); // Conductance parasitic PNP transitor +OP_xgs = ddx(XIsub, V(b)) ; // Conductance parasitic PNP transistor +OP_gsf = ddx(Isf, V(s)) ; // Conductance substrate-collector current +`endif + + + +// Small signal equivalent circuit capacitances +OP_scbe = - ddx(Qte_s, V(e)) - ddx(Qte_s, V(e1)); // Capacitance sidewall b-e junction + +OP_cbex = - ddx(Qte + Qbe + Qe, V(e1)) ; // Capacitance floor b-e junction + +OP_cbey = - ddx(Qbe, V(c2)); // Early effect on b-e diffusion junction + +OP_cbez = - ddx(Qbe, V(c1)); // Early effect on b-e diffusion junction + +OP_cbcx = - ddx(Qbc, V(e)) - ddx(Qbc, V(e1)); // Early effect on b-c diffusion junction + + +OP_cbcy = - ddx(Qtc + Qbc + Qepi, V(c2)); // Capacitance floor b-c junction +OP_cbcz = - ddx(Qtc + Qbc + Qepi, V(c1)); // Capacitance floor b-c junction + +// Capacitance extrinsic b-c junction : +OP_cbcex = ddx(Qtex + Qex,V(e)) + + ddx(Qtex + Qex,V(b1 )) + + ddx(Qtex + Qex,V(b2)) + + ddx(Qtex + Qex,V(e1)) + + ddx(Qtex + Qex,V(c2)) ; + +// Capacitance extrinsic b-c junction : +OP_xcbcex = ddx(XQtex + XQex, V(b)) ; + +OP_cb1b2 = - ddx(Qb1b2, V(b2)) - ddx(Qb1b2, V(c2)); // Capacitance AC current crowding + +OP_cb1b2x = - ddx(Qb1b2, V(e)) - ddx(Qb1b2, V(e1)); // Cross-capacitance AC current crowding +OP_cb1b2y = - ddx(Qb1b2, V(c2)); // Cross-capacitance AC current crowding +OP_cb1b2z = - ddx(Qb1b2, V(c1)) ; // Cross-capacitance AC current crowding + +`ifdef SUBSTRATE +OP_cts = ddx(Qts, V(s)) ; // Capacitance s-c junction +`endif + +// Approximate small signal equivalent circuit +dydx = (OP_gx - OP_gmux) / (OP_grcvy + OP_gmuy - OP_gy); +dydz = (OP_gz - OP_grcvz - OP_gmuz) / (OP_grcvy + OP_gmuy - OP_gy); +gpi = OP_sgpi + OP_gpix + OP_gmux + OP_gpiz + OP_gmuz + + (OP_gpiy + OP_gmuy) * (dydx + dydz); +OP_gm = (OP_grcvy * (OP_gx - OP_gmux + // Transconductance + OP_gz - OP_gmuz) - OP_grcvz * + (OP_gy - OP_gmuy)) / (OP_grcvy + OP_gmuy - OP_gy); +OP_beta = OP_gm / gpi; // Current amplification +OP_gout = ((OP_gy - OP_gmuy) * OP_grcvz - // Output conductance + (OP_gz - OP_gmuz) * OP_grcvy) / + (OP_grcvy + OP_gmuy - OP_gy); +OP_gmu = OP_gpiz + OP_gmuz + (OP_gpiy + OP_gmuy) * dydz + // Feedback transconductance + OP_gmuex + OP_xgmuex; +OP_rb = RBC_TM + OP_rbv; // Base resistance +OP_rc = OP_rcc + OP_rcblx + OP_rcbli; // Collector resistance +OP_cbe = OP_cbex + OP_scbe + OP_cbcx + // Base-emitter capacitance + (OP_cbey + OP_cbcy) * dydx + CBEO_M; +OP_cbc = (OP_cbey + OP_cbcy) * dydz + OP_cbcz + // Base-collector capacitance + OP_cbcex + OP_xcbcex + CBCO_M; + + +// Quantities to describe internal state of the model +gammax = (OP_gpix + OP_gmux - OP_grbvx) * OP_rbv; +gammay = (OP_gpiy + OP_gmuy - OP_grbvy) * OP_rbv; +gammaz = (OP_gpiz + OP_gmuz - OP_grbvz) * OP_rbv; +gbfx = OP_gpix + OP_sgpi * (1.0 + gammax); +gbfy = OP_gpiy + OP_sgpi * gammay; +gbfz = OP_gpiz + OP_sgpi * gammaz; + +// RvdT March 2008: +alpha_ft = (1.0 + (OP_grcvy * dydx * OP_rc) + + (OP_gx + gbfx + (OP_gy + gbfy) * dydx) * RE_TM)/ + (1.0 - (OP_grcvz + OP_grcvy * dydz) * OP_rc - + (OP_gz + gbfz + (OP_gy + gbfy) * dydz) * RE_TM); + +rx = pow((OP_grcvy * dydx + alpha_ft * (OP_grcvz + OP_grcvy * dydz)), -1); +rz = alpha_ft * rx; +ry = (1.0 - OP_grcvz * rz) / OP_grcvy; +rb1b2 = gammax * rx + gammay * ry + gammaz * rz; +rex = rz + rb1b2 - OP_rcbli; +xrex = rz + rb1b2 + RBC_TM * ((gbfx + OP_gmux) * rx + (gbfy + OP_gmuy) * ry + + (gbfz + OP_gmuz) * rz) - OP_rcbli - OP_rcblx; + +taut = OP_scbe * (rx + rb1b2) + (OP_cbex + OP_cbcx) * rx + (OP_cbey + OP_cbcy) * + ry + (OP_cbez + OP_cbcz) * rz + OP_cbcex * rex + OP_xcbcex * xrex + + (CBEO_M + CBCO_M) * (xrex - RCCxx_TM); + +OP_ft = 1.0 / (2.0 * `PI * taut); // Good approximation for cut-off frequency +OP_iqs = Iqs; // Current at onset of quasi-saturation +OP_xiwepi = xi_w; // Thickness of injection layer +OP_vb2c2star = Vb2c2star; // Physical value of internal base-collector bias + +//self-heating +`ifdef SELFHEATING +OP_pdiss = power; // Dissipation +`endif + +OP_tk = Tk; // Actual temperature + +`endif +end diff --git a/src/spicelib/devices/adms/mextram/admsva/opvars.inc b/src/spicelib/devices/adms/mextram/admsva/opvars.inc new file mode 100644 index 000000000..e892da1d6 --- /dev/null +++ b/src/spicelib/devices/adms/mextram/admsva/opvars.inc @@ -0,0 +1,156 @@ +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. + +// +// Operation point (output) variables +// + +// The external currents and current gain +`OPP(OP_ic, A, External DC collector current) +`OPP(OP_ib, A, External DC base current) +`OPP(OP_betadc, , External DC current gain Ic/Ib) + +// begin added in MXT 504.9: +`OPP(OP_ie, A, External DC emitter current) + +// The external biases +`OPP(OP_vbe, V, External base-emitter bias) +`OPP(OP_vce, V, External collector-emitter bias) +`OPP(OP_vbc, V, External base-collector bias) + +`ifdef SUBSTRATE +`OPP(OP_is, A, External DC substrate current) +`OPP(OP_vse, V, External substrate-emitter bias) +`OPP(OP_vbs, V, External base-substrate bias) +`OPP(OP_vsc, V, External substrate-collector bias) +`endif + +// end added in MXT 504.9 +// The internal biases +`OPP(OP_vb2e1, V, Internal base-emitter bias) +`OPP(OP_vb2c2, V, Internal base-collector bias) +`OPP(OP_vb2c1, V, Internal base-collector bias including epilayer) +`OPP(OP_vb1c1, V, External base-collector bias without contact resistances) +`OPP(OP_vc4c1, V, Bias over intrinsic buried layer) +`OPP(OP_vc3c4, V, Bias over extrinsic buried layer) +`OPP(OP_ve1e, V, Bias over emitter resistance) + +// The actual currents +`OPP(OP_in, A, Main current) +`OPP(OP_ic1c2, A, Epilayer current) +`OPP(OP_ib1b2, A, Pinched-base current) +`OPP(OP_ib1, A, Ideal forward base current) +`OPP(OP_sib1, A, Ideal side-wall base current) +// +// 504.8, RvdT, TU-Delft April. 2009, Zener tunneling current: +// +`OPP(OP_izteb, A, Zener tunneling current in the emitter base junction) +// +`OPP(OP_ib2, A, Non-ideal forward base current) +`OPP(OP_ib3, A, Non-ideal reverse base current) +`OPP(OP_iavl, A, Avalanche current) +`OPP(OP_iex, A, Extrinsic reverse base current) + +`OPP(OP_xiex, A, Extrinsic reverse base current) +`ifdef SUBSTRATE +`OPP(OP_isub, A, Substrate current) +`OPP(OP_xisub, A, Substrate current) +`OPP(OP_isf, A, Substrate failure current) +`endif +`OPP(OP_ire, A, Current through emitter resistance) +`OPP(OP_irbc, A, Current through constant base resistance) +`OPP(OP_ircblx, A, Current through extrinsic buried layer resistance) +`OPP(OP_ircbli, A, Current through intrinsic buried layer resistance) +`OPP(OP_ircc, A, Current through collector contact resistance) + +//The actual charges +`OPP(OP_qe, C, Emitter charge or emitter neutral charge) +`OPP(OP_qte, C, Base-emitter depletion charge) +`OPP(OP_sqte, C, Sidewall base-emitter depletion charge) +`OPP(OP_qbe, C, Base-emitter diffusion charge) +`OPP(OP_qbc, C, Base_collector diffusion charge) +`OPP(OP_qtc, C, Base-collector depletion charge) +`OPP(OP_qepi, C, Epilayer diffusion charge) +`OPP(OP_qb1b2, C, AC current crowding charge) +`OPP(OP_qtex, C, Extrinsic base-collector depletion charge) +`OPP(OP_xqtex, C, Extrinsic base-collector depletion charge) +`OPP(OP_qex, C, Extrinsic base-collector diffusion charge) +`OPP(OP_xqex, C, Extrinsic base-collector diffusion charge) +`ifdef SUBSTRATE +`OPP(OP_qts, C, Collector-substrate depletion charge) +`endif + +//Small signal equivalent circuit conductances and resistances +`OPP(OP_gx, S, Forward transconductance) +`OPP(OP_gy, S, Reverse transconductance) +`OPP(OP_gz, S, Reverse transconductance) +`OPP(OP_sgpi, S, Conductance sidewall b-e junction) +`OPP(OP_gpix, S, Conductance floor b-e junction) +`OPP(OP_gpiy, S, Early effect on recombination base current) +`OPP(OP_gpiz, S, Early effect on recombination base current) +`OPP(OP_gmux, S, Early effect on avalanche current limiting) +`OPP(OP_gmuy, S, Conductance of avalanche current) +`OPP(OP_gmuz, S, Conductance of avalanche current) +`OPP(OP_gmuex, S, Conductance of extrinsic b-c junction) +`OPP(OP_xgmuex, S, Conductance of extrinsic b-c junction) +`OPP(OP_grcvy, S, Conductance of epilayer current) +`OPP(OP_grcvz, S, Conductance of epilayer current) +`OPP(OP_rbv, Ohm, Base resistance) +`OPP(OP_grbvx, S, Early effect on base resistance) +`OPP(OP_grbvy, S, Early effect on base resistance) +`OPP(OP_grbvz, S, Early effect on base resistance) +`OPP(OP_re, Ohm, Emitter resistance) +`OPP(OP_rbc, Ohm, Constant base resistance) +`OPP(OP_rcc, Ohm, Collector contact resistance) +`OPP(OP_rcblx, Ohm, Extrinsic buried layer resistance) +`OPP(OP_rcbli, Ohm, Intrinsic buried layer resistance) +`ifdef SUBSTRATE +`OPP(OP_gs, S, Conductance parasitic PNP transistor) +`OPP(OP_xgs, S, Conductance parasitic PNP transistor) +`OPP(OP_gsf, S, Conductance substrate failure current) +`endif +//Small signal equivalent circuit capacitances +`OPP(OP_scbe, F, Capacitance sidewall b-e junction) +`OPP(OP_cbex, F, Capacitance floor b-e junction) +`OPP(OP_cbey, F, Early effect on b-e diffusion charge) +`OPP(OP_cbez, F, Early effect on b-e diffusion charge) +`OPP(OP_cbcx, F, Early effect on b-c diffusion charge) +`OPP(OP_cbcy, F, Capacitance floor b-c junction) +`OPP(OP_cbcz, F, Capacitance floor b-c junction) +`OPP(OP_cbcex, F, Capacitance extrinsic b-c junction) +`OPP(OP_xcbcex, F, Capacitance extrinsic b-c junction) +`OPP(OP_cb1b2, F, Capacitance AC current crowding) +`OPP(OP_cb1b2x, F, Cross-capacitance AC current crowding) +`OPP(OP_cb1b2y, F, Cross-capacitance AC current crowding) +`OPP(OP_cb1b2z, F, Cross-capacitance AC current crowding) +`ifdef SUBSTRATE +`OPP(OP_cts, F, Capacitance s-c junction) +`endif +//Approximate small signal equivalent circuit +`OPP(OP_gm, S,transconductance) +`OPP(OP_beta, , Current amplification) +`OPP(OP_gout, S, Output conductance) +`OPP(OP_gmu, S, Feedback transconductance) +`OPP(OP_rb, Ohm, Base resistance) +`OPP(OP_rc, Ohm, Collector resistance) +`OPP(OP_cbe, C, Base-emitter capacitance) +`OPP(OP_cbc, C, Base-collector capacitance) + +//quantities to describe internal state of the model +`OPP(OP_ft, , Good approximation for cut-off frequency) +`OPP(OP_iqs, A, Current at onset of quasi-saturation) +`OPP(OP_xiwepi, m, Thickness of injection layer) +`OPP(OP_vb2c2star, V, Physical value of internal base-collector bias) + +//self-heating +`ifdef SELFHEATING +`OPP(OP_pdiss, W, Dissipation) +`endif +`OPP(OP_tk, K, Actual temperature) + +//help variables +real dydx, dydz, gpi; +real gammax, gammay, gammaz, gbfx, gbfy, gbfz, alpha_ft; +real rx, ry, rz, rb1b2, rex, xrex, taut; diff --git a/src/spicelib/devices/adms/mextram/admsva/parameters.inc b/src/spicelib/devices/adms/mextram/admsva/parameters.inc new file mode 100644 index 000000000..f3f6b8f97 --- /dev/null +++ b/src/spicelib/devices/adms/mextram/admsva/parameters.inc @@ -0,0 +1,115 @@ +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. + +// Mextram parameters +`MPIco( LEVEL ,504 ,"" ,504 ,505 ,"Model level" ) +`MPRco( TREF ,25.0 ,"" ,-273.0 ,inf ,"Reference temperature" ) +`MPRnb( DTA ,0.0 ,"" ,"Difference between the local and global ambient temperatures" ) +`MPIcc( EXMOD ,1 ,"" ,0 ,2 ,"Flag for extended modeling of the reverse current gain" ) +`MPIcc( EXPHI ,1 ,"" ,0 ,1 ,"Flag for the distributed high-frequency effects in transient" ) +`MPIcc( EXAVL ,0 ,"" ,0 ,1 ,"Flag for extended modeling of avalanche currents" ) + +`ifdef SUBSTRATE +`MPIcc( EXSUB ,0 ,"" ,0 ,1 ,"Flag for extended modelling of substrate currents" ) +`endif + +`MPRoo( IS ,22.0a ,"" ,0.0 ,inf ,"Collector-emitter saturation current" ) +`MPRco( IK ,0.1 ,"" ,1.0p ,inf ,"Collector-emitter high injection knee current" ) +`MPRco( VER ,2.5 ,"" ,0.01 ,inf ,"Reverse Early voltage" ) +`MPRco( VEF ,44.0 ,"" ,0.01 ,inf ,"Forward Early voltage" ) +`MPRco( BF ,215.0 ,"" ,0.1m ,inf ,"Ideal forward current gain" ) +`MPRco( IBF ,2.7f ,"" ,0.0 ,inf ,"Saturation current of the non-ideal forward base current" ) +`MPRco( MLF ,2.0 ,"" ,0.1 ,inf ,"Non-ideality factor of the non-ideal forward base current" ) +`MPRcc( XIBI ,0.0 ,"" ,0.0 ,1.0 ,"Part of ideal base current that belongs to the sidewall" ) +`MPRco( IZEB ,0.0 ,"" ,0.0 ,inf ,"Pre-factor of emitter-base Zener tunneling current" ) +`MPRco( NZEB ,22.0 ,"" ,0.0 ,inf ,"Coefficient of emitter-base Zener tunneling current" ) +`MPRco( BRI ,7.0 ,"" ,1.0e-4 ,inf ,"Ideal reverse current gain" ) +`MPRco( IBR ,1.0f ,"" ,0.0 ,inf ,"Saturation current of the non-ideal reverse base current" ) +`MPRnb( VLR ,0.2 ,"" ,"Cross-over voltage of the non-ideal reverse base current" ) +`MPRcc( XEXT ,0.63 ,"" ,0.0 ,1.0 ,"Part of currents and charges that belong to extrinsic region" ) +`MPRco( WAVL ,1.1u ,"" ,1.0n ,inf ,"Epilayer thickness used in weak-avalanche model" ) +`MPRco( VAVL ,3.0 ,"" ,0.01 ,inf ,"Voltage determining curvature of avalanche current" ) +`MPRco( SFH ,0.3 ,"" ,0.0 ,inf ,"Current spreading factor of avalanche model when EXAVL=1" ) +`MPRco( RE ,5.0 ,"" ,1.0m ,inf ,"Emitter resistance" ) +`MPRco( RBC ,23.0 ,"" ,1.0m ,inf ,"Constant part of the base resistance" ) +`MPRco( RBV ,18.0 ,"" ,1.0m ,inf ,"Zero-bias value of the variable part of the base resistance" ) +`MPRco( RCC ,12.0 ,"" ,1.0m ,inf ,"Constant part of the collector resistance" ) +`MPRco( RCV ,150.0 ,"" ,1.0m ,inf ,"Resistance of the un-modulated epilayer" ) +`MPRco( SCRCV ,1250.0 ,"" ,1.0m ,inf ,"Space charge resistance of the epilayer" ) +`MPRco( IHC ,4.0m ,"" ,1.0p ,inf ,"Critical current for velocity saturation in the epilayer" ) +`MPRco( AXI ,0.3 ,"" ,0.02 ,inf ,"Smoothness parameter for the onset of quasi-saturation" ) +`MPRco( CJE ,73.0f ,"" ,0.0 ,inf ,"Zero-bias emitter-base depletion capacitance" ) +`MPRco( VDE ,0.95 ,"" ,0.05 ,inf ,"Emitter-base diffusion voltage" ) +`MPRco( PE ,0.4 ,"" ,0.01 ,0.99 ,"Emitter-base grading coefficient" ) +`MPRcc( XCJE ,0.4 ,"" ,0.0 ,1.0 ,"Sidewall fraction of the emitter-base depletion capacitance" ) +`MPRco( CBEO ,0.0 ,"" ,0.0 ,inf ,"Emitter-base overlap capacitance" ) +`MPRco( CJC ,78.0f ,"" ,0.0 ,inf ,"Zero-bias collector-base depletion capacitance" ) +`MPRco( VDC ,0.68 ,"" ,0.05 ,inf ,"Collector-base diffusion voltage" ) +`MPRco( PC ,0.5 ,"" ,0.01 ,0.99 ,"Collector-base grading coefficient" ) +`MPRco( XP ,0.35 ,"" ,0.0 ,0.99 ,"Constant part of Cjc" ) +`MPRco( MC ,0.5 ,"" ,0.0 ,1.0 ,"Coefficient for current modulation of CB depletion capacitance" ) +`MPRcc( XCJC ,32.0m ,"" ,0.0 ,1.0 ,"Fraction of CB depletion capacitance under the emitter" ) +`MPRco( RCBLX ,0.0 ,"" ,0.0 ,inf ,"Resistance Collector Buried Layer eXtrinsic" ) +`MPRco( RCBLI ,0.0 ,"" ,0.0 ,inf ,"Resistance Collector Buried Layer Intrinsic" ) +`MPRco( CBCO ,0.0 ,"" ,0.0 ,inf ,"Collector-base overlap capacitance" ) +`MPRco( MTAU ,1.0 ,"" ,0.1 ,inf ,"Non-ideality factor of the emitter stored charge" ) +`MPRco( TAUE ,2.0p ,"" ,0.0 ,inf ,"Minimum transit time of stored emitter charge" ) +`MPRoo( TAUB ,4.2p ,"" ,0.0 ,inf ,"Transit time of stored base charge" ) +`MPRco( TEPI ,41.0p ,"" ,0.0 ,inf ,"Transit time of stored epilayer charge" ) +`MPRco( TAUR ,520.0p ,"" ,0.0 ,inf ,"Transit time of reverse extrinsic stored base charge" ) +`MPRnb( DEG ,0.0 ,"" ,"Bandgap difference over the base" ) +`MPRco( XREC ,0.0 ,"" ,0.0 ,inf ,"Pre-factor of the recombination part of Ib1" ) +`MPRcc( XQB ,`one_third ,"" ,0.0 ,1.0 ,"Emitter-fraction of base diffusion charge" ) +`MPRnb( AQBO ,0.3 ,"" ,"Temperature coefficient of the zero-bias base charge" ) +`MPRnb( AE ,0.0 ,"" ,"Temperature coefficient of the resistivity of the emitter" ) +`MPRnb( AB ,1.0 ,"" ,"Temperature coefficient of the resistivity of the base" ) +`MPRnb( AEPI ,2.5 ,"" ,"Temperature coefficient of the resistivity of the epilayer" ) +`MPRnb( AEX ,0.62 ,"" ,"Temperature coefficient of the resistivity of the extrinsic base" ) +`MPRnb( AC ,2.0 ,"" ,"Temperature coefficient of the resistivity of the collector contact" ) +`MPRco( ACBL ,2.0 ,"" ,0.0 ,inf ,"Temperature coefficient of the resistivity of the collector buried layer" ) +`MPRnb( DVGBF ,50.0m ,"" ,"Band-gap voltage difference of the forward current gain" ) +`MPRnb( DVGBR ,45.0m ,"" ,"Band-gap voltage difference of the reverse current gain" ) +`MPRco( VGB ,1.17 ,"" ,0.1 ,inf ,"Band-gap voltage of the base" ) +`MPRco( VGC ,1.18 ,"" ,0.1 ,inf ,"Band-gap voltage of the collector" ) +`MPRco( VGJ ,1.15 ,"" ,0.1 ,inf ,"Band-gap voltage recombination emitter-base junction" ) +`MPRco( VGZEB ,1.15 ,"" ,0.1 ,inf ,"Band-gap voltage at Tref of Zener effect emitter-base junction" ) +`MPRoo( AVGEB ,4.73e-4 ,"" ,-inf ,inf ,"Temperature coefficient band-gap voltage for Zener effect emitter-base junction" ) +`MPRco( TVGEB ,636.0 ,"" ,0.0 ,inf ,"Temperature coefficient band-gap voltage for Zener effect emitter-base junction" ) +`MPRnb( DVGTE ,0.05 ,"" ,"Band-gap voltage difference of emitter stored charge" ) +`MPRnb( DAIS ,0.0 ,"" ,"Fine tuning of temperature dependence of C-E saturation current" ) +`MPRco( AF ,2.0 ,"" ,0.01 ,inf ,"Exponent of the Flicker-noise" ) +`MPRco( KF ,20.0p ,"" ,0.0 ,inf ,"Flicker-noise coefficient of the ideal base current" ) +`MPRco( KFN ,20.0p ,"" ,0.0 ,inf ,"Flicker-noise coefficient of the non-ideal base current" ) +`MPIcc( KAVL ,0 ,"" ,0 ,1 ,"Switch for white noise contribution due to avalanche" ) +`MPIcc( KC ,0 ,"" ,0 ,2 ,"Switch for RF correlation noise model selection" ) +`MPRcc( KE ,0.0 ,"" ,0.0 ,1.0 ,"Fraction of QE in excess phase shift" ) +`MPRcc( FTAUN ,0.0 ,"" ,0.0 ,1.0 ,"Fraction of noise transit time to total transit time" ) + +`ifdef SUBSTRATE +`MPRco( ISS ,48.0a ,"" ,0.0 ,inf ,"Base-substrate saturation current" ) +`MPRoo( ICSS ,-1.0 ,"" ,-inf ,inf ,"Collector-substrate ideal saturation current" ) +`MPRco( IKS ,250.0u ,"" ,1.0p ,inf ,"Base-substrate high injection knee current" ) +`MPRco( CJS ,315.0f ,"" ,0.0 ,inf ,"Zero-bias collector-substrate depletion capacitance" ) +`MPRoo( VDS ,0.62 ,"" ,0.05 ,inf ,"Collector-substrate diffusion voltage" ) +`MPRoo( PS ,0.34 ,"" ,0.01 ,0.99 ,"Collector-substrate grading coefficient" ) +`MPRco( VGS ,1.20 ,"" ,0.1 ,inf ,"Band-gap voltage of the substrate" ) +`MPRnb( AS ,1.58 ,"" ,"Substrate temperature coefficient" ) +`MPRnb( ASUB ,2.0 ,"" ,"Temperature coefficient for mobility of minorities in the substrate" ) +`endif + +`ifdef SELFHEATING +`MPRoo( RTH ,300.0 ,"" ,0.0 ,inf ,"Thermal resistance" ) +`MPRco( CTH ,3.0n ,"" ,0.0 ,inf ,"Thermal capacitance" ) +`MPRnb( ATH ,0.0 ,"" ,"Temperature coefficient of the thermal resistance" ) +`endif + +`MPRoo( MULT ,1.0 ,"" ,0.0 ,inf ,"Multiplication factor" ) +`MPIty( TYPE ,1 ,"" ,"Flag for NPN (1) or PNP (-1) transistor type" ) +`MPRoc( GMIN ,1.0e-13 ,"" ,0.0 ,1e-10 ,"Minimum conductance" ) + + + + + diff --git a/src/spicelib/devices/adms/mextram/admsva/tscaling.inc b/src/spicelib/devices/adms/mextram/admsva/tscaling.inc new file mode 100644 index 000000000..c5e27d255 --- /dev/null +++ b/src/spicelib/devices/adms/mextram/admsva/tscaling.inc @@ -0,0 +1,262 @@ +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. + +// Temperature scaling of parameters + + // The excess transistor temperature due to the self-heating +`ifdef SELFHEATING + Tki = V(dt); + // *** Convergence related smoothing *** + if (Tki < 0.0) begin + Tki = - ln(1.0 - Tki); + end + `linLog(Vdt, Tki, 200.0); +// `min_logexp(Vdt, Tki, 200.0, 10.0); +`else + Vdt = 0.0; +`endif + + // Temperature variables + Tk = Tamb + Vdt; + + tN = Tk / Trk; + Vt = `KBdivQQ * Tk; + Vtr = `KBdivQQ * Trk; + VtINV = 1.0 / Vt; + VtrINV = 1.0 / Vtr; + VdtINV = VtINV - VtrINV; + + lntN = ln(tN) ; + + // begin: RvdT, November 2008, "Zener tunneling model" +// VGZEB_T = VGZEBOK - AVGEB*Tk*Tk / (Tk + TVGEB) ; + `max_logexp(VGZEB_T, VGZEBOK - AVGEB*Tk*Tk / (Tk + TVGEB), 0.05, 0.1) ; + + // end: RvdT, November 2008, "Zener tunneling model" + + // Depletion capacitances + + UdeT = -3.0 * Vt * ln(tN) + VDE * tN + (1.0 - tN) * VGB; + `max_logexp(VDE_T, `VDLOW, UdeT, Vt); + + UdcT = -3.0 * Vt * ln(tN) + VDC * tN + (1.0 - tN) * VGC; + `max_logexp(VDC_T, `VDLOW, UdcT, Vt); + +`ifdef SUBSTRATE + UdsT = -3.0 * Vt * ln(tN) + VDS * tN + (1.0 - tN) * VGS; + `max_logexp(VDS_T, `VDLOW, UdsT, Vt); +`endif + inv_VDE_T = 1.0 / VDE_T ; + CJE_T_div_CJE = pow(VDE * inv_VDE_T, PE); + CJE_T = CJE * CJE_T_div_CJE ; + +`ifdef SUBSTRATE + CJS_T = CJS * pow(VDS / VDS_T, PS); +`endif + + CJCscale = ((1.0 - XP) * pow(VDC / VDC_T, PC) + XP); + CJCscaleINV = 1.0 / CJCscale; + + CJC_T = CJC * CJCscale; + XP_T = XP * CJCscaleINV; + + // Resistances + +// RvdT, November 2008: +// Instead of the following definition +// RE_T = RE * pow(tN, AE); +// we use, here, and in all following powers of tN, +// the following computationally cheaper implementation: + RE_T = RE * exp(lntN * AE); +// This is based on the observation that exp() is faster than pow(). +// Acknowledgement due to Geoffrey Coram. + + RBV_T = RBV * exp(lntN * (AB - AQBO)); + RBC_T = RBC * exp(lntN * AEX); + +// RvdT, 30-11-2007: new collector resistances RCCxx_T, RCCex_T, RCCin_T +`ifdef insideADMS +//dw limiting all the RCXXX to MIN_R + if (RCC > 0.0) + RCCxx_T = RCC * exp(lntN * AC); + else + RCCxx_T = `MIN_R * exp(lntN * AC); + if (RCBLX > 0.0) + RCCex_T = RCBLX * exp(lntN * ACBL); + else + RCCex_T = `MIN_R * exp(lntN * ACBL); + if (RCBLI > 0.0) + RCCin_T = RCBLI * exp(lntN * ACBL); + else + RCCin_T = `MIN_R * exp(lntN * ACBL); +`else + RCCxx_T = RCC * exp(lntN * AC); + RCCex_T = RCBLX * exp(lntN * ACBL); + RCCin_T = RCBLI * exp(lntN * ACBL); +`endif + + RCV_T = RCV * exp(lntN * AEPI); + + // Current gains + + BF_T = BF * exp(lntN * (AE - AB - AQBO)) * exp(-DVGBF * VdtINV); + BRI_T = BRI * exp(-DVGBR * VdtINV); + + // Currents and voltages + + IS_T = IS * exp(lntN * (4.0 - AB - AQBO + DAIS)) * exp(-VGB * VdtINV); + IK_T = IK * exp(lntN * (1.0 - AB)); + IBF_T = IBF * exp(lntN * (6.0 - 2.0 * MLF)) * exp(-VGJ * VdtINV / MLF); + IBR_T = IBR * tN * tN * exp(-VGC * VdtINV / 2.0); + +// begin RvdT, November 2008, MXT504.8_alpha +// T-scaling BE tunneling: +// + x = pow(VGZEB_T * inv_VGZEB_Tr, -0.5) ; +// y = pow(VDE_T * inv_VDE, PE) ; +// more efficient, because we need both y and 1.0 / y: + y = 1.0 / CJE_T_div_CJE ; +// definition: +// nZEB_T = NZEB* pow(VGZEB_T/VGZEB_Tr, 1.5) * pow(VDE_T / VDE, PE-1) ; +// more efficient implementation: +// nZEB_T = NZEB* VGZEB_T * VGZEB_T * x * y * VDE /(VDE_T*VGZEB_Tr*VGZEB_Tr) ; + nZEB_T = NZEB* VGZEB_T * VGZEB_T * x * y * VDE * inv_VDE_T*inv_VGZEB_Tr*inv_VGZEB_Tr ; + +// definition: +// IZEB_T = IZEB* pow(VGZEB_T/VGZEB_Tr, -0.5) * pow(VDE_T / VDE, 2-PE) * exp(NZEB-nZEB_T); +// more efficient implementation: + IZEB_T = IZEB* x * VDE_T * VDE_T * inv_VDE * inv_VDE * CJE_T_div_CJE * exp(NZEB-nZEB_T) ; +// +// end RvdT, November 2008, MXT504.8_alpha + + x = exp(lntN * AQBO) ; + VEF_T = VEF * x * CJCscaleINV; +// VER_T = VER * x * pow(VDE / VDE_T, -PE); + VER_T = VER * x * y; + +`ifdef SUBSTRATE + ISS_T = ISS * exp(lntN * (4.0 - AS)) * exp(-VGS * VdtINV); +// New 504.9: + ICSS_T = ICSS * exp(lntN * (3.5 - 0.5 * ASUB)) * exp(-VGS * VdtINV); +// End New 504.9. + + if ((ISS_T > 0.0)) + IKS_T = IKS * exp(lntN * (1.0 - AS)) * (IS_T / IS) * (ISS / ISS_T); + else + IKS_T = IKS * exp(lntN * (1.0 - AS)); +`endif + + // Transit times + + TAUE_T = TAUE * exp(lntN * (AB - 2.0)) * exp(-DVGTE * VdtINV); + TAUB_T = TAUB * exp(lntN * (AQBO + AB - 1.0)); + TEPI_T = TEPI * exp(lntN * (AEPI - 1.0)); + TAUR_T = TAUR * (TAUB_T + TEPI_T) / (TAUB + TEPI); + + // Avalanche constant + + Tk300 = Tk - 300.0; +// RvdT, 15-02-2008: prevent division by zero and overflow at high temperatures: + if (Tk < 525.0) + begin + BnT = Bn * (1.0 + 7.2e-4 * Tk300 - 1.6e-6 * Tk300 * Tk300) ; + end + else + begin + BnT = Bn * 1.081 ; + end + + // Heterojunction features + + DEG_T = DEG * exp(lntN * AQBO); + +`ifdef SELFHEATING + // Temperature scaling of the thermal resistance + + RTH_Tamb = RTH * pow(Tamb / Trk, ATH); +`endif + +// MULT - scaling + + IS_TM = IS_T * MULT; + IK_TM = IK_T * MULT; + IBF_TM = IBF_T * MULT; + IBR_TM = IBR_T * MULT; +// RvdT: November 2008, Zener tunneling parameters + IZEB_TM = IZEB_T * MULT ; + +// end Zener tunneling parameters + + + + + IHC_M = IHC * MULT; +`ifdef SUBSTRATE + ISS_TM = ISS_T * MULT; +// New: 504.9 + ICSS_TM = ICSS_T * MULT; + IKS_TM = IKS_T * MULT; +`endif + CJE_TM = CJE_T * MULT; + CJC_TM = CJC_T * MULT; + +// begin RvdT, 28-10-2008, MXT504.8_alpha +// Base-emitter tunneling current Mult scaling: +// BTJE_TM = BTJE_T * MULT; +// end RvdT, 28-10-2008, MXT504.8_alpha + + +`ifdef SUBSTRATE + CJS_TM = CJS_T * MULT; +`endif + + RE_TM = RE_T * invMULT; + RBC_TM = RBC_T * invMULT; + RBV_TM = RBV_T * invMULT; +// RvdT, 30-01-2007: new collector resistances: + RCCxx_TM = RCCxx_T * invMULT; + RCCex_TM = RCCex_T * invMULT; + RCCin_TM = RCCin_T * invMULT; + RCV_TM = RCV_T * invMULT; + + +// RvdT, 03-12-2007: new collector conductances +`ifdef insideADMS +//dw we have limited all the RCXXX to MIN_R + GCCxx_TM = 1.0 / RCCxx_TM ; + GCCex_TM = 1.0 / RCCex_TM ; + GCCin_TM = 1.0 / RCCin_TM ; +`else + if (RCC > 0.0) + begin + GCCxx_TM = 1.0 / RCCxx_TM ; + end + else + begin + GCCxx_TM = 0 ; + end + + if (RCBLX > 0.0) + begin + GCCex_TM = 1.0 / RCCex_TM ; + end + else + begin + GCCex_TM = 0 ; + end + + if (RCBLI > 0.0) + begin + GCCin_TM = 1.0 / RCCin_TM ; + end + else + begin + GCCin_TM = 0 ; + end +`endif + +`ifdef SELFHEATING + RTH_Tamb_M = RTH_Tamb * invMULT; +`endif diff --git a/src/spicelib/devices/adms/mextram/admsva/variables.inc b/src/spicelib/devices/adms/mextram/admsva/variables.inc new file mode 100644 index 000000000..c8c7f1ef5 --- /dev/null +++ b/src/spicelib/devices/adms/mextram/admsva/variables.inc @@ -0,0 +1,198 @@ +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. + +// Declaration of variables +real _x, _x0, _a, _dxa; + +// Model constants + +real An, Bn; + +// Temperature scaling variables + +real Tk, Trk, tN, Tamb; +real Vt, Vtr, VtINV, VtrINV, VdtINV; +real Vdt; + +real UdeT, VDE_T, UdcT, VDC_T; +real CJE_T, CJC_T, XP_T; +real CJCscale, CJCscaleINV; + +real RE_T, RBV_T, RBC_T, RCV_T; +// RvdT: 30-01-2007, new collector resistances: +real RCCxx_T, RCCex_T, RCCin_T; + +real BF_T, BRI_T; + +real IS_T, IK_T, IBF_T, IBR_T, VEF_T, VER_T; + +// RvdT: November 2008, Zener tunneling parameters and variables: +real Izteb, IZEB_T, E0BE, dE0BE,nZEB_T, pow2_2mPE, pow2_PEm2, inv_VDE, inv_VDE_T; +real eZEB, edZEB, DZEB, VGZEB_T, VGZEB_Tr, inv_VGZEB_Tr, CJE_T_div_CJE ; + +// RvdT: March 2009, Zener tunneling parameters and variables: +real VGZEBOK; + +// end Zener tunneling parameters + +real TAUE_T, TAUB_T, TEPI_T, TAUR_T; +real BnT, DEG_T, Tk300; + +`ifdef SELFHEATING +real RTH_Tamb; +`endif + +`ifdef SUBSTRATE +real UdsT, VDS_T, CJS_T, ISS_T, ICSS_T, IKS_T; +`endif + +// MULT - scaling variables + +real invMULT; +real IS_TM, IK_TM, IBF_TM, IBR_TM, IHC_M; +// RvdT: November 2008, Zener tunneling parameters +real IZEB_TM ; + +// end Zener tunneling parameters + + + + +real CJE_TM, CJC_TM; + +real RE_TM, RBC_TM, RBV_TM, RCV_TM, SCRCV_M; +// RvdT: 30-01-2007, new collector resistances: +real RCCxx_TM, RCCex_TM, RCCin_TM; +// RvdT: 03-12-2007, new collector conductances: +real GCCxx_TM, GCCex_TM, GCCin_TM; + + +real KF_M, KFN_M; + +`ifdef SELFHEATING +real RTH_Tamb_M, CTH_M; +`endif + +`ifdef SUBSTRATE +real ISS_TM, ICSS_TM, IKS_TM, CJS_TM; +`endif + + +// Epilayer model variables + +real K0, Kw, pW, Ec, Ic1c2; +real Vqs_th, Vqs, Iqs; +real alpha, vyi, yi, xi_w, xi_w1; +real gp0, gp02, p0star, Vb2c2star, eVb2c2star; +real B1, B2, Vxi0, Vch, Icap, pav; + +// Effective emitter and collector junction bias variables + +real Vfe, Vje, Vte; +real Vjunc, bjc, Vfc, Vjc, fI, Vcv, Vtc; + +// Transfer current variables + +real If0, f1, f2, n0, nB; +real q0I, q1I, qBI, Ir, If, In; + +// Base and substrate current(s) variables + +real Xext1; +real Ib1, Ib1_s, Ib2, Ib3; +real Ibf0, Iex; +real g1, g2, pWex, nBex; +real Xg1, XnBex, XIMex, XIMsub, Vex, VBex, Fex, XIex; + +`ifdef SUBSTRATE +real Isub, XIsub, Isf; +`endif + +// Distributed base effects variables + +real q0Q, q1Q, qBQ, Rb2, Ib1b2; +real dVteVb2e1, dVteVje, dVjeVb2e1; +real dQteVb2e1, dQbeVb2e1, dQeVb2e1; +real dn0Vb2e1; + +// Weak-avalanche current variables + +real dEdx0, xd, Weff, Wd, Eav, E0, Em, SHw, Efi, Ew; +real lambda, Gem, Gmax, Iavl; +real Icap_IHC; + +`ifdef SELFHEATING +real Tki, power; +`endif + +// Charges and capacitances variables + +real Qte, Vje_s, Qte_s; +real Qtc; +real Qb0, Qbe, Qbc, Qb1b2; +real Qbe_qs, Qbc_qs; +real Vjcex, Vtexv, Qtex, XVjcex, XVtexv, XQtex; + +`ifdef SUBSTRATE +real Vfs, Vjs, Qts; +`endif + +real Qe0, Qe; +real Qe_qs; +real Qepi0, Qepi, Xg2, XpWex, XQex; +real Qex; +real CBEO_M, CBCO_M; + +// Biases and exponential terms variables + +real Vb2c1, Vb2c2, Vb2e1, Vb1e1, Vb1b2, Vb1c4, Vc1c2; +real Vc3c4, Vc4c1; +`ifdef SUBSTRATE +real Vsc1, Vsc3, Vsc4, eVsc1, eVsc3, eVsc4; +`endif +real Vee1, Vbb1, Vbc3, Vcc3, Vbe, Vbc; +real eVb2c2, eVb2e1, eVb1e1, eVb1b2, eVb1c4, eVbc3; +real eVb1c4VDC, eVb2c2VDC, eVbc3VDC, eVb2c1VDC; + +// Help variables + +// RvdT, November 2008, lntN introduced to speed up T-scaling: +// Acknowledgements due to Geoffrey Coram +real lntN ; + +// RvdT, November 2008 variables for local use; may be re-used globally: +real x, y ; + +real dxa, sqr_arg; +real eps2, x2; +real alpha1, vdif, Ic1c2_Iqs, gp0_help; +real EmEav_Em, Vb2e1Vfe, termE, termC; +real Vex_bias; +real eps_VDC, a_VDE, a_VDC; + +real expl, tmpExp, tmpV; + + +`ifdef SUBSTRATE +real a_VDS; +`endif + +// Noise variables +real common; +real powerREC, powerRBC, powerRCCxx, powerRCCex, powerRCCin, powerRBV; +real powerCCS; +real powerFBCS, powerFBC1fB1, exponentFBC1fB2, powerFBC1fB2; +real powerEBSCS, powerEBSC1f; +real powerRBCS, powerRBC1f; +real powerExCS, powerExCSMOD, powerExC1f, powerExC1fMOD; +real powerIIS; + +`ifdef SUBSTRATE +real powerSubsCS_B1S, powerSubsCS_BS; +`endif + +// noise correlation help variables +real In_N, Gem_N, Taub_N, taun, Qbe_qs_eff; + diff --git a/src/spicelib/devices/adms/psp102/admsva/JUNCAP200_InitModel.include b/src/spicelib/devices/adms/psp102/admsva/JUNCAP200_InitModel.include new file mode 100644 index 000000000..f4dafbd85 --- /dev/null +++ b/src/spicelib/devices/adms/psp102/admsva/JUNCAP200_InitModel.include @@ -0,0 +1,184 @@ +//====================================================================================== +//====================================================================================== +// Filename: JUNCAP200_InitModel.include +//====================================================================================== +//====================================================================================== +// +// (c) Copyright 2007, All Rights Reserved, NXP Semiconductors +// +// +// Version: 102.1 (PSP), 200.2 (JUNCAP), April 2007 (Simkit 2.5) +// +//====================================================================================== +//====================================================================================== +// +// Further information can be found in the file readme.txt +// + + ////////////////////////////////////////////////////////////// + // + // Calculation of internal paramters which are independent + // on instance parameters + // + ////////////////////////////////////////////////////////////// + + TRJ_i = `CLIP_LOW( TRJ , `TRJ_cliplow); + IMAX_i = `CLIP_LOW( IMAX , `IMAX_cliplow); + CJORBOT_i = `CLIP_LOW( CJORBOT , `CJORBOT_cliplow); + CJORSTI_i = `CLIP_LOW( CJORSTI , `CJORSTI_cliplow); + CJORGAT_i = `CLIP_LOW( CJORGAT , `CJORGAT_cliplow); + VBIRBOT_i = `CLIP_LOW( VBIRBOT , `VBIR_cliplow); + VBIRSTI_i = `CLIP_LOW( VBIRSTI , `VBIR_cliplow); + VBIRGAT_i = `CLIP_LOW( VBIRGAT , `VBIR_cliplow); + PBOT_i = `CLIP_BOTH(PBOT , `P_cliplow,`P_cliphigh); + PSTI_i = `CLIP_BOTH(PSTI , `P_cliplow,`P_cliphigh); + PGAT_i = `CLIP_BOTH(PGAT , `P_cliplow,`P_cliphigh); + IDSATRBOT_i = `CLIP_LOW( IDSATRBOT , `IDSATR_cliplow); + IDSATRSTI_i = `CLIP_LOW( IDSATRSTI , `IDSATR_cliplow); + IDSATRGAT_i = `CLIP_LOW( IDSATRGAT , `IDSATR_cliplow); + CSRHBOT_i = `CLIP_LOW( CSRHBOT , `CSRH_cliplow); + CSRHSTI_i = `CLIP_LOW( CSRHSTI , `CSRH_cliplow); + CSRHGAT_i = `CLIP_LOW( CSRHGAT , `CSRH_cliplow); + XJUNSTI_i = `CLIP_LOW( XJUNSTI , `XJUN_cliplow); + XJUNGAT_i = `CLIP_LOW( XJUNGAT , `XJUN_cliplow); + CTATBOT_i = `CLIP_LOW( CTATBOT , `CTAT_cliplow); + CTATSTI_i = `CLIP_LOW( CTATSTI , `CTAT_cliplow); + CTATGAT_i = `CLIP_LOW( CTATGAT , `CTAT_cliplow); + MEFFTATBOT_i = `CLIP_LOW( MEFFTATBOT, `MEFFTAT_cliplow); + MEFFTATSTI_i = `CLIP_LOW( MEFFTATSTI, `MEFFTAT_cliplow); + MEFFTATGAT_i = `CLIP_LOW( MEFFTATGAT, `MEFFTAT_cliplow); + CBBTBOT_i = `CLIP_LOW( CBBTBOT , `CBBT_cliplow); + CBBTSTI_i = `CLIP_LOW( CBBTSTI , `CBBT_cliplow); + CBBTGAT_i = `CLIP_LOW( CBBTGAT , `CBBT_cliplow); + VBRBOT_i = `CLIP_LOW( VBRBOT , `VBR_cliplow); + VBRSTI_i = `CLIP_LOW( VBRSTI , `VBR_cliplow); + VBRGAT_i = `CLIP_LOW( VBRGAT , `VBR_cliplow); + PBRBOT_i = `CLIP_LOW( PBRBOT , `PBR_cliplow); + PBRSTI_i = `CLIP_LOW( PBRSTI , `PBR_cliplow); + PBRGAT_i = `CLIP_LOW( PBRGAT , `PBR_cliplow); + + tkr = `KELVINCONVERSION + TRJ_i; + tkd = max($temperature + DTA, `KELVINCONVERSION + `MINTEMP); + auxt = tkd / tkr; + KBOL_over_QELE = `KBOL / `QELE; + phitr = KBOL_over_QELE * tkr; + phitrinv = 1.0 / phitr; + phitd = KBOL_over_QELE * tkd; + phitdinv = 1.0 / phitd; + + // bandgap voltages at reference temperature + deltaphigr = -(7.02e-4 * tkr * tkr) / (1108.0 + tkr); + phigrbot = PHIGBOT + deltaphigr; + phigrsti = PHIGSTI + deltaphigr; + phigrgat = PHIGGAT + deltaphigr; + + // bandgap voltages at device temperature + deltaphigd = -(7.02e-4 * tkd * tkd) / (1108.0 + tkd); + phigdbot = PHIGBOT + deltaphigd; + phigdsti = PHIGSTI + deltaphigd; + phigdgat = PHIGGAT + deltaphigd; + + // factors ftd for ideal-current model + ftdbot = (pow(auxt, 1.5)) * exp(0.5 * ((phigrbot * phitrinv) - (phigdbot * phitdinv))); + ftdsti = (pow(auxt, 1.5)) * exp(0.5 * ((phigrsti * phitrinv) - (phigdsti * phitdinv))); + ftdgat = (pow(auxt, 1.5)) * exp(0.5 * ((phigrgat * phitrinv) - (phigdgat * phitdinv))); + + // temperature-scaled saturation current for ideal-current model + idsatbot = IDSATRBOT_i * ftdbot * ftdbot; + idsatsti = IDSATRSTI_i * ftdsti * ftdsti; + idsatgat = IDSATRGAT_i * ftdgat * ftdgat; + + // built-in voltages before limiting + ubibot = VBIRBOT_i * auxt - 2 * phitd * ln(ftdbot); + ubisti = VBIRSTI_i * auxt - 2 * phitd * ln(ftdsti); + ubigat = VBIRGAT_i * auxt - 2 * phitd * ln(ftdgat); + + // built-in voltages limited to phitd + vbibot = ubibot + phitd * ln(1 + exp((`vbilow - ubibot) * phitdinv)); + vbisti = ubisti + phitd * ln(1 + exp((`vbilow - ubisti) * phitdinv)); + vbigat = ubigat + phitd * ln(1 + exp((`vbilow - ubigat) * phitdinv)); + + // inverse values of built-in voltages + vbiinvbot = 1.0 / vbibot; + vbiinvsti = 1.0 / vbisti; + vbiinvgat = 1.0 / vbigat; + + // one minus the grading coefficient + one_minus_PBOT = 1 - PBOT_i; + one_minus_PSTI = 1 - PSTI_i; + one_minus_PGAT = 1 - PGAT_i; + + // one over "one minus the grading coefficient" + one_over_one_minus_PBOT = 1 / one_minus_PBOT; + one_over_one_minus_PSTI = 1 / one_minus_PSTI; + one_over_one_minus_PGAT = 1 / one_minus_PGAT; + + // temperature-scaled zero-bias capacitance + cjobot = CJORBOT_i * pow((VBIRBOT_i * vbiinvbot), PBOT_i); + cjosti = CJORSTI_i * pow((VBIRSTI_i * vbiinvsti), PSTI_i); + cjogat = CJORGAT_i * pow((VBIRGAT_i * vbiinvgat), PGAT_i); + + // prefactor in physical part of charge model + qprefbot = cjobot * vbibot * one_over_one_minus_PBOT; + qprefsti = cjosti * vbisti * one_over_one_minus_PSTI; + qprefgat = cjogat * vbigat * one_over_one_minus_PGAT; + + // prefactor in mathematical extension of charge model + qpref2bot = `a * cjobot; + qpref2sti = `a * cjosti; + qpref2gat = `a * cjogat; + + // zero-bias depletion widths at reference temperature, needed in SRH and TAT model + wdepnulrbot = `EPSSI / CJORBOT_i; + wdepnulrsti = XJUNSTI_i * `EPSSI / CJORSTI_i; + wdepnulrgat = XJUNGAT_i * `EPSSI / CJORGAT_i; + + // inverse values of "wdepnulr", used in BBT model + wdepnulrinvbot = 1 / wdepnulrbot; + wdepnulrinvsti = 1 / wdepnulrsti; + wdepnulrinvgat = 1 / wdepnulrgat; + + // inverse values of built-in voltages at reference temperature, needed in SRH and BBT model + VBIRBOTinv = 1 / VBIRBOT_i; + VBIRSTIinv = 1 / VBIRSTI_i; + VBIRGATinv = 1 / VBIRGAT_i; + + // some constants needed in erfc-approximation, needed in TAT model + perfc = (`SQRTPI * `aerfc); + berfc = ((-5 * (`aerfc) + 6 - pow((perfc), -2)) / 3); + cerfc = (1.0 - (`aerfc) - (berfc)); + + // half the bandgap energy, limited to values > phitd, needed in TAT model + deltaEbot = max(0.5 * phigdbot, phitd); + deltaEsti = max(0.5 * phigdsti, phitd); + deltaEgat = max(0.5 * phigdgat, phitd); + + // values of atat, needed in TAT model + atatbot = deltaEbot * phitdinv; + atatsti = deltaEsti * phitdinv; + atatgat = deltaEgat * phitdinv; + + // values of btatpart, needed in TAT model + btatpartbot = sqrt(32 * MEFFTATBOT_i * `MELE * `QELE * (deltaEbot * deltaEbot * deltaEbot)) / (3 * `HBAR); + btatpartsti = sqrt(32 * MEFFTATSTI_i * `MELE * `QELE * (deltaEsti * deltaEsti * deltaEsti)) / (3 * `HBAR); + btatpartgat = sqrt(32 * MEFFTATGAT_i * `MELE * `QELE * (deltaEgat * deltaEgat * deltaEgat)) / (3 * `HBAR); + + // temperature-scaled values of FBBT, needed in BBT model + fbbtbot = FBBTRBOT * (1 + STFBBTBOT * (tkd - tkr)); + fbbtsti = FBBTRSTI * (1 + STFBBTSTI * (tkd - tkr)); + fbbtgat = FBBTRGAT * (1 + STFBBTGAT * (tkd - tkr)); + + // values of fstop, needed in avalanche/breakdown model + fstopbot = 1 / (1 - pow(`alphaav, PBRBOT_i)); + fstopsti = 1 / (1 - pow(`alphaav, PBRSTI_i)); + fstopgat = 1 / (1 - pow(`alphaav, PBRGAT_i)); + + // inverse values of breakdown voltages, needed in avalanche/breakdown model + VBRinvbot = 1 / VBRBOT_i; + VBRinvsti = 1 / VBRSTI_i; + VBRinvgat = 1 / VBRGAT_i; + + // slopes for linear extraploation close to and beyond breakdown, needed in avalanche/breakdown model + slopebot = -(fstopbot * fstopbot * pow(`alphaav, (PBRBOT_i - 1))) * PBRBOT_i * VBRinvbot; + slopesti = -(fstopsti * fstopsti * pow(`alphaav, (PBRSTI_i - 1))) * PBRSTI_i * VBRinvsti; + slopegat = -(fstopgat * fstopgat * pow(`alphaav, (PBRGAT_i - 1))) * PBRGAT_i * VBRinvgat; diff --git a/src/spicelib/devices/adms/psp102/admsva/JUNCAP200_macrodefs.include b/src/spicelib/devices/adms/psp102/admsva/JUNCAP200_macrodefs.include new file mode 100644 index 000000000..00d5deed6 --- /dev/null +++ b/src/spicelib/devices/adms/psp102/admsva/JUNCAP200_macrodefs.include @@ -0,0 +1,285 @@ +//====================================================================================== +//====================================================================================== +// Filename: JUNCAP200_macrodefs.include +//====================================================================================== +//====================================================================================== +// +// (c) Copyright 2007, All Rights Reserved, NXP Semiconductors +// +// +// Version: 102.1 (PSP), 200.2 (JUNCAP), April 2007 (Simkit 2.5) +// +//====================================================================================== +//====================================================================================== +// +// Further information can be found in the file readme.txt +// + +/////////////////////////////////////////// +// +// Macros and constants used in JUNCAP2 +// +/////////////////////////////////////////// + +// Other constants +`define MINTEMP -250 +`define vbilow 0.050 +`define a 2 +`define epsch 0.1 +`define dvbi 0.050 +`define epsav 1E-6 +`define vbrmax 1000 +`define alphaav 0.999 +`define vmaxlarge 1E8 +`define aerfc 0.29214664 +`define twothirds 0.666666666666667 + + +// Clipping values +`define levelnumber 200 +`define AB_cliplow 0 +`define LS_cliplow 0 +`define LG_cliplow 0 +`define MULT_cliplow 0 +`define TRJ_cliplow `MINTEMP +`define IMAX_cliplow 1E-12 +`define CJORBOT_cliplow 1E-12 +`define CJORSTI_cliplow 1E-18 +`define CJORGAT_cliplow 1E-18 +`define VBIR_cliplow `vbilow +`define P_cliplow 0.05 +`define P_cliphigh 0.95 +`define IDSATR_cliplow 0 +`define CSRH_cliplow 0 +`define XJUN_cliplow 1E-9 +`define CTAT_cliplow 0 +`define MEFFTAT_cliplow 0.01 +`define CBBT_cliplow 0 +`define VBR_cliplow 0.1 +`define PBR_cliplow 0.1 + + +///////////////////////////////////////////////////////////////////////////// +// +// Macro definitions. +// +// Note that because at present locally scoped variables +// can only be in named blocks, the intermediate variables +// used in the macros below must be explicitly declared +// as variables. +// +///////////////////////////////////////////////////////////////////////////// + +// Instance parameter dependent initialization + +`define JuncapInitInstance(AB_i, LS_i, LG_i, VMAX, vbimin, vch, vfmin, vbbtlim) \ +if (idsatbot * AB_i > 0) begin \ + vmaxbot = phitd * ln(IMAX_i / (idsatbot * AB_i) + 1); \ +end else begin \ + vmaxbot = `vmaxlarge; \ +end \ +if (idsatsti * LS_i > 0) begin \ + vmaxsti = phitd * ln(IMAX_i / (idsatsti * LS_i) + 1); \ +end else begin \ + vmaxsti = `vmaxlarge; \ +end \ +if (idsatgat * LG_i > 0) begin \ + vmaxgat = phitd * ln(IMAX_i / (idsatgat * LG_i) + 1); \ +end else begin \ + vmaxgat = `vmaxlarge; \ +end \ +VMAX = min(min(vmaxbot, vmaxsti), vmaxgat); \ + \ +/* determination of minimum value of the relevant built-in voltages */ \ +vbibot2 = vbibot; \ +vbisti2 = vbisti; \ +vbigat2 = vbigat; \ +if (AB_i == 0) begin vbibot2 = vbisti + vbigat; end \ +if (LS_i == 0) begin vbisti2 = vbibot + vbigat; end \ +if (LG_i == 0) begin vbigat2 = vbibot + vbisti; end \ +vbimin = min(min(vbibot2, vbisti2), vbigat2); \ +vch = vbimin * `epsch; \ +if (vbimin == vbibot) begin vfmin = vbibot * (1 - (pow(`a, (-1.0 / PBOT_i)))); end \ +if (vbimin == vbisti) begin vfmin = vbisti * (1 - (pow(`a, (-1.0 / PSTI_i)))); end \ +if (vbimin == vbigat) begin vfmin = vbigat * (1 - (pow(`a, (-1.0 / PGAT_i)))); end \ + \ +/* determination of limiting value of conditioned voltage for BBT calculation */ \ +vbibot2r = VBIRBOT_i; \ +vbisti2r = VBIRSTI_i; \ +vbigat2r = VBIRGAT_i; \ +if (AB_i == 0) begin vbibot2r = VBIRSTI_i + VBIRGAT_i; end \ +if (LS_i == 0) begin vbisti2r = VBIRBOT_i + VBIRGAT_i; end \ +if (LG_i == 0) begin vbigat2r = VBIRBOT_i + VBIRSTI_i; end \ +vbbtlim = min(min(vbibot2r, vbisti2r), vbigat2r) - `dvbi; \ + + +// Special power-functions + +`define mypower(x,power,result) \ +if (power == 0.5) begin \ + result = sqrt(x); \ +end else begin \ + result = pow(x, power); \ +end + +`define mypower2(x,power,result) \ +if (power == -1) begin \ + result = 1 / (x); \ +end else begin \ + result = pow(x, power); \ +end + +`define mypower3(x,power,result) \ +if (power == 4) begin \ + result = (x) * (x) * (x) * (x); \ +end else begin \ + result = pow(x, power); \ +end + + +// Smoothing functions + +`define hypfunction2(x,x0,eps,hyp2) \ +hyp2 = 0.5 * ((x) + (x0) - sqrt(((x) - (x0)) * ((x) - (x0)) + 4 * (eps) * (eps))); + +`define hypfunction5(x,x0,eps,hyp5) \ +h1 = 4.0 * (eps) * (eps); \ +h2 = (eps) / (x0); \ +h2d = (x) + (eps) * h2; \ +h3 = (x0) + h2d; \ +h4 = (x0) - h2d; \ +h5 = sqrt(h4 * h4 + h1); \ +hyp5 = 2.0 * ((x) * (x0) / (h3 + h5)); + + +// A special function used to calculate TAT-currents, +// including an approximation of the erfc-function + +`define calcerfcexpmtat(y,m,result) \ +ysq = y * y; \ +if (y > 0) begin \ + terfc = 1 / (1 + perfc * y); \ +end else begin \ + terfc = 1 / (1 - perfc * y); \ +end \ +`expl_low(-ysq + m, tmp) \ +erfcpos = (`aerfc * terfc + berfc * (terfc * terfc) + cerfc * (terfc * terfc * terfc)) * tmp; \ +if (y > 0) begin \ + result = erfcpos; \ +end else begin\ + `expl_low(m, tmp) \ + result = 2 * tmp - erfcpos; \ +end + + +// This is the main function of the JUNCAP2-model. It returns the current and charge +// for a single diode + +`define juncapfunction(qpref,qpref2,vbiinv,one_minus_P,idsat,CSRH,CTAT,vbi,wdepnulr,VBIRinv,P,ftd,btatpart,atat,one_over_one_minus_P,CBBT,VBIR,wdepnulrinv,fbbt,VBR,VBRinv,PBR,fstop,slope,Ijprime,Qjprime) \ +`mypower((1 - vj * vbiinv), one_minus_P, tmp) \ +Qjprime = qpref * (1 - tmp) + qpref2 * (VAK - vj); \ +id = idsat * idmult; \ +if ((CSRH == 0) && (CTAT == 0)) begin \ + isrh = 0; \ +end else begin \ + vbi_minus_vjsrh = vbi-vjsrh; \ + wsrhstep = 1 - sqrt(1 - two_psistar / vbi_minus_vjsrh); \ + if (P == 0.5) begin \ + dwsrh = 0; \ + end else begin \ + dwsrh = ((wsrhstep * wsrhstep * ln(wsrhstep) / (1 - wsrhstep)) + wsrhstep) * (1 - 2 * P); \ + end \ + wsrh = wsrhstep + dwsrh; \ + `mypower(vbi_minus_vjsrh * VBIRinv, P, tmp) \ + wdep = wdepnulr * tmp; \ + asrh = ftd * ((zinv - 1) * wdep); \ + isrh = CSRH * (asrh * wsrh); \ +end \ +if (CTAT == 0) begin \ + itat = 0; \ +end else begin \ + btat = btatpart * ((wdep * one_minus_P) / vbi_minus_vjsrh); \ + twoatatoverthreebtat = (`twothirds * atat) / btat; \ + umaxbeforelimiting = twoatatoverthreebtat * twoatatoverthreebtat; \ + umax = sqrt(umaxbeforelimiting * umaxbeforelimiting / (umaxbeforelimiting * umaxbeforelimiting + 1)); \ + sqrtumax = sqrt(abs(umax)); \ + umaxpoweronepointfive = umax * sqrtumax; \ + `mypower2((1 + btat * umaxpoweronepointfive), (-P * one_over_one_minus_P), wgamma) \ + wtat = wsrh * wgamma / (wsrh + wgamma); \ + ktat = sqrt(0.375 * (btat / sqrtumax)); \ + ltat = 2 * (twoatatoverthreebtat * sqrtumax) - umax; \ + mtat = atat * twoatatoverthreebtat * sqrtumax - atat * umax + 0.5 * (btat * umaxpoweronepointfive); \ + xerfc = (ltat - 1) * ktat; \ + `calcerfcexpmtat(xerfc, mtat, erfctimesexpmtat) \ + gammamax = `SQRTPI * 0.5 * (atat * erfctimesexpmtat / ktat); \ + itat = CTAT * (asrh * gammamax * wtat); \ +end \ +if (CBBT == 0) begin \ + ibbt = 0; \ +end else begin \ + `mypower(((VBIR - vbbt) * VBIRinv), P, tmp) \ + Fmaxr = one_over_one_minus_P * ((VBIR - vbbt) * wdepnulrinv / tmp); \ + `expl(-fbbt / Fmaxr, tmp) \ + ibbt = CBBT * (VAK * Fmaxr * Fmaxr * tmp); \ +end \ +if (VBR > `vbrmax) begin \ + fbreakdown = 1; \ +end else begin \ + if (vav > -`alphaav * VBR) begin \ + `mypower3(abs(vav * VBRinv), PBR, tmp) \ + fbreakdown = 1 / (1 - tmp); \ + end else begin \ + fbreakdown = fstop + (vav + `alphaav * VBR) * slope; \ + end \ +end \ +Ijprime = (id + isrh + itat + ibbt) * fbreakdown; + + +// The following code is written as a macro because the naming of the instance parameters is +// different for JUNCAP2 stand-alone and JUNCAP2-in-PSP: AB, LS, LG for JUNCAP2 stand-alone, +// ABSOURCE, LSSOURCE, LGSOURCE for source junction in PSP and ABDRAIN, LSDRAIN, LGDRAIN for +// drain junction in PSP + +`define juncapcommon(AB_i,LS_i,LG_i,ijunbot,qjunbot,ijunsti,qjunsti,ijungat,qjungat) \ +vbbt = 0.0; \ +two_psistar = 0.0; \ +if ( !( ((AB_i) == 0) && ((LS_i) == 0) && ((LG_i) == 0) ) ) begin \ + `hypfunction5(VAK, vfmin, vch, vj) \ + if (VAK < VMAX) begin \ + `expl(0.5 * (VAK * phitdinv), zinv) \ + idmult = zinv * zinv; \ + end else begin \ + `expl(VMAX * phitdinv, exp_VMAX_over_phitd) \ + idmult = (1 + (VAK - VMAX) * phitdinv) * exp_VMAX_over_phitd; \ + zinv = sqrt(idmult); \ + end \ + idmult = idmult - 1.0; \ + z = 1 / zinv; \ + if (VAK > 0) begin \ + two_psistar = 2.0 * (phitd * ln(2.0 + z + sqrt((z + 1.0) * (z + 3.0)))); \ + end else begin \ + two_psistar = -VAK + 2.0 * (phitd * ln(2 * zinv + 1 + sqrt((1 + zinv) * (1 + 3 * zinv)))); \ + end \ + vjlim = vbimin - two_psistar; \ + `hypfunction2(VAK, vjlim, phitd, vjsrh) \ + `hypfunction2(VAK, vbbtlim, phitr, vbbt) \ + `hypfunction2(VAK, 0, `epsav, vav) \ +end \ +if ((AB_i) == 0) begin \ + ijunbot = 0; \ + qjunbot = 0; \ +end else begin \ + `juncapfunction(qprefbot,qpref2bot,vbiinvbot,one_minus_PBOT,idsatbot,CSRHBOT_i,CTATBOT_i,vbibot,wdepnulrbot,VBIRBOTinv,PBOT_i,ftdbot,btatpartbot,atatbot,one_over_one_minus_PBOT,CBBTBOT_i,VBIRBOT_i,wdepnulrinvbot,fbbtbot,VBRBOT_i,VBRinvbot,PBRBOT_i,fstopbot,slopebot,ijunbot, qjunbot) \ +end \ +if ((LS_i) == 0) begin \ + ijunsti = 0; \ + qjunsti = 0; \ +end else begin \ + `juncapfunction(qprefsti,qpref2sti,vbiinvsti,one_minus_PSTI,idsatsti,CSRHSTI_i,CTATSTI_i,vbisti,wdepnulrsti,VBIRSTIinv,PSTI_i,ftdsti,btatpartsti,atatsti,one_over_one_minus_PSTI,CBBTSTI_i,VBIRSTI_i,wdepnulrinvsti,fbbtsti,VBRSTI_i,VBRinvsti,PBRSTI_i,fstopsti,slopesti,ijunsti, qjunsti) \ +end \ +if ((LG_i) == 0) begin \ + ijungat = 0; \ + qjungat = 0; \ +end else begin \ + `juncapfunction(qprefgat,qpref2gat,vbiinvgat,one_minus_PGAT,idsatgat,CSRHGAT_i,CTATGAT_i,vbigat,wdepnulrgat,VBIRGATinv,PGAT_i,ftdgat,btatpartgat,atatgat,one_over_one_minus_PGAT,CBBTGAT_i,VBIRGAT_i,wdepnulrinvgat,fbbtgat,VBRGAT_i,VBRinvgat,PBRGAT_i,fstopgat,slopegat,ijungat, qjungat) \ +end diff --git a/src/spicelib/devices/adms/psp102/admsva/JUNCAP200_parlist.include b/src/spicelib/devices/adms/psp102/admsva/JUNCAP200_parlist.include new file mode 100644 index 000000000..e246d36ec --- /dev/null +++ b/src/spicelib/devices/adms/psp102/admsva/JUNCAP200_parlist.include @@ -0,0 +1,65 @@ +//====================================================================================== +//====================================================================================== +// Filename: JUNCAP200_parlist.include +//====================================================================================== +//====================================================================================== +// +// (c) Copyright 2007, All Rights Reserved, NXP Semiconductors +// +// +// Version: 102.1 (PSP), 200.2 (JUNCAP), April 2007 (Simkit 2.5) +// +//====================================================================================== +//====================================================================================== +// +// Further information can be found in the file readme.txt +// + + ////////////////////////////////////////// + // + // JUNCAP2 - Reduced parameterlist + // + ////////////////////////////////////////// + + parameter real IMAX = 1000 `from(`IMAX_cliplow ,inf ) `P(desc="Maximum current up to which forward current behaves exponentially" unit="A" ); + parameter real CJORBOT = 1E-3 `from(`CJORBOT_cliplow ,inf ) `P(desc="Zero-bias capacitance per unit-of-area of bottom component" unit="Fm^-2" ); + parameter real CJORSTI = 1E-9 `from(`CJORSTI_cliplow ,inf ) `P(desc="Zero-bias capacitance per unit-of-length of STI-edge component" unit="Fm^-1" ); + parameter real CJORGAT = 1E-9 `from(`CJORGAT_cliplow ,inf ) `P(desc="Zero-bias capacitance per unit-of-length of gate-edge component" unit="Fm^-1" ); + parameter real VBIRBOT = 1 `from(`VBIR_cliplow ,inf ) `P(desc="Built-in voltage at the reference temperature of bottom component" unit="V" ); + parameter real VBIRSTI = 1 `from(`VBIR_cliplow ,inf ) `P(desc="Built-in voltage at the reference temperature of STI-edge component" unit="V" ); + parameter real VBIRGAT = 1 `from(`VBIR_cliplow ,inf ) `P(desc="Built-in voltage at the reference temperature of gate-edge component" unit="V" ); + parameter real PBOT = 0.5 `from(`P_cliplow ,`P_cliphigh ) `P(desc="Grading coefficient of bottom component" unit="" ); + parameter real PSTI = 0.5 `from(`P_cliplow ,`P_cliphigh ) `P(desc="Grading coefficient of STI-edge component" unit="" ); + parameter real PGAT = 0.5 `from(`P_cliplow ,`P_cliphigh ) `P(desc="Grading coefficient of gate-edge component" unit="" ); + parameter real PHIGBOT = 1.16 `P(desc="Zero-temperature bandgap voltage of bottom component" unit="V" ); + parameter real PHIGSTI = 1.16 `P(desc="Zero-temperature bandgap voltage of STI-edge component" unit="V" ); + parameter real PHIGGAT = 1.16 `P(desc="Zero-temperature bandgap voltage of gate-edge component" unit="V" ); + parameter real IDSATRBOT = 1E-12 `from(`IDSATR_cliplow ,inf ) `P(desc="Saturation current density at the reference temperature of bottom component" unit="Am^-2" ); + parameter real IDSATRSTI = 1E-18 `from(`IDSATR_cliplow ,inf ) `P(desc="Saturation current density at the reference temperature of STI-edge component" unit="Am^-1" ); + parameter real IDSATRGAT = 1E-18 `from(`IDSATR_cliplow ,inf ) `P(desc="Saturation current density at the reference temperature of gate-edge component" unit="Am^-1" ); + parameter real CSRHBOT = 1E2 `from(`CSRH_cliplow ,inf ) `P(desc="Shockley-Read-Hall prefactor of bottom component" unit="Am^-3" ); + parameter real CSRHSTI = 1E-4 `from(`CSRH_cliplow ,inf ) `P(desc="Shockley-Read-Hall prefactor of STI-edge component" unit="Am^-2" ); + parameter real CSRHGAT = 1E-4 `from(`CSRH_cliplow ,inf ) `P(desc="Shockley-Read-Hall prefactor of gate-edge component" unit="Am^-2" ); + parameter real XJUNSTI = 100E-9 `from(`XJUN_cliplow ,inf ) `P(desc="Junction depth of STI-edge component" unit="m" ); + parameter real XJUNGAT = 100E-9 `from(`XJUN_cliplow ,inf ) `P(desc="Junction depth of gate-edge component" unit="m" ); + parameter real CTATBOT = 1E2 `from(`CTAT_cliplow ,inf ) `P(desc="Trap-assisted tunneling prefactor of bottom component" unit="Am^-3" ); + parameter real CTATSTI = 1E-4 `from(`CTAT_cliplow ,inf ) `P(desc="Trap-assisted tunneling prefactor of STI-edge component" unit="Am^-2" ); + parameter real CTATGAT = 1E-4 `from(`CTAT_cliplow ,inf ) `P(desc="Trap-assisted tunneling prefactor of gate-edge component" unit="Am^-2" ); + parameter real MEFFTATBOT = 0.25 `from(`MEFFTAT_cliplow ,inf ) `P(desc="Effective mass (in units of m0) for trap-assisted tunneling of bottom component" unit="" ); + parameter real MEFFTATSTI = 0.25 `from(`MEFFTAT_cliplow ,inf ) `P(desc="Effective mass (in units of m0) for trap-assisted tunneling of STI-edge component" unit="" ); + parameter real MEFFTATGAT = 0.25 `from(`MEFFTAT_cliplow ,inf ) `P(desc="Effective mass (in units of m0) for trap-assisted tunneling of gate-edge component" unit="" ); + parameter real CBBTBOT = 1E-12 `from(`CBBT_cliplow ,inf ) `P(desc="Band-to-band tunneling prefactor of bottom component" unit="AV^-3" ); + parameter real CBBTSTI = 1E-18 `from(`CBBT_cliplow ,inf ) `P(desc="Band-to-band tunneling prefactor of STI-edge component" unit="AV^-3m" ); + parameter real CBBTGAT = 1E-18 `from(`CBBT_cliplow ,inf ) `P(desc="Band-to-band tunneling prefactor of gate-edge component" unit="AV^-3m" ); + parameter real FBBTRBOT = 1E9 `P(desc="Normalization field at the reference temperature for band-to-band tunneling of bottom component" unit="Vm^-1" ); + parameter real FBBTRSTI = 1E9 `P(desc="Normalization field at the reference temperature for band-to-band tunneling of STI-edge component" unit="Vm^-1" ); + parameter real FBBTRGAT = 1E9 `P(desc="Normalization field at the reference temperature for band-to-band tunneling of gate-edge component" unit="Vm^-1" ); + parameter real STFBBTBOT = -1E-3 `P(desc="Temperature scaling parameter for band-to-band tunneling of bottom component" unit="K^-1" ); + parameter real STFBBTSTI = -1E-3 `P(desc="Temperature scaling parameter for band-to-band tunneling of STI-edge component" unit="K^-1" ); + parameter real STFBBTGAT = -1E-3 `P(desc="Temperature scaling parameter for band-to-band tunneling of gate-edge component" unit="K^-1" ); + parameter real VBRBOT = 10 `from(`VBR_cliplow ,inf ) `P(desc="Breakdown voltage of bottom component" unit="V" ); + parameter real VBRSTI = 10 `from(`VBR_cliplow ,inf ) `P(desc="Breakdown voltage of STI-edge component" unit="V" ); + parameter real VBRGAT = 10 `from(`VBR_cliplow ,inf ) `P(desc="Breakdown voltage of gate-edge component" unit="V" ); + parameter real PBRBOT = 4 `from(`PBR_cliplow ,inf ) `P(desc="Breakdown onset tuning parameter of bottom component" unit="V" ); + parameter real PBRSTI = 4 `from(`PBR_cliplow ,inf ) `P(desc="Breakdown onset tuning parameter of STI-edge component" unit="V" ); + parameter real PBRGAT = 4 `from(`PBR_cliplow ,inf ) `P(desc="Breakdown onset tuning parameter of gate-edge component" unit="V" ); diff --git a/src/spicelib/devices/adms/psp102/admsva/JUNCAP200_varlist.include b/src/spicelib/devices/adms/psp102/admsva/JUNCAP200_varlist.include new file mode 100644 index 000000000..cb4c5a680 --- /dev/null +++ b/src/spicelib/devices/adms/psp102/admsva/JUNCAP200_varlist.include @@ -0,0 +1,67 @@ +//====================================================================================== +//====================================================================================== +// Filename: JUNCAP200_varlist.include +//====================================================================================== +//====================================================================================== +// +// (c) Copyright 2007, All Rights Reserved, NXP Semiconductors +// +// +// Version: 102.1 (PSP), 200.2 (JUNCAP), April 2007 (Simkit 2.5) +// +//====================================================================================== +//====================================================================================== +// +// Further information can be found in the file readme.txt +// + + + // declaration of variables needed in macro "calcerfcexpmtat" + real ysq, terfc, erfcpos; + + // declaration of variables needed in hypfunction 5 + real h1, h2, h2d, h3, h4, h5; + + // declaration of variables used within macro "juncapfunction" + real tmp, id; + real isrh, vbi_minus_vjsrh, wsrhstep, dwsrh, wsrh, wdep, asrh; + real itat, btat, twoatatoverthreebtat, umaxbeforelimiting, umax, sqrtumax, umaxpoweronepointfive; + real wgamma, wtat, ktat, ltat, mtat, xerfc, erfctimesexpmtat, gammamax; + real ibbt, Fmaxr; + real fbreakdown; + + // declaration of clipped parameters + real TRJ_i, IMAX_i; + real CJORBOT_i, CJORSTI_i, CJORGAT_i, VBIRBOT_i, VBIRSTI_i, VBIRGAT_i; + real PBOT_i, PSTI_i, PGAT_i; + real IDSATRBOT_i, IDSATRSTI_i, IDSATRGAT_i, XJUNSTI_i, XJUNGAT_i; + real CSRHBOT_i, CSRHSTI_i, CSRHGAT_i, CTATBOT_i, CTATSTI_i, CTATGAT_i; + real MEFFTATBOT_i, MEFFTATSTI_i, MEFFTATGAT_i; + real CBBTBOT_i, CBBTSTI_i, CBBTGAT_i; + real VBRBOT_i, VBRSTI_i, VBRGAT_i, PBRBOT_i, PBRSTI_i, PBRGAT_i; + + // declaration of variables calculated outside macro "juncapfunction", voltage-independent part + real tkr, tkd, auxt, KBOL_over_QELE, phitr, phitrinv, phitd, phitdinv; + real deltaphigr, phigrbot, phigrsti, phigrgat, deltaphigd, phigdbot, phigdsti, phigdgat; + real ftdbot, ftdsti, ftdgat, idsatbot, idsatsti, idsatgat, exp_VMAX_over_phitd; + real ubibot, ubisti, ubigat, vbibot, vbisti, vbigat; + real vbibot2, vbisti2, vbigat2, vbibot2r, vbisti2r, vbigat2r; + real vbiinvbot, vbiinvsti, vbiinvgat; + real one_minus_PBOT, one_minus_PSTI, one_minus_PGAT; + real one_over_one_minus_PBOT, one_over_one_minus_PSTI, one_over_one_minus_PGAT; + real cjobot, cjosti, cjogat, qprefbot, qprefsti, qprefgat; + real vbimin, vch, vfmin, vbbtlim; + real qpref2bot, qpref2sti, qpref2gat; + real wdepnulrbot, wdepnulrsti, wdepnulrgat, wdepnulrinvbot, wdepnulrinvsti, wdepnulrinvgat; + real VBIRBOTinv, VBIRSTIinv, VBIRGATinv; + real perfc, berfc, cerfc; + real deltaEbot, deltaEsti, deltaEgat, atatbot, atatsti, atatgat; + real btatpartbot, btatpartsti, btatpartgat; + real fbbtbot, fbbtsti, fbbtgat; + real fstopbot, fstopsti, fstopgat, VBRinvbot, VBRinvsti, VBRinvgat; + real slopebot, slopesti, slopegat; + real vmaxbot, vmaxsti, vmaxgat, VMAX; + + // declaration of variables calculated outside macro "juncapfunction", voltage-dependent part + real VAK, idmult, vj, z, zinv, two_psistar, vjlim, vjsrh, vbbt, vav; + diff --git a/src/spicelib/devices/adms/psp102/admsva/PSP102_ChargesNQS.include b/src/spicelib/devices/adms/psp102/admsva/PSP102_ChargesNQS.include new file mode 100644 index 000000000..6ebe651fd --- /dev/null +++ b/src/spicelib/devices/adms/psp102/admsva/PSP102_ChargesNQS.include @@ -0,0 +1,303 @@ +//====================================================================================== +//====================================================================================== +// Filename: PSP102_ChargesNQS.include +//====================================================================================== +//====================================================================================== +// +// (c) Copyright 2007, All Rights Reserved, NXP Semiconductors +// +// +// Version: 102.1, April 2007 (Simkit 2.5) +// +//====================================================================================== +//====================================================================================== +// +// Further information can be found in the file readme.txt +// + + + /////////////////////////////////////////////// + // + // Calculate NQS-charge contributions + // + /////////////////////////////////////////////// + + Qp1 = vnorm * V(SPLINE1); + Qp2 = vnorm * V(SPLINE2); + Qp3 = vnorm * V(SPLINE3); + Qp4 = vnorm * V(SPLINE4); + Qp5 = vnorm * V(SPLINE5); + Qp6 = vnorm * V(SPLINE6); + Qp7 = vnorm * V(SPLINE7); + Qp8 = vnorm * V(SPLINE8); + Qp9 = vnorm * V(SPLINE9); + + Tnorm = 0.0; + + if (SWNQS_i != 0) begin + // Dimension and mobility information is included in Tnorm + Tnorm = MUNQS_i * phit1 * BET_i / (COX_qm * Gmob_dL); + thesat2 = thesat1 * thesat1 * phit1 * phit1; + + if (SWNQS_i == 1) begin + dQy = QpN - Qp0; + d2Qy = 6.0 * (Qp0 + QpN) - 12.0 * Qp1; + end else if (SWNQS_i == 2) begin + dQy = (-7.0 * Qp0 - 3.0 * Qp1 + 12.0 * Qp2 - 2.0 * QpN) / 5.0; + d2Qy = -18.0 / 5.0 * (-4.0 * Qp0 + 9.0 * Qp1 - 6.0 * Qp2 + QpN); + end else if (SWNQS_i == 3) begin + dQy = (-13.0 * Qp0 - 6.0 * Qp1 + 24.0 * Qp2 - 6.0 * Qp3 + QpN) / 7.0; + d2Qy = (180.0 * Qp0 - 408.0 * Qp1 + 288.0 * Qp2 - 72.0 * Qp3 + 12.0 * QpN) / 7.0; + end else if (SWNQS_i == 5) begin + dQy = (-181.0 * Qp0 - 84.0 * Qp1 + 24.0 * Qp4 - 6.0 * Qp5 - 90.0 * Qp3 + QpN + + 336.0 * Qp2) / 65.0; + d2Qy = (432.0 * Qp4 - 108.0 * Qp5 - 1620.0 * Qp3 + 18.0 * QpN + 3762.0 * Qp0 + - 8532.0 * Qp1 + 6048.0 * Qp2) / 65.0; + end else if (SWNQS_i == 9) begin + dQy = (1680.0 * Qp6 + 23400.0 * Qp4 + 5.0 * QpN - 87330.0 * Qp3 + 120.0 * Qp8 + - 450.0 * Qp7 - 81480.0 * Qp1 + 325920.0 * Qp2 + -175565.0 * Qp0 - 30.0 * Qp9) / 37829.0 - 30.0 / 181.0 * Qp5; + d2Qy = (-13500.0 * Qp7 + 702000.0 * Qp4 - 2619900 * Qp3 - 13793100.0 * Qp1 + + 9777600.0 * Qp2 + 6081750.0 * Qp0 + 150.0 * QpN + 3600.0 * Qp8 + - 900.0 * Qp9 + 50400 * Qp6) / 37829.0 - 900.0 / 181.0 * Qp5; + end else begin + dQy = 0; + d2Qy = 0; + end + `fq(Qp1, xg, dQy, d2Qy, fk1) + end + + if (SWNQS_i >= 2) begin + if (SWNQS_i == 2) begin + dQy = (2.0 * Qp0 - 12.0 * Qp1 + 3.0 * Qp2 + 7.0 * QpN) / 5.0; + d2Qy = -18.0 / 5.0 * (-4.0 * QpN + 9.0 * Qp2 - 6.0 * Qp1 + Qp0); + end else if (SWNQS_i == 3) begin + dQy = 0.5 * Qp0 - 3.0 * Qp1 + 3.0 * Qp3 - 0.5 * QpN; + d2Qy = (-48.0 * Qp0 + 288.0 * Qp1 - 480.0 * Qp2 + 288.0 * Qp3 - 48.0 * QpN) / 7.0; + end else if (SWNQS_i == 5) begin + dQy = (-291.0 * Qp1 - 6.0 * Qp2 - 84.0 * Qp4 + 21.0 * Qp5) / 65.0 + + (630.0 * Qp3 - 7.0 * QpN + 97.0 * Qp0) / 130.0; + d2Qy = (-1728.0 * Qp4 + 432.0 * Qp5 + 6480.0 * Qp3 - 72.0 * QpN - 1008 * Qp0 + + 6048 * Qp1 - 10152 * Qp2) / 65.0; + end else if (SWNQS_i == 9) begin + dQy = (-5880.0 * Qp6 - 81900.0 * Qp4 + 305655.0 * Qp3 - 420.0 * Qp8 + + 105.0 * Qp9 - 282255.0 * Qp1 + 1575.0 * Qp7 - 5850.0 * Qp2) / 37829.0 + + 105.0 / 181.0 * Qp5 + (94085.0 * Qp0 - 35.0 * QpN) / 75658.0; + d2Qy = (9777600.0 * Qp1 + 54000.0 * Qp7 - 2808000.0 * Qp4 + 10479600.0 * Qp3 + - 16413000.0 * Qp2 - 1629600.0 * Qp0 - 600.0 * QpN - 14400.0 * Qp8 + + 3600.0 * Qp9 - 201600.0 * Qp6) / 37829.0 + 3600.0 * Qp5 / 181.0; + end else begin + dQy = 0; + d2Qy = 0; + end + `fq(Qp2, xg, dQy, d2Qy, fk2) + end + + if (SWNQS_i >= 3) begin + if (SWNQS_i == 3) begin + dQy = (13.0 * QpN + 6.0 * Qp3 - 24.0 * Qp2 + 6.0 * Qp1 - Qp0) / 7.0; + d2Qy = (180.0 * QpN - 408.0 * Qp3 + 288.0 * Qp2 - 72.0 * Qp1 + 12.0 * Qp0) / 7.0; + end else if (SWNQS_i == 5) begin + dQy = (QpN - 6.0 * Qp5 + 24.0 * Qp4 - 24.0 * Qp2 + 6.0 * Qp1 - Qp0) / 5.0; + d2Qy = (1296.0 * (Qp4 + Qp2) - 324.0 * (Qp5 + Qp1) - 2052.0 * Qp3 + + 54.0 * (QpN + Qp0)) / 13.0; + end else if (SWNQS_i == 9) begin + dQy = (21840.0 * Qp6 + 304200.0 * Qp4 + 65.0 * QpN - 420.0 * Qp3 + 1560.0 * Qp8 + - 12605.0 * Qp0-390.0 * Qp9 + 75630.0 * Qp1 - 5850.0 * Qp7 + - 302520.0 * Qp2) / 37829.0 - 390.0 / 181.0 * Qp5; + d2Qy = (-2619900.0 * Qp1 - 202500.0 * Qp7 + 10530000.0 * Qp4 - 16601100.0 * Qp3 + + 10479600.0 * Qp2 + 436650.0 * Qp0 + 2250.0 * QpN + 54000.0 * Qp8 + - 13500.0 * Qp9 + 756000.0 * Qp6) / 37829.0 - 13500.0 * Qp5 / 181.0; + end else begin + dQy = 0; + d2Qy = 0; + end + `fq(Qp3, xg, dQy, d2Qy, fk3) + end + + if (SWNQS_i >= 4) begin + if (SWNQS_i == 5) begin + dQy = (-630.0 * Qp3 + 12.0 * Qp4 + 582.0 * Qp5 - 97.0 * QpN + 7.0 * Qp0 + - 42.0 * Qp1 + 168.0 * Qp2)/130.0; + d2Qy = (-10152.0 * Qp4 + 6048.0 * Qp5 + 6480.0 * Qp3 - 1008.0 * QpN + - 72.0 * Qp0 + 432.0 * Qp1 - 1728.0 * Qp2) / 65.0; + end + else if (SWNQS_i == 9) begin + dQy = (-81480.0 * Qp6 - 30.0 * Qp4 - 303975.0 * Qp3 - 5820.0 * Qp8 + + 1455.0 * Qp9 - 20265.0 * Qp1 + 21825.0 * Qp7 + 81060.0 * Qp2) / 37829.0 + - 485.0 / 75658.0 * QpN + 1455.0 * Qp5 / 181.0 + 6755.0 * Qp0 / 75658.0; + d2Qy = (702000.0 * Qp1 + 756000.0 * Qp7 - 16614600.0 * Qp4 + 10530000.0 * Qp3 + - 2808000.0 * Qp2 - 117000.0 * Qp0 - 8400.0 * QpN - 201600.0 * Qp8 + + 50400.0 * Qp9 - 2822400.0 * Qp6) / 37829.0 + 50400.0 * Qp5 / 181.0; + end else begin + dQy = 0; + d2Qy = 0; + end + `fq(Qp4, xg, dQy, d2Qy, fk4) + end + + if (SWNQS_i >= 5) begin + if (SWNQS_i == 5) begin + dQy = (-336.0 * Qp4 + 84.0 * Qp5 + 90.0 * Qp3 + 181.0 * QpN - Qp0 + 6.0 * Qp1 + - 24.0 * Qp2) / 65.0; + d2Qy = (18.0 * Qp0 + 3762.0 * QpN + 6048.0 * Qp4 + 432.0 * Qp2 - 1620.0 * Qp3 + - 108.0 * Qp1 - 8532.0 * Qp5) / 65.0; + end else if (SWNQS_i == 9) begin + dQy = (1680.0 * (Qp6 - Qp4) + 5.0 * (QpN - Qp0) + 450.0 * (Qp3 - Qp7) + + 120.0 * (Qp8 - Qp2) - 30.0 * (Qp9 - Qp1)) / 209.0; + d2Qy = (-900.0 * (Qp1 + Qp9) - 13500.0 * (Qp7 + Qp3) - 79500.0 * Qp5 + + 50400.0 * (Qp4 + Qp6) + 3600.0 * (Qp2 + Qp8) + 150.0 * (Qp0 + QpN)) / 181.0; + end else begin + dQy = 0; + d2Qy = 0; + end + `fq(Qp5, xg, dQy, d2Qy, fk5) + end + + if (SWNQS_i >= 6) begin + if (SWNQS_i == 9) begin + dQy = (30.0 * Qp6 + 81480.0 * Qp4 - 21825.0 * Qp3 - 81060.0 * Qp8 + 20265.0 * Qp9 + - 1455.0 * Qp1 + 303975.0 * Qp7 + 5820.0 * Qp2) / 37829.0 + -(6755.0 * QpN - 485.0 * Qp0) / 75658.0 - 1455.0 / 181.0 * Qp5; + d2Qy = (50400.0 * Qp1 + 10530000.0 * Qp7 - 2822400.0 * Qp4 + 756000.0 * Qp3 + - 201600.0 * Qp2 - 8400.0 * Qp0 - 117000.0 * QpN - 2808000.0 * Qp8 + + 702000.0 * Qp9 - 16614600.0 * Qp6) / 37829.0 + 50400.0 * Qp5 / 181.0; + end else begin + dQy = 0; + d2Qy = 0; + end + `fq(Qp6, xg, dQy, d2Qy, fk6) + end + + if (SWNQS_i >= 7) begin + if (SWNQS_i == 9) begin + dQy = (-304200.0 * Qp6 - 21840.0 * Qp4 + 12605.0 * QpN + 5850.0 * Qp3 + + 302520.0 * Qp8 - 65.0 * Qp0 - 75630.0 * Qp9 + 390.0 * Qp1 + 420.0 * Qp7 + - 1560.0 * Qp2) / 37829.0 + 390.0 / 181.0 * Qp5; + d2Qy = (-13500.0 * Qp1 - 16601100.0 * Qp7 + 756000.0 * Qp4 - 202500.0 * Qp3 + + 54000.0 * Qp2 + 2250.0 * Qp0 + 436650.0 * QpN + 10479600.0 * Qp8 + - 2619900.0 * Qp9 + 10530000.0 * Qp6) / 37829.0 - 13500.0 * Qp5 / 181.0; + end else begin + dQy = 0; + d2Qy = 0; + end + `fq(Qp7, xg, dQy, d2Qy, fk7) + end + + if (SWNQS_i >= 8) begin + if (SWNQS_i == 9) begin + dQy = (81900.0 * Qp6 + 5880.0 * Qp4 - 1575.0 * Qp3 + 5850.0 * Qp8 + 282255.0 * Qp9 + - 105.0 * Qp1 - 305655.0 * Qp7 + 420.0 * Qp2) / 37829.0 + (35.0 * Qp0 + - 94085.0 * QpN) / 75658.0 - 105.0 / 181.0 * Qp5; + d2Qy = (3600.0 * Qp1 + 10479600.0 * Qp7 - 201600.0 * Qp4 + 54000.0 * Qp3 + - 14400.0 * Qp2 - 600.0 * Qp0 - 1629600.0 * QpN - 16413000.0 * Qp8 + + 9777600.0 * Qp9 - 2808000.0 * Qp6) / 37829.0 + 3600.0 * Qp5 / 181.0; + end else begin + dQy = 0; + d2Qy = 0; + end + `fq(Qp8, xg, dQy, d2Qy, fk8) + end + + if (SWNQS_i >= 9) begin + if (SWNQS_i == 9) begin + dQy = (-23400.0 * Qp6 - 1680.0 * Qp4 + 175565.0 * QpN + 450.0 * Qp3 + - 325920.0 * Qp8 - 5.0 * Qp0 + 81480.0 * Qp9 + 30.0 * Qp1 + + 87330.0 * Qp7 - 120.0 * Qp2) / 37829.0 + 30.0 * Qp5 / 181.0; + d2Qy = (-900.0 * Qp1 - 2619900.0 * Qp7 + 50400.0 * Qp4 - 13500.0 * Qp3 + + 3600.0 * Qp2 + 150.0 * Qp0 + 6081750.0 * QpN + 9777600.0 * Qp8 + - 13793100.0 * Qp9 + 702000.0 * Qp6) / 37829.0 - 900.0 * Qp5 / 181.0; + end else begin + dQy = 0; + d2Qy = 0; + end + `fq(Qp9, xg, dQy, d2Qy, fk9) + end + + //-------------------------------------------------------------------- + + // Terminal charges for NQS + if (SWNQS_i != 0) begin + if (SWNQS_i == 1) begin + QS_NQS = (17.0 * Qp0 + 30.0 * Qp1 + QpN) / 96.0; + QD_NQS = (Qp0 + 30.0 * Qp1 + 17.0 * QpN) / 96.0; + `QiToPhi(Qp1,xg, temp1) + QG_NQS = xg - (x_sp + 4.0 * temp1 + x_dp) * `oneSixth; + end else if (SWNQS_i == 2) begin + QS_NQS = (11.0 * Qp0 + 24.0 * Qp1 + 9.0 * Qp2 + QpN) / 90.0; + QD_NQS = (11.0 * QpN + 24.0 * Qp2 + 9.0 * Qp1 + Qp0) / 90.0; + `QiToPhi(Qp1, xg, temp1) + `QiToPhi(Qp2, xg, temp2) + QG_NQS = xg - (x_sp + 3.0 * (temp1 + temp2) + x_dp) * 0.125; + end else if (SWNQS_i == 3) begin + QS_NQS = (251.0 * Qp0 + 594.0 * Qp1 + 312.0 * Qp2 + 174.0 * Qp3 + 13.0 * QpN) / 2688.0; + QD_NQS = (251.0 * QpN + 594.0 * Qp3 + 312.0 * Qp2 + 174.0 * Qp1 + 13.0 * Qp0) / 2688.0; + `QiToPhi(Qp1, xg, temp1) + `QiToPhi(Qp2, xg, temp2) + `QiToPhi(Qp3, xg, temp3) + QG_NQS = xg - (x_sp + 4.0 * temp1 + 2.0 * temp2 + 4.0 * temp3 + x_dp) / 12.0; + end else if (SWNQS_i == 5) begin + QS_NQS = (1187.0 * Qp0 + 43.0 * QpN) / 18720.0 + (503.0 * Qp1 + 172.0 * Qp4 + + 87.0 * Qp5 + 265.0 * Qp3 + 328.0 * Qp2) / 3120.0; + QD_NQS = (1187.0 * QpN + 43.0 * Qp0) / 18720.0 + (503.0 * Qp5 + 172.0 * Qp2 + + 87.0 * Qp1 + 265.0 * Qp3 + 328.0 * Qp4) / 3120.0; + `QiToPhi(Qp1, xg, temp1) + `QiToPhi(Qp2, xg, temp2) + `QiToPhi(Qp3, xg, temp3) + `QiToPhi(Qp4, xg, temp4) + `QiToPhi(Qp5, xg, temp5) + QG_NQS = xg - (x_sp + 4.0 * (temp1 + temp3 + temp5) + 2.0 * (temp2 + temp4) + x_dp) / 18.0; + end else if (SWNQS_i == 9) begin + QS_NQS = (75653.0 * Qp8 + 225999.0 * Qp4) / 3782900.0 + (151321.0 * Qp9 + + 454023.0 * Qp7 + 1073767.0 * Qp3 + 1564569.0 * Qp1) / 15131600.0 + + 75623.0 * Qp6 / 1891450.0 + 145.0 * Qp5 / 2896.0 + 72263.0 * Qp2 / 945725.0 + + (3504517.0 * Qp0 + 75653.0 * QpN) / 90789600.0; + QD_NQS = (75653.0 * Qp2 + 225999.0 * Qp6) / 3782900.0 + (151321.0 * Qp1 + + 454023.0 * Qp3 + 1073767.0 * Qp7 + 1564569.0 * Qp9) / 15131600.0 + + 75623.0 * Qp4 / 1891450.0 + 145.0 * Qp5 / 2896.0 + 72263.0 * Qp8 / 945725.0 + + (3504517.0 * QpN + 75653.0 * Qp0) / 90789600.0; + `QiToPhi(Qp1, xg, temp1) + `QiToPhi(Qp2, xg, temp2) + `QiToPhi(Qp3, xg, temp3) + `QiToPhi(Qp4, xg, temp4) + `QiToPhi(Qp5, xg, temp5) + `QiToPhi(Qp6, xg, temp6) + `QiToPhi(Qp7, xg, temp7) + `QiToPhi(Qp8, xg, temp8) + `QiToPhi(Qp9, xg, temp9) + QG_NQS = xg - (x_sp + 4.0 * (temp1 + temp3 + temp5 + temp7 + temp9) + + 2.0 * (temp2 + temp4 + temp6 + temp8) + x_dp) / 30.0; + end + QG_NQS = pd * QG_NQS; + + if (sigVds > 0) begin + Qs = COX_qm * phit1 * QS_NQS; + Qd = COX_qm * phit1 * QD_NQS; + end else begin + Qs = COX_qm * phit1 * QD_NQS; + Qd = COX_qm * phit1 * QS_NQS; + end + Qg = COX_qm * phit1 * QG_NQS; + Qb = -Qg - Qs - Qd; + end + + // Update internal nodes + V(RES1) <+ vnorm_inv * I(RES1) * r_nqs; + V(SPLINE1) <+ idt(-vnorm_inv * Tnorm * fk1, Qp1_0); + V(RES2) <+ vnorm_inv * I(RES2) * r_nqs; + V(SPLINE2) <+ idt(-vnorm_inv * Tnorm * fk2, Qp2_0); + V(RES3) <+ vnorm_inv * I(RES3) * r_nqs; + V(SPLINE3) <+ idt(-vnorm_inv * Tnorm * fk3, Qp3_0); + V(RES4) <+ vnorm_inv * I(RES4) * r_nqs; + V(SPLINE4) <+ idt(-vnorm_inv * Tnorm * fk4, Qp4_0); + V(RES5) <+ vnorm_inv * I(RES5) * r_nqs; + V(SPLINE5) <+ idt(-vnorm_inv * Tnorm * fk5, Qp5_0); + V(RES6) <+ vnorm_inv * I(RES6) * r_nqs; + V(SPLINE6) <+ idt(-vnorm_inv * Tnorm * fk6, Qp6_0); + V(RES7) <+ vnorm_inv * I(RES7) * r_nqs; + V(SPLINE7) <+ idt(-vnorm_inv * Tnorm * fk7, Qp7_0); + V(RES8) <+ vnorm_inv * I(RES8) * r_nqs; + V(SPLINE8) <+ idt(-vnorm_inv * Tnorm * fk8, Qp8_0); + V(RES9) <+ vnorm_inv * I(RES9) * r_nqs; + V(SPLINE9) <+ idt(-vnorm_inv * Tnorm * fk9, Qp9_0); + diff --git a/src/spicelib/devices/adms/psp102/admsva/PSP102_InitNQS.include b/src/spicelib/devices/adms/psp102/admsva/PSP102_InitNQS.include new file mode 100644 index 000000000..a42383d16 --- /dev/null +++ b/src/spicelib/devices/adms/psp102/admsva/PSP102_InitNQS.include @@ -0,0 +1,190 @@ +//====================================================================================== +//====================================================================================== +// Filename: PSP102_InitNQS.include +//====================================================================================== +//====================================================================================== +// +// (c) Copyright 2007, All Rights Reserved, NXP Semiconductors +// +// +// Version: 102.1, April 2007 (Simkit 2.5) +// +//====================================================================================== +//====================================================================================== +// +// Further information can be found in the file readme.txt +// + + ///////////////////////////////////////////////////////////////////////////// + // + // Computing initial (dc) values for internal nodes. + // This code is independent of internal-node voltages + // + ///////////////////////////////////////////////////////////////////////////// + + Qp1_0 = 0.0; + Qp2_0 = 0.0; + Qp3_0 = 0.0; + Qp4_0 = 0.0; + Qp5_0 = 0.0; + Qp6_0 = 0.0; + Qp7_0 = 0.0; + Qp8_0 = 0.0; + Qp9_0 = 0.0; + fk1 = 0.0; + fk2 = 0.0; + fk3 = 0.0; + fk4 = 0.0; + fk5 = 0.0; + fk6 = 0.0; + fk7 = 0.0; + fk8 = 0.0; + fk9 = 0.0; + if (SWNQS_i != 0) begin + dQis = 0.0; + dQy = 0.0; + dfQi = 0.0; + fQi = 0.0; + d2Qy = 0.0; + + Qp1 = 0.0; + Qp2 = 0.0; + Qp3 = 0.0; + Qp4 = 0.0; + Qp5 = 0.0; + Qp6 = 0.0; + Qp7 = 0.0; + Qp8 = 0.0; + Qp9 = 0.0; + + phi_p1 = 0.0; + phi_p2 = 0.0; + phi_p3 = 0.0; + phi_p4 = 0.0; + phi_p5 = 0.0; + phi_p6 = 0.0; + phi_p7 = 0.0; + phi_p8 = 0.0; + phi_p9 = 0.0; + + // Setting initial values for charge along the channel + // from interpolated DC-solution + if (xg > 0) begin + if (SWNQS_i == 1) begin + phi_p1 = `Phiy(0.5); + `PhiToQb(phi_p1,Qb_tmp) + Qp1_0 = -pd * (xg - phi_p1) - Qb_tmp; + end else if (SWNQS_i == 2) begin + phi_p1 = `Phiy(`oneThird); + `PhiToQb(phi_p1,Qb_tmp) + Qp1_0 = -pd * (xg - phi_p1) - Qb_tmp; + + phi_p2 = `Phiy(`twoThirds); + `PhiToQb(phi_p2,Qb_tmp) + Qp2_0 = -pd * (xg - phi_p2) - Qb_tmp; + if (sigVds < 0) begin + `swap(Qp1_0, Qp2_0) + end + end else if (SWNQS_i == 3) begin + phi_p1 = `Phiy(0.25); + `PhiToQb(phi_p1,Qb_tmp) + Qp1_0 = -pd * (xg - phi_p1) - Qb_tmp; + + phi_p2 = `Phiy(0.5); + `PhiToQb(phi_p2,Qb_tmp) + Qp2_0 = -pd * (xg - phi_p2) - Qb_tmp; + + phi_p3 = `Phiy(0.75); + `PhiToQb(phi_p3,Qb_tmp) + Qp3_0 = -pd * (xg - phi_p3) - Qb_tmp; + if (sigVds < 0) begin + `swap(Qp1_0, Qp3_0) + end + end else if (SWNQS_i == 5) begin + phi_p1 = `Phiy(`oneSixth); + `PhiToQb(phi_p1,Qb_tmp) + Qp1_0 = -pd * (xg - phi_p1) - Qb_tmp; + + phi_p2 = `Phiy(`oneThird); + `PhiToQb(phi_p2,Qb_tmp) + Qp2_0 = -pd * (xg - phi_p2) - Qb_tmp; + + phi_p3 = `Phiy(0.5); + `PhiToQb(phi_p3,Qb_tmp) + Qp3_0 = -pd * (xg - phi_p3) - Qb_tmp; + + phi_p4 = `Phiy(`twoThirds); + `PhiToQb(phi_p4,Qb_tmp) + Qp4_0 = -pd * (xg - phi_p4) - Qb_tmp; + + phi_p5 = `Phiy(0.8333333333333333); + `PhiToQb(phi_p5,Qb_tmp) + Qp5_0 = -pd * (xg - phi_p5) - Qb_tmp; + if (sigVds < 0) begin + `swap(Qp1_0, Qp5_0) + `swap(Qp2_0, Qp4_0) + end + end else if (SWNQS_i == 9) begin + phi_p1 = `Phiy(0.1); + `PhiToQb(phi_p1,Qb_tmp) + Qp1_0 = -pd * (xg - phi_p1) - Qb_tmp; + + phi_p2 = `Phiy(0.2); + `PhiToQb(phi_p2,Qb_tmp) + Qp2_0 = -pd * (xg - phi_p2) - Qb_tmp; + + phi_p3 = `Phiy(0.3); + `PhiToQb(phi_p3,Qb_tmp) + Qp3_0 = -pd * (xg - phi_p3) - Qb_tmp; + + phi_p4 = `Phiy(0.4); + `PhiToQb(phi_p4,Qb_tmp) + Qp4_0 = -pd * (xg - phi_p4) - Qb_tmp; + + phi_p5 = `Phiy(0.5); + `PhiToQb(phi_p5,Qb_tmp) + Qp5_0 = -pd * (xg - phi_p5) - Qb_tmp; + + phi_p6 = `Phiy(0.6); + `PhiToQb(phi_p6,Qb_tmp) + Qp6_0 = -pd * (xg - phi_p6) - Qb_tmp; + + phi_p7 = `Phiy(0.7); + `PhiToQb(phi_p7,Qb_tmp) + Qp7_0 = -pd * (xg - phi_p7) - Qb_tmp; + + phi_p8 = `Phiy(0.8); + `PhiToQb(phi_p8,Qb_tmp) + Qp8_0 = -pd * (xg - phi_p8) - Qb_tmp; + + phi_p9 = `Phiy(0.9); + `PhiToQb(phi_p9,Qb_tmp) + Qp9_0 = -pd * (xg - phi_p9) - Qb_tmp; + if (sigVds < 0) begin + `swap(Qp1_0, Qp9_0) + `swap(Qp2_0, Qp8_0) + `swap(Qp3_0, Qp7_0) + `swap(Qp4_0, Qp6_0) + end + end + end // (x_g >0) + end // (SWNQS_i != 0) + + x_sp = 0.0; + x_dp = 0.0; + Qp0 = 0.0; + QpN = 0.0; + if (SWNQS_i != 0.0) begin + x_sp = x_m - sigVds * 0.5 * dps * inv_phit1; + x_dp = x_m + sigVds * 0.5 * dps * inv_phit1; + Qp0 = 0.0; + QpN = 0.0; + if (x_sp > 0) begin + `PhiToQb(x_sp, QbSIGN) + Qp0 = -pd * (xg - x_sp) - QbSIGN; + end + if (x_dp > 0) begin + `PhiToQb(x_dp, QbSIGN) + QpN = -pd * (xg - x_dp) - QbSIGN; + end + end diff --git a/src/spicelib/devices/adms/psp102/admsva/PSP102_binning.include b/src/spicelib/devices/adms/psp102/admsva/PSP102_binning.include new file mode 100644 index 000000000..2c044e0ff --- /dev/null +++ b/src/spicelib/devices/adms/psp102/admsva/PSP102_binning.include @@ -0,0 +1,127 @@ +//====================================================================================== +//====================================================================================== +// Filename: PSP102_binning.include +//====================================================================================== +//====================================================================================== +// +// (c) Copyright 2007, All Rights Reserved, NXP Semiconductors +// +// +// Version: 102.1, April 2007 (Simkit 2.5) +// +//====================================================================================== +//====================================================================================== +// +// Further information can be found in the file readme.txt +// + + // auxiliary variables + iLEWE = iLE * iWE; + iiLE = LE / LEN; + iiWE = WE / WEN; + iiLEWE = iiLE * iiWE; + iiiLEWE = iiWE / iiLE; + + // auxiliary variables for COX only + iiLEcv = LEcv / LEN; + iiWEcv = WEcv / WEN; + iiLEWEcv = iiLEcv * iiWEcv; + + // auxiliary variables for CGOV only + iLEcv = LEN / LEcv; + iiiLEWEcv = iiWEcv / iiLEcv; + + // auxiliary variables for CGBOV only + iiLcv = Lcv / LEN; + iiWcv = Wcv / WEN; + iiLWcv = iiLcv * iiWcv; + + // auxiliary variables for CFR only + iLcv = LEN / Lcv; + iiiLWcv = iiWcv / iiLcv; + + // Process parameters + VFB = POVFB + iLE * PLVFB + iWE * PWVFB + iLEWE * PLWVFB; + STVFB = POSTVFB + iLE * PLSTVFB + iWE * PWSTVFB + iLEWE * PLWSTVFB; + TOX = POTOX; + NEFF = PONEFF + iLE * PLNEFF + iWE * PWNEFF + iLEWE * PLWNEFF; + VNSUB = POVNSUB; + NSLP = PONSLP; + DNSUB = PODNSUB; + DPHIB = PODPHIB + iLE * PLDPHIB + iWE * PWDPHIB + iLEWE * PLWDPHIB; + NP = PONP + iLE * PLNP + iWE * PWNP + iLEWE * PLWNP; + CT = POCT + iLE * PLCT + iWE * PWCT + iLEWE * PLWCT; + TOXOV = POTOXOV; + NOV = PONOV + iLE * PLNOV + iWE * PWNOV + iLEWE * PLWNOV; + + // DIBL parameters + CF = POCF + iLE * PLCF + iWE * PWCF + iLEWE * PLWCF; + CFB = POCFB; + + // Mobility parameters + BETN = POBETN + iLE * PLBETN + iiWE * PWBETN + iiiLEWE * PLWBETN; + STBET = POSTBET + iLE * PLSTBET + iWE * PWSTBET + iLEWE * PLWSTBET; + MUE = POMUE + iLE * PLMUE + iWE * PWMUE + iLEWE * PLWMUE; + STMUE = POSTMUE; + THEMU = POTHEMU; + STTHEMU = POSTTHEMU; + CS = POCS + iLE * PLCS + iWE * PWCS + iLEWE * PLWCS; + STCS = POSTCS; + XCOR = POXCOR + iLE * PLXCOR + iWE * PWXCOR + iLEWE * PLWXCOR; + STXCOR = POSTXCOR; + FETA = POFETA; + + // Series resistance parameters + RS = PORS + iLE * PLRS + iWE * PWRS + iLEWE * PLWRS; + STRS = POSTRS; + RSB = PORSB; + RSG = PORSG; + + // Velocity saturation parameters + THESAT = POTHESAT + iLE * PLTHESAT + iWE * PWTHESAT + iLEWE * PLWTHESAT; + STTHESAT = POSTTHESAT + iLE * PLSTTHESAT + iWE * PWSTTHESAT + iLEWE * PLWSTTHESAT; + THESATB = POTHESATB + iLE * PLTHESATB + iWE * PWTHESATB + iLEWE * PLWTHESATB; + THESATG = POTHESATG + iLE * PLTHESATG + iWE * PWTHESATG + iLEWE * PLWTHESATG; + + // Saturation voltage parameters + AX = POAX + iLE * PLAX + iWE * PWAX + iLEWE * PLWAX; + + // Channel length modulation (CLM) parameters + ALP = POALP + iLE * PLALP + iWE * PWALP + iLEWE * PLWALP; + ALP1 = POALP1 + iLE * PLALP1 + iWE * PWALP1 + iLEWE * PLWALP1; + ALP2 = POALP2 + iLE * PLALP2 + iWE * PWALP2 + iLEWE * PLWALP2; + VP = POVP; + + // Impact ionization parameters + A1 = POA1 + iLE * PLA1 + iWE * PWA1 + iLEWE * PLWA1; + A2 = POA2; + STA2 = POSTA2; + A3 = POA3 + iLE * PLA3 + iWE * PWA3 + iLEWE * PLWA3; + A4 = POA4 + iLE * PLA4 + iWE * PWA4 + iLEWE * PLWA4; + GCO = POGCO; + + // Gate current parameters + IGINV = POIGINV + iiLE * PLIGINV + iiWE * PWIGINV + iiLEWE * PLWIGINV; + IGOV = POIGOV + iLE * PLIGOV + iiWE * PWIGOV + iiiLEWE * PLWIGOV; + STIG = POSTIG; + GC2 = POGC2; + GC3 = POGC3; + CHIB = POCHIB; + + // Gate-induced drain leakage (GIDL) parameters + AGIDL = POAGIDL + iLE * PLAGIDL + iiWE * PWAGIDL + iiiLEWE * PLWAGIDL; + BGIDL = POBGIDL; + STBGIDL = POSTBGIDL; + CGIDL = POCGIDL; + + // Charge model parameters + COX = POCOX + iiLEcv * PLCOX + iiWEcv * PWCOX + iiLEWEcv * PLWCOX; + CGOV = POCGOV + iLEcv * PLCGOV + iiWEcv * PWCGOV + iiiLEWEcv * PLWCGOV; + CGBOV = POCGBOV + iiLcv * PLCGBOV + iiWcv * PWCGBOV + iiLWcv * PLWCGBOV; + CFR = POCFR + iLcv * PLCFR + iiWcv * PWCFR + iiiLWcv * PLWCFR; + + // Noise model parameters + FNT = POFNT; + NFA = PONFA + iLE * PLNFA + iWE * PWNFA + iLEWE * PLWNFA; + NFB = PONFB + iLE * PLNFB + iWE * PWNFB + iLEWE * PLWNFB; + NFC = PONFC + iLE * PLNFC + iWE * PWNFC + iLEWE * PLWNFC; diff --git a/src/spicelib/devices/adms/psp102/admsva/PSP102_binpars.include b/src/spicelib/devices/adms/psp102/admsva/PSP102_binpars.include new file mode 100644 index 000000000..3c0b61249 --- /dev/null +++ b/src/spicelib/devices/adms/psp102/admsva/PSP102_binpars.include @@ -0,0 +1,233 @@ +//====================================================================================== +//====================================================================================== +// Filename: PSP102_binpars.include +//====================================================================================== +//====================================================================================== +// +// (c) Copyright 2007, All Rights Reserved, NXP Semiconductors +// +// +// Version: 102.1, April 2007 (Simkit 2.5) +// +//====================================================================================== +//====================================================================================== +// +// Further information can be found in the file readme.txt +// + + /////////////////////////////////////////////////// + // PSP global model parameters (binning) + /////////////////////////////////////////////////// + + parameter real LEVEL = 1021 `P(desc="Model level" unit="" ); + parameter real TYPE = 1 `from( -1.0,1.0 ) `P(desc="Channel type parameter, +1=NMOS -1=PMOS" unit="" ); + parameter real TR = 21 `from( -273.0,inf ) `P(desc="nominal (reference) temperature" unit="C" ); + + // Switch parameters + parameter real SWIGATE = 0 `from( 0.0,1.0 ) `P(desc="Flag for gate current, 0=turn off IG" unit="" ); + parameter real SWIMPACT = 0 `from( 0.0,1.0 ) `P(desc="Flag for impact ionization current, 0=turn off II" unit="" ); + parameter real SWGIDL = 0 `from( 0.0,1.0 ) `P(desc="Flag for GIDL current, 0=turn off IGIDL" unit="" ); + parameter real SWJUNCAP = 0 `from( 0.0,3.0 ) `P(desc="Flag for juncap, 0=turn off juncap" unit="" ); + parameter real QMC = 1 `from( 0.0,inf ) `P(desc="Quantum-mechanical correction factor" unit="" ); + + // Process parameters + parameter real LVARO = 0 `P(desc="Geometry independent difference between actual and programmed poly-silicon gate length" unit="m" ); + parameter real LVARL = 0 `P(desc="Length dependence of difference between actual and programmed poly-silicon gate length" unit="" ); + parameter real LAP = 0 `P(desc="Effective channel length reduction per side due to lateral diffusion of source/drain dopant ions" unit="m" ); + parameter real WVARO = 0 `P(desc="Geometry independent difference between actual and programmed field-oxide opening" unit="m" ); + parameter real WVARW = 0 `P(desc="Width dependence of difference between actual and programmed field-oxide opening" unit="" ); + parameter real WOT = 0 `P(desc="Effective reduction of channel width per side due to lateral diffusion of channel-stop dopant ions" unit="m" ); + parameter real DLQ = 0 `P(desc="Effective channel length reduction for CV" unit="m" ); + parameter real DWQ = 0 `P(desc="Effective channel width reduction for CV" unit="m" ); + parameter real POVFB = -1 `P(desc="Coefficient for the geometry independent part of VFB" unit="V" ); + parameter real PLVFB = 0.0 `P(desc="Coefficient for the length dependence of VFB" unit="V" ); + parameter real PWVFB = 0.0 `P(desc="Coefficient for the width dependence of VFB" unit="V" ); + parameter real PLWVFB = 0.0 `P(desc="Coefficient for the length times width dependence of VFB" unit="V" ); + parameter real POSTVFB = 0.0005 `P(desc="Coefficient for the geometry independent part of STVFB" unit="V/K" ); + parameter real PLSTVFB = 0.0 `P(desc="Coefficient for the length dependence of STVFB" unit="V/K" ); + parameter real PWSTVFB = 0.0 `P(desc="Coefficient for the width dependence of STVFB" unit="V/K" ); + parameter real PLWSTVFB = 0.0 `P(desc="Coefficient for the length times width dependence of STVFB" unit="V/K" ); + parameter real POTOX = 2E-09 `P(desc="Coefficient for the geometry independent part of TOX" unit="m" ); + parameter real PONEFF = 5E+23 `P(desc="Coefficient for the geometry independent part of NEFF" unit="m^-3" ); + parameter real PLNEFF = 0.0 `P(desc="Coefficient for the length dependence of NEFF" unit="m^-3" ); + parameter real PWNEFF = 0.0 `P(desc="Coefficient for the width dependence of NEFF" unit="m^-3" ); + parameter real PLWNEFF = 0.0 `P(desc="Coefficient for the length times width dependence of NEFF" unit="m^-3" ); + parameter real POVNSUB = 0 `P(desc="Coefficient for the geometry independent part of VNSUB" unit="V" ); + parameter real PONSLP = 0.05 `P(desc="Coefficient for the geometry independent part of NSLP" unit="V" ); + parameter real PODNSUB = 0 `P(desc="Coefficient for the geometry independent part of DNSUB" unit="V^-1" ); + parameter real PODPHIB = 0 `P(desc="Coefficient for the geometry independent part of DPHIB" unit="V" ); + parameter real PLDPHIB = 0.0 `P(desc="Coefficient for the length dependence of DPHIB" unit="V" ); + parameter real PWDPHIB = 0.0 `P(desc="Coefficient for the width dependence of DPHIB" unit="V" ); + parameter real PLWDPHIB = 0.0 `P(desc="Coefficient for the length times width dependence of DPHIB" unit="V" ); + parameter real PONP = 1E+26 `P(desc="Coefficient for the geometry independent part of NP" unit="m^-3" ); + parameter real PLNP = 0.0 `P(desc="Coefficient for the length dependence of NP" unit="m^-3" ); + parameter real PWNP = 0.0 `P(desc="Coefficient for the width dependence of NP" unit="m^-3" ); + parameter real PLWNP = 0.0 `P(desc="Coefficient for the length times width dependence of NP" unit="m^-3" ); + parameter real POCT = 0 `P(desc="Coefficient for the geometry independent part of CT" unit="" ); + parameter real PLCT = 0.0 `P(desc="Coefficient for the length dependence of CT" unit="" ); + parameter real PWCT = 0.0 `P(desc="Coefficient for the width dependence of CT" unit="" ); + parameter real PLWCT = 0.0 `P(desc="Coefficient for the length times width dependence of CT" unit="" ); + parameter real POTOXOV = 2E-09 `P(desc="Coefficient for the geometry independent part of TOXOV" unit="m" ); + parameter real PONOV = 5E+25 `P(desc="Coefficient for the geometry independent part of NOV" unit="m^-3" ); + parameter real PLNOV = 0.0 `P(desc="Coefficient for the length dependence of NOV" unit="m^-3" ); + parameter real PWNOV = 0.0 `P(desc="Coefficient for the width dependence of NOV" unit="m^-3" ); + parameter real PLWNOV = 0.0 `P(desc="Coefficient for the length times width dependence of NOV" unit="m^-3" ); + + // DIBL parameters + parameter real POCF = 0 `P(desc="Coefficient for the geometry independent part of CF" unit="V^-1" ); + parameter real PLCF = 0.0 `P(desc="Coefficient for the length dependence of CF" unit="V^-1" ); + parameter real PWCF = 0.0 `P(desc="Coefficient for the width dependence of CF" unit="V^-1" ); + parameter real PLWCF = 0.0 `P(desc="Coefficient for the length times width dependence of CF" unit="V^-1" ); + parameter real POCFB = 0 `P(desc="Coefficient for the geometry independent part of CFB" unit="V^-1" ); + + // Mobility parameters + parameter real POBETN = 0.07 `P(desc="Coefficient for the geometry independent part of BETN" unit="m^2/V/s" ); + parameter real PLBETN = 0.0 `P(desc="Coefficient for the length dependence of BETN" unit="m^2/V/s" ); + parameter real PWBETN = 0.0 `P(desc="Coefficient for the width dependence of BETN" unit="m^2/V/s" ); + parameter real PLWBETN = 0.0 `P(desc="Coefficient for the length times width dependence of BETN" unit="m^2/V/s" ); + parameter real POSTBET = 1 `P(desc="Coefficient for the geometry independent part of STBET" unit="" ); + parameter real PLSTBET = 0.0 `P(desc="Coefficient for the length dependence of STBET" unit="" ); + parameter real PWSTBET = 0.0 `P(desc="Coefficient for the width dependence of STBET" unit="" ); + parameter real PLWSTBET = 0.0 `P(desc="Coefficient for the length times width dependence of STBET" unit="" ); + parameter real POMUE = 0.5 `P(desc="Coefficient for the geometry independent part of MUE" unit="m/V" ); + parameter real PLMUE = 0.0 `P(desc="Coefficient for the length dependence of MUE" unit="m/V" ); + parameter real PWMUE = 0.0 `P(desc="Coefficient for the width dependence of MUE" unit="m/V" ); + parameter real PLWMUE = 0.0 `P(desc="Coefficient for the length times width dependence of MUE" unit="m/V" ); + parameter real POSTMUE = 0 `P(desc="Coefficient for the geometry independent part of STMUE" unit="" ); + parameter real POTHEMU = 1.5 `P(desc="Coefficient for the geometry independent part of THEMU" unit="" ); + parameter real POSTTHEMU = 1.5 `P(desc="Coefficient for the geometry independent part of STTHEMU" unit="" ); + parameter real POCS = 0 `P(desc="Coefficient for the geometry independent part of CS" unit="" ); + parameter real PLCS = 0.0 `P(desc="Coefficient for the length dependence of CS" unit="" ); + parameter real PWCS = 0.0 `P(desc="Coefficient for the width dependence of CS" unit="" ); + parameter real PLWCS = 0.0 `P(desc="Coefficient for the length times width dependence of CS" unit="" ); + parameter real POSTCS = 0 `P(desc="Coefficient for the geometry independent part of STCS" unit="" ); + parameter real POXCOR = 0 `P(desc="Coefficient for the geometry independent part of XCOR" unit="V^-1" ); + parameter real PLXCOR = 0.0 `P(desc="Coefficient for the length dependence of XCOR" unit="V^-1" ); + parameter real PWXCOR = 0.0 `P(desc="Coefficient for the width dependence of XCOR" unit="V^-1" ); + parameter real PLWXCOR = 0.0 `P(desc="Coefficient for the length times width dependence of XCOR" unit="V^-1" ); + parameter real POSTXCOR = 0 `P(desc="Coefficient for the geometry independent part of STXCOR" unit="" ); + parameter real POFETA = 1 `P(desc="Coefficient for the geometry independent part of FETA" unit="" ); + + // Series resistance parameters + parameter real PORS = 30 `P(desc="Coefficient for the geometry independent part of RS" unit="Ohm" ); + parameter real PLRS = 0.0 `P(desc="Coefficient for the length dependence of RS" unit="Ohm" ); + parameter real PWRS = 0.0 `P(desc="Coefficient for the width dependence of RS" unit="Ohm" ); + parameter real PLWRS = 0.0 `P(desc="Coefficient for the length times width dependence of RS" unit="Ohm" ); + parameter real POSTRS = 1 `P(desc="Coefficient for the geometry independent part of STRS" unit="" ); + parameter real PORSB = 0 `P(desc="Coefficient for the geometry independent part of RSB" unit="V^-1" ); + parameter real PORSG = 0 `P(desc="Coefficient for the geometry independent part of RSG" unit="V^-1" ); + + // Velocity saturation parameters + parameter real POTHESAT = 1 `P(desc="Coefficient for the geometry independent part of THESAT" unit="V^-1" ); + parameter real PLTHESAT = 0.0 `P(desc="Coefficient for the length dependence of THESAT" unit="V^-1" ); + parameter real PWTHESAT = 0.0 `P(desc="Coefficient for the width dependence of THESAT" unit="V^-1" ); + parameter real PLWTHESAT = 0.0 `P(desc="Coefficient for the length times width dependence of THESAT" unit="V^-1" ); + parameter real POSTTHESAT = 1 `P(desc="Coefficient for the geometry independent part of STTHESAT" unit="" ); + parameter real PLSTTHESAT = 0.0 `P(desc="Coefficient for the length dependence of STTHESAT" unit="" ); + parameter real PWSTTHESAT = 0.0 `P(desc="Coefficient for the width dependence of STTHESAT" unit="" ); + parameter real PLWSTTHESAT = 0.0 `P(desc="Coefficient for the length times width dependence of STTHESAT" unit="" ); + parameter real POTHESATB = 0 `P(desc="Coefficient for the geometry independent part of THESATB" unit="V^-1" ); + parameter real PLTHESATB = 0.0 `P(desc="Coefficient for the length dependence of THESATB" unit="V^-1" ); + parameter real PWTHESATB = 0.0 `P(desc="Coefficient for the width dependence of THESATB" unit="V^-1" ); + parameter real PLWTHESATB = 0.0 `P(desc="Coefficient for the length times width dependence of THESATB" unit="V^-1" ); + parameter real POTHESATG = 0 `P(desc="Coefficient for the geometry independent part of THESATG" unit="V^-1" ); + parameter real PLTHESATG = 0.0 `P(desc="Coefficient for the length dependence of THESATG" unit="V^-1" ); + parameter real PWTHESATG = 0.0 `P(desc="Coefficient for the width dependence of THESATG" unit="V^-1" ); + parameter real PLWTHESATG = 0.0 `P(desc="Coefficient for the length times width dependence of THESATG" unit="V^-1" ); + + // Saturation voltage parameters + parameter real POAX = 3 `P(desc="Coefficient for the geometry independent part of AX" unit="" ); + parameter real PLAX = 0.0 `P(desc="Coefficient for the length dependence of AX" unit="" ); + parameter real PWAX = 0.0 `P(desc="Coefficient for the width dependence of AX" unit="" ); + parameter real PLWAX = 0.0 `P(desc="Coefficient for the length times width dependence of AX" unit="" ); + + // Channel length modulation (CLM) parameters + parameter real POALP = 0.01 `P(desc="Coefficient for the geometry independent part of ALP" unit="" ); + parameter real PLALP = 0.0 `P(desc="Coefficient for the length dependence of ALP" unit="" ); + parameter real PWALP = 0.0 `P(desc="Coefficient for the width dependence of ALP" unit="" ); + parameter real PLWALP = 0.0 `P(desc="Coefficient for the length times width dependence of ALP" unit="" ); + parameter real POALP1 = 0 `P(desc="Coefficient for the geometry independent part of ALP1" unit="V" ); + parameter real PLALP1 = 0.0 `P(desc="Coefficient for the length dependence of ALP1" unit="V" ); + parameter real PWALP1 = 0.0 `P(desc="Coefficient for the width dependence of ALP1" unit="V" ); + parameter real PLWALP1 = 0.0 `P(desc="Coefficient for the length times width dependence of ALP1" unit="V" ); + parameter real POALP2 = 0 `P(desc="Coefficient for the geometry independent part of ALP2" unit="V^-1" ); + parameter real PLALP2 = 0.0 `P(desc="Coefficient for the length dependence of ALP2" unit="V^-1" ); + parameter real PWALP2 = 0.0 `P(desc="Coefficient for the width dependence of ALP2" unit="V^-1" ); + parameter real PLWALP2 = 0.0 `P(desc="Coefficient for the length times width dependence of ALP2" unit="V^-1" ); + parameter real POVP = 0.05 `P(desc="Coefficient for the geometry independent part of VP" unit="V" ); + + // Impact ionization parameters + parameter real POA1 = 1 `P(desc="Coefficient for the geometry independent part of A1" unit="" ); + parameter real PLA1 = 0.0 `P(desc="Coefficient for the length dependence of A1" unit="" ); + parameter real PWA1 = 0.0 `P(desc="Coefficient for the width dependence of A1" unit="" ); + parameter real PLWA1 = 0.0 `P(desc="Coefficient for the length times width dependence of A1" unit="" ); + parameter real POA2 = 10 `P(desc="Coefficient for the geometry independent part of A2" unit="V" ); + parameter real POSTA2 = 0 `P(desc="Coefficient for the geometry independent part of STA2" unit="V" ); + parameter real POA3 = 1 `P(desc="Coefficient for the geometry independent part of A3" unit="" ); + parameter real PLA3 = 0.0 `P(desc="Coefficient for the length dependence of A3" unit="" ); + parameter real PWA3 = 0.0 `P(desc="Coefficient for the width dependence of A3" unit="" ); + parameter real PLWA3 = 0.0 `P(desc="Coefficient for the length times width dependence of A3" unit="" ); + parameter real POA4 = 0 `P(desc="Coefficient for the geometry independent part of A4" unit="V^-0.5" ); + parameter real PLA4 = 0.0 `P(desc="Coefficient for the length dependence of A4" unit="V^-0.5" ); + parameter real PWA4 = 0.0 `P(desc="Coefficient for the width dependence of A4" unit="V^-0.5" ); + parameter real PLWA4 = 0.0 `P(desc="Coefficient for the length times width dependence of A4" unit="V^-0.5" ); + parameter real POGCO = 0 `P(desc="Coefficient for the geometry independent part of GCO" unit="" ); + + // Gate current parameters + parameter real POIGINV = 0 `P(desc="Coefficient for the geometry independent part of IGINV" unit="A" ); + parameter real PLIGINV = 0.0 `P(desc="Coefficient for the length dependence of IGINV" unit="A" ); + parameter real PWIGINV = 0.0 `P(desc="Coefficient for the width dependence of IGINV" unit="A" ); + parameter real PLWIGINV = 0.0 `P(desc="Coefficient for the length times width dependence of IGINV" unit="A" ); + parameter real POIGOV = 0 `P(desc="Coefficient for the geometry independent part of IGOV" unit="A" ); + parameter real PLIGOV = 0.0 `P(desc="Coefficient for the length dependence of IGOV" unit="A" ); + parameter real PWIGOV = 0.0 `P(desc="Coefficient for the width dependence of IGOV" unit="A" ); + parameter real PLWIGOV = 0.0 `P(desc="Coefficient for the length times width dependence of IGOV" unit="A" ); + parameter real POSTIG = 2 `P(desc="Coefficient for the geometry independent part of STIG" unit="" ); + parameter real POGC2 = 0.375 `P(desc="Coefficient for the geometry independent part of GC2" unit="" ); + parameter real POGC3 = 0.063 `P(desc="Coefficient for the geometry independent part of GC3" unit="" ); + parameter real POCHIB = 3.1 `P(desc="Coefficient for the geometry independent part of CHIB" unit="V" ); + + // Gate-induced drain leakage (GIDL) parameters + parameter real POAGIDL = 0 `P(desc="Coefficient for the geometry independent part of AGIDL" unit="A/V^3" ); + parameter real PLAGIDL = 0.0 `P(desc="Coefficient for the length dependence of AGIDL" unit="A/V^3" ); + parameter real PWAGIDL = 0.0 `P(desc="Coefficient for the width dependence of AGIDL" unit="A/V^3" ); + parameter real PLWAGIDL = 0.0 `P(desc="Coefficient for the length times width dependence of AGIDL" unit="A/V^3" ); + parameter real POBGIDL = 41 `P(desc="Coefficient for the geometry independent part of BGIDL" unit="V" ); + parameter real POSTBGIDL = 0 `P(desc="Coefficient for the geometry independent part of STBGIDL" unit="V/K" ); + parameter real POCGIDL = 0 `P(desc="Coefficient for the geometry independent part of CGIDL" unit="" ); + + // Charge model parameters + parameter real POCOX = 1E-14 `P(desc="Coefficient for the geometry independent part of COX" unit="F" ); + parameter real PLCOX = 0.0 `P(desc="Coefficient for the length dependence of COX" unit="F" ); + parameter real PWCOX = 0.0 `P(desc="Coefficient for the width dependence of COX" unit="F" ); + parameter real PLWCOX = 0.0 `P(desc="Coefficient for the length times width dependence of COX" unit="F" ); + parameter real POCGOV = 1E-15 `P(desc="Coefficient for the geometry independent part of CGOV" unit="F" ); + parameter real PLCGOV = 0.0 `P(desc="Coefficient for the length dependence of CGOV" unit="F" ); + parameter real PWCGOV = 0.0 `P(desc="Coefficient for the width dependence of CGOV" unit="F" ); + parameter real PLWCGOV = 0.0 `P(desc="Coefficient for the length times width dependence of CGOV" unit="F" ); + parameter real POCGBOV = 0 `P(desc="Coefficient for the geometry independent part of CGBOV" unit="F" ); + parameter real PLCGBOV = 0.0 `P(desc="Coefficient for the length dependence of CGBOV" unit="F" ); + parameter real PWCGBOV = 0.0 `P(desc="Coefficient for the width dependence of CGBOV" unit="F" ); + parameter real PLWCGBOV = 0.0 `P(desc="Coefficient for the length times width dependence of CGBOV" unit="F" ); + parameter real POCFR = 0 `P(desc="Coefficient for the geometry independent part of CFR" unit="F" ); + parameter real PLCFR = 0.0 `P(desc="Coefficient for the length dependence of CFR" unit="F" ); + parameter real PWCFR = 0.0 `P(desc="Coefficient for the width dependence of CFR" unit="F" ); + parameter real PLWCFR = 0.0 `P(desc="Coefficient for the length times width dependence of CFR" unit="F" ); + + // Noise model parameters + parameter real POFNT = 1 `P(desc="Coefficient for the geometry independent part of FNT" unit="" ); + parameter real PONFA = 8E+22 `P(desc="Coefficient for the geometry independent part of NFA" unit="V^-1/m^4" ); + parameter real PLNFA = 0.0 `P(desc="Coefficient for the length dependence of NFA" unit="V^-1/m^4" ); + parameter real PWNFA = 0.0 `P(desc="Coefficient for the width dependence of NFA" unit="V^-1/m^4" ); + parameter real PLWNFA = 0.0 `P(desc="Coefficient for the length times width dependence of NFA" unit="V^-1/m^4" ); + parameter real PONFB = 3E+07 `P(desc="Coefficient for the geometry independent part of NFB" unit="V^-1/m^2" ); + parameter real PLNFB = 0.0 `P(desc="Coefficient for the length dependence of NFB" unit="V^-1/m^2" ); + parameter real PWNFB = 0.0 `P(desc="Coefficient for the width dependence of NFB" unit="V^-1/m^2" ); + parameter real PLWNFB = 0.0 `P(desc="Coefficient for the length times width dependence of NFB" unit="V^-1/m^2" ); + parameter real PONFC = 0 `P(desc="Coefficient for the geometry independent part of NFC" unit="V^-1" ); + parameter real PLNFC = 0.0 `P(desc="Coefficient for the length dependence of NFC" unit="V^-1" ); + parameter real PWNFC = 0.0 `P(desc="Coefficient for the width dependence of NFC" unit="V^-1" ); + parameter real PLWNFC = 0.0 `P(desc="Coefficient for the length times width dependence of NFC" unit="V^-1" ); + + // Other parameters + parameter real DTA = 0 `P(desc="Temperature offset w.r.t. ambient temperature" unit="K" ); diff --git a/src/spicelib/devices/adms/psp102/admsva/PSP102_macrodefs.include b/src/spicelib/devices/adms/psp102/admsva/PSP102_macrodefs.include new file mode 100644 index 000000000..f9e443db7 --- /dev/null +++ b/src/spicelib/devices/adms/psp102/admsva/PSP102_macrodefs.include @@ -0,0 +1,250 @@ +//====================================================================================== +//====================================================================================== +// Filename: PSP102_macrodefs.include +//====================================================================================== +//====================================================================================== +// +// (c) Copyright 2007, All Rights Reserved, NXP Semiconductors +// +// +// Version: 102.1, April 2007 (Simkit 2.5) +// +//====================================================================================== +//====================================================================================== +// +// Further information can be found in the file readme.txt +// + + +///////////////////////////////////////////// +// +// Macros and constants used in PSP +// +///////////////////////////////////////////// + +// Explicit Gmin +`define GMIN 1E-15 + +`define PMOS -1 +`define NMOS +1 + +// Some functions +`define MINA(x,y,a) 0.5*((x)+(y)-sqrt(((x)-(y))*((x)-(y))+(a))) +`define MAXA(x,y,a) 0.5*((x)+(y)+sqrt(((x)-(y))*((x)-(y))+(a))) + +// Physical constants +`define EPSOX 3.453E-11 +`define QMN 5.951993 +`define QMP 7.448711 + +// Other constants (PSP-mos) +`define DELTA1 0.02 +`define invSqrt2 7.0710678118654746e-01 +`define oneSixth 1.6666666666666667e-01 +`define exp80 5.5406223843935098e+34 +`define exp160 3.0698496406442424e+69 + +`ifdef NQSmodel + `define Gint GP + `define Bint BP + `define Bjs BS + `define Bjd BD +`else // NQSmodel + `define Gint G + `define Bint B + `define Bjs B + `define Bjd B +`endif // NQSModel + +///////////////////////////////////////////////////////////////////////////// +// +// Macro definitions. +// +// Note that because at present locally scoped variables +// can only be in named blocks, the intermediate variables +// used in the macros below must be explicitly declared +// as variables in the main code. +// +///////////////////////////////////////////////////////////////////////////// + + +// sigma function used in surface potential and other calculations +// (one call uses expressions for arguments so parentheses +// around the arguments in the expressions are necessary) +`define sigma(a,c,tau,eta,y) \ +nu = (a) + (c); \ +mu = nu * nu / (tau) + 0.5 * ((c) * (c)) - (a); \ +y = (eta) + (a) * nu / (mu + (nu / mu) * (c) * ((c) * (c) * `oneThird - (a))); + + +// modified version of sigma, which takes 4 arguments +`define sigma2(a,b,c,tau,eta,y) \ +nu = (a) + (c); \ +if (abs(tau) < 1e-120) begin /*sometimes tau is extremely small...*/\ + y = (eta); \ +end else begin \ + mu = (nu) * (nu) / (tau) + 0.5 * ((c) * (c)) - (a) * (b); \ + y = (eta) + (a) * nu / (mu + (nu / mu) * (c) * ((c) * (c) * `oneThird - (a) * (b))); \ +end + +// +// sp_s surface potential calculation +// +`define sp_s(sp,xg,xn,delta) \ +if (abs(xg) <= margin) begin \ + SP_S_temp1 = inv_xi * inv_xi * `oneSixth * `invSqrt2; \ + sp = xg * inv_xi * (1.0 + xg * (1.0 - (delta)) * Gf * SP_S_temp1); \ +end else begin \ + if (xg < -margin) begin \ + SP_S_yg = -xg; \ + SP_S_ysub = 1.25 * (SP_S_yg * inv_xi); \ + SP_S_eta = 0.5 * (SP_S_ysub + 10 - sqrt((SP_S_ysub - 6.0) * (SP_S_ysub - 6.0) + 64.0)); \ + SP_S_temp = SP_S_yg - SP_S_eta; \ + SP_S_a = SP_S_temp * SP_S_temp + Gf2*(SP_S_eta + 1.0);\ + SP_S_c = 2.0 * SP_S_temp - Gf2; \ + SP_S_tau = -SP_S_eta + ln(SP_S_a * inv_Gf2); \ + `sigma(SP_S_a, SP_S_c, SP_S_tau, SP_S_eta, SP_S_y0) \ + `expl_high(SP_S_y0, SP_S_delta0) \ + SP_S_delta1 = 1.0 / SP_S_delta0; \ + SP_S_temp = 1.0 / (2.0 + SP_S_y0 * SP_S_y0); \ + SP_S_xi0 = SP_S_y0 * SP_S_y0 * SP_S_temp; \ + SP_S_xi1 = 4.0 * (SP_S_y0 * SP_S_temp * SP_S_temp); \ + SP_S_xi2 = (8.0 * SP_S_temp - 12.0 * SP_S_xi0) * SP_S_temp * SP_S_temp; \ + SP_S_temp = SP_S_yg - SP_S_y0; \ + SP_S_temp1 = (delta) * SP_S_delta1; \ + SP_S_pC = 2.0 * SP_S_temp + Gf2 * (SP_S_delta0 - 1.0 - SP_S_temp1 + (delta) * (1.0 - SP_S_xi1)); \ + SP_S_qC = SP_S_temp * SP_S_temp - Gf2 * (SP_S_delta0 - SP_S_y0 - 1.0 + SP_S_temp1 + (delta) * (SP_S_y0 - 1.0 - SP_S_xi0)); \ + SP_S_temp = 2.0 - Gf2 * (SP_S_delta0 + SP_S_temp1 - (delta) * SP_S_xi2); \ + SP_S_temp = SP_S_pC * SP_S_pC - 2.0 * (SP_S_qC * SP_S_temp); \ + sp = -SP_S_y0 - 2.0 * (SP_S_qC / (SP_S_pC + sqrt(SP_S_temp))); \ + end else begin \ + SP_xg1 = 1.0 / (x1 + Gf * 7.324648775608221e-001); \ + SP_S_A_fac= (xi * x1 * SP_xg1 - 1.0) * SP_xg1; \ + SP_S_xbar = xg * inv_xi * (1.0 + SP_S_A_fac * xg); \ + `expl_low(-SP_S_xbar, SP_S_temp) \ + SP_S_w = 1.0 - SP_S_temp; \ + SP_S_x1 = xg + Gf2 * 0.5 - Gf * sqrt(xg + Gf2 * 0.25 - SP_S_w); \ + SP_S_bx = (xn) + 3.0; \ + SP_S_eta = `MINA(SP_S_x1, SP_S_bx, 5.0) - 0.5 * (SP_S_bx - sqrt(SP_S_bx * SP_S_bx + 5.0)); \ + SP_S_temp = xg - SP_S_eta; \ + SP_S_temp1= exp(-SP_S_eta); \ + SP_S_temp2= 1.0 / (2.0 + SP_S_eta * SP_S_eta); \ + SP_S_xi0 = SP_S_eta * SP_S_eta * SP_S_temp2; \ + SP_S_xi1 = 4.0 * (SP_S_eta * SP_S_temp2 * SP_S_temp2); \ + SP_S_xi2 = (8.0 * SP_S_temp2 - 12.0 * SP_S_xi0) * SP_S_temp2 * SP_S_temp2; \ + SP_S_a = max(1.0e-40, SP_S_temp * SP_S_temp - Gf2 * (SP_S_temp1 + SP_S_eta - 1.0 - (delta) * (SP_S_eta + 1.0 + SP_S_xi0))); \ + SP_S_b = 1.0 - 0.5 * (Gf2 * (SP_S_temp1 - (delta) * SP_S_xi2)); \ + SP_S_c = 2.0 * SP_S_temp + Gf2 * (1.0 - SP_S_temp1 - (delta) * (1.0 + SP_S_xi1)); \ + SP_S_tau = (xn) - SP_S_eta + ln(SP_S_a / Gf2); \ + `sigma2(SP_S_a, SP_S_b, SP_S_c, SP_S_tau, SP_S_eta, SP_S_x0) \ + if (SP_S_x0 < `se05) begin \ + SP_S_delta0 = exp(SP_S_x0); \ + SP_S_delta1 = 1.0 / SP_S_delta0; \ + SP_S_delta0 = (delta) * SP_S_delta0; \ + end else begin \ + if (SP_S_x0 > (xn) - `se05) begin \ + SP_S_delta0 = exp(SP_S_x0 - (xn)); \ + SP_S_delta1 = (delta) / SP_S_delta0; \ + end else begin \ + SP_S_delta0 = `ke05 / `P3((xn) - SP_S_x0 - `se05); \ + SP_S_delta1 = `ke05 / `P3(SP_S_x0 - `se05); \ + end \ + end \ + SP_S_temp = 1.0 / (2.0 + SP_S_x0 * SP_S_x0); \ + SP_S_xi0 = SP_S_x0 * SP_S_x0 * SP_S_temp; \ + SP_S_xi1 = 4.0 * (SP_S_x0 * SP_S_temp * SP_S_temp); \ + SP_S_xi2 = (8.0 * SP_S_temp - 12.0 * SP_S_xi0) * SP_S_temp * SP_S_temp; \ + SP_S_temp = xg - SP_S_x0; \ + SP_S_pC = 2.0 * SP_S_temp + Gf2 * (1.0 - SP_S_delta1 + SP_S_delta0 - (delta) * (1.0 + SP_S_xi1)); \ + SP_S_qC = SP_S_temp * SP_S_temp - Gf2 * (SP_S_delta1 + SP_S_x0 - 1.0 + SP_S_delta0 - (delta) * (SP_S_x0 + 1.0 + SP_S_xi0)); \ + SP_S_temp = 2.0 - Gf2 * (SP_S_delta1 + SP_S_delta0 - (delta) * SP_S_xi2); \ + SP_S_temp = SP_S_pC * SP_S_pC - 2.0 * (SP_S_qC * SP_S_temp); \ + sp = SP_S_x0 + 2.0 * (SP_S_qC / (SP_S_pC + sqrt(SP_S_temp))); \ + end \ +end + +// +// sp_s_d surface potential calculation at drain (subset of function sp_s) +// +`define sp_s_d(sp,xg,xn,delta) \ +if (abs(xg) <= margin) begin \ + SP_S_temp1 = inv_xi * inv_xi * `oneSixth * `invSqrt2; \ + sp = xg * inv_xi * (1.0 + xg * (1.0 - (delta)) * Gf * SP_S_temp1); \ +end else begin \ + SP_S_bx = (xn) + 3; \ + SP_S_eta = `MINA(SP_S_x1, SP_S_bx, 5.0) - 0.5 * (SP_S_bx - sqrt(SP_S_bx * SP_S_bx + 5.0)); \ + SP_S_temp = xg - SP_S_eta; \ + SP_S_temp1= exp(-SP_S_eta); \ + SP_S_temp2= 1.0 / (2.0 + SP_S_eta * SP_S_eta); \ + SP_S_xi0 = SP_S_eta * SP_S_eta * SP_S_temp2; \ + SP_S_xi1 = 4.0 * (SP_S_eta * SP_S_temp2 * SP_S_temp2); \ + SP_S_xi2 = (8.0 * SP_S_temp2 - 12.0 * SP_S_xi0) * SP_S_temp2 * SP_S_temp2; \ + SP_S_a = max(1.0e-40, SP_S_temp * SP_S_temp - Gf2 * (SP_S_temp1 + SP_S_eta - 1.0 - (delta) * (SP_S_eta + 1.0 + SP_S_xi0))); \ + SP_S_b = 1.0 - 0.5 * (Gf2 * (SP_S_temp1 - (delta) * SP_S_xi2)); \ + SP_S_c = 2.0 * SP_S_temp + Gf2 * (1.0 - SP_S_temp1 - (delta) * (1.0 + SP_S_xi1)); \ + SP_S_tau = (xn) - SP_S_eta + ln(SP_S_a / Gf2); \ + `sigma2(SP_S_a, SP_S_b, SP_S_c, SP_S_tau, SP_S_eta, SP_S_x0) \ + if (SP_S_x0 < `se05) begin \ + SP_S_delta0 = exp(SP_S_x0); \ + SP_S_delta1 = 1.0 / SP_S_delta0; \ + SP_S_delta0 = (delta) * SP_S_delta0; \ + end else begin \ + if (SP_S_x0 > (xn) - `se05) begin \ + SP_S_delta0 = exp(SP_S_x0 - (xn)); \ + SP_S_delta1 = (delta) / SP_S_delta0; \ + end else begin \ + SP_S_delta0 = `ke05 / `P3((xn) - SP_S_x0 - `se05); \ + SP_S_delta1 = `ke05 / `P3(SP_S_x0 - `se05); \ + end \ + end \ + SP_S_temp = 1.0 / (2.0 + SP_S_x0 * SP_S_x0); \ + SP_S_xi0 = SP_S_x0 * SP_S_x0 * SP_S_temp; \ + SP_S_xi1 = 4.0 * (SP_S_x0 * SP_S_temp * SP_S_temp); \ + SP_S_xi2 = (8.0 * SP_S_temp-12.0 * SP_S_xi0) * SP_S_temp * SP_S_temp; \ + SP_S_temp = xg - SP_S_x0; \ + SP_S_pC = 2.0 * SP_S_temp + Gf2 * (1.0 - SP_S_delta1 + SP_S_delta0 - (delta) * (1.0 + SP_S_xi1)); \ + SP_S_qC = SP_S_temp * SP_S_temp - Gf2 * (SP_S_delta1 + SP_S_x0 - 1.0 + SP_S_delta0 - (delta) * (SP_S_x0 + 1.0 + SP_S_xi0)); \ + SP_S_temp = 2.0 - Gf2*(SP_S_delta1+SP_S_delta0-(delta)*SP_S_xi2); \ + SP_S_temp = SP_S_pC * SP_S_pC - 2.0 * (SP_S_qC * SP_S_temp); \ + sp = SP_S_x0 + 2.0 * (SP_S_qC / (SP_S_pC + sqrt(SP_S_temp)));\ +end + +// +// sp_ov surface potential calculation for the overlap regions +// +`define sp_ov(sp,xg) \ +if (abs(xg) <= x_mrg_ov) begin \ + sp = (-(xg) * inv_xi_ov); \ +end else begin \ + if (xg < -x_mrg_ov) begin \ + SP_OV_yg = -xg; \ + SP_OV_z = x1 * SP_OV_yg * inv_xi_ov; \ + SP_OV_eta = 0.5 * (SP_OV_z + 10.0 - sqrt((SP_OV_z - 6.0) * (SP_OV_z - 6.0) + 64.0)); \ + SP_OV_a = (SP_OV_yg - SP_OV_eta) * (SP_OV_yg - SP_OV_eta) + GOV2 * (SP_OV_eta + 1.0); \ + SP_OV_c = 2.0 * (SP_OV_yg - SP_OV_eta) - GOV2; \ + SP_OV_tau = ln(SP_OV_a / GOV2) - SP_OV_eta; \ + `sigma(SP_OV_a, SP_OV_c, SP_OV_tau, SP_OV_eta, SP_OV_y0) \ + SP_OV_D0 = exp(SP_OV_y0); \ + SP_OV_temp = SP_OV_yg - SP_OV_y0; \ + SP_OV_p = 2.0 * SP_OV_temp + GOV2 * (SP_OV_D0 - 1.0); \ + SP_OV_q = SP_OV_temp * SP_OV_temp + GOV2 * (SP_OV_y0 + 1.0 - SP_OV_D0); \ + SP_OV_xi = 1.0 - GOV2 * 0.5 * SP_OV_D0; \ + SP_OV_temp = SP_OV_p * SP_OV_p - 4.0 * (SP_OV_xi * SP_OV_q); \ + SP_OV_w = 2.0 * (SP_OV_q / (SP_OV_p + sqrt(SP_OV_temp))); \ + sp = -(SP_OV_y0 + SP_OV_w); \ + end else begin \ + SP_OV_Afac = (xi_ov * x1 * inv_xg1 - 1.0) * inv_xg1; \ + SP_OV_xbar = xg * inv_xi_ov * (1.0 + SP_OV_Afac * xg); \ + `expl_low(-SP_OV_xbar, SP_OV_temp) \ + SP_OV_w = 1.0 - SP_OV_temp; \ + SP_OV_x0 = xg + GOV2 * 0.5 - GOV * sqrt(xg + GOV2 * 0.25 - SP_OV_w); \ + `expl_low(-SP_OV_x0, SP_OV_D0) \ + SP_OV_p = 2.0 * (xg - SP_OV_x0) + GOV2 * (1 - SP_OV_D0); \ + SP_OV_q = (xg - SP_OV_x0) * (xg - SP_OV_x0) - GOV2 * (SP_OV_x0 - 1.0 + SP_OV_D0); \ + SP_OV_xi = 1.0 - GOV2 * 0.5 * SP_OV_D0; \ + SP_OV_temp = SP_OV_p * SP_OV_p - 4.0 * (SP_OV_xi * SP_OV_q); \ + SP_OV_u = 2.0 * (SP_OV_q / (SP_OV_p + sqrt(SP_OV_temp))); \ + sp = SP_OV_x0 + SP_OV_u; \ + end \ + sp = -sp; \ +end diff --git a/src/spicelib/devices/adms/psp102/admsva/PSP102_module.include b/src/spicelib/devices/adms/psp102/admsva/PSP102_module.include new file mode 100644 index 000000000..638316c24 --- /dev/null +++ b/src/spicelib/devices/adms/psp102/admsva/PSP102_module.include @@ -0,0 +1,2359 @@ +`undef P +`define P(txt) (*txt*) +//====================================================================================== +//====================================================================================== +// Filename: PSP102_module.include +//====================================================================================== +//====================================================================================== +// +// (c) Copyright 2007, All Rights Reserved, NXP Semiconductors +// +// +// Version: 102.1, April 2007 (Simkit 2.5) +// +//====================================================================================== +//====================================================================================== +// +// Further information can be found in the file readme.txt +// + + // Node definitions + inout D, G, S, B; + electrical D; + electrical G; + electrical S; + electrical B; + + // Extra internal nodes for correlated drain and gate noise + electrical NOI; + electrical NOI2; + + // Extra branches for correlated drain and gate noise + branch (NOI) NOII; + branch (NOI) NOIR; + branch (NOI) NOIC; + +`ifdef NQSmodel + // Internal nodes for gate and bulk resistors + electrical GP; + electrical BP; + electrical BI; + electrical BS; + electrical BD; + + // Internal nodes for spline collocation + electrical INT1; + electrical INT2; + electrical INT3; + electrical INT4; + electrical INT5; + electrical INT6; + electrical INT7; + electrical INT8; + electrical INT9; + + branch(INT1) SPLINE1; + branch(INT2) SPLINE2; + branch(INT3) SPLINE3; + branch(INT4) SPLINE4; + branch(INT5) SPLINE5; + branch(INT6) SPLINE6; + branch(INT7) SPLINE7; + branch(INT8) SPLINE8; + branch(INT9) SPLINE9; + + branch(INT1) RES1; + branch(INT2) RES2; + branch(INT3) RES3; + branch(INT4) RES4; + branch(INT5) RES5; + branch(INT6) RES6; + branch(INT7) RES7; + branch(INT8) RES8; + branch(INT9) RES9; + +`endif // NQSmodel + + ////////////////////////// + // + // Model parameters + // + ////////////////////////// + +`ifdef LocalModel + /////////////////////////////////////////////////// + // PSP local model parameters + /////////////////////////////////////////////////// + + // Special model parameters, some are also simulator global variables + parameter real LEVEL = 102 `P(desc="Model level" unit="" ); + parameter real TYPE = 1.0 `from( -1.0,1.0 ) `P(desc="Channel type parameter, +1=NMOS -1=PMOS" unit="" ); + parameter real TR = 21.0 `from( -273.0,inf ) `P(desc="nominal (reference) temperature" unit="C" ); + + // Switch parameters that turn models or effects on or off + parameter real SWIGATE = 0.0 `from( 0.0,1.0 ) `P(desc="Flag for gate current, 0=turn off IG" unit="" ); + parameter real SWIMPACT = 0.0 `from( 0.0,1.0 ) `P(desc="Flag for impact ionization current, 0=turn off II" unit="" ); + parameter real SWGIDL = 0.0 `from( 0.0,1.0 ) `P(desc="Flag for GIDL current, 0=turn off IGIDL" unit="" ); + parameter real SWJUNCAP = 0.0 `from( 0.0,3.0 ) `P(desc="Flag for juncap, 0=turn off juncap" unit="" ); + parameter real QMC = 1.0 `from( 0.0,inf ) `P(desc="Quantum-mechanical correction factor" unit="" ); + + // Process parameters + parameter real VFB = -1.0 `P(desc="Flatband voltage at TR" unit="V" ); + parameter real STVFB = 5.0e-4 `P(desc="Temperature dependence of VFB" unit="V/K" ); + parameter real TOX = 2.0e-09 `from( 1e-10,inf ) `P(desc="Gate oxide thickness" unit="m" ); + parameter real NEFF = 5.0e+23 `from( 1e20,1e26 ) `P(desc="Effective substrate doping" unit="m^-3" ); + parameter real VNSUB = 0.0 `P(desc="Effective doping bias-dependence parameter" unit="V" ); + parameter real NSLP = 0.05 `from( 1e-3,inf ) `P(desc="Effective doping bias-dependence parameter" unit="V" ); + parameter real DNSUB = 0.0 `from( 0.0,1.0 ) `P(desc="Effective doping bias-dependence parameter" unit="V^-1" ); + parameter real DPHIB = 0.0 `P(desc="Offset parameter for PHIB" unit="V" ); + parameter real NP = 1.0e+26 `from( 0.0,inf ) `P(desc="Gate poly-silicon doping" unit="m^-3" ); + parameter real CT = 0.0 `from( 0.0,inf ) `P(desc="Interface states factor" unit="" ); + parameter real TOXOV = 2.0e-09 `from( 1e-10,inf ) `P(desc="Overlap oxide thickness" unit="m" ); + parameter real NOV = 5.0e+25 `from( 1e20,1e27 ) `P(desc="Effective doping of overlap region" unit="m^-3" ); + + // DIBL parameters + parameter real CF = 0.0 `from( 0.0,inf ) `P(desc="DIBL-parameter" unit="V^-1" ); + parameter real CFB = 0.0 `from( 0.0,1.0 ) `P(desc="Back bias dependence of CF" unit="V^-1" ); + + // Mobility parameters + parameter real BETN = 7e-2 `from( 0.0,inf ) `P(desc="Channel aspect ratio times zero-field mobility" unit="m^2/V/s" ); + parameter real STBET = 1.0 `P(desc="Temperature dependence of BETN" unit="" ); + parameter real MUE = 0.5 `from( 0.0,inf ) `P(desc="Mobility reduction coefficient at TR" unit="m/V" ); + parameter real STMUE = 0.0 `P(desc="Temperature dependence of MUE" unit="" ); + parameter real THEMU = 1.5 `from( 0.0,inf ) `P(desc="Mobility reduction exponent at TR" unit="" ); + parameter real STTHEMU = 1.5 `P(desc="Temperature dependence of THEMU" unit="" ); + parameter real CS = 0.0 `from( 0.0,inf ) `P(desc="Coulomb scattering parameter at TR" unit="" ); + parameter real STCS = 0.0 `P(desc="Temperature dependence of CS" unit="" ); + parameter real XCOR = 0.0 `from( 0.0,inf ) `P(desc="Non-universality factor" unit="V^-1" ); + parameter real STXCOR = 0.0 `P(desc="Temperature dependence of XCOR" unit="" ); + parameter real FETA = 1.0 `from( 0.0,inf ) `P(desc="Effective field parameter" unit="" ); + + // Series-resistance parameters (for resistance modeling as part of intrinsic mobility reduction) + parameter real RS = 30 `from( 0.0,inf ) `P(desc="Series resistance at TR" unit="Ohm" ); + parameter real STRS = 1.0 `P(desc="Temperature dependence of RS" unit="" ); + parameter real RSB = 0.0 `from( -0.5,1.0 ) `P(desc="Back-bias dependence of series resistance" unit="V^-1" ); + parameter real RSG = 0.0 `from( -0.5,inf ) `P(desc="Gate-bias dependence of series resistance" unit="V^-1" ); + + // Velocity saturation parameters + parameter real THESAT = 1.0 `from( 0.0,inf ) `P(desc="Velocity saturation parameter at TR" unit="V^-1" ); + parameter real STTHESAT = 1.0 `P(desc="Temperature dependence of THESAT" unit="" ); + parameter real THESATB = 0.0 `from( -0.5,1.0 ) `P(desc="Back-bias dependence of velocity saturation" unit="V^-1" ); + parameter real THESATG = 0.0 `from( -0.5,inf ) `P(desc="Gate-bias dependence of velocity saturation" unit="V^-1" ); + + // Saturation voltage parameters + parameter real AX = 3.0 `from( 2.0,inf ) `P(desc="Linear/saturation transition factor" unit="" ); + + // Channel length modulation (CLM) parameters + parameter real ALP = 0.01 `from( 0.0,inf ) `P(desc="CLM pre-factor" unit="" ); + parameter real ALP1 = 0.00 `from( 0.0,inf ) `P(desc="CLM enhancement factor above threshold" unit="V" ); + parameter real ALP2 = 0.00 `from( 0.0,inf ) `P(desc="CLM enhancement factor below threshold" unit="V^-1" ); + parameter real VP = 0.05 `from( 1e-10,inf ) `P(desc="CLM logarithm dependence factor" unit="V" ); + + // Impact ionization (II) parameters + parameter real A1 = 1.0 `from( 0.0,inf ) `P(desc="Impact-ionization pre-factor" unit="" ); + parameter real A2 = 10.0 `from( 0.0,inf ) `P(desc="Impact-ionization exponent at TR" unit="V" ); + parameter real STA2 = 0.0 `P(desc="Temperature dependence of A2" unit="V" ); + parameter real A3 = 1.0 `from( 0.0,inf ) `P(desc="Saturation-voltage dependence of impact-ionization" unit="" ); + parameter real A4 = 0.0 `from( 0.0,inf ) `P(desc="Back-bias dependence of impact-ionization" unit="V^-0.5" ); + + // Gate current parameters + parameter real GCO = 0.0 `from( -10.0,10.0 ) `P(desc="Gate tunnelling energy adjustment" unit="" ); + parameter real IGINV = 0.0 `from( 0.0,inf ) `P(desc="Gate channel current pre-factor" unit="A" ); + parameter real IGOV = 0.0 `from( 0.0,inf ) `P(desc="Gate overlap current pre-factor" unit="A" ); + parameter real STIG = 2.0 `P(desc="Temperature dependence of IGINV and IGOV" unit="" ); + parameter real GC2 = 0.375 `from( 0.0,10.0 ) `P(desc="Gate current slope factor" unit="" ); + parameter real GC3 = 0.063 `from( -2.0,2.0 ) `P(desc="Gate current curvature factor" unit="" ); + parameter real CHIB = 3.1 `from( 1.0,inf ) `P(desc="Tunnelling barrier height" unit="V" ); + + // Gate Induced Drain/Source Leakage (GIDL) parameters + parameter real AGIDL = 0.0 `from( 0.0,inf ) `P(desc="GIDL pre-factor" unit="A/V^3" ); + parameter real BGIDL = 41.0 `from( 0.0,inf ) `P(desc="GIDL probability factor at TR" unit="V" ); + parameter real STBGIDL = 0.0 `P(desc="Temperature dependence of BGIDL" unit="V/K" ); + parameter real CGIDL = 0.0 `P(desc="Back-bias dependence of GIDL" unit="" ); + + // Charge model parameters + parameter real COX = 1.0e-14 `from( 0.0,inf ) `P(desc="Oxide capacitance for intrinsic channel" unit="F" ); + parameter real CGOV = 1.0e-15 `from( 0.0,inf ) `P(desc="Oxide capacitance for gate-drain/source overlap" unit="F" ); + parameter real CGBOV = 0.0 `from( 0.0,inf ) `P(desc="Oxide capacitance for gate-bulk overlap" unit="F" ); + parameter real CFR = 0.0 `from( 0.0,inf ) `P(desc="Outer fringe capacitance" unit="F" ); + + // Noise parameters + parameter real FNT = 1.0 `from( 0.0,inf ) `P(desc="Thermal noise coefficient" unit="" ); + parameter real NFA = 8.0e+22 `from( 0.0,inf ) `P(desc="First coefficient of flicker noise" unit="V^-1/m^4" ); + parameter real NFB = 3.0e+07 `from( 0.0,inf ) `P(desc="Second coefficient of flicker noise" unit="V^-1/m^2" ); + parameter real NFC = 0.0 `from( 0.0,inf ) `P(desc="Third coefficient of flicker noise" unit="V^-1" ); +`ifdef NQSmodel + + // NQS parameters + parameter real SWNQS = 0.0 `from( 0.0,9.0 ) `P(desc="Flag for NQS, 0=off, 1, 2, 3, 5, or 9=number of collocation points" unit="" ); + parameter real MUNQS = 1.0 `from( 0.0,inf ) `P(desc="Relative mobility for NQS modelling" ); + parameter real RG = 1.0e-3 `from( 1.0e-6,inf ) `P(desc="Gate resistance" unit="Ohm" ); + parameter real RBULK = 1.0e-3 `from( 1.0e-6,inf ) `P(desc="Bulk resistance between node BP and BI" unit="Ohm" ); + parameter real RWELL = 1.0e-3 `from( 1.0e-6,inf ) `P(desc="Well resistance between node BI and B" unit="Ohm" ); + parameter real RJUNS = 1.0e-3 `from( 1.0e-6,inf ) `P(desc="Source-side bulk resistance between node BI and BS" unit="Ohm" ); + parameter real RJUND = 1.0e-3 `from( 1.0e-6,inf ) `P(desc="Drain-side bulk resistance between node BI and BD" unit="Ohm" ); +`endif // NQSmodel + + // JUNCAP Parameters + parameter real TRJ = 21 `from(`TRJ_cliplow,inf) `P(desc="reference temperature" unit="C" ); + `include "JUNCAP200_parlist.include" + + // Other parameters + parameter real DTA = 0.0 `P(desc="Temperature offset w.r.t. ambient temperature" unit="K" ); + + // Instance parameters + parameter real ABSOURCE = 1e-12 `from(`AB_cliplow,inf) `P(type="instance" desc="Bottom area of source junction" unit="m^2" ); + parameter real LSSOURCE = 1e-6 `from(`LS_cliplow,inf) `P(type="instance" desc="STI-edge length of source junction" unit="m" ); + parameter real LGSOURCE = 1e-6 `from(`LG_cliplow,inf) `P(type="instance" desc="Gate-edge length of source junction" unit="m" ); + parameter real ABDRAIN = 1e-12 `from(`AB_cliplow,inf) `P(type="instance" desc="Bottom area of drain junction" unit="m^2" ); + parameter real LSDRAIN = 1e-6 `from(`LS_cliplow,inf) `P(type="instance" desc="STI-edge length of drain junction" unit="m" ); + parameter real LGDRAIN = 1e-6 `from(`LG_cliplow,inf) `P(type="instance" desc="Gate-edge length of drain junction" unit="m" ); + parameter real AS = 1E-12 `from(`AB_cliplow,inf) `P(type="instance" desc="Bottom area of source junction" unit="m^2" ); + parameter real PS = 1E-6 `from(`LS_cliplow,inf) `P(type="instance" desc="Perimeter of source junction" unit="m" ); + parameter real AD = 1E-12 `from(`AB_cliplow,inf) `P(type="instance" desc="Bottom area of drain junction" unit="m^2" ); + parameter real PD = 1E-6 `from(`LS_cliplow,inf) `P(type="instance" desc="Perimeter of drain junction" unit="m" ); + parameter real JW = 1E-6 `from(`LG_cliplow,inf) `P(type="instance" desc="Gate-edge length of source/drain junction" unit="m" ); + parameter real MULT = 1.0 `from( 0.0,inf ) `P(type="instance" desc="Number of devices in parallel" unit="" ); +`else // LocalModel +`ifdef Binning + + `include "PSP102_binpars.include" + +`else // Binning + /////////////////////////////////////////////////// + // PSP global model parameters + /////////////////////////////////////////////////// + + // Special model parameters + parameter real LEVEL = 1020 `P(desc="Model level" unit="" ); + parameter real TYPE = 1.0 `from( -1,1 ) `P(desc="Channel type parameter, +1=NMOS -1=PMOS" unit="" ); + + // Reference Temperature + parameter real TR = 21.0 `from( -273.0,inf ) `P(desc="nominal (reference) temperature" unit="C" ); + + // Switch parameters that turn models or effects on or off + parameter real SWIGATE = 0.0 `from( 0.0,1.0 ) `P(desc="Flag for gate current, 0=turn off IG" unit="" ); + parameter real SWIMPACT = 0.0 `from( 0.0,1.0 ) `P(desc="Flag for impact ionization current, 0=turn off II" unit="" ); + parameter real SWGIDL = 0.0 `from( 0.0,1.0 ) `P(desc="Flag for GIDL current, 0=turn off IGIDL" unit="" ); + parameter real SWJUNCAP = 0.0 `from( 0.0,3.0 ) `P(desc="Flag for juncap, 0=turn off juncap" unit="" ); + parameter real QMC = 1.0 `from( 0.0,inf ) `P(desc="Quantum-mechanical correction factor" unit="" ); + + // Process Parameters + parameter real LVARO = 0.0 `P(desc="Geom. independent difference between actual and programmed gate length" unit="m" ); + parameter real LVARL = 0.0 `P(desc="Length dependence of LVAR" unit="" ); + parameter real LVARW = 0.0 `P(desc="Width dependence of LVAR" unit="" ); + parameter real LAP = 0.0 `P(desc="Effective channel length reduction per side" unit="m" ); + parameter real WVARO = 0.0 `P(desc="Geom. independent difference between actual and programmed field-oxide opening" unit="m" ); + parameter real WVARL = 0.0 `P(desc="Length dependence of WVAR" unit="" ); + parameter real WVARW = 0.0 `P(desc="Width dependence of WVAR" unit="" ); + parameter real WOT = 0.0 `P(desc="Effective channel width reduction per side" unit="m" ); + parameter real DLQ = 0.0 `P(desc="Effective channel length reduction for CV" unit="m" ); + parameter real DWQ = 0.0 `P(desc="Effective channel width reduction for CV" unit="m" ); + parameter real VFBO = -1.0 `P(desc="Geometry-independent flat-band voltage at TR" unit="V" ); + parameter real VFBL = 0.0 `P(desc="Length dependence of flat-band voltage" unit="" ); + parameter real VFBW = 0.0 `P(desc="Width dependence of flat-band voltage" unit="" ); + parameter real VFBLW = 0.0 `P(desc="Area dependence of flat-band voltage" unit="" ); + parameter real STVFBO = 5e-4 `P(desc="Geometry-independent temperature dependence of VFB" unit="V/K" ); + parameter real STVFBL = 0.0 `P(desc="Length dependence of temperature dependence of VFB" unit="" ); + parameter real STVFBW = 0.0 `P(desc="Width dependence of temperature dependence of VFB" unit="" ); + parameter real STVFBLW = 0.0 `P(desc="Area dependence of temperature dependence of VFB" unit="" ); + parameter real TOXO = 2e-9 `from( 1e-10,inf ) `P(desc="Gate oxide thickness" unit="m" ); + parameter real NSUBO = 3e23 `from( 1e20,inf ) `P(desc="Geometry independent substrate doping" unit="m^-3" ); + parameter real NSUBW = 0.0 `P(desc="Width dependence of background doping NSUBO due to segregation" unit="" ); + parameter real WSEG = 1e-8 `from( 1e-10,inf ) `P(desc="Char. length of segregation of background doping NSUBO" unit="m" ); + parameter real NPCK = 1e24 `from( 0.0,inf ) `P(desc="Pocket doping level" unit="m^-3" ); + parameter real NPCKW = 0.0 `P(desc="Width dependence of pocket doping NPCK due to segregation" unit="" ); + parameter real WSEGP = 1e-8 `from( 1e-10,inf ) `P(desc="Char. length of segregation of pocket doping NPCK" unit="m" ); + parameter real LPCK = 1e-8 `from( 1e-10,inf ) `P(desc="Char. length of lateral doping profile" unit="m" ); + parameter real LPCKW = 0.0 `P(desc="Width dependence of char. length of lateral doping profile" unit="" ); + parameter real FOL1 = 0.0 `P(desc="First length dependence coefficient for short channel body effect" unit="" ); + parameter real FOL2 = 0.0 `P(desc="Second length dependence coefficient for short channel body effect" unit="" ); + parameter real VNSUBO = 0.0 `P(desc="Effective doping bias-dependence parameter" unit="V" ); + parameter real NSLPO = 0.05 `P(desc="Effective doping bias-dependence parameter" unit="V" ); + parameter real DNSUBO = 0.0 `P(desc="Effective doping bias-dependence parameter" unit="V^-1" ); + parameter real DPHIBO = 0.0 `P(desc="Geometry independent offset of PHIB" unit="V" ); + parameter real DPHIBL = 0.0 `P(desc="Length dependence offset of PHIB" unit="V" ); + parameter real DPHIBLEXP= 1.0 `P(desc="Exponent for length dependence of offset of PHIB" unit="" ); + parameter real DPHIBW = 0.0 `P(desc="Width dependence of offset of PHIB" unit="" ); + parameter real DPHIBLW = 0.0 `P(desc="Area dependence of offset of PHIB" unit="" ); + parameter real NPO = 1e26 `P(desc="Geometry-independent gate poly-silicon doping" unit="m^-3" ); + parameter real NPL = 0.0 `P(desc="Length dependence of gate poly-silicon doping" unit="" ); + parameter real CTO = 0.0 `P(desc="Geometry-independent interface states factor" unit="" ); + parameter real CTL = 0.0 `P(desc="Length dependence of interface states factor" unit="" ); + parameter real CTLEXP = 1.0 `P(desc="Exponent for length dependence of interface states factor" unit="" ); + parameter real CTW = 0.0 `P(desc="Width dependence of interface states factor" unit="" ); + parameter real CTLW = 0.0 `P(desc="Area dependence of interface states factor" unit="" ); + parameter real TOXOVO = 2e-9 `from( 1e-10,inf ) `P(desc="Overlap oxide thickness" unit="m" ); + parameter real LOV = 0 `from( 0.0,inf ) `P(desc="Overlap length for gate/drain and gate/source overlap capacitance" unit="m" ); + parameter real NOVO = 5e25 `P(desc="Effective doping of overlap region" unit="m^-3" ); + + // DIBL Parameters + parameter real CFL = 0.0 `P(desc="Length dependence of DIBL-parameter" unit="V^-1" ); + parameter real CFLEXP = 2.0 `P(desc="Exponent for length dependence of CF" unit="" ); + parameter real CFW = 0.0 `P(desc="Width dependence of CF" unit="" ); + parameter real CFBO = 0.0 `P(desc="Back-bias dependence of CF" unit="V^-1" ); + + // Mobility Parameters + parameter real UO = 5e-2 `P(desc="Zero-field mobility at TR" unit="m^2/V/s" ); + parameter real FBET1 = 0.0 `P(desc="Relative mobility decrease due to first lateral profile" unit="" ); + parameter real FBET1W = 0.0 `P(desc="Width dependence of relative mobility decrease due to first lateral profile" unit="" ); + parameter real LP1 = 1e-8 `from( 1e-10,inf ) `P(desc="Mobility-related characteristic length of first lateral profile" unit="m" ); + parameter real LP1W = 0.0 `P(desc="Width dependence of mobility-related characteristic length of first lateral profile" unit="" ); + parameter real FBET2 = 0.0 `P(desc="Relative mobility decrease due to second lateral profile" unit="" ); + parameter real LP2 = 1e-8 `from( 1e-10,inf ) `P(desc="Mobility-related characteristic length of second lateral profile" unit="m" ); + parameter real BETW1 = 0.0 `P(desc="First higher-order width scaling coefficient of BETN" unit="" ); + parameter real BETW2 = 0.0 `P(desc="Second higher-order width scaling coefficient of BETN" unit="" ); + parameter real WBET = 1e-9 `from( 1e-10,inf ) `P(desc="Characteristic width for width scaling of BETN" unit="m" ); + parameter real STBETO = 1.0 `P(desc="Geometry independent temperature dependence of BETN" unit="" ); + parameter real STBETL = 0.0 `P(desc="Length dependence of temperature dependence of BETN" unit="" ); + parameter real STBETW = 0.0 `P(desc="Width dependence of temperature dependence of BETN" unit="" ); + parameter real STBETLW = 0.0 `P(desc="Area dependence of temperature dependence of BETN" unit="" ); + parameter real MUEO = 0.5 `P(desc="Geometry independent mobility reduction coefficient at TR" unit="m/V" ); + parameter real MUEW = 0.0 `P(desc="Width dependence of mobility reduction coefficient at TR" unit="" ); + parameter real STMUEO = 0.0 `P(desc="Temperature dependence of MUE" unit="" ); + parameter real THEMUO = 1.5 `P(desc="Mobility reduction exponent at TR" unit="" ); + parameter real STTHEMUO = 1.5 `P(desc="Temperature dependence of THEMU" unit="" ); + parameter real CSO = 0.0 `P(desc="Geometry independent coulomb scattering parameter at TR" unit="" ); + parameter real CSL = 0.0 `P(desc="Length dependence of CS" unit="" ); + parameter real CSLEXP = 0.0 `P(desc="Exponent for length dependence of CS" unit="" ); + parameter real CSW = 0.0 `P(desc="Width dependence of CS" unit="" ); + parameter real CSLW = 0.0 `P(desc="Area dependence of CS" unit="" ); + parameter real STCSO = 0.0 `P(desc="Temperature dependence of CS" unit="" ); + parameter real XCORO = 0.0 `P(desc="Geometry independent non-universality parameter" unit="V^-1" ); + parameter real XCORL = 0.0 `P(desc="Length dependence of non-universality parameter" unit="" ); + parameter real XCORW = 0.0 `P(desc="Width dependence of non-universality parameter" unit="" ); + parameter real XCORLW = 0.0 `P(desc="Area dependence of non-universality parameter" unit="" ); + parameter real STXCORO = 0.0 `P(desc="Temperature dependence of XCOR" unit="" ); + parameter real FETAO = 1.0 `P(desc="Effective field parameter" unit="" ); + + // Series Resistance + parameter real RSW1 = 2.5e3 `P(desc="Source/drain series resistance for 1 um wide channel at TR" unit="Ohm" ); + parameter real RSW2 = 0.0 `P(desc="Higher-order width scaling of RS" unit="" ); + parameter real STRSO = 1.0 `P(desc="Temperature dependence of RS" unit="" ); + parameter real RSBO = 0.0 `P(desc="Back-bias dependence of series resistance" unit="V^-1" ); + parameter real RSGO = 0.0 `P(desc="Gate-bias dependence of series resistance" unit="V^-1" ); + + // Velocity Saturation + parameter real THESATO = 0.0 `P(desc="Geometry independent velocity saturation parameter at TR" unit="V^-1" ); + parameter real THESATL = 0.05 `P(desc="Length dependence of THESAT" unit="V^-1" ); + parameter real THESATLEXP= 1.0 `P(desc="Exponent for length dependence of THESAT" unit="" ); + parameter real THESATW = 0.0 `P(desc="Width dependence of velocity saturation parameter" unit="" ); + parameter real THESATLW = 0.0 `P(desc="Area dependence of velocity saturation parameter" unit="" ); + parameter real STTHESATO= 1.0 `P(desc="Geometry independent temperature dependence of THESAT" unit="" ); + parameter real STTHESATL= 0.0 `P(desc="Length dependence of temperature dependence of THESAT" unit="" ); + parameter real STTHESATW= 0.0 `P(desc="Width dependence of temperature dependence of THESAT" unit="" ); + parameter real STTHESATLW= 0.0 `P(desc="Area dependence of temperature dependence of THESAT" unit="" ); + parameter real THESATBO = 0.0 `P(desc="Back-bias dependence of velocity saturation" unit="V^-1" ); + parameter real THESATGO = 0.0 `P(desc="Gate-bias dependence of velocity saturation" unit="V^-1" ); + + // Saturation Voltage + parameter real AXO = 18 `P(desc="Geometry independent linear/saturation transition factor" unit="" ); + parameter real AXL = 0.4 `from( 0.0,inf ) `P(desc="Length dependence of AX" unit="" ); + + // Channel Length Modulation + parameter real ALPL = 5e-4 `P(desc="Length dependence of ALP" unit="" ); + parameter real ALPLEXP = 1.0 `P(desc="Exponent for length dependence of ALP" unit="" ); + parameter real ALPW = 0.0 `P(desc="Width dependence of ALP" unit="" ); + parameter real ALP1L1 = 0.0 `P(desc="Length dependence of CLM enhancement factor above threshold" unit="V" ); + parameter real ALP1LEXP = 0.5 `P(desc="Exponent for length dependence of ALP1" unit="" ); + parameter real ALP1L2 = 0.0 `from( 0.0,inf ) `P(desc="Second_order length dependence of ALP1" unit="" ); + parameter real ALP1W = 0.0 `P(desc="Width dependence of ALP1" unit="" ); + parameter real ALP2L1 = 0.0 `P(desc="Length dependence of CLM enhancement factor below threshold" unit="V^-1" ); + parameter real ALP2LEXP = 0.5 `P(desc="Exponent for length dependence of ALP2" unit="" ); + parameter real ALP2L2 = 0.0 `from( 0.0,inf ) `P(desc="Second_order length dependence of ALP2" unit="" ); + parameter real ALP2W = 0.0 `P(desc="Width dependence of ALP2" unit="" ); + parameter real VPO = 0.05 `P(desc="CLM logarithmic dependence parameter" unit="V" ); + + // Weak-avalanche parameters + parameter real A1O = 1.0 `P(desc="Geometry independent impact-ionization pre-factor" unit="" ); + parameter real A1L = 0.0 `P(desc="Length dependence of A1" unit="" ); + parameter real A1W = 0.0 `P(desc="Width dependence of A1" unit="" ); + parameter real A2O = 10 `P(desc="Impact-ionization exponent at TR" unit="V" ); + parameter real STA2O = 0.0 `P(desc="Temperature dependence of A2" unit="V" ); + parameter real A3O = 1.0 `P(desc="Geometry independent saturation-voltage dependence of II" unit="" ); + parameter real A3L = 0.0 `P(desc="Length dependence of A3" unit="" ); + parameter real A3W = 0.0 `P(desc="Width dependence of A3" unit="" ); + parameter real A4O = 0.0 `P(desc="Geometry independent back-bias dependence of II" unit="V^-0.5" ); + parameter real A4L = 0.0 `P(desc="Length dependence of A4" unit="" ); + parameter real A4W = 0.0 `P(desc="Width dependence of A4" unit="" ); + + // Gate current parameters + parameter real GCOO = 0.0 `P(desc="Gate tunnelling energy adjustment" unit="" ); + parameter real IGINVLW = 0.0 `P(desc="Gate channel current pre-factor for 1 um^2 channel area" unit="A" ); + parameter real IGOVW = 0.0 `P(desc="Gate overlap current pre-factor for 1 um wide channel" unit="A" ); + parameter real STIGO = 2.0 `P(desc="Temperature dependence of IGINV and IGOV" unit="" ); + parameter real GC2O = 0.375 `P(desc="Gate current slope factor" unit="" ); + parameter real GC3O = 0.063 `P(desc="Gate current curvature factor" unit="" ); + parameter real CHIBO = 3.1 `P(desc="Tunnelling barrier height" unit="V" ); + + // Gate-induced drain leakage parameters + parameter real AGIDLW = 0.0 `P(desc="Width dependence of GIDL pre-factor" unit="A/V^3" ); + parameter real BGIDLO = 41 `P(desc="GIDL probability factor at TR" unit="V" ); + parameter real STBGIDLO = 0.0 `P(desc="Temperature dependence of BGIDL" unit="V/K" ); + parameter real CGIDLO = 0.0 `P(desc="Back-bias dependence of GIDL" unit="" ); + + // Charge Model Parameters + parameter real CGBOVL = 0.0 `P(desc="Oxide capacitance for gate-bulk overlap for 1 um^2 area" unit="F" ); + parameter real CFRW = 0.0 `P(desc="Outer fringe capacitance for 1 um wide channel" unit="F" ); + + // Noise Model Parameters + parameter real FNTO = 1.0 `P(desc="Thermal noise coefficient" unit="" ); + parameter real NFALW = 8e22 `P(desc="First coefficient of flicker noise for 1 um^2 channel area" unit="V^-1/m^4" ); + parameter real NFBLW = 3e7 `P(desc="Second coefficient of flicker noise for 1 um^2 channel area" unit="V^-1/m^2" ); + parameter real NFCLW = 0.0 `P(desc="Third coefficient of flicker noise for 1 um^2 channel area" unit="V^-1" ); + + // Other Parameters + parameter real DTA = 0 `P(desc="Temperature offset w.r.t. ambient circuit temperature" unit="K" ); +`endif // Binning +`ifdef NQSmodel + + // NQS parameters + parameter real SWNQS = 0.0 `from( 0.0,9.0 ) `P(desc="Flag for NQS, 0=off, 1, 2, 3, 5, or 9=number of collocation points" unit="" ); + parameter real MUNQSO = 1.0 `P(desc="Relative mobility for NQS modelling" ); + parameter real RGO = 1.0e-3 `P(desc="Gate resistance" ); + parameter real RBULKO = 1.0e-3 `P(desc="Bulk resistance between node BP and BI" unit="Ohm" ); + parameter real RWELLO = 1.0e-3 `P(desc="Well resistance between node BI and B" unit="Ohm" ); + parameter real RJUNSO = 1.0e-3 `P(desc="Source-side bulk resistance between node BI and BS" unit="Ohm" ); + parameter real RJUNDO = 1.0e-3 `P(desc="Drain-side bulk resistance between node BI and BD" unit="Ohm" ); +`endif // NQSmodel + + // Stress Model Parameters + parameter real SAREF = 1.0e-6 `from( 1e-9,inf ) `P(desc="Reference distance beteen OD-edge to poly from one side" unit="m" ); + parameter real SBREF = 1.0e-6 `from( 1e-9,inf ) `P(desc="Reference distance beteen OD-edge to poly from other side" unit="m" ); + parameter real WLOD = 0 `P(desc="Width parameter" unit="m" ); + parameter real KUO = 0 `P(desc="Mobility degradation/enhancement coefficient" unit="m" ); + parameter real KVSAT = 0 `from( -1.0,1.0 ) `P(desc="Saturation velocity degradation/enhancement coefficient" unit="m" ); + parameter real TKUO = 0 `P(desc="Temperature dependence of KUO" unit="" ); + parameter real LKUO = 0 `P(desc="Length dependence of KUO" unit="m^LLODKUO" ); + parameter real WKUO = 0 `P(desc="Width dependence of KUO" unit="m^WLODKUO" ); + parameter real PKUO = 0 `P(desc="Cross-term dependence of KUO" unit="m^(LLODKUO+WLODKUO)" ); + parameter real LLODKUO = 0 `from( 0.0,inf ) `P(desc="Length parameter for UO stress effect" unit="" ); + parameter real WLODKUO = 0 `from( 0.0,inf ) `P(desc="Width parameter for UO stress effect" unit="" ); + parameter real KVTHO = 0 `P(desc="Threshold shift parameter" unit="Vm" ); + parameter real LKVTHO = 0 `P(desc="Length dependence of KVTHO" unit="m^LLODVTH" ); + parameter real WKVTHO = 0 `P(desc="Width dependence of KVTHO" unit="m^WLODVTH" ); + parameter real PKVTHO = 0 `P(desc="Cross-term dependence of KVTHO" unit="m^(LLODVTH+WLODVTH)" ); + parameter real LLODVTH = 0 `from( 0.0,inf ) `P(desc="Length parameter for VTH-stress effect" unit="" ); + parameter real WLODVTH = 0 `from( 0.0,inf ) `P(desc="Width parameter for VTH-stress effect" unit="" ); + parameter real STETAO = 0 `P(desc="eta0 shift factor related to VTHO change" unit="m" ); + parameter real LODETAO = 1.0 `from( 0.0,inf ) `P(desc="eta0 shift modifaction factor for stress effect" unit="" ); + + // JUNCAP Parameters + parameter real TRJ = 21 `from(`TRJ_cliplow,inf) `P(desc="reference temperature" unit="C"); + `include "JUNCAP200_parlist.include" + + // Instance parameters + parameter real L = 10e-6 `from( 1e-9,inf ) `P(type="instance" desc="Design length" unit="m" ); + parameter real W = 10e-6 `from( 1e-9,inf ) `P(type="instance" desc="Design width" unit="m" ); + parameter real SA = 0.0 `P(type="instance" desc="Distance beteen OD-edge to poly from one side" unit="m" ); + parameter real SB = 0.0 `P(type="instance" desc="Distance beteen OD-edge to poly from other side" unit="m" ); + parameter real ABSOURCE = 1E-12 `from(`AB_cliplow,inf) `P(type="instance" desc="Bottom area of source junction" unit="m^2" ); + parameter real LSSOURCE = 1E-6 `from(`LS_cliplow,inf) `P(type="instance" desc="STI-edge length of source junction" unit="m" ); + parameter real LGSOURCE = 1E-6 `from(`LG_cliplow,inf) `P(type="instance" desc="Gate-edge length of source junction" unit="m" ); + parameter real ABDRAIN = 1E-12 `from(`AB_cliplow,inf) `P(type="instance" desc="Bottom area of drain junction" unit="m^2" ); + parameter real LSDRAIN = 1E-6 `from(`LS_cliplow,inf) `P(type="instance" desc="STI-edge length of drain junction" unit="m" ); + parameter real LGDRAIN = 1E-6 `from(`LG_cliplow,inf) `P(type="instance" desc="Gate-edge length of drain junction" unit="m" ); + parameter real AS = 1E-12 `from(`AB_cliplow,inf) `P(type="instance" desc="Bottom area of source junction" unit="m^2" ); + parameter real PS = 1E-6 `from(`LS_cliplow,inf) `P(type="instance" desc="Perimeter of source junction" unit="m" ); + parameter real AD = 1E-12 `from(`AB_cliplow,inf) `P(type="instance" desc="Bottom area of drain junction" unit="m^2" ); + parameter real PD = 1E-6 `from(`LS_cliplow,inf) `P(type="instance" desc="Perimeter of drain junction" unit="m" ); + parameter real MULT = 1.0 `from( 0.0,inf ) `P(type="instance" desc="Number of devices in parallel" unit="" ); + + ////////////////////////// + // + // Variables + // + ////////////////////////// + + // Variables for geometrical scaling rules + real L_i, W_i, SA_i, SB_i; + real LEN, WEN, iL, iW, delLPS, delWOD, LE, WE, iLE, iWE, Lcv, Wcv, LEcv, WEcv; + +`ifdef Binning + // Auxiliary variables for binning-rules + real iLEWE, iiLE, iiWE, iiLEWE, iiiLEWE; + real iLEcv, iiLEcv, iiWEcv, iiLEWEcv, iiiLEWEcv; + real iLcv, iiLcv, iiWcv, iiLWcv, iiiLWcv; +`else // Binning + // Intermediate variables used for geometry-scaling + real NSUBO_i, WSEG_i, NPCK_i, WSEGP_i, LPCK_i, LOV_i; + real LP1_i, LP2_i, WBET_i, AXL_i, ALP1L2_i, ALP2L2_i; + real NSUB, AA, BB, NSUB0e, NPCKe, LPCKe; + real FBET1e, LP1e, GPE, GWE, tmpx; +`endif // Binning + + // List of local parameters + real VFB, STVFB, TOX, NEFF, VNSUB, NSLP, DNSUB, DPHIB, NP, CT; + real TOXOV, NOV, CF, CFB; + real BETN, STBET, MUE, STMUE, THEMU, STTHEMU, CS, STCS, XCOR, STXCOR, FETA; + real RS, STRS, RSB, RSG; + real THESAT, STTHESAT, THESATB, THESATG; + real AX; + real ALP, ALP1, ALP2, VP; + real A1, A2, STA2, A3, A4; + real GCO, IGINV, IGOV, STIG, GC2, GC3, CHIB; + real AGIDL, BGIDL, STBGIDL, CGIDL; + real COX, CGOV, CGBOV, CFR; + real FNT, NFA, NFB, NFC; +`ifdef NQSmodel + real MUNQS, RG, RBULK, RWELL, RJUNS, RJUND; +`endif // NQSmodel + + // Variables for stress-model + real SAREF_i, SBREF_i, KVSAT_i, LLODKUO_i, WLODKUO_i, LLODVTH_i, WLODVTH_i, LODETAO_i; + real Invsa, Invsb, Invsaref, Invsbref, Kstressu0, rhobeta, rhobetaref, Kstressvth0; + real temp0, templ, tempw, Lx, Wx; +`endif // LocalModel + + // Variables used in electrical equations + real VFB_i, STVFB_i, TOX_i, NEFF_i, VNSUB_i, NSLP_i, DNSUB_i, NP_i, QMC_i, CT_i, TOXOV_i, NOV_i; + real CF_i, CFB_i, DPHIB_i; + real BET_i, STBET_i, MUE_i, STMUE_i, THEMU_i, STTHEMU_i, CS_i, STCS_i, XCOR_i, STXCOR_i, FETA_i; + real RS_i, THER_i, STRS_i, RSB_i, RSG_i; + real THESAT_i, STTHESAT_i, THESATB_i, THESATG_i; + real AX_i, ALP_i, ALP1_i, ALP2_i, VP_i; + real A1_i, A2_i, STA2_i, A3_i, A4_i; + real GCO_i, IGINV_i, IGOV_i, STIG_i, GC2_i, GC3_i, CHIB_i; + real AGIDL_i, BGIDL_i, STBGIDL_i, CGIDL_i; + real COX_i, CGOV_i, CGBOV_i, CFR_i; + real FNT_i, NFA_i, NFB_i, NFC_i; + real TR_i, MULT_i; + + real temp, temp1, temp2, tempM; + real help; + + real TKR, TKD, TKD_sq, dT, rT, rTn; + real phit, inv_phit, Eg, phibFac, CoxPrime, tox_sq; + real delVg, CoxovPrime, GOV, GOV2; + real np, kp, qq, qb0, dphibq, qlim2; + real E_eff0, eta_mu, BCH, BOV, inv_CHIB, GCQ, Dch, Dov; + real tf_bet, tf_mue, tf_cs, tf_xcor, tf_ther, tf_thesat, tf_ig; + real xi_ov, inv_xi_ov, x_mrg_ov, x1, inv_xg1, Vdsat_lim; + real nt, Cox_over_q; + + real phib, sqrt_phib, phix, aphi, bphi, phix1, phix2, G_0, phit1, inv_phit1, alpha_b; + real inv_VP, inv_AX, Sfl_prefac; + + real Vgs, Vgd, Vds, Vsb, Vsbstar; + real Vgb, Vgb1, Vgbstar, Vdb, Vdbstar, Vdsx, Vsbx; + + real Dnsub; + real Igidl, Igisl, Vtovd, Vtovs; + real x_s, sqm, alpha, alpha1, eta_p, phi_inf, za, xitsb, rhob; + real thesat1, wsat, ysat, zsat, r1, r2, dL, GdL, dL1, FdL, GR, Gmob, Gmob_dL, Gvsat, Gvsatinv, QCLM; + real xgm, Voxm, dps, qim, qim1, qim1_1, xgs_ov, xgd_ov, sigVds; + real Ux, xg; + real mu, nu, xn_s, delta_ns; + real Gf, Gf2, inv_Gf2, xi, inv_xi, margin; + real qeff, COX_qm; + + real SP_xg1, SP_S_temp,SP_S_temp1,SP_S_temp2; + real SP_S_yg, SP_S_ysub, SP_S_y0, SP_S_a, SP_S_b, SP_S_c; + real SP_S_bx, SP_S_tau, SP_S_eta, SP_S_delta0, SP_S_delta1; + real SP_S_pC, SP_S_qC, SP_S_A_fac; + real SP_S_x1, SP_S_w, SP_S_xbar, SP_S_x0; + real SP_S_xi0, SP_S_xi1, SP_S_xi2; + real SP_OV_yg, SP_OV_z, SP_OV_eta, SP_OV_a, SP_OV_c; + real SP_OV_tau, SP_OV_D0, SP_OV_y0, SP_OV_xi, SP_OV_temp; + real SP_OV_p, SP_OV_q, SP_OV_w, SP_OV_Afac, SP_OV_xbar; + real SP_OV_x0, SP_OV_u; + + real x_d, x_m, x_ds, Rxcor, delta_1s, xi0s, xi1s, xi2s, xi0d; + real Es, Em, Ed, Ds, Dm, Dd, Ps, xgs, qis, qbs, qbm, Eeffm, Vm; + real Phi_0, Phi_2, asat, Phi_0_2, Phi0_Phi2; + real Vdse, Vdsat, xn_d, k_ds, Udse; + real Mutmp, Phi_sat, delta_nd; + real pC, qC, Pm; + real d0, D_bar, km, x_pm, xi_pd, p_pd, u_pd, q_pd; + real xs_ov, xd_ov, Vovs, Vovd, psi_t; + real zg, delVsat, TP, Dsi, Dgate, u0, u0_div_H, x, xsq, inv_x, ex, inv_ex, Ag, Bg, Sg; + real H, Fj, Fj2; + real N1, Nm1, Delta_N1, Sfl; + real H0, t1, t2, sqt2, r, lc, lcinv2, g_ideal, CGeff, mid, mig, migid, c_igid, sqid, sqig; + real shot_igs, shot_igsx, shot_igd, shot_igdx, shot_iavl; + + real Ids, Iimpact, mavl, Igdov, Igsov, Igc0, igc, igcd_h; + real Igc, Igcd, Igcs, Igb, Igs, Igd; + real Idse, Igbe, Igse, Igde, Igidle, Igisle, Iimpacte; + real QI, QD, QB, QG, Qg, Qd, Qb, Qs, Qgs_ov, Qgd_ov; + real Qfgs, Qfgd, Qgb_ov; + + real arg1, arg2max, arg2mina; + + integer CHNL_TYPE; + +`ifdef NQSmodel + // Variables used in NQS-calculations + real SWNQS_i, MUNQS_i, RG_i, RBULK_i, RWELL_i, RJUNS_i, RJUND_i; + real Qp1_0, Qp2_0, Qp3_0, Qp4_0, Qp5_0, Qp6_0, Qp7_0, Qp8_0, Qp9_0; + real fk1, fk2, fk3, fk4, fk5, fk6, fk7, fk8, fk9; + + real phi_p1, phi_p2, phi_p3; + real phi_p4, phi_p5, phi_p6; + real phi_p7, phi_p8, phi_p9; + + real Qp1, Qp2, Qp3; + real Qp4, Qp5, Qp6; + real Qp7, Qp8, Qp9; + real Qp0, QpN; + + real QG_NQS, QS_NQS, QD_NQS; + real pd, Gp, Gp2, a_factrp, marginp, x_sp, x_dp; + + real dfQi, fQi, dQis, dQis_1, d2Qis, dQbs, dQy, d2Qy, dpsy2; + real ym, inorm, Tnorm, Qb_tmp, QbSIGN; + real r_nqs, vnorm, vnorm_inv; + real NQS_xg1, NQS_yg, NQS_z, NQS_eta, NQS_a, NQS_c, NQS_tau, NQS_D0, NQS_xi, NQS_p; + real NQS_q, NQS_temp, NQS_A_fac, NQS_xbar, NQS_w, NQS_x0, NQS_u, NQS_y0; + real xphi, fk0, thesat2, Fvsat; + real Vrg, Vrbulk, Vrwell, Vrjund, Vrjuns; + real ggate, gbulk, gwell, gjund, gjuns, nt0; + real rgatenoise, rbulknoise, rwellnoise, rjundnoise, rjunsnoise; + real temp3, temp4, temp5, temp6, temp7, temp8, temp9; +`endif // NQSmodel + + // JUNCAP2 variables + `include "JUNCAP200_varlist.include" + real isjunbot, qsjunbot, isjunsti, qsjunsti, isjungat, qsjungat, isjun, qsjun, sjnoise, sjnoisex; + real idjunbot, qdjunbot, idjunsti, qdjunsti, idjungat, qdjungat, idjun, qdjun, djnoise, djnoisex; + real Vjuns, Vjund, VMAXS, VMAXD; + real vbimins, vchs, vfmins, vbbtlims, vbimind, vchd, vfmind, vbbtlimd; + real ABSOURCE_i, LSSOURCE_i, LGSOURCE_i; + real ABDRAIN_i, LSDRAIN_i, LGDRAIN_i, juncapwidth; + + + +`ifdef insideADMS // OPinfo + ///////////////////////////////////////////////////////////////////////////// + // + // Variables for operating point info + // + ///////////////////////////////////////////////////////////////////////////// + + real id_op, is, ig, ib, P_D, facvsb, facvsb0, sig1k; + + real ctype `P(desc="Flag for channel type" unit=""); + real sdint `P(desc="Flag for source-drain interchange" unit=""); + + real ise `P(desc="Total source current" unit="A"); + real ige `P(desc="Total gate current" unit="A"); + real ide `P(desc="Total drain current" unit="A"); + real ibe `P(desc="Total bulk current" unit="A"); + real ids `P(desc="Drain current, excl. avalanche, tunnel, GISL, GIDL, and junction currents" unit="A"); + real idb `P(desc="Drain to bulk current" unit="A"); + real isb `P(desc="Source to bulk current" unit="A"); + real igs `P(desc="Gate-source tunneling current" unit="A"); + real igd `P(desc="Gate-drain tunneling current" unit="A"); + real igb `P(desc="Gate-bulk tunneling current" unit="A"); + real igcs `P(desc="Gate-channel tunneling current (source component)" unit="A"); + real igcd `P(desc="Gate-channel tunneling current (drain component)" unit="A"); + real iavl `P(desc="Substrate current due to weak avelanche" unit="A"); + real igisl `P(desc="Gate-induced source leakage current" unit="A"); + real igidl `P(desc="Gate-induced drain leakage current" unit="A"); + + real ijs `P(desc="Total source junction current" unit="A"); + real ijsbot `P(desc="Source junction current (bottom component)" unit="A"); + real ijsgat `P(desc="Source junction current (gate-edge component)" unit="A"); + real ijssti `P(desc="Source junction current (STI-edge component)" unit="A"); + real ijd `P(desc="Total drain junction current" unit="A"); + real ijdbot `P(desc="Drain junction current (bottom component)" unit="A"); + real ijdgat `P(desc="Drain junction current (gate-edge component)" unit="A"); + real ijdsti `P(desc="Drain junction current (STI-edge component)" unit="A"); + + real vds `P(desc="Drain-source voltage" unit="V"); + real vgs `P(desc="Gate-source voltage" unit="V"); + real vsb `P(desc="Source-bulk voltage" unit="V"); + real vto `P(desc="Zero-bias threshold voltage" unit="V"); + real vts `P(desc="Threshold voltage including back bias effects" unit="V"); + real vth `P(desc="Threshold voltage including back bias and drain bias effects" unit="V"); + real vgt `P(desc="Effective gate drive voltage including back bias and drain bias effects" unit="V"); + real vdss `P(desc="Drain saturation voltage at actual bias" unit="V"); + real vsat `P(desc="Saturation limit" unit="V"); + + real gm `P(desc="Transconductance" unit="1/Ohm"); + real gmb `P(desc="Substrate transconductance" unit="1/Ohm"); + real gds `P(desc="Output conductance" unit="1/Ohm"); + real gjs `P(desc="Source junction conductance" unit="1/Ohm"); + real gjd `P(desc="Drain junction conductance" unit="1/Ohm"); + + real cdd `P(desc="Drain capacitance" unit="F"); + real cdg `P(desc="Drain-gate capacitance" unit="F"); + real cds `P(desc="Drain-source capacitance" unit="F"); + real cdb `P(desc="Drain-bulk capacitance" unit="F"); + real cgd `P(desc="Gate-drain capacitance" unit="F"); + real cgg `P(desc="Gate capacitance" unit="F"); + real cgs `P(desc="Gate-source capacitance" unit="F"); + real cgb `P(desc="Gate-bulk capacitance" unit="F"); + real csd `P(desc="Source-drain capacitance" unit="F"); + real csg `P(desc="Source-gate capacitance" unit="F"); + real css `P(desc="Source capacitance" unit="F"); + real csb `P(desc="Source-bulk capacitance" unit="F"); + real cbd `P(desc="Bulk-drain capacitance" unit="F"); + real cbg `P(desc="Bulk-gate capacitance" unit="F"); + real cbs `P(desc="Bulk-source capacitance" unit="F"); + real cbb `P(desc="Bulk capacitance" unit="F"); + real cgsol `P(desc="Total gate-source overlap capacitance" unit="F"); + real cgdol `P(desc="Total gate-drain overlap capacitance" unit="F"); + + real cjs `P(desc="Total source junction capacitance" unit="F"); + real cjsbot `P(desc="Source junction capacitance (bottom component)" unit="F"); + real cjsgat `P(desc="Source junction capacitance (gate-edge component)" unit="F"); + real cjssti `P(desc="Source junction capacitance (STI-edge component)" unit="F"); + real cjd `P(desc="Total drain junction capacitance" unit="F"); + real cjdbot `P(desc="Drain junction capacitance (bottom component)" unit="F"); + real cjdgat `P(desc="Drain junction capacitance (gate-edge component)" unit="F"); + real cjdsti `P(desc="Drain junction capacitance (STI-edge component)" unit="F"); + + real weff `P(desc="Effective channel width for geometrical models" unit="m"); + real leff `P(desc="Effective channel length for geometrical models" unit="m"); + real u `P(desc="Transistor gain" unit=""); + real rout `P(desc="Small-signal output resistance" unit="Ohm"); + real vearly `P(desc="Equivalent Early voltage" unit="V"); + real beff `P(desc="Gain factor" unit="A/V^2"); + real fug `P(desc="Unity gain frequency at actual bias" unit="Hz"); + + real sfl `P(desc="Flicker noise current density at 1 Hz" unit="A/Hz"); + real sqrtsff `P(desc="Input-referred RMS white noise voltage density at 1 kHz" unit="V/sqrt(Hz)"); + real sqrtsfw `P(desc="Input-referred RMS white noise voltage density" unit="V/sqrt(Hz)"); + real sid `P(desc="White noise current density" unit="A^2/Hz"); + real sig `P(desc="Induced gate noise current density at 1 Hz" unit="A^2/Hz"); + real cigid `P(desc="Imaginary part of correlation coefficient between Sig and Sid" unit=""); + real fknee `P(desc="Cross-over frequency above which white noise is dominant" unit="Hz"); + real sigs `P(desc="Gate-source current noise spectral density" unit="A^2/Hz"); + real sigd `P(desc="Gate-drain current noise spectral density" unit="A^2/Hz"); + real siavl `P(desc="Impact ionization current noise spectral density" unit="A^2/Hz"); + real ssi `P(desc="Total source junction current noise spectral density" unit="A^2/Hz"); + real sdi `P(desc="Total drain junction current noise specral density" unit="A^2/Hz"); +`endif // OPinfo + + ///////////////////////////////////////////////////////////////////////////// + // + // Analog block with all calculations and contribs + // + ///////////////////////////////////////////////////////////////////////////// + + analog begin + + begin : initial_model + // Code independent of bias or instance parameters + // This block needs to be evaluated only once + +`ifdef LocalModel + // Do nothing +`else // LocalModel +`ifdef Binning + // There are no binning parameters that need clipping +`else // Binning + // Clipping of global model parameters + TOX_i = `CLIP_LOW(TOXO, 1e-10); + NSUBO_i = `CLIP_LOW(NSUBO, 1e20); + WSEG_i = `CLIP_LOW(WSEG, 1e-10); + NPCK_i = `CLIP_LOW(NPCK, 0.0); + WSEGP_i = `CLIP_LOW(WSEGP, 1e-10); + LPCK_i = `CLIP_LOW(LPCK, 1e-10); + TOXOV_i = `CLIP_LOW(TOXOVO, 1e-10); + LOV_i = `CLIP_LOW(LOV, 0.0); + LP1_i = `CLIP_LOW(LP1, 1e-10); + LP2_i = `CLIP_LOW(LP2, 1e-10); + WBET_i = `CLIP_LOW(WBET, 1e-10); + AXL_i = `CLIP_LOW(AXL, 0.0); + ALP1L2_i = `CLIP_LOW(ALP1L2, 0.0); + ALP2L2_i = `CLIP_LOW(ALP2L2, 0.0); +`endif // Binning + + KVSAT_i = `CLIP_BOTH(KVSAT, -1.0, 1.0); + LLODKUO_i = `CLIP_LOW(LLODKUO, 0.0); + WLODKUO_i = `CLIP_LOW(WLODKUO, 0.0); + LLODVTH_i = `CLIP_LOW(LLODVTH, 0.0); + WLODVTH_i = `CLIP_LOW(WLODVTH, 0.0); + LODETAO_i = `CLIP_LOW(LODETAO, 0.0); +`endif // LocalModel + + // 4.1 Internal parameters (including temperature scaling) + // (only internal parameters independent on instance parameters + // are calculated in this section) + if (TYPE >= 0) begin + CHNL_TYPE = `NMOS; + end else begin + CHNL_TYPE = `PMOS; + end + + // Transistor temperature + TR_i = `CLIP_LOW(TR, -273); + TKR = `KELVINCONVERSION + TR_i; + TKD = $temperature + DTA; + TKD_sq = TKD * TKD; + dT = TKD - TKR; + rT = TKD / TKR; + rTn = TKR / TKD; + phit = TKD * `KBOL / `QELE; + inv_phit = 1.0 / phit; + + // Local process parameters + Eg = 1.179 - 9.025e-5 * TKD - 3.05e-7 * TKD_sq; + phibFac = (1.045 + 4.5e-4 * TKD) * (0.523 + 1.4e-3 * TKD - 1.48e-6 * TKD_sq) * TKD_sq / 9.0E4; + phibFac = `MAX(phibFac, 1.0E-3); + +`ifdef NQSmodel + // Round SWNQS to nearest allowed value + if (SWNQS < 0.5) begin + SWNQS_i = 0.0; + end else begin + if (SWNQS < 1.5) begin + SWNQS_i = 1.0; + end else begin + if (SWNQS < 2.5) begin + SWNQS_i = 2.0; + end else begin + if (SWNQS < 4.0) begin + SWNQS_i = 3.0; + end else begin + if (SWNQS < 7.0) begin + SWNQS_i = 5.0; + end else begin + SWNQS_i = 9.0; + end + end + end + end + end + inorm = 1.0e-12; + r_nqs = 1.0e+3; + vnorm = 10.0; + vnorm_inv = 1.0 / vnorm; + + nt0 = 4 * `KBOL * TKD; // parameter for white noise of parasitic resistances +`endif // NQSmodel + + // JUNCAP2 + `include "JUNCAP200_InitModel.include" + + end // initial_model + + begin : initial_instance + // Code independent of bias, but dependent on instance parameters, + // (including code dependent on parameters which could IN PRINCIPLE be scaled) + // This block needs to be evaluated only once for each instance + +`ifdef LocalModel + juncapwidth= JW; + +`else // LocalModel + // Clipping of the instance parameters + SAREF_i = `CLIP_LOW(SAREF, 1e-9); + SBREF_i = `CLIP_LOW(SBREF, 1e-9); + L_i = `CLIP_LOW(L, 1e-9); + W_i = `CLIP_LOW(W, 1e-9); + SA_i = SA; + SB_i = SB; + + /////////////////////////////////////////// + // GEOMETRICAL PARAMETERSCALING + /////////////////////////////////////////// + + // 3.2 Transistor geometry + LEN = 1e-6; + WEN = 1e-6; + iL = LEN / L_i; + iW = WEN / W_i; +`ifdef Binning + delLPS = LVARO * (1.0 + LVARL * iL); + delWOD = WVARO * (1.0 + WVARW * iW); +`else // Binning + delLPS = LVARO * (1.0 + LVARL * iL) * (1.0 + LVARW * iW); + delWOD = WVARO * (1.0 + WVARL * iL) * (1.0 + WVARW * iW); +`endif // Binning + LE = `CLIP_LOW(L_i + delLPS - 2.0 * LAP, 1e-9); + WE = `CLIP_LOW(W_i + delWOD - 2.0 * WOT, 1e-9); + LEcv = `CLIP_LOW(L_i + delLPS - 2.0 * LAP + DLQ, 1e-9); + WEcv = `CLIP_LOW(W_i + delWOD - 2.0 * WOT + DWQ, 1e-9); + Lcv = `CLIP_LOW(L_i + delLPS + DLQ, 1e-9); + Wcv = `CLIP_LOW(W_i + delWOD + DWQ, 1e-9); + iLE = LEN / LE; + iWE = WEN / WE; + juncapwidth= WE; + +`ifdef Binning + // 3.4 Geometry scaling with binning scaling rules + `include "PSP102_binning.include" + +`else // Binning + // 3.3 Geometry scaling with physical scaling rules + + // Process parameters + VFB = VFBO * (1.0 + VFBL * iLE) * (1.0 + VFBW * iWE) * (1.0 + VFBLW * iLE * iWE); + STVFB = STVFBO * (1.0 + STVFBL * iLE) * (1.0 + STVFBW * iWE) * (1.0 + STVFBLW * iLE * iWE); + TOX = TOXO; + NSUB0e = NSUBO_i * `MAX(( 1.0 + NSUBW * iWE * ln( 1.0 + WE / WSEG_i )), 1.0E-03); + NPCKe = NPCK_i * `MAX(( 1.0 + NPCKW * iWE * ln( 1.0 + WE / WSEGP_i )), 1.0E-03); + LPCKe = LPCK_i * `MAX(( 1.0 + LPCKW * iWE * ln( 1.0 + WE / WSEGP_i )), 1.0E-03); + if (LE > (2 * LPCKe)) begin + AA = 7.5e10; + BB = sqrt(NSUB0e + 0.5 * NPCKe) - sqrt(NSUB0e); + NSUB = sqrt(NSUB0e) + AA * ln(1 + 2 * LPCKe / LE * (exp(BB / AA) - 1)); + NSUB = NSUB * NSUB; + end else begin + if (LE >= LPCKe) begin + NSUB = NSUB0e + NPCKe * LPCKe / LE; + end else begin // LE < LPCK + NSUB = NSUB0e + NPCKe * (2 - LE / LPCKe); + end + end + NEFF = NSUB * (1 - FOL1 * iLE - FOL2 * iLE * iLE); + VNSUB = VNSUBO; + NSLP = NSLPO; + DNSUB = DNSUBO; + DPHIB = (DPHIBO + DPHIBL * pow(iLE, DPHIBLEXP)) * (1.0 + DPHIBW * iWE) * (1.0 + DPHIBLW * iLE * iWE); + NP = NPO * `MAX(1e-6, (1.0 + NPL * iLE)); + CT = (CTO + CTL * pow(iLE, CTLEXP)) * (1.0 + CTW * iWE) * (1.0 + CTLW * iLE * iWE); + TOXOV = TOXOVO; + NOV = NOVO; + + // DIBL parameters + CF = CFL * pow(iLE, CFLEXP) * (1.0 + CFW * iWE); + CFB = CFBO; + + // Mobility parameters + FBET1e = FBET1 * (1.0 + FBET1W * iWE); + LP1e = LP1_i * `MAX(1.0 + LP1W * iWE, 1.0E-03); + GPE = 1.0 + FBET1e * LP1e / LE * (1.0 - exp(-LE / LP1e)) + FBET2 * LP2_i / LE * (1.0 - exp(-LE / LP2_i)); + GPE = `MAX(GPE, 1e-15); + GWE = 1.0 + BETW1 * iWE + BETW2 * iWE * ln(1.0 + WE / WBET_i); + BETN = UO * WE / (GPE * LE) * GWE; + STBET = STBETO * (1.0 + STBETL * iLE) * (1.0 + STBETW * iWE) * (1.0 + STBETLW * iLE * iWE); + MUE = MUEO * (1.0 + MUEW * iWE); + STMUE = STMUEO; + THEMU = THEMUO; + STTHEMU = STTHEMUO; + CS = (CSO + CSL * pow(iLE, CSLEXP)) * (1.0 + CSW * iWE) * (1.0 + CSLW * iLE * iWE); + STCS = STCSO; + XCOR = XCORO * (1.0 + XCORL * iLE) * (1.0 + XCORW * iWE) * (1.0 + XCORLW * iLE * iWE); + STXCOR = STXCORO; + FETA = FETAO; + + // Series resistance + RS = RSW1 * iWE * (1.0 + RSW2 * iWE); + STRS = STRSO; + RSB = RSBO; + RSG = RSGO; + + // Velocity saturation + THESAT = (THESATO + THESATL* GWE / GPE * pow(iLE, THESATLEXP)) * (1.0 + THESATW * iWE) * (1.0 + THESATLW * iLE * iWE); + STTHESAT = STTHESATO * (1.0 + STTHESATL * iLE) * (1.0 + STTHESATW * iWE) * (1.0 + STTHESATLW * iLE * iWE); + THESATB = THESATBO; + THESATG = THESATGO; + + // Saturation voltage + AX = AXO / (1.0 + AXL_i * iLE); + + // Channel length modulation + ALP = ALPL * pow(iLE, ALPLEXP) * (1.0 + ALPW * iWE); + tmpx = pow(iLE, ALP1LEXP); + ALP1 = ALP1L1 * tmpx * (1.0 + ALP1W * iWE) / (1.0 + ALP1L2_i * iLE * tmpx); + tmpx = pow(iLE, ALP2LEXP); + ALP2 = ALP2L1 * tmpx * (1.0 + ALP2W * iWE) / (1.0 + ALP2L2_i * iLE * tmpx); + VP = VPO; + + // Impact ionization + A1 = A1O * (1.0 + A1L * iLE) * (1.0 + A1W * iWE); + A2 = A2O; + STA2 = STA2O; + A3 = A3O * (1.0 + A3L * iLE) * (1.0 + A3W * iWE); + A4 = A4O * (1.0 + A4L * iLE) * (1.0 + A4W * iWE); + + // Gate current + GCO = GCOO; + IGINV = IGINVLW / (iWE * iLE); + IGOV = IGOVW * LOV_i / (LEN * iWE); + STIG = STIGO; + GC2 = GC2O; + GC3 = GC3O; + CHIB = CHIBO; + + // GIDL + AGIDL = AGIDLW * LOV_i / (LEN * iWE); + BGIDL = BGIDLO; + STBGIDL = STBGIDLO; + CGIDL = CGIDLO; + + // Charge model parameters + COX = `EPSOX * WEcv * LEcv / TOX_i; + CGOV = `EPSOX * WEcv * LOV_i / TOXOV_i; + CGBOV = CGBOVL * Lcv / LEN; + CFR = CFRW * Wcv / WEN; + FNT = FNTO; + + // Noise model parameters + NFA = iWE * iLE * NFALW; + NFB = iWE * iLE * NFBLW; + NFC = iWE * iLE * NFCLW; +`endif // Binning + +`ifdef NQSmodel + MUNQS = MUNQSO; + RG = RGO; + RWELL = RWELLO; + RBULK = RBULKO; + RJUNS = RJUNSO; + RJUND = RJUNDO; +`endif // NQSModel + + /////////////////////////////////////////// + // STRESSMODEL + /////////////////////////////////////////// + + // 3.5 Stress equations + if ((SA_i > 0) && (SB_i > 0)) begin + // Auxiliary variables + Invsa = 1.0 / (SA_i + 0.5 * L_i); + Invsb = 1.0 / (SB_i + 0.5 * L_i); + Invsaref = 1.0 / (SAREF_i + 0.5 * L_i); + Invsbref = 1.0 / (SBREF_i + 0.5 * L_i); + Lx = `MAX(L_i + delLPS, 1e-9); + Wx = `MAX(W_i + delWOD + WLOD, 1e-9); + templ = 1.0 / pow(Lx, LLODKUO_i); + tempw = 1.0 / pow(Wx, WLODKUO_i); + Kstressu0 = (1.0 + LKUO * templ + WKUO * tempw + PKUO * templ * tempw) * (1.0 + TKUO * (rT - 1.0)); + rhobeta = KUO * (Invsa + Invsb) / Kstressu0; + rhobetaref = KUO * (Invsaref + Invsbref) / Kstressu0; + templ = 1.0 / pow(Lx, LLODVTH_i); + tempw = 1.0 / pow(Wx, WLODVTH_i); + Kstressvth0= 1.0 + LKVTHO * templ + WKVTHO * tempw + PKVTHO * templ * tempw; + temp0 = Invsa + Invsb - Invsaref - Invsbref; + + // Parameter adaptations + BETN = BETN * (1.0 + rhobeta) / (1.0 + rhobetaref); + THESAT = THESAT * (1.0 + rhobeta) * (1.0 + KVSAT_i * rhobetaref) / ((1.0 + rhobetaref) * (1.0 + KVSAT_i * rhobeta)); + VFB = VFB + KVTHO * temp0 / Kstressvth0; + CF = CF + STETAO * temp0 / pow(Kstressvth0, LODETAO_i); + end + + /////////////////////////////////////////// + // END OF SCALINGRULES AND STRESSMODEL + /////////////////////////////////////////// + +`endif // LocalModel + // 4.1 Internal parameters (including temperature scaling) + + // Clipping of the local model parameters + VFB_i = VFB; + STVFB_i = STVFB; + TOX_i = `CLIP_LOW(TOX, 1e-10); + NEFF_i = `CLIP_BOTH(NEFF, 1e20, 1e26); + VNSUB_i = VNSUB; + NSLP_i = `CLIP_LOW(NSLP, 1e-3); + DNSUB_i = `CLIP_BOTH(DNSUB, 0.0, 1.0); + DPHIB_i = DPHIB; + NP_i = `CLIP_LOW(NP, 0.0); + QMC_i = `CLIP_LOW(QMC, 0.0); + CT_i = `CLIP_LOW(CT, 0.0); + TOXOV_i = `CLIP_LOW(TOXOV, 1e-10); + NOV_i = `CLIP_BOTH(NOV, 1e20, 1e27); + CF_i = `CLIP_LOW(CF, 0.0); + CFB_i = `CLIP_BOTH(CFB, 0.0, 1.0); + BET_i = `CLIP_LOW(BETN, 0.0); + STBET_i = STBET; + MUE_i = `CLIP_LOW(MUE, 0.0); + STMUE_i = STMUE; + THEMU_i = `CLIP_LOW(THEMU, 0.0); + STTHEMU_i = STTHEMU; + CS_i = `CLIP_LOW(CS, 0.0); + STCS_i = STCS; + XCOR_i = `CLIP_LOW(XCOR, 0.0); + STXCOR_i = STXCOR; + FETA_i = `CLIP_LOW(FETA, 0.0); + RS_i = `CLIP_LOW(RS, 0.0); + STRS_i = STRS; + RSB_i = `CLIP_BOTH(RSB, -0.5, 1.0); + RSG_i = `CLIP_LOW(RSG, -0.5); + THESAT_i = `CLIP_LOW(THESAT, 0.0); + STTHESAT_i = STTHESAT; + THESATB_i = `CLIP_BOTH(THESATB, -0.5, 1.0); + THESATG_i = `CLIP_LOW(THESATG, -0.5); + AX_i = `CLIP_LOW(AX, 2.0); + ALP_i = `CLIP_LOW(ALP, 0.0); + ALP1_i = `CLIP_LOW(ALP1, 0.0); + ALP2_i = `CLIP_LOW(ALP2, 0.0); + VP_i = `CLIP_LOW(VP, 1.0e-10); + A1_i = `CLIP_LOW(A1, 0.0); + A2_i = `CLIP_LOW(A2, 0.0); + STA2_i = STA2; + A3_i = `CLIP_LOW(A3, 0.0); + A4_i = `CLIP_LOW(A4, 0.0); + GCO_i = `CLIP_BOTH(GCO, -10.0, 10.0); + IGINV_i = `CLIP_LOW(IGINV, 0.0); + IGOV_i = `CLIP_LOW(IGOV, 0.0); + STIG_i = STIG; + GC2_i = `CLIP_BOTH(GC2, 0.0, 10.0); + GC3_i = `CLIP_BOTH(GC3, -10.0, 10.0); + CHIB_i = `CLIP_LOW(CHIB, 1.0); + AGIDL_i = `CLIP_LOW(AGIDL, 0.0); + BGIDL_i = `CLIP_LOW(BGIDL, 0.0); + STBGIDL_i = STBGIDL; + CGIDL_i = CGIDL; + COX_i = `CLIP_LOW(COX, 0.0); + CGOV_i = `CLIP_LOW(CGOV, 0.0); + CGBOV_i = `CLIP_LOW(CGBOV, 0.0); + CFR_i = `CLIP_LOW(CFR, 0.0); + FNT_i = `CLIP_LOW(FNT, 0.0); + NFA_i = `CLIP_LOW(NFA, 0.0); + NFB_i = `CLIP_LOW(NFB, 0.0); + NFC_i = `CLIP_LOW(NFC, 0.0); + MULT_i = `CLIP_LOW(MULT, 0.0); + + + // Local process parameters + phit1 = phit * (1.0 + CT_i * rTn); + inv_phit1 = 1.0 / phit1; + + VFB_i = VFB_i + STVFB_i * dT; + phib = Eg + DPHIB_i + 2.0 * phit * ln(NEFF_i * pow(phibFac, -0.75) * 4.0e-26); + phib = `MAX(phib, 5.0E-2); + CoxPrime = `EPSOX / TOX_i; + tox_sq = TOX_i * TOX_i; + G_0 = sqrt(2.0 * `QELE * NEFF_i * `EPSSI * inv_phit) / CoxPrime; + + // Poly-silicon depletion + kp = 0.0; + if (NP_i > 0.0) begin + arg2max = 8.0e7 / tox_sq; + np = `MAX(NP_i, arg2max); + np = `MAX(3.0e25, np); + kp = 2.0 * CoxPrime * CoxPrime * phit / (`QELE * np * `EPSSI); + end + + // QM corrections + qlim2 = 100.0 * phit * phit; + qq = 0.0; + if (QMC_i > 0.0) begin + qq = 0.4 * `QMN * QMC_i * pow(CoxPrime, `twoThirds); + if (CHNL_TYPE==`PMOS) begin + qq = `QMP / `QMN * qq; + end + qb0 = sqrt(phit * G_0 * G_0 * phib); + dphibq = 0.75 * qq * pow(qb0, `twoThirds); + phib = phib + dphibq; + G_0 = G_0 * (1.0 + 2.0 * `twoThirds * dphibq / qb0); + end + sqrt_phib = sqrt(phib); + phix = 0.95 * phib; + aphi = 0.0025 * phib * phib; + bphi = aphi; + phix2 = 0.5 * sqrt(bphi); + phix1 = `MINA(phix - phix2, 0, aphi); + + // Gate overlap + CoxovPrime = `EPSOX / TOXOV_i; + GOV = sqrt(2.0 * `QELE * NOV_i * `EPSSI * inv_phit) / CoxovPrime; + GOV2 = GOV * GOV; + xi_ov = 1.0 + GOV * `invSqrt2; + inv_xi_ov = 1.0 / xi_ov; + x_mrg_ov = 1.0e-5 * xi_ov; + + // Mobility parameters + tf_bet = pow(rTn, STBET_i); + BET_i = BET_i * CoxPrime * tf_bet; + THEMU_i = THEMU_i * pow(rTn, STTHEMU_i); + tf_mue = pow(rTn, STMUE_i); + MUE_i = MUE_i * tf_mue; + tf_cs = pow(rTn, STCS_i); + CS_i = CS_i * tf_cs; + tf_xcor = pow(rTn, STXCOR_i); + XCOR_i = XCOR_i * tf_xcor; + E_eff0 = 1.0e-8 * CoxPrime / `EPSSI; + eta_mu = 0.5 * FETA_i; + if (CHNL_TYPE == `PMOS) begin + eta_mu = `oneThird * FETA_i; + end + + // Series resistance + tf_ther = pow(rTn, STRS_i); + RS_i = RS_i * tf_ther; + THER_i = 2 * BET_i * RS_i; + + // Velocity saturation + tf_thesat = pow(rTn, STTHESAT_i); + THESAT_i = THESAT_i * tf_thesat; + Vdsat_lim = 3.912023005 * phit1; + + inv_AX = 1.0 / AX_i; + inv_VP = 1.0 / VP_i; + + // Impact ionization + A2_i = A2_i * pow(rT, STA2_i); + + // Gate current + tf_ig = pow(rT, STIG_i); + IGINV_i = IGINV_i * tf_ig; + IGOV_i = IGOV_i * tf_ig; + inv_CHIB = 1.0 / CHIB_i; + tempM = 4.0 * `oneThird * sqrt(2 * `QELE * `MELE * CHIB_i) / `HBAR; + BCH = tempM * TOX_i; + BOV = tempM * TOXOV_i; + GCQ = 0; + if (GC3_i < 0) begin + GCQ = -0.495 * GC2_i / GC3_i; + end + alpha_b = 0.5 * (phib + Eg); + Dch = GCO_i * phit1; + Dov = GCO_i * phit; + + // GIDL + AGIDL_i = AGIDL_i * 4e-18 / (TOXOV_i * TOXOV_i); + tempM = `MAX(1.0 + STBGIDL_i * dT, 0); + BGIDL_i = BGIDL_i * tempM * TOXOV_i * 5e8; + + // Noise + nt = FNT_i * 4 * `KBOL * TKD; + Cox_over_q = CoxPrime / `QELE; + Sfl_prefac = phit * phit * BET_i / Cox_over_q; + + // Additional internal parameters + x1 = 1.25; + inv_xg1 = 1.0 / (x1 + GOV * 7.324648775608221e-1); // = 1.0/(x1+GOV*sqrt(exp(-x1)+x1-1)); +`ifdef NQSmodel + + // NQS parameters and variables + MUNQS_i = `CLIP_LOW(MUNQS, 0.0); + RG_i = `CLIP_LOW(RG, 1.0e-6); + RBULK_i = `CLIP_LOW(RBULK, 1.0e-6); + RJUNS_i = `CLIP_LOW(RJUNS, 1.0e-6); + RJUND_i = `CLIP_LOW(RJUND, 1.0e-6); + RWELL_i = `CLIP_LOW(RWELL, 1.0e-6); + + // Conductance of parasitic resistance + ggate = MULT_i / RG_i; + gbulk = MULT_i / RBULK_i; + gjuns = MULT_i / RJUNS_i; + gjund = MULT_i / RJUND_i; + gwell = MULT_i / RWELL_i; +`endif // NQSmodel + + // JUNCAP2 + vbimins = 0.0; + vfmins = 0.0; + vchs = 0.0; + vbbtlims = 0.0; + vbimind = 0.0; + vfmind = 0.0; + vchd = 0.0; + vbbtlimd = 0.0; + vj = 0.0; + idmult = 0.0; + vjsrh = 0.0; + zinv = 0.0; + wdep = 0.0; + wsrh = 0.0; + asrh = 0.0; + vav = 0.0; + vbi_minus_vjsrh = 0.0; + + if (SWJUNCAP == 0.0) begin + ABSOURCE_i = 0.0; + LSSOURCE_i = 0.0; + LGSOURCE_i = 0.0; + ABDRAIN_i = 0.0; + LSDRAIN_i = 0.0; + LGDRAIN_i = 0.0; + VMAXS = 0.0; + VMAXD = 0.0; + end else begin + if (SWJUNCAP == 2.0) begin + ABSOURCE_i = `CLIP_LOW(AS, `AB_cliplow); + LSSOURCE_i = `CLIP_LOW(PS, `LS_cliplow); + LGSOURCE_i = juncapwidth; + ABDRAIN_i = `CLIP_LOW(AD, `AB_cliplow); + LSDRAIN_i = `CLIP_LOW(PD, `LS_cliplow); + LGDRAIN_i = juncapwidth; + end else begin + if (SWJUNCAP == 3.0) begin + ABSOURCE_i = `CLIP_LOW(AS, `AB_cliplow); + ABDRAIN_i = `CLIP_LOW(AD, `AB_cliplow); + LSSOURCE_i = `CLIP_LOW(PS - juncapwidth, `LS_cliplow); + LGSOURCE_i = juncapwidth; + LSDRAIN_i = `CLIP_LOW(PD - juncapwidth, `LS_cliplow); + LGDRAIN_i = juncapwidth; + end else begin + ABSOURCE_i = `CLIP_LOW(ABSOURCE, `AB_cliplow); + LSSOURCE_i = `CLIP_LOW(LSSOURCE, `LS_cliplow); + LGSOURCE_i = `CLIP_LOW(LGSOURCE, `LG_cliplow); + ABDRAIN_i = `CLIP_LOW(ABDRAIN, `AB_cliplow); + LSDRAIN_i = `CLIP_LOW(LSDRAIN, `LS_cliplow); + LGDRAIN_i = `CLIP_LOW(LGDRAIN, `LG_cliplow); + end + end + `JuncapInitInstance(ABSOURCE_i, LSSOURCE_i, LGSOURCE_i, VMAXS, vbimins, vchs, vfmins, vbbtlims) + `JuncapInitInstance(ABDRAIN_i, LSDRAIN_i, LGDRAIN_i, VMAXD, vbimind, vchd, vfmind, vbbtlimd) + end + + + end // initial_instance + + ///////////////////////////////////////////////////////////////////////////// + // + // DC bias dependent quantities (calculations for current contribs) + // + ///////////////////////////////////////////////////////////////////////////// + + begin : evaluateStatic + // Initialisation of some variables + SP_S_x1 = 0.0; + x_s = 0.0; + sqm = 0.0; + alpha = 0.0; + eta_p = 1.0; + xitsb = 0.0; + rhob = 0.0; + GdL = 1.0; + FdL = 1.0; + Gmob = 1.0; + Gmob_dL = 1.0; + Udse = 0.0; + QCLM = 0.0; + thesat1 = 0.0; + Gvsat = 1.0; + Gvsatinv = 1.0; + xgm = 0.0; + dps = 0.0; + qim = 0.0; + qim1 = 0.0; + H = 1.0; + xs_ov = 0.0; + xd_ov = 0.0; + Vovs = 0.0; + Vovd = 0.0; + Iimpact = 0.0; + mavl = 0.0; + +`ifdef NQSmodel + // Initialization of variables for NQS model + pd = 1.0; + ym = 0.0; + + Vrg = V(G ,GP); + Vrjuns = V(BS,BI); + Vrjund = V(BD,BI); + Vrbulk = V(BP,BI); + Vrwell = V(B ,BI); +`endif // NQSmodel + if (CHNL_TYPE == `NMOS) begin + Vgs = V(`Gint, S); + Vds = V(D, S); + Vsb = V(S, `Bint); + Vjuns = -V(S, `Bjs); + Vjund = -V(D, `Bjd); + end else begin + Vgs = -V(`Gint, S); + Vds = -V(D, S); + Vsb = -V(S, `Bint); + Vjuns = V(S, `Bjs); + Vjund = V(D, `Bjd); + end + + // Source-drain interchange + sigVds = 1.0; + if (Vds < 0.0) begin + sigVds = -1.0; + Vgs = Vgs - Vds; + Vsb = Vsb + Vds; + Vds = -Vds; + end + + Vgd = Vgs - Vds; + Vdb = Vds + Vsb; + Vgb = Vgs + Vsb; + + xgs_ov = -Vgs * inv_phit; + xgd_ov = -Vgd * inv_phit; + + // 4.2.1 Conditioning of terminal voltages + temp = `MINA(Vdb, Vsb, bphi) + phix; + Vsbstar = Vsb - `MINA(temp, 0, aphi) + phix1; + Vdbstar = Vds + Vsbstar; + Vgbstar = Vgs + Vsbstar; + Vgb1 = Vgbstar - VFB_i; + Vdsx = sqrt(Vds * Vds + 0.01) - 0.1; + Vsbx = Vsbstar + 0.5 * (Vds - Vdsx); + delVg = CF_i * (Vdsx * (1 + CFB_i * Vsbx)); // DIBL + Vgb1 = Vgb1 + delVg; + xg = Vgb1 * inv_phit1; + + // 4.2.2 Bias dependent body factor + if (DNSUB_i > 0.0) begin + Dnsub = DNSUB_i * `MAXA(0, Vgs + Vsb - VNSUB_i, NSLP_i); + Gf = G_0 * sqrt(1.0 + Dnsub); + end else begin + Gf = G_0; + end + + // 4.2.3 Surface potential at source side + Gf2 = Gf * Gf; + inv_Gf2 = 1.0 / Gf2; + xi = 1.0 + Gf * `invSqrt2; + inv_xi = 1.0 / xi; + Ux = Vsbstar * inv_phit1; + xn_s = phib * inv_phit1 + Ux; + if (xn_s < `se) + delta_ns = exp(-xn_s); + else + delta_ns = `ke / `P3(xn_s - `se); + margin = 1e-5 * xi; + + `sp_s(x_s, xg, xn_s, delta_ns) + x_d = x_s; + x_m = x_s; + x_ds = 0.0; + + // + // Core PSP current calculation + // + if (xg <= 0.0) begin + qis = 0.0; + Ids = 0.0; + xgm = xg - x_s; + Voxm = xgm * phit1; + qeff = Voxm; + Vdsat = Vdsat_lim; + end else begin // (xg > 0) + delta_1s = 0.0; + temp = 1.0 / (2.0 + x_s * x_s); + xi0s = x_s * x_s * temp; + xi1s = 4.0 * (x_s * temp * temp); + xi2s = (8.0 * temp - 12.0 * xi0s) * temp * temp; + if (x_s < `se05) begin + delta_1s = exp(x_s); + Es = 1.0 / delta_1s; + delta_1s = delta_ns * delta_1s; + end else if (x_s > (xn_s - `se05)) begin + delta_1s = exp(x_s - xn_s); + Es = delta_ns / delta_1s; + end else begin + delta_1s = `ke05 / `P3(xn_s - x_s - `se05); + Es = `ke05 / `P3(x_s - `se05); + end + Ds = delta_1s - delta_ns * (x_s + 1.0 + xi0s); + if (x_s < 1.0e-5) begin + Ps = 0.5 * (x_s * x_s * (1.0 - `oneThird * (x_s * (1.0 - 0.25 * x_s)))); + Ds = `oneSixth * (delta_ns * x_s * x_s * x_s * (1.0 + 1.75 * x_s)); + temp = sqrt(1.0 - `oneThird * (x_s * (1.0 - 0.25 * x_s))); + sqm = `invSqrt2 * (x_s * temp); + alpha = 1.0 + Gf * `invSqrt2 * (1.0 - 0.5 * x_s + `oneSixth * (x_s * x_s)) / temp; + end else begin + Ps = x_s - 1.0 + Es; + sqm = sqrt(Ps); + alpha = 1.0 + 0.5 * (Gf * (1.0 - Es) / sqm); + end + Em = Es; + Ed = Em; + Dm = Ds; + Dd = Dm; + + // 4.2.4 Drain saturation voltage + Rxcor = (1.0 + 0.2 * XCOR_i * Vsbx) / (1.0 + XCOR_i * Vsbx); + if ( Ds > `ke05) begin + xgs = Gf * sqrt(Ps + Ds); + qis = Gf2 * Ds * phit1 / (xgs + Gf * sqm); + qbs = sqm * Gf * phit1; + if (RSB_i < 0) begin + rhob = 1.0 / (1.0 - RSB_i * Vsbx); + end else begin + rhob = 1.0 + RSB_i * Vsbx; + end + if (RSG_i < 0) begin + temp = 1.0 - RSG_i * qis; + end else begin + temp = 1.0 / (1.0 + RSG_i * qis); + end + GR = THER_i * (rhob * temp * qis); + Eeffm = E_eff0 * (qbs + eta_mu * qis); + Mutmp = pow(Eeffm * MUE_i, THEMU_i) + CS_i * (Ps / (Ps + Ds + 1.0e-14)); + Gmob = (1.0 + Mutmp + GR) * Rxcor; + if (THESATB_i < 0) begin + xitsb = 1.0 / (1.0 - THESATB_i * Vsbx); + end else begin + xitsb = 1.0 + THESATB_i * Vsbx; + end + temp2 = qis * xitsb; + wsat = 100.0 * (temp2 / (100.0 + temp2)); + if (THESATG_i < 0) begin + temp = 1 / (1 - THESATG_i * wsat); + end else begin + temp = 1 + THESATG_i * wsat; + end + thesat1 = THESAT_i * (temp / Gmob); + phi_inf = qis / alpha + phit1; + ysat = thesat1 * phi_inf * `invSqrt2; + if (CHNL_TYPE==`PMOS) begin + ysat = ysat / sqrt(1.0 + ysat); + end + za = 2.0 / (1.0 + sqrt(1.0 + 4.0 * ysat)); + temp1 = za * ysat; + Phi_0 = phi_inf * za * (1.0 + 0.86 * (temp1 * (1.0 - temp1 * za) / (1.0 + 4.0 * (temp1 * temp1 * za)))); + asat = xgs + 0.5 * Gf2; + Phi_2 = 0.98 * (Gf2 * Ds * phit1 / (asat + sqrt(asat * asat - Gf2 * Ds * 0.98))); + Phi_0_2 = Phi_0 + Phi_2; + Phi0_Phi2 = 2.0 * (Phi_0 * Phi_2); + Phi_sat = Phi0_Phi2 / (Phi_0_2 + sqrt(Phi_0_2 * Phi_0_2 - 1.98 * Phi0_Phi2)); + Vdsat = Phi_sat - phit1 * ln(1.0 + Phi_sat * (Phi_sat - 2.0 * asat * phit1) * inv_Gf2 / (phit1 * phit1 * Ds)); + end else begin + Vdsat = Vdsat_lim; + end + temp = pow(Vds / Vdsat, AX_i); + Vdse = Vds * pow(1.0 + temp, -inv_AX); + + // 4.2.5 Surface potential at drain side + Udse = Vdse * inv_phit1; + xn_d = xn_s + Udse; + if (Udse < `se) begin + k_ds = exp(-Udse); + end else begin + k_ds = `ke / `P3(Udse - `se); + end + delta_nd = delta_ns * k_ds; + + `sp_s_d(x_d, xg, xn_d, delta_nd) + x_ds = x_d - x_s; + + // + // Approximations for extremely small x_ds: capacitance calulation + // + if (x_ds < 1.0E-10) begin + pC = 2.0 * (xg - x_s) + Gf2 * (1.0 - Es + delta_1s * k_ds - delta_nd * (1.0 + xi1s)); + qC = Gf2 * (1.0 - k_ds) * Ds; + temp = 2.0 - Gf2 * (Es + delta_1s * k_ds - delta_nd * xi2s); + temp = pC * pC - 2.0 * (temp * qC); + x_ds = 2.0 * (qC / (pC + sqrt(temp))); + x_d = x_s + x_ds; + end + dps = x_ds * phit1; // deltaPsi + + xi0d = x_d * x_d / (2.0 + x_d * x_d); + if (x_d < `se05) begin + Ed = exp(-x_d); + if (x_d < 1.0e-5) begin + Dd = `oneSixth * delta_nd * x_d * x_d * x_d * (1.0 + 1.75 * x_d); + end else begin + Dd = delta_nd * (1.0 / Ed - x_d - 1.0 - xi0d); + end + end else begin + if (x_d > (xn_d - `se05)) begin + temp = exp(x_d - xn_d); + Ed = delta_nd / temp; + Dd = temp - delta_nd * (x_d + 1.0 + xi0d); + end else begin + Ed = `ke05 / `P3(x_d - `se05); + temp = `ke05 / `P3(xn_d - x_d - `se05); + Dd = temp - delta_nd * (x_d + 1.0 + xi0d); + end + end + + // 4.2.6 Mid-point surface potential + x_m = 0.5 * (x_s + x_d); + Em = 0.0; + temp = Ed * Es; + if (temp > 0.0) begin + Em = sqrt(temp); + end + D_bar = 0.5 * (Ds + Dd); + Dm = D_bar + 0.125 * (x_ds * x_ds * (Em - 2.0 * inv_Gf2)); + + if (x_m < 1.0e-5) begin + Pm = 0.5 * (x_m * x_m * (1.0 - `oneThird * (x_m * (1.0 - 0.25 * x_m)))); + xgm = Gf * sqrt(Dm + Pm); + + // 4.2.7 Polysilicon depletion + if (kp > 0.0) begin + eta_p = 1.0 / sqrt(1.0 + kp * xgm); + end // (kp > 0.0) + temp = sqrt(1.0 - `oneThird * (x_m * (1.0 - 0.25 * x_m))); + sqm = `invSqrt2 * (x_m * temp); + alpha = eta_p + `invSqrt2 * (Gf * (1.0 - 0.5 * x_m + `oneSixth * (x_m * x_m)) / temp); + end else begin + Pm = x_m - 1.0 + Em; + xgm = Gf * sqrt(Dm + Pm); + + // 4.2.7 Polysilicon depletion + if (kp > 0.0) begin + d0 = 1.0 - Em + 2.0 * (xgm * inv_Gf2); + eta_p = 1.0 / sqrt(1.0 + kp * xgm); + temp = eta_p / (eta_p + 1.0); + x_pm = kp * (temp * temp * Gf2 * Dm); + p_pd = 2.0 * (xgm - x_pm) + Gf2 * (1.0 - Em + Dm); + q_pd = x_pm * (x_pm - 2.0 * xgm); + xi_pd = 1.0 - 0.5 * (Gf2 * (Em + Dm)); + u_pd = q_pd * p_pd / (p_pd * p_pd - xi_pd * q_pd); + x_m = x_m + u_pd; + km = exp(u_pd); + Em = Em / km; + Dm = Dm * km; + Pm = x_m - 1.0 + Em; + xgm = Gf * sqrt(Dm + Pm); + help = 1.0 - Em + 2.0 * (xgm * eta_p * inv_Gf2); + x_ds = x_ds * km * (d0 + D_bar) / (help + km * D_bar); + dps = x_ds * phit1; + end // (kp > 0.0) + sqm = sqrt(Pm); + alpha = eta_p + 0.5 * (Gf * (1.0 - Em) / sqm); + end + + // 4.2.8 Potential midpoint inversion charge + qim = phit1 * (Gf2 * Dm / (xgm + Gf * sqm)); + + // 4.2.8 Potential midpoint inversion charge (continued) + qim1 = qim + phit1 * alpha; + qim1_1 = 1.0 / qim1; + qbm = sqm * Gf * phit1; + // Series resistance + if (RSG_i < 0) begin + temp = 1.0 - RSG_i * qim; + end else begin + temp = 1.0 / (1.0 + RSG_i * qim); + end + GR = THER_i * (rhob * temp * qim); + // Mobility reduction + qeff = qbm + eta_mu * qim; + Eeffm = E_eff0 * qeff; + Mutmp = pow(Eeffm * MUE_i, THEMU_i) + CS_i * (Pm / (Pm + Dm + 1.0e-14)); + Gmob = (1.0 + Mutmp + GR) * Rxcor; + + // 4.2.9 Drain-source channel current + // Channel length modulation + r1 = qim * qim1_1; + r2 = phit1 * (alpha * qim1_1); + temp = ln((1.0 + (Vds - dps) * inv_VP) / (1.0 + (Vdse - dps) * inv_VP)); + temp1 = ln(1.0 + Vdsx * inv_VP); + dL = ALP_i * temp; + GdL = 1.0 / (1.0 + dL + dL * dL); + dL1 = dL + ALP1_i * (qim1_1 * r1 * temp) + ALP2_i * (qbm * r2 * r2 * temp1); + FdL = (1.0 + dL1 + dL1 * dL1) * GdL; + // Velocity saturation + temp2 = qim * xitsb; + wsat = 100.0 * (temp2 / (100.0 + temp2)); + Gmob_dL = Gmob * GdL; + if (THESATG_i < 0) begin + temp = 1 / (1 - THESATG_i * wsat); + end else begin + temp = 1 + THESATG_i * wsat; + end + thesat1 = THESAT_i * (temp / Gmob_dL); + zsat = thesat1 * thesat1 * dps * dps; + if (CHNL_TYPE == `PMOS) begin + zsat = zsat / (1.0 + thesat1 * dps); + end + Gvsat = 0.5 * (Gmob_dL * (1.0 + sqrt(1.0 + 2.0 * zsat))); + Gvsatinv = 1.0 / Gvsat; + // Drain-source current + Ids = BET_i * (FdL * qim1 * dps * Gvsatinv); + + // 4.2.10 Variables for calculation of intrinsic charges and gate current + Voxm = xgm * phit1; + temp = Gmob_dL * Gvsatinv; + alpha1 = alpha * (1.0 + 0.5 * (zsat * temp * temp)); + H = temp * qim1 / alpha1; + + // 4.2.11 Impact-Ionization + if (SWIMPACT != 0) begin + delVsat = Vds - A3_i * dps; + if (delVsat > 0) begin + temp2 = A2_i * ((1.0 + A4_i * (sqrt(phib + Vsbstar) - sqrt_phib)) / delVsat); + `expl_low(-temp2, temp) + mavl = A1_i * (delVsat * temp); + Iimpact = Ids * mavl; + end + end + end // (xg > 0) + + // 4.2.12 Surface potential in gate overlap regions + if (((SWIGATE != 0) && (IGOV_i > 0)) || ((SWGIDL != 0) && (AGIDL_i > 0)) || (CGOV_i > 0)) begin + `sp_ov(xs_ov, xgs_ov) + `sp_ov(xd_ov, xgd_ov) + Vovs = -phit * (xgs_ov + xs_ov); + Vovd = -phit * (xgd_ov + xd_ov); + end + + // 4.2.13 Gate current + Igsov = 0.0; + Igdov = 0.0; + Igc = 0.0; + Igs = 0.0; + Igd = 0.0; + Igb = 0.0; + Igcs = 0.0; + Igcd = 0.0; + if (SWIGATE != 0) begin + if (IGOV_i > 0) begin + + // Gate-source overlap component of gate current + arg2mina = Vovs + Dov; + psi_t = `MINA(0.0, arg2mina, 0.01); + zg = sqrt(Vovs * Vovs + 1.0e-6) * inv_CHIB; + if (GC3_i < 0) begin + zg = `MINA(zg, GCQ, 1.0e-6); + end + arg1 = (3.0 + xs_ov + psi_t * inv_phit); + `expl(arg1, Dsi) + arg1 = -Vgs * inv_phit; + `expl(arg1, temp) + Dgate = Dsi * temp; + temp = BOV * (-1.5 + zg * (GC2_i + GC3_i * zg)); + if (temp > 0) begin + TP = `P3(temp); + end else begin + `expl_low(temp, TP) + end + Igsov = IGOV_i * (TP * ln((1.0 + Dsi) / (1.0 + Dgate))); + + // Gate-drain overlap component of gate current + arg2mina = Vovd + Dov; + psi_t = `MINA(0.0, arg2mina, 0.01); + zg = sqrt(Vovd * Vovd + 1.0e-6) * inv_CHIB; + if (GC3_i < 0) begin + zg = `MINA(zg, GCQ, 1.0e-6); + end + arg1 = (3.0 + xd_ov + psi_t * inv_phit); + `expl(arg1, Dsi) + arg1 = -Vgd * inv_phit; + `expl(arg1, temp) + Dgate = Dsi * temp; + temp = BOV * (-1.5 + zg * (GC2_i + GC3_i * zg)); + if (temp > 0) begin + TP = `P3(temp); + end else begin + `expl_low(temp, TP) + end + Igdov = IGOV_i * (TP * ln((1.0 + Dsi) / (1.0 + Dgate))); + end + + // Gate-channel component of gate current + if (IGINV_i > 0) begin + if (xg <= 0.0) begin + temp = pow(Vds / Vdsat_lim, AX_i); + Udse = Vds * pow(1.0 + temp, -inv_AX) * inv_phit1; + end + `expl_low(x_ds-Udse, temp) + Vm = Vsbstar + phit1 * (0.5 * x_ds - ln(0.5 * (1.0 + temp))); + + arg2mina = Voxm + Dch; + psi_t = `MINA(0.0, arg2mina, 0.01); + zg = sqrt(Voxm * Voxm + 1.0e-6) * inv_CHIB; + if (GC3_i < 0) begin + zg = `MINA(zg, GCQ, 1.0e-06); + end + arg1 = (x_m + (psi_t - alpha_b - Vm) * inv_phit1); + `expl(arg1,Dsi) + arg1 = -(Vgs + Vsbstar - Vm) * inv_phit1; + `expl(arg1,temp) + Dgate = Dsi * temp; + temp = BCH * (-1.5 + zg * (GC2_i + GC3_i * zg)); + if (temp > 0) begin + TP = `P3(temp); + end else begin + `expl_low(temp, TP) + end + Igc0 = IGINV_i * (TP * ln((1.0 + Dsi) / (1.0 + Dgate))); + + // Source/drain partitioning of gate-channel current + if ((xg <= 0) || ((GC2_i == 0) && (GC3_i == 0))) begin + igc = 1.0; + igcd_h = 0.5; + end else begin + temp = GC2_i + 2.0 * GC3_i * zg; + u0 = CHIB_i / (temp * BCH); + x = 0.5 * (dps / u0); + u0_div_H = u0 / H; + Bg = u0_div_H * (1.0 - u0_div_H) * 0.5; + Ag = 0.5 - 3.0 * Bg; + if (x < 1.0e-3) begin + xsq = x * x; + igc = 1.0 + xsq * (`oneSixth + u0_div_H * `oneThird + `oneSixth * (xsq * (0.05 + 0.2 * u0_div_H))); + igcd_h = 0.5 * igc - `oneSixth * (x * (1.0 + xsq * (0.4 * (Bg + 0.25) + 0.0285714285714 * (xsq * (0.125 + Bg))))); + end else begin + inv_x = 1.0 / x; + `expl(x, ex) + inv_ex = 1.0 / ex; + temp = ex - inv_ex; + temp2 = ex + inv_ex; + igc = 0.5 * ((1.0 - u0_div_H) * temp * inv_x + u0_div_H * temp2); + igcd_h = 0.5 * (igc - temp * (Bg - Ag * inv_x * inv_x) - Ag * temp2 * inv_x); + end + end + Sg = 0.5 * (1.0 + xg / sqrt(xg * xg + 1.0e-6)); + Igc = Igc0 * igc * Sg; + Igcd = Igc0 * igcd_h * Sg; + Igcs = Igc - Igcd; + Igb = Igc0 * igc * (1.0 - Sg); + end // (IGINV >0) + Igs = Igsov + Igcs; + Igd = Igdov + Igcd; + end // (SWIGATE != 0) + + // 4.2.14 GIDL/GISL current + Igidl = 0.0; + Igisl = 0.0; + if ((SWGIDL != 0) && (AGIDL_i > 0)) begin + + // GIDL current computation + if (Vovd < 0) begin + Vtovd = sqrt(Vovd * Vovd + CGIDL_i * CGIDL_i * (Vdb * Vdb) + 1.0e-6); + temp = -BGIDL_i / Vtovd; + `expl_low(temp, temp2) + Igidl = -AGIDL_i * (Vdb * Vovd * Vtovd * temp2); + end + + // GISL current computation + if (Vovs < 0) begin + Vtovs = sqrt(Vovs * Vovs + CGIDL_i * CGIDL_i * (Vsb * Vsb) + 1.0e-6); + temp = -BGIDL_i / Vtovs; + `expl_low(temp, temp2) + Igisl = -AGIDL_i * (Vsb * Vovs * Vtovs * temp2); + end + end // (SWGIDL != 0) + + end // evaluateStatic + + + ///////////////////////////////////////////////////////////////////////////// + // + // AC bias dependent quantities (calculations for charge contribs) + // + ///////////////////////////////////////////////////////////////////////////// + + begin : evaluateDynamic + + // 4.2.16 Quantum mechanical corrections + COX_qm = COX_i; + if (qq > 0.0) begin + COX_qm = COX_i / (1.0 + qq * pow(qeff * qeff + qlim2, -1.0 * `oneSixth)); + end + + // 4.2.17 Intrinsic charge model + if (xg <= 0.0) begin + QG = Voxm; + QI = 0.0; + QD = 0.0; + QB = QG; + end else begin + Fj = 0.5 * (dps / H); + Fj2 = Fj * Fj; + QCLM = (1.0 - GdL) * (qim - 0.5 * (alpha * dps)); + QG = Voxm + 0.5 * (eta_p * dps * (Fj * GdL * `oneThird - 1.0 + GdL)); + temp = alpha * dps * `oneSixth; + QI = GdL * (qim + temp * Fj) + QCLM; + QD = 0.5 * (GdL * GdL * (qim - temp * (1.0 - Fj - 0.2 * Fj2)) + QCLM * (1.0 + GdL)); + QB = QG - QI; + end + Qg = QG * COX_qm; + Qd = -QD * COX_qm; + Qb = -QB * COX_qm; + + // 4.2.18 Extrinsic charge model + Qgs_ov = CGOV_i * Vovs; + Qgd_ov = CGOV_i * Vovd; + Qgb_ov = CGBOV_i * Vgb; + + // Outer fringe charge + Qfgs = CFR_i * Vgs; + Qfgd = CFR_i * Vgd; +`ifdef NQSmodel + + // Variables for NQS model + Gp = 0.0; + Gp2 = 0.0; + a_factrp = 0.0; + marginp = 0.0; + if (SWNQS_i != 0) begin + if (xg <= 0.0) begin + ym = 0.5; + pd = 1.0; + Gp = Gf; + end else begin + ym = 0.5 * ( 1.0 + 0.25 * (dps / H)); + pd = xgm / (xg - x_m); + Gp = Gf / pd; + end + Gp2 = Gp * Gp; + a_factrp = 1.0 + Gp * `invSqrt2; + marginp = 1e-5 * a_factrp; + end +`endif // NQSmodel + + end // evaluateDynamic + + + ///////////////////////////////////////////////////////////////////////////// + // + // JUNCAP2 contribs + // + ///////////////////////////////////////////////////////////////////////////// + + begin : evaluateStaticDynamic + + // Source side + VAK = Vjuns; + VMAX = VMAXS; + vbimin = vbimins; + vfmin = vfmins; + vch = vchs; + vbbtlim = vbbtlims; + `juncapcommon(ABSOURCE_i,LSSOURCE_i,LGSOURCE_i,isjunbot,qsjunbot,isjunsti,qsjunsti,isjungat,qsjungat) + + // Drain side + VAK = Vjund; + VMAX = VMAXD; + vbimin = vbimind; + vfmin = vfmind; + vch = vchd; + vbbtlim = vbbtlimd; + `juncapcommon(ABDRAIN_i,LSDRAIN_i,LGDRAIN_i,idjunbot,qdjunbot,idjunsti,qdjunsti,idjungat,qdjungat) + +`ifdef NQSmodel + // Set initial conditions for NQS model + `include "PSP102_InitNQS.include" + +`endif // NQSmodel + end // evaluateStaticDynamic + + + ///////////////////////////////////////////////////////////////////////////// + // + // Current contribs + // + ///////////////////////////////////////////////////////////////////////////// + + begin : loadStatic + + // 4.2.15 Total terminal currents + + // Intrinsic MOSFET current + Idse = MULT_i * Ids; + + // Gate (tunneling) current components + Igbe = MULT_i * Igb; + Igse = MULT_i * Igs; + Igde = MULT_i * Igd; + + // GIDL/GISL current + Igidle = MULT_i * Igidl; + Igisle = MULT_i * Igisl; + + // Impact ionization current + Iimpacte = MULT_i * Iimpact; + + // JUNCAP2 + isjun = MULT_i * (ABSOURCE_i * isjunbot + LSSOURCE_i * isjunsti + LGSOURCE_i * isjungat); + idjun = MULT_i * (ABDRAIN_i * idjunbot + LSDRAIN_i * idjunsti + LGDRAIN_i * idjungat); + + // Convert back for NMOS-PMOS and Source-Drain interchange + if (sigVds > 0) begin + I(D, `Bint) <+ CHNL_TYPE * (Iimpacte + Igidle); + I(D, S) <+ CHNL_TYPE * Idse; + I(`Gint, S) <+ CHNL_TYPE * Igse; + I(`Gint, D) <+ CHNL_TYPE * Igde; + I(S, `Bint) <+ CHNL_TYPE * Igisle; + end else begin + I(S, `Bint) <+ CHNL_TYPE * (Iimpacte + Igidle); + I(S, D) <+ CHNL_TYPE * Idse; + I(`Gint, D) <+ CHNL_TYPE * Igse; + I(`Gint, S) <+ CHNL_TYPE * Igde; + I(D, `Bint) <+ CHNL_TYPE * Igisle; + end + I(`Gint, `Bint) <+ CHNL_TYPE * Igbe; + I(`Bjs, S) <+ CHNL_TYPE * isjun; + I(`Bjd, D) <+ CHNL_TYPE * idjun; +`ifdef NQSmodel + I(G, GP) <+ Vrg * ggate; + I(BP, BI) <+ Vrbulk * gbulk; + I(BS, BI) <+ Vrjuns * gjuns; + I(BD, BI) <+ Vrjund * gjund; + I(B, BI) <+ Vrwell * gwell; +`endif // NQSmodel + + I(D, S) <+ Vds * `GMIN; + + end // loadStatic + + ///////////////////////////////////////////////////////////////////////////// + // + // ddt() contribs from charges (Note: MULT is handled explicitly) + // + ///////////////////////////////////////////////////////////////////////////// + + begin : loadDynamic +`ifdef NQSmodel + + // Calculate NQS charge contributions + `include "PSP102_ChargesNQS.include" +`endif // NQSmodel + + // 4.2.19 Total terminal charges + + // Intrinsic MOSFET charges + Qg = MULT_i * Qg; + Qb = MULT_i * Qb; + Qd = MULT_i * Qd; + Qs = -(Qg + Qb + Qd); + + // Total outerFringe + overlap for + // gate-source and gate-drain. + Qfgs = MULT_i * (Qfgs + Qgs_ov); + Qfgd = MULT_i * (Qfgd + Qgd_ov); + + // Gate-bulk overlap charge + Qgb_ov = MULT_i * Qgb_ov; + + // JUNCAP2 + qsjun = MULT_i * (ABSOURCE_i * qsjunbot + LSSOURCE_i * qsjunsti + LGSOURCE_i * qsjungat); + qdjun = MULT_i * (ABDRAIN_i * qdjunbot + LSDRAIN_i * qdjunsti + LGDRAIN_i * qdjungat); + + // Convert back (undo S-D interchange) + if (sigVds < 0) begin + temp = Qd; // Qd <--> Qs + Qd = Qs; + Qs = temp; + temp = Qfgd; // Qfgd <--> Qfgs + Qfgd = Qfgs; + Qfgs = temp; + end + + I(`Gint, S) <+ ddt(CHNL_TYPE * Qg); + I(`Bint, S) <+ ddt(CHNL_TYPE * Qb); + I(D, S) <+ ddt(CHNL_TYPE * Qd); + I(`Gint, S) <+ ddt(CHNL_TYPE * Qfgs); + I(`Gint, D) <+ ddt(CHNL_TYPE * Qfgd); + I(`Gint, `Bint) <+ ddt(CHNL_TYPE * Qgb_ov); + I(`Bjs, S) <+ ddt(CHNL_TYPE * qsjun); + I(`Bjd, D) <+ ddt(CHNL_TYPE * qdjun); + + end // loadDynamic + + + ///////////////////////////////////////////////////////////////////////////// + // + // Noise + // + ///////////////////////////////////////////////////////////////////////////// + + begin : noise + + // 4.2.20 Noise variable calculation + Sfl = 0.0; + mid = 0.0; + mig = 0.0; + migid = 0.0; + c_igid = 0.0; + CGeff = COX_qm * eta_p; + sqid = 0.0; + sqig = 0.0; + if ((xg > 0.0) && (MULT_i > 0) && (BET_i > 0)) begin + N1 = Cox_over_q * alpha * phit; + Nm1 = Cox_over_q * qim1; + Delta_N1 = Cox_over_q * (alpha * dps); + Sfl = (NFA_i - NFB_i * N1 + NFC_i * (N1 * N1)) * ln((Nm1 + 0.5 * Delta_N1) / (Nm1 - 0.5 * Delta_N1)); + Sfl = Sfl + (NFB_i + NFC_i * (Nm1 - 2.0 * N1)) * Delta_N1; + Sfl = Sfl_prefac * Ids * Gvsatinv * Sfl / N1; + + H0 = qim1 / alpha; + t1 = qim / qim1; + sqt2 = 0.5 * `oneSixth * (dps / H0); + t2 = sqt2 * sqt2; + r = H0 / H - 1.0; + lc = `CLIP_LOW(1.0 - 12 * (r * t2), 1e-20); + lcinv2 = 1 / (lc * lc); + g_ideal = BET_i * (FdL * qim1 * Gvsatinv); + CGeff = Gvsat * Gvsat * COX_qm * eta_p / (Gmob_dL * Gmob_dL); + mid = t1 + 12 * t2 - 24 * ((1.0 + t1) * t2 * r); + mid = `CLIP_LOW(mid, 1e-40); + mid = g_ideal * lcinv2 * mid; + mig = t1 / 12 - t2 * (t1 + 0.2 - 12 * t2) - 1.6 * (t2 * (t1 + 1.0 - 12 * t2) * r); + mig = `CLIP_LOW(mig, 1e-40); + mig = lcinv2 / g_ideal * mig; + migid = lcinv2 * sqt2 * (1.0 - 12 * t2 - (t1 + 19.2 * t2 - 12 * (t1 * t2)) * r); + sqid = sqrt(MULT_i * nt * mid); + sqig = sqrt(MULT_i * nt / mig); + c_igid = (sqid == 0) ? 0.0 : (migid * sqig / sqid); // = migid / sqrt(mig * mid); + c_igid = `CLIP_BOTH(c_igid, 0.0, 1.0); + end + shot_igsx = 2.0 * `QELE * abs(Igse); + shot_igdx = 2.0 * `QELE * abs(Igde); + shot_iavl = 2.0 * `QELE * ((mavl + 1) * abs(Iimpacte)); + // JUNCAP2 + sjnoisex = 2.0 * `QELE * abs(isjun); + djnoisex = 2.0 * `QELE * abs(idjun); + if (sigVds > 0) begin + shot_igs = shot_igsx; + shot_igd = shot_igdx; + sjnoise = sjnoisex; + djnoise = djnoisex + shot_iavl; + end else begin + shot_igs = shot_igdx; + shot_igd = shot_igsx; + sjnoise = sjnoisex + shot_iavl; + djnoise = djnoisex; + end +`ifdef NQSmodel + rgatenoise = nt0 * ggate; + rbulknoise = nt0 * gbulk; + rjunsnoise = nt0 * gjuns; + rjundnoise = nt0 * gjund; + rwellnoise = nt0 * gwell; +`endif // NQSmodel + + // Important note: + // In Verilog-A, correlated noise sources can only be implemented by using two additional + // internal nodes (NOI and NOI2). When implementing PSP in a circuit simlutor, it is + // generally not necessary to retain these internal nodes and therefore (for execution + // speed reasons) should be avoided. + + // Noise contribs + I(NOI2) <+ V(NOI2); + I(NOI2) <+ white_noise(c_igid); + I(NOII) <+ white_noise(sqig * sqig * (1.0 - c_igid)); + I(NOII) <+ -sqig * V(NOI2); + I(NOIR) <+ V(NOIR); + I(NOIC) <+ ddt(mig * CGeff * V(NOIC)); + I(D,S) <+ flicker_noise(MULT_i * Sfl, 1.0); + I(D,S) <+ white_noise(sqid * sqid * (1.0 - c_igid)); + I(D,S) <+ sqid * V(NOI2); + I(`Gint,S)<+ ddt(0.5 * ((1.0 + sigVds) * mig * CGeff * V(NOIC))); + I(`Gint,D)<+ ddt(0.5 * ((1.0 - sigVds) * mig * CGeff * V(NOIC))); + I(`Gint,S)<+ white_noise(shot_igs); + I(`Gint,D)<+ white_noise(shot_igd); + // JUNCAP2 + I(`Bjs,S) <+ white_noise(sjnoise, "shot"); + I(`Bjd,D) <+ white_noise(djnoise, "shot"); +`ifdef NQSmodel + // Parasitic resistances + I(GP,G) <+ white_noise(rgatenoise); + I(BP,BI) <+ white_noise(rbulknoise); + I(BS,BI) <+ white_noise(rjunsnoise); + I(BD,BI) <+ white_noise(rjundnoise); + I(B ,BI) <+ white_noise(rwellnoise); +`endif // NQSmodel + end // noise + + +`ifdef insideADMS // OPinfo + ///////////////////////////////////////////////////////////////////////////// + // + // Operating point info + // + ///////////////////////////////////////////////////////////////////////////// + + begin : OPinfo + + // The output variables defined below are currently not available in + // Verilog-A, but only in the SiMKit-C-code which was generated from + // this source. Similar functionality will be available in Verilog-A + // from Verilog-A version 2.2 onwards. However, a different syntax is + // to be used (see Verilog AMS language reference manual, version 2.2, + // november 2004, Accellera). + + // Auxiliary variables + id_op = Idse + Iimpacte + Igidle - Igde; + is = -Idse + Igisle - Igse; + ig = Igse + Igde + Igbe; + ib = -Iimpacte - Igbe - Igidle - Igisle; + + P_D = 1 + 0.25 * (Gf * kp); + facvsb0 = phib + 2 * phit1; + facvsb = Vsbstar + facvsb0; + sig1k = 2 * `PI * 1000 * CGeff; + sig1k = sig1k * sig1k * mig; + + + //////////////////////////////////////////////////////////////////////////////////// + // + // Actual operation point output variables + // + //////////////////////////////////////////////////////////////////////////////////// + + // Note: In this section (and ONLY in this section) `drain' always refers to + // the highest-potential end of the channel. Therefore, care has to be + // taken for derivatives w.r.t. terminal voltages when sigVds == -1. + + sdint = sigVds; + ctype = CHNL_TYPE; + + if (sigVds < 0) begin + // All variables in the actual model refering to junctions are + // not subject to SD-interchange. In the OP-output variables, + // SD-interchange is also done for the junctions, so that's + // what is happening here. Similar precautions have to be taken + // for those variables that are derivatives w.r.t. voltage branches + ise = is - idjun; + ige = ig; + ide = id_op - isjun; + ibe = ib + isjun + idjun; + ids = Idse; + idb = Iimpacte + Igidle - isjun; + isb = Igisle - idjun; + igs = Igse; + igd = Igde; + igb = Igbe; + igcs = MULT_i * Igcs; + igcd = MULT_i * Igcd; + iavl = Iimpacte; + igisl = Igisle; + igidl = Igidle; + + ijsbot = MULT_i * ABDRAIN_i * idjunbot; + ijsgat = MULT_i * LGDRAIN_i * idjungat; + ijssti = MULT_i * LSDRAIN_i * idjunsti; + ijs = ijsbot + ijsgat + ijssti; + ijdbot = MULT_i * ABSOURCE_i * isjunbot; + ijdgat = MULT_i * LGSOURCE_i * isjungat; + ijdsti = MULT_i * LSSOURCE_i * isjunsti; + ijd = ijdbot + ijdgat + ijdsti; + + vds = Vds; + vgs = Vgs; + vsb = Vsb; + vto = VFB_i + P_D * facvsb0 + Gf * sqrt(phit1 * facvsb0); + vts = VFB_i + P_D * facvsb - Vsbstar + Gf * sqrt(phit1 * facvsb ); + vth = vts - delVg; + vgt = vgs - vth; + vdss = Vdsat; + vsat = Vds - vdss; + + temp = Idse + Iimpacte + Igidle - Igde - isjun; // Total drain-current + gm = ddx( CHNL_TYPE * temp, V(`Gint, S)); + gmb = ddx(-CHNL_TYPE * temp, V(S, `Bint)); + gds = ddx(-CHNL_TYPE * temp, V(D, S)); + gds = gds - (gm + gmb); + + gjs = ddx(-idjun, V(D, `Bjd)); + gjd = ddx(-isjun, V(S, `Bjs)); + + css = ddx( CHNL_TYPE * Qd, V(D, S)); + csg = ddx(-CHNL_TYPE * Qd, V(`Gint, S)); + csb = ddx( CHNL_TYPE * Qd, V(S, `Bint)); + csd = css - csg - csb; + cgs = ddx(-CHNL_TYPE * Qg, V(D, S)); + cgg = ddx( CHNL_TYPE * Qg, V(`Gint, S)); + cgb = ddx( CHNL_TYPE * Qg, V(S, `Bint)); + cgd = cgg - cgs - cgb; + cds = ddx(-CHNL_TYPE * Qs, V(D, S)); + cdg = ddx(-CHNL_TYPE * Qs, V(`Gint, S)); + cdb = ddx( CHNL_TYPE * Qs, V(S, `Bint)); + cdd = cdg + cds + cdb; + cbs = ddx(-CHNL_TYPE * Qb, V(D, S)); + cbg = ddx(-CHNL_TYPE * Qb, V(`Gint, S)); + cbb = ddx(-CHNL_TYPE * Qb, V(S, `Bint)); + cbd = cbb - cbs - cbg; + cgsol = ddx(-CHNL_TYPE * Qfgd, V(D, S)); + cgdol = ddx( CHNL_TYPE * Qfgs, V(`Gint, S)); + + cjsbot = ddx(-MULT_i * CHNL_TYPE * ABDRAIN_i * qdjunbot, V(D, `Bjd)); + cjsgat = ddx(-MULT_i * CHNL_TYPE * LGDRAIN_i * qdjungat, V(D, `Bjd)); + cjssti = ddx(-MULT_i * CHNL_TYPE * LSDRAIN_i * qdjunsti, V(D, `Bjd)); + cjs = cjsbot + cjsgat + cjssti; + cjdbot = ddx(-MULT_i * CHNL_TYPE * ABSOURCE_i * qsjunbot, V(S, `Bjs)); + cjdgat = ddx(-MULT_i * CHNL_TYPE * LGSOURCE_i * qsjungat, V(S, `Bjs)); + cjdsti = ddx(-MULT_i * CHNL_TYPE * LSSOURCE_i * qsjunsti, V(S, `Bjs)); + cjd = cjdbot + cjdgat + cjdsti; + end else begin + ise = is - isjun; + ige = ig; + ide = id_op - idjun; + ibe = ib + isjun + idjun; + ids = Idse; + idb = Iimpacte + Igidle - idjun; + isb = Igisle - isjun; + igs = Igse; + igd = Igde; + igb = Igbe; + igcs = MULT_i * Igcs; + igcd = MULT_i * Igcd; + iavl = Iimpacte; + igisl = Igisle; + igidl = Igidle; + + ijsbot = MULT_i * ABSOURCE_i * isjunbot; + ijsgat = MULT_i * LGSOURCE_i * isjungat; + ijssti = MULT_i * LSSOURCE_i * isjunsti; + ijs = ijsbot + ijsgat + ijssti; + ijdbot = MULT_i * ABDRAIN_i * idjunbot; + ijdgat = MULT_i * LGDRAIN_i * idjungat; + ijdsti = MULT_i * LSDRAIN_i * idjunsti; + ijd = ijdbot + ijdgat + ijdsti; + + vds = Vds; + vgs = Vgs; + vsb = Vsb; + vto = VFB_i + P_D * facvsb0 + Gf * sqrt(phit1 * facvsb0); + vts = VFB_i + P_D * facvsb - Vsbstar + Gf * sqrt(phit1 * facvsb ); + vth = vts - delVg; + vgt = vgs - vth; + vdss = Vdsat; + vsat = Vds - vdss; + + temp = Idse + Iimpacte + Igidle - Igde - idjun; + gm = ddx( CHNL_TYPE * temp, V(`Gint, S)); + gmb = ddx(-CHNL_TYPE * temp, V(S, `Bint)); + gds = ddx( CHNL_TYPE * temp, V(D, S)); + + gjs = ddx(-isjun, V(S, `Bjs)); + gjd = ddx(-idjun, V(D, `Bjd)); + + cdd = ddx( CHNL_TYPE * Qd, V(D, S)); + cdg = ddx(-CHNL_TYPE * Qd, V(`Gint, S)); + cdb = ddx( CHNL_TYPE * Qd, V(S, `Bint)); + cds = cdd - cdg - cdb; + cgd = ddx(-CHNL_TYPE * Qg, V(D, S)); + cgg = ddx( CHNL_TYPE * Qg, V(`Gint, S)); + cgb = ddx( CHNL_TYPE * Qg, V(S, `Bint)); + cgs = cgg - cgd - cgb; + csd = ddx(-CHNL_TYPE * Qs, V(D, S)); + csg = ddx(-CHNL_TYPE * Qs, V(`Gint, S)); + csb = ddx( CHNL_TYPE * Qs, V(S, `Bint)); + css = csg + csd + csb; + cbd = ddx(-CHNL_TYPE * Qb, V(D, S)); + cbg = ddx(-CHNL_TYPE * Qb, V(`Gint, S)); + cbb = ddx(-CHNL_TYPE * Qb, V(S, `Bint)); + cbs = cbb - cbd - cbg; + cgsol = ddx( CHNL_TYPE * Qfgs, V(`Gint, S)); + cgdol = ddx(-CHNL_TYPE * Qfgd, V(D, S)); + + cjsbot = ddx(-MULT_i * CHNL_TYPE * ABSOURCE_i * qsjunbot, V(S, `Bjs)); + cjsgat = ddx(-MULT_i * CHNL_TYPE * LGSOURCE_i * qsjungat, V(S, `Bjs)); + cjssti = ddx(-MULT_i * CHNL_TYPE * LSSOURCE_i * qsjunsti, V(S, `Bjs)); + cjs = cjsbot + cjsgat + cjssti; + cjdbot = ddx(-MULT_i * CHNL_TYPE * ABDRAIN_i * qdjunbot, V(D, `Bjd)); + cjdgat = ddx(-MULT_i * CHNL_TYPE * LGDRAIN_i * qdjungat, V(D, `Bjd)); + cjdsti = ddx(-MULT_i * CHNL_TYPE * LSDRAIN_i * qdjunsti, V(D, `Bjd)); + cjd = cjdbot + cjdgat + cjdsti; + end +`ifdef LocalModel + weff = 0; + leff = 0; +`else + weff = WE; + leff = LE; +`endif + u = (abs(gds) < 1e-18) ? 0 : (gm / gds); + rout = (abs(gds) < 1e-18) ? 0 : (1.0 / gds); + vearly = (abs(gds) < 1e-18) ? 0 : (ide / gds); + beff = (abs(vgt) < 1e-12) ? 0 : (2 * abs(ide) / (vgt * vgt)); + fug = (abs(cgg + cgsol + cgdol) < 1e-30) ? 0.0 : gm / (2 * `PI * (cgg + cgsol + cgdol)); + + sfl = Sfl; + sqrtsff = (abs(gm) < 1e-18) ? 0 : (sqrt(MULT_i * Sfl / 1000) / gm); + sqrtsfw = (abs(gm) < 1e-18) ? 0 : (sqid / gm); + sid = sqid * sqid; + sig = MULT_i * nt * sig1k / (1 + sig1k * mig); + cigid = c_igid; + fknee = (sid == 0) ? 0 : Sfl / sid; + sigs = shot_igsx; + sigd = shot_igdx; + siavl = shot_iavl; + if (sigVds < 0) begin + ssi = djnoisex; + sdi = sjnoisex; + end else begin + ssi = sjnoisex; + sdi = djnoisex; + end + end // OPinfo +`endif // OPinfo + + end // analogBlock diff --git a/src/spicelib/devices/adms/psp102/admsva/PSP102_nqs_macrodefs.include b/src/spicelib/devices/adms/psp102/admsva/PSP102_nqs_macrodefs.include new file mode 100644 index 000000000..e14819dfe --- /dev/null +++ b/src/spicelib/devices/adms/psp102/admsva/PSP102_nqs_macrodefs.include @@ -0,0 +1,117 @@ +//====================================================================================== +//====================================================================================== +// Filename: PSP102_nqs_macrodefs.include +//====================================================================================== +//====================================================================================== +// +// (c) Copyright 2007, All Rights Reserved, NXP Semiconductors +// +// +// Version: 102.1, April 2007 (Simkit 2.5) +// +//====================================================================================== +//====================================================================================== +// +// Further information can be found in the file readme.txt +// + +////////////////////////////////////////// +// +// Macros used in PSP-NQS +// +////////////////////////////////////////// + +// Function to calculate bulk charge from surface potential +`define PhiToQb(phi,Qb_tmp) \ +if (abs(phi) <= margin) \ + Qb_tmp = -0.70710678 * phi * Gf * (1.0 - `oneSixth * phi * (1.0 - `oneSixth * phi)); \ +else begin \ + `expl((-phi), temp) \ + Qb_tmp = Gf * sqrt(temp + phi - 1.0); \ + if (phi > margin) \ + Qb_tmp = -Qb_tmp; \ +end + + +// Function used in fq-macro +`define PhiTod2Qis(xphi,d2Qis) \ +if (abs(xphi) <= margin) begin \ + Qb_tmp = -0.70710678 * xphi * Gf * (1.0 - `oneSixth * xphi * (1.0 - `oneSixth * xphi)); \ + dQbs = -0.70710678 * Gf * (1.0 - `oneThird * xphi * (1.0 - 0.25 * xphi)); \ + d2Qis = -0.235702 * Gf * (1.0 - 0.5 * xphi); \ +end else begin \ + `expl((-xphi),temp) \ + Qb_tmp = Gf * sqrt(temp + xphi - 1.0); \ + if (xphi > margin) \ + Qb_tmp = -Qb_tmp; \ + dQbs = 0.5 * Gf2 * (1.0 - temp) / Qb_tmp; \ + d2Qis = (dQbs * dQbs - 0.5 * Gf * Gf) / Qb_tmp + dQbs; \ +end + + + +// Function used in QiToPhi +`define sps(sp, xg) \ +if (abs(xg) <= marginp) begin \ + sp = xg / a_factrp; \ +end else begin \ + if (xg < -marginp) begin \ + NQS_yg = -xg; \ + NQS_z = 1.25 * NQS_yg / a_factrp; \ + NQS_eta = (NQS_z + 10.0 - sqrt((NQS_z - 6.0) * (NQS_z - 6.0) + 64.0)) * 0.5; \ + NQS_a = (NQS_yg - NQS_eta) * (NQS_yg - NQS_eta) + Gp2 * (NQS_eta + 1.0); \ + NQS_c = 2.0 * (NQS_yg - NQS_eta) - Gp2; \ + NQS_tau = ln(NQS_a / Gp2) - NQS_eta; \ + `sigma(NQS_a, NQS_c, NQS_tau, NQS_eta, NQS_y0) \ + `expl(NQS_y0, NQS_D0) \ + NQS_xi = 1.0 - Gp2 * NQS_D0 * 0.5; \ + NQS_p = 2.0 * (NQS_yg - NQS_y0) + Gp2 * (NQS_D0 - 1.0); \ + NQS_q = (NQS_yg - NQS_y0) * (NQS_yg - NQS_y0) + Gp2 * (NQS_y0 + 1.0 - NQS_D0); \ + NQS_temp = NQS_p * NQS_p - 4.0 * NQS_xi * NQS_q; \ + NQS_w = 2.0 * NQS_q / (NQS_p + sqrt(NQS_temp)); \ + sp = -(NQS_y0 + NQS_w); \ + end else begin \ + NQS_xg1 = 1.0 / ( 1.25 + 7.32464877560822e-01 * Gp); \ + NQS_A_fac = (1.25 * a_factrp * NQS_xg1 - 1.0) * NQS_xg1; \ + NQS_xbar = xg / a_factrp * (1.0 + NQS_A_fac * xg); \ + `expl(-NQS_xbar, NQS_temp) \ + NQS_w = 1.0 - NQS_temp; \ + NQS_x0 = xg + Gp2 * 0.5 - Gp * sqrt(xg + Gp2 * 0.25 - NQS_w); \ + `expl((-NQS_x0), NQS_D0) \ + NQS_xi = 1.0 - Gp2 * 0.5 * NQS_D0; \ + NQS_p = 2.0 * (xg - NQS_x0) + Gp2 * (1.0 - NQS_D0); \ + NQS_q = (xg - NQS_x0) * (xg - NQS_x0) - Gp2 * (NQS_x0 - 1.0 + NQS_D0); \ + NQS_temp = NQS_p * NQS_p - 4.0 * NQS_xi * NQS_q; \ + NQS_u = 2.0 * NQS_q / (NQS_p + sqrt(NQS_temp)); \ + sp = NQS_x0 + NQS_u; \ + end \ +end + + +// Function to calculate surface potential from inversion charge +`define QiToPhi(Qi,xg,xphi) \ + temp = Qi / pd + xg; \ + `sps(xphi,temp) + +// Calculation of fk +`define fq(Qi,xg,dQy,d2Qy,fk) \ + `QiToPhi(Qi, xg, xphi) \ + `PhiTod2Qis(xphi, d2Qis) \ + dQis = pd - dQbs; \ + dQis_1 = 1.0 / dQis; \ + fQi = Qi * dQis_1 - 1.0; \ + dfQi = (1.0 - Qi * d2Qis * dQis_1 * dQis_1) * dQis_1; \ + fk0 = dfQi * dQy * dQy + fQi * d2Qy; \ + dpsy2 = dQy * dQy * dQis_1 * dQis_1; \ + zsat = thesat2 * dpsy2; \ + if (CHNL_TYPE == `PMOS) \ + zsat = zsat / (1.0 + thesat1 * dps); \ + temp = sqrt(1.0 + 2.0 * zsat); \ + Fvsat = 2.0 / (1.0 + temp); \ + temp1 = d2Qy - dpsy2 * d2Qis; \ + fk = Fvsat * (fk0 - zsat * fQi * temp1 * Fvsat / temp); + + +// Interpolation of surface potential along channel +`define Phiy(y) \ + x_m + H * (1.0 - sqrt(1.0 - 2.0 * dps / H * ((y) - ym))) * inv_phit1 diff --git a/src/spicelib/devices/adms/psp102/admsva/SIMKIT_macrodefs.include b/src/spicelib/devices/adms/psp102/admsva/SIMKIT_macrodefs.include new file mode 100644 index 000000000..3ad24b402 --- /dev/null +++ b/src/spicelib/devices/adms/psp102/admsva/SIMKIT_macrodefs.include @@ -0,0 +1,122 @@ +//====================================================================================== +//====================================================================================== +// Filename: SIMKIT_macrodefs.include +//====================================================================================== +//====================================================================================== +// +// (c) Copyright 2007, All Rights Reserved, NXP Semiconductors +// +// +// Version: 102.1, April 2007 (Simkit 2.5) +// +//====================================================================================== +//====================================================================================== +// +// Further information can be found in the file readme.txt +// + +////////////////////////////////////////////////////////////// +// +// General macros and constants for compact va-models +// +////////////////////////////////////////////////////////////// + +`define VERS "0.0" +`define VREV "0.0" +`define VERSreal 0.0 +`define VREVreal 0.0 + +`define CLIP_LOW(val,min) ((val)>(min)?(val):(min)) +`define CLIP_HIGH(val,max) ((val)<(max)?(val):(max)) +`define CLIP_BOTH(val,min,max) ((val)>(min)?((val)<(max)?(val):(max)):(min)) + + // Note 1: In this va-code, the `P-macro is defined such that its argument + // is ignored during compilation; in this source code it acts as + // a comment + // Note 2: In this va-code, the "from" keyword in the parameter + // list is not used. Silent clipping is used instead. One could enable + // the Verilog-A range checking by redefining the `from-macro below. +// `define P(txt) + `define P(txt) (*txt*) + `define AT_MODEL + `define AT_INSTANCE + `define AT_NOISE + `define from(lower,upper) +// `define from(lower,upper) from[lower:upper] + +// Some functions +`define MAX(x,y) ((x)>(y)?(x):(y)) +`define MIN(x,y) ((x)<(y)?(x):(y)) + +// Mathematical constants +`define PI 3.1415926535897931 +`define SQRTPI 1.77245385090551603 + +// Physical constants +`define KELVINCONVERSION 273.15 +`define KBOL 1.3806505E-23 +`define QELE 1.6021918E-19 +`define HBAR 1.05457168E-34 +`define MELE 9.1093826E-31 +`define EPSSI 1.045E-10 + +// Other constants +`define oneThird 3.3333333333333333e-01 +`define twoThirds 6.6666666666666667e-01 + +// Constants needed in safe exponential function (called "expl") +`define se 4.6051701859880916e+02 +`define se05 2.3025850929940458e+02 +`define ke 1.0e-200 +`define ke05 1.0e-100 +`define keinv 1.0e200 +`define ke05inv 1.0e100 + +///////////////////////////////////////////////////////////////////////////// +// +// Macro definitions. +// +// Note that because variables in macros are not locally scoped, +// the intermediate variables used in the macros below must be +// explicitly declared in the main code. +// +///////////////////////////////////////////////////////////////////////////// + + +// P3 3rd order polynomial expansion of exp() +`define P3(u) (1.0 + (u) * (1.0 + 0.5 * ((u) * (1.0 + (u) * `oneThird)))) + + +// expl exp() with 3rd order polynomial extrapolation +// for very low values (exp_low), very high +// values (exp_high), or both (expl), to avoid overflows +// and underflows and retain C-3 continuity +`define expl(x, res) \ +if (abs(x) < `se05) begin\ + res = exp(x); \ +end else begin \ + if ((x) < -`se05) begin\ + res = `ke05 / `P3(-`se05 - (x)); \ + end else begin\ + res = `ke05inv * `P3((x) - `se05); \ + end \ +end + +`define expl_low(x, res) \ +if ((x) > -`se05) begin\ + res = exp(x); \ +end else begin\ + res = `ke05 / `P3(-`se05 - (x)); \ +end + +`define expl_high(x, res) \ +if ((x) < `se05) begin\ + res = exp(x); \ +end else begin \ + res = `ke05inv * `P3((x) - `se05); \ +end + +`define swap(a, b) \ +temp = a; \ +a = b; \ +b = temp; diff --git a/src/spicelib/devices/adms/psp102/admsva/psp102.va b/src/spicelib/devices/adms/psp102/admsva/psp102.va new file mode 100644 index 000000000..d319e4b4b --- /dev/null +++ b/src/spicelib/devices/adms/psp102/admsva/psp102.va @@ -0,0 +1,48 @@ +//====================================================================================== +//====================================================================================== +// Filename: psp102.va +//====================================================================================== +//====================================================================================== +// +// (c) Copyright 2007, All Rights Reserved, NXP Semiconductors +// +// +// Version: 102.1, April 2007 (Simkit 2.5) +// +//====================================================================================== +//====================================================================================== +// +// Further information can be found in the file readme.txt +// + +`include "discipline.h" + +`include "SIMKIT_macrodefs.include" + +`include "JUNCAP200_macrodefs.include" + +`include "PSP102_macrodefs.include" + + +///////////////////////////////////////////////////////////////////////////// +// +// PSP global model code +// +///////////////////////////////////////////////////////////////////////////// + +// `undef LocalModel +// `define Binning + +module PSP102VA(D, G, S, B) + +`P( + desc = "PSP MOSFET Model" + version = `VERS + revision = `VREV + simkit:name = "psp1020" + simkit:desc = "psp_1020" +); + +`include "PSP102_module.include" + +endmodule diff --git a/src/spicelib/devices/adms/psp102/admsva/readme.ngspice b/src/spicelib/devices/adms/psp102/admsva/readme.ngspice new file mode 100644 index 000000000..3f5e3d431 --- /dev/null +++ b/src/spicelib/devices/adms/psp102/admsva/readme.ngspice @@ -0,0 +1,8 @@ +ngspice customizations of package psp102.1 +------------------------------------------ + +- Mon Apr 30 15:28:25 WEDT 2007 (Berlin) + o renamed 'initializeModel/initializeInstance' to 'initial_model/initial_instance'. + (this issue should go away when auto-partionning done in adms.) + o redefined macro P(txt) in order to 'see' instance parameters + o status: psp code created by adms compiles diff --git a/src/spicelib/devices/adms/psp102/admsva/readme.txt b/src/spicelib/devices/adms/psp102/admsva/readme.txt new file mode 100644 index 000000000..5df9f5b4d --- /dev/null +++ b/src/spicelib/devices/adms/psp102/admsva/readme.txt @@ -0,0 +1,120 @@ +====================================================================================== +====================================================================================== + + --------------------------- + Verilog-A definition of PSP + --------------------------- + + + (c) Copyright 2007, All Rights Reserved, NXP Semiconductors + + + Version: PSP 102.1 (including JUNCAP2 200.2), April 2007 (Simkit 2.5) + +====================================================================================== +====================================================================================== + + Authors: G.D.J. Smit, A.J. Scholten, and D.B.M. Klaassen (NXP Semiconductors Research) + R. van Langevelde (Philips Research) + G. Gildenblat, X. Li, and W. Wu (The Arizona State University) + + + +The most recent version of the model code, the documentation, and contact information +can be found on: + + http://PSPmodel.asu.edu/ +or + http://www.nxp.com/Philips_Models/ + +====================================================================================== +====================================================================================== + +This package consists of several files: + + - readme.txt This file + + - psp102.va Main file for global ("geometrical") model + - psp102b.va Main file for global binning model + - psp102e.va Main file for local ("electrical") model + - psp102_nqs.va Main file for global ("geometrical") model with NQS-effects + - psp102b_nqs.va Main file for global binning model with NQS-effects + - psp102e_nqs.va Main file for local ("electrical") model with NQS-effects + - juncap200.va Main file for JUNCAP2 stand-alone model + + - SIMKIT_macrodefs.include Common macro definitions + - PSP102_macrodefs.include Macro definitions for PSP + - PSP102_module.include Actual model code for intrinsic MOS model + - PSP102_binning.include Geometry scaling equation for binning + - PSP102_binpars.include Parameterlist for global PSP binning model + - PSP102_nqs_macrodefs.include Macro definitions for PSP-NQS + - PSP102_InitNQS.include PSP-NQS initialization code + - PSP102_ChargesNQS.include Calculation of NQS-charge contributions + - JUNCAP200_macrodefs.include Macro definitions for JUNCAP2 model + - JUNCAP200_parlist.include JUNCAP2 parameter list + - JUNCAP200_varlist.include JUNCAP2 variable declarations + - JUNCAP200_InitModel.include JUNCAP2 model initialization code + +====================================================================================== +====================================================================================== + +Usage +----- + +Depending which model one wants to use, one should compile one of the seven .va-files +(psp102.va, psp102b.va, psp102e.va, psp102_nqs.va, psp102b_nqs.va, psp102e_nqs.va, and +juncap200.va). The module names are "PSP102VA" and "PSPNQS102VA" for the global PSP-model +(QS and NQS, respectively), and similarly "PSP102BVA" and "PSPNQS102BVA" for the binning +PSP-model, "PSP102EVA" and "PSPNQS102EVA" for the local PSP-model, and "JUNCAP200" for +the JUNCAP2-model. + + +====================================================================================== +====================================================================================== + +Release notes va-code of PSP 102.1, including JUNCAP2 200.2 (April 2007) +------------------------------------------------------------------------ + +Focus in this release has been on improving the simulation speed of PSP and JUNCAP2. +The model equations in this release of PSP 102.1 are identical to those in the +October 2006 release. This version features some minor impelementation changes +w.r.t. the previous release. + +The main changes have been in the SiMKit version generated from this verilog-A +implementation: improvements in the automatic C-code generation process +and compilation of the C-code. The result is reflected in the SiMKit 2.5 version of +PSP, which shows a very significant simulation speed improvement w.r.t SiMKit 2.4. + +The minor implementation changes in the verilog-A code will have some positive effect +on the simulation speed of the verilog-A version as well. Note, however, that the +simulation speed of the verilog-A version of PSP and the improvement w.r.t. the +previous version strongly depend on the verilog-A compiler used. + +PSP 102.1 is backwards compatible with the previous version, PSP 102.0. + + +====================================================================================== +====================================================================================== + +The functionality of the Verilog-A code in this package is the same as that of the +C-code, which is contained in SIMKIT version 2.5. Note that Operating Point information +is available only in the C-code, not in Verilog-A code. + + +The PSP-NQS model is provided as Verilog-A code. In SiMKit 2.5, a test version of +the PSP-NQS model is included (identical to that in SiMKit 2.4). This implementation +circumvents the problem of the SpectreVerilog-A-generated C-code being too large to +compile. Moreover, it is computationally more efficient as it uses less rows in the +simulator matrix. On the other hand, this implementation has some known limitations. +More information is available from the authors. Further improvements are expected in +future releases. + + +This Verilog-A code of PSP is primarily intended as a source for C-code generation +using ADMS. Most of the testing has been done on the C-code which was generated from it. + + +The authors want to thank Laurent Lemaitre and Colin McAndrew (Freescale) +for their help with ADMS and the implementation of the model code. Geoffrey +Coram (Analog Devices) is acknowledged for useful comments on the Verilog-A +code.