icache.py move icache_miss WAIT_ACK FSM state into method icache_miss_wait_ack()...
authorCole Poirier <colepoirier@gmail.com>
Mon, 5 Oct 2020 00:12:35 +0000 (17:12 -0700)
committerCole Poirier <colepoirier@gmail.com>
Mon, 5 Oct 2020 01:04:02 +0000 (18:04 -0700)
src/soc/experiment/icache.py

index 05cf9385f335cd2f1350b238fce247149fc981b8..59acd46a8b60ceee95776245535587b96f111bc2 100644 (file)
@@ -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):