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

📄 ddrsp64a.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: 	ddrsp64a-- File:	ddrsp64a.vhd-- Author:	Jiri Gaisler - Gaisler Research-- Description:	64-bit DDR266 memory controller with asych AHB 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;entity ddrsp64a is  generic (    memtech : integer := 0;    hindex  : integer := 0;    haddr   : integer := 0;    hmask   : integer := 16#f00#;    ioaddr  : integer := 16#000#;    iomask  : integer := 16#fff#;    MHz     : integer := 100;    col     : integer := 9;     Mbyte   : integer := 8;     fast    : integer := 0;     pwron   : integer := 0;    oepol   : integer := 0  );  port (    rst     : in  std_ulogic;    clk_ddr : in  std_ulogic;    clk_ahb : in  std_ulogic;    ahbsi   : in  ahb_slv_in_type;    ahbso   : out ahb_slv_out_type;    sdi     : in  sdctrl_in_type;    sdo     : out sdctrl_out_type  );end; architecture rtl of ddrsp64a isconstant REVISION  : integer := 0;constant CMD_PRE  : std_logic_vector(2 downto 0) := "010";constant CMD_REF  : std_logic_vector(2 downto 0) := "100";constant CMD_LMR  : std_logic_vector(2 downto 0) := "110";constant CMD_EMR  : std_logic_vector(2 downto 0) := "111";constant abuf : integer := 6;constant hconfig : ahb_config_type := (  0 => ahb_device_reg ( VENDOR_GAISLER, GAISLER_DDRSP, 0, REVISION, 0),  4 => ahb_membar(haddr, '1', '1', hmask),  5 => ahb_iobar(ioaddr, iomask),  others => zero32);type mcycletype is (midle, active, ext, leadout);type ahb_state_type is (midle, rhold, dread, dwrite, whold1, whold2);type sdcycletype is (act1, act2, act3, rd1, rd2, rd3, rd4, rd5, rd6, rd7, rd8,		     wr1, wr2, wr3, wr4a, wr4, wr5, sidle, ioreg1, ioreg2);type icycletype is (iidle, pre, ref1, ref2, emode, lmode, finish);-- sdram configuration registertype sdram_cfg_type is record  command          : std_logic_vector(2 downto 0);  csize            : std_logic_vector(1 downto 0);  bsize            : std_logic_vector(2 downto 0);  trcd             : std_ulogic;  -- tCD : 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(11 downto 0);  renable          : std_ulogic;  dllrst	   : std_ulogic;  refon            : std_ulogic;  cke              : std_ulogic;end record;type access_param is record  haddr         : std_logic_vector(31 downto 0);  size		: std_logic_vector(1 downto 0);  hwrite        : std_ulogic;  hio           : std_ulogic;end record;-- local registerstype ahb_reg_type is record  hready        : std_ulogic;  hsel          : std_ulogic;  hio           : std_ulogic;  startsd       : std_ulogic;  ready         : std_ulogic;  ready2        : std_ulogic;  write         : std_logic_vector(3 downto 0);  state         : ahb_state_type;  haddr         : std_logic_vector(31 downto 0);  hrdata        : std_logic_vector(31 downto 0);  hwdata        : std_logic_vector(31 downto 0);  hwrite        : std_ulogic;  htrans        : std_logic_vector(1 downto 0);  hresp 	: std_logic_vector(1 downto 0);  raddr         : std_logic_vector(abuf-1 downto 0);  size		: std_logic_vector(1 downto 0);  acc		: access_param;end record;type ddr_reg_type is record  startsd       : std_ulogic;  startsdold    : std_ulogic;  burst         : std_ulogic;  hready        : std_ulogic;  bdrive        : std_ulogic;  qdrive        : std_ulogic;  nbdrive       : std_ulogic;   mstate	: mcycletype;  sdstate	: sdcycletype;  cmstate	: mcycletype;  istate	: icycletype;  trfc          : std_logic_vector(2 downto 0);  refresh       : std_logic_vector(11 downto 0);  sdcsn  	: std_logic_vector(1  downto 0);  sdwen  	: std_ulogic;  rasn 		: std_ulogic;  casn 		: std_ulogic;  dqm  		: std_logic_vector(15 downto 0);  address  	: std_logic_vector(15 downto 2);  -- memory address  ba     	: std_logic_vector( 1 downto 0);  waddr         : std_logic_vector(abuf-1 downto 0);  cfg           : sdram_cfg_type;  hrdata        : std_logic_vector(127 downto 0);end record;signal vcc : std_ulogic;signal r, ri : ddr_reg_type;signal ra, rai : ahb_reg_type;signal rbdrive, ribdrive : std_logic_vector(31 downto 0);signal rdata, wdata : std_logic_vector(127 downto 0);attribute syn_preserve : boolean;attribute syn_preserve of rbdrive : signal is true; begin  vcc <= '1';  ahb_ctrl : process(rst, ahbsi, r, ra, rdata)  variable v       : ahb_reg_type;		-- local variables for registers  variable startsd : std_ulogic;  variable dout    : std_logic_vector(31 downto 0);  begin    v := ra; v.hresp := HRESP_OKAY; v.write := "0000";    case ra.raddr(1 downto 0) is    when "00" => v.hrdata := rdata(127 downto 96);    when "01" => v.hrdata := rdata(95 downto 64);    when "10" => v.hrdata := rdata(63 downto 32);    when others => v.hrdata := rdata(31 downto 0);    end case;    v.ready := not (ra.startsd xor r.startsdold);    v.ready2 := ra.ready;    if ((ahbsi.hready and ahbsi.hsel(hindex)) = '1') then      v.htrans := ahbsi.htrans; v.haddr := ahbsi.haddr;      v.size := ahbsi.hsize(1 downto 0); v.hwrite := ahbsi.hwrite;      if ahbsi.htrans(1) = '1' then        v.hio := ahbsi.hmbsel(1);	v.hsel := '1'; v.hready := '0';      end if;    end if;    if ahbsi.hready = '1' then v.hsel := ahbsi.hsel(hindex); end if;--    if (ra.hsel and ra.hio and not ra.hready) = '1' then v.hready := '1'; end if;    case ra.state is    when midle =>      if ((v.hsel and v.htrans(1)) = '1') then	if v.hwrite = '0' then 	  v.state := rhold; v.startsd := not ra.startsd;	else 	  v.state := dwrite; v.hready := '1'; --	  v.write(0) := not v.haddr(2); v.write(1) := v.haddr(2);	  v.write := decode(v.haddr(3 downto 2));	end if;      end if;      v.raddr := ra.haddr(7 downto 2);      v.ready := '0'; v.ready2 := '0';--      if not ((ra.hsel and ra.htrans(1) and not ra.htrans(0)) = '1') then       if ahbsi.hready = '1' then	v.acc := (v.haddr, v.size, v.hwrite, v.hio);      end if;    when rhold =>      v.raddr := ra.haddr(7 downto 2);      if ra.ready2 = '1' then	v.state := dread; v.hready := '1'; v.raddr := ra.raddr + 1;      end if;    when dread =>      v.raddr := ra.raddr + 1; v.hready := '1';      if ((v.hsel and v.htrans(1) and v.htrans(0)) = '0') or 	(ra.raddr(2 downto 0) = "000")      then v.state := midle; v.hready := '0'; end if;      v.acc := (v.haddr, v.size, v.hwrite, v.hio);    when dwrite =>       v.raddr := ra.haddr(7 downto 2); v.hready := '1';--      v.write(0) := not v.haddr(2); v.write(1) := v.haddr(2);      v.write := decode(v.haddr(3 downto 2));      if ((v.hsel and v.htrans(1) and v.htrans(0)) = '0') or         (ra.haddr(4 downto 2) = "111")      then	v.startsd := not ra.startsd; v.state := whold1;         v.write := "0000"; v.hready := '0';      end if;    when whold1 =>	v.state := whold2; v.ready := '0';    when whold2 =>      if ra.ready = '1' then	v.state := midle; v.acc := (v.haddr, v.size, v.hwrite, v.hio);      end if;    end case;    v.hwdata := ahbsi.hwdata;     if (ahbsi.hready and ahbsi.hsel(hindex) ) = '1' then      if ahbsi.htrans(1) = '0' then v.hready := '1'; end if;    end if;    dout := ra.hrdata(31 downto 0);    if rst = '0' then      v.hsel	      := '0';      v.hready	      := '1';      v.state	      := midle;      v.startsd       := '0';      v.hio           := '0';    end if;    rai <= v;    ahbso.hready  <= ra.hready;    ahbso.hresp   <= ra.hresp;    ahbso.hrdata  <= dout;    ahbso.hcache  <= not ra.hio;  end process;  ddr_ctrl : process(rst, r, ra, sdi, rbdrive, wdata)  variable v       : ddr_reg_type;		-- local variables for registers  variable startsd : std_ulogic;  variable dqm     : std_logic_vector(15 downto 0);  variable raddr   : std_logic_vector(13 downto 0);  variable adec    : std_ulogic;  variable rams    : std_logic_vector(1 downto 0);  variable ba      : std_logic_vector(1 downto 0);  variable haddr   : std_logic_vector(31 downto 0);  variable hsize   : std_logic_vector(1 downto 0);  variable hwrite  : std_ulogic;  variable htrans  : std_logic_vector(1 downto 0);  variable hready  : std_ulogic;  variable vbdrive : std_logic_vector(31 downto 0);  variable bdrive  : std_ulogic;   variable writecfg: std_ulogic;   variable regsd1   : std_logic_vector(31 downto 0);   -- data from registers  variable regsd2   : std_logic_vector(31 downto 0);   -- data from registers  begin-- Variable default settings to avoid latches    v := r; v.hready := '0'; writecfg := '0'; vbdrive := rbdrive;     v.hrdata := sdi.data; v.qdrive :='0';    regsd1 := (others => '0');    regsd1(31 downto 15) := r.cfg.refon & r.cfg.trp & r.cfg.trfc &	 r.cfg.trcd & r.cfg.bsize & r.cfg.csize & r.cfg.command &	 r.cfg.dllrst & r.cfg.renable & r.cfg.cke;     regsd1(11 downto 0) := r.cfg.refresh;     regsd2 := (others => '0');    regsd2(8 downto 0) := conv_std_logic_vector(MHz, 9);    regsd2(14 downto 12) := conv_std_logic_vector(3, 3);-- generate DQM from address and write size    case ra.acc.size is    when "00" =>      case ra.acc.haddr(3 downto 0) is      when "0000" => dqm := "0111111111111111";      when "0001" => dqm := "1011111111111111";      when "0010" => dqm := "1101111111111111";      when "0011" => dqm := "1110111111111111";      when "0100" => dqm := "1111011111111111";      when "0101" => dqm := "1111101111111111";      when "0110" => dqm := "1111110111111111";      when "0111" => dqm := "1111111011111111";      when "1000" => dqm := "1111111101111111";      when "1001" => dqm := "1111111110111111";      when "1010" => dqm := "1111111111011111";      when "1011" => dqm := "1111111111101111";      when "1100" => dqm := "1111111111110111";      when "1101" => dqm := "1111111111111011";      when "1110" => dqm := "1111111111111101";      when others => dqm := "1111111111111110";      end case;    when "01" =>      case ra.acc.haddr(3 downto 1) is      when "000"  => dqm := "0011111111111111";      when "001"  => dqm := "1100111111111111";      when "010"  => dqm := "1111001111111111";      when "011"  => dqm := "1111110011111111";      when "100"  => dqm := "1111111100111111";      when "101"  => dqm := "1111111111001111";      when "110"  => dqm := "1111111111110011";      when others => dqm := "1111111111111100";      end case;    when others =>       dqm := "0000000000000000";    end case;    v.startsd := ra.startsd;-- main FSM    case r.mstate is    when midle =>      if  r.startsd = '1' then	if (r.sdstate = sidle) and (r.cfg.command = "000") and 	   (r.cmstate = midle)         then 	  startsd := '1'; v.mstate := active;	end if;      end if;    when others => null;    end case;          startsd := r.startsd xor r.startsdold;-- generate row and column address size    haddr := ra.acc.haddr;    haddr(31 downto 20) := haddr(31 downto 20) and not conv_std_logic_vector(hmask, 12);    case r.cfg.csize is    when "00" => raddr := haddr(25 downto 12);    when "01" => raddr := haddr(26 downto 13);    when "10" => raddr := haddr(27 downto 14);    when others => raddr := haddr(28 downto 15);    end case;-- generate bank address    ba := genmux(r.cfg.bsize, haddr(29 downto 22)) &          genmux(r.cfg.bsize, haddr(28 downto 21));-- generate chip select    adec := genmux(r.cfg.bsize, haddr(30 downto 23));    rams := adec & not adec;-- sdram access FSM    if r.trfc /= "000" then v.trfc := r.trfc - 1; end if;

⌨️ 快捷键说明

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