----------------------------------------------------------------------------------
-- Company: University of Connecticut
-- Engineer: Igor Senderovich
-- 
-- Create Date:    04:14:41 10/01/2007 
-- Design Name: 
-- Module Name:    D-Packet - Behavioral 
-- Description:    Assembles D-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;

library FPGA_BasicComp;
use FPGA_BasicComp.BasicComp.all;

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

	   LocStamp : in STD_LOGIC_VECTOR (7 downto 0);

	   DACReg_Addr : out  STD_LOGIC_VECTOR (4 downto 0);
           DACReg_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;
	   db : out STD_LOGIC
	 );
end DPacket;

architecture Behavioral of DPacket 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 (4 downto 0);

	signal Done_Word, Go_NextWord, Go_Wr, Go_TxEnd : STD_LOGIC;
	signal PermitNextWord, DataEn, preDACstage, LastWord : STD_LOGIC;

begin
	
	-- write 2-byte word
	w: RAwr2BtoAddr
	port map (Clk, Rst, Go_Wr, X"F000", Data, 
		  RAwrGo, RAwrAddr, RAwrD, RAwrDone, Done_Word);

	Go_TxEnd <= Done_Word and not (DataEn or preDACstage);
	PermitNextWord <= Done_Word and (DataEn or preDACstage);
	u1: c_delay port map (Clk, PermitNextWord, Go_NextWord);
	Go_Wr <= Go or Go_NextWord;

	DACReg_Addr <= ChanCount when DataEn='1' else "ZZZZZ";
	Data <=	X"0042" when Go='1' else
		LocStamp & X"44" when (preDACstage and Go_NextWord)='1' else 
		DACReg_Q when (DataEn and Go_NextWord)='1' else 
		"ZZZZZZZZZZZZZZZZ";


	-- pad to 84 bytes by setting TXENDH (0x57) & TXENDL (0x58) to 0x0054 
	u2: wr2BtoAddr
	port map (Clk, Rst, Go_TxEnd, X"57", X"004F",
		  TxRx_Go, TxRx_A, TxRx_D, TxRx_RiW, TxRx_Done, Done);

	wrcontrol : process (Clk,Done_Word,Go,Go_NextWord,ChanCount,DataEn,preDACstage)
	begin
		if (Go='1') then
			DataEn <='0'; preDACstage <= '1'; LastWord <= '0';
			ChanCount <= "00000";
		else
			if falling_edge(Go_NextWord) then
				preDACstage <= '0';
				if (DataEn='1' and ChanCount/="11111") then
					ChanCount <= ChanCount + "00001";
				else
					ChanCount <= ChanCount;
				end if;
			else
				preDACstage <= preDACstage;
			end if;

			if (rising_edge(Done_Word)) then
				DataEn <= not (preDACstage or LastWord);
			else
				DataEn <= DataEn;
			end if;

			if falling_edge(Clk) and Done_Word='1' and ChanCount="11111" then
				LastWord <= '1';
			end if;

		end if;
	
	end process;

	db <= Go_Wr;

end Behavioral;
