VHDL: добавление операций в 8-битный ALU
Я очень новичок в VHDL, и мне необходимо изменить этот ALU с помощью дополнительных восьми операций, которые сами по себе не актуальны, но из тестирования в GTKwave я вижу, что clk(clock) и r(result) прекращают моделирование после первого восемь операций, кажется, хотя операционная форма признает их. И источник, и тестовый стенд прекрасно компилируются без ошибок, что приводит к неправильным сигналам. Осциллограмм / Тестирование
Я попытался это исправить, вернувшись к коду тестового стенда и изменивexit L1 when i >10;
'цикл от 10 до 20(или любой другой более 10), а затем перекомпиляция, но это привело к ошибке "сбой связанной проверки", которая озадачила меня. Я также попытался изменить модификацию, чтобы сделать ее 16-битной, но она не компилировалась - определенно не то решение, которое я себе представляю.
Не обращайте внимания на перепутанные оперативные комментарии.
Любая помощь будет высоко ценится, я полагаю, это очень упущение новичка.
Исходный код, полученный из http://vhdlguru.blogspot.co.uk/2011/06/vhdl-code-for-simple-alu.html
ИСХОДНЫЙ КОД
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Ex8 is
port( Clk : in std_logic; --clock signal
A,B : in signed(7 downto 0); --input operands
Op : in unsigned(3 downto 0); --Operation to be performed -- 2 to 3
R : out signed(7 downto 0) --output of ALU
);
end Ex8;
architecture Behavioral of Ex8 is
--temporary signal declaration.
signal Reg1,Reg2,Reg3 : signed(7 downto 0) := (others => '0');
begin
Reg1 <= A;
Reg2 <= B;
R <= Reg3;
process(Clk)
begin
if(rising_edge(Clk)) then --Do the calculation at the positive edge of clock cycle.
case Op is
when "0000" =>
Reg3 <= Reg1 + Reg2; --addition
when "0001" =>
Reg3 <= Reg1 - Reg2; --subtraction
when "0010" =>
Reg3 <= not Reg1; --NOT gate
when "0011" =>
Reg3 <= Reg1 nand Reg2; --NAND gate
when "0100" =>
Reg3 <= Reg1 nor Reg2; --NOR gate
when "0101" =>
Reg3 <= Reg1 and Reg2; --AND gate
when "0110" =>
Reg3 <= Reg1 or Reg2; --OR gate
when "0111" =>
Reg3 <= Reg1 xor Reg2; --XOR gate
when "1000" =>
Reg3 <= Reg1 / Reg2; --division
when "1001" =>
Reg3 <= Reg1 * Reg2; --multiplication
when "1010" =>
Reg3 <= Reg1 xnor Reg2; --rotate left
when "1011" =>
Reg3 <= Reg1 srl 4; --rotate right
when "1100" =>
Reg3 <= Reg1 & Reg2; --shift left logical
when "1101" =>
Reg3 <= Reg1 sll 4; --shift right logical
when "1110" =>
Reg3 <= Reg1 mod Reg2; --modulo
when "1111" =>
Reg3 <= Reg1 rem Reg2; --remainder
when others =>
NULL;
end case;
end if;
end process;
end Behavioral;
ИСПЫТАТЕЛЬНЫЙ СТЕНД
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY Ex8_tb IS
END Ex8_tb;
ARCHITECTURE behavior OF Ex8_tb IS
signal Clk : std_logic := '0';
signal A,B,R : signed(7 downto 0) := (others => '0');
signal Op : unsigned(3 downto 0) := (others => '0');
constant Clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: entity work.Ex8 PORT MAP (
Clk => Clk,
A => A,
B => B,
Op => Op,
R => R
);
-- Clock process definitions
Clk_process :process
variable i : POSITIVE := 1;
begin
L1: loop
Clk <= '0';
wait for Clk_period/2;
Clk <= '1';
wait for Clk_period/2;
i:= i+1;
exit L1 when i >10;
end loop L1; -- changed from failure to warning
assert false report "NONE. End of simulation." severity warning;
wait; -- added wait;
end process;
-- Stimulus process
stim_proc: process
begin
wait for Clk_period*1;
A <= "00010010"; --18 in decimal
B <= "00001010"; --10 in decimal
Op <= "0000"; wait for Clk_period; --add A and B
Op <= "0001"; wait for Clk_period; --subtract B from A.
Op <= "0010"; wait for Clk_period; --Bitwise NOT of A
Op <= "0011"; wait for Clk_period; --Bitwise NAND of A and B
Op <= "0100"; wait for Clk_period; --Bitwise NOR of A and B
Op <= "0101"; wait for Clk_period; --Bitwise AND of A and B
Op <= "0110"; wait for Clk_period; --Bitwise OR of A and B
Op <= "0111"; wait for Clk_period; --Bitwise XOR of A and B
Op <= "1000"; wait for Clk_period; --Bitwise DIV of A and B
Op <= "1001"; wait for Clk_period; --Bitwise MUL of A and B
Op <= "1010"; wait for Clk_period; --Bitwise ROL of A and B
Op <= "1011"; wait for Clk_period; --Bitwise ROR of A and B
Op <= "1100"; wait for Clk_period; --Bitwise SLL of A and B
Op <= "1101"; wait for Clk_period; --Bitwise SRL of A and B
Op <= "1110"; wait for Clk_period; --Bitwise MOD of A and B
Op <= "1111"; wait for Clk_period; --Bitwise REM of A and B
wait;
end process;
END;
1 ответ
В вашем коде есть одна проблема, которая мешает его компиляции; у вас есть тот, который мешает имитации (ошибка времени выполнения). Оба сбоя по одной и той же причине: размеры массивов не совпадают.
Эта строка может не скомпилироваться:
Reg3 <= Reg1 & Reg2;
Это потому что reg1
, reg2
а также reg3
все одинаковой ширины. &
это конкатенация - объединение двух массивов для создания большего массива. Ширина reg3
должен быть равен ширине reg1
плюс ширина reg2
, (Я говорю "возможно, нет", потому что он дал ошибку компиляции на одном симуляторе и ошибку времени выполнения на другом).
Затем я изменил эту строку:
exit L1 when i >10;
к этому:
exit L1 when i >20;
как вы предложили, а затем получили ошибку во время выполнения в этой строке:
Reg3 <= Reg1 * Reg2; --multiplication
Это опять потому что reg1
, reg2
а также reg3
все одинаковой ширины. Оператор умножения, определенный в numeric_std
Пакет выводит результат с шириной, равной сумме ширины двух операндов, то есть ширины reg1
плюс ширина reg2
,
Итак, вам нужно подумать о ширине ваших входов и выходов, или вам нужно сделать некоторое усечение (но это сделает вашу операцию конкатенации бессмысленной).