----------------------------------------------------------------------------------
-- Company: University of Connecticut
-- Engineer: Igor Senderovich
-- 
-- Create Date:    04:14:41 10/01/2007 
-- Design Name: 
-- Module Name:    S-Packet - Behavioral 
-- Description:    Assembles S-type packet - DAC values
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

library FPGA_BasicComp;
use FPGA_BasicComp.BasicComp.all;

entity SPacket is
    Port ( Clk : in  STD_LOGIC;
	   Rst : in STD_LOGIC;
	   Go : in STD_LOGIC;

	   LocStamp : in STD_LOGIC_VECTOR (7 downto 0);
	   PktNum : in STD_LOGIC_VECTOR (15 downto 0);

	   TempReg_Q : in  STD_LOGIC_VECTOR (15 downto 0);
	   ADCReg_Addr : out  STD_LOGIC_VECTOR (2 downto 0);
           ADCReg_Q : in  STD_LOGIC_VECTOR (15 downto 0);

	   RAwrGo   : out STD_LOGIC;
	   RAwrAddr : out STD_LOGIC_VECTOR (15 downto 0);
	   RAwrD    : out STD_LOGIC_VECTOR (7 downto 0);
	   RAwrDone : in  STD_LOGIC;

           TxRx_Go : out  STD_LOGIC;
           TxRx_RiW : out  STD_LOGIC;
           TxRx_A : out  STD_LOGIC_VECTOR (7 downto 0);
           TxRx_D : out  STD_LOGIC_VECTOR (7 downto 0);
           TxRx_Q : in STD_LOGIC_VECTOR (7 downto 0);
           TxRx_Done : in  STD_LOGIC;
			  
	   Done : out STD_LOGIC;
	   ser_Go : out STD_LOGIC;
  	   ser_D : out STD_LOGIC_VECTOR (7 downto 0)
	 );
end SPacket;

architecture Behavioral of SPacket is
	
	component RAwr2BtoAddr is
	    Port ( Clk : in  STD_LOGIC;
		   Rst : in STD_LOGIC;
		   Go : in STD_LOGIC;
		   RamAddr : in STD_LOGIC_VECTOR (15 downto 0); -- AddrH:AddrL
		   D : in STD_LOGIC_VECTOR (15 downto 0);        -- Data
		   RAwrGo   : out STD_LOGIC;
		   RAwrAddr : out STD_LOGIC_VECTOR (15 downto 0);
		   RAwrD    : out STD_LOGIC_VECTOR (7 downto 0);
		   RAwrDone : in  STD_LOGIC;
		   Done : out STD_LOGIC
		 );
	end component;

	signal Data : STD_LOGIC_VECTOR (15 downto 0);
	signal ChanCount : STD_LOGIC_VECTOR (5 downto 0);

	signal Done_Word : STD_LOGIC;-- := '0';
	signal Go_NextWord : STD_LOGIC;
	signal Go_Wr : STD_LOGIC;
	signal Go_TxEnd : STD_LOGIC;
	signal PermitNextWord : STD_LOGIC;
	signal En : STD_LOGIC;-- := '0';

begin
	
	-- write 2-byte word ('1' in MSB of addr just means increment from prev.)
	w: RAwr2BtoAddr
	port map (Clk, Rst, Go_Wr, X"F000", Data, 
		  RAwrGo, RAwrAddr, RAwrD, RAwrDone, Done_Word);
						
	PermitNextWord <= Done_Word and En;
	--u1: c_delay port map (Clk, PermitNextWord, Go_NextWord);
	--u1: Counter16bit port map (Clk, Rst, PermitNextWord, Go_NextWord);	
	u1: Counter4bit port map (Clk, Rst, PermitNextWord, Go_NextWord);	
	Go_Wr <= Go or Go_NextWord;	

	ADCReg_Addr <= ChanCount(2 downto 0) when Go_Wr='1' else "ZZZ";
	
	Go_TxEnd <= Done_Word and not En;

	-- pad to 46 bytes by setting TXENDH (0x57) & TXENDL (0x58) to 0x0040 
	uTxSt1: wr2BtoAddr
	port map (Clk, Rst, Go_TxEnd, X"57", X"0040", 
		  TxRx_Go, TxRx_A, TxRx_D, TxRx_RiW, TxRx_Done, Done);


	wrcontrol : process (Clk,Done_Word,Go,Go_TxEnd,ChanCount,LocStamp)
	begin
	
		if (Go='1') then
			Data <= X"0033";
			En <='1';
			ChanCount <= "001010";
		else
			if ChanCount(5 downto 4)="00" then
				case ChanCount(3 downto 0) is
					when "1001" => Data <= LocStamp & X"53";
					--when "1001" => Data <= PktNum;
					when "1000" => Data <= TempReg_Q;
					when others => Data <= ADCReg_Q;
				end case;
			else
				Data <= X"0000";
			end if;
			
			--Data <= PktNum;
			--Data <= X"000" & ChanCount(3 downto 0);
			
			if (rising_edge(Done_Word)) then
				if (ChanCount="001111") then -- crank this down by one and see
				--if (ChanCount="000000") then
					En <= '0';
					ChanCount <= ChanCount;
				else
					En <= En; 
					ChanCount <= ChanCount - "000001";
				end if;
			else
				ChanCount <= ChanCount;  En <= En;
			end if;
	
		end if;
	end process;

	ser_Go <= '0';--Go_Wr;
	ser_D  <= "ZZZZZZZZ";--Data(7 downto 0) when Go_Wr='1' else "ZZZZZZZZ";

end Behavioral;
