----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date: 07/23/2019 03:48:42 PM
-- Design Name: 
-- Module Name: udp_100g_tb - Behavioral
-- Project Name: 
-- Target Devices: 
-- Tool Versions: 
-- Description: 
-- 
-- Dependencies: 
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
-- 
----------------------------------------------------------------------------------


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;

-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity udp_100g_tb is
--  Port ( );
end udp_100g_tb;

architecture Behavioral of udp_100g_tb is
   constant LC_TX_CLK_PERIOD  : time := 3 ns;
   constant LC_RX_CLK_PERIOD  : time := 10 ns;
   
   signal tx_clk              : std_logic := '0';
   signal rx_clk              : std_logic := '0';
   
   signal reset               : std_logic := '0';
   
   signal s_axis_tx_tvalid    : std_logic := '0';                      
   signal s_axis_tx_tready    : std_logic := '0';                      
   signal s_axis_tx_tlast     : std_logic := '0';                      
   signal s_axis_tx_tkeep     : std_logic_vector(63 downto 0) := (others => '0');  
   signal s_axis_tx_tdata     : std_logic_vector(511 downto 0) := (others => '0'); 
   
   signal axis_cmac_loopback_tvalid    : std_logic := '0';              
   signal axis_cmac_loopback_tready    : std_logic := '0';              
   signal axis_cmac_loopback_tuser     : std_logic := '0';              
   signal axis_cmac_loopback_tlast     : std_logic := '0';              
   signal axis_cmac_loopback_tkeep     : std_logic_vector(63 downto 0); 
   signal axis_cmac_loopback_tdata     : std_logic_vector(511 downto 0);   
   
   signal rx_ready                     : std_logic := '0';
   signal rx_valid                     : std_logic := '0';
   
   signal cmac_rst                     : std_logic := '0';
   signal powergood                    : std_logic := '0';
   signal rx_aligned                   : std_logic := '0';
   signal init_done                    : std_logic := '0';
   signal not_init_done                : std_logic := '0';
   
   signal user_tx_rst                  : std_logic := '1';
   signal user_rx_rst                  : std_logic := '1';
   signal mask                         : std_logic := '0';
   signal masked_tready                : std_logic := '0';
 
   signal m_axis_rx_tvalid             : std_logic := '0';
   signal m_axis_rx_tready             : std_logic := '0';
   signal m_axis_rx_tlast              : std_logic := '0';
   signal m_axis_rx_tkeep              : std_logic_vector(63 downto 0) := (others => '0');
   signal m_axis_rx_tdata              : std_logic_vector(511 downto 0) := (others => '0');

   signal m_axis_arp_tvalid             : std_logic := '0';
   signal m_axis_arp_tready             : std_logic := '0';
   signal m_axis_arp_tlast              : std_logic := '0';
   signal m_axis_arp_tkeep              : std_logic_vector(63 downto 0) := (others => '0');
   signal m_axis_arp_tdata              : std_logic_vector(511 downto 0) := (others => '0');
   
begin

   tx_clk <= not tx_clk after LC_TX_CLK_PERIOD/2;
   not_init_done <= not init_done;

   axis_gen_inst: entity work.axis_generator
   port map(
      CLK                  => tx_clk,
      RESET                => not_init_done,
      M_AXIS_TVALID        => s_axis_tx_tvalid,
      M_AXIS_TREADY        => s_axis_tx_tready,
      M_AXIS_TLAST         => s_axis_tx_tlast,
      M_AXIS_TKEEP         => s_axis_tx_tkeep,
      M_AXIS_TDATA         => s_axis_tx_tdata
   );

   arp_gen_inst: entity work.arp_generator
      port map(
         CLK                  => tx_clk,
         RESET                => not_init_done,
         M_AXIS_TVALID        => m_axis_arp_tvalid,
         M_AXIS_TREADY        => m_axis_arp_tready,
         M_AXIS_TLAST         => m_axis_arp_tlast, 
         M_AXIS_TKEEP         => m_axis_arp_tkeep, 
         M_AXIS_TDATA         => m_axis_arp_tdata, 
         ARP_SRC_MAC          => x"6805ca1b37dc",
         ARP_SRC_IP           => x"c0a88901", --ffffffffffff 6805ca1b37dc 0806 0001 0800 06 04 0001 6805ca1b37dc c0a88901 000000000000 c0a88915 000000000000000000000000000000000000
         ARP_DST_IP           => x"c0a88915"
      );

--   udp_100g_inst: entity work.udp_100g
--   generic map(
--      g_arp_enable         => TRUE
--   )
--   port map(
--      -- Core reset
--      RESET                => reset,
--      -- Core clock
--      INIT_CLK             => tx_clk,
--      CORE_CLK             => tx_clk,

--      ------------   CMAC Interface    ---------
--      -- TX Datapath
--      M_AXIS_TX_TVALID     => axis_cmac_loopback_tvalid,
--      M_AXIS_TX_TREADY     => '1',
--      M_AXIS_TX_TUSER      => axis_cmac_loopback_tuser, 
--      M_AXIS_TX_TLAST      => axis_cmac_loopback_tlast, 
--      M_AXIS_TX_TKEEP      => axis_cmac_loopback_tkeep, 
--      M_AXIS_TX_TDATA      => axis_cmac_loopback_tdata, 
--      -- RX Datapath
--      S_AXIS_RX_TVALID     => m_axis_arp_tvalid,
--      S_AXIS_RX_TREADY     => m_axis_arp_tready,
--      S_AXIS_RX_TUSER      => '0', 
--      S_AXIS_RX_TLAST      => m_axis_arp_tlast, 
--      S_AXIS_RX_TKEEP      => m_axis_arp_tkeep, 
--      S_AXIS_RX_TDATA      => m_axis_arp_tdata, 
--      -- Control signals
--      CTL_RX_ENABLE            => open,
--      CTL_TX_ENABLE            => open,
--      CTL_TX_SEND_RFI          => open,
--      CTL_TX_SEND_LFI          => open,
--      CTL_TX_SEND_IDLE         => open,
--      CTL_TX_PREAMBLE          => open,
--      -- Status signals
--      STAT_RX_ALIGNED           => rx_aligned,
--      STAT_TX_OVERFLOW          => '0',
--      STAT_TX_UNDERFLOW         => '0',     
--      -- User interface reset signals from CMAC
--      USR_RX_RESET         => user_rx_rst,
--      USR_TX_RESET         => user_tx_rst,      
--      -- CMAC core reset
--      CMAC_RESET           => cmac_rst,
--      -- CMAC datapaths reset
--      RX_RESET             => open,
--      TX_RESET             => open,      
--      ------------   USER Interface    ---------
--      -- TX Datapath
--      S_AXIS_TX_TVALID     => s_axis_tx_tvalid,
--      S_AXIS_TX_TREADY     => s_axis_tx_tready,
--      S_AXIS_TX_TLAST      => s_axis_tx_tlast,
--      S_AXIS_TX_TKEEP      => s_axis_tx_tkeep,
--      S_AXIS_TX_TDATA      => s_axis_tx_tdata,
--      -- RX Datapath
--      M_AXIS_RX_TVALID     => m_axis_rx_tvalid,
--      M_AXIS_RX_TREADY     => m_axis_rx_tready,
--      M_AXIS_RX_TLAST      => m_axis_rx_tlast,
--      M_AXIS_RX_TKEEP      => m_axis_rx_tkeep,
--      M_AXIS_RX_TDATA      => m_axis_rx_tdata,
--      -- Host net info
--      HOST_MAC             => x"000000000010",
--      HOST_IP              => x"c0a88915",
--      HOST_NET_MASK        => x"ffffff00",
--      -- TX net info
--      TX_SRC_UDP           => x"0404",
--      TX_DST_UDP           => x"0505",
--      TX_DST_IP            => x"ffffffff",
--      TX_DST_MAC           => x"ffffffffffff",
--      -- RX packet info
--      RX_DST_UDP           => open,
--      RX_SRC_UDP           => open,
--      RX_SRC_IP            => open,
--      RX_SRC_MAC           => open,
--      RX_PACKET_LENGTH     => open,
      
--      INIT_DONE            => init_done
--   );



   udp_100g_inst: entity work.udp_100g
   generic map(
      g_tx_dfifo_depth  => 256, -- 512 bit data width (8 data bytes)
      g_tx_tfifo_depth  => 256,  -- 129 bit data width
      g_rx_dfifo_depth  => 256, -- 512 bit data width (8 data bytes)
      g_rx_tfifo_depth  => 256,  -- 129 bit data width
      g_arp_enable => TRUE
   )
   port map(
      -- Core reset
      RESET                => reset,
      -- Core clock
      CLK                  => tx_clk,
      CMAC_CLK             => tx_clk,

      ------------   CMAC Interface    ---------
      -- TX Datapath
      M_AXIS_TX_TVALID     => axis_cmac_loopback_tvalid,
      M_AXIS_TX_TREADY     => axis_cmac_loopback_tready,
      M_AXIS_TX_TUSER      => axis_cmac_loopback_tuser, 
      M_AXIS_TX_TLAST      => axis_cmac_loopback_tlast, 
      M_AXIS_TX_TKEEP      => axis_cmac_loopback_tkeep, 
      M_AXIS_TX_TDATA      => axis_cmac_loopback_tdata, 
      -- RX Datapath
      S_AXIS_RX_TVALID     => axis_cmac_loopback_tvalid,
      S_AXIS_RX_TREADY     => axis_cmac_loopback_tready,
      S_AXIS_RX_TUSER      => axis_cmac_loopback_tuser,
      S_AXIS_RX_TLAST      => axis_cmac_loopback_tlast,
      S_AXIS_RX_TKEEP      => axis_cmac_loopback_tkeep,
      S_AXIS_RX_TDATA      => axis_cmac_loopback_tdata,
      -- Control signals
      CTL_RX_ENABLE            => open,
      CTL_TX_ENABLE            => open,
      CTL_TX_SEND_RFI          => open,
      CTL_TX_SEND_LFI          => open,
      CTL_TX_SEND_IDLE         => open,
      CTL_TX_PREAMBLE          => open,
      -- Status signals
      STAT_RX_ALIGNED           => rx_aligned,
      STAT_TX_OVERFLOW          => '0',
      STAT_TX_UNDERFLOW         => '0',     
      -- User interface reset signals from CMAC
      USR_RX_RESET         => user_rx_rst,
      USR_TX_RESET         => user_tx_rst,      
      -- CMAC core reset
      CMAC_RESET           => cmac_rst,
      -- CMAC datapaths reset
      RX_RESET             => open,
      TX_RESET             => open,      
      ------------   USER Interface    ---------
      -- TX Datapath
      S_AXIS_TX_TVALID     => s_axis_tx_tvalid,
      S_AXIS_TX_TREADY     => s_axis_tx_tready,
      S_AXIS_TX_TLAST      => s_axis_tx_tlast,
      S_AXIS_TX_TKEEP      => s_axis_tx_tkeep,
      S_AXIS_TX_TDATA      => s_axis_tx_tdata,
      -- RX Datapath
      M_AXIS_RX_TVALID     => m_axis_rx_tvalid,
      M_AXIS_RX_TREADY     => m_axis_rx_tready,
      M_AXIS_RX_TLAST      => m_axis_rx_tlast,
      M_AXIS_RX_TKEEP      => m_axis_rx_tkeep,
      M_AXIS_RX_TDATA      => m_axis_rx_tdata,
      -- Host net info
      HOST_MAC             => x"000000000010",
      HOST_IP              => x"10000011",
      HOST_NET_MASK        => x"ffffff00",
      -- TX net info
      TX_SRC_UDP           => x"0404",
      TX_DST_UDP           => x"0505",
      TX_DST_IP            => x"ffffffff",
      TX_DST_MAC           => x"ffffffffffff",
      -- RX packet info
      RX_DST_UDP           => open,
      RX_SRC_UDP           => open,
      RX_SRC_IP            => open,
      RX_SRC_MAC           => open,
      RX_PACKET_LENGTH     => open,
      
      INIT_DONE            => init_done
   );

   axis_checker_inst: entity work.axis_checker 
   port map(
      CLK                  => tx_clk,
      RESET                => not_init_done,
      S_AXIS_TVALID        => m_axis_rx_tvalid,
      S_AXIS_TREADY        => m_axis_rx_tready,
      S_AXIS_TLAST         => m_axis_rx_tlast,
      S_AXIS_TKEEP         => m_axis_rx_tkeep,
      S_AXIS_TDATA         => m_axis_rx_tdata,
      ERROR                => open
   );

--   m_axis_rx_tready <= not m_axis_rx_tready after 100ns;
   
   user_tx_rst <= cmac_rst after 500ns;
   user_rx_rst <= cmac_rst after 700ns;
   powergood <= not cmac_rst  after 500ns;
   
--   axis_cmac_loopback_tready <= not axis_cmac_loopback_tready after 100ns;

   rx_aligned <= not cmac_rst after 1000ns;
   rx_ready <= not rx_ready after 7 ns;
   mask <= not mask after 13.1ns;
   masked_tready <= mask and axis_cmac_loopback_tready;
end Behavioral;
