├── .gitignore ├── Biolek └── LTSpice │ ├── Biolek_IV.png │ ├── Biolek_Time.png │ ├── Circuit_Biolek.png │ ├── README.md │ ├── memristor_biolek.sub │ ├── memristor_biolek_sim_IV.plt │ ├── memristor_biolek_sim_T.plt │ └── memristor_with_state.asy ├── Generic └── Verilog-A │ ├── AC_and_DC_Sweep.png │ ├── Homotopy_I.png │ ├── Homotopy_S.png │ ├── README.md │ ├── hys.va │ ├── test_hys.cir │ ├── test_hys_forward.cir │ ├── test_hys_homotopy.cir │ ├── test_hys_orig.cir │ ├── test_hys_reverse.cir │ └── test_hys_transient.cir ├── Joglekar ├── Ltspice │ ├── README.md │ ├── memristor.asy │ ├── memristor.sub │ └── memristor_sim.asc ├── Ltspice2 │ ├── Circuit_Joglekar.png │ ├── Joglekar_IV.png │ ├── Joglekar_Time.png │ ├── README.md │ ├── memristor_joglekar2.sub │ ├── memristor_joglekar2_sim_IV.plt │ ├── memristor_joglekar2_sim_T.plt │ └── memristor_with_state.asy ├── Verilog-A │ ├── README.md │ ├── memristor.va │ ├── memristor_sim.cir │ └── memristor_sim.png └── Xyce │ ├── N_DEV_MemristorJoglekar.C │ ├── N_DEV_MemristorJoglekar.h │ ├── README.md │ └── joglekar.cir ├── Knowm ├── LTSpice │ ├── Circuit_Knowm.png │ ├── Knowm_IV.png │ ├── Knowm_Time.png │ ├── README.md │ ├── memristor_knowm.sub │ ├── memristor_knowm_sim.asc │ ├── memristor_knowm_sim_IV.plt │ └── memristor_knowm_sim_T.plt ├── Verilog-A │ ├── README.md │ ├── knowm.va │ └── knowm_sim.cir └── Xyce │ ├── Generalized.png │ ├── MMSS_Xyce.png │ ├── N_DEV_MemristorKnowm.C │ ├── N_DEV_MemristorKnowm.h │ ├── README.md │ └── knowm.cir ├── Pershin ├── Ngspice │ └── memristor.cir └── README.md ├── README.md ├── University_of_Michigan └── LTSpice │ ├── Circuit_UMich.png │ ├── README.md │ ├── UMich_IV.png │ ├── UMich_Time.png │ ├── memristor_umich.sub │ ├── memristor_umich_sim.asc │ ├── memristor_umich_sim_IV.plt │ └── memristor_umich_sim_T.plt ├── Yakopcic ├── LTSpice │ ├── Circuit_Yakopcic.png │ ├── README.md │ ├── Yakopcic_IV.png │ ├── Yakopcic_Time.png │ ├── memristor_yakopcic.sub │ ├── memristor_yakopcic_sim.asc │ ├── memristor_yakopcic_sim_IV.plt │ └── memristor_yakopcic_sim_T.plt └── Xyce │ ├── README.md │ └── yakopcic.cir └── knowm_model_modified_verilogA_code /.gitignore: -------------------------------------------------------------------------------- 1 | *.*prn 2 | *.*la 3 | *.*log 4 | *.*vams 5 | *.*.va.adms 6 | **.xml 7 | .libs/ 8 | *.my 9 | 10 | -------------------------------------------------------------------------------- /Biolek/LTSpice/Biolek_IV.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Biolek/LTSpice/Biolek_IV.png -------------------------------------------------------------------------------- /Biolek/LTSpice/Biolek_Time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Biolek/LTSpice/Biolek_Time.png -------------------------------------------------------------------------------- /Biolek/LTSpice/Circuit_Biolek.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Biolek/LTSpice/Circuit_Biolek.png -------------------------------------------------------------------------------- /Biolek/LTSpice/README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | 3 | | Model Class | Model Language | Simulator | 4 | |---|---|---| 5 | |SPICE Subcircuit|SPICE|LTSpice| 6 | 7 | Other names: "The Ideal Memristor", "The Resistance Switch" 8 | 9 | ## Sources 10 | 11 | 1. Original Source of SPICE Model: 12 | 13 | ## How to Run Model 14 | 15 | 1. LTSpice Intro - [The Joglekar Resistance Switch Memristor Model in LTSpice](http://knowm.org/the-joglekar-resistance-switch-memristor-model-in-ltspice/) 16 | 1. LTSpice - [Memristor Models in LTSpice](http://knowm.org/memristor-models-in-ltspice/) 17 | -------------------------------------------------------------------------------- /Biolek/LTSpice/memristor_biolek.sub: -------------------------------------------------------------------------------- 1 | * HP Memristor SPICE Model Using Biolek Window 2 | 3 | * Connections: 4 | * TE: Top electrode 5 | * BE: Bottom electrode 6 | * XSV: External connection to plot state variable 7 | * that is not used otherwise 8 | 9 | .SUBCKT MEM_BIOLEK TE BE XSV 10 | 11 | * Ron: Minimum device resistance 12 | * Roff: Maximum device resistance 13 | * D: Width of the thin film 14 | * uv: Dopant mobility 15 | * p: Parameter for window function 16 | * x0: State varaible initial value 17 | 18 | .params Ron=100 Roff=1K x0=.076 D=16N uv=40F p=7 19 | 20 | * Biolek Window Function 21 | .func f(V1,I1)={1-pow((V1-stp(-I1)),(2*p))} 22 | 23 | * Memristor I-V Relationship 24 | .func IVRel(V1,V2) = V1/(Ron*V2 + Roff*(1-V2)) 25 | 26 | * Circuit to determine state variable 27 | Gx 0 XSV value={I(Gmem)*Ron*uv*f(V(XSV,0),I(Gmem))/pow(D,2)} 28 | Cx XSV 0 {1} 29 | .ic V(XSV) = x0 30 | 31 | * Current source representing memristor 32 | Gmem TE BE value={IVRel(V(TE,BE),V(XSV,0))} 33 | 34 | .ENDS MEM_BIOLEK -------------------------------------------------------------------------------- /Biolek/LTSpice/memristor_biolek_sim_IV.plt: -------------------------------------------------------------------------------- 1 | [Transient Analysis] 2 | { 3 | Npanes: 2 4 | Active Pane: 1 5 | { 6 | traces: 1 {336592898,0,"Ix(U1:TE)"} 7 | Parametric: "V(n001)" 8 | X: (' ',2,-1.2,0.02,1.2) 9 | Y[0]: ('m',1,-0.001,0.0002,0.0012) 10 | Y[1]: ('_',0,1e+308,0,-1e+308) 11 | Amps: ('m',0,0,1,-0.001,0.0002,0.0012) 12 | Log: 0 0 0 13 | NeyeDiagPeriods: 0 14 | TeyeEnd: 3 15 | }, 16 | { 17 | traces: 1 {268959747,0,"V(nc_01)"} 18 | Parametric: "V(n001)" 19 | X: (' ',2,-1.2,0.02,1.2) 20 | Y[0]: (' ',2,0.21,0.07,1.05) 21 | Y[1]: ('_',0,1e+308,0,-1e+308) 22 | Volts: (' ',0,0,2,0.21,0.07,1.05) 23 | Log: 0 0 0 24 | NeyeDiagPeriods: 0 25 | TeyeEnd: 3 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Biolek/LTSpice/memristor_biolek_sim_T.plt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Biolek/LTSpice/memristor_biolek_sim_T.plt -------------------------------------------------------------------------------- /Biolek/LTSpice/memristor_with_state.asy: -------------------------------------------------------------------------------- 1 | Version 4 2 | SymbolType CELL 3 | LINE Normal 4 33 -4 33 4 | LINE Normal 0 -48 0 -32 5 | LINE Normal 0 48 0 33 6 | LINE Normal 32 0 0 0 7 | CIRCLE Normal 4 33 -4 0 8 | CIRCLE Normal 4 -32 -4 0 9 | SYMATTR Prefix X 10 | SYMATTR Description Parameterized Memristor 11 | PIN 0 -48 RIGHT 8 12 | PINATTR PinName TE 13 | PINATTR SpiceOrder 1 14 | PIN 0 48 RIGHT 8 15 | PINATTR PinName BE 16 | PINATTR SpiceOrder 2 17 | PIN 32 0 LEFT 8 18 | PINATTR PinName xsv 19 | PINATTR SpiceOrder 3 20 | -------------------------------------------------------------------------------- /Generic/Verilog-A/AC_and_DC_Sweep.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Generic/Verilog-A/AC_and_DC_Sweep.png -------------------------------------------------------------------------------- /Generic/Verilog-A/Homotopy_I.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Generic/Verilog-A/Homotopy_I.png -------------------------------------------------------------------------------- /Generic/Verilog-A/Homotopy_S.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Generic/Verilog-A/Homotopy_S.png -------------------------------------------------------------------------------- /Generic/Verilog-A/README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | 3 | | Model Class | Model Language | Simulator | 4 | |---|---|---| 5 | |Well-formed|Verilog-A|Xyce| 6 | 7 | ## Instructions 8 | 9 | See: 10 | 11 | 12 | cd .../memristor-models-4-all/Generic/Verilog-A 13 | buildxyceplugin -o hys *.va /usr/local/lib 14 | Xyce -plugin /usr/local/lib/hys.so test_hys_forward.cir 15 | Xyce -plugin /usr/local/lib/hys.so test_hys_reverse.cir 16 | Xyce -plugin /usr/local/lib/hys.so test_hys_transient.cir 17 | 18 | gnuplot 19 | plot '.../memristor-models-4-all/Generic/Verilog-A/test_hys_forward.cir.prn' using 2:3 with lines title "forward DC Sweep", '.../memristor-models-4-all/Generic/Verilog-A/test_hys_reverse.cir.prn' using 2:3 with lines title "reverse DC Sweep", '.../memristor-models-4-all/Generic/Verilog-A/test_hys_transient.cir.prn' using 3:4 with lines title "Transient" 20 | 21 | Xyce -plugin /usr/local/lib/hys.so test_hys_homotopy.cir 22 | plot '.../memristor-models-4-all/Generic/Verilog-A/test_hys_homotopy.cir.HOMOTOPY.prn' using 3:4 with lines title "I" 23 | plot '.../memristor-models-4-all/Generic/Verilog-A/test_hys_homotopy.cir.HOMOTOPY.prn' using 3:5 with lines title "S" 24 | 25 | -------------------------------------------------------------------------------- /Generic/Verilog-A/hys.va: -------------------------------------------------------------------------------- 1 | // A device with hysteresis 2 | `include "disciplines.vams" 3 | `define attr(txt) (*txt*) 4 | 5 | module hys(p, n); 6 | 7 | inout p, n; 8 | electrical p, n, ns; 9 | 10 | parameter real R = 1e3 from (0:inf) `attr(info="R" type="instance"); 11 | parameter real k = 1 from (0:inf) `attr(info="k" type="instance"); 12 | parameter real tau = 1e-5 from (0:inf) `attr(info="tau" type="instance"); 13 | 14 | real s; 15 | 16 | analog begin 17 | s = V(ns, n); 18 | I(p, n) <+ V(p, n)/R * (1+tanh(k*s)); 19 | I(ns, n) <+ V(p, n) - pow(s, 3) + s; 20 | I(ns, n) <+ ddt(-tau*s); 21 | end 22 | 23 | endmodule -------------------------------------------------------------------------------- /Generic/Verilog-A/test_hys.cir: -------------------------------------------------------------------------------- 1 | * test hys.va in DC, TRAN and Homotopy 2 | 3 | V1 1 0 1 sin(0 0.7 1k) 4 | Yhys H1 0 1 5 | 6 | * DC analysis 7 | .dc V1 -1 1 0.01 8 | .print dc V(1) I(V1) N(Yhys!H1_ns) 9 | 10 | 11 | * transient simulation 12 | *.tran 1u 2m 13 | *.print tran V(1) I(V1) N(Yhys!H1_ns) 14 | 15 | 16 | -------------------------------------------------------------------------------- /Generic/Verilog-A/test_hys_forward.cir: -------------------------------------------------------------------------------- 1 | * test hys.va in DC forward 2 | 3 | V1 1 0 1 sin(0 0.7 1k) 4 | Yhys H1 1 0 5 | 6 | * DC analysis 7 | .dc V1 -1 1 0.01 8 | .print dc V(1) I(V1) N(Yhys!H1_ns) 9 | -------------------------------------------------------------------------------- /Generic/Verilog-A/test_hys_homotopy.cir: -------------------------------------------------------------------------------- 1 | * test hys.va in Homotopy 2 | 3 | V1 1 0 1 sin(0 0.7 1k) 4 | Yhys H1 1 0 5 | 6 | * homotopy analysis 7 | .dc V1 .7 .7 1 8 | .print homotopy V(1) I(V1) N(Yhys!H1_ns) 9 | .options nonlin continuation=1 10 | .options loca stepper=ARC 11 | + predictor=1 stepcontrol=1 12 | + conparam=V1:DCV0 13 | + initialvalue=-1.0 minvalue=-1.0 maxvalue=1.0 14 | + initialstepsize=0.01 minstepsize=1.0e-8 maxstepsize=0.1 15 | + aggressiveness=0.1 -------------------------------------------------------------------------------- /Generic/Verilog-A/test_hys_orig.cir: -------------------------------------------------------------------------------- 1 | * test hys.va in DC, TRAN and Homotopy 2 | 3 | V1 1 0 1 sin(0 0.7 1k) 4 | Yhys H1 1 0 5 | 6 | * DC analysis 7 | * .dc V1 1 -1 0.01 8 | * .print dc V(1) I(V1) N(Yhys!H1_ns) 9 | 10 | 11 | * transient simulation 12 | .tran 1u 2m 13 | .print tran V(1) I(V1) N(Yhys!H1_ns) 14 | 15 | 16 | * homotopy analysis 17 | *.dc V1 .7 .7 1 18 | *.print homotopy V(1) I(V1) N(Yhys!H1_ns) 19 | .options nonlin continuation=1 20 | .options loca stepper=ARC 21 | + predictor=1 stepcontrol=1 22 | + conparam=V1:DCV0 23 | + initialvalue=-1.0 minvalue=-1.0 maxvalue=1.0 24 | + initialstepsize=0.01 minstepsize=1.0e-8 maxstepsize=0.1 25 | + aggressiveness=0.1 -------------------------------------------------------------------------------- /Generic/Verilog-A/test_hys_reverse.cir: -------------------------------------------------------------------------------- 1 | * test hys.va in DC reverse 2 | 3 | V1 1 0 1 sin(0 0.7 1k) 4 | Yhys H1 0 1 5 | 6 | * DC analysis 7 | .dc V1 -1 1 0.01 8 | .print dc V(1) I(V1) N(Yhys!H1_ns) 9 | -------------------------------------------------------------------------------- /Generic/Verilog-A/test_hys_transient.cir: -------------------------------------------------------------------------------- 1 | * test hys.va in transient 2 | 3 | V1 1 0 1 sin(0 0.7 1k) 4 | Yhys H1 1 0 5 | 6 | * transient simulation 7 | .tran 1u 2m 8 | .print tran V(1) I(V1) N(Yhys!H1_ns) 9 | 10 | 11 | -------------------------------------------------------------------------------- /Joglekar/Ltspice/README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | 3 | | Model Class | Model Language | Simulator | 4 | |---|---|---| 5 | |SPICE Subcircuit|SPICE|LTSpice| 6 | 7 | Other names: "The Ideal Memristor", "The Resistance Switch" or "The HP Model" 8 | 9 | ## Sources 10 | 11 | 1. Original Source of SPICE Model: 12 | 13 | ## How to Run Model 14 | 15 | 1. LTSpice - [The Joglekar Resistance Switch Memristor Model in LTSpice](http://knowm.org/the-joglekar-resistance-switch-memristor-model-in-ltspice/) 16 | -------------------------------------------------------------------------------- /Joglekar/Ltspice/memristor.asy: -------------------------------------------------------------------------------- 1 | Version 4 2 | SymbolType BLOCK 3 | LINE Normal 4 33 -4 33 4 | LINE Normal 0 -48 0 -32 5 | LINE Normal 0 48 0 33 6 | CIRCLE Normal 4 33 -4 0 7 | CIRCLE Normal 4 -32 -4 0 8 | SYMATTR SpiceModel memristor 9 | SYMATTR Prefix X 10 | SYMATTR Description Parameterized Memristor 11 | SYMATTR ModelFile memristor.sub 12 | PIN 0 -48 RIGHT 8 13 | PINATTR PinName A 14 | PINATTR SpiceOrder 1 15 | PIN 0 48 RIGHT 8 16 | PINATTR PinName B 17 | PINATTR SpiceOrder 2 18 | -------------------------------------------------------------------------------- /Joglekar/Ltspice/memristor.sub: -------------------------------------------------------------------------------- 1 | *********************************************** 2 | * HP Memristor SPICE Model 3 | * For Transient Analysis only 4 | * created by Zdenek and Dalibor Biolek 5 | *********************************************** 6 | * Ron, Roff - Resistance in ON / OFF States 7 | * 8 | * Rinit - Resistance at T=0 9 | * 10 | * D - Width of the thin film 11 | * 12 | * uv - Migration coefficient 13 | * 14 | * p - Parameter of the WINDOW-function for 15 | * modeling nonlinear boundary conditions 16 | * 17 | * x - W/D Ratio, W is the actual width 18 | * of the doped area (from 0 to D) 19 | * 20 | *********************************************** 21 | .SUBCKT memristor plus minus PARAMS: 22 | + Ron=100 Roff=16K Rinit=11K D=10N uv=10F p=1 23 | 24 | *********************************************** 25 | * DIFFERENTIAL EQUATION MODELING * 26 | *********************************************** 27 | Gx 0 x value={I(Emem)*uv*Ron/D**2*f(V(x),p)} 28 | Cx x 0 1 IC={(Roff-Rinit)/(Roff-Ron)} 29 | Raux x 0 1000000 30 | 31 | *********************************************** 32 | * RESISTIVE PORT OF THE MEMRISTOR * 33 | *********************************************** 34 | Emem plus aux value={-I(Emem)*V(x)*(Roff-Ron)} 35 | Roff aux minus {Roff} 36 | 37 | *********************************************** 38 | * FLUX COMPUTATION * 39 | *********************************************** 40 | Eflux flux 0 value={SDT(V(plus,minus))} 41 | 42 | *********************************************** 43 | * CHARGE COMPUTATION * 44 | *********************************************** 45 | Echarge charge 0 value={SDT(I(Emem))} 46 | 47 | *********************************************** 48 | * WINDOW FUNCTIONS 49 | * FOR NONLINEAR DRIFT MODELING * 50 | *********************************************** 51 | * window function, according to Joglekar 52 | .func f(x,p)={1-(2*x-1)**(2*p)} 53 | 54 | .ENDS memristor 55 | -------------------------------------------------------------------------------- /Joglekar/Ltspice/memristor_sim.asc: -------------------------------------------------------------------------------- 1 | Version 4 2 | SHEET 1 880 680 3 | WIRE 416 0 16 0 4 | WIRE 416 16 416 0 5 | WIRE 16 32 16 0 6 | WIRE 16 144 16 112 7 | WIRE 224 144 16 144 8 | WIRE 416 144 416 112 9 | WIRE 416 144 224 144 10 | WIRE 224 192 224 144 11 | FLAG 224 192 0 12 | SYMBOL memristor 416 64 R0 13 | SYMATTR InstName Memristor 14 | SYMBOL voltage 16 16 R0 15 | WINDOW 123 0 0 Left 2 16 | WINDOW 39 0 0 Left 2 17 | SYMATTR InstName V1 18 | SYMATTR Value SINE(0 1.2 1 0 0 0) 19 | TEXT 96 -32 Left 2 !.tran 0 3s 0 3m 20 | -------------------------------------------------------------------------------- /Joglekar/Ltspice2/Circuit_Joglekar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Joglekar/Ltspice2/Circuit_Joglekar.png -------------------------------------------------------------------------------- /Joglekar/Ltspice2/Joglekar_IV.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Joglekar/Ltspice2/Joglekar_IV.png -------------------------------------------------------------------------------- /Joglekar/Ltspice2/Joglekar_Time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Joglekar/Ltspice2/Joglekar_Time.png -------------------------------------------------------------------------------- /Joglekar/Ltspice2/README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | 3 | | Model Class | Model Language | Simulator | 4 | |---|---|---| 5 | |SPICE Subcircuit|SPICE|LTSpice| 6 | 7 | Other names: "The Ideal Memristor", "The Resistance Switch" 8 | 9 | ## Sources 10 | 11 | 1. Original Source of SPICE Model: 12 | 13 | ## How to Run Model 14 | 15 | 1. LTSpice Intro - [The Joglekar Resistance Switch Memristor Model in LTSpice](http://knowm.org/the-joglekar-resistance-switch-memristor-model-in-ltspice/) 16 | 1. LTSpice - [Memristor Models in LTSpice](http://knowm.org/memristor-models-in-ltspice/) 17 | -------------------------------------------------------------------------------- /Joglekar/Ltspice2/memristor_joglekar2.sub: -------------------------------------------------------------------------------- 1 | * HP Memristor SPICE Model Using Joglekar Window 2 | 3 | * Connections: 4 | * TE: Top electrode 5 | * BE: Bottom electrode 6 | * XSV: External connection to plot state variable 7 | * that is not used otherwise 8 | 9 | .SUBCKT MEM_JOGLEKAR TE BE XSV 10 | 11 | * Ron: Minimum device resistance 12 | * Roff: Maximum device resistance 13 | * D: Width of the thin film 14 | * uv: Dopant mobility 15 | * p: Parameter for window function 16 | * x0: State variable initial value 17 | 18 | .params Ron=100 Roff=10K x0=.56 D=12N uv=50F p=7 19 | 20 | * Joglekar Window Function 21 | .func f(V1) = 1-pow((2*V1-1),(2*p)) 22 | 23 | * Memristor I-V Relationship 24 | .func IVRel(V1,V2) = V1/(Ron*V2 + Roff*(1-V2)) 25 | 26 | * Circuit to determine state variable 27 | Gx 0 XSV value={ I(Gmem)*Ron*uv*f(V(XSV,0))/pow(D,2) } 28 | Cx XSV 0 {1} 29 | .ic V(XSV) = x0 30 | 31 | * Current source representing memristor 32 | Gmem TE BE value={IVRel(V(TE,BE),V(XSV,0))} 33 | 34 | .ENDS MEM_JOGLEKAR 35 | -------------------------------------------------------------------------------- /Joglekar/Ltspice2/memristor_joglekar2_sim_IV.plt: -------------------------------------------------------------------------------- 1 | [Transient Analysis] 2 | { 3 | Npanes: 2 4 | Active Pane: 1 5 | { 6 | traces: 1 {336592898,0,"Ix(U1:TE)"} 7 | Parametric: "V(n001)" 8 | X: (' ',2,-1.2,0.02,1.2) 9 | Y[0]: ('m',1,-0.001,0.0002,0.0012) 10 | Y[1]: ('_',0,1e+308,0,-1e+308) 11 | Amps: ('m',0,0,1,-0.001,0.0002,0.0012) 12 | Log: 0 0 0 13 | NeyeDiagPeriods: 0 14 | TeyeEnd: 3 15 | }, 16 | { 17 | traces: 1 {268959747,0,"V(nc_01)"} 18 | Parametric: "V(n001)" 19 | X: (' ',2,-1.2,0.02,1.2) 20 | Y[0]: (' ',2,0.21,0.07,1.05) 21 | Y[1]: ('_',0,1e+308,0,-1e+308) 22 | Volts: (' ',0,0,2,0.21,0.07,1.05) 23 | Log: 0 0 0 24 | NeyeDiagPeriods: 0 25 | TeyeEnd: 3 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Joglekar/Ltspice2/memristor_joglekar2_sim_T.plt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Joglekar/Ltspice2/memristor_joglekar2_sim_T.plt -------------------------------------------------------------------------------- /Joglekar/Ltspice2/memristor_with_state.asy: -------------------------------------------------------------------------------- 1 | Version 4 2 | SymbolType CELL 3 | LINE Normal 4 33 -4 33 4 | LINE Normal 0 -48 0 -32 5 | LINE Normal 0 48 0 33 6 | LINE Normal 32 0 0 0 7 | CIRCLE Normal 4 33 -4 0 8 | CIRCLE Normal 4 -32 -4 0 9 | SYMATTR Prefix X 10 | SYMATTR Description Parameterized Memristor 11 | PIN 0 -48 RIGHT 8 12 | PINATTR PinName TE 13 | PINATTR SpiceOrder 1 14 | PIN 0 48 RIGHT 8 15 | PINATTR PinName BE 16 | PINATTR SpiceOrder 2 17 | PIN 32 0 LEFT 8 18 | PINATTR PinName xsv 19 | PINATTR SpiceOrder 3 20 | -------------------------------------------------------------------------------- /Joglekar/Verilog-A/README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | 3 | | Model Class | Model Language | Simulator | 4 | |---|---|---| 5 | |Ill-formed|Verilog-A|Xyce| 6 | 7 | ## Instructions 8 | 9 | cd .../memristor-models-4-all/Joglekar_Linear_Resistance_Switch/Verilog-A 10 | buildxyceplugin -o memristor *.va /usr/local/lib 11 | Xyce -plugin /usr/local/lib/memristor.so memristor_sim.cir 12 | gnuplot 13 | plot '.../memristor-models-4-all/Joglekar_Linear_Resistance_Switch/Verilog-A/memristor_sim.cir.prn' using 3:4 with lines title "I-V" -------------------------------------------------------------------------------- /Joglekar/Verilog-A/memristor.va: -------------------------------------------------------------------------------- 1 | `include "disciplines.vams" 2 | `include "constants.vams" 3 | 4 | `define X_BORDER_BUMP 10e-18 5 | 6 | `define attr(txt) (*txt*) 7 | 8 | module memristor1 (p,n); 9 | 10 | inout p,n; 11 | electrical p,n; 12 | 13 | parameter real Roff=16000 from (0:inf) `attr(info="Roff" type="instance"); 14 | parameter real Ron=100 from (0:inf) `attr(info="Ron" type="instance"); 15 | parameter real Rinit=11000 from (0:inf) `attr(info="Rinit" type="instance"); 16 | parameter real D=10n from (0:inf) `attr(info="D" type="instance"); 17 | parameter real uv=10e-15 from (0:inf) `attr(info="uv" type="instance"); 18 | parameter real p_coeff=1.0 from (0:inf) `attr(info="p_coeff" type="instance"); 19 | 20 | // local variables that should persist over time steps 21 | real w_last; 22 | real time_last; 23 | 24 | // local variables that hold temporary values 25 | real G; 26 | real window_function; 27 | real w; 28 | real dw; 29 | real R; 30 | real direction; 31 | real current; 32 | real time; 33 | real time_delta; 34 | 35 | 36 | analog 37 | begin 38 | 39 | @(initial_instance) 40 | begin 41 | w_last = ((Roff - Rinit) / (Roff - Ron)) * D; 42 | time_last = 0; 43 | end 44 | 45 | // calculate conductance 46 | G = 1 / (Ron * w_last / D + Roff * (1 - w_last / D)); 47 | current = G * V(p,n); 48 | 49 | 50 | direction = 0; 51 | if (current > 0) begin 52 | if(w_last<=0) begin 53 | direction=1; 54 | end 55 | end 56 | else begin 57 | if(w_last>=D) begin 58 | direction=-1; 59 | end 60 | end 61 | 62 | time = $realtime; 63 | time_delta = time - time_last; 64 | window_function = (1.0 - (pow(2 * w_last / D - 1, 2 * p_coeff))); 65 | dw = uv * Ron / D * current * window_function * time_delta; 66 | w = w_last + dw + direction * `X_BORDER_BUMP; 67 | 68 | if(w >= D) begin 69 | w = D; 70 | end 71 | if(w <= 0) begin 72 | w = 0; 73 | end 74 | 75 | // calculate conductance 76 | G = 1 / (Ron * w / D + Roff * (1 - w / D)); 77 | 78 | // set the current 79 | I(p,n) <+ -1.0*G*V(p,n); 80 | 81 | // persist variables 82 | w_last = w; 83 | time_last = time; 84 | 85 | end 86 | endmodule 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /Joglekar/Verilog-A/memristor_sim.cir: -------------------------------------------------------------------------------- 1 | 2 | * Voltage Sources 3 | V1 1 0 SIN(0V 1.2V 1Hz) 4 | 5 | * Memristors 6 | YMEMRISTOR1 M1 1 0 7 | 8 | * Analysis Command 9 | .TRAN 1ms 1s 10 | * Output 11 | .PRINT TRAN V(1) I(V1) 12 | 13 | .END 14 | -------------------------------------------------------------------------------- /Joglekar/Verilog-A/memristor_sim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Joglekar/Verilog-A/memristor_sim.png -------------------------------------------------------------------------------- /Joglekar/Xyce/N_DEV_MemristorJoglekar.C: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright Notice 3 | // 4 | // Additions/Modifications Copyright 2017 Tim Molter 5 | // 6 | // Copyright 2002 Sandia Corporation. Under the terms 7 | // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. 8 | // Government retains certain rights in this software. 9 | // 10 | // Xyce(TM) Parallel Electrical Simulator 11 | // Copyright (C) 2002-2016 Sandia Corporation 12 | // 13 | // This program is free software: you can redistribute it and/or modify 14 | // it under the terms of the GNU General Public License as published by 15 | // the Free Software Foundation, either version 3 of the License, or 16 | // (at your option) any later version. 17 | // 18 | // This program is distributed in the hope that it will be useful, 19 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | // GNU General Public License for more details. 22 | // 23 | // You should have received a copy of the GNU General Public License 24 | // along with this program. If not, see . 25 | // ---------------------------------------------------------------------------- 26 | 27 | //---------------------------------------------------------------------------- 28 | // 29 | // Purpose : Implementation of the Joglekar memristor model. 30 | // 31 | // Creator : Tim Molter, Knowm Inc. 32 | // 33 | // Creation Date : 01/11/17 34 | // 35 | //---------------------------------------------------------------------------- 36 | #include 37 | 38 | #include 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | namespace Xyce { 49 | namespace Device { 50 | namespace MemristorJoglekar { 51 | 52 | 53 | template 54 | ScalarT JogelkarWindowFunction( const ScalarT & X, double P ) 55 | { 56 | ScalarT fval = 1.0 - pow( (2.0*X - 1.0), (2*P) ); 57 | // if (DEBUG_DEVICE){ 58 | // Xyce::dout() << " P = " << P << std::endl; 59 | // Xyce::dout() << " X = " << X << std::endl; 60 | // } 61 | return fval; 62 | } 63 | 64 | 65 | // linear current voltage model, Reff 66 | template 67 | ScalarT Reff( const ScalarT & X, double RON, double ROFF ) 68 | { 69 | return RON * X + ROFF * (1 - X); 70 | } 71 | 72 | 73 | template 74 | ScalarT X_var_F( const ScalarT & V1, const ScalarT & V2, const ScalarT & X, double UV, double RON, double ROFF, double D, double P) 75 | { 76 | 77 | ScalarT Rval = Reff( X, RON, ROFF ); 78 | 79 | ScalarT Windowval = JogelkarWindowFunction(X, P ); 80 | 81 | return UV*RON/D/D/Rval*(V1-V2)*Windowval; 82 | } 83 | 84 | 85 | template 86 | ScalarT I_V( const ScalarT & V1, const ScalarT & V2, const ScalarT & X, double RON, double ROFF ){ 87 | 88 | ScalarT Rval= Reff( X, RON, ROFF ); 89 | 90 | return (V1-V2)/Rval; 91 | 92 | // if (DEBUG_DEVICE){ 93 | // Xyce::dout() << " REFF = " << ( RON * X + ROFF * (1 - X)) << std::endl; 94 | // Xyce::dout() << " REFF2 = " << (1 - X) << std::endl; 95 | // Xyce::dout() << " RON = " << RON << std::endl; 96 | // Xyce::dout() << " ROFF = " << ROFF << std::endl; 97 | // } 98 | } 99 | 100 | 101 | // 102 | // Common Jacobian Stamp for all MemristorJoglekar devices. 103 | // Because all memristors have identical Jacobian stamps, this data is 104 | // declared static and is shared by all memristor instances. 105 | // 106 | std::vector > Instance::jacStamp; 107 | 108 | //----------------------------------------------------------------------------- 109 | // Function : Xyce::Device::MemristorJoglekar::Instance::initializeJacobianStamp 110 | // Purpose : 111 | // Special Notes : 112 | // Scope : private 113 | // Creator : Richard Schiek, Electrical Models & Simulations 114 | // Creation Date : 2/11/2014 115 | //----------------------------------------------------------------------------- 116 | // 117 | // @brief Common Jacobian stamp initializer for all MemristorJoglekar devices. 118 | // 119 | // The Jacobian stamp is a sparse-matrix representation of the pattern 120 | // of non-zero elements that a device will put into the Jacobian matrix. 121 | // 122 | // The Jacobian stamp is used by the Topology package to determine indices 123 | // into the full Jacobian matrix for elements that correspond to this 124 | // device. 125 | // 126 | // There is one row of the Jacobian stamp for each equation associated with 127 | // a device. The number of elements in a row are the number of non-zero 128 | // elements in that row of the device's contribution to the Jacobian. 129 | // The values of the elements are numbers local to the device that 130 | // represent the column in which the non-zero element appears. 131 | // 132 | // For this memristor, there are two external nodes (the positive and negative 133 | // terminals of the device). The positive node is referred to as the 0th 134 | // node of the device, and the negative node the 1st node. 135 | // 136 | void Instance::initializeJacobianStamp() 137 | { 138 | if (jacStamp.empty()) 139 | { 140 | jacStamp.resize(3); 141 | jacStamp[0].resize(3); 142 | jacStamp[0][0] = 0; 143 | jacStamp[0][1] = 1; 144 | jacStamp[0][2] = 2; 145 | jacStamp[1].resize(3); 146 | jacStamp[1][0] = 0; 147 | jacStamp[1][1] = 1; 148 | jacStamp[1][2] = 2; 149 | jacStamp[2].resize(3); 150 | jacStamp[2][0] = 0; 151 | jacStamp[2][1] = 1; 152 | jacStamp[2][2] = 2; 153 | } 154 | } 155 | 156 | //----------------------------------------------------------------------------- 157 | // Function : Xyce::Device::MemristorJoglekar::Traits::loadInstanceParameters 158 | // Purpose : 159 | // Special Notes : 160 | // Scope : private 161 | // Creator : Richard Schiek, Electrical Models & Simulations 162 | // Creation Date : 10/23/2014 163 | //----------------------------------------------------------------------------- 164 | // 165 | // Loads the parameter definition into the instance parameter map. 166 | // 167 | // @param p instance parameter map 168 | // 169 | // Each parameter supported by the memristor device instance is 170 | // defined via the addPar call. The minimum information required is 171 | // the name of the parameter, the default value, and a member pointer 172 | // to a variable in the instance class to which the value will be 173 | // assigned. 174 | // 175 | // Additional information such as documentation for the parameter, units 176 | // (used only in output of tables for documentation), whether a special 177 | // boolean should be set if the parameter is given, etc. may be specified 178 | // using the various set* calls of the Xyce::Device::Descriptor class. 179 | // 180 | // It is important to note that since parameters defined by addPar are 181 | // defined as metadata separate from any instance, it is not possible to 182 | // establish interrelationships between parameter defaults here. Parameter 183 | // defaults specified in addPar are always constants. If a device requires 184 | // that parameter defaults depend on values of other parameters, this has to 185 | // be done in the instance constructor. Examples of such parameters in this 186 | // device are the "DTEMP" and "W" parameters, which are set to special defaults 187 | // at device instantiation time. Defaults for those parameters in the addPar 188 | // calls (and hence in the LaTeX tables in the reference guide produced from 189 | // this data) are misleading. 190 | // 191 | void Traits::loadInstanceParameters(ParametricData &p) 192 | { 193 | p.addPar("R_init", 0.0, &MemristorJoglekar::Instance::R_init_) 194 | .setUnit(U_OHM) 195 | .setDescription("Initial value for resistance"); 196 | 197 | } 198 | 199 | //----------------------------------------------------------------------------- 200 | // Function : Xyce::Device::MemristorJoglekar::Traits::loadModelParameters 201 | // Purpose : 202 | // Special Notes : The addPar calls here were refactored and moved here 203 | // from the model constructor. Those addPars had been 204 | // in place from 2/4/2005. 205 | // Scope : private 206 | // Creator : Richard Schiek, Electrical Models & Simulations 207 | // Creation Date : 10/23/2014 208 | //----------------------------------------------------------------------------- 209 | // 210 | // Loads the parameter definition into the model parameter map. 211 | // 212 | // @param p model parameter map 213 | // 214 | // @see Xyce::Device::MemristorJoglekar::Traits::loadInstanceParameters 215 | // 216 | // 217 | void Traits::loadModelParameters(ParametricData &p) 218 | { 219 | 220 | // Create parameter definitions for parameter member variables 221 | 222 | // NOTE: The first string arg need to be ALL CAPS! 223 | 224 | p.addPar("ROFF", 16000.0, &MemristorJoglekar::Model::Roff_) 225 | .setUnit(U_OHM) 226 | .setDescription("Off resistance."); 227 | p.addPar("RON", 100.0, &MemristorJoglekar::Model::Ron_) 228 | .setUnit(U_OHM) 229 | .setDescription("On resistance"); 230 | p.addPar("D", 10.0e-9, &MemristorJoglekar::Model::D_) 231 | .setUnit(U_METER) 232 | .setDescription("Width of the thin film"); 233 | p.addPar("UV", 10.0e-15, &MemristorJoglekar::Model::uv_) 234 | .setUnit(U_NONE) 235 | .setDescription("Migration coefficient"); 236 | p.addPar("P", 1.0, &MemristorJoglekar::Model::p_) 237 | .setUnit(U_NONE) 238 | .setDescription("Parameter of the WINDOW-function for modeling nonlinear boundary conditions"); 239 | 240 | } 241 | 242 | //----------------------------------------------------------------------------- 243 | // Function : Xyce::Device::MemristorJoglekar::Instance::Instance 244 | // Purpose : Instance constructor 245 | // Special Notes : 246 | // Scope : public 247 | // Creator : Richard Schiek, Electrical Models & Simulations 248 | // Creation Date : 10/23/2014 249 | //----------------------------------------------------------------------------- 250 | // 251 | // Construct a memristor instance. 252 | // 253 | Instance::Instance( 254 | const Configuration & configuration, 255 | const InstanceBlock & instance_block, 256 | Model & model, 257 | const FactoryBlock & factory_block) 258 | : DeviceInstance(instance_block, configuration.getInstanceParameters(), factory_block), 259 | model_(model), 260 | R_init_(0.0), 261 | G(0.0), 262 | i0(0.0), 263 | li_Pos(-1), 264 | li_Neg(-1), 265 | li_x(-1), 266 | li_store_tdt(-1), 267 | li_branch_data(0), 268 | 269 | 270 | APosEquPosNodeOffset(-1), 271 | APosEquNegNodeOffset(-1), 272 | APosEquXNodeOffset(-1), 273 | ANegEquPosNodeOffset(-1), 274 | ANegEquNegNodeOffset(-1), 275 | ANegEquXNodeOffset(-1), 276 | XEquVPosOffset(-1), 277 | XEquVNegOffset(-1), 278 | XEquXOffset(-1) 279 | 280 | #ifndef Xyce_NONPOINTER_MATRIX_LOAD 281 | , 282 | f_PosEquPosNodePtr(0), 283 | f_PosEquNegNodePtr(0), 284 | f_PosEquXNodePtr(0), 285 | f_NegEquPosNodePtr(0), 286 | f_NegEquNegNodePtr(0), 287 | f_NegEquXNodePtr(0), 288 | f_XEquPosNodePtr(0), 289 | f_XEquNegNodePtr(0), 290 | f_XEquXNodePtr(0), 291 | q_XEquXNodePtr(0) 292 | #endif 293 | 294 | { 295 | // Initialize DeviceInstance values 296 | numIntVars = 1; // Initialize number if internal nodes in DeviceInstance 297 | numExtVars = 2; // Initialize number if external nodes in DeviceInstance 298 | numStateVars = 0; // Initialize number if state variables in DeviceInstance 299 | setNumStoreVars(2); // Initialize number if store variables in DeviceInstance 300 | 301 | setNumBranchDataVars(0); // by default don't allocate space in branch vectors 302 | numBranchDataVarsIfAllocated = 1; // this is the space to allocate if lead current or power is needed. 303 | 304 | initializeJacobianStamp(); 305 | 306 | // Set params to constant default values from parameter definition 307 | setDefaultParams(); 308 | 309 | // Set params according to instance line and constant defaults from metadata 310 | setParams(instance_block.params); 311 | 312 | // Calculate any parameters specified as expressions 313 | updateDependentParameters(); 314 | 315 | // Process the parameters to complete initialization 316 | processParams(); 317 | 318 | } 319 | 320 | //----------------------------------------------------------------------------- 321 | // Function : Xyce::Device::MemristorJoglekar::Instance::processParams 322 | // Purpose : 323 | // Special Notes : 324 | // Scope : public 325 | // Creator : Richard Schiek, Electrical Models & Simulations 326 | // Creation Date : 10/23/2014 327 | //----------------------------------------------------------------------------- 328 | // Process parameters. 329 | // 330 | // @return true on success 331 | // 332 | // In general, the processParams method is intended as a place for complex 333 | // manipulation of parameters that must happen if temperature or other 334 | // external changes happen. 335 | // 336 | bool Instance::processParams() 337 | { 338 | 339 | // initialize X state (width between 0 and 1 and scaled to D) 340 | if (!given("R_init")){ 341 | R_init_ = model_.Roff_; 342 | } 343 | 344 | if (DEBUG_DEVICE){ 345 | Xyce::dout() << "----------Instance::processParams" << std::endl; 346 | Xyce::dout() << " R_init_ = " << R_init_ << std::endl; 347 | } 348 | 349 | return true; 350 | } 351 | 352 | //----------------------------------------------------------------------------- 353 | // Function : Xyce::Device::MemristorJoglekar::Instance::registerLIDs 354 | // Purpose : 355 | // Special Notes : 356 | // Scope : public 357 | // Creator : Richard Schiek, Electrical Models & Simulations 358 | // Creation Date : 10/23/2014 359 | //----------------------------------------------------------------------------- 360 | // 361 | // Register local IDs 362 | // 363 | // Register the local internal and external node IDs. 364 | // 365 | // @param intLIDVecRef internal local IDs from topology package 366 | // @param extLIDVecRef external local IDs from topology package 367 | // 368 | void Instance::registerLIDs( 369 | const std::vector & intLIDVecRef, 370 | const std::vector & extLIDVecRef) 371 | { 372 | AssertLIDs(intLIDVecRef.size() == numIntVars); 373 | AssertLIDs(extLIDVecRef.size() == numExtVars); 374 | 375 | // Copy the local ID lists. 376 | intLIDVec = intLIDVecRef; // Set the internal local IDs in DeviceInstance 377 | extLIDVec = extLIDVecRef; // Set the external local IDs in DeviceInstance 378 | 379 | li_Pos = extLIDVec[0]; 380 | li_Neg = extLIDVec[1]; 381 | 382 | // This lid is for the internal variable for layer thickness that determines resistance 383 | li_x = intLIDVec[0]; 384 | } 385 | 386 | //----------------------------------------------------------------------------- 387 | // Function : Xyce::Device::MemristorJoglekar::Instance::registerStateLIDs 388 | // Purpose : 389 | // Special Notes : 390 | // Scope : public 391 | // Creator : Richard Schiek, Electrical Models & Simulations 392 | // Creation Date : 10/23/2014 393 | //----------------------------------------------------------------------------- 394 | // 395 | // Register the local state IDs 396 | // 397 | // @note The memristor does not have any state vars, so this function 398 | // does nothing. 399 | // 400 | // @param staLIDVecRef State variable local IDs 401 | // 402 | // In general, devices may declare at construction that they require storage 403 | // locations in the "state vector." Topology assigns locations in the 404 | // state vector and returns "Local IDs" (LIDs) for devices to use for their 405 | // state vector entries. If a device uses state vector entries, it 406 | // uses the registerStateLIDs method to save the local IDs for later use. 407 | // 408 | // @author Robert Hoekstra, SNL, Parallel Computational Sciences 409 | // @date 06/12/02 410 | // 411 | void Instance::registerStateLIDs(const std::vector & staLIDVecRef) 412 | { 413 | AssertLIDs(staLIDVecRef.size() == numStateVars); 414 | } 415 | 416 | //----------------------------------------------------------------------------- 417 | // Function : Xyce::Device::MemristorJoglekar::Instance::registerStoreLIDs 418 | // Purpose : 419 | // Special Notes : 420 | // Scope : public 421 | // Creator : Richard Schiek, Electrical Models & Simulations 422 | // Creation Date : 12/18/2012 423 | //----------------------------------------------------------------------------- 424 | // Register the local store IDs 425 | // 426 | // In addition to state vector, Xyce maintains a separate datastructure 427 | // called a "store" vector. As with other such vectors, the device 428 | // declares at construction time how many store vector entries it needs, 429 | // and later Topology assigns locations for devices, returning LIDs. 430 | // 431 | // 432 | // 433 | void Instance::registerStoreLIDs(const std::vector & stoLIDVecRef) 434 | { 435 | AssertLIDs(stoLIDVecRef.size() == getNumStoreVars()); 436 | li_store_R = stoLIDVecRef[0]; 437 | li_store_tdt = stoLIDVecRef[1]; 438 | } 439 | 440 | //----------------------------------------------------------------------------- 441 | // Function : Xyce::Device::MemristorJoglekar::Instance::registerBranchDataLIDs 442 | // Purpose : 443 | // Special Notes : 444 | // Scope : public 445 | // Creator : Richard Schiek, Electrical Systems Modeling 446 | // Creation Date : 12/18/2012 447 | //----------------------------------------------------------------------------- 448 | // Register the local store IDs 449 | // 450 | // In addition to state vector, Xyce maintains a separate datastructure 451 | // called a "branch data" vector. As with other such vectors, the device 452 | // declares at construction time how many branch vector entries it needs, 453 | // and later Topology assigns locations for devices, returning LIDs. 454 | // 455 | // These LIDs are stored in this method for later use. 456 | // 457 | // The memristor device uses exactly one "branch data vector" element, where 458 | // it keeps the "lead current" that may be used on .PRINT lines as 459 | // "I(ymemristor)" for the current through ymemristor. and a junction voltage. 460 | // 461 | // @param stoLIDVecRef Store variable local IDs 462 | // 463 | // @author Richard Schiek, Electrical Systems Modeling 464 | // @date 12/18/2012 465 | void Instance::registerBranchDataLIDs(const std::vector & branchLIDVecRef) 466 | { 467 | AssertLIDs(branchLIDVecRef.size() == getNumBranchDataVars()); 468 | 469 | if (loadLeadCurrent) 470 | { 471 | li_branch_data= branchLIDVecRef[0]; 472 | } 473 | } 474 | 475 | //----------------------------------------------------------------------------- 476 | // Function : Instance::loadNodeSymbols 477 | // Purpose : 478 | // Special Notes : 479 | // Scope : public 480 | // Creator : Richard Schiek, Electrical Sysetms Modeling 481 | // Creation Date : 05/13/05 482 | //----------------------------------------------------------------------------- 483 | void Instance::loadNodeSymbols(Util::SymbolTable &symbol_table) const 484 | { 485 | addInternalNode(symbol_table, li_x, getName(), "x"); 486 | 487 | addStoreNode(symbol_table, li_store_R, getName(), "R"); 488 | addStoreNode(symbol_table, li_store_tdt, getName(), "TDT"); 489 | 490 | if (loadLeadCurrent) 491 | { 492 | addBranchDataNode( symbol_table, li_branch_data, getName(), "BRANCH_D"); 493 | } 494 | } 495 | 496 | //----------------------------------------------------------------------------- 497 | // Function : Xyce::Device::MemristorJoglekar::Instance::registerJacLIDs 498 | // Purpose : 499 | // Special Notes : 500 | // Scope : public 501 | // Creator : Richard Schiek, Electrical Models & Simulations 502 | // Creation Date : 10/23/2014 503 | //----------------------------------------------------------------------------- 504 | // 505 | // Register the Jacobian local IDs 506 | // 507 | // @param jacLIDVec Jacobian local Ids 508 | // 509 | // @see Xyce::Device::MemristorJoglekar::Instance::initializeJacobianStamp 510 | // 511 | // Having established local IDs for the solution variables, Topology must 512 | // also assign local IDs for the elements of the Jacobian matrix. 513 | // 514 | // For each non-zero element that was identified in the jacobianStamp, 515 | // Topology will assign a Jacobian LID. The jacLIDVec will have the 516 | // same structure as the JacStamp, but the values in the jacLIDVec will 517 | // be offsets into the row of the sparse Jacobian matrix corresponding 518 | // to the non-zero identified in the stamp. 519 | // 520 | // These offsets are stored in this method for use later when we load 521 | // the Jacobian. 522 | // 523 | // @author Robert Hoekstra, SNL, Parallel Computational Sciences 524 | // @date 08/27/01 525 | void Instance::registerJacLIDs(const std::vector< std::vector > & jacLIDVec) 526 | { 527 | // Let DeviceInstance do its work. 528 | DeviceInstance::registerJacLIDs(jacLIDVec); 529 | 530 | // Store offsets of the components of the Jacobian of this instance 531 | APosEquPosNodeOffset = jacLIDVec[0][0]; 532 | APosEquNegNodeOffset = jacLIDVec[0][1]; 533 | APosEquXNodeOffset = jacLIDVec[0][2]; 534 | ANegEquPosNodeOffset = jacLIDVec[1][0]; 535 | ANegEquNegNodeOffset = jacLIDVec[1][1]; 536 | ANegEquXNodeOffset = jacLIDVec[1][2]; 537 | XEquVPosOffset = jacLIDVec[2][0]; 538 | XEquVNegOffset = jacLIDVec[2][1]; 539 | XEquXOffset = jacLIDVec[2][2]; 540 | } 541 | 542 | //----------------------------------------------------------------------------- 543 | // Function : Xyce::Device::MemristorJoglekar::Instance::setupPointers 544 | // Purpose : 545 | // Special Notes : 546 | // Scope : public 547 | // Creator : Richard Schiek, Electrical Models & Simulations 548 | // Creation Date : 10/23/2014 549 | //----------------------------------------------------------------------------- 550 | // 551 | // Setup direct access pointer to solution matrix and vectors. 552 | // 553 | // @see Xyce::Device::MemristorJoglekar::Instance::registerJacLIDs 554 | // 555 | // As an alternative to the row offsets defined in registerJacLIDs, it 556 | // is also possible to obtain direct pointers of the Jacobian elements. 557 | // 558 | // This method uses the offsets obtained in registerJacLIDs to retrieve 559 | // the pointers. 560 | // 561 | // In this device the pointers to the matrix are only saved 562 | // (and are only used for matrix access) if 563 | // Xyce_NONPOINTER_MATRIX_LOAD is NOT defined at compile time. For 564 | // some devices the use of pointers instead of array indexing can be 565 | // a performance enhancement. 566 | // 567 | // Use of pointers in this device is disabled by defining 568 | // Xyce_NONPOINTER_MATRIX_LOAD at compile time. When disabled, array 569 | // indexing with the offsets from registerJacLIDs is used in 570 | // the matrix load methods. 571 | // 572 | // @author Eric Keiter, SNL 573 | // @date 11/30/08 574 | void Instance::setupPointers() 575 | { 576 | #ifndef Xyce_NONPOINTER_MATRIX_LOAD 577 | Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr); 578 | Linear::Matrix & dQdx = *(extData.dQdxMatrixPtr); 579 | f_PosEquPosNodePtr = &(dFdx[li_Pos][APosEquPosNodeOffset]); 580 | f_PosEquNegNodePtr = &(dFdx[li_Pos][APosEquNegNodeOffset]); 581 | f_PosEquXNodePtr = &(dFdx[li_Pos][APosEquXNodeOffset]); 582 | f_NegEquPosNodePtr = &(dFdx[li_Neg][ANegEquPosNodeOffset]); 583 | f_NegEquNegNodePtr = &(dFdx[li_Neg][ANegEquNegNodeOffset]); 584 | f_NegEquXNodePtr = &(dFdx[li_Neg][ANegEquXNodeOffset]); 585 | f_XEquPosNodePtr = &(dFdx[li_x][XEquVPosOffset]); 586 | f_XEquNegNodePtr = &(dFdx[li_x][XEquVNegOffset]); 587 | f_XEquXNodePtr = &(dFdx[li_x][XEquXOffset]); 588 | q_XEquXNodePtr = &(dQdx[li_x][XEquXOffset]); 589 | #endif 590 | } 591 | 592 | // The following 6 methods can just simply return true because the methods in the Master implementation cover this functionality. 593 | 594 | bool Instance::loadDAEQVector() 595 | { 596 | return true; 597 | } 598 | 599 | bool Instance::loadDAEFVector() 600 | { 601 | return true; 602 | } 603 | 604 | bool Instance::loadDAEdQdx() 605 | { 606 | return true; 607 | } 608 | 609 | bool Instance::loadDAEdFdx() 610 | { 611 | return true; 612 | } 613 | 614 | bool Instance::updatePrimaryState() 615 | { 616 | return true; 617 | } 618 | 619 | bool Instance::updateIntermediateVars() 620 | { 621 | return true; 622 | } 623 | 624 | //----------------------------------------------------------------------------- 625 | // Function : Xyce::Device::MemristorJoglekar::Instance::updateTemperature 626 | // Purpose : 627 | // Special Notes : 628 | // Scope : public 629 | // Creator : Richard Schiek, Electrical Models & Simulations 630 | // Creation Date : 10/23/2014 631 | //----------------------------------------------------------------------------- 632 | // 633 | // Update the parameters that depend on the temperature of the device 634 | // 635 | // @param temp_tmp temperature 636 | // 637 | // Xyce has a number of mechanisms that allow temperature to be changed 638 | // after a device has been instantiated. These include .STEP loops over 639 | // temperature. When temperature is changed, any device that has parameters 640 | // that depend on temperature must be updated. That updating happens here. 641 | // 642 | // The MemristorJoglekar device supports temperature-dependent resistance through its 643 | // TC1 (linear dependence) and TC2 (quadratic dependence) parameters. 644 | // If these parameters are specified, the resistance must be updated. 645 | // 646 | // @return true on success 647 | // 648 | // @author Tom Russo, Component Information and Models 649 | // @date 02/27/01 650 | bool Instance::updateTemperature(const double & temp_tmp) 651 | { 652 | return true; 653 | } 654 | 655 | //----------------------------------------------------------------------------- 656 | // Function : Xyce::Device::MemristorJoglekar::Model::processParams 657 | // Purpose : 658 | // Special Notes : 659 | // Scope : public 660 | // Creator : Richard Schiek, Electrical Models & Simulations 661 | // Creation Date : 10/23/2014 662 | //----------------------------------------------------------------------------- 663 | // 664 | // Process model parameters 665 | // 666 | // @return true on success 667 | // 668 | // @author Eric Keiter, SNL, Parallel Computational Sciences 669 | // @date 6/03/02 670 | bool Model::processParams() 671 | { 672 | return true; 673 | } 674 | 675 | //---------------------------------------------------------------------------- 676 | // Function : Xyce::Device::MemristorJoglekar::Model::processInstanceParams 677 | // Purpose : 678 | // Special Notes : 679 | // Scope : public 680 | // Creator : Richard Schiek, Electrical Models & Simulations 681 | // Creation Date : 10/23/2014 682 | //---------------------------------------------------------------------------- 683 | // 684 | // Process the instance parameters of instance owned by this model 685 | // 686 | // This method simply loops over all instances associated with this 687 | // model and calls their processParams method. 688 | // 689 | // @return true 690 | // 691 | // @author Dave Shirely, PSSI 692 | // @date 03/23/06 693 | bool Model::processInstanceParams() 694 | { 695 | for (InstanceVector::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it) 696 | { 697 | (*it)->processParams(); 698 | } 699 | 700 | return true; 701 | } 702 | 703 | //----------------------------------------------------------------------------- 704 | // Function : Xyce::Device::MemristorJoglekar::Model 705 | // Purpose : model block constructor 706 | // Special Notes : 707 | // Scope : public 708 | // Creator : Richard Schiek, Electrical Models & Simulations 709 | // Creation Date : 10/23/2014 710 | //----------------------------------------------------------------------------- 711 | // 712 | // Construct a memristor model from a "model block" that was created 713 | // by the netlist parser. 714 | // 715 | // @param configuration 716 | // @param model_block 717 | // @param factory_block 718 | // 719 | // @author Eric Keiter, SNL, Parallel Computational Sciences 720 | // @date 5/16/00 721 | Model::Model( 722 | const Configuration & configuration, 723 | const ModelBlock & model_block, 724 | const FactoryBlock & factory_block) 725 | : DeviceModel(model_block, configuration.getModelParameters(), factory_block), 726 | Roff_(0.0), 727 | Ron_(0.0), 728 | D_(0.0), 729 | uv_(0.0), 730 | p_(0.0) 731 | { 732 | // Set params to constant default values. 733 | setDefaultParams(); 734 | 735 | // Set params according to .model line and constant defaults from metadata. 736 | setModParams(model_block.params); 737 | 738 | // Set any non-constant parameter defaults. 739 | //if (!given("TNOM")) 740 | // tnom = getDeviceOptions().tnom; 741 | 742 | // Calculate any parameters specified as expressions. 743 | updateDependentParameters(); 744 | 745 | // calculate dependent (ie computed) params and check for errors. 746 | processParams(); 747 | 748 | } 749 | 750 | //----------------------------------------------------------------------------- 751 | // Function : Xyce::Device::MemristorJoglekar::Model::~Model 752 | // Purpose : destructor 753 | // Special Notes : 754 | // Scope : public 755 | // Creator : Richard Schiek, Electrical Models & Simulations 756 | // Creation Date : 10/23/2014 757 | //----------------------------------------------------------------------------- 758 | // 759 | // Destroy this model. 760 | // 761 | // Also destroys all instances that use this model. 762 | // 763 | // @author Eric Keiter, SNL, Parallel Computational Sciences 764 | // @date 3/16/00 765 | Model::~Model() 766 | { 767 | // Destory all owned instances 768 | for (InstanceVector::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it) 769 | { 770 | delete (*it); 771 | } 772 | } 773 | 774 | //----------------------------------------------------------------------------- 775 | // Function : N_DEV_MemristorJoglekarModel::printOutInstances 776 | // Purpose : debugging tool. 777 | // Special Notes : 778 | // Scope : public 779 | // Creator : Richard Schiek, Electrical Models & Simulations 780 | // Creation Date : 10/23/2014 781 | //----------------------------------------------------------------------------- 782 | // 783 | // Print instances associated with this model. 784 | // 785 | // printOutInstances was intended as a debugging tool, but a refactor some time back took out all the places where this function would be called. 786 | // 787 | // @param os output stream 788 | // 789 | // @return reference to output stream 790 | // 791 | // @author Eric Keiter, SNL, Parallel Computational Sciences 792 | // @date 4/03/00 793 | // 794 | std::ostream &Model::printOutInstances(std::ostream &os) const 795 | { 796 | os << std::endl; 797 | os << "Number of MemristorJoglekar Instances: " << instanceContainer.size() << std::endl; 798 | os << " name model name Parameters" << std::endl; 799 | 800 | int i = 0; 801 | for (InstanceVector::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it) 802 | { 803 | os << " " << i << ": " << (*it)->getName() << "\t"; 804 | os << getName(); 805 | os << "\tG(T) = " << (*it)->G; 806 | os << std::endl; 807 | ++i; 808 | } 809 | 810 | os << std::endl; 811 | 812 | return os; 813 | } 814 | 815 | //----------------------------------------------------------------------------- 816 | // Function : Model::forEachInstance 817 | // Purpose : 818 | // Special Notes : 819 | // Scope : public 820 | // Creator : Richard Schiek, Electrical Models & Simulations 821 | // Creation Date : 10/23/2014 822 | //----------------------------------------------------------------------------- 823 | // Apply a device instance "op" to all instances associated with this 824 | // model 825 | // 826 | // @param[in] op Operator to apply to all instances. 827 | // 828 | void Model::forEachInstance(DeviceInstanceOp &op) const /* override */ 829 | { 830 | for (std::vector::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it) 831 | op(*it); 832 | } 833 | 834 | //----------------------------------------------------------------------------- 835 | // Function : Xyce::Device::MemristorJoglekar::Master::updateState 836 | // Purpose : 837 | // Special Notes : 838 | // Scope : public 839 | // Creator : Richard Schiek, Electrical Models & Simulations 840 | // Creation Date : 10/23/2014 841 | //----------------------------------------------------------------------------- 842 | // 843 | // Update state for all memristor instances, regardless of model. 844 | // 845 | // @param solVec solution vector 846 | // @param staVec state vector 847 | // @param stoVec store vector 848 | // 849 | // @return true on success 850 | // 851 | // 852 | // @see Xyce::Device::MemristorJoglekar::Instance::updatePrimaryState 853 | // @author Eric Keiter, SNL 854 | // @date 11/26/08 855 | bool Master::updateState(double * solVec, double * staVec, double * stoVec) 856 | { 857 | 858 | // if (DEBUG_DEVICE){ 859 | // Xyce::dout() << " updateState " << std::endl; 860 | // } 861 | 862 | for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it) 863 | { 864 | Instance & ri = *(*it); 865 | 866 | double v_pos = solVec[ri.li_Pos]; 867 | double v_neg = solVec[ri.li_Neg]; 868 | double x = solVec[ri.li_x]; 869 | 870 | // handle boundary conditions - ugly hack 871 | if(x <= 0){ 872 | x = 0.001; 873 | }else if(x >= 1){ 874 | x = 1 - 0.001; 875 | } 876 | 877 | if (DEBUG_DEVICE){ 878 | Xyce::dout() << " x = " << x << std::endl; 879 | } 880 | 881 | { 882 | Sacado::Fad::SFad varV1( 3, 0, v_pos ); 883 | Sacado::Fad::SFad varV2( 3, 1, v_neg ); 884 | Sacado::Fad::SFad varX( 3, 2, x ); 885 | Sacado::Fad::SFad resultFad; 886 | resultFad = I_V( varV1, varV2, varX, ri.model_.Ron_, ri.model_.Roff_); 887 | 888 | ri.i0 = resultFad.val(); // current 889 | ri.G = resultFad.dx(0); // di/dv = conductance 890 | ri.dIdx = resultFad.dx(2); // di/dx 891 | 892 | // if (DEBUG_DEVICE){ 893 | // Xyce::dout() << " ri.i0 = " << ri.i0 << std::endl; 894 | // Xyce::dout() << " ri.G = " << ri.G << std::endl; 895 | // Xyce::dout() << " ri.dIdx = " << ri.dIdx << std::endl; 896 | // } 897 | } 898 | 899 | { 900 | // evaluate the state variable equation 901 | Sacado::Fad::SFad varV1( 3, 0, v_pos ); 902 | Sacado::Fad::SFad varV2( 3, 1, v_neg ); 903 | Sacado::Fad::SFad varX( 3, 2, x ); 904 | Sacado::Fad::SFad resultFad; 905 | 906 | resultFad = X_var_F( varV1, varV2, varX, ri.model_.uv_, ri.model_.Ron_, ri.model_.Roff_, ri.model_.D_, ri.model_.p_ ); 907 | 908 | ri.xVarFContribution = resultFad.val(); 909 | ri.dxFEqdVpos = resultFad.dx(0); 910 | ri.dxFEqdVneg = resultFad.dx(1); 911 | ri.dxFEqdx = resultFad.dx(2); 912 | 913 | // if (DEBUG_DEVICE){ 914 | // Xyce::dout() << " ri.xVarFContribution = " << ri.xVarFContribution << std::endl; 915 | // Xyce::dout() << " ri.dxFEqdVpos = " << ri.dxFEqdVpos << std::endl; 916 | // Xyce::dout() << " ri.dxFEqdVneg = " << ri.dxFEqdVneg << std::endl; 917 | // Xyce::dout() << " ri.dxFEqdx = " << ri.dxFEqdx << std::endl; 918 | // } 919 | 920 | } 921 | 922 | } 923 | 924 | return true; 925 | } 926 | 927 | //----------------------------------------------------------------------------- 928 | // Function : Xyce::Device::MemristorJoglekar::Master::loadDAEVectors 929 | // Purpose : 930 | // Special Notes : 931 | // Scope : public 932 | // Creator : Richard Schiek, Electrical Models & Simulations 933 | // Creation Date : 10/23/2014 934 | //----------------------------------------------------------------------------- 935 | // 936 | // Load DAE vectors of all memristor instances, regardless of model 937 | // 938 | // @param solVec solution vector 939 | // @param fVec f vector 940 | // @param qVec q vector 941 | // @param leadF store lead current f vector 942 | // @param leadQ store lead current q vector 943 | // 944 | // @return true on success 945 | // 946 | // @see Xyce::Device::MemristorJoglekar::Instance::loadDAEFVector 947 | // 948 | // @author Eric Keiter, SNL 949 | // @date 11/26/08 950 | 951 | bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * bVec, double * leadF, double * leadQ, double * junctionV) 952 | { 953 | // if (DEBUG_DEVICE){ 954 | // Xyce::dout() << "-loadDAEVectors" << std::endl; 955 | // } 956 | 957 | for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it) 958 | { 959 | Instance & ri = *(*it); 960 | fVec[ri.li_Pos] += ri.i0; 961 | fVec[ri.li_Neg] += -ri.i0; 962 | fVec[ri.li_x] += ri.xVarFContribution; 963 | qVec[ri.li_x] -= solVec[ri.li_x]; 964 | if( getSolverState().dcopFlag ) 965 | { 966 | qVec[ri.li_x] -= ((ri.model_.Roff_ - ri.R_init_) / (ri.model_.Roff_ - ri.model_.Ron_)) ; 967 | // if (DEBUG_DEVICE){ 968 | // Xyce::dout() << " &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& dcopFlag = " << ((ri.model_.Roff_ - ri.R_init_) / (ri.model_.Roff_ - ri.model_.Ron_))<< std::endl; 969 | // } 970 | } 971 | if( ri.G != 0 ) 972 | { 973 | double * storeVec = ri.extData.nextStoVectorRawPtr; 974 | storeVec[ri.li_store_R] = 1.0/ri.G; 975 | } 976 | 977 | if( ri.loadLeadCurrent ) 978 | { 979 | leadF[ri.li_branch_data] = ri.i0; 980 | junctionV[ri.li_branch_data] = solVec[ri.li_Pos] - solVec[ri.li_Neg]; 981 | } 982 | 983 | } 984 | return true; 985 | } 986 | 987 | //----------------------------------------------------------------------------- 988 | // Function : Xyce::Device::MemristorJoglekar::Master::loadDAEMatrices 989 | // Purpose : 990 | // Special Notes : 991 | // Scope : public 992 | // Creator : Richard Schiek, Electrical Models & Simulations 993 | // Creation Date : 10/23/2014 994 | //----------------------------------------------------------------------------- 995 | // 996 | // Load DAE matrices for all memristor instances, regardless of model 997 | // 998 | // @param dFdx matrix of derivatives of F vector with respect to solution 999 | // @param dQdx matrix of derivatives of Q vector with respect to solution 1000 | // 1001 | // @return true on success 1002 | // 1003 | // 1004 | // @see Xyce::Device::MemristorJoglekar::Instance::loadDAEdFdx 1005 | // 1006 | // @author Eric Keiter, SNL 1007 | // @date 11/26/08 1008 | 1009 | bool Master::loadDAEMatrices(Linear::Matrix & dFdx, Linear::Matrix & dQdx) 1010 | { 1011 | 1012 | // if (DEBUG_DEVICE){ 1013 | // Xyce::dout() << "-loadDAEMatrices" << std::endl; 1014 | // } 1015 | 1016 | for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it) 1017 | { 1018 | Instance & ri = *(*it); 1019 | 1020 | #ifndef Xyce_NONPOINTER_MATRIX_LOAD 1021 | *(ri.f_PosEquPosNodePtr) += ri.G; 1022 | *(ri.f_PosEquNegNodePtr) -= ri.G; 1023 | *(ri.f_PosEquXNodePtr) += ri.dIdx; 1024 | *(ri.f_NegEquPosNodePtr) -= ri.G; 1025 | *(ri.f_NegEquNegNodePtr) += ri.G; 1026 | *(ri.f_NegEquXNodePtr ) += ri.dIdx; 1027 | *(ri.f_XEquPosNodePtr ) += ri.dxFEqdVpos; 1028 | *(ri.f_XEquNegNodePtr ) += ri.dxFEqdVneg; 1029 | *(ri.f_XEquXNodePtr ) += ri.dxFEqdx; 1030 | *(ri.q_XEquXNodePtr ) = -1.0; 1031 | #else 1032 | dFdx[ri.li_Pos][ri.APosEquPosNodeOffset] += ri.G; 1033 | dFdx[ri.li_Pos][ri.APosEquNegNodeOffset] -= ri.G; 1034 | dFdx[ri.li_Pos][ri.APosEquXNodeOffset] += ri.dIdx; 1035 | dFdx[ri.li_Neg][ri.ANegEquPosNodeOffset] -= ri.G; 1036 | dFdx[ri.li_Neg][ri.ANegEquNegNodeOffset] += ri.G; 1037 | dFdx[ri.li_Neg][ri.ANegEquXNodeOffset] += ri.dIdx; 1038 | dFdx[ri.li_x][ri.XEquVPosOffset] += ri.dxFEqdVpos; 1039 | dFdx[ri.li_x][ri.XEquVNegOffset] += ri.dxFEqdVneg; 1040 | dFdx[ri.li_x][ri.XEquXOffset] += ri.dxFEqdx; 1041 | dQdx[ri.li_x][ri.XEquXOffset] = -1.0; 1042 | #endif 1043 | } 1044 | 1045 | return true; 1046 | } 1047 | 1048 | //----------------------------------------------------------------------------- 1049 | // Function : Xyce::Device::MemristorJoglekar::Traits::factory 1050 | // Purpose : 1051 | // Special Notes : 1052 | // Scope : public 1053 | // Creator : Richard Schiek, Electrical Models & Simulations 1054 | // Creation Date : 10/23/2014 1055 | //----------------------------------------------------------------------------- 1056 | // 1057 | // Create a new instance of the MemristorJoglekar device. 1058 | // 1059 | // @param configuration 1060 | // @param factory_block 1061 | // 1062 | Device * Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block) 1063 | { 1064 | return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_); 1065 | } 1066 | 1067 | //----------------------------------------------------------------------------- 1068 | // Function : Xyce::Device::MemristorJoglekar::registerDevice 1069 | // Purpose : 1070 | // Special Notes : 1071 | // Scope : public 1072 | // Creator : Richard Schiek, Electrical Models & Simulations 1073 | // Creation Date : 10/23/2014 1074 | //----------------------------------------------------------------------------- 1075 | // 1076 | // Define how to use the device in a netlist. 1077 | // 1078 | // This method is called from the Xyce::Device::registerOpenDevices 1079 | // function, which in turn is called by the device manager. 1080 | // 1081 | // The device is declared here to be an "joglekar" device, which must 1082 | // take a model card of type "joglekar". This device will correspond to model 1083 | // level 1 of memristor models. 1084 | void 1085 | registerDevice() 1086 | { 1087 | Config::addConfiguration() 1088 | .registerDevice("memristor", 4) 1089 | .registerModelType("memristor", 4); 1090 | } 1091 | 1092 | //----------------------------------------------------------------------------- 1093 | // Function : MemristorJoglekarSensitivity::operator 1094 | // Purpose : produces df/dp and dq/dp, where p=R. 1095 | // Special Notes : 1096 | // Scope : public 1097 | // Creator : Richard Schiek, Electrical Models & Simulations 1098 | // Creation Date : 10/23/2014 1099 | //----------------------------------------------------------------------------- 1100 | void MemristorJoglekarSensitivity::operator()( 1101 | const ParameterBase &entity, 1102 | const std::string & name, 1103 | std::vector & dfdp, 1104 | std::vector & dqdp, 1105 | std::vector & dbdp, 1106 | std::vector & Findices, 1107 | std::vector & Qindices, 1108 | std::vector & Bindices 1109 | ) const 1110 | { 1111 | const ParameterBase * e1 = &entity; 1112 | const Instance * in = dynamic_cast (e1); 1113 | 1114 | double * solVec = in->extData.nextSolVectorRawPtr; 1115 | double v_pos = solVec[in->li_Pos]; 1116 | double v_neg = solVec[in->li_Neg]; 1117 | 1118 | double dfdpLoc = -(v_pos-v_neg)*in->G*in->G; 1119 | 1120 | dfdp.resize(2); 1121 | dfdp[0] = +dfdpLoc; 1122 | dfdp[1] = -dfdpLoc; 1123 | 1124 | Findices.resize(2); 1125 | Findices[0] = in->li_Pos; 1126 | Findices[1] = in->li_Neg; 1127 | } 1128 | 1129 | } // namespace MemristorJoglekar 1130 | } // namespace Device 1131 | } // namespace Xyce -------------------------------------------------------------------------------- /Joglekar/Xyce/N_DEV_MemristorJoglekar.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright Notice 3 | // 4 | // Additions/Modifications Copyright 2017 Tim Molter 5 | // 6 | // Copyright 2002 Sandia Corporation. Under the terms 7 | // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. 8 | // Government retains certain rights in this software. 9 | // 10 | // Xyce(TM) Parallel Electrical Simulator 11 | // Copyright (C) 2002-2016 Sandia Corporation 12 | // 13 | // This program is free software: you can redistribute it and/or modify 14 | // it under the terms of the GNU General Public License as published by 15 | // the Free Software Foundation, either version 3 of the License, or 16 | // (at your option) any later version. 17 | // 18 | // This program is distributed in the hope that it will be useful, 19 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | // GNU General Public License for more details. 22 | // 23 | // You should have received a copy of the GNU General Public License 24 | // along with this program. If not, see . 25 | //----------------------------------------------------------------------------- 26 | 27 | //----------------------------------------------------------------------------- 28 | // 29 | // Purpose : Implementation of the Joglekar memristor model. 30 | // 31 | // Creator : Tim Molter, Knowm Inc. 32 | // 33 | // Creation Date : 01/11/17 34 | // 35 | //----------------------------------------------------------------------------- 36 | 37 | #ifndef Xyce_N_DEV_MemristorJoglekar_h 38 | #define Xyce_N_DEV_MemristorJoglekar_h 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | namespace Xyce { 48 | namespace Device { 49 | namespace MemristorJoglekar { 50 | 51 | class Model; 52 | class Instance; 53 | 54 | // sensitivity functor 55 | // not yet implemented. 56 | class MemristorJoglekarSensitivity : public baseSensitivity 57 | { 58 | public: 59 | MemristorJoglekarSensitivity() : 60 | baseSensitivity() {}; 61 | 62 | virtual ~MemristorJoglekarSensitivity() {}; 63 | 64 | virtual void operator()( 65 | const ParameterBase &entity, 66 | const std::string &name, 67 | std::vector & dfdp, 68 | std::vector & dqdp, 69 | std::vector & dbdp, 70 | std::vector & Findices, 71 | std::vector & Qindices, 72 | std::vector & Bindices 73 | ) const ; 74 | }; 75 | 76 | static MemristorJoglekarSensitivity memrSens; 77 | 78 | struct Traits : public DeviceTraits 79 | { 80 | static const char *name() {return "MemristorJoglekar";} 81 | static const char *deviceTypeName() {return "YMEMRISTOR level 4";} 82 | static int numNodes() {return 2;} 83 | static bool modelRequired() {return true;} 84 | static bool isLinearDevice() {return false;} 85 | 86 | static Device *factory(const Configuration &configuration, const FactoryBlock &factory_block); 87 | static void loadModelParameters(ParametricData &p); 88 | static void loadInstanceParameters(ParametricData &p); 89 | }; 90 | 91 | //----------------------------------------------------------------------------- 92 | // Class : Xyce::Device::MemristorJoglekar::Instance 93 | // Purpose : 94 | // Special Notes : 95 | // Creator : Richard Schiek, Electrical Models & Simulations 96 | // Creation Date : 10/23/2014 97 | //----------------------------------------------------------------------------- 98 | // 99 | // MemristorJoglekar device instance class. 100 | // 101 | // An instance is created for each occurance of the device in the netlist. 102 | // 103 | // It contains "unique" device information - ie stuff that will be 104 | // true of only one memristor in the circuit, such as the nodes to 105 | // which it is connected. A memristor is connected to only two 106 | // circuit nodes. 107 | // 108 | // This class does not directly contain information about its node 109 | // indices. It contains indices into the 5 parts (dFdx, dQdx, dx, F, 110 | // and Q) of the matrix problem A*dx = b, and also the solution 111 | // vector x. A is the Jacobian matrix that will be formed from dFdx 112 | // and d(dQ/dt)dx, dx is the update to x, and b is right hand side 113 | // function vector that will be formed from F and dQ/dt. These 114 | // indices are global, and determined by topology during the 115 | // initialization stage of execution. 116 | // 117 | class Instance : public DeviceInstance 118 | { 119 | friend class ParametricData; 120 | friend class Model; 121 | friend class Traits; 122 | friend class Master; 123 | friend class MemristorJoglekarSensitivity; 124 | 125 | public: 126 | Instance( 127 | const Configuration & configuration, 128 | const InstanceBlock & instance_block, 129 | Model & model, 130 | const FactoryBlock & factory_block); 131 | 132 | //--------------------------------------------------------------------------- 133 | // Function : Xyce::Device::MemristorJoglekar::Instance::~Instance 134 | // Purpose : destructor 135 | // Special Notes : 136 | // Scope : public 137 | // Creator : Richard Schiek, Electrical Models & Simulations 138 | // Creation Date : 10/23/2014 139 | //--------------------------------------------------------------------------- 140 | // 141 | // Destroys this instance 142 | // 143 | // @author Eric Keiter, SNL 144 | // @date 3/16/00 145 | ~Instance() {} 146 | 147 | private: 148 | Instance(const Instance &); 149 | Instance &operator=(const Instance &); 150 | 151 | public: 152 | 153 | //--------------------------------------------------------------------------- 154 | // Function : Xyce::Device::MemristorJoglekar::Instance::getModel 155 | // Purpose : destructor 156 | // Special Notes : 157 | // Scope : public 158 | // Creator : Richard Schiek, Electrical Models & Simulations 159 | // Creation Date : 10/23/2014 160 | //--------------------------------------------------------------------------- 161 | // 162 | // Gets the resistor model that owns this instance. 163 | // 164 | // @return reference to the owning MemristorJoglekar::Model 165 | // 166 | // @author David G. Baur Raytheon Sandia National Laboratories 1355 167 | // @date Mon Aug 12 08:36:37 2013 168 | Model &getModel() { return model_; } 169 | 170 | virtual void registerLIDs(const std::vector & intLIDVecRef, const std::vector & extLIDVecRef) /* override */; 171 | virtual void registerStateLIDs(const std::vector & staLIDVecRef) /* override */; 172 | virtual void registerStoreLIDs(const std::vector & stoLIDVecRef) /* override */; 173 | virtual void registerBranchDataLIDs(const std::vector & branchLIDVecRef) /* override */; 174 | virtual void registerJacLIDs(const std::vector< std::vector > & jacLIDVec) /* override */; 175 | 176 | void loadNodeSymbols(Util::SymbolTable &symbol_table) const; // override 177 | 178 | virtual bool processParams() /* override */; 179 | virtual bool updateTemperature(const double & temp_tmp) /* override */; 180 | virtual bool updateIntermediateVars() /* override */; 181 | virtual bool updatePrimaryState() /* override */; 182 | 183 | //--------------------------------------------------------------------------- 184 | // Function : Xyce::Device::MemristorJoglekar::Instance::jacobianStamp 185 | // Purpose : 186 | // Special Notes : 187 | // Scope : public 188 | // Creator : Richard Schiek, Electrical Models & Simulations 189 | // Creation Date : 10/23/2014 190 | //--------------------------------------------------------------------------- 191 | // 192 | // Return Jacobian stamp that informs topology of the layout of the 193 | // resistor jacobian. 194 | // 195 | // The Jacobian stamp describes the shape of the Jacobian to the 196 | // Topology subsystem. The Topology subsystem, in turn, returns 197 | // the offsets into the matrix and solution vectors where this 198 | // instance data is located. 199 | // 200 | // @return const reference to a std::vector of std::vector of 201 | // integers describing Jacobian stamp shape 202 | // 203 | // @author Robert Hoekstra 204 | // @date 8/20/2001 205 | virtual const std::vector< std::vector > &jacobianStamp() const /* override */ { 206 | return jacStamp; 207 | } 208 | 209 | virtual bool loadDAEQVector() /* override */; 210 | virtual bool loadDAEFVector() /* override */; 211 | virtual bool loadDAEdQdx() /* override */; 212 | virtual bool loadDAEdFdx() /* override */; 213 | 214 | 215 | virtual void setupPointers() /* override */; 216 | 217 | private: 218 | static std::vector< std::vector > jacStamp; //< All MemristorJoglekar instances have a common Jacobian Stamp 219 | static void initializeJacobianStamp(); 220 | 221 | Model & model_; //< Owning model 222 | 223 | // User-specified parameters: 224 | double R_init_; 225 | 226 | // Derived parameters: 227 | double G; //< Conductance(1.0/ohms) 228 | double Reff; //< Effective resistance 229 | double dReffdvpos; //< derivative of Reff with respect to Vpos 230 | double dReffdvneg; //< derivative of Reff with respect to Vneg 231 | double dReffdx; //< derivative of Reff with respect to x 232 | double dIdx; //< derivative of I with respect to x 233 | double i0; //< Current(ohms) 234 | double xVarFContribution; //< x, internal variable for thickness of conductive layer, F-vector contribution 235 | double dxFEqdVpos; //< derivative of X F equation with respect to Vpos 236 | double dxFEqdVneg; //< derivative of X F equation with respect to Vneg 237 | double dxFEqdx; //< derivative of X F equation with respect to X 238 | 239 | int li_Pos; //< Index for Positive Node 240 | int li_Neg; //< Index for Negative Node 241 | int li_x; //< Index for internal x, thickness, variable 242 | int li_store_R; //< Index to store resistance value 243 | int li_store_tdt; //< Index to store for next RTN time time delta t 244 | int li_branch_data; //< Index for Lead Current and junction voltage (for power calculations) 245 | 246 | // Offset variables corresponding to the above declared indices. 247 | int APosEquPosNodeOffset; //< Column index into matrix of Pos/Pos conductance 248 | int APosEquNegNodeOffset; //< Column index into matrix of Pos/Neg conductance 249 | int APosEquXNodeOffset; //< Column index into matrix for internal varaible x, layer thickness 250 | int ANegEquPosNodeOffset; //< Column index into matrix of Neg/Pos conductance 251 | int ANegEquNegNodeOffset; //< Column index into matrix of Neg/Neg conductance 252 | int ANegEquXNodeOffset; //< Column index into matrix for internal varaible x, layer thickness 253 | int XEquVPosOffset; //< Thickness governing equation, VPos dependence 254 | int XEquVNegOffset; //< Thickness governing equation, VNeg dependence 255 | int XEquXOffset; //< Thickness variable, in thickness governing equation equation 256 | 257 | #ifndef Xyce_NONPOINTER_MATRIX_LOAD 258 | // Pointers for Jacobian 259 | double * f_PosEquPosNodePtr; 260 | double * f_PosEquNegNodePtr; 261 | double * f_PosEquXNodePtr; 262 | double * f_NegEquPosNodePtr; 263 | double * f_NegEquNegNodePtr; 264 | double * f_NegEquXNodePtr; 265 | double * f_XEquPosNodePtr; 266 | double * f_XEquNegNodePtr; 267 | double * f_XEquXNodePtr; 268 | double * q_XEquXNodePtr; 269 | # 270 | #endif 271 | 272 | }; 273 | 274 | 275 | //----------------------------------------------------------------------------- 276 | // Class : Xyce::Device::MemristorJoglekar::Model 277 | // Purpose : 278 | // Special Notes : 279 | // Creator : Richard Schiek, Electrical Models & Simulations 280 | // Creation Date : 10/23/2014 281 | //----------------------------------------------------------------------------- 282 | // 283 | // MemristorJoglekar model class 284 | // 285 | class Model : public DeviceModel 286 | { 287 | friend class ParametricData; //< Allow ParametricData to changes member values 288 | friend class Instance; //< Don't force a lot of pointless getters 289 | friend class Traits; 290 | friend class Master; //< Don't force a lot of pointless getters 291 | 292 | public: 293 | typedef std::vector InstanceVector; 294 | 295 | Model( 296 | const Configuration & configuration, 297 | const ModelBlock & model_block, 298 | const FactoryBlock & factory_block); 299 | ~Model(); 300 | 301 | private: 302 | Model(); 303 | Model(const Model &); 304 | Model &operator=(const Model &); 305 | 306 | public: 307 | 308 | //--------------------------------------------------------------------------- 309 | // Function : Xyce::Device::MemristorJoglekar::Model::addInstance 310 | // Purpose : 311 | // Special Notes : 312 | // Scope : public 313 | // Creator : Richard Schiek, Electrical Models & Simulations 314 | // Creation Date : 10/23/2014 315 | //--------------------------------------------------------------------------- 316 | // 317 | // Add an instance to the list of instances associated with this model 318 | // 319 | // @author David G. Baur Raytheon Sandia National Laboratories 1355 320 | // @date 8/12/2013 321 | void addInstance(Instance *instance) 322 | { 323 | instanceContainer.push_back(instance); 324 | } 325 | 326 | virtual void forEachInstance(DeviceInstanceOp &op) const /* override */; 327 | 328 | virtual std::ostream &printOutInstances(std::ostream &os) const; 329 | 330 | virtual bool processParams() /* override */; 331 | virtual bool processInstanceParams() /* override */; 332 | 333 | private: 334 | InstanceVector instanceContainer; //< List of owned resistor instances 335 | 336 | // model parameters for Joglekar model 337 | 338 | double Roff_; 339 | double Ron_; 340 | double D_; 341 | double uv_; 342 | double p_; 343 | 344 | }; 345 | 346 | 347 | //----------------------------------------------------------------------------- 348 | // Class : Xyce::Device::MemristorJoglekar::Master 349 | // Purpose : 350 | // Special Notes : 351 | // Creator : Richard Schiek, Electrical Models & Simulations 352 | // Creation Date : 10/23/2014 353 | //----------------------------------------------------------------------------- 354 | // 355 | // MemristorJoglekar master 356 | // 357 | // The "master" class is the one that contains the updateState, loadDAEVectors 358 | // and loadDAEMatrices methods that are actually called when it is time to 359 | // compute and load device contributions. 360 | // 361 | // The default implementations of these methods in the DeviceMaster 362 | // template class simply loops over all instances and calls their 363 | // updatePrimaryState, loadDAEFVector/loadDAEQVector, and 364 | // loadDAEdFdx/loadDAEdQdx methods, respectively. 365 | // 366 | // For efficiency, the MemristorJoglekar class reimplements these methods to do the 367 | // work directly, instead of calling instance-level functions. 368 | // 369 | class Master : public DeviceMaster 370 | { 371 | friend class Instance; 372 | friend class Model; 373 | 374 | public: 375 | 376 | //--------------------------------------------------------------------------- 377 | // Function : Xyce::Device::MemristorJoglekar::Master::Master 378 | // Purpose : 379 | // Special Notes : 380 | // Scope : public 381 | // Creator : Richard Schiek, Electrical Models & Simulations 382 | // Creation Date : 10/23/2014 383 | //--------------------------------------------------------------------------- 384 | // 385 | // Construct a MemristorJoglekar Device. 386 | // 387 | // @param configuration 388 | // @param factory_block 389 | // @param solver_state 390 | // @param device_options 391 | Master( 392 | const Configuration & configuration, 393 | const FactoryBlock & factory_block, 394 | const SolverState & solver_state, 395 | const DeviceOptions & device_options) 396 | : DeviceMaster(configuration, factory_block, solver_state, device_options) 397 | {} 398 | 399 | virtual bool updateState(double * solVec, double * staVec, double * stoVec); 400 | virtual bool loadDAEVectors (double * solVec, double * fVec, double * qVec, double * bVec, double * leadF, double * leadQ, double * junctionV); 401 | virtual bool loadDAEMatrices(Linear::Matrix & dFdx, Linear::Matrix & dQdx); 402 | 403 | }; 404 | 405 | void registerDevice(); 406 | 407 | } // namespace MemristorJoglekar 408 | } // namespace Device 409 | } // namespace Xyce 410 | 411 | #endif // Xyce_N_DEV_MemristorJoglekar_h 412 | -------------------------------------------------------------------------------- /Joglekar/Xyce/README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | 3 | | Model Class | Model Language | Simulator | 4 | |---|---|---| 5 | |Ill-formed|Native Xyce Device|Xyce| 6 | 7 | ## Instructions 8 | 9 | See: 10 | 11 | ## Sources 12 | 13 | 1. Original Source of SPICE Model: 14 | 15 | ## How to Run Model 16 | 17 | Xyce /path/to/.../joglekar.cir 18 | gnuplot 19 | plot '/path/to/.../joglekar.cir.prn' using 3:4 with lines title "I-V" 20 | -------------------------------------------------------------------------------- /Joglekar/Xyce/joglekar.cir: -------------------------------------------------------------------------------- 1 | * Voltage Sources 2 | V1 1 0 SIN(0V 1.2V 1Hz) 3 | *V1 1 0 SIN(0V .4V 100Hz) 4 | 5 | * Memristors 6 | YMEMRISTOR mr1 1 0 mrm1 R_init=11000 7 | 8 | .MODEL mrm1 memristor (level=4 Roff=16000 Ron=100 D=10e-9 uv=10e-15 p=2.0) 9 | 10 | * Analysis Command 11 | .TRAN 10ns 1s 12 | * Output 13 | .PRINT TRAN V(1) I(V1) N(YMEMRISTOR!mr1:R) 14 | 15 | .END -------------------------------------------------------------------------------- /Knowm/LTSpice/Circuit_Knowm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Knowm/LTSpice/Circuit_Knowm.png -------------------------------------------------------------------------------- /Knowm/LTSpice/Knowm_IV.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Knowm/LTSpice/Knowm_IV.png -------------------------------------------------------------------------------- /Knowm/LTSpice/Knowm_Time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Knowm/LTSpice/Knowm_Time.png -------------------------------------------------------------------------------- /Knowm/LTSpice/README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | 3 | | Model Class | Model Language | Simulator | 4 | |---|---|---| 5 | |SPICE Subcircuit|SPICE|LTSpice| 6 | 7 | ## Sources 8 | 9 | 1. PLoS Original Source of Model: 10 | 1. Reworked definition of Model in dX/dt form: 11 | 12 | ## How to Run Model 13 | 14 | 1. LTSpice Intro - [The Joglekar Resistance Switch Memristor Model in LTSpice](http://knowm.org/the-joglekar-resistance-switch-memristor-model-in-ltspice/) 15 | 1. LTSpice - [Memristor Models in LTSpice](http://knowm.org/memristor-models-in-ltspice/) 16 | -------------------------------------------------------------------------------- /Knowm/LTSpice/memristor_knowm.sub: -------------------------------------------------------------------------------- 1 | * Knowm Mean Metastable Switch Memristor SPICE Model 2 | 3 | * Copyright Tim Molter Knowm Inc. 2017 4 | 5 | * Connections: 6 | * TE: Top electrode 7 | * BE: Bottom electrode 8 | * XSV: External connection to plot state variable 9 | * that is not used otherwise 10 | 11 | .SUBCKT MEM_KNOWM TE BE XSV 12 | 13 | * Ron: Minimum device resistance 14 | * Roff: Maximum device resistance 15 | * Von: Threshold voltage to turn device on 16 | * Voff: Threshold voltage to turn device off 17 | * TAU: Time constant 18 | * T: Temperature 19 | 20 | .params Ron=500 Roff=1500 Voff=0.27 Von=0.27 TAU=0.0001 T=298.5 x0=0 21 | 22 | * Function G(V(t)) - Describes the device threshold 23 | .func G(V) = V/Ron+(1-V)/Roff 24 | 25 | * Function F(V(t),x(t)) - Describes the SV motion 26 | .func F(V1,V2) = (1/TAU)*(( 1/(1+exp(-1/(T*boltz/echarge)*(V1-Von))) )*(1-V2)-( 1-(1/(1+exp(-1/(T*boltz/echarge)*(V1+Voff)))) )*V2 27 | 28 | * Memristor I-V Relationship 29 | .func IVRel(V1,V2) = V1*G(V2) 30 | 31 | * Circuit to determine state variable 32 | * dx/dt = F(V(t),x(t))*G(V(t)) 33 | Cx XSV 0 {1} 34 | .ic V(XSV) = x0 35 | Gx 0 XSV value={F(V(TE,BE),V(XSV,0))} 36 | 37 | * Current source for memristor IV response 38 | Gmem TE BE value={IVRel(V(TE,BE),V(XSV,0))} 39 | 40 | .ENDS MEM_KNOWM -------------------------------------------------------------------------------- /Knowm/LTSpice/memristor_knowm_sim.asc: -------------------------------------------------------------------------------- 1 | Version 4 2 | SHEET 1 880 680 3 | WIRE 416 0 16 0 4 | WIRE 416 16 416 0 5 | WIRE 16 32 16 0 6 | WIRE 16 144 16 112 7 | WIRE 224 144 16 144 8 | WIRE 416 144 416 112 9 | WIRE 416 144 224 144 10 | WIRE 224 192 224 144 11 | FLAG 224 192 0 12 | SYMBOL voltage 16 16 R0 13 | WINDOW 123 0 0 Left 2 14 | WINDOW 39 0 0 Left 2 15 | SYMATTR InstName V1 16 | SYMATTR Value SINE(0 0.5 100 0 0 0) 17 | SYMBOL memristor_with_state 416 64 R0 18 | SYMATTR InstName U1 19 | SYMATTR Value MEM_KNOWM 20 | TEXT 120 -80 Left 2 !.tran 0 0.04s 21 | TEXT 112 -40 Left 1 !.lib memristor_knowm.sub 22 | -------------------------------------------------------------------------------- /Knowm/LTSpice/memristor_knowm_sim_IV.plt: -------------------------------------------------------------------------------- 1 | [Transient Analysis] 2 | { 3 | Npanes: 2 4 | Active Pane: 1 5 | { 6 | traces: 1 {336592898,0,"Ix(U1:TE)"} 7 | Parametric: "V(n001)" 8 | X: (' ',2,-1.2,0.02,1.2) 9 | Y[0]: ('m',1,-0.001,0.0002,0.0012) 10 | Y[1]: ('_',0,1e+308,0,-1e+308) 11 | Amps: ('m',0,0,1,-0.001,0.0002,0.0012) 12 | Log: 0 0 0 13 | NeyeDiagPeriods: 0 14 | TeyeEnd: 3 15 | }, 16 | { 17 | traces: 1 {268959747,0,"V(nc_01)"} 18 | Parametric: "V(n001)" 19 | X: (' ',2,-1.2,0.02,1.2) 20 | Y[0]: (' ',2,0.21,0.07,1.05) 21 | Y[1]: ('_',0,1e+308,0,-1e+308) 22 | Volts: (' ',0,0,2,0.21,0.07,1.05) 23 | Log: 0 0 0 24 | NeyeDiagPeriods: 0 25 | TeyeEnd: 3 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Knowm/LTSpice/memristor_knowm_sim_T.plt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Knowm/LTSpice/memristor_knowm_sim_T.plt -------------------------------------------------------------------------------- /Knowm/Verilog-A/README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | 3 | | Model Class | Model Language | Simulator | 4 | |---|---|---| 5 | |Ill-formed|Verilog-A|Xyce| 6 | 7 | ## Resources 8 | 9 | 1. [Build Xyce from Source for ADMS Verilog-A Model Integration](http://knowm.org/build-xyce-from-source-for-adms-verilog-a-model-integration/) 10 | 1. [Well-posed Memristor Modeling with Xyce and Verilog-A](http://knowm.org/well-posed-memristor-modeling-with-xyce-and-verilog-a/) 11 | 12 | ## Instructions 13 | 14 | cd ~/workspaces/workspace_knowm/memristor-models-4-all/Knowm/Verilog-A 15 | buildxyceplugin -o metastableswitch *.va /usr/local/lib 16 | Xyce -plugin /usr/local/lib/metastableswitch.so memristor_sim.cir 17 | gnuplot 18 | plot '~/workspaces/workspace_knowm/memristor-models-4-all/Knowm/Verilog-A/memristor_sim.cir.prn' using 3:4 with lines title "I-V" 19 | 20 | 21 | -------------------------------------------------------------------------------- /Knowm/Verilog-A/knowm.va: -------------------------------------------------------------------------------- 1 | `include "disciplines.vams" 2 | `include "constants.vams" 3 | 4 | `define attr(txt) (*txt*) 5 | 6 | module knowmmemristor (p,n); 7 | 8 | inout p,n; 9 | electrical p,n; 10 | 11 | parameter real R_OFF=1E-6 from (0:inf) `attr(info="R_OFF" type="instance"); 12 | parameter real R_ON=10E-6 from (0:inf) `attr(info="R_ON" type="instance"); 13 | parameter real V_OFF=.2 from (0:inf) `attr(info="V_OFF" type="instance"); 14 | parameter real V_ON=.2 from (0:inf) `attr(info="V_ON" type="instance"); 15 | parameter real TAU=0.0001 from (0:inf) `attr(info="TAU" type="instance"); 16 | parameter real XO=0 from [0:1] `attr(info="XO" type="instance"); 17 | // TODO: use R_INIT instead of XO 18 | 19 | // local variables that should persist over time steps 20 | real g_off; 21 | real g_on; 22 | real Nb; 23 | real time_last; 24 | real global_on; 25 | 26 | // local variables that hold temporary values 27 | real G; 28 | real time; 29 | real time_delta; 30 | 31 | real exponent; 32 | real alpha; 33 | real Pa; 34 | real Pb; 35 | 36 | real num_ON_to_OFF; 37 | 38 | analog 39 | begin 40 | @(initial_instance) 41 | begin 42 | g_off = G_OFF / N; 43 | g_on = G_ON / N; 44 | Nb = (1 - N_ON_OFF_RATIO) * N; 45 | time_last = 0; 46 | global_on=0; 47 | end 48 | 49 | 50 | $strobe ("****************"); 51 | time = $realtime; 52 | time_delta = time - time_last; 53 | 54 | $strobe ("V(p,n) = ", V(p,n)); 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | // Probability from OFF to ON state 66 | exponent = -1 * (V(p,n) - V_ON) / $vt; 67 | alpha = time_delta / TC; 68 | Pa = alpha / (1.0 + (limexp(exponent))); 69 | 70 | if (Pa > 1.0) begin 71 | Pa = 1.0; 72 | end 73 | else if (Pa < 0.0) begin 74 | Pa = 0.0; 75 | end 76 | $strobe ("Pa = ", Pa); 77 | 78 | 79 | 80 | 81 | 82 | 83 | // Probability from ON to OFF state 84 | exponent = -1 * (V(p,n) + V_OFF) / $vt; 85 | alpha = time_delta / TC; 86 | Pb = alpha * (1 - 1 / ((1.0 + (limexp(exponent))))); 87 | 88 | if (Pb > 1.0) begin 89 | Pb = 1.0; 90 | end 91 | else if (Pb < 0.0) begin 92 | Pb = 0.0; 93 | end 94 | $strobe ("Pb = ", Pb); 95 | 96 | 97 | 98 | 99 | 100 | // conductance 101 | G = Nb * g_off + (N - Nb) * g_on; 102 | $strobe ("G = ", G); 103 | 104 | 105 | 106 | I(p,n) <+ -1.0*G*V(p,n); 107 | 108 | time_last = time; 109 | 110 | 111 | 112 | end 113 | endmodule 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /Knowm/Verilog-A/knowm_sim.cir: -------------------------------------------------------------------------------- 1 | 2 | * Voltage Sources 3 | V1 1 0 SIN(0V .25V 100Hz) 4 | 5 | * Memristors 6 | Yknowmmemristor M1 1 0 7 | 8 | * Analysis Command 9 | .TRAN .01ms 10ms 10 | * Output 11 | .PRINT TRAN V(1) I(V1) 12 | 13 | 14 | .END 15 | -------------------------------------------------------------------------------- /Knowm/Xyce/Generalized.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Knowm/Xyce/Generalized.png -------------------------------------------------------------------------------- /Knowm/Xyce/MMSS_Xyce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Knowm/Xyce/MMSS_Xyce.png -------------------------------------------------------------------------------- /Knowm/Xyce/N_DEV_MemristorKnowm.C: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Copyright Notice 3 | // 4 | // Additions/Modifications Copyright 2017 Tim Molter 5 | // 6 | // Copyright 2002 Sandia Corporation. Under the terms 7 | // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. 8 | // Government retains certain rights in this software. 9 | // 10 | // Xyce(TM) Parallel Electrical Simulator 11 | // Copyright (C) 2002-2016 Sandia Corporation 12 | // 13 | // This program is free software: you can redistribute it and/or modify 14 | // it under the terms of the GNU General Public License as published by 15 | // the Free Software Foundation, either version 3 of the License, or 16 | // (at your option) any later version. 17 | // 18 | // This program is distributed in the hope that it will be useful, 19 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | // GNU General Public License for more details. 22 | // 23 | // You should have received a copy of the GNU General Public License 24 | // along with this program. If not, see . 25 | // ---------------------------------------------------------------------------- 26 | 27 | //---------------------------------------------------------------------------- 28 | // 29 | // Purpose : Implementation of the Knowm M-MSS memristor model. 30 | // 31 | // Creator : Tim Molter, Knowm Inc. 32 | // 33 | // Creation Date : 01/04/17 34 | // 35 | // 36 | //---------------------------------------------------------------------------- 37 | #include 38 | #include 39 | 40 | #include 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | namespace Xyce { 51 | namespace Device { 52 | namespace MemristorKnowm { 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | template 61 | ScalarT p0ff2on( const ScalarT & V1, const ScalarT & V2, double VON, double TAU, double VT ) 62 | { 63 | ScalarT exponent = -1 * ((V1-V2) - VON) / VT; 64 | double alpha = 1 / TAU; 65 | ScalarT fval = alpha / (1.0 + exp(exponent)); 66 | return fval; 67 | } 68 | 69 | template 70 | ScalarT pOn2Off( const ScalarT & V1, const ScalarT & V2, double VOFF, double TAU, double VT ) 71 | { 72 | 73 | ScalarT exponent = -1 * ((V1-V2) + VOFF) / VT; 74 | double alpha = 1 / TAU; 75 | ScalarT fval = alpha * (1.0 - 1.0 / (1.0 + exp(exponent))); 76 | return fval; 77 | } 78 | 79 | template 80 | ScalarT dXdt( const ScalarT & V1, const ScalarT & V2, const ScalarT & X, double RON, double ROFF, double VON, double VOFF, double TAU, double VT) 81 | { 82 | 83 | // if (DEBUG_DEVICE){ 84 | // Xyce::dout() << " V1 = " << V1 << std::endl; 85 | // Xyce::dout() << " V2 = " << V2 << std::endl; 86 | // Xyce::dout() << " X = " << X << std::endl; 87 | // } 88 | 89 | // Probabilities 90 | ScalarT p0ff2onVal = p0ff2on(V1, V2, VON, TAU, VT); 91 | ScalarT pOn2OffVal = pOn2Off(V1, V2, VOFF, TAU, VT); 92 | 93 | // Number of switches making a transition 94 | ScalarT n0ff2on = (1 - X) * p0ff2onVal; 95 | ScalarT nOn2Off = X * pOn2OffVal; 96 | 97 | ScalarT fval = n0ff2on - nOn2Off; 98 | 99 | return fval; 100 | } 101 | 102 | 103 | 104 | 105 | 106 | 107 | template 108 | ScalarT SchottkyCurrent( const ScalarT & V1, const ScalarT & V2, double SchottkyForwardAlpha, double SchottkyForwardBeta, double SchottkyReverseAlpha, double SchottkyReverseBeta ) 109 | { 110 | return SchottkyReverseAlpha * (-1 * exp(-1 * SchottkyReverseBeta * (V1-V2))) + SchottkyForwardAlpha * (exp(SchottkyForwardBeta * (V1-V2))); 111 | } 112 | 113 | template 114 | ScalarT Geff( const ScalarT & X, double RON, double ROFF ) 115 | { 116 | return X / RON + (1 - X) / ROFF; 117 | } 118 | 119 | template 120 | ScalarT I_V( const ScalarT & V1, const ScalarT & V2, const ScalarT & X, double RON, double ROFF, double PHI, double SchottkyForwardAlpha, double SchottkyForwardBeta, double SchottkyReverseAlpha, double SchottkyReverseBeta ){ 121 | 122 | ScalarT Gval= Geff( X, RON, ROFF ); 123 | ScalarT KnowmCurrentval = (V1-V2)*Gval; 124 | 125 | ScalarT SchottkyCurrentval = SchottkyCurrent(V1, V2, SchottkyForwardAlpha, SchottkyForwardBeta, SchottkyReverseAlpha, SchottkyReverseBeta); 126 | 127 | ScalarT fval = PHI * KnowmCurrentval + (1 - PHI) * SchottkyCurrentval; 128 | 129 | // if (DEBUG_DEVICE){ 130 | // Xyce::dout() << " Geff = " << Gval << std::endl; 131 | // Xyce::dout() << " RON = " << RON << std::endl; 132 | // Xyce::dout() << " ROFF = " << ROFF << std::endl; 133 | // Xyce::dout() << " fval = " << fval << std::endl; 134 | // } 135 | 136 | return fval; 137 | } 138 | 139 | 140 | 141 | 142 | 143 | 144 | // 145 | // Common Jacobian Stamp for all MemristorKnowm devices. 146 | // Because all memristors have identical Jacobian stamps, this data is 147 | // declared static and is shared by all memristor instances. 148 | // 149 | std::vector > Instance::jacStamp; 150 | 151 | //----------------------------------------------------------------------------- 152 | // Function : Xyce::Device::MemristorKnowm::Instance::initializeJacobianStamp 153 | // Purpose : 154 | // Special Notes : 155 | // Scope : private 156 | // Creator : Richard Schiek, Electrical Models & Simulations 157 | // Creation Date : 2/11/2014 158 | //----------------------------------------------------------------------------- 159 | // 160 | // @brief Common Jacobian stamp initializer for all MemristorKnowm devices. 161 | // 162 | // The Jacobian stamp is a sparse-matrix representation of the pattern 163 | // of non-zero elements that a device will put into the Jacobian matrix. 164 | // 165 | // The Jacobian stamp is used by the Topology package to determine indices 166 | // into the full Jacobian matrix for elements that correspond to this 167 | // device. 168 | // 169 | // There is one row of the Jacobian stamp for each equation associated with 170 | // a device. The number of elements in a row are the number of non-zero 171 | // elements in that row of the device's contribution to the Jacobian. 172 | // The values of the elements are numbers local to the device that 173 | // represent the column in which the non-zero element appears. 174 | // 175 | // For this memristor, there are two external nodes (the positive and negative 176 | // terminals of the device). The positive node is referred to as the 0th 177 | // node of the device, and the negative node the 1st node. 178 | // 179 | void Instance::initializeJacobianStamp() 180 | { 181 | if (jacStamp.empty()) 182 | { 183 | jacStamp.resize(3); 184 | jacStamp[0].resize(3); 185 | jacStamp[0][0] = 0; 186 | jacStamp[0][1] = 1; 187 | jacStamp[0][2] = 2; 188 | jacStamp[1].resize(3); 189 | jacStamp[1][0] = 0; 190 | jacStamp[1][1] = 1; 191 | jacStamp[1][2] = 2; 192 | jacStamp[2].resize(3); 193 | jacStamp[2][0] = 0; 194 | jacStamp[2][1] = 1; 195 | jacStamp[2][2] = 2; 196 | } 197 | } 198 | 199 | //----------------------------------------------------------------------------- 200 | // Function : Xyce::Device::MemristorKnowm::Traits::loadInstanceParameters 201 | // Purpose : 202 | // Special Notes : 203 | // Scope : private 204 | // Creator : Richard Schiek, Electrical Models & Simulations 205 | // Creation Date : 10/23/2014 206 | //----------------------------------------------------------------------------- 207 | // 208 | // Loads the parameter definition into the instance parameter map. 209 | // 210 | // @param p instance parameter map 211 | // 212 | // Each parameter supported by the memristor device instance is 213 | // defined via the addPar call. The minimum information required is 214 | // the name of the parameter, the default value, and a member pointer 215 | // to a variable in the instance class to which the value will be 216 | // assigned. 217 | // 218 | // Additional information such as documentation for the parameter, units 219 | // (used only in output of tables for documentation), whether a special 220 | // boolean should be set if the parameter is given, etc. may be specified 221 | // using the various set* calls of the Xyce::Device::Descriptor class. 222 | // 223 | // It is important to note that since parameters defined by addPar are 224 | // defined as metadata separate from any instance, it is not possible to 225 | // establish interrelationships between parameter defaults here. Parameter 226 | // defaults specified in addPar are always constants. If a device requires 227 | // that parameter defaults depend on values of other parameters, this has to 228 | // be done in the instance constructor. Examples of such parameters in this 229 | // device are the "DTEMP" and "W" parameters, which are set to special defaults 230 | // at device instantiation time. Defaults for those parameters in the addPar 231 | // calls (and hence in the LaTeX tables in the reference guide produced from 232 | // this data) are misleading. 233 | // 234 | void Traits::loadInstanceParameters(ParametricData &p) 235 | { 236 | p.addPar("R_init", 0.0, &MemristorKnowm::Instance::R_init_) 237 | .setUnit(U_OHM) 238 | .setDescription("Initial value for resistance"); 239 | p.addPar("TEMP", 300.0, &MemristorKnowm::Instance::Temp_) 240 | .setUnit(U_DEGK) 241 | .setDescription("Device Temperature"); 242 | 243 | } 244 | 245 | //----------------------------------------------------------------------------- 246 | // Function : Xyce::Device::MemristorKnowm::Traits::loadModelParameters 247 | // Purpose : 248 | // Special Notes : The addPar calls here were refactored and moved here 249 | // from the model constructor. Those addPars had been 250 | // in place from 2/4/2005. 251 | // Scope : private 252 | // Creator : Richard Schiek, Electrical Models & Simulations 253 | // Creation Date : 10/23/2014 254 | //----------------------------------------------------------------------------- 255 | // 256 | // Loads the parameter definition into the model parameter map. 257 | // 258 | // @param p model parameter map 259 | // 260 | // @see Xyce::Device::MemristorKnowm::Traits::loadInstanceParameters 261 | // 262 | // 263 | void Traits::loadModelParameters(ParametricData &p) 264 | { 265 | // Create parameter definitions for parameter member variables 266 | 267 | // NOTE: The first string arg need to be ALL CAPS! 268 | 269 | p.addPar("ROFF", 16000.0, &MemristorKnowm::Model::Roff_) 270 | .setUnit(U_OHM) 271 | .setDescription("Off resistance."); 272 | p.addPar("RON", 100.0, &MemristorKnowm::Model::Ron_) 273 | .setUnit(U_OHM) 274 | .setDescription("On resistance"); 275 | p.addPar("VOFF", 1.0, &MemristorKnowm::Model::Voff_) 276 | .setUnit(U_VOLT) 277 | .setDescription("Threshold voltage to turn device off"); 278 | p.addPar("VON", 1.0, &MemristorKnowm::Model::Von_) 279 | .setUnit(U_VOLT) 280 | .setDescription("Threshold voltage to turn device on"); 281 | p.addPar("TAU", 10.0e-9, &MemristorKnowm::Model::Tau_) 282 | .setUnit(U_SECOND) 283 | .setDescription("Time constant"); 284 | 285 | p.addPar("PHI", 1.0, &MemristorKnowm::Model::Phi_) 286 | .setUnit(U_NONE) 287 | .setDescription("Schottky Forward Alpha_"); 288 | p.addPar("SFA", 0.0, &MemristorKnowm::Model::SchottkyForwardAlpha_) 289 | .setUnit(U_NONE) 290 | .setDescription("Schottky Forward Alpha_"); 291 | p.addPar("SFB", 0.0, &MemristorKnowm::Model::SchottkyForwardBeta_) 292 | .setUnit(U_NONE) 293 | .setDescription("Schottky Forward Beta"); 294 | p.addPar("SRA", 0.0, &MemristorKnowm::Model::SchottkyReverseAlpha_) 295 | .setUnit(U_NONE) 296 | .setDescription("Schottky Reverse Alpha"); 297 | p.addPar("SRB", 0.0, &MemristorKnowm::Model::SchottkyReverseBeta_) 298 | .setUnit(U_NONE) 299 | .setDescription("Schottky Reverse Beta"); 300 | 301 | } 302 | 303 | //----------------------------------------------------------------------------- 304 | // Function : Xyce::Device::MemristorKnowm::Instance::Instance 305 | // Purpose : Instance constructor 306 | // Special Notes : 307 | // Scope : public 308 | // Creator : Richard Schiek, Electrical Models & Simulations 309 | // Creation Date : 10/23/2014 310 | //----------------------------------------------------------------------------- 311 | // 312 | // Construct a memristor instance. 313 | // 314 | Instance::Instance( 315 | const Configuration & configuration, 316 | const InstanceBlock & instance_block, 317 | Model & model, 318 | const FactoryBlock & factory_block) 319 | : DeviceInstance(instance_block, configuration.getInstanceParameters(), factory_block), 320 | model_(model), 321 | R_init_(0.0), 322 | Temp_(300.0), 323 | G(0.0), 324 | i0(0.0), 325 | li_Pos(-1), 326 | li_Neg(-1), 327 | li_x(-1), 328 | li_store_tdt(-1), 329 | li_branch_data(0), 330 | 331 | 332 | APosEquPosNodeOffset(-1), 333 | APosEquNegNodeOffset(-1), 334 | APosEquXNodeOffset(-1), 335 | ANegEquPosNodeOffset(-1), 336 | ANegEquNegNodeOffset(-1), 337 | ANegEquXNodeOffset(-1), 338 | XEquVPosOffset(-1), 339 | XEquVNegOffset(-1), 340 | XEquXOffset(-1) 341 | 342 | #ifndef Xyce_NONPOINTER_MATRIX_LOAD 343 | , 344 | f_PosEquPosNodePtr(0), 345 | f_PosEquNegNodePtr(0), 346 | f_PosEquXNodePtr(0), 347 | f_NegEquPosNodePtr(0), 348 | f_NegEquNegNodePtr(0), 349 | f_NegEquXNodePtr(0), 350 | f_XEquPosNodePtr(0), 351 | f_XEquNegNodePtr(0), 352 | f_XEquXNodePtr(0), 353 | q_XEquXNodePtr(0) 354 | #endif 355 | 356 | { 357 | // Initialize DeviceInstance values 358 | numIntVars = 1; // Initialize number if internal nodes in DeviceInstance 359 | numExtVars = 2; // Initialize number if external nodes in DeviceInstance 360 | numStateVars = 0; // Initialize number if state variables in DeviceInstance 361 | setNumStoreVars(2); // Initialize number if store variables in DeviceInstance 362 | 363 | setNumBranchDataVars(0); // by default don't allocate space in branch vectors 364 | numBranchDataVarsIfAllocated = 1; // this is the space to allocate if lead current or power is needed. 365 | 366 | initializeJacobianStamp(); 367 | 368 | // Set params to constant default values from parameter definition 369 | setDefaultParams(); 370 | 371 | // Set params according to instance line and constant defaults from metadata 372 | setParams(instance_block.params); 373 | 374 | // Calculate any parameters specified as expressions 375 | updateDependentParameters(); 376 | 377 | // Process the parameters to complete initialization 378 | processParams(); 379 | 380 | } 381 | 382 | //----------------------------------------------------------------------------- 383 | // Function : Xyce::Device::MemristorKnowm::Instance::processParams 384 | // Purpose : 385 | // Special Notes : 386 | // Scope : public 387 | // Creator : Richard Schiek, Electrical Models & Simulations 388 | // Creation Date : 10/23/2014 389 | //----------------------------------------------------------------------------- 390 | // Process parameters. 391 | // 392 | // @return true on success 393 | // 394 | // In general, the processParams method is intended as a place for complex 395 | // manipulation of parameters that must happen if temperature or other 396 | // external changes happen. 397 | // 398 | bool Instance::processParams() 399 | { 400 | 401 | // initialize X state (width between 0 and 1 and scaled to D) 402 | if (!given("R_init")){ 403 | R_init_ = model_.Roff_; 404 | } 405 | 406 | // if (DEBUG_DEVICE){ 407 | // Xyce::dout() << "----------Instance::processParams" << std::endl; 408 | // Xyce::dout() << " R_init_ = " << R_init_ << std::endl; 409 | // } 410 | if (!given("TEMP")){ 411 | Temp_ = getDeviceOptions().temp.getImmutableValue(); 412 | } 413 | 414 | updateTemperature(Temp_); 415 | return true; 416 | } 417 | 418 | //----------------------------------------------------------------------------- 419 | // Function : Xyce::Device::MemristorKnowm::Instance::registerLIDs 420 | // Purpose : 421 | // Special Notes : 422 | // Scope : public 423 | // Creator : Richard Schiek, Electrical Models & Simulations 424 | // Creation Date : 10/23/2014 425 | //----------------------------------------------------------------------------- 426 | // 427 | // Register local IDs 428 | // 429 | // Register the local internal and external node IDs. 430 | // 431 | // @param intLIDVecRef internal local IDs from topology package 432 | // @param extLIDVecRef external local IDs from topology package 433 | // 434 | void Instance::registerLIDs( 435 | const std::vector & intLIDVecRef, 436 | const std::vector & extLIDVecRef) 437 | { 438 | AssertLIDs(intLIDVecRef.size() == numIntVars); 439 | AssertLIDs(extLIDVecRef.size() == numExtVars); 440 | 441 | // Copy the local ID lists. 442 | intLIDVec = intLIDVecRef; // Set the internal local IDs in DeviceInstance 443 | extLIDVec = extLIDVecRef; // Set the external local IDs in DeviceInstance 444 | 445 | li_Pos = extLIDVec[0]; 446 | li_Neg = extLIDVec[1]; 447 | 448 | // This lid is for the internal variable for layer thickness that determines resistance 449 | li_x = intLIDVec[0]; 450 | } 451 | 452 | //----------------------------------------------------------------------------- 453 | // Function : Xyce::Device::MemristorKnowm::Instance::registerStateLIDs 454 | // Purpose : 455 | // Special Notes : 456 | // Scope : public 457 | // Creator : Richard Schiek, Electrical Models & Simulations 458 | // Creation Date : 10/23/2014 459 | //----------------------------------------------------------------------------- 460 | // 461 | // Register the local state IDs 462 | // 463 | // @note The memristor does not have any state vars, so this function 464 | // does nothing. 465 | // 466 | // @param staLIDVecRef State variable local IDs 467 | // 468 | // In general, devices may declare at construction that they require storage 469 | // locations in the "state vector." Topology assigns locations in the 470 | // state vector and returns "Local IDs" (LIDs) for devices to use for their 471 | // state vector entries. If a device uses state vector entries, it 472 | // uses the registerStateLIDs method to save the local IDs for later use. 473 | // 474 | // @author Robert Hoekstra, SNL, Parallel Computational Sciences 475 | // @date 06/12/02 476 | // 477 | void Instance::registerStateLIDs(const std::vector & staLIDVecRef) 478 | { 479 | AssertLIDs(staLIDVecRef.size() == numStateVars); 480 | } 481 | 482 | //----------------------------------------------------------------------------- 483 | // Function : Xyce::Device::MemristorKnowm::Instance::registerStoreLIDs 484 | // Purpose : 485 | // Special Notes : 486 | // Scope : public 487 | // Creator : Richard Schiek, Electrical Models & Simulations 488 | // Creation Date : 12/18/2012 489 | //----------------------------------------------------------------------------- 490 | // Register the local store IDs 491 | // 492 | // In addition to state vector, Xyce maintains a separate datastructure 493 | // called a "store" vector. As with other such vectors, the device 494 | // declares at construction time how many store vector entries it needs, 495 | // and later Topology assigns locations for devices, returning LIDs. 496 | // 497 | // 498 | // 499 | void Instance::registerStoreLIDs(const std::vector & stoLIDVecRef) 500 | { 501 | AssertLIDs(stoLIDVecRef.size() == getNumStoreVars()); 502 | li_store_R = stoLIDVecRef[0]; 503 | li_store_tdt = stoLIDVecRef[1]; 504 | } 505 | 506 | //----------------------------------------------------------------------------- 507 | // Function : Xyce::Device::MemristorKnowm::Instance::registerBranchDataLIDs 508 | // Purpose : 509 | // Special Notes : 510 | // Scope : public 511 | // Creator : Richard Schiek, Electrical Systems Modeling 512 | // Creation Date : 12/18/2012 513 | //----------------------------------------------------------------------------- 514 | // Register the local store IDs 515 | // 516 | // In addition to state vector, Xyce maintains a separate datastructure 517 | // called a "branch data" vector. As with other such vectors, the device 518 | // declares at construction time how many branch vector entries it needs, 519 | // and later Topology assigns locations for devices, returning LIDs. 520 | // 521 | // These LIDs are stored in this method for later use. 522 | // 523 | // The memristor device uses exactly one "branch data vector" element, where 524 | // it keeps the "lead current" that may be used on .PRINT lines as 525 | // "I(ymemristor)" for the current through ymemristor. and a junction voltage. 526 | // 527 | // @param stoLIDVecRef Store variable local IDs 528 | // 529 | // @author Richard Schiek, Electrical Systems Modeling 530 | // @date 12/18/2012 531 | void Instance::registerBranchDataLIDs(const std::vector & branchLIDVecRef) 532 | { 533 | AssertLIDs(branchLIDVecRef.size() == getNumBranchDataVars()); 534 | 535 | if (loadLeadCurrent) 536 | { 537 | li_branch_data= branchLIDVecRef[0]; 538 | } 539 | } 540 | 541 | //----------------------------------------------------------------------------- 542 | // Function : Instance::loadNodeSymbols 543 | // Purpose : 544 | // Special Notes : 545 | // Scope : public 546 | // Creator : Richard Schiek, Electrical Sysetms Modeling 547 | // Creation Date : 05/13/05 548 | //----------------------------------------------------------------------------- 549 | void Instance::loadNodeSymbols(Util::SymbolTable &symbol_table) const 550 | { 551 | addInternalNode(symbol_table, li_x, getName(), "x"); 552 | 553 | addStoreNode(symbol_table, li_store_R, getName(), "R"); 554 | addStoreNode(symbol_table, li_store_tdt, getName(), "TDT"); 555 | 556 | if (loadLeadCurrent) 557 | { 558 | addBranchDataNode( symbol_table, li_branch_data, getName(), "BRANCH_D"); 559 | } 560 | } 561 | 562 | //----------------------------------------------------------------------------- 563 | // Function : Xyce::Device::MemristorKnowm::Instance::registerJacLIDs 564 | // Purpose : 565 | // Special Notes : 566 | // Scope : public 567 | // Creator : Richard Schiek, Electrical Models & Simulations 568 | // Creation Date : 10/23/2014 569 | //----------------------------------------------------------------------------- 570 | // 571 | // Register the Jacobian local IDs 572 | // 573 | // @param jacLIDVec Jacobian local Ids 574 | // 575 | // @see Xyce::Device::MemristorKnowm::Instance::initializeJacobianStamp 576 | // 577 | // Having established local IDs for the solution variables, Topology must 578 | // also assign local IDs for the elements of the Jacobian matrix. 579 | // 580 | // For each non-zero element that was identified in the jacobianStamp, 581 | // Topology will assign a Jacobian LID. The jacLIDVec will have the 582 | // same structure as the JacStamp, but the values in the jacLIDVec will 583 | // be offsets into the row of the sparse Jacobian matrix corresponding 584 | // to the non-zero identified in the stamp. 585 | // 586 | // These offsets are stored in this method for use later when we load 587 | // the Jacobian. 588 | // 589 | // @author Robert Hoekstra, SNL, Parallel Computational Sciences 590 | // @date 08/27/01 591 | void Instance::registerJacLIDs(const std::vector< std::vector > & jacLIDVec) 592 | { 593 | // Let DeviceInstance do its work. 594 | DeviceInstance::registerJacLIDs(jacLIDVec); 595 | 596 | // Store offsets of the components of the Jacobian of this instance 597 | APosEquPosNodeOffset = jacLIDVec[0][0]; 598 | APosEquNegNodeOffset = jacLIDVec[0][1]; 599 | APosEquXNodeOffset = jacLIDVec[0][2]; 600 | ANegEquPosNodeOffset = jacLIDVec[1][0]; 601 | ANegEquNegNodeOffset = jacLIDVec[1][1]; 602 | ANegEquXNodeOffset = jacLIDVec[1][2]; 603 | XEquVPosOffset = jacLIDVec[2][0]; 604 | XEquVNegOffset = jacLIDVec[2][1]; 605 | XEquXOffset = jacLIDVec[2][2]; 606 | } 607 | 608 | //----------------------------------------------------------------------------- 609 | // Function : Xyce::Device::MemristorKnowm::Instance::setupPointers 610 | // Purpose : 611 | // Special Notes : 612 | // Scope : public 613 | // Creator : Richard Schiek, Electrical Models & Simulations 614 | // Creation Date : 10/23/2014 615 | //----------------------------------------------------------------------------- 616 | // 617 | // Setup direct access pointer to solution matrix and vectors. 618 | // 619 | // @see Xyce::Device::MemristorKnowm::Instance::registerJacLIDs 620 | // 621 | // As an alternative to the row offsets defined in registerJacLIDs, it 622 | // is also possible to obtain direct pointers of the Jacobian elements. 623 | // 624 | // This method uses the offsets obtained in registerJacLIDs to retrieve 625 | // the pointers. 626 | // 627 | // In this device the pointers to the matrix are only saved 628 | // (and are only used for matrix access) if 629 | // Xyce_NONPOINTER_MATRIX_LOAD is NOT defined at compile time. For 630 | // some devices the use of pointers instead of array indexing can be 631 | // a performance enhancement. 632 | // 633 | // Use of pointers in this device is disabled by defining 634 | // Xyce_NONPOINTER_MATRIX_LOAD at compile time. When disabled, array 635 | // indexing with the offsets from registerJacLIDs is used in 636 | // the matrix load methods. 637 | // 638 | // @author Eric Keiter, SNL 639 | // @date 11/30/08 640 | void Instance::setupPointers() 641 | { 642 | #ifndef Xyce_NONPOINTER_MATRIX_LOAD 643 | Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr); 644 | Linear::Matrix & dQdx = *(extData.dQdxMatrixPtr); 645 | f_PosEquPosNodePtr = &(dFdx[li_Pos][APosEquPosNodeOffset]); 646 | f_PosEquNegNodePtr = &(dFdx[li_Pos][APosEquNegNodeOffset]); 647 | f_PosEquXNodePtr = &(dFdx[li_Pos][APosEquXNodeOffset]); 648 | f_NegEquPosNodePtr = &(dFdx[li_Neg][ANegEquPosNodeOffset]); 649 | f_NegEquNegNodePtr = &(dFdx[li_Neg][ANegEquNegNodeOffset]); 650 | f_NegEquXNodePtr = &(dFdx[li_Neg][ANegEquXNodeOffset]); 651 | f_XEquPosNodePtr = &(dFdx[li_x][XEquVPosOffset]); 652 | f_XEquNegNodePtr = &(dFdx[li_x][XEquVNegOffset]); 653 | f_XEquXNodePtr = &(dFdx[li_x][XEquXOffset]); 654 | q_XEquXNodePtr = &(dQdx[li_x][XEquXOffset]); 655 | #endif 656 | } 657 | 658 | // The following 6 methods can just simply return true becuase the methods in the Master implementation cover this functionality. 659 | 660 | bool Instance::loadDAEQVector() 661 | { 662 | return true; 663 | } 664 | 665 | bool Instance::loadDAEFVector() 666 | { 667 | return true; 668 | } 669 | 670 | bool Instance::loadDAEdQdx() 671 | { 672 | return true; 673 | } 674 | 675 | bool Instance::loadDAEdFdx() 676 | { 677 | return true; 678 | } 679 | 680 | bool Instance::updatePrimaryState() 681 | { 682 | return true; 683 | } 684 | 685 | bool Instance::updateIntermediateVars() 686 | { 687 | return true; 688 | } 689 | 690 | //----------------------------------------------------------------------------- 691 | // Function : Xyce::Device::MemristorKnowm::Instance::updateTemperature 692 | // Purpose : 693 | // Special Notes : 694 | // Scope : public 695 | // Creator : Richard Schiek, Electrical Models & Simulations 696 | // Creation Date : 10/23/2014 697 | //----------------------------------------------------------------------------- 698 | // 699 | // Update the parameters that depend on the temperature of the device 700 | // 701 | // @param temp_tmp temperature 702 | // 703 | // Xyce has a number of mechanisms that allow temperature to be changed 704 | // after a device has been instantiated. These include .STEP loops over 705 | // temperature. When temperature is changed, any device that has parameters 706 | // that depend on temperature must be updated. That updating happens here. 707 | // 708 | // @return true on success 709 | // 710 | // @author Tom Russo, Component Information and Models 711 | // @date 02/27/01 712 | bool Instance::updateTemperature(const double & temp_tmp) 713 | { 714 | // TEMP; 715 | if (DEBUG_DEVICE){ 716 | Xyce::dout() << " temp_tmp = " << temp_tmp << std::endl; 717 | } 718 | return true; 719 | } 720 | 721 | //----------------------------------------------------------------------------- 722 | // Function : Xyce::Device::MemristorKnowm::Model::processParams 723 | // Purpose : 724 | // Special Notes : 725 | // Scope : public 726 | // Creator : Richard Schiek, Electrical Models & Simulations 727 | // Creation Date : 10/23/2014 728 | //----------------------------------------------------------------------------- 729 | // 730 | // Process model parameters 731 | // 732 | // @return true on success 733 | // 734 | // @author Eric Keiter, SNL, Parallel Computational Sciences 735 | // @date 6/03/02 736 | bool Model::processParams() 737 | { 738 | return true; 739 | } 740 | 741 | //---------------------------------------------------------------------------- 742 | // Function : Xyce::Device::MemristorKnowm::Model::processInstanceParams 743 | // Purpose : 744 | // Special Notes : 745 | // Scope : public 746 | // Creator : Richard Schiek, Electrical Models & Simulations 747 | // Creation Date : 10/23/2014 748 | //---------------------------------------------------------------------------- 749 | // 750 | // Process the instance parameters of instance owned by this model 751 | // 752 | // This method simply loops over all instances associated with this 753 | // model and calls their processParams method. 754 | // 755 | // @return true 756 | // 757 | // @author Dave Shirely, PSSI 758 | // @date 03/23/06 759 | bool Model::processInstanceParams() 760 | { 761 | for (InstanceVector::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it) 762 | { 763 | (*it)->processParams(); 764 | } 765 | 766 | return true; 767 | } 768 | 769 | //----------------------------------------------------------------------------- 770 | // Function : Xyce::Device::MemristorKnowm::Model 771 | // Purpose : model block constructor 772 | // Special Notes : 773 | // Scope : public 774 | // Creator : Richard Schiek, Electrical Models & Simulations 775 | // Creation Date : 10/23/2014 776 | //----------------------------------------------------------------------------- 777 | // 778 | // Construct a memristor model from a "model block" that was created 779 | // by the netlist parser. 780 | // 781 | // @param configuration 782 | // @param model_block 783 | // @param factory_block 784 | // 785 | // @author Eric Keiter, SNL, Parallel Computational Sciences 786 | // @date 5/16/00 787 | Model::Model( 788 | const Configuration & configuration, 789 | const ModelBlock & model_block, 790 | const FactoryBlock & factory_block) 791 | : DeviceModel(model_block, configuration.getModelParameters(), factory_block), 792 | Roff_(0.0), 793 | Ron_(0.0), 794 | Von_(0.0), 795 | Voff_(0.0), 796 | Tau_(0.0) 797 | { 798 | // Set params to constant default values. 799 | setDefaultParams(); 800 | 801 | // Set params according to .model line and constant defaults from metadata. 802 | setModParams(model_block.params); 803 | 804 | // Set any non-constant parameter defaults. 805 | //if (!given("TNOM")) 806 | // tnom = getDeviceOptions().tnom; 807 | 808 | // Calculate any parameters specified as expressions. 809 | updateDependentParameters(); 810 | 811 | // calculate dependent (ie computed) params and check for errors. 812 | processParams(); 813 | 814 | 815 | } 816 | 817 | //----------------------------------------------------------------------------- 818 | // Function : Xyce::Device::MemristorKnowm::Model::~Model 819 | // Purpose : destructor 820 | // Special Notes : 821 | // Scope : public 822 | // Creator : Richard Schiek, Electrical Models & Simulations 823 | // Creation Date : 10/23/2014 824 | //----------------------------------------------------------------------------- 825 | // 826 | // Destroy this model. 827 | // 828 | // Also destroys all instances that use this model. 829 | // 830 | // @author Eric Keiter, SNL, Parallel Computational Sciences 831 | // @date 3/16/00 832 | Model::~Model() 833 | { 834 | // Destory all owned instances 835 | for (InstanceVector::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it) 836 | { 837 | delete (*it); 838 | } 839 | } 840 | 841 | //----------------------------------------------------------------------------- 842 | // Function : N_DEV_MemristorKnowmModel::printOutInstances 843 | // Purpose : debugging tool. 844 | // Special Notes : 845 | // Scope : public 846 | // Creator : Richard Schiek, Electrical Models & Simulations 847 | // Creation Date : 10/23/2014 848 | //----------------------------------------------------------------------------- 849 | // 850 | // Print instances associated with this model. 851 | // 852 | // printOutInstances was intended as a debugging tool, but a refactor some time back took out all the places where this function would be called. 853 | // 854 | // @param os output stream 855 | // 856 | // @return reference to output stream 857 | // 858 | // @author Eric Keiter, SNL, Parallel Computational Sciences 859 | // @date 4/03/00 860 | // 861 | std::ostream &Model::printOutInstances(std::ostream &os) const 862 | { 863 | os << std::endl; 864 | os << "Number of MemristorKnowm Instances: " << instanceContainer.size() << std::endl; 865 | os << " name model name Parameters" << std::endl; 866 | 867 | int i = 0; 868 | for (InstanceVector::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it) 869 | { 870 | os << " " << i << ": " << (*it)->getName() << "\t"; 871 | os << getName(); 872 | os << "\tG(T) = " << (*it)->G; 873 | os << std::endl; 874 | ++i; 875 | } 876 | 877 | os << std::endl; 878 | 879 | return os; 880 | } 881 | 882 | //----------------------------------------------------------------------------- 883 | // Function : Model::forEachInstance 884 | // Purpose : 885 | // Special Notes : 886 | // Scope : public 887 | // Creator : Richard Schiek, Electrical Models & Simulations 888 | // Creation Date : 10/23/2014 889 | //----------------------------------------------------------------------------- 890 | // Apply a device instance "op" to all instances associated with this 891 | // model 892 | // 893 | // @param[in] op Operator to apply to all instances. 894 | // 895 | void Model::forEachInstance(DeviceInstanceOp &op) const /* override */ 896 | { 897 | for (std::vector::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it) 898 | op(*it); 899 | } 900 | 901 | double initialX( double rOn, double rOff, double rInit){ 902 | 903 | double x = (rOn * (rInit - rOff )) / (rInit * (rOn - rOff)); 904 | if(x== -0){ 905 | x = 0.0; 906 | } 907 | 908 | return x; 909 | } 910 | 911 | //----------------------------------------------------------------------------- 912 | // Function : Xyce::Device::MemristorKnowm::Master::updateState 913 | // Purpose : 914 | // Special Notes : 915 | // Scope : public 916 | // Creator : Richard Schiek, Electrical Models & Simulations 917 | // Creation Date : 10/23/2014 918 | //----------------------------------------------------------------------------- 919 | // 920 | // Update state for all memristor instances, regardless of model. 921 | // 922 | // @param solVec solution vector 923 | // @param staVec state vector 924 | // @param stoVec store vector 925 | // 926 | // @return true on success 927 | // 928 | // @see Xyce::Device::MemristorKnowm::Instance::updatePrimaryState 929 | // @author Eric Keiter, SNL 930 | // @date 11/26/08 931 | bool Master::updateState(double * solVec, double * staVec, double * stoVec) 932 | { 933 | 934 | // if (DEBUG_DEVICE){ 935 | // Xyce::dout() << " updateState " << std::endl; 936 | // } 937 | 938 | for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it) 939 | { 940 | Instance & ri = *(*it); 941 | 942 | double v_pos = solVec[ri.li_Pos]; 943 | double v_neg = solVec[ri.li_Neg]; 944 | double x = solVec[ri.li_x]; 945 | // if (DEBUG_DEVICE){ 946 | // Xyce::dout() << " x_before = " << x << std::endl; 947 | // } 948 | 949 | 950 | { 951 | Sacado::Fad::SFad varV1( 3, 0, v_pos ); 952 | Sacado::Fad::SFad varV2( 3, 1, v_neg ); 953 | Sacado::Fad::SFad varX( 3, 2, x ); 954 | Sacado::Fad::SFad resultFad; 955 | resultFad = I_V( varV1, varV2, varX, ri.model_.Ron_, ri.model_.Roff_, ri.model_.Phi_, ri.model_.SchottkyForwardAlpha_, ri.model_.SchottkyForwardBeta_, ri.model_.SchottkyReverseAlpha_, ri.model_.SchottkyReverseBeta_ ); 956 | 957 | ri.i0 = resultFad.val(); // current 958 | ri.G = resultFad.dx(0); // di/dv = conductance 959 | ri.dIdx = resultFad.dx(2); // di/dx 960 | 961 | // if (DEBUG_DEVICE){ 962 | // Xyce::dout() << " ri.i0 = " << ri.i0 << std::endl; 963 | // Xyce::dout() << " ri.G = " << ri.G << std::endl; 964 | // Xyce::dout() << " ri.dIdx = " << ri.dIdx << std::endl; 965 | // } 966 | } 967 | 968 | { 969 | // evaluate the state variable equation 970 | Sacado::Fad::SFad varV1( 3, 0, v_pos ); 971 | Sacado::Fad::SFad varV2( 3, 1, v_neg ); 972 | Sacado::Fad::SFad varX( 3, 2, x ); 973 | Sacado::Fad::SFad resultFad; 974 | 975 | double vT = 0.026; 976 | vT = ri.Temp_ * CONSTKoverQ; 977 | // if (DEBUG_DEVICE){ 978 | // Xyce::dout() << " vT = " << vT << std::endl; 979 | // } 980 | resultFad = dXdt( varV1, varV2, varX, ri.model_.Ron_, ri.model_.Roff_, ri.model_.Von_, ri.model_.Voff_, ri.model_.Tau_, vT ); 981 | 982 | ri.xVarFContribution = resultFad.val(); 983 | if( getSolverState().dcopFlag ) 984 | { 985 | ri.xVarFContribution = 0; 986 | } 987 | ri.dxFEqdVpos = resultFad.dx(0); 988 | ri.dxFEqdVneg = resultFad.dx(1); 989 | ri.dxFEqdx = resultFad.dx(2); 990 | 991 | // if (DEBUG_DEVICE){ 992 | // Xyce::dout() << " ri.xVarFContribution = " << ri.xVarFContribution << std::endl; 993 | // Xyce::dout() << " ri.dxFEqdVpos = " << ri.dxFEqdVpos << std::endl; 994 | // Xyce::dout() << " ri.dxFEqdVneg = " << ri.dxFEqdVneg << std::endl; 995 | // Xyce::dout() << " ri.dxFEqdx = " << ri.dxFEqdx << std::endl; 996 | // } 997 | 998 | } 999 | 1000 | } 1001 | 1002 | return true; 1003 | } 1004 | 1005 | //----------------------------------------------------------------------------- 1006 | // Function : Xyce::Device::MemristorYakopcic::Master::loadDAEVectors 1007 | // Purpose : 1008 | // Special Notes : 1009 | // Scope : public 1010 | // Creator : Richard Schiek, Electrical Models & Simulations 1011 | // Creation Date : 10/23/2014 1012 | //----------------------------------------------------------------------------- 1013 | // 1014 | // Load DAE vectors of all memristor instances, regardless of model 1015 | // 1016 | // @param solVec solution vector 1017 | // @param fVec f vector 1018 | // @param qVec q vector 1019 | // @param leadF store lead current f vector 1020 | // @param leadQ store lead current q vector 1021 | // 1022 | // @return true on success 1023 | // 1024 | // @note Because the memristor device re-implements the base-class 1025 | // Master::loadDAEVectors, the Instance::loadDAEFVector method is 1026 | // never called. This method replaces those, and does the same work 1027 | // but inside a loop over all memristor instances. 1028 | // 1029 | // @see Xyce::Device::MemristorYakopcic::Instance::loadDAEFVector 1030 | // 1031 | // @author Eric Keiter, SNL 1032 | // @date 11/26/08 1033 | 1034 | bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * bVec, double * leadF, double * leadQ, double * junctionV) 1035 | { 1036 | // if (DEBUG_DEVICE){ 1037 | // Xyce::dout() << "-loadDAEVectors" << std::endl; 1038 | // } 1039 | 1040 | for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it) 1041 | { 1042 | Instance & ri = *(*it); 1043 | fVec[ri.li_Pos] += ri.i0; 1044 | fVec[ri.li_Neg] += -ri.i0; 1045 | fVec[ri.li_x] += ri.xVarFContribution; 1046 | qVec[ri.li_x] -= solVec[ri.li_x]; 1047 | if( getSolverState().dcopFlag ) 1048 | { 1049 | double x = initialX(ri.model_.Ron_, ri.model_.Roff_, ri.R_init_); 1050 | qVec[ri.li_x] += x; 1051 | // if (DEBUG_DEVICE){ 1052 | // Xyce::dout() << "DCOP x = " << x << std::endl; 1053 | // } 1054 | } 1055 | if( ri.G != 0 ) 1056 | { 1057 | double * storeVec = ri.extData.nextStoVectorRawPtr; 1058 | storeVec[ri.li_store_R] = 1.0/ri.G; 1059 | } 1060 | 1061 | if( ri.loadLeadCurrent ) 1062 | { 1063 | leadF[ri.li_branch_data] = ri.i0; 1064 | junctionV[ri.li_branch_data] = solVec[ri.li_Pos] - solVec[ri.li_Neg]; 1065 | } 1066 | 1067 | } 1068 | return true; 1069 | } 1070 | 1071 | //----------------------------------------------------------------------------- 1072 | // Function : Xyce::Device::MemristorYakopcic::Master::loadDAEMatrices 1073 | // Purpose : 1074 | // Special Notes : 1075 | // Scope : public 1076 | // Creator : Richard Schiek, Electrical Models & Simulations 1077 | // Creation Date : 10/23/2014 1078 | //----------------------------------------------------------------------------- 1079 | // 1080 | // Load DAE matrices for all memristor instances, regardless of model 1081 | // 1082 | // @param dFdx matrix of derivatives of F vector with respect to solution 1083 | // @param dQdx matrix of derivatives of Q vector with respect to solution 1084 | // 1085 | // @return true on success 1086 | // 1087 | // @note Because the memristor device re-implements the base-class 1088 | // Master::loadDAEMatrices, the Instance::loadDAEdFdx method is 1089 | // never called. This method replaces those, and does the same work 1090 | // but inside a loop over all memristor instances. 1091 | // 1092 | // @see Xyce::Device::MemristorYakopcic::Instance::loadDAEdFdx 1093 | // 1094 | // @author Eric Keiter, SNL 1095 | // @date 11/26/08 1096 | 1097 | bool Master::loadDAEMatrices(Linear::Matrix & dFdx, Linear::Matrix & dQdx) 1098 | { 1099 | 1100 | // if (DEBUG_DEVICE){ 1101 | // Xyce::dout() << "-loadDAEMatrices" << std::endl; 1102 | // } 1103 | 1104 | for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it) 1105 | { 1106 | Instance & ri = *(*it); 1107 | 1108 | #ifndef Xyce_NONPOINTER_MATRIX_LOAD 1109 | 1110 | *(ri.f_PosEquPosNodePtr) += ri.G; 1111 | *(ri.f_PosEquNegNodePtr) -= ri.G; 1112 | *(ri.f_NegEquPosNodePtr) -= ri.G; 1113 | *(ri.f_NegEquNegNodePtr) += ri.G; 1114 | 1115 | *(ri.f_PosEquXNodePtr) += ri.dIdx; 1116 | *(ri.f_NegEquXNodePtr ) += ri.dIdx; 1117 | 1118 | *(ri.f_XEquPosNodePtr ) += ri.dxFEqdVpos; 1119 | *(ri.f_XEquNegNodePtr ) += ri.dxFEqdVneg; 1120 | *(ri.f_XEquXNodePtr ) += ri.dxFEqdx; 1121 | 1122 | *(ri.q_XEquXNodePtr ) = -1.0; 1123 | 1124 | #else 1125 | dFdx[ri.li_Pos][ri.APosEquPosNodeOffset] += ri.G; 1126 | dFdx[ri.li_Pos][ri.APosEquNegNodeOffset] -= ri.G; 1127 | dFdx[ri.li_Neg][ri.ANegEquPosNodeOffset] -= ri.G; 1128 | dFdx[ri.li_Neg][ri.ANegEquNegNodeOffset] += ri.G; 1129 | dFdx[ri.li_Pos][ri.APosEquXNodeOffset] += ri.dIdx; 1130 | dFdx[ri.li_Neg][ri.ANegEquXNodeOffset] += ri.dIdx; 1131 | dFdx[ri.li_x][ri.XEquVPosOffset] += ri.dxFEqdVpos; 1132 | dFdx[ri.li_x][ri.XEquVNegOffset] += ri.dxFEqdVneg; 1133 | dFdx[ri.li_x][ri.XEquXOffset] += ri.dxFEqdx; 1134 | dQdx[ri.li_x][ri.XEquXOffset] = -1.0; 1135 | #endif 1136 | } 1137 | 1138 | return true; 1139 | } 1140 | 1141 | //----------------------------------------------------------------------------- 1142 | // Function : Xyce::Device::MemristorKnowm::Traits::factory 1143 | // Purpose : 1144 | // Special Notes : 1145 | // Scope : public 1146 | // Creator : Richard Schiek, Electrical Models & Simulations 1147 | // Creation Date : 10/23/2014 1148 | //----------------------------------------------------------------------------- 1149 | // 1150 | // Create a new instance of the MemristorKnowm device. 1151 | // 1152 | // @param configuration 1153 | // @param factory_block 1154 | // 1155 | Device * Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block) 1156 | { 1157 | return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_); 1158 | } 1159 | 1160 | //----------------------------------------------------------------------------- 1161 | // Function : Xyce::Device::MemristorKnowm::registerDevice 1162 | // Purpose : 1163 | // Special Notes : 1164 | // Scope : public 1165 | // Creator : Richard Schiek, Electrical Models & Simulations 1166 | // Creation Date : 10/23/2014 1167 | //----------------------------------------------------------------------------- 1168 | // 1169 | // Define how to use the device in a netlist. 1170 | // 1171 | // This method is called from the Xyce::Device::registerOpenDevices 1172 | // function, which in turn is called by the device manager. 1173 | // 1174 | // The device is declared here to be an "memristor" device, which must 1175 | // take a model card of type "memristor". This device will correspond to model 1176 | // level 1 of memristor models. 1177 | void 1178 | registerDevice() 1179 | { 1180 | Config::addConfiguration() 1181 | .registerDevice("memristor", 5) 1182 | .registerModelType("memristor", 5); 1183 | } 1184 | 1185 | //----------------------------------------------------------------------------- 1186 | // Function : MemristorKnowmSensitivity::operator 1187 | // Purpose : produces df/dp and dq/dp, where p=R. 1188 | // Special Notes : 1189 | // Scope : public 1190 | // Creator : Richard Schiek, Electrical Models & Simulations 1191 | // Creation Date : 10/23/2014 1192 | //----------------------------------------------------------------------------- 1193 | void MemristorKnowmSensitivity::operator()( 1194 | const ParameterBase &entity, 1195 | const std::string & name, 1196 | std::vector & dfdp, 1197 | std::vector & dqdp, 1198 | std::vector & dbdp, 1199 | std::vector & Findices, 1200 | std::vector & Qindices, 1201 | std::vector & Bindices 1202 | ) const 1203 | { 1204 | const ParameterBase * e1 = &entity; 1205 | const Instance * in = dynamic_cast (e1); 1206 | 1207 | double * solVec = in->extData.nextSolVectorRawPtr; 1208 | double v_pos = solVec[in->li_Pos]; 1209 | double v_neg = solVec[in->li_Neg]; 1210 | 1211 | double dfdpLoc = -(v_pos-v_neg)*in->G*in->G; 1212 | 1213 | dfdp.resize(2); 1214 | dfdp[0] = +dfdpLoc; 1215 | dfdp[1] = -dfdpLoc; 1216 | 1217 | Findices.resize(2); 1218 | Findices[0] = in->li_Pos; 1219 | Findices[1] = in->li_Neg; 1220 | } 1221 | 1222 | } // namespace MemristorKnowm 1223 | } // namespace Device 1224 | } // namespace Xyce -------------------------------------------------------------------------------- /Knowm/Xyce/N_DEV_MemristorKnowm.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright Notice 3 | // 4 | // Additions/Modifications Copyright 2017 Tim Molter 5 | // 6 | // Copyright 2002 Sandia Corporation. Under the terms 7 | // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. 8 | // Government retains certain rights in this software. 9 | // 10 | // Xyce(TM) Parallel Electrical Simulator 11 | // Copyright (C) 2002-2016 Sandia Corporation 12 | // 13 | // This program is free software: you can redistribute it and/or modify 14 | // it under the terms of the GNU General Public License as published by 15 | // the Free Software Foundation, either version 3 of the License, or 16 | // (at your option) any later version. 17 | // 18 | // This program is distributed in the hope that it will be useful, 19 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | // GNU General Public License for more details. 22 | // 23 | // You should have received a copy of the GNU General Public License 24 | // along with this program. If not, see . 25 | //----------------------------------------------------------------------------- 26 | 27 | //----------------------------------------------------------------------------- 28 | // 29 | // Purpose : Implementation of the MSS memristor model. 30 | // 31 | // Creator : Tim Molter, Knowm Inc. 32 | // 33 | // Creation Date : 12/26/2016 34 | // 35 | //----------------------------------------------------------------------------- 36 | 37 | #ifndef Xyce_N_DEV_MemristorKnowm_h 38 | #define Xyce_N_DEV_MemristorKnowm_h 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | namespace Xyce { 49 | namespace Device { 50 | namespace MemristorKnowm { 51 | 52 | class Model; 53 | class Instance; 54 | 55 | // sensitivity functor 56 | // not yet implemented. 57 | class MemristorKnowmSensitivity : public baseSensitivity 58 | { 59 | public: 60 | MemristorKnowmSensitivity() : 61 | baseSensitivity() {}; 62 | 63 | virtual ~MemristorKnowmSensitivity() {}; 64 | 65 | virtual void operator()( 66 | const ParameterBase &entity, 67 | const std::string &name, 68 | std::vector & dfdp, 69 | std::vector & dqdp, 70 | std::vector & dbdp, 71 | std::vector & Findices, 72 | std::vector & Qindices, 73 | std::vector & Bindices 74 | ) const ; 75 | }; 76 | 77 | static MemristorKnowmSensitivity memrSens; 78 | 79 | struct Traits : public DeviceTraits 80 | { 81 | static const char *name() {return "MemristorKnowm";} 82 | static const char *deviceTypeName() {return "YMEMRISTOR level 5";} 83 | static int numNodes() {return 2;} 84 | static bool modelRequired() {return true;} 85 | static bool isLinearDevice() {return false;} 86 | 87 | static Device *factory(const Configuration &configuration, const FactoryBlock &factory_block); 88 | static void loadModelParameters(ParametricData &p); 89 | static void loadInstanceParameters(ParametricData &p); 90 | }; 91 | 92 | //----------------------------------------------------------------------------- 93 | // Class : Xyce::Device::MemristorKnowm::Instance 94 | // Purpose : 95 | // Special Notes : 96 | // Creator : Richard Schiek, Electrical Models & Simulations 97 | // Creation Date : 10/23/2014 98 | //----------------------------------------------------------------------------- 99 | // 100 | // MemristorKnowm device instance class. 101 | // 102 | // An instance is created for each occurance of the device in the netlist. 103 | // 104 | // It contains "unique" device information - ie stuff that will be 105 | // true of only one memristor in the circuit, such as the nodes to 106 | // which it is connected. A memristor is connected to only two 107 | // circuit nodes. 108 | // 109 | // This class does not directly contain information about its node 110 | // indices. It contains indices into the 5 parts (dFdx, dQdx, dx, F, 111 | // and Q) of the matrix problem A*dx = b, and also the solution 112 | // vector x. A is the Jacobian matrix that will be formed from dFdx 113 | // and d(dQ/dt)dx, dx is the update to x, and b is right hand side 114 | // function vector that will be formed from F and dQ/dt. These 115 | // indices are global, and determined by topology during the 116 | // initialization stage of execution. 117 | // 118 | class Instance : public DeviceInstance 119 | { 120 | friend class ParametricData; 121 | friend class Model; 122 | friend class Traits; 123 | friend class Master; 124 | friend class MemristorKnowmSensitivity; 125 | 126 | public: 127 | Instance( 128 | const Configuration & configuration, 129 | const InstanceBlock & instance_block, 130 | Model & model, 131 | const FactoryBlock & factory_block); 132 | 133 | //--------------------------------------------------------------------------- 134 | // Function : Xyce::Device::MemristorKnowm::Instance::~Instance 135 | // Purpose : destructor 136 | // Special Notes : 137 | // Scope : public 138 | // Creator : Richard Schiek, Electrical Models & Simulations 139 | // Creation Date : 10/23/2014 140 | //--------------------------------------------------------------------------- 141 | // 142 | // Destroys this instance 143 | // 144 | // @author Eric Keiter, SNL 145 | // @date 3/16/00 146 | ~Instance() {} 147 | 148 | private: 149 | Instance(const Instance &); 150 | Instance &operator=(const Instance &); 151 | 152 | public: 153 | 154 | //--------------------------------------------------------------------------- 155 | // Function : Xyce::Device::MemristorKnowm::Instance::getModel 156 | // Purpose : destructor 157 | // Special Notes : 158 | // Scope : public 159 | // Creator : Richard Schiek, Electrical Models & Simulations 160 | // Creation Date : 10/23/2014 161 | //--------------------------------------------------------------------------- 162 | // 163 | // Gets the resistor model that owns this instance. 164 | // 165 | // @return reference to the owning MemristorKnowm::Model 166 | // 167 | // @author David G. Baur Raytheon Sandia National Laboratories 1355 168 | // @date Mon Aug 12 08:36:37 2013 169 | Model &getModel() { return model_; } 170 | 171 | virtual void registerLIDs(const std::vector & intLIDVecRef, const std::vector & extLIDVecRef) /* override */; 172 | virtual void registerStateLIDs(const std::vector & staLIDVecRef) /* override */; 173 | virtual void registerStoreLIDs(const std::vector & stoLIDVecRef) /* override */; 174 | virtual void registerBranchDataLIDs(const std::vector & branchLIDVecRef) /* override */; 175 | virtual void registerJacLIDs(const std::vector< std::vector > & jacLIDVec) /* override */; 176 | 177 | void loadNodeSymbols(Util::SymbolTable &symbol_table) const; // override 178 | 179 | virtual bool processParams() /* override */; 180 | virtual bool updateTemperature(const double & temp_tmp) /* override */; 181 | virtual bool updateIntermediateVars() /* override */; 182 | virtual bool updatePrimaryState() /* override */; 183 | 184 | //--------------------------------------------------------------------------- 185 | // Function : Xyce::Device::MemristorKnowm::Instance::jacobianStamp 186 | // Purpose : 187 | // Special Notes : 188 | // Scope : public 189 | // Creator : Richard Schiek, Electrical Models & Simulations 190 | // Creation Date : 10/23/2014 191 | //--------------------------------------------------------------------------- 192 | // 193 | // Return Jacobian stamp that informs topology of the layout of the 194 | // resistor jacobian. 195 | // 196 | // The Jacobian stamp describes the shape of the Jacobian to the 197 | // Topology subsystem. The Topology subsystem, in turn, returns 198 | // the offsets into the matrix and solution vectors where this 199 | // instance data is located. 200 | // 201 | // @return const reference to a std::vector of std::vector of 202 | // integers describing Jacobian stamp shape 203 | // 204 | // @author Robert Hoekstra 205 | // @date 8/20/2001 206 | virtual const std::vector< std::vector > &jacobianStamp() const /* override */ { 207 | return jacStamp; 208 | } 209 | 210 | virtual bool loadDAEQVector() /* override */; 211 | virtual bool loadDAEFVector() /* override */; 212 | virtual bool loadDAEdQdx() /* override */; 213 | virtual bool loadDAEdFdx() /* override */; 214 | 215 | 216 | virtual void setupPointers() /* override */; 217 | 218 | private: 219 | static std::vector< std::vector > jacStamp; //< All MemristorKnowm instances have a common Jacobian Stamp 220 | static void initializeJacobianStamp(); 221 | 222 | Model & model_; //< Owning model 223 | 224 | // User-specified parameters: 225 | double R_init_; 226 | double Temp_; // instance temperature (TEMP) 227 | 228 | // Derived parameters: 229 | double G; //< Conductance(1.0/ohms) 230 | double dReffdvpos; //< derivative of Reff with respect to Vpos 231 | double dReffdvneg; //< derivative of Reff with respect to Vneg 232 | double dReffdx; //< derivative of Reff with respect to x 233 | double dIdx; //< derivative of I with respect to x 234 | double i0; //< Current(ohms) 235 | double xVarFContribution; //< x, internal variable for thickness of conductive layer, F-vector contribution 236 | double dxFEqdVpos; //< derivative of X F equation with respect to Vpos 237 | double dxFEqdVneg; //< derivative of X F equation with respect to Vneg 238 | double dxFEqdx; //< derivative of X F equation with respect to X 239 | 240 | int li_Pos; //< Index for Positive Node 241 | int li_Neg; //< Index for Negative Node 242 | int li_x; //< Index for internal x, thickness, variable 243 | int li_store_R; //< Index to store resistance value 244 | int li_store_tdt; //< Index to store for next RTN time time delta t 245 | int li_branch_data; //< Index for Lead Current and junction voltage (for power calculations) 246 | 247 | // Offset variables corresponding to the above declared indices. 248 | int APosEquPosNodeOffset; //< Column index into matrix of Pos/Pos conductance 249 | int APosEquNegNodeOffset; //< Column index into matrix of Pos/Neg conductance 250 | int APosEquXNodeOffset; //< Column index into matrix for internal varaible x, layer thickness 251 | int ANegEquPosNodeOffset; //< Column index into matrix of Neg/Pos conductance 252 | int ANegEquNegNodeOffset; //< Column index into matrix of Neg/Neg conductance 253 | int ANegEquXNodeOffset; //< Column index into matrix for internal varaible x, layer thickness 254 | int XEquVPosOffset; //< Thickness governing equation, VPos dependence 255 | int XEquVNegOffset; //< Thickness governing equation, VNeg dependence 256 | int XEquXOffset; //< Thickness variable, in thickness governing equation equation 257 | 258 | #ifndef Xyce_NONPOINTER_MATRIX_LOAD 259 | // Pointers for Jacobian 260 | double * f_PosEquPosNodePtr; 261 | double * f_PosEquNegNodePtr; 262 | double * f_PosEquXNodePtr; 263 | double * f_NegEquPosNodePtr; 264 | double * f_NegEquNegNodePtr; 265 | double * f_NegEquXNodePtr; 266 | double * f_XEquPosNodePtr; 267 | double * f_XEquNegNodePtr; 268 | double * f_XEquXNodePtr; 269 | double * q_XEquXNodePtr; 270 | # 271 | #endif 272 | 273 | }; 274 | 275 | 276 | //----------------------------------------------------------------------------- 277 | // Class : Xyce::Device::MemristorKnowm::Model 278 | // Purpose : 279 | // Special Notes : 280 | // Creator : Richard Schiek, Electrical Models & Simulations 281 | // Creation Date : 10/23/2014 282 | //----------------------------------------------------------------------------- 283 | // 284 | // MemristorKnowm model class 285 | // 286 | class Model : public DeviceModel 287 | { 288 | friend class ParametricData; //< Allow ParametricData to changes member values 289 | friend class Instance; //< Don't force a lot of pointless getters 290 | friend class Traits; 291 | friend class Master; //< Don't force a lot of pointless getters 292 | 293 | public: 294 | typedef std::vector InstanceVector; 295 | 296 | Model( 297 | const Configuration & configuration, 298 | const ModelBlock & model_block, 299 | const FactoryBlock & factory_block); 300 | ~Model(); 301 | 302 | private: 303 | Model(); 304 | Model(const Model &); 305 | Model &operator=(const Model &); 306 | 307 | public: 308 | 309 | //--------------------------------------------------------------------------- 310 | // Function : Xyce::Device::MemristorKnowm::Model::addInstance 311 | // Purpose : 312 | // Special Notes : 313 | // Scope : public 314 | // Creator : Richard Schiek, Electrical Models & Simulations 315 | // Creation Date : 10/23/2014 316 | //--------------------------------------------------------------------------- 317 | // 318 | // Add an instance to the list of instances associated with this model 319 | // 320 | // @author David G. Baur Raytheon Sandia National Laboratories 1355 321 | // @date 8/12/2013 322 | void addInstance(Instance *instance) 323 | { 324 | instanceContainer.push_back(instance); 325 | } 326 | 327 | virtual void forEachInstance(DeviceInstanceOp &op) const /* override */; 328 | 329 | virtual std::ostream &printOutInstances(std::ostream &os) const; 330 | 331 | virtual bool processParams() /* override */; 332 | virtual bool processInstanceParams() /* override */; 333 | 334 | private: 335 | InstanceVector instanceContainer; //< List of owned resistor instances 336 | 337 | // model parameters for Knowm model 338 | 339 | double Roff_; 340 | double Ron_; 341 | double Voff_; 342 | double Von_; 343 | double Tau_; 344 | 345 | // model parameters for generalized Knowm model 346 | 347 | double Phi_; 348 | double SchottkyForwardAlpha_; 349 | double SchottkyForwardBeta_; 350 | double SchottkyReverseAlpha_; 351 | double SchottkyReverseBeta_; 352 | }; 353 | 354 | 355 | //----------------------------------------------------------------------------- 356 | // Class : Xyce::Device::MemristorKnowm::Master 357 | // Purpose : 358 | // Special Notes : 359 | // Creator : Richard Schiek, Electrical Models & Simulations 360 | // Creation Date : 10/23/2014 361 | //----------------------------------------------------------------------------- 362 | // 363 | // MemristorKnowm master 364 | // 365 | // The "master" class is the one that contains the updateState, loadDAEVectors 366 | // and loadDAEMatrices methods that are actually called when it is time to 367 | // compute and load device contributions. 368 | // 369 | // The default implementations of these methods in the DeviceMaster 370 | // template class simply loops over all instances and calls their 371 | // updatePrimaryState, loadDAEFVector/loadDAEQVector, and 372 | // loadDAEdFdx/loadDAEdQdx methods, respectively. 373 | // 374 | // For efficiency, the MemristorKnowm class reimplements these methods to do the 375 | // work directly, instead of calling instance-level functions. 376 | // 377 | class Master : public DeviceMaster 378 | { 379 | friend class Instance; 380 | friend class Model; 381 | 382 | public: 383 | 384 | //--------------------------------------------------------------------------- 385 | // Function : Xyce::Device::MemristorKnowm::Master::Master 386 | // Purpose : 387 | // Special Notes : 388 | // Scope : public 389 | // Creator : Richard Schiek, Electrical Models & Simulations 390 | // Creation Date : 10/23/2014 391 | //--------------------------------------------------------------------------- 392 | // 393 | // Construct a MemristorKnowm Device. 394 | // 395 | // @param configuration 396 | // @param factory_block 397 | // @param solver_state 398 | // @param device_options 399 | Master( 400 | const Configuration & configuration, 401 | const FactoryBlock & factory_block, 402 | const SolverState & solver_state, 403 | const DeviceOptions & device_options) 404 | : DeviceMaster(configuration, factory_block, solver_state, device_options) 405 | {} 406 | 407 | virtual bool updateState(double * solVec, double * staVec, double * stoVec); 408 | virtual bool loadDAEVectors (double * solVec, double * fVec, double * qVec, double * bVec, double * leadF, double * leadQ, double * junctionV); 409 | virtual bool loadDAEMatrices(Linear::Matrix & dFdx, Linear::Matrix & dQdx); 410 | 411 | }; 412 | 413 | void registerDevice(); 414 | 415 | } // namespace MemristorKnowm 416 | } // namespace Device 417 | } // namespace Xyce 418 | 419 | #endif // Xyce_N_DEV_MemristorKnowm_h 420 | -------------------------------------------------------------------------------- /Knowm/Xyce/README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | 3 | | Model Class | Model Language | Simulator | 4 | |---|---|---| 5 | |Ill-formed|Native Xyce Device|Xyce| 6 | 7 | ## Instructions 8 | 9 | See: 10 | 11 | ## Sources 12 | 13 | 1. Original Source of MSS Model: 14 | 15 | ## How to Run Model 16 | 17 | Xyce /path/to/.../knowm.cir 18 | gnuplot 19 | plot '/path/to/.../knowm.cir.prn' using 3:4 with lines title "I-V" 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Knowm/Xyce/knowm.cir: -------------------------------------------------------------------------------- 1 | * Voltage Sources 2 | V1 1 0 SIN(0V 0.5V 100Hz) 3 | 4 | * Memristors 5 | YMEMRISTOR mr1 1 0 mrm1 R_init=500 6 | 7 | .MODEL mrm1 memristor (level=5 Roff=1500 Ron=500 Voff=0.27 Von=0.27 TAU=0.0001 PHI=0.8 SFA=0.0008 SFB=4 SRA=0.0008 SRB=4) 8 | 9 | * Analysis Command 10 | .TRAN .1ms .04s 11 | * Output 12 | .PRINT TRAN V(1) I(V1) N(YMEMRISTOR!mr1:R) 13 | 14 | .END -------------------------------------------------------------------------------- /Pershin/Ngspice/memristor.cir: -------------------------------------------------------------------------------- 1 | Memristor with threshold 2 | * Y. V. Pershin, M. Di Ventra: "SPICE model of memristive devices with threshold", 3 | * arXiv:1204.2600v1 [physics.comp-ph] 12 Apr 2012, 4 | * http://arxiv.org/pdf/1204.2600.pdf 5 | 6 | * Parameter selection and plotting by 7 | * Holger Vogt 2012 8 | 9 | .param stime=10n 10 | .param vmax = 3 11 | 12 | * send parameters to the .control section 13 | .csparam stime={stime} 14 | .csparam vmax={vmax} 15 | 16 | Xmem 1 0 memristor 17 | * triangular sweep (you have to adapt the parameters to 'alter' command in the .control section) 18 | *V1 1 0 DC 0 PWL(0 0 '0.25*stime' 'vmax' '0.5*stime' 0 '0.75*stime' '-vmax' 'stime' 0) 19 | * sinusoidal sweep 20 | V1 0 1 DC 0 sin(0 'vmax' '1/stime') 21 | 22 | * memristor model with limits and threshold 23 | * "artificial" parameters alpha, beta, and vt. beta and vt adapted to basic programming frequency 24 | * just to obtain nice results! 25 | * You have to care for the physics and set real values! 26 | .subckt memristor plus minus PARAMS: Ron=1K Roff=10K Rinit=7.0K alpha=0 beta=20e3/stime Vt=1.6 27 | Bx 0 x I='((f1(V(plus)-V(minus))> 0) && (V(x) < Roff)) ? {f1(V(plus)-V(minus))}: ((((f1(V(plus)-V(minus)) < 0) && (V(x)>Ron)) ? {f1(V(plus)-V(minus))}: 0)) ' 28 | Vx x x1 dc 0 29 | Cx x1 0 1 IC={Rinit} 30 | Rmem plus minus r={V(x)} 31 | .func f1(y)={beta*y+0.5*(alpha-beta)*(abs(y+Vt)-abs(y-Vt))} 32 | .ends 33 | 34 | * transient simulation same programming voltage but rising frequencies 35 | .control 36 | *** first simulation *** 37 | * approx. 100 simulation points 38 | let deltime = stime/100 39 | tran $&deltime $&stime uic 40 | plot i(v1) vs v(1) 41 | .endc 42 | 43 | .end -------------------------------------------------------------------------------- /Pershin/README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | 3 | | Model Class | Model Language | Simulator | 4 | |---|---|---| 5 | |SPICE Subcircuit|SPICE|NGSpice| 6 | 7 | ## Instructions 8 | 9 | See: 10 | 11 | ## Sources 12 | 13 | 1. Original Source of SPICE Model: 14 | 15 | ## Resources 16 | 17 | 1. The Pershin Voltage Threshold Memristor Model in NGSpice: -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | 3 | *WE DO NOT PROVIDE FREE TECHNICAL SUPPORT* 4 | 5 | This project aims to be a collaborative effort to collect under one roof memristor models published to date. We welcome contribution of your own models or implementations of other people's models. We also welcome any suggestions and/or corrections. This is a collaborative effort. 6 | 7 | There is no single definitive model of any memristor. Due to the fact that most memristor researchers do not provide their devices to others for test, models that currently exist in the literature are only accurate within limited ranges usually defined by the circuit the are a part of. 8 | 9 | This project may be useful for you whether you are trying to simulate other people's existing models or as a way to start your own model development, as these working examples can help get you up to speed quickly. If it was useful for you please consider adding your own working example by submitting a pull request with the model files and a README file. We hope that eventually this repository can be used to quantitatively compare and benchmark memristor models in terms of model accuracy, model robustness and simulation speed to name a few possibilities. 10 | 11 | ## Meta Stable Switch Memristor Model 12 | 13 | The MSS model was developed before the Knowm memristors were created. It is a general memristor model that can be tuned to model a wide range of devices, from deterministic to probabolistic and binary to continuous. However, it has its own limitations just as all other models currently do. You should feel free to use and adapt any memristor model to fit memristors that you can measure. You can find more information on the generalized MSS model here: 14 | 15 | https://knowm.org/the-generalized-metastable-switch-memristor-model/ 16 | 17 | Information on the 'mean field' continuous version can be found here: 18 | 19 | https://knowm.org/the-mean-metastable-switch-memristor-model-in-xyce/ 20 | 21 | ## Model Classes 22 | 23 | In order to bring some sort of ordering to the different types of memristor models and their implementations, here are three model classes we can use for easier classification. 24 | 25 | ### SPICE Subcircuit 26 | 27 | Around 2008, the first memristor models designed for SPICE started showing up. A [paper by Biolek et al.](http://www.radioeng.cz/fulltexts/2009/09_02_210_214.pdf) showed how to implement a memristor model in SPICE as a `.subckt`. I call this a "hacked" model because in order to implement it you are constrained in using only existing SPICE elements such as resistors, capacitors, and various specialized voltage and current sources, hacking together a model from these pieces. In a post on knowm.org: [The Joglekar Resistance Switch Memristor Model in LTSpice](http://knowm.org/the-joglekar-resistance-switch-memristor-model-in-ltspice/), the SPICE subcircuit method is explained in great detail, demonstrating a working model and simulation in LTSpice. 28 | 29 | ### Transient Limited 30 | 31 | In another class of models, the memristor is usually defined in a more flexible and less rigid and less "hacked" manner in a language such as Verliog-A, MATLAB or ModSPEC. In such simulation environments, you are given more or less a blank slate to formulate your model using the language's full API and methods. Inside your model implementation, you are given access to the global voltage drop across the device and from there you define the current though the device. You are also given the current simulation time, and you can use this to calculate how long a certain voltage was applied since the last time-step, important in modeling memristors given their memory behavior. It only works for transient analysis, not DC sweeps. 32 | 33 | ### Complete 34 | 35 | In this well-posed model class, the simulation will work for both transient and DC sweep. Problems are avoided by following a strict set of guidelines for avoiding common pitfalls. 36 | 37 | In May, 2016, Wang and Roychowdhury published a paper titled [Well-Posed Models of Memristive Devices](https://arxiv.org/abs/1605.04897), in which they plainly list out all of the problems with the current approaches and implementations of memristor models: 38 | 39 | > Common ill-posedness mechanisms in models include division-by-zero errors, often due to expressions like 1/(x−a), which become unbounded (and feature a “doubly infinite” jump) at x=a; the use of log(), 1/(x−a) or sqrt() without ensuring that their arguments are always positive, regardless of bias; the fundamental misconception that non-real (i.e., complex) numbers or infinity are legal values for device models (they are not!); and “sharp”/“pointy” functions like |x|, whose derivatives are not continuous. Another key aspect of well-posedness is that the model’s equations must produce mathematically valid outputs for any mathematically valid input to the device. Possibly the most basic kind of input is one that is constant (“DC”) for all time. DC solutions (“operating points”) are fundamental in circuit design; they are typically the kind of solution a designer seeks first of all, and are used as starting points for other analyses like transient, small signal AC, etc. If a model’s equations do not produce valid DC outputs given DC inputs, it fails a very fundamental well-posedness requirement. For example, the equation d/dt o(t) = i(t) is ill posed, since no DC (constant) solution for the output o(t) is possible if the input i(t) is any non-zero constant. Such ill posedness is typically indicative of some fundamental physical principle being violated; for example, in the case of d/dt o(t) = i(t), the system is not strictly stable. Indeed, a well-posed model that is properly written and implemented should work consistently in every analysis (including DC, transient, AC, etc.). 40 | 41 | ## Copyright 42 | 43 | Since this is a collection of people's published work and original work, we think the best keep track of copyrights by making sure to include in the model files the original copyright header or, if missing, adding one that makes a best effort to source the original copyright holder. If unknown, at least link to a source where the model was found. The README files are copyrighted by the original and contributor authors. 44 | 45 | -------------------------------------------------------------------------------- /University_of_Michigan/LTSpice/Circuit_UMich.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/University_of_Michigan/LTSpice/Circuit_UMich.png -------------------------------------------------------------------------------- /University_of_Michigan/LTSpice/README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | 3 | | Model Class | Model Language | Simulator | 4 | |---|---|---| 5 | |SPICE Subcircuit|SPICE|LTSpice| 6 | 7 | ## Sources 8 | 9 | 1. Original Source of SPICE Model: 10 | 11 | ## How to Run Model 12 | 13 | 1. LTSpice Intro - [The Joglekar Resistance Switch Memristor Model in LTSpice](http://knowm.org/the-joglekar-resistance-switch-memristor-model-in-ltspice/) 14 | 1. LTSpice - [Memristor Models in LTSpice](http://knowm.org/memristor-models-in-ltspice/) 15 | -------------------------------------------------------------------------------- /University_of_Michigan/LTSpice/UMich_IV.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/University_of_Michigan/LTSpice/UMich_IV.png -------------------------------------------------------------------------------- /University_of_Michigan/LTSpice/UMich_Time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/University_of_Michigan/LTSpice/UMich_Time.png -------------------------------------------------------------------------------- /University_of_Michigan/LTSpice/memristor_umich.sub: -------------------------------------------------------------------------------- 1 | * Memristor subcircuit developed by Chang et al. 2 | 3 | * Connections: 4 | * TE: Top electrode 5 | * BE: Bottom electrode 6 | * XSV: External connection to plot state variable 7 | * that is not used otherwise 8 | 9 | .SUBCKT MEM_UMICH TE BE XSV 10 | 11 | * Parameters: 12 | * alpha: Prefactor for Schottky barrier 13 | * beta: Exponent for Schottky barrier 14 | * gamma: Prefactor for tunneling 15 | * delta: Exponent for tunneling 16 | * xmax: Maximum value of state variable 17 | * xmin: Minimum value of state variable 18 | * drift_bit: Binary value to switch the ionic drift in (1) 19 | * or out (0) of the equation 20 | * lambda: State variable multiplier 21 | * eta1, eta2: State variable exponential rates 22 | * tau: Diffusion coefficient 23 | 24 | .param alpha=0.5e-6 beta=0.5 gamma=4e-6 delta=2 xmax=1 xmin=0 25 | +drift_bit = 0 lambda=4.5 eta1=0.004 eta2=4 tau=10 26 | 27 | .param cp={1} 28 | Cpvar XSV 0 {cp} 29 | 30 | * Rate equation for state variable 31 | Gx 0 XSV value={ trunc(V(TE,BE),cp*V(XSV))*lambda*(eta1*sinh(eta2*V(TE,BE))- 32 | +drift_bit*cp*V(XSV)/tau) } 33 | 34 | .ic V(XSV) = 0.0 35 | 36 | * Auxiliary functions to limit the range of x 37 | .func sign2(var) {(sgn(var)+1)/2} 38 | .func trunc(var1,var2) {sign2(var1)*sign2(xmax-var2)+sign2(- 39 | +var1)*sign2(var2-xmin)} 40 | 41 | * Memristor IV Relationship 42 | Gm TE BE value={(1-cp*V(XSV))*alpha*(1-exp(- 43 | +beta*V(TE,BE)))+(cp*V(XSV))*gamma*sinh(delta*V(TE,BE))} 44 | 45 | .ENDS MEM_UMICH -------------------------------------------------------------------------------- /University_of_Michigan/LTSpice/memristor_umich_sim.asc: -------------------------------------------------------------------------------- 1 | Version 4 2 | SHEET 1 880 680 3 | WIRE 416 0 16 0 4 | WIRE 416 16 416 0 5 | WIRE 16 32 16 0 6 | WIRE 16 144 16 112 7 | WIRE 224 144 16 144 8 | WIRE 416 144 416 112 9 | WIRE 416 144 224 144 10 | WIRE 224 192 224 144 11 | FLAG 224 192 0 12 | SYMBOL voltage 16 16 R0 13 | WINDOW 123 0 0 Left 2 14 | WINDOW 39 0 0 Left 2 15 | SYMATTR InstName V1 16 | SYMATTR Value SINE(0 1.0 1 0 0 0) 17 | SYMBOL memristor_with_state 416 64 R0 18 | SYMATTR InstName U1 19 | SYMATTR Value MEM_UMICH 20 | TEXT 120 -80 Left 2 !.tran 0 3s 21 | TEXT 112 -40 Left 1 !.lib memristor_umich.sub 22 | -------------------------------------------------------------------------------- /University_of_Michigan/LTSpice/memristor_umich_sim_IV.plt: -------------------------------------------------------------------------------- 1 | [Transient Analysis] 2 | { 3 | Npanes: 2 4 | Active Pane: 1 5 | { 6 | traces: 1 {336592898,0,"Ix(U1:TE)"} 7 | Parametric: "V(n001)" 8 | X: (' ',2,-1.2,0.02,1.2) 9 | Y[0]: ('m',1,-0.001,0.0002,0.0012) 10 | Y[1]: ('_',0,1e+308,0,-1e+308) 11 | Amps: ('m',0,0,1,-0.001,0.0002,0.0012) 12 | Log: 0 0 0 13 | NeyeDiagPeriods: 0 14 | TeyeEnd: 3 15 | }, 16 | { 17 | traces: 1 {268959747,0,"V(nc_01)"} 18 | Parametric: "V(n001)" 19 | X: (' ',2,-1.2,0.02,1.2) 20 | Y[0]: (' ',2,0.21,0.07,1.05) 21 | Y[1]: ('_',0,1e+308,0,-1e+308) 22 | Volts: (' ',0,0,2,0.21,0.07,1.05) 23 | Log: 0 0 0 24 | NeyeDiagPeriods: 0 25 | TeyeEnd: 3 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /University_of_Michigan/LTSpice/memristor_umich_sim_T.plt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/University_of_Michigan/LTSpice/memristor_umich_sim_T.plt -------------------------------------------------------------------------------- /Yakopcic/LTSpice/Circuit_Yakopcic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Yakopcic/LTSpice/Circuit_Yakopcic.png -------------------------------------------------------------------------------- /Yakopcic/LTSpice/README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | 3 | | Model Class | Model Language | Simulator | 4 | |---|---|---| 5 | |SPICE Subcircuit|SPICE|LTSpice| 6 | 7 | ## Sources 8 | 9 | 1. Original Source of SPICE Model: 10 | 11 | ## How to Run Model 12 | 13 | 1. LTSpice Intro - [The Joglekar Resistance Switch Memristor Model in LTSpice](http://knowm.org/the-joglekar-resistance-switch-memristor-model-in-ltspice/) 14 | 1. LTSpice - [Memristor Models in LTSpice](http://knowm.org/memristor-models-in-ltspice/) 15 | -------------------------------------------------------------------------------- /Yakopcic/LTSpice/Yakopcic_IV.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Yakopcic/LTSpice/Yakopcic_IV.png -------------------------------------------------------------------------------- /Yakopcic/LTSpice/Yakopcic_Time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Yakopcic/LTSpice/Yakopcic_Time.png -------------------------------------------------------------------------------- /Yakopcic/LTSpice/memristor_yakopcic.sub: -------------------------------------------------------------------------------- 1 | * SPICE model for memristive devices 2 | * Created by Chris Yakopcic 3 | * Last Update: 8/9/2011 4 | * 5 | * Connections: 6 | * TE - top electrode 7 | * BE - bottom electrode 8 | * XSV - External connection to plot state variable 9 | * that is not used otherwise 10 | 11 | .subckt MEM_YAKOPCIC TE BE XSV 12 | 13 | * Fitting parameters to model different devices 14 | * a1, a2, b: Parameters for IV relationship 15 | * Vp, Vn: Pos. and neg. voltage thresholds 16 | * Ap, An: Multiplier for SV motion intensity 17 | * xp, xn: Points where SV motion is reduced 18 | * alphap, alphan: Rate at which SV motion decays 19 | * xo: Initial value of SV 20 | * eta: SV direction relative to voltage 21 | 22 | *.params a1=0.17 a2=0.17 b=0.05 Vp=0.16 Vn=0.15 23 | *+Ap=4000 An=4000 xp=0.3 xn=0.5 alphap=1 alphan=5 24 | *+xo=0.11 eta=1 25 | 26 | .params a1=.17 a2=.17 b=0.05 Vp=.65 Vn=0.56 Ap=4000 27 | +An=4000 xp=0.3 xn=0.5 alphap=1 alphan=5 xo=0.11 eta=1 28 | 29 | * Multiplicitive functions to ensure zero state 30 | * variable motion at memristor boundaries 31 | .func wp(V) = xp/(1-xp) - V/(1-xp) + 1 32 | .func wn(V) = V/(1-xn) 33 | 34 | * Function G(V(t)) - Describes the device threshold 35 | .func G(V) = IF(V <= Vp, IF(V >= -Vn, 0, -An*(exp(- 36 | +V)-exp(Vn))), Ap*(exp(V)-exp(Vp))) 37 | 38 | * Function F(V(t),x(t)) - Describes the SV motion 39 | .func F(V1,V2) = IF(eta*V1 >= 0, IF(V2 >= xp, exp(- 40 | +alphap*(V2-xp))*wp(V2) ,1), IF(V2 <= (1-xn), 41 | +exp(alphan*(V2+xn-1))*wn(V2) ,1)) 42 | 43 | * IV Response - Hyperbolic sine due to MIM structure 44 | .func IVRel(V1,V2) = IF(V1 >= 0, a1*V2*sinh(b*V1), 45 | +a2*V2*sinh(b*V1) ) 46 | 47 | * Circuit to determine state variable 48 | * dx/dt = F(V(t),x(t))*G(V(t)) 49 | Cx XSV 0 {1} 50 | .ic V(XSV) = xo 51 | Gx 0 XSV value={eta*F(V(TE,BE),V(XSV,0))*G(V(TE,BE))} 52 | * Current source for memristor IV response 53 | Gm TE BE value = {IVRel(V(TE,BE),V(XSV,0))} 54 | 55 | .ends MEM_YAKOPCIC -------------------------------------------------------------------------------- /Yakopcic/LTSpice/memristor_yakopcic_sim.asc: -------------------------------------------------------------------------------- 1 | Version 4 2 | SHEET 1 880 680 3 | WIRE 416 0 16 0 4 | WIRE 416 16 416 0 5 | WIRE 16 32 16 0 6 | WIRE 16 144 16 112 7 | WIRE 224 144 16 144 8 | WIRE 416 144 416 112 9 | WIRE 416 144 224 144 10 | WIRE 224 192 224 144 11 | FLAG 224 192 0 12 | SYMBOL voltage 16 16 R0 13 | WINDOW 123 0 0 Left 2 14 | WINDOW 39 0 0 Left 2 15 | SYMATTR InstName V1 16 | SYMATTR Value SINE(0 1.0 10 0 0 0) 17 | SYMBOL memristor_with_state 416 64 R0 18 | SYMATTR InstName U1 19 | SYMATTR Value MEM_YAKOPCIC 20 | TEXT 120 -80 Left 2 !.tran 0 .2s 21 | TEXT 112 -40 Left 1 !.lib memristor_yakopcic.sub 22 | -------------------------------------------------------------------------------- /Yakopcic/LTSpice/memristor_yakopcic_sim_IV.plt: -------------------------------------------------------------------------------- 1 | [Transient Analysis] 2 | { 3 | Npanes: 2 4 | Active Pane: 1 5 | { 6 | traces: 1 {336592898,0,"Ix(U1:TE)"} 7 | Parametric: "V(n001)" 8 | X: (' ',2,-1.2,0.02,1.2) 9 | Y[0]: ('m',1,-0.001,0.0002,0.0012) 10 | Y[1]: ('_',0,1e+308,0,-1e+308) 11 | Amps: ('m',0,0,1,-0.001,0.0002,0.0012) 12 | Log: 0 0 0 13 | NeyeDiagPeriods: 0 14 | TeyeEnd: 3 15 | }, 16 | { 17 | traces: 1 {268959747,0,"V(nc_01)"} 18 | Parametric: "V(n001)" 19 | X: (' ',2,-1.2,0.02,1.2) 20 | Y[0]: (' ',2,0.21,0.07,1.05) 21 | Y[1]: ('_',0,1e+308,0,-1e+308) 22 | Volts: (' ',0,0,2,0.21,0.07,1.05) 23 | Log: 0 0 0 24 | NeyeDiagPeriods: 0 25 | TeyeEnd: 3 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Yakopcic/LTSpice/memristor_yakopcic_sim_T.plt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowm/memristor-models-4-all/b6a11f46f96dc743aa7fae0bf8985e708d1f3832/Yakopcic/LTSpice/memristor_yakopcic_sim_T.plt -------------------------------------------------------------------------------- /Yakopcic/Xyce/README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | 3 | | Model Class | Model Language | Simulator | 4 | |---|---|---| 5 | |Ill-formed|Native Xyce Device|Xyce| 6 | 7 | ## Instructions 8 | 9 | See: 10 | 11 | ## Sources 12 | 13 | 1. Original Source of Yakopcic Model: 14 | 15 | ## How to Run Model 16 | 17 | Xyce /path/to/.../yakopcic.cir 18 | gnuplot 19 | plot '/path/to/.../yakopcic.cir.prn' using 3:4 with lines title "I-V" 20 | -------------------------------------------------------------------------------- /Yakopcic/Xyce/yakopcic.cir: -------------------------------------------------------------------------------- 1 | * Voltage Sources 2 | V1 1 0 SIN(0V 1.2V 1Hz) 3 | 4 | * Memristors 5 | ymemristor mr1 1 0 mrm1 6 | 7 | 8 | .MODEL mrm1 memristor level=3 a1=0.17 a2=0.17 b=0.05 vp=0.16 vn=0.15 9 | + ap=4000 an=4000 xp=0.3 xn=0.5 alphap=1 alphan=5 eta=1 10 | 11 | 12 | * Analysis Command 13 | .TRAN 1ms 1s 14 | * Output 15 | .PRINT TRAN V(1) I(V1) 16 | 17 | .END -------------------------------------------------------------------------------- /knowm_model_modified_verilogA_code: -------------------------------------------------------------------------------- 1 | 2 | --------------------------------------------------------------------------------