I am trying to write a assertion for the below check.
I have a test in which a signal goes high at any random point of time.
I have to check this using assertions whether it is going high at any time during simulation or not and if not then print an error.
I wrote the below one.
When the signal (sig1) goes ‘0’ to ‘1’ then it works fine, but if the signal does not goes high (0->1) then the error message is not getting printed.
Could you please suggest any idea to get it resolved.
Thank you for your suggestion.
I tried the same you suggested.
But I am getting the below error. “Operator ‘eventually’ not supported.”
could you please suggest some other way?
Suppose, 0 to n clock cycles are there in my simulation and the $rose(sig1) is coming after x clock cycles.
Then this assertion is showing errors for the (n-x) clock cycles, because after x clock cycles also it is expecting $rose(sig1) to come, but ideally it should check only once of $rose(sig1) throughout the signal.
In reply to sanjay864u:
I am not sure I totally understand your question, but if you just want one occurrence of the assertion use the initial statement.
import uvm_pkg::*; `include "uvm_macros.svh"
module top;
bit clk, a;
logic sig1;
default clocking @(posedge clk); endclocking
initial forever #10 clk=!clk;
initial assert_check: assert property (
@(posedge clk) strong(##[1:$] $rose(sig1)) );
initial begin
repeat(30) @(posedge clk) ;
sig1 =0;
repeat(200) begin
@(posedge clk);
#2 if (!randomize(a, sig1) with
{ a dist {1'b1:=1, 1'b0:=3};
sig1 dist {1'b1:=1, 1'b0:=20};
}) `uvm_error("MYERR", "This is a randomize error")
end
$finish;
end
endmodule
What about if I want to see that signal sig2 should change only once during simulation after sig1 asserted and error should fire if changed more than once.
@(posedge clk) strong(##[1:$] $rose(sig1)) );
This assertion only check once and it will be finished.
In reply to ben@SystemVerilog.us:
What about if I want to see that signal sig2 should change only once during simulation after sig1 asserted and error should fire if changed more than once.
@(posedge clk) strong(##[1:$] $rose(sig1)) );
This assertion only check once and it will be finished.
Your above sequence (used as a property) does not meet your requirements as it makes no mention of sig2. Also, with what you wrote, if sig1 occurs after 1 million cycles, your assertion creates 1 million separate threads. The simulator may do some optimization.
Thus, for a single firing, put the assertion in an initial block.
assertions typically have an antecedent and a consequence. Something like:
ap_s1s2: assert property (@(posedge clk) $rose(sig1) |-> s_eventually sig2 );
ap_s1s2b: assert property (@(posedge clk) $rose(sig1) |-> strong(##[*0:$] sig2));
ap_s1s2c: assert property (@(posedge clk) $rose(sig1) |-> strong(sig2[->1]));
FOr and error should fire if changed more than once, consider the use of the cover
bit my_error; // If true, fire a message
cp_s1s2b: cover property (@(posedge clk) $rose(sig1) |-> (sig2[->2]) my_error <= 1'b1;
Thank you Ben, I understand your point. But my requirement is,
Signal B should be only changed 1 time during Signal A’s assertion and de-assertion. Signal A may be asserted- de-asserted many time during simulation.
hai, ben.
here you are calling the assertion in the initial block right? initial block will execute only once at zero simulation time correct? then does the assertion checks only for first time?
An assertion is initiated at every leading clocking event.
An initial statement has ONE leading clocking event, thus it is initiated once.
A concurrent assertion instantiated directly in a unit has an implicit “always”.
A concurrent assertion instantiated inside an initial or always does not have this implicit always.
Ben systemverilog.us