diff --git a/examples/pss/19-nand-ro-IHP_ctrl.cir b/examples/pss/19-nand-ro-IHP_ctrl.cir new file mode 100644 index 000000000..e3ec97712 --- /dev/null +++ b/examples/pss/19-nand-ro-IHP_ctrl.cir @@ -0,0 +1,68 @@ +NAND-2 Ring Oscillator IHP Open PDK + +.lib "$PDK_ROOT/$PDK/libs.tech/ngspice/models/cornerMOSlv.lib" mos_tt + +.subckt nand2 a b vdd vss z +xm01 vdd a z vdd sg13_lv_pmos l=0.15u w=0.96u as=0.20405p ad=0.20405p ps=2.07u pd=2.07u +xm02 vss a sig3 vss sg13_lv_nmos l=0.15u w=0.82u as=0.1749p ad=0.1749p ps=1.85u pd=1.85u +xm03 z b vdd vdd sg13_lv_pmos l=0.15u w=0.96u as=0.20405p ad=0.20405p ps=2.07u pd=2.07u +xm04 sig3 b z vss sg13_lv_nmos l=0.15u w=0.82u as=0.1749p ad=0.1749p ps=1.85u pd=1.85u +c4 a vss 0.549f +c5 b vss 0.578f +c1 z vss 0.609f +.ends + +XNAND1 1 1 vd vs 2 nand2 +XNAND2 2 2 vd vs 3 nand2 +XNAND3 3 3 vd vs 4 nand2 +XNAND4 4 4 vd vs 5 nand2 +XNAND5 5 5 vd vs 6 nand2 +XNAND6 6 6 vd vs 7 nand2 +XNAND7 7 7 vd vs 8 nand2 +XNAND8 8 8 vd vs 9 nand2 +XNAND9 9 9 vd vs 10 nand2 +XNAND10 10 10 vd vs 11 nand2 +XNAND11 11 11 vd vs 12 nand2 +XNAND12 12 12 vd vs 13 nand2 +XNAND13 13 13 vd vs 14 nand2 +XNAND14 14 14 vd vs 15 nand2 +XNAND15 15 15 vd vs 16 nand2 +XNAND16 16 16 vd vs 17 nand2 +XNAND17 17 17 vd vs 18 nand2 +XNAND18 18 18 vd vs 19 nand2 +XNAND19 19 19 vd vs 1 nand2 + +XNAND20 1 1 vd 0 out nand2 + +Vdd vd 0 1.5 +Vss vs 0 0 + +.option noinit + +.tran 10p 80n uic + +.control +pre_osdi ../lib/ngspice/psp103_nqs.osdi ../lib/ngspice/psp103.osdi +set temp=0 +option klu +run +rusage +set xbrushwidth=3 +*plot i(Vss) ylimit 0 500u xlimit 50n 60n +plot out +plot out xlimit 50n 60n +meas tran tdiff TRIG V(out) val=0.7 rise=5 TARG v(out) val=0.7 rise=15 +let freq=10/tdiff +print freq +linearize out +fft out +plot mag(out) xlimit 300Meg 2300Meg +meas sp fmax MAX_AT out from=1e8 to=1e9 +echo +reset +pss 500e6 10n out 256 10 5 5e-3 uic +plot out xlimit 300Meg 2300Meg +inventory +.endc + +.end diff --git a/examples/pss/colpitt_osc_pss_ctrl.cir b/examples/pss/colpitt_osc_pss_ctrl.cir new file mode 100644 index 000000000..74ea012df --- /dev/null +++ b/examples/pss/colpitt_osc_pss_ctrl.cir @@ -0,0 +1,41 @@ +Colpitt's Oscillator Circuit +* Colpitt is an harmonic oscillator (LC based) which use +* a capacitive partition of resonator to feed the single +* active device. +* Predicted frequency is about 3.30435e+06 Hz. + +* Models: +.model qnl npn(level=1 bf=80 rb=100 ccs=2pf tf=0.3ns tr=6ns cje=3pf cjc=2pf va=50) + +r1 1 0 1 +q1 2 1 3 qnl +vcc 4 0 5 +rl 4 2 750 +c1 2 3 500p +c2 4 3 4500p +l1 4 2 5uH +re 3 6 4.65k +vee 6 0 dc -10 pwl 0 0 1e-9 -10 + +.control +** transient sim +tran 3n 120u 20u +plot V(2) v(3) +** fft of tran sim +linearize v(3) +fft v(3) +let dbv3 = db(v(3)) +plot dbv3 xlimit 1Meg 5Meg +** measure the frequency of oscillation +meas sp fosc MAX_AT dbv3 from=1Meg to=5Meg +** periodic steady state sim +pss 1e6 50e-6 3 256 10 50 5e-3 +set xbrushwidth=3 +plot v(3) ylimit 0 0.3 +.endc + +.end + + + + diff --git a/examples/pss/compl_cross_quad_osc_pss_ctrl.cir b/examples/pss/compl_cross_quad_osc_pss_ctrl.cir new file mode 100644 index 000000000..2c169508b --- /dev/null +++ b/examples/pss/compl_cross_quad_osc_pss_ctrl.cir @@ -0,0 +1,44 @@ +Complimentary Cross Quad CMOS Oscillator +* Predicted frequency is 5.61224e+08 Hz. +* +* PLOT i1 + +* Supply +vdd vdd gnd 1.2 pwl 0 1.2 1e-9 1.2 +rdd vdd vdd_ana 70m +rgnd gnd gnd_ana 70m + +* Cross quad +mpsx v_plus v_minus vdd_ana vdd_ana pch w=10u l=0.1u +mnsx v_plus v_minus gnd_ana gnd_ana nch w=10u l=0.1u +mpdx v_minus v_plus vdd_ana vdd_ana pch w=10u l=0.1u +mndx v_minus v_plus gnd_ana gnd_ana nch w=10u l=0.1u + +* Lumped elements model of real inductor +ls v_plus i1 19.462n ic=0.06 +rs i1 v_minus 7.789 +cs v_plus v_minus 443f +coxs v_plus is 2.178p +coxd v_minus id 2.178p +rsis is gnd_ana 308 +rsid id gnd_ana 308 +csis is gnd_ana 51f +csid id gnd_ana 51f + +* Parallel capacitor to determine leading resonance +cp v_plus v_minus 3.4p + +.model nch nmos ( version=4.7 level=54 lmin=0.1u lmax=20u wmin=0.1u wmax=10u ) +.model pch pmos ( version=4.7 level=54 lmin=0.1u lmax=20u wmin=0.1u wmax=10u ) + +.control +tran 0.05n 1u uic +plot i1 +reset +pss 400e6 2u 1 1024 10 10 5e-3 uic +set xbrushwidth=3 +plot i1 +.endc + +.end + diff --git a/examples/pss/hartley_osc_pss_ctrl.cir b/examples/pss/hartley_osc_pss_ctrl.cir new file mode 100644 index 000000000..6594a93d5 --- /dev/null +++ b/examples/pss/hartley_osc_pss_ctrl.cir @@ -0,0 +1,31 @@ +Hartley's Oscillator Circuit +* Hartley is an harmonic oscillator (LC based) which use +* an inductive partition of resonator to feed the single +* active device. Output is taken on node 2. +* Prediceted frequency is about 121.176 Hz. +* +* PLOT V(3) + +* Models: +.model qnl npn(level=1 bf=80 rb=100 ccs=2pf tf=0.3ns tr=6ns cje=3pf cjc=2pf va=50) + +vcc 1 0 5 pwl 0 0 1e-5 5 +r1 1 2 0.2k +q1 2 3 0 qnl +c1 3 4 633n +l1 3 0 1.5 +l2 0 4 500m +r2 4 2 100 + +.control +set xbrushwidth=3 +tran 10u 1 +plot v(2) +linearize v(2) +fft v(2) +plot mag(V(2)) xlimit 0 500 ylimit 0 1.5 +reset +pss 50 200e-3 2 1024 11 10 5e-3 +plot v(2) xlimit 0 500 ylimit 0 1.5 +.endc + diff --git a/examples/pss/ring_osc_pss_ctrl.cir b/examples/pss/ring_osc_pss_ctrl.cir new file mode 100644 index 000000000..04270ec96 --- /dev/null +++ b/examples/pss/ring_osc_pss_ctrl.cir @@ -0,0 +1,41 @@ +Ring CMOS Oscillator +* Oscillation is taken on node "bout". +* Predicted frequency is 3.8e+09 Hz. +* +* PLOT bout + +* Supply +vdd vdd gnd 1.2 pwl 0 1.2 1e-9 1.2 +rdd vdd vdd_ana 70m +rgnd gnd gnd_ana 70m + +* Inverter +mp1 inv1 inv3 vdd_ana vdd_ana pch w=10u l=0.18u +mn1 inv1 inv3 gnd_ana gnd_ana nch w=10u l=0.18u +mp2 inv2 inv1 vdd_ana vdd_ana pch w=10u l=0.18u +mn2 inv2 inv1 gnd_ana gnd_ana nch w=10u l=0.18u +mp3 inv3 inv2 vdd_ana vdd_ana pch w=10u l=0.18u +mn3 inv3 inv2 gnd_ana gnd_ana nch w=10u l=0.18u + +* Buffer out +mp4 bout inv3 vdd_ana vdd_ana pch w=10u l=0.18u +mn4 bout inv3 gnd_ana gnd_ana nch w=10u l=0.18u + +.model nch nmos ( version=4.7 level=54 lmin=0.1u lmax=20u wmin=0.1u wmax=10u ) +.model pch pmos ( version=4.7 level=54 lmin=0.1u lmax=20u wmin=0.1u wmax=10u ) + +.control +tran 0.005n 100n uic +plot v(bout) +linearize bout +fft bout +set xbrushwidth=3 +plot mag(bout) xlimit 0 35G + +reset +pss 2G 10n bout 1024 10 5 5e-3 uic +plot bout xlimit 0 35G +.endc + +.end + diff --git a/examples/pss/vackar_osc_pss_ctrl.cir b/examples/pss/vackar_osc_pss_ctrl.cir new file mode 100644 index 000000000..27f1c8eab --- /dev/null +++ b/examples/pss/vackar_osc_pss_ctrl.cir @@ -0,0 +1,33 @@ +Vackar's Oscillator Circuit +* Vackar is a derivation of Colpitt's oscillator (LC based). +* Oscillation is taken on node 4. +* Predicted frequency is 1.91803e+06Hz. + +* Models: +.model qnl npn(level=1 bf=80 rb=100 ccs=2pf tf=0.3ns tr=6ns cje=3pf cjc=2pf va=50) + +vcc 1 0 5 pwl 0 10 1e-9 5 +lrfc 1 2 100u +cdec 2 0 7n +q1 3 2 0 qnl +rb 3 0 4700 +c1 3 4 100p +c2 3 0 600p +c0 4 0 1n +l1 4 1 6.2u + +.control +tran 10n 20u +plot v(4) +linearize v(4) +fft v(4) +set xbrushwidth=3 +plot mag(v(4)) xlimit 0 10Meg +let maxfft=mag(v(4)) +meas sp fosc MAX_AT maxfft from=1Meg to=10Meg +reset +pss 1.8e6 10e-6 4 1024 10 50 5e-3 uic +plot v(4) xlimit 0 10Meg +.endc +.end + diff --git a/examples/pss/vdp_osc_pss.cir b/examples/pss/vdp_osc_pss.cir index f4e66815c..d5f399f71 100644 --- a/examples/pss/vdp_osc_pss.cir +++ b/examples/pss/vdp_osc_pss.cir @@ -1,17 +1,25 @@ Van Der Pol Oscillator * Prediceted frequency is about 4.54167e+06 Hz. -* Third harmonic is high as the first one -Ba gib 0 I=-1e-2*v(gib,0)+1e-2*v(gib,0)^3 +* Third harmonic is as high as the first one +Ba gib 0 I=-1e-2*v(gib,0)+1e-2*v(gib,0)^3 * Q is about 10 -La gib 0 1.2e-6 -Ra gib 0 158.113 -Ca gib 0 1e-9 ic=0.5 -*La gib 0 1e-9 -*Ra gib 0 474.6 -*Ca gib 0 1e-9 ic=0.5 -* Ghost node... Test for my PSS! -Rb bad 0 1k +RLa gib gib1 1m +La gib1 0 1.2e-6 +Ra gib 0 158.113 +Ca gib 0 1e-9 ic=-1 + +Vnew 0 gr 1 +Rnew gr gib 5k + +*La gib 0 1e-9 +*Ra gib 0 474.6 +*Ca gib 0 1e-9 ; ic=0.5 +* Ghost node... Test for my PSS! +*Rb bad 0 1k + +.tran 10e-9 20e-6 uic +.pss 0.5e6 100e-6 1 50 10 50 5e-3 uic + +.end -*.tran 1e-9 150e-6 uic -.pss 0.8e6 130e-6 1 50 10 50 5e-3 uic diff --git a/examples/pss/vdp_osc_pss_ctrl.cir b/examples/pss/vdp_osc_pss_ctrl.cir new file mode 100644 index 000000000..011d0943c --- /dev/null +++ b/examples/pss/vdp_osc_pss_ctrl.cir @@ -0,0 +1,37 @@ +Van Der Pol Oscillator +* Prediceted frequency is about 4.54167e+06 Hz. + +* Third harmonic is as high as the first one +Ba gib 0 I=-1e-2*v(gib,0)+1e-2*v(gib,0)^3 +* Q is about 10 +RLa gib gib1 1m +La gib1 0 1.2e-6 +Ra gib 0 158.113 +Ca gib 0 1e-9 ic=-1 + +Vnew 0 gr 1 +Rnew gr gib 5k + +*La gib 0 1e-9 +*Ra gib 0 474.6 +*Ca gib 0 1e-9 ; ic=0.5 +* Ghost node... Test for my PSS! +*Rb bad 0 1k + +.control +tran 10e-9 20e-6 uic +rusage time +plot gib xlimit 0 5u +meas tran ptdiff TRIG v(gib) val=0 RISE=25 TARG v(gib) val=0 RISE=50 +let freq = 25.0/ptdiff +echo frequency is $&freq +reset +pss 0.5e6 100e-6 1 50 10 50 5e-3 uic +rusage time +plot gib +setplot pss1 +plot gib +.endc + +.end + diff --git a/src/include/ngspice/iferrmsg.h b/src/include/ngspice/iferrmsg.h index 1d5a53adb..5ee6c12ed 100644 --- a/src/include/ngspice/iferrmsg.h +++ b/src/include/ngspice/iferrmsg.h @@ -36,6 +36,7 @@ Author: 1986 Thomas L. Quarles #define E_BAD_DOMAIN 15 /* output interface begin/end domain calls mismatched */ #define E_EXISTS_BAD 16 /* error - attempt to create duplicate */ /* instance or model. Bail out. */ +#define E_ERR_PSS 17 /* error - during PSS. Bail out. */ #define E_PRIVATE 100 /* messages above this number are private to */ /* the simulator and MUST be accompanied by */ diff --git a/src/spicelib/analysis/dcpss.c b/src/spicelib/analysis/dcpss.c index d02b33712..4a60f9d14 100644 --- a/src/spicelib/analysis/dcpss.c +++ b/src/spicelib/analysis/dcpss.c @@ -50,6 +50,7 @@ do { \ #define HISTORY 1024 #define GF_LAST 313 +//#define PSSDEBUG static int DFT(long int, int, double *, double *, double *, double, double *, double *, double *, double *, double *); @@ -132,7 +133,7 @@ DCpss(CKTcircuit *ckt, msize = SMPmatSize (ckt->CKTmatrix) ; RHS_copy_se = TMALLOC (double, msize) ; /* Set the current RHS reference for next Shooting Evaluation */ - RHS_copy_der = TMALLOC (double, msize) ; /* Used to compute current Derivative */ + RHS_copy_der = TMALLOC (double, msize) ; /* Used to compute current derivative */ RHS_derivative = TMALLOC (double, msize) ; pred = TMALLOC (double, msize) ; RHS_max = TMALLOC (double, msize) ; @@ -264,7 +265,7 @@ DCpss(CKTcircuit *ckt, (ckt->CKTmode & MODEUIC) | MODETRANOP | MODEINITFLOAT, ckt->CKTdcMaxIter); -#ifdef STEPDEBUG +#if defined(STEPDEBUG) || defined(PSSDEBUG) if(converged != 0) { fprintf(stdout,"\nTransient solution failed -\n"); CKTncDump(ckt); @@ -425,7 +426,7 @@ DCpss(CKTcircuit *ckt, if ((AlmostEqualUlps (ckt->CKTtime, nextstep, 10)) || (ckt->CKTtime > time_temp + 1 / ckt->CKTguessedFreq)) { -#ifdef STEPDEBUG +#ifdef PSSDEBUG fprintf (stderr, "IN_PSS: time point accepted in evolution for FFT calculations.\n") ; fprintf (stderr, "Circuit time %1.15g, final time %1.15g, point index %d and total requested points %ld\n", ckt->CKTtime, nextstep, pss_points_cycle, ckt->CKTpsspoints) ; @@ -446,14 +447,14 @@ DCpss(CKTcircuit *ckt, /* Set the next BreakPoint for PSS */ CKTsetBreak (ckt, time_temp + (1 / ckt->CKTguessedFreq) * ((double)pss_points_cycle / (double)ckt->CKTpsspoints)) ; -#ifdef STEPDEBUG +#ifdef PSSDEBUG fprintf (stderr, "Next breakpoint set in: %1.15g\n", time_temp + 1 / ckt->CKTguessedFreq * ((double)pss_points_cycle / (double)ckt->CKTpsspoints)) ; #endif } else { /* Algo can enter here but should do nothing */ -#ifdef STEPDEBUG +#ifdef PSSDEBUG fprintf (stderr, "IN_PSS: time point accepted in evolution but dropped for FFT calculations\n") ; #endif @@ -538,7 +539,7 @@ DCpss(CKTcircuit *ckt, /* Save the RHS_copy_der as the NEW CKTrhsOld */ RHS_copy_der [i] = ckt->CKTrhsOld [i + 1] ; -#ifdef STEPDEBUG +#ifdef PSSDEBUG fprintf (stderr, "Pred is so high or so low! Diff is: %g\n", err_conv [i]) ; #endif @@ -638,7 +639,7 @@ DCpss(CKTcircuit *ckt, /* pred is treated as FREQUENCY to avoid numerical overflow when derivative is close to ZERO */ pred [i] = RHS_derivative [i] / err_conv [i] ; -#ifdef STEPDEBUG +#ifdef PSSDEBUG fprintf (stderr, "Pred is so high or so low! Diff is: %g\n", err_conv [i]) ; #endif @@ -652,7 +653,7 @@ DCpss(CKTcircuit *ckt, predsum += pred [i] ; -#ifdef STEPDEBUG +#ifdef PSSDEBUG fprintf (stderr, "Predsum in time before to be divided by dynamic_test has value %g\n", 1 / predsum) ; fprintf (stderr, "Current Diff: %g, Derivative: %g, Frequency Projection: %g\n", err_conv [i], RHS_derivative [i], pred [i]) ; #endif @@ -717,7 +718,7 @@ DCpss(CKTcircuit *ckt, if (dynamic_test == 0) { /* Test for dynamic existence */ - fprintf (stderr, "No detectable dynamic on voltages nodes or currents branches. PSS analysis aborted\n") ; + fprintf (stderr, "Error: No detectable dynamic on voltages nodes or currents branches.\n PSS analysis aborted\n") ; /* Terminates plot in Time Domain and frees the allocated memory */ SPfrontEnd->OUTendPlot (job->PSSplot_td) ; @@ -728,7 +729,7 @@ DCpss(CKTcircuit *ckt, FREE (err_conv) ; FREE (psstimes) ; FREE (pssvalues) ; - return (E_PANIC) ; /* to be corrected with definition of new error macro in iferrmsg.h */ + return (E_ERR_PSS) ; /* error macro in iferrmsg.h */ } else if ((time_err_min_0 - time_temp) < 0) { @@ -766,7 +767,7 @@ DCpss(CKTcircuit *ckt, /* Enters here if guessed frequency is higher than the 'real' value */ ckt->CKTguessedFreq = 1 / (1 / ckt->CKTguessedFreq + fabs (predsum)) ; -#ifdef STEPDEBUG +#ifdef PSSDEBUG fprintf (stderr, "Frequency DOWN: est per %g, err min %g, err min 1 %g, err max %g, err %g\n", time_err_min_0 - time_temp, err_min_0, err_min_1, err_max, err) ; #endif @@ -775,7 +776,7 @@ DCpss(CKTcircuit *ckt, /* Enters here if guessed frequency is lower than the 'real' value */ ckt->CKTguessedFreq = 1 / (time_err_min_0 - time_temp) ; -#ifdef STEPDEBUG +#ifdef PSSDEBUG fprintf (stderr, "Frequency UP: est per %g, err min %g, err min 1 %g, err max %g, err %g\n", time_err_min_0 - time_temp, err_min_0, err_min_1, err_max, err) ; #endif @@ -809,7 +810,7 @@ DCpss(CKTcircuit *ckt, for (i = 1 ; i <= msize ; i++) RHS_copy_se [i - 1] = ckt->CKTrhsOld [i] ; -#ifdef STEPDEBUG +#ifdef PSSDEBUG fprintf (stderr, "RHS on new shooting cycle: ") ; for (i = 0 ; i < msize ; i++) fprintf (stderr, "%-15g ", RHS_copy_se [i]) ; @@ -833,7 +834,7 @@ DCpss(CKTcircuit *ckt, pss_state = PSS ; -#ifdef STEPDEBUG +#ifdef PSSDEBUG fprintf (stderr, "\nFrequency estimation (FE) and RHS period residual (PR) evolution\n") ; #endif @@ -882,7 +883,7 @@ DCpss(CKTcircuit *ckt, else fprintf (stderr, "\nConvergence not reached. However the most near convergence iteration has predicted (iteration %d) a fundamental frequency of %15.10g Hz\n", k, ckt->CKTguessedFreq) ; -#ifdef STEPDEBUG +#ifdef PSSDEBUG fprintf (stderr, "time_temp %g\n", time_temp) ; fprintf (stderr, "IN_PSS: FIRST time point accepted in evolution for FFT calculations\n") ; fprintf (stderr, "Circuit time %1.15g, final time %1.15g, point index %d and total requested points %ld\n", @@ -907,7 +908,7 @@ DCpss(CKTcircuit *ckt, { /* The algorithm enters here when in_pss is set */ -#ifdef STEPDEBUG +#ifdef PSSDEBUG fprintf (stderr, "ttemp %1.15g, final_time %1.15g, current_time %1.15g\n", time_temp, time_temp + 1 / ckt->CKTguessedFreq, ckt->CKTtime) ; #endif @@ -1133,20 +1134,17 @@ resume: /* gtri - begin - wbk - Modify Breakpoint stuff */ /* Throw out any permanent breakpoint times <= current time */ - for (;;) { + while ((ckt->CKTbreaks[0] <= ckt->CKTtime + ckt->CKTminBreak || + AlmostEqualUlps(ckt->CKTbreaks[0], ckt->CKTtime, 100)) && + ckt->CKTbreaks[0] < ckt->CKTfinalTime) { #ifdef STEPDEBUG - fprintf (stderr, " brk_pt: %g ckt_time: %g ckt_min_break: %g\n", ckt->CKTbreaks [0], ckt->CKTtime, ckt->CKTminBreak) ; + printf("throwing out permanent breakpoint times <= current time " + "(brk pt: %g)\n", + ckt->CKTbreaks[0]); + printf(" ckt_time: %g ckt_min_break: %g\n", + ckt->CKTtime, ckt->CKTminBreak); #endif - if(AlmostEqualUlps(ckt->CKTbreaks[0], ckt->CKTtime, 100) || - ckt->CKTbreaks[0] <= ckt->CKTtime + ckt->CKTminBreak) { -#ifdef STEPDEBUG - fprintf (stderr, "throwing out permanent breakpoint times <= current time (brk pt: %g)\n", ckt->CKTbreaks [0]) ; - fprintf (stderr, "ckt_time: %g ckt_min_break: %g\n", ckt->CKTtime, ckt->CKTminBreak) ; -#endif - CKTclrBreak(ckt); - } else { - break; - } + CKTclrBreak(ckt); } /* Force the breakpoint if appropriate */ if(ckt->CKTtime + ckt->CKTdelta > ckt->CKTbreaks[0]) { @@ -1286,7 +1284,7 @@ resume: return(converged); } -#ifdef STEPDEBUG +#ifdef PSSDEBUG if (pss_state == PSS) fprintf (stderr, "pss_state: %d, converged: %d\n", pss_state, converged) ; #endif diff --git a/src/spicelib/parser/ptfuncs.c b/src/spicelib/parser/ptfuncs.c index 92793f285..863a7921b 100644 --- a/src/spicelib/parser/ptfuncs.c +++ b/src/spicelib/parser/ptfuncs.c @@ -69,24 +69,21 @@ double PTpower(double arg1, double arg2) { double res; - if (newcompat.lt) { - if (arg1 == 0) + + if (arg1 == 0) + res = 0; + else if(arg1 > 0) + res = pow(arg1, arg2); + else { + /* If arg2 is quasi an integer, round it to have pow not fail + when arg1 is negative. Takes into account the double + representation which sometimes differs in the last digit(s). */ + if (AlmostEqualUlps(nearbyint(arg2), arg2, 10)) + res = pow(arg1, round(arg2)); + else + /* As per LTSPICE specification for ** */ res = 0; - else if(arg1 > 0) - res = pow(arg1, arg2); - else { - /* If arg2 is quasi an integer, round it to have pow not fail - when arg1 is negative. Takes into account the double - representation which sometimes differs in the last digit(s). */ - if (AlmostEqualUlps(nearbyint(arg2), arg2, 10)) - res = pow(arg1, round(arg2)); - else - /* As per LTSPICE specification for ** */ - res = 0; - } } - else - res = pow(fabs(arg1), arg2); return res; } @@ -106,7 +103,7 @@ PTpowerH(double arg1, double arg2) res = pow(arg1, arg2); } } - else if (newcompat.lt) { + else { if (arg1 >= 0) res = pow(arg1, arg2); else { @@ -120,8 +117,6 @@ PTpowerH(double arg1, double arg2) res = 0; } } - else - res = pow(fabs(arg1), arg2); return res; } diff --git a/src/spicelib/parser/sperror.c b/src/spicelib/parser/sperror.c index d669260d6..c5a7941d3 100644 --- a/src/spicelib/parser/sperror.c +++ b/src/spicelib/parser/sperror.c @@ -107,6 +107,9 @@ const char *SPerror(int type) case E_NOF2SRC: msg = "no F2 source for IM disto analysis"; break; + case E_ERR_PSS: + msg = "pss failed"; + break; case OK: return (NULL); default: