Professional Documents
Culture Documents
Peter Grove
Dialog Semiconductor
Edinburgh, United Kingdom
www.diasemi.com
ABSTRACT
In general Verilog-A has not been used to its full potential by analogue designers in
simulations. Some of this is down to the language support level in the various tools versus the
language reference manual. However, the main part is down to designers not having the correct
skill-set or training to write Verilog-A code in a style that makes it run fast without convergence
issues. Due to this, often block models are drawn schematics made of ideal components, which
has its own set of issues. This paper explains how to write Verilog-A models in a way that run
fast and allows the block to be modelled without ideal components. It also demonstrates how
simple Verilog-A checkers can be used to check top level hook-up. This technique can be applied
on the analogue part of Verilog-A/MS files.
Table of Contents
1 Introduction .............................................................................................................................. 4
2 Generic Structure...................................................................................................................... 4
2.1 ANALOGUE SIMULATOR INTERNALS................................................................................... 5
2.2 MONITORED EVENTS VS. CONTINUOUS TIME ...................................................................... 6
2.2.1 cross/above alternative ............................................................................................... 7
2.2.2 timer alternative .......................................................................................................... 8
3 Supporting Modules/Files ........................................................................................................ 9
3.1 MESSAGING SYSTEM .......................................................................................................... 9
3.2 VOLTAGE/CURRENT CHECKERS ....................................................................................... 10
3.3 DIGITAL INPUT CHECKER ................................................................................................. 13
3.4 GENERIC FUNCTIONS ........................................................................................................ 16
3.4.1 Smoothing Limiter ..................................................................................................... 16
3.4.2 Logical Comparators ................................................................................................ 18
3.4.3 Range Checkers ........................................................................................................ 19
3.4.4 Control Messages...................................................................................................... 20
4 Electrical Drivers.................................................................................................................... 21
4.1 OUTPUT DRIVER ............................................................................................................... 21
4.2 CURRENT OUTPUTS .......................................................................................................... 22
4.3 VOLTAGE OUTPUTS .......................................................................................................... 22
5 Electrical Receivers ................................................................................................................ 23
5.1 VOLTAGE INPUTS ............................................................................................................. 23
5.2 CURRENT INPUTS .............................................................................................................. 24
6 Model internals ....................................................................................................................... 25
6.1 SUPPLIED SIGNAL ............................................................................................................. 25
6.2 LOGIC CONTROLS ............................................................................................................. 25
6.3 FILTERS ............................................................................................................................ 26
6.4 STATIC CURRENTS ............................................................................................................ 29
7 Other tips ................................................................................................................................ 29
7.1 SWITCHES ......................................................................................................................... 29
7.2 COMMON SUB EXPRESSION ............................................................................................... 29
7.3 EXPRESSIONS .................................................................................................................... 30
7.4 MULTIPLE ANALOG BLOCKS ............................................................................................. 30
7.5 PARAMETER RANGES........................................................................................................ 30
7.6 TRIMS ............................................................................................................................... 30
7.7 VARIABLE CAPACITORS.................................................................................................... 30
8 Conclusions ............................................................................................................................ 31
9 References .............................................................................................................................. 31
10 Appendices .......................................................................................................................... 32
10.1 VOLTAGE/CURRENT CHECKER CODE ............................................................................. 32
10.2 DIGITAL INPUT CHECKER CODE ..................................................................................... 34
Table of Tables
Table 1 Suggested port list for Voltage/Current checker.............................................................. 12
Table 2 Suggested Instance parameters for Voltage/Current checker .......................................... 12
2 Generic Structure
Both XA© and HSPICE© support the Verilog-A language, by compiling the modules at run
time to be part of the main netlist. These tools only recompile the Verilog-A modules, if the file
has changed from run to run, thus eliminating the time spent recompiling the modules on
repeated simulation runs of the same netlist. These tools also concatenate all Verilog-A files so
only a single call to the compiler is needed. This minor optimization helps reduce the time
needed to setup a simulation. However often this is not the bottleneck in run time, but rather
poorly written Verilog-A files.
The most optimum approach to writing a Verilog-A model is to use real numbers within the
model itself and only have the electrical nodes on the ports. This cuts down the number of
electrical nodes for the simulator to solve each time step and should simplify the model. Using
electrical nodes internally would make the simulator maintain KCL, KVL for each node and
store the voltage and current natures for those nodes. Using real numbers remove this and allows
simpler calculation of the values, which can be optimised by the compiler. It is up to the model
writer to say whether each real number variable is a current value or a voltage. One could use a
variable naming standard of I<name> or V<name> to help others understand the formulas.
The first step in this approach is to categorise the input ports into supplies, voltage/current
references, digital signals, and normal signals. The relevant checkers can then be used on all but
normal signal inputs. Each checker should have the ports impedance modelled and matched as
close as possible. The outputs of the checkers can be used to control the models function. Normal
if(V(IN)>=THREHOLD) begin
if(!rising_triggered) begin
//V(IN) has just gone above THREHOLD
end
falling_triggered=0;
rising_triggered =1;
end
else begin
if(!falling_triggered) begin
//V(IN) has just gone below THREHOLD
end
falling_triggered=1;
rising_triggered =0;
end
`ifndef my_info
`define my_info(msg) if(`VERBOSITY >= 2) begin $strobe("INFO : %10.3fns : %m : %s",$abstime/1n, msg); end
`endif
`ifndef my_warn
`define my_warn(msg) if(`VERBOSITY >= 1) begin $strobe("WARN : %10.3fns : %m : %s",$abstime/1n, msg); end
`endif
`ifndef my_error
`define my_error(msg) begin $strobe("ERROR: %10.3fns : %m : %s",$abstime/1n, msg); end
`endif
`ifndef my_msg
`define my_msg(msg) begin $strobe("MSG : %10.3fns : %m : %s",$abstime/1n, msg); end
`endif
Currently there are no standard macros in the analogue environment using Verilog-A. This has
meant each model-writer invents his or her own method and formatting. What is proposed is to
define macros in Verilog-A to create a standard messaging system, each with a verbosity level to
control the information level that can then be used in every model. Using a standard messaging
format makes it easier for the log files to be parsed. In the code, the output message format is
<DEBUG|INFO|WARN|ERROR|MSG>, time in ns, instance name and finally the string passed
into the macro. This maybe whatever is decided as the standard for that design group or
company. The file containing all these definitions would then be included in every Verilog-A file
like the other standard include files: constants.va, disciplines.va.
For the my_debug macro one may want to use the $debug task instead of $strobe, as this will
display simulation data while the simulator is solving the equations, whereas $strobe displays
once the simulator has converged on a solution for all nodes.
Verilog-A does not have the $sformatf() system task which returns a formatted string, only the
$sformat() system task, which puts a formatted string into a declared string variable. Therefore,
to use the messaging macros a locally defined string variable, such as my_message, is needed.
This variable can be used multiple times in the module, so there is no need to use a string
variable for every $sformat() statement. (The call to the macros does not need a semi-colon as
they have been defined with begin and end around them.)
The Verilog-A/MS LRM has a restriction that the $sformat() statement may not be used within
a function. This means that there is no way to build up a string to be displayed. (This is most
likely due to the fact the $sformat() is a system task, and a function can’t call tasks since tasks
can take simulation time whereas functions can’t.)
InValid (-1)
INVALID_HIGH
InActive (0)
ACTIVE_HIGH
Active (1)
ACTIVE_LOW
InActive (0)
INVALID_LOW
InValid (-1)
This is by no means a complete list of checks that could be used, but explain the basics on how
a base-level checker module could be used. For example, on currents, an extra check could be
put on the maximum voltage drop across the RAIL and RX pin, to catch issues with biases going
from a high to low voltage domain. For biases, these checkers would make sure that there is only
one bias source and sink per net.
begin
if((low!=high) || (high<=0)) begin
`my_error("high !=low or low>high. Function output set to 0.0.")
pwr_smooth = 0.0;
end
else if(factor < 1) begin
`my_error("Input 'factor' >= 1. Function output set to 0.0.")
pwr_smooth = 0.0;
end
else begin
pwr_smooth = in/( pow(1.0+pow(in/high,2.0*factor),1.0/(2.0*factor)));
end
end
endfunction
With some minor adjustments, the equation can be made to vary from 0 to MAX rather than –
MAX to MAX. The main use for this is on the voltage feedback for current outputs, as explained
later.
begin
if(high<=0) begin
`my_error("high input <=0.0. Function output set to 0.0.")
pwr_ilimit = 0.0;
end
else if(factor < 1) begin
`my_error("Input 'factor' >= 1. Function output set to 0.0.")
pwr_ilimit = 0.0;
end
else begin
pwr_ilimit = (high+((2.0*in)-high)/(pow(1.0+pow(((2.0*in)-high)/high,2.0*factor),1.0/(2.0*factor))))/2.0;
end
end
endfunction
real value;
real high;
real low;
integer limited;
string msg;
integer ena;
begin
if((limted != -1) && (low > high) begin
`my_error("Min > Max to the function. Function output set to -1.")
check_range = -1;
end
else if(ena==1) begin
if((in <= high) && (in >= low)) begin
if(limited && (msg != "")) `my_info({"Output within limits for ",msg})
check_range = 0;
end
else begin
if(!limited && (msg != "")) `my_warn({"Output outwith limits for ",msg})
check_range = 1;
end
end
else begin
check_range = 0;
end
end
endfunction
integer op_limted;
integer value;
integer status;
integer ena;
string high_string;
string low_string;
begin
if(ena==1) begin
if(status!=value) begin
if(value==1) begin
`my_info(high_string)
check_ msg = 1;
end
else if(value==0) begin
`my_info(low_string)
check_ msg = 0;
end
else check_sig = -1;
end
else check_ msg = check_ msg;
end
else check_ msg = -1;
end
endfunction
integer supplied_msg;
The diode equation uses the limexp() function rather than the exp() function as the limexp()
function coordinates with the simulator to prevent it from declaring convergence while the
One could wrap the whole of the output driver into a macro to try and simplify the model code. It
could not be a module due to the limitation that port types can’t be a real number. However the
macro definition would not be the simplest to read, hence it is not shown here.
5 Electrical Receivers
The inputs receivers should in general have some impedance on the node. For a voltage input
this could be as simple as an RC network, for currents there needs to be feedback to steer the
current to the right place. Without any impedance the simulator will add GMIN to those nodes.
Z1
in
Z2 V in_value
vss
Figure 13 Voltage input model structure
integer supplied;
In the example code above, the block is a simple amplifier with a gain control. Using the if-
else approach, (1), the real number out would have discrete steps as the control signals changed.
(These could be smoothed out with a slew statement, but the simulator reports when the slew rate
is reached, which would be unwanted information.) In (2) the supplied and ena signals control
the outer if-else loop from (1) using on transition statement. The gain adjustment is done via a
second transition statement. This would allow a linear change from one gain to another, but
means the second transition statement is not varying between 0.0 and 1.0, but between gain
values. In (3) better control on how the gains cross over is done, using two separate transition
statements that both vary between 0.0 and 1.0. Using this approach all model discontinuities can
be dealt with in a controlled manor that the simulator is aware of. However equations can
become hard to read, so one may wrap them up into macros.
It is best to put the supplied and enable logic control signals on any current input receivers and
any voltage output drivers as a transition statement, so those loops are disabled when the block
should not be operating. (It is not an issue for voltage input receivers or current output drivers.)
The gm multiplication stage on the loops is the most obvious location to apply this to.
6.3 Filters
Most blocks will have some filters in them, and the Laplace statement is the easiest way to do
this. Laplace statements do have a restriction that the poles and zero have to be defined at
compile time. Dynamic changes to the poles or zero’s are not allowed. There are ways around
this using for loops to generate all the possible filter combinations, but this tends to make the
model very slow, or use too much memory if the number of filters is >100. Where possible either
use a parameter to select the filter values, or use the Laplace Integration theorem, Equation 3, to
create a time domain integral idt() operator that allows dynamic changes to the pole’s and zero’s.
The Laplace approach also suffers from the fact you can’t reset the filter, which is what a block
may do when it is disabled. The idt() approach does not suffer from this as the function has an
option input <assert>.
0
s
Equation 3 Laplace Integration Theorem
If one takes the polynomial form of the Laplace transform and re-arranges it it is possible to
create a generic equation that can be used to apply the Laplace Integration Theorem to. This
method only works if there are more pole’s (N) than zero’s (M), and that the pole filter order
does not change as that would change the number of integration stages required. i.e. PN must be
non-zero all the time. The later could be dealt with, but the code would become very complex,
and still have a restriction that a finite order would have to be defined at compile time.
N M
V0ut ∑ Pn S n = VIn ∑ Z m S m
n =0 m=0
(VIn Z m − VOut Pm )S m− N N −1
P S n− N
= ∑m=0 − VOut ∑ n
M
VOut
PN n = m +1 PN
Equation 4 Polynomial form for Laplace integration theorem
As an example if we have a 2 pole, P1, P2, and a 2 zero Z1, Z2 filter, using the Laplace
Integration theorem we can convert this to a time domain integral. Equation 5 shows how a
Laplace zero-pole form is translated into a time domain integral. Finally the equation is mapped
to the Verilog-A code. The 0’s are there to give the integrators an initial condition, and the rst is
to reset the filters back to this initial condition whenever it has a non-zero value. This could be
done with other zero-pole combinations, but care has to be taken to make sure the final Verilog-
A code is correct. A simple, but effective test, is to check the ac phase and magnitude of the time
domain integral form against the laplace_np() function for a specific value of zero’s and pole’s.
Vout ( S ) (1 + sZ1)(1 + sZ 2) 1 + s ( Z1 + Z 2) + s 2 ( Z1 * Z 2)
H (s) = = =
Vin( s ) (1 + sP1)(1 + sP 2) 1 + s ( P1 + P 2) + s 2 ( P1 * P 2)
Vout ( s ) * (1 + s ( P1 + P 2) + s 2 ( P1 * P 2)) = Vin( s ) * (1 + s ( Z1 + Z 2) + s 2 ( Z1 * Z 2))
1 ( P1 + P 2) 1 ( Z1 + Z 2)
Vout ( s ) * 2 + + ( P1 * P 2) = Vin( s ) * 2 + + ( Z1 * Z 2)
s s s s
1 Vin( s ) − Vout ( s ) Vin( s ) * ( Z 2 + Z1) − Vout ( s ) * ( P 2 + P1)
Vout ( s ) = + + Vin( s ) * Z 2 * Z1
P1 * P 2 s2 s
Vout (t ) =
1
(
P1 * P 2 ∫∫
)
(Vin(t ) − Vout (t ))dtdt + ∫ (Vin(t ) * ( Z 2 + Z1) − Vout (t ) * ( P 2 + P1))dt + Vin(t ) * Z 2 * Z1
Vout (t ) =
1
(
P1 * P 2 ∫∫
(Vin(t ) − Vout (t ))dt +(Vin(t ) * ( Z 2 + Z1) − Vout (t ) * ( P 2 + P1))dt + Vin(t ) * Z 2 * Z1)
Equation 5 2-pole/2-zero Laplace to time integral example
V(out)<+(1.0/(P1*P2))*(idt(idt(V(in,out),0,rst)+(V(in)*(Z2+Z1)-V(out)*(P1+P2)),0,rst)+(V(in)*(Z1*Z2)));
Another solution, which works on the integral and Laplace form of a filter, is to use feedback
from the filters output to limit the input. Care need to be taken on both approaches, so that the
result is what one expects. It is recommended to use the feedback option as this is likely to yield
the correct result over different scenarios. Figure 16 shows the implementation, where G is the
limiter whose output varies from 0 to 1 that is multiplied against the input. Although analogue
simulators appear to be continuous in time, they actually take time steps, which on the feedback
7 Other tips
There are many other optimizations that can be used to help speed up the Verilog-A models.
However not all are generic and some should really be done by the simulators themselves. This
section just focuses on some common tips for helping create optimal Verilog-A models.
7.1 Switches
Many people use the known if-else statement to model a switch, where one statement is a 0v
Voltage source between the nodes, and on another it is a 0A current source. This sort of
statement creates a discontinuity at the switching point and also changes the structure of the
circuit. A better method is to use a transition statement with a conductance, with an rdsoff value
of say 10G ohm. A diode could be added in parallel to mimic a real device and allow the node to
find an operating point.
7.6 Trims
Often blocks will have some trim or adjustment capability that affects the models. If this is
mult-bit wide quite often complex lines are code are created, whereas a simple for loop would
achieve the same value and is simpler to read. For example if you had a bus port called ota_gain
which was 4 bits wide. Using a digital input checker it could be converted to an internal integer
bus ota_gain_logic. Using the lines of code below this could be turned into a real number called
gain. Clearly if the step value is not unitised then it could use a parameter array to select the step.
8 Conclusions
Using the methods mentioned in this paper it is possible to write an optimal Verilog-A for
most blocks with no discontinuities that the simulator is not aware of. Each block can have an
input to output transfer function that maps into the simulator matrix with feedback so none of the
sources are ideal. Using the wrapper cells and structures described one can focus on the model
internals that are key to get functional and parametric equivalence rather than the interface
elements. This methodology does require the model writer to approach the model in a different
way to normal, but the speed improvement will mean more test cases can be run in less time,
improving confidence in the tape out. Cutting the number of electrical nodes down in the
simulation matrix reduces the need for multi-threaded simulations and thus licence usage.
There is still a lot of ambiguity as to what should be supported in the analogue simulator
verses the LRM [1], because this describes the mixed mode language rather than the analogue
specific one. Some vendors have added features in that help their customers, but appear not to
part of the Verilog-A language. There are some areas of the language and implementation that
would help;
1. Firstly real ports would help hierarchy in a Verilog-A models. This would save
unnecessary electrical nodes, when wrapping block up, like the checkers.
2. Functions should be able to access variables within the module scope they are defined
in.
3. Compiler optimisations so the model writer doesn’t have to do them.
4. A language linter similar to the level currently available for System Verilog.
5. Laplace support for variable poles/zero’s with checks.
9 References
[1] http://www.accellera.org/downloads/standards/v-ams/VAMS-LRM-2-3-1.pdf.
[2] “An Alternative approach to connect modules in Verilog-AMS”, Peter Grove SNUG 2012
[3] “The Designer's Guide to SPICE and Spectre®”, ISBN-13: 978-0792395713
[4] http://www.designers-guide.org/modeling/varactors.pdf
[5] “An Efficient Method to Simulate Threshold-Crossing Events”, G. Peter Fang IEEE 2008
[6] “The Mixed-Signal Methodology Guide”, ISBN-13: 978-1300035206
module VI_CHECK(RX,RAIL,FLAG,VAL);
/**********************************************************************
*** Ports ***
*********************************************************************/
inout RX;
inout RAIL;
output FLAG;
output VAL;
/**********************************************************************
*** Port Types ***
*********************************************************************/
electrical RX;
electrical RAIL;
voltage FLAG;
voltage VAL;
/**********************************************************************
*** Parameters ***
*********************************************************************/
parameter real tol = 1.0e-9 from [0:inf];
parameter real ACTIVE_HIGH = 0.0;
parameter real ACTIVE_LOW = 0.0;
parameter real INACTIVE_HIGH = (ACTIVE_HIGH > 0.0) ? ACTIVE_HIGH+tol:tol;
parameter real INACTIVE_LOW = (ACTIVE_LOW < 0.0) ? ACTIVE_LOW -tol:-tol;
/**********************************************************************
*** Local Parameters ***
*********************************************************************/
localparam ACTIVE = 1;
localparam INACTE = 0;
localparam INVALI = -1;
/**********************************************************************
*** Varibale declarations ***
*********************************************************************/
integer flag_int;
real value;
real warn_time;
real error_time;
/**********************************************************************
*** Model ***
*********************************************************************/
analog begin
if(chk_type == "ND") begin
I(RX,RAIL) <+ -1e-15 * (limexp(V(RAIL,RX)/$vt ) - 1.0); //Diode protection
I(RX,RAIL) <+ (V(RX,RAIL)>vth) * beta * pow(V(RX,RAIL)-vth,2); //MOS diode
I(RX,RAIL) <+ RX_c * ddt(V(RX,RAIL)); //MOS Bias Cap
value = I(RX,RAIL);
end
else if(chk_type == "PD") begin
I(RAIL,RX) <+ -1e-15 * (limexp(V(RX,RAIL)/$vt ) - 1.0); //Diode protection
I(RAIL,RX) <+ (V(RAIL,RX)>vth) * beta * pow(V(RAIL,RX)-vth,2); //MOS Diode
I(RX,RAIL) <+ RX_c * ddt(V(RX,RAIL)); //MOS Bias Cap
value = I(RAIL,RX);
end
else if(chk_type == "V") begin
I(RX,RAIL) <+ RX_g * V(RX,RAIL); //Voltage Load
I(RX,RAIL) <+ RX_c * ddt(V(RX,RAIL)); //Voltage Cap
value = V(RX,RAIL);
end
else begin
$sformat(my_message, "Invalid parameter option %0s passed into cell. Valid options are ND, PD,
V.",chk_type);
`my_error(my_message)
$finish(0);
end
`ifdef NO_CHECKS
flag_int = ACTIVE;
`else
@(initial_step) begin
error_time =-1;
warn_time =-1;
end
end
endmodule
module DIGINCHECK(A,VDD,VSS,D);
/**********************************************************************
*** Ports ***
*********************************************************************/
input A;
input VDD;
input VSS;
output D;
/**********************************************************************
*** Port Types ***
*********************************************************************/
electrical A;
electrical VDD;
electrical VSS;
voltage D;
/**********************************************************************
*** Parameters ***
*********************************************************************/
parameter real ACTIVE_LOW = 0.0;
parameter real VGSMAX = 0.0;
parameter real ART_VDD = 0.0;
parameter real ART_VSS = 0.0;
/**********************************************************************
*** Local Parameters ***
*********************************************************************/
localparam LOGIC_HIGH = 1;
localparam LOGIC_LOW = 0;
localparam LOGIC_X = -1;
/**********************************************************************
*** Varibale declarations ***
*********************************************************************/
integer a_logic_int;
real error_time;
real vdd_vss;
real vdd_a;
string my_message;
/**********************************************************************
*** Model ***
*********************************************************************/
analog begin
endmodule