Modules
Ports
Simple:
module inv (out, in);
output out;
input in;
assign out = ~in;
endmodule
Buses:
module mux (out, in0, in1, sel);
output [7:0] out;
input [7:0] in0, in1;
input sel;
assign out = sel ? in1 : in0;
endmodule
Register output:
module counter (out, clk);
output reg [3:0] out;
initial out = 0;
always @(posedge ckl) out = out + 1;
endmodule
Signed and Unsigned:
input unsigned [3:0] gain;
input signed [6:0] offset;
module buffer (out, in);
output out;
input in;
electrical out, in;
analog V(out) <+ V(in);
endmodule
Continuous:
module mux (out, in, sel);
output out;
input [1:0] in;
input sel;
electrical out;
electrical [1:0] in;
analog begin
@(sel)
;
V(out) <+ transition(sel === 0, 0, 100n)*V(in[0]);
V(out) <+ transition(sel === 1, 0, 100n)*V(in[1]);
end
endmodule
Real:
module mux (out, in, sel);
output wreal out;
input wreal [1:0] in;
input sel;
assign out = sel ? in[1] : in[0];
endmodule
Cadence Real:
module mux (out, in, sel);
output wreal out;
input wreal in[1:0];
input sel;
assign out = sel ? in[1] : in[0];
endmodule
Parameters
parameter bits=8, vdd=3.0;
parameter thresh=vdd/2;
parameter integer size=16;
parameter real td=0;
parameter integer bits = 8 from [23:0];
parameter integer dir = 1 from [-1:1] exclude 0;
parameter real period=1 from (0:inf);
parameter real toff=0 from [0:inf), td=0 exclude 0;
parameter real Vmin=0;
parameter real Vmax=Vmin+1 from (Vmin:inf);
parameter real poles[3:0] = {1.0, 3.198, 4.554, 12.0};
Range Limits:
from |
λ ≤ value ≤ υ |
from |
λ < value ≤ υ |
from |
λ ≤ value < υ |
from |
λ < value < υ |
exclude |
λ ≤ value ≤ υ |
exclude |
λ < value ≤ υ |
exclude |
λ ≤ value < υ |
exclude |
λ < value < υ |
exclude ε |
value != ε |
Declarations
reg active;
reg [5:0] gain_l, gain_r;
reg [7:0] mem [1023:0];
integer i, max_count=2432;
genvar k;
real val, thresh;
real weights [7:0] = {0.5, 1, 2, 5, 10, 20, 50, 100};
event update;
Function Definitions
Discrete:
function [15:0] mux;
input [15:0] in0, in1, in2, in3;
input [1:0] sel;
case (sel)
2'b00: mux = in0;
2'b01: mux = in1;
2'b10: mux = in2;
2'b11: mux = in3;
default: mux = 16'bX;
endcase
endfunction
Analog:
analog function real sinc;
input arg;
real arg;
if (arg != 0)
sinc = sin(arg)/arg;
else
sinc = 1
endfunction
Task Definitions
task checkValue;
input real measured, expected, abstol;
input [8*80:0] description;
inout tests, failures;
real error;
integer fails;
begin
error = abs(measured - expected);
fails = error > max(abstol,0);
$display(
"%0s: %s: expected=%f, measured=%f",
fails ? "FAIL" : "Pass", description, expected, measured
);
tests = tests + 1;
failures = failures + fails;
end
endtask
Continuous Assigns
assign a = b & c; // basic
assign #10 a = b & c; // with delay
Initial and Always Processes
Composite Statements
always @(posedge clk) begin
a <= b;
b <= a;
end
always @(posedge clk) begin : lcldecls
integer A, B;
A = b + c;
B = d + e;
a <= A*B;
end
always @(posedge clk) fork
a <= b;
b <= a;
join
fork : measure_lock_time
#250 begin
locked = 0;
disable measure_lock_time;
end
@(posedge lock) begin
locked = 1;
disable measure_lock_time;
end
join
Assignment Statements
a = b + c; // without delay
a = #10 b + c; // with delay
a <= b; // without delay
a <= #10 b + c; // with delay
Timing Statements
always #50 out = ~out;
always @(posedge clk)
q <= d;
always @(a or b or c or d)
y = (a | b) & (~c ^ d);
always @*
y = (a | b) & (~c ^ d);
always @* begin
y = (a | b) & (~c ^ d);
z = (e | f) & (~g ^ h);
end
always begin
vgain = pow(10, gain/20 - 1.6);
@(gain);
end
always @(posedge clk or negedge resetb) begin
if (~resetb)
q <= 0;
else
q <= d;
end
In Verilog-AMS only, you can access analog events:
always @(cross(V(in_p, in_n), +1)) count = count + 1;
for (ch=0; ch <= 11; ch=ch+1)
wait(locked) $display("freq=%fHz", measure_freq(out));
Conditional Statements
if (i > max_count)
i = 0;
if (sel)
out = in0;
else
out = in1;
if (sel==0)
out = in0;
else if (sel==1)
out = in1;
else if (sel==2)
out = in2;
else if (sel==3)
out = in3;
else
out = 'bx;
case (sel)
0: out = in0;
1: out = in1;
2: out = in2;
3: out = in3;
default: out = 'bx;
endcase
case (sel)
2'b00: out = in0;
2'b01: out = in1;
2'b10: out = in2;
2'b11: out = in3;
2'bxx, 2'bx1, 2'b0x, 2'b1x: out = 'bx;
endcase
always @result begin
casex (result[3:0])
4'b0000: $display("result is a multiple of sixteen.");
4'b?000: $display("result is a multiple of eight.");
4'b??00: $display("result is a multiple of four.");
4'b???0: $display("result is even.");
default: $display("result is odd.");
endcase
end
Looping Statements
ones = 0;
while (data) begin
ones = ones + data[0];
data = data >> 1;
end
This code counts the number of bits that are 1 in a number.
for (i = 0; i < 64; i = i + 1)
test_amplifier(.gain(i));
always @(posedge start) begin
repeat (8) begin
#1 out <= data[0];
data = data >> 1;
end
end
initial wait (start) forever #5 clk = ~clk;
Task Statements
checkValue(measured, expected, 10m, "V(out), tests, failures);
User-defined tasks definitions.
$strobe("Average period = %rs measured from %d periods.", period, total);
$display("a=%d", a);
$write("v=%f", f);
$monitor("Frequency = %rHz", freq);
Code |
Args |
Result |
|
1 |
Interpolate integer argument with binary format. |
|
1 |
Interpolate integer argument with ASCII character format. |
|
1 |
Interpolate integer argument with decimal format. |
|
1 |
Interpolate real argument with exponential format. |
|
1 |
Interpolate real argument with decimal format. |
|
1 |
Interpolate real argument with exponential or decimal format. |
|
1 |
Interpolate integer argument with hexadecimal format. |
|
0 |
Display hierarchical instance name. |
|
1 |
Interpolate integer argument with octal format. |
|
1 |
Interpolate real argument and display using SI scale factors. |
|
1 |
Interpolate argument as a string. |
%% |
0 |
Display ‘%’ . |
$finish;
$finish(0);
$stop;
$stop(0);
Miscellaneous Statements
fork : measure_lock_time
#250 begin
locked = 0;
disable measure_lock_time;
end
@(posedge lock) begin
locked = 1;
disable measure_lock_time;
end
join
always #50 begin : osc
out = ~out;
end
always @(posedge sync) disable osc;
always @(posedge start) begin : break
for (i=0; i<64; i=i+1) begin: continue
attenuation = i;
#1u;
if (clipped(V(pout), V(nout))) begin
$display('ERROR: attenuation = %d: output is clipped', i);
disable break
end
expected = pow(10, -attenuation/20.0);
measured = V(pout,nout) / V(pin,nin);
passes = (0.9*expected < measured) && (measured < 1.1*expected);
$display('%s: attenuation = %d', i, passes ? 'Pass' : 'FAIL');
if (passes) disable continue;
$display(' measured attenuation = %f', measured);
$display(' expected attenuation = %f', expected);
end
end
event update_result;
always @update_result
result = find_result(x, y, z);
initial
-> update_result;
Analog Process
Composite Statements
analog begin
freq = (V(in) – Vmin)*(Fmax – Fmin) / (Vmax – Vmin) + Fmin;
if (freq > Fmax) freq = Fmax;
if (freq < Fmin) freq = Fmin;
phase = 2*`M_PI*idtmod(freq, 0, 1, -0.5);
V(out) <+ ampl*cos(phase);
$bound_step(0.1/freq);
end
Assignment Statements
analog begin
V(res) <+ r * I(res);
end
analog begin
I(cap) <+ c * ddt(V(cap) - r*I(cap));
end
analog begin
V(ind) <+ l * ddt(I(ind) - g*V(ind));
end
analog begin
I(out) <+ gm * V(in);
I(out) <+ g * V(out);
I(out) <+ c * ddt(V(out));
end
analog
I(out) <+ gm * V(in) + g * V(out) + c * ddt(V(out));
analog begin:
V(out): V(pin,nin) == 0;
end
a = b + c;
Timing Statements
analog begin
@(timer(0, T)) hold = V(in);
V(out) <+ transition(hold, 0, 100n);
end
syntax: timer(time, [period], [ttol], [enable])
analog initial begin
seed = 286;
next = 0.5/freq;
end
analog begin
@(timer(next)) begin
hi = !hi;
dT = jitter*$rdist_normal(seed, 0, 1);
next = next + 0.5/freq * `M_SQRT1_2*dT;
end
V(out) <+ transition(hi ? Vhi : Vlo, 0, tt);
end
syntax: cross(wave, [dir], [ttol], [tol], [enable])
analog begin
@(cross(V(in) - vth, +1))
crossings = crossings + 1;
end
analog begin
t = last_crossing(V(in) - vth, +1);
@(cross(V(in) - vth, +1)) begin
if (t0 > 0)
$strobe("period = %rs (measured at %rs).", t - t0, $abstime);
t0 = t;
end
end
analog begin
@(cross(V(in) - vth))
;
V(out) <+ transition(V(in) > vth ? vh : vl, 0, tt);
end
syntax: above(wave, [ttol], [tol], [enable])
analog begin
@(above(V(in) - vth) or above(vth - V(in)))
lv = V(in) > vth;
V(out) <+ transition(lv ? vh : vl, 0, tt);
end
Initial and Final Step Events:
analog begin
@(initial_step or cross(V(in) - vth))
lv = V(in) > vth;
V(out) <+ transition(lv ? vh : vl, 0, tt);
end
analog begin
t0 = last_crossing(V(arm) - thresh, dir);
@(cross(V(arm) - thresh, dir))
armed = 1;
t1 = last_crossing(V(trigger) - thresh, dir);
@(cross(V(trigger) - thresh, dir)) begin
if (armed) begin
armed = 0;
count = count +1;
sum = sum + (t1 - t0);
end
end
@(final_step) begin
$strobe("delay measurements = %d.\n", count);
if (count) begin
mean = sum / count;
$strobe("delay mean (est)= %g.\n", mean);
end else
$strobe("Could not measure delay.\n");
end
end
analog begin
@(posedge ref) state = state + 1;
@(posedge fg) state = state - 1;
if (state > 1) state = 1;
if (state < -1) state = -1;
I(out) <+ Iout * transition(state, 0, 10n);
end
In Verilog-AMS only analog event statements may contain discrete events.
Conditional Statements
if (i > max_count)
i = 0;
if (sel)
out = in0;
else
out = in1;
if (sel==0)
out = in0;
else if (sel==1)
out = in1;
else if (sel==2)
out = in2;
else if (sel==3)
out = in3;
else
out = 0;
case (sel)
0: out = in0;
1: out = in1;
2: out = in2;
3: out = in3;
endcase
case (sel)
0: out = in0;
1: out = in1;
2: out = in2;
3: out = in3;
4: out = in4;
5, 6, 7: out = 0;
endcase
case (sel)
0: out = in0;
1: out = in1;
2: out = in2;
3: out = in3;
4: out = in4;
default: out = 0;
endcase
Looping Statements
ones = 0;
while (data) begin
ones = ones + data[0];
data = data >> 1;
end
for (i=0; i<4; i=i+1)
$strobe("V(out[%d] = %rV", i, V(out[i]));
genvar i;
for (i=0; i<4; i=i+1)
V(out[i]) <+ transition(result & (1 << i) ? Vdd : Vss, 0, 100n);
ones = 0;
repeat (8) begin
ones = ones + data[0];
data = data >> 1;
end
Task Statements
$strobe("Average period = %rs measured from %d periods.", period, total);
Code |
Args |
Result |
|
1 |
Interpolate integer argument with binary format. |
|
1 |
Interpolate integer argument with ASCII character format. |
|
1 |
Interpolate integer argument with decimal format. |
|
1 |
Interpolate real argument with exponential format. |
|
1 |
Interpolate real argument with decimal format. |
|
1 |
Interpolate real argument with exponential or decimal format. |
|
1 |
Interpolate integer argument with hexadecimal format. |
|
0 |
Display hierarchical instance name. |
|
1 |
Interpolate integer argument with octal format. |
|
1 |
Interpolate real argument and display using SI scale factors. |
|
1 |
Interpolate argument as a string. |
%% |
0 |
Display ‘%’ . |
$finish;
$stop;
$bound_step(100n);
analog begin
V(out) <+ transition(ampl, 0, 100n)*cos(`M_TWO_PI*freq);
if (ampl)
$bound_step(0.1/freq);
end
analog begin
@(cross(V(sense))
$discontinuity(0);
if (V(sense) > 0)
V(p,n) <+ 0;
else
I(p,n) <+ 0;
end
Analog Initial Process
analog initial begin
seed = 345;
next = 0.5/freq;
end
Instantiation
resistor #(50) R1 (n1, n2); // parameters & ports passed by order
resistor #(.r(50)) R1 (.p(n1), .n(n2)); // parameters & ports passed by name