Write and simulate Verilog in your browser
RTL Bench elaborates Verilog and SystemVerilog with Yosys โ the same open-source synthesizer used by every open ASIC flow. Paste a module, click Generate, and you have a schematic, a simulation, and a timing number. No install, no Makefile, no toolchain setup.
The smallest module that does something
A 4-bit counter with an active-low reset. Paste this into the editor and click Generate.
module counter (
input logic clk,
input logic rst_n,
output logic [3:0] q
);
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) q <= 4'h0;
else q <= q + 4'd1;
end
endmodule
Run this in RTL Bench
The always_ff block is SystemVerilog. If you prefer classic
Verilog, always @(posedge clk or negedge rst_n) works too โ
Yosys parses both without complaint.
What Yosys accepts
Yosys is strict in some places and lenient in others. Here is what actually works in RTL Bench:
| Feature | Works | Notes |
|---|---|---|
module / endmodule | โ | The standard container for everything. |
always_ff, always_comb | โ | SystemVerilog. Preferred over plain always. |
logic type | โ | SystemVerilog. Replaces wire/reg. |
parameter, localparam | โ | Fully supported, including parameterised modules. |
generate / for loops | โ | Elaborated at synthesis time. |
| Packed / unpacked arrays | โ | Packed works cleanly. Unpacked is supported for memories. |
function, task | โ | Inlined at elaboration. Keep them small. |
| Structs and typedefs | โ | SystemVerilog packed structs work. |
| Interfaces | โ ๏ธ | Module ports must be plain signals. Wrap interfaces as structs. |
assert / assume | โ | Ignored โ Yosys has no assertion layer. Use $display. |
| Classes and OOP | โ | Not supported. Yosys is a synthesizer, not a verifier. |
| Program blocks / clocking blocks | โ | Ignore them โ the synthesizable subset doesn't include them. |
Verilog vs. SystemVerilog
RTL Bench treats both as the same language. When you click Generate,
Yosys is invoked with read_verilog -sv, which accepts the
SystemVerilog subset in both .v and .sv files.
That means you can write logic, always_ff,
always_comb, and packed structs in a .v file
and Yosys will not complain. There is no benefit to using the older
Verilog-2001 syntax unless you specifically need compatibility with a
local tool that rejects SystemVerilog.
Common patterns that work well
Parameterised modules
The parameter keyword makes a module reusable. Yosys
elaborates each instantiation with its parameters resolved before
drawing the schematic.
module reg_file #(
parameter WIDTH = 32,
parameter DEPTH = 16
) (
input logic clk,
input logic we,
input logic [3:0] addr,
input logic [WIDTH-1:0] wdata,
output logic [WIDTH-1:0] rdata
);
logic [WIDTH-1:0] mem [0:DEPTH-1];
always_ff @(posedge clk)
if (we) mem[addr] <= wdata;
assign rdata = mem[addr];
endmodule
Generate loops for structure
A generate for loop unrolls at elaboration. It is the
clean way to write repetitive hardware without copy-paste.
genvar i;
generate
for (i = 0; i < 8; i = i + 1) begin : gen_adder
assign sum[i] = a[i] ^ b[i] ^ carry[i];
assign carry[i+1] = (a[i] & b[i]) | (carry[i] & (a[i] ^ b[i]));
end
endgenerate
RTL Bench expands this into eight separate adder cells in the schematic โ each labelled with the hierarchy path so you can trace it back to the source.
Packed structs for buses
SystemVerilog packed structs are the clean way to group signals that travel together. Yosys treats them as a single wide vector.
typedef struct packed {
logic [31:0] addr;
logic [31:0] data;
logic valid;
} axi_req_t;
module sink (
input axi_req_t req
);
assign done = req.valid;
endmodule
What does not work
The honest limitations:
- SystemVerilog interfaces. Port lists cannot contain interface instances. Pass the signals you need, or wrap the interface as a struct.
- Assertions and covergroups. Yosys ignores them. If you want SVA checking, use a real simulator.
- Classes and OOP. SystemVerilog classes are a verification feature, not a synthesis feature. Yosys will reject them.
realarithmetic. Only integer types are synthesizable. If you need a fixed-point multiplier, implement it with integer types.initialblocks that drive hardware.$dumpfileand$dumpvarswork in a testbench, butinitialassignments to design signals do not synthesise. Usealways_ffwith a reset.
begin/end, missing semicolons, or a port connection that names a signal that does not exist.
How elaboration works
When you click Generate, RTL Bench runs a short Yosys script:
read_verilog -svโ parse every uploaded Verilog file.hierarchy -top <name>โ pick a top module (or auto-detect).procโ flattenalwaysblocks into logic and DFFs.optโ remove dead logic and redundant cells.write_jsonโ emit the netlist the schematic renderer reads.
The whole thing runs in under two seconds for a small design. If you have many files, upload them all at once โ Yosys processes them in the order you provide.
Frequently asked questions
RTL Bench supports IEEE 1364-2001 and IEEE 1364-2005 Verilog, as well as core synthesizable subsets of IEEE 1800-2012 SystemVerilog (including logic, always_comb, always_ff, packages, and multidimensional arrays).
Blocking assignments (=) execute sequentially in procedural order and are used exclusively in combinational blocks (always @* or always_comb). Non-blocking assignments (<=) evaluate all right-hand sides concurrently and update left-hand registers simultaneously at the end of the time step, preventing race conditions in clocked sequential blocks (always @(posedge clk)).
As you type, an integrated lint engine runs Yosys and Verilator checks in the background. Syntax errors, undeclared nets, width mismatches, and combinational feedback loops are immediately underlined in the code editor with actionable diagnostic messages.