AvalonMM2Wishbone: use same addressing on avalon and wishbone, leave address translation to the user
This commit is contained in:
parent
3ab7ebe536
commit
f00eb4e112
|
@ -15,13 +15,9 @@ from litex.soc.interconnect.avalon import AvalonMMInterface
|
||||||
# Avalon MM <--> Wishbone Bridge -------------------------------------------------------------------
|
# Avalon MM <--> Wishbone Bridge -------------------------------------------------------------------
|
||||||
|
|
||||||
class AvalonMM2Wishbone(Module):
|
class AvalonMM2Wishbone(Module):
|
||||||
def __init__(self, data_width=32, address_width=32, wishbone_base_address=0x0, wishbone_extend_address_bits=0, avoid_combinatorial_loop=True):
|
def __init__(self, data_width=32, avalon_address_width=32, wishbone_address_width=32, wishbone_base_address=0x0, burst_increment=1, avoid_combinatorial_loop=True):
|
||||||
word_width = data_width // 8
|
self.a2w_avl = avl = AvalonMMInterface (data_width=data_width, adr_width=avalon_address_width)
|
||||||
word_width_bits = log2_int(word_width)
|
|
||||||
wishbone_address_width = address_width - word_width_bits + wishbone_extend_address_bits
|
|
||||||
|
|
||||||
self.a2w_wb = wb = wishbone.Interface(data_width=data_width, adr_width=wishbone_address_width, bursting=True)
|
self.a2w_wb = wb = wishbone.Interface(data_width=data_width, adr_width=wishbone_address_width, bursting=True)
|
||||||
self.a2w_avl = avl = AvalonMMInterface (data_width=data_width, adr_width=address_width)
|
|
||||||
|
|
||||||
read_access = Signal()
|
read_access = Signal()
|
||||||
readdatavalid = Signal()
|
readdatavalid = Signal()
|
||||||
|
@ -30,7 +26,7 @@ class AvalonMM2Wishbone(Module):
|
||||||
burst_cycle = Signal()
|
burst_cycle = Signal()
|
||||||
burst_cycle_last = Signal()
|
burst_cycle_last = Signal()
|
||||||
burst_count = Signal(len(avl.burstcount))
|
burst_count = Signal(len(avl.burstcount))
|
||||||
burst_address = Signal(address_width)
|
burst_address = Signal(wishbone_address_width)
|
||||||
burst_read = Signal()
|
burst_read = Signal()
|
||||||
|
|
||||||
self.sync += burst_cycle_last.eq(burst_cycle)
|
self.sync += burst_cycle_last.eq(burst_cycle)
|
||||||
|
@ -65,9 +61,9 @@ class AvalonMM2Wishbone(Module):
|
||||||
# Avalon -> Wishbone
|
# Avalon -> Wishbone
|
||||||
self.comb += [
|
self.comb += [
|
||||||
# Avalon is byte addresses, Wishbone word addressed
|
# Avalon is byte addresses, Wishbone word addressed
|
||||||
wb.adr.eq(avl.address[word_width_bits:] + wishbone_base_address),
|
wb.adr.eq(avl.address + wishbone_base_address),
|
||||||
If(burst_cycle & burst_cycle_last,
|
If(burst_cycle & burst_cycle_last,
|
||||||
wb.adr.eq(burst_address[word_width_bits:] + wishbone_base_address)
|
wb.adr.eq(burst_address + wishbone_base_address)
|
||||||
),
|
),
|
||||||
wb.dat_w.eq(avl.writedata),
|
wb.dat_w.eq(avl.writedata),
|
||||||
wb.we.eq(avl.write),
|
wb.we.eq(avl.write),
|
||||||
|
@ -87,7 +83,7 @@ class AvalonMM2Wishbone(Module):
|
||||||
If(~avl.waitrequest & (avl.burstcount > 1),
|
If(~avl.waitrequest & (avl.burstcount > 1),
|
||||||
burst_cycle.eq(1),
|
burst_cycle.eq(1),
|
||||||
NextValue(burst_count, avl.burstcount - 1),
|
NextValue(burst_count, avl.burstcount - 1),
|
||||||
NextValue(burst_address, avl.address + word_width),
|
NextValue(burst_address, avl.address + burst_increment),
|
||||||
If(avl.write,
|
If(avl.write,
|
||||||
NextState("BURST-WRITE")
|
NextState("BURST-WRITE")
|
||||||
),
|
),
|
||||||
|
@ -104,7 +100,7 @@ class AvalonMM2Wishbone(Module):
|
||||||
wb.cti.eq(wishbone.CTI_BURST_END)
|
wb.cti.eq(wishbone.CTI_BURST_END)
|
||||||
),
|
),
|
||||||
If(~avl.waitrequest,
|
If(~avl.waitrequest,
|
||||||
NextValue(burst_address, burst_address + word_width),
|
NextValue(burst_address, burst_address + burst_increment),
|
||||||
NextValue(burst_count, burst_count - 1),
|
NextValue(burst_count, burst_count - 1),
|
||||||
),
|
),
|
||||||
If(burst_count == 0,
|
If(burst_count == 0,
|
||||||
|
@ -122,7 +118,8 @@ class AvalonMM2Wishbone(Module):
|
||||||
wb.cti.eq(wishbone.CTI_BURST_END)
|
wb.cti.eq(wishbone.CTI_BURST_END)
|
||||||
),
|
),
|
||||||
If(wb.ack,
|
If(wb.ack,
|
||||||
NextValue(burst_address, burst_address + word_width),
|
avl.readdatavalid.eq(1),
|
||||||
|
NextValue(burst_address, burst_address + burst_increment),
|
||||||
NextValue(burst_count, burst_count - 1)
|
NextValue(burst_count, burst_count - 1)
|
||||||
),
|
),
|
||||||
If(burst_count == 0,
|
If(burst_count == 0,
|
||||||
|
|
|
@ -17,16 +17,16 @@ class TestAvalon2Wishbone(unittest.TestCase):
|
||||||
def test_sram(self):
|
def test_sram(self):
|
||||||
def generator(dut):
|
def generator(dut):
|
||||||
yield from dut.avl.bus_write(0x0000, 0x01234567)
|
yield from dut.avl.bus_write(0x0000, 0x01234567)
|
||||||
yield from dut.avl.bus_write(0x0004, 0x89abcdef)
|
yield from dut.avl.bus_write(0x0001, 0x89abcdef)
|
||||||
yield from dut.avl.bus_write(0x0008, 0xdeadbeef)
|
yield from dut.avl.bus_write(0x0002, 0xdeadbeef)
|
||||||
yield from dut.avl.bus_write(0x000c, 0xc0ffee00)
|
yield from dut.avl.bus_write(0x0003, 0xc0ffee00)
|
||||||
yield from dut.avl.bus_write(0x0010, 0x76543210)
|
yield from dut.avl.bus_write(0x0004, 0x76543210)
|
||||||
yield
|
yield
|
||||||
self.assertEqual((yield from dut.avl.bus_read(0x0000)), 0x01234567)
|
self.assertEqual((yield from dut.avl.bus_read(0x0000)), 0x01234567)
|
||||||
self.assertEqual((yield from dut.avl.bus_read(0x0004)), 0x89abcdef)
|
self.assertEqual((yield from dut.avl.bus_read(0x0001)), 0x89abcdef)
|
||||||
self.assertEqual((yield from dut.avl.bus_read(0x0008)), 0xdeadbeef)
|
self.assertEqual((yield from dut.avl.bus_read(0x0002)), 0xdeadbeef)
|
||||||
self.assertEqual((yield from dut.avl.bus_read(0x000c)), 0xc0ffee00)
|
self.assertEqual((yield from dut.avl.bus_read(0x0003)), 0xc0ffee00)
|
||||||
self.assertEqual((yield from dut.avl.bus_read(0x0010)), 0x76543210)
|
self.assertEqual((yield from dut.avl.bus_read(0x0004)), 0x76543210)
|
||||||
|
|
||||||
class DUT(Module):
|
class DUT(Module):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -53,10 +53,10 @@ class TestAvalon2Wishbone(unittest.TestCase):
|
||||||
yield
|
yield
|
||||||
yield
|
yield
|
||||||
self.assertEqual((yield from dut.avl.bus_read(0x0000)), 0x01234567)
|
self.assertEqual((yield from dut.avl.bus_read(0x0000)), 0x01234567)
|
||||||
self.assertEqual((yield from dut.avl.bus_read(0x0004)), 0x89abcdef)
|
self.assertEqual((yield from dut.avl.bus_read(0x0001)), 0x89abcdef)
|
||||||
self.assertEqual((yield from dut.avl.bus_read(0x0008)), 0xdeadbeef)
|
self.assertEqual((yield from dut.avl.bus_read(0x0002)), 0xdeadbeef)
|
||||||
self.assertEqual((yield from dut.avl.bus_read(0x000c)), 0xc0ffee00)
|
self.assertEqual((yield from dut.avl.bus_read(0x0003)), 0xc0ffee00)
|
||||||
self.assertEqual((yield from dut.avl.bus_read(0x0010)), 0x76543210)
|
self.assertEqual((yield from dut.avl.bus_read(0x0004)), 0x76543210)
|
||||||
yield
|
yield
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue