📄 mctrl.vhd
字号:
-----------------------------------------------------------------------------
-- 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 + -