---------------------------------------------------------------------------------- --EE 552 -- dram_test_memcont.vhd --Project : Porta-AMP --Author : Kevin Mlazgar -- --Created on : Dec 5, 1999 -- -- Program Functional Description -- -- A Test Bench based in hardware. -- -- Test the dram module. Write data to memory then read from -- memory verifying the contents. Keep a count of errors. -- Have a delay vector that can be widened to allow user -- to see first the high byte then the low byte read from -- memory... -- -- Max Speed: 43.29 MHz -- Optimized for speed... -- --** DEVICE SUMMARY ** -- --Chip/ Input Output Bidir Memory Memory LCs --POF Device Pins Pins Pins Bits % Utilized LCs % Utilized -- --dram_test -- EPF10K20RC240-4 2 30 16 0 0 % 220 19 % -- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library work; use work.sdram_package.all; use work.seg_decode_pkg.all; use work.mem_mgmt_cont_pkg.all; --use work.dram_int_pkg.all; entity dram_test_memcont is port ( clock : in std_logic; reset : in std_logic; -- 7 segment display display1 : out std_logic_vector(6 downto 0); display2 : out std_logic_vector(6 downto 0); dec_pt1 : out std_logic; dec_pt2 : out std_logic; -- DRAM external lines -- -- RAS lines to DRAM -- acts as bank select rasn : out std_logic_vector(3 downto 0); -- CASN line to common CASN line on DRAM DIMM casn : out std_logic; -- write enable line to DRAM -- '1' indicates a READ from DRAM -- '0' indicates a WRITE to DRAM wen : out std_logic; -- data path to DRAM dram_datapath : inout std_logic_vector(15 downto 0); -- address path to DRAM (time multiplexed address lines) dram_addresspath : out std_logic_vector(9 downto 0) ); end entity dram_test_memcont; architecture mixed of dram_test_memcont is type state_type is (write_check, write_wait1, write_wait2, increment_write_vector, check_if_done_write, end_write, read_check, read_wait_for_valid_data1, read_wait_for_valid_data2, output_bad_addr_15_8, output_bad_addr_15_8_again, output_bad_addr_7_0, output_bad_addr_7_0_again, check_result, increment_read_vector, check_if_done_read, increment_error_count, output_result_7_0, output_result_15_8 ); signal state : state_type; signal display_data1 : std_logic_vector(3 downto 0); signal display_data2 : std_logic_vector(3 downto 0); signal test_vector, test_vector_out : std_logic_vector(15 downto 0); alias test_vector_3_0 : std_logic_vector(3 downto 0) is test_vector(3 downto 0); alias test_vector_7_4 : std_logic_vector(3 downto 0) is test_vector(7 downto 4); alias test_vector_11_8 : std_logic_vector(3 downto 0) is test_vector(11 downto 8); alias test_vector_15_12 : std_logic_vector(3 downto 0) is test_vector(15 downto 12); -- count of errors detected in DRAM signal error_count : std_logic_vector(15 downto 0); alias error_count_3_0 : std_logic_vector(3 downto 0) is error_count(3 downto 0); alias error_count_7_4 : std_logic_vector(3 downto 0) is error_count(7 downto 4); alias error_count_11_8 : std_logic_vector(3 downto 0) is error_count(11 downto 8); alias error_count_15_12 : std_logic_vector(3 downto 0) is error_count(15 downto 12); signal mc_ram_ready_int : std_logic; signal mc_ram_enable_int : std_logic; signal mc_ram_read_write_int : std_logic; signal mc_ram_no_data_int : std_logic; signal mc_cmd_ack_int : std_logic; -- widen this vector to test more of memory signal count, count_end : std_logic_vector(17 downto 0); -- padding for the test vector (16 bits wide) if the count -- vector is smaller than 16 bits wide.... -- signal test_pad : std_logic_vector(5 downto 0); -- make this delay upto 21 downto 0 if you actually want to see the -- data being read during the test... signal delay_count, delay_end : std_logic_vector(21 downto 0); signal delay_done : std_logic; begin count_end <= (others => '1'); delay_end <= (others => '1'); -- various options that can be used as test vectors... --test_pad <= (others => '0'); --test_vector <= test_pad & count; --test_vector <= count; test_vector <= count(15 downto 0); --test_vector <= (others => '1'); --test_vector <= (others => '0'); --test_vector <= "1010101010101010"; dram_cont : mem_mgmt_cont port map ( -- clock mem_mgmt_clk => clock, -- reset mem_mgmt_reset => reset, -- **************************** -- ** DRAM Interface Signals ** -- RAS lines to DRAM -- acts as bank select rasn => rasn, -- CASN line to common CASN line on DRAM DIMM casn => casn, -- write enable line to DRAM -- '1' indicates a READ to DRAM -- '0' indicates a WRITE from DRAM wen => wen, -- data path to DRAM dram_datapath => dram_datapath, -- address path to DRAM (time multiplexed address lines) dram_addresspath => dram_addresspath, -- ****************************** -- ** Porta-AMP Direct Signals ** -- signal to the master indicating that the interface is ready for -- a command. -- The master should NEVER address the sdram interface if this -- signal is low. -- If a read or write had been issued or a refresh is in progress this -- signal will go low during the access. When it goes high again there -- is valid data available on the mc_datapath_out for a read, -- or the write is done. mc_ram_ready => mc_ram_ready_int, -- client active-high Chip Select signal is asserted when cpu is addressing -- the memory management controller. -- The data will be loaded into the write_data register of -- the primary data path if a write is also being issued... mc_ram_enable => mc_ram_enable_int, -- client read/writen line -- '1' indicates a READ -- '0' indicates a WRITE -- A 1 clock period latency is required to switch between these. -- i.e. wait a period before asserting mc_ram_enable! -- While doing a read or a write hold this signal at its value and -- assert mc_ram_enable to do another read or write. Once this signal -- is changed a further read or write will occur at the start of memory. mc_ram_read_write => mc_ram_read_write_int, -- signal indicating that there is no valid song data in sdram or -- that have reached end of present song... mc_ram_no_data => mc_ram_no_data_int, -- data path to Porta_AMP master mc_datapath_in => test_vector, mc_datapath_out => test_vector_out ); -- The decimal points will light up on the 7 seg display -- when the most significant HEX digits are displaying with state select dec_pt1 <= '0' when output_bad_addr_15_8, '0' when output_bad_addr_15_8_again, '0' when output_result_15_8, '1' when others; -- The decimal points will light up on the 7 seg display -- when the most significant HEX digits are displaying with state select dec_pt2 <= '0' when output_bad_addr_15_8, '0' when output_bad_addr_15_8_again, '0' when output_result_15_8, '1' when others; with state select display_data1 <= "0111" when write_check, test_vector_15_12 when output_bad_addr_15_8, test_vector_15_12 when output_bad_addr_15_8_again, test_vector_7_4 when output_bad_addr_7_0, test_vector_7_4 when output_bad_addr_7_0_again, error_count_7_4 when output_result_7_0, error_count_15_12 when output_result_15_8, display_data1 when others; seg7_dec1 : seg_decode port map ( value => display_data1, decode => display1 ); with state select display_data2 <= test_vector_11_8 when output_bad_addr_15_8, test_vector_11_8 when output_bad_addr_15_8_again, test_vector_3_0 when output_bad_addr_7_0, test_vector_3_0 when output_bad_addr_7_0_again, error_count_3_0 when output_result_7_0, error_count_11_8 when output_result_15_8, display_data2 when others; seg7_dec2 : seg_decode port map ( value => display_data2, decode => display2 ); -- test vector to be written to memory -- Acts as test vector, address, and number of times to write -- to memory... test_vector_count : process(reset, clock) begin if reset = '0' then count <= (others => '0'); elsif rising_edge(clock) then if state = end_write then count <= (others => '0'); elsif state = increment_write_vector or state = increment_read_vector then count <= count + 1; else count <= count; end if; end if; end process test_vector_count; -- counter of errors in memory error_counter : process(reset, clock) begin if reset = '0' then error_count <= (others => '0'); elsif rising_edge(clock) then if state = increment_error_count then error_count <= error_count + 1; else error_count <= error_count; end if; end if; end process error_counter; -- delay counter so can see result on 7 seg display delay_counter : process(reset, clock) begin if reset = '0' then delay_count <= (others => '0'); delay_done <= '0'; elsif rising_edge(clock) then if state = output_bad_addr_15_8 or state = output_bad_addr_15_8_again or state = output_bad_addr_7_0 or state = output_bad_addr_7_0_again or state = output_result_15_8 or state = output_result_7_0 then delay_count <= delay_count + 1; if delay_count = delay_end then delay_done <= '1'; else delay_done <= '0'; end if; else delay_count <= (others => '0'); end if; end if; end process delay_counter; with state select mc_ram_enable_int <= '1' when write_check, '1' when read_check, '0' when others; with state select mc_ram_read_write_int <= '0' when write_check, '0' when write_wait1, '0' when write_wait2, '0' when increment_write_vector, '0' when check_if_done_write, '1' when end_write, '1' when others; StateLogic : process (reset, clock) begin if reset = '0' then state <= write_check; elsif rising_edge(clock) then case state is -- check if dram is ready -- assert mc_ram_enable high and mc_ram_read_write low when write_check => if mc_ram_ready_int = '1' then state <= write_wait1; else state <= write_check; end if; when write_wait1 => if mc_ram_ready_int = '0' then state <= write_wait2; else state <= write_wait1; -- should NEVER occur end if; when write_wait2 => if mc_ram_ready_int = '1' then state <= increment_write_vector; else state <= write_wait2; end if; -- increment data to be written to memory when increment_write_vector => state <= check_if_done_write; -- when check_if_done_write => if count = count_end then state <= end_write; else state <= write_check; end if; -- indicate to DRAM that the write is over -- by deasserting the mc_ram_read_write to high -- reset the test vector when end_write => state <= read_check; -- check if dram is ready -- assert mc_ram_enable high and mc_ram_read_write high -- to start a read as soon as is ready... when read_check => if mc_ram_ready_int = '1' and mc_ram_no_data_int = '0' then state <= read_wait_for_valid_data1; else state <= read_check; end if; -- verify request being serviced when read_wait_for_valid_data1 => if mc_ram_ready_int = '0' then state <= read_wait_for_valid_data2; else state <= read_wait_for_valid_data1; end if; -- data out should be valid after here when read_wait_for_valid_data2 => if mc_ram_ready_int = '1' then state <= check_result; else state <= read_wait_for_valid_data2; end if; when check_result => if test_vector_out = test_vector then -- this word of memory OK, go to next state <= increment_read_vector; else -- this word of memory BAD, go on to next state <= increment_error_count; end if; -- increment the error count when increment_error_count => state <= output_bad_addr_15_8; when output_bad_addr_15_8 => if delay_done = '1' then state <= output_bad_addr_15_8_again; else state <= output_bad_addr_15_8; end if; when output_bad_addr_15_8_again => if delay_done = '1' then state <= output_bad_addr_7_0; else state <= output_bad_addr_15_8_again; end if; when output_bad_addr_7_0 => if delay_done = '1' then state <= output_bad_addr_7_0_again; else state <= output_bad_addr_7_0; end if; when output_bad_addr_7_0_again => if delay_done = '1' then state <= increment_read_vector; else state <= output_bad_addr_7_0_again; end if; -- increment the test vector when increment_read_vector => state <= check_if_done_read; -- check if are at end of testing sequence when check_if_done_read => if count = count_end then state <= output_result_15_8; else state <= read_check; end if; when output_result_15_8 => if delay_done = '1' then state <= output_result_7_0; else state <= output_result_15_8; end if; when output_result_7_0 => if delay_done = '1' then state <= output_result_15_8; else state <= output_result_7_0; end if; end case; end if; end process StateLogic; end mixed;