library  IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_unsigned.all;

entity AutoDAQ_SK2_v1 is
port (
	n_reset		:	IN STD_LOGIC ;
	n_write		:	IN STD_LOGIC ;
	subadd		: IN STD_LOGIC_VECTOR (6 DOWNTO 0);
	user_data	: INOUT STD_LOGIC_VECTOR (7 DOWNTO 0);
	SlowClock	:	in  std_logic;
	ChipSatb	:	in  std_logic;
	EndReadOut	:	in  std_logic;
	Resetb		:	out	std_logic;
	Start_Acq	:	out	std_logic;
	Start_Convb :	out	std_logic;
	Start_ReadOut :	out	std_logic;
	PWR_ON_A	:	out	std_logic;
	PWR_ON_ADC	:	out	std_logic;
	PWR_ON_DAC	:	out	std_logic;
	PWR_ON_D	:	out	std_logic;
	fast_RO		:	out	std_logic;
	SPY1		:	out	std_logic;
	SPY2		:	out	std_logic_vector (15 DOWNTO 0));
end AutoDAQ_SK2_v1;

architecture rtl of AutoDAQ_SK2_v1 is

	SIGNAL sel_word		: Std_Logic_vector (7 downto 0);
	SIGNAL word_23		: STD_LOGIC_VECTOR (7 DOWNTO 0);
	signal SynchStart1, SynchStart2, SynchStart3, Strt, StartCycle	:	std_logic;
	signal StateMe		: Std_Logic_Vector(3 downto 0);
	signal Counter16	: Std_Logic_Vector(15 downto 0);
	signal RstCmpt		: std_logic;

component reg_8bits
	PORT
	(
		aclr		: IN STD_LOGIC ;
		clock		: IN STD_LOGIC ;
		data		: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
		enable		: IN STD_LOGIC ;
		q		: OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
	);
end component;

component count16bits
	PORT
	(
		aclr		: IN STD_LOGIC ;
		clock		: IN STD_LOGIC ;
		cnt_en		: IN STD_LOGIC ;
		q		: OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
	);
END component;

begin

reg_8bits_inst : reg_8bits PORT MAP ( --// Machine d'ecriture du Word 23
		aclr	 => NOT (n_reset),
		clock	 => n_write,
		data	 => user_data,
		enable	 => sel_word(0),
		q	 => word_23
	);

------------------------------------------
-- Compteur  --
------------------------------------------
count16bit_inst : count16bits PORT MAP	(
		aclr		=> RstCmpt ,
		clock		=> SlowClock ,
		cnt_en		=> '1' ,
		q			=> Counter16
	);

------------------------------------------
-- Me Outputs                           --
------------------------------------------

with StateMe select
	Resetb	<=	'0'	when	"0001",
				'1'	when  	others;

with StateMe select
	Start_Acq	<=	'1'	when	"0010",
					'0'	when  	others;

with StateMe select
	Start_Convb	<=	'0'	when	"0101",
						'1'	when  	others;

with StateMe select
	Start_ReadOut	<=	'1'	when	"1101",
						'0'	when  	others;

with StateMe select
	RstCmpt	<=	'1'	when	"0000",	'1'	when	"0110", '1' when "0100", '1' when "1110",
				'0'	when  	others;

with StateMe select
	fast_RO		<=	'1'	when	"1100", '1'	when	"1101", '1' when "1001", '1' when "1000",
					'0'	when  	others;

with StateMe select
	PWR_ON_A	<=	'1'	when "0011", '1' when "0010", '1' when "0110",'1' when "0111",
				'0'	when  	others;

with StateMe select
	PWR_ON_ADC	<=	'1'	when "0110", '1' when "0111", '1' when "0101",'1' when "0100",
				'0'	when  	others;

with StateMe select
	PWR_ON_DAC	<=	'1'	when "0001", '1' when "0011", '1' when "0010",'1' when "0110",'1' when "0111",'1' when "0101",'1' when "0100",
				'0'	when  	others;

with StateMe select
	PWR_ON_D	<=	'1'	when "0001", '1' when "0011", '1' when "0010",'1' when "0110",'1' when "0111",'1' when "0101",'1' when "0100", '1' when "1100",
				'0'	when  	others;

------------------------------
-- Synchro StartCycle --
------------------------------
SynchInSignal1: process (n_reset, SlowClock)
begin
if  n_reset = '0' then
	SynchStart1		<= '0';
	SynchStart2		<= '0';
	SynchStart3		<= '0';
else
	if SlowClock'Event and SlowClock = '0' then
		SynchStart1  	<= StartCycle;
		SynchStart2 	<= SynchStart1;
		SynchStart3 	<= SynchStart2;
	end if;
end if;
end process SynchInSignal1;

Strt <= SynchStart2 AND (NOT(SynchStart3));

------------------------------------------
-- Machine Etat DAQ              --
------------------------------------------

MeDAQ : process (n_reset, SlowClock)
---------------------------------
begin
  if n_reset = '0' then
    StateMe <= "0000";
  else
    if SlowClock'event and SlowClock = '0' then
      case StateMe is
        when "0000" =>	if Strt = '1' then
                                  StateMe <= "0001";
                                else
                                  StateMe <= "0000";
                                end if;
		when "0001" =>	if Counter16(2)= '1' then
                                  StateMe <= "0011";
                                else
                                  StateMe <= "0001";
                                end if;
		when "0011" =>	if Counter16(3)= '1' then
                                  StateMe <= "0010";
                                else
                                  StateMe <= "0011";
                                end if;
		when "0010" =>	if (Counter16(12)= '1' OR ChipSatb = '0') then
                                  StateMe <= "0110";
                                else
                                  StateMe <= "0010";
                                end if;
		when "0110" =>	StateMe <= "0111";
		when "0111" =>	if Counter16(2)= '1' then
                                  StateMe <= "0101";
                                else
                                  StateMe <= "0111";
                                end if;
		when "0101" =>	if Counter16(3)= '1' then
                                  StateMe <= "0100";
                                else
                                  StateMe <= "0101";
                                end if;
		when "0100" =>	if ChipSatb = '1' then
                                  StateMe <= "1100";
                                else
                                  StateMe <= "0100";
                                end if;
		when "1100" =>	if Counter16(2)= '1' then
                                  StateMe <= "1101";
                                else
                                  StateMe <= "1100";
                                end if;
		when "1101" =>	if Counter16(3)= '1' then
                                  StateMe <= "1001";
                                else
                                  StateMe <= "1101";
                                end if;
		when "1001" =>	if EndReadOut = '1' then
                                  StateMe <= "1000";
                                else
                                  StateMe <= "1001";
                                end if;
		when "1000" =>	if EndReadOut = '0' then
                                  StateMe <= "0000";
                                else
                                  StateMe <= "1000";
                                end if;
		when others	=>	StateMe <= "0000";
      end case;
    end if;                             -- falling edge clock
  end if;                               -- reset
end process MeDAQ;

make_sel_word : PROCESS(subadd)
BEGIN
	CASE subadd IS
	WHEN "0010111"	=>	sel_word <= "00000001";	-- add(23) = 1
	WHEN OTHERS	=>	sel_word <= "00000000";
END CASE;
END PROCESS make_sel_word;

StartCycle	<=	word_23(7);  -- Enable Start Cycle signal (Acquisition, Conversion, ReadOut)
SPY1	<= Strt;
SPY2	<= Counter16;

end rtl;
