--=================================================================================================
-- File Name                           : stepper_theta_tb.vhd

-- Description                         : This module implements the test environment for
--                                       stepper_theta module.

-- Targeted device                     : Microsemi-SoC
-- Author                              : India Solutions Team
--
-- SVN Revision Information            :
-- SVN $Revision                       :
-- SVN $Date                           :
--
-- COPYRIGHT 2016 BY MICROSEMI
-- THE INFORMATION CONTAINED IN THIS DOCUMENT IS SUBJECT TO LICENSING RESTRICTIONS FROM MICROSEMI
-- CORP. IF YOU ARE NOT IN POSSESSION OF WRITTEN AUTHORIZATION FROM MICROSEMI FOR USE OF THIS
-- FILE, THEN THE FILE SHOULD BE IMMEDIATELY DESTROYED AND NO BACK-UP OF THE FILE SHOULD BE MADE.
--
--=================================================================================================

--=================================================================================================
-- Libraries
--=================================================================================================
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE STD.TEXTIO.ALL;
USE IEEE.STD_LOGIC_TEXTIO.ALL;
USE IEEE.STD_LOGIC_SIGNED.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE IEEE.MATH_REAL.ALL;   -- FOR UNIFORM, TRUNC FUNCTIONS
USE WORK.SIM_PKG.ALL;
LIBRARY MODELSIM_LIB;
USE MODELSIM_LIB.UTIL.ALL;
USE WORK.SIM_PKG.ALL;
--=================================================================================================
-- stepper_theta_tb entity declaration
--=================================================================================================

ENTITY stepper_theta_tb IS

END stepper_theta_tb;

--=================================================================================================
-- stepper_theta_tb architecture body
--=================================================================================================
ARCHITECTURE BEHAVIOURAL OF stepper_theta_tb IS

--=================================================================================================
-- Component declarations
--=================================================================================================
COMPONENT stepper_theta IS
PORT (
    reset_i                            : IN  STD_LOGIC;
    sys_clk_i                          : IN  STD_LOGIC;
    enable_i                           : IN  STD_LOGIC;
    mode_i                             : IN  STD_LOGIC;
    clear_buffer_i                     : IN  STD_LOGIC;
    slew_cnt_i                         : IN  STD_LOGIC_VECTOR(17    DOWNTO 0);
    rate_limit_i                       : IN  STD_LOGIC_VECTOR(17    DOWNTO 0);
    cmd_step_no_i                      : IN  STD_LOGIC_VECTOR(23    DOWNTO 0);
    theta_output_o                     : OUT STD_LOGIC_VECTOR(17    DOWNTO 0);
    step_count_o                       : OUT STD_LOGIC_VECTOR(23    DOWNTO 0)
);
END COMPONENT;
--=================================================================================================
-- Synthesis Attributes
--=================================================================================================
--NA--
--=================================================================================================
-- Signal declarations
--=================================================================================================
CONSTANT SYSCLK_PERIOD                 : TIME   := 10 ns;
CONSTANT g_RESET_STATE                 : INTEGER:= 0;
CONSTANT g_STD_IO_WIDTH                : INTEGER:= 18;

TYPE rate_state IS (IDLE,START,INP_DRIVER,SLEW_COUNT,INT_OUT_COMP,RESET_STATE,OUTPUT_COMPARE);
SIGNAL state                           : rate_state;
SIGNAL sys_clk_tb                      : STD_LOGIC := '0';
SIGNAL reset_tb                        : STD_LOGIC := '0';
SIGNAL s_reset_tb_dly                  : STD_LOGIC;
SIGNAL s_reset_pul_tb                  : STD_LOGIC;
SIGNAL s_start_tb                      : STD_LOGIC;
SIGNAL reset                           : STD_LOGIC;
SIGNAL reset_tmp                       : STD_LOGIC;
SIGNAL s_start_rand_tb                 : STD_LOGIC;
SIGNAL s_trig_tb                       : STD_LOGIC;
SIGNAL s_reset_rl_tb                   : STD_LOGIC;
SIGNAL s_enable_tmp_tb                 : STD_LOGIC;
SIGNAL s_mode_tb                       : STD_LOGIC;
SIGNAL s_clear_buffer_tb               : STD_LOGIC;
SIGNAL counter                         : STD_LOGIC_VECTOR(11 DOWNTO 0);
SIGNAL s_count_trig_tb                 : STD_LOGIC_VECTOR(11 DOWNTO 0);
SIGNAL s_theta_output_tb               : STD_LOGIC_VECTOR(g_STD_IO_WIDTH-1 DOWNTO 0);
SIGNAL s_rate_count_tb                 : STD_LOGIC_VECTOR(g_STD_IO_WIDTH-1 DOWNTO 0);
SIGNAL s_cmd_step_no_tb                : STD_LOGIC_VECTOR(g_STD_IO_WIDTH+5 DOWNTO 0);
SIGNAL s_stim                          : STD_LOGIC_VECTOR(g_STD_IO_WIDTH+5 DOWNTO 0);
SIGNAL s_stim_slew                     : STD_LOGIC_VECTOR(g_STD_IO_WIDTH-1 DOWNTO 0);
SIGNAL s_stim_rate                     : STD_LOGIC_VECTOR(g_STD_IO_WIDTH-1 DOWNTO 0);
SIGNAL s_count_out_tb                  : STD_LOGIC_VECTOR(g_STD_IO_WIDTH-1 DOWNTO 0);
SIGNAL s_step_count_tb                 : STD_LOGIC_VECTOR(g_STD_IO_WIDTH+5 DOWNTO 0);
SIGNAL s_slew_count_tb                 : STD_LOGIC_VECTOR(g_STD_IO_WIDTH-1 DOWNTO 0);
SIGNAL s_theta_tb                      : STD_LOGIC_VECTOR(g_STD_IO_WIDTH-1 DOWNTO 0);
SIGNAL s_step_count_out_tb             : STD_LOGIC_VECTOR(g_STD_IO_WIDTH +5 DOWNTO 0);
--========================================================
-- File read operations
--========================================================
--NA--
--========================================================
-- File write operations
--========================================================
--NA--
--========================================================
-- Procedure declarations
--========================================================
PROCEDURE stepper_theta_gen
	(
	SIGNAL reset_tb     		: IN STD_LOGIC;
	SIGNAL sys_clk_tb   		: IN STD_LOGIC;
	SIGNAL start        		: IN STD_LOGIC;
	SIGNAL mode          		: IN STD_LOGIC;
	SIGNAL clear          		: IN STD_LOGIC;
	SIGNAL cmd_step_no    		: IN STD_LOGIC_VECTOR(g_STD_IO_WIDTH+5 DOWNTO 0);
	SIGNAL slew_count   		: IN STD_LOGIC_VECTOR(g_STD_IO_WIDTH-1 DOWNTO 0);
	SIGNAL rate_count   		: IN STD_LOGIC_VECTOR(g_STD_IO_WIDTH-1 DOWNTO 0);
    SIGNAL count_out            : INOUT STD_LOGIC_VECTOR(g_STD_IO_WIDTH-1 DOWNTO 0);
	SIGNAL step_count_out       : INOUT STD_LOGIC_VECTOR(g_STD_IO_WIDTH+5 DOWNTO 0);
	SIGNAL theta_out         	: INOUT STD_LOGIC_VECTOR(g_STD_IO_WIDTH-1 DOWNTO 0)
	) IS
BEGIN
    IF reset_tb = '0' THEN
        count_out        	<= (OTHERS =>'0');
        step_count_out      <= (OTHERS =>'0');
        theta_out 			<= (OTHERS =>'0');
    ELSIF RISING_EDGE (sys_clk_tb) THEN
        IF(count_out = slew_count) THEN
            count_out <= (OTHERS => '0');
        ELSE
            IF(start = '1') THEN
                count_out <= count_out + '1';
            END IF;
        END IF;

        IF clear = '1' THEN
            count_out        	<= (OTHERS =>'0');
            step_count_out    	<= (OTHERS =>'0');
            theta_out 			<= (OTHERS =>'0');
        ELSE
            IF(count_out = slew_count)THEN
                IF(mode = '1') THEN
                    step_count_out <= (OTHERS => '0');
                    IF(cmd_step_no > x"000000") THEN
                        theta_out      <= theta_out + rate_count;
                    ELSE
                        theta_out      <= theta_out - rate_count;
                    END IF;
                ELSE
                    IF(step_count_out < cmd_step_no) THEN
                        step_count_out <= step_count_out + '1';
                        theta_out      <= theta_out + rate_count;
                    ELSIF(step_count_out > cmd_step_no) THEN
                        step_count_out <= step_count_out - '1';
                        theta_out      <= theta_out - rate_count;
                    END IF;
                END IF;
            END IF;
        END IF;
    END IF;
END stepper_theta_gen;

BEGIN
--------------------------------------------------------------------------
-- Name       : RESET_GEN_PROC
-- Description: PROCESS generates the reset signal
--------------------------------------------------------------------------
RESET_GEN_PROC:
    PROCESS
        VARIABLE vhdl_initial : BOOLEAN := TRUE;
    BEGIN
        IF ( vhdl_initial ) THEN
            reset_tb <= '0';
            WAIT FOR ( SYSCLK_PERIOD * 10 );
            reset_tb <= '1';
            WAIT;
        END IF;
    END PROCESS;

--------------------------------------------------------------------------
-- Name       : CLOCK_GEN
-- Description: Logic generates 10 Mhz clock
--------------------------------------------------------------------------
sys_clk_tb <= NOT sys_clk_tb AFTER (SYSCLK_PERIOD / 2.0 );

-- Secondary reset signal generation
 reset_tmp                            <= (reset_tb AND NOT(s_reset_rl_tb));
--------------------------------------------------------------------------
-- Name       : RESET_TEST_PROC
-- Description: Process to check the state of outputs at reset
--------------------------------------------------------------------------
RESET_TEST_PROC:
    PROCESS(s_reset_pul_tb,s_theta_output_tb,s_step_count_out_tb)
    BEGIN
        IF (s_reset_pul_tb = '1') THEN
            IF(s_theta_output_tb = "00"&x"0000" AND s_step_count_out_tb = "00"&x"0000")THEN
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                print(">>>>>>>>                      STEPPER_THETA IP SIMULATION                           <<<<<<<");
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                print(">>>>>>>>     THIS TESTBENCH COMPARES THE FUNCTIONALITY W.R.T THE TESTBENCH MODEL    <<<<<<<");
                print(">>>>>>>>     WITH IN THE TOLERANCE RANGE [-1,0,+1]                                  <<<<<<<");
                print(">>>>>>>>                                                                            <<<<<<<");
                print(">>>>>>>>     ALL  PARAMETERS/GENERICS ARE FIXED TO THE FOLLOWING:                   <<<<<<<");
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                print(">>>>>>>>     g_STD_IO_WIDTH    = 18                                                 <<<<<<<");
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                print("                                                        ");
                print("                                                        ");
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
				print(">>>>                                                <<<<");
                print(">>>>     TESTCASE         : RESET_TEST              <<<<");
				print(">>>>     theta_output_o   = 0                       <<<<");
				print(">>>>     step_count_o     = 0                       <<<<");
				print(">>>>     STATUS           : PASSED                  <<<<");
				print(">>>>     DESCRIPTION      :                         <<<<");
				print(">>>>                                                <<<<");
				print(">>>>     FEATURES COVERED :                         <<<<");
				print(">>>>                                                <<<<");
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            ELSE
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                print(">>>>>>>>                      STEPPER_THETA IP SIMULATION                           <<<<<<<");
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                print(">>>>>>>>     THIS TESTBENCH COMPARES THE FUNCTIONALITY W.R.T THE MATLAB MODEL       <<<<<<<");
                print(">>>>>>>>     WITH IN THE TOLERANCE RANGE [-1,0,+1]                                  <<<<<<<");
                print(">>>>>>>>                                                                            <<<<<<<");
                print(">>>>>>>>     ALL  PARAMETERS/GENERICS ARE FIXED TO THE FOLLOWING:                   <<<<<<<");
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                print(">>>>>>>>     g_STD_IO_WIDTH    = 18                                                 <<<<<<<");
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                print("                                                        ");
                print("                                                        ");
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
				print(">>>>                                                <<<<");
                print(">>>>     TESTCASE         : RESET_TEST              <<<<");
				print(">>>>     theta_output_o   /= 0                      <<<<");
				print(">>>>     step_count_o     /= 0                      <<<<");
				print(">>>>     STATUS           : FAILED                  <<<<");
				print(">>>>     DESCRIPTION      :                         <<<<");
				print(">>>>                                                <<<<");
				print(">>>>     FEATURES COVERED :                         <<<<");
				print(">>>>                                                <<<<");
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");

            END IF;
        END IF;
    END PROCESS;

--------------------------------------------------------------------------
-- Name       : RESET_PUL_GEN_PROC
-- Description: process to generate a reset pulse
--------------------------------------------------------------------------
RESET_PUL_GEN_PROC:
    PROCESS(reset_tb,sys_clk_tb)
    BEGIN
        IF(reset_tb = '0') THEN
            s_reset_tb_dly <= '0';
        ELSIF(RISING_EDGE (sys_clk_tb))THEN
            s_reset_tb_dly <= reset_tb;
        END IF;
    END PROCESS;

    s_reset_pul_tb <= reset_tb AND (not(s_reset_tb_dly));

--------------------------------------------------------------------------
-- Name       : INPUT_DRIVER_PROC
-- Description: Process to provide the input test vectors
--------------------------------------------------------------------------
    -------------------------
    -- Command step number
    -------------------------
    PROCESS(reset_tb,sys_clk_tb)
    VARIABLE seed1, seed2: integer :=7;
    VARIABLE rand: real;
    VARIABLE int_rand: integer;
    BEGIN
        IF(reset_tb = '0') THEN
            s_stim   <= (OTHERS => '0');
        ELSIF  RISING_EDGE(sys_clk_tb) THEN
            IF(s_start_rand_tb = '1') THEN
                UNIFORM(seed1,seed2, rand);
                int_rand := INTEGER(rand*50.0);
                s_stim <= std_logic_vector(to_signed(int_rand, 24));
            END IF;
        END IF;
    END PROCESS;
    -------------------------
    -- Slew count
    -------------------------
    PROCESS(reset_tb,sys_clk_tb)
    VARIABLE seed3, seed4: integer := 2;
    VARIABLE rand1: real;
    VARIABLE int_rand1: integer;
    BEGIN
        IF(reset_tb = '0') THEN
            s_stim_slew<= (OTHERS => '0');
        ELSIF  RISING_EDGE(sys_clk_tb) THEN
            IF(s_start_rand_tb = '1') THEN
                UNIFORM(seed3, seed4, rand1);
                int_rand1 := INTEGER(rand1*50.0);
                s_stim_slew <= std_logic_vector(to_unsigned(int_rand1, 18));
            END IF;
        END IF;
    END PROCESS;
    -------------------------
    -- Rate count
    -------------------------
    PROCESS(reset_tb,sys_clk_tb)
    VARIABLE seed5, seed6: integer := 10;
    VARIABLE rand2: real;
    VARIABLE int_rand2: integer;
    BEGIN
        IF(reset_tb = '0') THEN
            s_stim_rate<= (OTHERS => '0');
        ELSIF  RISING_EDGE(sys_clk_tb) THEN
            IF(s_start_rand_tb = '1') THEN
                UNIFORM(seed5, seed6, rand2);
                int_rand2 := INTEGER(rand2*4096.0);
                s_stim_rate <= std_logic_vector(to_unsigned(int_rand2, 18));
            END IF;
        END IF;
    END PROCESS;
--------------------------------------------------------------------------
-- Name       : FSM_STEPPER_THETA_TB_PROC
-- Description: FSM implements stepper theta IP testbench controller operation
--------------------------------------------------------------------------
FSM_STEPPER_THETA_TB_PROC:
    PROCESS(sys_clk_tb,reset_tb)
    BEGIN
        IF(reset_tb = '0') THEN
            state                       <= IDLE;
            s_cmd_step_no_tb            <= (OTHERS => '0');
            reset                       <= '0';
			s_start_rand_tb             <= '0';
			s_start_tb             		<= '0';
			s_enable_tmp_tb        		<= '0';
            s_reset_rl_tb               <= '0';
			s_mode_tb            		<= '0';
            s_clear_buffer_tb           <= '0';
            s_slew_count_tb             <= (OTHERS => '0');
            s_rate_count_tb             <= (OTHERS => '0');
        ELSIF (RISING_EDGE(sys_clk_tb)) THEN
            CASE(state)IS
--------------------
-- IDLE state
--------------------
            WHEN IDLE =>
				IF(counter < x"016") THEN -- 22 inputs
					state               <= START ;
					s_start_rand_tb 	<= '1';
				ELSE
					state <= IDLE;
				END IF;

--------------------
-- START state
--------------------
			WHEN START =>
				s_start_rand_tb <= '0';
				state <= INP_DRIVER;

--------------------
-- INP_DRIVER state
--------------------
            WHEN INP_DRIVER =>
                s_enable_tmp_tb         <= '1';
				s_start_rand_tb 		<= '0';
                s_start_tb     		    <= '1';
                IF(counter < x"014") THEN
                    s_slew_count_tb         <= s_stim_slew;
                    s_rate_count_tb         <= s_stim_rate;
                    s_mode_tb               <= '0';
                ELSE
                    s_slew_count_tb         <= "00"&x"0001";
                    s_rate_count_tb         <= "00"&x"7FFF";
                    s_mode_tb               <= '1';
                END IF;
				IF(counter < x"00A") THEN
					s_cmd_step_no_tb      <= s_stim;
				ELSIF(counter = x"015") THEN
                    s_cmd_step_no_tb      <= s_stim;
				ELSE
                    s_cmd_step_no_tb      <= NOT(s_stim) + '1';
                END IF;
                IF(counter < x"016") THEN
					s_clear_buffer_tb      <= '0';
                ELSE
                    s_clear_buffer_tb      <= '1';
                END IF;
                state <= OUTPUT_COMPARE;
--------------------
-- OUTPUT_COMPARE state
--------------------
			WHEN OUTPUT_COMPARE =>
				s_start_tb     		        <= '0';
                IF(s_clear_buffer_tb = '0') THEN
                    IF(s_count_out_tb < s_slew_count_tb) THEN
                        state               <= OUTPUT_COMPARE;
                    ELSE
                        IF(s_mode_tb = '0') THEN
                            IF(s_cmd_step_no_tb(23) = '0') THEN
                                IF(s_step_count_tb < s_cmd_step_no_tb AND s_step_count_out_tb < s_cmd_step_no_tb) THEN
                                    state               <= OUTPUT_COMPARE;
                                ELSE
                                    IF(s_theta_output_tb = s_theta_tb(g_STD_IO_WIDTH-1 DOWNTO 0) AND s_step_count_tb = s_cmd_step_no_tb AND s_step_count_out_tb = s_cmd_step_no_tb) THEN
                                        state               <= RESET_STATE;
                                        s_reset_rl_tb       <= '1';
                                        print("                                                                 ");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                        print_text_val("|  TESTCASE   :  ",(to_integer(signed(counter))),"                                               |");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                        print("   INPUTS                                                                            ");
                                        print_text_val("         CMD_STEPS         =  ",(to_integer(signed(s_cmd_step_no_tb))),"    ");
                                        print_text_val("         SLEW_COUNT        =  ",(to_integer(signed(s_slew_count_tb))),"     ");
                                        print_text_val("         RATE_COUNT        =  ",(to_integer(signed(s_rate_count_tb))),"     ");
                                        IF(s_cmd_step_no_tb(23) = '0') THEN
                                            print("         DIRECTION         =  FORWARD                                                ");
                                        ELSE
                                            print("         DIRECTION         =  REVERSE                                                ");
                                        END IF;
                                        print("         CLEAR_BUFFER      =  0                                                      ");
                                        print("                                                                                     ");
                                        print("     OUTPUTS                                                                         ");
                                        print_text_val("         DUT_THETA         =  ",(to_integer(signed(s_theta_output_tb))),"   ");
                                        print_text_val("         DUT_STEP          =  ",(to_integer(signed(s_step_count_out_tb)))," ");
                                        print_text_val("         TB_STEP           =  ",(to_integer(signed(s_step_count_tb))),"     ");
                                        print_text_val("         TB_THETA          =  ",(to_integer(signed(s_theta_tb(g_STD_IO_WIDTH-1 DOWNTO 0))))," ");
                                        print(">>>>                                                           <<<<");
                                        print(">>>>     STATUS            :  PASSED                           <<<<");
                                        print(">>>>     DESCRIPTION       :  TB AND DUT OUTPUTS MATCH         <<<<");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                    ELSE
                                        state               <= RESET_STATE;
                                        s_reset_rl_tb       <= '1';
                                        print("                                                                 ");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                        print_text_val("|  TESTCASE   :  ",(to_integer(signed(counter))),"                                               |");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                        print("   INPUTS                                                                            ");
                                        print_text_val("         CMD_STEPS         =  ",(to_integer(signed(s_cmd_step_no_tb))),"    ");
                                        print_text_val("         SLEW_COUNT        =  ",(to_integer(signed(s_slew_count_tb))),"     ");
                                        print_text_val("         RATE_COUNT        =  ",(to_integer(signed(s_rate_count_tb))),"     ");
                                        IF(s_cmd_step_no_tb(23) = '0') THEN
                                            print("         DIRECTION         =  FORWARD                                                ");
                                        ELSE
                                            print("         DIRECTION         =  REVERSE                                                ");
                                        END IF;
                                        print("         CLEAR_BUFFER      =  0                                                      ");
                                        print("                                                                                     ");
                                        print("     OUTPUTS                                                                         ");
                                        print_text_val("         DUT_THETA         =  ",(to_integer(signed(s_theta_output_tb))),"   ");
                                        print_text_val("         DUT_STEP          =  ",(to_integer(signed(s_step_count_out_tb)))," ");
                                        print_text_val("         TB_STEP           =  ",(to_integer(signed(s_step_count_tb))),"     ");
                                        print_text_val("         TB_THETA          =  ",(to_integer(signed(s_theta_tb(g_STD_IO_WIDTH-1 DOWNTO 0))))," ");
                                        print(">>>>                                                           <<<<");
                                        print(">>>>     STATUS            :  FAILED                           <<<<");
                                        print(">>>>     DESCRIPTION       :  TB AND DUT OUTPUTS DO NOT MATCH  <<<<");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                    END IF;
                                END IF;
                            ELSE
                                IF(s_step_count_tb > s_cmd_step_no_tb AND s_step_count_out_tb > s_cmd_step_no_tb) THEN
                                    state               <= OUTPUT_COMPARE;
                                ELSE
                                    IF(s_theta_output_tb = s_theta_tb(g_STD_IO_WIDTH-1 DOWNTO 0) AND s_step_count_tb = s_cmd_step_no_tb AND s_step_count_out_tb = s_cmd_step_no_tb) THEN
                                        state               <= RESET_STATE;
                                        s_reset_rl_tb       <= '1';
                                        print("                                                                 ");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                        print_text_val("|  TESTCASE   :  ",(to_integer(signed(counter))),"                                               |");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                        print("   INPUTS                                                                            ");
                                        print_text_val("         CMD_STEPS         =  ",(to_integer(signed(s_cmd_step_no_tb))),"    ");
                                        print_text_val("         SLEW_COUNT        =  ",(to_integer(signed(s_slew_count_tb))),"     ");
                                        print_text_val("         RATE_COUNT        =  ",(to_integer(signed(s_rate_count_tb))),"     ");
                                        IF(s_cmd_step_no_tb(23) = '0') THEN
                                            print("         DIRECTION         =  FORWARD                                                ");
                                        ELSE
                                            print("         DIRECTION         =  REVERSE                                                ");
                                        END IF;
                                        print("         CLEAR_BUFFER      =  0                                                      ");
                                        print("                                                                                     ");
                                        print("     OUTPUTS                                                                         ");
                                        print_text_val("         DUT_THETA         =  ",(to_integer(signed(s_theta_output_tb))),"   ");
                                        print_text_val("         DUT_STEP          =  ",(to_integer(signed(s_step_count_out_tb)))," ");
                                        print_text_val("         TB_STEP           =  ",(to_integer(signed(s_step_count_tb))),"     ");
                                        print_text_val("         TB_THETA          =  ",(to_integer(signed(s_theta_tb(g_STD_IO_WIDTH-1 DOWNTO 0))))," ");
                                        print(">>>>                                                           <<<<");
                                        print(">>>>     STATUS            :  PASSED                           <<<<");
                                        print(">>>>     DESCRIPTION       :  TB AND DUT OUTPUTS MATCH         <<<<");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                    ELSE
                                        state               <= RESET_STATE;
                                        s_reset_rl_tb       <= '1';
                                        print("                                                                 ");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                        print_text_val("|  TESTCASE   :  ",(to_integer(signed(counter))),"                                               |");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                        print("   INPUTS                                                                            ");
                                        print_text_val("         CMD_STEPS         =  ",(to_integer(signed(s_cmd_step_no_tb))),"    ");
                                        print_text_val("         SLEW_COUNT        =  ",(to_integer(signed(s_slew_count_tb))),"     ");
                                        print_text_val("         RATE_COUNT        =  ",(to_integer(signed(s_rate_count_tb))),"     ");
                                        IF(s_cmd_step_no_tb(23) = '0') THEN
                                            print("         DIRECTION         =  FORWARD                                                ");
                                        ELSE
                                            print("         DIRECTION         =  REVERSE                                                ");
                                        END IF;
                                        print("         CLEAR_BUFFER      =  0                                                      ");
                                        print("                                                                                     ");
                                        print("     OUTPUTS                                                                         ");
                                        print_text_val("         DUT_THETA         =  ",(to_integer(signed(s_theta_output_tb))),"   ");
                                        print_text_val("         DUT_STEP          =  ",(to_integer(signed(s_step_count_out_tb)))," ");
                                        print_text_val("         TB_STEP           =  ",(to_integer(signed(s_step_count_tb))),"     ");
                                        print_text_val("         TB_THETA          =  ",(to_integer(signed(s_theta_tb(g_STD_IO_WIDTH-1 DOWNTO 0))))," ");
                                        print(">>>>                                                           <<<<");
                                        print(">>>>     STATUS            :  FAILED                           <<<<");
                                        print(">>>>     DESCRIPTION       :  TB AND DUT OUTPUTS DO NOT MATCH  <<<<");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                    END IF;
                                END IF;
                            END IF;
                        ELSE
                            IF(s_cmd_step_no_tb(23) = '0') THEN
                                IF(s_theta_output_tb < "01"&x"FFFC" AND s_theta_tb < "01"&x"FFFC") THEN
                                    state               <= OUTPUT_COMPARE;
                                ELSE
                                    IF(s_theta_output_tb = "01"&x"FFFC" AND s_theta_tb = "01"&x"FFFC") THEN
                                        state               <= RESET_STATE;
                                        s_reset_rl_tb       <= '1';
                                        print("                                                                 ");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                        print_text_val("|  TESTCASE   :  ",(to_integer(signed(counter))),"                                               |");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                        print("   INPUTS                                                                            ");
                                        print_text_val("         CMD_STEPS         =  ",(to_integer(signed(s_cmd_step_no_tb))),"    ");
                                        print_text_val("         SLEW_COUNT        =  ",(to_integer(signed(s_slew_count_tb))),"     ");
                                        print_text_val("         RATE_COUNT        =  ",(to_integer(signed(s_rate_count_tb))),"     ");
                                        IF(s_cmd_step_no_tb(23) = '0') THEN
                                            print("         DIRECTION         =  FORWARD                                                ");
                                        ELSE
                                            print("         DIRECTION         =  REVERSE                                                ");
                                        END IF;
                                        print("         CLEAR_BUFFER      =  0                                                      ");
                                        print("                                                                                     ");
                                        print("     OUTPUTS                                                                         ");
                                        print_text_val("         DUT_THETA         =  ",(to_integer(signed(s_theta_output_tb))),"   ");
                                        print_text_val("         DUT_STEP          =  ",(to_integer(signed(s_step_count_out_tb)))," ");
                                        print_text_val("         TB_STEP           =  ",(to_integer(signed(s_step_count_tb))),"     ");
                                        print_text_val("         TB_THETA          =  ",(to_integer(signed(s_theta_tb(g_STD_IO_WIDTH-1 DOWNTO 0))))," ");
                                        print(">>>>                                                           <<<<");
                                        print(">>>>     STATUS            :  PASSED                           <<<<");
                                        print(">>>>     DESCRIPTION       :  TB AND DUT OUTPUTS MATCH         <<<<");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                    ELSE
                                        state               <= RESET_STATE;
                                        s_reset_rl_tb       <= '1';
                                        print("                                                                 ");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                        print_text_val("|  TESTCASE   :  ",(to_integer(signed(counter))),"                                               |");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                        print("   INPUTS                                                                            ");
                                        print_text_val("         CMD_STEPS         =  ",(to_integer(signed(s_cmd_step_no_tb))),"    ");
                                        print_text_val("         SLEW_COUNT        =  ",(to_integer(signed(s_slew_count_tb))),"     ");
                                        print_text_val("         RATE_COUNT        =  ",(to_integer(signed(s_rate_count_tb))),"     ");
                                        IF(s_cmd_step_no_tb(23) = '0') THEN
                                            print("         DIRECTION         =  FORWARD                                                ");
                                        ELSE
                                            print("         DIRECTION         =  REVERSE                                                ");
                                        END IF;
                                        print("         CLEAR_BUFFER      =  0                                                      ");
                                        print("                                                                                     ");
                                        print("     OUTPUTS                                                                         ");
                                        print_text_val("         DUT_THETA         =  ",(to_integer(signed(s_theta_output_tb))),"   ");
                                        print_text_val("         DUT_STEP          =  ",(to_integer(signed(s_step_count_out_tb)))," ");
                                        print_text_val("         TB_STEP           =  ",(to_integer(signed(s_step_count_tb))),"     ");
                                        print_text_val("         TB_THETA          =  ",(to_integer(signed(s_theta_tb(g_STD_IO_WIDTH-1 DOWNTO 0))))," ");
                                        print(">>>>                                                           <<<<");
                                        print(">>>>     STATUS            :  FAILED                           <<<<");
                                        print(">>>>     DESCRIPTION       :  TB AND DUT OUTPUTS DO NOT MATCH  <<<<");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                    END IF;
                                END IF;
                            ELSE
                                IF(s_theta_output_tb > "10"&x"0004" AND s_theta_tb > "10"&x"0004") THEN
                                    state               <= OUTPUT_COMPARE;
                                ELSE
                                    IF(s_theta_output_tb = "10"&x"0004" AND s_theta_tb = "10"&x"0004") THEN
                                        state               <= RESET_STATE;
                                        s_reset_rl_tb       <= '1';
                                        print("                                                                 ");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                        print_text_val("|  TESTCASE   :  ",(to_integer(signed(counter))),"                                               |");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                        print("   INPUTS                                                                            ");
                                        print_text_val("         CMD_STEPS         =  ",(to_integer(signed(s_cmd_step_no_tb))),"    ");
                                        print_text_val("         SLEW_COUNT        =  ",(to_integer(signed(s_slew_count_tb))),"     ");
                                        print_text_val("         RATE_COUNT        =  ",(to_integer(signed(s_rate_count_tb))),"     ");
                                        IF(s_cmd_step_no_tb(23) = '0') THEN
                                            print("         DIRECTION         =  FORWARD                                                ");
                                        ELSE
                                            print("         DIRECTION         =  REVERSE                                                ");
                                        END IF;
                                        print("         CLEAR_BUFFER      =  0                                                      ");
                                        print("                                                                                     ");
                                        print("     OUTPUTS                                                                         ");
                                        print_text_val("         DUT_THETA         =  ",(to_integer(signed(s_theta_output_tb))),"   ");
                                        print_text_val("         DUT_STEP          =  ",(to_integer(signed(s_step_count_out_tb)))," ");
                                        print_text_val("         TB_STEP           =  ",(to_integer(signed(s_step_count_tb))),"     ");
                                        print_text_val("         TB_THETA          =  ",(to_integer(signed(s_theta_tb(g_STD_IO_WIDTH-1 DOWNTO 0))))," ");
                                        print(">>>>                                                           <<<<");
                                        print(">>>>     STATUS            :  PASSED                           <<<<");
                                        print(">>>>     DESCRIPTION       :  TB AND DUT OUTPUTS MATCH         <<<<");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                    ELSE
                                        state               <= RESET_STATE;
                                        s_reset_rl_tb       <= '1';
                                        print("                                                                 ");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                        print_text_val("|  TESTCASE   :  ",(to_integer(signed(counter))),"                                               |");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                        print("   INPUTS                                                                            ");
                                        print_text_val("         CMD_STEPS         =  ",(to_integer(signed(s_cmd_step_no_tb))),"    ");
                                        print_text_val("         SLEW_COUNT        =  ",(to_integer(signed(s_slew_count_tb))),"     ");
                                        print_text_val("         RATE_COUNT        =  ",(to_integer(signed(s_rate_count_tb))),"     ");
                                        IF(s_cmd_step_no_tb(23) = '0') THEN
                                            print("         DIRECTION         =  FORWARD                                                ");
                                        ELSE
                                            print("         DIRECTION         =  REVERSE                                                ");
                                        END IF;
                                        print("         CLEAR_BUFFER      =  0                                                      ");
                                        print("                                                                                     ");
                                        print("     OUTPUTS                                                                         ");
                                        print_text_val("         DUT_THETA         =  ",(to_integer(signed(s_theta_output_tb))),"   ");
                                        print_text_val("         DUT_STEP          =  ",(to_integer(signed(s_step_count_out_tb)))," ");
                                        print_text_val("         TB_STEP           =  ",(to_integer(signed(s_step_count_tb))),"     ");
                                        print_text_val("         TB_THETA          =  ",(to_integer(signed(s_theta_tb(g_STD_IO_WIDTH-1 DOWNTO 0))))," ");
                                        print(">>>>                                                           <<<<");
                                        print(">>>>     STATUS            :  FAILED                           <<<<");
                                        print(">>>>     DESCRIPTION       :  TB AND DUT OUTPUTS DO NOT MATCH  <<<<");
                                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                                    END IF;
                                END IF;
                            END IF;
                        END IF;
                    END IF;
                ELSE
                    IF((s_theta_output_tb = "00"&x"0000") AND (s_theta_tb = "00"&x"0000") AND (s_step_count_tb = x"000000") AND (s_step_count_out_tb = x"000000")) THEN
                        state               <= RESET_STATE;
                        s_reset_rl_tb       <= '1';
                        print("                                                                 ");
                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                        print_text_val("|  TESTCASE   :  ",(to_integer(signed(counter))),"                                               |");
                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                        print("   INPUTS                                                                            ");
                        print_text_val("         CMD_STEPS         =  ",(to_integer(signed(s_cmd_step_no_tb))),"    ");
                        print_text_val("         SLEW_COUNT        =  ",(to_integer(signed(s_slew_count_tb))),"     ");
                        print_text_val("         RATE_COUNT        =  ",(to_integer(signed(s_rate_count_tb))),"     ");
                        IF(s_cmd_step_no_tb(23) = '0') THEN
                                            print("         DIRECTION         =  FORWARD                                                ");
                                        ELSE
                                            print("         DIRECTION         =  REVERSE                                                ");
                                        END IF;
                        print("         CLEAR_BUFFER      =  0                                                      ");
                        print("                                                                                     ");
                        print("     OUTPUTS                                                                         ");
                        print_text_val("         DUT_THETA         =  ",(to_integer(signed(s_theta_output_tb))),"   ");
                        print_text_val("         DUT_STEP          =  ",(to_integer(signed(s_step_count_out_tb)))," ");
                        print_text_val("         TB_STEP           =  ",(to_integer(signed(s_step_count_tb))),"     ");
                        print_text_val("         TB_THETA          =  ",(to_integer(signed(s_theta_tb(g_STD_IO_WIDTH-1 DOWNTO 0))))," ");
                        print(">>>>                                                           <<<<");
                        print(">>>>     STATUS            :  PASSED                           <<<<");
                        print(">>>>     DESCRIPTION       :  TB AND DUT OUTPUTS MATCH         <<<<");
                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                    ELSE
                        state               <= RESET_STATE;
                        s_reset_rl_tb       <= '1';
                        print("                                                                 ");
                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                        print_text_val("|  TESTCASE   :  ",(to_integer(signed(counter))),"                                               |");
                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                        print("   INPUTS                                                                            ");
                        print_text_val("         CMD_STEPS         =  ",(to_integer(signed(s_cmd_step_no_tb))),"    ");
                        print_text_val("         SLEW_COUNT        =  ",(to_integer(signed(s_slew_count_tb))),"     ");
                        print_text_val("         RATE_COUNT        =  ",(to_integer(signed(s_rate_count_tb))),"     ");                                            
                        IF(s_cmd_step_no_tb(23) = '0') THEN
                                            print("         DIRECTION         =  FORWARD                                                ");
                                        ELSE
                                            print("         DIRECTION         =  REVERSE                                                ");
                                        END IF;
                        print("         CLEAR_BUFFER      =  0                                                      ");
                        print("                                                                                     ");
                        print("     OUTPUTS                                                                         ");
                        print_text_val("         DUT_THETA         =  ",(to_integer(signed(s_theta_output_tb))),"   ");
                        print_text_val("         DUT_STEP          =  ",(to_integer(signed(s_step_count_out_tb)))," ");
                        print_text_val("         TB_STEP           =  ",(to_integer(signed(s_step_count_tb))),"     ");
                        print_text_val("         TB_THETA          =  ",(to_integer(signed(s_theta_tb(g_STD_IO_WIDTH-1 DOWNTO 0))))," ");
                        print(">>>>                                                           <<<<");
                        print(">>>>     STATUS            :  FAILED                           <<<<");
                        print(">>>>     DESCRIPTION       :  TB AND DUT OUTPUTS DO NOT MATCH  <<<<");
                        print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                    END IF;
                END IF;
--------------------
-- RESET_STATE state
--------------------
			WHEN RESET_STATE =>
				state <= IDLE;
				s_reset_rl_tb       <= '0';
                IF(counter = x"016") THEN
                    state <= IDLE;
                    print("");
                    print("");
                    print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                    print("<<<<            END OF STEPPER_THETA IP SIMULATION             >>>>");
                    print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                END IF;

--------------------
-- OTHERS state
--------------------
            WHEN OTHERS =>
                state               <= IDLE;
            END CASE;
        END IF;
    END PROCESS;
--------------------------------------------------------------------------
-- Name       : COUNT_PROC
-- Description: Counter to decide the number of iterations
--------------------------------------------------------------------------
COUNT_PROC:
	PROCESS(reset_tb,sys_clk_tb)
	BEGIN
		IF(reset_tb = '0') THEN
			counter <= (OTHERS => '0');
		ELSIF RISING_EDGE (sys_clk_tb) THEN
			IF(state = START) THEN
				IF(counter < x"016") THEN
					counter <= counter + '1';
				END IF;
			END IF;
		END IF;
	END PROCESS;

--------------------------------------------------------------------------
-- Name       : TRIG_COUNT_PROC
-- Description: Counter to generate the trigger
--------------------------------------------------------------------------
TRIG_COUNT_PROC:    
    PROCESS(reset_tb,sys_clk_tb)
	BEGIN
        IF reset_tb = '0' THEN
            s_count_trig_tb <= (OTHERS => '0');
            s_trig_tb   <= '0';
        ELSIF rising_edge(sys_clk_tb) THEN
            IF(s_enable_tmp_tb = '0') THEN
                s_count_trig_tb <= (OTHERS => '0');
                s_trig_tb   <= '0';
            ELSE
                IF(s_count_trig_tb > x"063") THEN
                    s_count_trig_tb <= (OTHERS => '0');
                    s_trig_tb   <= '1';
                ELSE
                    s_count_trig_tb <= s_count_trig_tb + '1';
                    s_trig_tb   <= '0';
                END IF;
            END IF;
        END IF;
    END PROCESS;
--=================================================================================================
-- Component Instantiations
--=================================================================================================
-- Testbench stepper theta model
	PROCESS(reset_tb,sys_clk_tb)
	BEGIN
		stepper_theta_gen (reset_tmp,sys_clk_tb,s_trig_tb,s_mode_tb,s_clear_buffer_tb,s_cmd_step_no_tb,s_slew_count_tb,s_rate_count_tb,s_count_out_tb,s_step_count_tb,s_theta_tb);
	END PROCESS;
-------------------------------------------------
-- STEPPER_THETA_UUT_INST
-------------------------------------------------
STEPPER_THETA_UUT_INST:stepper_theta
PORT MAP(
    reset_i                           =>  reset_tmp,
    sys_clk_i                         =>  sys_clk_tb,
    enable_i                          =>  s_enable_tmp_tb,
    mode_i                            =>  s_mode_tb,
    clear_buffer_i                    =>  s_clear_buffer_tb,
    slew_cnt_i                        =>  s_slew_count_tb,
    rate_limit_i                      =>  s_rate_count_tb,
    cmd_step_no_i                     =>  s_cmd_step_no_tb,
    theta_output_o                    =>  s_theta_output_tb,
    step_count_o                      =>  s_step_count_out_tb
);
end behavioural;