----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date: 07/09/2019 09:25:11 AM
-- Design Name: 
-- Module Name: packet_generator - 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 packet_generator is
   generic (
      g_data_width      : integer := 512
   );
   port (
      -- Reset and clock
      RESET             : in  std_logic;
      CLK               : in  std_logic;
      -- Control
      PKT_GEN_ENABLE    : in  std_logic;
      -- Master axis
      M_AXIS_TREADY     : in  std_logic;
      M_AXIS_TVALID     : out std_logic;
      M_AXIS_TDATA      : out std_logic_vector(g_data_width-1 downto 0);
      M_AXIS_TUSER      : out std_logic;
      M_AXIS_TKEEP      : out std_logic_vector(g_data_width/8-1 downto 0);
      M_AXIS_TLAST      : out std_logic
   
    );
end packet_generator;

architecture Behavioral of packet_generator is


   -- data counter
   signal cnt              : std_logic_vector(63 downto 0) := (others => '0');
   constant LC_CNT_MAX     : std_logic_vector(cnt'range) := (others => '1');
   
   -- packet pause counter
   constant LC_PAUSE_LEN   : natural := 100;   
   signal pause_cnt        : natural range 0 to LC_PAUSE_LEN := 0;
   
   -- axis data internal
   signal m_axis_tdata_i   : std_logic_vector(M_AXIS_TDATA'range) := (others => '0');   
   
begin
   
   m_axis_tdata_i(m_axis_tdata_i'length-1 downto m_axis_tdata_i'length-64) <= cnt;
   m_axis_tdata_i(m_axis_tdata_i'length-64-1 downto 0) <= (others => '0');

   M_AXIS_TVALID <= '1' when PKT_GEN_ENABLE = '1' and pause_cnt = LC_PAUSE_LEN else '0';
   M_AXIS_TLAST <= '1' when PKT_GEN_ENABLE = '1' and pause_cnt = LC_PAUSE_LEN else '0';
   M_AXIS_TDATA <= m_axis_tdata_i;
   M_AXIS_TKEEP <= x"ff00000000000000";
   M_AXIS_TUSER <= '0';
   

   pkt_gen_cnt_proc: process(CLK) 
      begin
         if rising_edge(CLK) then
            if RESET = '1' then
               pause_cnt <= 0;
            else
               if PKT_GEN_ENABLE = '1' then
                  if pause_cnt < LC_PAUSE_LEN then
                     pause_cnt <= pause_cnt + 1;
                  else
                     if M_AXIS_TREADY = '1' then
                        pause_cnt <= 0;
                        if cnt < LC_CNT_MAX then
                           cnt <= std_logic_vector(unsigned(cnt) + 1);
                        else
                           cnt <= (others => '0');
                        end if;
                     end if;
                  end if;
               else
                  pause_cnt <= 0;
               end if;
            end if;
         end if;
      end process;
         

end Behavioral;
