Skip to content

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:

  1. Encapsulating behavior : It allows reusability and brings abstraction.
  2. Defining terminals and disciplines : It defines inputs, outputs, internal wires, domain (electrical) etc.
  3. 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.
  4. 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, or vco_behavioral.
  • Terminal list: Defines the connection points. They work like SPICE pins.
  • Verilog-A uses inout for 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, but integer and string types 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:

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

  1. Use parameter constraints - Helps simulators avoid invalid conditions.
  2. Avoid discontinuities - Use transition() or tanh() for soft switching.
  3. Group related equations together - Improves readability.
  4. Use meaningful variable names - Avoid cryptic abbreviations.
  5. Test models in isolation - Always simulate individual modules before using them in a large system.