VHDL:向 8 位 ALU 添加操作

VHDL: Adding operations to 8-bit ALU

我是 VHDL 的新手,需要用另外八个操作修改这个 ALU,这些操作本身不相关,但从 GTKwave 中的测试我看到 clk(clock) 和 r(result) 似乎在前八个操作后停止模拟,尽管 op 波形承认它们。源代码和测试平台都编译得很好,没有错误,导致看起来不正确的波形。 Waveforms/Testing

我试图通过返回测试平台代码并将“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;

您的代码中有一处问题导致无法编译;你有一个阻止它模拟的(运行-time error)。两者都因同样的原因而失败:数组大小不匹配。

这一行可能无法编译:

Reg3 <= Reg1 & Reg2;

这是因为reg1reg2reg3都是一样的宽度。 &concatenation - 连接两个数组以形成更大的数组。 reg3的宽度需要等于reg1的宽度加上reg2的宽度。 (我说 "might not" 因为它在一个模拟器上给出了 编译错误 而在另一个模拟器上给出了 运行 时间错误 )。

然后我更改了这一行:

exit L1 when i >10;

对此:

exit L1 when i >20;

如您所建议,然后在这一行出现 运行 时间错误:

Reg3 <= Reg1 * Reg2;    --multiplication

这又是因为reg1reg2reg3都是一样的宽度。 numeric_std包中定义的乘法运算符输出的结果宽度等于两个操作数的宽度之和,即reg1的宽度加上reg2的宽度。

因此,您需要考虑输入和输出的宽度,或者您需要做一些 t运行cation(但这会使您的连接操作毫无意义)。