SVA to make sure only one bit of a bus is '1' at any given time

Hi All,

I’m trying to write an assertion to make sure that only 1-bit of a bus is ‘1’ at any given time (There could be times where all bits are zeros). I used a for loop to write an assertion for the above scenario as follows:

    always @(posedge clk) begin
        for(int i=0; i<20; i++)begin
            automatic int j=i;
            if(sel[j]) begin
                check_sel_one_hot : assert property (sel[j] |-> |sel[(j+1) +: 20]);
                break;
            end
        end
    end

However, I get the following error when I try running this :

*E : Specified object tb_top.vif.unmblk1.j is a subprogram parameter or (auto) variable.
*E : The above error is for XMMIRROR at File : ./top_if.sv, line : 130

I’m not sure if I’m using the automatic variable wrong. I appreciate if anyone can point out the problem with the above piece of code.

Also, please let me know if there is a simpler way to write this assertion.

Thanks in advance.

In reply to szy0014:

You should use the $onehot0 system function.

use ($onehot(sel) or sel==0) in your assertion.

There are few issues with your code

  1. you have this assertion in an always block, so you don’t need concurrent assertion.
  2. your bit splicing can go out of boundary.

if your intention was not to use any system Verilog inbuilt functions you can try something like this.

always @(posedge clk) begin
for(int i=0; i<20; i++)begin
if(sel[i]) begin
check_sel_one_hot : assert property (sel[i] == !(|sel[20:20-i+1]));
end
end
end

Hi,

The simple way write an assertion for this requirement is by using $countones systemfunction as shown below.


checker_1 : assert property (@(posedge clk) a |-> $countones(a) == 1);

Hope this helps.
Putta Satish