-----------------------------------------------------------------
-- Project : agfo10_a.ise -- 25042008-RRI-RAL-hydrus-KPA
-- File : ip_dpram1.vhd -- gk,  06032008-RRI-RAL-crater
-- The original source code copied from Deepak. - Version 8
-- Modified for the Burst mode data acquisition.
-- This module (ip_dpram1.vhd) takes care of the input stage of 
-- the AgFo firmware.
-- 
-----------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library UNISIM;
use UNISIM.VComponents.all;
-----------------------------------------------------------------
entity ip_dpram1 is
    Port ( 
--	 usb_data_in         : in STD_LOGIC_VECTOR (31 downto 0);
--	 usb_load_in         : in STD_LOGIC;
--	 channel_no          : out STD_LOGIC_VECTOR (7 downto 0);
    ch_sel_reg          : in STD_LOGIC_VECTOR (7 downto 0);
    ch_sel_reg1         : in STD_LOGIC_VECTOR (7 downto 0);


    reset_in            : in std_logic;    
	 clk_in					: in std_logic;
	 sctn_in 				: in std_logic;
	 fout_in 				: in std_logic;
	 burst_rd_synch_in 	: in std_logic;
    burst_mode_in    	: in std_logic;
	 ch_sel_mode_in 	   : in std_logic;
	 ser_data_ready_in 	: in std_logic;
	 valid_data_5clk_in	: in std_logic;
	 read_start_in       : in std_logic;
	 read_started_in     : in std_logic;
	 data_in					: in std_logic_vector(9 downto 0);
	 
	 ram_dina_out 			: out std_logic_vector(9 downto 0);
    ram_addra_out			: out std_logic_VECTOR(9 downto 0);
    ram_wea_out 			: out std_logic_VECTOR(0 downto 0);
    ram_clkb_out 		   : out std_logic;
    ram_addrb_out 	   : out std_logic_VECTOR(9 downto 0);
	 
    valid_data        : out std_logic;
	 regceb_out				  : out std_logic;
    data_out				  : out std_logic_vector(9 downto 0);
	 burst_rd_complete_out : out std_logic
	 );
end ip_dpram1;
-----------------------------------------------------------------

architecture Behavioral of ip_dpram1 is
------------------- RAM IP-Core Component -----------------------
component ram1024
    port (
    clka		: IN std_logic;
    dina		: IN std_logic_VECTOR(9 downto 0);
    addra	: IN std_logic_VECTOR(9 downto 0);
    wea		: IN std_logic_VECTOR(0 downto 0);
    clkb		: IN std_logic;
    addrb	: IN std_logic_VECTOR(9 downto 0);
    regceb	: IN std_logic;
    doutb	: OUT std_logic_VECTOR(9 downto 0));
end component;

---------- XST black box declaration
attribute box_type : string;
attribute box_type of ram1024 : component is "black_box";

-----------------------------------------------------------------
signal wraddr,rdaddr, rdaddr_L1, rdaddr_L2, wraddr_L1 : std_logic_vector(9 downto 0) := "0000000000";
signal burst_wr_complete,burst_rd_complete,chsel_wr_complete,
       chsel_rd_complete : std_logic := '0';
signal sctnL1,foutL1,dataloadflag : std_logic := '0';
signal regceb,regceb_L1,regceb_L2,firstfoutflag : std_logic := '0';
signal start_burst_read, last_read, burst_rd_synchL1 : std_logic := '0';
signal wea : std_logic_VECTOR(0 downto 0);
signal regceb_clk_ratio,regceb_flag,start_wr,start_rd,valid_data_L3,valid_data_L2,valid_data_L1: std_logic;
signal regceb_counter : std_logic_vector(2 downto 0) := "000";
signal ser_data_ready,valid_data_5clk : std_logic;
signal data,marker,data_L1 : std_logic_vector(9 downto 0);

signal usbL1 : std_logic_vector(31 downto 0);
signal check_ld_low,usb_load_int,valid_load : std_logic;
----signal ch_sel_reg,ch_sel_reg1 : std_logic_vector(7 downto 0);

-----------------------------------------------------------------
begin
-----------------------------------------------------------------
-------------------------------------------------------------------
---- usb load decode
--------------------------------------------------------------------
--process(clk_in)
--begin
--  if clk_in'event and clk_in = '1' then 
--   if(reset_in = '1') then
--	  check_ld_low <= '0';
--	end if;  	
--   usb_load_int <= usb_load_in;
--  	if usb_load_int = '1' and check_ld_low = '0' then
--		  valid_load <= '1';
--		  check_ld_low <= '1';
--	elsif usb_load_int = '1' and check_ld_low = '1' then 	  
--		  valid_load <= valid_load ;
--		  check_ld_low <= check_ld_low;
--	elsif usb_load_int = '0' and check_ld_low = '1' then
--		  check_ld_low<= '0';
--		  valid_load <= valid_load;
--	elsif usb_load_int = '0' and check_ld_low = '0' then		
--		  valid_load <= valid_load ;
--		  check_ld_low<= '0';--check_ld_low;
--	end if;	  
--   if valid_load = '1' then
--	    valid_load <= '0';
--       usbL1 <= usb_data_in;
--   end if;	
--   ch_sel_reg <= usbL1(31 downto 24);	
--   ch_sel_reg1 <= ch_sel_reg + '1';	
--   channel_no <= usbL1(31 downto 24);	
--
--  end if;
--end process;
--
-------------------------------------------------------------------
--
--
process(clk_in)
begin
if(clk_in'event and clk_in= '1') then
 regceb_L1 <= regceb;
 regceb_L2 <= regceb_L1;	
 regceb_out <= regceb_L2;
 
 valid_data_L2 <= valid_data_L1;
 valid_data_L3 <= valid_data_L2;
 valid_data   <= valid_data_L3;
 
 rdaddr_L1 <= rdaddr;
 rdaddr_L2 <= rdaddr_L1;
 
 ser_data_ready <= ser_data_ready_in;
 valid_data_5clk <= valid_data_5clk_in;
 data <= data_in;
 
 wraddr_L1 <= wraddr;
 data_L1 <= data;

 sctnL1 <= sctn_in;
 foutL1 <= fout_in;
 burst_rd_synchL1 <= burst_rd_synch_in;

 if reset_in = '1' then
	  burst_rd_complete <= '1';
	  burst_rd_complete_out <= '1';
	  burst_wr_complete <= '0';
	  chsel_wr_complete <= '0';
	  chsel_rd_complete <= '1';
	  
	  wraddr <= (others => '0');
	  wea(0) <= '0';
	  rdaddr <= (others => '0');
	  regceb <= '0';
	  firstfoutflag <= '0';
	  dataloadflag <= '0';

	  start_burst_read <= '0';
	  last_read <= '0';
	  
     start_wr <= '0';
     start_rd <= '1';
     valid_data_L1 <= '0';


 else  
	if(burst_mode_in = '1') then 		 
	 if((ser_data_ready = '1')and(burst_rd_complete = '1')) then 
	  firstfoutflag <= '0';
	  if((valid_data_5clk='1') and (dataloadflag='0') )then
		 dataloadflag <= '1';
		 wea(0) <= '1';
	  elsif((valid_data_5clk='1') and (dataloadflag='1'))then
		 wea(0) <= '0';
		 dataloadflag <= dataloadflag;
	  elsif((valid_data_5clk='0') and (dataloadflag='1'))then	 
			wea(0) <= '0';
			dataloadflag <= '0';
	  elsif((valid_data_5clk='0') and (dataloadflag='0'))then	 
			wea(0) <= '0';
			dataloadflag <= '0';
	  end if;
   
  	  if(wea(0)='1') then
		 if(wraddr = 1023) then
--		 if(wraddr = 110) then  -- for checking
		   burst_wr_complete <= '1';
			burst_rd_complete <= '0';
			burst_rd_complete_out <= '0';
			wraddr <= (others => '0');
		 else
		  burst_wr_complete <= '0';
		  wraddr <= wraddr + '1'; 
		 end if; 
	  else
		 wraddr <= wraddr;
	  end if;
    elsif((ser_data_ready = '0') and (burst_rd_complete = '0')) then
	  burst_wr_complete <= burst_wr_complete;
	  wraddr <= (others => '0');
	  wea(0) <= '0';
    elsif((ser_data_ready = '0') and (burst_rd_complete = '1') and wraddr = 1023) then
--	 elsif((ser_data_ready = '0') and (burst_rd_complete = '1') and wraddr = 110) then  -- for checking
	  burst_wr_complete <= '0';
	  wraddr <= (others => '0');
	  wea(0) <= '0';
	 elsif((ser_data_ready = '0') and (burst_rd_complete = '1') and wraddr < 1023) then
--	 elsif((ser_data_ready = '0') and (burst_rd_complete = '1') and wraddr < 110) then	 
	  burst_wr_complete <= burst_wr_complete;
	  wraddr <= (others => '0');
	  wea(0) <= '0';	 
    elsif((ser_data_ready = '1') and (burst_rd_complete = '0')) then
	  wraddr <= wraddr;
	  wea <= wea;
	  burst_wr_complete <= burst_wr_complete; 
	 end if;
	
	elsif(ch_sel_mode_in = '1') then   -- for the channel selection mode
	 if((ser_data_ready = '1')and(chsel_rd_complete = '1')) then 
	  if((valid_data_5clk='1') and (dataloadflag='0') )then
		 dataloadflag <= '1';
		 wea(0) <= '1';
	  elsif((valid_data_5clk='1') and (dataloadflag='1'))then
		 wea(0) <= '0';
		 dataloadflag <= dataloadflag;
	  elsif((valid_data_5clk='0') and (dataloadflag='1'))then	 
			wea(0) <= '0';
			dataloadflag <= '0';
	  elsif((valid_data_5clk='0') and (dataloadflag='0'))then	 
			wea(0) <= '0';
			dataloadflag <= '0';
	  end if;
--------------------------------------------------------------------
  	  if(wea(0)='1') then
--		 if(wraddr = 24) then   -- frozen for 24 channels
		 if(wraddr = ch_sel_reg1) then  -- selection from usb 
		    marker <= data;
          wraddr <= wraddr + '1'; 
--		 elsif (wraddr > 24) then  -- frozen for 24 channels
		 elsif (wraddr > ch_sel_reg1) then  -- selection from usb  
          wraddr <= (others => '0');
       elsif (wraddr = 0 and start_wr = '0') then 
          start_wr <= '1';
	 	    wraddr <= wraddr + '1'; 
		 else
 	 	    wraddr <= wraddr + '1'; 
		 end if; 
	  else
		 wraddr <= wraddr;
	  end if;
--
--=========================================================

	 elsif (ser_data_ready = '0') then 
          wraddr <= (others => '0');
          wea(0) <= '0';
      
--	  if(wea(0)='1') then
--     	  chsel_wr_complete <= '1';
--		  chsel_rd_complete <= '0';
--		  wraddr <= (others => '0');
--	  end if;	  
    end if ;
	end if; 
	
	
---- For reading the RAM burstmode
	if(burst_mode_in = '1') then 
    
	 if((burst_wr_complete = '1')and(burst_rd_complete='0')) then

     if(burst_rd_synchL1 = '1' and start_burst_read = '0') then
	    rdaddr <= (others => '0');
		 start_burst_read <= '1';
		 last_read <= '0';
  	  elsif(foutL1 = '1' and start_burst_read = '1' and rdaddr < 1023 and last_read = '0') then 
--   elsif(foutL1 = '1' and start_burst_read = '1' and rdaddr < 110 and last_read = '0') then 	  
		 regceb <= '1';
		 rdaddr <= rdaddr + '1';
	  elsif(foutL1 = '1' and start_burst_read = '1' and rdaddr = 1023 and last_read = '0') then
--	  elsif(foutL1 = '1' and start_burst_read = '1' and rdaddr = 110 and last_read = '0') then 	  
	    regceb <= '1';
		 last_read <= '1';
	  elsif(foutL1 = '1' and start_burst_read = '1' and last_read = '1') then		 
		 burst_wr_complete <= '0';
		 burst_rd_complete <= '1';
		 burst_rd_complete_out <= '1';
		 rdaddr <= (others => '0');
		 last_read <= '0';
		 start_burst_read <= '0';
     end if;    
	  
	  if(regceb = '1') then   -- put here for burst mode Anish 09-03-2009
	     regceb <= '0';
     end if;
	 end if; 
	 
   elsif(ch_sel_mode_in = '1') then   -- For reading the RAM Channel Selection mode
		
--	  if(foutL1 = '1' and chsel_rd_complete = '0') then
--	     regceb <= '1';
--		  rdaddr <= (others => '0');
--		  chsel_wr_complete <= '0';
--	     chsel_rd_complete <= '1';
--     end if;
--	   if(foutL1 = '1' and start_wr = '1' and rdaddr = 0 and regceb = '0' ) then
	   if(foutL1 = '1' and start_wr = '1' and rdaddr = 0) then
	      regceb <= '1';
		   rdaddr <= rdaddr + '1';
			start_rd <= '0';
			valid_data_L1 <= '1';
--	   elsif (foutL1 = '0' and start_rd = '0' and rdaddr < 23 and regceb = '0') then -- for 24 channels
--	   elsif (foutL1 = '0' and start_rd = '0' and rdaddr > 0 and rdaddr < 23) then -- for 24 channels
	   elsif (foutL1 = '0' and start_rd = '0' and rdaddr > 0 and rdaddr < ch_sel_reg) then -- for 24 channels
		   rdaddr <= rdaddr + '1';
	      regceb <= '1';
--      elsif (foutL1 = '0' and start_rd = '0' and rdaddr = 23 and regceb = '0') then -- for 24 channels
--      elsif (foutL1 = '0' and start_rd = '0' and rdaddr = 23) then -- for 24 channels
      elsif (foutL1 = '0' and start_rd = '0' and rdaddr = ch_sel_reg) then -- for 24 channels
     	   regceb <= '1';
         start_rd <= '1';
         rdaddr <= (others => '0');
			start_wr <= '0';
	   elsif(start_wr = '0') then
         regceb <= '0';	
			valid_data_L1 <= '0';
      end if;
   end if;  
  
 end if;
end if; 
end process;
-----------------------------------------------------------------	
dpram_inst1 : ram1024
        port map (
            clka 		=> clk_in,
            dina 		=> data_L1,  -- data   - earlier used signal
            addra 	=> wraddr_L1,-- wraddr - earlier used signal
            wea 		=> wea,
            clkb 		=> clk_in,
            addrb 	=> rdaddr_L1,--rdaddr_L2,  --
            regceb 	=> regceb_L2,--regceb_L1,  --
            doutb 	=> data_out
				);
----------------------------------------------------------------- 
ram_dina_out 		<= data;
ram_addra_out		<= wraddr;
ram_wea_out 		<= wea;
ram_clkb_out 		<= clk_in;
ram_addrb_out 	   <= rdaddr_L2;   --rdaddr;

end Behavioral;
--===============================================================

------ end of file : ip_dpram1.vhd ------------------------------
