soc/interconnect/axi: add capabilities to AXIBurst2Beat and simplify/optimize
This commit is contained in:
parent
305b8879de
commit
6de2713524
|
@ -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 ----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
Loading…
Reference in New Issue