What a Proof Covers
Draw the cone of influence of every property, find the logic no property reads, measure the proof core by cutting, and read cover depths as bounded coverage.
- Lesson
- F7.1
- Time
- 20 min
- Runs on
- SymbiYosys
- Check
- 5 questions
A counter block was signed off as "all properties proven". Months later its debug register returned a stale value after every wrap. No property read that register, so no proof had ever looked at it.
The Cone of One Property
Read the diagram as text
- en, fast_in: free inputs
- fast: speed mode register: step by 2
- count: wraps 9 to 0 (8 to 0 when fast)
- dbg: debug mirror of count, one cycle late
- a_cnt: count <= 9
- en, fast_in → fast
- fast → count
- count → a_cnt
- count → dbg: feeds, but nothing reads dbg
Measured by Yosys: the cone of a_cnt holds count, fast. The debug register is in no cone, so no run of this property can say anything about it.
%ci* walks the input cone of a check to a fixed point; intersecting with registers and memories keeps the state. count_q and past are bench registers.read_verilog -formal -sv design.sv
prep -top ctr_dbg
flatten
opt_clean
write_json net.json
cd ctr_dbg
select -write cone_a_cnt.txt a_cnt %ci* t:$dff t:$mem_v2 %u %i
select -write cone_a_dbg.txt a_dbg %ci* t:$dff t:$mem_v2 %u %i
# cone_a_cnt.txt count fast
# cone_a_dbg.txt count count_q dbg fast pastA property reads a few signals. Those depend on registers, which depend on inputs and other registers. Everything reachable backwards from the property is its cone of influence. Logic outside the cone cannot change the verdict, so tools drop it before solving.
One More Property, a Bigger Map
| ctr_dbg with the mirror bug | Registers in the cones | Measured result |
|---|---|---|
count <= 9 only | count, fast | Prove PASS (k = 10) |
plus dbg == $past(count) | count, count_q, dbg, fast, past | FAIL at reported step 8 |
| both, mirror fixed | count, count_q, dbg, fast, past | Prove PASS (k = 10) |
Prove mode, smtbmc yices, depth 10, reset assumed in step 0. One property changed; the map grew over dbg and caught the bug.
Measured: FAIL at reported step 8 (smtbmc yices, prove depth 10). In the wrap cycle the faulty mirror skips its update, so dbg is still 7 when it should be 9.
The first run was a true proof of a true property. It said nothing about dbg, because dbg was not in its cone. Coverage starts by asking which logic your properties read at all.
The Map of the Module Spine
| Check on the 4 × 8 FIFO | Registers in its cone | Bits |
|---|---|---|
a_empty | count, rd_ptr, wr_ptr | 7 |
a_full | count, rd_ptr, wr_ptr | 7 |
a_count | count | 3 |
a_level | count, rd_ptr, wr_ptr | 7 |
a_e2e | count, dut.mem, rd_ptr, sb_n, sb0, sb1, sb2, sb3, wr_ptr | 74 |
The four glue checks of F3.4 together reach count, rd_ptr, wr_ptr: 7 of the FIFO's 39 state bits. The 32-bit memory is white until the end-to-end check arrives.
White logic is unverified, not wrong. Here the white part is the data, the one thing a FIFO exists to keep. COI coverage is cheap and runs early, so run it before you believe a green dashboard. The next lesson measures what that white memory hides.
Inside the Cone: The Proof Core
Cut on fixed ctr_dbg, count <= 9 only | Measured result |
|---|---|
count cut: any value, every cycle | FAIL at reported step 2 |
fast cut | Prove PASS (k = 10) |
dbg cut (outside the cone) | Prove PASS (k = 10) |
A cut turns a register's output into a free input ($anyseq). Prove mode, smtbmc yices, depth 10.
fast is in the cone, yet the proof survives its cut: the counter stays at or below 9 at either speed. The part of the cone a proof needs is its proof core. The open tools do not print it; one cut per register measures it.
Logic in the cone but outside the core is a review question. It may be dead, redundant, or simply checked by no property. Here the speed mode needs its own property.
Bounded Coverage
Four covers on the spine, reached at reported steps 3, 6, 6, 8. A bounded run must reach past the deepest one.
Linear scale. 0 to 20 steps.
- Checked bound
- 10
- Required bound
- 9
- Claim
- Bounded check only
Measured: one entry at step 3; full at step 6; full, push and pop together at step 6; full again after two reads at step 8. The spine passes bmc at depth 10.
Cover mode prints the step each cover was reached at. The deepest one, step 8, is the shortest trace that shows that behaviour. A bounded proof below it never saw that behaviour; F7.3 turns this into a required depth.
Asked in Interviews
| Question | Answer |
|---|---|
| What does formal coverage mean? | Structural: which logic the properties read (the cone) and which logic the proofs needed (the core). Bounded: how deep covers and bounded runs reached. Behavioural: whether the properties notice injected faults (mutation, F7.2). |
| How does the proof core differ from the cone of influence? | The cone is everything the property could depend on. The core is the part the proof actually used, found from the invariant or by cutting registers one at a time. |
| Can a block be "proven" with white logic on the map? | Its properties are proven. The white logic is not verified, and the sign-off must name it and say why it is acceptable. |
Try It
The lab is ctr_dbg with the mirror bug and only the count property: Prove PASS (k = 10) in 0.5 s. Both rules in concurrent SVA; the design carries their immediate forms.
count_q (a registered copy) and a past guard.assert property (@(posedge clk) disable iff (rst) count <= 4'd9);
assert property (@(posedge clk) disable iff (rst) dbg == $past(count));Read the claim
Run as it is. PASS: but is
dbgverified? Check the cone listing above.Grow the map
Add
if (past) a_dbg: assert(dbg == count_q);to the check block and run. Read the step wheredbgfalls behind.Cut inside the cone
Fix the mirror, delete the new check, and turn
fastinto$anyseq. Then cutcountinstead. Which register is in the core?
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 proof covers its cone of influence and nothing else; draw the union of the cones before trusting a sign-off.
- White logic on the cone map is unverified, not wrong: name it in the review.
- The proof core is the part of the cone the proof used; cutting one register at a time measures it.
- Cover depths are bounded coverage: a bounded run below the deepest cover never saw that behaviour.