Verilog-A built-in functions¶
Basic Arithmetic & Utility Functions¶
| Function | Description |
|---|---|
| abs(x) | Absolute value |
| max(x, y) | Maximum of two values |
| min(x, y) | Minimum of two values |
| ceil(x) | Smallest integer ≥ x |
| floor(x) | Largest integer ≤ x |
| round(x) | Round to nearest integer |
| pow(x, y) | x raised to power y |
| sqrt(x) | Square root |
| sign(x) | Sign of x (−1, 0, +1) |
| hypot(x,y) | √(x2+y2) |
Example:
y = max(abs(x), 1e-6);
real i_comp, q_comp, magnitude;
analog begin
i_comp = V(in_i);
q_comp = V(in_q);
// Calculate magnitude: sqrt(I^2 + Q^2)
magnitude = hypot(i_comp, q_comp);
V(out) <+ magnitude;
end
Crucial Convergence Issues at x = 0 for sqrt(x)
In analog simulators (like Spectre or HSPICE), every function must have a continuous derivative to help the simulator converge on a solution. The derivative of sqrt(x) is:
$$\cfrac{d}{dx}\sqrt{x}=\cfrac{1}{2\sqrt{x}}$$
As x approaches 0, the derivative approaches infinity. This often causes the simulator to fail or "hang" because it cannot find a stable slope to follow.
Exponential & Logarithmic Functions¶
| Function | Description |
|---|---|
| exp(x) | eˣ |
| ln(x) | Natural logarithm |
| log(x) | Base-10 logarithm |
| limexp(x) | Limited exponential (numerically safe) |
Note
Always prefer limexp() in device models to avoid convergence issues.
Example:
I(p,n) <+ Is * (limexp(V(p,n)/Vt) - 1);
Trigonometric Functions¶
| Function | Description |
|---|---|
| sin(x) | Sine |
| cos(x) | Cosine |
| tan(x) | Tangent |
| asin(x) | Inverse sine |
| acos(x) | Inverse cosine |
| atan(x) | Inverse tangent |
| atan2(y, x) | Four-quadrant inverse tangent |
Example:
V(out) <+ A * sin(2*`M_PI*f*time);
M_PI is a built-in physical constant representing π.
Hyperbolic Functions¶
| Function | Description |
|---|---|
| sinh(x) | Hyperbolic sine |
| cosh(x) | Hyperbolic cosine |
| tanh(x) | Hyperbolic tangent |
| atanh(x) | Inverse hyperbolic tangent |
| asinh(x) | Inverse hyperbolic sine |
| acosh(x) | Inverse hyperbolic cosine |
Common use: soft limiting, saturation models
Example:
V(out) <+ Vmax * tanh(V(in)/Vmax);
Random & Statistical Functions¶
| Function | Description |
|---|---|
| random() | Uniform random number (0–1) |
| rdist_normal(mean, sigma) | Gaussian distribution |
| rdist_uniform(min, max) | Uniform distribution |
| rdist_poisson(lambda) | Poisson distribution |
Example:
offset = rdist_normal(0, sigma_offset);
Used in:
- mismatch modeling
- Monte-Carlo simulations
Time & Simulation Functions¶
| Function | Description |
|---|---|
| time | Current simulation time |
| abstime | Absolute time |
| realtime | Real-time variable |
Example:
V(out) <+ sin(2*`M_PI*f*time);
Derivative & Integral Functions¶
| Function | Description |
|---|---|
| ddt(x) | Time derivative (dx/dt) |
| idt(x, ic) | Time integral with initial condition |
Example:
I(p,n) <+ C * ddt(V(p,n));
Transition & Smoothing Functions¶
| Function | Description |
|---|---|
| transition(x, td, tr) | Smooth transition |
| slew(x, rate) | Slew-rate limiting |
Example:
V(out) <+ transition(Vin > Vth, 0, 1n);
Used for:
- comparators
- DACs
- digital-to-analog boundaries
Laplace & Frequency-Domain Functions¶
| Function | Description |
|---|---|
| laplace_zp(input, z[], p[], k) | Zero-pole form |
| laplace_nd(input, num[], den[]) | numerator-denominator form |
| laplace_zd(input, z[], d[]) | zero-denominator form |
| laplace_np(input, z[], p[], k) | numerator-pole form |
Example : laplace_zp¶
In Verilog-A, laplace_zp (Zeros-Poles) is the most efficient way to model complex filters when you already know where the poles and zeros should be located on the complex plane.
`include "disciplines.vams"
`include "constants.vams"
module butterworth_2nd(in, out);
input in; output out;
electrical in, out;
parameter real fc = 1000; // Cutoff frequency in Hz
real wc, p_re, p_im;
analog begin
@(initial_step) begin
wc = 2 * `M_PI * fc;
// Calculate real and imaginary parts for 45-degree pole placement
p_re = -wc / sqrt(2);
p_im = wc / sqrt(2);
end
// Syntax: laplace_zp(input, {zeros}, {poles}, gain)
// No zeros: empty brackets {}
// Two poles: (p_re + j*p_im) and (p_re - j*p_im)
V(out) <+ laplace_zp(V(in), {}, {p_re, p_im, p_re, -p_im}, 1.0);
end
endmodule
Example : laplace_nd¶
For a simple RC filter, the transfer function is :
$$H(s) = \frac{\frac{\omega_0}{Q}s}{s^2 + \frac{\omega_0}{Q}s + \omega_0^2}$$
Here, num[]={0,w0/Q} and den[]={w0**2,w0/Q,1}.
parameter real f0 = 1M; // Center frequency
parameter real Q = 10; // Quality factor
real w0;
analog begin
w0 = 2 * `M_PI * f0;
// Numerator: 0*s^0 + (w0/Q)*s^1
// Denominator: w0^2*s^0 + (w0/Q)*s^1 + 1*s^2
V(out) <+ laplace_nd(V(in), {0, w0/Q}, {w0**2, w0/Q, 1});
end
Example : laplace_zd¶
Creating a notch filter with transfer function:
$$H(s)=\cfrac{s^2+\omega{}_o^2}{a_2s^2+a_1s+a_0}$$
`include "disciplines.vams"
`include "constants.vams"
module notch_filter(in, out);
input in; output out;
electrical in, out;
parameter real f0 = 60; // Frequency to block
parameter real Q = 2; // Quality factor
real w0, a0, a1, a2;
analog begin
@(initial_step) begin
w0 = 2 * `M_PI * f0;
// Denominator coefficients for s^0, s^1, s^2
a0 = w0**2;
a1 = w0/Q;
a2 = 1.0;
end
// Zeros: {re1, im1, re2, im2, .. }
// Zeros: {0, w0} and {0, -w0} -> creates (s^2 + w0^2)
// Denominator: {a0, a1, a2} -> creates (a2*s^2 + a1*s + a0)
V(out) <+ laplace_zd(V(in), {0, w0, 0, -w0}, {a0, a1, a2});
end
endmodule
Example : laplace_np¶
Creating a bandpass filter:
$$H(s)=\cfrac{s}{(s+p_{re}+jp_{im})(s+p_{re}-jp_{im})}$$
`include "disciplines.vams"
`include "constants.vams"
module bandpass_np(in, out);
input in; output out;
electrical in, out;
parameter real f_center = 1e6; // 1MHz center
parameter real bandwidth = 1e5; // 100kHz bandwidth
real p_re, p_im, gain;
analog begin
@(initial_step) begin
// Real part of pole relates to bandwidth
p_re = -`M_PI * bandwidth;
// Imaginary part relates to center frequency
p_im = 2 * `M_PI * f_center;
gain = 1.0;
end
// Numerator: {0, gain} -> represents (0 + gain*s)
// Poles: Two complex conjugate poles
V(out) <+ laplace_np(V(in), {0, gain}, {p_re, p_im, p_re, -p_im});
end
endmodule
Limiting & Protection Functions¶
| Function | Description |
|---|---|
| limit(x, min, max) | Hard limit |
| clip(x, min, max) | Hard clip |
Example:
V(out) <+ limit(Vin, -1.2, 1.2);
Noise Functions¶
Used to model physical noise sources.
- white_noise(psd, name)
- flicker_noise(psd, exponent, name)
Example:
I(p,n) <+ white_noise(4*P_K*temperature/R, "thermal");
Event and Crossing Functions¶
Used for mixed-signal and event-driven behavior.
- cross(expr, direction) – detect zero crossings
- timer(t) – periodic event trigger
Example:
@(cross(V(in)-Vth, +1)) begin
state = 1;
end