$past with an input signal - system-verilog

I want to verify that if an event occurrs, then at “num_ticks” in the past, some signal should have been asserted.
As an example, the property I wrote is:
property test_past;
#(posedge clk)
$rose(gnt) |-> $past(req, num_ticks);
endproperty
The problem here is with num_ticks. If num_ticks is an input signal to the module in which the property is written, then the assertion fails. If I declare num_ticks as an int, and assign it to a constant, it passes.
Does $past only work for constant values? This is not mentioned in the LRM.
I am using Questasim 10.3

You might use multiple assertions for this purpose.
Suppose num_ticks is 4 bits wide, then you can do like this.
genvar x;
generate
for (x=0; x<16; x++)
begin
property test_past;
#(posedge clk)
(num_ticks == x) && $rose(gnt) |-> $past(req, x);
endproperty
end
endgenerate

Related

Stable for n*8 cycles property

I am learning SVA and trying to get my head around this check: data can only change every 8 cycles.
I know I can do that check by adding a counter that counts clock cycles and checking against it that way:
bit[2:0] count;
always #(posedge clk)
begin
count++;
end
change_n8cycles: assert property (#(posedge clk) $changed(data) |-> count == 0);
However, I'm interested in a way to do that with only SVA. So far, I was thinking of something like that (which doesn't compile)
property change_n8cycles(valid, ready, data);
#(posedge clk)
$changed(data) |=> $stable(data)[*7] ##1 ($stable(data)[*8])[0:$] ##0 $changed(data);
endproperty : change_n8cycles
I feel there is an elegant way using an approach similar; or using recursive properties. However, I couldn't find it.
I would propose to use local variable in order to verify that
property change_n8cycles(valid, ready, data);
int lv_cnt;
#(posedge clk)
($changed(data), lv_cnt=0) ##1 ($stable(data), lv_cnt=lv_cnt+1)[*1:$] ##1 $changed(data) |-> lv_cnt == 8;
endproperty
Or use some modeling layer
always #(posedge clk) begin
if($changed(data))
count=0;
else
count++;
end
property change_n8cycles(data);
#(posedge clk)
$changed(data) |-> $past(count) == 8;
endproperty

SV assertion based on event trigger

Assume SV interface contains a concurrent assertion property.
Is it possible to enable this assertion only when an event is triggered? I tried writing property inside a task in interface file, but I ended up with error: near "property": syntax error, unexpected property.
Interface intf;
task e1();
-> e1;
endtask
wait(e1.triggered); // something like this, where property waits for trigger
property prop1;
#(posedge clk) a ##1 b;
endproperty
endinterface
Thank you.
I think you need to consider that properties are best written synchronously and are evaluated on every clock cycle. You property says that one cycle after every clock cycle where a occurs b occurs. I guess what you're after is something like:
if e1 occurs, then a should be true (on the next rising edge of
clk?) and then b should be true on the rising edge of clk after
that
So, one way of doing that would be to create an always block that generates a pulse one clock wide should e1 occur, eg:
always begin
#(e1);
#(posedge clk) e = 1'b1;
#(posedge clk) e = 1'b0;
end
property prop1;
#(posedge clk) e |-> a ##1 b;
endproperty
or some variation of that. I feel like I should be worried about races, however.

Data Mux SVA compare

I've trouble designing assertions(SVA) for this scenario.
When a mux sel is asserted, the data_in is expected to be stable for 2 clocks ; clock prior to mux sel being asserted, and the current clock when mux sel is asserted.
Now the data_in is a wide vector/bus signal, whereby some bits of the bus are Z and X during functional mode (this is expected), while this bits may carry value during non-functional mode.
This then implies, the approach to design the SVA would be to compare bit by bit of data bus when mux sel is asserted.
This is my approach, but SVA fails and am not sure why.
generate
for( genvar i=1 ; i<BUS_WIDTH ; i++ ) begin
always # (posedge clk) begin
if(!$isunknown(data_in[i]) && reset) begin
data_in_temp_prev[i] <= data_in[i];
if (mux_sel==1 && reset==1 && i>0) begin
SVA_TEST: assert property (data_in[i] == data_in_temp_prev[i-1]) else `uvm_error("TRIAL_SVA",$sformatf("datain expected to be stable for 2 clks prior to mux sel"));
end //if
end //if isunknown
else begin
din0_temp_prev[i] <= 0;
end
end //always
end // for genvar
endgenerate
Any suggestions on how to approach designing this SVA ?
Thanks.
If I understood correctly your problem, you don't need all this structure for this kind of problem, look at my example below and tell me if helps or not.
property mux_compare;
disable iff(!reset)
#(posedge mux_sel)
!$isunknown(data_in)
|->
#(posedge clk)
$stable(data_in) [*2];
endproperty: mux_compare
My approach to SVA checkers is to use a standard structure to properties to avoid all kinds of problems. the structure is to always use clocked properties with "disable iff" and always use an implication operator, where the left hand side is the trigger and the right hand side is what we want to verify.
Here's an example from the LRM:
property abc(a, b, c);
disable iff (c) #(posedge clk) a |=> b;
endproperty
similarly to the answer above, I would do this:
property mux_compare;
disable iff(!reset) #(posedge clk)
mux_sel===1 |->
!$isunknown(data_in[i]) || $stable(data_in) && data_in[i] == $past(data_in[i],2);
endproperty: mux_compare

How to pass information from inside sequence/property to the outside world

I have a property that is waiting for two different sequence to happen, as follows (the sequence and property are already simplified here):
sequence seq1;
logic [3:0] a;
#(posedge clk) (some_signal1 == 1, a = other_signal1);
endsequence
sequence seq2;
logic [3:0] b;
#(posedge clk) (some_signal2 == 1, b = other_signal2);
endsequence
property abc;
seq1 ##[1:$] seq2;
endproperty
some_signal1,some_signal2, other_signal1, other_signal2 are all RTL signals.
My question:
When the property abc is passed or covered, I want to know the corresponding other_signal1 and other_signal2 sampled in the sequences. How can I access those signals values?
I am thinking to hierarchically access the sequence local variables, such as seq1.a or seq2.b. But these are not allowed, as they are locals.
Declaring those variables as formal argument also does not help, because formal argument can not be assigned in the LHS.
My intention is that I am going to use those signals for other purpose, i.e.:
cover property (abc) begin
// grab seq1.a and seq2.b, and do some other tasks
end
You can do one of 3 things on the right of the comma inside the ( , ):
an assignment (to a local variable)
increment or decrement
call a tasks, task method, void function, void function method or system task.
(see IEEE1800-2012, 16.11 Calling subroutines on match of a sequence)
A task call is the key to this. You can assign to variables outside the task scope within a task called from within the sequence:
sequence seq1;
#(posedge clk) (some_signal1 == 1, assign_a(other_signal1));
endsequence
sequence seq2;
#(posedge clk) (some_signal2 == 1, assign_b(other_signal2));
endsequence
property abc;
seq1 ##[1:$] seq2;
endproperty
cover property (abc)
$display("a= %d, b= %d", a , b);
task assign_a(input int i);
a = i;
endtask
task assign_b(input int i);
b = i;
endtask
http://www.edaplayground.com/x/akw

system verilog assertion disable condition

I have this assertion in order to check clk freq:
assert property clk_freq;
int cnt;
#(posedge fast_clk, clk_1MHz) disable_iff(!enable_check)
($rose(clk_1MHz), cnt=0) |=> (!$rose(clk_1MHz),cnt++) [*0:$] ##1 $rose(clk_1MHz), cnt==fast_clk_freq;
endproperty
fast_clk starts to toggle during (not from beginning) of the simulation after disable_check is asserted.
The problem is that it seems that the assertion ignores the disable_iff
Question: is a $rose(clk_1Mhz) event "registered" even though the assertion is disabled (or am I missing something else ?)
There is no disable_iff keywords, it is disable iff (without the underscore). Properties can have local variables but the local variables cannot be defined inline with assert. Separate the property definition and the assertion instantiation.
The clock sampling doesn't seem to be correct. #(posedge fast_clk, clk_1MHz) mean on rising fast_clk or any change to clk_1MHz. clk_1MHz is the sampled data value, therefore it should not be a clock.
$rose(clk_1MHz), cnt==fast_clk_freq is ilegal syntax, sugest: $rose(clk_1MHz) ##0 cnt==fast_clk_freq
Suggested property definition and the assertion instantiation:
property p_clk_freq;
int cnt;
#(posedge fast_clk) disable iff(!enable_check)
($rose(clk_1MHz), cnt=0) |=> (!$rose(clk_1MHz),cnt++)[*0:$] ##1 $rose(clk_1MHz) ##0 cnt==fast_clk_freq;
endproperty
a_clk_freq : assert property(p_clk_freq);
For more on assertions refer to section 16 of IEEE Std 1800-2012.