In reply to kalva:
With reference to your paper on Understanding SVA Engine for above example I could model below,
For T1 → On antecedent match → t_consequent → separate 5 threads → On any thread match it will succeed
For T2 → On antecedent match → t_consequent → separate 5 threads → On any thread match it will succeed
Your understanding of SVA is correct; this is how it works.
But same gnt is succeeding for 2 independent threads (req) which is potentially incorrect for a system in which there has to be a “gnt” for every “req”. Is there any operator/construct or re-code SVA we need to overcome this problem? Apology if I have overlooked your paper which talks about solution, can you please point me to the relevant section?
To accomplish uniqueness, you need supporting logic. Below are 2 solutions: mine and a modified version of the one suggested by the previous post. The previous post made the error of not incrementing the gnt_num when the property failed (i.e., when no gnt was received within the 1:5 clk periods.
/*You are correct that if you have 5 req pulse came with single gnt (on say 6th cycle) then you have 5 separate attempts all waiting for that ONE gnt. When the gnt arrives, it satisfies each of those 10 attempts.
(From my book) What is desired for this assertion is the exclusivity or uniqueness of each attempted thread sequences, meaning that one successful consequent does not terminate all concurrent attempts waiting for that consequent.
To accomplish this, one could use concepts of a familiar model seen in hardware stores in the paint department. There, the store provides a spool of tickets, each with a number. As a customer comes in, he takes a ticket. The clerk serving the customers has a sign that reads "NOW SERVING, TICKET #X". The customer that has the ticket gets served, the others have to wait. When done, the number X in incremented, and the next in-line customer gets served.
The assertion code could then be written as follows:*/
import uvm_pkg::*; `include "uvm_macros.svh"
module top;
timeunit 1ns; timeprecision 100ps;
bit clk,req, gnt, rst;
int ticket, now_serving;
int req_num,gnt_num;
initial forever #10 clk=!clk;
always @(posedge clk) begin
if(rst) begin
req_num<=0; gnt_num<=0;
end
else begin
if(req) req_num<= req_num +1'b1;
// if(gnt) gnt_num<= gnt_num + 1'b1;
end
end
function void inc_gnt_num();
gnt_num<= gnt_num + 1'b1;
endfunction
property p_not_working;
int num;
(req, num=req_num) |-> ##[1:5](gnt && (num == gnt_num));
endproperty
ap_not_working: assert property(@ (posedge clk) p_not_working );
property p1;
int num;
(req, num=req_num) |-> ##[1:5](gnt && (num == gnt_num), inc_gnt_num());
endproperty
ap_1: assert property(@ (posedge clk) p1 ) else inc_gnt_num();
///////////////////////
function void inc_ticket();
ticket = ticket + 1'b1;
endfunction
property reqgnt_unique;
int v_serving_ticket;
@(posedge clk) (req, v_serving_ticket=ticket, inc_ticket()) |->
##[1:5] now_serving==v_serving_ticket ##0 gnt;
endproperty
ap_reqgnt_unique: assert property(reqgnt_unique)
now_serving =now_serving+1; else now_serving =now_serving+1;
initial begin
repeat(100) begin
@(posedge clk); #1;
if (!randomize(req, gnt) with
{ req dist {1'b1:=1, 1'b0:=3};
gnt dist {1'b1:=1, 1'b0:=5};
}) `uvm_error("MYERR", "This is a randomize error")
end
repeat(200) begin
@(posedge clk); #1
if (!randomize(req, gnt) with
{ req dist {1'b1:=1, 1'b0:=3};
gnt dist {1'b1:=0, 1'b0:=1};
}) `uvm_error("MYERR", "This is a randomize error")
end
$stop;
end
endmodule
Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact http://cvcblr.com/home.html
** SVA Handbook 4th Edition, 2016 ISBN 978-1518681448
…
- SVA Package: Dynamic and range delays and repeats SVA: Package for dynamic and range delays and repeats - SystemVerilog - Verification Academy
- Free books: Component Design by Example https://rb.gy/9tcbhl
Real Chip Design and Verification Using Verilog and VHDL($3) https://rb.gy/cwy7nb
- Papers: