Nemofy
Skip to main content

Verilog Lab

Pick a starter circuit below or write your own RTL Code & TestBench, then click Run Simulation.

Loading circuit lab…
Digital Design & Verification Guide

Complete Guide to Verilog & SystemVerilog Simulation and RTL Synthesis

Hardware Description Languages (HDLs) describe digital circuits structurally and behaviorally. Unlike sequential software programs that execute line by line on a CPU, Verilog modules describe hardware blocks that operate concurrently on every clock edge or input transition.

Combinational vs. Sequential Logic in RTL Design

Digital circuits fall into two foundational categories: combinational logic, where the output depends solely on the current inputs, and sequential logic, where the output depends on both current inputs and stored state (flip-flops or registers) synchronized to a clock signal.

In Verilog and SystemVerilog, combinational logic is modeled using continuous assignments (assign statements) or procedural blocks sensitive to all inputs (always @(*) or always_comb). Sequential logic is modeled using edge-sensitive procedural blocks (always @(posedge clk) or always_ff @(posedge clk)) that infer D-type flip-flops.

Parameterized Synchronous Counter with Active-Low Reset
module sync_counter #(
  parameter int WIDTH = 8
) (
  input  logic             clk,
  input  logic             rst_n,
  input  logic             en,
  output logic [WIDTH-1:0] count
);
  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n)
      count <= '0;
    else if (en)
      count <= count + 1'b1;
  end
endmodule
  • Use blocking assignments (=) inside combinational blocks (always @(*) / always_comb).
  • Use non-blocking assignments (<=) inside clocked sequential blocks (always @(posedge clk) / always_ff) to prevent simulation race conditions.
  • Always assign a default value to every output in combinational blocks to avoid unintended transparent latches during synthesis.

Writing Effective Testbenches & Generating VCD Waveforms

A testbench is an unclocked top-level wrapper module that instantiates your Design Under Test (DUT), generates clock and reset stimuli, drives input vectors, and monitors output responses. To inspect signals in the Waveform Viewer, include the standard $dumpfile and $dumpvars system tasks inside an initial block.

Self-checking testbenches go beyond visual waveform inspection by automatically comparing the DUT output against a golden reference model and printing PASS or FAIL diagnostics via $display or $error.

Standard Testbench Structure for Waveform Capture
module tb_counter;
  logic       clk = 0;
  logic       rst_n = 0;
  logic       en = 0;
  logic [7:0] count;

  // 10ns clock period (100 MHz)
  always #5 clk = ~clk;

  sync_counter #(.WIDTH(8)) dut (
    .clk(clk), .rst_n(rst_n), .en(en), .count(count)
  );

  initial begin
    $dumpfile("dump.vcd");
    $dumpvars(0, tb_counter);
    #12 rst_n = 1; en = 1;
    #80 en = 0;
    #20 $finish;
  end
endmodule

Understanding Gate-Level Synthesis with Yosys

When you click Synthesize in the Verilog Lab, your behavioral RTL code is parsed and elaborated into a structural netlist of logic primitives—such as AND, OR, XOR, NOT, multiplexers ($mux), and D flip-flops ($dff). Reviewing the synthesized schematic helps you verify that your code maps cleanly to hardware without inferred latches or redundant combinational paths.

Verilog & SystemVerilog Design Rules Quick Reference

Circuit TypeProcedural BlockAssignment OperatorCommon Pitfall
Combinational Logicalways @(*) / always_combBlocking (=)Missing else/default branch infers an unintended latch
Sequential Flip-Flopsalways @(posedge clk) / always_ffNon-blocking (<=)Using blocking (=) causes simulation race conditions
Continuous Wire Assignassign y = a & b;Continuous (=)Driving the same wire from multiple assign statements
Testbench Stimulusinitial begin ... endBlocking (=) / Non-blocking (<=)Forgetting $finish or $dumpvars(0, tb)

Frequently Asked Questions

Reviewed by Nemofy EngineeringAsk a Question →
Why does my simulation say no VCD waveform was generated?
Ensure your testbench includes $dumpfile("dump.vcd"); and $dumpvars(0, <testbench_module_name>); inside an initial block, and that your simulation terminates cleanly with $finish; before timing out.
What is the difference between Verilog-2005 and SystemVerilog-2012 in the lab?
SystemVerilog extends IEEE 1364 Verilog with the unified logic data type, dedicated hardware blocks (always_ff, always_comb, always_latch), enums, structs, interfaces, and object-oriented verification constructs.
Why did my combinational case statement create a latch during synthesis?
If a case or if-else statement inside an always @(*) block does not assign a value to an output register in every possible branch, hardware must preserve the previous value—which requires inferring a level-sensitive latch. Add a default assignment at the top of the block.