In this Topic Hide
Verilog-A allows definitions to contain repeated elements defined using vectors of nodes. Here we present an example that defines an RC network with any number of elements.
`include "discipline.h" |
/* Model for an n-stage RC ladder network */ |
module rc_ladder(inode[0], inode[n]) ; |
electrical [0:n] inode ; |
/* The compile_time attribute is a SIMetrix extension and is |
not part of the Verilog standard. compile_time parameters |
must be defined at the time the module is compiled. Their |
values can be specified on the .LOAD line in the netlist |
using the "ctparams" parameter. E.g. ctparams="n=8" |
If not specified on the .LOAD line, the default value |
specified here will be used. */ |
(* type="compile_time" *) parameter integer n=16 ; |
parameter r=1k ; |
parameter c=1n ; |
genvar i ; |
analog |
begin |
for (i=0 ; i<=n-1 ; i=i+1) |
begin |
I(inode[i],inode[i+1]) <+(V(inode[i],inode[i+1]))/r; |
I(inode[i+1]) <+ ddt(V(inode[i+1])*c) ; |
end |
end |
endmodule |
This design introduces the following language features:
Verilog-A allows nodes to be specified as vectors. This can be used to implement devices that have multiple inputs or outputs (such as ADCs and DACs) as well as devices like the above example which has multiple internal elements.
The Verilog-A specification allows the size of vectored nodes to be specified as a parameter that can be assigned at run time. SIMetrix does allow this in some simple cases but this would not be accepted in the above example. Usually, however, vectored node sizes (n in the above example) are specified as a constant to be available at compile time. This can be done in a number of ways:
'define n 16 |
Vectors of nodes can be specified in the node discipline declaration. In the example above, this is the line:
electrical [0:n] inode ; |
The nodes are accessed using square brackets enclosing a constant expression in the same way that array variables are used. For example, inode[0] is the first node in the vectored node inode while inode[n] is the last.
We saw for-loops in the butterworth filter example. Analog for loops are syntactically identical but use a special type of variable called a genvar instead of a normal variable. Analog for loops are the only type of loop where you can iterate through vectored nodes. They are also the only type of loop where you can use analog operators.
genvars are inherited from the Verilog-A version 1.0 concept called generate statements. Generate statements define a method of replicating a statement any number of times while increasing or decreasing a controlling variable - the generate variable or genvar. In computer science this technique is often called loop-unrolling. Generate statements are now considered obsolete and have been replaced by analog for loops but the functionality is similar.
The Verilog-A language specification does not stipulate that analog for loops should be unrolled but it does impose a number of restrictions on the use of genvars to make unrolling possible as long as all constant values are available at compile time. Unrolling loops that refer to vectored nodes is considerably more efficient than evaluation at run-time.
SIMetrix will unroll analog for loops if it can. If it can't, because one or more values in the for-loop could not be evaluated at compile-time, it will still attempt to implement the design but this process may fail in which case an error message will be displayed. If it succeeds, a level 2 warning will be raised advising that the design would be more efficient if some variables were constant.
Compile-time parameters are a SIMetrix extension and not part of the language specification. Compile-time parameters may be assigned in the .LOAD statement in the netlist or they may be defined using an attribute in the Verilog-A code, or both. This concept is in its infancy and we hope to develop it further. The attribute in the code (this is the (* type="compile_time" *) prefixing the parameter keyword) declares the parameter as compile-time and provides a default value. The value may be overridden in the .LOAD statement in the netlist.
|