						----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    14:52:12 08/25/2010 
-- Design Name: 
-- Module Name:    pcie_to_ddr3_write_clockdomain_bridge - 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 using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

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

entity pcie_to_ddr3_write_clockdomain_bridge is
	port(
		-- pcie section
		pcie_rst : in std_logic;
		pcie_write_clk : in std_logic;
		pci_write_data_fifo_wr_en : in std_logic;
		pci_write_data_fifo_din : in std_logic_vector(255 downto 0);
		pci_write_addr_fifo_wr_en : in std_logic;
		pci_write_addr_fifo_din : in std_logic_vector(31 downto 0);
		
		-- ddr3 section
		ddr3_rst : in std_logic;
		ddr3_write_clk : in std_logic;
		ddr3_test_write_addr_fifo_wr_en : out std_logic;
		ddr3_test_write_addr_fifo_din : out std_logic_vector(31 downto 0);
		ddr3_test_write_data_fifo_wr_en : out std_logic;
		ddr3_test_write_data_fifo_din : out std_logic_vector(255 downto 0)
	);
end pcie_to_ddr3_write_clockdomain_bridge;

architecture Behavioral of pcie_to_ddr3_write_clockdomain_bridge is

	component dist_fifo_fwft_32x16
	port (
		rst: IN std_logic;
		wr_clk: IN std_logic;
		rd_clk: IN std_logic;
		din: IN std_logic_VECTOR(31 downto 0);
		wr_en: IN std_logic;
		rd_en: IN std_logic;
		dout: OUT std_logic_VECTOR(31 downto 0);
		full: OUT std_logic;
		empty: OUT std_logic;
		rd_data_count: OUT std_logic_VECTOR(4 downto 0);
		wr_data_count: OUT std_logic_VECTOR(4 downto 0));
	end component;

	component dist_fifo_fwft_256x16
	port (
		rst: IN std_logic;
		wr_clk: IN std_logic;
		rd_clk: IN std_logic;
		din: IN std_logic_VECTOR(255 downto 0);
		wr_en: IN std_logic;
		rd_en: IN std_logic;
		dout: OUT std_logic_VECTOR(255 downto 0);
		full: OUT std_logic;
		empty: OUT std_logic;
		rd_data_count: OUT std_logic_VECTOR(4 downto 0);
		wr_data_count: OUT std_logic_VECTOR(4 downto 0));
	end component;

	signal ctrl_fsm : std_logic_vector(1 downto 0);
	
	signal ddr3_addr_fifo_rcnt : std_logic_vector(4 downto 0);
	signal ddr3_data_fifo_ren : std_logic;
	signal ddr3_addr_fifo_ren : std_logic;

begin

	process(ddr3_write_clk)
	begin
		if rising_edge(ddr3_write_clk) then
			if ddr3_rst = '1' then
				ddr3_data_fifo_ren <= '0';
				ddr3_addr_fifo_ren <= '0';
				
				ctrl_fsm <= "00";
			else
				case ctrl_fsm is
					when "00" =>
						if (ddr3_addr_fifo_rcnt /= 0) then
							ddr3_data_fifo_ren <= '1';
							ddr3_addr_fifo_ren <= '1';
							
							ctrl_fsm <= "01";
						else
							ddr3_data_fifo_ren <= '0';
							ddr3_addr_fifo_ren <= '0';
							
							ctrl_fsm <= "00";
						end if;
					
					when "01" =>
						ddr3_data_fifo_ren <= '0';
						ddr3_addr_fifo_ren <= '0';
						
						ctrl_fsm <= "10";
					when "10" =>
						ddr3_data_fifo_ren <= '0';
						ddr3_addr_fifo_ren <= '0';
						
						ctrl_fsm <= "00";
						
					when others => null;
					
				end case;
			end if;
		end if;
	end process;
	
	ddr3_test_write_addr_fifo_wr_en <= ddr3_addr_fifo_ren;
	ddr3_test_write_data_fifo_wr_en <= ddr3_data_fifo_ren;


	clockdomain_addr_fifo : dist_fifo_fwft_32x16
	port map (
		rst => pcie_rst,
		wr_clk => pcie_write_clk,
		rd_clk => ddr3_write_clk,
		din => pci_write_addr_fifo_din,
		wr_en => pci_write_addr_fifo_wr_en,
		rd_en => ddr3_addr_fifo_ren,
		dout => ddr3_test_write_addr_fifo_din,
		full => open,
		empty => open,
		rd_data_count => ddr3_addr_fifo_rcnt,
		wr_data_count => open);
			
	clockdomain_data_fifo : dist_fifo_fwft_256x16
	port map (
		rst => pcie_rst,
		wr_clk => pcie_write_clk,
		rd_clk => ddr3_write_clk,
		din => pci_write_data_fifo_din,
		wr_en => pci_write_data_fifo_wr_en,
		rd_en => ddr3_data_fifo_ren,
		dout => ddr3_test_write_data_fifo_din,
		full => open,
		empty => open,
		rd_data_count => open,
		wr_data_count => open);

end Behavioral;

