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
- SVA Handbook 4th Edition, 2016 ISBN 978-1518681448
- A Pragmatic Approach to VMM Adoption 2006 ISBN 0-9705394-9-5
- Using PSL/SUGAR for Formal and Dynamic Verification 2nd Edition, 2004, ISBN 0-9705394-6-0
- Real Chip Design and Verification Using Verilog and VHDL, 2002 isbn 978-1539769712
- Component Design by Example ", 2001 ISBN 0-9705394-0-1
- VHDL Coding Styles and Methodologies, 2nd Edition, 1999 ISBN 0-7923-8474-1
- VHDL Answers to Frequently Asked Questions, 2nd Edition ISBN 0-7923-8115
- SVA Alternative for Complex Assertions
Verification Horizons - March 2018 Issue | Verification Academy - SVA: Package for dynamic and range delays and repeats | Verification Academy
- SVA in a UVM Class-based Environment
SVA in a UVM Class-based Environment | Verification Horizons | Verification Academy