From 2ef046704e83f6d834b4b72cca3e3ce8c3a3b294 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 3 Jun 2026 16:40:45 +0200 Subject: [PATCH] A digital NAND gate 9-stage ring oscillator (less than 30ms simulation time) --- examples/xspice/various/ro_nand_digi.cir | 50 +++++++ src/spicelib/analysis/dcpss.c | 1 + src/spicelib/analysis/dctran.c | 2 + src/spicelib/analysis/optran.c | 1 + src/spicelib/devices/hfet1/hfetload.c | 43 +++--- src/spicelib/devices/hfet2/hfet2load.c | 31 ++-- src/spicelib/devices/hicum2/hicumL2.cpp | 181 ++++++++++++----------- src/spicelib/devices/jfet/jfetload.c | 29 ++-- src/spicelib/devices/jfet2/jfet2load.c | 39 ++--- src/spicelib/devices/mes/mesload.c | 31 ++-- src/spicelib/devices/mesa/mesaload.c | 33 +++-- src/spicelib/devices/vdmos/vdmosload.c | 69 +++++---- 12 files changed, 297 insertions(+), 213 deletions(-) create mode 100644 examples/xspice/various/ro_nand_digi.cir diff --git a/examples/xspice/various/ro_nand_digi.cir b/examples/xspice/various/ro_nand_digi.cir new file mode 100644 index 000000000..3c852928d --- /dev/null +++ b/examples/xspice/various/ro_nand_digi.cir @@ -0,0 +1,50 @@ +.TITLE DIGITAL RING OSCILLATOR, 9 stages, NAND gates, enable + +.OPTIONS NOACCT NOINIT NOMOD NOPAGE METHOD=gear XTRTOL=7 +.PARAM TEMP=25 VDD=3.3 + +.subckt ringOsc int_di1 a_clock d_en0 riseDelay=200e-12 fallDelay=200e-12 + A_ring_osc0 [int_di1 d_en0] int_di2 CM_NAND0 + A_ring_osc1 [int_di2 d_en0] int_di3 CM_NAND0 + A_ring_osc2 [int_di3 d_en0] int_di4 CM_NAND0 + A_ring_osc3 [int_di4 d_en0] int_di5 CM_NAND0 + A_ring_osc4 [int_di5 d_en0] int_di6 CM_NAND0 + A_ring_osc5 [int_di6 d_en0] int_di7 CM_NAND0 + A_ring_osc6 [int_di7 d_en0] int_di8 CM_NAND0 + A_ring_osc7 [int_di8 d_en0] int_di9 CM_NAND0 + A_ring_osc8 [int_di9 d_en0] int_di1 CM_NAND0 + + .model CM_NAND0 d_nand ( rise_delay= {riseDelay} fall_delay= {fallDelay} ) + A_adc1 [%vd(a_clock 0)] [d_en0] ADC + * oscillation starts only if no unknown logic state is produced at d_en0 + .model ADC adc_bridge in_low='VDD/2' in_high='VDD/2' +.ends + +* analogue output +abridge1 [node1] [aout] dac1 +.model dac1 dac_bridge( out_low = 0 out_high = {VDD} out_undef = {VDD/2} ++ input_load = 5.0e-12 t_rise = 200e-12 t_fall = 200e-12 ) + +* calling the r.o. +X1 node1 node2 node3 ringOsc riseDelay=200e-12 fallDelay=200e-12 +* enable signal +V_en node2 0 PULSE(0 3.3 30n 1n 1n 40n 80n) + +.control + tran 200p 200n +* sim time and memory usage + rusage +* plot and display the digital data + plot node1 node3 digitop + set xbrushwidth=2 + plot node1 node3 digitop xlimit 60n 80n + edisplay +* frequency and delay (measure 10 periods) + meas tran tdiff TRIG v(aout) VAL=1.65 RISE=2 TARG v(aout) VAL=1.65 RISE=12 + let freq = 10/tdiff*1e-9 + let del = 1/freq/9/2 + echo The oscillation frequency is $&freq GHz, the gate delay is $&del ns +.endc + +.endc +.end diff --git a/src/spicelib/analysis/dcpss.c b/src/spicelib/analysis/dcpss.c index aa0cee3c8..6bd998f5a 100644 --- a/src/spicelib/analysis/dcpss.c +++ b/src/spicelib/analysis/dcpss.c @@ -1015,6 +1015,7 @@ shootingexit: FREE (err_conv) ; FREE (psstimes) ; FREE (pssvalues) ; + ckt->CKTag[0] = ckt->CKTag[1] = 0.; return (OK) ; } } diff --git a/src/spicelib/analysis/dctran.c b/src/spicelib/analysis/dctran.c index ff203a082..083986231 100644 --- a/src/spicelib/analysis/dctran.c +++ b/src/spicelib/analysis/dctran.c @@ -449,6 +449,7 @@ DCtran(CKTcircuit *ckt, fprintf(stdout, "\nNote: Autostop after %e s, all measurement conditions are fulfilled.\n", ckt->CKTtime); /* Final return from tran upon success */ + ckt->CKTag[0] = ckt->CKTag[1] = 0.; return(OK); } if(SPfrontEnd->IFpauseTest()) { @@ -907,6 +908,7 @@ resume: SPfrontEnd->OUTendPlot(job->TRANplot); job->TRANplot = NULL; UPDATE_STATS(0); + ckt->CKTag[0] = ckt->CKTag[1] = 0.; /* return upon convergence failure */ return(E_TIMESTEP); } diff --git a/src/spicelib/analysis/optran.c b/src/spicelib/analysis/optran.c index 86dceab55..6f12dd6d3 100644 --- a/src/spicelib/analysis/optran.c +++ b/src/spicelib/analysis/optran.c @@ -484,6 +484,7 @@ OPtran(CKTcircuit *ckt, int oldconverged) SPfrontEnd->IFerrorf(ERR_INFO, "Transient op finished successfully"); ckt->CKTmaxStep = prevmaxstepsize; ckt->CKTstep = prevstepsize; + ckt->CKTag[0] = ckt->CKTag[1] = 0.; return(OK); } diff --git a/src/spicelib/devices/hfet1/hfetload.c b/src/spicelib/devices/hfet1/hfetload.c index c3c9c0530..fe4929ad7 100644 --- a/src/spicelib/devices/hfet1/hfetload.c +++ b/src/spicelib/devices/hfet1/hfetload.c @@ -313,7 +313,7 @@ int HFETAload(GENmodel *inModel, CKTcircuit *ckt) * compute equivalent drain current source */ cd = cdrain - cgd; - if ( (ckt->CKTmode & (MODETRAN|MODEINITSMSIG)) || + if ( (ckt->CKTmode & (MODEDCTRANCURVE|MODETRAN|MODEINITSMSIG)) || ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) ){ /* * charge storage elements @@ -357,28 +357,31 @@ int HFETAload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTstate1 + here->HFETAqds) = *(ckt->CKTstate0 + here->HFETAqds); } - error = NIintegrate(ckt,&geq,&ceq,capgs,here->HFETAqgs); - if(error) return(error); - ggspp = geq; - cgspp = *(ckt->CKTstate0 + here->HFETAcqgs); - cg = cg + cgspp; - error = NIintegrate(ckt,&geq,&ceq,capgd,here->HFETAqgd); - if(error) return(error); - ggdpp = geq; - cgdpp = *(ckt->CKTstate0 + here->HFETAcqgd); - cg = cg + cgdpp; - cd = cd - cgdpp; - error = NIintegrate(ckt,&geq,&ceq,CDS,here->HFETAqds); - if(error) return(error); - gds += geq; - cd += *(ckt->CKTstate0 + here->HFETAcqds); - if (ckt->CKTmode & MODEINITTRAN) { - *(ckt->CKTstate1 + here->HFETAcqgs) = + /* no integration, if dc sweep, but keep evaluating capacitances */ + if (!(ckt->CKTmode & MODEDCTRANCURVE)) { + error = NIintegrate(ckt, &geq, &ceq, capgs, here->HFETAqgs); + if (error) return(error); + ggspp = geq; + cgspp = *(ckt->CKTstate0 + here->HFETAcqgs); + cg = cg + cgspp; + error = NIintegrate(ckt, &geq, &ceq, capgd, here->HFETAqgd); + if (error) return(error); + ggdpp = geq; + cgdpp = *(ckt->CKTstate0 + here->HFETAcqgd); + cg = cg + cgdpp; + cd = cd - cgdpp; + error = NIintegrate(ckt, &geq, &ceq, CDS, here->HFETAqds); + if (error) return(error); + gds += geq; + cd += *(ckt->CKTstate0 + here->HFETAcqds); + if (ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->HFETAcqgs) = *(ckt->CKTstate0 + here->HFETAcqgs); - *(ckt->CKTstate1 + here->HFETAcqgd) = + *(ckt->CKTstate1 + here->HFETAcqgd) = *(ckt->CKTstate0 + here->HFETAcqgd); - *(ckt->CKTstate1 + here->HFETAcqds) = + *(ckt->CKTstate1 + here->HFETAcqds) = *(ckt->CKTstate0 + here->HFETAcqds); + } } } } diff --git a/src/spicelib/devices/hfet2/hfet2load.c b/src/spicelib/devices/hfet2/hfet2load.c index ad891e435..63189d7ae 100644 --- a/src/spicelib/devices/hfet2/hfet2load.c +++ b/src/spicelib/devices/hfet2/hfet2load.c @@ -218,7 +218,7 @@ int HFET2load(GENmodel *inModel, CKTcircuit *ckt) capgd = temp; } cd = cdrain - cgd; - if((ckt->CKTmode & (MODETRAN|MODEINITSMSIG)) || ((ckt->CKTmode & MODETRANOP) && + if((ckt->CKTmode & (MODEDCTRANCURVE|MODETRAN|MODEINITSMSIG)) || ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) ){ /* charge storage elements */ vgs1 = *(ckt->CKTstate1 + here->HFET2vgs); @@ -248,19 +248,22 @@ int HFET2load(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTstate1 + here->HFET2qgs) = *(ckt->CKTstate0 + here->HFET2qgs); *(ckt->CKTstate1 + here->HFET2qgd) = *(ckt->CKTstate0 + here->HFET2qgd); } - error = NIintegrate(ckt,&geq,&ceq,capgs,here->HFET2qgs); - if(error) return(error); - ggs = ggs + geq; - cg = cg + *(ckt->CKTstate0 + here->HFET2cqgs); - error = NIintegrate(ckt,&geq,&ceq,capgd,here->HFET2qgd); - if(error) return(error); - ggd = ggd + geq; - cg = cg + *(ckt->CKTstate0 + here->HFET2cqgd); - cd = cd - *(ckt->CKTstate0 + here->HFET2cqgd); - cgd = cgd + *(ckt->CKTstate0 + here->HFET2cqgd); - if (ckt->CKTmode & MODEINITTRAN) { - *(ckt->CKTstate1 + here->HFET2cqgs) = *(ckt->CKTstate0 + here->HFET2cqgs); - *(ckt->CKTstate1 + here->HFET2cqgd) = *(ckt->CKTstate0 + here->HFET2cqgd); + /* no integration, if dc sweep, but keep evaluating capacitances */ + if (!(ckt->CKTmode & MODEDCTRANCURVE)) { + error = NIintegrate(ckt, &geq, &ceq, capgs, here->HFET2qgs); + if (error) return(error); + ggs = ggs + geq; + cg = cg + *(ckt->CKTstate0 + here->HFET2cqgs); + error = NIintegrate(ckt, &geq, &ceq, capgd, here->HFET2qgd); + if (error) return(error); + ggd = ggd + geq; + cg = cg + *(ckt->CKTstate0 + here->HFET2cqgd); + cd = cd - *(ckt->CKTstate0 + here->HFET2cqgd); + cgd = cgd + *(ckt->CKTstate0 + here->HFET2cqgd); + if (ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->HFET2cqgs) = *(ckt->CKTstate0 + here->HFET2cqgs); + *(ckt->CKTstate1 + here->HFET2cqgd) = *(ckt->CKTstate0 + here->HFET2cqgd); + } } } } diff --git a/src/spicelib/devices/hicum2/hicumL2.cpp b/src/spicelib/devices/hicum2/hicumL2.cpp index d2da2e46a..512252d7f 100644 --- a/src/spicelib/devices/hicum2/hicumL2.cpp +++ b/src/spicelib/devices/hicum2/hicumL2.cpp @@ -2611,96 +2611,99 @@ HICUMload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTstate1 + here->HICUMqcth) = *(ckt->CKTstate0 + here->HICUMqcth) ; } + /* no integration, if dc sweep, but keep evaluating capacitances */ + if (!(ckt->CKTmode & MODEDCTRANCURVE)) { + //Integrate all charges and add the displacement current to the branch currents + //Qrbi + error = NIintegrate(ckt, &geq, &ceq, Qrbi_Vbpbi, here->HICUMqrbi); + if (error) return(error); + Ibpbi_Vbpbi += geq; + Ibpbi += *(ckt->CKTstate0 + here->HICUMcqrbi); + //Qjei + error = NIintegrate(ckt, &geq, &ceq, Cjei, here->HICUMqjei); + if (error) return(error); + Ibiei_Vbiei += geq; + Ibiei += *(ckt->CKTstate0 + here->HICUMcqjei); + //Qdeix + if (!model->HICUMnqs) { + error = NIintegrate(ckt, &geq, &ceq, Qdeix_Vbiei, here->HICUMqf); + if (error) return(error); + Ibiei_Vbiei += geq; + Ibiei_Vxf = 0; + Ibiei += *(ckt->CKTstate0 + here->HICUMcqf); + } + else { //Qdeix is now a function of Vxf(t) + error = NIintegrate(ckt, &geq, &ceq, Qdeix_Vxf, here->HICUMqf); + if (error) return(error); + Ibiei_Vxf = geq; + Ibiei += *(ckt->CKTstate0 + here->HICUMcqf); + } + //Qr + error = NIintegrate(ckt, &geq, &ceq, Qr_Vbici, here->HICUMqr); + if (error) return(error); + Ibici_Vbici += geq; + Ibici += *(ckt->CKTstate0 + here->HICUMcqr); + //Qjci + error = NIintegrate(ckt, &geq, &ceq, Cjci, here->HICUMqjci); + if (error) return(error); + Ibici_Vbici += geq; + Ibici += *(ckt->CKTstate0 + here->HICUMcqjci); + //Qjep + error = NIintegrate(ckt, &geq, &ceq, Cjep, here->HICUMqjep); + if (error) return(error); + Ibpei_Vbpei += geq; + Ibpei += *(ckt->CKTstate0 + here->HICUMcqjep); + //Qjcx_i + error = NIintegrate(ckt, &geq, &ceq, Cjcx_i, here->HICUMqjcx0_i); + if (error) return(error); + Ibci_Vbci = geq; + Ibci = *(ckt->CKTstate0 + here->HICUMcqcx0_t_i); + //Qjcx_ii + error = NIintegrate(ckt, &geq, &ceq, Cjcx_ii, here->HICUMqjcx0_ii); + if (error) return(error); + Ibpci_Vbpci += geq; + Ibpci += *(ckt->CKTstate0 + here->HICUMcqcx0_t_ii); + //Qdsu + error = NIintegrate(ckt, &geq, &ceq, Qdsu_Vbpci, here->HICUMqdsu); + if (error) return(error); + Ibpci_Vbpci += geq; + Ibpci += *(ckt->CKTstate0 + here->HICUMcqdsu); + //Qjs + error = NIintegrate(ckt, &geq, &ceq, Cjs, here->HICUMqjs); + if (error) return(error); + Isici_Vsici += geq; + Isici += *(ckt->CKTstate0 + here->HICUMcqjs); + //Qscp + error = NIintegrate(ckt, &geq, &ceq, Cscp, here->HICUMqscp); + if (error) return(error); + Isc_Vsc = geq; + Isc = *(ckt->CKTstate0 + here->HICUMcqscp); + if (model->HICUMnqs) { + //Qxf1 + error = NIintegrate(ckt, &geq, &ceq, Qxf1_Vxf1, here->HICUMqxf1); + if (error) return(error); + Ixf1_Vxf1 += geq; + Ixf1 += *(ckt->CKTstate0 + here->HICUMcqxf1); + //Qxf2 + error = NIintegrate(ckt, &geq, &ceq, Qxf2_Vxf2, here->HICUMqxf2); + if (error) return(error); + Ixf2_Vxf2 += geq; + Ixf2 += *(ckt->CKTstate0 + here->HICUMcqxf2); + //Qxf + error = NIintegrate(ckt, &geq, &ceq, Qxf_Vxf, here->HICUMqxf); + if (error) return(error); + Ixf_Vxf += geq; + Ixf += *(ckt->CKTstate0 + here->HICUMcqxf); + } - //Integrate all charges and add the displacement current to the branch currents - //Qrbi - error = NIintegrate(ckt,&geq,&ceq,Qrbi_Vbpbi,here->HICUMqrbi); - if(error) return(error); - Ibpbi_Vbpbi += geq; - Ibpbi += *(ckt->CKTstate0 + here->HICUMcqrbi); - //Qjei - error = NIintegrate(ckt,&geq,&ceq,Cjei,here->HICUMqjei); - if(error) return(error); - Ibiei_Vbiei += geq; - Ibiei += *(ckt->CKTstate0 + here->HICUMcqjei); - //Qdeix - if (!model->HICUMnqs) { - error = NIintegrate(ckt,&geq,&ceq,Qdeix_Vbiei,here->HICUMqf); - if(error) return(error); - Ibiei_Vbiei += geq; - Ibiei_Vxf = 0; - Ibiei += *(ckt->CKTstate0 + here->HICUMcqf); - } else { //Qdeix is now a function of Vxf(t) - error = NIintegrate(ckt,&geq,&ceq,Qdeix_Vxf,here->HICUMqf); - if(error) return(error); - Ibiei_Vxf = geq; - Ibiei += *(ckt->CKTstate0 + here->HICUMcqf); - } - //Qr - error = NIintegrate(ckt,&geq,&ceq,Qr_Vbici,here->HICUMqr); - if(error) return(error); - Ibici_Vbici += geq; - Ibici += *(ckt->CKTstate0 + here->HICUMcqr); - //Qjci - error = NIintegrate(ckt,&geq,&ceq,Cjci,here->HICUMqjci); - if(error) return(error); - Ibici_Vbici += geq; - Ibici += *(ckt->CKTstate0 + here->HICUMcqjci); - //Qjep - error = NIintegrate(ckt,&geq,&ceq,Cjep,here->HICUMqjep); - if(error) return(error); - Ibpei_Vbpei += geq; - Ibpei += *(ckt->CKTstate0 + here->HICUMcqjep); - //Qjcx_i - error = NIintegrate(ckt,&geq,&ceq,Cjcx_i,here->HICUMqjcx0_i); - if(error) return(error); - Ibci_Vbci = geq; - Ibci = *(ckt->CKTstate0 + here->HICUMcqcx0_t_i); - //Qjcx_ii - error = NIintegrate(ckt,&geq,&ceq,Cjcx_ii,here->HICUMqjcx0_ii); - if(error) return(error); - Ibpci_Vbpci += geq; - Ibpci += *(ckt->CKTstate0 + here->HICUMcqcx0_t_ii); - //Qdsu - error = NIintegrate(ckt,&geq,&ceq,Qdsu_Vbpci,here->HICUMqdsu); - if(error) return(error); - Ibpci_Vbpci += geq; - Ibpci += *(ckt->CKTstate0 + here->HICUMcqdsu); - //Qjs - error = NIintegrate(ckt,&geq,&ceq,Cjs,here->HICUMqjs); - if(error) return(error); - Isici_Vsici += geq; - Isici += *(ckt->CKTstate0 + here->HICUMcqjs); - //Qscp - error = NIintegrate(ckt,&geq,&ceq,Cscp,here->HICUMqscp); - if(error) return(error); - Isc_Vsc = geq; - Isc = *(ckt->CKTstate0 + here->HICUMcqscp); - if (model->HICUMnqs) { - //Qxf1 - error = NIintegrate(ckt,&geq,&ceq,Qxf1_Vxf1,here->HICUMqxf1); - if(error) return(error); - Ixf1_Vxf1 += geq; - Ixf1 += *(ckt->CKTstate0 + here->HICUMcqxf1); - //Qxf2 - error = NIintegrate(ckt,&geq,&ceq,Qxf2_Vxf2,here->HICUMqxf2); - if(error) return(error); - Ixf2_Vxf2 += geq; - Ixf2 += *(ckt->CKTstate0 + here->HICUMcqxf2); - //Qxf - error = NIintegrate(ckt,&geq,&ceq,Qxf_Vxf,here->HICUMqxf); - if(error) return(error); - Ixf_Vxf += geq; - Ixf += *(ckt->CKTstate0 + here->HICUMcqxf); - } - - if (model->HICUMselfheat) - { - //Qth - error = NIintegrate(ckt,&geq,&ceq,here->HICUMcth_scaled,here->HICUMqcth); - if(error) return(error); - Icth_Vrth = geq; - Icth = *(ckt->CKTstate0 + here->HICUMcqcth); + if (model->HICUMselfheat) + { + //Qth + error = NIintegrate(ckt, &geq, &ceq, here->HICUMcth_scaled, here->HICUMqcth); + if (error) return(error); + Icth_Vrth = geq; + Icth = *(ckt->CKTstate0 + here->HICUMcqcth); + } } if(ckt->CKTmode & MODEINITTRAN) { diff --git a/src/spicelib/devices/jfet/jfetload.c b/src/spicelib/devices/jfet/jfetload.c index b1e0ac106..f91d0d589 100644 --- a/src/spicelib/devices/jfet/jfetload.c +++ b/src/spicelib/devices/jfet/jfetload.c @@ -452,21 +452,24 @@ JFETload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTstate1 + here->JFETqgd) = *(ckt->CKTstate0 + here->JFETqgd); } - error = NIintegrate(ckt,&geq,&ceq,capgs,here->JFETqgs); - if(error) return(error); - ggs = ggs + geq; - cg = cg + *(ckt->CKTstate0 + here->JFETcqgs); - error = NIintegrate(ckt,&geq,&ceq,capgd,here->JFETqgd); - if(error) return(error); - ggd = ggd + geq; - cg = cg + *(ckt->CKTstate0 + here->JFETcqgd); - cd = cd - *(ckt->CKTstate0 + here->JFETcqgd); - cgd = cgd + *(ckt->CKTstate0 + here->JFETcqgd); - if (ckt->CKTmode & MODEINITTRAN) { - *(ckt->CKTstate1 + here->JFETcqgs) = + /* no integration, if dc sweep, but keep evaluating capacitances */ + if (!(ckt->CKTmode & MODEDCTRANCURVE)) { + error = NIintegrate(ckt, &geq, &ceq, capgs, here->JFETqgs); + if (error) return(error); + ggs = ggs + geq; + cg = cg + *(ckt->CKTstate0 + here->JFETcqgs); + error = NIintegrate(ckt, &geq, &ceq, capgd, here->JFETqgd); + if (error) return(error); + ggd = ggd + geq; + cg = cg + *(ckt->CKTstate0 + here->JFETcqgd); + cd = cd - *(ckt->CKTstate0 + here->JFETcqgd); + cgd = cgd + *(ckt->CKTstate0 + here->JFETcqgd); + if (ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->JFETcqgs) = *(ckt->CKTstate0 + here->JFETcqgs); - *(ckt->CKTstate1 + here->JFETcqgd) = + *(ckt->CKTstate1 + here->JFETcqgd) = *(ckt->CKTstate0 + here->JFETcqgd); + } } } } diff --git a/src/spicelib/devices/jfet2/jfet2load.c b/src/spicelib/devices/jfet2/jfet2load.c index ff68f3745..151e1d6c2 100644 --- a/src/spicelib/devices/jfet2/jfet2load.c +++ b/src/spicelib/devices/jfet2/jfet2load.c @@ -211,7 +211,7 @@ JFET2load(GENmodel *inModel, CKTcircuit *ckt) cg = cg + cgd; cd = cd - cgd; - if ( (ckt->CKTmode & (MODETRAN | MODEAC | MODEINITSMSIG) ) || + if ( (ckt->CKTmode & (MODEDCTRANCURVE | MODETRAN | MODEAC | MODEINITSMSIG) ) || ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) ){ /* * charge storage elements @@ -244,26 +244,29 @@ JFET2load(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTstate1 + here->JFET2qds) = *(ckt->CKTstate0 + here->JFET2qds); } - error = NIintegrate(ckt,&geq,&ceq,capgs,here->JFET2qgs); - if(error) return(error); - ggs = ggs + geq; - cg = cg + *(ckt->CKTstate0 + here->JFET2cqgs); - error = NIintegrate(ckt,&geq,&ceq,capgd,here->JFET2qgd); - if(error) return(error); - ggd = ggd + geq; - cg = cg + *(ckt->CKTstate0 + here->JFET2cqgd); - cd = cd - *(ckt->CKTstate0 + here->JFET2cqgd); - cgd = cgd + *(ckt->CKTstate0 + here->JFET2cqgd); - error = NIintegrate(ckt,&geq,&ceq,capds,here->JFET2qds); - cd = cd + *(ckt->CKTstate0 + here->JFET2cqds); - if(error) return(error); - if (ckt->CKTmode & MODEINITTRAN) { - *(ckt->CKTstate1 + here->JFET2cqgs) = + /* no integration, if dc sweep, but keep evaluating capacitances */ + if (!(ckt->CKTmode & MODEDCTRANCURVE)) { + error = NIintegrate(ckt, &geq, &ceq, capgs, here->JFET2qgs); + if (error) return(error); + ggs = ggs + geq; + cg = cg + *(ckt->CKTstate0 + here->JFET2cqgs); + error = NIintegrate(ckt, &geq, &ceq, capgd, here->JFET2qgd); + if (error) return(error); + ggd = ggd + geq; + cg = cg + *(ckt->CKTstate0 + here->JFET2cqgd); + cd = cd - *(ckt->CKTstate0 + here->JFET2cqgd); + cgd = cgd + *(ckt->CKTstate0 + here->JFET2cqgd); + error = NIintegrate(ckt, &geq, &ceq, capds, here->JFET2qds); + cd = cd + *(ckt->CKTstate0 + here->JFET2cqds); + if (error) return(error); + if (ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->JFET2cqgs) = *(ckt->CKTstate0 + here->JFET2cqgs); - *(ckt->CKTstate1 + here->JFET2cqgd) = + *(ckt->CKTstate1 + here->JFET2cqgd) = *(ckt->CKTstate0 + here->JFET2cqgd); - *(ckt->CKTstate1 + here->JFET2cqds) = + *(ckt->CKTstate1 + here->JFET2cqds) = *(ckt->CKTstate0 + here->JFET2cqds); + } } } } diff --git a/src/spicelib/devices/mes/mesload.c b/src/spicelib/devices/mes/mesload.c index 2226991ba..32a83a2ec 100644 --- a/src/spicelib/devices/mes/mesload.c +++ b/src/spicelib/devices/mes/mesload.c @@ -335,7 +335,7 @@ MESload(GENmodel *inModel, CKTcircuit *ckt) * compute equivalent drain current source */ cd = cdrain - cgd; - if ( (ckt->CKTmode & (MODETRAN|MODEINITSMSIG)) || + if ( (ckt->CKTmode & (MODEDCTRANCURVE | MODETRAN | MODEINITSMSIG)) || ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) ){ /* * charge storage elements @@ -382,21 +382,24 @@ MESload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTstate1 + here->MESqgd) = *(ckt->CKTstate0 + here->MESqgd); } - error = NIintegrate(ckt,&geq,&ceq,capgs,here->MESqgs); - if(error) return(error); - ggs = ggs + geq; - cg = cg + *(ckt->CKTstate0 + here->MEScqgs); - error = NIintegrate(ckt,&geq,&ceq,capgd,here->MESqgd); - if(error) return(error); - ggd = ggd + geq; - cg = cg + *(ckt->CKTstate0 + here->MEScqgd); - cd = cd - *(ckt->CKTstate0 + here->MEScqgd); - cgd = cgd + *(ckt->CKTstate0 + here->MEScqgd); - if (ckt->CKTmode & MODEINITTRAN) { - *(ckt->CKTstate1 + here->MEScqgs) = + /* no integration, if dc sweep, but keep evaluating capacitances */ + if (!(ckt->CKTmode & MODEDCTRANCURVE)) { + error = NIintegrate(ckt, &geq, &ceq, capgs, here->MESqgs); + if (error) return(error); + ggs = ggs + geq; + cg = cg + *(ckt->CKTstate0 + here->MEScqgs); + error = NIintegrate(ckt, &geq, &ceq, capgd, here->MESqgd); + if (error) return(error); + ggd = ggd + geq; + cg = cg + *(ckt->CKTstate0 + here->MEScqgd); + cd = cd - *(ckt->CKTstate0 + here->MEScqgd); + cgd = cgd + *(ckt->CKTstate0 + here->MEScqgd); + if (ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->MEScqgs) = *(ckt->CKTstate0 + here->MEScqgs); - *(ckt->CKTstate1 + here->MEScqgd) = + *(ckt->CKTstate1 + here->MEScqgd) = *(ckt->CKTstate0 + here->MEScqgd); + } } } } diff --git a/src/spicelib/devices/mesa/mesaload.c b/src/spicelib/devices/mesa/mesaload.c index e1ffecd4a..9b8081f53 100644 --- a/src/spicelib/devices/mesa/mesaload.c +++ b/src/spicelib/devices/mesa/mesaload.c @@ -326,7 +326,7 @@ MESAload(GENmodel *inModel, CKTcircuit *ckt) * compute equivalent drain current source */ cd = cdrain - cgd; - if ( (ckt->CKTmode & (MODETRAN|MODEINITSMSIG)) || + if ( (ckt->CKTmode & (MODEDCTRANCURVE | MODETRAN | MODEINITSMSIG)) || ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) ){ /* * charge storage elements @@ -362,22 +362,25 @@ MESAload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTstate1 + here->MESAqgd) = *(ckt->CKTstate0 + here->MESAqgd); } - error = NIintegrate(ckt,&geq,&ceq,capgs,here->MESAqgs); - if(error) return(error); - ggspp = geq; - cgspp = *(ckt->CKTstate0 + here->MESAcqgs); - cg = cg + cgspp; - error = NIintegrate(ckt,&geq,&ceq,capgd,here->MESAqgd); - if(error) return(error); - ggdpp = geq; - cgdpp = *(ckt->CKTstate0 + here->MESAcqgd); - cg = cg + cgdpp; - cd = cd - cgdpp; - if (ckt->CKTmode & MODEINITTRAN) { - *(ckt->CKTstate1 + here->MESAcqgs) = + /* no integration, if dc sweep, but keep evaluating capacitances */ + if (!(ckt->CKTmode & MODEDCTRANCURVE)) { + error = NIintegrate(ckt, &geq, &ceq, capgs, here->MESAqgs); + if (error) return(error); + ggspp = geq; + cgspp = *(ckt->CKTstate0 + here->MESAcqgs); + cg = cg + cgspp; + error = NIintegrate(ckt, &geq, &ceq, capgd, here->MESAqgd); + if (error) return(error); + ggdpp = geq; + cgdpp = *(ckt->CKTstate0 + here->MESAcqgd); + cg = cg + cgdpp; + cd = cd - cgdpp; + if (ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->MESAcqgs) = *(ckt->CKTstate0 + here->MESAcqgs); - *(ckt->CKTstate1 + here->MESAcqgd) = + *(ckt->CKTstate1 + here->MESAcqgd) = *(ckt->CKTstate0 + here->MESAcqgd); + } } } } diff --git a/src/spicelib/devices/vdmos/vdmosload.c b/src/spicelib/devices/vdmos/vdmosload.c index 12f39be0c..addbe4921 100644 --- a/src/spicelib/devices/vdmos/vdmosload.c +++ b/src/spicelib/devices/vdmos/vdmosload.c @@ -477,7 +477,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) /* * vdmos capacitor model */ - if (ckt->CKTmode & (MODETRAN | MODETRANOP | MODEINITSMSIG)) { + if (ckt->CKTmode & (MODEDCTRANCURVE | MODETRAN | MODETRANOP | MODEINITSMSIG)) { /* * calculate gate - drain, gate - source capacitors * drain-source capacitor is evaluated with the body diode below @@ -567,18 +567,24 @@ bypass: * calculate equivalent conductances and currents for * vdmos capacitors */ - error = NIintegrate(ckt, &gcgs, &ceqgs, capgs, here->VDMOSqgs); - if (error) return(error); - error = NIintegrate(ckt, &gcgd, &ceqgd, capgd, here->VDMOSqgd); - if (error) return(error); - ceqgs = ceqgs - gcgs*vgs + ckt->CKTag[0] * - *(ckt->CKTstate0 + here->VDMOSqgs); - ceqgd = ceqgd - gcgd*vgd + ckt->CKTag[0] * - *(ckt->CKTstate0 + here->VDMOSqgd); - if (selfheat) - { - error = NIintegrate(ckt, &gcTt, &ceqqth, capth, here->VDMOSqth); + /* no integration, if dc sweep, but keep evaluating capacitances */ + if (!(ckt->CKTmode & MODEDCTRANCURVE)) { + error = NIintegrate(ckt, &gcgs, &ceqgs, capgs, here->VDMOSqgs); if (error) return(error); + error = NIintegrate(ckt, &gcgd, &ceqgd, capgd, here->VDMOSqgd); + if (error) return(error); + ceqgs = ceqgs - gcgs * vgs + ckt->CKTag[0] * + *(ckt->CKTstate0 + here->VDMOSqgs); + ceqgd = ceqgd - gcgd * vgd + ckt->CKTag[0] * + *(ckt->CKTstate0 + here->VDMOSqgd); + if (selfheat) + { + error = NIintegrate(ckt, &gcTt, &ceqqth, capth, here->VDMOSqth); + if (error) return(error); + } + } + else { + gcgs = gcgd = ceqgs = ceqgd = 0.; } } @@ -932,27 +938,30 @@ bypass: *(ckt->CKTstate1 + here->VDIOcapCharge) = *(ckt->CKTstate0 + here->VDIOcapCharge); } - error = NIintegrate(ckt, &geq, &ceq, capd, here->VDIOcapCharge); - if (error) return(error); - gd = gd + geq; - cd = cd + *(ckt->CKTstate0 + here->VDIOcapCurrent); - if (ckt->CKTmode & MODEINITTRAN) { - *(ckt->CKTstate1 + here->VDIOcapCurrent) = - *(ckt->CKTstate0 + here->VDIOcapCurrent); - } - if (revrec) { - /* soft recovery subcircuit */ + /* no integration, if dc sweep, but keep evaluating capacitances */ + if (!(ckt->CKTmode & MODEDCTRANCURVE)) { + error = NIintegrate(ckt, &geq, &ceq, capd, here->VDIOcapCharge); + if (error) return(error); + gd = gd + geq; + cd = cd + *(ckt->CKTstate0 + here->VDIOcapCurrent); if (ckt->CKTmode & MODEINITTRAN) { - *(ckt->CKTstate1 + here->VDIOsrcapCharge) = - *(ckt->CKTstate0 + here->VDIOsrcapCharge); + *(ckt->CKTstate1 + here->VDIOcapCurrent) = + *(ckt->CKTstate0 + here->VDIOcapCurrent); } - error = NIintegrate(ckt,&geq,&ceq,capsr,here->VDIOsrcapCharge); - if(error) return(error); - gqcsr = geq; - cqcsr = *(ckt->CKTstate0 + here->VDIOsrcapCurrent); - if (ckt->CKTmode & MODEINITTRAN) { - *(ckt->CKTstate1 + here->VDIOsrcapCurrent) = + if (revrec) { + /* soft recovery subcircuit */ + if (ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->VDIOsrcapCharge) = + *(ckt->CKTstate0 + here->VDIOsrcapCharge); + } + error = NIintegrate(ckt, &geq, &ceq, capsr, here->VDIOsrcapCharge); + if (error) return(error); + gqcsr = geq; + cqcsr = *(ckt->CKTstate0 + here->VDIOsrcapCurrent); + if (ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->VDIOsrcapCurrent) = *(ckt->CKTstate0 + here->VDIOsrcapCurrent); + } } } }