Search code examples
vhdlghdl

My VHDL ALU code fails to output the result of addition, but outputs the result of subtraction just fine?


I am writing a testbench for the first time and it doesn't work. It's for a simple 4 bit ALU with addition and subtraction only, working with unsigned numbers and the overflow/underflow should throw an error.

I expected for the temp_result to be assigned to the result fine but right there seems to be the problem. I tried using variables, signals, but there was always some problem. I think temp_result is the culprit. maybe how it was invoked or the assignment to result is wrong, or in the wrong part of code. Or maybe the testbench port map.

I am new to VHDL.

HERE IS THE MAIN CODE :

entity ALU is
    port (
        A: in  unsigned(3 downto 0);
        B: in  unsigned(3 downto 0);
        result: out unsigned(3 downto 0);
        opcode: in  bit;
        error: out bit
    );
end entity ALU;

architecture Behavioral of ALU is
    signal temp_result: unsigned(4 downto 0);
begin
    process(A, B, opcode)
    begin
        case opcode is
            when '0' =>
                temp_result <= resize(A, temp_result'length) + resize(B, temp_result'length);
            when '1' =>
                temp_result <= resize(A, temp_result'length) - resize(B, temp_result'length);
        end case;
        
        -- Assign result
        result <= temp_result(3 downto 0);

        -- Error output
        if temp_result(4) = '1' then
            error <= '1';
        else
            error <= '0';
        end if;
    end process;
end Behavioral;

AND HERE IS THE TESTBENCH :

entity ALU_Testbench is
end ALU_Testbench;

architecture tb_arch of ALU_Testbench is
    -- Signals for testbench
    signal A_tb, B_tb: unsigned(3 downto 0);
    signal opcode_tb: bit;
    signal result_tb: unsigned(3 downto 0);
    signal error_tb: bit;

    -- Component declaration
    component ALU
        port (
            A: in  unsigned(3 downto 0);
            B: in  unsigned(3 downto 0);
            result: out unsigned(3 downto 0);
            opcode: in  bit;
            error: out bit
        );
    end component;

begin
    uut_instance: ALU
        port map (
            A => A_tb,
            B => B_tb,
            opcode => opcode_tb,
            result => result_tb,
            error => error_tb
        );

    -- Stimulus process
    stim_proc: process
    begin
        -- Addition test
        A_tb <= "0011"; 
        B_tb <= "0010"; 
        opcode_tb <= '0'; 
        wait for 10 ns; 
       
        -- Subtraction test
        A_tb <= "0011"; 
        B_tb <= "0010"; 
        opcode_tb <= '1'; 
        wait for 10 ns; 
        wait;
    end process stim_proc;
end tb_arch;

Waveform screenshot


Solution

  • temp_result is a signal, so it gets its new value when the process terminates. But the process is not sensitive to temp_result (missing in the sensitivity list (A,B, opcode)). Therefore the process cannot assign the new value at temp_result to result. So to fix your problem you must add temp_result to the sensitivity list or change the signal temp_result into a variable declared in the process. A variable gets its new value immediately, so in this case you don't have to change your sensitivity list.