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;
这是因为reg1
、reg2
和reg3
都是一样的宽度。 &
是 concatenation - 连接两个数组以形成更大的数组。 reg3
的宽度需要等于reg1
的宽度加上reg2
的宽度。 (我说 "might not" 因为它在一个模拟器上给出了 编译错误 而在另一个模拟器上给出了 运行 时间错误 )。
然后我更改了这一行:
exit L1 when i >10;
对此:
exit L1 when i >20;
如您所建议,然后在这一行出现 运行 时间错误:
Reg3 <= Reg1 * Reg2; --multiplication
这又是因为reg1
、reg2
和reg3
都是一样的宽度。 numeric_std
包中定义的乘法运算符输出的结果宽度等于两个操作数的宽度之和,即reg1
的宽度加上reg2
的宽度。
因此,您需要考虑输入和输出的宽度,或者您需要做一些 t运行cation(但这会使您的连接操作毫无意义)。
我是 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;
这是因为reg1
、reg2
和reg3
都是一样的宽度。 &
是 concatenation - 连接两个数组以形成更大的数组。 reg3
的宽度需要等于reg1
的宽度加上reg2
的宽度。 (我说 "might not" 因为它在一个模拟器上给出了 编译错误 而在另一个模拟器上给出了 运行 时间错误 )。
然后我更改了这一行:
exit L1 when i >10;
对此:
exit L1 when i >20;
如您所建议,然后在这一行出现 运行 时间错误:
Reg3 <= Reg1 * Reg2; --multiplication
这又是因为reg1
、reg2
和reg3
都是一样的宽度。 numeric_std
包中定义的乘法运算符输出的结果宽度等于两个操作数的宽度之和,即reg1
的宽度加上reg2
的宽度。
因此,您需要考虑输入和输出的宽度,或者您需要做一些 t运行cation(但这会使您的连接操作毫无意义)。