-----------------------------------------------------------------
-- test bench for FSM (ESD book figure 2.7)
-- by Weijun Zhang, 04/2001
-----------------------------------------------------------------

LIBRARY ieee;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_unsigned.ALL;
USE ieee.std_logic_1164.ALL;

ENTITY fsm_tb IS -- entity declaration
END fsm_tb;

-----------------------------------------------------------------

ARCHITECTURE TB OF fsm_tb IS

    SIGNAL T_a : STD_LOGIC;
    SIGNAL T_clock : STD_LOGIC;
    SIGNAL T_reset : STD_LOGIC;
    SIGNAL T_x : STD_LOGIC;

    COMPONENT seq_design
        PORT (
            a : IN STD_LOGIC;
            clock : IN STD_LOGIC;
            reset : IN STD_LOGIC;
            x : OUT STD_LOGIC
        );
    END COMPONENT;

BEGIN

    U_fsm : seq_design PORT MAP(T_a, T_clock, T_reset, T_x);

    PROCESS
    BEGIN
        T_clock <= '1'; -- clock cycle 10 ns
        WAIT FOR 5 ns;
        T_clock <= '0';
        WAIT FOR 5 ns;
    END PROCESS;

    PROCESS

        VARIABLE err_cnt : INTEGER := 0;

    BEGIN

        -- case 1		
        T_reset <= '1';
        WAIT FOR 20 ns;
        ASSERT (T_x = '0') REPORT "Failed Case 1" SEVERITY error;
        IF (T_x /= '0') THEN
            err_cnt := err_cnt + 1;
        END IF;

        -- case 2
        T_reset <= '0';
        T_a <= '0';
        WAIT FOR 20 ns;
        ASSERT (T_x = '0') REPORT "Failed Case 2" SEVERITY error;
        IF (T_x /= '0') THEN
            err_cnt := err_cnt + 1;
        END IF;

        -- case 3
        WAIT FOR 30 ns;
        T_a <= '1';
        WAIT FOR 35 ns;
        ASSERT (T_x = '1') REPORT "Failed Case 3" SEVERITY error;
        IF (T_x /= '1') THEN
            err_cnt := err_cnt + 1;
        END IF;

        -- case 4
        WAIT FOR 70 ns;
        T_reset <= '1';
        WAIT FOR 10 ns;
        ASSERT (T_x = '0') REPORT "Failed Case 4" SEVERITY error;
        IF (T_x /= '0') THEN
            err_cnt := err_cnt + 1;
        END IF;

        -- summary of all the tests	
        IF (err_cnt = 0) THEN
            ASSERT false
            REPORT "Testbench of FSM completely successfully!"
                SEVERITY note;
        ELSE
            ASSERT true
            REPORT "Something wrong, Check again pls!"

                SEVERITY error;
        END IF;

        WAIT;

    END PROCESS;

END TB;

----------------------------------------------------------------------
CONFIGURATION CFG_TB OF fsm_TB IS
    FOR TB
    END FOR;
END CFG_TB;