Point three open simulators at the same UVM environment.
On the versions tested, two exit before simulation starts and the third completes.
Completion is not the same as verdict integrity.
Every verification team evaluating an open-source simulator asks the same question first: will it run my UVM environment? Not a toy sequence - the actual environment, with the factory, phasing, agents, scoreboard and register model. This article points three open tools at one Accellera 1800.2-2020 UVM DV environment, on specific versions, and reports what each of them prints. It also states what "runs UVM" has to actually mean before any PASS is worth reading.
What the run produced, tool by tool
The figure below is the measured capability matrix across the workloads in this study, on the specific tool versions we tested. The UVM row is what this article is about; the other rows are covered elsewhere in the series.
Two columns exit. One runs. What "exit" means, on each tool, in its own output:
What "runs UVM" has to mean before any PASS is worth reading
A tool that can run a UVM environment can also print PASS when the run did nothing useful. Two examples from this study surfaced that risk in our own engine, and they are why every FSimX number later in this article is scoped to the four-part bar.
- On one release, the hello_world verdict depended on the directory the run was launched from: it passed from the example directory and failed from an absolute path elsewhere, because a same-named include from a sibling example was resolving ahead of the source-adjacent one. A verdict that moves with your shell is not a verdict. It was root-caused to include resolution, fixed so a relative include resolves against its own file's directory first, and locked behind a two-directory identical-verdict gate with a planted decoy.
- A larger example ran for 500 microseconds with a scoreboard that recorded zero writes and zero reads. FSimX's own verdict system flagged it as a suspicious pass rather than scoring it green, and we excluded it from every datum in the study. A scoreboard that checks nothing must never read as a pass, and the engine says so with the evidence line that triggered the flag.
So the bar this article measures against, before comparing any tool, is: the environment elaborated, transactions occurred, checking occurred, and the verdict reflects the work. Two tools do not reach that bar on this workload; one reaches it with the four-part check enforced. That is what the rest of this article shows.
Where the two other tools stop, on the versions tested
The workload is a stack of three UVM environments of increasing weight, all built on the Accellera 1800.2-2020 UVM library: a hello_world smoke test, a mini_ubus environment with a driver, monitor and scoreboard carrying bus traffic, and the full upstream rv_timer UVM DV environment from a widely used open-source silicon-verification suite. Tested versions: Icarus Verilog 13.0-devel (s20251012), Verilator 5.040 (2025-08-30), and FSimX 0.5.320-beta+550-g026d4795.
On this workload, Icarus Verilog does not reach the testbench. It fails inside the UVM library, in a DPI header, and reports it the way it reports any construct it cannot handle:
$ # Icarus Verilog, UVM hello_world uvm_hdl.svh:77: syntax error I give up. (elapsed 0.01 s)
Verilator gets further into analysis on this workload and then stops on the class type system. On the same hello_world it emits two dozen errors in UVM class typing, of which two are representative:
$ # Verilator, UVM hello_world %Error: uvm_process_guard.svh:119: Assign RHS expects a CLASSREFDTYPE 'uvm_sequence_base', got BASICDTYPE 'int' %Error-UNSUPPORTED: Member call on object 'm_context' which is a 'REFDTYPE' ... 24 class-system errors total (elapsed 1.76 s)
Both results are version-specific and we say so: Verilator 5.040 against UVM 2020.3.1, and the Verilator project has an active UVM effort under way. The point is not that these tools are bad. It is that against this UVM library and these versions, the two tools exit in the headers - so any PASS/FAIL statement about UVM here has to be scoped exactly that way.
What FSimX runs, and what the numbers are
FSimX compiles the same Accellera library and the hello_world test in 0.62 seconds and runs it to a UVM-report pass in 0.87 seconds total. Adding traffic does not change the story: mini_ubus, with a driver, a monitor, and a scoreboard checking transactions, passes with scoreboard 3/3 matches in 1.15 seconds.
$ fsxrun -f uvm_mini_ubus.f -top ubus_tb_top UVM_INFO @ 0: reporter [RNTST] Running test ubus_example_base_test... UVM_INFO scoreboard: byte-compare 3/3 matches UVM_INFO @ 1150ns: reporter [FINISH] ** UVM TEST PASSED ** total wall 1.15 s
The scale test is the full upstream rv_timer UVM DV environment: 342 files, 653 design units, the whole register-abstraction and agent stack. It is not a reduced example. FSimX elaborates it and runs it to its own end-of-test verdict.
$ fsxrun -f rv_timer_dv.f -top tb +UVM_TESTNAME=rv_timer_random_test COMPILE 342 files, 653 design units 4.10 s ELABORATE 69 instances, 1108 signals, 0 errors 0.05 s UVM env up: agents, monitors, scoreboard, RAL TEST PASSED at 3.502 us total 10.84 s, reproduced 3/3, peak RSS 861 MB
Compile in 4.10 seconds, elaborate in 0.05 seconds, run to TEST PASSED at 3.502 microseconds of simulated time, 10.84 seconds end to end, three runs out of three. There is no comparison column for these three rows on the versions tested, because neither of the other tools compiles the library the environment is built on.
On the versions tested, that is what the FSimX numbers above are scoped to.
