"hot bit" randomization

hello everyone!
in my testbench i have to make a random signal “[31:0] distortion”. it must contain one (or, in other case, two) hot bit(s) (hot bit is “1”, all others are “0”). So i have a problem with writing a constraint: i really don’t want to write all possible combinations of these bits (if there are two of them, there will be 32! combinations, so…). Does anyone have solution for this problem?

Rather than constrain distortion[31:0] to be one-hot or two-hot, how about doing the following:

randc bit [5:0] one_hot_bit;
randc bit [5:0] two_hot_bit;

constraint c_two_hot_bit {
 two_hot_bit != one_hot_bit;
}

function bit [31:0] calc_distortion(bit [5:0] ohb);
 bit [31:0] d;
 d = 32'd1 << ohb;
 return d;
endfunction

function bit [31:0] calc_distortion2(bit [5:0] ohb1, bit [5:0] ohb2);
 bit [31:0] d;
 d = (32'd1 << ohb1) | (32'd1 << ohb2);
 return d;
endfunction

Regards,
Ed

Use $countones system-function


  rand bit [31:0] vec_1;
  constraint cst_max_2_hot_bits {
    $countones(vec_1) inside {1,2};
  } // cst_max_2_hot_bits

HTH,
Ajeetha, CVC

In reply to ajeetha:

I have one more solution for the same. In this, randomization does not repeat until all the possible states.

class one_hot;

rand bit[0:31] state;
randc bit[0:4] one_hot_bit;

constraint one_hot_state {
foreach (state[i])
if(i == one_hot_bit) state[31-i]==1;
else state[31-i]==0;
}

function void my_display();
$display(“Value of state is %b, value of one_hot_bit is %d\n”, state, one_hot_bit);
endfunction

endclass

class two_hot;

rand bit[0:31] state;
randc bit[0:4] first_hot_bit;
randc bit[0:4] second_hot_bit;

constraint two_hot {
first_hot_bit != second_hot_bit;
}

constraint one_hot_state {
foreach (state[i])
if(i == first_hot_bit) state[31-i]==1;
else if (i == second_hot_bit ) state[31-i]==1;
else state[31-i]==0;
}

function void my_display();
$display(“Value of state is %b, value of first_hot_bit is %d, value of second_hot_bit is %d\n”, state, first_hot_bit, second_hot_bit);
endfunction

endclass

program p1;
one_hot ONEHOT = new();
two_hot TWOHOT = new();

initial begin
repeat(32) begin
ONEHOT.randomize();
TWOHOT.randomize();
ONEHOT.my_display();
TWOHOT.my_display();
end
end

endprogram

In reply to vybhava:

I use ies12.10.008, ies12.20.006 and VCS2012.09beta for this method of constraint. But it doesn’t work. In this version of tools, we can use $countones(vec_1) to calculate the number of bit 1, but not use this system function in constraint. Please tell me which version and tools you used for this method. Thank you.

In reply to gaurson:

I used Questa 10.2. Is there a detailed error message from other tools with pointers to LRM?

Ajeetha, CVC

In reply to ajeetha:

A quick follow-up. Found 2 relevant mantis items:

http://www.eda.org/svdb/view.php?id=2476
http://www.eda.org/svdb/view.php?id=3054

Looks like Questa has implemented this feature ahead of others. Check with your vendor on their plans for this handy feature.

Ajeetha, CVC

In reply to ajeetha:

Hi Ajeetha,

I like your solution, even if it only runs on Questa at the moment!
However, using an inside constraint will give a value with 2 bits set to 1, most of the time (presumably because the constraint solver has to pick a value for vec_1 before calling $countones and there are many more combinations of vec_1 with 2 bits set than just one).

An alternative constraint to overcome that problem would be to use dist instead:

constraint cdist {$countones(vec_1) dist{1:=90, 2:=10};}

to give a value with only 1 bit set to 1 approximately 90% of the time.

Regards,
Dave

In reply to dlong:

Dave,

You are correct that without the dist constraint, the number of solutions with 2 bits set (496) is much greater than the number of solutions with 1 bit set (32).

But these built-in iterative constraints are expanded out as an equation like

( int'(vec_1[31]) + int'(vec_1[30])+...+int'(vec_1[0]) ) dist {1:=90, 2:=10};}

so there is no implied variable solving order created by calling any of the built-in methods or functions.

In reply to dave_59:

In ies and VCS, the error message is that a system function or task call can not be used within a constrain expression. Maybe Questa have the feature and others dont.

Hi Dave,
Thanks for the explanation - very interesting! Is the mechanism you describe a “feature” of the way in which system functions are implemented in Questa rather than something I could find in the standard? The text in section 18.5.12 says

“Functions shall be called before constraints are solved, and their return values shall be treated as state variables”

This corresponds to the results I see if I replace $countones with my own countones member function (either along the lines of the one in section 18.5.12 or one that simply returns the sum of all bits in a single statement).

Regards,
Dave

In reply to dlong:

Look at the links posted in Comment #5. This is the behavior of the methods like sum() in a constraint already described in the current LRM. $countones is already supported in in the LRM for assertions, which means the function call needs to be expanded into the appropriate set of equations.