Assertion for counter

Your requirements are complex, and SVA s really not meant for such complex problems.
I wrote a paper dealing with SVA Alternative for Complex Assertions
Verification Horizons - March 2018 Issue | Verification Academy

If I understand your requirements, you want a counter to start 2 clocks after the start and keeps on counting modulo value until the fall of start

NOT EVERY ASSERTION NEEDS TO BE WITTEN IN SVA. Following is the model that I described in my paper, the key elements are shown below:


always  @(posedge clk)  begin 
            if($rose(start)) 
            fork t_count();
            join_none
        end 
        
        task automatic t_count(); 
            automatic int vdata;  
            vdata=data; 
            @(posedge clk) begin : thetask       
                assert (counter==0);
                repeat (2) @(posedge clk); // delayed count 
                while(!$fell(start)) begin : thewhile 
                    @(posedge clk);
                    assert(counter==$past(counter + 1'b1) % vdata);
                end : thewhile
                @(posedge clk); 
                assert(counter==$past(counter));
            end : thetask       
        endtask  

Converting the above to SVA is complex and requires external flags set by function calls to keep each thread separate, particularly since you need the counter to count forever until the fall of start. It’s more complex than it is worth it.

The testbench is shown below. Am leaving it up to you to debug and fix the models to your needs.


    import uvm_pkg::*; `include "uvm_macros.svh" 
    module top; 
        timeunit 1ns;     timeprecision 100ps;    
        bit clk, start;
        int data=5; 
        int counter;   
        default clocking @(posedge clk); 
        endclocking
        initial forever #10 clk=!clk;  
        
        always  @(posedge clk)  begin 
            if($rose(start)) 
            fork t_count();
            join_none
        end 
        
        task automatic t_count(); 
            automatic int vdata;  
            vdata=data; 
            @(posedge clk) begin : thetask       
                assert (counter==0);
                repeat (2) @(posedge clk); // delayed count 
                while(!$fell(start)) begin : thewhile 
                    @(posedge clk);
                    assert(counter==$past(counter +1'b1) % vdata);
                end : thewhile
                @(posedge clk); 
                assert(counter==$past(counter));
            end : thetask       
        endtask 
        
        initial begin : a1
            int ldata;
            forever 
            @(posedge clk) 
            if($rose(start)) begin : r1
                ldata=data;
                counter<= 0; 
                repeat(2) @(posedge clk);
                while (!$fell(start)) begin : thewhile2
                    counter <= (counter + 1'b1) % ldata;
                    @(posedge clk);
                end : thewhile2
            end : r1
        end : a1
        
        
        
        initial begin 
            bit vstart; 
            int vdata; 
            repeat(200) begin 
                @(posedge clk);  #2;  
                if (!randomize(vstart, vdata)  with 
                { vstart dist {1'b1:=25, 1'b0:=1};
                  vdata dist {3:=1, 5:=2};      
            }) `uvm_error("MYERR", "This is a randomize error")
            start <= vstart; 
            data <= 5;
        end 
        $stop; 
    end 
endmodule      

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact Home - My cvcblr


  1. SVA Alternative for Complex Assertions
    Verification Horizons - March 2018 Issue | Verification Academy
  2. SVA: Package for dynamic and range delays and repeats | Verification Academy
  3. SVA in a UVM Class-based Environment
    SVA in a UVM Class-based Environment | Verification Horizons | Verification Academy