diff --git a/core.vhdl b/core.vhdl index d02609b..8ba5b70 100644 --- a/core.vhdl +++ b/core.vhdl @@ -159,7 +159,7 @@ begin if rising_edge(clk) then rst_fetch1 <= core_rst; rst_fetch2 <= core_rst; - rst_icache <= core_rst or dbg_icache_rst or ex1_icache_inval; + rst_icache <= core_rst; rst_dcache <= core_rst; rst_dec1 <= core_rst; rst_dec2 <= core_rst; @@ -202,6 +202,7 @@ begin i_out => icache_to_fetch2, m_in => mmu_to_icache, flush_in => flush, + inval_in => dbg_icache_rst or ex1_icache_inval, stall_out => icache_stall_out, wishbone_out => wishbone_insn_out, wishbone_in => wishbone_insn_in diff --git a/icache.vhdl b/icache.vhdl index 553b885..264a963 100644 --- a/icache.vhdl +++ b/icache.vhdl @@ -54,6 +54,7 @@ entity icache is stall_out : out std_ulogic; flush_in : in std_ulogic; + inval_in : in std_ulogic; wishbone_out : out wishbone_master_out; wishbone_in : in wishbone_slave_out @@ -173,6 +174,7 @@ architecture rtl of icache is store_way : way_t; store_index : index_t; store_row : row_t; + store_valid : std_ulogic; -- TLB miss state fetch_failed : std_ulogic; @@ -570,6 +572,14 @@ begin -- Not useful normally but helps avoiding tons of sim warnings r.wb.adr <= (others => '0'); else + -- Process cache invalidations + if inval_in = '1' then + for i in index_t loop + cache_valids(i) <= (others => '0'); + end loop; + r.store_valid <= '0'; + end if; + -- Main state machine case r.state is when IDLE => @@ -599,6 +609,7 @@ begin r.store_index <= req_index; r.store_way <= replace_way; r.store_row <= get_row(req_laddr); + r.store_valid <= '1'; -- Prep for first wishbone read. We calculate the address of -- the start of the cache line and start the WB cycle. @@ -638,7 +649,7 @@ begin r.wb.cyc <= '0'; -- Cache line is now valid - cache_valids(r.store_index)(r.store_way) <= '1'; + cache_valids(r.store_index)(r.store_way) <= r.store_valid and not inval_in; -- We are done r.state <= IDLE; diff --git a/icache_tb.vhdl b/icache_tb.vhdl index 828a610..39e28d5 100644 --- a/icache_tb.vhdl +++ b/icache_tb.vhdl @@ -34,6 +34,7 @@ begin i_out => i_in, m_in => m_out, flush_in => '0', + inval_in => '0', wishbone_out => wb_bram_in, wishbone_in => wb_bram_out );