Verilog-A Basic Structure and Syntax¶
The structure of a verilog-a model starts from the module. A Verilog-A module is similar in concept to a SPICE subcircuit or a Verilog module, but with a focus on continuous-time analog behavior. Everything from terminal definitions to parameterization and analog equations lives inside the module structure.
The module structure serves four major roles:
- Encapsulating behavior : It allows reusability and brings abstraction.
- Defining terminals and disciplines : It defines inputs, outputs, internal wires, domain (electrical) etc.
- Allowing parameterization : It allows the model to adapt to different configurations. E.g., Same ADC code can be re-configured to 10-bit or 14-bit using parameterization. In some simulators (e.g., Cadence virtuoso), the parameters appear as symbol properties at higher hierarchy.
- Providing a place for analog equations : Actual definition of the model which decides the behavior.
Nonlinear Diode Model¶
Below is a simple diode model illustrating a complete module structure:
`include "constants.vams"
`include "disciplines.vams"
module diode(p, n);
inout p, n; // declares terminals
electrical p, n; // declares disciplines
parameter real Is = 1e-14 from (0:inf); // defines parameters with limits
parameter real N = 1.0 from (0:10);
real Vd; // uses local variables
analog begin // using analog behavioral modeling
Vd = V(p, n);
I(p, n) <+ Is * (exp(Vd/(N*$vt)) - 1); //applies a physical equation
end
endmodule
It demonstrates the complete, minimal Verilog-A structure. Let's break it one by one.
Module Declaration¶
Every Verilog-A model begins with a module keyword and ends with endmodule. The module declaration optionally lists terminals:
module diode(p, n);
inout p, n;
electrical p, n;
// ...
endmodule
Key points¶
- Module name: Should be descriptive, e.g.,
resistor,opamp_simple, orvco_behavioral. - Terminal list: Defines the connection points. They work like SPICE pins.
- Verilog-A uses
inoutfor all analog terminals (because analog nodes inherently allow bidirectional flow).
This simple structure sets the stage for adding behavior.
Terminals and Disciplines¶
Terminals, also known as ports or nodes, represent the connection points of a module to the external circuit or to other internal components. They are the interface through which signals and quantities (like voltage and current in electrical circuits) interact.
Terminals are declared within a module definition, typically with a direction (input, output, or inout) and a discipline.
module resistor(p, n);
inout p, n; // terminals
electrical p, n; // discipline
// ...
endmodule
A discipline defines the nature of the physical quantities associated with a terminal or a branch. It specifies the domain (continuous or discrete) and the potential and flow natures (e.g., voltage and current for electrical, force and velocity for mechanical). It ensure type-checking and compatibility between different parts of an analog model. They enforce rules for how different physical quantities can interact.
Terminals must be declared with a discipline, which describes what physical quantities the terminal carries. The most common discipline in Verilog-A is:
electrical
The electrical discipline defines voltage as the potential nature and current as the flow nature. When a terminal is declared as electrical, it implies that voltage and current are the relevant quantities at that point.
Common disciplines¶
Other disciplines are :
| Name | Potential | Flow | Domain |
|---|---|---|---|
| electrical | Voltage | Current | Continous |
| thermal | Temperature | Power | Continous |
| kinematic | Position | Force | Continuous |
| logic | - | - | Discrete |
But for most analog electronic applications, electrical is sufficient. The standard disciplines are included by using the line `include "disciplines.vams" at the beginning of a Verilog-A file.
Example
`include "constants.vams"
`include "disciplines.vams" //including standard discipline file
module low_pass_filter(in, out);
input in;
output out;
electrical in, out;
parameter real R = 1k;
parameter real C = 1n;
analog begin
V(out) <+ laplace_nd(V(in), {1}, {R*C, 1});
end
endmodule
Parameter Definitions¶
Parameters allow a module to be flexible, configurable, and reusable. They behave like SPICE model parameters.
Example:
parameter real R = 1k from (0:inf); // parameter with limits : recommended
parameter real R = 1k; // parameter without limits : not recommended
If parameter limits are not specified, simulations may pass unexpected values to parameters without generating warnings, which can significantly increase debugging time.
Key features¶
- Type: Most parameters are
real, butintegerandstringtypes are allowed. - Default value: Ensures the model works out-of-the-box.
- Constraints: The
from (min:max)syntax helps simulators avoid invalid values.
Parameterization is essential for building models such as:
- Variable resistors
- Configurable filters
- Op-amp gain/bandwidth models
- Device models with multiple physical parameters
Local Variables¶
Local variables are internal to the module and cannot be modified by the circuit netlist.
Example:
real v_diff;
These variables store temporary values, intermediate computations, or internal states.
Cross-event detection¶
The cross() function is a monitored event function used to detect when an analog signal or expression crosses a specific threshold (typically zero) in a specified direction. It is particularly useful for modeling analog-to-digital interfaces or other events dependent on voltage or current thresholds.
Basic Syntax
cross(expression, direction, time_tol, expr_tol, enable)
- expression (required): The analog expression or signal that is being monitored for a zero-crossing. The event is triggered when this expression crosses zero.
- direction (optional): Specifies the direction of the crossing.
- +1: Triggers only on a rising edge (when expression crosses zero from negative to positive).
- -1: Triggers only on a falling edge (when expression crosses zero from positive to negative).
- 0 (default): Triggers on either rising or falling edges.
- time_tol (optional): A time tolerance for detecting the zero-crossing. The simulator attempts to cut or extend the time step to accurately resolve the crossing within this tolerance.
- expr_tol (optional): An expression tolerance for detecting the zero-crossing. The event is triggered when the expression is within this tolerance of zero.
- enable (optional): An enable signal that, when false, prevents the cross() event from being detected.
For example :
@(cross(V(in) - vth, +1)) state = 1;
Useful for comparators, switched-capacitor systems, and oscillators.
Tips for Writing Good Verilog-A Modules¶
- Use parameter constraints - Helps simulators avoid invalid conditions.
- Avoid discontinuities - Use
transition()ortanh()for soft switching. - Group related equations together - Improves readability.
- Use meaningful variable names - Avoid cryptic abbreviations.
- Test models in isolation - Always simulate individual modules before using them in a large system.