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,

Итак, вам нужно подумать о ширине ваших входов и выходов, или вам нужно сделать некоторое усечение (но это сделает вашу операцию конкатенации бессмысленной).

Другие вопросы по тегам