soc/interconnect/axi: add AXILite -> AXI converter

This commit is contained in:
Jędrzej Boczar 2020-07-30 13:38:17 +02:00
parent 8a0684b15e
commit e78d950a31
2 changed files with 109 additions and 0 deletions

View File

@ -430,6 +430,66 @@ class AXI2AXILite(Module):
) )
) )
# AXI Lite to AXI ----------------------------------------------------------------------------------
class AXILite2AXI(Module):
def __init__(self, axi_lite, axi, write_id=0, read_id=0, prot=0, burst_type="INCR"):
assert isinstance(axi_lite, AXILiteInterface)
assert isinstance(axi, AXIInterface)
assert axi_lite.data_width == axi.data_width
assert axi_lite.address_width == axi.address_width
# n bytes, encoded as log2(n)
burst_size = log2_int(axi.data_width // 8)
# burst type has no meaning as we use burst length of 1, but AXI slaves may require
# certain type of bursts, so it is probably safest to use INCR in general
burst_type = {
"FIXED": 0b00,
"INCR": 0b01,
"WRAP": 0b10,
}[burst_type]
self.comb += [
axi.aw.valid.eq(axi_lite.aw.valid),
axi_lite.aw.ready.eq(axi.aw.ready),
axi.aw.addr.eq(axi_lite.aw.addr),
axi.aw.burst.eq(burst_type),
axi.aw.len.eq(0), # 1 transfer per burst
axi.aw.size.eq(burst_size),
axi.aw.lock.eq(0), # Normal access
axi.aw.prot.eq(prot),
axi.aw.cache.eq(0b0011), # Normal Non-cacheable Bufferable
axi.aw.qos.eq(0),
axi.aw.id.eq(write_id),
axi.w.valid.eq(axi_lite.w.valid),
axi_lite.w.ready.eq(axi.w.ready),
axi.w.data.eq(axi_lite.w.data),
axi.w.strb.eq(axi_lite.w.strb),
axi.w.last.eq(1),
axi_lite.b.valid.eq(axi.b.valid),
axi_lite.b.resp.eq(axi.b.resp),
axi.b.ready.eq(axi_lite.b.ready),
axi.ar.valid.eq(axi_lite.ar.valid),
axi_lite.ar.ready.eq(axi.ar.ready),
axi.ar.addr.eq(axi_lite.ar.addr),
axi.ar.burst.eq(burst_type),
axi.ar.len.eq(0),
axi.ar.size.eq(burst_size),
axi.ar.lock.eq(0),
axi.ar.prot.eq(prot),
axi.ar.cache.eq(0b0011),
axi.ar.qos.eq(0),
axi.ar.id.eq(read_id),
axi_lite.r.valid.eq(axi.r.valid),
axi_lite.r.resp.eq(axi.r.resp),
axi_lite.r.data.eq(axi.r.data),
axi.r.ready.eq(axi_lite.r.ready),
]
# AXI Lite to Wishbone ----------------------------------------------------------------------------- # AXI Lite to Wishbone -----------------------------------------------------------------------------
class AXILite2Wishbone(Module): class AXILite2Wishbone(Module):

View File

@ -177,6 +177,55 @@ class TestAXILite(unittest.TestCase):
run_simulation(dut, [generator(dut)]) run_simulation(dut, [generator(dut)])
self.assertEqual(dut.errors, 0) self.assertEqual(dut.errors, 0)
def test_axilite2axi2mem(self):
class DUT(Module):
def __init__(self, mem_bus="wishbone"):
self.axi_lite = AXILiteInterface()
axi = AXIInterface()
self.submodules.axil2axi = AXILite2AXI(self.axi_lite, axi)
interface_cls, converter_cls, sram_cls = {
"wishbone": (wishbone.Interface, AXI2Wishbone, wishbone.SRAM),
"axi_lite": (AXILiteInterface, AXI2AXILite, AXILiteSRAM),
}[mem_bus]
bus = interface_cls()
self.submodules += converter_cls(axi, bus)
sram = sram_cls(1024, init=[0x12345678, 0xa55aa55a])
self.submodules += sram
self.comb += bus.connect(sram.bus)
def generator(axi_lite, datas, resps):
data, resp = (yield from axi_lite.read(0x00))
resps.append((resp, RESP_OKAY))
datas.append((data, 0x12345678))
data, resp = (yield from axi_lite.read(0x04))
resps.append((resp, RESP_OKAY))
datas.append((data, 0xa55aa55a))
for i in range(32):
resp = (yield from axi_lite.write(4*i, i))
resps.append((resp, RESP_OKAY))
for i in range(32):
data, resp = (yield from axi_lite.read(4*i))
resps.append((resp, RESP_OKAY))
datas.append((data, i))
for mem_bus in ["wishbone", "axi_lite"]:
with self.subTest(mem_bus=mem_bus):
# to have more verbose error messages store errors in list((actual, expected))
datas = []
resps = []
def actual_expected(results): # split into (list(actual), list(expected))
return list(zip(*results))
dut = DUT(mem_bus)
run_simulation(dut, [generator(dut.axi_lite, datas, resps)])
self.assertEqual(*actual_expected(resps))
msg = "\n".join("0x{:08x} vs 0x{:08x}".format(actual, expected) for actual, expected in datas)
self.assertEqual(*actual_expected(datas), msg="actual vs expected:\n" + msg)
def test_axilite2csr(self): def test_axilite2csr(self):
@passive @passive
def csr_mem_handler(csr, mem): def csr_mem_handler(csr, mem):