Near the end of a project, the simulation coverage report always has holes: coverage points that no test has hit. For each one, the team must decide whether to write a new test or to exclude the point as impossible. Guessing wastes weeks either way. Formal answers the question exactly: it either produces a trace that reaches the point, which becomes the recipe for a test, or it proves that the point can never be reached. This article classifies four coverage holes of a state machine.

8 min read | Intermediate

What You'll Learn

  • Explain how formal helps close simulation coverage
  • Turn a coverage point into a cover property or a meant-to-fail check
  • Classify holes as reachable, with a trace, or unreachable, with a proof
  • Use the classification to write tests and exclusions

The Coverage Problem

Functional coverage in a UVM testbench lists situations that must be exercised: states, transitions, combinations of inputs and states. A typical report at 95 percent coverage leaves hundreds of holes. Some are hard to hit with random stimulus; some can never be hit at all. Without knowing which is which, engineers spend days tuning constraints for points that are impossible.

Formal classifies each hole:

  • Reachable: the tool returns a trace. Its input sequence shows exactly how to reach the point, and becomes a directed test or a constraint change.
  • Unreachable: the tool proves the point can never happen. It is excluded from coverage, with the proof as justification.

Commercial tools offer this as an unreachability app that reads the coverage database directly. By hand, each hole becomes a cover property.

The Example: Four Holes

The request controller from the finite state machines article, in its fixed form, has these four holes in a simulation coverage report:

Coverage pointCondition
Acknowledge while waitingbusy && ack
Request while in ERRerr && req
Busy and error togetherbusy && err
ERR with the timer runningstate == ERR && t != 0

As covers in SVA:


c_ack:  cover property (@(posedge clk) disable iff (rst) busy && ack);
c_req:  cover property (@(posedge clk) disable iff (rst) err && req);
c_both: cover property (@(posedge clk) disable iff (rst) busy && err);
c_tmr:  cover property (@(posedge clk) disable iff (rst) state == ERR && t != 3'd0);

Results

In the lab form, each cover is a meant-to-fail assertion, such as always @(*) if (!init) assert (!(busy && ack));. On the lab engine:

  • Acknowledge while waiting: fails at step 2, so reachable. The trace: a request in step 1, the controller waits in step 2, and the acknowledge arrives in that same cycle. A test only needs an acknowledge one cycle after a request; a random test whose memory model always takes two cycles or more never produces it.
  • Request while in ERR: fails at step 6, so reachable: a request, four cycles without an acknowledge, and another request while in ERR.
  • Busy and error together: passes. In prove mode, with k-induction and with PDR, it is proven: busy and err decode different states, so they can never be high together.
  • ERR with the timer running: passes, and is proven as well: the controller clears the timer whenever it enters ERR.

The first two become directed tests, written from the traces. The last two are excluded from coverage, each with a short note citing the proof. The coverage report is then complete, honestly.

Quick Check

Q: A meant-to-fail check for a coverage point passes at depth 10. Can the point be excluded?

Show Answer

Not yet. A bounded pass only says it is unreachable within 10 cycles. For an exclusion you need a proof, by induction or PDR, or an argument that the depth exceeds the diameter of the relevant logic.

Reading a Cover Trace as a Test

A cover trace lists the inputs in every cycle, which is a test stimulus. For "acknowledge while waiting": reset in step 0, req in step 1, ack in step 2. In a UVM testbench, that becomes a sequence that issues a request and configures the memory model to answer after one cycle. Many teams convert cover traces into tests automatically.

Quick Check

Q: A coverage point is proven unreachable, but the specification says the situation must be possible. What now?

Show Answer

That is a bug, either in the design or in the formal assumptions. Do not exclude the point; investigate why the situation cannot occur, as in the covers article where a collision case revealed a priority bug.

Running It in ChipVerify Lab

The example below is the fixed controller with the four coverage points as meant-to-fail checks, of which only the first is active. Run it, then activate the others one at a time.

Common Mistakes

Mistake #1: Excluding holes on a bounded result

Exclusions need proofs. A bounded pass can hide a point that is reachable after many cycles.

Mistake #2: Excluding holes that the specification requires

An unreachable situation that the specification expects is a bug report, not an exclusion.

Mistake #3: Ignoring the assumptions in the formal setup

A point may be unreachable only because the formal environment is over-constrained. Make sure the assumptions match the simulation environment, or are weaker.

Practice Exercise

Challenge: Classify the Holes

Open the example. Run it with each of the four meant-to-fail checks active in turn. Record which fail, with the step and a one-line description of the trace, and which pass.

Hint

Uncomment one check at a time. A failing check gives the trace you need for the test.

Solution

"Acknowledge while waiting" fails at step 2 (request in step 1, acknowledge in step 2). "Request while in ERR" fails at step 6 (request, four cycles without acknowledge, request again). "Busy and error together" and "ERR with the timer running" pass, and both are proven unreachable in prove mode. The first two become tests, the last two exclusions.

Open the ready-made example in the lab and run the formal check from the formal panel. The free tier allows a depth of up to 10 cycles, and PRO allows up to 100.

Summary

  • Formal turns every coverage hole into either a trace or a proof of unreachability.
  • Reachable holes become directed tests, written from the cover trace.
  • Unreachable holes are excluded, with a proof as justification, not a bounded pass.
  • Of four holes in the request controller, two were reachable in 2 and 6 steps and two were proven unreachable.
  • An unreachable situation that the specification requires is a bug, not an exclusion.
Did you find what you were looking for?

Quiz

No quiz questions available for this article.