mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-13 15:18:09 +00:00
So that the dcache could in future be used by an MMU, this moves logic to do with data formatting, rA updates for update-form instructions, and handling of unaligned loads and stores out of dcache and into loadstore1. For now, dcache connects only to loadstore1, and loadstore1 now has the connection to writeback. Dcache generates a stall signal to loadstore1 which indicates that the request presented in the current cycle was not accepted and should be presented again. However, loadstore1 doesn't currently use it because we know that we can never hit the circumstances where it might be set. For unaligned transfers, loadstore1 generates two requests to dcache back-to-back, and then waits to see two acks back from dcache (cycles where d_in.valid is true). Loadstore1 now has a FSM for tracking how many acks we are expecting from dcache and for doing the rA update cycles when necessary. Handling for reservations and conditional stores is still in dcache. Loadstore1 now generates its own stall signal back to decode2, so we no longer need the logic in execute1 that generated the stall for the first two cycles. Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
133 lines
3.2 KiB
VHDL
133 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';
|
|
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;
|