I am trying to build up a basic non-ideal opamp model in Verilog A and am having trouble understanding why my implementation of the voltage limiting doesn't function as I would expect it to(credit given to a model I saw somewhere that use an identical idea).
Specifically, when I run a DC sweep from -20 to 20(where vss=-15 and vdd=15), I observe ideal behavior. Any explanations/help would be very appreciated.
Code:`include "constants.vams"
`include "disciplines.vams"
module ideal_opamp_va (vp, vn, vdd, vss, vout);
input vdd, vss, vn, vp;
output vout;
electrical vdd, vss, vn, vp, vout;
parameter real rin = 1M from (0:inf), //Input Resistance
g = 50000 from (0:inf), //Large Signal Voltage Gain
threedb=1M from (0:inf), //3dB Frequency
imax = 10m from (0:inf), //Maximum Ouput Current
ro = 50 from (0:inf); //Output Resistance
real vo_freq, io, vo, vomax, vomin;
analog begin
//definitions
vo = V(vout);
vomax = V(vdd);
vomin = V(vss);
//input current
I(vp,vn) <+ V(vp,vn)/rin + white_noise(4 * `P_K * $temperature/rin, "thermal") + flicker_noise(4 * `P_K * $temperature/rin, 1, "pink");
//frequency response
vo_freq = laplace_nd(V(vp,vn)*g, {1}, {1, 1/(`M_TWO_PI*threedb)});
//output current
io = (vo_freq-V(vout))/ro;
// limit output voltage
if (V(vout) >= 0)
io = io*tanh((vomax-V(vout)));
else
io = io*tanh(abs(vomin-V(vout)));
//output current limit
if (I(vout) > imax)
io = imax;
if (I(vout) < -imax)
io = -imax;
I(vout) <+ slew(io,threedb*imax);
end
endmodule