I have a 32-bit source select line which is encoded using one-hot encoding.
Every 4 bit nibble is the select line of a different output, and can get only the values 0,1,2,4,8 (since it is one-hot)
In the module 4 inputs are multiplexed to 8 outputs.
Since 1 input cannot be directed to multiple outputs I need to create a constraint that will force 1,2,4 and 8 occur once or none at all, and other nibbles will be set to 0.
I thought to create a nibbles vector and randomize each element and concatenate it to my target register in post_randomization phase.
Does someone know what is the best solution to my situation?
A dist constraint is a statistical distribution and not a hard constraint. You can use the sum reduction method to constrain that an output appears at most once.
module top;
class test;
// Test fields
rand bit [8*4-1:0] ipe_stream_src_sel;
rand bit [3:0] src_sel[8];
const bit [3:0] one_hot[] = {0,1,2,4,8};
constraint src_sel_c {
foreach(src_sel[i]) {
src_sel[i] inside {one_hot};
ipe_stream_src_sel[i+:4] == src_sel[i]; // use instead of post_randomize
}
foreach(one_hot[sel])
sel != 0 -> src_sel.sum() with ( int'(item==one_hot[sel]) ) <= 1;
}
endclass : test
test t = new;
initial repeat (5) begin
assert(t.randomize);
$displayh("%p",t);
end
endmodule
assuming I got It properly is this what you are looking for?
class ciif_sync_test_config;
// Test fields
bit [31:0] ipe_stream_src_sel;
rand bit [3:0] r_src_sel[8];
bit [3:0] src_sel[8];
constraint src_sel_c {
unique {r_src_sel};
foreach(r_src_sel[i]){
r_src_sel[i] <= 8};}
function void post_randomize();
foreach(r_src_sel[jj]) begin
if(r_src_sel[jj] inside {0,1,2,4,8})
src_sel[jj] = r_src_sel[jj];
else src_sel[jj] = 0;
end
endfunction
function void print();
foreach(src_sel[ii]) begin
$display("ciif_sync_test_config: value of src_sel[%0d] is: %0h",ii,src_sel[ii]);
end
endfunction
endclass // inu_ciif_config