Assertion for counter

Hi,

I have a brief knowledge on assertions but i do want to get an idea on how i can write an assertion for this scenario

I have a counter. when you give a value and start the counter, the counter starts from 0 and starts counting upwards, and when it reaches the value you have given, it will go back to zero and start to count up again.

There is a overflow signal, which gets toggled whenever the overflow happens (the counter reaches the value given)

So to start the counter, i have to give the start bit as 1’b1.

When the start bit is high, it take 2 clock cycles for the counter to start counting. For eg. if the value given is 5, then overflow occurs at the 7th clock cycle. But if you do not stop the counter (by giving the start bit as 1’b0) the counter keeps on running, but this time the overflow occurs at 5th clock cycle itself.

How can i write an assertion for this ?

In reply to sid1406:

Could you please show your code? This helps to give you an advice.

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

In reply to ben@SystemVerilog.us:

I updated the testbench in my previous reply.
Ben

In reply to ben@SystemVerilog.us:

Thanks Ben for the reply. I will check it out and let you know if i have any queries

-Srisidharth