I am a beginner in VHDL/FPGA programming. I want to compare two 32-bit std_logic_vector
s. I am currently using:
if ( RX_FRAME(to_integer(s_data_counter)).Data /= REF_FRAME(to_integer(s_data_counter)).Data ) then
s_bad_frame <= '1';
state <= DONE;
end if;
Here RX_FRAME
and REF_FRAME
are 2 arrays of std_logic_vector(31 downto 0)
I want to know how the synthesis tool translates /=
into hardware.
Is it advisable to use this? Or should I do an XOR
of the concerned vectors and check the resulting vector against zeros? In case I do an XOR
and check against zeroes, doesn't it increase the amount of hardware needed?
I am using Vivado Design Suite 2015.3.
As Morten already presented, compare operations are implemented in LUTs doing some kind of X(N)OR and AND/(N)OR aggregation.
But it could be faster ...
FPGAs have fast carry chains, which can be used to speed up compare operations with wide inputs, but synthesis tools mostly don't utilize this special resources.
How to do an equality comparation using a carry chain?
Carry chains can be implemented as kill-propagate chains. This naming comes from ripple carry adders, wherein a carry out can be generated, propagated from carry in or be killed.
A comparator starts with an active carry in (all is equal). Each step computes in the LUT: An = Bn. If yes, propagate the carry bit else kill it.
If the carry out is high (the initial value has survived the chain) all bits were equal.
I don't have an example code for the equal or unequal operation, but I have a similar example for prefix and
and prefix or
operators using carry chains to speed up computation for wide inputs.
prefix_and
calculates: y(i) <= '1' when x(i downto 0) = (i downto 0 => '1') else '0';
Explanation:
The resulting vector is 1
until the first 0
is found, after that it is 0
.
Or in other words: The first zero found at position i
while going from 0 to n
kills all remaining bits regardless of the input bits.
prefix_or
calculates: y(i) <= '0' when x(i downto 0) = (i downto 0 => '0') else '1';
Explanation:
The resulting vector is 0
until the first 1
is found, after that it is 1
.
Or in other words: The first one found at position i
while going from 0 to n
generates an one and propagates it to all remaining bits regardless of the input bits.
The following code is a generic VHDL description of prefix_and
. It is vendor independent, but uses special primitives (MUXCY) on Xilinx FPGAs.
architecture rtl of arith_prefix_and is
begin
y(0) <= x(0);
gen1: if N > 1 generate
signal p : unsigned(N-1 downto 1);
begin
p(1) <= x(0) and x(1);
gen2: if N > 2 generate
p(N-1 downto 2) <= unsigned(x(N-1 downto 2));
-- Generic Carry Chain through Addition
genGeneric: if VENDOR /= VENDOR_XILINX generate
signal s : std_logic_vector(N downto 1);
begin
s <= std_logic_vector(('0' & p) + 1);
y(N-1 downto 2) <= s(N downto 3) xor ('0' & x(N-1 downto 3));
end generate genGeneric;
-- Direct Carry Chain by MUXCY Instantiation
genXilinx: if VENDOR = VENDOR_XILINX generate
component MUXCY
port (
S : in std_logic;
DI : in std_logic;
CI : in std_logic;
O : out std_logic
);
end component;
signal c : std_logic_vector(N-1 downto 0);
begin
c(0) <= '1';
genChain: for i in 1 to N-1 generate
mux : MUXCY
port map (
S => p(i),
DI => '0',
CI => c(i-1),
O => c(i)
);
end generate genChain;
y(N-1 downto 2) <= c(N-1 downto 2);
end generate genXilinx;
end generate gen2;
y(1) <= p(1);
end generate gen1;
end architecture;
Source: PoC.arith.prefix_and