⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddr_sdr.vhd

📁 ddr verilog代码,实现DDR内存控制
💻 VHD
📖 第 1 页 / 共 3 页
字号:
----------------------------------------------------------------------------
--
-- PROJECT         DDR-SDRAM Controller Core
--
-- AUTHOR          Markus Lemke
--                 markus@opencores.org
--                 www.array-electronics.de
--
-- SIMULATOR       Model Technology ModelSim 5.4
-- COMPILER        Exemplar Leonardo Spectrum 2001.1d
--
-- DATE            $Date: 2003/03/19 06:45:13 $
--
-- LANGUAGE        VHDL 93
--
-- LIBRARY         ieee, work, unisim
--
-- ABSTRACT        DDR-SDRAM Controller
--                 Top design file,
--                 see readme.txt for more information
--
----------------------------------------------------------------------------
--
-- Copyright (C) 2002 Markus Lemke, www.array-electronics.de
--  
-- Everyone is permitted to copy and distribute  and  modify 
-- this  document  under  the  terms of the OpenIPCore Hardware
-- General  Public License "OHGPL" which can  be  read  in  the
-- file LICENSE.
--  
-- The  License  grants  you  the right to copy, modify  and
-- redistribute this file,  but only under  certain  conditions 
-- described in the License.  Among other things,  the  License
-- requires that  this  copyright  notice  and  the  associated
-- disclaimer  be preserved on  all copies.  Every copy of this
-- file must include a copy of the License, normally in a plain
-- ASCII text file named LICENSE.
--  
-- 
-- DISCLAIMER
-- 
-- THIS SOFTWARE  IS  PROVIDED  ``AS IS''  AND  WITHOUT ANY  
-- EXPRESS  OR  IMPLIED  WARRANTIES, INCLUDING, BUT NOT LIMITED 
-- TO, THE  IMPLIED  WARRANTIES OF  MERCHANTABILITY AND FITNESS
-- FOR A  PARTICULAR  PURPOSE.  IN NO EVENT SHALL THE AUTHOR OR 
-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-- SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL  DAMAGES  (INCLUDING,
-- BUT NOT  LIMITED TO,  PROCUREMENT  OF  SUBSTITUTE  GOODS  OR 
-- SERVICES;  LOSS  OF  USE,  DATA,  OR  PROFITS;  OR  BUSINESS 
-- INTERRUPTION) HOWEVER CAUSED  AND ON ANY THEORY O LIABILITY,
-- WHETHER  IN CONTRACT, STRICT  LIABILITY, OR  TORT (INCLUDING 
-- NEGLIGENCE OR OTHERWISE)  ARISING IN ANY WAY OUT OF THE  USE 
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 
-- DAMAGE.                              
----------------------------------------------------------------------------



------------------------------------------------------------------------------------------------------------
-- DDR-SDRAM Controller Core
------------------------------------------------------------------------------------------------------------
library ieee, work;
use ieee.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use work.ddr_sdr_conf_pkg.all;

entity ddr_sdr is
   port (
      -- Clocks and Reset
      rst_n                 : in std_logic ;  -- external async reset, low active
      clk                   : in std_logic;   -- system clock (e.g. 100MHz), from fpga pad

      sys_rst_qn            : out std_logic;  -- sync reset low active, released after dcms locked
      sys_clk_out           : out std_logic;  -- system clock, dcm output
      clk_fb                : in std_logic;   -- feedback clock
      
      -- User Interface
      cmd                   : in std_logic_vector(U_CMD_WIDTH -1 downto 0);   -- command: read, write, nop
      cmd_vld               : in std_logic;                                   -- '1' when command valid
      addr                  : in std_logic_vector(U_ADDR_WIDTH-1 downto 0);   -- (ROW & BANK & COL)
      busy_q                : out std_logic;                   -- busy flag, when active commands are ignored
      
      -- Input Data
      data_in               : in std_logic_vector(U_DATA_WIDTH-1 downto 0);
      data_req_q            : out std_logic;  -- '1' two clocks before data is clocked in
      data_out_q            : out std_logic_vector(U_DATA_WIDTH -1 downto 0); -- read data
      data_vld_q            : out std_logic;  -- data_out_q is valid when '1'

      -- DDR SDRAM Signals
      sdr_clk               : out std_logic;    -- ddr_sdram_clock
      sdr_clk_n             : out std_logic;    -- /ddr_sdram_clock
      cke_q                 : out std_logic;    -- clock enable
      cs_qn                 : out std_logic;    -- /chip select
      ras_qn                : out std_logic;    -- /ras
      cas_qn                : out std_logic;    -- /cas
      we_qn                 : out std_logic;    -- /write enable
      dm_q                  : out std_logic_vector(DDR_DM_WIDTH-1 downto 0);     -- data mask bits, set to "00"
      dqs_q                 : out std_logic_vector(DDR_DQS_WIDTH-1 downto 0);    -- data strobe, only for write
      ba_q                  : out std_logic_vector(DDR_BANK_WIDTH-1 downto 0);   -- bank select
      a_q                   : out std_logic_vector(DDR_ADDR_WIDTH-1 downto 0);   -- address bus 
      data                  : inout std_logic_vector(DDR_DATA_WIDTH-1 downto 0); -- bidir data bus
                          
      -- Status
      dcm_error_q           : out std_logic -- indicates DCM Errors
   );

   attribute buffer_sig : string;
   attribute buffer_sig of clk    : signal is "IBUFG";
   attribute buffer_sig of clk_fb : signal is "IBUFG";
end;

-- pragma translate_off
library unisim;
-- pragma translate_on

architecture behave of ddr_sdr is

  -- User Interface
   component user_if is
      port (
         rst_int_n             : in std_logic; -- async reset, lo-active
         sys_clk               : in std_logic;
      
         -- user interface
         cmd                   : in std_logic_vector(U_CMD_WIDTH -1 downto 0); -- command: read, write, nop
         cmd_vld               : in std_logic;
         addr                  : in std_logic_vector(U_ADDR_WIDTH-1 downto 0); -- ROW, BANK, COLUMN
         busy_q                : out std_logic; -- busy flag, when active commands are ignored
      
         -- Datenaustausch mit Controller
         init_finished         : in boolean;
         new_cmd_q             : out boolean;
         new_cmd_ack           : in boolean;
         do_prech_q            : out boolean; -- precharge followed by activate
         do_wait_q             : out boolean; -- additional delay requested
      
         cmd_q                 : buffer std_logic_vector(U_CMD_WIDTH -1 downto 0);
         addr_q                : out std_logic_vector(U_ADDR_WIDTH -1 downto 0)
      );
   end component;
   
   -- Global Buffer BUFG
   component bufg
      port ( i : in std_ulogic;
             o : out std_ulogic );
   end component;
   -- pragma translate_off
   for all: bufg use entity unisim.bufg;
   -- pragma translate_on
   
   signal ld_init_cnt_q : boolean;
   signal init_cnt0_q   : boolean;
   signal init_cnt1_q   : boolean;
   signal locked        : std_logic_vector(1 downto 0);
   signal data_lo1_q    : std_logic_vector(DDR_DATA_WIDTH-1 downto 0);
   signal data_lo2_q    : std_logic_vector(DDR_DATA_WIDTH-1 downto 0);
   signal data_hi_q     : std_logic_vector(DDR_DATA_WIDTH-1 downto 0);
   signal sys_clk       : std_logic;
   signal rst_int_n     : std_logic;
   signal wr_ena_q      : std_logic;
   signal wr_ena2_q     : std_logic;
   signal wr_ena3_q     : std_logic;
   signal wr_ena3_qn    : std_logic;
   signal dcm_rst_q     : std_logic;
   signal srst_sys_q    : std_logic;

   type RD_ENA_DEL_TYPE is array(4 downto 0) of boolean;
   signal rd_ena_del_q  : RD_ENA_DEL_TYPE;
   
   type MUX_TYPE is (NORMAL, DELAYED);
   signal mux_q : MUX_TYPE;
   

begin 
   -----------------------------------------------------------------------
   -- Generate synchronous reset for DDR-SDRAM-Controller and DCM's
   --
   init: block
      signal rst_in : std_logic;
      signal srst_clk_q, srst_q : std_logic;
      signal sys_reset_q, sys_reset_1_q : std_logic;
      signal dcm1_locked_q, dcm2_locked_q : std_logic_vector(2 downto 0);
      signal cnt_q : unsigned(4 downto 0);
      type STATE_TYPE is (s0, s1, s2, s3, s4);
      signal state_q : STATE_TYPE;
   begin
      rst_in <= not rst_n;

      -- make synchronous reset 'srst_q' from asynchronous external 'rst_n'
      -- 'srst_q' is synchronous to clock 'clk'
      reset1: entity work.reset
         port map (
            clk    => clk,
            rst_in => rst_in,
            srst_q => srst_clk_q );

      -- make synchronous reset signal 'srst_sys_q' which is synchronous to
      -- clock 'sys_clk'
      reset2: entity work.reset
         port map (
            clk    => sys_clk,
            rst_in => sys_reset_1_q,
            srst_q => srst_q );

      srst_sys_q <= srst_q;

      process(clk)
      begin
         if rising_edge(clk) then
            case state_q is
               when s0 =>
                  state_q <= s1;
                  sys_reset_q <= '1'; -- after 1 ns;
                  dcm_rst_q <= '0';
                  cnt_q <= "11111";
                  
               when s1 =>
                  cnt_q <= cnt_q - 1;
                  if cnt_q = 0 then
                     dcm_rst_q <= '1';
                     state_q <= s2;
                  end if;

               when s2 =>
                  cnt_q <= cnt_q - 1;
                  if cnt_q = 0 then
                     dcm_rst_q <= '0';
                     state_q <= s3;
                  end if;

               when s3 =>
                  if dcm1_locked_q(2)='1' and dcm2_locked_q(2)='1' then
                     state_q <= s4;
                     dcm_error_q <= '0';
                  end if;
            
               when s4 =>
                  sys_reset_q <= '0' after 1 ns;   -- release system reset
                  if dcm1_locked_q(2)='0' or dcm2_locked_q(2)='0' then
                     dcm_error_q <= '1';
                  end if;
                  
            end case;
            sys_reset_1_q <= sys_reset_q;

            -- synchronize 'dcm1_locked'
            dcm1_locked_q <= dcm1_locked_q(1 downto 0) & locked(0);
            dcm2_locked_q <= dcm2_locked_q(1 downto 0) & locked(1);
            
            if srst_clk_q='1' then
               state_q <= s0;
            end if;
         end if;
      end process;
   end block;
   -------------------------------------------------------------------   

   -------------------------------------------------------------------------------------------------------
   -- DDR-SDRAM Control 
   -------------------------------------------------------------------------------------------------------
   ctrl: block 
      type STATE_TYPE is (IDLE, WAIT_200US, INIT1_PRECHARGE, INIT2_PRECHARGE,
                          INIT_REFRESH, INIT_EXT_MODE, INIT1_MODE, WAIT_DLL, WR_PRECH, RD_PRECH,
                          INIT2_MODE, ST_WAIT_CMD, ST_RFSH_0, ST_RFSH_1, ST_RFSH_2, ST_RFSH_3, ST_RFSH_4,
                          ST_READ1, ST_WRITE1, ST_WR_ACTIVATE, ST_WAIT_WR, ST_RD_ACTIVATE, ST_WAIT_RD);
                          
      signal state_q : STATE_TYPE;

      signal sdr_if_q  : PART_IF_TYPE;
      signal sdr_if2_q : PART_IF_TYPE;
      signal ld_ct_cnt_q : boolean;
      signal ct0_q : boolean;
      signal second_refresh_q : boolean;
      signal ct_cnt_q : integer range 0 to 9;
      signal ld_dll_cnt_q : boolean;
      signal dll_cnt0_q : boolean;
      type TRISTATE_TYPE is array (0 to DDR_DATA_WIDTH-1) of boolean;
      signal tristate_q : TRISTATE_TYPE;
      signal dqsz_q    : std_logic_vector(DDR_DQS_WIDTH-1 downto 0);
      signal dqs       : std_logic_vector(DDR_DQS_WIDTH-1 downto 0);
      signal a_int_q   : std_logic_vector(DDR_ADDR_WIDTH-1 downto 0);  
      signal a_int2_q  : std_logic_vector(DDR_ADDR_WIDTH-1 downto 0);  
      signal cs_int_qn : std_logic;
      signal ba_int_q  : std_logic_vector(DDR_BANK_WIDTH-1 downto 0);
      signal ba_int2_q : std_logic_vector(DDR_BANK_WIDTH-1 downto 0);
      
      signal bus_switch_q : std_logic_vector(2 downto 0); -- delay for switching the data bus
      signal z_q : std_logic; -- Tristate signal, derived from bus_switch_q

      signal clk_int, sys_clk270, fpga_clk, fpga_clk270 : std_logic;

      signal rst : std_logic;

      signal cke_int_q  : std_logic;
      signal cke_int2_q : std_logic;

      signal d2sdr    : std_logic_vector(DDR_DATA_WIDTH-1 downto 0);
      signal ddr_data : std_logic_vector(U_DATA_WIDTH-1 downto 0);
      signal rd_ena_q : boolean;
      
      signal rst_qn   : std_logic;

      attribute preserve_signal : boolean;
      attribute preserve_signal of dqsz_q : signal is true;
      attribute preserve_signal of tristate_q : signal is true;
      attribute preserve_signal of z_q : signal is true;
      attribute preserve_signal of rst_qn : signal is true;
      
      signal init_finished_q : boolean;
      signal new_cmd_ack_q   : boolean;
      signal do_prech_q      : boolean;
      signal cmd_ui_q        : std_logic_vector(U_CMD_WIDTH-1 downto 0);
      signal addr_ui_q       : std_logic_vector(U_ADDR_WIDTH-1 downto 0);
      signal new_cmd_q       : boolean;
      
      -- Data Output
      type SHIFT_TYPE is array (1 downto 0) of std_logic_vector(U_DATA_WIDTH-1 downto 0);
      signal shift_q : SHIFT_TYPE;
      
      signal row_adr_q    : std_logic_vector(DDR_ADDR_WIDTH-1 downto 0);
      signal col_adr_q    : std_logic_vector(DDR_ADDR_WIDTH-1 downto 0);
      signal do_wait_q    : boolean;
      signal del_cnt_q    : integer range 0 to 7;
      signal del0_q       : boolean;
      signal ld_del_cnt_q : boolean;
      signal w_srg_q      : std_logic_vector(5 downto 0);
      signal tras_cnt_q   : integer range 0 to TRAS-1;
      
      signal clk133   : std_logic;
      signal clk133_o : std_logic;
      

      -------------------------------------------------------------------------------------------------
      -- phase shift definition
      -- clkin_clkfb_skew = phase_shift/256 x period_clkin
      -------------------------------------------------------------------------------------------------
      function func_phase_shift return integer
      is

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -