/models-ngspice17/bsim3v1/b3v1check.c

https://github.com/henjo/gnucap-models · C · 364 lines · 309 code · 35 blank · 20 comment · 60 complexity · c16f9bfbb7de842fabf8fd832ac70266 MD5 · raw file

  1. /**********
  2. * Copyright 1990 Regents of the University of California. All rights reserved.
  3. * File: b3v1check.c
  4. * Author: 1995 Min-Chie Jeng and Mansun Chan.
  5. * Modified by Paolo Nenzi 2002
  6. **********/
  7. /*
  8. * Release Notes:
  9. * BSIM3v3.1, Released by yuhua 96/12/08
  10. */
  11. #include "ngspice.h"
  12. #include "cktdefs.h"
  13. #include "bsim3v1def.h"
  14. #include "trandefs.h"
  15. #include "const.h"
  16. #include "sperror.h"
  17. #include "devdefs.h"
  18. #include "suffix.h"
  19. int
  20. BSIM3v1checkModel(BSIM3v1model *model, BSIM3v1instance *here, CKTcircuit *ckt)
  21. {
  22. struct bsim3v1SizeDependParam *pParam;
  23. int Fatal_Flag = 0;
  24. FILE *fplog;
  25. if ((fplog = fopen("b3v3_1check.log", "w")) != NULL)
  26. { pParam = here->pParam;
  27. fprintf(fplog, "BSIM3V3.1 Parameter Check\n");
  28. fprintf(fplog, "Model = %s\n", model->BSIM3v1modName);
  29. fprintf(fplog, "W = %g, L = %g\n", here->BSIM3v1w, here->BSIM3v1l);
  30. if (pParam->BSIM3v1nlx < -pParam->BSIM3v1leff)
  31. { fprintf(fplog, "Fatal: Nlx = %g is less than -Leff.\n",
  32. pParam->BSIM3v1nlx);
  33. printf("Fatal: Nlx = %g is less than -Leff.\n",
  34. pParam->BSIM3v1nlx);
  35. Fatal_Flag = 1;
  36. }
  37. if (model->BSIM3v1tox <= 0.0)
  38. { fprintf(fplog, "Fatal: Tox = %g is not positive.\n",
  39. model->BSIM3v1tox);
  40. printf("Fatal: Tox = %g is not positive.\n", model->BSIM3v1tox);
  41. Fatal_Flag = 1;
  42. }
  43. if (pParam->BSIM3v1npeak <= 0.0)
  44. { fprintf(fplog, "Fatal: Nch = %g is not positive.\n",
  45. pParam->BSIM3v1npeak);
  46. printf("Fatal: Nch = %g is not positive.\n",
  47. pParam->BSIM3v1npeak);
  48. Fatal_Flag = 1;
  49. }
  50. if (pParam->BSIM3v1nsub <= 0.0)
  51. { fprintf(fplog, "Fatal: Nsub = %g is not positive.\n",
  52. pParam->BSIM3v1nsub);
  53. printf("Fatal: Nsub = %g is not positive.\n",
  54. pParam->BSIM3v1nsub);
  55. Fatal_Flag = 1;
  56. }
  57. if (pParam->BSIM3v1ngate < 0.0)
  58. { fprintf(fplog, "Fatal: Ngate = %g is not positive.\n",
  59. pParam->BSIM3v1ngate);
  60. printf("Fatal: Ngate = %g Ngate is not positive.\n",
  61. pParam->BSIM3v1ngate);
  62. Fatal_Flag = 1;
  63. }
  64. if (pParam->BSIM3v1ngate > 1.e25)
  65. { fprintf(fplog, "Fatal: Ngate = %g is too high.\n",
  66. pParam->BSIM3v1ngate);
  67. printf("Fatal: Ngate = %g Ngate is too high\n",
  68. pParam->BSIM3v1ngate);
  69. Fatal_Flag = 1;
  70. }
  71. if (pParam->BSIM3v1xj <= 0.0)
  72. { fprintf(fplog, "Fatal: Xj = %g is not positive.\n",
  73. pParam->BSIM3v1xj);
  74. printf("Fatal: Xj = %g is not positive.\n", pParam->BSIM3v1xj);
  75. Fatal_Flag = 1;
  76. }
  77. if (pParam->BSIM3v1dvt1 < 0.0)
  78. { fprintf(fplog, "Fatal: Dvt1 = %g is negative.\n",
  79. pParam->BSIM3v1dvt1);
  80. printf("Fatal: Dvt1 = %g is negative.\n", pParam->BSIM3v1dvt1);
  81. Fatal_Flag = 1;
  82. }
  83. if (pParam->BSIM3v1dvt1w < 0.0)
  84. { fprintf(fplog, "Fatal: Dvt1w = %g is negative.\n",
  85. pParam->BSIM3v1dvt1w);
  86. printf("Fatal: Dvt1w = %g is negative.\n", pParam->BSIM3v1dvt1w);
  87. Fatal_Flag = 1;
  88. }
  89. if (pParam->BSIM3v1w0 == -pParam->BSIM3v1weff)
  90. { fprintf(fplog, "Fatal: (W0 + Weff) = 0 cauing divided-by-zero.\n");
  91. printf("Fatal: (W0 + Weff) = 0 cauing divided-by-zero.\n");
  92. Fatal_Flag = 1;
  93. }
  94. if (pParam->BSIM3v1dsub < 0.0)
  95. { fprintf(fplog, "Fatal: Dsub = %g is negative.\n", pParam->BSIM3v1dsub);
  96. printf("Fatal: Dsub = %g is negative.\n", pParam->BSIM3v1dsub);
  97. Fatal_Flag = 1;
  98. }
  99. if (pParam->BSIM3v1b1 == -pParam->BSIM3v1weff)
  100. { fprintf(fplog, "Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n");
  101. printf("Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n");
  102. Fatal_Flag = 1;
  103. }
  104. if (pParam->BSIM3v1u0temp <= 0.0)
  105. { fprintf(fplog, "Fatal: u0 at current temperature = %g is not positive.\n", pParam->BSIM3v1u0temp);
  106. printf("Fatal: u0 at current temperature = %g is not positive.\n",
  107. pParam->BSIM3v1u0temp);
  108. Fatal_Flag = 1;
  109. }
  110. /* Check delta parameter */
  111. if (pParam->BSIM3v1delta < 0.0)
  112. { fprintf(fplog, "Fatal: Delta = %g is less than zero.\n",
  113. pParam->BSIM3v1delta);
  114. printf("Fatal: Delta = %g is less than zero.\n", pParam->BSIM3v1delta);
  115. Fatal_Flag = 1;
  116. }
  117. if (pParam->BSIM3v1vsattemp <= 0.0)
  118. { fprintf(fplog, "Fatal: Vsat at current temperature = %g is not positive.\n", pParam->BSIM3v1vsattemp);
  119. printf("Fatal: Vsat at current temperature = %g is not positive.\n",
  120. pParam->BSIM3v1vsattemp);
  121. Fatal_Flag = 1;
  122. }
  123. /* Check Rout parameters */
  124. if (pParam->BSIM3v1pclm <= 0.0)
  125. { fprintf(fplog, "Fatal: Pclm = %g is not positive.\n", pParam->BSIM3v1pclm);
  126. printf("Fatal: Pclm = %g is not positive.\n", pParam->BSIM3v1pclm);
  127. Fatal_Flag = 1;
  128. }
  129. if (pParam->BSIM3v1drout < 0.0)
  130. { fprintf(fplog, "Fatal: Drout = %g is negative.\n", pParam->BSIM3v1drout);
  131. printf("Fatal: Drout = %g is negative.\n", pParam->BSIM3v1drout);
  132. Fatal_Flag = 1;
  133. }
  134. if (model->BSIM3v1unitLengthSidewallJctCap > 0.0 ||
  135. model->BSIM3v1unitLengthGateSidewallJctCap > 0.0)
  136. {
  137. if (here->BSIM3v1drainPerimeter < pParam->BSIM3v1weff)
  138. { fprintf(fplog, "Warning: Pd = %g is less than W.\n",
  139. here->BSIM3v1drainPerimeter);
  140. printf("Warning: Pd = %g is less than W.\n",
  141. here->BSIM3v1drainPerimeter);
  142. here->BSIM3v1drainPerimeter =pParam->BSIM3v1weff;
  143. }
  144. if (here->BSIM3v1sourcePerimeter < pParam->BSIM3v1weff)
  145. { fprintf(fplog, "Warning: Ps = %g is less than W.\n",
  146. here->BSIM3v1sourcePerimeter);
  147. printf("Warning: Ps = %g is less than W.\n",
  148. here->BSIM3v1sourcePerimeter);
  149. here->BSIM3v1sourcePerimeter =pParam->BSIM3v1weff;
  150. }
  151. }
  152. /* Check capacitance parameters */
  153. if (pParam->BSIM3v1clc < 0.0)
  154. { fprintf(fplog, "Fatal: Clc = %g is negative.\n", pParam->BSIM3v1clc);
  155. printf("Fatal: Clc = %g is negative.\n", pParam->BSIM3v1clc);
  156. Fatal_Flag = 1;
  157. }
  158. if (model->BSIM3v1paramChk ==1)
  159. {
  160. /* Check L and W parameters */
  161. if (pParam->BSIM3v1leff <= 5.0e-8)
  162. { fprintf(fplog, "Warning: Leff = %g may be too small.\n",
  163. pParam->BSIM3v1leff);
  164. printf("Warning: Leff = %g may be too small.\n",
  165. pParam->BSIM3v1leff);
  166. }
  167. if (pParam->BSIM3v1leffCV <= 5.0e-8)
  168. { fprintf(fplog, "Warning: Leff for CV = %g may be too small.\n",
  169. pParam->BSIM3v1leffCV);
  170. printf("Warning: Leff for CV = %g may be too small.\n",
  171. pParam->BSIM3v1leffCV);
  172. }
  173. if (pParam->BSIM3v1weff <= 1.0e-7)
  174. { fprintf(fplog, "Warning: Weff = %g may be too small.\n",
  175. pParam->BSIM3v1weff);
  176. printf("Warning: Weff = %g may be too small.\n",
  177. pParam->BSIM3v1weff);
  178. }
  179. if (pParam->BSIM3v1weffCV <= 1.0e-7)
  180. { fprintf(fplog, "Warning: Weff for CV = %g may be too small.\n",
  181. pParam->BSIM3v1weffCV);
  182. printf("Warning: Weff for CV = %g may be too small.\n",
  183. pParam->BSIM3v1weffCV);
  184. }
  185. /* Check threshold voltage parameters */
  186. if (pParam->BSIM3v1nlx < 0.0)
  187. { fprintf(fplog, "Warning: Nlx = %g is negative.\n", pParam->BSIM3v1nlx);
  188. printf("Warning: Nlx = %g is negative.\n", pParam->BSIM3v1nlx);
  189. }
  190. if (model->BSIM3v1tox < 1.0e-9)
  191. { fprintf(fplog, "Warning: Tox = %g is less than 10A.\n",
  192. model->BSIM3v1tox);
  193. printf("Warning: Tox = %g is less than 10A.\n", model->BSIM3v1tox);
  194. }
  195. if (pParam->BSIM3v1npeak <= 1.0e15)
  196. { fprintf(fplog, "Warning: Nch = %g may be too small.\n",
  197. pParam->BSIM3v1npeak);
  198. printf("Warning: Nch = %g may be too small.\n",
  199. pParam->BSIM3v1npeak);
  200. }
  201. else if (pParam->BSIM3v1npeak >= 1.0e21)
  202. { fprintf(fplog, "Warning: Nch = %g may be too large.\n",
  203. pParam->BSIM3v1npeak);
  204. printf("Warning: Nch = %g may be too large.\n",
  205. pParam->BSIM3v1npeak);
  206. }
  207. if (pParam->BSIM3v1nsub <= 1.0e14)
  208. { fprintf(fplog, "Warning: Nsub = %g may be too small.\n",
  209. pParam->BSIM3v1nsub);
  210. printf("Warning: Nsub = %g may be too small.\n",
  211. pParam->BSIM3v1nsub);
  212. }
  213. else if (pParam->BSIM3v1nsub >= 1.0e21)
  214. { fprintf(fplog, "Warning: Nsub = %g may be too large.\n",
  215. pParam->BSIM3v1nsub);
  216. printf("Warning: Nsub = %g may be too large.\n",
  217. pParam->BSIM3v1nsub);
  218. }
  219. if ((pParam->BSIM3v1ngate > 0.0) &&
  220. (pParam->BSIM3v1ngate <= 1.e18))
  221. { fprintf(fplog, "Warning: Ngate = %g is less than 1.E18cm^-3.\n",
  222. pParam->BSIM3v1ngate);
  223. printf("Warning: Ngate = %g is less than 1.E18cm^-3.\n",
  224. pParam->BSIM3v1ngate);
  225. }
  226. if (pParam->BSIM3v1dvt0 < 0.0)
  227. { fprintf(fplog, "Warning: Dvt0 = %g is negative.\n",
  228. pParam->BSIM3v1dvt0);
  229. printf("Warning: Dvt0 = %g is negative.\n", pParam->BSIM3v1dvt0);
  230. }
  231. if (fabs(1.0e-6 / (pParam->BSIM3v1w0 + pParam->BSIM3v1weff)) > 10.0)
  232. { fprintf(fplog, "Warning: (W0 + Weff) may be too small.\n");
  233. printf("Warning: (W0 + Weff) may be too small.\n");
  234. }
  235. /* Check subthreshold parameters */
  236. if (pParam->BSIM3v1nfactor < 0.0)
  237. { fprintf(fplog, "Warning: Nfactor = %g is negative.\n",
  238. pParam->BSIM3v1nfactor);
  239. printf("Warning: Nfactor = %g is negative.\n", pParam->BSIM3v1nfactor);
  240. }
  241. if (pParam->BSIM3v1cdsc < 0.0)
  242. { fprintf(fplog, "Warning: Cdsc = %g is negative.\n",
  243. pParam->BSIM3v1cdsc);
  244. printf("Warning: Cdsc = %g is negative.\n", pParam->BSIM3v1cdsc);
  245. }
  246. if (pParam->BSIM3v1cdscd < 0.0)
  247. { fprintf(fplog, "Warning: Cdscd = %g is negative.\n",
  248. pParam->BSIM3v1cdscd);
  249. printf("Warning: Cdscd = %g is negative.\n", pParam->BSIM3v1cdscd);
  250. }
  251. /* Check DIBL parameters */
  252. if (pParam->BSIM3v1eta0 < 0.0)
  253. { fprintf(fplog, "Warning: Eta0 = %g is negative.\n",
  254. pParam->BSIM3v1eta0);
  255. printf("Warning: Eta0 = %g is negative.\n", pParam->BSIM3v1eta0);
  256. }
  257. /* Check Abulk parameters */
  258. if (fabs(1.0e-6 / (pParam->BSIM3v1b1 + pParam->BSIM3v1weff)) > 10.0)
  259. { fprintf(fplog, "Warning: (B1 + Weff) may be too small.\n");
  260. printf("Warning: (B1 + Weff) may be too small.\n");
  261. }
  262. /* Check Saturation parameters */
  263. if (pParam->BSIM3v1a2 < 0.01)
  264. { fprintf(fplog, "Warning: A2 = %g is too small. Set to 0.01.\n", pParam->BSIM3v1a2);
  265. printf("Warning: A2 = %g is too small. Set to 0.01.\n",
  266. pParam->BSIM3v1a2);
  267. pParam->BSIM3v1a2 = 0.01;
  268. }
  269. else if (pParam->BSIM3v1a2 > 1.0)
  270. { fprintf(fplog, "Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n",
  271. pParam->BSIM3v1a2);
  272. printf("Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n",
  273. pParam->BSIM3v1a2);
  274. pParam->BSIM3v1a2 = 1.0;
  275. pParam->BSIM3v1a1 = 0.0;
  276. }
  277. if (pParam->BSIM3v1rdsw < 0.0)
  278. { fprintf(fplog, "Warning: Rdsw = %g is negative. Set to zero.\n",
  279. pParam->BSIM3v1rdsw);
  280. printf("Warning: Rdsw = %g is negative. Set to zero.\n",
  281. pParam->BSIM3v1rdsw);
  282. pParam->BSIM3v1rdsw = 0.0;
  283. pParam->BSIM3v1rds0 = 0.0;
  284. }
  285. else if ((pParam->BSIM3v1rds0 > 0.0) && (pParam->BSIM3v1rds0 < 0.001))
  286. { fprintf(fplog, "Warning: Rds at current temperature = %g is less than 0.001 ohm. Set to zero.\n",
  287. pParam->BSIM3v1rds0);
  288. printf("Warning: Rds at current temperature = %g is less than 0.001 ohm. Set to zero.\n",
  289. pParam->BSIM3v1rds0);
  290. pParam->BSIM3v1rds0 = 0.0;
  291. }
  292. if (pParam->BSIM3v1vsattemp < 1.0e3)
  293. { fprintf(fplog, "Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM3v1vsattemp);
  294. printf("Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM3v1vsattemp);
  295. }
  296. if (pParam->BSIM3v1pdibl1 < 0.0)
  297. { fprintf(fplog, "Warning: Pdibl1 = %g is negative.\n",
  298. pParam->BSIM3v1pdibl1);
  299. printf("Warning: Pdibl1 = %g is negative.\n", pParam->BSIM3v1pdibl1);
  300. }
  301. if (pParam->BSIM3v1pdibl2 < 0.0)
  302. { fprintf(fplog, "Warning: Pdibl2 = %g is negative.\n",
  303. pParam->BSIM3v1pdibl2);
  304. printf("Warning: Pdibl2 = %g is negative.\n", pParam->BSIM3v1pdibl2);
  305. }
  306. /* Check overlap capacitance parameters */
  307. if (model->BSIM3v1cgdo < 0.0)
  308. { fprintf(fplog, "Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM3v1cgdo);
  309. printf("Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM3v1cgdo);
  310. model->BSIM3v1cgdo = 0.0;
  311. }
  312. if (model->BSIM3v1cgso < 0.0)
  313. { fprintf(fplog, "Warning: cgso = %g is negative. Set to zero.\n", model->BSIM3v1cgso);
  314. printf("Warning: cgso = %g is negative. Set to zero.\n", model->BSIM3v1cgso);
  315. model->BSIM3v1cgso = 0.0;
  316. }
  317. if (model->BSIM3v1cgbo < 0.0)
  318. { fprintf(fplog, "Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM3v1cgbo);
  319. printf("Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM3v1cgbo);
  320. model->BSIM3v1cgbo = 0.0;
  321. }
  322. }/* loop for the parameter check for warning messages */
  323. fclose(fplog);
  324. }
  325. else
  326. { fprintf(stderr, "Warning: Can't open log file. Parameter checking skipped.\n");
  327. }
  328. return(Fatal_Flag);
  329. }