Tutorial 11 · Verilog Series

Verilog System Tasks & Functions

System tasks and functions are the simulator's built-in toolbox — identified by a leading $. They let you print signal values, query simulation time, generate random stimulus, load memory from files, control waveform capture, and gracefully exit simulation. None of them synthesize to hardware.

$display$monitor$strobe $time$random$readmemh $dumpfile$clog2$signed
SYSTEM TASK CATEGORIES DISPLAY $display $write $strobe $monitor TIME $time $realtime $stime $finish/$stop RANDOM $random $urandom MEMORY $readmemh $readmemb $writememh MATH / TYPE $clog2 $signed $unsigned $bits $dumpfile · $dumpvars · $dumpon · $dumpoff · $dumpall

1. Display Tasks: $display, $write, $strobe, $monitor

TaskWhen it printsNewline?
$displayImmediately when statement executesYes
$writeImmediately when statement executesNo
$strobeEnd of current time step (after NBA updates)Yes
$monitorWhenever any listed signal changes; auto-triggeredYes
initial begin
  $display("Time=%0t a=%b b=%b", $time, a, b); // prints now
  $write("hex=%h ", data);                        // no newline
  $write("dec=%0d\n", data);                      // manual newline
end

// $strobe — see settled NBA values
always @(posedge clk)
  $strobe("t=%0t q=%h", $time, q);  // prints after q<= updates

// $monitor — one active at a time
initial
  $monitor("t=%0t a=%b b=%b sum=%h", $time, a, b, sum);
When to use $strobe: Use it whenever you are monitoring signals driven by non-blocking assignments (<=). $display inside the same always block sees the old value; $strobe sees the new settled value at the end of the time step.

2. Format Specifiers

SpecifierFormatExample output
%bBinary0101_1100
%oOctal134
%h / %xHexadecimal5c
%dDecimal (signed, padded) 92
%0dDecimal (no leading spaces)92
%sStringhello
%tTime (uses $timeformat)100 ns
%eScientific notation9.200e+01
%fFixed-point real92.000000
\nNewline (in $write)
\tTab
// $timeformat(units, precision, suffix, width)
initial $timeformat(-9, 2, " ns", 10);
// -9 = nanoseconds, 2 decimal places, " ns" suffix, 10 chars wide
initial $display("t=%t", $time);  // e.g. "t=    100.00 ns"

3. Time Tasks: $time, $realtime, $stime

FunctionReturn typeNotes
$time64-bit integerScaled to the timescale time unit
$realtimereal (float)More precise; needed for fractional time steps
$stime32-bit integerTruncated; use only for very short simulations
`timescale 1ns/1ps

initial begin
  #10.5;
  $display("$time    = %0t", $time);    // 10 (truncated to ns)
  $display("$realtime= %f", $realtime); // 10.500000
end

4. Simulation Control: $finish, $stop

$finish;        // exit simulator — use in automated regression
$finish(0);     // exit quietly (no time/location message)
$finish(2);     // exit with full diagnostic message

$stop;          // suspend; drop into interactive debug mode
$stop(0);      // suspend quietly
Always use $finish at the end of your testbench. Without it the simulator will either hang waiting for events or the simulation will end without clear output. Put it after your pass/fail summary print.

5. Severity Tasks: $error, $warning, $fatal, $info

These are IEEE 1800-2009 (SystemVerilog) additions, but supported by most Verilog-2001 simulators including Icarus Verilog 11+.

$info   ("Simulation started at t=%0t", $time);   // informational
$warning("Unexpected X on bus at t=%0t", $time); // warning, continues
$error  ("FAIL: expected %h got %h", exp, got);  // error, continues
$fatal  ("Unrecoverable error — aborting");       // error + $finish

$fatal is like $error followed by $finish — it marks the simulation as failed and exits. In regressions, simulator exit code reflects whether $fatal was called.

6. Random Generation: $random, $urandom

// $random returns signed 32-bit
data = $random;            // any signed 32-bit value
data = {$random} % 256;   // unsigned 0–255
data = $random % 16;     // signed -15 to +15 (watch for negatives)

// Seed for reproducibility
integer seed = 42;
data = $random(seed);     // reproducible sequence from seed

// Random testbench pattern
integer i;
initial begin
  for (i=0; i<100; i++) begin
    @(posedge clk);
    data_in <= {$random} % 256;   // random 8-bit value
    addr    <= {$random} % 16;    // random 4-bit address
  end
end
Negative modulo trap: $random % N can return negative values because $random is signed. Use {$random} % N (wrap in concatenation to make unsigned) or mask: ($random & 32'hFFFF) % N.

7. File I/O: $fopen, $fdisplay, $fwrite, $fclose

integer fh;   // file handle

initial begin
  fh = $fopen("results.txt", "w");  // open for write
  if (fh == 0) begin
    $error("Cannot open results.txt");
    $finish;
  end

  $fdisplay(fh, "Simulation log — %0t", $time);
  $fwrite  (fh, "data=%h\n", data);

  $fclose(fh);
  $finish;
end

File mode strings: "r" read, "w" write (truncate), "a" append, "rb"/"wb" binary. $fopen returns 0 on failure — always check it.

8. Memory Loading: $readmemh, $readmemb

$readmemh loads hex values from a text file into a Verilog memory array. Each whitespace-separated token in the file becomes one element.

reg [7:0] rom [0:255];   // 256-byte ROM

initial begin
  $readmemh("program.hex", rom);           // fill [0:255]
  $readmemh("program.hex", rom, 0, 127);   // fill only [0:127]
  $readmemb("init.bin", rom);              // binary version
end

Example program.hex file (each hex value separated by whitespace or newlines):

// program.hex
A5 3C 00 FF 12 AB CD EF
10 20 30 40 50 60 70 80
// @address can skip to an offset
@10 DE AD BE EF
The @address directive inside the file lets you specify a non-contiguous address. Values before @10 fill indices 0–7; values after fill from index 16 (0x10).

9. Waveform Dump: $dumpfile, $dumpvars

initial begin
  $dumpfile("wave.vcd");          // output VCD filename
  $dumpvars(0, tb_top);           // 0=all levels, tb_top=scope
  $dumpvars(1, tb_top.dut);      // 1=top level of dut only
  $dumpvars(0, tb_top.dut.clk);  // specific signal
end

// Pause/resume dump for a specific window
initial begin
  #1000;
  $dumpoff;   // stop recording
  #500;
  $dumpon;    // resume recording
  $dumpall;   // force dump of current state
end

Open the resulting wave.vcd in GTKWave (gtkwave wave.vcd) to view signal waveforms. For large simulations, use $dumpoff to record only the window of interest — VCD files grow quickly.

10. Math / Type System Functions

FunctionDescriptionExample
$clog2(n)⌈log₂(n)⌉ — bits needed for n values$clog2(256)=8, $clog2(200)=8
$signed(expr)Treat expression as signed$signed(8'hFF) = -1
$unsigned(expr)Treat expression as unsigned$unsigned(-1) = 255 (8-bit)
$bits(type)Bit-width of a type or variable$bits(reg[7:0]) = 8
$high(arr)Highest index of array dimension
$low(arr)Lowest index of array dimension
parameter DEPTH = 1024;
parameter ADDR_W = $clog2(DEPTH);  // = 10 — auto-size the address bus

reg [7:0] a = 8'hFF;
initial begin
  $display("unsigned: %0d", a);           // 255
  $display("signed:   %0d", $signed(a));   // -1
end

11. Quick Reference Cheatsheet

System Task / FunctionOne-line description
$display(fmt, args)Print + newline, immediately
$write(fmt, args)Print, no newline, immediately
$strobe(fmt, args)Print + newline, at end of time step
$monitor(fmt, args)Auto-print on any signal change
$monitoron / $monitoroffEnable / disable $monitor output
$timeCurrent time as 64-bit integer
$realtimeCurrent time as real number
$timeformat(u,p,s,w)Configure %t display format
$finish[(n)]Terminate simulation
$stop[(n)]Suspend simulation (interactive debug)
$info / $warning / $error / $fatalSeverity-tagged messages
$random[(seed)]Signed 32-bit pseudo-random integer
$fopen(name, mode)Open file, returns handle
$fclose(handle)Close file
$fdisplay(h, fmt, …)$display to file handle
$fwrite(h, fmt, …)$write to file handle
$readmemh(file, mem)Load hex file into array
$readmemb(file, mem)Load binary file into array
$dumpfile(name)Set VCD output file
$dumpvars(levels, scope)Enable VCD recording
$dumpon / $dumpoffResume / pause VCD recording
$dumpallForce dump of all current values
$clog2(n)Ceiling log₂(n) — synthesis-time constant
$signed(x) / $unsigned(x)Type cast for arithmetic