📄 icache.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: icache
-- File: icache.vhd
-- Author: Jiri Gaisler - ESA/ESTEC
-- Description: This unit implements the instruction cache controller.
------------------------------------------------------------------------------
-- Version control:
-- 17-05-1998: : First implemetation
-- 14-12-1998: : Switched to synchronous ram
-- 01-05-1999: : Simplified the control FSM from 20 to 3 states
-- 26-09-1999: : Release 1.0
------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned."+";
use work.config.all;
use work.sparcv8.all; -- ASI declarations
use work.iface.all;
use work.macro.all; -- xorv()
entity icache is
port (
Clk : in std_logic;
Rst : in std_logic;
ici : in icache_in_type;
ico : out icache_out_type;
dci : in dcache_in_type;
dco : in dcache_out_type;
mcii : out memory_ic_in_type;
mcio : in memory_ic_out_type;
icrami : out icram_in_type;
icramo : in icram_out_type
);
end;
architecture rtl of icache is
constant TAG_HIGH : integer := ITAG_HIGH;
constant TAG_LOW : integer := IOFFSET_BITS + ILINE_BITS + 2;
constant OFFSET_HIGH: integer := TAG_LOW - 1;
constant OFFSET_LOW : integer := ILINE_BITS + 2;
constant LINE_HIGH : integer := OFFSET_LOW - 1;
constant LINE_LOW : integer := 2;
constant lline : std_logic_vector((ILINE_BITS -1) downto 0) := (others=>'1');
type rdatatype is (itag, idata, memory); -- sources during cache read
type icache_control_type is record -- all registers
req, burst, mds, holdn : std_logic;
overrun : std_logic; --
underrun : std_logic; --
istate : integer range 0 to 2; -- FSM vector
write : std_logic; -- icache I/F strobes
branch : std_logic;
xaddress : std_logic_vector(31 downto LINE_LOW); -- common address buffer
waddress : std_logic_vector(31 downto LINE_LOW);-- write address buffer
hit, cachable : std_logic;
su : std_logic;
tparerr : std_logic; -- tag parity error
dparerr : std_logic; -- data parity error
flush : std_logic; -- flush in progress
flush2 : std_logic; -- flush in progress
faddr : std_logic_vector(IOFFSET_BITS - 1 downto 0); -- flush address
tapar : std_logic; -- tag addr parity
dapar : std_logic; -- data addr parity
end record;
signal r, c : icache_control_type; -- r is registers, c is combinational
begin
ictrl : process(rst, r, mcio, ici, dci, dco, icramo)
variable rdatasel : rdatatype;
variable faddress : std_logic_vector(31 downto 2);
variable twrite, diagen, dwrite : std_logic;
variable taddr : std_logic_vector(TAG_HIGH downto LINE_LOW); -- tag address
variable wtag : std_logic_vector(TAG_HIGH downto TAG_LOW); -- write tag value
variable ddatain : std_logic_vector((IDWORD_BITS -1) downto 0);
variable rdata : std_logic_vector((IDWORD_BITS -1) downto 0);
variable diagdata : std_logic_vector((IDWORD_BITS -1) downto 0);
variable vmaskraw, vmask : std_logic_vector((ILINE_SIZE -1) downto 0);
variable xaddr_inc : std_logic_vector((ILINE_BITS -1) downto 0);
variable xlastline, lastline, nlastline, nnlastline : std_logic;
variable enable : std_logic;
variable error : std_logic;
variable wcachable, whit, cachable, hit, valid, dvalid : std_logic;
variable tparerr : std_logic;
variable tparin : std_logic;
variable dparerr : std_logic;
variable cacheon : std_logic;
variable dparin : std_logic;
variable diagrdy : std_logic;
variable v : icache_control_type;
begin
-- init local variables
v := r;
v.mds := '1'; dwrite := '0'; twrite := '0'; diagen := '0';
error := '0'; v.tparerr := '0'; v.dparerr := '0';
v.write := mcio.ready; diagrdy := '0'; v.holdn := '1';
cacheon := mcio.ics(0) and not r.flush;
enable := '1';
rdatasel := idata; -- read data from cache as default
ddatain := mcio.data; -- load full word from memory
wtag := r.waddress(TAG_HIGH downto TAG_LOW);
-- generate access parameters during pipeline stall
if ((r.overrun and r.mds) or not (r.overrun or dco.hold)) = '1' then
taddr := ici.fpc(TAG_HIGH downto LINE_LOW);
else
taddr := ici.rpc(TAG_HIGH downto LINE_LOW);
end if;
if r.overrun = '1' then
faddress := r.xaddress;
else
faddress := ici.fpc(31 downto 2);
end if;
-- parity checking (1)
if ITAGPAR then
tparerr := xorv(r.tapar & icramo.itramout.tag &
icramo.itramout.valid & icramo.itramout.parity);
else
tparerr := '0';
end if;
if IDATPAR then
dparerr := xorv(r.dapar & icramo.idramout.data & icramo.idramout.parity);
else
dparerr := '0';
end if;
-- generate cache hit and valid bits
if (faddress(31) = '0') and (faddress(30 downto 29) /= "01") then
cachable := not r.flush;
else
cachable := '0';
end if;
if (icramo.itramout.tag = faddress(TAG_HIGH downto TAG_LOW)) then
hit := cachable and not tparerr;
else
hit := '0';
end if;
xlastline := '0';
lastline := '0';
if r.xaddress(LINE_HIGH downto LINE_LOW) = lline then
xlastline := '1';
end if;
if ici.fpc(LINE_HIGH downto LINE_LOW) = lline then
lastline := '1';
end if;
-- lastline := '0';
-- if (r.overrun and r.mds) = '1' then
-- if r.xaddress(LINE_HIGH downto LINE_LOW) = lline then
-- lastline := '1';
-- end if;
-- else
-- if ici.fpc(LINE_HIGH downto LINE_LOW) = lline then
-- lastline := '1';
-- end if;
-- end if;
-- if faddress(LINE_HIGH downto LINE_LOW) = lline then
-- lastline := '1';
-- else
-- lastline := '0';
-- end if;
if r.waddress(LINE_HIGH downto LINE_LOW+1) = lline((ILINE_BITS -1) downto 1) then
nlastline := '1';
else
nlastline := '0';
end if;
-- pragma translate_off
if not is_x(faddress(LINE_HIGH downto LINE_LOW)) then
-- pragma translate_on
valid := genmux(faddress(LINE_HIGH downto LINE_LOW), icramo.itramout.valid);
-- pragma translate_off
end if;
-- pragma translate_on
dvalid := valid and not dparerr;
if (r.holdn and dco.hold and not ici.nullify) = '1' then
v.hit := hit; v.cachable := cachable; v.xaddress := ici.fpc(31 downto 2);
v.su := ici.su;
end if;
-- pragma translate_off
if not is_x(r.waddress) then
-- pragma translate_on
xaddr_inc := r.waddress(LINE_HIGH downto LINE_LOW) + 1;
-- pragma translate_off
end if;
-- pragma translate_on
if xaddr_inc((ILINE_BITS -1) downto 1) = lline((ILINE_BITS -1) downto 1) then
nnlastline := '1';
else
nnlastline := '0';
end if;
if r.write = '1' then
v.waddress(LINE_HIGH downto LINE_LOW) := xaddr_inc;
end if;
-- main Icache state machine
case r.istate is
when 0 => -- main state and cache hit
if (r.write and not r.mds) = '1' then rdatasel := memory; end if;
v.overrun := (r.overrun or
((not ici.nullify) and dco.hold and not (cacheon and hit and dvalid))) and
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -