From 04772b6a0bbe7017f5f7b44cfa203c3f7efbff64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Harboe?= Date: Tue, 1 Mar 2011 20:52:55 +0100 Subject: whitespace fixes: use fromdos on all .vhd files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Øyvind Harboe --- misc/ddrsdram/src/ddr_pkg.vhd | 212 +-- misc/ddrsdram/src/ddr_top.vhd | 1486 ++++++++++----------- misc/ddrsdram/src/mt46v16m16.vhd | 2640 +++++++++++++++++++------------------- 3 files changed, 2169 insertions(+), 2169 deletions(-) (limited to 'misc/ddrsdram/src') diff --git a/misc/ddrsdram/src/ddr_pkg.vhd b/misc/ddrsdram/src/ddr_pkg.vhd index 0e41a88..af4a705 100644 --- a/misc/ddrsdram/src/ddr_pkg.vhd +++ b/misc/ddrsdram/src/ddr_pkg.vhd @@ -1,107 +1,107 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.all; -use IEEE.STD_LOGIC_UNSIGNED.ALL; - -package ddr is - - function mirror_bus32 ( org_sig : std_logic_vector) return std_logic_vector; - function mirror_bus4 ( org_sig : std_logic_vector) return std_logic_vector; - - component ddr_top - generic( - simulate_io_time : boolean := false); - port ( -- Asyncronous reset and clocks - areset : in std_logic; - cpu_clk : in std_logic; - cpu_clk_2x : in std_logic; - cpu_clk_4x : in std_logic; - ddr_in_clk : in std_logic; - ddr_in_clk_2x : in std_logic; - - -- Command interface - ddr_command : in std_logic_vector(15 downto 0); - ddr_command_we : in std_logic; - refresh_en : in std_logic; - - - -- Data interface signals - ddr_data_read : out std_logic_vector(31 downto 0); -- Data read from DDR SDRAM - ddr_data_write : in std_logic_vector(35 downto 0); -- Data to be written to DDR SDRAM - ddr_req_adr : in std_logic_vector(25 downto 1); -- Request address - ddr_req : in std_logic; -- Request DDR SDRAM access - ddr_busy : out std_logic; -- Request acknowledge - ddr_rd_wr_n : in std_logic; -- Access type 1=READ, 0=WRITE - ddr_req_len : in std_logic; -- Number of 16-bits words to transfer (0=2, 1=8) - ddr_read_en : out std_logic; -- Enable signal for read data - ddr_write_en : out std_logic; -- Enable (read) signal for data write - - -- DDR SDRAM Signals - sdr_clk_p : out std_logic; -- ddr_sdram_clock - sdr_clk_n_p : out std_logic; -- /ddr_sdram_clock - cke_q_p : out std_logic; -- clock enable - cs_qn_p : out std_logic; -- /chip select - ras_qn_p : inout std_logic; -- /ras - cas_qn_p : inout std_logic; -- /cas - we_qn_p : inout std_logic; -- /write enable - dm_q_p : out std_logic_vector(1 downto 0); -- data mask bits, set to "00" - dqs_q_p : out std_logic_vector(1 downto 0); -- data strobe, only for write - ba_q_p : out std_logic_vector(1 downto 0); -- bank select - sdr_a_p : out std_logic_vector(12 downto 0); -- address bus - sdr_d_p : inout std_logic_vector(15 downto 0)); -- bidir data bus - end component; - - component MT46V16M16 - GENERIC ( -- Timing for -75Z CL2 - tCK : TIME := 7.500 ns; - tCH : TIME := 3.375 ns; -- 0.45*tCK - tCL : TIME := 3.375 ns; -- 0.45*tCK - tDH : TIME := 0.500 ns; - tDS : TIME := 0.500 ns; - tIH : TIME := 0.900 ns; - tIS : TIME := 0.900 ns; - tMRD : TIME := 15.000 ns; - tRAS : TIME := 40.000 ns; - tRAP : TIME := 20.000 ns; - tRC : TIME := 65.000 ns; - tRFC : TIME := 75.000 ns; - tRCD : TIME := 20.000 ns; - tRP : TIME := 20.000 ns; - tRRD : TIME := 15.000 ns; - tWR : TIME := 15.000 ns; - addr_bits : INTEGER := 13; - data_bits : INTEGER := 16; - cols_bits : INTEGER := 9 - ); - PORT ( - Dq : INOUT STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0) := (OTHERS => 'Z'); - Dqs : INOUT STD_LOGIC_VECTOR (1 DOWNTO 0) := "ZZ"; - Addr : IN STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0); - Ba : IN STD_LOGIC_VECTOR (1 DOWNTO 0); - Clk : IN STD_LOGIC; - Clk_n : IN STD_LOGIC; - Cke : IN STD_LOGIC; - Cs_n : IN STD_LOGIC; - Ras_n : IN STD_LOGIC; - Cas_n : IN STD_LOGIC; - We_n : IN STD_LOGIC; - Dm : IN STD_LOGIC_VECTOR (1 DOWNTO 0) - ); - end component; - -end; - -package body ddr is - - function mirror_bus32 ( org_sig : std_logic_vector) return std_logic_vector is - begin - return (org_sig(7 downto 0) & org_sig(15 downto 8) & org_sig(23 downto 16) & org_sig(31 downto 24)); - end function mirror_bus32; - - function mirror_bus4 ( org_sig : std_logic_vector) return std_logic_vector is - begin - return (org_sig(0) & org_sig(1) & org_sig(2) & org_sig(3)); - end function mirror_bus4; - -end package body; - +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +package ddr is + + function mirror_bus32 ( org_sig : std_logic_vector) return std_logic_vector; + function mirror_bus4 ( org_sig : std_logic_vector) return std_logic_vector; + + component ddr_top + generic( + simulate_io_time : boolean := false); + port ( -- Asyncronous reset and clocks + areset : in std_logic; + cpu_clk : in std_logic; + cpu_clk_2x : in std_logic; + cpu_clk_4x : in std_logic; + ddr_in_clk : in std_logic; + ddr_in_clk_2x : in std_logic; + + -- Command interface + ddr_command : in std_logic_vector(15 downto 0); + ddr_command_we : in std_logic; + refresh_en : in std_logic; + + + -- Data interface signals + ddr_data_read : out std_logic_vector(31 downto 0); -- Data read from DDR SDRAM + ddr_data_write : in std_logic_vector(35 downto 0); -- Data to be written to DDR SDRAM + ddr_req_adr : in std_logic_vector(25 downto 1); -- Request address + ddr_req : in std_logic; -- Request DDR SDRAM access + ddr_busy : out std_logic; -- Request acknowledge + ddr_rd_wr_n : in std_logic; -- Access type 1=READ, 0=WRITE + ddr_req_len : in std_logic; -- Number of 16-bits words to transfer (0=2, 1=8) + ddr_read_en : out std_logic; -- Enable signal for read data + ddr_write_en : out std_logic; -- Enable (read) signal for data write + + -- DDR SDRAM Signals + sdr_clk_p : out std_logic; -- ddr_sdram_clock + sdr_clk_n_p : out std_logic; -- /ddr_sdram_clock + cke_q_p : out std_logic; -- clock enable + cs_qn_p : out std_logic; -- /chip select + ras_qn_p : inout std_logic; -- /ras + cas_qn_p : inout std_logic; -- /cas + we_qn_p : inout std_logic; -- /write enable + dm_q_p : out std_logic_vector(1 downto 0); -- data mask bits, set to "00" + dqs_q_p : out std_logic_vector(1 downto 0); -- data strobe, only for write + ba_q_p : out std_logic_vector(1 downto 0); -- bank select + sdr_a_p : out std_logic_vector(12 downto 0); -- address bus + sdr_d_p : inout std_logic_vector(15 downto 0)); -- bidir data bus + end component; + + component MT46V16M16 + GENERIC ( -- Timing for -75Z CL2 + tCK : TIME := 7.500 ns; + tCH : TIME := 3.375 ns; -- 0.45*tCK + tCL : TIME := 3.375 ns; -- 0.45*tCK + tDH : TIME := 0.500 ns; + tDS : TIME := 0.500 ns; + tIH : TIME := 0.900 ns; + tIS : TIME := 0.900 ns; + tMRD : TIME := 15.000 ns; + tRAS : TIME := 40.000 ns; + tRAP : TIME := 20.000 ns; + tRC : TIME := 65.000 ns; + tRFC : TIME := 75.000 ns; + tRCD : TIME := 20.000 ns; + tRP : TIME := 20.000 ns; + tRRD : TIME := 15.000 ns; + tWR : TIME := 15.000 ns; + addr_bits : INTEGER := 13; + data_bits : INTEGER := 16; + cols_bits : INTEGER := 9 + ); + PORT ( + Dq : INOUT STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0) := (OTHERS => 'Z'); + Dqs : INOUT STD_LOGIC_VECTOR (1 DOWNTO 0) := "ZZ"; + Addr : IN STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0); + Ba : IN STD_LOGIC_VECTOR (1 DOWNTO 0); + Clk : IN STD_LOGIC; + Clk_n : IN STD_LOGIC; + Cke : IN STD_LOGIC; + Cs_n : IN STD_LOGIC; + Ras_n : IN STD_LOGIC; + Cas_n : IN STD_LOGIC; + We_n : IN STD_LOGIC; + Dm : IN STD_LOGIC_VECTOR (1 DOWNTO 0) + ); + end component; + +end; + +package body ddr is + + function mirror_bus32 ( org_sig : std_logic_vector) return std_logic_vector is + begin + return (org_sig(7 downto 0) & org_sig(15 downto 8) & org_sig(23 downto 16) & org_sig(31 downto 24)); + end function mirror_bus32; + + function mirror_bus4 ( org_sig : std_logic_vector) return std_logic_vector is + begin + return (org_sig(0) & org_sig(1) & org_sig(2) & org_sig(3)); + end function mirror_bus4; + +end package body; + \ No newline at end of file diff --git a/misc/ddrsdram/src/ddr_top.vhd b/misc/ddrsdram/src/ddr_top.vhd index 033e9f8..2aceae9 100644 --- a/misc/ddrsdram/src/ddr_top.vhd +++ b/misc/ddrsdram/src/ddr_top.vhd @@ -1,743 +1,743 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.all; -use IEEE.STD_LOGIC_UNSIGNED.ALL; - -library UNISIM; -use UNISIM.vcomponents.all; - -entity ddr_top is - generic( - simulate_io_time : boolean := false); - port ( -- Asyncronous reset and clocks - areset : in std_logic; - cpu_clk : in std_logic; - cpu_clk_2x : in std_logic; - cpu_clk_4x : in std_logic; - ddr_in_clk : in std_logic; - ddr_in_clk_2x : in std_logic; - - -- Command interface - ddr_command : in std_logic_vector(15 downto 0); - ddr_command_we : in std_logic; - refresh_en : in std_logic; - - -- Data interface signals - ddr_data_read : out std_logic_vector(31 downto 0); -- Data read from DDR SDRAM - ddr_data_write : in std_logic_vector(35 downto 0); -- Data to be written to DDR SDRAM - ddr_req_adr : in std_logic_vector(25 downto 1); -- Request address - ddr_req : in std_logic; -- Request DDR SDRAM access - ddr_busy : out std_logic; -- Request acknowledge - ddr_rd_wr_n : in std_logic; -- Access type 1=READ, 0=WRITE - ddr_req_len : in std_logic; -- Number of 16-bits words to transfer (0=2, 1=8) - ddr_read_en : out std_logic; -- Enable signal for read data - ddr_write_en : out std_logic; -- Enable (read) signal for data write - - -- DDR SDRAM Signals - sdr_clk_p : out std_logic; -- ddr_sdram_clock - sdr_clk_n_p : out std_logic; -- /ddr_sdram_clock - cke_q_p : out std_logic; -- clock enable - cs_qn_p : out std_logic; -- /chip select - ras_qn_p : inout std_logic; -- /ras - cas_qn_p : inout std_logic; -- /cas - we_qn_p : inout std_logic; -- /write enable - dm_q_p : out std_logic_vector(1 downto 0); -- data mask bits, set to "00" - dqs_q_p : out std_logic_vector(1 downto 0); -- data strobe, only for write - ba_q_p : out std_logic_vector(1 downto 0); -- bank select - sdr_a_p : out std_logic_vector(12 downto 0); -- address bus - sdr_d_p : inout std_logic_vector(15 downto 0)); -- bidir data bus -end ddr_top; - -architecture behave of ddr_top is - -attribute keep : string; - -type clk4_type is array(0 to 15) of std_logic_vector(1 downto 0); - -signal cpu_clk_tog : std_logic; -signal ddr_cmd : std_logic_vector(15 downto 0); -signal ddr_cmd_we_smp : std_logic; -signal new_command : std_logic; - -signal cpu_clk_2x_smp1 : std_logic; -signal cpu_clk_2x_smp2 : std_logic; -signal cpu_clk_4x_smp1 : std_logic; -signal cpu_clk_4x_smp2 : std_logic; - -signal clk2_phase : std_logic; -signal clk4_phase : std_logic_vector(3 downto 0); -signal clk4_phase_short : clk4_type; -attribute keep of clk4_phase_short:signal is "true"; - -signal ddr_clk_tog : std_logic; -signal ddr_clk_smp1 : std_logic; -signal ddr_clk_smp2 : std_logic; -signal ddr_clk_phase : std_logic; - -signal smp_req_adr : std_logic_vector(25 downto 1); -signal smp_req_type : std_logic; -signal smp_req_len : std_logic; -signal ddr_write_en_int : std_logic; -signal ddr_read_en_int : std_logic; - -signal dqs_q : std_logic_vector(1 downto 0); -signal dqs_oe_n : std_logic_vector(1 downto 0); -attribute keep of dqs_oe_n:signal is "true"; -signal cas_qn : std_logic; -signal ras_qn : std_logic; -signal we_qn : std_logic; -signal ba_q : std_logic_vector(1 downto 0); -signal sdr_clk : std_logic; -signal sdr_clk_n : std_logic; -signal sdr_a : std_logic_vector(12 downto 0); -signal sdr_d : std_logic_vector(15 downto 0); -signal sdr_smp : std_logic_vector(35 downto 0); -signal sdr_oe_n : std_logic_vector(15 downto 0); -attribute keep of sdr_oe_n:signal is "true"; -signal sdr_oe_ctrl : std_logic_vector(15 downto 0); -attribute keep of sdr_oe_ctrl:signal is "true"; -signal sdr_wr_msw : std_logic_vector(17 downto 0); -attribute keep of sdr_wr_msw:signal is "true"; -signal dm_q : std_logic_vector(1 downto 0); - -signal nowin_idle_dqs : std_logic_vector(1 downto 0); -signal nowin_wr_nop1_d : std_logic_vector(15 downto 0); -signal nowin_wr_nop1_dqs : std_logic_vector(1 downto 0); -signal nowin_wr_nop1_dm : std_logic_vector(1 downto 0); -signal nowin_wr_nop2_dqs : std_logic_vector(1 downto 0); -signal nowin_wr_nop3_d : std_logic_vector(15 downto 0); -signal nowin_wr_nop3_dqs : std_logic_vector(1 downto 0); -attribute keep of nowin_idle_dqs:signal is "true"; -attribute keep of nowin_wr_nop1_d:signal is "true"; -attribute keep of nowin_wr_nop1_dqs:signal is "true"; -attribute keep of nowin_wr_nop1_dm:signal is "true"; -attribute keep of nowin_wr_nop2_dqs:signal is "true"; -attribute keep of nowin_wr_nop3_d:signal is "true"; -attribute keep of nowin_wr_nop3_dqs:signal is "true"; - -signal cas_n_smp : std_logic; -signal ras_n_smp : std_logic; -signal we_n_smp : std_logic; -signal read_start_sig : std_logic; -signal sdr_d_in : std_logic_vector(15 downto 0); -signal read_time_cnt : std_logic_vector(1 downto 0); -signal read_input_en : std_logic; -signal read_input_en_del : std_logic; -signal ddr_data_read_int : std_logic_vector(31 downto 0); - -signal refresh_pend : std_logic; -signal refresh_end : std_logic; -signal refresh_cnt : std_logic_vector(9 downto 0); -signal refresh_wait_cnt : std_logic_vector(3 downto 0); -signal refresh_wait_end : std_logic; - -signal cas_qn_p_del : std_logic; -signal ras_qn_p_del : std_logic; -signal we_qn_p_del : std_logic; -signal sdr_d_p_del : std_logic_vector(15 downto 0); - -signal saved_row : std_logic_vector(26 downto 11); -signal operation : std_logic_vector(1 downto 0); - -signal ddr_req_adr_int : std_logic_vector(25 downto 1); - -type state_type is (idle, act, act_nop1, act_nop2, rd_wr, rd_nop1, - rd_nop2,rd_nop3,rd_nop4, rd_nop5,pre, pre_nop1, pre_nop2, wr_nop1, wr_nop2, - wr_nop3, cmd, cpu_pre, refresh, refresh_wait); -signal ddr_state : state_type; - -constant Clk_to_Output : time := 2.2 ns; -constant Input_Setup : time := 2.5 ns; - -constant Refresh_Interval : std_logic_vector(9 downto 0) := "1111100110"; - -begin - - iotimingon: - if simulate_io_time generate - begin - cas_qn_p_del <= 'X' after 0 ns, cas_qn_p after Input_Setup; - ras_qn_p_del <= 'X' after 0 ns, ras_qn_p after Input_Setup; - we_qn_p_del <= 'X' after 0 ns, we_qn_p after Input_Setup; - sdr_d_p_del <= "XXXXXXXXXXXXXXXX" after 0 ns, sdr_d_p after Input_Setup; - end generate; - - iotimingoff: - if not simulate_io_time generate - begin - cas_qn_p_del <= cas_qn_p; - ras_qn_p_del <= ras_qn_p; - we_qn_p_del <= we_qn_p; - sdr_d_p_del <= sdr_d_p; - end generate; - - ddr_write_en <= ddr_write_en_int; - ddr_read_en <= ddr_read_en_int; - ddr_data_read <= ddr_data_read_int; - - ddr_req_adr_int <= (ddr_req_adr(24 downto 10) & '0' & ddr_req_adr(9 downto 1)) when (simulate_io_time) else ddr_req_adr; - - process(cpu_clk, areset) -- Toggle a flip-flop with cpu_clk, in order - begin -- to find phase relation with 2x and 4x clocks - if areset = '1' then - cpu_clk_tog <= '0'; - elsif (cpu_clk'event and cpu_clk = '1') then - cpu_clk_tog <= not(cpu_clk_tog); - end if; - end process; - - process(cpu_clk_2x, areset) -- Find phase relation between cpu_clk and cpu_clk_2x - begin - if areset = '1' then - cpu_clk_2x_smp1 <= '0'; - cpu_clk_2x_smp2 <= '0'; - clk2_phase <= '0'; - elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then - cpu_clk_2x_smp1 <= cpu_clk_tog; - cpu_clk_2x_smp2 <= cpu_clk_2x_smp1; - if (cpu_clk_2x_smp1 = '1' and cpu_clk_2x_smp2 = '0') then - clk2_phase <= '0'; - else - clk2_phase <= not(clk2_phase); - end if; - end if; - end process; - - process(cpu_clk_4x, areset) -- Find phase relation between cpu_clk and cpu_clk_4x - begin - if areset = '1' then - cpu_clk_4x_smp1 <= '0'; - cpu_clk_4x_smp2 <= '0'; - clk4_phase <= "0000"; - clk4_phase_short(0) <= "00"; - clk4_phase_short(1) <= "00"; - clk4_phase_short(2) <= "00"; - clk4_phase_short(3) <= "00"; - clk4_phase_short(4) <= "00"; - clk4_phase_short(5) <= "00"; - clk4_phase_short(6) <= "00"; - clk4_phase_short(7) <= "00"; - clk4_phase_short(8) <= "00"; - clk4_phase_short(9) <= "00"; - clk4_phase_short(10) <= "00"; - clk4_phase_short(11) <= "00"; - clk4_phase_short(12) <= "00"; - clk4_phase_short(13) <= "00"; - clk4_phase_short(14) <= "00"; - clk4_phase_short(15) <= "00"; - elsif (cpu_clk_4x'event and cpu_clk_4x = '1') then - cpu_clk_4x_smp1 <= cpu_clk_tog; - cpu_clk_4x_smp2 <= cpu_clk_4x_smp1; - for i in 0 to 15 loop - if (cpu_clk_4x_smp1 = '1' and cpu_clk_4x_smp2 = '0') then - clk4_phase <= "0100"; - clk4_phase_short(i) <= "01"; - else - clk4_phase <= (clk4_phase(2 downto 0) & clk4_phase(3)); - clk4_phase_short(i) <= clk4_phase_short(i)(0) & clk4_phase_short(i)(1); - end if; - end loop; - end if; - end process; - - process(cpu_clk_4x, areset) -- - begin - if areset = '1' then - sdr_clk <= '0'; - sdr_clk_n <= '0'; - elsif (cpu_clk_4x'event and cpu_clk_4x = '1') then - if clk4_phase_short(0)(0) = '1' then - sdr_clk <= '1'; - else - sdr_clk <= '0'; - end if; - if clk4_phase_short(0)(1) = '1' then - sdr_clk_n <= '1'; - else - sdr_clk_n <= '0'; - end if; - end if; - end process; - - cke_q_p <= '1' after Clk_to_Output; - cs_qn_p <= '0' after Clk_to_Output; - - process(cpu_clk_4x, areset) -- - begin - if areset = '1' then - ras_qn_p <= '1'; - cas_qn_p <= '1'; - we_qn_p <= '1'; - dqs_q_p <= "ZZ"; - sdr_a_p <= "0000000000000"; - ba_q_p <= "00"; - sdr_clk_p <= '0'; - sdr_clk_n_p <= '1'; - elsif (cpu_clk_4x'event and cpu_clk_4x = '1') then - ras_qn_p <= transport ras_qn after Clk_to_Output; - cas_qn_p <= transport cas_qn after Clk_to_Output; - we_qn_p <= transport we_qn after Clk_to_Output; - if dqs_oe_n(0) = '0' then - dqs_q_p(0) <= transport dqs_q(0) after Clk_to_Output; - else - dqs_q_p(0) <= transport 'Z' after Clk_to_Output; - end if; - if dqs_oe_n(1) = '0' then - dqs_q_p(1) <= transport dqs_q(1) after Clk_to_Output; - else - dqs_q_p(1) <= transport 'Z' after Clk_to_Output; - end if; - sdr_a_p <= transport sdr_a after Clk_to_Output; - ba_q_p <= transport ba_q after Clk_to_Output; - sdr_clk_p <= transport sdr_clk after Clk_to_Output; - sdr_clk_n_p <= transport sdr_clk_n after Clk_to_Output; - end if; - end process; - - process(cpu_clk_2x, areset) -- - begin - if areset = '1' then - ddr_state <= idle; - ras_qn <= '1'; - cas_qn <= '1'; - we_qn <= '1'; - smp_req_adr <= (others => '0'); - smp_req_type <= '0'; - smp_req_len <= '0'; - sdr_a <= "XXXXXXXXXXXXX"; - ba_q <= "00"; - ddr_busy <= '1'; - saved_row <= "1000000000000000"; - ddr_write_en_int <= '0'; - ddr_read_en_int <= '0'; - nowin_idle_dqs <= "11"; - nowin_wr_nop1_d <= "0000000000000000"; - nowin_wr_nop1_dqs <= "00"; - nowin_wr_nop1_dm <= "00"; - nowin_wr_nop2_dqs <= "00"; - nowin_wr_nop3_d <= "0000000000000000"; - nowin_wr_nop3_dqs <= "00"; - elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then - - -- Default values - ras_qn <= '1'; - cas_qn <= '1'; - we_qn <= '1'; - sdr_a <= "XXXXXXXXXXXXX"; - ddr_busy <= '1'; - ddr_write_en_int <= '0'; - ddr_read_en_int <= '0'; - - nowin_idle_dqs <= "00"; - nowin_wr_nop1_d <= "0000000000000000"; - nowin_wr_nop1_dqs <= "00"; - nowin_wr_nop1_dm <= "00"; - nowin_wr_nop2_dqs <= "00"; - nowin_wr_nop3_d <= "0000000000000000"; - nowin_wr_nop3_dqs <= "00"; - - case ddr_state is - when idle => - smp_req_adr <= ddr_req_adr_int; - smp_req_type <= ddr_rd_wr_n; - smp_req_len <= ddr_req_len; - ddr_busy <= '0'; - operation <= "00"; - if refresh_pend = '1' then - operation <= "01"; - ddr_state <= pre; - elsif new_command = '1' then - if ddr_cmd(15) = '1' then - operation <= "10"; - ddr_state <= cpu_pre; - else - ddr_state <= cmd; - end if; - elsif (ddr_req = '1' and ddr_req_adr_int(25 downto 11) = saved_row(25 downto 11) and saved_row(26) = '0') then - operation <= "11"; - ddr_write_en_int <= not(ddr_rd_wr_n); - ddr_state <= rd_wr; - elsif ddr_req = '1' then - operation <= "11"; - ddr_state <= pre; - else - ddr_state <= idle; - nowin_idle_dqs <= "11"; - end if; - when act => - sdr_a <= smp_req_adr(23 downto 11); - ba_q <= smp_req_adr(25 downto 24); - ras_qn <= '0'; - ddr_write_en_int <= not(smp_req_type); - ddr_state <= act_nop1; - when act_nop1 => - ddr_state <= act_nop2; - when act_nop2 => - ddr_state <= rd_wr; - when rd_wr => - sdr_a(10) <= '0'; -- Disable auto precharge - sdr_a(9 downto 0) <= smp_req_adr(10 downto 1); - ba_q <= smp_req_adr(25 downto 24); - saved_row <= '0' & smp_req_adr(25 downto 11); - cas_qn <= '0'; - we_qn <= smp_req_type; - if smp_req_type = '1' then - ddr_state <= rd_nop1; - else - ddr_state <= wr_nop1; - nowin_wr_nop1_d <= "1111111111111111"; - nowin_wr_nop1_dqs <= "11"; - nowin_wr_nop1_dm <= "11"; - end if; - when wr_nop1 => - ddr_state <= wr_nop2; - nowin_wr_nop2_dqs <= "11"; - when wr_nop2 => - ddr_state <= wr_nop3; - nowin_wr_nop3_d <= "1111111111111111"; - nowin_wr_nop3_dqs <= "11"; - when wr_nop3 => - nowin_idle_dqs <= "11"; - ddr_state <= idle; - when rd_nop1 => - ddr_state <= rd_nop2; - when rd_nop2 => - if operation /= "11" then - nowin_idle_dqs <= "11"; - ddr_state <= idle; - else - ddr_state <= rd_nop3; - end if; - when rd_nop3 => - ddr_state <= rd_nop4; - when rd_nop4 => - ddr_read_en_int <= '1'; - ddr_state <= rd_nop5; - when rd_nop5 => - nowin_idle_dqs <= "11"; - ddr_state <= idle; - when pre => - ras_qn <= '0'; - we_qn <= '0'; - sdr_a(10) <= '1'; -- Precharge all banks - ba_q <= smp_req_adr(25 downto 24); - ddr_state <= pre_nop1; - when pre_nop1 => - ddr_state <= pre_nop2; - when cmd => - cas_qn <= '0'; - ras_qn <= '0'; - we_qn <= '0'; - ba_q <= ddr_cmd(14 downto 13); - sdr_a <= ddr_cmd(12 downto 0); - nowin_idle_dqs <= "11"; - ddr_state <= idle; - when cpu_pre => - ddr_state <= pre; - when refresh => - cas_qn <= '0'; - ras_qn <= '0'; - saved_row(26) <= '1'; - ddr_state <= refresh_wait; - when refresh_wait => - if refresh_wait_end = '1' then - ddr_state <= pre_nop2; - end if; - when pre_nop2 => - if operation = "01" then - operation <= "10"; - ddr_state <= refresh; - elsif operation = "10" then - nowin_idle_dqs <= "11"; - ddr_state <= idle; - else - ddr_state <= act; - end if; - when others => - ddr_state <= idle; - nowin_idle_dqs <= "11"; - end case; - end if; - end process; - - process(cpu_clk, areset) -- - begin - if areset = '1' then - ddr_cmd <= "0000000000000000"; - elsif (cpu_clk'event and cpu_clk = '1') then - if ddr_command_we = '1' then - ddr_cmd <= ddr_command; - else - ddr_cmd <= ddr_cmd; - end if; - end if; - end process; - - process(cpu_clk_2x, areset) -- - begin - if areset = '1' then - ddr_cmd_we_smp <= '0'; - new_command <= '0'; - sdr_smp <= "000000000000000000000000000000000000"; - elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then - ddr_cmd_we_smp <= ddr_command_we; - if ddr_command_we = '0' and ddr_cmd_we_smp = '1' then - new_command <= '1'; - elsif ddr_state = cmd or ddr_state = cpu_pre then - new_command <= '0'; - else - new_command <= new_command; - end if; - - if ddr_write_en_int = '1' then - sdr_smp <= ddr_data_write; - else - sdr_smp <= sdr_smp; - end if; - - end if; - end process; - - process(cpu_clk_4x, areset) -- - begin - if areset = '1' then - dqs_q <= "00"; - dqs_oe_n <= "11"; - sdr_oe_ctrl <= "1111111111111111"; - sdr_wr_msw <= "000000000000000000"; - elsif (cpu_clk_4x'event and cpu_clk_4x = '1') then - - for i in 0 to 15 loop - if nowin_wr_nop1_d(i) = '1' and clk4_phase_short(i)(0) = '1' then - sdr_oe_ctrl(i) <= '0'; - elsif nowin_wr_nop3_d(i) = '1' and clk4_phase_short(i)(0) = '1' then - sdr_oe_ctrl(i) <= '1'; - end if; - end loop; - - for i in 0 to 1 loop - if nowin_idle_dqs(i) = '1' or nowin_wr_nop3_dqs(i) = '1' then - dqs_oe_n(i) <= '1'; - elsif nowin_wr_nop1_dqs(i) = '1' then - dqs_oe_n(i) <= '0'; - end if; - end loop; - - for i in 0 to 1 loop - if (nowin_wr_nop2_dqs(i) = '1' and clk4_phase_short(i)(0) = '1') then - dqs_q(i) <= '1'; - else - dqs_q(i) <= '0'; - end if; - end loop; - - for i in 0 to 15 loop - if nowin_wr_nop1_d(i) = '1' and clk4_phase_short(i)(1) = '1' then - sdr_wr_msw(i) <= '1'; - else - sdr_wr_msw(i) <= '0'; - end if; - end loop; - - for i in 0 to 1 loop - if nowin_wr_nop1_dm(i) = '1' and clk4_phase_short(i)(1) = '1' then - sdr_wr_msw(i+16) <= '1'; - else - sdr_wr_msw(i+16) <= '0'; - end if; - end loop; - - end if; - end process; - - -- NOTE! DATA OUTPUT PATH. CLOCKED ON FALLING 4X CLOCK - process(cpu_clk_4x, areset) -- - begin - if areset = '1' then - sdr_d_p <= "ZZZZZZZZZZZZZZZZ"; - dm_q_p <= "11"; - sdr_oe_n <= "1111111111111111"; - sdr_d <= "0000000000000000"; - dm_q <= "11"; - elsif (cpu_clk_4x'event and cpu_clk_4x = '0') then - - for i in 0 to 15 loop - if sdr_oe_n(i) = '0' then - sdr_d_p(i) <= transport sdr_d(i) after Clk_to_Output; - else - sdr_d_p(i) <= transport 'Z' after Clk_to_Output; - end if; - end loop; - - dm_q_p <= transport dm_q after Clk_to_Output; - - for i in 0 to 15 loop - if sdr_oe_ctrl(i) = '0' then - sdr_oe_n(i) <= '0'; - else - sdr_oe_n(i) <= '1'; - end if; - end loop; - - for i in 0 to 15 loop - if sdr_wr_msw(i) = '1' then - sdr_d(i) <= sdr_smp(i); - else - sdr_d(i) <= sdr_smp(i+16); - end if; - end loop; - - for i in 0 to 1 loop - if sdr_wr_msw(i+16) = '1' then - dm_q(i) <= sdr_smp(i+32); - else - dm_q(i) <= sdr_smp(i+34); - end if; - end loop; - - end if; - end process; - - process(cpu_clk_2x, areset) -- - begin - if areset = '1' then - refresh_cnt <= "0000000000"; - refresh_pend <= '0'; - refresh_end <= '0'; - refresh_wait_cnt <= "0000"; - refresh_wait_end <= '0'; - elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then - - if refresh_cnt = Refresh_Interval then - refresh_end <= '1'; - else - refresh_end <= '0'; - end if; - - if refresh_end = '1' then - refresh_cnt <= "0000000000"; - else - refresh_cnt <= refresh_cnt + '1'; - end if; - - if refresh_end = '1' and refresh_en = '1' then - refresh_pend <= '1'; - elsif ddr_state = refresh then - refresh_pend <= '0'; - else - refresh_pend <= refresh_pend; - end if; - - if ddr_state = refresh_wait then - refresh_wait_cnt <= refresh_wait_cnt + '1'; - else - refresh_wait_cnt <= "0000"; - end if; - - if refresh_wait_cnt = "1011" then - refresh_wait_end <= '1'; - else - refresh_wait_end <= '0'; - end if; - - end if; - end process; - - -- 911. THIS IS A DUMMY FOR FGPA IMPEMENTATION TESTING - - process(ddr_in_clk, areset) - begin - if areset = '1' then - ddr_clk_tog <= '0'; - elsif (ddr_in_clk'event and ddr_in_clk = '1') then - ddr_clk_tog <= not(ddr_clk_tog); - end if; - end process; - - process(ddr_in_clk_2x, areset) - begin - if areset = '1' then - ddr_clk_smp1 <= '0'; - ddr_clk_smp2 <= '0'; - ddr_clk_phase <= '0'; - elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then - ddr_clk_smp1 <= ddr_clk_tog; - ddr_clk_smp2 <= ddr_clk_smp1; - if ddr_clk_smp1 = '1' and ddr_clk_smp2 = '0' then - ddr_clk_phase <= '0'; - else - ddr_clk_phase <= not(ddr_clk_phase); - end if; - end if; - end process; - - process(ddr_in_clk_2x, areset) - begin - if areset = '1' then - cas_n_smp <= '0'; - ras_n_smp <= '0'; - we_n_smp <= '0'; - read_start_sig <= '0'; - elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then - cas_n_smp <= cas_qn_p_del; - ras_n_smp <= ras_qn_p_del; - we_n_smp <= we_qn_p_del; - if ras_n_smp = '1' and cas_n_smp = '0' and we_n_smp = '1' and ddr_clk_phase = '1' then - read_start_sig <= '1'; - else - read_start_sig <= '0'; - end if; - end if; - end process; - - process(ddr_in_clk_2x, areset) - begin - if areset = '1' then - sdr_d_in <= "0000000000000000"; - elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then - sdr_d_in <= sdr_d_p_del; - end if; - end process; - - process(ddr_in_clk_2x, areset) - begin - if areset = '1' then - read_time_cnt <= "00"; - read_input_en <= '0'; - elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then - - if read_start_sig = '1' then - read_time_cnt <= "01"; - elsif read_time_cnt = "00" then - read_time_cnt <= read_time_cnt; - else - read_time_cnt <= read_time_cnt + '1'; - end if; - - if read_time_cnt = "11" then - read_input_en <= '1'; - else - read_input_en <= '0'; - end if; - - read_input_en_del <= read_input_en; - - end if; - end process; - - process(ddr_in_clk_2x, areset) - begin - if areset = '1' then - ddr_data_read_int <= "00000000000000000000000000000000"; - elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then - if read_input_en = '1' then - ddr_data_read_int(15 downto 0) <= sdr_d_in; - end if; - if read_input_en_del = '1' then - ddr_data_read_int(31 downto 16) <= sdr_d_in; - end if; - end if; - end process; - -end behave; - - +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +library UNISIM; +use UNISIM.vcomponents.all; + +entity ddr_top is + generic( + simulate_io_time : boolean := false); + port ( -- Asyncronous reset and clocks + areset : in std_logic; + cpu_clk : in std_logic; + cpu_clk_2x : in std_logic; + cpu_clk_4x : in std_logic; + ddr_in_clk : in std_logic; + ddr_in_clk_2x : in std_logic; + + -- Command interface + ddr_command : in std_logic_vector(15 downto 0); + ddr_command_we : in std_logic; + refresh_en : in std_logic; + + -- Data interface signals + ddr_data_read : out std_logic_vector(31 downto 0); -- Data read from DDR SDRAM + ddr_data_write : in std_logic_vector(35 downto 0); -- Data to be written to DDR SDRAM + ddr_req_adr : in std_logic_vector(25 downto 1); -- Request address + ddr_req : in std_logic; -- Request DDR SDRAM access + ddr_busy : out std_logic; -- Request acknowledge + ddr_rd_wr_n : in std_logic; -- Access type 1=READ, 0=WRITE + ddr_req_len : in std_logic; -- Number of 16-bits words to transfer (0=2, 1=8) + ddr_read_en : out std_logic; -- Enable signal for read data + ddr_write_en : out std_logic; -- Enable (read) signal for data write + + -- DDR SDRAM Signals + sdr_clk_p : out std_logic; -- ddr_sdram_clock + sdr_clk_n_p : out std_logic; -- /ddr_sdram_clock + cke_q_p : out std_logic; -- clock enable + cs_qn_p : out std_logic; -- /chip select + ras_qn_p : inout std_logic; -- /ras + cas_qn_p : inout std_logic; -- /cas + we_qn_p : inout std_logic; -- /write enable + dm_q_p : out std_logic_vector(1 downto 0); -- data mask bits, set to "00" + dqs_q_p : out std_logic_vector(1 downto 0); -- data strobe, only for write + ba_q_p : out std_logic_vector(1 downto 0); -- bank select + sdr_a_p : out std_logic_vector(12 downto 0); -- address bus + sdr_d_p : inout std_logic_vector(15 downto 0)); -- bidir data bus +end ddr_top; + +architecture behave of ddr_top is + +attribute keep : string; + +type clk4_type is array(0 to 15) of std_logic_vector(1 downto 0); + +signal cpu_clk_tog : std_logic; +signal ddr_cmd : std_logic_vector(15 downto 0); +signal ddr_cmd_we_smp : std_logic; +signal new_command : std_logic; + +signal cpu_clk_2x_smp1 : std_logic; +signal cpu_clk_2x_smp2 : std_logic; +signal cpu_clk_4x_smp1 : std_logic; +signal cpu_clk_4x_smp2 : std_logic; + +signal clk2_phase : std_logic; +signal clk4_phase : std_logic_vector(3 downto 0); +signal clk4_phase_short : clk4_type; +attribute keep of clk4_phase_short:signal is "true"; + +signal ddr_clk_tog : std_logic; +signal ddr_clk_smp1 : std_logic; +signal ddr_clk_smp2 : std_logic; +signal ddr_clk_phase : std_logic; + +signal smp_req_adr : std_logic_vector(25 downto 1); +signal smp_req_type : std_logic; +signal smp_req_len : std_logic; +signal ddr_write_en_int : std_logic; +signal ddr_read_en_int : std_logic; + +signal dqs_q : std_logic_vector(1 downto 0); +signal dqs_oe_n : std_logic_vector(1 downto 0); +attribute keep of dqs_oe_n:signal is "true"; +signal cas_qn : std_logic; +signal ras_qn : std_logic; +signal we_qn : std_logic; +signal ba_q : std_logic_vector(1 downto 0); +signal sdr_clk : std_logic; +signal sdr_clk_n : std_logic; +signal sdr_a : std_logic_vector(12 downto 0); +signal sdr_d : std_logic_vector(15 downto 0); +signal sdr_smp : std_logic_vector(35 downto 0); +signal sdr_oe_n : std_logic_vector(15 downto 0); +attribute keep of sdr_oe_n:signal is "true"; +signal sdr_oe_ctrl : std_logic_vector(15 downto 0); +attribute keep of sdr_oe_ctrl:signal is "true"; +signal sdr_wr_msw : std_logic_vector(17 downto 0); +attribute keep of sdr_wr_msw:signal is "true"; +signal dm_q : std_logic_vector(1 downto 0); + +signal nowin_idle_dqs : std_logic_vector(1 downto 0); +signal nowin_wr_nop1_d : std_logic_vector(15 downto 0); +signal nowin_wr_nop1_dqs : std_logic_vector(1 downto 0); +signal nowin_wr_nop1_dm : std_logic_vector(1 downto 0); +signal nowin_wr_nop2_dqs : std_logic_vector(1 downto 0); +signal nowin_wr_nop3_d : std_logic_vector(15 downto 0); +signal nowin_wr_nop3_dqs : std_logic_vector(1 downto 0); +attribute keep of nowin_idle_dqs:signal is "true"; +attribute keep of nowin_wr_nop1_d:signal is "true"; +attribute keep of nowin_wr_nop1_dqs:signal is "true"; +attribute keep of nowin_wr_nop1_dm:signal is "true"; +attribute keep of nowin_wr_nop2_dqs:signal is "true"; +attribute keep of nowin_wr_nop3_d:signal is "true"; +attribute keep of nowin_wr_nop3_dqs:signal is "true"; + +signal cas_n_smp : std_logic; +signal ras_n_smp : std_logic; +signal we_n_smp : std_logic; +signal read_start_sig : std_logic; +signal sdr_d_in : std_logic_vector(15 downto 0); +signal read_time_cnt : std_logic_vector(1 downto 0); +signal read_input_en : std_logic; +signal read_input_en_del : std_logic; +signal ddr_data_read_int : std_logic_vector(31 downto 0); + +signal refresh_pend : std_logic; +signal refresh_end : std_logic; +signal refresh_cnt : std_logic_vector(9 downto 0); +signal refresh_wait_cnt : std_logic_vector(3 downto 0); +signal refresh_wait_end : std_logic; + +signal cas_qn_p_del : std_logic; +signal ras_qn_p_del : std_logic; +signal we_qn_p_del : std_logic; +signal sdr_d_p_del : std_logic_vector(15 downto 0); + +signal saved_row : std_logic_vector(26 downto 11); +signal operation : std_logic_vector(1 downto 0); + +signal ddr_req_adr_int : std_logic_vector(25 downto 1); + +type state_type is (idle, act, act_nop1, act_nop2, rd_wr, rd_nop1, + rd_nop2,rd_nop3,rd_nop4, rd_nop5,pre, pre_nop1, pre_nop2, wr_nop1, wr_nop2, + wr_nop3, cmd, cpu_pre, refresh, refresh_wait); +signal ddr_state : state_type; + +constant Clk_to_Output : time := 2.2 ns; +constant Input_Setup : time := 2.5 ns; + +constant Refresh_Interval : std_logic_vector(9 downto 0) := "1111100110"; + +begin + + iotimingon: + if simulate_io_time generate + begin + cas_qn_p_del <= 'X' after 0 ns, cas_qn_p after Input_Setup; + ras_qn_p_del <= 'X' after 0 ns, ras_qn_p after Input_Setup; + we_qn_p_del <= 'X' after 0 ns, we_qn_p after Input_Setup; + sdr_d_p_del <= "XXXXXXXXXXXXXXXX" after 0 ns, sdr_d_p after Input_Setup; + end generate; + + iotimingoff: + if not simulate_io_time generate + begin + cas_qn_p_del <= cas_qn_p; + ras_qn_p_del <= ras_qn_p; + we_qn_p_del <= we_qn_p; + sdr_d_p_del <= sdr_d_p; + end generate; + + ddr_write_en <= ddr_write_en_int; + ddr_read_en <= ddr_read_en_int; + ddr_data_read <= ddr_data_read_int; + + ddr_req_adr_int <= (ddr_req_adr(24 downto 10) & '0' & ddr_req_adr(9 downto 1)) when (simulate_io_time) else ddr_req_adr; + + process(cpu_clk, areset) -- Toggle a flip-flop with cpu_clk, in order + begin -- to find phase relation with 2x and 4x clocks + if areset = '1' then + cpu_clk_tog <= '0'; + elsif (cpu_clk'event and cpu_clk = '1') then + cpu_clk_tog <= not(cpu_clk_tog); + end if; + end process; + + process(cpu_clk_2x, areset) -- Find phase relation between cpu_clk and cpu_clk_2x + begin + if areset = '1' then + cpu_clk_2x_smp1 <= '0'; + cpu_clk_2x_smp2 <= '0'; + clk2_phase <= '0'; + elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then + cpu_clk_2x_smp1 <= cpu_clk_tog; + cpu_clk_2x_smp2 <= cpu_clk_2x_smp1; + if (cpu_clk_2x_smp1 = '1' and cpu_clk_2x_smp2 = '0') then + clk2_phase <= '0'; + else + clk2_phase <= not(clk2_phase); + end if; + end if; + end process; + + process(cpu_clk_4x, areset) -- Find phase relation between cpu_clk and cpu_clk_4x + begin + if areset = '1' then + cpu_clk_4x_smp1 <= '0'; + cpu_clk_4x_smp2 <= '0'; + clk4_phase <= "0000"; + clk4_phase_short(0) <= "00"; + clk4_phase_short(1) <= "00"; + clk4_phase_short(2) <= "00"; + clk4_phase_short(3) <= "00"; + clk4_phase_short(4) <= "00"; + clk4_phase_short(5) <= "00"; + clk4_phase_short(6) <= "00"; + clk4_phase_short(7) <= "00"; + clk4_phase_short(8) <= "00"; + clk4_phase_short(9) <= "00"; + clk4_phase_short(10) <= "00"; + clk4_phase_short(11) <= "00"; + clk4_phase_short(12) <= "00"; + clk4_phase_short(13) <= "00"; + clk4_phase_short(14) <= "00"; + clk4_phase_short(15) <= "00"; + elsif (cpu_clk_4x'event and cpu_clk_4x = '1') then + cpu_clk_4x_smp1 <= cpu_clk_tog; + cpu_clk_4x_smp2 <= cpu_clk_4x_smp1; + for i in 0 to 15 loop + if (cpu_clk_4x_smp1 = '1' and cpu_clk_4x_smp2 = '0') then + clk4_phase <= "0100"; + clk4_phase_short(i) <= "01"; + else + clk4_phase <= (clk4_phase(2 downto 0) & clk4_phase(3)); + clk4_phase_short(i) <= clk4_phase_short(i)(0) & clk4_phase_short(i)(1); + end if; + end loop; + end if; + end process; + + process(cpu_clk_4x, areset) -- + begin + if areset = '1' then + sdr_clk <= '0'; + sdr_clk_n <= '0'; + elsif (cpu_clk_4x'event and cpu_clk_4x = '1') then + if clk4_phase_short(0)(0) = '1' then + sdr_clk <= '1'; + else + sdr_clk <= '0'; + end if; + if clk4_phase_short(0)(1) = '1' then + sdr_clk_n <= '1'; + else + sdr_clk_n <= '0'; + end if; + end if; + end process; + + cke_q_p <= '1' after Clk_to_Output; + cs_qn_p <= '0' after Clk_to_Output; + + process(cpu_clk_4x, areset) -- + begin + if areset = '1' then + ras_qn_p <= '1'; + cas_qn_p <= '1'; + we_qn_p <= '1'; + dqs_q_p <= "ZZ"; + sdr_a_p <= "0000000000000"; + ba_q_p <= "00"; + sdr_clk_p <= '0'; + sdr_clk_n_p <= '1'; + elsif (cpu_clk_4x'event and cpu_clk_4x = '1') then + ras_qn_p <= transport ras_qn after Clk_to_Output; + cas_qn_p <= transport cas_qn after Clk_to_Output; + we_qn_p <= transport we_qn after Clk_to_Output; + if dqs_oe_n(0) = '0' then + dqs_q_p(0) <= transport dqs_q(0) after Clk_to_Output; + else + dqs_q_p(0) <= transport 'Z' after Clk_to_Output; + end if; + if dqs_oe_n(1) = '0' then + dqs_q_p(1) <= transport dqs_q(1) after Clk_to_Output; + else + dqs_q_p(1) <= transport 'Z' after Clk_to_Output; + end if; + sdr_a_p <= transport sdr_a after Clk_to_Output; + ba_q_p <= transport ba_q after Clk_to_Output; + sdr_clk_p <= transport sdr_clk after Clk_to_Output; + sdr_clk_n_p <= transport sdr_clk_n after Clk_to_Output; + end if; + end process; + + process(cpu_clk_2x, areset) -- + begin + if areset = '1' then + ddr_state <= idle; + ras_qn <= '1'; + cas_qn <= '1'; + we_qn <= '1'; + smp_req_adr <= (others => '0'); + smp_req_type <= '0'; + smp_req_len <= '0'; + sdr_a <= "XXXXXXXXXXXXX"; + ba_q <= "00"; + ddr_busy <= '1'; + saved_row <= "1000000000000000"; + ddr_write_en_int <= '0'; + ddr_read_en_int <= '0'; + nowin_idle_dqs <= "11"; + nowin_wr_nop1_d <= "0000000000000000"; + nowin_wr_nop1_dqs <= "00"; + nowin_wr_nop1_dm <= "00"; + nowin_wr_nop2_dqs <= "00"; + nowin_wr_nop3_d <= "0000000000000000"; + nowin_wr_nop3_dqs <= "00"; + elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then + + -- Default values + ras_qn <= '1'; + cas_qn <= '1'; + we_qn <= '1'; + sdr_a <= "XXXXXXXXXXXXX"; + ddr_busy <= '1'; + ddr_write_en_int <= '0'; + ddr_read_en_int <= '0'; + + nowin_idle_dqs <= "00"; + nowin_wr_nop1_d <= "0000000000000000"; + nowin_wr_nop1_dqs <= "00"; + nowin_wr_nop1_dm <= "00"; + nowin_wr_nop2_dqs <= "00"; + nowin_wr_nop3_d <= "0000000000000000"; + nowin_wr_nop3_dqs <= "00"; + + case ddr_state is + when idle => + smp_req_adr <= ddr_req_adr_int; + smp_req_type <= ddr_rd_wr_n; + smp_req_len <= ddr_req_len; + ddr_busy <= '0'; + operation <= "00"; + if refresh_pend = '1' then + operation <= "01"; + ddr_state <= pre; + elsif new_command = '1' then + if ddr_cmd(15) = '1' then + operation <= "10"; + ddr_state <= cpu_pre; + else + ddr_state <= cmd; + end if; + elsif (ddr_req = '1' and ddr_req_adr_int(25 downto 11) = saved_row(25 downto 11) and saved_row(26) = '0') then + operation <= "11"; + ddr_write_en_int <= not(ddr_rd_wr_n); + ddr_state <= rd_wr; + elsif ddr_req = '1' then + operation <= "11"; + ddr_state <= pre; + else + ddr_state <= idle; + nowin_idle_dqs <= "11"; + end if; + when act => + sdr_a <= smp_req_adr(23 downto 11); + ba_q <= smp_req_adr(25 downto 24); + ras_qn <= '0'; + ddr_write_en_int <= not(smp_req_type); + ddr_state <= act_nop1; + when act_nop1 => + ddr_state <= act_nop2; + when act_nop2 => + ddr_state <= rd_wr; + when rd_wr => + sdr_a(10) <= '0'; -- Disable auto precharge + sdr_a(9 downto 0) <= smp_req_adr(10 downto 1); + ba_q <= smp_req_adr(25 downto 24); + saved_row <= '0' & smp_req_adr(25 downto 11); + cas_qn <= '0'; + we_qn <= smp_req_type; + if smp_req_type = '1' then + ddr_state <= rd_nop1; + else + ddr_state <= wr_nop1; + nowin_wr_nop1_d <= "1111111111111111"; + nowin_wr_nop1_dqs <= "11"; + nowin_wr_nop1_dm <= "11"; + end if; + when wr_nop1 => + ddr_state <= wr_nop2; + nowin_wr_nop2_dqs <= "11"; + when wr_nop2 => + ddr_state <= wr_nop3; + nowin_wr_nop3_d <= "1111111111111111"; + nowin_wr_nop3_dqs <= "11"; + when wr_nop3 => + nowin_idle_dqs <= "11"; + ddr_state <= idle; + when rd_nop1 => + ddr_state <= rd_nop2; + when rd_nop2 => + if operation /= "11" then + nowin_idle_dqs <= "11"; + ddr_state <= idle; + else + ddr_state <= rd_nop3; + end if; + when rd_nop3 => + ddr_state <= rd_nop4; + when rd_nop4 => + ddr_read_en_int <= '1'; + ddr_state <= rd_nop5; + when rd_nop5 => + nowin_idle_dqs <= "11"; + ddr_state <= idle; + when pre => + ras_qn <= '0'; + we_qn <= '0'; + sdr_a(10) <= '1'; -- Precharge all banks + ba_q <= smp_req_adr(25 downto 24); + ddr_state <= pre_nop1; + when pre_nop1 => + ddr_state <= pre_nop2; + when cmd => + cas_qn <= '0'; + ras_qn <= '0'; + we_qn <= '0'; + ba_q <= ddr_cmd(14 downto 13); + sdr_a <= ddr_cmd(12 downto 0); + nowin_idle_dqs <= "11"; + ddr_state <= idle; + when cpu_pre => + ddr_state <= pre; + when refresh => + cas_qn <= '0'; + ras_qn <= '0'; + saved_row(26) <= '1'; + ddr_state <= refresh_wait; + when refresh_wait => + if refresh_wait_end = '1' then + ddr_state <= pre_nop2; + end if; + when pre_nop2 => + if operation = "01" then + operation <= "10"; + ddr_state <= refresh; + elsif operation = "10" then + nowin_idle_dqs <= "11"; + ddr_state <= idle; + else + ddr_state <= act; + end if; + when others => + ddr_state <= idle; + nowin_idle_dqs <= "11"; + end case; + end if; + end process; + + process(cpu_clk, areset) -- + begin + if areset = '1' then + ddr_cmd <= "0000000000000000"; + elsif (cpu_clk'event and cpu_clk = '1') then + if ddr_command_we = '1' then + ddr_cmd <= ddr_command; + else + ddr_cmd <= ddr_cmd; + end if; + end if; + end process; + + process(cpu_clk_2x, areset) -- + begin + if areset = '1' then + ddr_cmd_we_smp <= '0'; + new_command <= '0'; + sdr_smp <= "000000000000000000000000000000000000"; + elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then + ddr_cmd_we_smp <= ddr_command_we; + if ddr_command_we = '0' and ddr_cmd_we_smp = '1' then + new_command <= '1'; + elsif ddr_state = cmd or ddr_state = cpu_pre then + new_command <= '0'; + else + new_command <= new_command; + end if; + + if ddr_write_en_int = '1' then + sdr_smp <= ddr_data_write; + else + sdr_smp <= sdr_smp; + end if; + + end if; + end process; + + process(cpu_clk_4x, areset) -- + begin + if areset = '1' then + dqs_q <= "00"; + dqs_oe_n <= "11"; + sdr_oe_ctrl <= "1111111111111111"; + sdr_wr_msw <= "000000000000000000"; + elsif (cpu_clk_4x'event and cpu_clk_4x = '1') then + + for i in 0 to 15 loop + if nowin_wr_nop1_d(i) = '1' and clk4_phase_short(i)(0) = '1' then + sdr_oe_ctrl(i) <= '0'; + elsif nowin_wr_nop3_d(i) = '1' and clk4_phase_short(i)(0) = '1' then + sdr_oe_ctrl(i) <= '1'; + end if; + end loop; + + for i in 0 to 1 loop + if nowin_idle_dqs(i) = '1' or nowin_wr_nop3_dqs(i) = '1' then + dqs_oe_n(i) <= '1'; + elsif nowin_wr_nop1_dqs(i) = '1' then + dqs_oe_n(i) <= '0'; + end if; + end loop; + + for i in 0 to 1 loop + if (nowin_wr_nop2_dqs(i) = '1' and clk4_phase_short(i)(0) = '1') then + dqs_q(i) <= '1'; + else + dqs_q(i) <= '0'; + end if; + end loop; + + for i in 0 to 15 loop + if nowin_wr_nop1_d(i) = '1' and clk4_phase_short(i)(1) = '1' then + sdr_wr_msw(i) <= '1'; + else + sdr_wr_msw(i) <= '0'; + end if; + end loop; + + for i in 0 to 1 loop + if nowin_wr_nop1_dm(i) = '1' and clk4_phase_short(i)(1) = '1' then + sdr_wr_msw(i+16) <= '1'; + else + sdr_wr_msw(i+16) <= '0'; + end if; + end loop; + + end if; + end process; + + -- NOTE! DATA OUTPUT PATH. CLOCKED ON FALLING 4X CLOCK + process(cpu_clk_4x, areset) -- + begin + if areset = '1' then + sdr_d_p <= "ZZZZZZZZZZZZZZZZ"; + dm_q_p <= "11"; + sdr_oe_n <= "1111111111111111"; + sdr_d <= "0000000000000000"; + dm_q <= "11"; + elsif (cpu_clk_4x'event and cpu_clk_4x = '0') then + + for i in 0 to 15 loop + if sdr_oe_n(i) = '0' then + sdr_d_p(i) <= transport sdr_d(i) after Clk_to_Output; + else + sdr_d_p(i) <= transport 'Z' after Clk_to_Output; + end if; + end loop; + + dm_q_p <= transport dm_q after Clk_to_Output; + + for i in 0 to 15 loop + if sdr_oe_ctrl(i) = '0' then + sdr_oe_n(i) <= '0'; + else + sdr_oe_n(i) <= '1'; + end if; + end loop; + + for i in 0 to 15 loop + if sdr_wr_msw(i) = '1' then + sdr_d(i) <= sdr_smp(i); + else + sdr_d(i) <= sdr_smp(i+16); + end if; + end loop; + + for i in 0 to 1 loop + if sdr_wr_msw(i+16) = '1' then + dm_q(i) <= sdr_smp(i+32); + else + dm_q(i) <= sdr_smp(i+34); + end if; + end loop; + + end if; + end process; + + process(cpu_clk_2x, areset) -- + begin + if areset = '1' then + refresh_cnt <= "0000000000"; + refresh_pend <= '0'; + refresh_end <= '0'; + refresh_wait_cnt <= "0000"; + refresh_wait_end <= '0'; + elsif (cpu_clk_2x'event and cpu_clk_2x = '1') then + + if refresh_cnt = Refresh_Interval then + refresh_end <= '1'; + else + refresh_end <= '0'; + end if; + + if refresh_end = '1' then + refresh_cnt <= "0000000000"; + else + refresh_cnt <= refresh_cnt + '1'; + end if; + + if refresh_end = '1' and refresh_en = '1' then + refresh_pend <= '1'; + elsif ddr_state = refresh then + refresh_pend <= '0'; + else + refresh_pend <= refresh_pend; + end if; + + if ddr_state = refresh_wait then + refresh_wait_cnt <= refresh_wait_cnt + '1'; + else + refresh_wait_cnt <= "0000"; + end if; + + if refresh_wait_cnt = "1011" then + refresh_wait_end <= '1'; + else + refresh_wait_end <= '0'; + end if; + + end if; + end process; + + -- 911. THIS IS A DUMMY FOR FGPA IMPEMENTATION TESTING + + process(ddr_in_clk, areset) + begin + if areset = '1' then + ddr_clk_tog <= '0'; + elsif (ddr_in_clk'event and ddr_in_clk = '1') then + ddr_clk_tog <= not(ddr_clk_tog); + end if; + end process; + + process(ddr_in_clk_2x, areset) + begin + if areset = '1' then + ddr_clk_smp1 <= '0'; + ddr_clk_smp2 <= '0'; + ddr_clk_phase <= '0'; + elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then + ddr_clk_smp1 <= ddr_clk_tog; + ddr_clk_smp2 <= ddr_clk_smp1; + if ddr_clk_smp1 = '1' and ddr_clk_smp2 = '0' then + ddr_clk_phase <= '0'; + else + ddr_clk_phase <= not(ddr_clk_phase); + end if; + end if; + end process; + + process(ddr_in_clk_2x, areset) + begin + if areset = '1' then + cas_n_smp <= '0'; + ras_n_smp <= '0'; + we_n_smp <= '0'; + read_start_sig <= '0'; + elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then + cas_n_smp <= cas_qn_p_del; + ras_n_smp <= ras_qn_p_del; + we_n_smp <= we_qn_p_del; + if ras_n_smp = '1' and cas_n_smp = '0' and we_n_smp = '1' and ddr_clk_phase = '1' then + read_start_sig <= '1'; + else + read_start_sig <= '0'; + end if; + end if; + end process; + + process(ddr_in_clk_2x, areset) + begin + if areset = '1' then + sdr_d_in <= "0000000000000000"; + elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then + sdr_d_in <= sdr_d_p_del; + end if; + end process; + + process(ddr_in_clk_2x, areset) + begin + if areset = '1' then + read_time_cnt <= "00"; + read_input_en <= '0'; + elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then + + if read_start_sig = '1' then + read_time_cnt <= "01"; + elsif read_time_cnt = "00" then + read_time_cnt <= read_time_cnt; + else + read_time_cnt <= read_time_cnt + '1'; + end if; + + if read_time_cnt = "11" then + read_input_en <= '1'; + else + read_input_en <= '0'; + end if; + + read_input_en_del <= read_input_en; + + end if; + end process; + + process(ddr_in_clk_2x, areset) + begin + if areset = '1' then + ddr_data_read_int <= "00000000000000000000000000000000"; + elsif (ddr_in_clk_2x'event and ddr_in_clk_2x = '1') then + if read_input_en = '1' then + ddr_data_read_int(15 downto 0) <= sdr_d_in; + end if; + if read_input_en_del = '1' then + ddr_data_read_int(31 downto 16) <= sdr_d_in; + end if; + end if; + end process; + +end behave; + + diff --git a/misc/ddrsdram/src/mt46v16m16.vhd b/misc/ddrsdram/src/mt46v16m16.vhd index 6b89345..356bb28 100644 --- a/misc/ddrsdram/src/mt46v16m16.vhd +++ b/misc/ddrsdram/src/mt46v16m16.vhd @@ -1,1320 +1,1320 @@ ------------------------------------------------------------------------------------------ --- --- File Name: MT46V16M16.VHD --- Version: 2.1 --- Date: January 14th, 2002 --- Model: Behavioral --- Simulator: NCDesktop - http://www.cadence.com --- ModelSim PE - http://www.model.com --- --- Dependencies: None --- --- Author: Son P. Huynh --- Email: sphuynh@micron.com --- Phone: (208) 368-3825 --- Company: Micron Technology, Inc. --- Part Number: MT46V16M16 (4 Mb x 16 x 4 Banks) --- --- Description: Micron 256 Mb SDRAM DDR (Double Data Rate) --- --- Limitation: Doesn't model internal refresh counter --- --- Note: --- --- Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY --- WHATSOEVER AND MICRON SPECIFICALLY DISCLAIMS ANY --- IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR --- A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT. --- --- Copyright (c) 1998 Micron Semiconductor Products, Inc. --- All rights researved --- --- Rev Author Date Changes --- --- ---------------------------- ---------- ------------------------------------- --- 2.1 Son P. Huynh 01/14/2002 - Fix Burst_counter --- Micron Technology, Inc. --- --- 2.0 Son P. Huynh 11/08/2001 - Second release --- Micron Technology, Inc. - Rewrote and remove SHARED VARIABLE --- ------------------------------------------------------------------------------------------ - -LIBRARY IEEE; - USE IEEE.STD_LOGIC_1164.ALL; - USE IEEE.STD_LOGIC_UNSIGNED.ALL; - USE IEEE.STD_LOGIC_ARITH.ALL; - -ENTITY MT46V16M16 IS - GENERIC ( -- Timing for -75Z CL2 - tCK : TIME := 7.500 ns; - tCH : TIME := 3.375 ns; -- 0.45*tCK - tCL : TIME := 3.375 ns; -- 0.45*tCK - tDH : TIME := 0.500 ns; - tDS : TIME := 0.500 ns; - tIH : TIME := 0.900 ns; - tIS : TIME := 0.900 ns; - tMRD : TIME := 15.000 ns; - tRAS : TIME := 40.000 ns; - tRAP : TIME := 20.000 ns; - tRC : TIME := 65.000 ns; - tRFC : TIME := 75.000 ns; - tRCD : TIME := 20.000 ns; - tRP : TIME := 20.000 ns; - tRRD : TIME := 15.000 ns; - tWR : TIME := 15.000 ns; - addr_bits : INTEGER := 13; - data_bits : INTEGER := 16; - cols_bits : INTEGER := 9 - ); - PORT ( - Dq : INOUT STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0) := (OTHERS => 'Z'); - Dqs : INOUT STD_LOGIC_VECTOR (1 DOWNTO 0) := "ZZ"; - Addr : IN STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0); - Ba : IN STD_LOGIC_VECTOR (1 DOWNTO 0); - Clk : IN STD_LOGIC; - Clk_n : IN STD_LOGIC; - Cke : IN STD_LOGIC; - Cs_n : IN STD_LOGIC; - Ras_n : IN STD_LOGIC; - Cas_n : IN STD_LOGIC; - We_n : IN STD_LOGIC; - Dm : IN STD_LOGIC_VECTOR (1 DOWNTO 0) - ); -END MT46V16M16; - -ARCHITECTURE behave OF MT46V16M16 IS - -- Array for Read pipeline - TYPE Array_Read_cmnd IS ARRAY (8 DOWNTO 0) OF STD_LOGIC; - TYPE Array_Read_bank IS ARRAY (8 DOWNTO 0) OF STD_LOGIC_VECTOR (1 DOWNTO 0); - TYPE Array_Read_cols IS ARRAY (8 DOWNTO 0) OF STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0); - - -- Array for Write pipeline - TYPE Array_Write_cmnd IS ARRAY (2 DOWNTO 0) OF STD_LOGIC; - TYPE Array_Write_bank IS ARRAY (2 DOWNTO 0) OF STD_LOGIC_VECTOR (1 DOWNTO 0); - TYPE Array_Write_cols IS ARRAY (2 DOWNTO 0) OF STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0); - - -- Array for Auto Precharge - TYPE Array_Read_precharge IS ARRAY (3 DOWNTO 0) OF STD_LOGIC; - TYPE Array_Write_precharge IS ARRAY (3 DOWNTO 0) OF STD_LOGIC; - TYPE Array_Count_precharge IS ARRAY (3 DOWNTO 0) OF INTEGER; - - -- Array for Manual Precharge - TYPE Array_A10_precharge IS ARRAY (8 DOWNTO 0) OF STD_LOGIC; - TYPE Array_Bank_precharge IS ARRAY (8 DOWNTO 0) OF STD_LOGIC_VECTOR (1 DOWNTO 0); - TYPE Array_Cmnd_precharge IS ARRAY (8 DOWNTO 0) OF STD_LOGIC; - - -- Array for Burst Terminate - TYPE Array_Cmnd_bst IS ARRAY (8 DOWNTO 0) OF STD_LOGIC; - - -- Array for Memory Access - TYPE Array_ram_type IS ARRAY (2**cols_bits - 1 DOWNTO 0) OF STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0); - TYPE Array_ram_pntr IS ACCESS Array_ram_type; - TYPE Array_ram_stor IS ARRAY (2**addr_bits - 1 DOWNTO 0) OF Array_ram_pntr; - - -- Data pair - SIGNAL Dq_pair : STD_LOGIC_VECTOR (2 * data_bits - 1 DOWNTO 0); - SIGNAL Dm_pair : STD_LOGIC_VECTOR (3 DOWNTO 0); - - -- Mode Register - SIGNAL Mode_reg : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0) := (OTHERS => '0'); - - -- Command Decode Variables - SIGNAL Active_enable, Aref_enable, Burst_term, Ext_mode_enable : STD_LOGIC := '0'; - SIGNAL Mode_reg_enable, Prech_enable, Read_enable, Write_enable : STD_LOGIC := '0'; - - -- Burst Length Decode Variables - SIGNAL Burst_length_2, Burst_length_4, Burst_length_8, Burst_length_f : STD_LOGIC := '0'; - - -- Cas Latency Decode Variables - SIGNAL Cas_latency_15, Cas_latency_2, Cas_latency_25, Cas_latency_3, Cas_latency_4 : STD_LOGIC := '0'; - - -- Internal Control Signals - SIGNAL Cs_in, Ras_in, Cas_in, We_in : STD_LOGIC := '0'; - - -- System Clock - SIGNAL Sys_clk : STD_LOGIC := '0'; - - -- Dqs buffer - SIGNAL Dqs_out : STD_LOGIC_VECTOR (1 DOWNTO 0) := "ZZ"; - -BEGIN - -- Strip the strength - Cs_in <= To_X01 (Cs_n); - Ras_in <= To_X01 (Ras_n); - Cas_in <= To_X01 (Cas_n); - We_in <= To_X01 (We_n); - - -- Commands Decode - Active_enable <= NOT(Cs_in) AND NOT(Ras_in) AND Cas_in AND We_in; - Aref_enable <= NOT(Cs_in) AND NOT(Ras_in) AND NOT(Cas_in) AND We_in; - Burst_term <= NOT(Cs_in) AND Ras_in AND Cas_in AND NOT(We_in); - Ext_mode_enable <= NOT(Cs_in) AND NOT(Ras_in) AND NOT(Cas_in) AND NOT(We_in) AND Ba(0) AND NOT(Ba(1)); - Mode_reg_enable <= NOT(Cs_in) AND NOT(Ras_in) AND NOT(Cas_in) AND NOT(We_in) AND NOT(Ba(0)) AND NOT(Ba(1)); - Prech_enable <= NOT(Cs_in) AND NOT(Ras_in) AND Cas_in AND NOT(We_in); - Read_enable <= NOT(Cs_in) AND Ras_in AND NOT(Cas_in) AND We_in; - Write_enable <= NOT(Cs_in) AND Ras_in AND NOT(Cas_in) AND NOT(We_in); - - -- Burst Length Decode - Burst_length_2 <= NOT(Mode_reg(2)) AND NOT(Mode_reg(1)) AND Mode_reg(0); - Burst_length_4 <= NOT(Mode_reg(2)) AND Mode_reg(1) AND NOT(Mode_reg(0)); - Burst_length_8 <= NOT(Mode_reg(2)) AND Mode_reg(1) AND Mode_reg(0); - Burst_length_f <= (Mode_reg(2)) AND Mode_reg(1) AND Mode_reg(0); - - -- CAS Latency Decode - Cas_latency_15 <= Mode_reg(6) AND NOT(Mode_reg(5)) AND (Mode_reg(4)); - Cas_latency_2 <= NOT(Mode_reg(6)) AND Mode_reg(5) AND NOT(Mode_reg(4)); - Cas_latency_25 <= Mode_reg(6) AND Mode_reg(5) AND NOT(Mode_reg(4)); - Cas_latency_3 <= NOT(Mode_reg(6)) AND Mode_reg(5) AND Mode_reg(4); - Cas_latency_4 <= (Mode_reg(6)) AND NOT(Mode_reg(5)) AND NOT(Mode_reg(4)); - - -- Dqs buffer - Dqs <= Dqs_out; - - -- - -- System Clock - -- - int_clk : PROCESS (Clk, Clk_n) - VARIABLE ClkZ, CkeZ : STD_LOGIC := '0'; - begin - IF Clk = '1' AND Clk_n = '0' THEN - ClkZ := '1'; - CkeZ := Cke; - ELSIF Clk = '0' AND Clk_n = '1' THEN - ClkZ := '0'; - END IF; - Sys_clk <= CkeZ AND ClkZ; - END PROCESS; - - -- - -- Main Process - -- - state_register : PROCESS - -- Precharge Variables - VARIABLE Pc_b0, Pc_b1, Pc_b2, Pc_b3 : STD_LOGIC := '0'; - - -- Activate Variables - VARIABLE Act_b0, Act_b1, Act_b2, Act_b3 : STD_LOGIC := '1'; - - -- Data IO variables - VARIABLE Data_in_enable, Data_out_enable : STD_LOGIC := '0'; - - -- Internal address mux variables - VARIABLE Cols_brst : STD_LOGIC_VECTOR (2 DOWNTO 0); - VARIABLE Prev_bank : STD_LOGIC_VECTOR (1 DOWNTO 0) := "00"; - VARIABLE Bank_addr : STD_LOGIC_VECTOR (1 DOWNTO 0) := "00"; - VARIABLE Cols_addr : STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0); - VARIABLE Rows_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0); - VARIABLE B0_row_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0); - VARIABLE B1_row_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0); - VARIABLE B2_row_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0); - VARIABLE B3_row_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0); - - -- DLL Reset variables - VARIABLE DLL_enable : STD_LOGIC := '0'; - VARIABLE DLL_reset : STD_LOGIC := '0'; - VARIABLE DLL_done : STD_LOGIC := '0'; - VARIABLE DLL_count : INTEGER := 0; - - -- Timing Check - VARIABLE MRD_chk : TIME := 0 ns; - VARIABLE RFC_chk : TIME := 0 ns; - VARIABLE RRD_chk : TIME := 0 ns; - VARIABLE RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3 : TIME := 0 ns; - VARIABLE RAP_chk0, RAP_chk1, RAP_chk2, RAP_chk3 : TIME := 0 ns; - VARIABLE RC_chk0, RC_chk1, RC_chk2, RC_chk3 : TIME := 0 ns; - VARIABLE RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3 : TIME := 0 ns; - VARIABLE RP_chk0, RP_chk1, RP_chk2, RP_chk3 : TIME := 0 ns; - VARIABLE WR_chk0, WR_chk1, WR_chk2, WR_chk3 : TIME := 0 ns; - - -- Read pipeline variables - VARIABLE Read_cmnd : Array_Read_cmnd; - VARIABLE Read_bank : Array_Read_bank; - VARIABLE Read_cols : Array_Read_cols; - - -- Write pipeline variables - VARIABLE Write_cmnd : Array_Write_cmnd; - VARIABLE Write_bank : Array_Write_bank; - VARIABLE Write_cols : Array_Write_cols; - - -- Auto Precharge variables - VARIABLE Read_precharge : Array_Read_precharge := ('0' & '0' & '0' & '0'); - VARIABLE Write_precharge : Array_Write_precharge := ('0' & '0' & '0' & '0'); - VARIABLE Count_precharge : Array_Count_precharge := ( 0 & 0 & 0 & 0 ); - - -- Manual Precharge variables - VARIABLE A10_precharge : Array_A10_precharge; - VARIABLE Bank_precharge : Array_Bank_precharge; - VARIABLE Cmnd_precharge : Array_Cmnd_precharge; - - -- Burst Terminate variable - VARIABLE Cmnd_bst : Array_Cmnd_bst; - - -- Memory Banks - VARIABLE Bank0 : Array_ram_stor; - VARIABLE Bank1 : Array_ram_stor; - VARIABLE Bank2 : Array_ram_stor; - VARIABLE Bank3 : Array_ram_stor; - - -- Burst Counter - VARIABLE Burst_counter : STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0); - - -- Internal Dqs initialize - VARIABLE Dqs_int : STD_LOGIC := '0'; - - -- Data buffer for DM Mask - VARIABLE Data_buf : STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0) := (OTHERS => 'Z'); - - -- - -- Initialize empty rows - -- - PROCEDURE Init_mem (Bank : STD_LOGIC_VECTOR; Row_index : INTEGER) IS - VARIABLE i, j : INTEGER := 0; - BEGIN - IF Bank = "00" THEN - IF Bank0 (Row_index) = NULL THEN -- Check to see if row empty - Bank0 (Row_index) := NEW Array_ram_type; -- Open new row for access - FOR i IN (2**cols_bits - 1) DOWNTO 0 LOOP -- Filled row with zeros - FOR j IN (data_bits - 1) DOWNTO 0 LOOP - Bank0 (Row_index) (i) (j) := '0'; - END LOOP; - END LOOP; - END IF; - ELSIF Bank = "01" THEN - IF Bank1 (Row_index) = NULL THEN - Bank1 (Row_index) := NEW Array_ram_type; - FOR i IN (2**cols_bits - 1) DOWNTO 0 LOOP - FOR j IN (data_bits - 1) DOWNTO 0 LOOP - Bank1 (Row_index) (i) (j) := '0'; - END LOOP; - END LOOP; - END IF; - ELSIF Bank = "10" THEN - IF Bank2 (Row_index) = NULL THEN - Bank2 (Row_index) := NEW Array_ram_type; - FOR i IN (2**cols_bits - 1) DOWNTO 0 LOOP - FOR j IN (data_bits - 1) DOWNTO 0 LOOP - Bank2 (Row_index) (i) (j) := '0'; - END LOOP; - END LOOP; - END IF; - ELSIF Bank = "11" THEN - IF Bank3 (Row_index) = NULL THEN - Bank3 (Row_index) := NEW Array_ram_type; - FOR i IN (2**cols_bits - 1) DOWNTO 0 LOOP - FOR j IN (data_bits - 1) DOWNTO 0 LOOP - Bank3 (Row_index) (i) (j) := '0'; - END LOOP; - END LOOP; - END IF; - END IF; - END; - - -- - -- Burst Counter - -- - PROCEDURE Burst_decode IS - VARIABLE Cols_temp : STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0) := (OTHERS => '0'); - BEGIN - -- Advance burst counter - Burst_counter := Burst_counter + 1; - - -- Burst Type - IF Mode_reg (3) = '0' THEN - Cols_temp := Cols_addr + 1; - ELSIF Mode_reg (3) = '1' THEN - Cols_temp (2) := Burst_counter (2) XOR Cols_brst (2); - Cols_temp (1) := Burst_counter (1) XOR Cols_brst (1); - Cols_temp (0) := Burst_counter (0) XOR Cols_brst (0); - END IF; - - -- Burst Length - IF Burst_length_2 = '1' THEN - Cols_addr (0) := Cols_temp (0); - ELSIF Burst_length_4 = '1' THEN - Cols_addr (1 DOWNTO 0) := Cols_temp (1 DOWNTO 0); - ELSIF Burst_length_8 = '1' THEN - Cols_addr (2 DOWNTO 0) := Cols_temp (2 DOWNTO 0); - ELSE - Cols_addr := Cols_temp; - END IF; - - -- Data counter - IF Burst_length_2 = '1' THEN - IF Burst_counter >= 2 THEN - IF Data_in_enable = '1' THEN - Data_in_enable := '0'; - ELSIF Data_out_enable = '1' THEN - Data_out_enable := '0'; - END IF; - END IF; - ELSIF Burst_length_4 = '1' THEN - IF Burst_counter >= 4 THEN - IF Data_in_enable = '1' THEN - Data_in_enable := '0'; - ELSIF Data_out_enable = '1' THEN - Data_out_enable := '0'; - END IF; - END IF; - ELSIF Burst_length_8 = '1' THEN - IF Burst_counter >= 8 THEN - IF Data_in_enable = '1' THEN - Data_in_enable := '0'; - ELSIF Data_out_enable = '1' THEN - Data_out_enable := '0'; - END IF; - END IF; - END IF; - END; - - BEGIN - WAIT ON Sys_clk; - - -- - -- Manual Precharge Pipeline - -- - IF ((Sys_clk'EVENT AND Sys_clk = '0') OR (Sys_clk'EVENT AND Sys_clk = '1')) THEN - -- A10 Precharge Pipeline - A10_precharge(0) := A10_precharge(1); - A10_precharge(1) := A10_precharge(2); - A10_precharge(2) := A10_precharge(3); - A10_precharge(3) := A10_precharge(4); - A10_precharge(4) := A10_precharge(5); - A10_precharge(5) := A10_precharge(6); - A10_precharge(6) := A10_precharge(7); - A10_precharge(7) := A10_precharge(8); - A10_precharge(8) := '0'; - - -- Bank Precharge Pipeline - Bank_precharge(0) := Bank_precharge(1); - Bank_precharge(1) := Bank_precharge(2); - Bank_precharge(2) := Bank_precharge(3); - Bank_precharge(3) := Bank_precharge(4); - Bank_precharge(4) := Bank_precharge(5); - Bank_precharge(5) := Bank_precharge(6); - Bank_precharge(6) := Bank_precharge(7); - Bank_precharge(7) := Bank_precharge(8); - Bank_precharge(8) := "00"; - - -- Command Precharge Pipeline - Cmnd_precharge(0) := Cmnd_precharge(1); - Cmnd_precharge(1) := Cmnd_precharge(2); - Cmnd_precharge(2) := Cmnd_precharge(3); - Cmnd_precharge(3) := Cmnd_precharge(4); - Cmnd_precharge(4) := Cmnd_precharge(5); - Cmnd_precharge(5) := Cmnd_precharge(6); - Cmnd_precharge(6) := Cmnd_precharge(7); - Cmnd_precharge(7) := Cmnd_precharge(8); - Cmnd_precharge(8) := '0'; - - -- Terminate Read if same bank or all banks - IF ((Cmnd_precharge (0) = '1') AND - (Bank_precharge (0) = Bank_addr OR A10_precharge (0) = '1') AND - (Data_out_enable = '1')) THEN - Data_out_enable := '0'; - END IF; - END IF; - - -- - -- Burst Terminate Pipeline - -- - IF ((Sys_clk'EVENT AND Sys_clk = '0') OR (Sys_clk'EVENT AND Sys_clk = '1')) THEN - -- Burst Terminate pipeline - Cmnd_bst (0) := Cmnd_bst (1); - Cmnd_bst (1) := Cmnd_bst (2); - Cmnd_bst (2) := Cmnd_bst (3); - Cmnd_bst (3) := Cmnd_bst (4); - Cmnd_bst (4) := Cmnd_bst (5); - Cmnd_bst (5) := Cmnd_bst (6); - Cmnd_bst (6) := Cmnd_bst (7); - Cmnd_bst (7) := Cmnd_bst (8); - Cmnd_bst (8) := '0'; - - -- Terminate current Read - IF ((Cmnd_bst (0) = '1') AND (Data_out_enable = '1')) THEN - Data_out_enable := '0'; - END IF; - END IF; - - -- - -- Dq and Dqs Drivers - -- - IF ((Sys_clk'EVENT AND Sys_clk = '0') OR (Sys_clk'EVENT AND Sys_clk = '1')) THEN - -- Read Command Pipeline - Read_cmnd (0) := Read_cmnd (1); - Read_cmnd (1) := Read_cmnd (2); - Read_cmnd (2) := Read_cmnd (3); - Read_cmnd (3) := Read_cmnd (4); - Read_cmnd (4) := Read_cmnd (5); - Read_cmnd (5) := Read_cmnd (6); - Read_cmnd (6) := Read_cmnd (7); - Read_cmnd (7) := Read_cmnd (8); - Read_cmnd (8) := '0'; - - -- Read Bank Pipeline - Read_bank (0) := Read_bank (1); - Read_bank (1) := Read_bank (2); - Read_bank (2) := Read_bank (3); - Read_bank (3) := Read_bank (4); - Read_bank (4) := Read_bank (5); - Read_bank (5) := Read_bank (6); - Read_bank (6) := Read_bank (7); - Read_bank (7) := Read_bank (8); - Read_bank (8) := "00"; - - -- Read Column Pipeline - Read_cols (0) := Read_cols (1); - Read_cols (1) := Read_cols (2); - Read_cols (2) := Read_cols (3); - Read_cols (3) := Read_cols (4); - Read_cols (4) := Read_cols (5); - Read_cols (5) := Read_cols (6); - Read_cols (6) := Read_cols (7); - Read_cols (7) := Read_cols (8); - Read_cols (8) := (OTHERS => '0'); - - -- Initialize Read command - IF Read_cmnd (0) = '1' THEN - Data_out_enable := '1'; - Bank_addr := Read_bank (0); - Cols_addr := Read_cols (0); - Cols_brst := Cols_addr (2 DOWNTO 0); - Burst_counter := (OTHERS => '0'); - - -- Row address mux - CASE Bank_addr IS - WHEN "00" => Rows_addr := B0_row_addr; - WHEN "01" => Rows_addr := B1_row_addr; - WHEN "10" => Rows_addr := B2_row_addr; - WHEN OTHERS => Rows_addr := B3_row_addr; - END CASE; - END IF; - - -- Toggle Dqs during Read command - IF Data_out_enable = '1' THEN - Dqs_int := '0'; - IF Dqs_out = "00" THEN - Dqs_out <= "11"; - ELSIF Dqs_out = "11" THEN - Dqs_out <= "00"; - ELSE - Dqs_out <= "00"; - END IF; - ELSIF Data_out_enable = '0' AND Dqs_int = '0' THEN - Dqs_out <= "ZZ"; - END IF; - - -- Initialize Dqs for Read command - IF Read_cmnd (2) = '1' THEN - IF Data_out_enable = '0' THEN - Dqs_int := '1'; - Dqs_out <= "00"; - END IF; - END IF; - - -- Read Latch - IF Data_out_enable = '1' THEN - -- Initialize Memory - Init_mem (Bank_addr, CONV_INTEGER(Rows_addr)); - - -- Output Data - CASE Bank_addr IS - WHEN "00" => Dq <= Bank0 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); - WHEN "01" => Dq <= Bank1 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); - WHEN "10" => Dq <= Bank2 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); - WHEN OTHERS => Dq <= Bank3 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); - END CASE; - - -- Increase Burst Counter - Burst_decode; - ELSE - Dq <= (OTHERS => 'Z'); - END IF; - END IF; - - -- - -- Write FIFO and DM Mask Logic - -- - IF Sys_clk'EVENT AND Sys_clk = '1' THEN - -- Write command pipeline - Write_cmnd (0) := Write_cmnd (1); - Write_cmnd (1) := Write_cmnd (2); - Write_cmnd (2) := '0'; - - -- Write command pipeline - Write_bank (0) := Write_bank (1); - Write_bank (1) := Write_bank (2); - Write_bank (2) := "00"; - - -- Write column pipeline - Write_cols (0) := Write_cols (1); - Write_cols (1) := Write_cols (2); - Write_cols (2) := (OTHERS => '0'); - - -- Initialize Write command - IF Write_cmnd (0) = '1' THEN - Data_in_enable := '1'; - Bank_addr := Write_bank (0); - Cols_addr := Write_cols (0); - Cols_brst := Cols_addr (2 DOWNTO 0); - Burst_counter := (OTHERS => '0'); - - -- Row address mux - CASE Bank_addr IS - WHEN "00" => Rows_addr := B0_row_addr; - WHEN "01" => Rows_addr := B1_row_addr; - WHEN "10" => Rows_addr := B2_row_addr; - WHEN OTHERS => Rows_addr := B3_row_addr; - END CASE; - END IF; - - -- Write data - IF Data_in_enable = '1' THEN - -- Initialize memory - Init_mem (Bank_addr, CONV_INTEGER(Rows_addr)); - - -- Write first data - IF Dm_pair (1) = '0' OR Dm_pair (0) = '0' THEN - -- Data Buffer - CASE Bank_addr IS - WHEN "00" => Data_buf := Bank0 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); - WHEN "01" => Data_buf := Bank1 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); - WHEN "10" => Data_buf := Bank2 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); - WHEN OTHERS => Data_buf := Bank3 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); - END CASE; - - -- Perform DM Mask - IF Dm_pair (0) = '0' THEN - Data_buf ( 7 DOWNTO 0) := Dq_pair ( 7 DOWNTO 0); - END IF; - IF Dm_pair (1) = '0' THEN - Data_buf (15 DOWNTO 8) := Dq_pair (15 DOWNTO 8); - END IF; - - -- Write Data - CASE Bank_addr IS - WHEN "00" => Bank0 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf; - WHEN "01" => Bank1 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf; - WHEN "10" => Bank2 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf; - WHEN OTHERS => Bank3 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf; - END CASE; - END IF; - - -- Increase Burst Counter - Burst_decode; - - -- Write second data - IF Dm_pair (3) = '0' OR Dm_pair (2) = '0' THEN - -- Data Buffer - CASE Bank_addr IS - WHEN "00" => Data_buf := Bank0 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); - WHEN "01" => Data_buf := Bank1 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); - WHEN "10" => Data_buf := Bank2 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); - WHEN OTHERS => Data_buf := Bank3 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); - END CASE; - - -- Perform DM Mask - IF Dm_pair (2) = '0' THEN - Data_buf ( 7 DOWNTO 0) := Dq_pair (23 DOWNTO 16); - END IF; - IF Dm_pair (3) = '0' THEN - Data_buf (15 DOWNTO 8) := Dq_pair (31 DOWNTO 24); - END IF; - - -- Write Data - CASE Bank_addr IS - WHEN "00" => Bank0 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf; - WHEN "01" => Bank1 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf; - WHEN "10" => Bank2 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf; - WHEN OTHERS => Bank3 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf; - END CASE; - END IF; - - -- Increase Burst Counter - Burst_decode; - - -- tWR start and tWTR check - IF Dm_pair (3 DOWNTO 2) = "00" OR Dm_pair (1 DOWNTO 0) = "00" THEN - CASE Bank_addr IS - WHEN "00" => WR_chk0 := NOW; - WHEN "01" => WR_chk1 := NOW; - WHEN "10" => WR_chk2 := NOW; - WHEN OTHERS => WR_chk3 := NOW; - END CASE; - - -- tWTR check - ASSERT (Read_enable = '0') - REPORT "tWTR violation during Read" - SEVERITY WARNING; - END IF; - END IF; - END IF; - - -- - -- Auto Precharge Calculation - -- - IF Sys_clk'EVENT AND Sys_clk = '1' THEN - -- Precharge counter - IF Read_precharge (0) = '1' OR Write_precharge (0) = '1' THEN - Count_precharge (0) := Count_precharge (0) + 1; - END IF; - IF Read_precharge (1) = '1' OR Write_precharge (1) = '1' THEN - Count_precharge (1) := Count_precharge (1) + 1; - END IF; - IF Read_precharge (2) = '1' OR Write_precharge (2) = '1' THEN - Count_precharge (2) := Count_precharge (2) + 1; - END IF; - IF Read_precharge (3) = '1' OR Write_precharge (3) = '1' THEN - Count_precharge (3) := Count_precharge (3) + 1; - END IF; - - -- Read with AutoPrecharge Calculation - -- The device start internal precharge when: - -- 1. Meet tRAS requirement - -- 2. BL/2 cycles after command - IF ((Read_precharge(0) = '1') AND (NOW - RAS_chk0 >= tRAS)) THEN - IF ((Burst_length_2 = '1' AND Count_precharge(0) >= 1) OR - (Burst_length_4 = '1' AND Count_precharge(0) >= 2) OR - (Burst_length_8 = '1' AND Count_precharge(0) >= 4)) THEN - Pc_b0 := '1'; - Act_b0 := '0'; - RP_chk0 := NOW; - Read_precharge(0) := '0'; - END IF; - END IF; - IF ((Read_precharge(1) = '1') AND (NOW - RAS_chk1 >= tRAS)) THEN - IF ((Burst_length_2 = '1' AND Count_precharge(1) >= 1) OR - (Burst_length_4 = '1' AND Count_precharge(1) >= 2) OR - (Burst_length_8 = '1' AND Count_precharge(1) >= 4)) THEN - Pc_b1 := '1'; - Act_b1 := '0'; - RP_chk1 := NOW; - Read_precharge(1) := '0'; - END IF; - END IF; - IF ((Read_precharge(2) = '1') AND (NOW - RAS_chk2 >= tRAS)) THEN - IF ((Burst_length_2 = '1' AND Count_precharge(2) >= 1) OR - (Burst_length_4 = '1' AND Count_precharge(2) >= 2) OR - (Burst_length_8 = '1' AND Count_precharge(2) >= 4)) THEN - Pc_b2 := '1'; - Act_b2 := '0'; - RP_chk2 := NOW; - Read_precharge(2) := '0'; - END IF; - END IF; - IF ((Read_precharge(3) = '1') AND (NOW - RAS_chk3 >= tRAS)) THEN - IF ((Burst_length_2 = '1' AND Count_precharge(3) >= 1) OR - (Burst_length_4 = '1' AND Count_precharge(3) >= 2) OR - (Burst_length_8 = '1' AND Count_precharge(3) >= 4)) THEN - Pc_b3 := '1'; - Act_b3 := '0'; - RP_chk3 := NOW; - Read_precharge(3) := '0'; - END IF; - END IF; - - -- Write with AutoPrecharge Calculation - -- The device start internal precharge when: - -- 1. Meet tRAS requirement - -- 2. Two clock after last burst - -- Since tWR is time base, the model will compensate tRP - IF ((Write_precharge(0) = '1') AND (NOW - RAS_chk0 >= tRAS)) THEN - IF ((Burst_length_2 = '1' AND Count_precharge (0) >= 4) OR - (Burst_length_4 = '1' AND Count_precharge (0) >= 5) OR - (Burst_length_8 = '1' AND Count_precharge (0) >= 7)) THEN - Pc_b0 := '1'; - Act_b0 := '0'; - RP_chk0 := NOW - ((2 * tCK) - tWR); - Write_precharge(0) := '0'; - END IF; - END IF; - IF ((Write_precharge(1) = '1') AND (NOW - RAS_chk1 >= tRAS)) THEN - IF ((Burst_length_2 = '1' AND Count_precharge (1) >= 4) OR - (Burst_length_4 = '1' AND Count_precharge (1) >= 5) OR - (Burst_length_8 = '1' AND Count_precharge (1) >= 7)) THEN - Pc_b1 := '1'; - Act_b1 := '0'; - RP_chk1 := NOW - ((2 * tCK) - tWR); - Write_precharge(1) := '0'; - END IF; - END IF; - IF ((Write_precharge(2) = '1') AND (NOW - RAS_chk2 >= tRAS)) THEN - IF ((Burst_length_2 = '1' AND Count_precharge (2) >= 4) OR - (Burst_length_4 = '1' AND Count_precharge (2) >= 5) OR - (Burst_length_8 = '1' AND Count_precharge (2) >= 7)) THEN - Pc_b2 := '1'; - Act_b2 := '0'; - RP_chk2 := NOW - ((2 * tCK) - tWR); - Write_precharge(2) := '0'; - END IF; - END IF; - IF ((Write_precharge(3) = '1') AND (NOW - RAS_chk3 >= tRAS)) THEN - IF ((Burst_length_2 = '1' AND Count_precharge (3) >= 4) OR - (Burst_length_4 = '1' AND Count_precharge (3) >= 5) OR - (Burst_length_8 = '1' AND Count_precharge (3) >= 7)) THEN - Pc_b3 := '1'; - Act_b3 := '0'; - RP_chk3 := NOW - ((2 * tCK) - tWR); - Write_precharge(3) := '0'; - END IF; - END IF; - END IF; - - -- - -- DLL Counter - -- - IF Sys_clk'EVENT AND Sys_clk = '1' THEN - IF (DLL_Reset = '1' AND DLL_done = '0') THEN - DLL_count := DLL_count + 1; - IF (DLL_count >= 200) THEN - DLL_done := '1'; - END IF; - END IF; - END IF; - - -- - -- Control Logic - -- - IF Sys_clk'EVENT AND Sys_clk = '1' THEN - -- Auto Refresh - IF Aref_enable = '1' THEN - -- Auto Refresh to Auto Refresh - ASSERT (NOW - RFC_chk >= tRFC) - REPORT "tRFC violation during Auto Refresh" - SEVERITY WARNING; - - -- Precharge to Auto Refresh - ASSERT ((NOW - RP_chk0 >= tRP) AND (NOW - RP_chk1 >= tRP) AND - (NOW - RP_chk2 >= tRP) AND (NOW - RP_chk3 >= tRP)) - REPORT "tRP violation during Auto Refresh" - SEVERITY WARNING; - - -- Precharge to Auto Refresh - ASSERT (Pc_b0 = '1' AND Pc_b1 = '1' AND Pc_b2 = '1' AND Pc_b3 = '1') - REPORT "All banks must be Precharge before Auto Refresh" - SEVERITY WARNING; - - -- Record current tRFC time - RFC_chk := NOW; - END IF; - - -- Extended Load Mode Register - IF Ext_mode_enable = '1' THEN - IF (Pc_b0 = '1' AND Pc_b1 = '1' AND Pc_b2 = '1' AND Pc_b3 = '1') THEN - IF (Addr (0) = '0') THEN - DLL_enable := '1'; - ELSE - DLL_enable := '0'; - END IF; - END IF; - - -- Precharge to EMR - ASSERT (Pc_b0 = '1' AND Pc_b1 = '1' AND Pc_b2 = '1' AND Pc_b3 = '1') - REPORT "All bank must be Precharged before Extended Mode Register" - SEVERITY WARNING; - - -- Precharge to EMR - ASSERT ((NOW - RP_chk0 >= tRP) AND (NOW - RP_chk1 >= tRP) AND - (NOW - RP_chk2 >= tRP) AND (NOW - RP_chk3 >= tRP)) - REPORT "tRP violation during Extended Load Register" - SEVERITY WARNING; - - -- LMR/EMR to EMR - ASSERT (NOW - MRD_chk >= tMRD) - REPORT "tMRD violation during Extended Mode Register" - SEVERITY WARNING; - - -- Record current tMRD time - MRD_chk := NOW; - END IF; - - -- Load Mode Register - IF Mode_reg_enable = '1' THEN - -- Register mode - Mode_reg <= Addr; - - -- DLL Reset - IF (DLL_enable = '1' AND Addr (8) = '1') THEN - DLL_reset := '1'; - DLL_done := '0'; - DLL_count := 0; - ELSIF (DLL_enable = '1' AND DLL_reset = '0' AND Addr (8) = '0') THEN - ASSERT (FALSE) - REPORT "DLL is ENABLE: DLL RESET is require" - SEVERITY WARNING; - ELSIF (DLL_enable = '0' AND Addr (8) = '1') THEN - ASSERT (FALSE) - REPORT "DLL is DISABLE: DLL RESET will be ignored" - SEVERITY WARNING; - END IF; - - -- Precharge to LMR - ASSERT (Pc_b0 = '1' AND Pc_b1 = '1' AND Pc_b2 = '1' AND Pc_b3 = '1') - REPORT "All bank must be Precharged before Load Mode Register" - SEVERITY WARNING; - - -- Precharge to EMR - ASSERT ((NOW - RP_chk0 >= tRP) AND (NOW - RP_chk1 >= tRP) AND - (NOW - RP_chk2 >= tRP) AND (NOW - RP_chk3 >= tRP)) - REPORT "tRP violation during Load Mode Register" - SEVERITY WARNING; - - -- LMR/ELMR to LMR - ASSERT (NOW - MRD_chk >= tMRD) - REPORT "tMRD violation during Load Mode Register" - SEVERITY WARNING; - - -- Check for invalid Burst Length - ASSERT ((Addr (2 DOWNTO 0) = "001") OR -- BL = 2 - (Addr (2 DOWNTO 0) = "010") OR -- BL = 4 - (Addr (2 DOWNTO 0) = "011")) -- BL = 8 - REPORT "Invalid Burst Length during Load Mode Register" - SEVERITY WARNING; - - -- Check for invalid CAS Latency - ASSERT ((Addr (6 DOWNTO 4) = "010") OR -- CL = 2.0 - (Addr (6 DOWNTO 4) = "110")) -- CL = 2.5 - REPORT "Invalid CAS Latency during Load Mode Register" - SEVERITY WARNING; - - -- Record current tMRD time - MRD_chk := NOW; - END IF; - - -- Active Block (latch Bank and Row Address) - IF Active_enable = '1' THEN - -- Activate an OPEN bank can corrupt data - ASSERT ((Ba = "00" AND Act_b0 = '0') OR - (Ba = "01" AND Act_b1 = '0') OR - (Ba = "10" AND Act_b2 = '0') OR - (Ba = "11" AND Act_b3 = '0')) - REPORT "Bank is already activated - data can be corrupted" - SEVERITY WARNING; - - -- Activate Bank 0 - IF Ba = "00" AND Pc_b0 = '1' THEN - -- Activate to Activate (same bank) - ASSERT (NOW - RC_chk0 >= tRC) - REPORT "tRC violation during Activate Bank 0" - SEVERITY WARNING; - - -- Precharge to Active - ASSERT (NOW - RP_chk0 >= tRP) - REPORT "tRP violation during Activate Bank 0" - SEVERITY WARNING; - - -- Record Variables for checking violation - Act_b0 := '1'; - Pc_b0 := '0'; - B0_row_addr := Addr; - RC_chk0 := NOW; - RCD_chk0 := NOW; - RAS_chk0 := NOW; - RAP_chk0 := NOW; - END IF; - - -- Activate Bank 1 - IF Ba = "01" AND Pc_b1 = '1' THEN - -- Activate to Activate (same bank) - ASSERT (NOW - RC_chk1 >= tRC) - REPORT "tRC violation during Activate Bank 1" - SEVERITY WARNING; - - -- Precharge to Active - ASSERT (NOW - RP_chk1 >= tRP) - REPORT "tRP violation during Activate Bank 1" - SEVERITY WARNING; - - -- Record Variables for checking violation - Act_b1 := '1'; - Pc_b1 := '0'; - B1_row_addr := Addr; - RC_chk1 := NOW; - RCD_chk1 := NOW; - RAS_chk1 := NOW; - RAP_chk1 := NOW; - END IF; - - -- Activate Bank 2 - IF Ba = "10" AND Pc_b2 = '1' THEN - -- Activate to Activate (same bank) - ASSERT (NOW - RC_chk2 >= tRC) - REPORT "tRC violation during Activate Bank 2" - SEVERITY WARNING; - - -- Precharge to Active - ASSERT (NOW - RP_chk2 >= tRP) - REPORT "tRP violation during Activate Bank 2" - SEVERITY WARNING; - - -- Record Variables for checking violation - Act_b2 := '1'; - Pc_b2 := '0'; - B2_row_addr := Addr; - RC_chk2 := NOW; - RCD_chk2 := NOW; - RAS_chk2 := NOW; - RAP_chk2 := NOW; - END IF; - - -- Activate Bank 3 - IF Ba = "11" AND Pc_b3 = '1' THEN - -- Activate to Activate (same bank) - ASSERT (NOW - RC_chk3 >= tRC) - REPORT "tRC violation during Activate Bank 3" - SEVERITY WARNING; - - -- Precharge to Active - ASSERT (NOW - RP_chk3 >= tRP) - REPORT "tRP violation during Activate Bank 3" - SEVERITY WARNING; - - -- Record Variables for checking violation - Act_b3 := '1'; - Pc_b3 := '0'; - B3_row_addr := Addr; - RC_chk3 := NOW; - RCD_chk3 := NOW; - RAS_chk3 := NOW; - RAP_chk3 := NOW; - END IF; - - -- Activate Bank A to Activate Bank B - IF (Prev_bank /= Ba) THEN - ASSERT (NOW - RRD_chk >= tRRD) - REPORT "tRRD violation during Activate" - SEVERITY WARNING; - END IF; - - -- AutoRefresh to Activate - ASSERT (NOW - RFC_chk >= tRFC) - REPORT "tRFC violation during Activate" - SEVERITY WARNING; - - -- Record Variables for Checking Violation - RRD_chk := NOW; - Prev_bank := Ba; - END IF; - - -- Precharge Block - Consider NOP if bank already precharged or in process of precharging - IF Prech_enable = '1' THEN - -- EMR or LMR to Precharge - ASSERT (NOW - MRD_chk >= tMRD) - REPORT "tMRD violation during Precharge" - SEVERITY WARNING; - - -- Precharge Bank 0 - IF ((Addr (10) = '1' OR (Addr (10) = '0' AND Ba = "00")) AND Act_b0 = '1') THEN - Act_b0 := '0'; - Pc_b0 := '1'; - RP_chk0 := NOW; - - -- Activate to Precharge bank 0 - ASSERT (NOW - RAS_chk0 >= tRAS) - REPORT "tRAS violation during Precharge" - SEVERITY WARNING; - - -- tWR violation check for Write - ASSERT (NOW - WR_chk0 >= tWR) - REPORT "tWR violation during Precharge" - SEVERITY WARNING; - END IF; - - -- Precharge Bank 1 - IF ((Addr (10) = '1' OR (Addr (10) = '0' AND Ba = "01")) AND Act_b1 = '1') THEN - Act_b1 := '0'; - Pc_b1 := '1'; - RP_chk1 := NOW; - - -- Activate to Precharge - ASSERT (NOW - RAS_chk1 >= tRAS) - REPORT "tRAS violation during Precharge" - SEVERITY WARNING; - - -- tWR violation check for Write - ASSERT (NOW - WR_chk1 >= tWR) - REPORT "tWR violation during Precharge" - SEVERITY WARNING; - END IF; - - -- Precharge Bank 2 - IF ((Addr (10) = '1' OR (Addr (10) = '0' AND Ba = "10")) AND Act_b2 = '1') THEN - Act_b2 := '0'; - Pc_b2 := '1'; - RP_chk2 := NOW; - - -- Activate to Precharge - ASSERT (NOW - RAS_chk2 >= tRAS) - REPORT "tRAS violation during Precharge" - SEVERITY WARNING; - - -- tWR violation check for Write - ASSERT (NOW - WR_chk2 >= tWR) - REPORT "tWR violation during Precharge" - SEVERITY WARNING; - END IF; - - -- Precharge Bank 3 - IF ((Addr (10) = '1' OR (Addr (10) = '0' AND Ba = "11")) AND Act_b3 = '1') THEN - Act_b3 := '0'; - Pc_b3 := '1'; - RP_chk3 := NOW; - - -- Activate to Precharge - ASSERT (NOW - RAS_chk3 >= tRAS) - REPORT "tRAS violation during Precharge" - SEVERITY WARNING; - - -- tWR violation check for Write - ASSERT (NOW - WR_chk3 >= tWR) - REPORT "tWR violation during Precharge" - SEVERITY WARNING; - END IF; - - -- Pipeline for READ - IF CAS_latency_15 = '1' THEN - A10_precharge (3) := Addr(10); - Bank_precharge (3) := Ba; - Cmnd_precharge (3) := '1'; - ELSIF CAS_latency_2 = '1' THEN - A10_precharge (4) := Addr(10); - Bank_precharge (4) := Ba; - Cmnd_precharge (4) := '1'; - ELSIF CAS_latency_25 = '1' THEN - A10_precharge (5) := Addr(10); - Bank_precharge (5) := Ba; - Cmnd_precharge (5) := '1'; - ELSIF CAS_latency_3 = '1' THEN - A10_precharge (6) := Addr(10); - Bank_precharge (6) := Ba; - Cmnd_precharge (6) := '1'; - ELSIF CAS_latency_4 = '1' THEN - A10_precharge (8) := Addr(10); - Bank_precharge (8) := Ba; - Cmnd_precharge (8) := '1'; - END IF; - END IF; - - -- Burst Terminate - IF Burst_term = '1' THEN - -- Pipeline for Read - IF CAS_latency_15 = '1' THEN - Cmnd_bst (3) := '1'; - ELSIF CAS_latency_2 = '1' THEN - Cmnd_bst (4) := '1'; - ELSIF CAS_latency_25 = '1' THEN - Cmnd_bst (5) := '1'; - ELSIF CAS_latency_3 = '1' THEN - Cmnd_bst (6) := '1'; - ELSIF CAS_latency_4 = '1' THEN - Cmnd_bst (8) := '1'; - END IF; - - -- Terminate Write - ASSERT (Data_in_enable = '0') - REPORT "It's illegal to Burst Terminate a Write" - SEVERITY WARNING; - - -- Terminate Read with Auto Precharge - ASSERT (Read_precharge (0) = '0' AND Read_precharge (1) = '0' AND - Read_precharge (2) = '0' AND Read_precharge (3) = '0') - REPORT "It's illegal to Burst Terminate a Read with Auto Precharge" - SEVERITY WARNING; - END IF; - - -- Read Command - IF Read_enable = '1' THEN - -- CAS Latency Pipeline - IF Cas_latency_15 = '1' THEN - Read_cmnd (3) := '1'; - Read_bank (3) := Ba; - Read_cols (3) := Addr (8 DOWNTO 0); - ELSIF Cas_latency_2 = '1' THEN - Read_cmnd (4) := '1'; - Read_bank (4) := Ba; - Read_cols (4) := Addr (8 DOWNTO 0); - ELSIF Cas_latency_25 = '1' THEN - Read_cmnd (5) := '1'; - Read_bank (5) := Ba; - Read_cols (5) := Addr (8 DOWNTO 0); - ELSIF Cas_latency_3 = '1' THEN - Read_cmnd (6) := '1'; - Read_bank (6) := Ba; - Read_cols (6) := Addr (8 DOWNTO 0); - ELSIF Cas_latency_4 = '1' THEN - Read_cmnd (8) := '1'; - Read_bank (8) := Ba; - Read_cols (8) := Addr (8 DOWNTO 0); - END IF; - - -- Write to Read: Terminate Write Immediately - IF Data_in_enable = '1' THEN - Data_in_enable := '0'; - END IF; - - -- Interrupting a Read with Auto Precharge (same bank only) - ASSERT (Read_precharge(CONV_INTEGER(Ba)) = '0') - REPORT "It's illegal to interrupt a Read with Auto Precharge" - SEVERITY WARNING; - - -- Activate to Read - ASSERT ((Ba = "00" AND Act_b0 = '1') OR - (Ba = "01" AND Act_b1 = '1') OR - (Ba = "10" AND Act_b2 = '1') OR - (Ba = "11" AND Act_b3 = '1')) - REPORT "Bank is not Activated for Read" - SEVERITY WARNING; - - -- Activate to Read without Auto Precharge - IF Addr (10) = '0' THEN - ASSERT ((Ba = "00" AND NOW - RCD_chk0 >= tRCD) OR - (Ba = "01" AND NOW - RCD_chk1 >= tRCD) OR - (Ba = "10" AND NOW - RCD_chk2 >= tRCD) OR - (Ba = "11" AND NOW - RCD_chk3 >= tRCD)) - REPORT "tRCD violation during Read" - SEVERITY WARNING; - END IF; - - -- Activate to Read with Auto Precharge - IF Addr (10) = '1' THEN - ASSERT ((Ba = "00" AND NOW - RAP_chk0 >= tRAP) OR - (Ba = "01" AND NOW - RAP_chk1 >= tRAP) OR - (Ba = "10" AND NOW - RAP_chk2 >= tRAP) OR - (Ba = "11" AND NOW - RAP_chk3 >= tRAP)) - REPORT "tRAP violation during Read" - SEVERITY WARNING; - END IF; - - -- Auto precharge - IF Addr (10) = '1' THEN - Read_precharge (Conv_INTEGER(Ba)) := '1'; - Count_precharge (Conv_INTEGER(Ba)) := 0; - END IF; - - -- DLL Check - IF (DLL_reset = '1') THEN - ASSERT (DLL_done = '1') - REPORT "DLL RESET not complete" - SEVERITY WARNING; - END IF; - END IF; - - -- Write Command - IF Write_enable = '1' THEN - -- Pipeline for Write - Write_cmnd (2) := '1'; - Write_bank (2) := Ba; - Write_cols (2) := Addr (8 DOWNTO 0); - - -- Interrupting a Write with Auto Precharge (same bank only) - ASSERT (Write_precharge(CONV_INTEGER(Ba)) = '0') - REPORT "It's illegal to interrupt a Write with Auto Precharge" - SEVERITY WARNING; - - -- Activate to Write - ASSERT ((Ba = "00" AND Act_b0 = '1') OR - (Ba = "01" AND Act_b1 = '1') OR - (Ba = "10" AND Act_b2 = '1') OR - (Ba = "11" AND Act_b3 = '1')) - REPORT "Bank is not Activated for Write" - SEVERITY WARNING; - - -- Activate to Write - ASSERT ((Ba = "00" AND NOW - RCD_chk0 >= tRCD) OR - (Ba = "01" AND NOW - RCD_chk1 >= tRCD) OR - (Ba = "10" AND NOW - RCD_chk2 >= tRCD) OR - (Ba = "11" AND NOW - RCD_chk3 >= tRCD)) - REPORT "tRCD violation during Write" - SEVERITY WARNING; - - -- Auto precharge - IF Addr (10) = '1' THEN - Write_precharge (Conv_INTEGER(Ba)) := '1'; - Count_precharge (Conv_INTEGER(Ba)) := 0; - END IF; - END IF; - END IF; - END PROCESS; - - -- - -- Dqs Receiver - -- - dqs_rcvrs : PROCESS - VARIABLE Dm_temp : STD_LOGIC_VECTOR (1 DOWNTO 0); - VARIABLE Dq_temp : STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0); - BEGIN - WAIT ON Dqs; - -- Latch data at posedge Dqs - IF Dqs'EVENT AND Dqs (1) = '1' AND Dqs (0) = '1' THEN - Dq_temp := Dq; - Dm_temp := Dm; - END IF; - -- Latch data at negedge Dqs - IF Dqs'EVENT AND Dqs (1) = '0' AND Dqs (0) = '0' THEN - Dq_pair <= (Dq & Dq_temp); - Dm_pair <= (Dm & Dm_temp); - END IF; - END PROCESS; - - -- - -- Setup timing checks - -- - Setup_check : PROCESS - BEGIN - WAIT ON Sys_clk; - IF Sys_clk'EVENT AND Sys_clk = '1' THEN - ASSERT(Cke'LAST_EVENT >= tIS) - REPORT "CKE Setup time violation -- tIS" - SEVERITY WARNING; - ASSERT(Cs_n'LAST_EVENT >= tIS) - REPORT "CS# Setup time violation -- tIS" - SEVERITY WARNING; - ASSERT(Cas_n'LAST_EVENT >= tIS) - REPORT "CAS# Setup time violation -- tIS" - SEVERITY WARNING; - ASSERT(Ras_n'LAST_EVENT >= tIS) - REPORT "RAS# Setup time violation -- tIS" - SEVERITY WARNING; - ASSERT(We_n'LAST_EVENT >= tIS) - REPORT "WE# Setup time violation -- tIS" - SEVERITY WARNING; - ASSERT(Addr'LAST_EVENT >= tIS) - REPORT "ADDR Setup time violation -- tIS" - SEVERITY WARNING; - ASSERT(Ba'LAST_EVENT >= tIS) - REPORT "BA Setup time violation -- tIS" - SEVERITY WARNING; - END IF; - END PROCESS; - - -- - -- Hold timing checks - -- - Hold_check : PROCESS - BEGIN - WAIT ON Sys_clk'DELAYED (tIH); - IF Sys_clk'DELAYED (tIH) = '1' THEN - ASSERT(Cke'LAST_EVENT >= tIH) - REPORT "CKE Hold time violation -- tIH" - SEVERITY WARNING; - ASSERT(Cs_n'LAST_EVENT >= tIH) - REPORT "CS# Hold time violation -- tIH" - SEVERITY WARNING; - ASSERT(Cas_n'LAST_EVENT >= tIH) - REPORT "CAS# Hold time violation -- tIH" - SEVERITY WARNING; - ASSERT(Ras_n'LAST_EVENT >= tIH) - REPORT "RAS# Hold time violation -- tIH" - SEVERITY WARNING; - ASSERT(We_n'LAST_EVENT >= tIH) - REPORT "WE# Hold time violation -- tIH" - SEVERITY WARNING; - ASSERT(Addr'LAST_EVENT >= tIH) - REPORT "ADDR Hold time violation -- tIH" - SEVERITY WARNING; - ASSERT(Ba'LAST_EVENT >= tIH) - REPORT "BA Hold time violation -- tIH" - SEVERITY WARNING; - END IF; - END PROCESS; - -END behave; +----------------------------------------------------------------------------------------- +-- +-- File Name: MT46V16M16.VHD +-- Version: 2.1 +-- Date: January 14th, 2002 +-- Model: Behavioral +-- Simulator: NCDesktop - http://www.cadence.com +-- ModelSim PE - http://www.model.com +-- +-- Dependencies: None +-- +-- Author: Son P. Huynh +-- Email: sphuynh@micron.com +-- Phone: (208) 368-3825 +-- Company: Micron Technology, Inc. +-- Part Number: MT46V16M16 (4 Mb x 16 x 4 Banks) +-- +-- Description: Micron 256 Mb SDRAM DDR (Double Data Rate) +-- +-- Limitation: Doesn't model internal refresh counter +-- +-- Note: +-- +-- Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY +-- WHATSOEVER AND MICRON SPECIFICALLY DISCLAIMS ANY +-- IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR +-- A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT. +-- +-- Copyright (c) 1998 Micron Semiconductor Products, Inc. +-- All rights researved +-- +-- Rev Author Date Changes +-- --- ---------------------------- ---------- ------------------------------------- +-- 2.1 Son P. Huynh 01/14/2002 - Fix Burst_counter +-- Micron Technology, Inc. +-- +-- 2.0 Son P. Huynh 11/08/2001 - Second release +-- Micron Technology, Inc. - Rewrote and remove SHARED VARIABLE +-- +----------------------------------------------------------------------------------------- + +LIBRARY IEEE; + USE IEEE.STD_LOGIC_1164.ALL; + USE IEEE.STD_LOGIC_UNSIGNED.ALL; + USE IEEE.STD_LOGIC_ARITH.ALL; + +ENTITY MT46V16M16 IS + GENERIC ( -- Timing for -75Z CL2 + tCK : TIME := 7.500 ns; + tCH : TIME := 3.375 ns; -- 0.45*tCK + tCL : TIME := 3.375 ns; -- 0.45*tCK + tDH : TIME := 0.500 ns; + tDS : TIME := 0.500 ns; + tIH : TIME := 0.900 ns; + tIS : TIME := 0.900 ns; + tMRD : TIME := 15.000 ns; + tRAS : TIME := 40.000 ns; + tRAP : TIME := 20.000 ns; + tRC : TIME := 65.000 ns; + tRFC : TIME := 75.000 ns; + tRCD : TIME := 20.000 ns; + tRP : TIME := 20.000 ns; + tRRD : TIME := 15.000 ns; + tWR : TIME := 15.000 ns; + addr_bits : INTEGER := 13; + data_bits : INTEGER := 16; + cols_bits : INTEGER := 9 + ); + PORT ( + Dq : INOUT STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0) := (OTHERS => 'Z'); + Dqs : INOUT STD_LOGIC_VECTOR (1 DOWNTO 0) := "ZZ"; + Addr : IN STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0); + Ba : IN STD_LOGIC_VECTOR (1 DOWNTO 0); + Clk : IN STD_LOGIC; + Clk_n : IN STD_LOGIC; + Cke : IN STD_LOGIC; + Cs_n : IN STD_LOGIC; + Ras_n : IN STD_LOGIC; + Cas_n : IN STD_LOGIC; + We_n : IN STD_LOGIC; + Dm : IN STD_LOGIC_VECTOR (1 DOWNTO 0) + ); +END MT46V16M16; + +ARCHITECTURE behave OF MT46V16M16 IS + -- Array for Read pipeline + TYPE Array_Read_cmnd IS ARRAY (8 DOWNTO 0) OF STD_LOGIC; + TYPE Array_Read_bank IS ARRAY (8 DOWNTO 0) OF STD_LOGIC_VECTOR (1 DOWNTO 0); + TYPE Array_Read_cols IS ARRAY (8 DOWNTO 0) OF STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0); + + -- Array for Write pipeline + TYPE Array_Write_cmnd IS ARRAY (2 DOWNTO 0) OF STD_LOGIC; + TYPE Array_Write_bank IS ARRAY (2 DOWNTO 0) OF STD_LOGIC_VECTOR (1 DOWNTO 0); + TYPE Array_Write_cols IS ARRAY (2 DOWNTO 0) OF STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0); + + -- Array for Auto Precharge + TYPE Array_Read_precharge IS ARRAY (3 DOWNTO 0) OF STD_LOGIC; + TYPE Array_Write_precharge IS ARRAY (3 DOWNTO 0) OF STD_LOGIC; + TYPE Array_Count_precharge IS ARRAY (3 DOWNTO 0) OF INTEGER; + + -- Array for Manual Precharge + TYPE Array_A10_precharge IS ARRAY (8 DOWNTO 0) OF STD_LOGIC; + TYPE Array_Bank_precharge IS ARRAY (8 DOWNTO 0) OF STD_LOGIC_VECTOR (1 DOWNTO 0); + TYPE Array_Cmnd_precharge IS ARRAY (8 DOWNTO 0) OF STD_LOGIC; + + -- Array for Burst Terminate + TYPE Array_Cmnd_bst IS ARRAY (8 DOWNTO 0) OF STD_LOGIC; + + -- Array for Memory Access + TYPE Array_ram_type IS ARRAY (2**cols_bits - 1 DOWNTO 0) OF STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0); + TYPE Array_ram_pntr IS ACCESS Array_ram_type; + TYPE Array_ram_stor IS ARRAY (2**addr_bits - 1 DOWNTO 0) OF Array_ram_pntr; + + -- Data pair + SIGNAL Dq_pair : STD_LOGIC_VECTOR (2 * data_bits - 1 DOWNTO 0); + SIGNAL Dm_pair : STD_LOGIC_VECTOR (3 DOWNTO 0); + + -- Mode Register + SIGNAL Mode_reg : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0) := (OTHERS => '0'); + + -- Command Decode Variables + SIGNAL Active_enable, Aref_enable, Burst_term, Ext_mode_enable : STD_LOGIC := '0'; + SIGNAL Mode_reg_enable, Prech_enable, Read_enable, Write_enable : STD_LOGIC := '0'; + + -- Burst Length Decode Variables + SIGNAL Burst_length_2, Burst_length_4, Burst_length_8, Burst_length_f : STD_LOGIC := '0'; + + -- Cas Latency Decode Variables + SIGNAL Cas_latency_15, Cas_latency_2, Cas_latency_25, Cas_latency_3, Cas_latency_4 : STD_LOGIC := '0'; + + -- Internal Control Signals + SIGNAL Cs_in, Ras_in, Cas_in, We_in : STD_LOGIC := '0'; + + -- System Clock + SIGNAL Sys_clk : STD_LOGIC := '0'; + + -- Dqs buffer + SIGNAL Dqs_out : STD_LOGIC_VECTOR (1 DOWNTO 0) := "ZZ"; + +BEGIN + -- Strip the strength + Cs_in <= To_X01 (Cs_n); + Ras_in <= To_X01 (Ras_n); + Cas_in <= To_X01 (Cas_n); + We_in <= To_X01 (We_n); + + -- Commands Decode + Active_enable <= NOT(Cs_in) AND NOT(Ras_in) AND Cas_in AND We_in; + Aref_enable <= NOT(Cs_in) AND NOT(Ras_in) AND NOT(Cas_in) AND We_in; + Burst_term <= NOT(Cs_in) AND Ras_in AND Cas_in AND NOT(We_in); + Ext_mode_enable <= NOT(Cs_in) AND NOT(Ras_in) AND NOT(Cas_in) AND NOT(We_in) AND Ba(0) AND NOT(Ba(1)); + Mode_reg_enable <= NOT(Cs_in) AND NOT(Ras_in) AND NOT(Cas_in) AND NOT(We_in) AND NOT(Ba(0)) AND NOT(Ba(1)); + Prech_enable <= NOT(Cs_in) AND NOT(Ras_in) AND Cas_in AND NOT(We_in); + Read_enable <= NOT(Cs_in) AND Ras_in AND NOT(Cas_in) AND We_in; + Write_enable <= NOT(Cs_in) AND Ras_in AND NOT(Cas_in) AND NOT(We_in); + + -- Burst Length Decode + Burst_length_2 <= NOT(Mode_reg(2)) AND NOT(Mode_reg(1)) AND Mode_reg(0); + Burst_length_4 <= NOT(Mode_reg(2)) AND Mode_reg(1) AND NOT(Mode_reg(0)); + Burst_length_8 <= NOT(Mode_reg(2)) AND Mode_reg(1) AND Mode_reg(0); + Burst_length_f <= (Mode_reg(2)) AND Mode_reg(1) AND Mode_reg(0); + + -- CAS Latency Decode + Cas_latency_15 <= Mode_reg(6) AND NOT(Mode_reg(5)) AND (Mode_reg(4)); + Cas_latency_2 <= NOT(Mode_reg(6)) AND Mode_reg(5) AND NOT(Mode_reg(4)); + Cas_latency_25 <= Mode_reg(6) AND Mode_reg(5) AND NOT(Mode_reg(4)); + Cas_latency_3 <= NOT(Mode_reg(6)) AND Mode_reg(5) AND Mode_reg(4); + Cas_latency_4 <= (Mode_reg(6)) AND NOT(Mode_reg(5)) AND NOT(Mode_reg(4)); + + -- Dqs buffer + Dqs <= Dqs_out; + + -- + -- System Clock + -- + int_clk : PROCESS (Clk, Clk_n) + VARIABLE ClkZ, CkeZ : STD_LOGIC := '0'; + begin + IF Clk = '1' AND Clk_n = '0' THEN + ClkZ := '1'; + CkeZ := Cke; + ELSIF Clk = '0' AND Clk_n = '1' THEN + ClkZ := '0'; + END IF; + Sys_clk <= CkeZ AND ClkZ; + END PROCESS; + + -- + -- Main Process + -- + state_register : PROCESS + -- Precharge Variables + VARIABLE Pc_b0, Pc_b1, Pc_b2, Pc_b3 : STD_LOGIC := '0'; + + -- Activate Variables + VARIABLE Act_b0, Act_b1, Act_b2, Act_b3 : STD_LOGIC := '1'; + + -- Data IO variables + VARIABLE Data_in_enable, Data_out_enable : STD_LOGIC := '0'; + + -- Internal address mux variables + VARIABLE Cols_brst : STD_LOGIC_VECTOR (2 DOWNTO 0); + VARIABLE Prev_bank : STD_LOGIC_VECTOR (1 DOWNTO 0) := "00"; + VARIABLE Bank_addr : STD_LOGIC_VECTOR (1 DOWNTO 0) := "00"; + VARIABLE Cols_addr : STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0); + VARIABLE Rows_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0); + VARIABLE B0_row_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0); + VARIABLE B1_row_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0); + VARIABLE B2_row_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0); + VARIABLE B3_row_addr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0); + + -- DLL Reset variables + VARIABLE DLL_enable : STD_LOGIC := '0'; + VARIABLE DLL_reset : STD_LOGIC := '0'; + VARIABLE DLL_done : STD_LOGIC := '0'; + VARIABLE DLL_count : INTEGER := 0; + + -- Timing Check + VARIABLE MRD_chk : TIME := 0 ns; + VARIABLE RFC_chk : TIME := 0 ns; + VARIABLE RRD_chk : TIME := 0 ns; + VARIABLE RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3 : TIME := 0 ns; + VARIABLE RAP_chk0, RAP_chk1, RAP_chk2, RAP_chk3 : TIME := 0 ns; + VARIABLE RC_chk0, RC_chk1, RC_chk2, RC_chk3 : TIME := 0 ns; + VARIABLE RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3 : TIME := 0 ns; + VARIABLE RP_chk0, RP_chk1, RP_chk2, RP_chk3 : TIME := 0 ns; + VARIABLE WR_chk0, WR_chk1, WR_chk2, WR_chk3 : TIME := 0 ns; + + -- Read pipeline variables + VARIABLE Read_cmnd : Array_Read_cmnd; + VARIABLE Read_bank : Array_Read_bank; + VARIABLE Read_cols : Array_Read_cols; + + -- Write pipeline variables + VARIABLE Write_cmnd : Array_Write_cmnd; + VARIABLE Write_bank : Array_Write_bank; + VARIABLE Write_cols : Array_Write_cols; + + -- Auto Precharge variables + VARIABLE Read_precharge : Array_Read_precharge := ('0' & '0' & '0' & '0'); + VARIABLE Write_precharge : Array_Write_precharge := ('0' & '0' & '0' & '0'); + VARIABLE Count_precharge : Array_Count_precharge := ( 0 & 0 & 0 & 0 ); + + -- Manual Precharge variables + VARIABLE A10_precharge : Array_A10_precharge; + VARIABLE Bank_precharge : Array_Bank_precharge; + VARIABLE Cmnd_precharge : Array_Cmnd_precharge; + + -- Burst Terminate variable + VARIABLE Cmnd_bst : Array_Cmnd_bst; + + -- Memory Banks + VARIABLE Bank0 : Array_ram_stor; + VARIABLE Bank1 : Array_ram_stor; + VARIABLE Bank2 : Array_ram_stor; + VARIABLE Bank3 : Array_ram_stor; + + -- Burst Counter + VARIABLE Burst_counter : STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0); + + -- Internal Dqs initialize + VARIABLE Dqs_int : STD_LOGIC := '0'; + + -- Data buffer for DM Mask + VARIABLE Data_buf : STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0) := (OTHERS => 'Z'); + + -- + -- Initialize empty rows + -- + PROCEDURE Init_mem (Bank : STD_LOGIC_VECTOR; Row_index : INTEGER) IS + VARIABLE i, j : INTEGER := 0; + BEGIN + IF Bank = "00" THEN + IF Bank0 (Row_index) = NULL THEN -- Check to see if row empty + Bank0 (Row_index) := NEW Array_ram_type; -- Open new row for access + FOR i IN (2**cols_bits - 1) DOWNTO 0 LOOP -- Filled row with zeros + FOR j IN (data_bits - 1) DOWNTO 0 LOOP + Bank0 (Row_index) (i) (j) := '0'; + END LOOP; + END LOOP; + END IF; + ELSIF Bank = "01" THEN + IF Bank1 (Row_index) = NULL THEN + Bank1 (Row_index) := NEW Array_ram_type; + FOR i IN (2**cols_bits - 1) DOWNTO 0 LOOP + FOR j IN (data_bits - 1) DOWNTO 0 LOOP + Bank1 (Row_index) (i) (j) := '0'; + END LOOP; + END LOOP; + END IF; + ELSIF Bank = "10" THEN + IF Bank2 (Row_index) = NULL THEN + Bank2 (Row_index) := NEW Array_ram_type; + FOR i IN (2**cols_bits - 1) DOWNTO 0 LOOP + FOR j IN (data_bits - 1) DOWNTO 0 LOOP + Bank2 (Row_index) (i) (j) := '0'; + END LOOP; + END LOOP; + END IF; + ELSIF Bank = "11" THEN + IF Bank3 (Row_index) = NULL THEN + Bank3 (Row_index) := NEW Array_ram_type; + FOR i IN (2**cols_bits - 1) DOWNTO 0 LOOP + FOR j IN (data_bits - 1) DOWNTO 0 LOOP + Bank3 (Row_index) (i) (j) := '0'; + END LOOP; + END LOOP; + END IF; + END IF; + END; + + -- + -- Burst Counter + -- + PROCEDURE Burst_decode IS + VARIABLE Cols_temp : STD_LOGIC_VECTOR (cols_bits - 1 DOWNTO 0) := (OTHERS => '0'); + BEGIN + -- Advance burst counter + Burst_counter := Burst_counter + 1; + + -- Burst Type + IF Mode_reg (3) = '0' THEN + Cols_temp := Cols_addr + 1; + ELSIF Mode_reg (3) = '1' THEN + Cols_temp (2) := Burst_counter (2) XOR Cols_brst (2); + Cols_temp (1) := Burst_counter (1) XOR Cols_brst (1); + Cols_temp (0) := Burst_counter (0) XOR Cols_brst (0); + END IF; + + -- Burst Length + IF Burst_length_2 = '1' THEN + Cols_addr (0) := Cols_temp (0); + ELSIF Burst_length_4 = '1' THEN + Cols_addr (1 DOWNTO 0) := Cols_temp (1 DOWNTO 0); + ELSIF Burst_length_8 = '1' THEN + Cols_addr (2 DOWNTO 0) := Cols_temp (2 DOWNTO 0); + ELSE + Cols_addr := Cols_temp; + END IF; + + -- Data counter + IF Burst_length_2 = '1' THEN + IF Burst_counter >= 2 THEN + IF Data_in_enable = '1' THEN + Data_in_enable := '0'; + ELSIF Data_out_enable = '1' THEN + Data_out_enable := '0'; + END IF; + END IF; + ELSIF Burst_length_4 = '1' THEN + IF Burst_counter >= 4 THEN + IF Data_in_enable = '1' THEN + Data_in_enable := '0'; + ELSIF Data_out_enable = '1' THEN + Data_out_enable := '0'; + END IF; + END IF; + ELSIF Burst_length_8 = '1' THEN + IF Burst_counter >= 8 THEN + IF Data_in_enable = '1' THEN + Data_in_enable := '0'; + ELSIF Data_out_enable = '1' THEN + Data_out_enable := '0'; + END IF; + END IF; + END IF; + END; + + BEGIN + WAIT ON Sys_clk; + + -- + -- Manual Precharge Pipeline + -- + IF ((Sys_clk'EVENT AND Sys_clk = '0') OR (Sys_clk'EVENT AND Sys_clk = '1')) THEN + -- A10 Precharge Pipeline + A10_precharge(0) := A10_precharge(1); + A10_precharge(1) := A10_precharge(2); + A10_precharge(2) := A10_precharge(3); + A10_precharge(3) := A10_precharge(4); + A10_precharge(4) := A10_precharge(5); + A10_precharge(5) := A10_precharge(6); + A10_precharge(6) := A10_precharge(7); + A10_precharge(7) := A10_precharge(8); + A10_precharge(8) := '0'; + + -- Bank Precharge Pipeline + Bank_precharge(0) := Bank_precharge(1); + Bank_precharge(1) := Bank_precharge(2); + Bank_precharge(2) := Bank_precharge(3); + Bank_precharge(3) := Bank_precharge(4); + Bank_precharge(4) := Bank_precharge(5); + Bank_precharge(5) := Bank_precharge(6); + Bank_precharge(6) := Bank_precharge(7); + Bank_precharge(7) := Bank_precharge(8); + Bank_precharge(8) := "00"; + + -- Command Precharge Pipeline + Cmnd_precharge(0) := Cmnd_precharge(1); + Cmnd_precharge(1) := Cmnd_precharge(2); + Cmnd_precharge(2) := Cmnd_precharge(3); + Cmnd_precharge(3) := Cmnd_precharge(4); + Cmnd_precharge(4) := Cmnd_precharge(5); + Cmnd_precharge(5) := Cmnd_precharge(6); + Cmnd_precharge(6) := Cmnd_precharge(7); + Cmnd_precharge(7) := Cmnd_precharge(8); + Cmnd_precharge(8) := '0'; + + -- Terminate Read if same bank or all banks + IF ((Cmnd_precharge (0) = '1') AND + (Bank_precharge (0) = Bank_addr OR A10_precharge (0) = '1') AND + (Data_out_enable = '1')) THEN + Data_out_enable := '0'; + END IF; + END IF; + + -- + -- Burst Terminate Pipeline + -- + IF ((Sys_clk'EVENT AND Sys_clk = '0') OR (Sys_clk'EVENT AND Sys_clk = '1')) THEN + -- Burst Terminate pipeline + Cmnd_bst (0) := Cmnd_bst (1); + Cmnd_bst (1) := Cmnd_bst (2); + Cmnd_bst (2) := Cmnd_bst (3); + Cmnd_bst (3) := Cmnd_bst (4); + Cmnd_bst (4) := Cmnd_bst (5); + Cmnd_bst (5) := Cmnd_bst (6); + Cmnd_bst (6) := Cmnd_bst (7); + Cmnd_bst (7) := Cmnd_bst (8); + Cmnd_bst (8) := '0'; + + -- Terminate current Read + IF ((Cmnd_bst (0) = '1') AND (Data_out_enable = '1')) THEN + Data_out_enable := '0'; + END IF; + END IF; + + -- + -- Dq and Dqs Drivers + -- + IF ((Sys_clk'EVENT AND Sys_clk = '0') OR (Sys_clk'EVENT AND Sys_clk = '1')) THEN + -- Read Command Pipeline + Read_cmnd (0) := Read_cmnd (1); + Read_cmnd (1) := Read_cmnd (2); + Read_cmnd (2) := Read_cmnd (3); + Read_cmnd (3) := Read_cmnd (4); + Read_cmnd (4) := Read_cmnd (5); + Read_cmnd (5) := Read_cmnd (6); + Read_cmnd (6) := Read_cmnd (7); + Read_cmnd (7) := Read_cmnd (8); + Read_cmnd (8) := '0'; + + -- Read Bank Pipeline + Read_bank (0) := Read_bank (1); + Read_bank (1) := Read_bank (2); + Read_bank (2) := Read_bank (3); + Read_bank (3) := Read_bank (4); + Read_bank (4) := Read_bank (5); + Read_bank (5) := Read_bank (6); + Read_bank (6) := Read_bank (7); + Read_bank (7) := Read_bank (8); + Read_bank (8) := "00"; + + -- Read Column Pipeline + Read_cols (0) := Read_cols (1); + Read_cols (1) := Read_cols (2); + Read_cols (2) := Read_cols (3); + Read_cols (3) := Read_cols (4); + Read_cols (4) := Read_cols (5); + Read_cols (5) := Read_cols (6); + Read_cols (6) := Read_cols (7); + Read_cols (7) := Read_cols (8); + Read_cols (8) := (OTHERS => '0'); + + -- Initialize Read command + IF Read_cmnd (0) = '1' THEN + Data_out_enable := '1'; + Bank_addr := Read_bank (0); + Cols_addr := Read_cols (0); + Cols_brst := Cols_addr (2 DOWNTO 0); + Burst_counter := (OTHERS => '0'); + + -- Row address mux + CASE Bank_addr IS + WHEN "00" => Rows_addr := B0_row_addr; + WHEN "01" => Rows_addr := B1_row_addr; + WHEN "10" => Rows_addr := B2_row_addr; + WHEN OTHERS => Rows_addr := B3_row_addr; + END CASE; + END IF; + + -- Toggle Dqs during Read command + IF Data_out_enable = '1' THEN + Dqs_int := '0'; + IF Dqs_out = "00" THEN + Dqs_out <= "11"; + ELSIF Dqs_out = "11" THEN + Dqs_out <= "00"; + ELSE + Dqs_out <= "00"; + END IF; + ELSIF Data_out_enable = '0' AND Dqs_int = '0' THEN + Dqs_out <= "ZZ"; + END IF; + + -- Initialize Dqs for Read command + IF Read_cmnd (2) = '1' THEN + IF Data_out_enable = '0' THEN + Dqs_int := '1'; + Dqs_out <= "00"; + END IF; + END IF; + + -- Read Latch + IF Data_out_enable = '1' THEN + -- Initialize Memory + Init_mem (Bank_addr, CONV_INTEGER(Rows_addr)); + + -- Output Data + CASE Bank_addr IS + WHEN "00" => Dq <= Bank0 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); + WHEN "01" => Dq <= Bank1 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); + WHEN "10" => Dq <= Bank2 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); + WHEN OTHERS => Dq <= Bank3 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); + END CASE; + + -- Increase Burst Counter + Burst_decode; + ELSE + Dq <= (OTHERS => 'Z'); + END IF; + END IF; + + -- + -- Write FIFO and DM Mask Logic + -- + IF Sys_clk'EVENT AND Sys_clk = '1' THEN + -- Write command pipeline + Write_cmnd (0) := Write_cmnd (1); + Write_cmnd (1) := Write_cmnd (2); + Write_cmnd (2) := '0'; + + -- Write command pipeline + Write_bank (0) := Write_bank (1); + Write_bank (1) := Write_bank (2); + Write_bank (2) := "00"; + + -- Write column pipeline + Write_cols (0) := Write_cols (1); + Write_cols (1) := Write_cols (2); + Write_cols (2) := (OTHERS => '0'); + + -- Initialize Write command + IF Write_cmnd (0) = '1' THEN + Data_in_enable := '1'; + Bank_addr := Write_bank (0); + Cols_addr := Write_cols (0); + Cols_brst := Cols_addr (2 DOWNTO 0); + Burst_counter := (OTHERS => '0'); + + -- Row address mux + CASE Bank_addr IS + WHEN "00" => Rows_addr := B0_row_addr; + WHEN "01" => Rows_addr := B1_row_addr; + WHEN "10" => Rows_addr := B2_row_addr; + WHEN OTHERS => Rows_addr := B3_row_addr; + END CASE; + END IF; + + -- Write data + IF Data_in_enable = '1' THEN + -- Initialize memory + Init_mem (Bank_addr, CONV_INTEGER(Rows_addr)); + + -- Write first data + IF Dm_pair (1) = '0' OR Dm_pair (0) = '0' THEN + -- Data Buffer + CASE Bank_addr IS + WHEN "00" => Data_buf := Bank0 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); + WHEN "01" => Data_buf := Bank1 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); + WHEN "10" => Data_buf := Bank2 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); + WHEN OTHERS => Data_buf := Bank3 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); + END CASE; + + -- Perform DM Mask + IF Dm_pair (0) = '0' THEN + Data_buf ( 7 DOWNTO 0) := Dq_pair ( 7 DOWNTO 0); + END IF; + IF Dm_pair (1) = '0' THEN + Data_buf (15 DOWNTO 8) := Dq_pair (15 DOWNTO 8); + END IF; + + -- Write Data + CASE Bank_addr IS + WHEN "00" => Bank0 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf; + WHEN "01" => Bank1 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf; + WHEN "10" => Bank2 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf; + WHEN OTHERS => Bank3 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf; + END CASE; + END IF; + + -- Increase Burst Counter + Burst_decode; + + -- Write second data + IF Dm_pair (3) = '0' OR Dm_pair (2) = '0' THEN + -- Data Buffer + CASE Bank_addr IS + WHEN "00" => Data_buf := Bank0 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); + WHEN "01" => Data_buf := Bank1 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); + WHEN "10" => Data_buf := Bank2 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); + WHEN OTHERS => Data_buf := Bank3 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)); + END CASE; + + -- Perform DM Mask + IF Dm_pair (2) = '0' THEN + Data_buf ( 7 DOWNTO 0) := Dq_pair (23 DOWNTO 16); + END IF; + IF Dm_pair (3) = '0' THEN + Data_buf (15 DOWNTO 8) := Dq_pair (31 DOWNTO 24); + END IF; + + -- Write Data + CASE Bank_addr IS + WHEN "00" => Bank0 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf; + WHEN "01" => Bank1 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf; + WHEN "10" => Bank2 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf; + WHEN OTHERS => Bank3 (CONV_INTEGER(Rows_addr)) (CONV_INTEGER(Cols_addr)) := Data_buf; + END CASE; + END IF; + + -- Increase Burst Counter + Burst_decode; + + -- tWR start and tWTR check + IF Dm_pair (3 DOWNTO 2) = "00" OR Dm_pair (1 DOWNTO 0) = "00" THEN + CASE Bank_addr IS + WHEN "00" => WR_chk0 := NOW; + WHEN "01" => WR_chk1 := NOW; + WHEN "10" => WR_chk2 := NOW; + WHEN OTHERS => WR_chk3 := NOW; + END CASE; + + -- tWTR check + ASSERT (Read_enable = '0') + REPORT "tWTR violation during Read" + SEVERITY WARNING; + END IF; + END IF; + END IF; + + -- + -- Auto Precharge Calculation + -- + IF Sys_clk'EVENT AND Sys_clk = '1' THEN + -- Precharge counter + IF Read_precharge (0) = '1' OR Write_precharge (0) = '1' THEN + Count_precharge (0) := Count_precharge (0) + 1; + END IF; + IF Read_precharge (1) = '1' OR Write_precharge (1) = '1' THEN + Count_precharge (1) := Count_precharge (1) + 1; + END IF; + IF Read_precharge (2) = '1' OR Write_precharge (2) = '1' THEN + Count_precharge (2) := Count_precharge (2) + 1; + END IF; + IF Read_precharge (3) = '1' OR Write_precharge (3) = '1' THEN + Count_precharge (3) := Count_precharge (3) + 1; + END IF; + + -- Read with AutoPrecharge Calculation + -- The device start internal precharge when: + -- 1. Meet tRAS requirement + -- 2. BL/2 cycles after command + IF ((Read_precharge(0) = '1') AND (NOW - RAS_chk0 >= tRAS)) THEN + IF ((Burst_length_2 = '1' AND Count_precharge(0) >= 1) OR + (Burst_length_4 = '1' AND Count_precharge(0) >= 2) OR + (Burst_length_8 = '1' AND Count_precharge(0) >= 4)) THEN + Pc_b0 := '1'; + Act_b0 := '0'; + RP_chk0 := NOW; + Read_precharge(0) := '0'; + END IF; + END IF; + IF ((Read_precharge(1) = '1') AND (NOW - RAS_chk1 >= tRAS)) THEN + IF ((Burst_length_2 = '1' AND Count_precharge(1) >= 1) OR + (Burst_length_4 = '1' AND Count_precharge(1) >= 2) OR + (Burst_length_8 = '1' AND Count_precharge(1) >= 4)) THEN + Pc_b1 := '1'; + Act_b1 := '0'; + RP_chk1 := NOW; + Read_precharge(1) := '0'; + END IF; + END IF; + IF ((Read_precharge(2) = '1') AND (NOW - RAS_chk2 >= tRAS)) THEN + IF ((Burst_length_2 = '1' AND Count_precharge(2) >= 1) OR + (Burst_length_4 = '1' AND Count_precharge(2) >= 2) OR + (Burst_length_8 = '1' AND Count_precharge(2) >= 4)) THEN + Pc_b2 := '1'; + Act_b2 := '0'; + RP_chk2 := NOW; + Read_precharge(2) := '0'; + END IF; + END IF; + IF ((Read_precharge(3) = '1') AND (NOW - RAS_chk3 >= tRAS)) THEN + IF ((Burst_length_2 = '1' AND Count_precharge(3) >= 1) OR + (Burst_length_4 = '1' AND Count_precharge(3) >= 2) OR + (Burst_length_8 = '1' AND Count_precharge(3) >= 4)) THEN + Pc_b3 := '1'; + Act_b3 := '0'; + RP_chk3 := NOW; + Read_precharge(3) := '0'; + END IF; + END IF; + + -- Write with AutoPrecharge Calculation + -- The device start internal precharge when: + -- 1. Meet tRAS requirement + -- 2. Two clock after last burst + -- Since tWR is time base, the model will compensate tRP + IF ((Write_precharge(0) = '1') AND (NOW - RAS_chk0 >= tRAS)) THEN + IF ((Burst_length_2 = '1' AND Count_precharge (0) >= 4) OR + (Burst_length_4 = '1' AND Count_precharge (0) >= 5) OR + (Burst_length_8 = '1' AND Count_precharge (0) >= 7)) THEN + Pc_b0 := '1'; + Act_b0 := '0'; + RP_chk0 := NOW - ((2 * tCK) - tWR); + Write_precharge(0) := '0'; + END IF; + END IF; + IF ((Write_precharge(1) = '1') AND (NOW - RAS_chk1 >= tRAS)) THEN + IF ((Burst_length_2 = '1' AND Count_precharge (1) >= 4) OR + (Burst_length_4 = '1' AND Count_precharge (1) >= 5) OR + (Burst_length_8 = '1' AND Count_precharge (1) >= 7)) THEN + Pc_b1 := '1'; + Act_b1 := '0'; + RP_chk1 := NOW - ((2 * tCK) - tWR); + Write_precharge(1) := '0'; + END IF; + END IF; + IF ((Write_precharge(2) = '1') AND (NOW - RAS_chk2 >= tRAS)) THEN + IF ((Burst_length_2 = '1' AND Count_precharge (2) >= 4) OR + (Burst_length_4 = '1' AND Count_precharge (2) >= 5) OR + (Burst_length_8 = '1' AND Count_precharge (2) >= 7)) THEN + Pc_b2 := '1'; + Act_b2 := '0'; + RP_chk2 := NOW - ((2 * tCK) - tWR); + Write_precharge(2) := '0'; + END IF; + END IF; + IF ((Write_precharge(3) = '1') AND (NOW - RAS_chk3 >= tRAS)) THEN + IF ((Burst_length_2 = '1' AND Count_precharge (3) >= 4) OR + (Burst_length_4 = '1' AND Count_precharge (3) >= 5) OR + (Burst_length_8 = '1' AND Count_precharge (3) >= 7)) THEN + Pc_b3 := '1'; + Act_b3 := '0'; + RP_chk3 := NOW - ((2 * tCK) - tWR); + Write_precharge(3) := '0'; + END IF; + END IF; + END IF; + + -- + -- DLL Counter + -- + IF Sys_clk'EVENT AND Sys_clk = '1' THEN + IF (DLL_Reset = '1' AND DLL_done = '0') THEN + DLL_count := DLL_count + 1; + IF (DLL_count >= 200) THEN + DLL_done := '1'; + END IF; + END IF; + END IF; + + -- + -- Control Logic + -- + IF Sys_clk'EVENT AND Sys_clk = '1' THEN + -- Auto Refresh + IF Aref_enable = '1' THEN + -- Auto Refresh to Auto Refresh + ASSERT (NOW - RFC_chk >= tRFC) + REPORT "tRFC violation during Auto Refresh" + SEVERITY WARNING; + + -- Precharge to Auto Refresh + ASSERT ((NOW - RP_chk0 >= tRP) AND (NOW - RP_chk1 >= tRP) AND + (NOW - RP_chk2 >= tRP) AND (NOW - RP_chk3 >= tRP)) + REPORT "tRP violation during Auto Refresh" + SEVERITY WARNING; + + -- Precharge to Auto Refresh + ASSERT (Pc_b0 = '1' AND Pc_b1 = '1' AND Pc_b2 = '1' AND Pc_b3 = '1') + REPORT "All banks must be Precharge before Auto Refresh" + SEVERITY WARNING; + + -- Record current tRFC time + RFC_chk := NOW; + END IF; + + -- Extended Load Mode Register + IF Ext_mode_enable = '1' THEN + IF (Pc_b0 = '1' AND Pc_b1 = '1' AND Pc_b2 = '1' AND Pc_b3 = '1') THEN + IF (Addr (0) = '0') THEN + DLL_enable := '1'; + ELSE + DLL_enable := '0'; + END IF; + END IF; + + -- Precharge to EMR + ASSERT (Pc_b0 = '1' AND Pc_b1 = '1' AND Pc_b2 = '1' AND Pc_b3 = '1') + REPORT "All bank must be Precharged before Extended Mode Register" + SEVERITY WARNING; + + -- Precharge to EMR + ASSERT ((NOW - RP_chk0 >= tRP) AND (NOW - RP_chk1 >= tRP) AND + (NOW - RP_chk2 >= tRP) AND (NOW - RP_chk3 >= tRP)) + REPORT "tRP violation during Extended Load Register" + SEVERITY WARNING; + + -- LMR/EMR to EMR + ASSERT (NOW - MRD_chk >= tMRD) + REPORT "tMRD violation during Extended Mode Register" + SEVERITY WARNING; + + -- Record current tMRD time + MRD_chk := NOW; + END IF; + + -- Load Mode Register + IF Mode_reg_enable = '1' THEN + -- Register mode + Mode_reg <= Addr; + + -- DLL Reset + IF (DLL_enable = '1' AND Addr (8) = '1') THEN + DLL_reset := '1'; + DLL_done := '0'; + DLL_count := 0; + ELSIF (DLL_enable = '1' AND DLL_reset = '0' AND Addr (8) = '0') THEN + ASSERT (FALSE) + REPORT "DLL is ENABLE: DLL RESET is require" + SEVERITY WARNING; + ELSIF (DLL_enable = '0' AND Addr (8) = '1') THEN + ASSERT (FALSE) + REPORT "DLL is DISABLE: DLL RESET will be ignored" + SEVERITY WARNING; + END IF; + + -- Precharge to LMR + ASSERT (Pc_b0 = '1' AND Pc_b1 = '1' AND Pc_b2 = '1' AND Pc_b3 = '1') + REPORT "All bank must be Precharged before Load Mode Register" + SEVERITY WARNING; + + -- Precharge to EMR + ASSERT ((NOW - RP_chk0 >= tRP) AND (NOW - RP_chk1 >= tRP) AND + (NOW - RP_chk2 >= tRP) AND (NOW - RP_chk3 >= tRP)) + REPORT "tRP violation during Load Mode Register" + SEVERITY WARNING; + + -- LMR/ELMR to LMR + ASSERT (NOW - MRD_chk >= tMRD) + REPORT "tMRD violation during Load Mode Register" + SEVERITY WARNING; + + -- Check for invalid Burst Length + ASSERT ((Addr (2 DOWNTO 0) = "001") OR -- BL = 2 + (Addr (2 DOWNTO 0) = "010") OR -- BL = 4 + (Addr (2 DOWNTO 0) = "011")) -- BL = 8 + REPORT "Invalid Burst Length during Load Mode Register" + SEVERITY WARNING; + + -- Check for invalid CAS Latency + ASSERT ((Addr (6 DOWNTO 4) = "010") OR -- CL = 2.0 + (Addr (6 DOWNTO 4) = "110")) -- CL = 2.5 + REPORT "Invalid CAS Latency during Load Mode Register" + SEVERITY WARNING; + + -- Record current tMRD time + MRD_chk := NOW; + END IF; + + -- Active Block (latch Bank and Row Address) + IF Active_enable = '1' THEN + -- Activate an OPEN bank can corrupt data + ASSERT ((Ba = "00" AND Act_b0 = '0') OR + (Ba = "01" AND Act_b1 = '0') OR + (Ba = "10" AND Act_b2 = '0') OR + (Ba = "11" AND Act_b3 = '0')) + REPORT "Bank is already activated - data can be corrupted" + SEVERITY WARNING; + + -- Activate Bank 0 + IF Ba = "00" AND Pc_b0 = '1' THEN + -- Activate to Activate (same bank) + ASSERT (NOW - RC_chk0 >= tRC) + REPORT "tRC violation during Activate Bank 0" + SEVERITY WARNING; + + -- Precharge to Active + ASSERT (NOW - RP_chk0 >= tRP) + REPORT "tRP violation during Activate Bank 0" + SEVERITY WARNING; + + -- Record Variables for checking violation + Act_b0 := '1'; + Pc_b0 := '0'; + B0_row_addr := Addr; + RC_chk0 := NOW; + RCD_chk0 := NOW; + RAS_chk0 := NOW; + RAP_chk0 := NOW; + END IF; + + -- Activate Bank 1 + IF Ba = "01" AND Pc_b1 = '1' THEN + -- Activate to Activate (same bank) + ASSERT (NOW - RC_chk1 >= tRC) + REPORT "tRC violation during Activate Bank 1" + SEVERITY WARNING; + + -- Precharge to Active + ASSERT (NOW - RP_chk1 >= tRP) + REPORT "tRP violation during Activate Bank 1" + SEVERITY WARNING; + + -- Record Variables for checking violation + Act_b1 := '1'; + Pc_b1 := '0'; + B1_row_addr := Addr; + RC_chk1 := NOW; + RCD_chk1 := NOW; + RAS_chk1 := NOW; + RAP_chk1 := NOW; + END IF; + + -- Activate Bank 2 + IF Ba = "10" AND Pc_b2 = '1' THEN + -- Activate to Activate (same bank) + ASSERT (NOW - RC_chk2 >= tRC) + REPORT "tRC violation during Activate Bank 2" + SEVERITY WARNING; + + -- Precharge to Active + ASSERT (NOW - RP_chk2 >= tRP) + REPORT "tRP violation during Activate Bank 2" + SEVERITY WARNING; + + -- Record Variables for checking violation + Act_b2 := '1'; + Pc_b2 := '0'; + B2_row_addr := Addr; + RC_chk2 := NOW; + RCD_chk2 := NOW; + RAS_chk2 := NOW; + RAP_chk2 := NOW; + END IF; + + -- Activate Bank 3 + IF Ba = "11" AND Pc_b3 = '1' THEN + -- Activate to Activate (same bank) + ASSERT (NOW - RC_chk3 >= tRC) + REPORT "tRC violation during Activate Bank 3" + SEVERITY WARNING; + + -- Precharge to Active + ASSERT (NOW - RP_chk3 >= tRP) + REPORT "tRP violation during Activate Bank 3" + SEVERITY WARNING; + + -- Record Variables for checking violation + Act_b3 := '1'; + Pc_b3 := '0'; + B3_row_addr := Addr; + RC_chk3 := NOW; + RCD_chk3 := NOW; + RAS_chk3 := NOW; + RAP_chk3 := NOW; + END IF; + + -- Activate Bank A to Activate Bank B + IF (Prev_bank /= Ba) THEN + ASSERT (NOW - RRD_chk >= tRRD) + REPORT "tRRD violation during Activate" + SEVERITY WARNING; + END IF; + + -- AutoRefresh to Activate + ASSERT (NOW - RFC_chk >= tRFC) + REPORT "tRFC violation during Activate" + SEVERITY WARNING; + + -- Record Variables for Checking Violation + RRD_chk := NOW; + Prev_bank := Ba; + END IF; + + -- Precharge Block - Consider NOP if bank already precharged or in process of precharging + IF Prech_enable = '1' THEN + -- EMR or LMR to Precharge + ASSERT (NOW - MRD_chk >= tMRD) + REPORT "tMRD violation during Precharge" + SEVERITY WARNING; + + -- Precharge Bank 0 + IF ((Addr (10) = '1' OR (Addr (10) = '0' AND Ba = "00")) AND Act_b0 = '1') THEN + Act_b0 := '0'; + Pc_b0 := '1'; + RP_chk0 := NOW; + + -- Activate to Precharge bank 0 + ASSERT (NOW - RAS_chk0 >= tRAS) + REPORT "tRAS violation during Precharge" + SEVERITY WARNING; + + -- tWR violation check for Write + ASSERT (NOW - WR_chk0 >= tWR) + REPORT "tWR violation during Precharge" + SEVERITY WARNING; + END IF; + + -- Precharge Bank 1 + IF ((Addr (10) = '1' OR (Addr (10) = '0' AND Ba = "01")) AND Act_b1 = '1') THEN + Act_b1 := '0'; + Pc_b1 := '1'; + RP_chk1 := NOW; + + -- Activate to Precharge + ASSERT (NOW - RAS_chk1 >= tRAS) + REPORT "tRAS violation during Precharge" + SEVERITY WARNING; + + -- tWR violation check for Write + ASSERT (NOW - WR_chk1 >= tWR) + REPORT "tWR violation during Precharge" + SEVERITY WARNING; + END IF; + + -- Precharge Bank 2 + IF ((Addr (10) = '1' OR (Addr (10) = '0' AND Ba = "10")) AND Act_b2 = '1') THEN + Act_b2 := '0'; + Pc_b2 := '1'; + RP_chk2 := NOW; + + -- Activate to Precharge + ASSERT (NOW - RAS_chk2 >= tRAS) + REPORT "tRAS violation during Precharge" + SEVERITY WARNING; + + -- tWR violation check for Write + ASSERT (NOW - WR_chk2 >= tWR) + REPORT "tWR violation during Precharge" + SEVERITY WARNING; + END IF; + + -- Precharge Bank 3 + IF ((Addr (10) = '1' OR (Addr (10) = '0' AND Ba = "11")) AND Act_b3 = '1') THEN + Act_b3 := '0'; + Pc_b3 := '1'; + RP_chk3 := NOW; + + -- Activate to Precharge + ASSERT (NOW - RAS_chk3 >= tRAS) + REPORT "tRAS violation during Precharge" + SEVERITY WARNING; + + -- tWR violation check for Write + ASSERT (NOW - WR_chk3 >= tWR) + REPORT "tWR violation during Precharge" + SEVERITY WARNING; + END IF; + + -- Pipeline for READ + IF CAS_latency_15 = '1' THEN + A10_precharge (3) := Addr(10); + Bank_precharge (3) := Ba; + Cmnd_precharge (3) := '1'; + ELSIF CAS_latency_2 = '1' THEN + A10_precharge (4) := Addr(10); + Bank_precharge (4) := Ba; + Cmnd_precharge (4) := '1'; + ELSIF CAS_latency_25 = '1' THEN + A10_precharge (5) := Addr(10); + Bank_precharge (5) := Ba; + Cmnd_precharge (5) := '1'; + ELSIF CAS_latency_3 = '1' THEN + A10_precharge (6) := Addr(10); + Bank_precharge (6) := Ba; + Cmnd_precharge (6) := '1'; + ELSIF CAS_latency_4 = '1' THEN + A10_precharge (8) := Addr(10); + Bank_precharge (8) := Ba; + Cmnd_precharge (8) := '1'; + END IF; + END IF; + + -- Burst Terminate + IF Burst_term = '1' THEN + -- Pipeline for Read + IF CAS_latency_15 = '1' THEN + Cmnd_bst (3) := '1'; + ELSIF CAS_latency_2 = '1' THEN + Cmnd_bst (4) := '1'; + ELSIF CAS_latency_25 = '1' THEN + Cmnd_bst (5) := '1'; + ELSIF CAS_latency_3 = '1' THEN + Cmnd_bst (6) := '1'; + ELSIF CAS_latency_4 = '1' THEN + Cmnd_bst (8) := '1'; + END IF; + + -- Terminate Write + ASSERT (Data_in_enable = '0') + REPORT "It's illegal to Burst Terminate a Write" + SEVERITY WARNING; + + -- Terminate Read with Auto Precharge + ASSERT (Read_precharge (0) = '0' AND Read_precharge (1) = '0' AND + Read_precharge (2) = '0' AND Read_precharge (3) = '0') + REPORT "It's illegal to Burst Terminate a Read with Auto Precharge" + SEVERITY WARNING; + END IF; + + -- Read Command + IF Read_enable = '1' THEN + -- CAS Latency Pipeline + IF Cas_latency_15 = '1' THEN + Read_cmnd (3) := '1'; + Read_bank (3) := Ba; + Read_cols (3) := Addr (8 DOWNTO 0); + ELSIF Cas_latency_2 = '1' THEN + Read_cmnd (4) := '1'; + Read_bank (4) := Ba; + Read_cols (4) := Addr (8 DOWNTO 0); + ELSIF Cas_latency_25 = '1' THEN + Read_cmnd (5) := '1'; + Read_bank (5) := Ba; + Read_cols (5) := Addr (8 DOWNTO 0); + ELSIF Cas_latency_3 = '1' THEN + Read_cmnd (6) := '1'; + Read_bank (6) := Ba; + Read_cols (6) := Addr (8 DOWNTO 0); + ELSIF Cas_latency_4 = '1' THEN + Read_cmnd (8) := '1'; + Read_bank (8) := Ba; + Read_cols (8) := Addr (8 DOWNTO 0); + END IF; + + -- Write to Read: Terminate Write Immediately + IF Data_in_enable = '1' THEN + Data_in_enable := '0'; + END IF; + + -- Interrupting a Read with Auto Precharge (same bank only) + ASSERT (Read_precharge(CONV_INTEGER(Ba)) = '0') + REPORT "It's illegal to interrupt a Read with Auto Precharge" + SEVERITY WARNING; + + -- Activate to Read + ASSERT ((Ba = "00" AND Act_b0 = '1') OR + (Ba = "01" AND Act_b1 = '1') OR + (Ba = "10" AND Act_b2 = '1') OR + (Ba = "11" AND Act_b3 = '1')) + REPORT "Bank is not Activated for Read" + SEVERITY WARNING; + + -- Activate to Read without Auto Precharge + IF Addr (10) = '0' THEN + ASSERT ((Ba = "00" AND NOW - RCD_chk0 >= tRCD) OR + (Ba = "01" AND NOW - RCD_chk1 >= tRCD) OR + (Ba = "10" AND NOW - RCD_chk2 >= tRCD) OR + (Ba = "11" AND NOW - RCD_chk3 >= tRCD)) + REPORT "tRCD violation during Read" + SEVERITY WARNING; + END IF; + + -- Activate to Read with Auto Precharge + IF Addr (10) = '1' THEN + ASSERT ((Ba = "00" AND NOW - RAP_chk0 >= tRAP) OR + (Ba = "01" AND NOW - RAP_chk1 >= tRAP) OR + (Ba = "10" AND NOW - RAP_chk2 >= tRAP) OR + (Ba = "11" AND NOW - RAP_chk3 >= tRAP)) + REPORT "tRAP violation during Read" + SEVERITY WARNING; + END IF; + + -- Auto precharge + IF Addr (10) = '1' THEN + Read_precharge (Conv_INTEGER(Ba)) := '1'; + Count_precharge (Conv_INTEGER(Ba)) := 0; + END IF; + + -- DLL Check + IF (DLL_reset = '1') THEN + ASSERT (DLL_done = '1') + REPORT "DLL RESET not complete" + SEVERITY WARNING; + END IF; + END IF; + + -- Write Command + IF Write_enable = '1' THEN + -- Pipeline for Write + Write_cmnd (2) := '1'; + Write_bank (2) := Ba; + Write_cols (2) := Addr (8 DOWNTO 0); + + -- Interrupting a Write with Auto Precharge (same bank only) + ASSERT (Write_precharge(CONV_INTEGER(Ba)) = '0') + REPORT "It's illegal to interrupt a Write with Auto Precharge" + SEVERITY WARNING; + + -- Activate to Write + ASSERT ((Ba = "00" AND Act_b0 = '1') OR + (Ba = "01" AND Act_b1 = '1') OR + (Ba = "10" AND Act_b2 = '1') OR + (Ba = "11" AND Act_b3 = '1')) + REPORT "Bank is not Activated for Write" + SEVERITY WARNING; + + -- Activate to Write + ASSERT ((Ba = "00" AND NOW - RCD_chk0 >= tRCD) OR + (Ba = "01" AND NOW - RCD_chk1 >= tRCD) OR + (Ba = "10" AND NOW - RCD_chk2 >= tRCD) OR + (Ba = "11" AND NOW - RCD_chk3 >= tRCD)) + REPORT "tRCD violation during Write" + SEVERITY WARNING; + + -- Auto precharge + IF Addr (10) = '1' THEN + Write_precharge (Conv_INTEGER(Ba)) := '1'; + Count_precharge (Conv_INTEGER(Ba)) := 0; + END IF; + END IF; + END IF; + END PROCESS; + + -- + -- Dqs Receiver + -- + dqs_rcvrs : PROCESS + VARIABLE Dm_temp : STD_LOGIC_VECTOR (1 DOWNTO 0); + VARIABLE Dq_temp : STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0); + BEGIN + WAIT ON Dqs; + -- Latch data at posedge Dqs + IF Dqs'EVENT AND Dqs (1) = '1' AND Dqs (0) = '1' THEN + Dq_temp := Dq; + Dm_temp := Dm; + END IF; + -- Latch data at negedge Dqs + IF Dqs'EVENT AND Dqs (1) = '0' AND Dqs (0) = '0' THEN + Dq_pair <= (Dq & Dq_temp); + Dm_pair <= (Dm & Dm_temp); + END IF; + END PROCESS; + + -- + -- Setup timing checks + -- + Setup_check : PROCESS + BEGIN + WAIT ON Sys_clk; + IF Sys_clk'EVENT AND Sys_clk = '1' THEN + ASSERT(Cke'LAST_EVENT >= tIS) + REPORT "CKE Setup time violation -- tIS" + SEVERITY WARNING; + ASSERT(Cs_n'LAST_EVENT >= tIS) + REPORT "CS# Setup time violation -- tIS" + SEVERITY WARNING; + ASSERT(Cas_n'LAST_EVENT >= tIS) + REPORT "CAS# Setup time violation -- tIS" + SEVERITY WARNING; + ASSERT(Ras_n'LAST_EVENT >= tIS) + REPORT "RAS# Setup time violation -- tIS" + SEVERITY WARNING; + ASSERT(We_n'LAST_EVENT >= tIS) + REPORT "WE# Setup time violation -- tIS" + SEVERITY WARNING; + ASSERT(Addr'LAST_EVENT >= tIS) + REPORT "ADDR Setup time violation -- tIS" + SEVERITY WARNING; + ASSERT(Ba'LAST_EVENT >= tIS) + REPORT "BA Setup time violation -- tIS" + SEVERITY WARNING; + END IF; + END PROCESS; + + -- + -- Hold timing checks + -- + Hold_check : PROCESS + BEGIN + WAIT ON Sys_clk'DELAYED (tIH); + IF Sys_clk'DELAYED (tIH) = '1' THEN + ASSERT(Cke'LAST_EVENT >= tIH) + REPORT "CKE Hold time violation -- tIH" + SEVERITY WARNING; + ASSERT(Cs_n'LAST_EVENT >= tIH) + REPORT "CS# Hold time violation -- tIH" + SEVERITY WARNING; + ASSERT(Cas_n'LAST_EVENT >= tIH) + REPORT "CAS# Hold time violation -- tIH" + SEVERITY WARNING; + ASSERT(Ras_n'LAST_EVENT >= tIH) + REPORT "RAS# Hold time violation -- tIH" + SEVERITY WARNING; + ASSERT(We_n'LAST_EVENT >= tIH) + REPORT "WE# Hold time violation -- tIH" + SEVERITY WARNING; + ASSERT(Addr'LAST_EVENT >= tIH) + REPORT "ADDR Hold time violation -- tIH" + SEVERITY WARNING; + ASSERT(Ba'LAST_EVENT >= tIH) + REPORT "BA Hold time violation -- tIH" + SEVERITY WARNING; + END IF; + END PROCESS; + +END behave; -- cgit v1.1