// assertion to check if all bits get set atleast once in simulation for a multibit vector
import uvm_pkg::*; `include "uvm_macros.svh"
module top;
bit clk, enb=1;
bit[3:0] fgs; // flags to check
default clocking @(posedge clk); endclocking
initial forever #10 clk=!clk;
property p_flags;
bit[3:0] v=0;
enb |-> (1, v=v | fgs)[*1:$] ##0 (v==4'b1111 || enb==0);
// When enb gets set to 0, another attempt gets started in the Preponed region
endproperty
ap: assert property(p_flags) enb=0;
initial begin
repeat(200) begin
@(posedge clk);
if (!randomize(fgs) with
{$countones(fgs)==1;}
) `uvm_error("MYERR", "This is a randomize error")
end
$finish;
end
endmodule
Thanks a ton for help, the assertion property is not failing is none of the bits gets set. I modified your constraint to {$countones(fgs)==0;} and no failure get generated.
Thanks for helping, your solution works fine but it always fails in the end if bits gets set to 0. I had to modify it a bit to get it working for my case:
a_p_check_single_bit_to_be_set : assert property (p_check_single_bit_to_be_set)
enb=0;
else
$display(“SVA”, “Bit was never set to 1”);
I incorporated this change from Ben’s solution.
This works fine for me but problem is eventually property is not yet supported by all tools AFAIK. Is there any way we can achieve the same without using eventually.
In reply to rohitk:
OOPS! There are TWO errors in my solution, and one in Srini’s
My solution needs a strong sequence, as a weak sequence would not fail if not completed.
This assertion needs to be fired ONCE. In both of our original solutions, at every clock yo have a new attempt, and some of those later attempts could produce a failure.
Below is a solution that will work for you. I am assuming that during the first 45 time units, the system is being initialized, and after that, you have a go signal. You don’t need this go signal if you want the assertion to be fired once at time 0.
// assertion to check if all bits get set atleast once in simulation for a multibit vector
import uvm_pkg::*; `include "uvm_macros.svh"
module top;
bit clk, go;
bit[3:0] fgs; // flags to check
default clocking @(posedge clk); endclocking
initial forever #10 clk=!clk;
property p_flags;
bit[3:0] v=0;
go |-> strong( (1, v=v | fgs)[*1:$] ##0 (v==4'b1111));
endproperty
initial begin // option 1
wait(go);
ap_flags: assert property(p_flags);
end
generate for (genvar g_i=0; g_i<4; g_i++)
initial begin // opton2
wait(go);
ap_fgsi: assert property( go |-> s_eventually fgs[g_i]);;
end
endgenerate
initial begin
#45 go <= 1'b1;
repeat(25) begin
@(posedge clk);
if (!randomize(fgs) with
{$countones(fgs)==1;
fgs <= 7;
}
) `uvm_error("MYERR", "This is a randomize error")
end
$finish;
end
endmodule
This works fine for me but problem is eventually property is not yet supported by all tools AFAIK. Is there any way we can achieve the same without using eventually.
generate for (genvar g_i=0; g_i<4; g_i++)
initial begin // opton2
wait(go);
ap_fgsbi: assert property( go |-> strong(fgs[g_i][-> 1]) );
end
endgenerate
In reply to ben@SystemVerilog.us:
I received an interesting new approach in resolving this assertion:
“I think that it be more efficient to use an always procedure that remembers that a bit has been set and then use an immediate assertion in a final block to check that all bits are set.” Below is code for that assertion. The complete model is at http://SystemVerilog.us/bitset.sv
module top;
bit clk, go;
bit[3:0] fgs; // flags to check
bit[3:0] chkfgs;
default clocking @(posedge clk); endclocking
...
generate for (genvar g_i=0; g_i<4; g_i++)
always_ff @(posedge clk)
if(go && fgs[g_i]) chkfgs[g_i] <= 1'b1;
endgenerate
// ap_chkfgs: assert final (chkfgs==4'b1111); // Incorrect! see below
final ap_chkfgs: assert (chkfgs==4'b1111); // OK
final ap_chkfgs: assert (chkfgs==4'b1111); // OK
// you do NOT need the 2nd final in
// final ap_chkfgs: assert final (chkfgs==4'b1111); // superfulous 2nd final