RTL Bench PRO

Multi-file projects

Real designs are not one file. RTL Bench takes a folder of Verilog, SystemVerilog, and VHDL files, merges them into a single compilation unit, and figures out which module is the top โ€” without you telling it.

Uploading a folder

Two buttons in the top bar do the same thing with different scopes:

  • ๐Ÿ“Ž Files โ€” pick individual files from your computer. Multi-select works.
  • ๐Ÿ“ Folder โ€” pick a directory. Everything inside it is uploaded, preserving the folder structure.
studio โ€” upload folder
rv32_alu_top.sv
adder_sub.sv
logic_ops.sv
// rv32_alu_top.sv module rv32_alu_top (...); adder_sub u_adder (...); logic_ops u_logic (...); endmodule
// adder_sub.sv module adder_sub (...); assign b_xor = b ^ {32{op}}; assign y = a + b_xor + op; endmodule
// logic_ops.sv module logic_ops (...); case (sel) 3'b100: y = a ^ b; 3'b110: y = a | b; endcase
// ...switching files...
a[31:0] b[31:0] op[3:0] u_adder adder_sub u_logic logic_ops
Upload a folder โ†’ file chips appear automatically โ†’ editor cycles through each file โ†’ the top module is chosen for you.

After upload, the file chips appear at the top of the editor. Click any chip to switch to that file. The editor shows one file at a time; the compilation sees them all.

How the top module is detected

When you click Generate, RTL Bench scans every uploaded file and builds a list of all modules. It then looks for the one that is never instantiated by any other module โ€” that is the top.

In the example above: rv32_alu_top instantiates adder_sub and logic_ops. Neither of those instantiates anything else. So rv32_alu_top is the only module that is not referenced by another, and it becomes the top.

// Detection logic, simplified:
instances_of = { }
for module in all_modules:
    for cell in module.cells:
        instances_of.add(cell.type)

top_candidates = all_modules โˆ’ instances_of
top = first(top_candidates)
๐Ÿ’ก If more than one module is never instantiated (a design with multiple roots, or a design with a testbench), RTL Bench picks the first one it finds. To force a specific module, select it in the TOP: dropdown in the top bar.

Overriding the top

The TOP: dropdown lists every module and entity in your project. Pick one and click Generate. Useful when:

  • You have a design with multiple roots and want to see one at a time.
  • You are simulating a submodule in isolation.
  • You have a testbench and want to force the DUT as top.

The dropdown defaults to auto, which uses the never-instantiated heuristic. Any explicit choice overrides it.

Mixed-language projects

You can mix Verilog, SystemVerilog, and VHDL files in the same upload. RTL Bench groups them by extension, runs the appropriate backend on each group, and stitches the resulting netlists into a single hierarchy. See mixed-language projects for the full guide.

ExtensionBackendWhat happens
.v, .sv, .svh, .vh Yosys read_verilog -sv Parsed natively. Headers (.svh, .vh) are available for `include but not compiled directly.
.vhd, .vhdl GHDL via Yosys plugin Elaborated with ghdl --std=08, then converted to a Yosys netlist.
.hex, .mem, .dat, .txt, .bin N/A Copied to the working directory for $readmemh and $readmemb. Not compiled.

Cross-language instantiation works: a SystemVerilog top can instantiate a VHDL entity, or the reverse. RTL Bench matches instantiations by entity/module name across both backends.

โš ๏ธ VHDL is case-insensitive, Verilog is not. If your VHDL entity is named ALU_Core, instantiate it as ALU_Core or alu_core from Verilog โ€” not Alu_Core. The mismatch is silent until elaboration fails.

Memory initialisation with $readmemh

ROM and RAM initialisation files work. Include the .hex or .mem file in your upload, and RTL Bench copies it into the working directory before synthesis. Then $readmemh finds it as if the file were local.

initial begin
    $readmemh("rom.hex", mem);
end

Works with or without a leading ./ in the path. If the file lives in a subfolder of your upload, the relative path is preserved.

Hierarchy vs. Flat

Two display modes control how the schematic represents submodules:

ModeWhat you seeWhen to use
Hierarchy Each instantiated submodule is a labelled box with ports. Default. Preserves design intent, stays fast on large designs.
Flat Every submodule unrolled to primitive gates. Only when you need to see inside one submodule.

Hierarchy is what you want 95 % of the time. It is fast, keeps the schematic readable, and preserves the names you wrote in the source. Flat is useful when you need to trace a specific signal through a submodule and want to see every gate on its path.

โš ๏ธ Flattening a design with many multipliers (20+) will freeze the browser while ELK lays out the graph. RTL Bench asks first โ€” heed the warning. If you accept and it hangs, reload the page.

Duplicate module names

Two files that both declare module alu will collide. Yosys reads them in upload order and the second one overwrites the first. There is no warning โ€” the tool silently uses whichever was parsed last.

This matters most when you paste a design that includes an example project and then add your own modules. If your module is also called alu, you will see the wrong schematic. Rename one of them before uploading.

Folder structure is preserved

If you upload a folder that looks like this:

my_design/
โ”œโ”€โ”€ top.sv
โ”œโ”€โ”€ rtl/
โ”‚   โ”œโ”€โ”€ alu.sv
โ”‚   โ””โ”€โ”€ regfile.sv
โ”œโ”€โ”€ mem/
โ”‚   โ””โ”€โ”€ rom.hex
โ””โ”€โ”€ include/
    โ””โ”€โ”€ defs.svh

RTL Bench keeps the relative paths. `include "defs.svh" resolves against the current working directory, and $readmemh("mem/rom.hex") finds the file. You do not need to flatten the structure before uploading.

What to do when the top is wrong

  • Check the TOP: dropdown. If it says auto, RTL Bench guessed. Pick the module you want explicitly.
  • Look for a testbench. If your design has a tb or tb_* module, it is also never instantiated โ€” so it is a valid top candidate. Rename it or force the DUT as top.
  • Look for a wrapper. Some designs have a wrapper module that instantiates the real top. Both are uninstantiated. RTL Bench picks the first one in file order, which may not be the wrapper.

Frequently asked questions

How do I specify which file contains the top-level module?

In the workbench file tree, you can designate the top module using the module dropdown or editor header. When compiling, RTL Bench parses all project files and elaborates the designated top-level module and its instantiated sub-hierarchy.

Are `include` directives and header files supported?

Yes. You can create .vh or .svh files and include them using standard compiler directives like `include "defs.vh". The backend compiler includes the project workspace in its search path.

Can I use memory initialization files like `.hex` or `.mem` in multi-file projects?

Yes. Memory initialization files uploaded to your workspace can be referenced directly by Verilog tasks like $readmemh("init.hex", mem) or $readmemb during both simulation and synthesis.

Next

Try it in the workbench โ†’