Как уже представил Мортен, операции сравнения реализованы в таблицах LUT, выполняющих некоторую агрегацию X(N)OR и AND/(N)OR.
Но это могло бы быть быстрее...
FPGA имеют быстрые цепочки переноса, которые можно использовать для ускорения операций сравнения с широкими входными данными, но инструменты синтеза в основном не используют эти специальные ресурсы.
Как выполнить сравнение на равенство с помощью цепочки переноса?
Цепочки переноса можно реализовать как цепочки kill-propagate. Это название происходит от сумматоров с пульсирующим переносом, в которых перенос может быть сгенерирован, распространен из переноса или уничтожен.
Компаратор начинается с активного переноса (все равны). Каждый шаг вычисляется в LUT: An = Bn. Если да, распространите бит переноса, иначе убейте его.
Если перенос высокий (начальное значение пережило цепочку), все биты были равны.
Приложение для Мортена Зилмера
У меня нет примера кода для операции равно или неравно, но у меня есть аналогичный пример для операторов prefix and
и prefix or
, использующих цепочки переноса для ускорения вычислений для широких входных данных. .
prefix_and
вычисляет: y(i) <= '1' when x(i downto 0) = (i downto 0 => '1') else '0';
Объяснение:
Результирующий вектор равен 1
, пока не будет найден первый 0
, после чего он равен 0
.
Или, другими словами: первый ноль, найденный в позиции i
при переходе от 0 to n
убийства strong> все оставшиеся биты независимо от входных битов.
prefix_or
вычисляет: y(i) <= '0' when x(i downto 0) = (i downto 0 => '0') else '1';
Объяснение:
Результирующий вектор равен 0
, пока не будет найден первый 1
, после этого он будет 1
.
Или, другими словами: первый найденный в позиции i
при переходе от 0 to n
< strong>генерирует единицу и распространяет ее на все оставшиеся биты независимо от входных битов.
Следующий код представляет собой общее описание VHDL для prefix_and
. Он не зависит от поставщика, но использует специальные примитивы (MUXCY) на ПЛИС Xilinx.
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;
Источник: PoC.arith.prefix_and
person
Paebbels
schedule
20.01.2016