A regression runs thousands of tests. Debugging one means replaying it exactly with extra visibility and no source edits.
Plusargs (+NAME=value on the simulator command line) provide that control.
Task | Use |
|---|---|
| Read a number from the command line; returns 0 if absent, so provide a default. |
| True if the flag is present. |
| Print with or without a newline. |
| Current simulation time. |
| Print automatically whenever a listed signal changes; handy for a quick look. |
| Write a VCD waveform file. |
| Reproducible random numbers when seeded. |
| Report a failure with severity; |
Directed tests for the corner cases you know (reset, full, empty, back-to-back), then constrained-random for the ones you do not.
A scoreboard (queue) for in-order data, an associative array when order may differ.
A watchdog timer and a final PASS/FAIL line so regressions can be scripted.
Assertions for protocol rules that must hold every cycle, plus coverage to show that the interesting cases actually occurred.
The random seed and the command line. Rerun with the same seed to reproduce the failure, then add +VERBOSE (or turn on waveform dumping) to see detail without changing the code.
This standalone listing uses the same two-stage pipeline as the preceding lesson. Each seeded byte is driven on a falling edge, checked after a rising edge, and logged when verbose. The final byte is drained before the verdict, so the seed, mismatch log and VCD describe one timed experiment. The reference stores the previous input rather than copying the pipeline implementation.
module instrumented_pipe (
input logic clk, rst_n,
input logic [7:0] d,
output logic [7:0] y
);
logic [7:0] s1;
always_ff @(posedge clk or negedge rst_n)
if (!rst_n) begin s1 <= '0; y <= '0; end
else begin s1 <= d; y <= s1; end
endmodule
# run with defaults
vvp sim.out
# replay a failure and get detailed output and waveforms
vvp sim.out +SEED=4711 +N=200 +VERBOSEThe language defines the $urandom seed argument as input-only. Some Icarus versions overwrite it as a historical deviation. Seed from a copy as a compatibility precaution so the original value stays in the log for replay.
The loop assigns d inside its body on every iteration. A declaration such as logic [7:0] x = $urandom; inside a static initial block would not work: an initialiser on a static variable runs only once, so every iteration would reuse the same value.