Modules

Ports

Reference

Simple:

module inv (out, in);
   output out;
   input in;

   assign out = ~in;
endmodule

Busses:

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

Reference

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

Reference

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

Reference

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

Reference:

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

Reference:

assign a = b & c;       // basic
assign #10 a = b & c;   // with delay

Initial and Always Processes

Reference

Composite Statements

Sequential:

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

Concurrent:

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

Blocking Assignment:

a = b + c;       // without delay
a = #10 b + c;   // with delay

Nonblocking Assignment:

a <= b;          // without delay
a <= #10 b + c;  // with delay

Timing Statements

Delay Statements:

always #50 out = ~out;

Event Statements:

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;

Wait Statements:

for (ch=0; ch <= 11; ch=ch+1)
   wait(locked) $display("freq=%fHz", measure_freq(out));

Conditional Statements

If 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 Statements:

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

While 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 Statements:

for (i = 0; i < 64; i = i + 1)
   test_amplifier(.gain(i));

Repeat Statements:

always @(posedge start) begin
   repeat (8) begin
       #1 out <= data[0];
       data = data >> 1;
   end
end

Forever Statements:

initial wait (start) forever #5 clk = ~clk;

Task Statements

Reference:

checkValue(measured, expected, 10m, "V(out), tests, failures);

User-defined tasks definitions.

Display Tasks:

$strobe("Average period = %rs measured from %d periods.", period, total);
$display("a=%d", a);
$write("v=%f", f);
$monitor("Frequency = %rHz", freq);
Argument formatting codes for the display tasks.
Code Args Result
%b , %B 1 Interpolate integer argument with binary format.
%c , %C 1 Interpolate integer argument with ASCII character format.
%d , %D 1 Interpolate integer argument with decimal format.
%e , %E 1 Interpolate real argument with exponential format.
%f , %F 1 Interpolate real argument with decimal format.
%g , %G 1 Interpolate real argument with exponential or decimal format.
%h , %H 1 Interpolate integer argument with hexadecimal format.
%m , %M 0 Display hierarchical instance name.
%o , %O 1 Interpolate integer argument with octal format.
%r , %R 1 Interpolate real argument and display using SI scale factors.
%s , %S 1 Interpolate argument as a string.
%% 0 Display ‘%’ .

Termination Tasks:

$finish;
$finish(0);
$stop;
$stop(0);

Miscellaneous Statements

Disable:

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

Trigger:

event update_result;

always @update_result
   result = find_result(x, y, z);

initial
   -> update_result;

Analog Process

Reference

Composite Statements

Sequential:

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

Contribution:

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));

Indirect Assignment:

analog begin:
   V(out): V(pin,nin) == 0;
end

Assignment:

a = b + c;

Timing Statements

Event Statements:

analog begin
   @(timer(0, T)) hold = V(in);
   V(out) <+ transition(hold, 0, 100n);
end

Timer Event:

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

Cross Event:

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

Above Event:

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

Discrete Events:

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 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 Statements:

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

While Statements:

ones = 0;
while (data) begin
   ones = ones + data[0];
   data = data >> 1;
end

For Statements:

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);

Repeat Statements:

ones = 0;
repeat (8) begin
    ones = ones + data[0];
    data = data >> 1;
end

Task Statements

Display:

$strobe("Average period = %rs measured from %d periods.", period, total);
Argument formatting codes for the display tasks.
Code Args Result
%b , %B 1 Interpolate integer argument with binary format.
%c , %C 1 Interpolate integer argument with ASCII character format.
%d , %D 1 Interpolate integer argument with decimal format.
%e , %E 1 Interpolate real argument with exponential format.
%f , %F 1 Interpolate real argument with decimal format.
%g , %G 1 Interpolate real argument with exponential or decimal format.
%h , %H 1 Interpolate integer argument with hexadecimal format.
%m , %M 0 Display hierarchical instance name.
%o , %O 1 Interpolate integer argument with octal format.
%r , %R 1 Interpolate real argument and display using SI scale factors.
%s , %S 1 Interpolate argument as a string.
%% 0 Display ‘%’ .

Termination:

$finish;
$stop;

Timestep Control:

$bound_step(100n);


analog begin
   V(out) <+ transition(ampl, 0, 100n)*cos(`M_TWO_PI*freq);
   if (ampl)
      $bound_step(0.1/freq);
end

Discontinuity:

analog begin
   @(cross(V(sense))
      $discontinuity(0);
   if (V(sense) > 0)
      V(p,n) <+ 0;
   else
      I(p,n) <+ 0;
end

Analog Initial Process

Reference

analog initial begin
   seed = 345;
   next = 0.5/freq;
end

Instantiation

Reference

resistor #(50) R1 (n1, n2);              // parameters & ports passed by order
resistor #(.r(50)) R1 (.p(n1), .n(n2));  // parameters & ports passed by name