soc/interconnect/axi: add capabilities to AXIBurst2Beat and simplify/optimize
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 29 Apr 2019 11:11:48 +0000 (13:11 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 29 Apr 2019 12:02:05 +0000 (14:02 +0200)
litex/soc/interconnect/axi.py
test/test_axi.py

index 5cb1e9adda9c3aaefec63199e6bd30a317c691d9..f9dd2078413eb4e51df22639fa0ae8881f3467b5 100644 (file)
@@ -66,66 +66,54 @@ class AXIInterface(Record):
 # AXI Bursts to Beats ------------------------------------------------------------------------------
 
 class AXIBurst2Beat(Module):
-    def __init__(self, ax_burst, ax_beat):
+    def __init__(self, ax_burst, ax_beat, capabilities={BURST_FIXED, BURST_INCR, BURST_WRAP}):
+        assert BURST_FIXED in capabilities
 
         # # #
 
-        self.count = count = Signal(8)
-        size = Signal(8 + 4)
-        offset = Signal(8 + 4)
-
-        # convert burst size to bytes
-        cases = {}
-        cases["default"] = size.eq(1024)
-        for i in range(10):
-            cases[i] = size.eq(2**i)
-        self.comb += Case(ax_burst.size, cases)
-
-        # fsm
-        self.submodules.fsm = fsm = FSM(reset_state="IDLE")
-        fsm.act("IDLE",
-            ax_beat.valid.eq(ax_burst.valid),
-            ax_beat.first.eq(1),
-            ax_beat.last.eq(ax_burst.len == 0),
-            ax_beat.addr.eq(ax_burst.addr),
+        beat_count  = Signal(8)
+        beat_size   = Signal(8 + 4)
+        beat_offset = Signal(8 + 4)
+        beat_wrap   = Signal(8 + 4)
+
+        # compute parameters
+        self.comb += beat_size.eq(1 << ax_burst.size)
+        self.comb += beat_wrap.eq(ax_burst.len*beat_size)
+
+        # combinatorial logic
+        self.comb += [
+            ax_beat.valid.eq(ax_burst.valid | ~ax_beat.first),
+            ax_beat.first.eq(beat_count == 0),
+            ax_beat.last.eq(beat_count == ax_burst.len),
+            ax_beat.addr.eq(ax_burst.addr + beat_offset),
             ax_beat.id.eq(ax_burst.id),
-            If(ax_beat.valid & ax_beat.ready,
-                If(ax_burst.len != 0,
-                    NextState("BURST2BEAT")
-                ).Else(
+            If(ax_beat.ready,
+                If(ax_beat.last,
                     ax_burst.ready.eq(1)
                 )
-            ),
-            NextValue(count, 1),
-            NextValue(offset, size),
-        )
-        wrap_offset = Signal(8 + 4)
-        self.sync += wrap_offset.eq((ax_burst.len - 1)*size)
-        fsm.act("BURST2BEAT",
-            ax_beat.valid.eq(1),
-            ax_beat.first.eq(0),
-            ax_beat.last.eq(count == ax_burst.len),
-            If((ax_burst.burst == BURST_INCR) |
-               (ax_burst.burst == BURST_WRAP),
-                ax_beat.addr.eq(ax_burst.addr + offset)
-            ).Else(
-                ax_beat.addr.eq(ax_burst.addr)
-            ),
-            ax_beat.id.eq(ax_burst.id),
+            )
+        ]
+
+        # synchronous logic
+        self.sync += [
             If(ax_beat.valid & ax_beat.ready,
                 If(ax_beat.last,
-                    ax_burst.ready.eq(1),
-                    NextState("IDLE")
+                    beat_count.eq(0),
+                    beat_offset.eq(0)
+                ).Else(
+                    beat_count.eq(beat_count + 1),
+                    If(((ax_burst.burst == BURST_INCR) & (BURST_INCR in capabilities)) |
+                       ((ax_burst.burst == BURST_WRAP) & (BURST_WRAP in capabilities)),
+                        beat_offset.eq(beat_offset + beat_size)
+                    )
                 ),
-                NextValue(count, count + 1),
-                NextValue(offset, offset + size),
-                If(ax_burst.burst == BURST_WRAP,
-                    If(offset == wrap_offset,
-                        NextValue(offset, 0)
+                If((ax_burst.burst == BURST_WRAP) & (BURST_WRAP in capabilities),
+                    If(beat_offset == beat_wrap,
+                        beat_offset.eq(0)
                     )
                 )
             )
-        )
+        ]
 
 # AXI to Wishbone ----------------------------------------------------------------------------------
 
index 6c51caa82e674a95457dcacb047da6872b869bc0..c8d23880a4686bf5c42af6d21957d1e58ed834b3 100644 (file)
@@ -23,7 +23,7 @@ class Burst:
                 offset = i*2**(self.size)
                 r += [Beat(self.addr + offset)]
             elif self.type == BURST_WRAP:
-                offset = (i*2**(self.size))%((2**self.size)*(self.len))
+                offset = (i*2**(self.size))%((2**self.size)*(self.len + 1))
                 r += [Beat(self.addr + offset)]
             else:
                 r += [Beat(self.addr)]