马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
小弟初学VerilogA,从一本书上摘了个VerilogA的全差分运放的代码,结果用仿真其小信号观察其幅频相频特性时,发现放大器的两个输出端输出结果不一样,vout_p正确,vout_n有问题,感觉像是多了一些零极点。看了半天也没发现哪里有问题,求大神帮忙。另外,代码最后有一段(soft output limiting)是描述直流电压输出范围的代码,看不明白,麻烦给解释一下。
`include "discipline.h" `include "constants.h"
module diff_opamp(vout_p,vout_n,vref,vin_p,vin_n,vsupply_p,vsupply_n); input vref,vsupply_p,vsupply_n; inout vout_p,vout_n,vin_p,vin_n; parameter
freq_unitygain=1e6; parameter
gain=1000; parameter
r_in=10e6; parameter
i_bias=0; parameter
r_out=100; parameter real
iin_max=100e-6; parameter real
slew_rate=20e6; parameter
vin_offset=0; parameter
vsoft=0.5; real
gm_nom; real
vmax_in; real
vin_al,c1,r1; electrical vout_p,vout_n,vref,vin_p,vin_n,vsupply_n,vsupply_p; electrical cout_n,cout_p;
//
branch (cout_n,vref) cap_n;
//
branch (cout_p,vref) cap_p;
analog begin
@(initial_step or initial_step("dc"))begin
c1=iin_max/slew_rate;
gm_nom=2*3.14*freq_unitygain*c1;
r1=gain/gm_nom;
vmax_in=iin_max/gm_nom;
end
//
//input stage
//
V(vref)<+ V(vsupply_n)+0.5*V(vsupply_p,vsupply_n);
vin_al=V(vin_p,vin_n)/2+vin_offset;
I(vref,vin_n)<+i_bias;
I(vref,vin_p)<+i_bias;
I(vin_p,vin_n)<+V(vin_p,vin_n)/r_in+vin_offset/r_in;
//
//GM stage with slew rating
//
I(cout_n,vref)<+ V(cout_n,vref)/100e6;
I(cout_p,vref)<+ V(cout_p,vref)/100e6;
if(vin_al>vmax_in)begin
I(vref,cout_p)<+ iin_max;
I(vref,cout_n)<+ -iin_max;
end
else if(vin_al<-vmax_in)begin
I(vref,cout_p)<+ -iin_max;
I(vref,cout_n)<+
iin_max;
end
else begin
I(vref,cout_p)<+0.5*gm_nom*vin_al;
I(vref,cout_n)<+ -0.5*gm_nom*vin_al;
end
//
//dominate pole
//
//
V(cap_n)<+idt(I(cap_n))/c1;
//
V(cap_p)<+idt(I(cap_p))/c1;
I(vref,cout_n)<+ c1*ddt(V(vref,cout_n));
I(vref,cout_p)<+ c1*ddt(V(vref,cout_p));
I(vref,cout_n)<+ V(vref,cout_n)/r1;
I(vref,cout_p)<+ V(vref,cout_p)/r1;
//
//output stage
//
I(vout_n,vref)<+ V(vref,cout_n)/r1;
I(vout_n,vref)<+ V(vout_n,vref)/r1;
I(vout_p,vref)<+ V(vref,cout_p)/r1;
I(vout_p,vref)<+ V(vout_p,vref)/r1;
//
//soft output limiting
//
if(V(vout_p)>(V(vsupply_p)-vsoft))begin
I(cout_p,vref)<+gm_nom*(V(vout_p,vsupply_p)+vsoft);
end
else if(V(vout_p)<(V(vsupply_n)+vsoft))begin
I(cout_p,vref)<+gm_nom*(V(vout_p,vsupply_n)-vsoft);
end
if(V(vout_n)>(V(vsupply_n)-vsoft))begin
I(cout_n,vref)<+gm_nom*(V(vout_n,vsupply_p)+vsoft);
end
else if(V(vout_n)<(V(vsupply_n)+vsoft))begin
I(cout_n,vref)<+gm_nom*(V(vout_n,vsupply_n)-vsoft);
end
end endmodule |