here is a verilog-a model for you reference.
Code:// VerilogA of Two-stage Differential OTA
`include "constants.vams"
`include "disciplines.vams"
module opamp_diff_2stage(VOP, VOM, VP, VM, VCM, VDD,VSS);
output VOP;
electrical VOP;
output VOM;
electrical VOM;
input VM;
electrical VM;
input VP;
electrical VP;
input VCM; //output common-mode voltage
electrical VCM;
input VDD,VSS;
electrical VDD,VSS;
parameter real gain = 1e6 ; //dc gain
parameter real f0 = 1e7 ; //0dB BW of 1st-pole system with cload;
parameter real f2 = 10e7 ; //non-domainant pole of two-stage ota
parameter real cload = 1p ; //OTA output loading capacitance;
parameter real ro2 = 100e3 ; //2nd stage ota output res
parameter real cicm = 10f ; //1st stage cm cap
parameter real vod_diff = 0.2 ; //input stage MOS over-drive voltage
parameter real vsoft= 0.1 ; //output soft limit voltage (vdsat)
real gm1,gm2,ro1,vin_max,iin_max,idiff,gain1,gain2,slew_rate, satp,satn;
real rout1, gout1 ;
real rout2, gout2;
real co1,co2,cc, tmp;
electrical VMID, VO1P, VO1M, VBUFP, VBUFM, VOCM;
real gain_cmfb, gm_cmfb ;
analog begin
@ ( initial_step or initial_step("dc") ) begin
cc=1p; // compensation cap
co1 = 1f ; //1st stage output cap
co2 = 1f ; //2nd stage output cap
gm1=2*`M_PI*f0*cc;
gm2=2*`M_PI*f2*(co2+cload);
ro1=gain/(gm1*gm2*ro2);
gain1=gm1*ro1;
gain2=gm2*ro2;
iin_max=gm1*vod_diff;
vin_max=iin_max/gm1;
slew_rate=iin_max/cc; //=2*`M_PI*f0*vod_diff;
gain_cmfb=10*gain;
gm_cmfb=gain_cmfb/(ro1*gm2*ro2);
end
V(VMID)<+ (V(VDD)+V(VSS))/2;
//input cap
I(VP)<+cicm*ddt(V(VP));
I(VM)<+cicm*ddt(V(VM));
// diff input stage current limit
if(V(VP,VM)>vin_max) idiff=iin_max;
else if(V(VP,VM)<-vin_max) idiff=-iin_max;
else idiff=gm1*V(VP,VM);
// output stage saturation
if(vsoft>0) begin
if(abs(V(VOP,VMID))<V(VDD,VMID)-vsoft) satp=1;
else if(abs(V(VOP,VMID))>V(VDD,VMID)) satp=0;
else begin
tmp= (V(VDD,VMID)-abs(V(VOP,VMID)))/vsoft;
satp= 3*pow(tmp,2)-2*pow(tmp,3);
end
end
else satp = 1;
if(vsoft>0) begin
if(abs(V(VOM,VMID))<V(VDD,VMID)-vsoft) satn=1;
else if(abs(V(VOM,VMID))>V(VDD,VMID)) satn=0;
else begin
tmp= (V(VDD,VMID)-abs(V(VOM,VMID)))/vsoft;
satn= 3*pow(tmp,2)-2*pow(tmp,3);
end
end
else satn = 1;
gout2 = gm2 -(gm2-1/ro2)*min(satp,satn);
rout2 = 1/gout2;
gout1 = gm1 -(gm1-1/ro1)*min(satn,satp);
rout1 = 1/gout1;
// 1st-stage ota
I(VMID,VO1P)<+ idiff/2;
I(VMID,VO1P)<+ co1*ddt(V(VMID,VO1P));
I(VMID,VO1P)<+ 1/rout1*V(VMID,VO1P);
I(VMID,VO1M)<+ -idiff/2;
I(VMID,VO1M)<+ co1*ddt(V(VMID,VO1M));
I(VMID,VO1M)<+ 1/rout1*V(VMID,VO1M);
// 2nd stage ota output
I(VMID,VOP)<+ -gm2*V(VO1M,VMID);
I(VMID,VOP)<+ co2*ddt(V(VMID,VOP)) ;
I(VMID,VOP)<+ 1/rout2*V(VMID,VOP);
I(VMID,VOM)<+ -gm2*V(VO1P,VMID);
I(VMID,VOM)<+ co2*ddt(V(VMID,VOM)) ;
I(VMID,VOM)<+ 1/rout2*V(VMID,VOM);
// miller compensation cap with buffer
V(VBUFP)<+V(VOP);
I(VO1M,VBUFP)<+ cc*ddt(V(VO1M,VBUFP)) ;
V(VBUFM)<+V(VOM);
I(VO1P,VBUFM)<+ cc*ddt(V(VO1P,VBUFM)) ;
// CMFB
V(VOCM)<+(V(VOP)+V(VOM))/2;
I(VMID,VO1P)<+ gm_cmfb*V(VOCM,VCM);
I(VMID,VO1M)<+ gm_cmfb*V(VOCM,VCM);
end
endmodule