Search code examples
vhdlhdltest-benchalughdl

VHDL when running ghdl -r my testbench is getting stuck after passing two values


This is my program in vhdl is small ALU only allowed to compare, sum, substract and multiply by 2. I'm not getting errors when I compile the two codes, but I tried everything I know to solve and also using old examples I had, and I can't see where the error is. The testbench is getting stucked before the second report "un altre" gets printed, while executing the code.

    library ieee;
    use IEEE.Std_logic_1164.all;
    use ieee.numeric_std.all;

    entity ALU is
    port(
        A, B: in std_logic_vector(4 downto 0);
        OP: in std_logic_vector(3 downto 0);
        RESSUM: out unsigned(9 downto 0);
        RESRES: out signed(9 downto 0);
        SEG0, SEG1, SEG2, SEG3: out std_logic_vector(6 downto 0);
        O: out std_logic_vector(2 downto 0)
    );
    end entity ALU;

    architecture ALU_ARCH of ALU is
    begin
    process
    begin
        case OP is
            when "0001" =>
                if A < B then
                    O <= "001";
                    SEG2 <= "0000000";
                    SEG1 <= "1010000";
                    SEG0 <= "1101111";
                elsif A = B then
                    O <= "010";
                    SEG2 <= "0000000";
                    SEG1 <= "1111001";
                    SEG0 <= "1100111";
                else
                    O <= "100";
                    SEG2 <= "0000000";
                    SEG1 <= "0111000";
                    SEG0 <= "1101111";
                end if;
            when "0010" =>
                RESSUM <= unsigned(A) + unsigned(B);

            when "0100" =>
                RESRES <= resize(signed(unsigned(A) - unsigned(B)), 10);
                if A < B then
                    SEG2 <= "0000000";
                    SEG1 <= "0000000";
                    SEG0 <= "1000000";
                end if;
            when "1000" =>
                RESSUM <= unsigned(A) sll to_integer(signed(B));
            when others =>
                SEG2 <= "1111001";
                SEG1 <= "1010000";
                SEG0 <= "1010000";
        end case;
    end process;
    end ALU_ARCH;

    library ieee;
    use IEEE.Std_logic_1164.all;
    use IEEE.numeric_std.all;

    entity ALU_TB is
    end entity ALU_TB;

    architecture bench of ALU_TB is
    component ALU
        port(
            A, B: in std_logic_vector(4 downto 0);
            O: out std_logic_vector(2 downto 0);
            OP: in std_logic_vector(3 downto 0);
            RESSUM: out unsigned(9 downto 0);
            RESRES: out signed(9 downto 0);
            SEG0, SEG1, SEG2, SEG3: out std_logic_vector(6 downto 0)
        );
    end component;

    for alu_0: ALU use entity work.alu;

    signal A, B: std_logic_vector(4 downto 0);
    signal O: std_logic_vector(2 downto 0);
    signal OP: std_logic_vector(3 downto 0);
    signal RESSUM: unsigned(9 downto 0);
    signal RESRES: signed(9 downto 0);
    signal SEG0, SEG1, SEG2, SEG3: std_logic_vector(6 downto 0);

    begin
    alu_0: ALU port map (
        A => A,
        B => B,
        O => O,
        OP => OP,
        RESSUM => RESSUM,
        RESRES => RESRES,
        SEG0 => SEG0,
        SEG1 => SEG1,
        SEG2 => SEG2,
        SEG3 => SEG3
    );

    process
    begin
        report "comenca";
        OP <= "0001";
        A <= "10001";
        B <= "01111";
        report "un altre";
        wait for 100 ns;
        A <= "10001";
        B <= "01111";
        wait for 1000 ns;
        report "un altre";
        report "Acabat";
        end process;
    end bench;

I tried to run the testbench without getting stucked, changing integers to std_logic_vectors, before this approach I didn't use component only the entity, but nothing result well functioning program.


Solution

  • The ALU process in your ALU entity has neither a wait statement nor sensitivity list, making it an infinite loop, hence no output being produced as GHDL is stuck looping in the process forever.

    I recommend adding a sensitivity list, ideally using the VHDL 2008 process(all) construct, so that the compiler can work out the sensitivity list for you. If you are stuck with an older VHDL revision, the you will need

    process(OP, A, B)
    

    Using process(all) is favoured so that if code is changed in the future, you dont forget to update the sensitivity list.

    SIDE NOTE: when the sensitivity list is fixed, your code will produce latches because not all outputs are assigned an output in all branches of your asynchronous process. All signal assigned in the process must be assigned in all branches to avoid this.