Флаги для ALU в VHDL не обновляются при запуске симуляции - PullRequest
0 голосов
/ 11 марта 2020

Пока что все работает так, как задумано, за исключением 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;
...