Hello World - Verilator + UVM example - Quickstart
Running UVM on Verilator: Introducing af_vlt_uvm
Over the past year, AsFigo has been contacted by verification engineers across the globe — 30-year veterans, interns, junior engineers - from the US and UK, the EU, and junior engineers in India — all asking the same questions:
- How do I get UVM running on Verilator?
- Is there a working Makefile?
- A quick example I can try?
git clone to a running UVM simulation on
Verilator in minutes.
Why Verilator + UVM?
The EDA community has shown strong interest in running UVM testbenches on Verilator. The appeal is obvious: Verilator is free, extremely fast, and widely available on CI/CD infrastructure. The challenge is equally obvious: UVM was written for commercial simulators and makes heavy use of OOP, dynamic casting, and language constructs that Verilator handles differently from IEEE-compliant commercial tools.
We kept seeing the same questions on forums:
- "which flags do I pass?"
- "why does
randomize()give a width-truncation warning?"
What is af_vlt_uvm?
af_vlt_uvm is a SystemVerilog macro and package library that:
- Ships the IEEE 1800.2-2017 UVM BCL (
af_uvm_bcl/) with surgical,`ifdef-guarded modifications to compile on Verilator without DPI (-DUVM_NO_DPI) and without pulling in TLM-2 or the RAL unless explicitly requested. - Provides a thin AsFigo layer (
af_uvm/src/af_uvm_pkg.svandaf_uvm_macros.svh) with productivity macros ported and extended from the open-source Go2UVM project (VerifWorks, LGPLv3). - Supplies a ready-made Verilator flags file (
scripts/af_uvm_src.f) and per-example Makefiles so you can go fromgit cloneto a passing simulation with a singlemake vlt.
The Macro Library at a Glance
All macros live in af_uvm_macros.svh and follow a simple naming rule:
AF_UVM_*(ALL_CAPS) — behavioral macros that expand to statements.af_uvm_*(lowercase) — reporting macros, analogous to`uvm_infobut shorter and Verilator-clean.
A taste of what you can write today:
module af_hello_world_uvm;
import af_uvm_pkg::*;
int addr, data;
initial begin
printAfBanner(); // prints AsFigo copyright in sim log
`af_uvm_display("Welcome to UVM + Verilator!")
#10;
`uvm_info("AsFigo", "Hello from uvm_info!", UVM_MEDIUM)
#10;
`af_uvm_display("Hello from af_uvm_display!")
`AF_UVM_RAND_STD(addr) // std::randomize with error check
`AF_UVM_RAND_STD_WITH(data, { data inside {[0:255]}; })
`af_uvm_printf(("addr=0x%0h data=0x%0h", addr, data))
#10;
$finish;
end
endmodule : af_hello_world_uvm
Compile and Run
# one-time environment setup (tcsh)
source setup.csh
# build and run the hello-world example
cd examples/af_hello_world_uvm/sim_dir
make vlt
The Verilator invocation underneath is straightforward:
verilator -j `nproc` -f flist
./obj_dir/Vaf_hello_world_uvm
Key flags in scripts/af_uvm_src.f: --binary --timing -DUVM_NO_DPI
--timescale 1ns/1ps -Wall -Wno-fatal.
We compile with -Wall and treat warnings as informational (not fatal) so
users see every issue without a hard stop; our goal is zero warnings on the AsFigo
layer itself.
Verilator-Specific Fixes We Made
In the process of getting a clean compile we encountered — and fixed — several recurring Verilator issues that affect anyone trying to run UVM:
- WIDTHTRUNC on
uvm_report_enabled(): the function returns a 2-statebitbut UVM macros compare it against an integer. Fixed by changing all comparisons to!= 0. - WIDTHTRUNC on
randomize(): Verilator treats the return value as a single bit. Fixed inAF_UVM_RANDby comparing== 0, and inAF_UVM_RAND_WITHby capturing the result in a localintbefore comparing. - IMPORTSTAR at $unit scope: a stray
import af_uvm_pkg::*outside any package or module triggered a Verilator warning. Removed; the import belongs inside each module that needs it. - TLM-2 and RAL compile errors: wrapped with
`ifdef AF_VLT_UVM_INCLUDE_TLM2and`ifdef AF_VLT_UVM_INCLUDE_RALguards inaf_uvm_bcl/src/uvm_pkg.sv. - Binary named incorrectly: Verilator names the binary after the
first file it sees. Fixed by adding
--top-module af_hello_world_uvmto the per-example flist.
Repository Layout
af_vlt_uvm/
├── af_uvm_bcl/ # IEEE 1800.2-2017 UVM BCL (AsFigo-patched)
├── af_uvm/
│ └── src/ # af_uvm_pkg.sv, af_uvm_macros.svh
├── examples/
│ └── af_hello_world_uvm/
│ ├── src/
│ └── sim_dir/ # Makefile + flist
├── scripts/
│ └── af_uvm_src.f # shared Verilator flags + UVM source list
├── uvc/ # UVM Verification Components (coming soon)
├── setup.sh
├── setup.csh
└── README.md
Licensing
The UVM BCL retains its original copyright notices from AMD, Cadence, Mentor, NVIDIA, Semifore, and Synopsys, and is used under the Apache 2.0 License. AsFigo additions and modifications are also Apache 2.0. The Go2UVM macros (VerifWorks) that inspired portions of the macro library are LGPLv3.
What Is Coming Next
- A base test class (
af_uvm_base_test) that runs a proper UVM phase flow on Verilator — including printing the AsFigo banner automatically instart_of_simulation_phase. - A FIFO end-to-end example with a driver, monitor, scoreboard, and coverage.
- API documentation generated by Natural Docs and published to GitHub Pages.
- Support for Icarus Verilog (
iverilog) — on the roadmap for 2027.
Try It
git clone https://github.com/asfigo/af_vlt_uvm.git
cd af_vlt_uvm
source setup.sh
cd examples/af_hello_world_uvm/sim_dir
make vlt
Issues, pull requests, and questions are welcome on the GitHub issue tracker.
— AsFigo Technologies, August 2026
Comments
Post a Comment