SVA: an alternative to the "always"

Question: Once enable goes high in the next cycle, one pulse on signal “a” (1 cycle)
should be generated and from there it should be generated for every three clock cycles.

Got this request and it looked like a perfect adaptation for the use of the always property,
something like the following, but that did not work as with edaplayground tools do not seem to support
that property correctly.


ap_a10: assert property(
    @(posedge clk) $rose(enb) |-> always[1:100] (a |-> ##1 !a[*3] ##1 a))
      notify(1); else notify(0); */ 

So I took a different approach where with support logic I issued a “go” signal when enb completed the pulse.


// The enable and the go and the "a==1" after the enb
 initial begin
    $dumpfile("dump.vcd"); $dumpvars;
    repeat(3) @(posedge clk);  // a start delay 
    begin  
      enb <= 1;  
      fork t_a10(); join_none  // the test vector generation task 
      @(posedge clk) enb <= 0; go <=1; @(posedge clk);      
      am_0a: assert property (@(posedge clk) a==1) 
        $display("%t a==1 after enb goes to 0", $realtime); else
        $display("%t a==0 after enb goes to 0", $realtime);
    end
    repeat(50) @(posedge(clk)); 
    $finish;
  end

The assertion

    
  ap_a10b: assert property(
    disable iff(go==0)
    @(posedge clk) a |-> ##1 !a[*3] ##1 a)
      notify(1); else notify(0); 

Code and results

module top;
  /* Once enable goes high in the next cycle, one pulse on signal "a" (1 cycle) 
     should be generated and from there it should be generated for every ten clock cycles. */
  bit clk, enb, a, go, reset_n;
  int pass, fail;
  initial forever #1 clk = !clk;
  let T=3;
  function void notify(bit p); 
    if(p) begin pass=pass+1; $display("%t ap_a10 PASS", $realtime); end 
      else begin fail=fail+1; $display("%t ap_a10 FAIL", $realtime); end
  endfunction
  
  /* ap_a10: assert property(
    @(posedge clk) $rose(enb) |-> always[1:100] (a |-> ##1 !a[*3] ##1 a))
      notify(1); else notify(0); */ 
    
  ap_a10b: assert property(
    disable iff(go==0)
    @(posedge clk) a |-> ##1 !a[*3] ##1 a)
      notify(1); else notify(0); 

  task automatic t_a10(); // test vector generation 
    repeat(4) begin // good condition 
      @(posedge clk) a<=1;
      repeat(T) @(posedge clk) a<=0; 
    end
    repeat(4) begin // error condition 
      @(posedge clk) a<=1;
      repeat(T-1) @(posedge clk) a<=0; 
    end
  endtask 
  
  initial begin
    $dumpfile("dump.vcd"); $dumpvars;
    repeat(3) @(posedge clk);  // a start delay 
    begin  
      enb <= 1;  
      fork t_a10(); join_none
      @(posedge clk) enb <= 0; go <=1; @(posedge clk);      
      am_0a: assert property (@(posedge clk) a==1) 
        $display("%t a==1 after enb goes to 0", $realtime); else
        $display("%t a==0 after enb goes to 0", $realtime);
    end
    repeat(50) @(posedge(clk)); 
    $finish;
  end
endmodule
run -all
#                    9 a==1 after enb goes to 0
#                   17 ap_a10 PASS
#                   25 ap_a10 PASS
#                   33 ap_a10 PASS
#                   41 ap_a10 PASS
#                   47 ap_a10 FAIL
#                   53 ap_a10 FAIL
#                   59 ap_a10 FAIL
#                   67 ap_a10 FAIL
# ** 

Ben Cohen
Ben@systemverilog.us
Link to the list of papers and books that I wrote, many are now donated.

or Cohen_Links_to_papers_books - Google Docs