mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-11 23:43:15 +00:00
It bitrotted... more signals need to be initialized. This also adds a lot more accesses with different timing conditions allowing to test cases of hit during reloads, hit with reload formward, hit on idle cache etc... It also exposes a bug where the cache miss caused by the read of 0x140 uses the same victim way as previous cache miss of 0x40 (same index). This bug will need to be fixed separately, but at least this exposes it. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
244 lines
7.3 KiB
VHDL
244 lines
7.3 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
|
|
library work;
|
|
use work.common.all;
|
|
use work.wishbone_types.all;
|
|
|
|
entity dcache_tb is
|
|
end dcache_tb;
|
|
|
|
architecture behave of dcache_tb is
|
|
signal clk : std_ulogic;
|
|
signal rst : std_ulogic;
|
|
|
|
signal d_in : Loadstore1ToDcacheType;
|
|
signal d_out : DcacheToLoadstore1Type;
|
|
|
|
signal m_in : MmuToDcacheType;
|
|
signal m_out : DcacheToMmuType;
|
|
|
|
signal wb_bram_in : wishbone_master_out;
|
|
signal wb_bram_out : wishbone_slave_out;
|
|
|
|
constant clk_period : time := 10 ns;
|
|
|
|
signal stall : std_ulogic;
|
|
begin
|
|
dcache0: entity work.dcache
|
|
generic map(
|
|
LINE_SIZE => 64,
|
|
NUM_LINES => 4
|
|
)
|
|
port map(
|
|
clk => clk,
|
|
rst => rst,
|
|
d_in => d_in,
|
|
d_out => d_out,
|
|
stall_out => stall,
|
|
m_in => m_in,
|
|
m_out => m_out,
|
|
wishbone_out => wb_bram_in,
|
|
wishbone_in => wb_bram_out
|
|
);
|
|
|
|
-- BRAM Memory slave
|
|
bram0: entity work.wishbone_bram_wrapper
|
|
generic map(
|
|
MEMORY_SIZE => 1024,
|
|
RAM_INIT_FILE => "icache_test.bin"
|
|
)
|
|
port map(
|
|
clk => clk,
|
|
rst => rst,
|
|
wishbone_in => wb_bram_in,
|
|
wishbone_out => wb_bram_out
|
|
);
|
|
|
|
clk_process: process
|
|
begin
|
|
clk <= '0';
|
|
wait for clk_period/2;
|
|
clk <= '1';
|
|
wait for clk_period/2;
|
|
end process;
|
|
|
|
rst_process: process
|
|
begin
|
|
rst <= '1';
|
|
wait for 2*clk_period;
|
|
rst <= '0';
|
|
wait;
|
|
end process;
|
|
|
|
stim: process
|
|
begin
|
|
-- Clear stuff
|
|
d_in.valid <= '0';
|
|
d_in.load <= '0';
|
|
d_in.nc <= '0';
|
|
d_in.hold <= '0';
|
|
d_in.dcbz <= '0';
|
|
d_in.reserve <= '0';
|
|
d_in.virt_mode <= '0';
|
|
d_in.priv_mode <= '1';
|
|
d_in.addr <= (others => '0');
|
|
d_in.data <= (others => '0');
|
|
d_in.byte_sel <= (others => '1');
|
|
m_in.valid <= '0';
|
|
m_in.addr <= (others => '0');
|
|
m_in.pte <= (others => '0');
|
|
m_in.tlbie <= '0';
|
|
m_in.doall <= '0';
|
|
m_in.tlbld <= '0';
|
|
|
|
wait for 4*clk_period;
|
|
wait until rising_edge(clk);
|
|
|
|
-- Cacheable read of address 4
|
|
report "cache read address 4...";
|
|
d_in.load <= '1';
|
|
d_in.nc <= '0';
|
|
d_in.addr <= x"0000000000000004";
|
|
d_in.valid <= '1';
|
|
wait until rising_edge(clk) and stall = '0';
|
|
d_in.valid <= '0';
|
|
|
|
wait until rising_edge(clk) and d_out.valid = '1';
|
|
assert d_out.data = x"0000000100000000"
|
|
report "data @" & to_hstring(d_in.addr) &
|
|
"=" & to_hstring(d_out.data) &
|
|
" expected 0000000100000000"
|
|
severity failure;
|
|
|
|
-- Cacheable read of address 30 (hit after hit forward from reload)
|
|
report "cache read address 30...";
|
|
d_in.load <= '1';
|
|
d_in.nc <= '0';
|
|
d_in.addr <= x"0000000000000030";
|
|
d_in.valid <= '1';
|
|
wait until rising_edge(clk) and stall = '0';
|
|
d_in.valid <= '0';
|
|
|
|
wait until rising_edge(clk) and d_out.valid = '1';
|
|
assert d_out.data = x"0000000D0000000C"
|
|
report "data @" & to_hstring(d_in.addr) &
|
|
"=" & to_hstring(d_out.data) &
|
|
" expected 0000000D0000000C"
|
|
severity failure;
|
|
|
|
-- Ensure reload completes
|
|
wait for 100*clk_period;
|
|
wait until rising_edge(clk);
|
|
|
|
-- Cacheable read of address 38 (hit on idle cache)
|
|
report "cache read address 38...";
|
|
d_in.load <= '1';
|
|
d_in.nc <= '0';
|
|
d_in.addr <= x"0000000000000038";
|
|
d_in.valid <= '1';
|
|
wait until rising_edge(clk) and stall = '0';
|
|
d_in.valid <= '0';
|
|
|
|
wait until rising_edge(clk) and d_out.valid = '1';
|
|
assert d_out.data = x"0000000F0000000E"
|
|
report "data @" & to_hstring(d_in.addr) &
|
|
"=" & to_hstring(d_out.data) &
|
|
" expected 0000000F0000000E"
|
|
severity failure;
|
|
|
|
-- Cacheable read of address 130 (miss after hit, same index)
|
|
-- This will use way 2
|
|
report "cache read address 130...";
|
|
d_in.load <= '1';
|
|
d_in.nc <= '0';
|
|
d_in.addr <= x"0000000000000130";
|
|
d_in.valid <= '1';
|
|
wait until rising_edge(clk) and stall = '0';
|
|
d_in.valid <= '0';
|
|
|
|
wait until rising_edge(clk) and d_out.valid = '1';
|
|
assert d_out.data = x"0000004d0000004c"
|
|
report "data @" & to_hstring(d_in.addr) &
|
|
"=" & to_hstring(d_out.data) &
|
|
" expected 0000004d0000004c"
|
|
severity failure;
|
|
|
|
-- Ensure reload completes
|
|
wait for 100*clk_period;
|
|
wait until rising_edge(clk);
|
|
|
|
-- Cacheable read again of address 130 (hit in idle cache)
|
|
-- This should feed from way 2
|
|
report "cache read address 130...";
|
|
d_in.load <= '1';
|
|
d_in.nc <= '0';
|
|
d_in.addr <= x"0000000000000130";
|
|
d_in.valid <= '1';
|
|
wait until rising_edge(clk) and stall = '0';
|
|
d_in.valid <= '0';
|
|
|
|
wait until rising_edge(clk) and d_out.valid = '1';
|
|
assert d_out.data = x"0000004d0000004c"
|
|
report "data @" & to_hstring(d_in.addr) &
|
|
"=" & to_hstring(d_out.data) &
|
|
" expected 0000004d0000004c"
|
|
severity failure;
|
|
|
|
-- Cacheable read of address 40
|
|
report "cache read address 40...";
|
|
d_in.load <= '1';
|
|
d_in.nc <= '0';
|
|
d_in.addr <= x"0000000000000040";
|
|
d_in.valid <= '1';
|
|
wait until rising_edge(clk);
|
|
d_in.valid <= '0';
|
|
|
|
wait until rising_edge(clk) and d_out.valid = '1';
|
|
assert d_out.data = x"0000001100000010"
|
|
report "data @" & to_hstring(d_in.addr) &
|
|
"=" & to_hstring(d_out.data) &
|
|
" expected 0000001100000010"
|
|
severity failure;
|
|
|
|
-- Cacheable read of address 140 (miss after miss, same index)
|
|
-- This should use way 2
|
|
report "cache read address 140...";
|
|
d_in.load <= '1';
|
|
d_in.nc <= '0';
|
|
d_in.addr <= x"0000000000000140";
|
|
d_in.valid <= '1';
|
|
wait until rising_edge(clk) and stall = '0';
|
|
d_in.valid <= '0';
|
|
|
|
wait until rising_edge(clk) and d_out.valid = '1';
|
|
assert d_out.data = x"0000005100000050"
|
|
report "data @" & to_hstring(d_in.addr) &
|
|
"=" & to_hstring(d_out.data) &
|
|
" expected 0000005100000050"
|
|
severity failure;
|
|
|
|
-- Non-cacheable read of address 200
|
|
report "non-cache read address 200...";
|
|
d_in.load <= '1';
|
|
d_in.nc <= '1';
|
|
d_in.addr <= x"0000000000000200";
|
|
d_in.valid <= '1';
|
|
wait until rising_edge(clk) and stall = '0';
|
|
d_in.valid <= '0';
|
|
wait until rising_edge(clk) and d_out.valid = '1';
|
|
assert d_out.data = x"0000008100000080"
|
|
report "data @" & to_hstring(d_in.addr) &
|
|
"=" & to_hstring(d_out.data) &
|
|
" expected 0000008100000080"
|
|
severity failure;
|
|
|
|
wait until rising_edge(clk);
|
|
wait until rising_edge(clk);
|
|
wait until rising_edge(clk);
|
|
wait until rising_edge(clk);
|
|
|
|
std.env.finish;
|
|
end process;
|
|
end;
|