RTL Bench PRO

Verilator & Cycle Simulation

RTL Bench doesn't just run one simulator. It intelligently routes your design to the best engine available: Icarus Verilog for rapid, event-driven simulation, or Verilator to compile your HDL into lightning-fast C++ for massive designs.

Event-Driven vs. Cycle-Based

To understand why RTL Bench switches engines, you have to understand the fundamental difference between how they simulate hardware.

EngineTypeHow it worksBest for
Icarus Verilog Event-Driven Maintains an event queue. When a signal changes, it wakes up every gate connected to that signal. Highly accurate for timing, but slow on large designs. Small designs, testbenches with #delays, and quick iteration.
Verilator Cycle-Based Compiles Verilog into a C++ program. It evaluates the entire design in chunks (cycles) rather than tracking every individual signal event. Large designs, RISC-V cores, and simulations running millions of cycles.

When does RTL Bench switch?

When you click Run Testbench, the backend extracts the gate-level metrics of your synthesized design. It then uses a heuristic to decide which engine will give you the result fastest.

Verilator requires compiling C++ code, which takes 3–5 seconds of overhead. If your design is tiny, Icarus is instant. If your design is huge, Verilator's C++ execution will finish before Icarus even starts.

// Simplified routing logic:
if (design.cells < 30000 && !is_pure_combinational) {
    return "icarus"; // Too small to justify C++ compile time
} else if (design.flops > 5000 || design.muls > 20) {
    return "verilator"; // Large design, use C++ speed
}
💡 The "Combinational" Exception: Verilator requires a clock to sequence its C++ evaluation. If you have a massive, purely combinational circuit (no clock port), RTL Bench will force it to stay in Icarus, or generate a fake clock, to prevent the simulation from hanging.

Reading the Engine Badge

Look at the top-right of the Simulation drawer. Next to your PASS/FAIL status, you will see a badge that tells you exactly which engine ran.

  • ICARUS · EVENT — The design was small enough that event-driven simulation was instantaneous.
  • VERILATOR · CYCLE — The design was large, so it was compiled to C++ for maximum speed.
  • ⚠ ICARUS · EVENT — Verilator was attempted, but failed. (See the Fallback section below).

The Graceful Fallback

Verilator is a very strict compiler. It will throw a fatal error if it encounters things like multiple drivers (short circuits) or complex SystemVerilog timing constructs that it cannot synthesize.

If Verilator crashes, RTL Bench does not just throw a red error screen at you. Instead, it catches the C++ compilation error, logs it, and silently falls back to Icarus Verilog so you still get your waveforms.

When this happens, the badge changes to a yellow warning: ⚠ ICARUS · EVENT. Hovering over the badge will show you exactly why Verilator rejected the design.

⚠️ Because Verilator translates your code to C++, it drops all Verilog-specific timing constructs like #10 or wait(1ns). RTL Bench automatically rewrites your testbench to use cycle-accurate @(posedge clk) blocks when routing to Verilator. If it cannot rewrite the TB, it falls back to Icarus.

Why not just use Verilator for everything?

Because of the compile-time penalty. For a tiny 8-bit adder, Icarus takes 0.1 seconds to simulate. Verilator takes 4 seconds to invoke `g++`, compile the C++, and link the binary.

By keeping small designs on Icarus, RTL Bench guarantees that clicking "Run" feels instant. The switch to Verilator only happens when your design is complex enough that C++ execution time saves you more than the compilation time.

Frequently asked questions

Why is Verilator so much faster than traditional event-driven simulators?

Verilator is a cycle-accurate compiler. Instead of interpreting event queues and signal transitions dynamically like Icarus Verilog or ModelSim, Verilator translates synthesizable Verilog directly into highly optimized multithreaded C++ code, resulting in 10x to 100x speedups.

Does Verilator support 4-state logic (X and Z states)?

By default, Verilator simulates 2-state logic (0 and 1) for maximum execution speed, treating X and Z as 0 or 1. However, Verilator provides lint warnings and flags (such as --x-assign) to detect uninitialized registers and potential simulation/synthesis mismatches.

Can I generate VCD or FST waveforms with Verilator in RTL Bench?

Yes. When waveform generation is enabled, the compiled C++ testbench includes VCD or FST tracing, allowing you to inspect high-speed waveforms directly in the RTL Bench waveform viewer.

Next

Try it in the workbench →