diff --git a/src/maths/ni/niconv.c b/src/maths/ni/niconv.c index cf1097999..570ceff09 100644 --- a/src/maths/ni/niconv.c +++ b/src/maths/ni/niconv.c @@ -15,6 +15,7 @@ Author: 1985 Thomas L. Quarles #include "ngspice/smpdefs.h" + int NIconvTest(CKTcircuit *ckt) { @@ -80,20 +81,10 @@ NIconvTest(CKTcircuit *ckt) ckt->CKTtroubleElt = NULL; return(1); } -#endif - +#else + /* KCL Verification */ } - } - -#ifdef KIRCHHOFF - node = ckt->CKTnodes; - - /* KCL Verification */ - node = ckt->CKTnodes ; - for (i = 1 ; i <= size ; i++) - { - node = node->next ; - if ((node->type == SP_VOLTAGE) && (!ckt->CKTnodeIsLinear [i]) && (ckt->CKTvoltCurNode [i])) + else if ((node->type == SP_VOLTAGE) && (!ckt->CKTnodeIsLinear [i]) && (ckt->CKTvoltCurNode [i])) { maximum = 0 ; ptr = ckt->CKTmkCurKCLarray [i] ; @@ -108,7 +99,7 @@ NIconvTest(CKTcircuit *ckt) maximum = fabs (ptr->KCLcurrent) ; #ifdef STEPDEBUG - fprintf (stderr, "Index KCL Array: %d\tValue: %-.9g\tMaximum: %-.9g\n", j, fabs(ptr->KCLcurrent), maximum) ; + fprintf (stderr, "Index KCL Array: %d\tValue: %-.9g\tMaximum: %-.9g\n", j, fabs (ptr->KCLcurrent), maximum) ; j++ ; #endif @@ -122,9 +113,10 @@ NIconvTest(CKTcircuit *ckt) if (fabs (ckt->CKTfvk [i]) > (ckt->CKTreltol * maximum + ckt->CKTabstol)) return 1 ; +#endif + } } -#endif #ifdef NEWCONV i = CKTconvTest(ckt); diff --git a/src/spicelib/devices/bsim4/b4ld.c b/src/spicelib/devices/bsim4/b4ld.c index b4a25d3e7..88c4077dd 100644 --- a/src/spicelib/devices/bsim4/b4ld.c +++ b/src/spicelib/devices/bsim4/b4ld.c @@ -4621,7 +4621,7 @@ line860: ceqqd_SnodePrime_fvk = ceqqd ; ceqqb = cqbody - gcbgb * vgb - gcbgmb * vgmb + gcbdb * vbd + gcbsb * vbs; - ceqqb_fvk = cqbody - gcbgmb * vgmb ; + ceqqb_fvk = cqbody ; ceqqb_SnodePrime_fvk = ceqqb ; if (here->BSIM4rgateMod == 3) @@ -5349,300 +5349,82 @@ line900: #ifdef KIRCHHOFF /////////////////////////////////////////// - /* KCL verification - Linear and Dynamic Part */ -/* *(ckt->CKTfvk+here->BSIM4dNodePrime) -= m * (ceqjd_fvk - ceqbd_fvk - ceqdrn_fvk - ceqqd_fvk + Idtoteq_fvk) ; - *(ckt->CKTfvk+here->BSIM4dNodePrime) += m * (T1 * ddxpart_dVd + dxpart * ggtd) * *(ckt->CKTrhsOld+here->BSIM4dNodePrime) ; - *(ckt->CKTfvk+here->BSIM4dNodePrime) -= m * gdtot * *(ckt->CKTrhsOld+here->BSIM4dNode) ; - *(ckt->CKTfvk+here->BSIM4dNodePrime) += m * (dxpart * ggtg + T1 * ddxpart_dVg) * *(ckt->CKTrhsOld+here->BSIM4gNodePrime) ; - *(ckt->CKTfvk+here->BSIM4dNodePrime) -= m * (- dxpart * ggts - T1 * ddxpart_dVs) * *(ckt->CKTrhsOld+here->BSIM4sNodePrime) ; - *(ckt->CKTfvk+here->BSIM4dNodePrime) -= m * (- T1 * ddxpart_dVb - dxpart * ggtb) * *(ckt->CKTrhsOld+here->BSIM4bNodePrime) ; + *(ckt->CKTfvk+here->BSIM4dNodePrime) -= m * (ceqjd_fvk - ceqbd_fvk - ceqdrn_fvk - ceqqd_fvk + Idtoteq_fvk) ; /* NO ceqgdtot in FVK */ + *(here->KCLcurrentdNodePrime_1) = -(m * ceqjd_fvk) ; + *(here->KCLcurrentdNodePrime_2) = m * ceqbd_fvk ; + *(here->KCLcurrentdNodePrime_3) = m * ceqdrn_fvk ; + *(here->KCLcurrentdNodePrime_4) = m * ceqqd_fvk ; + *(here->KCLcurrentdNodePrime_5) = -(m * Idtoteq_fvk) ; - *(ckt->CKTfvk+here->BSIM4gNodePrime) += m * (ceqqg_fvk + Igtoteq_fvk) ; + *(ckt->CKTfvk+here->BSIM4gNodePrime) += m * (ceqqg_fvk + Igtoteq_fvk) ; /* NO ceqgcrg in FVK */ + *(here->KCLcurrentgNodePrime_1) = m * ceqqg_fvk ; + *(here->KCLcurrentgNodePrime_2) = m * Igtoteq_fvk ; - *(ckt->CKTfvk+here->BSIM4sNodePrime) -= m * (- gcsdb - T1 * dsxpart_dVd - sxpart * ggtd) * *(ckt->CKTrhsOld+here->BSIM4dNodePrime) ; - *(ckt->CKTfvk+here->BSIM4sNodePrime) += m * (gcsgb + sxpart * ggtg + T1 * dsxpart_dVg) * *(ckt->CKTrhsOld+here->BSIM4gNodePrime) ; - *(ckt->CKTfvk+here->BSIM4sNodePrime) += m * (T1 * dsxpart_dVs + gstot + gcssb + sxpart * ggts) * *(ckt->CKTrhsOld+here->BSIM4sNodePrime) ; - *(ckt->CKTfvk+here->BSIM4sNodePrime) -= m * gstot * *(ckt->CKTrhsOld+here->BSIM4sNode) ; - *(ckt->CKTfvk+here->BSIM4sNodePrime) -= m * (gjbs - gcsbb - sxpart * ggtb - T1 * dsxpart_dVb) * *(ckt->CKTrhsOld+here->BSIM4bNodePrime) ; - - *(ckt->CKTfvk+here->BSIM4bNodePrime) += m * (- gjbd) * *(ckt->CKTrhsOld+here->BSIM4dNodePrime) ; - *(ckt->CKTfvk+here->BSIM4bNodePrime) += m * (- gjbs) * *(ckt->CKTrhsOld+here->BSIM4sNodePrime) ; - *(ckt->CKTfvk+here->BSIM4bNodePrime) += m * (gjbd + gjbs - gcbgmb) * *(ckt->CKTrhsOld+here->BSIM4bNodePrime) ; - - if (here->BSIM4rgateMod == 1) - { - *(ckt->CKTfvk+here->BSIM4gNodePrime) += m * (- ggtg + gIgtotg) * *(ckt->CKTrhsOld+here->BSIM4gNodePrime) ; - *(ckt->CKTfvk+here->BSIM4gNodePrime) += m * (- ggtd + gIgtotd) * *(ckt->CKTrhsOld+here->BSIM4dNodePrime) ; - *(ckt->CKTfvk+here->BSIM4gNodePrime) += m * (- ggts + gIgtots) * *(ckt->CKTrhsOld+here->BSIM4sNodePrime) ; - *(ckt->CKTfvk+here->BSIM4gNodePrime) += m * (- ggtb + gIgtotb) * *(ckt->CKTrhsOld+here->BSIM4bNodePrime) ; - } - - if (!here->BSIM4rbodyMod) - { - } else { - *(ckt->CKTfvk+here->BSIM4dbNode) += m * (ceqjd_fvk + ceqqjd_fvk) ; - - *(ckt->CKTfvk+here->BSIM4bNodePrime) -= m * (ceqbd_fvk + ceqbs_fvk - ceqqb_fvk + Ibtoteq_fvk) ; - - *(ckt->CKTfvk+here->BSIM4sbNode) += m * (ceqjs_fvk + ceqqjs_fvk) ; - - *(ckt->CKTfvk+here->BSIM4sNodePrime) -= m * (ceqdrn_fvk - ceqbs_fvk + ceqjs_fvk + ceqqd_SnodePrime_fvk + ceqqg_SnodePrime_fvk + ceqqb_SnodePrime_fvk + ceqqjd_SnodePrime_fvk + ceqqjs_SnodePrime_fvk + ceqqgmid_fvk + Istoteq_fvk) ; - } - -*/ - /* KCL verification - Linear and Static Part */ -/* if (here->BSIM4rgateMod == 1) - { - *(ckt->CKTfvk+here->BSIM4gNodeExt) += m * geltd * *(ckt->CKTrhsOld+here->BSIM4gNodeExt) ; - *(ckt->CKTfvk+here->BSIM4gNodePrime) -= m * geltd * *(ckt->CKTrhsOld+here->BSIM4gNodeExt) ; - *(ckt->CKTfvk+here->BSIM4gNodeExt) -= m * geltd * *(ckt->CKTrhsOld+here->BSIM4gNodePrime) ; - *(ckt->CKTfvk+here->BSIM4gNodePrime) += m * geltd * *(ckt->CKTrhsOld+here->BSIM4gNodePrime) ; - } - - *(ckt->CKTfvk+here->BSIM4dNodePrime) += m * gdpr * *(ckt->CKTrhsOld+here->BSIM4dNodePrime) ; - *(ckt->CKTfvk+here->BSIM4dNodePrime) -= m * gdpr * *(ckt->CKTrhsOld+here->BSIM4dNode) ; - - *(ckt->CKTfvk+here->BSIM4dNode) -= m * gdpr * *(ckt->CKTrhsOld+here->BSIM4dNodePrime) ; - *(ckt->CKTfvk+here->BSIM4dNode) += m * gdpr * *(ckt->CKTrhsOld+here->BSIM4dNode) ; - - *(ckt->CKTfvk+here->BSIM4sNodePrime) += m * gspr * *(ckt->CKTrhsOld+here->BSIM4sNodePrime) ; - *(ckt->CKTfvk+here->BSIM4sNodePrime) -= m * gspr * *(ckt->CKTrhsOld+here->BSIM4sNode) ; - - *(ckt->CKTfvk+here->BSIM4sNode) -= m * gspr * *(ckt->CKTrhsOld+here->BSIM4sNodePrime) ; - *(ckt->CKTfvk+here->BSIM4sNode) += m * gspr * *(ckt->CKTrhsOld+here->BSIM4sNode) ; - - if (here->BSIM4rbodyMod) - { - *(ckt->CKTfvk+here->BSIM4sNodePrime) -= m * (- gcsbsb) * *(ckt->CKTrhsOld+here->BSIM4sbNode) ; - - *(ckt->CKTfvk+here->BSIM4dbNode) += m * here->BSIM4grbdb * *(ckt->CKTrhsOld+here->BSIM4dbNode) ; - *(ckt->CKTfvk+here->BSIM4dbNode) -= m * here->BSIM4grbdb * *(ckt->CKTrhsOld+here->BSIM4bNode) ; - *(ckt->CKTfvk+here->BSIM4dbNode) += m * here->BSIM4grbpd * *(ckt->CKTrhsOld+here->BSIM4dbNode) ; - *(ckt->CKTfvk+here->BSIM4dbNode) -= m * here->BSIM4grbpd * *(ckt->CKTrhsOld+here->BSIM4bNodePrime) ; - - *(ckt->CKTfvk+here->BSIM4bNodePrime) -= m * here->BSIM4grbpd * *(ckt->CKTrhsOld+here->BSIM4dbNode) ; - *(ckt->CKTfvk+here->BSIM4bNodePrime) -= m * here->BSIM4grbpb * *(ckt->CKTrhsOld+here->BSIM4bNode) ; - *(ckt->CKTfvk+here->BSIM4bNodePrime) -= m * here->BSIM4grbps * *(ckt->CKTrhsOld+here->BSIM4sbNode) ; - *(ckt->CKTfvk+here->BSIM4bNodePrime) += m * (here->BSIM4grbpd + here->BSIM4grbps + here->BSIM4grbpb) * *(ckt->CKTrhsOld+here->BSIM4bNodePrime) ; - - *(ckt->CKTfvk+here->BSIM4sbNode) -= m * here->BSIM4grbps * *(ckt->CKTrhsOld+here->BSIM4bNodePrime) ; - *(ckt->CKTfvk+here->BSIM4sbNode) -= m * here->BSIM4grbsb * *(ckt->CKTrhsOld+here->BSIM4bNode) ; - *(ckt->CKTfvk+here->BSIM4sbNode) += m * here->BSIM4grbsb * *(ckt->CKTrhsOld+here->BSIM4sbNode) ; - *(ckt->CKTfvk+here->BSIM4sbNode) += m * here->BSIM4grbps * *(ckt->CKTrhsOld+here->BSIM4sbNode) ; - - *(ckt->CKTfvk+here->BSIM4bNode) -= m * here->BSIM4grbdb * *(ckt->CKTrhsOld+here->BSIM4dbNode) ; - *(ckt->CKTfvk+here->BSIM4bNode) -= m * here->BSIM4grbpb * *(ckt->CKTrhsOld+here->BSIM4bNodePrime) ; - *(ckt->CKTfvk+here->BSIM4bNode) -= m * here->BSIM4grbsb * *(ckt->CKTrhsOld+here->BSIM4sbNode) ; - *(ckt->CKTfvk+here->BSIM4bNode) += m * (here->BSIM4grbsb + here->BSIM4grbdb + here->BSIM4grbpb) * *(ckt->CKTrhsOld+here->BSIM4bNode) ; - } -*/ - -////////////////////////////////////////////// - -// RHS - *(ckt->CKTfvk + here->BSIM4dNodePrime) -= m * (ceqjd - ceqbd + ceqgdtot - ceqdrn - ceqqd + Idtoteq) ; /* NO ceqgdtot in FVK */ - - *(ckt->CKTfvk + here->BSIM4gNodePrime) += m * (ceqqg - ceqgcrg + Igtoteq) ; /* NO ceqgcrg in FVK */ - - if (here->BSIM4rgateMod == 2) - *(ckt->CKTfvk + here->BSIM4gNodeExt) += m * ceqgcrg ; /* NO ceqgcrg in FVK */ - else if (here->BSIM4rgateMod == 3) - *(ckt->CKTfvk + here->BSIM4gNodeMid) += m * (ceqqgmid + ceqgcrg) ; /* NO ceqgcrg in FVK */ + if (here->BSIM4rgateMod == 3) + { + *(ckt->CKTfvk+here->BSIM4gNodeMid) += m * ceqqgmid_fvk ; /* NO ceqgcrg in FVK */ + *(here->KCLcurrentgNodeMid) = m * ceqqgmid_fvk ; + } if (!here->BSIM4rbodyMod) { - *(ckt->CKTfvk + here->BSIM4bNodePrime) -= m * (ceqbd + ceqbs - ceqjd - ceqjs - ceqqb + Ibtoteq) ; - *(ckt->CKTfvk + here->BSIM4sNodePrime) -= m * (ceqdrn - ceqbs + ceqjs - + ceqqg + ceqqb + ceqqd + ceqqgmid - ceqgstot + Istoteq) ; /* NO ceqgstot in FVK */ - } else { - *(ckt->CKTfvk + here->BSIM4dbNode) += m * (ceqjd + ceqqjd) ; - *(ckt->CKTfvk + here->BSIM4bNodePrime) -= m * (ceqbd + ceqbs - ceqqb + Ibtoteq) ; - *(ckt->CKTfvk + here->BSIM4sbNode) += m * (ceqjs + ceqqjs) ; - *(ckt->CKTfvk + here->BSIM4sNodePrime) -= m * (ceqdrn - ceqbs + ceqjs + ceqqd - + ceqqg + ceqqb + ceqqjd + ceqqjs + ceqqgmid - ceqgstot + Istoteq) ; /* NO ceqgstot in FVK */ - } + *(ckt->CKTfvk+here->BSIM4bNodePrime) -= m * (ceqbd_fvk + ceqbs_fvk - ceqjd_fvk - ceqjs_fvk - ceqqb_fvk + Ibtoteq_fvk) ; + *(here->KCLcurrentbNodePrime_1) = -(m * ceqbd_fvk) ; + *(here->KCLcurrentbNodePrime_2) = -(m * ceqbs_fvk) ; + *(here->KCLcurrentbNodePrime_3) = m * ceqjd_fvk ; + *(here->KCLcurrentbNodePrime_4) = m * ceqjs_fvk ; + *(here->KCLcurrentbNodePrime_5) = m * ceqqb_fvk ; + *(here->KCLcurrentbNodePrime_6) = -(m * Ibtoteq_fvk) ; - if (model->BSIM4rdsMod) - { - *(ckt->CKTfvk + here->BSIM4dNode) += m * ceqgdtot ; /* NO ceqgdtot in FVK */ - *(ckt->CKTfvk + here->BSIM4sNode) -= m * ceqgstot ; /* NO ceqgstot in FVK */ + *(ckt->CKTfvk+here->BSIM4sNodePrime) -= m * (ceqdrn_fvk - ceqbs_fvk + ceqjs_fvk + + ceqqg_fvk + ceqqb_fvk + ceqqd_fvk + + ceqqgmid_fvk + Istoteq_fvk) ; /* NO ceqgstot in FVK */ + *(here->KCLcurrentsNodePrime_1) = -(m * ceqdrn_fvk) ; + *(here->KCLcurrentsNodePrime_2) = m * ceqbs_fvk ; + *(here->KCLcurrentsNodePrime_3) = -(m * ceqjs_fvk) ; + *(here->KCLcurrentsNodePrime_4) = -(m * ceqqg_fvk) ; + *(here->KCLcurrentsNodePrime_5) = -(m * ceqqb_fvk) ; + *(here->KCLcurrentsNodePrime_6) = -(m * ceqqd_fvk) ; + *(here->KCLcurrentsNodePrime_7) = -(m * ceqqgmid_fvk) ; + *(here->KCLcurrentsNodePrime_8) = -(m * Istoteq_fvk) ; + } else { + *(ckt->CKTfvk+here->BSIM4dbNode) += m * (ceqjd_fvk + ceqqjd_fvk) ; + *(here->KCLcurrentdbNode_1) = m * ceqjd_fvk ; + *(here->KCLcurrentdbNode_2) = m * ceqqjd_fvk ; + + *(ckt->CKTfvk+here->BSIM4bNodePrime) -= m * (ceqbd_fvk + ceqbs_fvk - ceqqb_fvk + Ibtoteq_fvk) ; + *(here->KCLcurrentbNodePrime_1) = -(m * ceqbd_fvk) ; + *(here->KCLcurrentbNodePrime_2) = -(m * ceqbs_fvk) ; + *(here->KCLcurrentbNodePrime_3) = m * ceqqb_fvk ; + *(here->KCLcurrentbNodePrime_4) = -(m * Ibtoteq_fvk) ; + + *(ckt->CKTfvk+here->BSIM4sbNode) += m * (ceqjs_fvk + ceqqjs_fvk) ; + *(here->KCLcurrentsbNode_1) = m * ceqjs_fvk ; + *(here->KCLcurrentsbNode_2) = m * ceqqjs_fvk ; + + *(ckt->CKTfvk+here->BSIM4sNodePrime) -= m * (ceqdrn_fvk - ceqbs_fvk + ceqjs_fvk + ceqqd_fvk + + ceqqg_fvk + ceqqb_fvk + ceqqjd_fvk + ceqqjs_fvk + + ceqqgmid_fvk + Istoteq_fvk) ; /* NO ceqgstot in FVK */ + *(here->KCLcurrentsNodePrime_1) = -(m * ceqdrn_fvk) ; + *(here->KCLcurrentsNodePrime_2) = m * ceqbs_fvk ; + *(here->KCLcurrentsNodePrime_3) = -(m * ceqjs_fvk) ; + *(here->KCLcurrentsNodePrime_4) = -(m * ceqqd_fvk) ; + *(here->KCLcurrentsNodePrime_5) = -(m * ceqqg_fvk) ; + *(here->KCLcurrentsNodePrime_6) = -(m * ceqqb_fvk) ; + *(here->KCLcurrentsNodePrime_7) = -(m * ceqqjd_fvk) ; + *(here->KCLcurrentsNodePrime_8) = -(m * ceqqjs_fvk) ; + *(here->KCLcurrentsNodePrime_9) = -(m * ceqqgmid_fvk) ; + *(here->KCLcurrentsNodePrime_10) = -(m * Istoteq_fvk) ; } if (here->BSIM4trnqsMod) - *(ckt->CKTfvk + here->BSIM4qNode) -= m * (cqcheq - cqdef) ; + { + *(ckt->CKTfvk+here->BSIM4qNode) -= m * (cqcheq_fvk - cqdef_fvk) ; + *(here->KCLcurrentqNode_1) = -(m * cqcheq_fvk) ; + *(here->KCLcurrentqNode_2) = m * cqdef_fvk ; + } - -// Matrice - if (here->BSIM4rgateMod == 1) - { - *(ckt->CKTfvk + here->BSIM4gNodeExt) += m * geltd * *(ckt->CKTrhsOld + here->BSIM4gNodeExt) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) -= m * geltd * *(ckt->CKTrhsOld + here->BSIM4gNodeExt) ; - *(ckt->CKTfvk + here->BSIM4gNodeExt) -= m * geltd * *(ckt->CKTrhsOld + here->BSIM4gNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) += m * (gcggb + geltd - ggtg + gIgtotg) * *(ckt->CKTrhsOld + here->BSIM4gNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) += m * (gcgdb - ggtd + gIgtotd) * *(ckt->CKTrhsOld + here->BSIM4dNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) += m * (gcgsb - ggts + gIgtots) * *(ckt->CKTrhsOld + here->BSIM4sNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) += m * (gcgbb - ggtb + gIgtotb) * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - } /* WDLiu: gcrg already subtracted from all gcrgg below */ - else if (here->BSIM4rgateMod == 2) - { - *(ckt->CKTfvk + here->BSIM4gNodeExt) += m * gcrg * *(ckt->CKTrhsOld + here->BSIM4gNodeExt) ; - *(ckt->CKTfvk + here->BSIM4gNodeExt) += m * gcrgg * *(ckt->CKTrhsOld + here->BSIM4gNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodeExt) += m * gcrgd * *(ckt->CKTrhsOld + here->BSIM4dNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodeExt) += m * gcrgs * *(ckt->CKTrhsOld + here->BSIM4sNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodeExt) += m * gcrgb * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) -= m * gcrg * *(ckt->CKTrhsOld + here->BSIM4gNodeExt) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) += m * (gcggb - gcrgg - ggtg + gIgtotg) * *(ckt->CKTrhsOld + here->BSIM4gNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) += m * (gcgdb - gcrgd - ggtd + gIgtotd) * *(ckt->CKTrhsOld + here->BSIM4dNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) += m * (gcgsb - gcrgs - ggts + gIgtots) * *(ckt->CKTrhsOld + here->BSIM4sNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) += m * (gcgbb - gcrgb - ggtb + gIgtotb) * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - } - else if (here->BSIM4rgateMod == 3) - { - *(ckt->CKTfvk + here->BSIM4gNodeExt) += m * geltd * *(ckt->CKTrhsOld + here->BSIM4gNodeExt) ; - *(ckt->CKTfvk + here->BSIM4gNodeExt) -= m * geltd * *(ckt->CKTrhsOld + here->BSIM4gNodeMid) ; - *(ckt->CKTfvk + here->BSIM4gNodeMid) -= m * geltd * *(ckt->CKTrhsOld + here->BSIM4gNodeExt) ; - *(ckt->CKTfvk + here->BSIM4gNodeMid) += m * (geltd + gcrg + gcgmgmb) * *(ckt->CKTrhsOld + here->BSIM4gNodeMid) ; - *(ckt->CKTfvk + here->BSIM4gNodeMid) += m * (gcrgd + gcgmdb) * *(ckt->CKTrhsOld + here->BSIM4dNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodeMid) += m * gcrgg * *(ckt->CKTrhsOld + here->BSIM4gNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodeMid) += m * (gcrgs + gcgmsb) * *(ckt->CKTrhsOld + here->BSIM4sNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodeMid) += m * (gcrgb + gcgmbb) * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - *(ckt->CKTfvk + here->BSIM4dNodePrime) += m * gcdgmb * *(ckt->CKTrhsOld + here->BSIM4gNodeMid) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) -= m * gcrg * *(ckt->CKTrhsOld + here->BSIM4gNodeMid) ; - *(ckt->CKTfvk + here->BSIM4sNodePrime) += m * gcsgmb * *(ckt->CKTrhsOld + here->BSIM4gNodeMid) ; - *(ckt->CKTfvk + here->BSIM4bNodePrime) += m * gcbgmb * *(ckt->CKTrhsOld + here->BSIM4gNodeMid) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) += m * (gcggb - gcrgg - ggtg + gIgtotg) * *(ckt->CKTrhsOld + here->BSIM4gNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) += m * (gcgdb - gcrgd - ggtd + gIgtotd) * *(ckt->CKTrhsOld + here->BSIM4dNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) += m * (gcgsb - gcrgs - ggts + gIgtots) * *(ckt->CKTrhsOld + here->BSIM4sNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) += m * (gcgbb - gcrgb - ggtb + gIgtotb) * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - } else { - *(ckt->CKTfvk + here->BSIM4gNodePrime) += m * (gcggb - ggtg + gIgtotg) * *(ckt->CKTrhsOld + here->BSIM4gNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) += m * (gcgdb - ggtd + gIgtotd) * *(ckt->CKTrhsOld + here->BSIM4dNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) += m * (gcgsb - ggts + gIgtots) * *(ckt->CKTrhsOld + here->BSIM4sNodePrime) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) += m * (gcgbb - ggtb + gIgtotb) * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - } - - if (model->BSIM4rdsMod) - { - *(ckt->CKTfvk + here->BSIM4dNode) += m * gdtotg * *(ckt->CKTrhsOld + here->BSIM4gNodePrime) ; - *(ckt->CKTfvk + here->BSIM4dNode) += m * gdtots * *(ckt->CKTrhsOld + here->BSIM4sNodePrime) ; - *(ckt->CKTfvk + here->BSIM4dNode) += m * gdtotb * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - *(ckt->CKTfvk + here->BSIM4sNode) += m * gstotd * *(ckt->CKTrhsOld + here->BSIM4dNodePrime) ; - *(ckt->CKTfvk + here->BSIM4sNode) += m * gstotg * *(ckt->CKTrhsOld + here->BSIM4gNodePrime) ; - *(ckt->CKTfvk + here->BSIM4sNode) += m * gstotb * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - } - - *(ckt->CKTfvk + here->BSIM4dNodePrime) += m * (gdpr + here->BSIM4gds + here->BSIM4gbd + T1 * ddxpart_dVd - gdtotd + RevSum - + gcddb + gbdpdp + dxpart * ggtd - gIdtotd) * *(ckt->CKTrhsOld + here->BSIM4dNodePrime) ; - - *(ckt->CKTfvk + here->BSIM4dNodePrime) -= m * (gdpr + gdtot) * *(ckt->CKTrhsOld + here->BSIM4dNode) ; - - *(ckt->CKTfvk + here->BSIM4dNodePrime) += m * (Gm + gcdgb - gdtotg + gbdpg - gIdtotg + dxpart * ggtg - + T1 * ddxpart_dVg) * *(ckt->CKTrhsOld + here->BSIM4gNodePrime) ; - - *(ckt->CKTfvk + here->BSIM4dNodePrime) -= m * (here->BSIM4gds + gdtots - dxpart * ggts + gIdtots - T1 * ddxpart_dVs - + FwdSum - gcdsb - gbdpsp) * *(ckt->CKTrhsOld + here->BSIM4sNodePrime) ; - - *(ckt->CKTfvk + here->BSIM4dNodePrime) -= m * (gjbd + gdtotb - Gmbs - gcdbb - gbdpb + gIdtotb - T1 * ddxpart_dVb - - dxpart * ggtb) * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - - *(ckt->CKTfvk + here->BSIM4dNode) -= m * (gdpr - gdtotd) * *(ckt->CKTrhsOld + here->BSIM4dNodePrime) ; - - *(ckt->CKTfvk + here->BSIM4dNode) += m * (gdpr + gdtot) * *(ckt->CKTrhsOld + here->BSIM4dNode) ; - - *(ckt->CKTfvk + here->BSIM4sNodePrime) -= m * (here->BSIM4gds + gstotd + RevSum - gcsdb - gbspdp - T1 * dsxpart_dVd - - sxpart * ggtd + gIstotd) * *(ckt->CKTrhsOld + here->BSIM4dNodePrime) ; - - *(ckt->CKTfvk + here->BSIM4sNodePrime) += m * (gcsgb - Gm - gstotg + gbspg + sxpart * ggtg + T1 * dsxpart_dVg - - gIstotg) * *(ckt->CKTrhsOld + here->BSIM4gNodePrime) ; - - *(ckt->CKTfvk + here->BSIM4sNodePrime) += m * (gspr + here->BSIM4gds + here->BSIM4gbs + T1 * dsxpart_dVs - gstots + FwdSum - + gcssb + gbspsp + sxpart * ggts - gIstots) * *(ckt->CKTrhsOld + here->BSIM4sNodePrime) ; - - *(ckt->CKTfvk + here->BSIM4sNodePrime) -= m * (gspr + gstot) * *(ckt->CKTrhsOld + here->BSIM4sNode) ; - - *(ckt->CKTfvk + here->BSIM4sNodePrime) -= m * (gjbs + gstotb + Gmbs - gcsbb - gbspb - sxpart * ggtb - T1 * dsxpart_dVb - + gIstotb) * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - - *(ckt->CKTfvk + here->BSIM4sNode) -= m * (gspr - gstots) * *(ckt->CKTrhsOld + here->BSIM4sNodePrime) ; - - *(ckt->CKTfvk + here->BSIM4sNode) += m * (gspr + gstot) * *(ckt->CKTrhsOld + here->BSIM4sNode) ; - - *(ckt->CKTfvk + here->BSIM4bNodePrime) += m * (gcbdb - gjbd + gbbdp - gIbtotd) * *(ckt->CKTrhsOld + here->BSIM4dNodePrime) ; - - *(ckt->CKTfvk + here->BSIM4bNodePrime) += m * (gcbgb - here->BSIM4gbgs - gIbtotg) * *(ckt->CKTrhsOld + here->BSIM4gNodePrime) ; - - *(ckt->CKTfvk + here->BSIM4bNodePrime) += m * (gcbsb - gjbs + gbbsp - gIbtots) * *(ckt->CKTrhsOld + here->BSIM4sNodePrime) ; - - *(ckt->CKTfvk + here->BSIM4bNodePrime) += m * (gjbd + gjbs + gcbbb - here->BSIM4gbbs - - gIbtotb) * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - - ggidld = here->BSIM4ggidld; - ggidlg = here->BSIM4ggidlg; - ggidlb = here->BSIM4ggidlb; - ggislg = here->BSIM4ggislg; - ggisls = here->BSIM4ggisls; - ggislb = here->BSIM4ggislb; - - /* stamp gidl */ - *(ckt->CKTfvk + here->BSIM4dNodePrime) += m * ggidld * *(ckt->CKTrhsOld + here->BSIM4dNodePrime) ; - *(ckt->CKTfvk + here->BSIM4dNodePrime) += m * ggidlg * *(ckt->CKTrhsOld + here->BSIM4gNodePrime) ; - *(ckt->CKTfvk + here->BSIM4dNodePrime) -= m * (ggidlg + ggidld + ggidlb) * *(ckt->CKTrhsOld + here->BSIM4sNodePrime) ; - *(ckt->CKTfvk + here->BSIM4dNodePrime) += m * ggidlb * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - *(ckt->CKTfvk + here->BSIM4bNodePrime) -= m * ggidld * *(ckt->CKTrhsOld + here->BSIM4dNodePrime) ; - *(ckt->CKTfvk + here->BSIM4bNodePrime) -= m * ggidlg * *(ckt->CKTrhsOld + here->BSIM4gNodePrime) ; - *(ckt->CKTfvk + here->BSIM4bNodePrime) += m * (ggidlg + ggidld + ggidlb) * *(ckt->CKTrhsOld + here->BSIM4sNodePrime) ; - *(ckt->CKTfvk + here->BSIM4bNodePrime) -= m * ggidlb * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - - /* stamp gisl */ - *(ckt->CKTfvk + here->BSIM4sNodePrime) -= m * (ggisls + ggislg + ggislb) * *(ckt->CKTrhsOld + here->BSIM4dNodePrime) ; - *(ckt->CKTfvk + here->BSIM4sNodePrime) += m * ggislg * *(ckt->CKTrhsOld + here->BSIM4gNodePrime) ; - *(ckt->CKTfvk + here->BSIM4sNodePrime) += m * ggisls * *(ckt->CKTrhsOld + here->BSIM4sNodePrime) ; - *(ckt->CKTfvk + here->BSIM4sNodePrime) += m * ggislb * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - *(ckt->CKTfvk + here->BSIM4bNodePrime) += m * (ggislg + ggisls + ggislb) * *(ckt->CKTrhsOld + here->BSIM4dNodePrime) ; - *(ckt->CKTfvk + here->BSIM4bNodePrime) -= m * ggislg * *(ckt->CKTrhsOld + here->BSIM4gNodePrime) ; - *(ckt->CKTfvk + here->BSIM4bNodePrime) -= m * ggisls * *(ckt->CKTrhsOld + here->BSIM4sNodePrime) ; - *(ckt->CKTfvk + here->BSIM4bNodePrime) -= m * ggislb * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - - if (here->BSIM4rbodyMod) - { - *(ckt->CKTfvk + here->BSIM4dNodePrime) += m * (gcdbdb - here->BSIM4gbd) * *(ckt->CKTrhsOld + here->BSIM4dbNode) ; - *(ckt->CKTfvk + here->BSIM4sNodePrime) -= m * (here->BSIM4gbs - gcsbsb) * *(ckt->CKTrhsOld + here->BSIM4sbNode) ; - *(ckt->CKTfvk + here->BSIM4dbNode) += m * (gcdbdb - here->BSIM4gbd) * *(ckt->CKTrhsOld + here->BSIM4dNodePrime) ; - *(ckt->CKTfvk + here->BSIM4dbNode) += m * (here->BSIM4gbd - gcdbdb + here->BSIM4grbpd - + here->BSIM4grbdb) * *(ckt->CKTrhsOld + here->BSIM4dbNode) ; - *(ckt->CKTfvk + here->BSIM4dbNode) -= m * here->BSIM4grbpd * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - *(ckt->CKTfvk + here->BSIM4dbNode) -= m * here->BSIM4grbdb * *(ckt->CKTrhsOld + here->BSIM4bNode) ; - *(ckt->CKTfvk + here->BSIM4bNodePrime) -= m * here->BSIM4grbpd * *(ckt->CKTrhsOld + here->BSIM4dbNode) ; - *(ckt->CKTfvk + here->BSIM4bNodePrime) -= m * here->BSIM4grbpb * *(ckt->CKTrhsOld + here->BSIM4bNode) ; - *(ckt->CKTfvk + here->BSIM4bNodePrime) -= m * here->BSIM4grbps * *(ckt->CKTrhsOld + here->BSIM4sbNode) ; - *(ckt->CKTfvk + here->BSIM4bNodePrime) += m * (here->BSIM4grbpd + here->BSIM4grbps - + here->BSIM4grbpb) * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - - /* WDLiu: (gcbbb - here->BSIM4gbbs) already added to BPbpPtr */ - - *(ckt->CKTfvk + here->BSIM4sbNode) += m * (gcsbsb - here->BSIM4gbs) * *(ckt->CKTrhsOld + here->BSIM4sNodePrime) ; - *(ckt->CKTfvk + here->BSIM4sbNode) -= m * here->BSIM4grbps * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - *(ckt->CKTfvk + here->BSIM4sbNode) -= m * here->BSIM4grbsb * *(ckt->CKTrhsOld + here->BSIM4bNode) ; - *(ckt->CKTfvk + here->BSIM4sbNode) += m * (here->BSIM4gbs - gcsbsb + here->BSIM4grbps - + here->BSIM4grbsb) * *(ckt->CKTrhsOld + here->BSIM4sbNode) ; - *(ckt->CKTfvk + here->BSIM4bNode) -= m * here->BSIM4grbdb * *(ckt->CKTrhsOld + here->BSIM4dbNode) ; - *(ckt->CKTfvk + here->BSIM4bNode) -= m * here->BSIM4grbpb * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - *(ckt->CKTfvk + here->BSIM4bNode) -= m * here->BSIM4grbsb * *(ckt->CKTrhsOld + here->BSIM4sbNode) ; - *(ckt->CKTfvk + here->BSIM4bNode) += m * (here->BSIM4grbsb + here->BSIM4grbdb - + here->BSIM4grbpb) * *(ckt->CKTrhsOld + here->BSIM4bNode) ; - } - - if (here->BSIM4trnqsMod) - { - *(ckt->CKTfvk + here->BSIM4qNode) += m * (gqdef + here->BSIM4gtau) * *(ckt->CKTrhsOld + here->BSIM4qNode) ; - *(ckt->CKTfvk + here->BSIM4qNode) += m * (ggtg - gcqgb) * *(ckt->CKTrhsOld + here->BSIM4gNodePrime) ; - *(ckt->CKTfvk + here->BSIM4qNode) += m * (ggtd - gcqdb) * *(ckt->CKTrhsOld + here->BSIM4dNodePrime) ; - *(ckt->CKTfvk + here->BSIM4qNode) += m * (ggts - gcqsb) * *(ckt->CKTrhsOld + here->BSIM4sNodePrime) ; - *(ckt->CKTfvk + here->BSIM4qNode) += m * (ggtb - gcqbb) * *(ckt->CKTrhsOld + here->BSIM4bNodePrime) ; - *(ckt->CKTfvk + here->BSIM4dNodePrime) += m * dxpart * here->BSIM4gtau * *(ckt->CKTrhsOld + here->BSIM4qNode) ; - *(ckt->CKTfvk + here->BSIM4sNodePrime) += m * sxpart * here->BSIM4gtau * *(ckt->CKTrhsOld + here->BSIM4qNode) ; - *(ckt->CKTfvk + here->BSIM4gNodePrime) -= m * here->BSIM4gtau * *(ckt->CKTrhsOld + here->BSIM4qNode) ; - } +/////////////////////////////////////////// #endif #endif diff --git a/src/spicelib/devices/bsim4/b4node.c b/src/spicelib/devices/bsim4/b4node.c index dfb6b7cda..e5511085a 100644 --- a/src/spicelib/devices/bsim4/b4node.c +++ b/src/spicelib/devices/bsim4/b4node.c @@ -12,6 +12,7 @@ BSIM4nodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt) { BSIM4model *model = (BSIM4model *)inModel ; BSIM4instance *here ; + int error ; /* loop through all the BSIM4 models */ for ( ; model != NULL ; model = model->BSIM4nextModel) @@ -39,6 +40,59 @@ BSIM4nodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt) ckt->CKTnodeIsLinear [here->BSIM4bNodePrime] = 0 ; ckt->CKTnodeIsLinear [here->BSIM4sbNode] = 0 ; ckt->CKTnodeIsLinear [here->BSIM4qNode] = 0 ; + + + error = CKTmkCurKCL (ckt, here->BSIM4dNodePrime, &(here->KCLcurrentdNodePrime_1)) ; + error = CKTmkCurKCL (ckt, here->BSIM4dNodePrime, &(here->KCLcurrentdNodePrime_2)) ; + error = CKTmkCurKCL (ckt, here->BSIM4dNodePrime, &(here->KCLcurrentdNodePrime_3)) ; + error = CKTmkCurKCL (ckt, here->BSIM4dNodePrime, &(here->KCLcurrentdNodePrime_4)) ; + error = CKTmkCurKCL (ckt, here->BSIM4dNodePrime, &(here->KCLcurrentdNodePrime_5)) ; + error = CKTmkCurKCL (ckt, here->BSIM4gNodePrime, &(here->KCLcurrentgNodePrime_1)) ; + error = CKTmkCurKCL (ckt, here->BSIM4gNodePrime, &(here->KCLcurrentgNodePrime_2)) ; + + if (here->BSIM4rgateMod == 3) + error = CKTmkCurKCL (ckt, here->BSIM4gNodeMid, &(here->KCLcurrentgNodeMid)) ; + + if (!here->BSIM4rbodyMod) + { + error = CKTmkCurKCL (ckt, here->BSIM4bNodePrime, &(here->KCLcurrentbNodePrime_1)) ; + error = CKTmkCurKCL (ckt, here->BSIM4bNodePrime, &(here->KCLcurrentbNodePrime_2)) ; + error = CKTmkCurKCL (ckt, here->BSIM4bNodePrime, &(here->KCLcurrentbNodePrime_3)) ; + error = CKTmkCurKCL (ckt, here->BSIM4bNodePrime, &(here->KCLcurrentbNodePrime_4)) ; + error = CKTmkCurKCL (ckt, here->BSIM4bNodePrime, &(here->KCLcurrentbNodePrime_5)) ; + error = CKTmkCurKCL (ckt, here->BSIM4bNodePrime, &(here->KCLcurrentbNodePrime_6)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_1)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_2)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_3)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_4)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_5)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_6)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_7)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_8)) ; + } else { + error = CKTmkCurKCL (ckt, here->BSIM4dbNode, &(here->KCLcurrentdbNode_1)) ; + error = CKTmkCurKCL (ckt, here->BSIM4dbNode, &(here->KCLcurrentdbNode_2)) ; + error = CKTmkCurKCL (ckt, here->BSIM4bNodePrime, &(here->KCLcurrentbNodePrime_1)) ; + error = CKTmkCurKCL (ckt, here->BSIM4bNodePrime, &(here->KCLcurrentbNodePrime_2)) ; + error = CKTmkCurKCL (ckt, here->BSIM4bNodePrime, &(here->KCLcurrentbNodePrime_3)) ; + error = CKTmkCurKCL (ckt, here->BSIM4bNodePrime, &(here->KCLcurrentbNodePrime_4)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sbNode, &(here->KCLcurrentsbNode_1)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sbNode, &(here->KCLcurrentsbNode_2)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_1)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_2)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_3)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_4)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_5)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_6)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_7)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_8)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_9)) ; + error = CKTmkCurKCL (ckt, here->BSIM4sNodePrime, &(here->KCLcurrentsNodePrime_10)) ; + } + + if (here->BSIM4trnqsMod) + error = CKTmkCurKCL (ckt, here->BSIM4qNode, &(here->KCLcurrentqNode_1)) ; + error = CKTmkCurKCL (ckt, here->BSIM4qNode, &(here->KCLcurrentqNode_2)) ; } } diff --git a/src/spicelib/devices/bsim4/bsim4def.h b/src/spicelib/devices/bsim4/bsim4def.h index 3505fc347..bd0a7860a 100644 --- a/src/spicelib/devices/bsim4/bsim4def.h +++ b/src/spicelib/devices/bsim4/bsim4def.h @@ -569,6 +569,39 @@ typedef struct sBSIM4instance double **BSIM4nVar; #endif /* NONOISE */ +#ifdef KIRCHHOFF + double *KCLcurrentdNodePrime_1 ; + double *KCLcurrentdNodePrime_2 ; + double *KCLcurrentdNodePrime_3 ; + double *KCLcurrentdNodePrime_4 ; + double *KCLcurrentdNodePrime_5 ; + double *KCLcurrentgNodePrime_1 ; + double *KCLcurrentgNodePrime_2 ; + double *KCLcurrentgNodeMid ; + double *KCLcurrentbNodePrime_1 ; + double *KCLcurrentbNodePrime_2 ; + double *KCLcurrentbNodePrime_3 ; + double *KCLcurrentbNodePrime_4 ; + double *KCLcurrentbNodePrime_5 ; + double *KCLcurrentbNodePrime_6 ; + double *KCLcurrentsNodePrime_1 ; + double *KCLcurrentsNodePrime_2 ; + double *KCLcurrentsNodePrime_3 ; + double *KCLcurrentsNodePrime_4 ; + double *KCLcurrentsNodePrime_5 ; + double *KCLcurrentsNodePrime_6 ; + double *KCLcurrentsNodePrime_7 ; + double *KCLcurrentsNodePrime_8 ; + double *KCLcurrentsNodePrime_9 ; + double *KCLcurrentsNodePrime_10 ; + double *KCLcurrentdbNode_1 ; + double *KCLcurrentdbNode_2 ; + double *KCLcurrentsbNode_1 ; + double *KCLcurrentsbNode_2 ; + double *KCLcurrentqNode_1 ; + double *KCLcurrentqNode_2 ; +#endif + } BSIM4instance ; struct bsim4SizeDependParam diff --git a/src/spicelib/devices/cap/Makefile.am b/src/spicelib/devices/cap/Makefile.am index 78d8daaff..ae995c303 100644 --- a/src/spicelib/devices/cap/Makefile.am +++ b/src/spicelib/devices/cap/Makefile.am @@ -30,6 +30,9 @@ libcap_la_SOURCES = \ captrunc.c +if KIRCHHOFF_WANTED +libcap_la_SOURCES += capnode.c +endif AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include AM_CFLAGS = $(STATIC) diff --git a/src/spicelib/devices/cap/capdefs.h b/src/spicelib/devices/cap/capdefs.h index 09ebf9fa9..c241b4d91 100644 --- a/src/spicelib/devices/cap/capdefs.h +++ b/src/spicelib/devices/cap/capdefs.h @@ -59,6 +59,11 @@ typedef struct sCAPinstance { int CAPsenParmNo; /* parameter # for sensitivity use; set equal to 0 if not a design parameter*/ +#ifdef KIRCHHOFF + double *KCLcurrentPos ; + double *KCLcurrentNeg ; +#endif + } CAPinstance ; #define CAPqcap CAPstate /* charge on the capacitor */ diff --git a/src/spicelib/devices/cap/capext.h b/src/spicelib/devices/cap/capext.h index 4fd5c6d0d..bde63d8fa 100644 --- a/src/spicelib/devices/cap/capext.h +++ b/src/spicelib/devices/cap/capext.h @@ -23,3 +23,6 @@ extern int CAPsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int CAPtemp(GENmodel*,CKTcircuit*); extern int CAPtrunc(GENmodel*,CKTcircuit*,double*); +#ifdef KIRCHHOFF +extern int CAPnodeIsNonLinear (GENmodel *, CKTcircuit *) ; +#endif diff --git a/src/spicelib/devices/cap/capinit.c b/src/spicelib/devices/cap/capinit.c index f3cc19208..fc11998a4 100644 --- a/src/spicelib/devices/cap/capinit.c +++ b/src/spicelib/devices/cap/capinit.c @@ -74,7 +74,7 @@ SPICEdev CAPinfo = { /* DEVmodSize */ &CAPmSize, #ifdef KIRCHHOFF - /* DEVnodeIsNonLinear */ NULL + /* DEVnodeIsNonLinear */ CAPnodeIsNonLinear #endif }; diff --git a/src/spicelib/devices/cap/capload.c b/src/spicelib/devices/cap/capload.c index 13e166e30..8789aa321 100644 --- a/src/spicelib/devices/cap/capload.c +++ b/src/spicelib/devices/cap/capload.c @@ -79,8 +79,11 @@ CAPload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTrhs+here->CAPnegNode) += m * ceq; #ifdef KIRCHHOFF - *(ckt->CKTfvk+here->CAPposNode) += m * *(ckt->CKTstate0+here->CAPqcap+1) ; - *(ckt->CKTfvk+here->CAPnegNode) -= m * *(ckt->CKTstate0+here->CAPqcap+1) ; + *(ckt->CKTfvk+here->CAPposNode) += m * *(ckt->CKTstate0+here->CAPccap) ; + *(ckt->CKTfvk+here->CAPnegNode) -= m * *(ckt->CKTstate0+here->CAPccap) ; + + *(here->KCLcurrentPos) = m * *(ckt->CKTstate0+here->CAPccap) ; + *(here->KCLcurrentNeg) = -(m * *(ckt->CKTstate0+here->CAPccap)) ; #endif } else diff --git a/src/spicelib/devices/cap/capnode.c b/src/spicelib/devices/cap/capnode.c new file mode 100644 index 000000000..2b37003eb --- /dev/null +++ b/src/spicelib/devices/cap/capnode.c @@ -0,0 +1,29 @@ +/********** +Author: 2013 Francesco Lannutti +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "capdefs.h" +#include "ngspice/sperror.h" + +int +CAPnodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt) +{ + CAPmodel *model = (CAPmodel *)inModel ; + CAPinstance *here ; + int error ; + + /* loop through all the CAP models */ + for ( ; model != NULL ; model = model->CAPnextModel) + { + /* loop through all the instances of the model */ + for (here = model->CAPinstances ; here != NULL ; here = here->CAPnextInstance) + { + error = CKTmkCurKCL (ckt, here->CAPposNode, &(here->KCLcurrentPos)) ; + error = CKTmkCurKCL (ckt, here->CAPnegNode, &(here->KCLcurrentNeg)) ; + } + } + + return (OK) ; +} diff --git a/src/spicelib/devices/dio/diodefs.h b/src/spicelib/devices/dio/diodefs.h index 2ea4cd4ac..e25ccbf28 100644 --- a/src/spicelib/devices/dio/diodefs.h +++ b/src/spicelib/devices/dio/diodefs.h @@ -142,6 +142,12 @@ typedef struct sDIOinstance { double **DIOnVar; #endif /* NONOISE */ +#ifdef KIRCHHOFF + double *KCLcurrentPos ; + double *KCLcurrentNeg ; + double *KCLcurrentPosPrime ; +#endif + } DIOinstance ; #define DIOsenGeq DIOsens /* stores the perturbed values of geq */ diff --git a/src/spicelib/devices/dio/dioext.h b/src/spicelib/devices/dio/dioext.h index 4583195cb..349f379bd 100644 --- a/src/spicelib/devices/dio/dioext.h +++ b/src/spicelib/devices/dio/dioext.h @@ -28,4 +28,7 @@ extern int DIOtrunc(GENmodel*,CKTcircuit*,double*); extern int DIOdisto(int,GENmodel*,CKTcircuit*); extern int DIOnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int DIOdSetup(DIOmodel*,CKTcircuit*); + +#ifdef KIRCHHOFF extern int DIOnodeIsNonLinear (GENmodel *, CKTcircuit *) ; +#endif diff --git a/src/spicelib/devices/dio/dioload.c b/src/spicelib/devices/dio/dioload.c index a06ea41e5..b6d69eb35 100644 --- a/src/spicelib/devices/dio/dioload.c +++ b/src/spicelib/devices/dio/dioload.c @@ -408,6 +408,17 @@ next2: *(ckt->CKTstate0 + here->DIOvoltage) = vd; *(here->DIOnegPosPrimePtr) -= gd; *(here->DIOposPrimePosPtr) -= gspr; *(here->DIOposPrimeNegPtr) -= gd; + +#ifdef KIRCHHOFF + *(ckt->CKTfvk+here->DIOposNode) += gspr * (*(ckt->CKTrhsOld+here->DIOposNode) - *(ckt->CKTrhsOld+here->DIOposPrimeNode)) ; + *(ckt->CKTfvk+here->DIOnegNode) -= cd ; + *(ckt->CKTfvk+here->DIOposPrimeNode) += (cd - gspr * (*(ckt->CKTrhsOld+here->DIOposNode) - *(ckt->CKTrhsOld+here->DIOposPrimeNode))) ; + + *(here->KCLcurrentPos) = gspr * (*(ckt->CKTrhsOld+here->DIOposNode) - *(ckt->CKTrhsOld+here->DIOposPrimeNode)) ; + *(here->KCLcurrentNeg) = -cd ; + *(here->KCLcurrentPosPrime) = cd - gspr * (*(ckt->CKTrhsOld+here->DIOposNode) - *(ckt->CKTrhsOld+here->DIOposPrimeNode)) ; +#endif + } } return(OK); diff --git a/src/spicelib/devices/dio/dionode.c b/src/spicelib/devices/dio/dionode.c index 0f19a8795..5c5aef3fc 100644 --- a/src/spicelib/devices/dio/dionode.c +++ b/src/spicelib/devices/dio/dionode.c @@ -12,6 +12,7 @@ DIOnodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt) { DIOmodel *model = (DIOmodel *)inModel ; DIOinstance *here ; + int error ; /* loop through all the DIO models */ for ( ; model != NULL ; model = model->DIOnextModel) @@ -21,6 +22,10 @@ DIOnodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt) { ckt->CKTnodeIsLinear [here->DIOposPrimeNode] = 0 ; ckt->CKTnodeIsLinear [here->DIOnegNode] = 0 ; + + error = CKTmkCurKCL (ckt, here->DIOposNode, &(here->KCLcurrentPos)) ; + error = CKTmkCurKCL (ckt, here->DIOnegNode, &(here->KCLcurrentNeg)) ; + error = CKTmkCurKCL (ckt, here->DIOposPrimeNode, &(here->KCLcurrentPosPrime)) ; } } diff --git a/src/spicelib/devices/res/Makefile.am b/src/spicelib/devices/res/Makefile.am index c3d8f33ae..6a1c398d0 100644 --- a/src/spicelib/devices/res/Makefile.am +++ b/src/spicelib/devices/res/Makefile.am @@ -27,6 +27,9 @@ libres_la_SOURCES = \ restemp.c +if KIRCHHOFF_WANTED +libres_la_SOURCES += resnode.c +endif AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include AM_CFLAGS = $(STATIC) diff --git a/src/spicelib/devices/res/resdefs.h b/src/spicelib/devices/res/resdefs.h index ed8581e71..c9ff7b6d3 100644 --- a/src/spicelib/devices/res/resdefs.h +++ b/src/spicelib/devices/res/resdefs.h @@ -81,6 +81,11 @@ typedef struct sRESinstance { double **RESnVar; #endif /* NONOISE */ +#ifdef KIRCHHOFF + double *KCLcurrentPos ; + double *KCLcurrentNeg ; +#endif + } RESinstance ; diff --git a/src/spicelib/devices/res/resext.h b/src/spicelib/devices/res/resext.h index ee4be5516..4d5f87b66 100644 --- a/src/spicelib/devices/res/resext.h +++ b/src/spicelib/devices/res/resext.h @@ -20,3 +20,7 @@ extern void RESsPrint(GENmodel*,CKTcircuit*); extern int RESsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int REStemp(GENmodel*,CKTcircuit*); extern int RESnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); + +#ifdef KIRCHHOFF +extern int RESnodeIsNonLinear (GENmodel *, CKTcircuit *) ; +#endif diff --git a/src/spicelib/devices/res/resload.c b/src/spicelib/devices/res/resload.c index 07d3673e3..8356c4472 100644 --- a/src/spicelib/devices/res/resload.c +++ b/src/spicelib/devices/res/resload.c @@ -38,6 +38,9 @@ RESload(GENmodel *inModel, CKTcircuit *ckt) #ifdef KIRCHHOFF *(ckt->CKTfvk+here->RESposNode) += here->REScurrent ; *(ckt->CKTfvk+here->RESnegNode) -= here->REScurrent ; + + *(here->KCLcurrentPos) = here->REScurrent ; + *(here->KCLcurrentNeg) = -(here->REScurrent) ; #endif } diff --git a/src/spicelib/devices/res/resnode.c b/src/spicelib/devices/res/resnode.c new file mode 100644 index 000000000..9e6cbbf60 --- /dev/null +++ b/src/spicelib/devices/res/resnode.c @@ -0,0 +1,29 @@ +/********** +Author: 2013 Francesco Lannutti +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "resdefs.h" +#include "ngspice/sperror.h" + +int +RESnodeIsNonLinear (GENmodel *inModel, CKTcircuit *ckt) +{ + RESmodel *model = (RESmodel *)inModel ; + RESinstance *here ; + int error ; + + /* loop through all the RES models */ + for ( ; model != NULL ; model = model->RESnextModel) + { + /* loop through all the instances of the model */ + for (here = model->RESinstances ; here != NULL ; here = here->RESnextInstance) + { + error = CKTmkCurKCL (ckt, here->RESposNode, &(here->KCLcurrentPos)) ; + error = CKTmkCurKCL (ckt, here->RESnegNode, &(here->KCLcurrentNeg)) ; + } + } + + return (OK) ; +}