Line 1... |
Line 1... |
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
-- mips_cache_stub.vhdl -- 1-word cache module
|
-- mips_cache_stub.vhdl -- 1-word cache module
|
--
|
--
|
-- This module has the same interface and logic as a real cache but the cache
|
-- This module has the same interface and logic as a real cache but the cache
|
-- memory is just 1 word for each of code and data.
|
-- memory is just 1 word for each of code and data, and it's missing any tag
|
|
-- matching logic so all accesses 'miss'.
|
--
|
--
|
-- It interfaces the CPU to the following:
|
-- It interfaces the CPU to the following:
|
--
|
--
|
-- 1.- Internal 32-bit-wide BRAM for read only
|
-- 1.- Internal 32-bit-wide BRAM for read only
|
-- 2.- Internal 32-bit I/O bus
|
-- 2.- Internal 32-bit I/O bus
|
-- 3.- External 16-bit wide SRAM
|
-- 3.- External 16-bit or 8-bit wide static memory (SRAM or FLASH)
|
--
|
--
|
-- The SRAM memory interface signals are meant to connect directly to FPGA pins
|
-- The SRAM memory interface signals are meant to connect directly to FPGA pins
|
-- and all outputs are registered (tco should be minimal).
|
-- and all outputs are registered (tco should be minimal).
|
-- SRAM data inputs are NOT registered, though. They go through a couple muxes
|
-- SRAM data inputs are NOT registered, though. They go through a couple muxes
|
-- before reaching the first register so watch out for tsetup.
|
-- before reaching the first register so watch out for tsetup.
|
Line 58... |
Line 59... |
-- 2.- Access to unmapped areas will crash the CPU
|
-- 2.- Access to unmapped areas will crash the CPU
|
-- A couple states are missing in the state machine for handling accesses
|
-- A couple states are missing in the state machine for handling accesses
|
-- to unmapped areas. I haven't yet decided how to handle that (return
|
-- to unmapped areas. I haven't yet decided how to handle that (return
|
-- zero, trigger trap, mirror another mapped area...).
|
-- zero, trigger trap, mirror another mapped area...).
|
--
|
--
|
-- 3.- Code refills from SRAM is unimplemented yet
|
-- 3.- Does not work as a real 1-word cache yet
|
-- To be done for sheer lack of time.
|
|
--
|
|
-- 4.- Does not work as a real 1-word cache yet
|
|
-- That functionality is still missing, all accesses 'miss'. It should be
|
-- That functionality is still missing, all accesses 'miss'. It should be
|
-- implemented, as a way to test the real cache logic on a small scale.
|
-- implemented, as a way to test the real cache logic on a small scale.
|
--
|
--
|
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
|
|
Line 76... |
Line 74... |
use work.mips_pkg.all;
|
use work.mips_pkg.all;
|
|
|
|
|
entity mips_cache_stub is
|
entity mips_cache_stub is
|
generic (
|
generic (
|
BRAM_ADDR_SIZE : integer := 10;
|
BRAM_ADDR_SIZE : integer := 10; -- BRAM address size
|
SRAM_ADDR_SIZE : integer := 17
|
SRAM_ADDR_SIZE : integer := 17; -- Static RAM/Flash address size
|
|
|
|
-- these cache parameters are unused in thie implementation, they're
|
|
-- here for compatibility to the real cache module.
|
|
LINE_SIZE : integer := 4; -- Line size in words
|
|
CACHE_SIZE : integer := 256 -- I- and D- cache size in lines
|
);
|
);
|
port(
|
port(
|
clk : in std_logic;
|
clk : in std_logic;
|
reset : in std_logic;
|
reset : in std_logic;
|
|
|
-- Interface to CPU core
|
-- Interface to CPU core
|
data_rd_addr : in std_logic_vector(31 downto 0);
|
data_addr : in std_logic_vector(31 downto 0);
|
|
|
data_rd : out std_logic_vector(31 downto 0);
|
data_rd : out std_logic_vector(31 downto 0);
|
data_rd_vma : in std_logic;
|
data_rd_vma : in std_logic;
|
|
|
|
byte_we : in std_logic_vector(3 downto 0);
|
|
data_wr : in std_logic_vector(31 downto 0);
|
|
|
code_rd_addr : in std_logic_vector(31 downto 2);
|
code_rd_addr : in std_logic_vector(31 downto 2);
|
code_rd : out std_logic_vector(31 downto 0);
|
code_rd : out std_logic_vector(31 downto 0);
|
code_rd_vma : in std_logic;
|
code_rd_vma : in std_logic;
|
|
|
data_wr_addr : in std_logic_vector(31 downto 2);
|
|
byte_we : in std_logic_vector(3 downto 0);
|
|
data_wr : in std_logic_vector(31 downto 0);
|
|
|
|
mem_wait : out std_logic;
|
mem_wait : out std_logic;
|
cache_enable : in std_logic;
|
cache_enable : in std_logic;
|
|
|
-- interface to FPGA i/o devices
|
-- interface to FPGA i/o devices
|
io_rd_data : in std_logic_vector(31 downto 0);
|
io_rd_data : in std_logic_vector(31 downto 0);
|
Line 622... |
Line 625... |
-- Raise 'read_pending' at 1st cycle of a data read, clear it when
|
-- Raise 'read_pending' at 1st cycle of a data read, clear it when
|
-- the read (and/or refill) operation has been done.
|
-- the read (and/or refill) operation has been done.
|
-- data_rd_addr_reg always has the addr of any pending read
|
-- data_rd_addr_reg always has the addr of any pending read
|
if data_rd_vma='1' then
|
if data_rd_vma='1' then
|
read_pending <= '1';
|
read_pending <= '1';
|
data_rd_addr_reg <= data_rd_addr(31 downto 2);
|
data_rd_addr_reg <= data_addr(31 downto 2);
|
elsif ps=data_refill_sram_1 or
|
elsif ps=data_refill_sram_1 or
|
ps=data_refill_sram8_3 or
|
ps=data_refill_sram8_3 or
|
ps=data_refill_bram_1 or
|
ps=data_refill_bram_1 or
|
ps=data_read_io_0 or
|
ps=data_read_io_0 or
|
ps=data_ignore_read then
|
ps=data_ignore_read then
|
Line 637... |
Line 640... |
-- the write (writethrough actually) operation has been done.
|
-- the write (writethrough actually) operation has been done.
|
-- data_wr_addr_reg always has the addr of any pending write
|
-- data_wr_addr_reg always has the addr of any pending write
|
if byte_we/="0000" and ps=idle then
|
if byte_we/="0000" and ps=idle then
|
byte_we_reg <= byte_we;
|
byte_we_reg <= byte_we;
|
data_wr_reg <= data_wr;
|
data_wr_reg <= data_wr;
|
data_wr_addr_reg <= data_wr_addr;
|
data_wr_addr_reg <= data_addr(31 downto 2);
|
write_pending <= '1';
|
write_pending <= '1';
|
elsif ps=data_writethrough_sram_1b or
|
elsif ps=data_writethrough_sram_1b or
|
ps=data_write_io_0 or
|
ps=data_write_io_0 or
|
ps=data_ignore_write then
|
ps=data_ignore_write then
|
write_pending <= '0';
|
write_pending <= '0';
|
Line 826... |
Line 829... |
ps=code_refill_sram8_3 or
|
ps=code_refill_sram8_3 or
|
ps=code_refill_sram_1)
|
ps=code_refill_sram_1)
|
else '0';
|
else '0';
|
|
|
-- The lowest addr bit will only be used when accessing byte-wide memory, and
|
-- The lowest addr bit will only be used when accessing byte-wide memory, and
|
-- even when we're reading word-aligned code (we need to read the four bytes)
|
-- even when we're reading word-aligned code (because we need to read the four
|
|
-- bytes one by one).
|
sram_address(0) <=
|
sram_address(0) <=
|
'0' when (ps=data_refill_sram8_0 or ps=data_refill_sram8_2 or
|
'0' when (ps=data_refill_sram8_0 or ps=data_refill_sram8_2 or
|
ps=code_refill_sram8_0 or ps=code_refill_sram8_2) else
|
ps=code_refill_sram8_0 or ps=code_refill_sram8_2) else
|
'1';
|
'1';
|
|
|