Пока что все работает так, как задумано, за исключением Cout (вынос) и V (переполнение), когда я симулирую в тестовом стенде. Я получаю постоянное Нас при выполнении сложения и вычитания. Я выполнил некоторые из вычислений, которые я тестирую, вручную, поэтому я знаю, какие из них должны иметь значение переноса и значение переполнения.
entity ALU is
Port ( Cin : in STD_LOGIC_VECTOR ( 0 downto 0);
ALUCntrl : in STD_LOGIC_VECTOR ( 3 downto 0);
A, B : in STD_LOGIC_VECTOR (31 downto 0);
ALUout : out STD_LOGIC_VECTOR (31 downto 0);
Cout, Z, V : out STD_LOGIC );
end ALU;
architecture Behavioral of ALU is
SIGNAL result : STD_LOGIC_VECTOR (32 downto 0);
SIGNAL bCout, bZ, bV : STD_LOGIC;
begin
WITH ALUCntrl SELECT
result(31 downto 0) <= A and B when "0000",
A or B when "0001",
A xor B when "0011",
std_logic_vector(unsigned(A) + unsigned(B) + unsigned(Cin)) WHEN "0010",
std_logic_vector(unsigned(A) - unsigned(B)) WHEN "0110",
A xnor B WHEN "1100",
A xnor B WHEN "1111",
"00000000000000000000000000000000" WHEN OTHERS;
WITH result(31 downto 0) SELECT
bZ <= '1' WHEN "00000000000000000000000000000000",
'0' WHEN OTHERS;
WITH ALUCntrl SELECT
bCout <= result(32) WHEN "0010",
result(32) WHEN "0110",
'0' WHEN OTHERS;
PROCESS(ALUCntrl)
BEGIN
CASE ALUCntrl IS
WHEN "0010" =>-- Addition Overflow
IF ((A(31) = '1') and (B(31) = '1') and (result(31) = '0')) THEN
bV <= '1';
ELSIF ((A(31) = '0') and (B(31) = '0') and (result(31) = '1')) THEN
bV <= '1';
ELSE
bV <= '0';
END IF;
WHEN "0110" => -- Subtraction overflow
IF ((A(31) = '0') and (B(31) ='1') and (result(31) = '1')) THEN
bV <= '1';
ELSIF ((A(31) = '1') and (B(31) = '0') and (result(31) = '0')) THEN
bV <= '1';
ELSE
bV <= '0';
END IF;
WHEN OTHERS =>
bV <= '0';
END CASE;
END PROCESS;
ALUout <= result(31 downto 0);
Cout <= bCout;
Z <= bZ;
V <= bV;
end Behavioral;
TEST-BENCH
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity ALU_tb is
-- Port ( );
end ALU_tb;
architecture Behavioral of ALU_tb is
-- INPUTS
signal Cin : STD_LOGIC_VECTOR ( 0 downto 0);
signal A, B : STD_LOGIC_VECTOR (31 downto 0);
signal ALUCntrl : STD_LOGIC_VECTOR ( 3 downto 0);
-- OUTPUTS
signal ALUout : STD_LOGIC_VECTOR (31 downto 0);
signal Cout, Z, V : STD_LOGIC;
component ALU is
port(
Cin : in STD_LOGIC_VECTOR ( 0 downto 0);
A, B : in STD_LOGIC_VECTOR (31 downto 0);
ALUCntrl : in STD_LOGIC_VECTOR ( 3 downto 0);
ALUout : out STD_LOGIC_VECTOR (31 downto 0);
Cout, Z, V : out STD_LOGIC );
end component ALU;
begin
design_ALU: ALU
port map(
Cin => Cin,
A => A,
B => B,
ALUCntrl => ALUCntrl,
ALUout => ALUout,
Cout => Cout,
Z => Z,
V => V
);
tb : PROCESS
BEGIN
ALUCntrl <= "0000"; -- AND
Cin <= "00";
A <= "11111111111111111111111111111111";
B <= "00000000000000000000000000000000";
wait for 250ns;
ALUCntrl <= "0001"; -- OR
A <= "10011000100110001001100010011000";
B <= "10001001100010011000100110001001";
wait for 250ns;
ALUCntrl <= "0011"; -- XOR
A <= "00000001000000010000000100000001";
B <= "00010000000100000001000000010000";
wait for 250ns;
ALUCntrl <= "0010"; -- ADD
A <= "00000000000000000000000000000001";
B <= "11111111111111111111111111111111";
wait for 250ns;
ALUCntrl <= "0010"; -- ADD
A <= "01100011100010010111010101001111";
B <= "10101101010101100010010011100110";
wait for 250ns;
ALUCntrl <= "0010"; -- ADD
Cin <= "01";
A <= "00000000000000000000000000000001";
B <= "11111111111111111111111111111111";
wait for 250ns;
ALUCntrl <= "0010"; -- ADD
A <= "01100011100010010111010101001111";
B <= "10101101010101100010010011100110";
wait for 250ns;
ALUCntrl <= "0010"; -- ADD
A <= "11111111111111111111111111111111";
B <= "11111111111111111111111111111111";
wait for 250ns;
ALUCntrl <= "0110"; -- SUB
A <= "00000000000000000000000000000000";
B <= "00000000000000000000000000000001";
wait for 250ns;
ALUCntrl <= "0110"; -- SUB
A <= "11111001011010000100011110000011";
B <= "11111001100110001101010101100010";
wait for 250ns;
ALUCntrl <= "0110"; -- SUB
A <= "10000000000000000000000000000000";
B <= "00000001000000000000000000000000";
wait for 250ns;
ALUCntrl <= "1100"; -- NOR
A <= "10011010101111001101111011011111";
B <= "10011010101111001101111011111101";
wait for 250ns;
ALUCntrl <= "1111"; -- XNOR
A <= "10001001101111001101111000110100";
B <= "11000101001110111101011010000111";
wait;
END PROCESS tb;
end Behavioral;