--=================================================================================================
-- File Name                           : sinc3_filter_tb.vhd

-- Description                         : This module implements the test environment for
--                                       sinc3_filter 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
LIBRARY MODELSIM_LIB;
USE MODELSIM_LIB.UTIL.ALL;
use work.coreparameters.all;
--=================================================================================================
-- sinc3_filter_tb entity declaration
--=================================================================================================
ENTITY sinc3_filter_tb IS

END sinc3_filter_tb;

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


COMPONENT sinc3_filter IS

GENERIC(
   
    -- Specifies width of all input and output ports
    g_STD_IO_WIDTH                     : INTEGER := 18;
	
	-- Decimation factor
	g_DECIMATION_FACTOR				   : INTEGER  RANGE 2 TO 20 := 6;
    
    --Polarity
    g_BIPOLAR                          : INTEGER RANGE 0 TO 1 := 1;
    
    --Negate Output
    g_NEGATE_OUTPUT                    : INTEGER RANGE 0 TO 1 := 1
);

PORT (
--Port list
    -- system reset
    reset_i                            : IN  STD_LOGIC;

    -- ADC clock
    clk_adc_i                          : IN  STD_LOGIC;

    -- ADC data bit stream
    data_adc_i                     	   : IN  STD_LOGIC;

    --Hold input
    hold_i                     	       : IN  STD_LOGIC;

    -- Filtered data output
    data_o                             : OUT STD_LOGIC_VECTOR(g_STD_IO_WIDTH-1 DOWNTO 0);

    -- Decimated clock
    clk_dec_o                          : OUT STD_LOGIC

);
END COMPONENT;

--=================================================================================================
-- Signal declarations
--=================================================================================================
CONSTANT SYSCLK_PERIOD                       : TIME := 10 ns;
SIGNAL sys_clk_tb                            : STD_LOGIC:= '0';
SIGNAL reset_tb                              : STD_LOGIC:= '0';
SIGNAL s_count                               : STD_LOGIC_VECTOR(4 DOWNTO 0);
SIGNAL s_compare                             : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL s_data                                : STD_LOGIC_VECTOR(17 DOWNTO 0);
SIGNAL s_clk_dec                             : STD_LOGIC;
SIGNAL s_hold                                : STD_LOGIC;
SIGNAL s_one                                 : STD_LOGIC:= '1';
SIGNAL s_sys_clk_adc                         : STD_LOGIC:= '1';
SIGNAL s_output                              : STD_LOGIC:= '1';


BEGIN

--------------------------------------------------------------------------
-- Name       : RESET_GEN_PROC
-- Description: PROCESS generates the start SIGNAL for rate limiter module
--------------------------------------------------------------------------
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       : HOLD_GEN_PROC
-- Description: PROCESS generates the hold signal
--------------------------------------------------------------------------
HOLD_GEN_PROC:
    PROCESS
    BEGIN
		s_hold <= '1';
		WAIT FOR 1 us;
		s_hold <= '0';
		WAIT FOR 100 us;
		s_hold <= '1';
		WAIT FOR 1 us;
		s_hold <= '0';
		WAIT;
    END PROCESS;
	
--------------------------------------------------------------------------
-- Name       : CLOCK_GEN
-- Description: Logic generates 10 Mhz clock
--------------------------------------------------------------------------
sys_clk_tb      <= NOT sys_clk_tb AFTER (SYSCLK_PERIOD / 2.0 );
s_sys_clk_adc   <= NOT s_sys_clk_adc AFTER (SYSCLK_PERIOD );

--------------------------------------------------------------------------
-- Name       : ADC_DATA_GEN_PROC
-- Description: Logic generates data patterns similar to the ADC - 
--              a ramp signal should be generated at the output.
-------------------------------------------------------------------------- 
ADC_DATA_GEN_PROC:
PROCESS(reset_tb,sys_clk_tb)
    BEGIN
        IF(reset_tb = '0') THEN
            s_count <= (OTHERS => '0');
            s_output <= '0';
            s_compare <= (OTHERS => '0');
        ELSIF RISING_EDGE (sys_clk_tb) THEN
                IF(s_count < '0'&x"F")THEN
                    s_count <= s_count + '1';
                    IF(s_count < ('0'&s_compare(7 DOWNTO 4)))THEN
                        s_output <= '1';
                    ELSE
                        s_output <= '0';
                    END IF;
                ELSE
                    s_count <= '0'&x"0";
                    s_compare <= s_compare + '1';
                END IF;                
        END IF;
    END PROCESS;
--=================================================================================================
-- Component Instantiations
--=================================================================================================
-------------------------------------------------
-- sinc3_filter_INST
-------------------------------------------------
sinc3_filter_INST: sinc3_filter
GENERIC MAP(
    g_STD_IO_WIDTH                   =>  g_STD_IO_WIDTH,
	g_DECIMATION_FACTOR              =>  g_DECIMATION_FACTOR,
    g_BIPOLAR                        =>  g_BIPOLAR,
	g_NEGATE_OUTPUT                  =>  g_NEGATE_OUTPUT
)
port MAP(
    reset_i                         => reset_tb ,
    clk_adc_i                       => s_sys_clk_adc ,
    data_adc_i                      => s_output,
	hold_i                          => s_hold,
    data_o	                        => s_data,
    clk_dec_o                       => s_clk_dec
);

END behavioral;