Verilog purpose and tool flow

Learning objectives
  • Explain what Verilog models
  • Distinguish design RTL from testbench code
  • Follow preprocess, compile, elaborate, simulate, synthesize, and timing stages
  • Run a small design with Icarus Verilog
1 Objective→ 2 Learn→ 3 Example→ 4 Practice→ 5 Verify→ 6 Continue
How to study this lessonUnderstand the idea first. Use the example to see the behaviour, practise where provided, then make sure you can explain the result before continuing.
Verilog source
→
Compile
→
Elaborate
→
Simulate
↘ Synthesize
Concept diagram: Verilog purpose and tool flow

Explanation

Verilog describes concurrent hardware

A software program usually executes statements in sequence. Hardware blocks operate at the same time. Verilog therefore contains concurrent modules and processes. Statement order matters inside a procedural block, but separate blocks run concurrently.

Use Verilog for two related jobs:

Code Purpose Synthesized?
Design RTL Describes registers, combinational logic, hierarchy, and memories Yes, when supported
Testbench Creates stimulus, checks outputs, controls simulation, and writes waves No

The simulator can accept constructs that do not represent hardware. A successful simulation does not prove that every line can be synthesized.

The tool flow

  1. Preprocess: expand include files and macros.
  2. Compile: parse source and check names, syntax, and types.
  3. Elaborate: build the instance hierarchy, apply parameters, resolve ports, and expand generate blocks.
  4. Simulate: execute events over simulated time.
  5. Synthesize: translate supported RTL into logic cells or FPGA primitives.
  6. Lint and timing checks: find suspicious source patterns and test implementation timing assumptions.

Read every error from the first reported cause. Later errors can be side effects. Treat width, implicit-net, latch, multiple-driver, and unsupported-construct warnings as engineering work.

Small design and testbench

// and_gate.v - design RTL
module and_gate (
    input  wire a,
    input  wire b,
    output wire y
);
    assign y = a & b;
endmodule
// and_gate_tb.v - simulation-only testbench
`timescale 1ns/1ps
module and_gate_tb;
    reg  a;
    reg  b;
    wire y;

    and_gate dut (.a(a), .b(b), .y(y));

    initial begin
        a = 0; b = 0; #1;
        if (y !== 0) $fatal(1, "00 failed");
        a = 1; b = 1; #1;
        if (y !== 1) $fatal(1, "11 failed");
        $display("TEST PASS");
        $finish;
    end
endmodule

Run it from the directory containing both files:

iverilog -g2012 -Wall -s and_gate_tb -o simv and_gate.v and_gate_tb.v
vvp simv

-s and_gate_tb selects the simulation top. -Wall enables useful warnings. A normal run prints TEST PASS.

Files and reproducibility

Keep design sources, testbench sources, file lists, scripts, logs, and generated output in predictable locations. Record the exact command and tool version. Generated executables and wave files should not replace source-controlled inputs.

Worked example

Suppose compilation reports Unknown module type: and_gate. Check that and_gate.v is on the command line, the module name matches the instance type, and letter case matches. If compilation succeeds but TEST PASS never appears, confirm that the intended testbench is the selected top and that it reaches $finish.

Check yourself

Why can a delay such as #1 be useful in a testbench but unsuitable as the implementation of a hardware delay? At which stage are parameters and hierarchy resolved?