FVO — Formal Verification Online
Lesson 4.5 · Formal Property Verification (FPV) Basics

Adding assumptions and assertions

Now translate the specification, item by item. Inputs rules become assumptions; behaviour of the timer becomes assertions.

periodic_timer_fv.sv
// periodic_timer_fv.sv — formal wrapper for the periodic timer
module periodic_timer_fv #(
  parameter int W = 8
) (
  input logic         clk,
  input logic         rst,
  input logic         load,
  input logic [W-1:0] period,
  input logic         stop
);
  logic [W-1:0] count, period_q;
  logic         running, irq;

  periodic_timer #(.W(W)) dut (.*);

  initial assume (rst);
  default clocking cb @(posedge clk); endclocking
  default disable iff (rst);

  // ------------------------------------------------------------ assumptions
  // Spec 1: software never loads a period of 1
  m_period_legal: assume property (load |-> period != W'(1));

  // ------------------------------------------------------------ assertions
  // Spec 2: count decrements while running
  a_decrement:  assert property (running && !stop && !load && count > W'(1)
                                 |=> count == $past(count) - W'(1));
  // Spec 3: reload and interrupt at the end of a period
  a_reload:     assert property (running && !stop && !load && count == W'(1)
                                 |=> count == period_q && irq);
  a_irq_cause:  assert property (irq |-> $past(running && !stop && !load && count == W'(1)));
  a_irq_pulse:  assert property (irq |=> !irq);
  // Spec 4: stop holds the value
  a_stop_holds: assert property (running && stop && !load |=> $stable(count));
  // Spec 5: load has priority
  a_load:       assert property (load |=> count == $past(period) && irq == 1'b0);
  // Invariant: a running timer always has a count within its period
  a_count_rng:  assert property (running |-> count != '0 && count <= period_q);

  // ------------------------------------------------------------ covers
  c_running:   cover property (running);
  c_irq:       cover property (irq);
  c_two_irqs:  cover property (irq ##[1:$] irq);
  c_stop_hold: cover property (running && stop ##1 running && stop);
  c_reload_while_running: cover property (running && load);
endmodule
periodic_timer.sby
# periodic_timer.sby
[tasks]
prove
cover

[options]
prove: mode prove
cover: mode cover
depth 24

[engines]
prove: abc pdr
cover: smtbmc

[script]
read -formal periodic_timer.sv periodic_timer_fv.sv
prep -top periodic_timer_fv

[files]
periodic_timer.sv
periodic_timer_fv.sv

The first run — without the assumption

Suppose you initially forgot m_period_legal. The tool reports that a_irq_pulse fails with a short trace:

012345FAILclkrstloadperiod1count01irq
Counterexample for a_irq_pulse: period = 1 reloads count = 1 every cycle, so irq stays high instead of pulsing.

Is this a bug? The spec explicitly forbids a period of 1, so the trace uses illegal stimulus. The right fix is the assumption — and only because the spec says so. If the spec had allowed a period of 1, the right fix would be in the RTL or in the spec itself.

With the assumption in place, all assertions should prove and all covers should be hit.

Was this page helpful?

Tip: select any text on the page before clicking Report and it will be quoted in your report.