Search code examples
mipsvhdl

VHDL: std logic vector not holding value between process calls


I have the following code snippet:

SIGNAL ALU_hilo : STD_LOGIC_VECTOR(63 downto 0);

PROCESS ( ALU_ctl, Ainput, Binput )
BEGIN
-- Select ALU operation
    CASE ALU_ctl IS
        -- ALU performs ALUresult = A_input AND B_input
        WHEN "0000"     =>  ALU_Internal    <= Ainput AND Binput; 
        -- ALU performs ALUresult = A_input OR B_input
        WHEN "0001"     =>  ALU_Internal    <= Ainput OR Binput;
        -- ALU performs ALUresult = A_input + B_input
        WHEN "0010"     =>  ALU_Internal    <= Ainput + Binput;
        -- ALU performs ?
        WHEN "0011"     =>  ALU_Internal <= X"00000000";
        -- ALU performs ?
        WHEN "0100"     =>  ALU_Internal    <= X"00000000";
        -- ALU performs ?
        WHEN "0101"     =>  ALU_Internal    <= X"00000000";
        -- ALU performs ALUresult = A_input - B_input
        WHEN "0110"     =>  ALU_Internal    <= Ainput - Binput;
        -- ALU performs SLT
        WHEN "0111"     =>  ALU_Internal    <= Ainput - Binput ;
        -- ALU performs MFHI
        WHEN "1101"     =>  ALU_Internal <= ALU_hilo(63 downto 32);
        -- ALU performs MFLO
        WHEN "1100"     =>  ALU_Internal <= ALU_hilo(31 downto 0);
        -- ALU performs MULT
        when "1000"     =>  ALU_hilo <= Ainput * Binput;
        WHEN "1001"     =>  ALU_Internal <= Binput(15 downto 0) & X"0000";
        WHEN OTHERS     =>  ALU_Internal    <= X"00000000";
    END CASE;
END PROCESS;

All of the other signals here are declared previously and work fine. My problem is that ALU_hilo is being overwritten with 0x0 on subsequent process calls where ALU_ctl is not "1000". How can I fix this so that ALU_hilo holds its value unless ALU_ctl is 1000?


Solution

  • You're creating latches for signals that are only assigned for specific conditions of one of the signals in the sensitivity list.

    You're more than likely seeing an event on Ainput or Binput (or both) while ALU_ctl is still "1000".

    Without controlling when you enable latches specifically, this process may not synthesize to your intended function. If you intend to create latches here you should use an enable that's only valid when all other signals used in the process are unchanging.

    You could similarly us a clock edge and create registers instead of latches where ALU_ctl serves as an address to select which register is updated. It would imply that Ainput and Binput occur on the same clock.

    (And processes aren't called, their execution is resumed when one of their sensitivity list elements has an event. There's an implied wait on ALU_ctl, Ainput, Binput; as the last statement of the process. A process is a sequence of statements that will repeat unless stopped.)