The Designer's Guide Community
Forum
Welcome, Guest. Please Login or Register. Please follow the Forum guidelines.
May 19th, 2024, 4:19am
Pages: 1
Send Topic Print
verilog-A opamp output limiting (Read 17436 times)
seanpai
New Member
*
Offline



Posts: 6

verilog-A opamp output limiting
Apr 20th, 2012, 6:44pm
 
Hi guys, I am doing an opamp behavior model for my LDO. And when I want to limit my output, there is a error in my simulation. It looks like a discontinuity problem. I don't know how to resolve this problem, so can anyone give me some suggestions? My code is showed below.
// VerilogA for lib_cpai_ct369_oa, beh_ldo_hcap_4ct, veriloga

`include "discipline.h"
`include "constants.h"

`define PI        3.14159265358979323846264338327950288419716939937511
`define clip(x,L,H) min(H,max(L,x+(H+L)/2))


//--------------------
// opamp
//
// -  operational amplifier
//
// vin_p,vin_n:      differential input voltage [V,A]
// vout:      output voltage [V,A]
// vref:      reference voltage [V,A]
// vspply_p:      positive supply voltage [V,A]
// vspply_n:      negative supply voltage [V,A]
//
// INSTANCE parameters
//    gain           = gain []
//    freq_unitygain = unity gain frequency [Hz]
//    rin            = input resistance [Ohms]
//    vin_offset     = input offset voltage referred to negative [V]
//    ibias          = input current [A]
//    iin_max           = maximum current [A]
//    slew_rate      = slew rate [A/F]
//    rout           = output resistance [Ohms]
//    vsoft          = soft output limiting value [V]
//
// MODEL parameters
//    {none}
//

module beh_ldo_opamp_v2(vin_n,vin_p,vdd33,vss33,vout,i50u,pd);
input vin_n, vin_p;
inout vout, vdd33, vss33, i50u, pd;
electrical vout, vin_n, vin_p, vdd33, vss33, i50u, pd;
parameter real gain = 810;
parameter real freq_unitygain  = 557e6;
parameter real vin_offset = 0.0;
parameter real iin_max = 25e-6;
parameter real slew_rate = 17e6;
parameter real r2=26K from (0:inf);
parameter real ratio=1;  
parameter real gm_nom= 182.2e-6;
parameter real rout=80;

//parameter real gm_out= 155e-6;
//parameter real vov_p= 149.3e-3; //152e-3
//parameter real vov_n= 335e-3; //156e-3

parameter real vsoft=0.27; //0.67
branch(vdd33,i50u) res;  
   
  real c1;
  real r1;
  real vmax_in;
  real vin_val;
 
  //electrical cout;

  analog function real ftanh; // define a tanh function for output smoothing
  input x,L,H; real x,L,H,dv;
  begin
  dv=(H-L) / 2;
  ftanh = L+ dv*(1+ tanh(x/dv));
  end
  endfunction


  analog begin

     @ ( initial_step or initial_step("dc") ) begin
      //c1 = iin_max/(slew_rate);
      c1 = gm_nom/ (2 * `PI * freq_unitygain);
      //gm_nom = 2 * `PI * freq_unitygain * c1;
      r1 = gain/gm_nom;
      vmax_in = iin_max/gm_nom;
     end

     vin_val = V(vin_n,vin_p) + vin_offset;
     
         
    //pd
   
     if (V(pd, vss33) >= 0.5*V(vdd33,vss33)) //see as logic conditonal equation
       
       begin
             
        I(vdd33, i50u) <+ 0;
       
      I(vdd33, vin_n) <+ ratio*I(res);
               
       
     end
     
     else
           
     begin
       
     //i50u current flow
   
        V(res) <+ I(res) * r2;  //equal to V(vdd33,i50u) <+  I(vdd33,i50u) *r2;
        I(vdd33, vin_n) <+ ratio*I(res);


      // Vout range
       
     if ( V(vout,vss33) > (V(vdd33,vss33) - vsoft) )
         I(vout, vss33) <+ ftanh((V(vdd33,vss33) - vsoft), vsoft, V(vdd33,vss33)-vsoft )/r1;
     
       else if ( V(vout, vss33) < (V(vss33) + vsoft) )
         I(vout, vss33) <+ ftanh((V(vdd33,vss33) - vsoft), vsoft, V(vdd33,vss33)-vsoft )/r1;
   
       else
   
     // GM stage with slewing
   
     I(vout, vss33) <+ ftanh( gm_nom*vin_val, -iin_max, iin_max );
             
       end
     
             
     // Dominant Pole.
     
      I(vout, vss33) <+ ddt(c1*V(vout, vss33));
      I(vout, vss33) <+ V(vout, vss33)/r1;
      
         
  end
endmodule

Thanks for any reply.
Back to top
 
 
View Profile   IP Logged
boe
Community Fellow
*****
Offline



Posts: 615

Re: verilog-A opamp output limiting
Reply #1 - Apr 23rd, 2012, 1:31pm
 
Seanpai,
you should be more specific about the error you see.
A few hints: Why not stick to the example opamp you recently asked about?
At a short glance, ftanh and its use look strange to me.

- B O E
PS: In another thread Forum Administrator wrote on Nov 24th, 2011, 1:24pm:
Normally I will not answer questions from people that cannot be bothered to format their code in a readable fashion...
A wise policy I tend to follow too...
Back to top
 
 
View Profile   IP Logged
Geoffrey_Coram
Senior Fellow
******
Offline



Posts: 1999
Massachusetts, USA
Re: verilog-A opamp output limiting
Reply #2 - Apr 25th, 2012, 10:45am
 
These lines have no dependence on the input voltage:

      if ( V(vout,vss33) > (V(vdd33,vss33) - vsoft) )
        I(vout, vss33) <+ ftanh((V(vdd33,vss33) - vsoft), vsoft, V(vdd33,vss33)-vsoft )/r1;
   
      else if ( V(vout, vss33) < (V(vss33) + vsoft) )
        I(vout, vss33) <+ ftanh((V(vdd33,vss33) - vsoft), vsoft, V(vdd33,vss33)-vsoft )/r1;

so their derivatives wrt the input voltage are zero.  Also, RHS of the contributions look to be equal, but I would expect different values when the output is above versus below V(vss33) + vsoft.
Back to top
 
 

If at first you do succeed, STOP, raise your standards, and stop wasting your time.
View Profile WWW   IP Logged
seanpai
New Member
*
Offline



Posts: 6

Re: verilog-A opamp output limiting
Reply #3 - Apr 26th, 2012, 3:29pm
 
To boe:
Thank you for your reply. I just begin to use this forum, therefore I may miss some important post rules. I will be more careful in the future. About my code, I have figured it out and will post it in the following for others' reference. (the attachment is the behavior model of this code)
----------------------------------opamp behavior code--------------------------------
`include "discipline.h"
`include "constants.h"

`define PI        3.14159265358979323846264338327950288419716939937511
`define clip(x,L,H) min(H,max(L,x+(H+L)/2))

//--------------------
// opamp
//
// -  operational amplifier
//
// vin_p,vin_n:      differential input voltage [V,A]
// vout:      output voltage [V,A]
// vref:      reference voltage [V,A]
// vspply_p:      positive supply voltage [V,A]
// vspply_n:      negative supply voltage [V,A]
//
// INSTANCE parameters
//    gain           = gain []
//    freq_unitygain = unity gain frequency [Hz]
//    iin_max           = maximum current [A]
//    vin_offset     = input offset voltage referred to negative [V]
//    slew_rate      = slew rate [A/F]
//    rout           = output resistance [Ohms]
//    vsoft          = soft output limiting value [V]
//
// MODEL parameters
//    {none}
//

module beh_ldo_opamp_v2(vin_n,vin_p,vdd33,vss33,vout,i50u,pd);
input vin_n, vin_p;
inout vout, vdd33, vss33, i50u, pd;
electrical vout, vin_n, vin_p, vdd33, vss33, i50u, pd;

parameter real gain = 810;
parameter real freq_unitygain  = 557e6;
parameter real vin_offset = 0.0;
parameter real iin_max = 25e-6;
parameter real slew_rate = 17e6;
parameter real r2=26K from (0:inf);
parameter real ratio=1;  
parameter real gm_nom= 182.2e-6;
parameter real vsoft=327.6e-3; //0.67 or 327.6e-3

branch(vdd33,i50u) res;  
   
  real c1;
  real r1;
  real vmax_in;
  real vin_val;
 
  analog begin

     @ ( initial_step or initial_step("dc") ) begin
      c1 = gm_nom/ (2 * `PI * freq_unitygain);
      r1 = gain/gm_nom;
      vmax_in = iin_max/gm_nom;
     end

     vin_val = V(vin_n,vin_p) + vin_offset;
     
    //pd
   
     if (V(pd, vss33) >= 0.5*V(vdd33,vss33)) //see as logic conditonal equation
       
       begin
             
        I(vdd33, i50u) <+ 0;
       
      I(vdd33, vin_n) <+ ratio*I(res);
               
     end
     
     else
           
       begin
       
     //i50u current flow
   
        V(res) <+ I(res) * r2;  //equal to V(vdd33,i50u) <+  I(vdd33,i50u) *r2;
        I(vdd33, vin_n) <+ ratio*I(res);

     // GM stage with slewing
           
     if (vin_val > vmax_in)
        I(vout, vss33) <+ iin_max;
     else if (vin_val < -vmax_in)
        I(vout, vss33) <+ -iin_max;
     else
        I(vout, vss33) <+ gm_nom*vin_val;
     
       end
                   
     // Dominant Pole.
     
      I(vout, vss33) <+ ddt(c1*V(vout, vss33));
      I(vout, vss33) <+ V(vout, vss33)/r1;
   
    // Vout range
   
       if ( V(vout) > (V(vdd33) - vsoft) )
            I(vout) <+ (gm_nom * gain) * (V(vout, vdd33)+ vsoft);

       else if ( V(vout) < (V(vss33) + vsoft) )  
            I(vout) <+ (gm_nom * gain) * (V(vout) - vsoft );
       
  end
endmodule
 --------------------------------------code end-----------------------------------------
My original question is in the Vout range part. But now I understand it comes from adding a compensation current, which is the function of vout and vsoft. If anyone has the same question, I hope this is helpful for you. Or you can reply me and then we can make a discussion further.  

To Geoffrey_Coram:
Thank you for your reply. It did help to me.  
Back to top
 

behavior_model_of_opamp.JPG
View Profile   IP Logged
Geoffrey_Coram
Senior Fellow
******
Offline



Posts: 1999
Massachusetts, USA
Re: verilog-A opamp output limiting
Reply #4 - Apr 27th, 2012, 5:46am
 
I had some trouble reading your code; the forum text formatting messes up indenting unless you use the # button to insert code (as I have done).

Since you're including constants.h, you should use `M_PI rather than defining your own.

I'll also note that your initial_step code won't work properly if someone tries to sweep a parameter (eg, gain), since the initial step block will only be executed on the first point of a dc sweep.  There's not that much math in it, so I wouldn't bother trying to optimize the execution.  (If your simulator supports it, using localparams would be a good solution.)

-Geoffrey

Code:
`include "discipline.h"
`include "constants.h"

`define clip(x,L,H) min(H,max(L,x+(H+L)/2))

//--------------------
// opamp
//
// -  operational amplifier
//
// vin_p,vin_n:	differential input voltage [V,A]
// vout:	output voltage [V,A]
// vref:	reference voltage [V,A]
// vspply_p:	positive supply voltage [V,A]
// vspply_n:	negative supply voltage [V,A]
//
// INSTANCE parameters
//    gain	     = gain []
//    freq_unitygain = unity gain frequency [Hz]
//    iin_max	     = maximum current [A]
//    vin_offset     = input offset voltage referred to negative [V]
//    slew_rate      = slew rate [A/F]
//    rout	     = output resistance [Ohms]
//    vsoft          = soft output limiting value [V]
//
// MODEL parameters
//    {none}
//

module beh_ldo_opamp_v2(vin_n,vin_p,vdd33,vss33,vout,i50u,pd);
    input vin_n, vin_p;
    inout vout, vdd33, vss33, i50u, pd;
    electrical vout, vin_n, vin_p, vdd33, vss33, i50u, pd;

    parameter real gain = 810;
    parameter real freq_unitygain  = 557e6;
    parameter real vin_offset = 0.0;
    parameter real iin_max = 25e-6;
    parameter real slew_rate = 17e6;
    parameter real r2=26K from (0:inf);
    parameter real ratio=1;  
    parameter real gm_nom= 182.2e-6;
    parameter real vsoft=327.6e-3; //0.67 or 327.6e-3

    branch(vdd33,i50u) res;  

`ifdef __VAMS_COMPACT_MODELING__
    // localparam should be supported
    localparam real c1 = gm_nom/ (2 * `M_PI * freq_unitygain);
    localparam real r1 = gain/gm_nom;
    localparam real vmax_in = iin_max/gm_nom;
`else
    real c1, r1, vmax_in;
`endif
    real vin_val;

    analog begin
`ifdef __VAMS_COMPACT_MODELING__
`else
	  c1 = gm_nom/ (2 * `M_PI * freq_unitygain);
	  r1 = gain/gm_nom;
	  vmax_in = iin_max/gm_nom;
`endif

	  vin_val = V(vin_n,vin_p) + vin_offset;
    
	  //pd
	  if (V(pd, vss33) >= 0.5*V(vdd33,vss33)) begin
		//see as logic conditional equation
		I(vdd33, i50u) <+ 0;
		I(vdd33, vin_n) <+ ratio*I(res);

	  end else begin
		//i50u current flow
		V(res) <+ I(res) * r2; //equal to V(vdd33,i50u) <+  I(vdd33,i50u) * r2;
		I(vdd33, vin_n) <+ ratio*I(res);

		// GM stage with slewing
		if (vin_val > vmax_in)
		    I(vout, vss33) <+ iin_max;
		else if (vin_val < -vmax_in)
		    I(vout, vss33) <+ -iin_max;
		else
		    I(vout, vss33) <+ gm_nom*vin_val;
    
	  end

	  // Dominant Pole.
	  I(vout, vss33) <+ ddt(c1*V(vout, vss33));
	  I(vout, vss33) <+ V(vout, vss33)/r1;
  
	  // Vout range
	  if ( V(vout) > (V(vdd33) - vsoft) )
		I(vout) <+ (gm_nom * gain) * (V(vout, vdd33)+ vsoft);
	  else if ( V(vout) < (V(vss33) + vsoft) )  
		I(vout) <+ (gm_nom * gain) * (V(vout) - vsoft );

    end
endmodule
 

Back to top
 
 

If at first you do succeed, STOP, raise your standards, and stop wasting your time.
View Profile WWW   IP Logged
Pages: 1
Send Topic Print
Copyright 2002-2024 Designer’s Guide Consulting, Inc. Designer’s Guide® is a registered trademark of Designer’s Guide Consulting, Inc. All rights reserved. Send comments or questions to editor@designers-guide.org. Consider submitting a paper or model.