soc/interconnect/axi: add capabilities to AXIBurst2Beat and simplify/optimize

This commit is contained in:
Florent Kermarrec 2019-04-29 13:11:48 +02:00
parent 305b8879de
commit 6de2713524
2 changed files with 35 additions and 47 deletions

View File

@ -66,66 +66,54 @@ class AXIInterface(Record):
# AXI Bursts to Beats ------------------------------------------------------------------------------ # AXI Bursts to Beats ------------------------------------------------------------------------------
class AXIBurst2Beat(Module): 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) beat_count = Signal(8)
size = Signal(8 + 4) beat_size = Signal(8 + 4)
offset = Signal(8 + 4) beat_offset = Signal(8 + 4)
beat_wrap = Signal(8 + 4)
# convert burst size to bytes # compute parameters
cases = {} self.comb += beat_size.eq(1 << ax_burst.size)
cases["default"] = size.eq(1024) self.comb += beat_wrap.eq(ax_burst.len*beat_size)
for i in range(10):
cases[i] = size.eq(2**i)
self.comb += Case(ax_burst.size, cases)
# fsm # combinatorial logic
self.submodules.fsm = fsm = FSM(reset_state="IDLE") self.comb += [
fsm.act("IDLE", ax_beat.valid.eq(ax_burst.valid | ~ax_beat.first),
ax_beat.valid.eq(ax_burst.valid), ax_beat.first.eq(beat_count == 0),
ax_beat.first.eq(1), ax_beat.last.eq(beat_count == ax_burst.len),
ax_beat.last.eq(ax_burst.len == 0), ax_beat.addr.eq(ax_burst.addr + beat_offset),
ax_beat.addr.eq(ax_burst.addr),
ax_beat.id.eq(ax_burst.id), ax_beat.id.eq(ax_burst.id),
If(ax_beat.valid & ax_beat.ready, If(ax_beat.ready,
If(ax_burst.len != 0, If(ax_beat.last,
NextState("BURST2BEAT")
).Else(
ax_burst.ready.eq(1) 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", # synchronous logic
ax_beat.valid.eq(1), self.sync += [
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),
If(ax_beat.valid & ax_beat.ready, If(ax_beat.valid & ax_beat.ready,
If(ax_beat.last, If(ax_beat.last,
ax_burst.ready.eq(1), beat_count.eq(0),
NextState("IDLE") 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), If((ax_burst.burst == BURST_WRAP) & (BURST_WRAP in capabilities),
NextValue(offset, offset + size), If(beat_offset == beat_wrap,
If(ax_burst.burst == BURST_WRAP, beat_offset.eq(0)
If(offset == wrap_offset,
NextValue(offset, 0)
)
) )
) )
) )
]
# AXI to Wishbone ---------------------------------------------------------------------------------- # AXI to Wishbone ----------------------------------------------------------------------------------

View File

@ -23,7 +23,7 @@ class Burst:
offset = i*2**(self.size) offset = i*2**(self.size)
r += [Beat(self.addr + offset)] r += [Beat(self.addr + offset)]
elif self.type == BURST_WRAP: 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)] r += [Beat(self.addr + offset)]
else: else:
r += [Beat(self.addr)] r += [Beat(self.addr)]