Your First Proof: The Same SVA, No Testbench
Run the error-response rule with free inputs, read the trace the solver writes, and see why the same assertion passed eighteen thousand times in simulation.
- Lesson
- F1.2
- Time
- 15 min
- Runs on
- SymbiYosys
- Check
- 4 questions
The error-response rule from A1.3 Implication and vacuous success (after a read that returns SLVERR, rvalid must drop) passed eighteen thousand times per regression. Nobody noticed that every pass was vacuous: the tests never addressed the error range, so the antecedent never fired. The team bound the same assertion into a formal run, and it failed in three cycles, with an address the test plan had never listed. The tool is not given addresses; it takes all of them.
Measured with smtbmc yices at depth 20. The sampled violation is step 3; SBY reports the clocked check at step 4.
Two Benches, One Rule
araddr, arvalid or rready; the solver may give them any value at every step. Arrows mean "supplies the inputs".Read the diagram as text
- Simulation driver: clock, reset, 18,000 addresses below F0
- rd_slave + assertion: one driven sequence
- Free inputs: araddr, arvalid, rready: any value, every step
- rd_slave + property: reset assumed in step 0
- Simulation driver → rd_slave + assertion: the chosen stimulus
- Free inputs → rd_slave + property: every allowed sequence
The RTL and the error-response rule are the same text on both sides. Only the source of the inputs changes.
A simulation bench drives one sequence. The A1.3 driver walked 18,000 addresses below F0, so rresp was never SLVERR, the antecedent never held, and every attempt of the assertion passed without checking anything. A formal bench has no driver. The design, the property and a reset assumption are the whole setup; the inputs are free, and at every step the solver may give them any value.
Three words from here on. A property is the rule. A counterexample is a trace that breaks it. A proof is the tool's statement that no counterexample exists within what it checked, bounded or unbounded (F1.5).
Read the Counterexample
Each frame holds the state and the free input values at one formal step. The obligation starts when the SLVERR handshake completes.
arvalid=0, araddr=0x00
rvalid=0, rresp=00No SLVERR obligation
No obligation yetarvalid=1, araddr=0xF0
rvalid=0, rresp=00No SLVERR obligation
No obligation yetarvalid=0, araddr=0x00
rvalid=1, rresp=10SLVERR handshake starts the obligation
No obligation yetarvalid=0, araddr=0x00
rvalid=1, rresp=10Required: rvalid = 0
× Failsarvalid=0, araddr=0x00
rvalid=1, rresp=10SBY reports the sampled failure
× Fails
Select a frame to inspect its inputs and assertion.
Step 3 violates the next-cycle rule; step 4 is where the clocked check is reported. Select a frame to inspect it.
The tool found the one sequence that breaks the rule and wrote it down: a .vcd with every signal, step by step. The shaded rows are the inputs it chose; the marked step is where the assertion fails. A formal counterexample is a directed test the tool wrote for you, and SBY also writes trace_tb.v, a testbench that replays it in any simulator.
| Run | Measured result | Time on this machine |
|---|---|---|
| Verilator, the A1.3 bench | 18,000 attempts; 0 SLVERR antecedents; 18,000 vacuous attempts | 227 ms |
sby bmc, clocked immediate assertion, yices | FAIL at reported step 4 | 372 ms |
sby bmc, the concurrent SVA through the subset compiler, yices | FAIL at reported step 4 | 351 ms |
sby bmc, the same SVA with |-> instead of |=> | FAIL at reported step 3 | 383 ms |
sby bmc, the fixed RTL | BMC PASS to depth 20 | 354 ms |
sby bmc, the concurrent SVA, z3 | FAIL at reported step 4 | 450 ms |
Same RTL, same rule. Yices chose address F0; Z3 chose F1. Both are in the error range, and the exact value is the solver's choice, not a fact about the design.
The |-> row fails one step earlier because the overlapping implication asks for !rvalid in the same cycle as the handshake, while rvalid is still high by definition. That is the wrong property, not a second bug; F1.4 sorts the two apart.
The Property in Two Forms
Concurrent SVA (what a JasperGold or VC Formal user writes)
assert property (@(posedge clk) disable iff (rst) rvalid && rready && rresp == 2'b10 |=> !rvalid);
An SLVERR completion requires rvalid low on the next clock.
Clocked immediate assertion (what this engine runs)
reg err_done=0;
always @(posedge clk) begin
err_done <= !rst && rvalid && rready && rresp == 2'b10;
if (!rst && err_done) assert(!rvalid);
end
err_done remembers the antecedent; the guard checks the next sample.
Both forms say the same thing. |=> becomes a flop that remembers "an SLVERR completed last cycle" and an assert guarded by it. The page shows the SVA because that is what the industry writes, and the engine form because that is what runs here; F3.1 teaches the translation table. In a real project the formal file is bound to the design, never edited into it (A7.1 Packaging and binding).
[options]
mode bmc
depth 20
[engines]
smtbmc yices
[script]
read_verilog -formal -sv design.sv
prep -top rd_slave
[files]
design.svWhat the Result Establishes
Depth 20 checks clocked samples 0 to 18. The buggy read channel fails at reported step 4 (sampled state 3), well inside the bound; the fixed one passes to the bound.
Linear scale. 0 to 25 steps.
- Checked bound
- 20
- Required bound
- 20
- First reported failure
- 4
- Claim
- Counterexample found
Required bound here means the task target. The fixed twin passes BMC at depth 20 (samples 0 to 18); no unbounded proof is claimed.
The fixed twin passes BMC at depth 20: no input sequence of up to 20 cycles from reset breaks the rule. That is a bounded result with its depth attached, not a proof for all time. The buggy twin fails at reported step 4; a FAIL is a reachable counterexample from the assumed reset.
A separate two-bit teaching model: reset reaches 00 and 11. An induction step may start at 01, a state reset never reaches, and step into the bad state 10.
The helper invariant a == b excludes 01 and 10. A counterexample to induction does not by itself show a reachable bug; F2.4 returns to this picture.
Read the states and transitions
- 00: initial, depth 0.
- 11: reachable, depth 1.
- 01: unreachable, depth 0.
- 10: bad, depth 1.
- 00 → 11.
- 11 → 00.
- 01 → 10 (induction candidate).
Illustration. A teaching drawing for the induction lesson, not a state enumeration of rd_slave. The counterexample on this page is reachable from reset.
Asked in Interviews
| Question | Answer |
|---|---|
| Does formal need a testbench? What replaces the stimulus? | No driver; the inputs are free and the solver chooses them. Assumptions (F1.3) shape what it may choose. |
| Why did my assertion pass in simulation and fail in formal? | Simulation checked only the inputs the tests produced; formal checked all of them and found one the tests never sent. |
Try It
Run and read
Run as it is: FAIL at reported step 4. In the trace find the address the solver chose; any value at or above F0 breaks the rule, and the exact value may differ between solvers.
Change the implication
Clear the
err_doneblock, paste the concurrent property into props.sv, change|=>to|->and run. FAIL one step earlier: the same-cycle check asks for!rvalidwhile the handshake is happening.Fix the RTL
Replace the condition
rresp == 2'b10 && !extrawith1'b0, leave props.sv blank, and run: BMC PASS to depth 20.
design.sv
props.sv
Use assert property (@(posedge clk) ...);. Leave blank for immediate assertions in the design.
Inputs are free unless constrained. Run to find a counterexample or check a proof.
Model: one positive-edge clock, binary data. Sampled history requires declaration-initialized variables; primary-input history is unsupported.
SBY summary and log
Check Yourself
Remember
- A property is the rule; a counterexample is a trace that breaks it; a proof says none exists within what was checked.
- Inputs are free; the solver chooses them, and assumptions shape what it may choose.
- A formal counterexample is a directed test the tool wrote; trace_tb.v replays it.
- At depth 20 this flow checks clocked samples 0 to 18; a PASS there is bounded, not a proof.