From ae8657f6316f13b534e374192da45e3d0e47e34c Mon Sep 17 00:00:00 2001 From: rlar Date: Wed, 28 Mar 2018 17:12:07 +0200 Subject: [PATCH] testcases --- test-csw-dc.cir | 53 ++++++++++++++++++++++++++++++++++++++++++ test-csw-tran.cir | 59 +++++++++++++++++++++++++++++++++++++++++++++++ test-sw-dc.cir | 52 +++++++++++++++++++++++++++++++++++++++++ test-sw-tran.cir | 57 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 221 insertions(+) create mode 100644 test-csw-dc.cir create mode 100644 test-csw-tran.cir create mode 100644 test-sw-dc.cir create mode 100644 test-sw-tran.cir diff --git a/test-csw-dc.cir b/test-csw-dc.cir new file mode 100644 index 000000000..1f94d2f31 --- /dev/null +++ b/test-csw-dc.cir @@ -0,0 +1,53 @@ +* test hysteresis in a dc sweep + +* test both implementations +* the regular one, and the Jon Engelbert variant +* (which is selected by a negative VH parameter) + +v1 11 0 dc=0 +b1 1 0 i= 0.5 + 0.2*cos(v(11)) +vm1 0 1 dc=0 + +I2 2 0 -1mA +W2 2 0 vm1 SWITCH1A + +I3 3 0 -1mA +W3 3 0 vm1 SWITCH1B + +.MODEL SWITCH1A CSW IT=0.5 IH=0.1 RON=100 ROFF=1400 +.MODEL SWITCH1B CSW IT=0.5 IH=-0.1 RON=100 ROFF=1400 + +.control + +dc v1 -7 7 0.01 + +showmod all + +let v_thp = 0.5 + 0.1 +let v_thm = 0.5 - 0.1 + +let len = length("v-sweep") +let gold = vector(len) + +let kk = 0 +repeat $&len + let delta = kk ? (i(vm1)[kk] - i(vm1)[kk-1]) : 0 + let sw = (delta ge 0) ? (i(vm1)[kk] ge v_thp) : (i(vm1)[kk] ge v_thm) + let gold[kk] = sw ? 0.1 : 1.4 + let kk = kk + 1 +end + +let abs_err1 = vecmax(abs(v(2) - gold)) +let abs_err2 = vecmax(abs(v(3) - gold)) +echo "INFO: $&abs_err1 $&abs_err2" +if (abs_err1 ge 1e-12) or (abs_err2 ge 1e-12) + echo "ERROR: mismatch" +end + +plot v(2) v(3) gold +plot v(2)+0.005*v(11) vs i(vm1)+0.002*v(11) +plot v(3)+0.005*v(11) vs i(vm1)+0.002*v(11) + +.endc + +.end diff --git a/test-csw-tran.cir b/test-csw-tran.cir new file mode 100644 index 000000000..4c7687356 --- /dev/null +++ b/test-csw-tran.cir @@ -0,0 +1,59 @@ +* test hysteresis in a tran + +* test both implementations +* the regular one, and the Jon Engelbert variant +* (which is selected by a negative VH parameter) +* rising and falling +* check for plenty of timesteps around the ideal switch point +* swtrunc is expected to chime in and force the tran engine to +* shrink the the timesteps down to very small values +* then switch +* and then the tran engine will raise the timesteps back to their usual value + +i11 11 0 pwl(0s 0 1s 0 2s 1) +vm11 0 11 dc=0 +i12 12 0 pwl(0s 1 1s 1 2s 0) +vm12 0 12 dc=0 + +I2 2 0 -1mA +W2 2 0 vm11 SWITCH2 + +I3 3 0 -1mA +W3 3 0 vm11 SWITCH3 + +I4 4 0 -1mA +W4 4 0 vm12 SWITCH4 + +I5 5 0 -1mA +W5 5 0 vm12 SWITCH5 + +.MODEL SWITCH2 CSW IT=0.25 IH=0.1 RON=100 ROFF=1400 +.MODEL SWITCH3 CSW IT=0.35 IH=-0.1 RON=100 ROFF=1400 +.MODEL SWITCH4 CSW IT=0.45 IH=0.1 RON=100 ROFF=1400 +.MODEL SWITCH5 CSW IT=0.55 IH=-0.1 RON=100 ROFF=1400 + +.control + +tran 10ms 4s + +let t_gold2 = 1.35s +let t_gold3 = 1.45s +let t_gold4 = 1.55s +let t_gold5 = 1.65s + +* how much timesteps are there around the switching point +let n_steps2 = length(time) * mean(abs(time - t_gold2) le 1e-9) +let n_steps3 = length(time) * mean(abs(time - t_gold3) le 1e-9) +let n_steps4 = length(time) * mean(abs(time - t_gold4) le 1e-9) +let n_steps5 = length(time) * mean(abs(time - t_gold5) le 1e-9) + +echo "INFO: $&n_steps2 $&n_steps3 $&n_steps4 $&n_steps5" +if (n_steps2 lt 20) or (n_steps3 lt 20) or (n_steps4 lt 20) or (n_steps5 lt 20) + echo "ERROR: truncation failed" +end + +plot v(2) v(3) v(4) v(5) i(vm11) i(vm12) + +.endc + +.end diff --git a/test-sw-dc.cir b/test-sw-dc.cir new file mode 100644 index 000000000..fd4aad47e --- /dev/null +++ b/test-sw-dc.cir @@ -0,0 +1,52 @@ +* test hysteresis in a dc sweep + +* test both implementations +* the regular one, and the Jon Engelbert variant +* (which is selected by a negative VH parameter) + +v1 11 0 dc=0 +b1 1 0 v= 0.5 + 0.2*cos(v(11)) + +I2 2 0 -1mA +SW2 2 0 1 0 SWITCH1A + +I3 3 0 -1mA +SW3 3 0 1 0 SWITCH1B + +.MODEL SWITCH1A SW VT=0.5 VH=0.1 RON=100 ROFF=1400 +.MODEL SWITCH1B SW VT=0.5 VH=-0.1 RON=100 ROFF=1400 + +.control + +dc v1 -7 7 0.01 + +showmod all + +let v_thp = 0.5 + 0.1 +let v_thm = 0.5 - 0.1 + +let len = length("v-sweep") +let gold = vector(len) + +let kk = 0 +repeat $&len + let delta = kk ? (v(1)[kk] - v(1)[kk-1]) : 0 + let sw = (delta ge 0) ? (v(1)[kk] ge v_thp) : (v(1)[kk] ge v_thm) + let gold[kk] = sw ? 0.1 : 1.4 + let kk = kk + 1 +end + +let abs_err1 = vecmax(abs(v(2) - gold)) +let abs_err2 = vecmax(abs(v(3) - gold)) +echo "INFO: $&abs_err1 $&abs_err2" +if (abs_err1 ge 1e-12) or (abs_err2 ge 1e-12) + echo "ERROR: mismatch" +end + +plot v(2) v(3) gold +plot v(2)+0.005*v(11) vs v(1)+0.002*v(11) +plot v(3)+0.005*v(11) vs v(1)+0.002*v(11) + +.endc + +.end diff --git a/test-sw-tran.cir b/test-sw-tran.cir new file mode 100644 index 000000000..b6fc33149 --- /dev/null +++ b/test-sw-tran.cir @@ -0,0 +1,57 @@ +* test hysteresis in a tran + +* test both implementations +* the regular one, and the Jon Engelbert variant +* (which is selected by a negative VH parameter) +* rising and falling +* check for plenty of timesteps around the ideal switch point +* swtrunc is expected to chime in and force the tran engine to +* shrink the the timesteps down to very small values +* then switch +* and then the tran engine will raise the timesteps back to their usual value + +v11 11 0 pwl(0s 0 1s 0 2s 1) +v12 12 0 pwl(0s 1 1s 1 2s 0) + +I2 2 0 -1mA +SW2 2 0 11 0 SWITCH2 + +I3 3 0 -1mA +SW3 3 0 11 0 SWITCH3 + +I4 4 0 -1mA +SW4 4 0 12 0 SWITCH4 + +I5 5 0 -1mA +SW5 5 0 12 0 SWITCH5 + +.MODEL SWITCH2 SW VT=0.25 VH=0.1 RON=100 ROFF=1400 +.MODEL SWITCH3 SW VT=0.35 VH=-0.1 RON=100 ROFF=1400 +.MODEL SWITCH4 SW VT=0.45 VH=0.1 RON=100 ROFF=1400 +.MODEL SWITCH5 SW VT=0.55 VH=-0.1 RON=100 ROFF=1400 + +.control + +tran 10ms 4s + +let t_gold2 = 1.35s +let t_gold3 = 1.45s +let t_gold4 = 1.55s +let t_gold5 = 1.65s + +* how much timesteps are there around the switching point +let n_steps2 = length(time) * mean(abs(time - t_gold2) le 1e-9) +let n_steps3 = length(time) * mean(abs(time - t_gold3) le 1e-9) +let n_steps4 = length(time) * mean(abs(time - t_gold4) le 1e-9) +let n_steps5 = length(time) * mean(abs(time - t_gold5) le 1e-9) + +echo "INFO: $&n_steps2 $&n_steps3 $&n_steps4 $&n_steps5" +if (n_steps2 lt 20) or (n_steps3 lt 20) or (n_steps4 lt 20) or (n_steps5 lt 20) + echo "ERROR: truncation failed" +end + +plot v(2) v(3) v(4) v(5) v(11) v(12) + +.endc + +.end