1 /**********
2 Copyright 2013 Dietmar Warning. All rights reserved.
3 Author:   2013 Dietmar Warning
4 **********/
5 
6 #include "ngspice/ngspice.h"
7 #include "ngspice/cktdefs.h"
8 #include "bsim4v7def.h"
9 #include "ngspice/trandefs.h"
10 #include "ngspice/sperror.h"
11 #include "ngspice/suffix.h"
12 #include "ngspice/cpdefs.h"
13 
14 
15 int
BSIM4v7soaCheck(CKTcircuit * ckt,GENmodel * inModel)16 BSIM4v7soaCheck(CKTcircuit *ckt, GENmodel *inModel)
17 {
18     BSIM4v7model *model = (BSIM4v7model *) inModel;
19     BSIM4v7instance *here;
20     double vgs, vgd, vgb, vds, vbs, vbd;    /* actual mos voltages */
21     int maxwarns;
22     static int warns_vgs = 0, warns_vgd = 0, warns_vgb = 0, warns_vds = 0, warns_vbs = 0, warns_vbd = 0;
23 
24     if (!ckt) {
25         warns_vgs = 0;
26         warns_vgd = 0;
27         warns_vgb = 0;
28         warns_vds = 0;
29         warns_vbs = 0;
30         warns_vbd = 0;
31         return OK;
32     }
33 
34     maxwarns = ckt->CKTsoaMaxWarns;
35 
36     for (; model; model = BSIM4v7nextModel(model)) {
37 
38         for (here = BSIM4v7instances(model); here; here = BSIM4v7nextInstance(here)) {
39 
40             vgs = ckt->CKTrhsOld [here->BSIM4v7gNodePrime] -
41                   ckt->CKTrhsOld [here->BSIM4v7sNodePrime];
42 
43             vgd = ckt->CKTrhsOld [here->BSIM4v7gNodePrime] -
44                   ckt->CKTrhsOld [here->BSIM4v7dNodePrime];
45 
46             vgb = ckt->CKTrhsOld [here->BSIM4v7gNodePrime] -
47                   ckt->CKTrhsOld [here->BSIM4v7bNodePrime];
48 
49             vds = ckt->CKTrhsOld [here->BSIM4v7dNodePrime] -
50                   ckt->CKTrhsOld [here->BSIM4v7sNodePrime];
51 
52             vbs = ckt->CKTrhsOld [here->BSIM4v7bNodePrime] -
53                   ckt->CKTrhsOld [here->BSIM4v7sNodePrime];
54 
55             vbd = ckt->CKTrhsOld [here->BSIM4v7bNodePrime] -
56                   ckt->CKTrhsOld [here->BSIM4v7dNodePrime];
57 
58             if (!model->BSIM4v7vgsrMaxGiven) {
59                 if (fabs(vgs) > model->BSIM4v7vgsMax)
60                     if (warns_vgs < maxwarns) {
61                         soa_printf(ckt, (GENinstance*) here,
62                                    "Vgs=%g has exceeded Vgs_max=%g\n",
63                                    vgs, model->BSIM4v7vgsMax);
64                         warns_vgs++;
65                     }
66                 if (!model->BSIM4v7vgbMaxGiven) {
67                     if (fabs(vgb) > model->BSIM4v7vgsMax)
68                         if (warns_vgb < maxwarns) {
69                             soa_printf(ckt, (GENinstance*) here,
70                                        "Vgb=%g has exceeded Vgs_max=%g\n",
71                                        vgb, model->BSIM4v7vgsMax);
72                             warns_vgb++;
73                         }
74                 } else {
75                     if (fabs(vgb) > model->BSIM4v7vgbMax)
76                         if (warns_vgb < maxwarns) {
77                             soa_printf(ckt, (GENinstance*) here,
78                                        "Vgb=%g has exceeded Vgb_max=%g\n",
79                                        vgb, model->BSIM4v7vgbMax);
80                             warns_vgb++;
81                         }
82                 }
83             } else {
84                 if (model->BSIM4v7type > 0) {
85                     if (vgs > model->BSIM4v7vgsMax)
86                         if (warns_vgs < maxwarns) {
87                             soa_printf(ckt, (GENinstance*) here,
88                                        "Vgs=%g has exceeded Vgs_max=%g\n",
89                                        vgs, model->BSIM4v7vgsMax);
90                             warns_vgs++;
91                         }
92                     if (-1*vgs > model->BSIM4v7vgsrMax)
93                         if (warns_vgs < maxwarns) {
94                             soa_printf(ckt, (GENinstance*) here,
95                                        "Vgs=%g has exceeded Vgsr_max=%g\n",
96                                        vgs, model->BSIM4v7vgsrMax);
97                             warns_vgs++;
98                         }
99                 } else {
100                     if (vgs > model->BSIM4v7vgsrMax)
101                         if (warns_vgs < maxwarns) {
102                             soa_printf(ckt, (GENinstance*) here,
103                                        "Vgs=%g has exceeded Vgsr_max=%g\n",
104                                        vgs, model->BSIM4v7vgsrMax);
105                             warns_vgs++;
106                         }
107                     if (-1*vgs > model->BSIM4v7vgsMax)
108                         if (warns_vgs < maxwarns) {
109                             soa_printf(ckt, (GENinstance*) here,
110                                        "Vgs=%g has exceeded Vgs_max=%g\n",
111                                        vgs, model->BSIM4v7vgsMax);
112                             warns_vgs++;
113                         }
114                 }
115             }
116 
117             if (!model->BSIM4v7vgdrMaxGiven) {
118                 if (fabs(vgd) > model->BSIM4v7vgdMax)
119                     if (warns_vgd < maxwarns) {
120                         soa_printf(ckt, (GENinstance*) here,
121                                    "Vgd=%g has exceeded Vgd_max=%g\n",
122                                    vgd, model->BSIM4v7vgdMax);
123                         warns_vgd++;
124                     }
125             } else {
126                 if (model->BSIM4v7type > 0) {
127                     if (vgd > model->BSIM4v7vgdMax)
128                         if (warns_vgd < maxwarns) {
129                             soa_printf(ckt, (GENinstance*) here,
130                                        "Vgd=%g has exceeded Vgd_max=%g\n",
131                                        vgd, model->BSIM4v7vgdMax);
132                             warns_vgd++;
133                         }
134                     if (-1*vgd > model->BSIM4v7vgdrMax)
135                         if (warns_vgd < maxwarns) {
136                             soa_printf(ckt, (GENinstance*) here,
137                                        "Vgd=%g has exceeded Vgdr_max=%g\n",
138                                        vgd, model->BSIM4v7vgdrMax);
139                             warns_vgd++;
140                         }
141                 } else {
142                     if (vgd > model->BSIM4v7vgdrMax)
143                         if (warns_vgd < maxwarns) {
144                             soa_printf(ckt, (GENinstance*) here,
145                                        "Vgd=%g has exceeded Vgdr_max=%g\n",
146                                        vgd, model->BSIM4v7vgdrMax);
147                             warns_vgd++;
148                         }
149                     if (-1*vgd > model->BSIM4v7vgdMax)
150                         if (warns_vgd < maxwarns) {
151                             soa_printf(ckt, (GENinstance*) here,
152                                        "Vgd=%g has exceeded Vgd_max=%g\n",
153                                        vgd, model->BSIM4v7vgdMax);
154                             warns_vgd++;
155                         }
156                 }
157             }
158 
159             if (fabs(vds) > model->BSIM4v7vdsMax)
160                 if (warns_vds < maxwarns) {
161                     soa_printf(ckt, (GENinstance*) here,
162                                "Vds=%g has exceeded Vds_max=%g\n",
163                                vds, model->BSIM4v7vdsMax);
164                     warns_vds++;
165                 }
166 
167             if (!model->BSIM4v7vgbrMaxGiven) {
168                 if (fabs(vgb) > model->BSIM4v7vgbMax)
169                     if (warns_vgb < maxwarns) {
170                         soa_printf(ckt, (GENinstance*) here,
171                                    "Vgb=%g has exceeded Vgb_max=%g\n",
172                                    vgb, model->BSIM4v7vgbMax);
173                         warns_vgb++;
174                     }
175             } else {
176                 if (model->BSIM4v7type > 0) {
177                     if (vgb > model->BSIM4v7vgbMax)
178                         if (warns_vgb < maxwarns) {
179                             soa_printf(ckt, (GENinstance*) here,
180                                        "Vgb=%g has exceeded Vgb_max=%g\n",
181                                        vgb, model->BSIM4v7vgbMax);
182                             warns_vgb++;
183                         }
184                     if (-1*vgb > model->BSIM4v7vgbrMax)
185                         if (warns_vgb < maxwarns) {
186                             soa_printf(ckt, (GENinstance*) here,
187                                        "Vgb=%g has exceeded Vgbr_max=%g\n",
188                                        vgb, model->BSIM4v7vgbrMax);
189                             warns_vgb++;
190                         }
191                 } else {
192                     if (vgb > model->BSIM4v7vgbrMax)
193                         if (warns_vgb < maxwarns) {
194                             soa_printf(ckt, (GENinstance*) here,
195                                        "Vgb=%g has exceeded Vgbr_max=%g\n",
196                                        vgb, model->BSIM4v7vgbrMax);
197                             warns_vgb++;
198                         }
199                     if (-1*vgb > model->BSIM4v7vgbMax)
200                         if (warns_vgb < maxwarns) {
201                             soa_printf(ckt, (GENinstance*) here,
202                                        "Vgb=%g has exceeded Vgb_max=%g\n",
203                                        vgb, model->BSIM4v7vgbMax);
204                             warns_vgb++;
205                         }
206                 }
207             }
208 
209             if (!model->BSIM4v7vbsrMaxGiven) {
210                 if (!model->BSIM4v7vbsMaxGiven) {
211                     if (fabs(vbs) > model->BSIM4v7vbdMax)
212                         if (warns_vbs < maxwarns) {
213                             soa_printf(ckt, (GENinstance*) here,
214                                        "Vbs=%g has exceeded Vbd_max=%g\n",
215                                        vbs, model->BSIM4v7vbdMax);
216                             warns_vbs++;
217                         }
218                 } else {
219                     if (fabs(vbs) > model->BSIM4v7vbsMax)
220                         if (warns_vbs < maxwarns) {
221                             soa_printf(ckt, (GENinstance*) here,
222                                        "Vbs=%g has exceeded Vbs_max=%g\n",
223                                        vbs, model->BSIM4v7vbsMax);
224                             warns_vbs++;
225                         }
226                 }
227             } else {
228                 if (!model->BSIM4v7vbsMaxGiven) {
229                     if (model->BSIM4v7type > 0) {
230                         if (vbs > model->BSIM4v7vbdMax)
231                             if (warns_vbs < maxwarns) {
232                                 soa_printf(ckt, (GENinstance*) here,
233                                            "Vbs=%g has exceeded Vbd_max=%g\n",
234                                            vbs, model->BSIM4v7vbdMax);
235                                 warns_vbs++;
236                             }
237                         if (-1*vbs > model->BSIM4v7vbsrMax)
238                             if (warns_vbs < maxwarns) {
239                                 soa_printf(ckt, (GENinstance*) here,
240                                            "Vbs=%g has exceeded Vbsr_max=%g\n",
241                                            vbs, model->BSIM4v7vbsrMax);
242                                 warns_vbs++;
243                             }
244                     } else {
245                         if (vbs > model->BSIM4v7vbsrMax)
246                             if (warns_vbs < maxwarns) {
247                                 soa_printf(ckt, (GENinstance*) here,
248                                            "Vbs=%g has exceeded Vbsr_max=%g\n",
249                                            vbs, model->BSIM4v7vbsrMax);
250                                 warns_vbs++;
251                             }
252                         if (-1*vbs > model->BSIM4v7vbdMax)
253                             if (warns_vbs < maxwarns) {
254                                 soa_printf(ckt, (GENinstance*) here,
255                                            "Vbs=%g has exceeded Vbd_max=%g\n",
256                                            vbs, model->BSIM4v7vbdMax);
257                                 warns_vbs++;
258                             }
259                     }
260                 } else {
261                     if (model->BSIM4v7type > 0) {
262                         if (vbs > model->BSIM4v7vbsMax)
263                             if (warns_vbs < maxwarns) {
264                                 soa_printf(ckt, (GENinstance*) here,
265                                            "Vbs=%g has exceeded Vbs_max=%g\n",
266                                            vbs, model->BSIM4v7vbsMax);
267                                 warns_vbs++;
268                             }
269                         if (-1*vbs > model->BSIM4v7vbsrMax)
270                             if (warns_vbs < maxwarns) {
271                                 soa_printf(ckt, (GENinstance*) here,
272                                            "Vbs=%g has exceeded Vbsr_max=%g\n",
273                                            vbs, model->BSIM4v7vbsrMax);
274                                 warns_vbs++;
275                             }
276                     } else {
277                         if (vbs > model->BSIM4v7vbsrMax)
278                             if (warns_vbs < maxwarns) {
279                                 soa_printf(ckt, (GENinstance*) here,
280                                            "Vbs=%g has exceeded Vbsr_max=%g\n",
281                                            vbs, model->BSIM4v7vbsrMax);
282                                 warns_vbs++;
283                             }
284                         if (-1*vbs > model->BSIM4v7vbsMax)
285                             if (warns_vbs < maxwarns) {
286                                 soa_printf(ckt, (GENinstance*) here,
287                                            "Vbs=%g has exceeded Vbs_max=%g\n",
288                                            vbs, model->BSIM4v7vbsMax);
289                                 warns_vbs++;
290                             }
291                     }
292                 }
293             }
294 
295             if (!model->BSIM4v7vbdrMaxGiven) {
296                 if (fabs(vbd) > model->BSIM4v7vbdMax)
297                     if (warns_vbd < maxwarns) {
298                         soa_printf(ckt, (GENinstance*) here,
299                                    "Vbd=%g has exceeded Vbd_max=%g\n",
300                                    vbd, model->BSIM4v7vbdMax);
301                         warns_vbd++;
302                     }
303             } else {
304                 if (model->BSIM4v7type > 0) {
305                     if (vbd > model->BSIM4v7vbdMax)
306                         if (warns_vbd < maxwarns) {
307                             soa_printf(ckt, (GENinstance*) here,
308                                        "Vbd=%g has exceeded Vbd_max=%g\n",
309                                        vbd, model->BSIM4v7vbdMax);
310                             warns_vbd++;
311                         }
312                     if (-1*vbd > model->BSIM4v7vbdrMax)
313                         if (warns_vbd < maxwarns) {
314                             soa_printf(ckt, (GENinstance*) here,
315                                        "Vbd=%g has exceeded Vbdr_max=%g\n",
316                                        vbd, model->BSIM4v7vbdrMax);
317                             warns_vbd++;
318                         }
319                 } else {
320                     if (vbd > model->BSIM4v7vbdrMax)
321                         if (warns_vbd < maxwarns) {
322                             soa_printf(ckt, (GENinstance*) here,
323                                        "Vbd=%g has exceeded Vbdr_max=%g\n",
324                                        vbd, model->BSIM4v7vbdrMax);
325                             warns_vbd++;
326                         }
327                     if (-1*vbd > model->BSIM4v7vbdMax)
328                         if (warns_vbd < maxwarns) {
329                             soa_printf(ckt, (GENinstance*) here,
330                                        "Vbd=%g has exceeded Vbd_max=%g\n",
331                                        vbd, model->BSIM4v7vbdMax);
332                             warns_vbd++;
333                         }
334                 }
335             }
336 
337         }
338     }
339 
340     return OK;
341 }
342