|
|
|
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;
|
|
|
|
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,
|
|
|
|
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.addr <= (others => '0');
|
|
|
|
d_in.data <= (others => '0');
|
|
|
|
m_in.valid <= '0';
|
|
|
|
m_in.addr <= (others => '0');
|
|
|
|
m_in.pte <= (others => '0');
|
|
|
|
|
|
|
|
wait for 4*clk_period;
|
|
|
|
wait until rising_edge(clk);
|
|
|
|
|
|
|
|
-- Cacheable read of address 4
|
|
|
|
d_in.load <= '1';
|
|
|
|
d_in.nc <= '0';
|
|
|
|
d_in.addr <= x"0000000000000004";
|
|
|
|
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"0000000100000000"
|
|
|
|
report "data @" & to_hstring(d_in.addr) &
|
|
|
|
"=" & to_hstring(d_out.data) &
|
|
|
|
" expected 0000000100000000"
|
|
|
|
severity failure;
|
|
|
|
-- wait for clk_period;
|
|
|
|
|
|
|
|
-- Cacheable read of address 30
|
|
|
|
d_in.load <= '1';
|
|
|
|
d_in.nc <= '0';
|
|
|
|
d_in.addr <= x"0000000000000030";
|
|
|
|
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"0000000D0000000C"
|
|
|
|
report "data @" & to_hstring(d_in.addr) &
|
|
|
|
"=" & to_hstring(d_out.data) &
|
|
|
|
" expected 0000000D0000000C"
|
|
|
|
severity failure;
|
|
|
|
|
|
|
|
-- Non-cacheable read of address 100
|
|
|
|
d_in.load <= '1';
|
|
|
|
d_in.nc <= '1';
|
|
|
|
d_in.addr <= x"0000000000000100";
|
|
|
|
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"0000004100000040"
|
|
|
|
report "data @" & to_hstring(d_in.addr) &
|
|
|
|
"=" & to_hstring(d_out.data) &
|
|
|
|
" expected 0000004100000040"
|
|
|
|
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;
|