I need an or_reduce for an array of std_logic_vectors

  • Thread starter Richard Nicholas
  • Start date
R

Richard Nicholas

Hi,

If I have a std_logic_vector:

signal vec : std_logic_vector(0 to N);

I can easily get the OR of all the bits with or_reduce(vec).

What what if I have an array of std_logic_vectors:

type arr_type is array (0 to X) of std_logic_vector(0 to N)
signal my_arr : arr_type;

I want a function that ORs all fo the vectors in the array to produce one result
std_logic_vector(0 to N) where each bit of the result is the OR of all the bits at that
location. I.e. bit 0 of the result is the OR of all the bit 0s of each entry in my_arr?

Does something like this already exist or if not, hopefully someone can sketch out a function
that would be able to do this for variable X and N? I've made some attempts with
for/generate and for/loop but I didn't hit on anything that would compile. Thanks in
advance.

Richard Nicholas
 
R

Richard Nicholas

Hi,

If I have a std_logic_vector:

signal vec : std_logic_vector(0 to N);

I can easily get the OR of all the bits with or_reduce(vec).

What what if I have an array of std_logic_vectors:

type arr_type is array (0 to X) of std_logic_vector(0 to N)
signal my_arr : arr_type;

I want a function that ORs all fo the vectors in the array to produce one result
std_logic_vector(0 to N) where each bit of the result is the OR of all the bits at that
location. I.e. bit 0 of the result is the OR of all the bit 0s of each entry in my_arr?

Does something like this already exist or if not, hopefully someone can sketch out a function
that would be able to do this for variable X and N? I've made some attempts with
for/generate and for/loop but I didn't hit on anything that would compile. Thanks in
advance.

Richard Nicholas

One thing I forgot to mention: this does not need to be synthesizable. Its for behavioral
code.

Richard Nicholas
 
A

alb

Hi Richard,

On 06/11/2013 16:34, Richard Nicholas wrote:
[]
type arr_type is array (0 to X) of std_logic_vector(0 to N)
signal my_arr : arr_type;

I want a function that ORs all fo the vectors in the array to produce one result
std_logic_vector(0 to N) where each bit of the result is the OR of all the bits at that
location. I.e. bit 0 of the result is the OR of all the bit 0s of each entry in my_arr?

If I understood correctly your question I guess that something along
these lines should work.

<code>
-- not compiled nor tried... just a hint!
function you_name_it(arg : my_arr)
return std_logic is
variable temp : std_logic_vector (arg'length - 1 downto 0);
begin
-- WARNING: no sanity check on vector dimension!
for i in 0 to temp'length - 1 loop
temp(i) := or_reduce(arg(i)(arg(i)'range));
end loop;
return or_reduce(temp);
end;
Does something like this already exist or if not, hopefully someone can sketch out a function
that would be able to do this for variable X and N? I've made some attempts with
for/generate and for/loop but I didn't hit on anything that would compile. Thanks in
advance.

Maybe it would be more useful for you to post your attempts and try to
understand why you did not manage.

Al
 
K

KJ

What what if I have an array of std_logic_vectors:

type arr_type is array (0 to X) of std_logic_vector(0 to N)
signal my_arr : arr_type;

I want a function that ORs all fo the vectors in the array to produce one result
std_logic_vector(0 to N) where each bit of the result is the OR of all the bits
at that location. I.e. bit 0 of the result is the OR of all the bit 0s of each
entry in my_arr?

Does something like this already exist or if not, hopefully someone can sketch
out a function that would be able to do this for variable X and N?

-- Not tested, but pretty close...definitely more than just a sketch
function or_reduce(L: arr_type) return std_logic is
variable RetVal: std_logic_vector(L'range);
begin
for i in L'range loop
RetVa(i) := or_reduce(L(i));
end loop;
return(RetVal);
end function or_reduce;

Kevin Jennings
 
A

alb

Hi KJ,

On 07/11/2013 03:28, KJ wrote:
[]
-- Not tested, but pretty close...definitely more than just a sketch
function or_reduce(L: arr_type) return std_logic is
variable RetVal: std_logic_vector(L'range);
begin
for i in L'range loop
RetVa(i) := or_reduce(L(i));
end loop;
return(RetVal);

I guess it should read:
return(or_reduce(RetVal));
end function or_reduce;

I always envy your capability to write such neat functions! Mine was
close, but certainly some steps behind :)
 
K

KJ

I guess it should read:
return(or_reduce(RetVal));

That might be want the OP really wants, but what he stated was "where each bit of the result is the OR of all the bits at that location." which means he wants a vector of 'or_reduce' results, not an 'or_reduce' of the 'or_reduce' results.

Kevin Jennings
 
A

alb

Hi KJ,

That might be want the OP really wants, but what he stated was "where
each bit of the result is the OR of all the bits at that location."
which means he wants a vector of 'or_reduce' results, not an
'or_reduce' of the 'or_reduce' results.

You are right, I 'extrapolated' a little bit too much :). But then the
return value of your function should be a std_logic_vector the size of
which is unknown until instantiation.

Can an unconstrained array be the result of a function? I believe I had
troubles with this in the past.

Al
 
R

Richard Nicholas

-- Not tested, but pretty close...definitely more than just a sketch
function or_reduce(L: arr_type) return std_logic is
variable RetVal: std_logic_vector(L'range);
begin
for i in L'range loop
RetVa(i) := or_reduce(L(i));
end loop;
return(RetVal);
end function or_reduce;

Thank you both for your help. I probably did not explain what I was looking for clearly. I
wanted a function that would just OR all the vectors in the array, not or_reduce each vector,
creating a new vector of those results.

With the help of a colleague, I think we have a solution that does what I need:

function array_or( vectors : req_arr) return std_ulogic_vector is

variable result : std_ulogic_vector (vectors(0)'range);

begin
result := vectors(0);
for i in 1 to req_arr'length-1 loop
result := result or vectors(i);
end loop;

return result;
end array_or;

It could be made slightly more general by not taking advantage of the fact that all the
vectors are of the form (0 to N). Thanks again.

Richard Nicholas
 
K

KJ

But then the return value of your function should be a std_logic_vector the
size of which is unknown until instantiation. Can an unconstrained array be
the result of a function? I believe I had troubles with this in the past.

You're correct, the result of my function should have been a vector.

To answer your question, you don't define the range of an output vector doing so would be an error. I intended to have:
function or_reduce(L: arr_type) return std_logic_vector

If you define the range of the output vector like this...
function or_reduce(L: arr_type) return std_logic_vector(0 to 2)
That would produce a compile error.

Kevin Jennings
 
A

alb

Hi Richard,

Thank you both for your help. I probably did not explain what I was looking for clearly. I
wanted a function that would just OR all the vectors in the array, not or_reduce each vector,
creating a new vector of those results.

Reading somehow the OP it should have been indeed clear, I think the
preamble with the or_reduce example biased our mindset (or at least mine!).
With the help of a colleague, I think we have a solution that does what I need:

function array_or( vectors : req_arr) return std_ulogic_vector is

variable result : std_ulogic_vector (vectors(0)'range);

begin
result := vectors(0);
for i in 1 to req_arr'length-1 loop
result := result or vectors(i);
end loop;

return result;
end array_or;


Actually you get the same result simply using KJ's function preceded by
a 'transpose' function on the array (matrix):

<code>
my_array_t <= transpose (my_array);
my_vector <= or_reduce (my_array_t);
</code>

This separation will help you reuse your code, since now your functions
are not bound to your specific operation.
It could be made slightly more general by not taking advantage of the
fact that all the vectors are of the form (0 to N). Thanks again.

IMO that generalization has to go in the data structure, not in the
functions which operate on them. If you have an 'array' of 'something',
each element has to be the same 'something', but if you have a register
instead, you can collect vectors of different sizes.

Be aware though that depending on the operation you are doing the value
that you pick for elements that need to be padded may affect your
result. Padding with zero does not affect an or_reduce, but it does
affect an and_reduce!

Al
 
R

Richard Nicholas

IMO that generalization has to go in the data structure, not in the
functions which operate on them. If you have an 'array' of 'something',
each element has to be the same 'something', but if you have a register
instead, you can collect vectors of different sizes.

Yes, this function will only operate on arrays that start at 0. Each location of the array
has a std_ulogic_vector -- all are the same size. I realized later that the code I posted
does not depend on those std_ulogic_vectors having the form (0 to N) because I used 'range to
define the size of those vectors. So as long as the array indexes always start with 0, I
think this function should handle any sizes of vectors.

Richard Nicholas
 
A

alb

Hi KJ,

On 07/11/2013 17:57, KJ wrote:
[]
If you define the range of the output vector like this...
function or_reduce(L: arr_type) return std_logic_vector(0 to 2)
That would produce a compile error.

Ok, I verified what happened in my case. I have two functions to convert
between integers and slv:

<code>
-------------------------------------------------------------------------------

function htoi (L : std_ulogic_vector) return integer is
variable val : integer;
begin
val := to_integer(unsigned(L));
return val;
end function;

-------------------------------------------------------------------------------

function itoh (L : integer) return std_ulogic_vector is
variable val : std_ulogic_vector(31 downto 0);
begin
val := std_logic_vector(to_unsigned(L, val'length));
return val;
end function;
</code>

In the 'itoh' function I considered that integers are 32 bits max and I
constrained val accordingly.

When I call the function I'm not sure if I need to constrain the
dimensions of the returned value:

<code>
signal my_slv0: std_logic_vector(7 downto 0);
signal my_slv1: std_logic_vector(7 downto 0);

my_slv0 <= itoh(123);
my_slv1 <= itoh(123)(my_slv1'range);
</code>

vcom compiles ok for both cases, while synplify_pro flags an error
saying "Width mismatch, location has width 8, value 32" for my_slv0.

What is the correct assignment?

Thanks in advance,

Al
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,034
Messages
2,570,356
Members
47,002
Latest member
RobertoLip

Latest Threads

Top