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

📄 sdmctrl.vhd

📁 free hardware ip core about sparcv8,a soc cpu in vhdl
💻 VHD
📖 第 1 页 / 共 2 页
字号:
--------------------------------------------------------------------------------  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: 	sdmctrl-- File:	sdmctrl.vhd-- Author:	Jiri Gaisler - Gaisler Research-- Description:	SDRAM memory controller to fit with LEON2 memory controller.------------------------------------------------------------------------------library ieee;use ieee.std_logic_1164.all;library grlib;use grlib.amba.all;use grlib.stdlib.all;library gaisler;use gaisler.memctrl.all;entity sdmctrl is  generic (    pindex  : integer := 0;    invclk  : integer := 0;    fast    : integer := 0;    wprot   : integer := 0;    sdbits  : integer := 32;    pageburst : integer := 0  );  port (    rst    : in  std_ulogic;    clk    : in  std_ulogic;    sdi    : in  sdram_in_type;    sdo    : out sdram_out_type;    apbi   : in  apb_slv_in_type;    apbo   : out apb_slv_out_type;    wpo    : in  wprot_out_type;    sdmo   : out sdram_mctrl_out_type  );end; architecture rtl of sdmctrl isconstant WPROTEN  : boolean := (wprot /= 0);constant SDINVCLK : boolean := (invclk /= 0);constant BUS64    : boolean := (sdbits = 64);type mcycletype is (midle, active, leadout);type sdcycletype is (act1, act2, act3, rd1, rd2, rd3, rd4, rd5, rd6, rd7, rd8,		     wr1, wr2, wr3, wr4, wr5, sidle);type icycletype is (iidle, pre, ref, lmode, finish);-- sdram configuration registertype sdram_cfg_type is record  command          : std_logic_vector(1 downto 0);  csize            : std_logic_vector(1 downto 0);  bsize            : std_logic_vector(2 downto 0);  casdel           : std_ulogic;  -- CAS to data delay: 2/3 clock cycles  trfc             : std_logic_vector(2 downto 0);  trp              : std_ulogic;  -- precharge to activate: 2/3 clock cycles  refresh          : std_logic_vector(14 downto 0);  renable          : std_ulogic;  pageburst        : std_ulogic;end record;-- local registerstype reg_type is record  hready        : std_ulogic;  hsel          : std_ulogic;  bdrive        : std_ulogic;  burst         : std_ulogic;  busy          : std_ulogic;  bdelay        : std_ulogic;  wprothit      : std_ulogic;  startsd       : std_ulogic;  aload         : std_ulogic;  mstate	: mcycletype;  sdstate	: sdcycletype;  cmstate	: mcycletype;  istate	: icycletype;  icnt          : std_logic_vector(2 downto 0);  cfg           : sdram_cfg_type;  trfc          : std_logic_vector(2 downto 0);  refresh       : std_logic_vector(14 downto 0);  sdcsn  	: std_logic_vector(1  downto 0);  sdwen  	: std_ulogic;  rasn 		: std_ulogic;  casn 		: std_ulogic;  dqm  		: std_logic_vector(7 downto 0);  bsel 		: std_ulogic;  -- only needed to keep address lines from switch too much  address  	: std_logic_vector(16 downto 2);  -- memory addressend record;signal r, ri : reg_type;begin  ctrl : process(rst, apbi, sdi, wpo, r)  variable v : reg_type;		-- local variables for registers  variable startsd : std_ulogic;  variable dataout : std_logic_vector(31 downto 0); -- data from memory  variable haddr   : std_logic_vector(31 downto 0);  variable regsd : std_logic_vector(31 downto 0);   -- data from registers  variable dqm      : std_logic_vector(7 downto 0);  variable raddr    : std_logic_vector(12 downto 0);  variable adec     : std_ulogic;  variable busy     : std_ulogic;  variable aload    : std_ulogic;  variable rams     : std_logic_vector(1 downto 0);  variable hresp    : std_logic_vector(1 downto 0);  variable ba       : std_logic_vector(1 downto 0);  variable lline    : std_logic_vector(2 downto 0);  variable rline    : std_logic_vector(2 downto 0);  variable lineburst : boolean;  begin-- Variable default settings to avoid latches    v := r; startsd := '0'; v.busy := '0'; hresp := HRESP_OKAY;    lline := not r.cfg.casdel &  r.cfg.casdel &  r.cfg.casdel;    rline := not r.cfg.casdel &  r.cfg.casdel &  r.cfg.casdel;    if sdi.hready = '1' then v.hsel := sdi.hsel; end if;    if (sdi.hready and sdi.hsel ) = '1' then      if sdi.htrans(1) = '1' then v.hready := '0'; end if;    end if;    if fast = 1 then haddr := sdi.rhaddr; else haddr := sdi.haddr; end if;    if (pageburst = 0) or ((pageburst = 2) and r.cfg.pageburst = '0') then      lineburst := true;    else lineburst := false; end if;-- main state    case sdi.hsize is    when "00" =>      case sdi.rhaddr(1 downto 0) is      when "00" => dqm := "11110111";      when "01" => dqm := "11111011";      when "10" => dqm := "11111101";      when others => dqm := "11111110";      end case;    when "01" =>      if sdi.rhaddr(1) = '0' then dqm := "11110011"; else  dqm := "11111100"; end if;    when others => dqm := "11110000";    end case;    if BUS64 and (r.bsel = '1') then      dqm := dqm(3 downto 0) & "1111";    end if;-- main FSM    case r.mstate is    when midle =>      if (v.hsel and sdi.nhtrans(1)) = '1' then	if (r.sdstate = sidle) and (r.cfg.command = "00") and 	   (r.cmstate = midle) and (sdi.idle = '1')        then 	  if fast = 1 then v.startsd := '1'; else startsd := '1'; end if;	  v.mstate := active;	end if;      end if;    when others => null;    end case;          startsd := r.startsd or startsd;-- generate row and column address size    case r.cfg.csize is    when "00" => raddr := haddr(22 downto 10);     when "01" => raddr := haddr(23 downto 11);    when "10" => raddr := haddr(24 downto 12);    when others =>       if r.cfg.bsize = "111" then raddr := haddr(26 downto 14);      else raddr := haddr(25 downto 13); end if;    end case;-- generate bank address    ba := genmux(r.cfg.bsize, haddr(28 downto 21)) &          genmux(r.cfg.bsize, haddr(27 downto 20));-- generate chip select    if BUS64 then      adec := genmux(r.cfg.bsize, haddr(30 downto 23));      v.bsel := genmux(r.cfg.bsize, sdi.rhaddr(29 downto 22));    else      adec := genmux(r.cfg.bsize, haddr(29 downto 22)); v.bsel := '0';    end if;    if (sdi.srdis = '0') and (r.cfg.bsize = "111") then adec := not adec; end if;    rams := adec & not adec;    if r.trfc /= "000" then v.trfc := r.trfc - 1; end if;-- sdram access FSM    case r.sdstate is    when sidle =>      v.bdelay := '0';      if (startsd = '1') and (r.cfg.command = "00") and (r.cmstate = midle) then        v.address(16 downto 2) := ba & raddr;	v.sdcsn := not rams(1 downto 0); v.rasn := '0'; v.sdstate := act1; 	v.startsd := '0';      end if;    when act1 =>	v.rasn := '1'; v.trfc := r.cfg.trfc;	if r.cfg.casdel = '1' then v.sdstate := act2; else	  v.sdstate := act3;          v.hready := sdi.hwrite and sdi.htrans(0) and sdi.htrans(1);	end if;        if WPROTEN then 	  v.wprothit := wpo.wprothit;	  if wpo.wprothit = '1' then hresp := HRESP_ERROR; end if;	end if;    when act2 =>	v.sdstate := act3;         v.hready := sdi.hwrite and sdi.htrans(0) and sdi.htrans(1);        if WPROTEN and (r.wprothit = '1') then 	  hresp := HRESP_ERROR; v.hready := '0'; 	end if;    when act3 =>      v.casn := '0';       v.address(14 downto 2) := sdi.rhaddr(13 downto 12) & '0' & sdi.rhaddr(11 downto 2);      v.dqm := dqm; v.burst := r.hready;      if sdi.hwrite = '1' then	v.sdstate := wr1; v.sdwen := '0'; v.bdrive := '1';        if sdi.htrans = "11" or (r.hready = '0') then v.hready := '1'; end if;        if WPROTEN and (r.wprothit = '1') then	  hresp := HRESP_ERROR; v.hready := '1'; 	  v.sdstate := wr1; v.sdwen := '1'; v.bdrive := '0'; v.casn := '1';	end if;      else v.sdstate := rd1; end if;    when wr1 =>      v.address(14 downto 2) := sdi.rhaddr(13 downto 12) & '0' & sdi.rhaddr(11 downto 2);      if (((r.burst and r.hready) = '1') and (sdi.rhtrans = "11"))      and not (WPROTEN and (r.wprothit = '1'))      then 	v.hready := sdi.htrans(0) and sdi.htrans(1) and r.hready;	if ((sdi.rhaddr(5 downto 2) = "1111") and (r.cfg.command = "10")) then -- exit on refresh	  v.hready := '0';	end if;      else        v.sdstate := wr2; v.bdrive := '0'; v.casn := '1'; v.sdwen := '1';	v.dqm := (others => '1');      end if;    when wr2 =>      if (r.trfc(2 downto 1) = "00") then        if (r.cfg.trp = '0') then v.rasn := '0'; v.sdwen := '0'; end if;        v.sdstate := wr3;      end if;    when wr3 =>      if (r.cfg.trp = '1') then 	v.rasn := '0'; v.sdwen := '0'; v.sdstate := wr4;      else         v.sdcsn := "11"; v.rasn := '1'; v.sdwen := '1';        if r.trfc = "000" then v.sdstate := sidle; end if;      end if;    when wr4 =>      v.sdcsn := "11"; v.rasn := '1'; v.sdwen := '1';       if (r.cfg.trp = '1') then v.sdstate := wr5;      else 	if r.trfc = "000" then v.sdstate := sidle; end if;      end if;    when wr5 =>

⌨️ 快捷键说明

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