diff --git a/dcache.vhdl b/dcache.vhdl index 08b17f8..11f563f 100644 --- a/dcache.vhdl +++ b/dcache.vhdl @@ -341,7 +341,7 @@ architecture rtl of dcache is end_row_ix : row_in_line_t; rows_valid : row_per_line_valid_t; acks_pending : unsigned(2 downto 0); - inc_acks : std_ulogic; + stalled : std_ulogic; dec_acks : std_ulogic; choose_victim : std_ulogic; victim_way : way_t; @@ -1414,6 +1414,9 @@ begin r1.wb.stb <= '0'; r1.ls_valid <= '0'; r1.mmu_done <= '0'; + r1.acks_pending <= to_unsigned(0, 3); + r1.stalled <= '0'; + r1.dec_acks <= '0'; -- Not useful normally but helps avoiding tons of sim warnings r1.wb.adr <= (others => '0'); @@ -1421,8 +1424,6 @@ begin -- One cycle pulses reset r1.slow_valid <= '0'; r1.write_bram <= '0'; - r1.inc_acks <= '0'; - r1.dec_acks <= '0'; r1.ls_valid <= '0'; -- complete tlbies and TLB loads in the third cycle @@ -1509,6 +1510,19 @@ begin r1.choose_victim <= '1'; end if; + -- Update count of pending acks + acks := r1.acks_pending; + if r1.wb.cyc = '0' then + acks := to_unsigned(0, 3); + elsif r1.wb.stb = '1' and r1.stalled = '0' and r1.dec_acks = '0' then + acks := acks + 1; + elsif (r1.wb.stb = '0' or r1.stalled = '1') and r1.dec_acks = '1' then + acks := acks - 1; + end if; + r1.acks_pending <= acks; + r1.stalled <= wishbone_in.stall and r1.wb.cyc; + r1.dec_acks <= wishbone_in.ack and r1.wb.cyc; + -- Main state machine case r1.state is when IDLE => @@ -1563,7 +1577,6 @@ begin when OP_STORE_HIT | OP_STORE_MISS => if req.dcbz = '0' then r1.state <= STORE_WAIT_ACK; - r1.acks_pending <= to_unsigned(1, 3); r1.full <= '0'; r1.slow_valid <= '1'; if req.mmu_req = '0' then @@ -1657,15 +1670,6 @@ begin when STORE_WAIT_ACK => stbs_done := r1.wb.stb = '0'; - acks := r1.acks_pending; - if r1.inc_acks /= r1.dec_acks then - if r1.inc_acks = '1' then - acks := acks + 1; - else - acks := acks - 1; - end if; - end if; - r1.acks_pending <= acks; -- Clear stb when slave accepted request if wishbone_in.stall = '0' then -- See if there is another store waiting to be done @@ -1691,7 +1695,6 @@ begin -- Store requests never come from the MMU r1.ls_valid <= '1'; stbs_done := false; - r1.inc_acks <= '1'; else r1.wb.stb <= '0'; stbs_done := true; @@ -1706,7 +1709,6 @@ begin r1.wb.cyc <= '0'; r1.wb.stb <= '0'; end if; - r1.dec_acks <= '1'; end if; when NC_LOAD_WAIT_ACK =>