fpga.loveHomeNewsIssuesVideosToolsWiki
Home / Issues / Issue 202606 / Open Source Lab
Open Source Lab

Verilator in Action: Your First Regression Test in 30 Minutes

Editorial Board · Issue 202606 · FPGA in the AI Era

Verilator in Action: Your First Regression Test in 30 Minutes

Fig. Verilator in Action: Your First Regression Test in 30 Minutes · themed illustration

Verilator is the most active open-source Verilog/SystemVerilog simulator: it compiles RTL into a C++ model, typically runs an order of magnitude faster than commercial event-driven simulators, and is free. This article gets it running — in 30 minutes.

1. Why Verilator

  • Fast: compiles to native C++ execution, great for large regressions and CI (continuous integration) pipelines;
  • Open source: MIT license; pairs with Yosys synthesis and nextpnr place & route for a complete open FPGA flow;
  • Ecosystem: combinable with Cocotb (Python testing) and OSVVM (open verification methodology).

2. Installation

  • macOS: brew install verilator;
  • Debian/Ubuntu: apt install verilator (the distro version is old; build from source for the latest);
  • Source: git clone https://github.com/verilator/verilator then build per the README, ~5 minutes.

3. Minimal Runnable Example

An 8-bit counter DUT (counter.sv):

module counter #(parameter W = 8) (
  input  logic       clk, rst_n,
  output logic [W-1:0] q
);
  always_ff @(posedge clk or negedge rst_n)
    if (!rst_n) q <= '0;
    else        q <= q + 1;
endmodule

C++ testbench (sim_main.cpp):

#include "Vcounter.h"
#include "verilated.h"
int main(int argc, char** argv) {
  Verilated::commandArgs(argc, argv);
  Vcounter dut;
  int errors = 0;
  for (int i = 0; i < 256; i++) {
    dut.clk = 0; dut.eval();
    dut.clk = 1; dut.eval();
    if (dut.q != (i & 0xff)) errors++;
  }
  return errors ? 1 : 0;
}

Build and run:

verilator --binary --trace --timing counter.sv sim_main.cpp
./obj_dir/Vcounter

Exit code 0 means the regression passed. --trace generates a .vcd waveform viewable with GTKWave; --timing enables timing semantics such as always_ff.

4. Common Pitfalls (Remember These 3)

  • Uninitialized warnings: add --x-initial-edge or an explicit reset to avoid simulation/synthesis mismatch;
  • Four-state signals: Verilator defaults to 0/1 two-state simulation; x/z need explicit --x-assign handling;
  • Delay control: the classic #5 clk = ~clk needs the --timing switch in Verilator 5; for pure cycle simulation, drive the clock from a counter.

5. Next Steps

  • Replace the counter with your real module and wire up Yosys (read_verilog → synth → write_netlist) for a synthesis consistency comparison;
  • With a board, use nextpnr to place, route, and download, verifying that RTL simulation matches board behavior;
  • This column will break down LiteX (SoC generation) and OSVVM (verification methodology) hands-on in future issues.
← Previous article · A 100-Day Roadmap for FPGA BeginnersNext article · China’s FPGA Ecosystem: Toolchains and Cases from Four Vendors →
← Back to this issue