diff --git a/ChangeLog b/ChangeLog index 5e79f71da..76ad48826 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2009-12-21 Holger Vogt - * com_measure2.com, measure.c: add vector to the meas command + * com_measure2.com, measure.c: add vectors to the meas command. + inpcom.c: no parsing of ternary function in .control section (not + yet defined anyway). + /examples/measure /examples/control_structs: new or updated example + files. 2009-12-20 Holger Vogt * fixing the time 0 value of sine in isrc, vsrc diff --git a/examples/control_structs/foreach_bjt_ft.sp b/examples/control_structs/foreach_bjt_ft.sp new file mode 100644 index 000000000..ef5e9d472 --- /dev/null +++ b/examples/control_structs/foreach_bjt_ft.sp @@ -0,0 +1,51 @@ +BJT ft Test + +vce 1 0 dc 3.0 +vgain 1 c dc 0.0 +f 0 2 vgain -1000 +l 2 b 1g +c 2 0 1g +ib 0 b dc 0.0 ac 1.0 +ic 0 c 0.01 +q1 c b 0 bfs17 + +.control +foreach myic 0.5e-3 1e-3 5e-3 10e-3 50e-3 100e-3 + alter ic = $myic + ac dec 10 10k 5g +end +*foreach mytf 50p 100p 150p 200p 250p 300p +* altermod q.x1.q1 tf = $mytf +* ac dec 10 10k 5g +*end +plot abs(ac1.vgain#branch) abs(ac2.vgain#branch) abs(ac3.vgain#branch) abs(ac4.vgain#branch) abs(ac5.vgain#branch) abs(ac6.vgain#branch) ylimit 0.1 100 loglog +.endc + +***************************************************************** +* SPICE2G6 MODEL OF THE NPN BIPOLAR TRANSISTOR BFS17 (SOT-23) * +* REV: 98.1 DANALYSE GMBH BERLIN (27.07.1998) * +***************************************************************** +.SUBCKT BFS17C 1 2 3 +Q1 6 5 7 BFS17 1.000 +LC 1 6 0.350N +L1 2 4 0.400N +LB 4 5 0.500N +L2 3 8 0.400N +LE 8 7 0.600N +CGBC 4 6 70.00F +CGBE 4 8 0.150P +CGCE 6 8 15.00F +.ENDS +.MODEL BFS17 NPN (level=1 IS=0.480F NF=1.008 BF=99.655 VAF=90.000 IKF=0.190 ++ ISE=7.490F NE=1.762 NR=1.010 BR=38.400 VAR=7.000 IKR=93.200M ++ ISC=0.200F NC=1.042 ++ RB=1.500 IRB=0.100M RBM=1.200 ++ RE=0.500 RC=2.680 ++ CJE=1.325P VJE=0.700 MJE=0.220 FC=0.890 ++ CJC=1.050P VJC=0.610 MJC=0.240 XCJC=0.400 ++ TF=56.940P TR=1.000N PTF=21.000 ++ XTF=68.398 VTF=0.600 ITF=0.700 ++ XTB=1.600 EG=1.110 XTI=3.000 ++ KF=1.000F AF=1.000) + +.end diff --git a/examples/control_structs/repeat3.sp b/examples/control_structs/repeat3.sp new file mode 100644 index 000000000..74665a1a1 --- /dev/null +++ b/examples/control_structs/repeat3.sp @@ -0,0 +1,16 @@ +*test sequence for repeat +.control + let loop = 0 + while loop < 4 + let index = 0 + repeat + let index = index + 1 + if index > 4 + break + end + end + echo + echo index "$&index" loop "$&loop" + let loop = loop + 1 + end +.endc \ No newline at end of file diff --git a/examples/measure/inv-meas-tran-control.sp b/examples/measure/inv-meas-tran-control.sp new file mode 100644 index 000000000..48f7d09ad --- /dev/null +++ b/examples/measure/inv-meas-tran-control.sp @@ -0,0 +1,113 @@ +Inverter example circuit +* This netlist demonstrates the following: +* global nodes (vdd, gnd) +* autostop (.tran defines simulation end as 4ns but simulation stops at +* 142.5ps when .measure statements are evaluated) +* scale (all device units are in microns) +* model binning (look in device.values file for which bin chosen) +* +* m.x1.mn: +* model = nch.2 +* +* m.x1.mp: +* model = pch.2 +* +* parameters +* parameterized subckt +* vsrc with repeat +* .measure statements for delay and an example ternary operator +* device listing and parameter listing +* You can run the example circuit with this command: +* +* ngspice inverter3.sp + + +* global nodes +.global vdd gnd + +* autostop -- stop simulation early if .measure statements done +* scale -- define scale factor for mosfet device parameters (l,w,area,perimeter) +*.option autostop +.option scale = 1e-6 + +* model binning +.model nch.1 nmos ( version=4.4 level=54 lmin=0.1u lmax=20u wmin=0.1u wmax=10u ) +.model nch.2 nmos ( version=4.4 level=54 lmin=0.1u lmax=20u wmin=10u wmax=100u ) +.model pch.1 pmos ( version=4.4 level=54 lmin=0.1u lmax=20u wmin=0.1u wmax=10u ) +.model pch.2 pmos ( version=4.4 level=54 lmin=0.1u lmax=20u wmin=10u wmax=100u ) + +* parameters +.param vp = 1.0v +.param lmin = 0.10 +.param wmin = 0.12 +.param plmin = 'lmin' +.param nlmin = 'lmin' +.param wpmin = 'wmin' +.param wnmin = 'wmin' +.param drise = 400ps +.param dfall = 100ps +.param trise = 100ps +.param tfall = 100ps +.param period = 1ns +.param skew_meas = 'vp/2' + +* parameterized subckt +.subckt inv in out pw='wpmin' pl='plmin' nw='wnmin' nl='nlmin' +mp out in vdd vdd pch w='pw' l='pl' +mn out in gnd gnd nch w='nw' l='nl' +.ends + +v0 vdd gnd 'vp' + +* vsrc with repeat +v1 in gnd pwl ++ 0ns 'vp' ++ 'dfall-0.8*tfall' 'vp' ++ 'dfall-0.4*tfall' '0.9*vp' ++ 'dfall+0.4*tfall' '0.1*vp' ++ 'dfall+0.8*tfall' 0v ++ 'drise-0.8*trise' 0v ++ 'drise-0.4*trise' '0.1*vp' ++ 'drise+0.4*trise' '0.9*vp' ++ 'drise+0.8*trise' 'vp' ++ 'period+dfall-0.8*tfall' 'vp' ++ r='dfall-0.8*tfall' + +x1 in out inv pw=60 nw=20 +c1 out gnd 220fF + +.control +tran 1ps 4ns +meas tran inv_delay trig v(in) val=0.5 fall=1 targ v(out) val=0.5 rise=1 +meas tran inv_delay2 trig v(in) val=0.5 td=1n fall=1 targ v(out) val=0.5 rise=1 +meas tran test_data1 trig AT = 1n targ v(out) val=0.5 rise=3 +meas tran out_slew trig v(out) val=0.2 rise=2 targ v(out) val=0.8 rise=2 + +*.meas tran delay_chk param='(inv_delay < 100ps) ? 1 : 0' +if ( inv_delay < 100ps ) + let delay_chk = 1 +else + let delay_chk = 0 +end +echo delay_chk = "$&delay_chk" + +meas tran skew when v(out)=0.6 +let skew_meas = 0.5 +meas tran skew2 when v(out)=skew_meas +meas tran skew3 when v(out)=skew_meas fall=2 +meas tran skew4 when v(out)=skew_meas fall=LAST +meas tran skew5 FIND v(out) AT=2n +let dfall = 100p +let period = 1n +let delta = dfall+period +meas tran v0_min min i(v0) from=dfall to=delta +meas tran i_v0_min min_at i(v0) from=dfall to=delta +meas tran v0_avg avg i(v0) from = dfall to = delta +meas tran v0_integ integ i(v0) from=dfall to=delta +meas tran v0_rms rms i(v0) from=dfall to=delta +rusage all +plot v(in) v(out) +.endc + +.end + diff --git a/examples/measure/mos-meas-dc-control.sp b/examples/measure/mos-meas-dc-control.sp new file mode 100644 index 000000000..82301b5f6 --- /dev/null +++ b/examples/measure/mos-meas-dc-control.sp @@ -0,0 +1,32 @@ +***** Single NMOS Transistor .measure (Id-Vd) *** +m1 d g s b nch L=0.6u W=10.0u + +vgs g 0 3.5 +vds d 0 3.5 +vs s 0 dc 0 +vb b 0 dc 0 + +* model binning +.model nch.1 nmos ( version=4.4 level=54 lmin=0.1u lmax=20u wmin=0.1u wmax=10u ) +.model nch.2 nmos ( version=4.4 level=54 lmin=0.1u lmax=20u wmin=10u wmax=100u ) +.model pch.1 pmos ( version=4.4 level=54 lmin=0.1u lmax=20u wmin=0.1u wmax=10u ) +.model pch.2 pmos ( version=4.4 level=54 lmin=0.1u lmax=20u wmin=10u wmax=100u ) + +.control +dc vds 0 3.5 0.05 vgs 0.5 3.5 0.5 +meas dc is_at FIND i(vs) AT=1 +meas dc is_max max i(vs) from=0 to=3.5 +meas dc vds_at2 when i(vs)=10m +meas dc vd_diff1 trig i(vs) val=0.005 rise=1 targ i(vs) val=0.01 rise=1 +meas dc vd_diff2 trig i(vs) val=0.005 rise=1 targ i(vs) val=0.01 rise=2 +*rusage all +plot i(vs) +.endc + + +.end + + + + + diff --git a/examples/measure/mos-meas-dc.sp b/examples/measure/mos-meas-dc.sp index b2868aadf..eb3892db0 100644 --- a/examples/measure/mos-meas-dc.sp +++ b/examples/measure/mos-meas-dc.sp @@ -18,21 +18,10 @@ vb b 0 dc 0 .meas dc is_at FIND i(vs) AT=1 .meas dc is_max max i(vs) from=0 to=3.5 -.meas dc vds_at when i(vs)=0.01 -* the following fails (probably does not recognize m or u): -.meas dc vds_at2 when i(vs)=10000u +.meas dc vds_at2 when i(vs)=10m .meas dc vd_diff1 trig i(vs) val=0.005 rise=1 targ i(vs) val=0.01 rise=1 .meas dc vd_diff2 trig i(vs) val=0.005 rise=1 targ i(vs) val=0.01 rise=2 - -*.meas ac fixed_diff trig AT = 10k targ v(out) val=0.1 rise=1 -*.meas ac vout_avg avg v(out) from=10k to=1MEG -*.meas ac vout_integ integ v(out) from=20k to=500k -*.meas ac freq_at2 when v(out)=0.1 fall=LAST -*.meas ac bw_chk param='(vout_diff < 100k) ? 1 : 0' -*.meas ac bw_chk2 param='(vout_diff > 500k) ? 1 : 0' -*.meas ac vout_rms rms v(out) from=10 to=1G - .control run *rusage all diff --git a/examples/measure/rc-meas-ac-control.sp b/examples/measure/rc-meas-ac-control.sp new file mode 100644 index 000000000..9b57929d5 --- /dev/null +++ b/examples/measure/rc-meas-ac-control.sp @@ -0,0 +1,64 @@ +RC band pass example circuit +* This netlist demonstrates the following: +* global nodes (vdd, gnd) + +* .measure statements for delay and an example ternary operator + +* You can run the example circuit with this command: +* +* ngspice rc-meas-ac.sp + + +* global nodes +.global vdd gnd + +* autostop -- stop simulation early if .measure statements done +*.option autostop + +vin in gnd dc 0 ac 1 + +R1 in mid1 1k +c1 mid1 gnd 1n +C2 mid1 out 500p +R2 out gnd 1k + + +.control +ac DEC 10 1k 10MEG +meas ac vout_at FIND v(out) AT=1MEG +meas ac vout_atr FIND vr(out) AT=1MEG +meas ac vout_ati FIND vi(out) AT=1MEG +meas ac vout_atm FIND vm(out) AT=1MEG +meas ac vout_atp FIND vp(out) AT=1MEG +meas ac vout_atd FIND vdb(out) AT=1MEG +meas ac vout_max max v(out) from=1k to=10MEG +meas ac freq_at when v(out)=0.1 +meas ac vout_diff trig v(out) val=0.1 rise=1 targ v(out) val=0.1 fall=1 +meas ac fixed_diff trig AT = 10k targ v(out) val=0.1 rise=1 +meas ac vout_avg avg v(out) from=10k to=1MEG +meas ac vout_integ integ v(out) from=20k to=500k +meas ac freq_at2 when v(out)=0.1 fall=LAST +*meas ac bw_chk param='(vout_diff < 100k) ? 1 : 0' +if (vout_diff < 100k) + let bw_chk = 1 +else + let bw_chk = 0 +end +echo bw_chk = "$&bw_chk" +*meas ac bw_chk2 param='(vout_diff > 500k) ? 1 : 0' +if (vout_diff > 500k) + let bw_chk2 = 1 +else + let bw_chk2 = 0 +end +echo bw_chk2 = "$&bw_chk2" +meas ac vout_rms rms v(out) from=10 to=1G +*rusage all +plot v(out) +plot ph(v(out)) +plot mag(v(out)) +plot db(v(out)) +.endc + +.end + diff --git a/src/frontend/com_measure2.c b/src/frontend/com_measure2.c index 09f63569f..19d79a301 100644 --- a/src/frontend/com_measure2.c +++ b/src/frontend/com_measure2.c @@ -516,7 +516,10 @@ static void measure_at( svalue = dScale->v_compdata[i].cx_real; } else if (cieq (meas->m_analysis,"sp")) { - value = get_value(meas, d, i); //d->v_compdata[i].cx_real; + if (d->v_compdata) + value = get_value(meas, d, i); //d->v_compdata[i].cx_real; + else + value = d->v_realdata[i]; svalue = dScale->v_realdata[i]; } else { @@ -589,7 +592,10 @@ static void measure_minMaxAvg( svalue = dScale->v_compdata[i].cx_real; } else if (cieq (meas->m_analysis,"sp")) { - value = get_value(meas, d, i); //d->v_compdata[i].cx_real; + if (d->v_compdata) + value = get_value(meas, d, i); //d->v_compdata[i].cx_real; + else + value = d->v_realdata[i]; svalue = dScale->v_realdata[i]; } else { @@ -1072,7 +1078,7 @@ static int measure_parse_when ( wordlist *wl, /* in : word list to parse */ char *errBuf /* in/out: buffer where we write error messages */ ) { - int pCnt; + int pCnt, err = 0; char *p, *pVar1, *pVar2; meas->m_vec = NULL; meas->m_vec2 = NULL; @@ -1109,7 +1115,7 @@ static int measure_parse_when ( correct_vec(meas); } else - meas->m_val = atof(pVar2); + meas->m_val = INPevaluate( &pVar2, &err, 1 ); } else { if (measure_parse_stdParams(meas, wl, NULL, errBuf) == 0) return 0; diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index b717e2b6f..cd48522f6 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -1012,17 +1012,24 @@ inp_fix_ternary_operator_str( char *line ) static void inp_fix_ternary_operator( struct line *start_card ) { - struct line *card; - char *line; + struct line *card; + char *line; + bool found_control = FALSE; - for ( card = start_card; card != NULL; card = card->li_next ) { - line = card->li_line; + for ( card = start_card; card != NULL; card = card->li_next ) { + line = card->li_line; - if ( *line == '*' ) continue; - if ( strstr( line, "?" ) && strstr( line, ":" ) ) { - card->li_line = inp_fix_ternary_operator_str( line ); - } - } + /* exclude replacement of ternary function between .control and .endc */ + if ( ciprefix( ".control", line ) ) found_control = TRUE; + if ( ciprefix( ".endc", line ) ) found_control = FALSE; + if (found_control) continue; + + + if ( *line == '*' ) continue; + if ( strstr( line, "?" ) && strstr( line, ":" ) ) { + card->li_line = inp_fix_ternary_operator_str( line ); + } + } } /*------------------------------------------------------------------------- diff --git a/src/frontend/measure.c b/src/frontend/measure.c index 088bad76b..2de6c10ca 100644 --- a/src/frontend/measure.c +++ b/src/frontend/measure.c @@ -73,7 +73,7 @@ com_meas(wordlist *wl) { d = vec_get(vec_found); if (d) { /* get its value */ - sprintf(newval, "%f\0", d->v_realdata[0]); + sprintf(newval, "%e\0", d->v_realdata[0]); tfree(vec_found); wl_index->wl_word = copy(newval); } @@ -89,7 +89,7 @@ com_meas(wordlist *wl) { d = vec_get(vec_found); if (d) { *equal_ptr = '\0'; - sprintf(newval, "%s=%f\0", token, d->v_realdata[0]); + sprintf(newval, "%s=%e\0", token, d->v_realdata[0]); // memory leak with first part of vec_found ? tfree(token); wl_index->wl_word = copy(newval);