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.
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