You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
7.3 KiB
243 lines
7.3 KiB
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;
|
|
|