Verilog-AMS and VHDL-AMS are hardware description languages, capable of describing mixed-signal (i.e. analog and digital) hardware. In this series of postings, we’ll be talking about Verilog-A (i.e. the officially defined subset of Verilog-AMS that supports analog) and “VHDL-A” (not officially defined, but defined here as "the parts of VHDL-AMS that supports analog").
ADS support Verilog-A but not VHDL-A so this series of posting will explain how to create a Verilog-A model if all you have to start from is a VHDL-A model. It isn’t a comprehensive Verilog or VHDL reference manual: you can find plenty of those by searching on the Internet. The idea here is to get you started. You’ll have to refer to those other resources for the in-depth information. Another good resource is Best Practices for Compact Modeling in Verilog-A, J. Electron Devices Soc. (Aug. 2015) by Colin C. McAndrew et al. It's not about how to code models in Verilog-A, it's about how to code them well.
Let jump right in and compare how the two languages express the simplest possible analog component, the resistor:
Code fragment 1a: Resistor in VHDL-A
use electrical_system.all;
entity resistor is
generic (r: real := 0.0);
port(terminal p, n: electrical);
end entity resistor;
architecture signal_flow of resistor is
quantity vr across ir through p to n;
begin
vr == ir * r;
end architecture signal_flow;
Code fragment 1b: Resistor in Verilog-A
`include "disciplines.vams"
module resistor(p, n);
parameter real r=0.0;
inout p, n;
electrical p, n;
analog begin
V(p,n) <+ I(p,n) * r;
end
endmodule
Keywords are in bold. The other identifiers are defined in the code itself, or in the included libraries. For example in both langauges, the identifier electrical is not a keyword: it is defined in a standard library. VHDL-A has:
use electrical_system.all;
…and Verilog-A has:
`include "disciplines.vams"
We won’t go into the contents of these yet. Suffice it to say that they serve a similar purpose, namely to save you from writing the basic “plumbing” required to set up your model.
The two languages diverge in the next lines.
VHDL-A divides the code up into entity and architecture sections. The entity keyword is used to introduce the description of the interface of the component. Here we define ports p and n and a parameter, r. Then, the architecture keyword is used to introduce the description of its internal details. An entity can have more than one architecture ("polymorphism"), so we have to give each one a name, signal_flow in this case, so we can specify which morphology we want to use later on. To implement an architecture with ohmic behavior, we first state explicitly that the voltage V and current I are the across and through variables, respectively, of our ports with:
quantity vr across ir through p to n
(Side note: The terminology “through and across variables” comes from the mathematics of the class of problem that all SPICE-like solvers solve, namely differential algebraic equations or DAEs. In Verilog-A, through and across variables like voltage and currents are called "natures" and a pair of related through and across variables is called a "discipline." Voltage and current natures, plus some other information like tolerances, form the electrical discipline. Confusingly, VHDL-A uses the term "nature" for the pair of natures, whereas Verilog-A uses "discipline.")
Then we specify Ohm’s law, V=IR, for the branch constitutive equation:
vr == ir * r
The "double equal signs" operator implies the simulator should force the equation to be true for every time step in the simulation: it isn’t a one-time assignment like the a = b in C and Java nor the a := b in Pascal and ADA. (And it isn't at all like the equality test A == B in C and Java.)
In contrast, Verilog-A combines the entity/architecture ideas. The module keyword is used to introduce both interface (the parameter, inout, and electrical lines) and the internals (the block that is bounded by analog begin … end ).
The line:
V(p,n) <+ I(p,n) * r;
...is called a contribution statement. It is similar to the one in VHDL with double equals == except that the operator in Verilog-A is <+ . Why <+ ? It's because Verilog-A allows multiple contributions to add to the voltage V(p,n). For example,
V(p,n) <+ V(p2,n2);
V(p,n) <+ V(p3,n3);
…is equivalent to:
V(p,n) <+ V(p2,n2)+ V(p3,n3);
Similar to == in VHDL, <+ in Verilog-A implies the simulator should do whatever it takes (iteration!) to force the equation to be true for every time step in the simulation.
In Verilog-A, there is no need for a line like quantity vr across ir through p to n that we had in VHDL because the so-called access functions, V() and I(), are defined in the `included disciplines.vams header file and thereby associated with any instances of the electrical discipline.
So, that's a component. Part 2 shows you how include the Verilog-A version into ADS create a testbench that instantiates the component, adds some stimulus, and shows you the response.