----------------------------------------------------------------------------------
-- 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;

