Troubleshooting¶
The diagnostics cpptb emits are deliberately specific — each one names the key, path, or clock it is about. This page collects them in one place: what each message means, and the fix. Messages are grouped by when they appear.
Project and build errors¶
These stop the run before compilation and exit with code 2; the message is
on stderr, prefixed cpptb:.
Message |
Meaning and fix |
|---|---|
|
Only the two contract-complete backends are accepted. Pick one — or delete the key, since |
|
The timing backend owns the host loop and emits its own |
|
The timing defines are owned by |
|
Two optimization settings would leave whichever Verilator applies last in charge. Use |
|
The framework host loop was not found from the resolved framework root. Point |
An ambiguous top module |
More than one candidate root elaborates; the message lists them. Select one with |
Testbench compile errors¶
A
static_assertnaming a hierarchy path. The discovery scan did not see that access, so the generated catalog has no entry for it — typically because the access sits behind a preprocessor branch that was inactive during the discovery compile, or the testbench file was added without a rebuild. Make the access visible in a compiled translation unit and rebuild (--rebuildif the cache disagrees). See the discovery step in How a build works.hierarchy scope array index is out of range. A literal index into a scope array is outside the declared bounds; the valid range is part of the generated type. Runtime (non-literal) indices are checked at run time instead, with the scope path and valid indices in the message.A misspelled signal is an ordinary compile error — the
Dutstruct simply has no such member.cpptb-codegen --inspect-hierarchyprints what was generated.
Run-time errors¶
Message |
Meaning and fix |
|---|---|
|
The simulator process died before writing its result. The reason is in |
|
The binary and the runner disagree on the result schema — a stale build against a newer checkout. Rebuild ( |
|
Test names are the registered C++ function names. |
|
|
|
Period halves and phase must be whole multiples of the simulator precision |
|
Only a one-bit input can be scheduler-driven. A DUT-produced clock is awaited, not started — see DUT-produced clocks |
|
Two tests in one binary register the same pin with different periods or phases. Per-test configurations are legal only when they agree |
|
Phase order within a timestep is enforced. Leave |
A write rejected during |
|
|
The in-simulation cycle watchdog ( |
Reading a hang¶
A test that times out — by run.timeout_cycles, by a registered
simulation_timeout, or by end-of-simulation starvation — captures the
scheduler wait graph before cancellation, prints it, and stores it in the
result JSON. The graph names each process, its spawn site, and the exact
edge, phase, event, queue, lock, or semaphore it is parked on, with a
conservative deadlock classification. Start there rather than with a
waveform: it usually names the missing set() or the never-published event
directly.
Exit codes¶
0 — every selected test passed. 1 — a test failed or errored. 2 — the
run never started (project, configuration, generation, or build error). See
cpptb command line.