# 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 ----------------------------------------------------------------------------------