A self-checking testbench computes an expected result and compares it with the observed output at a defined time. A reference model should express the specification clearly enough to avoid duplicating the same RTL mistake. Use comparisons that also catch unexpected x or z states in simulation.
Worked example
The loop checks every binary input combination of an AND equation against a simple expected value. Case inequality makes unknowns count as failures. A failing result is printed explicitly; a regression runner should treat any FAIL message as a failed test.
module example;
reg a,b;wire y;reg expected;integer k,errors;
assign y=a & b;
initial begin
errors=0;
for(k=0;k<4;k=k+1) begin
{a,b}=k[1:0];expected=(k==3);#1;
if(y !== expected) errors=errors+1;
end
if(errors) $display("FAIL errors=%0d",errors);
else $display("PASS");
$finish;
end
endmodule
What to watch for
Checking immediately after a clock edge can race scheduled register updates. Specify the observation point instead of only the expected arithmetic value.
Try it yourself
Why can y != expected miss an unknown result in an if statement?
Answer: Logical inequality can itself evaluate to x. A testbench case-inequality comparison yields a definite mismatch when x or z differs from the expected state.
How to study this topic
Save the example in a .v file and identify its top module before compiling. Separate stimulus and observation from synthesizable RTL. Change one input, width or boundary condition at a time, predict the result, and compare that prediction with simulation. A syntax check does not establish synthesis support or timing closure.
Continue learning
Next: System tasks and file IO
Browse the complete Verilog index
Explore related programmes
These recorded programmes are upcoming. This article is general educational content, not a syllabus or course sample.
Verilog