VHDL множитель, выход которого имеет ту же сторону своих входов
Я использую VHDL для описания 32-битного множителя, для системы, которая будет реализована на ПЛИС Xilinx, я обнаружил в Интернете, что практическое правило заключается в том, что если у вас есть входные данные размером N-бит, то выход должен иметь (2*N)-биты размера. Я использую его для системы обратной связи, возможно ли иметь множитель с выходом того же размера, что и его входы?
Клянусь, однажды я нашел приложение fpga, в котором в коде vhdl есть блоки сумматоров и умножителей, соединенные с сигналами одинакового размера. Человек, который написал код, сказал мне, что вы просто должны поместить результат продукта в 64-битный сигнал, а затем на выходе должны получить наиболее значимые 32-битные результаты (что не обязательно было на наиболее значимых 32-битных). 64-битного сигнала).
В то время я строю систему (по-видимому, работает), используя следующий код:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Multiplier32Bits is
port(
CLK: in std_logic;
A,B: in std_logic_vector(31 downto 0);
R: out std_logic_vector(31 downto 0)
);
end Multiplier32Bits;
architecture Behavioral of Multiplier32Bits is
signal next_state: std_logic_vector(63 downto 0);
signal state: std_logic_vector(31 downto 0);
begin
Sequential: process(CLK,state,next_state)
begin
if CLK'event and CLK = '1' then
state <= next_state(61 downto 30);
else
state <= state;
end if;
end process Sequential;
--Combinational part
next_state <= std_logic_vector(signed(A)*signed(B));
--Output assigment
R <= state;
end Behavioral;
Я думал, что это сработало, потому что в то время у меня была симуляция блока с симулятором Active-HDL FPGA, но я знаю, что я симулирую всю 32-битную систему, используя iSim из Xilinx ISE Design Suite. Я обнаружил, что мой вывод имеет большое отличие от реального продукта входов A и B, который я не знаю, просто ли потеря точности из-за пропуска 32 бит или мой код просто плохой.
2 ответа
У вашего кода есть некоторые проблемы:
next_state
а такжеstate
не входит в список чувствительности- Письмо
CLK'event and CLK = '1'
должен быть замененrising_edge(CLK)
state <= state;
не имеет никакого эффекта и заставляет некоторые инструменты, такие как ISE, неправильно истолковывать шаблон. Убери это.- Размещение пробелов вокруг операторов не повредит, но улучшает читабельность.
- Почему вы ожидаете результат a * b в битах от 30 до 61 вместо 0 до 31?
state
а такжеnext_state
не представляют состояния конечного автомата. Это просто реестр.
Улучшенный код:
architecture Behavioral of Multiplier32Bits is
signal next_state: std_logic_vector(63 downto 0);
signal state: std_logic_vector(31 downto 0);
begin
Sequential: process(CLK)
begin
if rising_edge(CLK) then
state <= next_state(31 downto 0);
end if;
end process Sequential;
--Combinational part
next_state <= std_logic_vector(signed(A) * signed(B));
--Output assigment
R <= state;
end architecture Behavioral;
Я полностью согласен со всем, что пишет Пеббельс. Но я объясню вам эти вещи о количестве бит в результате. Поэтому я объясню это примерами из базы 10.
9 * 9 = 81 (two 1 digit numbers gives maximum of 2 digits)
99 * 99 = 9801 (two 2 digit numbers gives maximum of 4 digits)
999 * 999 = 998001 (two 3 digit numbers gives maximum of 6 digits)
9999 * 9999 = 99980001 (4 digits -> 8 digits)
И так далее... Это совершенно то же самое для двоичного файла. Вот почему результат равен (2*N)-битам размера входных данных.
Но если ваши числа меньше, то результат будет соответствовать тому же числу цифр, что и факторы:
3 * 3 = 9
10 * 9 = 90
100 * 99 = 990
И так далее. Так что, если ваши числа достаточно малы, то результат будет 32-битным. Конечно, как уже писал Пеббельс, результат будет в наименее значимой части сигнала.
И, как уже указывал JHBonarius, если ваш ввод состоит не из целых чисел, а из чисел с фиксированной запятой, то вам придется делать пост-сдвиг. Если это ваш случай, напишите это в комментарии, и я объясню, что делать.