SVA : using $past

In reply to prashantk:

First, I was wrong on the following statement
“$rose(a_4bitbus) means that a_4bitbus went from 4’b0000 to something other than 4’b0000. Thus you would get a rose if a_4bitbus went from 4’b0000 to 4’b0001 or to 4’b1010 or 4’b0100 …”
That is in error. after doing the following simulation, it became clear to me that for

**bit[3:0]** a_4bitbus;
**$rose(a_4bitbus) is same as $rose(a_4bitbus[0])**

I should have re-read my book, as in it I state

$rose returns true when the sampled value of a Boolean signal argument transition is true at the current cycle (i.e., least significant bit of the expression==1’b1) and FALSE in the previous cycle (i.e., was 0, X, or Z), with respect to the clock of its context, otherwise it returns FALSE.

My apologies, when I am wrong, I am wrong.


import uvm_pkg::*; `include "uvm_macros.svh" 
`timescale 1ns/1ns
module top; 
	bit clk, a, b; 
	bit[3:0] data, data_past; 
	default clocking @(posedge clk); endclocking
	initial forever #10 clk=!clk;  
	
	always_ff  @(posedge clk)  begin 
		data_past <= data; 
	end 	
 
	ap_rose_4bits: assert property( 
				($rose(data), $display("@t=%t, data=%b", $time, data)) |-> data[0]) 
				$display("@t=%t  PASS", $time);  else $display("@t=%t  PAIL", $time); 
	
	ap_change: assert property($changed(data) |-> data_past==$past(data,1)) 
			$display("@t=%t, ap_change PASS", $time);  else
            $display("@t=%t, ap_change FAIL", $time);
	
	initial begin 
		repeat(200) begin 
			@(posedge clk);   
			if (!randomize(data)) `uvm_error("MYERR", "This is a randomize error") 
				/*if (!randomize(data)  with 
					{ data dist {4'b0000:=8, 4'b1001:=1, 4'b0110:=1, 4'b0100:=1};
					}) `uvm_error("MYERR", "This is a randomize error")	*/		
		end 
		   $stop; 
	end 
endmodule  
// simulation 
 @t=                  30, ap_change PASS
# @t=                  70, ap_change PASS
# @t=                 110  PASS
# @t=                 110, data=0101
# @t=                 110, ap_change PASS
# @t=                 130, ap_change PASS
# @t=                 150, ap_change PASS
# @t=                 170  PASS
# @t=                 170, data=1111
# @t=                 170, ap_change PASS
# @t=                 190, ap_change PASS
# @t=                 230, ap_change PASS
# @t=                 250, ap_change PASS
# @t=                 270, ap_change PASS
# @t=                 290  PASS 

For your $past question, here is what I wrote in my book. Hopefully that should answer your questions.
SVA Handbook 4th Edition
“The $past function provides the sampled value that an expression held in a previous nth cycle. The syntax of the function is: [1]
$past( expression1 [, number_of_ticks] [, expression2] [, clocking_event])
expression1 represents the expression being sought.
The three optional arguments define the following:
 expression1 and expression2 can be any expression allowed in assertions.
 number_of_ticks specifies the number of clock ticks in the past. number_of_ticks must be one or greater, and must be static (i.e., known at elaboration time). If number_of_ticks is not specified, then it defaults to 1. If the specified clock tick in the past is before the start of simulation, the returned value from the $past function is a value of X.
 expression2 is used as a gating expression for the clocking event. The value returned for $past is expression1 sampled number_of_ticks gated cycles ago. In other words, for:
$past(data, 3, load_enable, @(posedge clk)) the returned value is the sampled value of data in the 3rd prior cycle in which load_enable was true. This is demonstrated in Figure 4.1.1.1-2 /ch4/4.2/past.sv
 clocking_event specifies the clocking event for sampling expression. A clock tick is based on clocking_event.
 Examples: :
regload |=> reg_data==$past(data); // value of load_data at the previous cycle
regload |-> ##2 reg_data==$past(data, 2); // value of load_data at 2 cycles ago
regload |-> ##2 reg_data==$past(data, 2, 1, @(posedge clk)); // value of load_data at 2 cycles ago
regload |-> ##2 reg_data==$past(data, 3, load_enable, @ (posedge clk) );”

One more thing on the $past, To avoid intial potential errors, consider using a ##1 in the antecedent; thus, " ##1 $changed(data) |->$past(…"
A long time ago, when I first learned VHDL, a consultant taught me a simple lesson: Whenever you fail to understand a syntax, run a samll sample program to test your understandings. The likelyhood that the simulation tool understands and implements the language better than you do is very high.
:)

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us