blob: 6e2c0b8cd38ab85eb5dbc231b4a127100149a9f5 [file] [log] [blame]
// Copyright 2020 The SkyWater PDK Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
`include "constants.vams"
`include "disciplines.vams"
module sky130_fd_pr_reram__reram_cell(TE, BE);
inout TE; // top electrode
inout BE; // bottom electrode
electrical TE, BE;
// ==================================================
// input parameters
// --------------------------------------------------
// physical area and thickness
parameter real area_ox = 0.1024e-12 from (0:inf); // area of TE/BE overlap [meters^2]
parameter real Tox = 5.0e-9 from (0:inf); // thickness of oxide between TE and BE [meters]
parameter real Tfilament_max = 4.9e-9 from (0:inf); // maximum thickness of conductive filament (for minimum resistance) [meters]
parameter real Tfilament_min = 3.3e-9 from (0:inf); // minimum thickness of conductive filament (for maximum resistance) [meters]
parameter real Tfilament_0 = 3.3e-9 from [Tfilament_min:Tfilament_max]; // initial thickness of conductive filament (at t=0 for transient simulation) [meters]
// activation energy
parameter real Eact_generation = 1.501 from (0:inf); // activation energy for vacancy generation [eV]
parameter real Eact_recombination = 1.500 from (0:inf); // activation energy for vacancy recombination [eV]
// calibration parameters: I-V
parameter real I_k1 = 6.140e-5 from (0:inf); // current calibration parameter [Amps]
parameter real Tfilament_ref = 4.7249e-9 from (0:inf); // filament thickness calibration parameter [meters]
parameter real V_ref = 0.430 from (0:inf); // voltage calibration parameter [Volts]
// calibration parameters: filament growth
parameter real velocity_k1 = 150 from (0:inf); // velocity calibration parameter [meters/second]
parameter real gamma_k0 = 16.5 from (0:inf); // enhancement factor calibration parameter [unitless]
parameter real gamma_k1 = -1.25 from (-inf:inf); // enhancement factor calibration parameter [unitless]
// calibration parameters: temperature
parameter real Temperature_0 = 300 from (0:inf); // intial temperature [degrees Kelvin]
parameter real C_thermal = 3.1825e-16 from (0:inf); // effective thermal capacitance [Joules/Kelvin]
parameter real tau_thermal = 0.23e-9 from (0:inf); // effective thermal time constant [seconds]
// simulation control
parameter real t_step = 1.0e-9 from (0:inf); // maximum time step [seconds]
// ==================================================
// internal parameters
parameter real a0 = 0.25e-9; // atomic distance [m]
real Tfilament_current; // current filament thickness [m]
real Tfilament_dTdt; // current filament thickness, derivative w.r.t. time [m/s]
real gamma; // local enhancement factor
real Temperature_current; // current temperature
real kT_over_q; // e.g., 0.0259 at 300 degrees K [eV]
// transient simulation parameters
real t_current; // current time step [s]
real t_previous; // previous time step [s]
real t_delta; // difference between current vs. previous time step
real iout;
// local functions
analog function real soft_minmax;
input x, xmin, xmax;
real x, xmin, xmax;
begin
if (x > xmax) begin
soft_minmax = xmax;
end else if (x < xmin) begin
soft_minmax = xmin;
end else begin
soft_minmax = x;
end
end
endfunction // soft_minmax
// core equations
analog begin
@(initial_instance) begin
// initial condition
$strobe("ReRAM inital instance");
Temperature_current = Temperature_0;
Tfilament_current = Tfilament_0;
end
$bound_step(t_step); // bound maximum time step
t_current = $abstime; // current time
t_delta = t_current - t_previous;
gamma = gamma_k0 + gamma_k1 * pow((Tox - Tfilament_current)/1.0e-9, 3);
kT_over_q = (`P_K * Temperature_current) / `P_Q;
Tfilament_dTdt = velocity_k1 * (exp(-Eact_generation / kT_over_q) * exp( gamma * a0/Tox * V(TE,BE) / kT_over_q) -
exp(-Eact_recombination / kT_over_q) * exp(-gamma * a0/Tox * V(TE,BE) / kT_over_q));
Tfilament_current = Tfilament_current + Tfilament_dTdt * t_delta; // 1st-order update to filament thickness
Tfilament_current = soft_minmax(Tfilament_current, Tfilament_min, Tfilament_max); // bound filament thickness
I(TE,BE) <+ I_k1 * exp(-(Tox - Tfilament_current)/(Tox - Tfilament_ref)) * sinh( V(TE,BE)/V_ref );
Temperature_current = (Temperature_current + t_delta * (abs(V(TE,BE)*I(TE,BE)) / C_thermal + Temperature_0/tau_thermal))
/ (1 + t_delta/tau_thermal); // 1st-order update to temperature
//Temperature_current = 300;
t_previous = $abstime; // current time step is previous time step for next iteration
end
endmodule