----------------------------------------------
-- MSS copyright 1999-2011
-- Filename: DDR2_SDRAM_CONTROLLER_TEST.VHD 
-- Version: Rev 1b
-- Last modified: 10/30/11
-- Authors: 
-- 	Adam Kwiatkowski / MSS
--		Alain Zarembowitch / MSS
-- Inheritance: DDR2_SDRAM_CONTROLLER_TEST.VHD, 6-04-07 (COM-1500)
-- 
-- Description: 
-- Checks the DDR2 SDRAM controller proper operation and return a status code (ok, etc)
-- The DDR2_SDRAM_CONTROLLER_TEST checks the SDRAM by writing to a range of addresses, 
-- then reads back the data from the same address range to compare with the original data.
--
-- Rev 1b 10/28/11 AZ 
-- editorial + detect FAILED_BITS word
-- 
----------------------------------------------
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 DDR2_SDRAM_CONTROLLER_TEST is
	Generic (

	NSDRAM_BYTES: in integer;
		-- 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)
	NCLKS: in integer := 1;
		-- number of differential clock pairs: 1 for IC, 2 for SODIMM
	ADDRESS_MAP: in std_logic_vector(4 downto 0);
		-- 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;
		-- (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;
		-- 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
		-- goal: calibrate out signal round-trip delay. 
		-- Coarse settings: integer multiple of the 1/2 CLK period rounded up. 
		-- Fine calibration (within 1/2 CLK period) is automatic.
		-- Example Spartan-6 125 MHz: 
		--    Output delay for SDRAM_CKx: 9ns
		--    Input delay for SDRAM_DQSy: 4ns
		--    RTDELAY_COARSE = 13ns*2*125MHz =  3.25 rounded up to 4.
	);
port (
	ASYNC_RESET : IN std_logic;
	CLK_DDR2_REF : IN std_logic;
	CLK_DDR2G_OUT: out std_logic;

	--// test range
	ADDR_MIN: in std_logic_vector(31 downto 0);
	ADDR_MAX: in std_logic_vector(31 downto 0);
		-- address range for testing SDRAM write/read from ADDR_MIN (inclusive) to ADDR_MAX (exclusive)
		-- address is expressed in DDR2 SDRAM words (1 word = SDRAM data bus width)
		
	--// test results
	DONE: out std_logic;
		-- 1 when the test is complete
	SUCCESS: out std_logic;
		-- 1 when all words read from SDRAM are correct
	ERROR: out std_logic;
		-- 1 when a read word is incorrect (short pulse)
	FAILED_BITS: out std_logic_vector(127 downto 0);
		-- read when DONE = '1'
		-- helps diagnoise hardware problems related to the data bus (bad memory, PCB, assembly, shorts, etc)
		

--	FIRST_FAILED_ADDRESS: out std_logic_vector(30 downto 0);
		-- read when DONE = '1'
		
	
	--// DDR2 SDRAM Interface (Direct connection to SDRAM I/O pins)
	SDRAM_DQ: inout std_logic_vector((8*NSDRAM_BYTES - 1) downto 0);
		-- Bi-directional data lines. DDR
	SDRAM_DQS_P: inout std_logic_vector((NSDRAM_BYTES - 1) downto 0);
	SDRAM_DQS_N: inout std_logic_vector((NSDRAM_BYTES - 1) downto 0);
		-- Bi-directional data strobe lines (differential)

	SDRAM_ODT : OUT std_logic_vector(1 downto 0);
	
	-- clocks
	SDRAM_CK_P: out std_logic_vector((NCLKS - 1) downto 0);
	SDRAM_CK_N: out std_logic_vector((NCLKS - 1) downto 0);
		-- clocks 0/1 (differential)
	SDRAM_CKE: out std_logic_vector((NCLKS - 1) downto 0);
		-- clock 0/1 enable
	SDRAM_CASN: out std_logic;
	SDRAM_RASN: out std_logic;
	SDRAM_WEN: out std_logic;
	SDRAM_SN: out std_logic_vector(1 downto 0);
		--	Chip Select # (rank 0/1)
	
	SDRAM_DM: out std_logic_vector((NSDRAM_BYTES - 1) downto 0);
		-- Input Data Mask
	
	-- Address signals
	SDRAM_BA: out std_logic_vector(2 downto 0);
	SDRAM_A: out std_logic_vector(15 downto 0); 
		 --Address lines. 
		
	SDRAM_DQ_DIR: out std_logic;
	SDRAM_DQS_DIR: out std_logic;
		-- direction of the bi-directional bus SDRAM_DQ and SDRAM_DQS
		-- for use in simulating a delay between FPGA and SDRAM
		
   --// Test Points
   TEST_POINTS: out std_logic_vector(20 downto 1)
		
);
end entity;

architecture Behavioral of ddr2_sdram_controller_test is
-----------------------------------------------------------------
-- COMPONENTS
-----------------------------------------------------------------
	COMPONENT DDR2_SDRAM_CONTROLLER
	Generic (
	PLATFORM: integer := 6;
		-- 5 = Xilinx Virtex-5
		-- 6 = Xilinx Spartan-6
	NSDRAM_BYTES: in integer := 2;
		-- 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)
	NCLKS: in integer := 1;
		-- number of differential clock pairs: 1 for IC, 2 for SODIMM
	ADDRESS_MAP: in std_logic_vector(4 downto 0) := "00001";
		-- 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 := 1250;
		-- actual DDR2 clock frequency in 100KHz units (used to calculate timers within)
		-- For example: 1250 means a 125 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 := 2
		-- goal: calibrate out signal round-trip delay. 
		-- Coarse settings: integer multiple of the 1/2 CLK period rounded up. 
		-- Fine calibration (within 1/2 CLK period) is automatic.
		-- Example Spartan-6 125 MHz: 
		--    Output delay for SDRAM_CKx: 9ns
		--    Input delay for SDRAM_DQSy: 4ns
		--    RTDELAY_COARSE = 13ns*2*125MHz =  3.25 rounded up to 4.
	);
	PORT(
		CLK_DDR2_REF: in std_logic; 
		ASYNC_RESET: in std_logic;
		CLK_DDR2G_OUT: out 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((NCLKS - 1) downto 0);
		SDRAM_CK_N: out std_logic_vector((NCLKS - 1) downto 0);
		SDRAM_CKE: out std_logic_vector((NCLKS - 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_DQ_DIR: out std_logic;
		SDRAM_DQS_DIR: out std_logic;
		SDRAM_TP : OUT std_logic_vector(10 downto 1)
		);
	END COMPONENT;

-----------------------------------------------------------------
-- SIGNALS
-----------------------------------------------------------------
signal CLK: std_logic := '0';

signal SDRAM_TP : std_logic_vector(10 downto 1) := (others => '0');

--// SDRAM CONTROLLER 
signal SDRAM_READY: std_logic := '0';
signal BURST_START_ADDR : std_logic_vector(31 downto 0) := x"00000000";
signal BURST_START_ADDR_PLUS4 : std_logic_vector(31 downto 0) := (others => '0');
signal TRANSACTION_REQ: std_logic_vector(1 downto 0) := "00";
signal TRANSACTION_REQ_NO: std_logic_vector(3 downto 0) := "0000";
signal TRANSACTION_REQ_ACK: std_logic := '0';
signal DATA_IN_CTS: std_logic := '0';
signal DATA_IN_CTS_D: std_logic := '0';
signal DATA_IN : std_logic_vector(127 downto 0) := (others => '0');
signal DATA_OUT : std_logic_vector((16*NSDRAM_BYTES - 1) downto 0) := (others => '0');
signal DATA_OUT_D : std_logic_vector((16*NSDRAM_BYTES - 1) downto 0) := (others => '0');
signal DATA_OUT_D2 : std_logic_vector((16*NSDRAM_BYTES - 1) downto 0) := (others => '0');
signal DATA_OUT_EN: std_logic := '0';
signal DATA_OUT_EN_D: std_logic := '0';
signal DATA_OUT_EN_D2: std_logic := '0';


--// SCHEDULER
signal STATE: integer range 0 to 31 := 0;
signal DATA_REPLICA : std_logic_vector(127 downto 0) := (others => '0');
signal NONMATCHINGWORDSCNT: std_logic_vector(31 downto 0) := (others => '0');
signal DATABYTE_COMPARE: std_logic_vector(15 downto 0) := (others => '0');

--// MONITORING
signal SUCCESS_local: std_logic := '1';
signal FAILED_BITS_local: std_logic_vector(127 downto 0) := (others => '0');

-----------------------------------------------------------------
-- IMPLEMENTATION
-----------------------------------------------------------------
begin

CLK_DDR2G_OUT <= CLK;

--//------ TEST SCHEDULER --------------------------------------
SCHEDULER_001: process(ASYNC_RESET, CLK)
begin
	if (ASYNC_RESET = '1') then
		STATE <= 0;
		DONE <= '0';
	elsif rising_edge(CLK) then
		if(STATE = 0) and (SDRAM_READY = '1') then
			-- write from start address to stop address
			STATE <= 1;
			DONE <= '0';
		elsif(STATE = 1) and (TRANSACTION_REQ_ACK = '1') and (BURST_START_ADDR_PLUS4 >=  ADDR_MAX)then
			-- read from start address to stop address
			STATE <= 2;
		elsif(STATE = 2) and (TRANSACTION_REQ_ACK = '1') and (BURST_START_ADDR_PLUS4 >=  ADDR_MAX)then
			-- done initiating reading requests. goto state 4 to wait for end of read data.
			STATE <= 3;
		elsif(STATE = 3) and (DATA_OUT_EN = '0') then
			-- check is now complete
			STATE <= 4;	
			DONE <= '1';
		end if;
	end if;
end process;

BURST_START_ADDR_GEN: process(ASYNC_RESET, CLK)
begin
	if (ASYNC_RESET = '1') then
		TRANSACTION_REQ <= "00";	-- no transaction request: idle
		TRANSACTION_REQ_NO <= "0000";
	elsif rising_edge(CLK) then
		if(STATE = 0) and (SDRAM_READY = '1') then
			-- write from ADDR_MIN to ADDR_MAX-1
			BURST_START_ADDR <= ADDR_MIN;
			BURST_START_ADDR_PLUS4 <= ADDR_MIN + 4;	-- BL = 4. compute ahead (for best timing)
			TRANSACTION_REQ <= "10";	-- burst write transaction requested
			TRANSACTION_REQ_NO <= TRANSACTION_REQ_NO + 1;
		elsif(STATE = 1) and (TRANSACTION_REQ_ACK = '1') and (BURST_START_ADDR_PLUS4 <  ADDR_MAX)then
			-- continue writing
			BURST_START_ADDR <= BURST_START_ADDR_PLUS4;	-- Burst length BL = 4
			BURST_START_ADDR_PLUS4 <= BURST_START_ADDR_PLUS4 + 4;	-- BL = 4 compute ahead (for best timing)
			--TRANSACTION_REQ <= "10";	-- burst write transaction requested
			TRANSACTION_REQ_NO <= TRANSACTION_REQ_NO + 1;
		elsif(STATE = 1) and (TRANSACTION_REQ_ACK = '1') and (BURST_START_ADDR_PLUS4 >=  ADDR_MAX)then
			-- done writing. Read first word from ADDR_MIN
			BURST_START_ADDR <= ADDR_MIN;
			BURST_START_ADDR_PLUS4 <= ADDR_MIN + 4;	-- BL = 4 compute ahead (for best timing)
			TRANSACTION_REQ <= "01";	-- burst read transaction requested
			TRANSACTION_REQ_NO <= TRANSACTION_REQ_NO + 1;
		elsif(STATE = 2) and (TRANSACTION_REQ_ACK = '1') and (BURST_START_ADDR_PLUS4 <  ADDR_MAX)then
			-- continue reading
			BURST_START_ADDR <= BURST_START_ADDR_PLUS4;  -- Burst length BL = 4
			BURST_START_ADDR_PLUS4 <= BURST_START_ADDR_PLUS4 + 4;	-- BL = 4 compute ahead (for best timing)
			--TRANSACTION_REQ <= "01";	-- burst read transaction requested
			TRANSACTION_REQ_NO <= TRANSACTION_REQ_NO + 1;
		elsif(STATE = 2) and (TRANSACTION_REQ_ACK = '1') and (BURST_START_ADDR_PLUS4 >=  ADDR_MAX)then
			-- done 
			TRANSACTION_REQ <= "00";	-- no transaction request: idle
		end if;
	end if;
end process;


--//------ WRITE TO SDRAM ------------------------------------
-- data must be provided exactly 2 CLKs after the clear to send DATA_IN_CTS
DATA_IN_GEN: process(CLK)
begin
	if rising_edge(CLK) then
		DATA_IN_CTS_D <= DATA_IN_CTS;
		
		if(STATE = 0) and (SDRAM_READY = '1') then
			-- write from start address to stop address
			DATA_IN <= (others => '0');
		elsif(DATA_IN_CTS_D = '1') then
			-- continue writing. 2 16-bit words per period
			DATA_IN(7 downto 0) <= DATA_IN(7 downto 0) + x"FB";	-- 251 is prime
			DATA_IN(15 downto 8) <= DATA_IN(15 downto 8) + x"61";	-- 97 is prime
			DATA_IN(23 downto 16) <= DATA_IN(23 downto 16) + x"3D";	-- 61 is prime
			DATA_IN(31 downto 24) <= DATA_IN(31 downto 24) + x"95";	-- 149 is prime
			DATA_IN(41 downto 32) <= DATA_IN(41 downto 32) + 1;
			DATA_IN(51 downto 42) <= DATA_IN(51 downto 42) + 1;
			DATA_IN(61 downto 52) <= DATA_IN(61 downto 52) + 1;
			DATA_IN(71 downto 62) <= DATA_IN(71 downto 62) + 1;
			DATA_IN(81 downto 72) <= DATA_IN(81 downto 72) + 1;
			DATA_IN(91 downto 82) <= DATA_IN(91 downto 82) + 1;
			DATA_IN(101 downto 92) <= DATA_IN(101 downto 92) + 1;
			DATA_IN(111 downto 102) <= DATA_IN(111 downto 102) + 1;
			DATA_IN(121 downto 112) <= DATA_IN(121 downto 112) + 1;
			DATA_IN(127 downto 122) <= DATA_IN(127 downto 122) + 1;
		end if;
	end if;
end process;

--//------ READ FROM SDRAM AND COMPARE ------------------------------------
-- generate a data replica aligned with received data DATA_OUT_D
DATA_REPLICA_GEN: process(CLK)
begin
	if rising_edge(CLK) then
		if(STATE = 0) or (STATE = 1) then
			-- reset data sequence
			DATA_REPLICA <= (others => '0');
		elsif((STATE = 2) or (STATE = 3)) and (DATA_OUT_EN = '1') then
			-- continue writing. 2 words per period
			DATA_REPLICA(7 downto 0) <= DATA_REPLICA(7 downto 0) + x"FB";	-- 251 is prime
			DATA_REPLICA(15 downto 8) <= DATA_REPLICA(15 downto 8) + x"61";	-- 97 is prime
			DATA_REPLICA(23 downto 16) <= DATA_REPLICA(23 downto 16) + x"3D";	-- 61 is prime
			DATA_REPLICA(31 downto 24) <= DATA_REPLICA(31 downto 24) + x"95";	-- 149 is prime
			DATA_REPLICA(41 downto 32) <= DATA_REPLICA(41 downto 32) + 1;
			DATA_REPLICA(51 downto 42) <= DATA_REPLICA(51 downto 42) + 1;
			DATA_REPLICA(61 downto 52) <= DATA_REPLICA(61 downto 52) + 1;
			DATA_REPLICA(71 downto 62) <= DATA_REPLICA(71 downto 62) + 1;
			DATA_REPLICA(81 downto 72) <= DATA_REPLICA(81 downto 72) + 1;
			DATA_REPLICA(91 downto 82) <= DATA_REPLICA(91 downto 82) + 1;
			DATA_REPLICA(101 downto 92) <= DATA_REPLICA(101 downto 92) + 1;
			DATA_REPLICA(111 downto 102) <= DATA_REPLICA(111 downto 102) + 1;
			DATA_REPLICA(121 downto 112) <= DATA_REPLICA(121 downto 112) + 1;
			DATA_REPLICA(127 downto 122) <= DATA_REPLICA(127 downto 122) + 1;
		end if;
	end if;
end process;

-- reclock
RECLOCK_001: process(CLK)
begin
	if rising_edge(CLK) then
		DATA_OUT_D <= DATA_OUT;
		DATA_OUT_D2 <= DATA_OUT_D;
		DATA_OUT_EN_D <= DATA_OUT_EN;
		DATA_OUT_EN_D2 <= DATA_OUT_EN_D;
		-- compare replica with received data, byte by byte. 0 means matching bytes.
		-- (faster than one large comparison)
		if(DATA_OUT_EN_D = '1') then
			for I in 0 to (2*NSDRAM_BYTES - 1) loop
				if (DATA_REPLICA((8*I + 7) downto (8*I)) /= DATA_OUT_D((8*I + 7) downto (8*I))) then
					DATABYTE_COMPARE(I) <= '1';
				else
					DATABYTE_COMPARE(I) <= '0';
				end if;
				-- remember the first address and data		
				for J in 0 to 7 loop
					if(FAILED_BITS_local(8*I + J) = '0') then
						-- first instance of bit failure
						--FIRST_FAILED_ADDRESS <= DATA_COUNTER_D2(30 downto 0);
						FAILED_BITS_local(8*I + J) <= DATA_OUT_D(8*I + J) xor DATA_REPLICA(8*I + J);
					end if;
				end loop;
			end loop;
		end if;
	end if;
end process;
FAILED_BITS <= FAILED_BITS_local;

-- count the number of non-matching words
COUNT_NON_MATCHING_001: process(CLK)
begin
	if rising_edge(CLK) then
		if(STATE = 0) then
			NONMATCHINGWORDSCNT <= (others => '0');
			ERROR <= '0';
		elsif(DATA_OUT_EN_D2 = '1') and (DATABYTE_COMPARE((2*NSDRAM_BYTES - 1) downto 0) /= 0) then
			NONMATCHINGWORDSCNT <= NONMATCHINGWORDSCNT + 1;
			ERROR <= '1';
		else
			ERROR <= '0';
		end if;
	end if;
end process;

SUCCESS_GEN: process(CLK)
begin
	if rising_edge(CLK) then
		if(STATE = 0) then
			SUCCESS_local <= '0';
		elsif(STATE = 4) and (NONMATCHINGWORDSCNT = 0) then
			SUCCESS_local <= '1';
		end if;
	end if;
end process;
SUCCESS <= SUCCESS_local;
			

--//------ SDRAM CONTROLLER ------------------------------------
Inst_DDR2_SDRAM_CONTROLLER: DDR2_SDRAM_CONTROLLER 
generic map(
	PLATFORM => 6,
	NSDRAM_BYTES => NSDRAM_BYTES,
	NCLKS => NCLKS,
	ADDRESS_MAP => ADDRESS_MAP,
	CLOCK_CYCLES => CLOCK_CYCLES,
	DDR2_CLK_FREQ => DDR2_CLK_FREQ,	
	RTDELAY_COARSE => RTDELAY_COARSE
)
PORT MAP(	---------------------------------- USER SIDE
	CLK_DDR2_REF => CLK_DDR2_REF,
	ASYNC_RESET => ASYNC_RESET,
	CLK_DDR2G_OUT => CLK,
	START_ADDR => BURST_START_ADDR,
	TRANSACTION_REQ => TRANSACTION_REQ,
	TRANSACTION_REQ_NO => TRANSACTION_REQ_NO,
	TRANSACTION_REQ_ACK => TRANSACTION_REQ_ACK,
	DATA_IN => DATA_IN((16*NSDRAM_BYTES - 1) downto 0),
	DATA_IN_CTS => DATA_IN_CTS,
	DATA_OUT => DATA_OUT,
	DATA_OUT_EN => DATA_OUT_EN,
	SELF_REFRESH_REQ => '0',
	SDRAM_READY => SDRAM_READY,
	SDRAM_DQ => SDRAM_DQ,  ------------------------ SDRAM SIDE
	SDRAM_DQS_P => SDRAM_DQS_P((NSDRAM_BYTES - 1) downto 0),
	SDRAM_DQS_N => SDRAM_DQS_N((NSDRAM_BYTES - 1) downto 0),
	SDRAM_ODT => SDRAM_ODT,
	SDRAM_CK_P => SDRAM_CK_P,
	SDRAM_CK_N => SDRAM_CK_N,
	SDRAM_CKE => SDRAM_CKE,
	SDRAM_CASN => SDRAM_CASN,
	SDRAM_RASN => SDRAM_RASN,
	SDRAM_WEN => SDRAM_WEN,
	SDRAM_SN => SDRAM_SN,	
	SDRAM_DM => SDRAM_DM,
	SDRAM_BA => SDRAM_BA,
	SDRAM_A => SDRAM_A,
	SDRAM_DQ_DIR => SDRAM_DQ_DIR,  --------------- TEST POINTS
	SDRAM_DQS_DIR => SDRAM_DQS_DIR,
	SDRAM_TP => SDRAM_TP
);


--// TEST POINTS ---------
TPS_GEN: process(CLK)
begin
	if rising_edge(CLK) then
		TEST_POINTS(1) <= DATA_OUT_EN_D;
		TEST_POINTS(2) <= DATABYTE_COMPARE(0);
		TEST_POINTS(3) <= DATABYTE_COMPARE(1);
		TEST_POINTS(4) <= DATABYTE_COMPARE(2);
		TEST_POINTS(5) <= DATABYTE_COMPARE(3);
		TEST_POINTS(6) <= DATABYTE_COMPARE(4);
		TEST_POINTS(7) <= DATABYTE_COMPARE(5);
		TEST_POINTS(8) <= DATABYTE_COMPARE(6);
		TEST_POINTS(9) <= DATABYTE_COMPARE(7);
	end if;
end process;
		TEST_POINTS(10) <= '1' when (STATE = 2) else '0';

end Behavioral;

