--------------------------------------------------------------------------------
-- Company: 
-- Engineer:
--
-- Create Date:   17:50:08 03/12/2016
-- Design Name:   
-- Module Name:   C:/Xilinx/Projects/nexys3_phy/message_parser_tb.vhd
-- Project Name:  nexys3_phy
-- Target Device:  
-- Tool versions:  
-- Description:   
-- 
-- VHDL Test Bench Created by ISE for module: message_parser
-- 
-- Dependencies:
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes: 
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test.  Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation 
-- simulation model.
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
 
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
 
entity message_parser_tb IS
end message_parser_tb;
 
 
architecture behavior of message_parser_tb is
 
	component command_processor
	port (
		clk									: in  std_logic;
		command_available					: in  std_logic;
		command_contents					: in  std_logic_vector(31 downto 0);
		command_reply_available			: out std_logic;
		command_reply_contents			: out std_logic_vector(31 downto 0);
		firmware_version					: in  std_logic_vector(15 downto 0);
		GPIO_LEDs							: out std_logic_vector(5 downto 0);
		GPIO_Switches						: in  std_logic_vector(7 downto 0);
		GPIO_Buttons						: in  std_logic_vector(4 downto 0);
		Disp_seg								: out std_logic_vector(7 downto 0);
		Disp_an								: out std_logic_vector(3 downto 0)
	);
	end component;
	
	
   signal clk											: std_logic := '0';
   signal GPIO_Switches								: std_logic_vector(7 downto 0) := "10000001";
   signal GPIO_Buttons								: std_logic_vector(4 downto 0) := (others => '0');
	
   signal GPIO_LEDs									: std_logic_vector(5 downto 0);
   signal Disp_seg									: std_logic_vector(7 downto 0);
   signal Disp_an										: std_logic_vector(3 downto 0);
	
	
	component message_command_glue is
	port (
		tx_clk									: in  std_logic;
		clk										: in  std_logic;
		message_command_available			: in  std_logic;
		message_command_contents			: in  std_logic_vector(31 downto 0);
		message_command_reply_available	: out std_logic;
		message_command_reply_contents	: out std_logic_vector(31 downto 0);
		command_available						: out std_logic;
		command_contents						: out std_logic_vector(31 downto 0);
		command_reply_available				: in  std_logic;
		command_reply_contents				: in  std_logic_vector(31 downto 0)
	);
	end component;
	
	signal message_command_available				: std_logic;
	signal message_command_contents				: std_logic_vector(31 downto 0);
	signal message_command_reply_available		: std_logic;
	signal message_command_reply_contents		: std_logic_vector(31 downto 0);
	
	
	component command_to_message_in is
	port (
		tx_clk								: in  std_logic;
		new_command							: in  std_logic;
		command								: in  std_logic_vector(63 downto 0);
		message_fifo_in_wr_en			: out std_logic;
		message_fifo_in_din				: out std_logic_vector(8 downto 0)
	);
	end component;
 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
	component message_parser
	port (
		reset_enet_counters				: out std_logic;
		tx_clk								: in  std_logic;
		message_fifo_in_wr_en			: in  std_logic;
		message_fifo_in_din				: in  std_logic_vector(8 downto 0);
		message_fifo_in_full				: out std_logic;
		message_fifo_out_rd_en			: in  std_logic;
		message_fifo_out_dout			: out std_logic_vector(63 downto 0);
		message_fifo_out_empty			: out std_logic;
		command_available					: out std_logic;
		command_contents					: out std_logic_vector(31 downto 0);
		command_reply_available			: in  std_logic;
		command_reply_contents			: in  std_logic_vector(31 downto 0);
		num_good_pkts_counter			: in  std_logic_vector(31 downto 0);
		num_bad_pkts_counter				: in  std_logic_vector(31 downto 0);
		firmware_version					: in  std_logic_vector(15 downto 0);
		send_reply							: out std_logic;
		reply_busy							: in  std_logic;
		phy_cmd_available					: out std_logic;
		phy_command							: out std_logic_vector(31 downto 0);
		phy_cmd_busy						: in  std_logic;
		phy_reply							: in  std_logic_vector(31 downto 0);
		rx_data_error						: in  std_logic;
		tx_data_error						: out std_logic;
		unused_inputs						: in  std_logic_vector(3 downto 0)
	);
	end component;
    

   --Inputs
   signal tx_clk										: std_logic := '0';
   signal message_fifo_in_wr_en					: std_logic := '0';
   signal message_fifo_in_din						: std_logic_vector(8 downto 0) := (others => '0');
   signal message_fifo_out_rd_en					: std_logic := '0';
   signal command_reply_available				: std_logic := '0';
   signal command_reply_contents					: std_logic_vector(31 downto 0) := (others => '0');
   signal num_good_pkts_counter					: std_logic_vector(31 downto 0) := (others => '0');
   signal num_bad_pkts_counter					: std_logic_vector(31 downto 0) := (others => '0');
   signal firmware_version							: std_logic_vector(15 downto 0) := (others => '0');
   signal reply_busy									: std_logic := '0';
   signal phy_cmd_busy								: std_logic := '0';
   signal phy_reply									: std_logic_vector(31 downto 0) := (others => '0');
   signal rx_data_error								: std_logic := '0';
   signal unused_inputs								: std_logic_vector(3 downto 0) := (others => '0');

 	--Outputs
   signal reset_enet_counters						: std_logic;
   signal message_fifo_in_full					: std_logic;
   signal message_fifo_out_dout					: std_logic_vector(63 downto 0);
   signal message_fifo_out_empty					: std_logic;
   signal command_available						: std_logic;
   signal command_contents							: std_logic_vector(31 downto 0);
   signal send_reply									: std_logic;
   signal phy_cmd_available						: std_logic;
   signal phy_command								: std_logic_vector(31 downto 0);
   signal tx_data_error								: std_logic;

   -- Clock period definitions
 constant clk_period									: time := 10 ns;
 constant tx_clk_period								: time := 40 ns;

	signal new_command								: std_logic := '0';
	signal command										: std_logic_vector(63 downto 0) := (others => '0');
	
begin

	command_processor_0 : command_processor
	port map (
		clk										=> clk,
		command_available						=> command_available,
		command_contents						=> command_contents,
		command_reply_available				=> command_reply_available,
		command_reply_contents				=> command_reply_contents,
		firmware_version						=> firmware_version,
		GPIO_LEDs								=> GPIO_LEDs,
		GPIO_Switches							=> GPIO_Switches,
		GPIO_Buttons							=> GPIO_Buttons,
		Disp_seg									=> Disp_seg,
		Disp_an									=> Disp_an
	);
	
	
	message_command_glue_0 : message_command_glue
	port map (
		tx_clk									=> tx_clk,
		clk										=> clk,
		message_command_available			=> message_command_available,
		message_command_contents			=> message_command_contents,
		message_command_reply_available	=> message_command_reply_available,
		message_command_reply_contents	=> message_command_reply_contents,
		command_available						=> command_available,
		command_contents						=> command_contents,
		command_reply_available				=> command_reply_available,
		command_reply_contents				=> command_reply_contents
	);
	
 
	-- Instantiate the Unit Under Test (UUT)
	uut: message_parser
	port map (
		reset_enet_counters					=> reset_enet_counters,
		tx_clk									=> tx_clk,
		message_fifo_in_wr_en				=> message_fifo_in_wr_en,
		message_fifo_in_din					=> message_fifo_in_din,
		message_fifo_in_full					=> message_fifo_in_full,
		message_fifo_out_rd_en				=> message_fifo_out_rd_en,
		message_fifo_out_dout				=> message_fifo_out_dout,
		message_fifo_out_empty				=> message_fifo_out_empty,
		command_available						=> message_command_available,
		command_contents						=> message_command_contents,
		command_reply_available				=> message_command_reply_available,
		command_reply_contents				=> message_command_reply_contents,
		num_good_pkts_counter				=> num_good_pkts_counter,
		num_bad_pkts_counter					=> num_bad_pkts_counter,
		firmware_version						=> firmware_version,
		send_reply								=> send_reply,
		reply_busy								=> reply_busy,
		phy_cmd_available						=> phy_cmd_available,
		phy_command								=> phy_command,
		phy_cmd_busy							=> phy_cmd_busy,
		phy_reply								=> phy_reply,
		rx_data_error							=> rx_data_error,
		tx_data_error							=> tx_data_error,
		unused_inputs							=> unused_inputs
	);

   -- Clock process definitions
   tx_clk_process : process
   begin
		tx_clk <= '0';
		wait for tx_clk_period/2;
		tx_clk <= '1';
		wait for tx_clk_period/2;
   end process;
	
   clk_process : process
   begin
		clk <= '0';
		wait for clk_period/2;
		clk <= '1';
		wait for clk_period/2;
   end process;


 	command_to_message_in_0 : command_to_message_in
	port map (
		tx_clk						=> tx_clk,
		new_command					=> new_command,
		command						=> command,
		message_fifo_in_wr_en	=> message_fifo_in_wr_en,
		message_fifo_in_din		=> message_fifo_in_din
	);
	

   -- Stimulus process
   stim_proc: process
   begin		
      -- hold reset state for 100 ns.
      wait for 100 ns;
		
		message_fifo_out_rd_en <= '1';

      wait for tx_clk_period*10;

      -- insert stimulus here 
		
		wait until rising_edge(tx_clk);
			
		for loopVar in 1 to 1 loop
			case loopVar is
				when 1 =>
					command <= x"01010000" & x"1" & x"01" & "0000" & "00000000" & "00000000";
			end case;
			
			wait until rising_edge(tx_clk);
			new_command <= '1';
			
			wait until rising_edge(tx_clk);
			new_command <= '0';
			
			wait until (message_command_reply_available = '1');
			
			wait for clk_period*5;
			wait until rising_edge(tx_clk);
		end loop;

      wait;
   end process;

end;
