library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all; -- lib for unsigned and signed

entity ultranet_serializer  is
	port
	(
		clk			: in std_logic;
		ch1_in		: in std_logic_vector(23 downto 0);
		ch2_in		: in std_logic_vector(23 downto 0);
		ch3_in		: in std_logic_vector(23 downto 0);
		ch4_in		: in std_logic_vector(23 downto 0);
		ch5_in		: in std_logic_vector(23 downto 0);
		ch6_in		: in std_logic_vector(23 downto 0);
		ch7_in		: in std_logic_vector(23 downto 0);
		ch8_in		: in std_logic_vector(23 downto 0);
		new_data	: in std_logic;
		aes_lrck	: in std_logic;


		ch_out 		: out std_logic_vector(23 downto 0)
	);
end entity;

architecture rtl of ultranet_serializer is
	signal new_data_pos_edge	: std_logic;
	signal znew_data			: std_logic;
	signal aes_lrck_edge		: std_logic;
	signal zaes_lrck			: std_logic;
	signal zzaes_lrck			: std_logic;
	signal zzzaes_lrck			: std_logic;
	
	signal ch1_buffer			: std_logic_vector(23 downto 0);
	signal ch2_buffer			: std_logic_vector(23 downto 0);
	signal ch3_buffer			: std_logic_vector(23 downto 0);
	signal ch4_buffer			: std_logic_vector(23 downto 0);
	signal ch5_buffer			: std_logic_vector(23 downto 0);
	signal ch6_buffer			: std_logic_vector(23 downto 0);
	signal ch7_buffer			: std_logic_vector(23 downto 0);
	signal ch8_buffer			: std_logic_vector(23 downto 0);

	signal channel_cnt			: integer range 0 to 7 := 0;        -- TODO:  range should be 0 to 7 for the 8 ADCs
begin
	detect_new_data_edge : process(clk) begin
		if rising_edge(clk) then
			znew_data <= new_data;
			if new_data = '1' and znew_data = '0' then
				new_data_pos_edge <= '1';
			else
				new_data_pos_edge <= '0';
			end if;
		end if;
	end process;

	detect_aes_lrck_edge : process(clk) begin
		if rising_edge(clk) then
			zaes_lrck <= aes_lrck;
			zzaes_lrck <= zaes_lrck;
			zzzaes_lrck <= zzaes_lrck;
			if zzaes_lrck /= zzzaes_lrck then
				aes_lrck_edge <= '1';
			else
				aes_lrck_edge <= '0';
			end if;
		end if;
	end process;

	process(clk)
	begin
		if (rising_edge(clk)) then
			if new_data_pos_edge = '1' then
				-- Buffer the sample for each input channel
				ch1_buffer <= ch1_in;
				ch2_buffer <= ch2_in;
				ch3_buffer <= ch3_in;
				ch4_buffer <= ch4_in;
				ch5_buffer <= ch5_in;
				ch6_buffer <= ch6_in;
				ch7_buffer <= ch7_in;
				ch8_buffer <= ch8_in;

				-- Reset the channel counter to the last channel, this is unusual but the 
				-- aes_lrck_edge comming a short time after the new_data will overflow the counter to the 
				-- first channel
				channel_cnt <= 0;       -- TODO:  reset value should be 7 for 8 ADCs
			end if;

			if aes_lrck_edge = '1' then		
				-- Increment the channel counter on each pulse
				channel_cnt <= channel_cnt + 1; 

				-- Output the corrsponding sample
				if channel_cnt = 0 then
					ch_out <= ch1_buffer;
				elsif channel_cnt = 1 then
					ch_out <= ch2_buffer;
				elsif channel_cnt = 2 then
					ch_out <= ch3_buffer;
				elsif channel_cnt = 3 then
					ch_out <= ch4_buffer;
				elsif channel_cnt = 4 then
					ch_out <= ch5_buffer;
				elsif channel_cnt = 5 then
					ch_out <= ch6_buffer;
				elsif channel_cnt = 6 then
					ch_out <= ch7_buffer;
				elsif channel_cnt = 7 then
					ch_out <= ch8_buffer;
				end if;

			end if;

		end if;
	end process;
end rtl;