AND all elements of an n-bit array in VHDL

2020-02-12 08:20发布

问题:

lets say I have an n-bit array. I want to AND all elements in the array. Similar to wiring each element to an n-bit AND gate.

How do I achieve this in VHDL?

Note: I am trying to use re-usable VHDL code so I want to avoid hard coding something like

    result <= array(0) and array(1) and array(2)....and array(n); 

Thanks Oshara

回答1:

Solution 1: With unary operator

VHDL-2008 defines unary operators, like these:

outp <= and "11011";
outp <= xor "11011";
outp <= and inp; --this would be your case

However, they might not be supported yet by your compiler.

Solution 2: With pure combinational (and traditional) code

Because in concurrent code you cannot assign a value to a signal more than once, your can create a temp signal with an "extra" dimension. In your case, the output is one-bit, so the temp signal should be a 1D array, as shown below.

-------------------------------------------
entity unary_AND IS
    generic (N: positive := 8); --array size
    port (
        inp: in bit_vector(N-1 downto 0);
        outp: out bit);
end entity;
-------------------------------------------
architecture unary_AND of unary_AND is
    signal temp: bit_vector(N-1 downto 0);
begin
    temp(0) <= inp(0);
    gen: for i in 1 to N-1 generate
        temp(i) <= temp(i-1) and inp(i);
    end generate; 
    outp <= temp(N-1); 
end architecture;
-------------------------------------------

The inferred circuit is shown in the figure below.

Solution 3: With sequential code

This is simpler than solution 2, though you are now using sequential code to solve a purely combinational problem (but the hardware will be the same). You can either write a code similar to that in solution 2, but with a process and loop (the latter, in place of generate) or using a function. Because in sequential code you are allowed to assign a value to a signal more than once, the temp signal of solution 2 is not needed here.



回答2:

If you have VHDL-2008 available, then reduction and is build into the language as David Koontz and Pedroni have explained.

If you only have VHDL-2003 and prior available, then you can use a function like:

function and_reduct(slv : in std_logic_vector) return std_logic is
  variable res_v : std_logic := '1';  -- Null slv vector will also return '1'
begin
  for i in slv'range loop
    res_v := res_v and slv(i);
  end loop;
  return res_v;
end function;

You can then use the function both inside and outside functions with:

signal arg : std_logic_vector(7 downto 0);
signal res : std_logic;
...
res <= and_reduct(arg);


回答3:

My favorite, non-VHDL-2008 solution is:

use ieee.std_logic_unsigned.all ;  -- assuming not VHDL-2008
. . . 
result <= '1' when not MyArray = 0 else '0' ; 

With VHDL-2008, I recommend that you use the "and" reduction built-in (see Pedroni's post) and use the IEEE standard package "ieee.numeric_std_unsigned.all" instead of the shareware package "std_logic_unsigned".