diff --git a/README.SEEgenerator b/README.SEEgenerator new file mode 100644 index 000000000..12c8d3858 --- /dev/null +++ b/README.SEEgenerator @@ -0,0 +1,173 @@ +SEE (single event effects) generator + +The SEE generator generates current pulses, which resemble the +charge generation and flow causes by a penetrating particle. + +How to use it: +Select LET and charge collection depth cdepth, define them as parameters. +Identify all nodes of a circuit netlist which are pn junctions, +and thus are sensitive to pulses. + +Set up the SEEgenerator by adding for example + +* charge collection depth (in µm) +.param d = 1 +* LET (linear energy transfer) in MeV*cm²/mg +.param let = 12 +aseegen1 NULL [%id(xcell.n1 m1) %id(xcell.n2 m2) %id(xcell.n1 m1) %id(xcell.n2 m2)] seemod1 +.model seemod1 seegen (tdelay = 11n tperiod=25n let='let' cdepth='d') + +to the netlist. + +Each sensitive node from the (flattend) netlist may be added to assegen1, together with its +reference node, for example GND for NMOS, nwell potential for PMOS. This procedure is +currently to be done manually, an automated setup is in preparation. + +After a transient simulation, plotting the data output versus a non-radiated device +may reveal the SEE influence. + +Several examples are gieven in ./src/axamples/xspice/see: inverters, SRAM cell, opamp, +also as loop with varying LET to detect the threshold. + +As literature please see for example + Ygor Quadros de Aguiar, Frédéric Wrobel. Jean-Luc Autran, Rubén García Alía + Single-Event Effects, from Space to Accelerator Environments + Springer 2025 + +Detailed description (will be added to the manual): + +NAME_TABLE: + +C_Function_Name: cm_seegen +Spice_Model_Name: seegen +Description: "single event effect generator" + + +PORT_TABLE: + +Port_Name: ctrl out +Description: "control input" "output" +Direction: in out +Default_Type: v i +Allowed_Types: [v,vd,i,id] [i,id] +Vector: no yes +Vector_Bounds: - [1 -] +Null_Allowed: yes no + + +PARAMETER_TABLE: + +Parameter_Name: tfall trise +Description: "pulse fall time" "pulse rise time" +Data_Type: real real +Default_Value: 500e-12 20e-12 +Limits: - - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes + + +PARAMETER_TABLE: + +Parameter_Name: tdelay inull +Description: "pulse delay" "max current" +Data_Type: real real +Default_Value: 0 0 +Limits: - - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes + + +PARAMETER_TABLE: + +Parameter_Name: tperiod ctrlthres +Description: "pulse repetition" "control voltage threshold" +Data_Type: real real +Default_Value: 0 0.5 +Limits: - - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes + + +PARAMETER_TABLE: + +Parameter_Name: let cdepth +Description: "lin energy transfer" "charge collection depth" +Data_Type: real real +Default_Value: 10 1 +Limits: - - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes + + +PARAMETER_TABLE: + +Parameter_Name: angle perlim +Description: "particle angle" "pulse repetition" +Data_Type: real boolean +Default_Value: 0 TRUE +Limits: [0 1.57079] - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes + +STATIC_VAR_TABLE: + +Static_Var_Name: last_t_value +Data_Type: pointer +Vector: no +Description: "next pulse start time" + +STATIC_VAR_TABLE: + +Static_Var_Name: pulse_number +Data_Type: pointer +Vector: no +Description: "number of pulse" + +STATIC_VAR_TABLE: + +Static_Var_Name: last_ctrl +Data_Type: pointer +Vector: no +Description: "last control value" + +Description +This code model generates "double exponentially" formed current pulses according to + +i(t) = inull * (exp(-(t-tdelay)/tfall) - (exp(-(t-tdelay)/trise) for t > tdelay +i(t) = 0 for t < tdelay + +with inull given as parameter input or (if not given), calculated as +inull = 1.035e-14 * let/cos(angle) * cdepth / (tfall - trise) +with data for silicon, cdepth in µm, let in MeV*cm²/mg, angle in radians. + +Minimum is one pulse output (a node pair, or a single node with the other grounded). +Several output node pairs may be defined per code model instance. Parameter tperiod +may then be used to create pulses in sequence. Per default only one sequence is running, +with one pulse for each node. +Parameter perlim, set to FALSE, allows running and repeating the sequence until +the end of the simulation. The first pulse is issued in the first +node pair of the node list in the vector [], the second (after time tperiod has elapsed), +is injected by the second node (pair) of the list and so on. When the sequence is repeated, +again the output starts pulsing at port (node pair) number 1. + +The control input ctrl (voltage or current) may be used +to start or repeat the whole sequence, depending on the circuit status. A rising voltage +at ctrl, when crossing the threshold given by ctrlthres, will initiate the sequence (including +tdelay and tperiod). + +This model will work in transient analysis. + +Example ngspice usage (with control) + +aseegen1 ctrl [%id(n1 m1) %id(n2 m2) %id(n1 m1) %id(n2 m2)] seemod1 +.model seemod1 seegen (tdelay = 8n tperiod=25n) + +Example ngspice usage (without control, ctrl replaced by NULL, parameters as offered by default) + +aseegen2 NULL [%id(n1 m1) %id(n5 n6) %id(n6 n7) %i(isingle) ] seemod2 +.model seemod2 seegen (tdelay = 0 tperiod=0 ctrlthres=0.5 inull=0 tfall=500p trise=20p perlim=FALSE) diff --git a/examples/xspice/see/CMOSOpAmp/CMOS-OP1.cir b/examples/xspice/see/CMOSOpAmp/CMOS-OP1.cir new file mode 100644 index 000000000..2e2b2e480 --- /dev/null +++ b/examples/xspice/see/CMOSOpAmp/CMOS-OP1.cir @@ -0,0 +1,33 @@ +.title KiCad schematic +.include "cmos_sub.mod" +.include "seegen4.mod" +V1 Vcc 0 DC 3.3 +XU1 VGP2 VGP4P8 Vbias VSN4N8 seegen4 +XMN9 Vbias Vbias 0 0 NCH W=5u L=1.4u +V5 in+ 0 DC 1.65 +R1 out in- 100k +R2 in in- 20k +V4 in 0 DC 1.65 SIN( 1.65 100m 1k 0 0 0 ) AC 1 +XMN3 out Vbias 0 0 NCH W=17.4u L=1.4u +C2 out 0 2p +XMP2 out VGP2 Vcc Vcc PCH W=14.5u L=1.4u +C1 VGP2 out 1.2p +XMP4 VGP4P8 VGP4P8 Vcc Vcc PCH W=2.8u L=1.4u +I1 Vcc Vbias 12u +XMN4 VGP4P8 in- VSN4N8 0 NCH W=2.8u L=1.4u +XMN8 VGP2 in+ VSN4N8 0 NCH W=2.8u L=1.4u +XMN2 VSN4N8 Vbias 0 0 NCH W=5u L=1.4u +XMP8 VGP2 VGP4P8 Vcc Vcc PCH W=2.8u L=1.4u + +.control +set xbrushwidth=2 + +tran 20n 2m +plot v(VGP4P8) +plot in out + +ac dec 10 1 1Meg +plot db(out) +.endc + +.end diff --git a/examples/xspice/see/CMOSOpAmp/cmos_sub.mod b/examples/xspice/see/CMOSOpAmp/cmos_sub.mod new file mode 100644 index 000000000..c72096db9 --- /dev/null +++ b/examples/xspice/see/CMOSOpAmp/cmos_sub.mod @@ -0,0 +1,13 @@ +* subcircuit model file + +.include modelcard.nmos +.include modelcard.pmos + +.subckt NCH D G S B W=1 L=1 +MN1 D G S B N1 W={W} L={L} AS={3*L*W} AD={3*L*W} PS={6*L+W} AS={6*L+W} +.ends + + +.subckt PCH D G S B W=1 L=1 +MP1 D G S B P1 W={W} L={L} AS={3*L*W} AD={3*L*W} PS={6*L+W} AS={6*L+W} +.ends diff --git a/examples/xspice/see/CMOSOpAmp/modelcard.nmos b/examples/xspice/see/CMOSOpAmp/modelcard.nmos new file mode 100644 index 000000000..06885ff57 --- /dev/null +++ b/examples/xspice/see/CMOSOpAmp/modelcard.nmos @@ -0,0 +1,46 @@ +*model = bsim3v3 +*Berkeley Spice Compatibility +*http://bsim.berkeley.edu/BSIM4/BSIM3/ftpv330.zip +* Lmin= .35 Lmax= 20 Wmin= .6 Wmax= 20 +.model N1 NMOS ++Level= 8 ++version=3.3.0 ++Tnom=27.0 ++Acnqsmod=1 elm=3 ++Capmod=3 ++Nch= 2.498E+17 Tox=9E-09 Xj=1.00000E-07 ++Lint=9.36e-8 Wint=1.47e-7 ++Lintnoi=1e-9 ++Vth0= .6322 K1= .756 K2= -3.83e-2 K3= -2.612 ++Dvt0= 2.812 Dvt1= 0.462 Dvt2=-9.17e-2 ++Nlx= 3.52291E-08 W0= 1.163e-6 ++K3b= 2.233 ++Vsat= 86301.58 Ua= 6.47e-9 Ub= 4.23e-18 Uc=-4.706281E-11 ++Rdsw= 650 U0= 388.3203 wr=1 ++A0= .3496967 Ags=.1 B0=0.546 B1= 1 ++Dwg = -6.0E-09 Dwb = -3.56E-09 Prwb = -.213 ++Keta=-3.605872E-02 A1= 2.778747E-02 A2= .9 ++Voff=-6.735529E-02 NFactor= 1.139926 Cit= 1.622527E-04 ++Cdsc=-2.147181E-05 ++Cdscb= 0 Dvt0w = 0 Dvt1w = 0 Dvt2w = 0 ++Cdscd = 0 Prwg = 0 ++Eta0= 1.0281729E-02 Etab=-5.042203E-03 ++Dsub= .31871233 ++Pclm= 1.114846 Pdiblc1= 2.45357E-03 Pdiblc2= 6.406289E-03 ++Drout= .31871233 Pscbe1= 5000000 Pscbe2= 5E-09 Pdiblcb = -.234 ++Pvag= 0 delta=0.01 ++ Wl = 0 Ww = -1.420242E-09 Wwl = 0 ++ Wln = 0 Wwn = .2613948 Ll = 1.300902E-10 ++ Lw = 0 Lwl = 0 Lln = .316394 ++ Lwn = 0 ++kt1=-.3 kt2=-.051 ++At= 22400 ++Ute=-1.48 ++Ua1= 3.31E-10 Ub1= 2.61E-19 Uc1= -3.42e-10 ++Kt1l=0 Kt1=-0.1 Prt=764.3 + + + + + + diff --git a/examples/xspice/see/CMOSOpAmp/modelcard.pmos b/examples/xspice/see/CMOSOpAmp/modelcard.pmos new file mode 100644 index 000000000..ab86a38ee --- /dev/null +++ b/examples/xspice/see/CMOSOpAmp/modelcard.pmos @@ -0,0 +1,38 @@ +*model = bsim3v3 +*Berkeley Spice Compatibility +*http://bsim.berkeley.edu/BSIM4/BSIM3/ftpv330.zip +* Lmin= .35 Lmax= 20 Wmin= .6 Wmax= 20 +.model P1 PMOS ++Level= 8 ++version=3.3.0 ++Tnom=27.0 ++Acnqsmod=1 elm=3 ++Nch= 3.533024E+17 Tox=9E-09 Xj=1.00000E-07 ++Lint=6.23e-8 Wint=1.22e-7 ++Lintnoi=1e-9 ++Vth0=-.6732829 K1= .8362093 K2=-8.606622E-02 K3= 1.82 ++Dvt0= 1.903801 Dvt1= .5333922 Dvt2=-.1862677 ++Nlx= 1.28e-8 W0= 2.1e-6 ++K3b= -0.24 Prwg=-0.001 Prwb=-0.323 ++Vsat= 103503.2 Ua= 1.39995E-09 Ub= 1.e-19 Uc=-2.73e-11 ++ Rdsw= 460 U0= 138.7609 ++A0= .4716551 Ags=0.12 ++Keta=-1.871516E-03 A1= .3417965 A2= 0.83 ++Voff=-.074182 NFactor= 1.54389 Cit=-1.015667E-03 ++Cdsc= 8.937517E-04 ++Cdscb= 1.45e-4 Cdscd=1.04e-4 ++ Dvt0w=0.232 Dvt1w=4.5e6 Dvt2w=-0.0023 ++Eta0= 6.024776E-02 Etab=-4.64593E-03 ++Dsub= .23222404 ++Pclm= .989 Pdiblc1= 2.07418E-02 Pdiblc2= 1.33813E-3 ++Drout= .3222404 Pscbe1= 118000 Pscbe2= 1E-09 ++Pvag= 0 ++kt1= -0.25 kt2= -0.032 prt=64.5 ++At= 33000 ++Ute= -1.5 ++Ua1= 4.312e-9 Ub1= 6.65e-19 Uc1= 0 ++Kt1l=0 + + + + diff --git a/examples/xspice/see/CMOSOpAmp/seegen4.mod b/examples/xspice/see/CMOSOpAmp/seegen4.mod new file mode 100644 index 000000000..c29d787fe --- /dev/null +++ b/examples/xspice/see/CMOSOpAmp/seegen4.mod @@ -0,0 +1,10 @@ +* SEE generator model +.subckt seegen4 n1 n2 n3 n4 +.param tochar = 2e-13 +.param tfall = 500p trise=50p +.param Inull = 'tochar/(tfall-trise)' +* Eponential current source without control input +* only NMOS nodes with reference GND (substrate). +aseegen1 NULL [%i(n1) %i(n2) %i(n3) %i(n4)] seemod1 +.model seemod1 seegen (tdelay = 0.62m tperiod=0.1m inull='Inull' perlim=FALSE) +.ends \ No newline at end of file diff --git a/examples/xspice/see/ihp_inverter_set.net b/examples/xspice/see/ihp_inverter_set.net new file mode 100644 index 000000000..c5793da8b --- /dev/null +++ b/examples/xspice/see/ihp_inverter_set.net @@ -0,0 +1,45 @@ +* IHP Open PDK +* simple inverter + +* Path to the PDK +*.include "D:\Spice_general\skywater-pdk\libraries\sky130_fd_pr\latest\models\corners/tt.spice" +.lib "D:\Spice_general\IHP-Open-PDK\ihp-sg13g2\libs.tech\ngspice\models\cornerMOSlv.lib" mos_tt +*.include lib_out1.lib + +.param vdd = 1.2 +.param deltat=11n + +* the voltage sources: +Vdd vd gnd DC 'vdd' +V1 in gnd pulse(0 'vdd' 0p 200p 100p 5n 10n) + +* Eponential current source +Iset out 0 EXP(0 2.5m 'deltat' 10p 'deltat' 500p) +*Cset out 0 10f + +Xnot1 in vdd vss out not1 +Vmeasvss vss 0 0 +Vmeasvdd vd vdd 0 + +.subckt not1 a vdd vss z +xm01 z a vdd vdd sg13_lv_pmos l=0.15u w=0.99u as=0.26235p ad=0.26235p ps=2.51u pd=2.51u +xm02 z a vss vss sg13_lv_nmos l=0.15u w=0.495u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u +c3 a vss 0.384f +c2 z vss 0.576f +.ends + +* simulation command: +.tran 100ps 50ns ; 0 10p + +.options method=gear + +.control +run +rusage +*set nolegend +set xbrushwidth=3 +plot i(Vmeasvss) i(Vmeasvdd) +plot in out +.endc + +.end diff --git a/examples/xspice/see/ihp_simple_sram_seegen.net b/examples/xspice/see/ihp_simple_sram_seegen.net new file mode 100644 index 000000000..26d7e5a33 --- /dev/null +++ b/examples/xspice/see/ihp_simple_sram_seegen.net @@ -0,0 +1,61 @@ +* IHP Open PDK +* simple SRAM cell, exponential current pulses + +* Path to the PDK +*.include "D:\Spice_general\skywater-pdk\libraries\sky130_fd_pr\latest\models\corners/tt.spice" +.lib "D:\Spice_general\IHP-Open-PDK\ihp-sg13g2\libs.tech\ngspice\models\cornerMOSlv.lib" mos_tt +*.include lib_out1.lib + +.param vdd = 1.2 +.param deltat=11n deltat2=27n +.param tochar = 1e-13 +.param talpha = 500p tbeta=10p +.param Inull = 'tochar/(talpha-tbeta)' + +* the voltage sources: +Vdd vd gnd DC 'vdd' +Vwl wl 0 0 PULSE 0 'vdd' 45n 1n 1n 7n 1 +Vbl bl 0 'vdd' +Vbln bln 0 0 + +*V1 in gnd pulse(0 'vdd' 0p 200p 100p 5n 10n) + +* Eponential current source without control input +aseegen1 NULL [%id(n1 m1) %id(n2 m2) %id(n1 m1) %id(n2 m2)] seemod1 +.model seemod1 seegen (tdelay = 11n tperiod=25n inull='Inull') + +Xnot1 n1 vdd vss n2 not1 +Xnot2 n2 vdd vss n1 not1 +xmo02 n2 wl bl vss sg13_lv_nmos l=0.15u w=0.495u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u +xmo01 n1 wl bln vss sg13_lv_nmos l=0.15u w=0.495u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u + +Vmeasvss vss 0 0 +Vmeasvdd vd vdd 0 +Vm1 m1 0 0 +Vm2 m2 0 0 + +.subckt not1 a vdd vss z +xm01 z a vdd vdd sg13_lv_pmos l=0.15u w=0.99u as=0.26235p ad=0.26235p ps=2.51u pd=2.51u +xm02 z a vss vss sg13_lv_nmos l=0.15u w=0.495u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u +c3 a vss 0.384f +c2 z vss 0.576f +.ends + +* starting condition for SRAM cell +.ic v(n2)=0 v(n1)='vdd' + +* simulation command: +.tran 100ps 100ns ; 0 10p + +.options method=gear + +.control +run +rusage +*set nolegend +set xbrushwidth=3 +plot i(Vmeasvss) i(Vmeasvdd) +plot n1 n2+2 wl+4 i(vm1)*10000+6 i(vm2)*10000+8 +.endc + +.end diff --git a/examples/xspice/see/ihp_simple_sram_seegen_ctrl.net b/examples/xspice/see/ihp_simple_sram_seegen_ctrl.net new file mode 100644 index 000000000..ce13a7dca --- /dev/null +++ b/examples/xspice/see/ihp_simple_sram_seegen_ctrl.net @@ -0,0 +1,60 @@ +* Simple SRAM cell in a subcircuit, double exponential current pulses +* control volate +* IHP Open PDK + +* Path to the PDK +.lib "D:\Spice_general\IHP-Open-PDK\ihp-sg13g2\libs.tech\ngspice\models\cornerMOSlv.lib" mos_tt + +.param vdd = 1.2 +.param deltat=11n deltat2=25n +.param tochar = 1e-13 +.param talpha = 500p tbeta=20p +.param Inull = 'tochar/(talpha-tbeta)' + +* the voltage sources: +Vdd vd gnd DC 'vdd' +Vwl wl 0 0 PULSE 0 'vdd' 50n 1n 1n 7n 1 +Vbl bl 0 'vdd' +Vbln bln 0 0 +Vctrl ctrl 0 pulse (0 1 10n 1n 1n 1 1) + +* Exponential current source with control input +aseegen1 ctrl [%id(n1 m1) %id(n2 m2) %id(n1 m1) %id(n2 m2)] seemod1 +.model seemod1 seegen (tdelay = 8n tperiod=25n) + +Xnot1 n1 vdd vss n2 not1 +Xnot2 n2 vdd vss n1 not1 +xmo02 n2 wl bl vss sg13_lv_nmos l=0.15u w=0.495u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u +xmo01 n1 wl bln vss sg13_lv_nmos l=0.15u w=0.495u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u + +Vmeasvss vss 0 0 +Vmeasvdd vd vdd 0 +Vm1 m1 0 0 +Vm2 m2 0 0 + +.subckt not1 a vdd vss z +xm01 z a vdd vdd sg13_lv_pmos l=0.15u w=0.99u as=0.26235p ad=0.26235p ps=2.51u pd=2.51u +xm02 z a vss vss sg13_lv_nmos l=0.15u w=0.495u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u +c3 a vss 0.384f +c2 z vss 0.576f +.ends + +* starting condition for SRAM cell +.ic v(n2)=0 v(n1)='vdd' + +* simulation command: +.tran 100ps 120ns + +.options method=gear + +.control +pre_osdi C:\Spice64\lib\ngspice\psp103_nqs.osdi +run +rusage +*set nolegend +set xbrushwidth=3 +plot i(Vmeasvss) i(Vmeasvdd) +plot n1 n2+2 wl+4 i(vm1)*10000+6 i(vm2)*10000+8 +.endc + +.end diff --git a/examples/xspice/see/ihp_simple_sram_seegen_subckt.net b/examples/xspice/see/ihp_simple_sram_seegen_subckt.net new file mode 100644 index 000000000..7b689f852 --- /dev/null +++ b/examples/xspice/see/ihp_simple_sram_seegen_subckt.net @@ -0,0 +1,69 @@ +* Simple SRAM cell in a subcircuit, double exponential current pulses +* IHP Open PDK + +* Path to the PDK +.lib "D:\Spice_general\IHP-Open-PDK\ihp-sg13g2\libs.tech\ngspice\models\cornerMOSlv.lib" mos_tt + +.param vdd = 1.2 +.param deltat=11n deltat2=27n +*.param tochar = 1e-13 ; tochar dependency on LET not yet defined +.param tfall = 500p trise=20p ; tau in exponent for pulse +.param let = 11 +.param cdepth = 0.9 +*.param Inull = 'tochar/(tfall-trise)' + +* the voltage sources: +Vdd vd gnd DC 'vdd' +Vwl wl 0 0 PULSE 0 'vdd' 45n 1n 1n 7n 1 +Vbl1 bl1 0 'vdd' +Vbl2 bl2 0 0 + +**** SEE generator without control input, double exponential current sources +aseegen1 NULL [%id(xcell.n1 m1) %id(xcell.n2 m2) %id(xcell.n1 m1) %id(xcell.n2 m2)] seemod1 +.model seemod1 seegen (tdelay = 11n tperiod=25n let='let' cdepth='cdepth' tfall='tfall' trise='trise') +* alternative syntax, if no current measurement required and reference nodes are GND +*aseegen1 NULL [%i(xcell.n1) %i(xcell.n2) %i(xcell.n1) %i(xcell.n2)] seemod1 + +**** the SRAM cell +Xcell bl1 bl2 wl vdd vss srcell + +.subckt srcell bl1 bl2 wl vdd vss +Xnot1 n1 vdd vss n2 not1 +Xnot2 n2 vdd vss n1 not1 +xmo02 n2 wl bl1 vss sg13_lv_nmos l=0.15u w=0.495u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u +xmo01 n1 wl bl2 vss sg13_lv_nmos l=0.15u w=0.495u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u +.ends + +**** Current measurements +Vmeasvss vss 0 0 +Vmeasvdd vd vdd 0 +Vm1 m1 0 0 +Vm2 m2 0 0 + +**** Inverter cell +.subckt not1 a vdd vss z +xm01 z a vdd vdd sg13_lv_pmos l=0.15u w=0.99u as=0.26235p ad=0.26235p ps=2.51u pd=2.51u +xm02 z a vss vss sg13_lv_nmos l=0.15u w=0.495u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u +c3 a vss 0.384f +c2 z vss 0.576f +.ends + +* starting condition for SRAM cell +.ic v(xcell.n2)=0 v(xcell.n1)='vdd' + +* simulation command: +.tran 100ps 120ns + +*.options method=gear + +.control +pre_osdi C:\Spice64\lib\ngspice\psp103_nqs.osdi +run +rusage +*set nolegend +set xbrushwidth=3 +plot i(Vmeasvss) i(Vmeasvdd) +plot xcell.n1 xcell.n2+2 wl+4 i(vm1)*10000+6 i(vm2)*10000+8 +.endc + +.end diff --git a/examples/xspice/see/ihp_simple_sram_seegen_subckt_vary.net b/examples/xspice/see/ihp_simple_sram_seegen_subckt_vary.net new file mode 100644 index 000000000..5bd6c80da --- /dev/null +++ b/examples/xspice/see/ihp_simple_sram_seegen_subckt_vary.net @@ -0,0 +1,81 @@ +* Simple SRAM cell in a subcircuit, double exponential current pulses +* total charge is varied. +* IHP Open PDK + +* Path to the PDK +.lib "D:\Spice_general\IHP-Open-PDK\ihp-sg13g2\libs.tech\ngspice\models\cornerMOSlv.lib" mos_tt + +.param vdd = 1.2 +*.param tochar = 1e-13 ; tochar dependency on LET not yet defined + +.param d = 1 +.param let = 12 + +.param tochar = 1.035e-14 * let * d +.csparam let = 'let' ; send param value to .control section +.param tfall = 500p trise = 100p ; tau in exponent for pulse +.param Inull = 'tochar/(tfall-trise)' + +* the voltage sources: +Vdd vd gnd DC 'vdd' +Vwl wl 0 0 PULSE 0 'vdd' 45n 1n 1n 7n 1 +Vbl1 bl1 0 'vdd' +Vbl2 bl2 0 0 + +**** SEE generator without control input, double exponential current sources +aseegen1 NULL [%id(xcell.n1 m1) %id(xcell.n2 m2) %id(xcell.n1 m1) %id(xcell.n2 m2)] seemod1 +.model seemod1 seegen (tdelay = 11n tperiod=25n tfall='tfall' trise='trise' let='let' cdepth='d') +* alternative syntax, if no current measurement required and reference nodes are GND +*aseegen1 NULL [%i(xcell.n1) %i(xcell.n2) %i(xcell.n1) %i(xcell.n2)] seemod1 + +**** the SRAM cell +Xcell bl1 bl2 wl vdd vss srcell + +.subckt srcell bl1 bl2 wl vdd vss +Xnot1 n1 vdd vss n2 not1 +Xnot2 n2 vdd vss n1 not1 +xmo02 n2 wl bl1 vss sg13_lv_nmos l=0.15u w=0.495u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u +xmo01 n1 wl bl2 vss sg13_lv_nmos l=0.15u w=0.495u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u +.ends + +**** Current measurements +Vmeasvss vss 0 0 +Vmeasvdd vd vdd 0 +Vm1 m1 0 0 +Vm2 m2 0 0 + +**** Inverter cell +.subckt not1 a vdd vss z +xm01 z a vdd vdd sg13_lv_pmos l=0.15u w=0.99u as=0.26235p ad=0.26235p ps=2.51u pd=2.51u +xm02 z a vss vss sg13_lv_nmos l=0.15u w=0.495u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u +c3 a vss 0.384f +c2 z vss 0.576f +.ends + +* starting condition for SRAM cell +.ic v(xcell.n2)=0 v(xcell.n1)='vdd' + +* simulation command: +.tran 100ps 120ns + +*.options method=gear + +.options noinit + +.control +pre_osdi C:\Spice64\lib\ngspice\psp103_nqs.osdi +set xbrushwidth=3 +let newlet = let + +repeat 5 + print newlet + run + plot xcell.n1 xcell.n2+2 wl+4 i(vm1)*10000+6 i(vm2)*10000+8 ylimit -1 10 + let newlet = newlet - 1 + alterparam let = $&newlet + reset +end +rusage +.endc + +.end diff --git a/examples/xspice/see/ihp_simple_sram_set.net b/examples/xspice/see/ihp_simple_sram_set.net new file mode 100644 index 000000000..394a8554e --- /dev/null +++ b/examples/xspice/see/ihp_simple_sram_set.net @@ -0,0 +1,64 @@ +* IHP Open PDK +* simple SRAM cell, exponential current pulses + +* Path to the PDK +*.include "D:\Spice_general\skywater-pdk\libraries\sky130_fd_pr\latest\models\corners/tt.spice" +.lib "D:\Spice_general\IHP-Open-PDK\ihp-sg13g2\libs.tech\ngspice\models\cornerMOSlv.lib" mos_tt +*.include lib_out1.lib + +.param vdd = 1.2 +.param deltat=11n deltat2=27n +.param tochar = 1e-13 +.param talpha = 500p tbeta=10p +.param Inull = 'tochar/(talpha-tbeta)' + +* the voltage sources: +Vdd vd gnd DC 'vdd' +Vwl wl 0 0 PULSE 0 'vdd' 45n 1n 1n 7n 1 +Vbl bl 0 'vdd' +Vbln bln 0 0 + +*V1 in gnd pulse(0 'vdd' 0p 200p 100p 5n 10n) + +* Eponential current source +Iset1 n1 m1 EXP(0 'Inull' 'deltat' 'tbeta' 'deltat' 'talpha') +Iset2 n2 m2 EXP(0 'Inull' 'deltat2' 'tbeta' 'deltat2' 'talpha') +Iset3 n1 m1 EXP(0 'Inull' 'deltat+50n' 'tbeta' 'deltat+50n' 'talpha') +Iset4 n2 m2 EXP(0 'Inull' 'deltat2+50n' 'tbeta' 'deltat2+50n' 'talpha') +*Cset out 0 10f + +Xnot1 n1 vdd vss n2 not1 +Xnot2 n2 vdd vss n1 not1 +xmo02 n2 wl bl vss sg13_lv_nmos l=0.15u w=0.495u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u +xmo01 n1 wl bln vss sg13_lv_nmos l=0.15u w=0.495u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u + +Vmeasvss vss 0 0 +Vmeasvdd vd vdd 0 +Vm1 m1 0 0 +Vm2 m2 0 0 + +.subckt not1 a vdd vss z +xm01 z a vdd vdd sg13_lv_pmos l=0.15u w=0.99u as=0.26235p ad=0.26235p ps=2.51u pd=2.51u +xm02 z a vss vss sg13_lv_nmos l=0.15u w=0.495u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u +c3 a vss 0.384f +c2 z vss 0.576f +.ends + +* starting condition for SRAM cell +.ic v(n2)=0 v(n1)='vdd' + +* simulation command: +.tran 100ps 100ns ; 0 10p + +.options method=gear + +.control +run +rusage +*set nolegend +set xbrushwidth=3 +plot i(Vmeasvss) i(Vmeasvdd) +plot n1 n2+2 wl+4 i(vm1)*10000+6 i(vm2)*10000+8 +.endc + +.end diff --git a/examples/xspice/see/ihp_two_inverters_set.net b/examples/xspice/see/ihp_two_inverters_set.net new file mode 100644 index 000000000..e31712d0b --- /dev/null +++ b/examples/xspice/see/ihp_two_inverters_set.net @@ -0,0 +1,48 @@ +* IHP Open PDK +* simple inverter + +* Path to the PDK +*.include "D:\Spice_general\skywater-pdk\libraries\sky130_fd_pr\latest\models\corners/tt.spice" +.lib "D:\Spice_general\IHP-Open-PDK\ihp-sg13g2\libs.tech\ngspice\models\cornerMOSlv.lib" mos_tt +*.include lib_out1.lib + +.param vdd = 1.2 +.param deltat=11n deltat2=27n + +* the voltage sources: +Vdd vd gnd DC 'vdd' +V1 in gnd pulse(0 'vdd' 0p 200p 100p 5n 10n) + +* Eponential current source +Iset1 out1 0 EXP(0 250u 'deltat' 10p 'deltat' 500p) +Iset2 out1 0 EXP(0 250u 'deltat2' 10p 'deltat2' 500p) +*Cset out 0 10f + +Xnot1 in vdd vss out1 not1 +Xnot2 out1 vdd vss out not1 + +Vmeasvss vss 0 0 +Vmeasvdd vd vdd 0 + +.subckt not1 a vdd vss z +xm01 z a vdd vdd sg13_lv_pmos l=0.15u w=0.99u as=0.26235p ad=0.26235p ps=2.51u pd=2.51u +xm02 z a vss vss sg13_lv_nmos l=0.15u w=0.495u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u +c3 a vss 0.384f +c2 z vss 0.576f +.ends + +* simulation command: +.tran 100ps 50ns ; 0 10p + +.options method=gear + +.control +run +rusage +*set nolegend +set xbrushwidth=3 +plot i(Vmeasvss) i(Vmeasvdd) +plot in out1+2 out+4 +.endc + +.end diff --git a/examples/xspice/see/repeat_loop_seegen.net b/examples/xspice/see/repeat_loop_seegen.net new file mode 100644 index 000000000..222814719 --- /dev/null +++ b/examples/xspice/see/repeat_loop_seegen.net @@ -0,0 +1,41 @@ +* Repeat loop, double exponential current pulses + +.param let = 10.5 cdepth = 1.2 +.csparam let = 'let' +.param tfall = 500p trise = 20p ; tau in exponent for pulse + +R1 n1 0 1e4 +R2 n2 0 1e4 +R3 n3 0 1e4 +R4 n4 0 1e4 + + +**** SEE generator without control input, double exponential current sources +aseegen1 NULL [%id(n1 0) %id(n2 0) %id(n3 0) %id(n4 0)] seemod1 +.model seemod1 seegen (tdelay = 11n tperiod=25n let='let' cdepth='cdepth' trise='trise' tfall='tfall') +* alternative syntax, if no current measurement required and reference nodes are GND +*aseegen1 NULL [%i(n1) %i(n2) %i(n3) %i(n4)] seemod1 + + + +* simulation command: +.tran 100ps 120ns + +*.options method=gear + +.control +set xbrushwidth=3 +*run +*plot n1 n2+2 n3+4 n4+6 +let newlet = let +repeat 10 + run + plot n1 n2+2 n3+4 n4+6 ylimit -3 7 + let newlet = newlet - 0.5 + alterparam let = $&newlet + reset +end +rusage +.endc + +.end diff --git a/examples/xspice/see/seegen_cm1.cir b/examples/xspice/see/seegen_cm1.cir new file mode 100644 index 000000000..a4bd7e371 --- /dev/null +++ b/examples/xspice/see/seegen_cm1.cir @@ -0,0 +1,22 @@ +Test of seegen code model + +aseegen1 NULL [%id(n1 p1) %id(n2 p2) %id(n3 p3)] seemod1 +.model seemod1 seegen (tdelay = 5n tperiod=4.5n) + +Rsee1 n1 0 1 +Vmeas1 p1 0 0 + +Rsee2 n2 0 1 +Vmeas2 p2 0 0 + +Rsee3 n3 0 1 +Vmeas3 p3 0 0 + +.control +tran 10p 35n +rusage time +set xbrushwidth=3 +plot i(Vmeas1) i(Vmeas2)+200u i(Vmeas3)+400u +.endc + +.end diff --git a/examples/xspice/see/set1.cir b/examples/xspice/see/set1.cir new file mode 100644 index 000000000..6fa666144 --- /dev/null +++ b/examples/xspice/see/set1.cir @@ -0,0 +1,23 @@ +SET pulse test + +.param alpha = 100p beta = 500p deltat = 1n + +* Arbitrary currnt source with expression +Bset1 1 0 I = ternary_fcn(TIME < 'deltat', 0, 2.5m * (exp(-(TIME-'deltat')/'alpha')-exp(-(TIME-'deltat')/'beta'))) +R1 1 11 1 +Vmeas 11 0 0 + +* Eponential current source +Iset 2 0 EXP(0 -2.5m 'deltat' 'alpha' 'deltat' 'beta') +R2 2 22 1 +Vmeas2 22 0 0 + + +.control +tran 1p 10n +set xbrushwidth=2 +plot I(Vmeas)-I(Vmeas2) +plot I(Vmeas) I(Vmeas2) +.endc + +.end diff --git a/src/xspice/icm/xtradev/modpath.lst b/src/xspice/icm/xtradev/modpath.lst index ec7a2f87f..53d9cbea3 100644 --- a/src/xspice/icm/xtradev/modpath.lst +++ b/src/xspice/icm/xtradev/modpath.lst @@ -10,3 +10,4 @@ zener memristor sidiode pswitch +seegenerator diff --git a/src/xspice/icm/xtradev/seegenerator/cfunc.mod b/src/xspice/icm/xtradev/seegenerator/cfunc.mod new file mode 100644 index 000000000..11bee5c74 --- /dev/null +++ b/src/xspice/icm/xtradev/seegenerator/cfunc.mod @@ -0,0 +1,231 @@ +/*.......1.........2.........3.........4.........5.........6.........7.........8 +================================================================================ + +FILE seegenerator/cfunc.mod + +Public Domain + +Universty Duisburg-Essen +Duisburg, Germany +Project Flowspace + +AUTHORS + + 19 May 2025 Holger Vogt + + +MODIFICATIONS + + + +SUMMARY + + This file contains the model-specific routines used to + functionally describe the see (single event effects) generator code model. + + +INTERFACES + + FILE ROUTINE CALLED + + +REFERENCED FILES + + Inputs from and outputs to ARGS structure. + + +NON-STANDARD FEATURES + + NONE + +===============================================================================*/ + +/*=== INCLUDE FILES ====================*/ + + + + +/*=== CONSTANTS ========================*/ + + + + +/*=== MACROS ===========================*/ + + + + +/*=== LOCAL VARIABLES & TYPEDEFS =======*/ + +static void +cm_seegen_callback(ARGS, Mif_Callback_Reason_t reason) +{ + switch (reason) { + case MIF_CB_DESTROY: { + double *last_t_value = STATIC_VAR (last_t_value); + if (last_t_value) + free(last_t_value); + STATIC_VAR (last_t_value) = NULL; + int *pulse_number = STATIC_VAR (pulse_number); + if (pulse_number) + free(pulse_number); + STATIC_VAR (pulse_number) = NULL; + break; + double *last_ctrl = STATIC_VAR (last_ctrl); + if (last_ctrl) + free(last_ctrl); + STATIC_VAR (last_ctrl) = NULL; + } + } +} + + +/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ + + + + + +/*============================================================================== + +FUNCTION void cm_seegen() + +AUTHORS + + 19 May 2025 Holger Vogt + +SUMMARY + + This function implements the see generator code model. + +INTERFACES + + FILE ROUTINE CALLED + + CMutil.c void cm_smooth_corner(); + void cm_smooth_discontinuity(); + void cm_climit_fcn() + +RETURNED VALUE + + Returns inputs and outputs via ARGS structure. + +GLOBAL VARIABLES + + NONE + +NON-STANDARD FEATURES + + model source: + Ygor Quadros de Aguiar, Frédéric Wrobel. Jean-Luc Autran, Rubén García Alía + Single-Event Effects, from Space to Accelerator Environments + Springer 2025 + +==============================================================================*/ + +/*=== CM_SEEGEN ROUTINE ===*/ + +void cm_seegen(ARGS) /* structure holding parms, + inputs, outputs, etc. */ +{ + double tfall; /* pulse fall time */ + double trise; /* pulse rise time */ + double tdelay; /* delay until first pulse */ + double inull; /* max. current of pulse */ + double let; /* linear energy transfer */ + double cdepth; /* charge collection depth */ + double angle; /* particle entrance angle */ + double tperiod; /* pulse repetition period */ + double ctrlthres; /* control voltage threshold */ + double ctrl; /* control input */ + double out; /* output current */ + double *last_t_value; /* static storage of next pulse time */ + int *pulse_number; /* static storage of next pulse time */ + double *last_ctrl; /* static storage of last ctrl value */ + double tcurr = TIME; /* current simulation time */ + + if (ANALYSIS == MIF_AC) { + return; + } + + /* Retrieve frequently used parameters... */ + + tfall = PARAM(tfall); + trise = PARAM(trise); + tdelay = PARAM(tdelay); + tperiod = PARAM(tperiod); + inull = PARAM(inull); + let = PARAM(let); + cdepth = PARAM(cdepth); + angle = PARAM(angle); + ctrlthres = PARAM(ctrlthres); + + if (PORT_NULL(ctrl)) + ctrl = 1; + else + ctrl = INPUT(ctrl); + + if (INIT==1) { + /* Allocate storage for last_t_value */ + STATIC_VAR(last_t_value) = (double *) malloc(sizeof(double)); + last_t_value = (double *) STATIC_VAR(last_t_value); + *last_t_value = tdelay; + STATIC_VAR(pulse_number) = (int *) malloc(sizeof(int)); + pulse_number = (int *) STATIC_VAR(pulse_number); + *pulse_number = 1; + STATIC_VAR(last_ctrl) = (double *) malloc(sizeof(double)); + last_ctrl = (double *) STATIC_VAR(last_ctrl); + *last_ctrl = ctrl; + /* set breakpoints at first pulse start and pulse maximum times */ + double tatmax = *last_t_value + tfall * trise * log(trise/tfall) / (trise - tfall); + cm_analog_set_perm_bkpt(*last_t_value); + cm_analog_set_perm_bkpt(tatmax); + } + else { + + last_t_value = (double *) STATIC_VAR(last_t_value); + pulse_number = (int *) STATIC_VAR(pulse_number); + last_ctrl = (double *) STATIC_VAR(last_ctrl); + + if (*last_ctrl < ctrlthres && ctrl >= ctrlthres) { + *last_t_value = *last_t_value + tcurr; + *last_ctrl = ctrl; + } + + /* the double exponential current pulse function */ + if (tcurr < *last_t_value) + out = 0; + else { + if (inull == 0) { + double LETeff = let/cos(angle); + double Qc = 1.035e-14 * LETeff * cdepth; + inull = Qc / (tfall - trise); + } + out = inull * (exp(-(tcurr-*last_t_value)/tfall) - exp(-(tcurr-*last_t_value)/trise)); + } + if (tcurr > *last_t_value + tperiod * 0.9) { + /* return some info */ + cm_message_printf("port name: out, node pair no.: %d, \nnode names: %s, %s, pulse time: %e", + *pulse_number, cm_get_node_name("out", *pulse_number - 1), + cm_get_neg_node_name("out", *pulse_number - 1), *last_t_value); + /* set the time for the next pulse */ + *last_t_value = *last_t_value + tperiod; + /* set breakpoints at new pulse start and pulse maximum times */ + double tatmax = *last_t_value + tfall * trise * log(trise/tfall) / (trise - tfall); + cm_analog_set_perm_bkpt(*last_t_value); + cm_analog_set_perm_bkpt(tatmax); + (*pulse_number)++; + if (*pulse_number > PORT_SIZE(out)) { + if (PARAM(perlim) == FALSE) + *pulse_number = 1; + else + *last_t_value = 1e12; /* stop any output */ + } + } + if (*pulse_number - 1 < PORT_SIZE(out)) + OUTPUT(out[*pulse_number - 1]) = out; + } +} + + + diff --git a/src/xspice/icm/xtradev/seegenerator/ifspec.ifs b/src/xspice/icm/xtradev/seegenerator/ifspec.ifs new file mode 100644 index 000000000..58d28f039 --- /dev/null +++ b/src/xspice/icm/xtradev/seegenerator/ifspec.ifs @@ -0,0 +1,120 @@ +/*.......1.........2.........3.........4.........5.........6.........7.........8 +================================================================================ +Public Domain + + +Universty Duisburg-Essen +Duisburg, Germany +Project Flowspace + +AUTHORS + +Holger Vogt 19 May 2025 + + + +SUMMARY + + This file contains the interface specification file for the + analog seegen code model. + +===============================================================================*/ + +NAME_TABLE: + +C_Function_Name: cm_seegen +Spice_Model_Name: seegen +Description: "single event effect generator" + + +PORT_TABLE: + +Port_Name: ctrl out +Description: "control input" "output" +Direction: in out +Default_Type: v i +Allowed_Types: [v,vd,i,id] [i,id] +Vector: no yes +Vector_Bounds: - [1 -] +Null_Allowed: yes no + + +PARAMETER_TABLE: + +Parameter_Name: tfall trise +Description: "pulse fall time" "pulse rise time" +Data_Type: real real +Default_Value: 500e-12 20e-12 +Limits: - - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes + + +PARAMETER_TABLE: + +Parameter_Name: tdelay inull +Description: "pulse delay" "max current" +Data_Type: real real +Default_Value: 0 0 +Limits: - - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes + + +PARAMETER_TABLE: + +Parameter_Name: tperiod ctrlthres +Description: "pulse repetition" "control voltage threshold" +Data_Type: real real +Default_Value: 0 0.5 +Limits: - - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes + + +PARAMETER_TABLE: + +Parameter_Name: let cdepth +Description: "lin energy transfer" "charge collection depth" +Data_Type: real real +Default_Value: 10 1 +Limits: - - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes + + +PARAMETER_TABLE: + +Parameter_Name: angle perlim +Description: "particle angle" "pulse repetition" +Data_Type: real boolean +Default_Value: 0 TRUE +Limits: [0 1.57079] - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes + +STATIC_VAR_TABLE: + +Static_Var_Name: last_t_value +Data_Type: pointer +Vector: no +Description: "next pulse start time" + +STATIC_VAR_TABLE: + +Static_Var_Name: pulse_number +Data_Type: pointer +Vector: no +Description: "number of pulse" + +STATIC_VAR_TABLE: + +Static_Var_Name: last_ctrl +Data_Type: pointer +Vector: no +Description: "last control value" diff --git a/visualc/xspice/xtradev.vcxproj b/visualc/xspice/xtradev.vcxproj index 54a4add88..6a9b35f54 100644 --- a/visualc/xspice/xtradev.vcxproj +++ b/visualc/xspice/xtradev.vcxproj @@ -248,6 +248,10 @@ ..\..\src\xspice\%(RelativeDir);%(AdditionalIncludeDirectories) + + ..\..\src\xspice\%(RelativeDir);%(AdditionalIncludeDirectories) + + @@ -275,6 +279,8 @@ + +