
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;

entity avalon_stream_splitter is
  generic
    (
      PIXEL_BW    : positive := 8;
      NUM_OUTPUTS : positive := 3
      );
  port
    (
      -- Avalon clock interface
      csi_reset         : in  std_logic;
      csi_clk           : in  std_logic;
      -- Avalon streaming sink 
      asi_ready         : out std_logic;
      asi_valid         : in  std_logic;
      asi_data          : in  std_logic_vector(PIXEL_BW - 1 downto 0);
      asi_startofpacket : in  std_logic;
      asi_endofpacket   : in  std_logic;
      -- Avalon streaming source
      aso_ready         : in  std_logic_vector(NUM_OUTPUTS - 1 downto 0);
      aso_valid         : out std_logic_vector(NUM_OUTPUTS - 1 downto 0);
      aso_data          : out std_logic_vector((NUM_OUTPUTS*PIXEL_BW) - 1 downto 0);
      aso_startofpacket : out std_logic_vector(NUM_OUTPUTS - 1 downto 0);
      aso_endofpacket   : out std_logic_vector(NUM_OUTPUTS - 1 downto 0)
      );
end entity;

architecture behavior of avalon_stream_splitter is

  --if any of the outputs are not ready, then set the input to not ready
  function ready_test (
    input : std_logic_vector)
    return std_logic is
    variable output : std_logic := '1';
  begin
    for i in input'range loop
      if input(i) = '0' then
        output := '0';
      end if;
    end loop;  -- i
    return output;
  end function;

begin


--  connect_outputs : for i in 0 to (NUM_OUTPUTS - 1) generate
--    aso_valid(i)                                     <= asi_valid;
--    aso_data(((i+1)*PIXEL_BW) - 1 downto i*PIXEL_BW) <= asi_data;
--    aso_startofpacket(i)                            <= asi_startofpacket;
--    aso_endofpacket(i)                              <= asi_endofpacket;
--  end generate;


  process(csi_reset, csi_clk)
  begin
    if csi_reset = '1' then
      asi_ready         <= '0';
      aso_valid         <= (others => '0');
      aso_data          <= (others => '0');
      aso_startofpacket <= (others => '0');
      aso_endofpacket   <= (others => '0');
    elsif rising_edge(csi_clk) then
      for i in 0 to (NUM_OUTPUTS - 1) loop
        aso_valid(i)                                     <= asi_valid;
        aso_data(((i+1)*PIXEL_BW) - 1 downto i*PIXEL_BW) <= asi_data;
        aso_startofpacket(i)                             <= asi_startofpacket;
        aso_endofpacket(i)                               <= asi_endofpacket;
      end loop;
      asi_ready <= ready_test(aso_ready);
    end if;
  end process;

end architecture;
