Merge the runs under a conflict check.
Prove which uncovered points can never execute.
Retire those by proof, and let an independent check refuse false closure.
A coverage report near the end of a project is mostly uncovered points that will never be hit. Some are gaps in the test plan. Others are structurally dead: a branch a constant makes impossible, a state the reset logic can never leave, a signal not present in the executable model. The usual way to clear those is a manual waiver, and a waiver is a claim on the engineer's word that a point is unreachable. Formal reachability replaces the word with a proof. Coverage a formal tool shows can never execute is retired from the target by proof, and the number that reaches signoff moves only by what the prover could establish.
The design under measurement is wz_mini_soc, a WIOWIZ-original SoC run across 8 instances. Coverage comes from FSiMX v0.5.267; the unreachability evidence comes from a vwiz-formal v0.14.1 proof bundle. FSiMX Studio joins the two on stable point ids, applies the proof to the denominator, and shows the ladder from raw to proof-refined at every step.
Merging two runs under a conflict check
Coverage from separate runs is combined before it is refined. A merge that simply adds bins together will happily fuse two databases that disagree about the design, and then every number downstream is built on a contradiction. The merge here is guarded: point ids from each run are matched, and a run that describes a point differently from another run is a conflict, not a silent overwrite. Matching definitions union their hits; mismatched definitions stop the merge and name the first offender.
The result is one database whose points mean the same thing across every run that contributed to it. That property is what makes the later proof join sound: the formal bundle keys its verdicts on the same ids, so a proof about u_dma.branch.17 attaches to exactly the point the merged runs measured, never to a lookalike.
Formal reachability as an independent check
The formal proof engine (vwiz-formal) proves which uncovered gaps are truly unreachable. Only those leave the coverage target, and the ladder from raw to proof-refined stays visible. On the branch metric for this SoC: raw 77/89 (86.52%) refined to 77/86 (89.53%). Three points left the denominator, each with a STRUCTURAL_DEAD proof; the numerator did not move, because refinement removes points that could never be hit, not points that were.
The check is independent by construction. FSiMX Studio does not accept a formal result on trust: the bundle is imported hash-gated, joined on stable point ids, and refused if it contradicts what simulation already established. An independent arbiter that adopts a producer's every claim is not a check; it is a relay. The value is in what it declines.
The contradiction catch
The reason to keep the check independent is that a trusted producer can be wrong. A formal bundle once marked A_DMA_COUNT as UNREACHABLE while the merged simulation database held 48 hits for that same point. A point simulation reaches 48 times is not unreachable, and the two verdicts cannot both stand. The proof and the witness are about one point id, so the conflict is exact, not a heuristic guess.
EVIDENCE JOIN bundle=vwiz-formal points=4283 keyed=1 contradiction REJECT: formal marked a simulation-hit point unreachable first : assertion.dut.A_DMA_COUNT formal : UNREACHABLE sim : 48 hits exit 2 • rollback • database unchanged
The import was rejected atomically: exit code 2, full rollback, the false verdict never entered the database. Reconciliation is not a merge of the two answers into a middle value. A simulation hit is a witness of reachability that a proof cannot overturn, so the hit stands and the proof is thrown out with the offending point named. The producer fixes its model and re-submits; nothing about the point is quietly downgraded in the meantime.
| point | formal verdict | sim hits | reconciled outcome |
|---|---|---|---|
| assertion.dut.A_DMA_COUNT | UNREACHABLE | 48 | import rejected, rollback |
| u_dma.branch.17 | STRUCTURAL_DEAD | 0 | retired from target |
| u_cpu.branch.42 | REACHABLE | 0 | kept, still a gap |
| u_timer.branch.09 | UNDETERMINED | 0 | kept, still counted |
Dead code retired by proof, not by waiver
A manual waiver says a point cannot happen and asks the report to believe it. A STRUCTURAL_DEAD proof shows the point cannot happen and lets the report check the evidence. For this run the difference is four numbers: 3 structurally-dead proofs removed from the target, 0 manual waivers. Every point that left the denominator carries a prover's reason next to it: “signal not in executable model” for one, a constant-forced condition for another, and the audited exclusion ledger records each removal so signoff can re-derive the refined number from the raw one.
Whole-design closure is incremental for the same reason. This round's proof governs the branch metric only; line, toggle, and FSM carry simulation coverage with no formal verdicts yet. The formal model gains executable equations metric by metric, so the whole-design denominator moves by only 3 points while the branch metric refines by proof. Every denominator change is proof-governed; none is fabricated to make the number look finished.
The three-way result
The point of the exercise is a report that separates three states instead of two. Covered is a point simulation hit. Uncovered splits: a point the prover shows is unreachable is retired from the target, and a point that stays reachable or undetermined is kept and still counted against the goal. A two-state report forces the undetermined middle into one bucket or the other, and either choice is a lie about what is known. The three-way result keeps the unknown visible.
On the signoff cockpit the ladder reads raw 4314 to refined 4311: 3 dead by proof, 9 unknown kept, 0 waivers. The refined denominator is the number that reaches signoff, and every step from the raw count to it is a proof or a hit on the record, re-derivable by anyone who reads the ledger.
One gate protects all of this: a bundle whose point ids are not in the design's coverage catalog is refused, not guessed. When a formal submission keyed 89 verdicts on ids absent from the FSimX catalog, the orphan gate rejected the whole import rather than attach verdicts to points that do not exist. Coverage measures what is measured, or it says nothing.
A proof lets the report check it, and refuses the word that fails.
