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.
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)
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.
| Extension | Backend | What 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.
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:
| Mode | What you see | When 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.
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
tbortb_*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
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.
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.
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.