The Designer's Guide Community Forum
https://designers-guide.org/forum/YaBB.pl
Modeling >> Behavioral Models >> Fully Differential Opamp MacroModel in Cadence
https://designers-guide.org/forum/YaBB.pl?num=1503793304

Message started by repah on Aug 26th, 2017, 5:21pm

Title: Fully Differential Opamp MacroModel in Cadence
Post by repah on Aug 26th, 2017, 5:21pm

I am trying to design a fully differential opamp (infinite gain, infinite bandwidth) with Cadence to simulate a Discrete Time Sigma Delta Modulator at the system level.

What is best to use ?  A Verilog model ? or Controlled sources - VCCS etc.

Does anyone have any examples of controlled source model macromodels for a fully differential opamp ?

Thank you.

Title: Re: Fully Differential Opamp MacroModel in Cadence
Post by davidshw on Aug 28th, 2017, 6:25pm

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



Title: Re: Fully Differential Opamp MacroModel in Cadence
Post by Geoffrey_Coram on Sep 5th, 2017, 6:01am

Hi, davidshw -
Thanks for posting that code. I'd recommend a few tweaks:

- combine the port declarations:
output VOP, VOM;
input VP, VM, VCM, VDD, VSS;
electrical VOP, VOM, VP, VM, VCM, VDD, VSS;

- remove the "@initial_step" condition: instead of

                 @ ( initial_step or initial_step("dc") ) begin
                 cc=1p;            // compensation cap
                 co1 = 1f ;      //1st stage output cap
                 co2 = 1f ;      //2nd stage output cap

just have

                 begin
                 cc=1p;            // compensation cap
                 co1 = 1f ;      //1st stage output cap
                 co2 = 1f ;      //2nd stage output cap

Otherwise the simulator may think it needs to set up special storage to handle remembering those values from timepoint to timepoint.

It actually seems to me that those capacitance values ought to be parameters rather than hard-coded numbers.

The Designer's Guide Community Forum » Powered by YaBB 2.2.2!
YaBB © 2000-2008. All Rights Reserved.