📄 b4geo.c
字号:
/**** BSIM4.4.0 Released by Xuemei(Jane) Xi 03/04/2004 ****//********** * Copyright 2003 Regents of the University of California. All rights reserved. * File: b4geo.c of BSIM4.4.0. * Author: 2000 Weidong Liu * Authors: 2001- Xuemei Xi, Jin He, Kanyu Cao, Mohan Dunga, Mansun Chan, Ali Niknejad, Chenming Hu. * Project Director: Prof. Chenming Hu. **********/#include "ngspice.h"/* * WDLiu: * This subrutine is a special module to process the geometry dependent * parasitics for BSIM4, which calculates Ps, Pd, As, Ad, and Rs and Rd * for multi-fingers and varous GEO and RGEO options. */intBSIM4RdsEndIso(double, double, double, double, double, double, int, int, double *);intBSIM4RdsEndSha(double, double, double, double, double, double, int, int, double *);intBSIM4NumFingerDiff(nf, minSD, nuIntD, nuEndD, nuIntS, nuEndS)int minSD;double nf, *nuIntD, *nuEndD, *nuIntS, *nuEndS;{int NF; NF = (int)nf; if ((NF%2) != 0) { *nuEndD = *nuEndS = 1.0; *nuIntD = *nuIntS = 2.0 * MAX((nf - 1.0) / 2.0, 0.0); } else { if (minSD == 1) /* minimize # of source */ { *nuEndD = 2.0; *nuIntD = 2.0 * MAX((nf / 2.0 - 1.0), 0.0); *nuEndS = 0.0; *nuIntS = nf; } else { *nuEndD = 0.0; *nuIntD = nf; *nuEndS = 2.0; *nuIntS = 2.0 * MAX((nf / 2.0 - 1.0), 0.0); } }return 0;}intBSIM4PAeffGeo(nf, geo, minSD, Weffcj, DMCG, DMCI, DMDG, Ps, Pd, As, Ad)int geo, minSD; double Weffcj, DMCG, DMCI, DMDG;double nf, *Ps, *Pd, *As, *Ad;{double T0, T1, T2;double ADiso, ADsha, ADmer, ASiso, ASsha, ASmer;double PDiso, PDsha, PDmer, PSiso, PSsha, PSmer;double nuIntD = 0.0, nuEndD = 0.0, nuIntS = 0.0, nuEndS = 0.0; if (geo < 9) /* For geo = 9 and 10, the numbers of S/D diffusions already known */ BSIM4NumFingerDiff(nf, minSD, &nuIntD, &nuEndD, &nuIntS, &nuEndS); T0 = DMCG + DMCI; T1 = DMCG + DMCG; T2 = DMDG + DMDG; PSiso = PDiso = T0 + T0 + Weffcj; PSsha = PDsha = T1; PSmer = PDmer = T2; ASiso = ADiso = T0 * Weffcj; ASsha = ADsha = DMCG * Weffcj; ASmer = ADmer = DMDG * Weffcj; switch(geo) { case 0: *Ps = nuEndS * PSiso + nuIntS * PSsha; *Pd = nuEndD * PDiso + nuIntD * PDsha; *As = nuEndS * ASiso + nuIntS * ASsha; *Ad = nuEndD * ADiso + nuIntD * ADsha; break; case 1: *Ps = nuEndS * PSiso + nuIntS * PSsha; *Pd = (nuEndD + nuIntD) * PDsha; *As = nuEndS * ASiso + nuIntS * ASsha; *Ad = (nuEndD + nuIntD) * ADsha; break; case 2: *Ps = (nuEndS + nuIntS) * PSsha; *Pd = nuEndD * PDiso + nuIntD * PDsha; *As = (nuEndS + nuIntS) * ASsha; *Ad = nuEndD * ADiso + nuIntD * ADsha; break; case 3: *Ps = (nuEndS + nuIntS) * PSsha; *Pd = (nuEndD + nuIntD) * PDsha; *As = (nuEndS + nuIntS) * ASsha; *Ad = (nuEndD + nuIntD) * ADsha; break; case 4: *Ps = nuEndS * PSiso + nuIntS * PSsha; *Pd = nuEndD * PDmer + nuIntD * PDsha; *As = nuEndS * ASiso + nuIntS * ASsha; *Ad = nuEndD * ADmer + nuIntD * ADsha; break; case 5: *Ps = (nuEndS + nuIntS) * PSsha; *Pd = nuEndD * PDmer + nuIntD * PDsha; *As = (nuEndS + nuIntS) * ASsha; *Ad = nuEndD * ADmer + nuIntD * ADsha; break; case 6: *Ps = nuEndS * PSmer + nuIntS * PSsha; *Pd = nuEndD * PDiso + nuIntD * PDsha; *As = nuEndS * ASmer + nuIntS * ASsha; *Ad = nuEndD * ADiso + nuIntD * ADsha; break; case 7: *Ps = nuEndS * PSmer + nuIntS * PSsha; *Pd = (nuEndD + nuIntD) * PDsha; *As = nuEndS * ASmer + nuIntS * ASsha; *Ad = (nuEndD + nuIntD) * ADsha; break; case 8: *Ps = nuEndS * PSmer + nuIntS * PSsha; *Pd = nuEndD * PDmer + nuIntD * PDsha; *As = nuEndS * ASmer + nuIntS * ASsha; *Ad = nuEndD * ADmer + nuIntD * ADsha; break; case 9: /* geo = 9 and 10 happen only when nf = even */ *Ps = PSiso + (nf - 1.0) * PSsha; *Pd = nf * PDsha; *As = ASiso + (nf - 1.0) * ASsha; *Ad = nf * ADsha; break; case 10: *Ps = nf * PSsha; *Pd = PDiso + (nf - 1.0) * PDsha; *As = nf * ASsha; *Ad = ADiso + (nf - 1.0) * ADsha; break; default: printf("Warning: Specified GEO = %d not matched\n", geo); }return 0;}intBSIM4RdseffGeo(nf, geo, rgeo, minSD, Weffcj, Rsh, DMCG, DMCI, DMDG, Type, Rtot)int geo, rgeo, minSD, Type;double nf, Weffcj, Rsh, DMCG, DMCI, DMDG;double *Rtot;{double Rint=0.0, Rend = 0.0;double nuIntD = 0.0, nuEndD = 0.0, nuIntS = 0.0, nuEndS = 0.0; if (geo < 9) /* since geo = 9 and 10 only happen when nf = even */ { BSIM4NumFingerDiff(nf, minSD, &nuIntD, &nuEndD, &nuIntS, &nuEndS); /* Internal S/D resistance -- assume shared S or D and all wide contacts */ if (Type == 1) { if (nuIntS == 0.0) Rint = 0.0; else Rint = Rsh * DMCG / ( Weffcj * nuIntS); } else { if (nuIntD == 0.0) Rint = 0.0; else Rint = Rsh * DMCG / ( Weffcj * nuIntD); } } /* End S/D resistance -- geo dependent */ switch(geo) { case 0: if (Type == 1) BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndS, rgeo, 1, &Rend); else BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndD, rgeo, 0, &Rend); break; case 1: if (Type == 1) BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndS, rgeo, 1, &Rend); else BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndD, rgeo, 0, &Rend); break; case 2: if (Type == 1) BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndS, rgeo, 1, &Rend); else BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndD, rgeo, 0, &Rend); break; case 3: if (Type == 1) BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndS, rgeo, 1, &Rend); else BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndD, rgeo, 0, &Rend); break; case 4: if (Type == 1) BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndS, rgeo, 1, &Rend); else Rend = Rsh * DMDG / Weffcj; break; case 5: if (Type == 1) BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndS, rgeo, 1, &Rend); else Rend = Rsh * DMDG / (Weffcj * nuEndD); break; case 6: if (Type == 1) Rend = Rsh * DMDG / Weffcj; else BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndD, rgeo, 0, &Rend); break; case 7: if (Type == 1) Rend = Rsh * DMDG / (Weffcj * nuEndS); else BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEndD, rgeo, 0, &Rend); break; case 8: Rend = Rsh * DMDG / Weffcj; break; case 9: /* all wide contacts assumed for geo = 9 and 10 */ if (Type == 1) { Rend = 0.5 * Rsh * DMCG / Weffcj; if (nf == 2.0) Rint = 0.0; else Rint = Rsh * DMCG / (Weffcj * (nf - 2.0)); } else { Rend = 0.0; Rint = Rsh * DMCG / (Weffcj * nf); } break; case 10: if (Type == 1) { Rend = 0.0; Rint = Rsh * DMCG / (Weffcj * nf); } else { Rend = 0.5 * Rsh * DMCG / Weffcj;; if (nf == 2.0) Rint = 0.0; else Rint = Rsh * DMCG / (Weffcj * (nf - 2.0)); } break; default: printf("Warning: Specified GEO = %d not matched\n", geo); } if (Rint <= 0.0) *Rtot = Rend; else if (Rend <= 0.0) *Rtot = Rint; else *Rtot = Rint * Rend / (Rint + Rend);if(*Rtot==0.0) printf("Warning: Zero resistance returned from RdseffGeo\n");return 0;}intBSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEnd, rgeo, Type, Rend)double Weffcj, Rsh, DMCG, DMCI, DMDG;int rgeo, Type;double nuEnd, *Rend;{ if (Type == 1) { switch(rgeo) { case 1: case 2: case 5: if (nuEnd == 0.0) *Rend = 0.0; else *Rend = Rsh * DMCG / (Weffcj * nuEnd); break; case 3: case 4: case 6: if ((DMCG + DMCI) == 0.0) printf("(DMCG + DMCI) can not be equal to zero\n"); if (nuEnd == 0.0) *Rend = 0.0; else *Rend = Rsh * Weffcj / (3.0 * nuEnd * (DMCG + DMCI)); break; default: printf("Warning: Specified RGEO = %d not matched\n", rgeo); } } else { switch(rgeo) { case 1: case 3: case 7: if (nuEnd == 0.0) *Rend = 0.0; else *Rend = Rsh * DMCG / (Weffcj * nuEnd); break; case 2: case 4: case 8: if ((DMCG + DMCI) == 0.0) printf("(DMCG + DMCI) can not be equal to zero\n"); if (nuEnd == 0.0) *Rend = 0.0; else *Rend = Rsh * Weffcj / (3.0 * nuEnd * (DMCG + DMCI)); break; default: printf("Warning: Specified RGEO = %d not matched\n", rgeo); } }return 0;}intBSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEnd, rgeo, Type, Rend)double Weffcj, Rsh, DMCG, DMCI, DMDG;int rgeo, Type;double nuEnd, *Rend;{ if (Type == 1) { switch(rgeo) { case 1: case 2: case 5: if (nuEnd == 0.0) *Rend = 0.0; else *Rend = Rsh * DMCG / (Weffcj * nuEnd); break; case 3: case 4: case 6: if (DMCG == 0.0) printf("DMCG can not be equal to zero\n"); if (nuEnd == 0.0) *Rend = 0.0; else *Rend = Rsh * Weffcj / (6.0 * nuEnd * DMCG); break; default: printf("Warning: Specified RGEO = %d not matched\n", rgeo); } } else { switch(rgeo) { case 1: case 3: case 7: if (nuEnd == 0.0) *Rend = 0.0; else *Rend = Rsh * DMCG / (Weffcj * nuEnd); break; case 2: case 4: case 8: if (DMCG == 0.0) printf("DMCG can not be equal to zero\n"); if (nuEnd == 0.0) *Rend = 0.0; else *Rend = Rsh * Weffcj / (6.0 * nuEnd * DMCG); break; default: printf("Warning: Specified RGEO = %d not matched\n", rgeo); } }return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -