-- ADS1274 VHDL component 
-- 24 bit ADC, 4 channel, simultaneous sampling at 128k SPS

-- Configured for high-speed mode, frame-sync format, and 
-- TDM with fixed data position

-- This component reads a continuous stream of data from the ADC
-- and writes it to 4 x 24-bit output ports. A separate component
-- adds a header packet, and shifts the data into a FIFO.

-- Steven Merrifield, June 2008


library ieee;
use ieee.std_logic_1164.all;

entity ads1274 is
port (
	clk : in std_logic;
	adc_fsync : out std_logic;
	adc_clk : out std_logic;
	adc_sclk : out std_logic;
	adc_data : in std_logic;
	ch1 : out std_logic_vector(23 downto 0);
	ch2 : out std_logic_vector(23 downto 0);
	ch3 : out std_logic_vector(23 downto 0);
	ch4 : out std_logic_vector(23 downto 0)
);
end ads1274;


architecture behav of ads1274 is

signal sclk_sig : std_logic;
signal adc_clk_sig : std_logic;
signal cnt : integer range 1 to 128;
signal frame_sig : std_logic_vector(128 downto 1);
begin

	adc_clk_sig <= clk;	-- change as required, eg divide
	adc_clk <= adc_clk_sig;	-- 32.768MHz


	-- ADC serial clock is 1/2 the ADC clock, synchronised on the falling edge
	process(adc_clk_sig)
	begin
		if (adc_clk_sig'event and adc_clk_sig='0') then
			sclk_sig <= not sclk_sig;
		end if;
	end process;
	adc_sclk <= sclk_sig;

				
	-- latch and shift incoming data on the rising edge
	process(sclk_sig)
	begin
		if (sclk_sig'event and sclk_sig='1') then
			frame_sig <= frame_sig(127 downto 1) & adc_data;			
		end if;
	end process;


	-- ADC frame sync pulse is high for one cycle every 128 cycles, falling edge
	process(sclk_sig)
	begin
		if (sclk_sig'event and sclk_sig='0') then
			cnt <= cnt + 1;
			if (cnt = 128) then
				adc_fsync <= '1';
				cnt <= 1;
				ch1 <= frame_sig(128 downto 105);
				ch2 <= frame_sig(104 downto 81);
				ch3 <= frame_sig(80 downto 57);
				ch4 <= frame_sig(56 downto 33);
			else
				adc_fsync <= '0';
			end if;
		end if;
	end process;

end behav;


