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

ENTITY FSM_Tx_Transport IS
  PORT (Tx_Buf:				IN STD_LOGIC_VECTOR(47 DOWNTO 0);
		Start:				IN STD_LOGIC;
		Tx_Coreclk: 		IN STD_LOGIC;	-- Edge detector output (Tx_Coreclock from ALTLVDS_Tx)
		clk: 				IN STD_LOGIC;
		reset: 				IN STD_LOGIC;
		Tx_Out: 			OUT STD_LOGIC_VECTOR(7 DOWNTO 0);	-- Byte of message to transmit (feed to ALTLVDS_Tx)
		sIdle, sTx:			OUT STD_LOGIC);
END FSM_Tx_Transport;

ARCHITECTURE arch OF FSM_Tx_Transport IS					-- states of FSM
  TYPE state_type IS (Idle, Tx); 						
  SIGNAL state_reg, state_next: state_type;
  
  SIGNAL B6:			STD_LOGIC_VECTOR(7 DOWNTO 0);
  SIGNAL B5:			STD_LOGIC_VECTOR(7 DOWNTO 0);
  SIGNAL B4:			STD_LOGIC_VECTOR(7 DOWNTO 0);
  SIGNAL B3:			STD_LOGIC_VECTOR(7 DOWNTO 0);
  SIGNAL B2:			STD_LOGIC_VECTOR(7 DOWNTO 0);
  SIGNAL B1:			STD_LOGIC_VECTOR(7 DOWNTO 0);
  
  SIGNAL Buf:			STD_LOGIC_VECTOR(7 DOWNTO 0);
  
  SIGNAL Flag_Start:	STD_LOGIC := '0';
  SIGNAL Flag_Tx:		STD_LOGIC := '0';
  SIGNAL counter:		UNSIGNED(3 DOWNTO 0) := X"0";
  SIGNAL Ready_Idle:	STD_LOGIC := '0';
  SIGNAL Ready_Tx:		STD_LOGIC := '0';
  
BEGIN
  PROCESS(clk, reset)
  BEGIN
    IF(reset = '1') THEN
	  state_reg <= Idle;
	  Flag_Start <= '0';
	  Flag_Tx <= '0';
	  counter <= X"0";
	  Ready_Idle <= '0';
	  Ready_Tx <= '0';
	  
	  B6 <= X"00";
	  B5 <= X"00";
	  B4 <= X"00";
	  B3 <= X"00";
	  B2 <= X"00";
	  B1 <= X"00";
	  Buf <= X"00";
	  
	ELSIF(clk'EVENT AND clk='1') THEN
	  state_reg <= state_next;
----------
	  IF((Start = '0')AND(Flag_Start = '1')) THEN
		Flag_Start <= '0';
	  END IF;
	  IF((Tx_Coreclk = '0')AND(Flag_Tx = '1')) THEN
		Flag_Tx <= '0';
	  END IF;
----------
	  IF(state_reg = Idle) THEN
		Tx_Out <= X"00";
--		Buf <= X"00";
		IF((Start = '1')AND(Flag_Start = '0')) THEN
		  Flag_Start <= '1';
		  B6 <= Tx_Buf(47 DOWNTO 40);
		  B5 <= Tx_Buf(39 DOWNTO 32);
		  B4 <= Tx_Buf(31 DOWNTO 24);
		  B3 <= Tx_Buf(23 DOWNTO 16);
		  B2 <= Tx_Buf(15 DOWNTO 8);
		  B1 <= Tx_Buf(7 DOWNTO 0);
		  counter <= X"0";
		  Ready_Idle <= '1';
		END IF;  
	  ELSE
		Ready_Idle <= '0';
	  END IF;
	  
	  IF(state_reg = Tx) THEN
      ---------
		IF(counter = X"0") THEN
		  IF((Tx_Coreclk = '1')AND(Flag_Tx = '0')) THEN
			Flag_Tx <= '1';
			counter <= X"1";
--			Tx_Out <= X"52";
			Tx_Out <= B6;
--			Buf <= B6;
		  END IF;
		END IF;
      ----------
		IF(counter = X"1") THEN
		  IF((Tx_Coreclk = '1')AND(Flag_Tx = '0')) THEN
			Flag_Tx <= '1';
			counter <= X"2";
--			Tx_Out <= X"50";
			Tx_Out <= B5;
--			Buf <= B5;
		  END IF;
		END IF;
      ----------
		IF(counter = X"2") THEN
		  IF((Tx_Coreclk = '1')AND(Flag_Tx = '0')) THEN
			Flag_Tx <= '1';
			counter <= X"3";
--			Tx_Out <= X"00";
			Tx_Out <= B4;
--			Buf <= B4;
		  END IF;
		END IF;
      ----------
		IF(counter = X"3") THEN
		  IF((Tx_Coreclk = '1')AND(Flag_Tx = '0')) THEN
			Flag_Tx <= '1';
			counter <= X"4";
--			Tx_Out <= X"00";
			Tx_Out <= B3;
--			Buf <= B3;
		  END IF;
		END IF;
      ----------
		IF(counter = X"4") THEN
		  IF((Tx_Coreclk = '1')AND(Flag_Tx = '0')) THEN
			Flag_Tx <= '1';
			counter <= X"5";
--			Tx_Out <= X"8D";
			Tx_Out <= B2;
--			Buf <= B2;
		  END IF;
		END IF;
      ----------
		IF(counter = X"5") THEN
		  IF((Tx_Coreclk = '1')AND(Flag_Tx = '0')) THEN
			Flag_Tx <= '1';
			counter <= X"6";
--			Tx_Out <= X"10";
			Tx_Out <= B1;
--			Buf <= B1;
		  END IF;
		END IF;
      ----------
		IF(counter = X"6") THEN
		  IF((Tx_Coreclk = '1')AND(Flag_Tx = '0')) THEN
			Flag_Tx <= '1';
			counter <= X"0";
			Tx_Out <= X"00";
--			Buf <= X"00";
			Ready_Tx <= '1';
		  END IF;
		END IF;
      ----------
	  ELSE
		Ready_Tx <= '0';
	  END IF;
---------	  
	END IF;
  END PROCESS;
  
------------
PROCESS(state_reg, Ready_Idle, Ready_Tx)
  BEGIN
  CASE state_reg IS
	WHEN Idle =>
	  IF(Ready_Idle = '1') THEN
		state_next <= Tx;
	  ELSE
		state_next <= Idle;
	  END IF;
	WHEN Tx =>
	  IF(Ready_Tx = '1') THEN
		state_next <= Idle;
	  ELSE
		state_next <= Tx;
	  END IF;	
  END CASE;
END PROCESS;

--- Output logic --------------------------------------------------------------------

--  Tx_Out <= Buf;

  sIdle <= '1' WHEN (state_reg = Idle) ELSE
		   '0';
  sTx <= '1' WHEN (state_reg = Tx) ELSE
		 '0';

END arch;
