GHDLFLAGS=--std=08 -Psim-unisim
CFLAGS=-O2 -Wall
-all = core_tb simple_ram_behavioural_tb soc_reset_tb icache_tb multiply_tb dmi_dtm_tb divider_tb \
+all = core_tb simple_ram_behavioural_tb soc_reset_tb icache_tb dcache_tb multiply_tb dmi_dtm_tb divider_tb \
rotator_tb countzero_tb
# XXX
icache.o: common.o wishbone_types.o plru.o cache_ram.o
icache_tb.o: common.o wishbone_types.o icache.o simple_ram_behavioural.o
dcache.o: common.o wishbone_types.o plru.o cache_ram.o
+dcache_tb.o: common.o wishbone_types.o dcache.o simple_ram_behavioural.o
insn_helpers.o:
loadstore1.o: common.o helpers.o
logical.o: decode_types.o
icache_tb: icache_tb.o
$(GHDL) -e $(GHDLFLAGS) -Wl,simple_ram_behavioural_helpers_c.o $@
+dcache_tb: dcache_tb.o
+ $(GHDL) -e $(GHDLFLAGS) -Wl,simple_ram_behavioural_helpers_c.o $@
+
plru_tb: plru_tb.o
$(GHDL) -e $(GHDLFLAGS) $@
--- /dev/null
+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 : DcacheToWritebackType;
+
+ 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.mw_soc_memory
+ generic map(
+ MEMORY_SIZE => 128,
+ 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');
+ d_in.write_reg <= (others => '0');
+ d_in.length <= (others => '0');
+ d_in.byte_reverse <= '0';
+ d_in.sign_extend <= '0';
+ d_in.update <= '0';
+ d_in.update_reg <= (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.write_enable = '1';
+ assert d_out.valid = '1';
+ assert d_out.write_data = x"0000000100000000"
+ report "data @" & to_hstring(d_in.addr) &
+ "=" & to_hstring(d_out.write_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.write_enable = '1';
+ assert d_out.valid = '1';
+ assert d_out.write_data = x"0000000D0000000C"
+ report "data @" & to_hstring(d_in.addr) &
+ "=" & to_hstring(d_out.write_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.write_enable = '1';
+ assert d_out.valid = '1';
+ assert d_out.write_data = x"0000004100000040"
+ report "data @" & to_hstring(d_in.addr) &
+ "=" & to_hstring(d_out.write_data) &
+ " expected 0000004100000040"
+ severity failure;
+
+ wait for clk_period*4;
+
+ assert false report "end of test" severity failure;
+ wait;
+
+ end process;
+end;