Assertion: Expected data check // A review from a user's question

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. 

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