I need an or_reduce for an array of std_logic_vectors

Discussion in 'VHDL' started by Richard Nicholas, Nov 6, 2013.

  1. 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

    Richard Nicholas
    Richard Nicholas, Nov 6, 2013
    1. Advertisements

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

    Richard Nicholas
    Richard Nicholas, Nov 6, 2013
    1. Advertisements

  3. Richard Nicholas

    alb Guest

    Hi Richard,

    On 06/11/2013 16:34, Richard Nicholas wrote:
    If I understood correctly your question I guess that something along
    these lines should work.

    -- 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);
    -- 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);
    Maybe it would be more useful for you to post your attempts and try to
    understand why you did not manage.

    alb, Nov 6, 2013
  4. Richard Nicholas

    KJ Guest

    -- 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);
    for i in L'range loop
    RetVa(i) := or_reduce(L(i));
    end loop;
    end function or_reduce;

    Kevin Jennings
    KJ, Nov 7, 2013
  5. Richard Nicholas

    alb Guest

    Hi KJ,

    On 07/11/2013 03:28, KJ wrote:
    I guess it should read:
    I always envy your capability to write such neat functions! Mine was
    close, but certainly some steps behind :)
    alb, Nov 7, 2013
  6. Richard Nicholas

    KJ Guest

    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
    KJ, Nov 7, 2013
  7. Richard Nicholas

    alb Guest

    Hi KJ,

    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.

    alb, Nov 7, 2013
  8. 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);

    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
    Richard Nicholas, Nov 7, 2013
  9. Richard Nicholas

    KJ Guest

    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
    KJ, Nov 7, 2013
  10. Richard Nicholas

    alb Guest

    Hi Richard,

    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!).

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

    my_array_t <= transpose (my_array);
    my_vector <= or_reduce (my_array_t);

    This separation will help you reuse your code, since now your functions
    are not bound to your specific operation.
    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!

    alb, Nov 12, 2013
  11. 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
    Richard Nicholas, Nov 12, 2013
  12. Richard Nicholas

    alb Guest

    Hi KJ,

    On 07/11/2013 17:57, KJ wrote:
    Ok, I verified what happened in my case. I have two functions to convert
    between integers and slv:


    function htoi (L : std_ulogic_vector) return integer is
    variable val : integer;
    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);
    val := std_logic_vector(to_unsigned(L, val'length));
    return val;
    end function;

    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:

    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);

    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,

    alb, Nov 13, 2013
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.