The Designer's Guide Community Forum
https://designers-guide.org/forum/YaBB.pl
Modeling >> Behavioral Models >> Ferroelectric Capacitor model using verilog-a
https://designers-guide.org/forum/YaBB.pl?num=1548416170

Message started by aguntuk on Jan 25th, 2019, 3:36am

Title: Ferroelectric Capacitor model using verilog-a
Post by aguntuk on Jan 25th, 2019, 3:36am

Hello,
I am trying to develop a behavioral model of a ferroelectric capacitor using verilog-a. The ferroelectric material is HfO2 in between the capacitor plates. I know the polarization hysteresis formula which works for my HfO2 capacitor. So I try to model the polarization hysteresis first whose unit is "uC/cm^2". So to get the charge (Q) I just need to multiply the area of the capacitor. Form charge (Q), I can get the current (I) in the capacitor of my capacitor model. Here is the formula for the polarization:

PF(P/E)(V) = PS(P/E) tanh(((V-Vc(P/E))÷2Vc(P/E))*ln((PS+Pr)/(PS-Pr)))

For (P/E): P refers to upward hysteresis and E refers to downward hysteresis.

My verilog-a code:

Code:
`include "constants.vams"
`include "disciplines.vams"

// in: Input terminal
// out: Output terminal
// th: thickness

module Fe_cap_HfO2(in, out);
//Nodes
     inout in, out;
     electrical in, out, x, y, m;

// parameter declaration: name = default value [units]
     parameter real area = 0.046755; // [cm2]
     parameter real Pr_p = 11.7325; // [uC/cm2]
     parameter real Pr_e = -12.0627; // [uC/cm2]
     parameter real Ps_p = 22.6455; // [uC/cm2]
     parameter real Ps_e = -22.6455; // [uC/cm2]
     parameter real Vc_p = 1.22232; // [V]
     parameter real Vc_e = -1.067; // [V]
     parameter real th = 1e-8; // [nm]
     
// Variables      
     real Pf; // polarization variable
     real Vbr_p; // breakdown voltage (positive)
     real Vbr_e; // breakdown voltage (negative)
     real Q; // capacitor charge

     analog begin
           Vbr_p = 3*Vc_p;
           Vbr_e = -3*Vc_p;
           
           if (V(in) > 0)
              begin
                 if (V(in) > Vbr_p)
                    V(x) <+ Vbr_p;
                 else
                    V(m) <+ V(in);
              end
           else if (V(in) < 0)
              begin
               if (V(in) < Vbr_e)
                    V(y) <+ Vbr_e;
                 else
                    V(m) <+ V(in);
              end
           
           
           @(cross(Vbr_e<V(m)<Vbr_p, +1.0))
           Pf = Ps_p*tanh[{(V(m)-Vc_p)/(2*Vc_p)}*ln{(Ps_p+Pr_p)/(Ps_p-Pr_p)}];
           
           @(cross(Vbr_e<V(m)<Vbr_p, -1.0))
           Pf = Ps_e*tanh[{(V(m)-Vc_e)/(2*Vc_e)}*ln{(Ps_e+Pr_e)/(Ps_e-Pr_e)}];
           
           Q = Pf*area;
           
           I(in, out) <+ ddt(Q);
       end

     endmodule


While saving the verilog-a code in the cellview in Cadence Virtuoso, it shows error which I attached in the image as screenshot. What is the problem in the identifier definition?

And is the conditional statement ok for my code to characterize the hysteresis?

I am not that expert in verilog-a. Can anyone help me?

I am using Cadence Virtuoso with spectre simulator.
Version: ICADV12.3-64b.500.21

Title: Re: Ferroelectric Capacitor model using verilog-a
Post by Ken Kundert on Jan 25th, 2019, 2:04pm

Here are a few things.
  • You have defined too many electrical nodes. This is not an error, just a bad practice. Generally you only use nodes for terminals and structural models. You probably want to use variable for everything except the capacitor terminals.
  • You cannot combine multiple conditionals in one expression. So 'Vbr_e<V(m)<Vbr_p' in the cross function is clearly wrong. Furthermore, the the cross function takes a continuous expression not a discrete expression, so you should not use conditionals at all. Instead you should use something like 'Vbr_e - V(m)'. The cross triggers as that expression crosses through 0.
  • You group expressions with parentheses only. Brackets and braces have special meanings and cannot be used interchangeably as parentheses, so 'tanh[{(V(m)-Vc_p)/(2*Vc_p)}*ln{(Ps_p+Pr_p)/(Ps_p-Pr_p)}]' is clearly wrong, You should replace the braces and brackets with parentheses.
That is just the most obvious of issues. If you fix those you may find other issues. If you write back, please include the error message.

From a style perspective, you should not use in and out as the terminal names for a capacitor. Capacitor does not have an input and output pin. You should use names that are descriptive. Also, you should try to precompute complicated expressions involving only constants. For example:
   localparam logp = ln((Ps_p+Pr_p)/(Ps_p-Pr_p));
   localparam loge = ln((Ps_e+Pr_e)/(Ps_e-Pr_e));
Otherwise your model might be slower than it needs to be.

-Ken

Title: Re: Ferroelectric Capacitor model using verilog-a
Post by aguntuk on Jan 28th, 2019, 4:02am

Hi Ken,
Thanks a lot. your suggestions are helpful.

I wanted to upload also another image with the post but I could not post 2 images, it takes only the last uploaded image. Anyway. I have uploaded my hysteresis picture in this reply.

As you see the hysteresis covers between the same bias voltage range - one going upward and another downward, which contributes to capacitance with 2 peaks for ferroelectric HfO2 cap. I used the '@cross' function because I wanted to distinguish between 2 hysteresis curves that eventually gives me charge, Q.

If I use suppose 'Vbr_e - V(m)' then it is conditioned according to 0 crossing not according to my range whether upward or downward. If-else conditional statement is not giving me to come to single statement. Do you have any other idea to come to the statement for PF(P) and PF(E)?


Ken Kundert wrote on Jan 25th, 2019, 2:04pm:
Here are a few things.
  • You have defined too many electrical nodes. This is not an error, just a bad practice. Generally you only use nodes for terminals and structural models. You probably want to use variable for everything except the capacitor terminals.
  • You cannot combine multiple conditionals in one expression. So 'Vbr_e<V(m)<Vbr_p' in the cross function is clearly wrong. Furthermore, the the cross function takes a continuous expression not a discrete expression, so you should not use conditionals at all. Instead you should use something like 'Vbr_e - V(m)'. The cross triggers as that expression crosses through 0.
  • You group expressions with parentheses only. Brackets and braces have special meanings and cannot be used interchangeably as parentheses, so 'tanh[{(V(m)-Vc_p)/(2*Vc_p)}*ln{(Ps_p+Pr_p)/(Ps_p-Pr_p)}]' is clearly wrong, You should replace the braces and brackets with parentheses.
That is just the most obvious of issues. If you fix those you may find other issues. If you write back, please include the error message.

From a style perspective, you should not use in and out as the terminal names for a capacitor. Capacitor does not have an input and output pin. You should use names that are descriptive. Also, you should try to precompute complicated expressions involving only constants. For example:
   localparam logp = ln((Ps_p+Pr_p)/(Ps_p-Pr_p));
   localparam loge = ln((Ps_e+Pr_e)/(Ps_e-Pr_e));
Otherwise your model might be slower than it needs to be.

-Ken


Title: Re: Ferroelectric Capacitor model using verilog-a
Post by Ken Kundert on Jan 28th, 2019, 3:30pm

If you need another image,just create an additional post.

Using cross to implement hysteresis works okay with ideal hysteresis, but does not model the hysteresis you find in typical components, such as nonlinear magnetics. With the cross approach, you will not be modeling 'minor loops' in the hysteresis curve. For a more sophisticated hysteresis model, you might want to study Simulation and Modeling of Nonlinear Magnetics for inspiration.

-Ken

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