Verilog: describing hardware
Verilog is a hardware description language (HDL). Its job is to describe circuit behavior in a way a synthesis tool can turn into actual logic gates — flip-flops, muxes, adders. A simple counter looks like this:
module counter (
input wire clk,
input wire rst_n,
output reg [3:0] count
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
count <= 4'd0;
else
count <= count + 4'd1;
end
endmodule
Verilog is fine for describing hardware. It's clumsy for verifying it. It has no classes, no dynamic arrays, no built-in randomization, no object-oriented structure — all things that become essential once your testbench itself grows into a real piece of software.
SystemVerilog: a verification language grafted onto Verilog
SystemVerilog is a superset of Verilog — every legal Verilog file is also legal SystemVerilog — that adds a large set of verification-focused features: classes, inheritance, dynamic and associative arrays, constrained randomization, functional coverage constructs, and assertions. This is what lets a testbench be written like actual object-oriented software instead of a flat pile of always-blocks.
class packet;
rand bit [7:0] data;
rand bit [3:0] addr;
constraint c_addr { addr inside {[0:15]}; }
function void display();
$display("addr=%0d data=%0d", addr, data);
endfunction
endclass
module tb;
packet pkt;
initial begin
pkt = new();
repeat (5) begin
pkt.randomize();
pkt.display();
end
end
endmodule
That packet class is a self-contained, reusable object with its own randomization constraints — the constrained-random approach from Part 3, expressed directly in the language. This is a genuine leap over plain Verilog. But notice what's still missing: nothing here says how a testbench should be structured — where the driver lives, how a scoreboard should be connected, how phases like "build" and "run" should be sequenced. Every team that used only SystemVerilog ended up inventing its own answer to those questions, which made testbenches hard to reuse across projects, or even across teams in the same company.
UVM: a standard structure, built out of SystemVerilog classes
UVM (Universal Verification Methodology) doesn't add new language syntax on top of SystemVerilog — it's a library of SystemVerilog base classes, plus a set of conventions, that answers exactly the structural question SystemVerilog left open. It defines standard building blocks — uvm_driver, uvm_monitor, uvm_sequence, uvm_scoreboard, uvm_env — and a standard way for them to be built, connected, and run, called phasing (build_phase, connect_phase, run_phase, and a few more — Part 7 walks through this in detail).
Because every UVM environment follows the same structure, an engineer who has seen one UVM testbench can find their way around a completely different one, at a different company, verifying a completely different protocol — the components have different names, but the shape is the same. That reusability, more than any single technical feature, is why the next part of this series is about why the industry converged on UVM specifically.
| Layer | What it adds |
|---|---|
| Verilog | Describes hardware behavior for synthesis |
| SystemVerilog | Adds classes, randomization, coverage, assertions — verification as software |
| UVM | Standard structure and reuse on top of SystemVerilog's class library |
Takeaway
Verilog describes hardware. SystemVerilog gives you the object-oriented tools to build a serious testbench. UVM is that toolset, organized into a standard, reusable structure that the whole industry recognizes. Each layer solves a problem the one below it left open.