From: Cole Poirier Date: Mon, 5 Oct 2020 00:12:35 +0000 (-0700) Subject: icache.py move icache_miss WAIT_ACK FSM state into method icache_miss_wait_ack()... X-Git-Tag: 24jan2021_ls180~238 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3f9b3e3cd66c01994d70ddd5f9f7977ad0fc6eff;p=soc.git icache.py move icache_miss WAIT_ACK FSM state into method icache_miss_wait_ack() to reduce clutter, indentation --- diff --git a/src/soc/experiment/icache.py b/src/soc/experiment/icache.py index 05cf9385..59acd46a 100644 --- a/src/soc/experiment/icache.py +++ b/src/soc/experiment/icache.py @@ -896,6 +896,75 @@ class ICache(Elaboratable): sync += r.state.eq(State.WAIT_ACK) + def icache_miss_wait_ack(self, m, r, replace_way, inval_in, + stbs_done, cache_valid_bits): + comb = m.d.comb + sync = m.d.sync + + wb_in = self.wb_in + + # Requests are all sent if stb is 0 + stbs_zero = Signal() + comb += stbs_zero.eq(r.wb.stb == 0) + comb += stbs_done.eq(stbs_zero) + + # If we are still sending requests, was one accepted? + with m.If(~wb_in.stall & ~stbs_zero): + # That was the last word ? # We are done sending. + # Clear stb and set stbs_done # so we can handle + # an eventual last ack on # the same cycle. + with m.If(is_last_row_addr(r.req_adr, r.end_row_ix)): + sync += Display("IS_LAST_ROW_ADDR " \ + "r.wb.addr:%x r.end_row_ix:%x " \ + "r.wb.stb:%x stbs_zero:%x " \ + "stbs_done:%x", r.wb.adr, \ + r.end_row_ix, r.wb.stb, \ + stbs_zero, stbs_done) + sync += r.wb.stb.eq(0) + comb += stbs_done.eq(1) + + # Calculate the next row address + rarange = Signal(LINE_OFF_BITS - ROW_OFF_BITS) + comb += rarange.eq( + r.req_adr[ROW_OFF_BITS:LINE_OFF_BITS] + 1 + ) + sync += r.req_adr[ROW_OFF_BITS:LINE_OFF_BITS].eq( + rarange + ) + sync += Display("RARANGE r.req_adr:%x rarange:%x " + "stbs_zero:%x stbs_done:%x", + r.req_adr, rarange, stbs_zero, stbs_done) + + # Incoming acks processing + with m.If(wb_in.ack): + sync += Display("WB_IN_ACK data:%x stbs_zero:%x " + "stbs_done:%x", + wb_in.dat, stbs_zero, stbs_done) + + sync += r.rows_valid[r.store_row % ROW_PER_LINE].eq(1) + + # Check for completion + with m.If(stbs_done & + is_last_row(r.store_row, r.end_row_ix)): + # Complete wishbone cycle + sync += r.wb.cyc.eq(0) + sync += r.req_adr.eq(0) # be nice, clear addr + + # Cache line is now valid + cv = Signal(INDEX_BITS) + comb += cv.eq(cache_valid_bits[r.store_index]) + comb += cv.bit_select(replace_way, 1).eq( + r.store_valid & ~inval_in + ) + sync += cache_valid_bits[r.store_index].eq(cv) + + sync += r.state.eq(State.IDLE) + + # not completed, move on to next request in row + with m.Else(): + # Increment store row counter + sync += r.store_row.eq(next_row(r.store_row)) + # Cache miss/reload synchronous machine def icache_miss(self, m, cache_valid_bits, r, req_is_miss, @@ -941,67 +1010,10 @@ class ICache(Elaboratable): tagset, cache_tags ) - # Requests are all sent if stb is 0 - stbs_zero = Signal() - comb += stbs_zero.eq(r.wb.stb == 0) - comb += stbs_done.eq(stbs_zero) - - # If we are still sending requests, was one accepted? - with m.If(~wb_in.stall & ~stbs_zero): - # That was the last word ? # We are done sending. - # Clear stb and set stbs_done # so we can handle - # an eventual last ack on # the same cycle. - with m.If(is_last_row_addr(r.req_adr, r.end_row_ix)): - sync += Display("IS_LAST_ROW_ADDR " \ - "r.wb.addr:%x r.end_row_ix:%x " \ - "r.wb.stb:%x stbs_zero:%x " \ - "stbs_done:%x", r.wb.adr, \ - r.end_row_ix, r.wb.stb, \ - stbs_zero, stbs_done) - sync += r.wb.stb.eq(0) - comb += stbs_done.eq(1) - - # Calculate the next row address - rarange = Signal(LINE_OFF_BITS - ROW_OFF_BITS) - comb += rarange.eq( - r.req_adr[ROW_OFF_BITS:LINE_OFF_BITS] + 1 - ) - sync += r.req_adr[ROW_OFF_BITS:LINE_OFF_BITS].eq( - rarange - ) - sync += Display("RARANGE r.req_adr:%x rarange:%x " - "stbs_zero:%x stbs_done:%x", - r.req_adr, rarange, stbs_zero, stbs_done) - - # Incoming acks processing - with m.If(wb_in.ack): - sync += Display("WB_IN_ACK data:%x stbs_zero:%x " - "stbs_done:%x", - wb_in.dat, stbs_zero, stbs_done) - - sync += r.rows_valid[r.store_row % ROW_PER_LINE].eq(1) - - # Check for completion - with m.If(stbs_done & - is_last_row(r.store_row, r.end_row_ix)): - # Complete wishbone cycle - sync += r.wb.cyc.eq(0) - sync += r.req_adr.eq(0) # be nice, clear addr - - # Cache line is now valid - cv = Signal(INDEX_BITS) - comb += cv.eq(cache_valid_bits[r.store_index]) - comb += cv.bit_select(replace_way, 1).eq( - r.store_valid & ~inval_in - ) - sync += cache_valid_bits[r.store_index].eq(cv) - - sync += r.state.eq(State.IDLE) - - # not completed, move on to next request in row - with m.Else(): - # Increment store row counter - sync += r.store_row.eq(next_row(r.store_row)) + self.icache_miss_wait_ack( + m, r, replace_way, inval_in, + stbs_done, cache_valid_bits + ) # TLB miss and protection fault processing with m.If(flush_in | m_in.tlbld):