Merge branch 'master' into avalon-burst-test
This commit is contained in:
commit
33fbf558a2
|
@ -28,6 +28,28 @@ vbits = 12
|
||||||
# Video Timings ------------------------------------------------------------------------------------
|
# Video Timings ------------------------------------------------------------------------------------
|
||||||
|
|
||||||
video_timings = {
|
video_timings = {
|
||||||
|
"160x100@60Hz" : {
|
||||||
|
"pix_clk" : 1.655e6,
|
||||||
|
"h_active" : 160,
|
||||||
|
"h_blanking" : 80,
|
||||||
|
"h_sync_offset" : 8,
|
||||||
|
"h_sync_width" : 32,
|
||||||
|
"v_active" : 100,
|
||||||
|
"v_blanking" : 15,
|
||||||
|
"v_sync_offset" : 1,
|
||||||
|
"v_sync_width" : 8,
|
||||||
|
},
|
||||||
|
"320x200@60Hz" : {
|
||||||
|
"pix_clk" : 5.16e6,
|
||||||
|
"h_active" : 320,
|
||||||
|
"h_blanking" : 80,
|
||||||
|
"h_sync_offset" : 8,
|
||||||
|
"h_sync_width" : 32,
|
||||||
|
"v_active" : 200,
|
||||||
|
"v_blanking" : 15,
|
||||||
|
"v_sync_offset" : 1,
|
||||||
|
"v_sync_width" : 8,
|
||||||
|
},
|
||||||
"640x480@60Hz" : {
|
"640x480@60Hz" : {
|
||||||
"pix_clk" : 25.175e6,
|
"pix_clk" : 25.175e6,
|
||||||
"h_active" : 640,
|
"h_active" : 640,
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -64,9 +60,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")
|
||||||
),
|
),
|
||||||
|
@ -105,7 +101,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,
|
||||||
|
@ -125,7 +121,7 @@ class AvalonMM2Wishbone(Module):
|
||||||
),
|
),
|
||||||
If(wb.ack,
|
If(wb.ack,
|
||||||
avl.readdatavalid.eq(1),
|
avl.readdatavalid.eq(1),
|
||||||
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,
|
||||||
|
|
|
@ -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):
|
||||||
|
@ -57,10 +57,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