Search code examples
vhdl

VHDL Conditionals won't set values


I've tried this with both case statements and if statements and can't get it to work. I have the code below. It should allow me to select an ALU operation and then set the value of Results. Results is a signal that is then passed on to Output, which is the output node.

As you can see, I have the actual case check doing what I want it to do, and also have the fallback doing the same thing. I cannot fathon why it is not getting done. But yet, my Output variable always come back undefined in the testbench. When I look at the file in GTKWave, I can see that the Results value also remains unset. However, the adder is doing exactly what it should be doing and outputting the correct value. Just for whatever reason, the case statement refuses to set it.

I can also remove all of the conditionals and just put the code in and everything works fine, except for course for the fact that then I have an overly complicated adder and not an ALU. Any help would be greatly appreciated.

entity ALU is
    port (
        A, B: in std_ulogic_vector(31 downto 0);
        Selection: in std_ulogic_vector(5 downto 0);
        Carry_in: in std_ulogic;
        Output: out std_ulogic_vector(31 downto 0);
        CF, ZF, NF, VF: out std_ulogic
    );
end ALU;

architecture ALU_ARCH of ALU is
component ADDER is
    port (
        A: in std_ulogic_vector(31 downto 0);
        B: in std_ulogic_vector(31 downto 0);
        Carry_in: in std_ulogic;
        Overflow: out std_ulogic;
        Carry_out: out std_ulogic;
        Sum: out std_ulogic_vector(31 downto 0)
    );
end component;

signal Adder_ci, Adder_co, Adder_overflow: std_ulogic;
signal Adder_B, Adder_sum: std_ulogic_vector(31 downto 0);

signal Results: std_ulogic_vector(31 downto 0);

begin
ADDITION: ADDER port map(A => A, B => Adder_B, Sum => Adder_sum, Carry_in => Adder_ci, Carry_out => Adder_co, Overflow => Adder_overflow);

process(A, B, Selection, Carry_In)
begin
case Selection is
    when "000000" =>  --ADD
        Adder_B <= B;
        Adder_ci <= '0';
        CF <= Adder_co;
        Results <= Adder_sum;       
        NF <= Results(31);
        VF <= Adder_overflow;
    when others =>
        Adder_B <= B;
        Adder_ci <= '0';
        CF <= Adder_co;
        Results <= Adder_sum;       
        NF <= Results(31);
        VF <= Adder_overflow;
end case;

end process;

Output <= Results; 

end ALU_ARCH;

The test bench I am using to check it is listed in the code below, just in case I'm doing something wrong in there.

entity ALU_TB is
end ALU_TB;

architecture test_arch of ALU_TB is
    component ALU
    port (
        A, B: in std_ulogic_vector(31 downto 0);
        Selection: in std_ulogic_vector(5 downto 0);
        Carry_in: in std_ulogic;
        Output: out std_ulogic_vector(31 downto 0);
        CF, ZF, NF, VF: out std_ulogic
    );
    end component;

signal Carry_in, CF, ZF, NF, VF: std_ulogic;
signal Selection: std_ulogic_vector(5 downto 0);
signal A, B, Output: std_ulogic_vector(31 downto 0);

begin
    ALUb: ALU port map(A => A, B => B, Selection => Selection, Carry_in => Carry_in, Output => Output, CF => CF, NF => NF, ZF => ZF, VF => VF);

    process 

    variable AT : integer;  
    variable BT : integer;  
    begin
        Selection <= "000000";
        AT := 80;
        BT := 16;
        Carry_in <= '0';
        A <= std_ulogic_vector( to_signed(AT, A'length) ); 
        B <= std_ulogic_vector( to_signed(BT, B'length) ); 
        wait for 1 ns;
        if Output /= std_ulogic_vector( to_signed( (AT + BT) , Output'length) ) then 
            assert false report "Failed in 1";
        end if;

        wait;

    end process;

end test_arch;

I'm not sure if it matters, but I'm doing all of this in GHDL on a Mac.


Solution

  • When your test sets the inputs the selection process is triggered to do its assignments which leads to a new adder output. However, that change in the Adder_sum will not trigger the process since it's not in the sensitivity list so the sum will not be assigned to the Results signal.

    There are several solutions. One would be to trigger on all signals using process(all).