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

📄 icache.vhd

📁 一个航天航空用的Sparc处理器(配美国欧洲宇航局用的R_tems嵌入式操作系统)的VHDL源代码
💻 VHD
📖 第 1 页 / 共 2 页
字号:
-----------------------------------------------------------------------------
--  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 + -