-------------------------------------------------------------
-- MSS copyright 2014
-- Filename:  TB_FFT_CONTROL2.VHD
-- Authors: 
--		Alain Zarembowitch / MSS
-- Version: Rev 1
-- Last modified: 4/22/14
-- Inheritance: 	N/A
--
-- description:  import a stimulus file consisting of complex baseband waveform samples (as 
-- created by Matlab for example) and feed it to the FFT.
--
-- The Matlab .m program to generate the stimulus file is siggen_psk2.m in directory /sim
--
-- Usage:
-- 1. run the .m Matlab program to generate the baseband waveform
-- 2. copy the resulting stimulus input.txt file to the /sim directory
---------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
ENTITY tb_fft_control2 IS
END tb_fft_control2;
 
ARCHITECTURE behavior OF tb_fft_control2 IS 
 
--------------------------------------------------------
--      COMPONENTS
--------------------------------------------------------
 
    COMPONENT FFT_CONTROL2
    PORT(
         CLK : IN  std_logic;
         DATA_I_IN : IN  std_logic_vector(17 downto 0);
         DATA_Q_IN : IN  std_logic_vector(17 downto 0);
         FFT_INDEX_IN : IN  std_logic_vector(10 downto 0);
         SAMPLE_CLK_IN : IN  std_logic;
         FWD_INVN : IN  std_logic;
         FFT_START : IN  std_logic;
         IO_ENABLED : OUT  std_logic;
         FFT_SCALE : IN  std_logic_vector(11 downto 0);
         FFT_BYPASS : IN  std_logic;
         DATA_I_OUT : OUT  std_logic_vector(17 downto 0);
         DATA_Q_OUT : OUT  std_logic_vector(17 downto 0);
         FFT_INDEX_OUT : IN  std_logic_vector(10 downto 0);
         SAMPLE_CLK_OUT : OUT  std_logic;
         SAMPLE_CLK_OUT_REQ : IN  std_logic;
         OVERFLOW : OUT  std_logic_vector(5 downto 0)
        );
    END COMPONENT;
    
	COMPONENT INFILE2SIM
	 Generic (
		FILENAME: string
	 );
	PORT(
		CLK : IN std_logic;
		SAMPLE_CLK_IN : IN std_logic;          
		DATA1 : OUT std_logic_vector(11 downto 0);
		DATA2 : OUT std_logic_vector(11 downto 0);
		DATA3 : OUT std_logic_vector(11 downto 0)
		);
	END COMPONENT;

--------------------------------------------------------
--     SIGNALS
--------------------------------------------------------
   signal CLK : std_logic := '0';
   constant CLK_period : time := 10 ns;
	
	signal STATE: integer := 0;

   signal INFILE_DATA_I : std_logic_vector(11 downto 0) := (others => '0');
   signal INFILE_DATA_Q : std_logic_vector(11 downto 0) := (others => '0');
	signal INFILE_SAMPLE_CLK_IN : std_logic := '0';
	
   signal DATA_I_IN : std_logic_vector(17 downto 0) := (others => '0');
   signal DATA_Q_IN : std_logic_vector(17 downto 0) := (others => '0');
   signal FFT_INDEX_IN : std_logic_vector(10 downto 0) := (others => '0');
   signal SAMPLE_CLK_IN : std_logic := '0';
   signal FWD_INVN : std_logic := '0';
   signal FFT_START : std_logic := '0';
   signal FFT_SCALE : std_logic_vector(11 downto 0) := (others => '0');
   signal FFT_BYPASS : std_logic := '0';
   signal FFT_INDEX_OUT : std_logic_vector(10 downto 0) := (others => '0');
   signal SAMPLE_CLK_OUT_REQ : std_logic := '0';

 	--Outputs
   signal IO_ENABLED : std_logic;
   signal DATA_I_OUT : std_logic_vector(17 downto 0);
   signal DATA_Q_OUT : std_logic_vector(17 downto 0);
   signal SAMPLE_CLK_OUT : std_logic;
   signal OVERFLOW : std_logic_vector(5 downto 0);

 
--------------------------------------------------------
--      IMPLEMENTATION
--------------------------------------------------------
BEGIN
   -- Clock process definitions
   CLK_process :process
   begin
		CLK <= '0';
		wait for CLK_period/2;
		CLK <= '1';
		wait for CLK_period/2;
   end process;
  
 	-- read stimulus file
 	-- Baseband input 2*12-bit precision, signed decimal. Range -2048 to +2047
	Inst_INFILE2SIM: INFILE2SIM 
	generic map(
		FILENAME => "sim\input.txt"
	)
	PORT MAP(
		CLK => CLK,
		SAMPLE_CLK_IN => INFILE_SAMPLE_CLK_IN,
		DATA1 => INFILE_DATA_I,
		DATA2 => INFILE_DATA_Q,
		DATA3 => open
	);
	
	-- state machine
	STATE_GEN_001: process(CLK)
	begin
		if rising_edge(CLK) then
			if(STATE = 0) and (IO_ENABLED = '1') then
				-- ready to start a new FFT
				STATE <= 1;
				FFT_INDEX_IN <= (others => '0');
				INFILE_SAMPLE_CLK_IN <= '1';
			elsif(STATE = 1) and ((not FFT_INDEX_IN) = 0) then
				-- this is the last sample
				INFILE_SAMPLE_CLK_IN <= '0';
				-- start the FFT
				FFT_START <= '1';
				STATE <= 2;
			elsif(STATE = 1) then
				FFT_INDEX_IN <= FFT_INDEX_IN + 1;
			elsif(STATE = 2) then
				FFT_START <= '0';
				STATE <= 3;
			end if;
		end if;
	end process;

	DATA_I_IN <= INFILE_DATA_I & "000000";
	DATA_Q_IN <= INFILE_DATA_Q & "000000";
	
	-- Instantiate the Unit Under Test (UUT)
   uut: FFT_CONTROL2 PORT MAP (
          CLK => CLK,
          DATA_I_IN => DATA_I_IN,
          DATA_Q_IN => DATA_Q_IN,
          FFT_INDEX_IN => FFT_INDEX_IN,
          SAMPLE_CLK_IN => SAMPLE_CLK_IN,
          FWD_INVN => '1',
          FFT_START => FFT_START,
          IO_ENABLED => IO_ENABLED,
          FFT_SCALE => FFT_SCALE,
          FFT_BYPASS => '0',
          DATA_I_OUT => DATA_I_OUT,
          DATA_Q_OUT => DATA_Q_OUT,
          FFT_INDEX_OUT => FFT_INDEX_OUT,
          SAMPLE_CLK_OUT => SAMPLE_CLK_OUT,
          SAMPLE_CLK_OUT_REQ => SAMPLE_CLK_OUT_REQ,
          OVERFLOW => OVERFLOW
        );

 

END;
