Wall-clock time splits across several consumers, and the split shifts with design size and testbench style. In a class-based environment on a mid-size block, the testbench plus instrumentation often costs more than the RTL itself.
The shares below are illustrative, not measured on any one design. They show the usual ranking for a reasonably written testbench.
WHERE WALL-CLOCK TIME GOES (illustrative class-based TB, mid-size block)
RTL event evaluation roughly one third
TB procedural code roughly one quarter
Wave dumping (full hier) roughly one fifth
Coverage sampling under one tenth
Assertions (SVA) under one tenth
Logging and file I/O a few percent
The ranking INVERTS for badly written TBs:
one polling loop or per-cycle sformatf can push
TB procedural code past half the total on its own.Consumer | Scales with | Controlled from |
|---|---|---|
RTL evaluation | Design activity | Mostly fixed from the testbench side. |
TB procedural code | How the testbench is written | Fully under the testbench author control. |
Waves and coverage | Whether they are enabled | Easiest wins when speed matters. |
Assertions | Checker density | Usually worth the cost. Disable only with sign-off. |
Every major simulator ships a profiler that attributes CPU time to modules, processes and source lines. The workflow is the same across vendors: run a representative test with profiling on, fix the single biggest consumer, and re-run.
PROFILING WORKFLOW
1. Pick a representative test, not the shortest smoke test.
2. Run once with the vendor profiler enabled.
3. Read the report top-down and fix rank 1 only.
4. Re-run the profiler and repeat.
Anti-pattern: trimming coverage cost while a
scoreboard polling loop burns the top entry unexamined.Without a profiler, differential runs localize cost with zero tool knowledge. Toggle one feature per run and compare wall-clock times.
DIFFERENTIAL RUNS (illustrative example, minutes per run)
run A: everything on 42
run B: waves off 31 waves cost about 11
run C: B plus coverage off 27 coverage about 4
run D: C plus suspect monitor off 14 the monitor is the storyA healthy environment is RTL-dominant. A testbench-dominant profile is a bug report on the testbench.
RTL dominant: the testbench is healthy. Speedups come from compile flags or running fewer cycles.
TB dominant: look for polling loops, hot-path string building and copy storms. The next lesson covers each.
Waves dominant: the run dumps too much hierarchy, or waves are on in regression.
Coverage dominant: a covergroup sampled per clock instead of per transaction.
File I/O dominant: verbose logging at scale. A million detail lines is real CPU and disk time.
A polling loop. One wake-up per cycle for the whole test means the process checks a condition ten million times. An event wait or wait expression wakes it exactly when the condition becomes true.
Whether a suspect testbench process dominates the remaining 27 minutes. Disable the suspect monitor or driver in run D. The pattern isolates one consumer per run.
A small testbench with the measurement hooks used through this topic: an opt-in +WAVES dump, a verbosity knob and a logged seed that really seeds the run.
timeunit 1ns; timeprecision 1ps;
module perf_dut (
input logic clk,
output logic [7:0] count
);
// Plain always: an always_ff variable may not also be written by an initial.
initial count = '0;
always @(posedge clk) count <= count + 8'd1;
endmodule