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

📄 mctrl.vhd

📁 一个航天航空用的Sparc处理器(配美国欧洲宇航局用的R_tems嵌入式操作系统)的VHDL源代码
💻 VHD
📖 第 1 页 / 共 3 页
字号:
-----------------------------------------------------------------------------
--  This file is a part of the LEON VHDL model
--  Copyright (C) 1999  European Space Agency (ESA)
--
--  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.
--
--  See the file COPYING for the full details of the license.
-----------------------------------------------------------------------------
-- Entity: 	mctrl
-- File:	mctrl.vhd
-- Author:	Jiri Gaisler - ESA/ESTEC
-- Description:	Mememory controller. Implements the following interfaces:
--		* 8- and 32-bits external memory bus
--		* internal 32-bit peripheral bus
--		* instruction and data cache fill buses
--		* optional DMA bus
--		
--		Contains the two memory configuartion registers, cache
--		control register, power-down function, write protection
--		registers, memory status register, EDAC test register.
------------------------------------------------------------------------------
-- Version control:
-- 24-01-1998:	First implemetation
-- 26-09-1999:	Release 1.0
------------------------------------------------------------------------------

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 work.config.all;
use work.iface.all;
use work.sparcv8.all;
use work.macro.all;

entity mctrl is
  port (
    rst    : in  std_logic;
    clk    : in  std_logic;
    mcii   : in  memory_ic_in_type;
    mcio   : out memory_ic_out_type;
    mcdi   : in  memory_dc_in_type;
    mcdo   : out memory_dc_out_type;
    mcmi   : in  memory_dma_in_type;
    mcmo   : out memory_dma_out_type;
    memi   : in  memory_in_type;
    memo   : out memory_out_type;
    pbi    : out pbus_in_type;
    pbo    : in  pbus_out_type;
    peo    : in  peri_out_type;
    syso   : in  sys_out_type;
    mctrli : in  mctrl_in_type;
    mctrlo : out mctrl_out_type
  );
end; 

architecture rtl of mctrl is

type bustype is (idle, bw1, bw2, busy);
type reqtype is (data, inst, dma, refresh);
type areatype is (none, rom, ram, io, regs, pci);
type memcycletype is (idle, ldin, ldout, main, bwrite, bwait, berr);
type regcycletype is (idle, lregs, eregs, rwrite, ewrite);

-- cache control register type

type cctrltype is record
  ib     : std_logic;				-- icache burst enable
  ite    : std_logic_vector(1 downto 0);	-- icache tag error counter
  ide    : std_logic_vector(1 downto 0);	-- icache data error counter
  dte    : std_logic_vector(1 downto 0);	-- dcache tag error counter
  dde    : std_logic_vector(1 downto 0);	-- dcache data error counter
  dfrz   : std_logic;				-- dcache freeze enable
  ifrz   : std_logic;				-- icache freeze enable
  dcs    : std_logic_vector(1 downto 0);	-- dcache state
  ics    : std_logic_vector(1 downto 0);	-- icache state
end record;

-- memory configuration register 1 type

type mcfg1type is record
  romrws           : std_logic_vector(3 downto 0);
  romwws           : std_logic_vector(3 downto 0);
  romwidth         : std_logic_vector(1 downto 0);
  romedac          : std_logic;
  romwrite         : std_logic;
  romleadin        : std_logic;
  romleadout       : std_logic;
  rombanksz        : std_logic_vector(3 downto 0);
  extlatch         : std_logic;
  ioen             : std_logic;
  iows             : std_logic_vector(3 downto 0);
  ioleadin         : std_logic;
  ioleadout        : std_logic;
  iordy            : std_logic;
  iowidth          : std_logic_vector(1 downto 0);
end record;

-- memory configuration register 2 type

type mcfg2type is record
  ramrws           : std_logic_vector(1 downto 0);
  ramwws           : std_logic_vector(1 downto 0);
  ramwidth         : std_logic_vector(1 downto 0);
  ramedac          : std_logic;
  ramleadin        : std_logic;
  ramleadout       : std_logic;
  rambanksz        : std_logic_vector(3 downto 0);
end record;

-- memory status register type

type memstattype is record
  errtype          : std_logic_vector(2 downto 0);
  asi              : std_logic_vector(3 downto 0);
  read             : std_logic;
  newerr           : std_logic;
  mulerr           : std_logic;
  lock             : std_logic;
end record;

-- EDAC control register type

type edacctrltype is record
  wcheckbits       : std_logic_vector(6 downto 0);
  wbypass          : std_logic;
end record;

-- write protection register

type wprottype is record
  addr    : std_logic_vector(14 downto 0);
  mask    : std_logic_vector(14 downto 0);
  enable  : std_logic;
  ablock  : std_logic;
end record;

-- local registers

type reg_type is record
  address          : std_logic_vector(31 downto 0);  -- memory address
  address2 	   : std_logic_vector(31 downto 0);  -- pipelined memory address
  data             : std_logic_vector(31 downto 0);  -- latched memory data
  cb               : std_logic_vector(6 downto 0);   -- latched memory checkbits
  ba               : std_logic_vector(1 downto 0);   -- latched memory checkbits
  writedata        : std_logic_vector(31 downto 0);
  readdata         : std_logic_vector(31 downto 0);
  writecb          : std_logic_vector(6 downto 0);   -- latched memory checkbits
  brdyn            : std_logic;
  ready            : std_logic;
  ready2           : std_logic;
  iready           : std_logic;
  dready           : std_logic;
  mready           : std_logic;
  wren             : 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(3 downto 0);
  ramoen	   : std_logic_vector(3 downto 0);
  asi 		   : std_logic_vector(3 downto 0);
  size		   : std_logic_vector(1 downto 0);
  oen              : std_logic;
  iosn             : std_logic;
  read             : std_logic;
  regen            : std_logic;
  bstate           : memcycletype;
  rstate           : regcycletype;
  area  	   : areatype;
  busstate	   : bustype;
  master 	   : reqtype;
  mcfg1		   : mcfg1type;
  mcfg2		   : mcfg2type;
  cctrl		   : cctrltype;
  edacctrl         : edacctrltype;
  failaddr         : std_logic_vector(31 downto 0);
  memstat          : memstattype;
  bexcn            : std_logic;		-- latched external bexcn
  mexc             : std_logic;
  imexc            : std_logic;
  dmexc            : std_logic;
  mmexc            : std_logic;
  checkedac        : std_logic;
  checkedac2       : std_logic;
  werr             : std_logic;
  cerror           : std_logic;
  ajam             : std_logic;
  ld8              : std_logic;
  pwd              : std_logic;
end record;

type wprotregs is record
  wprot1, wprot2   : wprottype;
end record;

-- memory status error types
constant ERR_CEDAC  : std_logic_vector(2 downto 0) := "000";	-- edac cerr
constant ERR_UEDAC  : std_logic_vector(2 downto 0) := "001";	-- edac merr
constant ERR_ILLA   : std_logic_vector(2 downto 0) := "010";	-- illega addr
constant ERR_ILLC   : std_logic_vector(2 downto 0) := "011";
constant ERR_WP     : std_logic_vector(2 downto 0) := "100";	-- write error
constant ERR_BEXC   : std_logic_vector(2 downto 0) := "101";	-- ext bus exc.

signal r, ri : reg_type;
signal wrn : std_logic_vector(3 downto 0);
signal writen : std_logic;
signal wpr, wpv : wprotregs;

begin

  ctrl : process(rst, mcii, mcdi, mcmi, memi, r, pbo, mctrli, wpr, peo, syso)
  variable v : reg_type;		-- local variables for registers
  variable cbout : std_logic_vector(6 downto 0);	-- EDAC checkbits
  variable start,  burst : std_logic;
  variable startregs, startmem, mem16 : 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(3 downto 0);
  variable romsn : std_logic;
  variable ready, leadin, leadout : std_logic;
  variable csen : std_logic;			-- Generate chip selects
  variable edacdatain  : std_logic_vector(31 downto 0);
  variable failaddr  : std_logic_vector(31 downto 0);
  variable edaccbin  : std_logic_vector(6 downto 0);
  variable edata  : edaccorrtype;
  variable merrtype  : std_logic_vector(2 downto 0); -- memory error type
  variable cerror, merror : std_logic;
  variable imerror, dmerror, mmerror : std_logic;	-- EDAC error
  variable busw   : std_logic_vector(1 downto 0); -- bus width
  variable banksz   : std_logic_vector(3 downto 0); -- bank size
  variable chkaddr : std_logic_vector(31 downto 0); -- 
  variable bwidth  : std_logic_vector(1 downto 0); -- 
  variable bdrive : std_logic;
  variable aprot   : std_logic_vector(14 downto 0); -- 
  variable wprothit, wprothit1, wprothit2 : std_logic;
  variable wprot1, wprot2   : wprottype;
  variable bexc : std_logic;
  begin

-- Variable default settings to avoid latches

    v := r;

    startmem := '0'; mem16 := '0';
    startregs := '0'; start := '0'; 
    regsd := (others => '0'); csen := '0';
    merrtype := "---"; 
    merror := '0'; imerror := '0'; dmerror := '0'; mmerror := '0';
    ready := '1'; busw := "11"; bdrive := '0';
    edacdatain := (others => '-'); edaccbin := (others => '-');

    v.regen := '0'; v.area := none; v.cerror := '0';
    v.ready := '0'; v.iready := '0'; v.dready := '0'; v.mready := '0';
    v.wren := '0';  v.mexc := '0'; v.checkedac := '0'; v.checkedac2 := '0';
    v.werr := '0'; v.ld8 := '0'; v.bdrive := (others => '0');

    v.cb := memi.checkbits; v.data := memi.data; v.bexcn := memi.bexcn;
    v.ready2 := r.ready; v.brdyn := memi.brdyn;

-- cache error counters

    if mcii.tparerr = '1' then
      if v.cctrl.ite /= "11" then v.cctrl.ite := v.cctrl.ite + 1; end if;
    end if;

    if mcii.dparerr = '1' then
      if v.cctrl.ide /= "11" then v.cctrl.ide := v.cctrl.ide + 1; end if;
    end if;

    if mcdi.tparerr = '1' then
      if v.cctrl.dte /= "11" then v.cctrl.dte := v.cctrl.dte + 1; end if;
    end if;

    if mcdi.dparerr = '1' then
      if v.cctrl.dde /= "11" then v.cctrl.dde := v.cctrl.dde + 1; end if;
    end if;

-- decode current bus width

    case r.area is
    when rom => 
      if r.read  = '1' then
        busw := r.mcfg1.romwidth;
      else
	busw := "11";
      end if;
    when ram => 
      busw := r.mcfg2.ramwidth;
    when others => null;
    end case;

-- EDAC handling

    if (((r.area = rom) and (r.mcfg1.romedac = '1')) or
       ((r.area = ram) and (r.mcfg2.ramedac = '1')))
    then
      v.checkedac := '1';
      v.checkedac2 := r.read and r.ready;
    end if;

    cbout := (others => '0');
    if MEMEDAC then	-- EDAC enabled
      if FASTEDAC then	-- fast EDAC (separate read/write encoding)
        case busw is
        when "00" =>
          edacdatain := r.readdata;
          edaccbin := r.data(30 downto 24);
        when others =>
          edacdatain := r.data;
          edaccbin := r.cb;
        end case;
        cbout := chkbitgen(r.writedata);
        edata := edaccorr(edacdatain, chkbitgen(edacdatain), edaccbin);
      else	-- slow EDAC (shared read/write encoding)
        if r.read = '1' then
          case busw is
          when "00" =>
            edacdatain := r.readdata;
            edaccbin := r.data(30 downto 24);
          when others =>
            edacdatain := r.data;
            edaccbin := r.cb;
          end case;
        else
          edacdatain := r.writedata;
          edaccbin := (others => '-');
        end if;
        cbout := chkbitgen(edacdatain);
        edata := edaccorr(edacdatain, cbout, edaccbin);
      end if;
      if r.edacctrl.wbypass = '1' then
        cbout :=  r.edacctrl.wcheckbits;
      end if;
    else		-- EDAC disabled
      edata.error := '0'; edata.merror := '0';
      edata.cb := (others => '0'); cbout := (others => '0');
      case busw is
      when "00" => edata.data := r.readdata;
      when others => edata.data := r.data;
      end case;
    end if;


-- select burst access depending on request source

    case r.master is
    when data => burst := mcdi.burst; 
    when inst => burst := mcii.burst;
    when dma => burst := mcmi.burst and DMAEN;

⌨️ 快捷键说明

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