My design requires converting a One Hot encoded vector to Binary from.
For this purpose - I want to write a generic function that can accept any size of vector.
My problem is that Systemverilog doesn't allow the function to have an unconstrained array input.
How can I solve this ?
This is what I wrote so far.
Code:
function one_hot_to_binary ( logic /*missing_type_and_size*/ vector_one_hot ) ;
logic [ $clog2 ( $size ( vector_one_hot ) ) - 1 : 0 ] vector_binary = 0 ; // Define an appropriately sized binary vector.
foreach ( vector_one_hot [ index ] )
begin
if ( vector_one_hot [ index ] == 1'b1 ) // If the bit index is '1' do a logic OR with the index value.
begin
vector_binary = vector_binary | index ;
end
end
return vector_binary ;
endfunction
You could just make it output an integer for vector_binary. I kind of doubt you would ever need to have a one-hot to binary that requires 2**32-1 hot inputs.
You can assign that integer to any width array you want as Verilog/Systemveriog will just truncate the integer to fit.
There hopefully are better ways to do this now. I know that you can create a parameterized abstract class that has a static method. you can set the parameters when calling the function, allowing you to have inputs of any size. I think you can also set type instead of just size. You end up with something like myClass#(type(x))::myFunction(x) or myClass#($size(x))::myFunction(x). this can be reduced in length with macros, typedefs, inheritence, and/or the 'let' construct if that is supported.
While ugly, it should be synthesizable. I tested a similar version years ago and it was in vivado.