--=================================================================================================
-- File Name                           : seq_controller_tb.vhd

-- Description                         : This module implements the test environment for
--                                       seq_controller block

-- 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
LIBRARY MODELSIM_LIB;
USE MODELSIM_LIB.UTIL.ALL;
USE WORK.SIM_PKG.ALL;
--=================================================================================================
-- seq_controller_tb entity declaration
--=================================================================================================
ENTITY seq_controller_tb IS

END seq_controller_tb;

--=================================================================================================
-- seq_controller_tb architecture body
--=================================================================================================
ARCHITECTURE behavioral OF seq_controller_tb IS

COMPONENT seq_controller IS
GENERIC(
    g_DEBUG                            : INTEGER := 0
);
PORT(
    reset_i                            : IN STD_LOGIC;
    sys_clk_i                          : IN STD_LOGIC;
    fault_i                            : IN STD_LOGIC;
    start_motor_i                      : IN STD_LOGIC;
    stop_motor_i                       : IN STD_LOGIC;
    fault_clear_i                      : IN STD_LOGIC;
    speed_ref_i                        : IN STD_LOGIC_VECTOR(17 DOWNTO 0);
    speed_cl_i                         : IN STD_LOGIC_VECTOR(17 DOWNTO 0);
    vq_i                               : IN STD_LOGIC_VECTOR(17 DOWNTO 0);
    max_ar_i                           : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
    calib_done_i                       : IN STD_LOGIC;
    pwm_midmatch_i                     : IN STD_LOGIC;
    foc_done_i                         : IN STD_LOGIC;
    config_reg_i                       : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
	adc_start_o                        : OUT STD_LOGIC;
	cl_status_o                        : OUT STD_LOGIC;
	en_idq_pi_o                        : OUT STD_LOGIC;
	en_pwm_o                           : OUT STD_LOGIC;
	motor_stopped_o                    : OUT STD_LOGIC;
	reset_rl_o                         : OUT STD_LOGIC;
	soft_stop_o                        : OUT STD_LOGIC;
    sensor_reset_o                     : OUT STD_LOGIC;
    state_o                            : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END COMPONENT;

--=================================================================================================
-- Signal declarations
--=================================================================================================
CONSTANT SYSCLK_PERIOD                       : TIME := 100 ns;
SIGNAL sys_clk_tb                            : STD_LOGIC:= '0';
SIGNAL reset_tb                              : STD_LOGIC:= '0';
SIGNAL s_reset_tb_pul                        : STD_LOGIC;
SIGNAL s_reset_tb_dly                        : STD_LOGIC;
SIGNAL s_reset_tb_dly1                       : STD_LOGIC;
SIGNAL s_fault_tb                            : STD_LOGIC;
SIGNAL s_normal_test_end_tb                  : STD_LOGIC;
SIGNAL s_fault_test_tb                       : STD_LOGIC;
SIGNAL s_start_motor_tb                      : STD_LOGIC;
SIGNAL s_stop_motor_tb                       : STD_LOGIC;
SIGNAL s_fault_clear_tb                      : STD_LOGIC;
SIGNAL s_calib_done_tb                       : STD_LOGIC;
SIGNAL s_foc_done_tb                         : STD_LOGIC;
SIGNAL s_adc_start_tb                        : STD_LOGIC;
SIGNAL s_cl_status_tb                        : STD_LOGIC;
SIGNAL s_en_idq_pi_tb                        : STD_LOGIC;
SIGNAL s_en_pwm_tb                           : STD_LOGIC;
SIGNAL s_motor_stopped_tb                    : STD_LOGIC;
SIGNAL s_reset_rl_tb                         : STD_LOGIC;
SIGNAL s_soft_stop_tb                        : STD_LOGIC;
SIGNAL s_soft_stop_in_tb                     : STD_LOGIC;
SIGNAL s_sensor_reset_tb                     : STD_LOGIC;
SIGNAL s_mm_tb                                  : STD_LOGIC;
SIGNAL s_mm_tb_pul                         : STD_LOGIC;
SIGNAL s_mm_tb_dly                         : STD_LOGIC;
SIGNAL s_state_trans                         : STD_LOGIC;
SIGNAL s_max_ar_tb                           : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_restart_count_tb                    : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_config_reg_tb                       : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_dut_state_tb                        : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_dut_state_tb_dly                    : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_start_motor_dut_ext                 : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_stop_motor_dut_ext                  : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_fault_tb_ext                        : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_fault_clear_tb_ext                  : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_calib_done_tb_ext                   : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_adc_start_tb_ext                    : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_cl_status_tb_ext                    : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_en_idq_pi_tb_ext                    : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_en_pwm_tb_ext                       : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_motor_stopped_tb_ext                : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_reset_ramp_tb_ext                   : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_soft_stop_tb_ext                    : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_sensor_reset_tb_ext                 : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_pwm_midmatch_tb_ext                 : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL s_foc_done_tb_ext                     : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL counter_trig                          : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL counter_trig_tmp                      : STD_LOGIC_VECTOR(12 DOWNTO 0);
SIGNAL s_speed_ref_tb                        : STD_LOGIC_VECTOR(17 DOWNTO 0);
SIGNAL s_speed_cl_tb                         : STD_LOGIC_VECTOR(17 DOWNTO 0);
SIGNAL s_vq_tb                               : STD_LOGIC_VECTOR(17 DOWNTO 0);
SIGNAL s_counter_tb                          : STD_LOGIC_VECTOR(17 DOWNTO 0);
TYPE   op_state is                          (IDLE,OFFSET_CAL_WAIT,OFFSET_CAL,SENSOR_CALIB_WAIT,SENSOR_CALIB,VBYF,CBYF,CBYF_WAIT,CLOSED_LOOP_WAIT,
                                            CLOSED_LOOP,AUTO_RESTART,AUTO_RESTART_WAIT,FAULT,STOPPING_WAIT,STOPPING,DUMMY);
SIGNAL   state                               : op_state;
--========================================================
-- File read operations
--========================================================
--NA--
--========================================================
-- File Write operations
--========================================================
--NA--
--========================================================
-- Procedure Declarations
--========================================================
--NA--
BEGIN
--========================================================
-- SIGNAL spy operations
--========================================================
--NA--
 --------------------------------------------------------------------------
-- 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 );

--------------------------------------------------------------------------
-- 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';
            s_reset_tb_dly1 <= '0';
        ELSIF(RISING_EDGE (sys_clk_tb))THEN
            s_reset_tb_dly <= reset_tb;
            s_reset_tb_dly1 <= s_reset_tb_dly;
        END IF;
    END PROCESS;
    
s_reset_tb_pul <= s_reset_tb_dly AND (not(s_reset_tb_dly1 ));

--------------------------------------------------------------------------
-- Name       : RESET_TEST_PROC
-- Description: PROCESS to check the state of all outputs at reset
--------------------------------------------------------------------------
RESET_TEST_PROC:
    PROCESS(s_reset_tb_pul,
            s_adc_start_tb,
            s_cl_status_tb,
            s_en_idq_pi_tb,
            s_en_pwm_tb,
            s_motor_stopped_tb,
            s_reset_rl_tb,
            s_soft_stop_tb,
            s_sensor_reset_tb)
    BEGIN
        IF (s_reset_tb_pul = '1') THEN
            IF((s_adc_start_tb = '0') AND (s_cl_status_tb = '0') AND (s_en_idq_pi_tb = '0') AND (s_en_pwm_tb = '0') AND
            (s_motor_stopped_tb = '1') AND (s_reset_rl_tb = '1') AND (s_soft_stop_tb = '0') AND (s_sensor_reset_tb = '0'))THEN
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                print(">>>>>>>>            SEQ_CONTROLLER IP INTEGRATED 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("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                print("                                                        ");
                print("                                                        ");
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                print(">>>>        SEQ_CONTROLLER_RESET_TEST : PASSED      <<<<");
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                print(">>>>        adc_start_o      = 0                    <<<<");
                print(">>>>        cl_status_o      = 0                    <<<<");
                print(">>>>        en_idq_pi_o      = 0                    <<<<");
                print(">>>>        en_pwm_o         = 0                    <<<<");
                print(">>>>        motor_stopped_o  = 0                    <<<<");
                print(">>>>        reset_rl_o       = 0                    <<<<");
                print(">>>>        soft_stop_o      = 0                    <<<<");
                print(">>>>        sensor_reset_o   = 0                    <<<<");
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            ELSE
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                print(">>>>>>>>            SEQ_CONTROLLER IP INTEGRATED 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("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                print("                                                        ");
                print("                                                        ");
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                print(">>>>        SEQ_CONTROLLER_RESET_TEST : FAILED      <<<<");
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                print(">>>>        adc_start_o      /= 0                   <<<<");
                print(">>>>        cl_status_o      /= 0                   <<<<");
                print(">>>>        en_idq_pi_o      /= 0                   <<<<");
                print(">>>>        en_pwm_o         /= 0                   <<<<");
                print(">>>>        motor_stopped_o  /= 0                   <<<<");
                print(">>>>        reset_rl_o       /= 0                   <<<<");
                print(">>>>        soft_stop_o      /= 0                   <<<<");
                print(">>>>        sensor_reset_o   /= 0                   <<<<");
                print("<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            END IF;
        END IF;
    END PROCESS;
--------------------------------------------------------------------------
-- Name       : FSM_SEQ_CONTROLLER_TB_PROC
-- Description: FSM implements seq_controller IP testbench controller operation
--------------------------------------------------------------------------
FSM_SEQ_CONTROLLER_TB_PROC:
    PROCESS(sys_clk_tb,s_reset_tb_dly1)
    BEGIN
        IF(s_reset_tb_dly1 = '0') THEN
            state                       <= IDLE;
            s_speed_cl_tb               <= (OTHERS => '0');
            s_speed_ref_tb              <= (OTHERS => '0');
            s_vq_tb                     <= (OTHERS => '0');
            s_config_reg_tb             <= (OTHERS => '0');
            counter_trig_tmp            <= (OTHERS => '0');
            counter_trig                <= (OTHERS => '0');
            s_fault_clear_tb            <= '0';
            s_calib_done_tb             <= '0';
            s_start_motor_tb            <= '0';
            s_stop_motor_tb             <= '0';
            s_fault_tb                  <= '0';
             s_state_trans              <= '0';
            s_normal_test_end_tb        <= '0';
            s_fault_test_tb             <= '0';
            s_soft_stop_in_tb           <= '0';
            s_foc_done_tb               <= '0';
            s_max_ar_tb                 <= (OTHERS => '0');
        ELSIF (RISING_EDGE(sys_clk_tb)) THEN
            CASE(state)IS
--------------------
-- IDLE state
--------------------
            WHEN IDLE =>
                s_fault_clear_tb        <= '0';
                s_state_trans           <= '0';
                IF(s_normal_test_end_tb = '0') THEN
                    s_start_motor_tb    <= '1';
                    s_stop_motor_tb     <= '0';
                    s_max_ar_tb         <= x"5";
                    state               <= OFFSET_CAL_WAIT;
                    s_state_trans       <= '1';
                ELSIF(s_fault_test_tb = '1') THEN
                    s_start_motor_tb    <= '1';
                    s_fault_tb          <= '1';
                    s_fault_test_tb     <= '0';
                    state               <= FAULT;
                     s_state_trans      <= '1';
                ELSE
                    s_start_motor_tb    <= '1';
                    s_config_reg_tb     <= x"B";
                    s_stop_motor_tb     <= '0';
                    state               <=  OFFSET_CAL;
                     s_state_trans      <= '1';
                END IF;
--------------------
-- OFFSET_CAL_WAIT state
--------------------
            WHEN OFFSET_CAL_WAIT =>
                state                  <= OFFSET_CAL;
                s_state_trans          <= '0';
--------------------
-- OFFSET_CAL state
--------------------
            WHEN OFFSET_CAL =>
                IF(counter_trig < x"2") THEN
                    IF(counter_trig_tmp = '1'&x"FFF")THEN
                        counter_trig_tmp <= (OTHERS => '0');
                        counter_trig     <= counter_trig + '1';
                    ELSE
                        counter_trig_tmp <= counter_trig_tmp + '1';
                    END IF;
                ELSE
                    s_calib_done_tb <= '1';
                    IF(s_config_reg_tb <= x"B") THEN
                        state <= STOPPING_WAIT;
                         s_state_trans   <= '1';
                    ELSE
                        state    <= SENSOR_CALIB_WAIT;
                         s_state_trans   <= '1';
                        s_config_reg_tb  <= x"2";
                        counter_trig     <= (OTHERS => '0');
                        counter_trig_tmp <= (OTHERS => '0');
                    END IF;
                END IF;
--------------------
-- SENSOR_CALIB_WAIT state
--------------------
            WHEN SENSOR_CALIB_WAIT =>
                s_state_trans            <= '0';
                state                    <= SENSOR_CALIB;
--------------------
-- SENSOR_CALIB state
--------------------
            WHEN SENSOR_CALIB =>
                IF(counter_trig < x"4") THEN
                    IF(counter_trig_tmp = '1'&x"FFF")THEN
                        counter_trig_tmp <= (OTHERS => '0');
                        counter_trig     <= counter_trig + '1';

                    ELSE
                        counter_trig_tmp <= counter_trig_tmp + '1';
                    END IF;
                ELSE
                    state                <= VBYF ;
                     s_state_trans       <= '1';
                    s_config_reg_tb      <= x"2"; --v/f
                END IF;
--------------------
-- VBYF state
--------------------
            WHEN VBYF  =>
                s_state_trans            <= '0';
                state <= CLOSED_LOOP_WAIT;
                s_speed_ref_tb           <= "00"&x"2050";
                s_speed_cl_tb            <= "00"&x"2000";
--------------------
-- CLOSED_LOOP_WAIT state
--------------------
            WHEN CLOSED_LOOP_WAIT =>
                s_state_trans            <= '0';
                state                    <= CLOSED_LOOP;
--------------------
-- CLOSED_LOOP state
--------------------
            WHEN CLOSED_LOOP =>
                s_state_trans            <= '1';
                s_config_reg_tb          <= x"5";
                s_vq_tb                  <= "00"&x"0400";
                s_speed_ref_tb           <= "00"&x"2050";
                state                    <= AUTO_RESTART_WAIT;
--------------------
-- AUTO_RESTART_WAIT state
--------------------
            WHEN AUTO_RESTART_WAIT =>
                s_state_trans            <= '0';
                state                    <= AUTO_RESTART;
--------------------
-- AUTO_RESTART state
--------------------
            WHEN AUTO_RESTART =>
                IF(s_restart_count_tb = s_max_ar_tb) THEN
                   state                 <= FAULT;
                    s_state_trans        <= '1';
                ELSE
                    state <= CBYF_WAIT;
                     s_state_trans       <= '1';
                    s_speed_ref_tb       <= "00"&x"0000";
                END IF;
--------------------
-- CBYF_WAIT state
--------------------
            WHEN CBYF_WAIT =>
                s_state_trans            <= '0';
                state                    <= CBYF;
                s_speed_ref_tb           <= "00"&x"2050";
--------------------
-- CBYF state
--------------------
            WHEN CBYF =>
                s_state_trans            <= '1';
                s_speed_ref_tb           <= "00"&x"2050";
                s_speed_cl_tb            <= "00"&x"2000";
                state                    <= CLOSED_LOOP;
--------------------
-- FAULT state
--------------------
            WHEN FAULT  =>
                s_state_trans            <= '0';
                IF(s_restart_count_tb = s_max_ar_tb) THEN
                    s_fault_clear_tb     <= '1';
                    s_normal_test_end_tb <= '1';
                    s_fault_test_tb      <= '1';
                    s_state_trans        <= '1';
                    state                <= IDLE;
                ELSE
                    s_fault_tb           <= '0';
                    s_fault_test_tb      <= '0';
                    s_start_motor_tb     <= '0';
                    s_state_trans        <= '1';
                    state                <= IDLE;
                END IF;
--------------------
-- STOPPING_WAIT state
--------------------
            WHEN STOPPING_WAIT  =>
                    s_state_trans       <= '0';
                IF(s_dut_state_tb = x"5") THEN
                    s_soft_stop_in_tb   <= '1';
                    s_stop_motor_tb     <= '1';
                    s_speed_ref_tb      <= (OTHERS => '0');
                ELSIF(s_dut_state_tb = x"7") THEN
                    s_foc_done_tb       <= '1';
                    s_speed_ref_tb      <= (OTHERS => '0');
                    state               <= STOPPING;
                    s_state_trans       <= '1';                      
                ELSE                    
                    state               <= STOPPING_WAIT;                         
                END IF;
--------------------
-- STOPPING state
--------------------
            WHEN STOPPING =>
                s_state_trans           <= '1';
                s_foc_done_tb           <= '0';
                s_stop_motor_tb         <= '0';                
                state                   <= IDLE;
--------------------
-- DEFAULT state
--------------------
            WHEN OTHERS =>
                state                   <= IDLE;
            END CASE;
        END IF;
    END PROCESS;
--------------------------------------------------------------------------
-- Name       : AUTO_RESTART_COUNT_PROC
-- Description: Counter for auto restart
--------------------------------------------------------------------------
AUTO_RESTART_COUNT_PROC:
    PROCESS(reset_tb,sys_clk_tb)
    BEGIN
        IF(reset_tb = '0') THEN
            s_restart_count_tb   <= (OTHERS => '0');
        ELSIF RISING_EDGE (sys_clk_tb) THEN
            IF(s_normal_test_end_tb = '0') THEN
                IF(state  = AUTO_RESTART) THEN
                    IF(s_restart_count_tb < s_max_ar_tb) THEN
                        s_restart_count_tb  <= s_restart_count_tb + '1';
                    END IF;
                END IF;
            ELSE
                    s_restart_count_tb   <= (OTHERS => '0');
            END IF;    
        END IF;
    END PROCESS;
--------------------------------------------------------------------------
-- Name       : MIDMATCH_GEN_PROC
-- Description: Counter to generate pwm midmatch 
--------------------------------------------------------------------------
MIDMATCH_GEN_PROC:
PROCESS(reset_tb,sys_clk_tb)
BEGIN
    IF(reset_tb = '0') THEN
        s_counter_tb      <= (OTHERS => '0');
        s_mm_tb              <= '0';
        s_mm_tb_dly     <= '0';
    ELSIF RISING_EDGE(sys_clk_tb) THEN
        IF(s_en_pwm_tb = '1') THEN
            IF(s_mm_tb = '0') THEN
                IF(s_counter_tb < "00"&x"FFFF" ) THEN
                    s_counter_tb <= s_counter_tb + '1';
                ELSE
                    s_mm_tb  <= '1';
                END IF;
            ELSE
                IF(s_counter_tb > "00"&x"0000") THEN
                    s_counter_tb <= s_counter_tb - '1';
                ELSE
                    s_mm_tb <= '0';
                END IF;
            END IF;
        ELSE
            s_counter_tb <= (OTHERS => '0');
            s_mm_tb         <= '0';
        END IF;
        s_mm_tb_dly  <= s_mm_tb;
    END IF;
END PROCESS;
s_mm_tb_pul           <= s_mm_tb AND (NOT(s_mm_tb_dly));

--------------------------------------------------------------------------
-- Name       : RESIZE_PROC
-- Description: Resize testbench signals
--------------------------------------------------------------------------
s_start_motor_dut_ext   <= "000"& s_start_motor_tb;
s_stop_motor_dut_ext    <= "000"& s_stop_motor_tb;
s_fault_tb_ext          <= "000"& s_fault_tb;
s_fault_clear_tb_ext    <= "000"& s_fault_clear_tb;
s_calib_done_tb_ext     <= "000"& s_calib_done_tb;
s_adc_start_tb_ext      <= "000"& s_adc_start_tb;
s_cl_status_tb_ext      <= "000"& s_cl_status_tb;
s_en_idq_pi_tb_ext      <= "000"& s_en_idq_pi_tb;
s_en_pwm_tb_ext         <= "000"& s_en_pwm_tb;
s_motor_stopped_tb_ext  <= "000"& s_motor_stopped_tb;
s_reset_ramp_tb_ext     <= "000"& s_reset_rl_tb;
s_soft_stop_tb_ext      <= "000"& s_soft_stop_in_tb;
s_sensor_reset_tb_ext   <= "000"& s_sensor_reset_tb;
s_pwm_midmatch_tb_ext   <= "000"& s_mm_tb_pul;
s_foc_done_tb_ext       <= "000"& s_foc_done_tb;

--------------------------------------------------------------------------
-- Name       : TB_DELAY_PROC
-- Description: Process to delay state
--------------------------------------------------------------------------
TB_DELAY_PROC:
    PROCESS(reset_tb,sys_clk_tb)
    BEGIN
        IF(reset_tb = '0') THEN
            s_dut_state_tb_dly     <= (OTHERS => '0');
        ELSIF RISING_EDGE(sys_clk_tb) THEN
            s_dut_state_tb_dly     <= s_dut_state_tb;
        END IF;
    END PROCESS;
--------------------------------------------------------------------------
-- Name       : DISPLAY_RESULTS_PROC
-- Description: Process to display output results
--------------------------------------------------------------------------
DISPLAY_RESULTS_PROC:
    PROCESS(sys_clk_tb)
    BEGIN
        IF(s_state_trans = '1') THEN
            CASE(s_dut_state_tb) IS
                WHEN OTHERS =>
                    print("<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                    CASE(s_dut_state_tb_dly) IS
                        WHEN x"0" => print("PRESENT_STATE = IDLE");
                        WHEN x"1" => print("PRESENT_STATE = OFFSET_CALC");
                        WHEN x"2" => print("PRESENT_STATE = SENSOR_CALIB");
                        WHEN x"3" => print("PRESENT_STATE = VBYF");
                        WHEN x"4" => print("PRESENT_STATE = CBYF");
                        WHEN x"5" => print("PRESENT_STATE = CLOSED_LOOP");
                        WHEN x"6" => print("PRESENT_STATE = AUTO_RESTART");
                        WHEN x"7" => print("PRESENT_STATE = STOPPING");
                        WHEN x"8" => print("PRESENT_STATE = FAULT");
                        WHEN OTHERS => print("PRESENT_STATE = FAULT");
                    END CASE;
                    print("INPUTS");
                    print_text_val("    start_motor_i      =",to_integer(signed(s_start_motor_dut_ext)),"");
                    print_text_val("    start_motor_i      =",to_integer(signed(s_stop_motor_dut_ext)),"");
                    print_text_val("    fault_i            =",to_integer(signed(s_fault_tb_ext)),"");
                    print_text_val("    fault_clear_i      =",to_integer(signed(s_fault_clear_tb_ext)),"");
                    print_text_val("    calib_done_i       =",to_integer(signed(s_calib_done_tb_ext)),"");
                    print_text_val("    speed_ref_i        =",to_integer(signed(s_speed_ref_tb)),"");
                    print_text_val("    speed_cl_i         =",to_integer(signed(s_speed_cl_tb)),"");
                    print_text_val("    vq_i               =",to_integer(signed(s_vq_tb)),"");
                    print_text_val("    max_ar_i           =",to_integer(signed(s_max_ar_tb)),"");
                    print_text_val("    pwm_midmatch_i     =",to_integer(signed(s_pwm_midmatch_tb_ext)),"");
                    print_text_val("    foc_done_i         =",to_integer(signed(s_foc_done_tb_ext)),"");
                    print_text_val("    config_reg_i       =",to_integer(signed(s_config_reg_tb)),"");
                    print("INTERMEDIATE SIGNALS");
                    print_text_val("    adc_trigger_count  =",to_integer(signed(counter_trig_tmp)),"");
                    print_text_val("    sensor_calib_count =",to_integer(signed(counter_trig)),"");
                    print_text_val("    restart_count      =",to_integer(signed(s_restart_count_tb)),"");
                    print("OUTPUTS");
                    print_text_val("    adc_start_o        =",to_integer(signed(s_adc_start_tb_ext    )),"");
                    print_text_val("    cl_status_o        =",to_integer(signed(s_cl_status_tb_ext    )),"");
                    print_text_val("    en_idqpi_o         =",to_integer(signed(s_en_idq_pi_tb_ext    )),"");
                    print_text_val("    en_pwm_o           =",to_integer(signed(s_en_pwm_tb_ext       )),"");
                    print_text_val("    motor_stopped_o    =",to_integer(signed(s_motor_stopped_tb_ext)),"");
                    print_text_val("    reset_rl_o       =",to_integer(signed(s_reset_ramp_tb_ext   )),"");
                    print_text_val("    soft_stop_o        =",to_integer(signed(s_soft_stop_tb_ext    )),"");
                    print_text_val("    sensor_reset_o     =",to_integer(signed(s_sensor_reset_tb_ext )),"");
                    CASE(s_dut_state_tb) IS
                        WHEN x"0" => print("NEXT_STATE = IDLE");
                        WHEN x"1" => print("NEXT_STATE = OFFSET_CALC");
                        WHEN x"2" => print("NEXT_STATE = SENSOR_CALIB");
                        WHEN x"3" => print("NEXT_STATE = VBYF");
                        WHEN x"4" => print("NEXT_STATE = CBYF");
                        WHEN x"5" => print("NEXT_STATE = CLOSED_LOOP");
                        WHEN x"6" => print("NEXT_STATE = AUTO_RESTART");
                        WHEN x"7" => print("NEXT_STATE = STOPPING");
                        WHEN x"8" => print("NEXT_STATE = FAULT");
                        WHEN OTHERS => print("NEXT_STATE = FAULT");
                    END CASE;
                    print("<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            END CASE;
        END IF;   
    END PROCESS;
--=================================================================================================
-- Component Instantiations
--=================================================================================================
-------------------------------------------------
-- SEQ_CONTROLLER_UUT_INST
-------------------------------------------------
SEQ_CONTROLLER_UUT_INST: seq_controller
GENERIC MAP(g_DEBUG      => 1)
PORT MAP(
    reset_i                            => reset_tb,
    sys_clk_i                          => sys_clk_tb,
    fault_i                            => s_fault_tb,
    start_motor_i                      => s_start_motor_tb,
    stop_motor_i                       => s_stop_motor_tb,
    fault_clear_i                      => s_fault_clear_tb,
    speed_ref_i                        => s_speed_ref_tb,
    speed_cl_i                         => s_speed_cl_tb,
    vq_i                               => s_vq_tb,
    max_ar_i                           => s_max_ar_tb,
    calib_done_i                       => s_calib_done_tb,
    pwm_midmatch_i                     => s_mm_tb_pul,
    foc_done_i                         => s_foc_done_tb,
    config_reg_i                       => s_config_reg_tb,
	adc_start_o                        => s_adc_start_tb,
	cl_status_o                        => s_cl_status_tb,
	en_idq_pi_o                        => s_en_idq_pi_tb,
	en_pwm_o                           => s_en_pwm_tb,
	motor_stopped_o                    => s_motor_stopped_tb,
	reset_rl_o                         => s_reset_rl_tb,
	soft_stop_o                        => s_soft_stop_tb,
    sensor_reset_o                     => s_sensor_reset_tb,
    state_o                            => s_dut_state_tb
);
END behavioral;