----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date: 07/23/2019 03:52:40 PM
-- Design Name: 
-- Module Name: axis_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;
use IEEE.STD_LOGIC_UNSIGNED.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 axis_generator is
   port (
      CLK                  : in  std_logic;
      RESET                : in  std_logic;
      M_AXIS_TVALID        : out std_logic;
      M_AXIS_TREADY        : in  std_logic;
      M_AXIS_TLAST         : out std_logic;
      M_AXIS_TKEEP         : out std_logic_vector(63 downto 0);
      M_AXIS_TDATA         : out std_logic_vector(511 downto 0)
   );
end axis_generator;

architecture Behavioral of axis_generator is

   constant LAST_CYCLE_TKEEP  : std_logic_vector(63 downto 0) := x"00000000000000ff";--x"ffffffffffffffff";--x"0000000000000001"; -- --
   constant LC_PAUSE_CNT      : natural := 0;
   constant LC_VALID_CNT      : natural := 5;
   signal cnt                 : natural range 0 to LC_VALID_CNT + LC_PAUSE_CNT := 0;
   
   signal data_cnt            : std_logic_vector(511 downto 0) := (others => '0');
   constant LC_DATA_CNT_MAX   : std_logic_vector(511 downto 0) := (others => '1');
   
   
   signal tlast                : std_logic := '0';
   signal tvalid                : std_logic := '0';
   signal tkeep               : std_logic_vector(M_AXIS_TKEEP'range) := (others => '0');
begin

   axis_gen_proc: process(CLK) 
      begin 
         if rising_edge(CLK) then
            if RESET = '1' then 
               data_cnt <= (others => '0');
               cnt <= 0;
            else         
               -- update counter
               if (M_AXIS_TREADY and tvalid) = '1' then
                  if data_cnt < LC_DATA_CNT_MAX then 
                     data_cnt <= data_cnt + 1;
                  else
                     data_cnt <= (others => '0');
                  end if;    
               end if;
                   
               if cnt < LC_VALID_CNT then
                  if M_AXIS_TREADY = '1' and tvalid = '1' then 
                     cnt <= cnt + 1;
                  end if;
               elsif cnt < LC_VALID_CNT + LC_PAUSE_CNT then 
                  cnt <= cnt + 1;
               else
                  cnt <= 0;
               end if;
            end if;
         end if;
      end process;

      tvalid <= '1' when cnt < LC_VALID_CNT else '0';

      M_AXIS_TDATA <= data_cnt;
      M_AXIS_TVALID <= tvalid;
      M_AXIS_TLAST <= '1' when cnt = LC_VALID_CNT-1 else '0';--tlast;
      M_AXIS_TKEEP <= (others => '1') when cnt < LC_VALID_CNT-1 else LAST_CYCLE_TKEEP;-- tkeep;

end Behavioral;
