-- ddr_pads.vhd (DDR SDRAM pads) -- 'intersect' ray-triangle intersection soft core -- -- Copyright (C) 2007 Wenzel Jakob -- -- 01000000000000100000000 -- 00001000011111000001000 -- 00000001100000111000000 -- 01000010001110000101001 -- 00000110010001000100010 -- 00100110010011001100000 -- 10000100011000011000100 -- 00000110001111100000000 -- 00100011100000000010000 -- 00010000111111110000000 -- 00010000000000000001000 -- -- This program is free software; you can redistribute it and/or -- modify it under the terms of the GNU General Public License -- as published by the Free Software Foundation; either version 2 -- of the License, or (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software Foundation -- Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -- -- ============================================================ -- -- Instantiates SSTL2_I pads and registers to interface with an -- external DDR SDRAM. library ieee, work; use ieee.std_logic_1164.all; use work.techmap.all; use work.ddr_memctrl_pkg.all; entity ddr_pads is generic ( TECH : integer; DDR_DQ_WIDTH : integer; DDR_ADDR_WIDTH : integer; DDR_BANK_WIDTH : integer; DDR_DM_WIDTH : integer; DDR_DQS_WIDTH : integer ); port ( -- Internal clock clk0 : in std_ulogic; -- Data capture clock cclk : in std_ulogic; -- Internal clock with 90 deg. phase shift dqsclk : in std_ulogic; -- Internal clock with 180 deg. phase shift ddrclk : in std_logic; -- Global synchronous reset rst : in std_ulogic; -- DDR SDRAM / Differential clock (pos) ddr_clk : out std_ulogic; -- DDR SDRAM / Differential clock (neg) ddr_clk_n : out std_ulogic; -- DDR SDRAM / Clock enable signal ddr_cke : out std_ulogic; -- DDR SDRAM / Chip select signal ddr_cs_n : out std_ulogic; -- DDR SDRAM / Bi-directional data bus ddr_dq : inout std_logic_vector(DDR_DQ_WIDTH - 1 downto 0); -- DDR SDRAM / Bi-directional data strobe ddr_dqs : inout std_logic_vector(DDR_DQS_WIDTH - 1 downto 0); -- DDR SDRAM / Memory bank control lines ddr_bank : out std_logic_vector(DDR_BANK_WIDTH - 1 downto 0); -- DDR SDRAM / Address control lines ddr_addr : out std_logic_vector(DDR_ADDR_WIDTH - 1 downto 0); -- DDR SDRAM / Row address strobe ddr_ras_n : out std_ulogic; -- DDR SDRAM / Column address strobe ddr_cas_n : out std_ulogic; -- DDR SDRAM / Write enable ddr_we_n : out std_ulogic; -- DDR SDRAM / Byte I/O mask ddr_dm : out std_logic_vector(DDR_DM_WIDTH - 1 downto 0); -- Controller / DDR Control signals pad_i : in ddr_pad_t; -- Controller / DDR bank out input, registered on rising edge bank_i : in std_logic_vector(DDR_BANK_WIDTH - 1 downto 0); -- Controller / DDR address out input, registered on rising edge addr_i : in std_logic_vector(DDR_ADDR_WIDTH-1 downto 0); -- Controller / DDR Data out input, registered on rising edge dqo_i : in std_logic_vector(DDR_DQ_WIDTH*2-1 downto 0); -- Controller / DDR Data in output dqi_o : out std_logic_vector(DDR_DQ_WIDTH*2-1 downto 0) ); end ddr_pads; architecture structure of ddr_pads is signal dqs_io_b : std_logic_vector(DDR_DQS_WIDTH - 1 downto 0) := (others => '0'); signal dqs_oth_b : std_logic_vector(DDR_DQS_WIDTH - 1 downto 0) := (others => '0'); signal dqsen_r : std_ulogic := '0'; signal dqsdrv_r : std_ulogic := '0'; signal GND : std_ulogic := '0'; begin GND <= '0'; ddrclock: ddr_clkpad generic map ( TECH => TECH ) port map ( clk => ddrclk, ddr_clk_o => ddr_clk, ddr_clk_n_o => ddr_clk_n ); ddr_dqs_inst: for i in 0 to DDR_DQS_WIDTH-1 generate pad_inst: ddr_dqs_pad generic map ( TECH => TECH ) port map ( dqsclk => dqsclk, rst => rst, en_i => dqsen_r, drv_i => dqsdrv_r, dqs_io_o => dqs_io_b(i), dqs_oth_o => dqs_oth_b(i), ddr_dqs => ddr_dqs(i) ); end generate ddr_dqs_inst; ddr_dq_inst: for i in 0 to DDR_DQ_WIDTH-1 generate begin pad: ddr_dq_pad generic map ( TECH => TECH ) port map ( clk0 => clk0, cclk => cclk, rst => rst, dqs_io_i => dqs_io_b(i / 8), dqs_oth_i => dqs_oth_b(i / 8), d0_i => dqo_i(DDR_DQ_WIDTH + i), d1_i => dqo_i(i), d0_o => dqi_o(DDR_DQ_WIDTH + i), d1_o => dqi_o(i), en_i => pad_i.dqen, ddr_dq => ddr_dq(i) ); end generate ddr_dq_inst; -- DDR SDRAM is always selected ddr_cs_n <= GND; -- Address bus ddr_addr_inst: for i in 0 to DDR_ADDR_WIDTH-1 generate begin ddr_pad_inst: ddr_ctrl_pad generic map ( TECH => TECH ) port map ( clk0 => clk0, rst => rst, do_i => addr_i(i), ddr_ctrl_o => ddr_addr(i) ); end generate ddr_addr_inst; ddr_bank_inst: for i in 0 to DDR_BANK_WIDTH-1 generate pad: ddr_ctrl_pad generic map ( TECH => TECH ) port map ( clk0 => clk0, rst => rst, do_i => bank_i(i), ddr_ctrl_o => ddr_bank(i) ); end generate ddr_bank_inst; ddr_cke_inst: ddr_ctrl_pad generic map ( TECH => TECH ) port map ( clk0 => clk0, rst => rst, do_i => pad_i.cke, ddr_ctrl_o => ddr_cke ); ddr_ras_inst: ddr_ctrl_pad generic map ( TECH => TECH ) port map ( clk0 => clk0, rst => rst, do_i => pad_i.ras_n, ddr_ctrl_o => ddr_ras_n ); ddr_cas_inst: ddr_ctrl_pad generic map ( TECH => TECH ) port map ( clk0 => clk0, rst => rst, do_i => pad_i.cas_n, ddr_ctrl_o => ddr_cas_n ); ddr_we_inst: ddr_ctrl_pad generic map ( TECH => TECH ) port map ( clk0 => clk0, rst => rst, do_i => pad_i.we_n, ddr_ctrl_o => ddr_we_n ); -- DM feature not used ddr_dm_inst: for i in 0 to DDR_DM_WIDTH-1 generate pad: opad generic map ( TECH => TECH, level => io_sstl2_i ) port map ( i => GND, o => ddr_dm(i) ); end generate; clock_domain: process(clk0, rst) begin if rising_edge(clk0) then if rst = '1' then dqsen_r <= '0'; dqsdrv_r <= '0'; else dqsen_r <= pad_i.dqsen; dqsdrv_r <= pad_i.dqsdrv; end if; end if; end process clock_domain; end structure;