--------------------------------------------------
-- SDRAM CONTROLLER COMPONENT DECLARATION 
--------------------------------------------------

	COMPONENT DDR2_SDRAM_CONTROLLER
	Generic (
	NSDRAM_BYTES: in integer := 8;
		-- number of data bytes on the SDRAM data bus 
		-- The same data width for both user data interface and DDR2 interface
		-- 1 = 8-bit word (IC)
		-- 2 = 16-bit word (IC, e.g. COM-1600)
		-- 4 = 32-bit word (ICs or partial DIMM/SODIMM)
		-- 8 = 64-bit word (DIMM/SODIMM, e.g. COM-1500)
	ADDRESS_MAP: in std_logic_vector(4 downto 0) := "10010";
		-- the logical to physical address mapping can vary depending on the hardware.
		-- See DDR2 SDRAM hardware specifications.
		-- the most common mappings are described below:
		-- 00000: 1Gb x8 IC, column A[9:0], 8 banks BA[2:0], row A[13:0], 1 rank CS# 
		-- 00001: 1Gb x16 IC, column A[9:0], 8 banks BA[2:0], row A[12:0], 1 rank CS#
		-- 00010: 2Gb x8 IC, column A[9:0], 8 banks BA[2:0], row A[14:0], 1 rank CS#
		-- 00011: 2Gb x16 IC, column A[9:0], 8 banks BA[2:0], row A[13:0], 1 rank CS#
		-- 0xxxx: other ICs, reserved for future use
		-- 10000: 1GB DIMM/SODIMM, column A[9:0], 8 banks BA[2:0], row A[12:0], 2 ranks S0#/S1#
		-- 10001: 2GB DIMM/SODIMM, column A[9:0], 8 banks BA[2:0], row A[13:0], 2 ranks S0#/S1#
		-- 10010: 4GB DIMM/SODIMM, column A[9:0], 8 banks BA[2:0], row A[14:0], 2 ranks S0#/S1#
		-- 1xxxx: other DIMM/SODIMMs, reserved for future use
	CLOCK_CYCLES: in integer := 3;
		-- (CAS latency) -  (RAS-CAS-Delay time) -  (RAS precharge time)
		-- CL - tRCD - tRP
		-- See DDR2 SDRAM hardware specifications.
		-- 3 =  3-3-3  DDR2-400
		-- 4 =  4-4-4  DDR2-533
		-- 5 =  5-5-5  DDR2-667
		-- 6 =  6-6-6  DDR2-800
	DDR2_CLK_FREQ: in integer := 2000;
		-- actual DDR2 clock frequency in 100KHz units (used to calculate timers within)
		-- For example: 2000 means a 200 MHz clock and a maximum throughput of 400 Mtransactions/s.
		-- The specified value can be significantly slower than the SDRAM DDR2 speed grade 
		-- (since the FPGA may be the bottleneck)
	RTDELAY_COARSE: in integer := 0
		-- calibrate out signal round-trip delay. 
		-- Coarse settings: integer multiple of the CLK period rounded up. 
	);
	PORT(
		SYNC_RESET : IN std_logic;
		CLK: in std_logic;
		START_ADDR : IN std_logic_vector(31 downto 0);
		TRANSACTION_REQ : IN std_logic_vector(1 downto 0);
		TRANSACTION_REQ_NO : IN std_logic_vector(3 downto 0);
		TRANSACTION_REQ_ACK : OUT std_logic;
		DATA_IN: in std_logic_vector((16*NSDRAM_BYTES - 1) downto 0);
		DATA_IN_CTS: out std_logic;
		DATA_OUT: out std_logic_vector((16*NSDRAM_BYTES - 1) downto 0);
		DATA_OUT_EN : OUT std_logic;
		SELF_REFRESH_REQ : IN std_logic;    
		SDRAM_DQ : INOUT std_logic_vector((8*NSDRAM_BYTES - 1) downto 0);
		SDRAM_DQS_P : INOUT std_logic_vector((NSDRAM_BYTES - 1) downto 0);
		SDRAM_DQS_N : INOUT std_logic_vector((NSDRAM_BYTES - 1) downto 0);      
		SDRAM_ODT : OUT std_logic_vector(1 downto 0);
		SDRAM_CK_P: out std_logic_vector(1 downto 0);
		SDRAM_CK_N: out std_logic_vector(1 downto 0);
		SDRAM_CKE: out std_logic_vector(1 downto 0);
		SDRAM_CASN : OUT std_logic;
		SDRAM_RASN : OUT std_logic;
		SDRAM_WEN : OUT std_logic;
		SDRAM_SN: out std_logic_vector(1 downto 0);
		SDRAM_DM : OUT std_logic_vector((NSDRAM_BYTES - 1) downto 0);
		SDRAM_BA : OUT std_logic_vector(2 downto 0);
		SDRAM_A : OUT std_logic_vector(15 downto 0);
		SDRAM_READY: OUT std_logic;
		SDRAM_TP : OUT std_logic_vector(10 downto 1)
		);
	END COMPONENT;
--------------------------------------------------
-- SDRAM CONTROLLER COMPONENT INSTANTIATION EXAMPLE
--------------------------------------------------
-- example: 16-bit DDR2 SDRAM 1Gbit IC
--

--// DDR2 INTERFACE
signal SDRAM_A_X: std_logic_vector(15 downto 0);
signal SDRAM_ODT_X: std_logic_vector(1 downto 0);
signal SDRAM_CK_P_X: std_logic_vector(1 downto 0);
signal SDRAM_CK_N_X: std_logic_vector(1 downto 0);
signal SDRAM_CKE_X: std_logic_vector(1 downto 0);
signal SDRAM_TP: std_logic_vector(10 downto 1);


Inst_DDR2_SDRAM_CONTROLLER: DDR2_SDRAM_CONTROLLER 
generic map(
	NSDRAM_BYTES => 2,
	ADDRESS_MAP => "00001",
	CLOCK_CYCLES => 3,
	DDR2_CLK_FREQ => 1400,
	RTDELAY_COARSE => 0
)
PORT MAP(	---------------------------------- USER SIDE
	SYNC_RESET => ASYNC_RESET,
	CLK => CLK_DDR2,
	START_ADDR => x"00000000",
	TRANSACTION_REQ => "00",
	TRANSACTION_REQ_NO => "0000",
	TRANSACTION_REQ_ACK => open,
	DATA_IN => x"00000000",
	DATA_IN_CTS => open,
	DATA_OUT => open,
	DATA_OUT_EN => open,
	SELF_REFRESH_REQ => '0',
	RTDELAY_CHECK => '0',
	SDRAM_DQ => SDRAM_DQ,  ------------------------ SDRAM SIDE
	SDRAM_DQS_P => SDRAM_DQS_P,
	SDRAM_DQS_N => SDRAM_DQS_N,
	SDRAM_ODT => SDRAM_ODT_X,
	SDRAM_CK_P => SDRAM_CK_P_X,
	SDRAM_CK_N => SDRAM_CK_N_X,
	SDRAM_CKE => SDRAM_CKE_X,
	SDRAM_CASN => SDRAM_CASN,
	SDRAM_RASN => SDRAM_RASN,
	SDRAM_WEN => SDRAM_WEN,
	SDRAM_SN => open,	-- SDRAM CS is always active at the chip
	SDRAM_DM => SDRAM_DM,
	SDRAM_BA => SDRAM_BA,
	SDRAM_A => SDRAM_A_X,
	SDRAM_TP => SDRAM_TP  ------------------------ ROUND-TRIP DELAY CHECK TEST POINTS
);
SDRAM_A <= SDRAM_A_X(12 downto 0);
SDRAM_ODT <= SDRAM_ODT_X(0);
SDRAM_CK_P <= SDRAM_CK_P_X(0);
SDRAM_CK_N <= SDRAM_CK_N_X(0);
SDRAM_CKE <= SDRAM_CKE_X(0);
