----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    11:23:01 02/25/2009 
-- Design Name: 
-- Module Name:    packetization - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;

entity packetization is
    Port ( rst 			: in  STD_LOGIC;
			  TX_RST  		: in  STD_LOGIC;
			  clk_125 		: in  STD_LOGIC; -- read clk 125Mhz
			  clk_165 		: in std_logic;
			  sctn_in 		: in STD_LOGIC;
           sig 			: in  STD_LOGIC_VECTOR (1 downto 0); -- fibre no
           start_rd 		: in  STD_LOGIC;           
			  data_in 		: in STD_LOGIC_VECTOR (79 downto 0); -- read data from RAM
		  
	  		  fibre_no		: in STD_LOGIC_VECTOR(2 downto 0);
			  no_ch_fibre1 : in STD_LOGIC_VECTOR(2 downto 0);   --0 to 7 chs
			  no_ch_fibre2 : in STD_LOGIC_VECTOR(2 downto 0);   --8 to 15 chs
			  no_ch_fibre3	: in STD_LOGIC_VECTOR(2 downto 0);  --16 to 23 chs
			  no_ch_fibre4	: in STD_LOGIC_VECTOR(2 downto 0); --24 to 31 chs	
			  node_in		: in STD_LOGIC_VECTOR(7 downto 0); --24 to 31 chs			  
				  
--OUTPUTS			  
			  addrb			: out std_logic_VECTOR(3 downto 0);  -- addr to ram
           rd_complete 	: out  STD_LOGIC;             -- to ram
           dout 			: out  STD_LOGIC_VECTOR (15 downto 0);  --to MGT
			  charisk 		: out std_logic_vector (1 downto 0); -- to MGT;
  			  txchardispmode: out std_logic_vector (1 downto 0); -- to MGT;
  			  txchardispval: out std_logic_vector (1 downto 0) -- to MGT;
			  

			 ); 
end packetization;

architecture PACK of packetization is

signal data_inL1 : std_logic_vector(79 downto 0); -- latch i/p data

signal rst_125,rst_165,start_rd_125,sctn_ack,sctn_ack_125,sctn_on,sctn_on_125,start_rd_int,start_rd_intL1  : std_logic;
signal k_char : std_logic_vector(15 downto 0) := X"BCBC" ;
signal header : std_logic_vector(15 downto 0) := X"0800" ;
signal checksum : std_logic_vector(15 downto 0);
signal seq : std_logic_vector(21 downto 0) := (others => '0');
signal node : std_logic_vector(7 downto 0) := X"00";

signal countera,counterb,counterb_int,counterc : std_logic_vector(3 downto 0);
signal counterd : std_logic_vector(6 downto 0);
signal no_ch_fibre_cnt : std_logic_vector(2 downto 0);
signal no_ch_fibre : std_logic_vector(2 downto 0);
signal addrb_int,addrb_int1,addrb_int2 : std_logic_vector(3 downto 0);


BEGIN

process(clk_165)
begin
  if clk_165'event and clk_165 = '1' then
      rst_165 <= rst;
		sctn_ack <= sctn_ack_125;
		if(rst_165 = '1') then
		  sctn_on <= '0';
		elsif sctn_in = '0' and sctn_ack = '0' then
			sctn_on <= '1'; 
		elsif sctn_ack = '1' then
		   sctn_on <= '0';
	   end if;		
 end if;
end process; 

 process(clk_125)
 begin 
   if clk_125'event and clk_125 = '1' then 
	 rst_125 <= TX_RST; --rst;
--	 start_rd_int <= start_rd; 
--	 start_rd_125 <= start_rd_int;
	 start_rd_intL1 <= start_rd;
    sctn_on_125 <= sctn_on;
    data_inL1 <= data_in;
	 addrb <= addrb_int;
	
--	 if enb_temp = '1' then
--	     enb_temp <= '0';
--    end if;  
	 
	 if rst_125 = '1' then
		      addrb_int <= (others => '0');
--				enb_temp <= '0';
     		   rd_complete <= '0';
				checksum <= (others => '0');
				dout <= k_char;
				charisk <= "11";
				countera <= (others => '0');
				counterb <= (others => '0');
				counterc <= (others => '0');
				counterd <= (others => '0');
				no_ch_fibre_cnt <= (others => '0');
				sctn_on_125 <= '0';
				sctn_ack_125 <= '0';
				seq <= (others => '0');
				
				txchardispval  <= "00";
				txchardispmode <= "00";
	 else
      if start_rd_intL1 = '1' and counterd = 0 then
			start_rd_125 <= '1';
		end if;
		  if start_rd_125 = '1' and countera = 0 then
			    charisk <= "00";
				 txchardispval  <= "00";
				 txchardispmode <= "00";
				 
				 dout <= header;    															--header
				 checksum <= checksum xor header;
				 countera <= countera + '1';
		   elsif start_rd_125 = '1' and countera = 1 then
			    charisk <= "00";
 				 txchardispval  <= "00";
				 txchardispmode <= "00";
				 
				 dout <= node & sig & seq(21 downto 16);								--node,sig,seq
  				 checksum <=  checksum xor (node & sig & seq(21 downto 16));
				 countera <= countera + '1';
			 elsif start_rd_125 = '1' and countera = 2 then
 			    charisk <= "00";
				 txchardispval  <= "00";
				 txchardispmode <= "00";
				 
				 dout <= seq(15 downto 0);													--seq
				 checksum <=  checksum xor  seq(15 downto 0);
				 countera <= countera + '1';
--				 enb <= '1';
--				 enb_temp <= '1';
				 addrb_int <= "0001";
--				 counterb <= counterb + '1';
			 elsif start_rd_125 = '1' and  countera = 3 then		 			--    
				   charisk <= "00";
					txchardispval  <= "00";
					txchardispmode <= "00";
					
					if start_rd_125 = '1' and counterb < 4 then
						counterb <= counterb + '1';
					end if;
					
					if  counterb = 0 then
						dout <= data_inL1(15 downto 0);
						checksum <=  checksum xor  data_inL1(15 downto 0);
--						addrb_int <= addrb_int + '1';
					elsif counterb = 1 then
						dout <= data_inL1(31 downto 16);
						checksum <=  checksum xor  data_inL1(31 downto 16);

					elsif  counterb = 2 then
						dout <= data_inL1(47 downto 32);
						checksum <=  checksum xor  data_inL1(47 downto 32);
					elsif  counterb = 3 then
						dout <= data_inL1(63 downto 48);
						checksum <=  checksum xor  data_inL1(63 downto 48);
					elsif counterb = 4 then
						dout <= data_inL1(79 downto 64);
						checksum <=  checksum xor  data_inL1(79 downto 64);
--						enb <= '1';
--						enb_temp <= '1';
						addrb_int <= addrb_int + '1';
						counterb <= (others => '0');
   					counterc <= counterc + '1';
						if counterc = 1 and no_ch_fibre_cnt < no_ch_fibre then 
							counterc <= (others => '0');
							no_ch_fibre_cnt <= no_ch_fibre_cnt +'1';
						elsif counterc = 1 and no_ch_fibre_cnt = no_ch_fibre then
							counterc <= (others => '0');
							addrb_int <= (others => '0');
							no_ch_fibre_cnt <= (others => '0');
							countera <= countera +'1';
						end if;	
					end if;
			 elsif  start_rd_125 = '1' and countera = 4 then		
					charisk <= "00";			 
					dout <= checksum;
					countera <= countera +'1';
					rd_complete <= '1';
					txchardispval  <= "00";
					txchardispmode <= "00";
			 elsif start_rd_125 = '1' and countera = 5 then
					charisk <= "11";	
					checksum <= (others => '0');	
					txchardispval  <= "01";
					txchardispmode <= "11";
					dout <= k_char;
					countera <= countera + '1';
					if (sctn_on_125 = '1') then
					  seq <= (others => '0');
					  sctn_ack_125 <= '1';
					else
                 seq <= seq + '1';
					  sctn_ack_125 <= '0';
					end if;					
			elsif start_rd_125 = '1' and countera = 6 then
					charisk <= "11";	
					txchardispval  <= "00";
					txchardispmode <= "00";
					dout <= k_char;
					countera <= countera + '1';
			end if;	
--			if counterd < 84 and start_rd_125 = '1' then 
			if counterd < 85 and start_rd_125 = '1' then 
				counterd <= counterd + 1;
--			elsif counterd >= 84 then
			elsif counterd >= 85 then
				countera <= (others => '0') ;
				start_rd_125 <= '0';
				counterd <= (others => '0') ;
			end if;  
      end if;   
   end if;
end process;


process(clk_125)
begin
  if clk_125'event and clk_125 = '1' then 
	  node <= node_in; --usbL1(23 downto 16);
  if sig  = "00" then
	  no_ch_fibre <= no_ch_fibre1;--usbL1(5 downto 3);
  elsif sig = "01" then
	  no_ch_fibre<= no_ch_fibre2; --usbL1(8 downto 6); 
  elsif sig = "10" then
	  no_ch_fibre<= no_ch_fibre3; --usbL1(11 downto 9);  
  elsif sig = "11" then
	  no_ch_fibre<= no_ch_fibre4; --usbL1(14 downto 12);  
  end if;
  end if;

end process;

	
end PACK;

