You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
microwatt/dcache_tb.vhdl

134 lines
3.2 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 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,
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';
dcache: Implement data TLB This adds a TLB to dcache, providing the ability to translate addresses for loads and stores. No protection mechanism has been implemented yet. The MSR_DR bit controls whether addresses are translated through the TLB. The TLB is a fixed-pagesize, set-associative cache. Currently the page size is 4kB and the TLB is 2-way set associative with 64 entries per set. This implements the tlbie instruction. RB bits 10 and 11 control whether the whole TLB is invalidated (if either bit is 1) or just a single entry corresponding to the effective page number in bits 12-63 of RB. As an extension until we get a hardware page table walk, a tlbie instruction with RB bits 9-11 set to 001 will load an entry into the TLB. The TLB entry value is in RS in the format of a radix PTE. Currently there is no proper handling of TLB misses. The load or store will not be performed but no interrupt is generated. In order to make timing at 100MHz on the Arty A7-100, we compare the real address from each way of the TLB with the tag from each way of the cache in parallel (requiring # TLB ways * # cache ways comparators). Then the result is selected based on which way hit in the TLB. That avoids a timing path going through the TLB EA comparators, the multiplexer that selects the RA, and the cache tag comparators. The hack where addresses of the form 0xc------- are marked as cache-inhibited is kept for now but restricted to real-mode accesses. Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
4 years ago
d_in.tlbie <= '0';
d_in.nc <= '0';
d_in.addr <= (others => '0');
d_in.data <= (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);
assert false report "end of test" severity failure;
wait;
end process;
end;