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

📄 mctrl.vhd

📁 用VHDL语言实现的ARM处理器的标准内核的源代码程序
💻 VHD
📖 第 1 页 / 共 2 页
字号:
------------------------------------------------------------------------------  This file is a part of the LEON VHDL model--  Copyright (C) 1999  European Space Agency (ESA)----  This library is free software; you can redistribute it and/or--  modify it under the terms of the GNU Lesser General Public--  License as published by the Free Software Foundation; either--  version 2 of the License, or (at your option) any later version.----  See the file COPYING.LGPL for the full details of the license.------------------------------------------------------------------------------- Entity: 	mctrl-- File:	mctrl.vhd-- Author:	Jiri Gaisler - ESA/ESTEC-- Description:	External memory controller.------------------------------------------------------------------------------library IEEE;use IEEE.std_logic_1164.all;use IEEE.std_logic_unsigned."+";use IEEE.std_logic_unsigned."-";use IEEE.std_logic_unsigned.conv_integer;use IEEE.std_logic_arith.conv_unsigned;use work.peri_mem_config.all;use work.peri_mem_comp.all;use work.peri_io_comp.all;use work.tech_map.all;use work.macro.all;use work.amba.all;entity mctrl is  port (    rst    : in  std_logic;    clk    : in  std_logic;    memi   : in  memory_in_type;    memo   : out memory_out_type;    ahbsi  : in  ahb_slv_in_type;    ahbso  : out ahb_slv_out_type;    apbi   : in  apb_slv_in_type;    apbo   : out apb_slv_out_type;    pioo   : in  pio_out_type;    wpo    : in  wprot_out_type;    sdo    : out sdram_out_type;    mctrlo : out mctrl_out_type  );end; architecture rtl of mctrl istype areatype is (rom, io, ram);type memcycletype is (idle, berr, bread, bwrite, bread8, bwrite8, bread16, bwrite16);-- memory configuration register 1 typetype mcfg1type is record  romrws           : std_logic_vector(3 downto 0);  romwws           : std_logic_vector(3 downto 0);  romwidth         : std_logic_vector(1 downto 0);  romwrite         : std_logic;  ioen             : std_logic;  iows             : std_logic_vector(3 downto 0);  bexcen           : std_logic;  brdyen           : std_logic;  iowidth          : std_logic_vector(1 downto 0);end record;-- memory configuration register 2 typetype mcfg2type is record  ramrws           : std_logic_vector(1 downto 0);  ramwws           : std_logic_vector(1 downto 0);  ramwidth         : std_logic_vector(1 downto 0);  rambanksz        : std_logic_vector(3 downto 0);  rmw              : std_logic;  brdyen           : std_logic;  srdis            : std_logic;  sdren            : std_logic;end record;-- memory status register type-- local registerstype reg_type is record  address          : std_logic_vector(31 downto 0);  -- memory address  data             : std_logic_vector(31 downto 0);  -- latched memory data  writedata        : std_logic_vector(31 downto 0);  writedata8       : std_logic_vector(15 downto 0);  -- lsb write data buffer  readdata         : std_logic_vector(31 downto 0);  brdyn            : std_logic;  ready            : std_logic;  ready8           : std_logic;  bdrive           : std_logic_vector(3 downto 0);  ws               : std_logic_vector(3 downto 0);  romsn		   : std_logic_vector(1 downto 0);  ramsn		   : std_logic_vector(4 downto 0);  ramoen	   : std_logic_vector(4 downto 0);  size		   : std_logic_vector(1 downto 0);  busw		   : std_logic_vector(1 downto 0);  psel		   : std_logic_vector(1 downto 0);  oen              : std_logic;  iosn		   : std_logic_vector(1 downto 0);  read             : std_logic;  wrn              : std_logic_vector(3 downto 0);  writen           : std_logic;  bstate           : memcycletype;  area  	   : areatype;  mcfg1		   : mcfg1type;  mcfg2		   : mcfg2type;  bexcn            : std_logic;		-- latched external bexcn  echeck           : std_logic;  brmw             : std_logic;  haddr            : std_logic_vector(31 downto 0);  hsel             : std_logic;  srhsel           : std_logic;  hwrite           : std_logic;  hburst           : std_logic_vector(2 downto 0);  htrans           : std_logic_vector(1 downto 0);  hresp 	   : std_logic_vector(1 downto 0);end record;component sdmctrl  port (    rst    : in  std_logic;    clk    : in  std_logic;    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 component; signal r, ri : reg_type;signal wrnout : std_logic_vector(3 downto 0);signal promdata : std_logic_vector(31 downto 0); -- data from boot-promsignal sdmo : sdram_mctrl_out_type;signal sdi  : sdram_in_type;signal sdapbo   :  apb_slv_out_type;begin  ctrl : process(rst, ahbsi, apbi, memi, r, pioo, promdata, wpo, sdmo		)  variable v : reg_type;		-- local variables for registers  variable start : std_logic;  variable dataout : std_logic_vector(31 downto 0); -- data from memory  variable regsd : std_logic_vector(31 downto 0);   -- data from registers  variable memdata : std_logic_vector(31 downto 0);   -- data to memory  variable rws : std_logic_vector(3 downto 0);		-- read waitstates  variable wws : std_logic_vector(3 downto 0);		-- write waitstates  variable wsnew : std_logic_vector(3 downto 0);		-- write waitstates  variable adec : std_logic_vector(1 downto 0);  variable rams : std_logic_vector(4 downto 0);  variable bready, leadin : std_logic;  variable csen : std_logic;			-- Generate chip selects  variable aprot   : std_logic_vector(14 downto 0); --   variable wrn   : std_logic_vector(3 downto 0); --   variable bexc, addrerr : std_logic;  variable ready : std_logic;  variable writedata : std_logic_vector(31 downto 0);  variable bwdata : std_logic_vector(31 downto 0);  variable merrtype  : std_logic_vector(2 downto 0); -- memory error type  variable noerror : std_logic;  variable area  : areatype;  variable bdrive : std_logic_vector(3 downto 0);  variable ramsn : std_logic_vector(4 downto 0);  variable romsn, busw : std_logic_vector(1 downto 0);  variable iosn : std_logic;  variable lock : std_logic;  variable wprothitx : std_logic;  variable brmw : std_logic;  variable bpsel : std_logic;  variable psel : std_logic;  variable bidle: std_logic;  variable haddr   : std_logic_vector(31 downto 0);  variable hsize   : std_logic_vector(1 downto 0);  variable hwrite  : std_logic;  variable hburst  : std_logic_vector(2 downto 0);  variable htrans  : std_logic_vector(1 downto 0);  variable sdhsel, srhsel, hready  : std_logic;  begin-- Variable default settings to avoid latches    v := r; wprothitx := '0'; v.ready8 := '0'; v.iosn(0) := r.iosn(1);    ready := '0'; addrerr := '0'; regsd := (others => '0'); csen := '0';    v.ready := '0'; v.echeck := '0'; bpsel := '0';    merrtype := "---"; bready := '1';    v.data := memi.data; v.bexcn := memi.bexcn; v.brdyn := memi.brdyn;    if (((r.brdyn and r.mcfg1.brdyen) = '1') and (r.area = io)) or       (((r.brdyn and r.mcfg2.brdyen) = '1') and (r.area = ram) and	 (r.ramsn(4) = '0') and CFG_PERIMEM_RAMSEL5)    then      bready := '0';    else bready := '1'; end if;    v.hresp := HRESP_OKAY;    if CFG_PERIMEM_SDRAMEN and (r.hsel = '1') and (ahbsi.hready = '0') then       haddr := r.haddr;  hsize := r.size; hburst := r.hburst;      htrans := r.htrans; hwrite := r.hwrite;    else       haddr := ahbsi.haddr;  hsize := ahbsi.hsize(1 downto 0);       hburst := ahbsi.hburst; htrans := ahbsi.htrans; hwrite := ahbsi.hwrite;    end if;    if CFG_PERIMEM_SDRAMEN then      sdhsel := ahbsi.hsel and r.mcfg2.sdren and ahbsi.haddr(30) and		(ahbsi.haddr(29) or r.mcfg2.srdis);      srhsel := ahbsi.hsel and not sdhsel;    else sdhsel := '0'; srhsel := ahbsi.hsel; end if;-- decode memory area parameters    case haddr(30 downto 28) is    when "000" | "001" => area := rom;    when "010" | "011" => area := io;    when others => area := ram;    end case;    leadin := '0'; rws := "----"; wws := "----"; adec := "--";    busw := (others => '-'); brmw := '0';    case area is    when rom =>       busw := r.mcfg1.romwidth;    when ram =>       adec := genmux(r.mcfg2.rambanksz, haddr(29 downto 14)) &              genmux(r.mcfg2.rambanksz, haddr(28 downto 13));      if sdhsel = '1' then busw := "10";      else        busw := r.mcfg2.ramwidth;        if ((r.mcfg2.rmw and ahbsi.hwrite) = '1') and 	 ((CFG_PERIMEM_BUS16EN and (busw = "01") and (hsize = "00")) or	  ((busw(1) = '1') and (hsize(1) = '0'))        )        then brmw := '1'; end if;	 -- do a read-modify-write cycle      end if;    when io =>      leadin := '1';      busw := r.mcfg1.iowidth;    when others =>    end case;-- decode waitstates, illegal access and cacheability    case r.area is    when rom =>      rws := r.mcfg1.romrws; wws := r.mcfg1.romwws;      if (r.mcfg1.romwrite or r.read) = '0' then addrerr := '1'; end if;    when ram =>      rws := "00" & r.mcfg2.ramrws; wws := "00" & r.mcfg2.ramwws;    when io =>      rws := r.mcfg1.iows; wws := r.mcfg1.iows;      if r.mcfg1.ioen = '0' then addrerr := '1'; end if;    when others => null;    end case;-- generate data buffer enables    bdrive := (others => '1');    case r.busw is    when "00" => if CFG_PERIMEM_BUS8EN then bdrive := "0001"; end if;    when "01" => if CFG_PERIMEM_BUS16EN then bdrive := "0011"; end if;    when others =>    end case;-- generate chip select and output enable    rams := '0' & decode(adec);    if CFG_PERIMEM_RAMSEL5 then       if haddr(29) = '1' then rams := "10000"; end if;    end if;    iosn := '1'; ramsn := (others => '1'); romsn := (others => '1');    psel := '1'; v.psel(1) := r.psel(0);    case area is    when rom =>       if ((CFG_PERIMEM_BOOT = perimem_memory) or ((CFG_PERIMEM_BOOT = perimem_dual) and (pioo.io8lsb(4) = '0'))) then	romsn(0) := haddr(28);       else psel := haddr(28); end if;      romsn(1) := not haddr(28);    when ram => ramsn := not rams;    when io => iosn := '0';     when others => null;    end case;-- generate write strobe    wrn := "0000";    case r.busw is    when "00" =>       if CFG_PERIMEM_BUS8EN then wrn := "1110"; end if;    when "01" =>       if CFG_PERIMEM_BUS16EN then	if (r.size = "00") and (r.brmw = '0') then	  wrn := "11" & (not r.address(0)) & r.address(0);        else wrn := "1100"; end if;      end if;    when "10" | "11" =>      case r.size is      when "00" =>         case r.address(1 downto 0) is        when "00" => wrn := "1110";        when "01" => wrn := "1101";        when "10" => wrn := "1011";        when others => wrn := "0111";        end case;      when "01" =>         wrn := not r.address(1) & not r.address(1) & r.address(1) & r.address(1);      when others => null;      end case;    when others => null;    end case;    if (r.mcfg2.rmw = '1') and (r.area = ram) then wrn := not bdrive; end if;    if (((ahbsi.hready and ahbsi.hsel) = '1') or (((sdmo.aload and r.hsel) = '1') and CFG_PERIMEM_SDRAMEN))    then      v.area := area;      v.address  := haddr; v.psel(0) := psel;      if (busw = "00") and (hwrite = '0') and (area /= io) and CFG_PERIMEM_BUS8EN      then v.address(1 downto 0) := "00"; end if;      if (busw = "01") and (hwrite = '0') and (area /= io) and CFG_PERIMEM_BUS16EN      then v.address(1 downto 0) := "00"; end if;      if (brmw = '1') then 	v.read := '1';       else v.read := not hwrite; end if;      v.busw := busw; v.brmw := brmw;    end if;-- Select read data depending on bus width    if CFG_PERIMEM_BUS8EN and (r.busw = "00") then       memdata := r.readdata(23 downto 0) & r.data(31 downto 24);    elsif CFG_PERIMEM_BUS16EN and (r.busw = "01") then       memdata := r.readdata(15 downto 0) & r.data(31 downto 16);    else       memdata := r.data;    end if;    bwdata := memdata;-- Merge data during byte write    writedata := ahbsi.hwdata;    if ((r.brmw and r.busw(1)) = '1')    then      case r.address(1 downto 0) is      when "00" => 	writedata(15 downto 0) := bwdata(15 downto 0);	if r.size = "00" then 	  writedata(23 downto 16) := bwdata(23 downto 16);	end if;      when "01" => 	writedata(31 downto 24) := bwdata(31 downto 24);	writedata(15 downto 0) := bwdata(15 downto 0);      when "10" => 	writedata(31 downto 16) := bwdata(31 downto 16);	if r.size = "00" then 	  writedata(7 downto 0) := bwdata(7 downto 0);	end if;      when  others => 	writedata(31 downto 8) := bwdata(31 downto 8);      end case;    end if;    if (r.brmw = '1') and (r.busw = "01") and CFG_PERIMEM_BUS16EN then      if (r.address(0) = '0') then         writedata(23 downto 16) :=  r.data(23 downto 16);      else        writedata(31 downto 24) :=  r.data(31 downto 24);      end if;    end if;-- save read data during 8/16 bit reads    if CFG_PERIMEM_BUS8EN and (r.ready8 = '1') and (r.busw = "00") then      v.readdata := v.readdata(23 downto 0) & r.data(31 downto 24);    elsif CFG_PERIMEM_BUS16EN and (r.ready8 = '1') and (r.busw = "01") then      v.readdata := v.readdata(15 downto 0) & r.data(31 downto 16);    end if;-- Ram, rom, IO access FSM    if r.read = '1' then wsnew := rws; else wsnew := wws; end if;    case r.bstate is    when idle =>      v.ws := wsnew;       if r.bdrive(0) = '1' then         if r.busw(1) = '1' then v.writedata := writedata;	else	  v.writedata(31 downto 16) := writedata(31 downto 16);	  v.writedata8 := writedata(15 downto 0);	end if;      end if;      if (r.srhsel = '1') and ((sdmo.busy = '0') or not CFG_PERIMEM_SDRAMEN)      then        if CFG_PERIMEM_WPROTEN then wprothitx := wpo.wprothit; end if;	if (wprothitx or addrerr) = '1' then

⌨️ 快捷键说明

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