diff --git a/dcache.vhdl b/dcache.vhdl index 566389c..1e7fff1 100644 --- a/dcache.vhdl +++ b/dcache.vhdl @@ -367,6 +367,7 @@ architecture rtl of dcache is write_tag : std_ulogic; slow_valid : std_ulogic; wb : wishbone_master_out; + reloading : std_ulogic; reload_tag : cache_tag_t; store_way : way_t; store_row : row_t; @@ -431,7 +432,6 @@ architecture rtl of dcache is signal r0_valid : std_ulogic; signal r0_stall : std_ulogic; - signal fwd_same_tag : std_ulogic; signal use_forward_st : std_ulogic; signal use_forward_rl : std_ulogic; signal use_forward2 : std_ulogic; @@ -957,7 +957,6 @@ begin variable hit_ways : way_expand_t; variable go : std_ulogic; variable nc : std_ulogic; - variable s_hit : std_ulogic; variable s_tag : cache_tag_t; variable s_pte : tlb_pte_t; variable s_ra : real_addr_t; @@ -999,7 +998,6 @@ begin if r0.req.virt_mode = '1' then for j in tlb_way_t loop if tlb_valid_way(j) = '1' then - s_hit := '0'; s_pte := read_tlb_pte(j, tlb_pte_way); s_ra := s_pte(REAL_ADDR_BITS - 1 downto TLB_LG_PGSZ) & r0.req.addr(TLB_LG_PGSZ - 1 downto 0); @@ -1053,7 +1051,6 @@ begin end if; end if; req_same_tag <= rel_match; - fwd_same_tag <= fwd_match; -- This is 1 if the snooped write from the previous cycle hits the same -- cache line that is being accessed in this cycle. @@ -1072,7 +1069,7 @@ begin if rel_match = '1' and r1.store_row = req_row then -- Use the forwarding path if this cycle is a write to this row use_forward_st <= r1.write_bram; - if r1.state = RELOAD_WAIT_ACK and wishbone_in.ack = '1' then + if r1.reloading = '1' and wishbone_in.ack = '1' then use_forward_rl <= '1'; end if; end if; @@ -1105,12 +1102,12 @@ begin end if; -- See if the request matches the line currently being reloaded - if r1.state = RELOAD_WAIT_ACK and rel_match = '1' then + if r1.reloading = '1' and rel_match = '1' then assert not is_X(rindex); assert not is_X(r1.store_index); end if; hit_reload := '0'; - if r1.state = RELOAD_WAIT_ACK and rel_match = '1' and + if r1.reloading = '1' and rel_match = '1' and rindex = r1.store_index then -- Ignore is_hit from above, because a load miss writes the new tag -- but doesn't clear the valid bit on the line before refilling it. @@ -1347,7 +1344,7 @@ begin wr_sel_m <= (others => '0'); if r1.write_bram = '1' or - (r1.state = RELOAD_WAIT_ACK and wishbone_in.ack = '1') then + (r1.reloading = '1' and wishbone_in.ack = '1') then assert not is_X(replace_way); if to_unsigned(i, WAY_BITS) = replace_way then wr_sel_m <= ram_wr_select; @@ -1410,7 +1407,7 @@ begin r1.forward_row <= r1.store_row; r1.forward_sel <= ram_wr_select; r1.forward_valid <= r1.write_bram; - if r1.state = RELOAD_WAIT_ACK and wishbone_in.ack = '1' then + if r1.reloading = '1' and wishbone_in.ack = '1' then r1.forward_valid <= '1'; end if; @@ -1476,6 +1473,7 @@ begin r1.wb.stb <= '0'; r1.ls_valid <= '0'; r1.mmu_done <= '0'; + r1.reloading <= '0'; r1.acks_pending <= to_unsigned(0, 3); r1.stalled <= '0'; r1.dec_acks <= '0'; @@ -1654,6 +1652,7 @@ begin if req.nc = '0' then -- Track that we had one request sent r1.state <= RELOAD_WAIT_ACK; + r1.reloading <= '1'; r1.write_tag <= '1'; ev.load_miss <= '1'; @@ -1690,7 +1689,8 @@ begin -- dcbz is handled much like a load miss except -- that we are writing to memory instead of reading r1.state <= RELOAD_WAIT_ACK; - r1.write_tag <= not req.is_hit; + r1.reloading <= not req.nc; + r1.write_tag <= not req.nc and not req.is_hit; r1.wb.we <= '1'; r1.wb.cyc <= '1'; r1.wb.stb <= '1'; @@ -1763,7 +1763,10 @@ begin -- Cache line is now valid assert not is_X(r1.store_index); assert not is_X(r1.store_way); - cache_valids(to_integer(r1.store_index))(to_integer(r1.store_way)) <= '1'; + if r1.reloading = '1' then + cache_valids(to_integer(r1.store_index))(to_integer(r1.store_way)) <= '1'; + end if; + r1.reloading <= '0'; ev.dcache_refill <= not r1.dcbz; -- Second half of a lq/lqarx can assume a hit on this line now diff --git a/loadstore1.vhdl b/loadstore1.vhdl index e3bd558..a274d0f 100644 --- a/loadstore1.vhdl +++ b/loadstore1.vhdl @@ -695,7 +695,6 @@ begin v.flush := '1'; when OP_DCBZ => v.dcbz := '1'; - v.align_intr := v.nc; when OP_TLBIE => v.tlbie := '1'; v.is_slbia := l_in.insn(7);