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

📄 ddrctrl.vhd

📁 free hardware ip core about sparcv8,a soc cpu in vhdl
💻 VHD
📖 第 1 页 / 共 3 页
字号:
--------------------------------------------------------------------------------  This file is a part of the GRLIB VHDL IP LIBRARY--  Copyright (C) 2003, Gaisler Research----  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA ------------------------------------------------------------------------------- Entity:      ddrctrl-- File:        ddrctrl.vhd-- Author:      David Lindh - Gaisler Research-- Description: DDR-RAM memory controller with AMBA interface------------------------------------------------------------------------------library ieee;use ieee.std_logic_1164.all;library grlib;use grlib.amba.all;use grlib.stdlib.all;library gaisler;use grlib.devices.all;use gaisler.memctrl.all;library techmap;use techmap.gencomp.all;use techmap.allmem.all;use gaisler.ddrrec.all;entity ddrctrl is  generic (    hindex1    :     integer := 0;    haddr1     :     integer := 0;    hmask1     :     integer := 16#f80#;    hindex2    :     integer := 0;    haddr2     :     integer := 0;    hmask2     :     integer := 16#f80#;    pindex     :     integer := 3;    paddr      :     integer := 0;    numahb     :     integer := 1;       -- Allowed: 1, 2    ahb1sepclk :     integer := 0;       -- Allowed: 0, 1    ahb2sepclk :     integer := 0;       -- Allowed: 0, 1    modbanks   :     integer := 1;       -- Allowed: 1, 2    numchips   :     integer := 2;       -- Allowed: 1, 2, 4, 8, 16    chipbits   :     integer := 16;      -- Allowed: 4, 8, 16    chipsize   :     integer := 256;     -- Allowed: 64, 128, 256, 512, 1024 (MB)    plldelay   :     integer := 0;       -- Allowed: 0, 1 (Use 200us start up delay)    tech       :     integer := virtex2;    clkperiod  :     integer := 10);     -- (ns)  port (    rst       : in  std_ulogic;    clk0      : in  std_ulogic;    clk90     : in  std_ulogic;    clk180    : in  std_ulogic;    clk270    : in  std_ulogic;    hclk1     : in  std_ulogic;    hclk2     : in  std_ulogic;    pclk      : in  std_ulogic;    ahb1si    : in  ahb_slv_in_type;    ahb1so    : out ahb_slv_out_type;    ahb2si    : in  ahb_slv_in_type;    ahb2so    : out ahb_slv_out_type;    apbsi     : in  apb_slv_in_type;    apbso     : out apb_slv_out_type;    ddsi      : out ddrmem_in_type;    ddso      : in  ddrmem_out_type);end ddrctrl;architecture rtl of ddrctrl is-------------------------------------------------------------------------------  -- Constants-------------------------------------------------------------------------------  constant DELAY_15600NS   : integer := (15600 / clkperiod);  constant DELAY_7800NS    : integer := (7800 / clkperiod);  constant DELAY_7_15600NS : integer := (7*(15600 / clkperiod));  constant DELAY_7_7800NS  : integer := (7*(7800 / clkperiod));  constant DELAY_200US : integer := (200000 / clkperiod);      constant REVISION : integer := 0;  constant pmask    : integer := 16#fff#;  constant pconfig  : apb_config_type := (  0 => ahb_device_reg ( VENDOR_GAISLER, GAISLER_DDRMP, 0, REVISION, 0),  1 => apb_iobar(paddr, pmask));  constant dqsize     : integer := numchips*chipbits;  constant dmsize     : integer := (dqsize/8);  constant strobesize : integer := (dqsize/8) * dmvector(chipbits);     --------------------------------------------------------------------------------- Signals-------------------------------------------------------------------------------    signal toAHB        : two_ahb_ctrl_in_type;  signal fromAHB      : two_ahb_ctrl_out_type;  signal fromAHB2Main : two_ahb_ctrl_out_type;     signal apbr         : apb_reg_type;  signal apbri        : apb_reg_type;  signal fromAPB      : apb_ctrl_out_type;  signal fromAPB2Main : apb_ctrl_out_type;      signal mainr        : main_reg_type;  signal mainri       : main_reg_type;  signal fromMain     : main_ctrl_out_type;  signal fromMain2APB : apb_ctrl_in_type;       signal fromMain2AHB : two_ahb_ctrl_in_type;  signal fromMain2HS  : hs_in_type;   signal toHS         : hs_in_type;  signal fromHS       : hs_out_type;  begin  -- achitecture rtl--------------------------------------------------------------------------------- Error reports  assert (tech = virtex2 or tech = virtex4 or tech = lattice) report "Unsupported technology by DDR controller (generic tech)" severity failure;  assert (modbanks=1 or modbanks=2) report "Only 1 or 2 module banks is supported (generic modbanks)" severity failure;  assert (chipbits=4 or chipbits=8 or chipbits=16) report "DDR chips either have 4, 8 or 16 bits output (generic chipbits)" severity failure;  assert (chipsize=64 or chipsize=128 or chipsize=256 or chipsize=512 or chipsize=1024) report "DDR chips either have 64, 128, 256, 512 or 1024 Mbit size" severity failure;  assert (buffersize>=2) report "Buffer must have room for at least 2 bursts (generic buffersize)" severity failure;  assert (plldelay=0 or plldelay=1) report "Invalid setting for DDRRAM PLL delay (generic plldelay)" severity failure;   assert (numahb=1 or numahb=2) report "Only one or two AHB interfaces can be used (generic numahb)" severity failure;--------------------------------------------------------------------------------- APB control    -- Controls APB bus. Contains the DDRCFG register. Clear memcmd    -- bits when a memory command requested on APB is complete.   apbcomb : process(apbr, apbsi, fromMain2APB, rst)     variable v : apb_reg_type;   begin     v:= apbr;     if rst = '0' then -- Reset       v.ddrcfg_reg := ddrcfg_reset;      elsif fromMain2APB.apb_cmd_done = '1' then -- Clear memcmd bits       v.ddrcfg_reg(28 downto 27) := "00";     elsif (apbsi.psel(pindex) and apbsi.penable and apbsi.pwrite) = '1' then -- Write       v.ddrcfg_reg := apbsi.pwdata(31 downto 1) & fromMain2APB.ready;     else       v.ddrcfg_reg(0) := fromMain2APB.ready;     end if;     apbri <= v;     fromAPB.ddrcfg_reg <= v.ddrcfg_reg;    end process apbcomb;   apbclk : process(pclk)     begin       if rising_edge(pclk) then apbr <= apbri; end if;   end process;         apbso.prdata <= fromAPB.ddrcfg_reg; apbso.pirq <= (others => '0');   apbso.pindex <= pindex; apbso.pconfig <= pconfig;  ------------------------------------------------------------------------------- -- Main controller-------------------------------------------------------------------------------   maincomb     : process(mainr, fromAHB, fromAHB2Main, fromAPB2Main, rst, fromHS)     variable v : main_reg_type;   begin     v := mainr; v.loadcmdbuffer := '0'; -- Clear Cmd loading bit-------------------------------------------------------------------------------     -- DDRCFG control     -- Reads DDRCFG from APB controller. Handles refresh command from refresh     -- timer and memoory comand requested on APB.         case v.apbstate is       when idle =>         v.apb_cmd_done := '0';         -- Refresh timer signals refresh         if v.doRefresh = '1' and v.ddrcfg.refresh = '1' then           v.apbstate := refresh;         -- LMR cmd on APB bus         elsif fromAPB2Main.ddrcfg_reg(28 downto 27) = "11" then             v.lockAHB := "11";            v.apbstate := wait_lmr1;         -- Refresh or Precharge cmd on APB BUS         elsif fromAPB2Main.ddrcfg_reg(28 downto 27) > "00" then           v.apbstate := cmd;           -- Nothing to be done         else           v.ddrcfg.memcmd  := "00";         end if;       -- Refresh from Timer       when refresh =>         if v.mainstate = idle then v.ddrcfg.memcmd := "10"; end if;         if v.dorefresh = '0' then v.ddrcfg.memcmd := "00"; v.apbstate := idle; end if;       -- Refresh or Precharge from APB BUS       when cmd =>         if v.mainstate = idle then v.ddrcfg.memcmd := fromAPB2Main.ddrcfg_reg(28 downto 27); end if;         v.apbstate := cmdDone;               -- Wait until no more cmd can arrive from AHB ctrl        when wait_lmr1 => v.apbstate := wait_lmr2;       when wait_lmr2 => v.apbstate := cmdlmr;       when cmdlmr =>          -- Check that no new R/W cmd is to be performed         if fromAHB2Main(0).rw_cmd_valid = v.rw_cmd_done(0) and           fromAHB2Main(1).rw_cmd_valid = v.rw_cmd_done(1)  and v.mainstate = idle then           v.ddrcfg.memcmd := "11";           v.ddrcfg.cas := fromAPB2Main.ddrcfg_reg(30 downto 29);           v.ddrcfg.bl := fromAPB2Main.ddrcfg_reg(26 downto 25);           v.apbstate := cmdDone;         end if;                when cmdDone =>         v.lockAHB := "00";         if v.memCmdDone = '1' then           v.ddrcfg.memcmd := "00"; v.apb_cmd_done := '1'; v.apbstate := cmdDone2;         end if;       when cmdDone2 =>               if fromAPB2Main.ddrcfg_reg(28 downto 27) = "00" then             v.apb_cmd_done := '0'; v.apbstate := idle;           end if;     end case;          if v.mainstate = idle  then       v.ddrcfg.refresh    := fromAPB2Main.ddrcfg_reg(31);       v.ddrcfg.autopre    := fromAPB2Main.ddrcfg_reg(24);       v.ddrcfg.r_predict  := fromAPB2Main.ddrcfg_reg(23 downto 22);       v.ddrcfg.w_prot     := fromAPB2Main.ddrcfg_reg(21 downto 20);       v.ddrcfg.ready      := fromAPB2Main.ddrcfg_reg(0);     end if; -------------------------------------------------------------------------------     -- Calcualtes burst length     case v.ddrcfg.bl is       when "00"   => v.burstlength := 2;       when "01"   => v.burstlength := 4;       when "10"   => v.burstlength := 8;       when others => v.burstlength := 8;     end case; -------------------------------------------------------------------------------     -- Calculates row and column address          v.tmpcoladdress := (others => (others => '0'));     v.rowaddress    := (others => (others => '0'));     v.coladdress    := (others => (others => '0'));     v.tmpcolbits := 0; v.colbits := 0; v.rowbits := 0;     -- Based on the size of the chip its organization can be calculated     case chipsize is       when 64     => v.tmpcolbits := 10; v.rowbits := 12; v.refreshTime := DELAY_15600NS; v.maxRefreshTime := DELAY_7_15600NS;  -- 64Mbit       when 128    => v.tmpcolbits := 11; v.rowbits := 12; v.refreshTime := DELAY_15600NS; v.maxRefreshTime := DELAY_7_15600NS;  -- 128Mbit       when 256    => v.tmpcolbits := 11; v.rowbits := 13; v.refreshTime := DELAY_7800NS; v.maxRefreshTime := DELAY_7_7800NS;  -- 256Mbit       when 512    => v.tmpcolbits := 12; v.rowbits := 13; v.refreshTime := DELAY_7800NS; v.maxRefreshTime := DELAY_7_7800NS;  -- 512Mbit       when 1024   => v.tmpcolbits := 12; v.rowbits := 14; v.refreshTime := DELAY_7800NS; v.maxRefreshTime := DELAY_7_7800NS;  -- 1Gbit                        when others => v.tmpcolbits := 10; v.rowbits := 12; v.refreshTime := DELAY_7800NS; v.maxRefreshTime := DELAY_7_7800NS;  -- Others 64Mbit     end case;     case chipbits is       when 4      => v.colbits := v.tmpcolbits;      -- x4 bits       when 8      => v.colbits := (v.tmpcolbits-1);  -- x8 bits       when 16     => v.colbits := (v.tmpcolbits-2);  -- x16 bits       when others => null;     end case;     v.addressrange := v.colbits + v.rowbits;      -- AHB controller 1 --      for i in 0 to ahbadr loop       if (i < v.colbits) then         v.tmpcoladdress(0)(i) := fromAHB(0).asramso.dataout(i); end if;       if (i < (v.addressrange) and i >= v.colbits) then         v.rowaddress(0)(i-v.colbits)  := fromAHB(0).asramso.dataout(i); end if;       if (i < (v.addressrange+2) and i >= v.addressrange) then         v.intbankbits(0)(i - v.addressrange) := fromAHB(0).asramso.dataout(i); end if;     end loop;         -- Inserts bank address and auto precharge bit as A10     v.coladdress(0)(adrbits-1 downto 0)           := v.intbankbits(0) &                                                 v.tmpcoladdress(0)(12 downto 10) &  -- Bit 13 to 11                                                 v.ddrcfg.autopre &  -- Bit 10                                                 v.tmpcoladdress(0)(9 downto 0);  --Bit 9 to 0     v.rowaddress(0)(adrbits-1 downto (adrbits-2)) := v.intbankbits(0);     -- Calculate total numer of useable address bits     if modbanks = 2 then       -- Calculate memory module bank (CS signals)

⌨️ 快捷键说明

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