Your First Module & Testbench

Modules, ports and assign, then a testbench that drives the inputs and prints the outputs.

Everything in Verilog lives in a module: a block of hardware with input and output ports, like a chip with pins. To check a module you write a second module, the testbench, which has no ports: it creates signals, connects them to the module and changes them over time.

A real module: two gates

module and_or ( ... ); opens the module and lists its ports.

input wire a means a is an input of 1 bit.

assign y_and = a & b; creates an AND gate driving y_and.

endmodule closes the module.

The testbench

reg a, b; are the testbench's own variables, assigned inside initial.

and_or dut (.a(a), ...) places one copy (an instance) of the module and connects its ports by name.

{a, b} = i; assigns the two low bits of i to a and b at once (concatenation on the left).

$dumpfile/$dumpvars record every signal into wave.vcd for a waveform viewer.

and_or dut (a, b, y_or, y_and);

and_or dut (.a(a), .b(b), .y_and(y_and), .y_or(y_or));

Positional connection depends on the order of the ports in the module header; swapping two outputs is silent. Named connection (.port(signal)) is order-independent and is the standard in real projects.

module tb; wire a, b; initial a = 1; // error module tb; reg a, b; initial a = 1;

Signals assigned inside initial or always blocks must be reg (variables). Wires can only be driven by assign or by a module output.

Why does a testbench module have no ports?

It is the top of the simulation: it creates every signal itself, so nothing outside it needs to connect to it.

What does $finish do, and what happens without it?

It ends the simulation. Without it, a testbench with a free-running clock (always #5 clk = ~clk) would simulate forever.

What does {a, b} = 2; set a and b to?

2 is binary 10, so a = 1 and b = 0: the concatenation {a, b} receives the value with a as the most significant bit.