--- FSM_Tx_Logic -----------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;

ENTITY FSM_Tx_Logic IS
  PORT (InpBuf_WrN: 	IN STD_LOGIC_VECTOR(47 DOWNTO 0);
		Ready_v:		IN STD_LOGIC;
		Transport_Idle: IN STD_LOGIC;						-- Edge detector output (Tx_Coreclock from ALTLVDS_Tx)
		clk: 			IN STD_LOGIC;
		reset: 			IN STD_LOGIC;

		Tx_Buf: 		OUT STD_LOGIC_VECTOR(47 DOWNTO 0);
		Start:			OUT STD_LOGIC;
		
		Ack_WrN:		OUT STD_LOGIC;
		sIdle: 			OUT STD_LOGIC);

END FSM_Tx_Logic;

ARCHITECTURE arch OF FSM_Tx_Logic IS
  TYPE state_type IS (Idle, Wait_Capture); -- states of FSM
  SIGNAL state_reg, state_next: state_type;
  SIGNAL counter_Ack:			UNSIGNED(3 DOWNTO 0) := X"0";
  SIGNAL counter_FSM:			UNSIGNED(3 DOWNTO 0) := X"0";
  SIGNAL Ready_Idle:			STD_LOGIC := '0';
  SIGNAL Ready_WaitCapture:		STD_LOGIC := '0';
  SIGNAL Ready_Sgnls:			STD_LOGIC := '0';
  SIGNAL Buf_WrN:				STD_LOGIC_VECTOR(47 DOWNTO 0) := X"000000000000";
  
BEGIN
--- process for changing of states ----------------
  PROCESS(clk, reset)
  BEGIN
	IF(reset = '1') THEN
	  state_reg <= Idle;
	  counter_Ack <= X"0";
	  counter_FSM <= X"0";
	  Ready_Idle <= '0';
	  Ready_WaitCapture <= '0';
	  Ready_Sgnls <= '0';
	  Tx_Buf <= X"000000000000";
	  Ack_WrN <= '0';
	  Start <= '0';
	ELSIF(clk'EVENT AND clk='1') THEN
------------
      state_reg		<= state_next;
	  Ready_Sgnls	<= Ready_v;
	  Buf_WrN		<= InpBuf_WrN;
------------
	  IF((state_reg = Idle)AND(Transport_Idle = '1')) THEN
			IF(Ready_Sgnls = '1') THEN
			  Tx_Buf <= Buf_WrN;
			  Start <= '1';
			  Ack_WrN <= '1';
			  Ready_Idle <= '1';
			ELSE
			  Tx_Buf <= X"000000000000";
			  Start <= '0';
			  Ack_WrN <= '0';
			  Ready_Idle <= '0';
			END IF;
	  ELSE
		Ready_Idle <= '0';
	END IF;
------------
	  IF(state_reg = Wait_Capture) THEN
		counter_Ack <= counter_Ack + 1;
		IF(counter_Ack = X"2") THEN
		  Ack_WrN <= '0';
		END IF;
		IF((Transport_Idle = '0')AND(counter_Ack = X"2")) THEN
		  counter_Ack <= X"0";
		  Start <= '0';
		  Ready_WaitCapture <= '1';
		END IF;
	  ELSE
		Ready_WaitCapture <= '0';
		counter_Ack <= X"0";
	  END IF;
------------
    END IF;
  END PROCESS;

-------------------------------------------------------------- 
PROCESS(state_reg, Ready_Idle, Ready_WaitCapture)
  BEGIN
  CASE state_reg IS
----------
	WHEN Idle =>
	  IF(Ready_Idle = '1') THEN
		state_next <= Wait_Capture;
	  ELSE
		state_next <= Idle;
	  END IF;
--------------
	WHEN Wait_Capture =>
	  IF(Ready_WaitCapture = '1') THEN
		state_next <= Idle;
	  ELSE
		state_next <= Wait_Capture;
	  END IF;
  END CASE;
END PROCESS;

--- Concurrent logic --------------------------------------------------------------------

  sIdle <= '1' WHEN (state_reg = Idle) ELSE
		   '0';
END arch;
