Analog Simulation Insights

# 7 Tips to improve your Verilog-AMS model

Well, because this blog is a technical blog, I thought it was a good time for a geek-friendly post :).  Armed with my usual optimism and with the help of our in-house expert Dave Cronauer, I decided to give you a few tips to make your Verilog-AMS module more efficient. Dealing with customer issues for many years, one recurrent observation I had about behavioral models is that performance is strongly correlated with the quality of your module. Using a simpler model and changing some of your modeling techniques can bring you a significant speed up in term of simulations.

So I wanted to provide a few hints on how to improve performance significantly by slightly tweaking your Verilog-A model.  As usual, feel free to add to this post with any comments you may have. When moving from the discrete domain to the continuous domain, use a transition filter.  The filter smooths the discrete event and provides a continuous path for the analog solver.  For example, change this 1 bit d2a from this:

module d2a1bit1 (d,a);

input d;

logic d;

inout a;

electrical a;

analog begin

V(a) <+ ((d)? 0.0 : 2.5);

end

endmodule

to:

module d2a1bit2 (d,a);

input d;

logic d;

inout a;

electrical a;

analog begin

V(a) <+ transition(((d)? 0.0 : 2.5),0,20p);

end

endmodule

2- Use branch statements

This makes them more readable and less prone to typos by replacing long strings with shorter variables. As well, it insures continuity when querying voltages and currents. Redo a capacitor model from this:

module cap1 (p,m);

inout p,m;

electrical p,m;

analog begin

I(p,m) <+ ddt(1p*V(p,m));

end

endmodule

to this:

module cap2 (p,m);

inout p,m;

electrical p,m;

branch (p,m) b1;

analog begin

I(b1) <+ ddt(1p*V(b1));

end

endmodule

3- Model in terms of current

When possible, create models in the form of “I(port) <+ function(other variables);”.  Most analog simulators create their matrix by summing currents at nodes, using KCL.  Redo a resistor model from this:

module res1 (p,m);

inout p,m;

electrical p,m;

branch (p,m) b1;

analog begin

V(b1) <+ 500*I(b1);

end

endmodule

to this better model:

module res2 (p,m);

inout p,m;

electrical p,m;

branch (p,m) b1;

analog begin

I(b1) <+ V(b1)/500;

end

endmodule

An even better model replaces the division with multiplication:

module res3 (p,m);

inout p,m;

electrical p,m;

branch (p,m) b1;

analog begin

I(b1) <+ V(b1)*0.002;

end

endmodule

4-Make a better switch model

A very simple relay model is shown in the Verilog-AMS LRM of the analog section is shown below:

analog begin

closed = (V(ps,ns) > vth ? 1 : 0);

if (closed)

V(p,n) <+ 0;

else

I(p,n) <+ 0;

end

This is a poor model as the resistance across the switch changes instantly from 0.0 (ideal short) to infinite (ideal open).  A better model has finite conductance

analog begin

closed = (V(ps,ns) > vth ? 1 : 0);

if (closed) cond = 1.0;

else cond = 1.0e-9;

I(b1) <+ V(b1)*transition(cond,0,10p);

end

endmodule

In small test benches, both circuits may simulate.  But in larger circuits with capacitance and inductance on the nets, the first model may have convergence problems.  The second model will simulate better.

5-Reduce the analog section

Move as much code as possible from the analog section, contained within “analog begin” to “end” statements, to digital sections.  Typically, the analog section is more computationally intensive, so you want to make this as compact as possible.  Also, segmenting the large analog block into smaller digital and analog blocks makes the model more readable.  For example, the power checking and the digital logic section of a module should be taken out of the analog section and kept as a self-contained digital sections

analog begin

@(above(V(sup),0.5)) begin

// Supply active code

end

@(digital_in) begin

// Digital logic

end

// Remaining analog code

end

endmodule

should be

always @(digital_in) begin

// Digital logic

end

always @(above(V(sup),0.5)) begin

// Supply active code

end

analog begin

// Remaining analog code

end

endmodule