diff options
Diffstat (limited to 'misc/ddrsdram/src/ddr_top.vhd')
-rw-r--r-- | misc/ddrsdram/src/ddr_top.vhd | 743 |
1 files changed, 743 insertions, 0 deletions
diff --git a/misc/ddrsdram/src/ddr_top.vhd b/misc/ddrsdram/src/ddr_top.vhd new file mode 100644 index 0000000..2aceae9 --- /dev/null +++ b/misc/ddrsdram/src/ddr_top.vhd @@ -0,0 +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; + + |