OpenCores
URL https://opencores.org/ocsvn/layer2/layer2/trunk

Subversion Repositories layer2

[/] [layer2/] [trunk/] [vhdl/] [ddr/] [rtl/] [ddr_init.vhd] - Rev 2

Compare with Previous | Blame | View Log

--------------------------------------------------------------------------------
-- Mycron® DDR SDRAM - MT46V32M16 - 8 Meg x 16 x 4 banks                      --
--------------------------------------------------------------------------------
-- Copyright (C)2012  Mathias Hörtnagl <mathias.hoertnagl@gmail.comt>         --
--                                                                            --
-- 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 3 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, see <http://www.gnu.org/licenses/>.      --
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity ddr_init is
   port (
      clk0      : in  std_logic;
      rst       : in  std_logic;
      SD_CKE    : out std_logic;
      SD_BA     : out std_logic_vector(1 downto 0);
      SD_A      : out std_logic_vector(12 downto 0);
      SD_CMD    : out std_logic_vector(3 downto 0);
      init_done : out boolean
   );
end ddr_init;
 
architecture rtl of ddr_init is
 
   -----------------------------------------------------------------------------
   -- Controller Commands                                                     --
   -----------------------------------------------------------------------------
   constant CMD_LMR          : std_logic_vector(3 downto 0) := "0000";
   constant CMD_AUTO_REFRESH : std_logic_vector(3 downto 0) := "0001";
   constant CMD_PRECHARGE    : std_logic_vector(3 downto 0) := "0010";
   constant CMD_NOP          : std_logic_vector(3 downto 0) := "0111";
 
   -----------------------------------------------------------------------------
   -- Mode Rgister Addresses                                                  --
   -----------------------------------------------------------------------------
   -- Addresses for the two mode registers, selected via SD_BA.
   constant BMR_ADDR : std_logic_vector(1 downto 0) := "00";
   constant EMR_ADDR : std_logic_vector(1 downto 0) := "01";
 
   -----------------------------------------------------------------------------
   -- Base Mode Rgister                                                       --
   -----------------------------------------------------------------------------
   -- Operating modes.
   constant OP_NORMAL  : std_logic_vector(5 downto 0) := "000000";
   constant OP_DLL_RST : std_logic_vector(5 downto 0) := "000010";
 
   -- CAS latency.
   constant CAS_2  : std_logic_vector(2 downto 0) := "010";
 
   -- Burst type.
   constant BT_S : std_logic := '0';      -- Sequential.
 
   -- Burst lengths.
   constant BL_2 : std_logic_vector(2 downto 0) := "001";
 
   -----------------------------------------------------------------------------
   -- Extended Mode Rgister                                                   --
   -----------------------------------------------------------------------------
   -- DLL.
   constant DLL_ENABLE  : std_logic := '0';
   constant DLL_DISABLE : std_logic := '1';
 
   -- Drive strength.
   constant DS_NORMAL  : std_logic := '0';
 
 
   -----------------------------------------------------------------------------
   -- Initialization                                                          --
   -----------------------------------------------------------------------------
   type init_state_t is (
      Wait20000,                          -- Wait for 200µs.
      CKE_High,                           -- Assert CKE.
      Precharge0, Precharge0Wait,         -- First precharge.
      ProgramEMR, ProgramEMRWait,         -- Set Extended Mode Register.
      ProgramMR, ProgramMRWait,           -- Set Base Mode Register.
      Precharge1, Precharge1Wait,         -- second precharge.
      AutoRefresh0, AutoRefresh0Wait,     -- First autorefresh.
      AutoRefresh1, AutoRefresh1Wait,     -- Second autorefresh.
      ProgramMR1, ProgramMR1Wait,         -- Set Base Mode Register.
      Wait200,                            -- Wait for 200 cycles.
      Done                                -- Initialization done!
   );
 
   type init_t is record
      s   : init_state_t;
      c   : natural range 0 to 19999;
   end record;
 
   constant init_d  : init_t := init_t'( Wait20000, 0);
   signal i, iin    : init_t := init_d;
begin
 
   -----------------------------------------------------------------------------
   -- Initialization                                                          --
   -----------------------------------------------------------------------------
   initial : process(i)
   begin
 
      iin       <= i;
      SD_CKE    <= '1';
      SD_BA     <= "00";
      SD_CMD    <= CMD_NOP;
      SD_A      <= (others => '0');
      init_done <= false;
 
      case i.s is
 
         -----------------------------------------------------------------------
         -- 5. Wait for 200µs.                                                --
         -----------------------------------------------------------------------
         when Wait20000 =>
            SD_CKE <= '0';
            if i.c = 19999 then
               iin.c <= 0;
               iin.s <= CKE_High;
            else
               iin.c <= i.c + 1;
            end if;
 
         -----------------------------------------------------------------------
         -- 6. Bring CKE high.                                                --
         -----------------------------------------------------------------------
         when CKE_High =>
            iin.s <= Precharge0;
 
         -----------------------------------------------------------------------
         -- 7. Precharge all banks.                                           --
         -----------------------------------------------------------------------
         when Precharge0 =>
            SD_CMD      <= CMD_PRECHARGE;
            SD_A(10) <= '1';               -- Precharge all operation.
            iin.s       <= Precharge0Wait;
 
         -- PRECHARGE command period tRP: 15ns
         when Precharge0Wait =>
            if i.c = 1 then
               iin.c <= 0;
               iin.s <= ProgramEMR;
            else
               iin.c <= i.c + 1;
            end if;
 
         -----------------------------------------------------------------------
         -- 9. Program the Extended Mode Register.                            --
         -----------------------------------------------------------------------
         when ProgramEMR =>
            SD_CMD  <= CMD_LMR;
            SD_BA   <= EMR_ADDR;              -- Select Extended Mode Register.
            SD_A    <= "00000000000" & DS_NORMAL & DLL_DISABLE;
            iin.s   <= ProgramEMRWait;
 
         -- LOAD MODE REGISTER command cycle time tMRD: 12ns
         when ProgramEMRWait =>
            if i.c = 1 then
               iin.c <= 0;
               iin.s <= ProgramMR;
            else
               iin.c <= i.c + 1;
            end if;
 
         -----------------------------------------------------------------------
         -- 11. Program the Mode Rgister                                      --
         -----------------------------------------------------------------------
         when ProgramMR =>
            SD_CMD  <= CMD_LMR;
            SD_BA   <= BMR_ADDR;              -- Select Base Mode Register.
            SD_A    <= OP_NORMAL & CAS_2 & BT_S & BL_2;
            iin.s   <= ProgramMRWait;
 
         -- LOAD MODE REGISTER command cycle time tMRD: 12ns
         when ProgramMRWait =>
            if i.c = 1 then
               iin.c <= 0;
               iin.s <= Precharge1;
            else
               iin.c <= i.c + 1;
            end if;
 
         -----------------------------------------------------------------------
         -- 13. Precharge all banks.                                          --
         -----------------------------------------------------------------------
         when Precharge1 =>
            SD_CMD   <= CMD_PRECHARGE;
            SD_A(10) <= '1';               -- Precharge all operation.
            iin.s    <= Precharge1Wait;
 
         -- PRECHARGE command period tRP: 15ns
         when Precharge1Wait =>
            if i.c = 1 then
               iin.c <= 0;
               iin.s <= AutoRefresh0;
            else
               iin.c <= i.c + 1;
            end if;
 
         -----------------------------------------------------------------------
         -- 15. Auto Refresh.                                                 --
         -----------------------------------------------------------------------
         when AutoRefresh0 =>
            SD_CMD <= CMD_AUTO_REFRESH;
            iin.s  <= AutoRefresh0Wait;
 
         -- AUTO REFRESH command period tRFC: 72ns
         when AutoRefresh0Wait =>
            if i.c = 7 then
               iin.c <= 0;
               iin.s <= AutoRefresh1;
            else
               iin.c <= i.c + 1;
            end if;
 
         -----------------------------------------------------------------------
         -- 17. Auto Refresh.                                                 --
         -----------------------------------------------------------------------
         when AutoRefresh1 =>
            SD_CMD <= CMD_AUTO_REFRESH;
            iin.s  <= AutoRefresh1Wait;
 
         -- AUTO REFRESH command period tRFC: 72ns
         when AutoRefresh1Wait =>
            if i.c = 7 then
               iin.c <= 0;
               iin.s <= ProgramMR1;
            else
               iin.c <= i.c + 1;
            end if;
 
         -----------------------------------------------------------------------
         -- 19. Program the Mode Rgister (Clear DLL Bit)                      --
         -----------------------------------------------------------------------
         when ProgramMR1 =>
            SD_CMD  <= CMD_LMR;
            SD_BA   <= BMR_ADDR;              -- Select Base Mode Register.
            SD_A    <= OP_NORMAL & CAS_2 & BT_S & BL_2;
            iin.s   <= ProgramMR1Wait;
 
         -- LOAD MODE REGISTER command cycle time tMRD: 12ns
         when ProgramMR1Wait =>
            if i.c = 1 then
               iin.c <= 0;
               iin.s <= Wait200;
            else
               iin.c <= i.c + 1;
            end if;            
 
         -----------------------------------------------------------------------
         -- 21. Wait for 200 cycles.                                          --
         -----------------------------------------------------------------------
         when Wait200 =>
            if i.c = 199 then
               iin.c <= 0;
               iin.s <= Done;
            else
               iin.c <= i.c + 1;
            end if;
 
         -----------------------------------------------------------------------
         -- Initialization done.                                              --
         -----------------------------------------------------------------------
         when Done =>
            init_done <= true;
      end case;
   end process;
 
 
   -----------------------------------------------------------------------------
   -- Register                                                                --
   -----------------------------------------------------------------------------
   reg : process(clk0)
   begin
      if rising_edge(clk0) then
         if rst = '1' then i <= init_d; else i <= iin; end if;
      end if;
   end process;
end rtl;

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.