trsim User Guide
The Tuwa RTL Simulator, version 1.0 (Windows x64)
Copyright (c) 2026 Muhammad Anisur Rahman. Released under the MIT Licence.
What trsim is
trsim is a Verilog simulator. You give it your design and a testbench, it elaborates and runs them, and it tells you what happened: the text your design printed, whether the run passed, and a waveform file you can look at.
It runs two ways:
- From the command line, which is what a build script or a regression run wants. The exit code says whether the run was clean.
- From a window, with an editor, a project, and a waveform viewer.
Both use the same engine, so a design behaves the same either way.
Installing
Unzip the archive anywhere you like. There is no installer, no registry entry, no runtime to install, no registration and no licence server.
trsim.exe the command-line simulator
trsimgui.exe the windowed front end
trsimeng.dll the engine both of them use
examples\ six worked designs
manuals\ these manuals
LICENSE
README.md
The only requirement is that trsimeng.dll sits beside the two programs. If you move trsim.exe somewhere on your PATH, move the DLL with it.
To check the download before you trust it, compare the SHA-256 in trsim-1.0.zip.sha256 with the file you received:
certutil -hashfile trsim-1.0.zip SHA256
Your first run
cd examples\01_counter
..\..\trsim.exe -top counter_tb -time 5000 counter.v
counter: 8-bit loadable up-counter
ok after reset = 0
ok after 5 counts = 5
ok held with en low = 5
ok after load 0xA0 = 160
ok wrapped past 0xFF = 0
ok async reset is immediate = 0
PASS counter
Three things happened. trsim compiled counter.v, elaborated counter_tb as the top level, and ran it for 5000 ns. The testbench decided for itself whether each check passed. And because the testbench calls $dumpfile and $dumpvars, a counter.vcd waveform file is now sitting next to the source.
Running your own design
Name the top-level module, say how long to run, and list your sources:
trsim -top my_tb -time 100000 rtl\*.v tb\my_tb.v
Include directories are given the usual way:
trsim -top my_tb -time 100000 +incdir+rtl\include rtl\*.v tb\my_tb.v
If your source sets its own `timescale, that wins. Otherwise -timeunit tells trsim what -time is counted in:
trsim -top my_tb -time 500 -timeunit us rtl\*.v tb\my_tb.v
See the Command Reference manual for every option.
Writing a testbench that reports its own verdict
trsim is most useful when the testbench decides whether the run was correct, rather than leaving you to read numbers. The pattern used throughout the examples is:
integer errors = 0;
task expect;
input [8*24:1] what;
input [7:0] got;
input [7:0] want;
begin
if (got !== want) begin
errors = errors + 1;
$display(" FAIL %0s: got %0d, expected %0d", what, got, want);
end else
$display(" ok %0s = %0d", what, got);
end
endtask
and at the end:
if (errors == 0) $display("PASS my_design");
else $display("FAIL my_design (%0d error(s))", errors);
$finish;
Two details make this work well:
- Use
!==rather than!=.!==compares x and z exactly, so an uninitialised signal is caught instead of silently comparing equal. - Count every failure instead of stopping at the first. A broken run then tells you the whole story in one go.
What trsim prints
A normal run prints, in order: which files it compiled, any warnings, the link step, then whatever your design writes with $display and friends, and finally the time the simulation ended.
-q suppresses the banner. To keep a copy of everything as well as seeing it on screen:
trsim -q -o run.log -top my_tb -time 100000 rtl\*.v tb\my_tb.v
Exit codes
This is what a build script should read.
| Code | Meaning |
|---|---|
0 | ran to completion with no failures |
1 | the design did not compile or link |
2 | the simulation reported a failure |
3 | the command line was wrong |
A simple regression step:
trsim -q -top my_tb -time 100000 rtl\*.v tb\my_tb.v
if errorlevel 1 exit /b 1
The windowed front end
Run trsimgui.exe, or run trsim with no arguments and it will start the GUI for you. It gives you an editor, a project, the simulator output, and a waveform viewer. See the Waveforms manual for the viewer.
Two back ends
By default trsim interprets the design. It can also compile it to C, which is much faster on a large design:
trsim -top my_tb -time 100000 -native build\my_tb.c rtl\*.v tb\my_tb.v
You then build build\my_tb.c with any C compiler and run the result. See the Compiled Backend manual.
When something goes wrong
"Unresolved external 'name'" at link time. A module was instantiated but never compiled. Check that every source file is on the command line, and that +incdir+ points where your `include files are.
The simulation ends immediately. -time is in the unit given by -timeunit, or by the `timescale in your source. If your clock has a 10 ns period and you asked for -time 100, you got ten cycles.
A signal reads x or z when you expected a value. trsim compares with !== faithfully, so this is usually real: a reg that nothing assigned, or a wire with no driver. The waveform viewer draws x and z distinctly, which is the quickest way to find where it starts.
It behaves differently from another simulator. Please report it. The most useful report is the smallest .v file that shows the difference, together with what the other simulator prints. See the Verilog Support manual for the gaps that are already known.
Getting help
The manuals in this folder:
| Manual | Covers |
|---|---|
| User Guide | this document |
| Command Reference | every option, exit codes, environment variables |
| Verilog Support | what the language front end accepts, and the known gaps |
| Waveforms | VCD output and the waveform viewer |
| Compiled Backend | -native, building the generated C, performance |
| Examples | a walk through the six shipped designs |