In reply to davidct:
In reply to ben@SystemVerilog.us:
Hi Ben,
I tried to run your code with Cadence Incisive 15.2.
I got this error:
($rose(go), push_data(data), my_ticket=get_ticket()) |-> (1,t_check_data(my_ticket));
|
ncvlog: *E,SFLNOS (tb.sv,35|75): Delays or wait statements in match item task calls are not supported.
What’s the workaround?
David
- This is a tool issue, task calls are supported by 1800’2012
sequence_match_item ::= operator_assignment | inc_or_dec_expression | subroutine_call
subroutine_call ::= tf_call | system_tf_call | method_call | [ std:: ] randomize_call
tf_call(note 37) ::= ps_or_hierarchical_tf_identifier { attribute_instance } [ ( list_of_arguments ) ]
Note 37: It shall be illegal to omit the parentheses in a tf_call unless the subroutine is a task, void function, or class method. If the subroutine is a nonvoid class function method, it shall be illegal to omit the parentheses if the call is directly
recursive.
- Workaround is to use tasks
See my paper at
PAPER: Understanding the SVA Engine + Simple alternate solutions - SystemVerilog - Verification Academy - Workaround Code below
// Model also at http://SystemVerilog.us/vf/question2a.sv
import uvm_pkg::*; `include "uvm_macros.svh"
module top;
bit clk, go, ready, rst=0;
int now_serving=1, ticket=0;
int q_data[$], data, pipe1, pipe2, out;
initial forever #10 clk=!clk;
function automatic void push_data(int data);
q_data.push_back(data);
endfunction : push_data
function automatic int get_ticket();
ticket=ticket+1'b1;
return ticket;
endfunction : get_ticket
/* ap_go_ready: assert property(
@(posedge clk) disable iff (rst)
($rose(go), push_data(data)) |->
ready[->1] ##0 out == q_data.pop_front());*/
// * Error: question2.sv(11): The method 'pop_front' is not allowed in assertions as it has side effects.
task automatic t_go_ready();
automatic int my_ticket;
if($rose(go, @(posedge clk))) begin
push_data(data);
my_ticket=get_ticket();
t_check_data(my_ticket);
end
else return;
endtask
task automatic t_check_data(int my_ticket);
forever begin
@(posedge clk) if(ready && my_ticket==now_serving) begin : is_ready
a_data_check: assert(out == q_data.pop_front());
$display("@ %t my_ticket", $time, my_ticket);
now_serving <= now_serving+1'b1;
return;
end
// ready[->1] ##0 out == q_data.pop_front());
end
endtask
always_ff @(posedge clk) begin
fork
t_go_ready();
join
end
property p_go_ready;
int my_ticket;
@(posedge clk) disable iff (rst)
($rose(go), push_data(data), my_ticket=get_ticket()) |-> (1,t_check_data(my_ticket));
endproperty
// ap_go_ready: assert property(p_go_ready);
always_ff @(posedge clk) begin
if(go) begin
pipe1 <= data;
pipe2 <= pipe1;
end
end
/* So when $rose(go) occurred twice, the payload was also updated twice before ready == 1.
When ready ==1, the payload had 2nd data but ready==1 with out was expecting the 1st data.
So I got a FAIL in simulator.
How to update the assertion to add a pipeline or FIFO so that the payload data gets
properly matched up with corresponding ready ?
Also, maybe make the FIFO/pipeline generic enough to have an N-deep and store more levels.*/
initial begin
repeat(200) begin
@(posedge clk);
if (!randomize(data, go, ready) with
{ data inside {[1:200]};
go dist {1'b1:=1, 1'b0:=3};
ready dist {1'b1:=1, 1'b0:=7};
}) `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 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