soc/interconnect/axi: add Wishbone2AXILite

This commit is contained in:
Florent Kermarrec 2019-11-20 12:32:22 +01:00
parent 4b073a440a
commit 04017519c8
2 changed files with 110 additions and 1 deletions

View File

@ -66,7 +66,7 @@ class AXIInterface(Record):
self.ar = stream.Endpoint(ax_description(address_width, id_width))
self.r = stream.Endpoint(r_description(data_width, id_width))
# AXI Lite Definition -----------------------------------------------------------------------------------
# AXI Lite Definition ------------------------------------------------------------------------------
def ax_lite_description(address_width):
return [("addr", address_width)]
@ -336,3 +336,78 @@ class AXI2Wishbone(Module):
axi2axi_lite = AXI2AXILite(axi, axi_lite)
axi_lite2wishbone = AXILite2Wishbone(axi_lite, wishbone, base_address)
self.submodules += axi2axi_lite, axi_lite2wishbone
# Wishbone to AXILite ------------------------------------------------------------------------------
class Wishbone2AXILite(Module):
def __init__(self, wishbone, axi_lite, base_address=0x00000000):
wishbone_adr_shift = log2_int(axi_lite.data_width//8)
assert axi_lite.data_width == len(wishbone.dat_r)
assert axi_lite.address_width == len(wishbone.adr) + wishbone_adr_shift
_cmd_done = Signal()
_data_done = Signal()
_addr = Signal(len(wishbone.adr))
self.comb += _addr.eq(wishbone.adr - base_address//4)
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
fsm.act("IDLE",
NextValue(_cmd_done, 0),
NextValue(_data_done, 0),
If(wishbone.stb & wishbone.cyc,
If(wishbone.we,
NextState("WRITE")
).Else(
NextState("READ")
)
)
)
fsm.act("WRITE",
# cmd
axi_lite.aw.valid.eq(~_cmd_done),
axi_lite.aw.addr[wishbone_adr_shift:].eq(_addr),
If(axi_lite.aw.valid & axi_lite.aw.ready,
NextValue(_cmd_done, 1)
),
# data
axi_lite.w.valid.eq(~_data_done),
axi_lite.w.data.eq(wishbone.dat_w),
axi_lite.w.strb.eq(wishbone.sel),
If(axi_lite.w.valid & axi_lite.w.ready,
NextValue(_data_done, 1),
),
# resp
axi_lite.b.ready.eq(_cmd_done & _data_done),
If(axi_lite.b.valid & axi_lite.b.ready,
If(axi_lite.b.resp == RESP_OKAY,
wishbone.ack.eq(1),
NextState("IDLE")
).Else(
NextState("ERROR")
)
)
)
fsm.act("READ",
# cmd
axi_lite.ar.valid.eq(~_cmd_done),
axi_lite.ar.addr[wishbone_adr_shift:].eq(_addr),
If(axi_lite.ar.valid & axi_lite.ar.ready,
NextValue(_cmd_done, 1)
),
# data & resp
axi_lite.r.ready.eq(_cmd_done),
If(axi_lite.r.valid & axi_lite.r.ready,
If(axi_lite.r.resp == RESP_OKAY,
wishbone.dat_r.eq(axi_lite.r.data),
wishbone.ack.eq(1),
NextState("IDLE"),
).Else(
NextState("ERROR")
)
)
)
fsm.act("ERROR",
wishbone.ack.eq(1),
wishbone.err.eq(1),
NextState("IDLE")
)

View File

@ -326,3 +326,37 @@ class TestAXI(unittest.TestCase):
r_valid_random = 90,
r_ready_random = 90
)
def test_wishbone2axi2wishbone(self):
class DUT(Module):
def __init__(self):
self.wishbone = wishbone.Interface(data_width=32)
# # #
axi = AXILiteInterface(data_width=32, address_width=32)
wb = wishbone.Interface(data_width=32)
wishbone2axi = Wishbone2AXILite(self.wishbone, axi)
axi2wishbone = AXILite2Wishbone(axi, wb)
self.submodules += wishbone2axi, axi2wishbone
sram = wishbone.SRAM(1024, init=[0x12345678, 0xa55aa55a])
self.submodules += sram
self.comb += wb.connect(sram.bus)
def generator(dut):
dut.errors = 0
if (yield from dut.wishbone.read(0)) != 0x12345678:
dut.errors += 1
if (yield from dut.wishbone.read(1)) != 0xa55aa55a:
dut.errors += 1
for i in range(32):
yield from dut.wishbone.write(i, i)
for i in range(32):
if (yield from dut.wishbone.read(i)) != i:
dut.errors += 1
dut = DUT()
run_simulation(dut, [generator(dut)], vcd_name="toto.vcd")
self.assertEqual(dut.errors, 0)