--------------------------------------------------------------------------------
-- Company: <Name>
--
-- File: MC_System_top_tb.vhd
-- File history:
--      <Revision number>: <Date>: <Comments>
--      <Revision number>: <Date>: <Comments>
--      <Revision number>: <Date>: <Comments>
--
-- Description: 
--
-- <Description here>
--
-- Targeted device: <Family::SmartFusion2> <Die::M2S010> <Package::484 FBGA>
-- Author: <Name>
--
--------------------------------------------------------------------------------


library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.std_logic_textio.all;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;

entity MC_System_top_tb is
end MC_System_top_tb;

architecture behavioral of MC_System_top_tb is

    constant SYSCLK_PERIOD : time := 100 ns; -- 10MHZ

    signal SYSCLK : std_logic := '0';
    signal NSYSRESET : std_logic := '0';
    signal command_reg_tb : std_logic_vector(15 downto 0);
    signal adc_sck_o_tb  :std_logic;
    signal adc_cs_o_tb  :std_logic;
    signal adc_sdo_o_tb:std_logic;
    signal counter_tb : std_logic_vector(4 downto 0);
    signal adc_sdi_tb : std_logic;
    signal data_reg_tb : std_logic_vector(15 downto 0);
    signal slave_sel_cnt : std_logic_vector(2 downto 0);
    signal adc_cs_o_tb_dly: std_logic;

    component MC_System_top
        -- ports
        port( 
            -- Inputs
            A0_ADC_SDI_I : in std_logic;
            A1_ADC_SDI_I : in std_logic;
            USB_ULPI_DIR : in std_logic;
            USB_ULPI_NXT : in std_logic;
            USB_ULPI_XCLK : in std_logic;
            DEVRST_N : in std_logic;
           -- A0_FAULT_CLR_I : in std_logic;

            -- Outputs
            GPIO_0_M2F : out std_logic;
            A0_PWM_UL_O : out std_logic;
            A0_PWM_UH_O : out std_logic;
            A0_PWM_WH_O : out std_logic;
            A0_PWM_WL_O : out std_logic;
            A0_ADC_SCK_O : out std_logic;
            A0_PWM_VL_O : out std_logic;
            A0_PWM_VH_O : out std_logic;
            A0_ADC_CS_O : out std_logic;
            A0_ADC_SDO_O : out std_logic;
            A1_PWM_UL_O : out std_logic;
            A1_PWM_UH_O : out std_logic;
            A1_PWM_WH_O : out std_logic;
            A1_PWM_WL_O : out std_logic;
            A1_ADC_SCK_O : out std_logic;
            A1_PWM_VL_O : out std_logic;
            A1_PWM_VH_O : out std_logic;
            A1_ADC_CS_O : out std_logic;
            A1_ADC_SDO_O : out std_logic;
            A0_RUNNING_LED : out std_logic;
            USB_ULPI_STP : out std_logic;

            -- Inouts
            USB_ULPI_DATA : inout std_logic_vector(7 downto 0)

        );
    end component;

begin

    process
        variable vhdl_initial : BOOLEAN := TRUE;

    begin
        if ( vhdl_initial ) then
            -- Assert Reset
            NSYSRESET <= '0';
            wait for ( SYSCLK_PERIOD * 10 );
            
            NSYSRESET <= '1';
            wait;
        end if;
    end process;

    -- Clock Driver
    SYSCLK <= not SYSCLK after (SYSCLK_PERIOD / 2.0 );

    -- Instantiate Unit Under Test:  MC_System_top
    MC_System_top_0 : MC_System_top
        -- port map
        port map( 
            -- Inputs
            A0_ADC_SDI_I   => adc_sdi_tb,
            A1_ADC_SDI_I   => adc_sdi_tb,
            USB_ULPI_DIR   => '0',
            USB_ULPI_NXT   => '0',
            USB_ULPI_XCLK  => SYSCLK,
            DEVRST_N       => NSYSRESET,
           -- A0_FAULT_CLR_I => '0',

            -- Outputs
            GPIO_0_M2F     => open,
            A0_PWM_UL_O    => open,
            A0_PWM_UH_O    => open,
            A0_PWM_WH_O    => open,
            A0_PWM_WL_O    => open,
            A0_ADC_SCK_O   => adc_sck_o_tb,
            A0_PWM_VL_O    => open,
            A0_PWM_VH_O    => open,
            A0_ADC_CS_O    => adc_cs_o_tb,
            A0_ADC_SDO_O   => adc_sdo_o_tb,
            A1_PWM_UL_O    => open,
            A1_PWM_UH_O    => open,
            A1_PWM_WH_O    => open,
            A1_PWM_WL_O    => open,
            A1_ADC_SCK_O   => open,
            A1_PWM_VL_O    => open,
            A1_PWM_VH_O    => open,
            A1_ADC_CS_O    => open,
            A1_ADC_SDO_O   => open,
            A0_RUNNING_LED => open,
            USB_ULPI_STP   => open,
            USB_ULPI_DATA  => open

        );

        
        
        
            
   
  PROCESS(NSYSRESET,adc_sck_o_tb)
       BEGIN
        IF NSYSRESET = '0' THEN
           command_reg_tb <= (others => '0');
           counter_tb <= (others => '0');
           data_reg_tb  <= x"1FFF";
           adc_sdi_tb <= '0';
           slave_sel_cnt  <= (others => '0');
           adc_cs_o_tb_dly <= '0';
         
        ELSIF falling_edge(adc_sck_o_tb) THEN			
        adc_cs_o_tb_dly <= adc_cs_o_tb;
            IF(adc_cs_o_tb = '0') THEN
                if(counter_tb < "01"&x"0") then
                command_reg_tb(15 downto 0) <= command_reg_tb(14 downto 0) & adc_sdo_o_tb ;
                data_reg_tb (15 downto 1) <= data_reg_tb(14 downto 0);
                data_reg_tb(0) <= '0';
                counter_tb <= counter_tb + "00001";                
                else
                    counter_tb <= (others => '0');
                    END IF;
               if(slave_sel_cnt < 4) then 
                    if (adc_cs_o_tb_dly = '1') then
             		slave_sel_cnt <= slave_sel_cnt + 1;
               -- else
				    -- slave_sel_cnt <= (others => '0');
                end if;
                else
                    slave_sel_cnt <= (others => '0');
             end if;    
               
            else
				case slave_sel_cnt is
                when "000" =>
                   data_reg_tb <= x"0FFF";
                when "001"  =>
                   data_reg_tb <= x"1AFF";
                when "010" =>
                   data_reg_tb <= x"2802";
                when "011" =>
                   data_reg_tb <= x"3003";
                when others =>
                   data_reg_tb <= x"0FFF";
                end case;

                counter_tb <= (others => '0');
            
            END IF;
            adc_sdi_tb <= data_reg_tb(15);
        END IF;
      END PROCESS;

end behavioral;

