soc/interconnect/wishbone: Cleanup in burst cycles support logic

This commit is contained in:
Rafal Kolucki 2022-04-12 15:32:29 +02:00
parent ad46a57403
commit 8c1bc139ab
3 changed files with 60 additions and 72 deletions

View File

@ -196,7 +196,8 @@ class AXILiteInterface:
self.data_width = data_width self.data_width = data_width
self.address_width = address_width self.address_width = address_width
self.clock_domain = clock_domain self.clock_domain = clock_domain
self.bursting = False # Not supported in AXI Lite if bursting is not False:
raise NotImplementedError("AXI-Lite does not support bursting")
self.aw = stream.Endpoint(ax_lite_description(address_width), name=name) self.aw = stream.Endpoint(ax_lite_description(address_width), name=name)
self.w = stream.Endpoint(w_lite_description(data_width), name=name) self.w = stream.Endpoint(w_lite_description(data_width), name=name)

View File

@ -39,17 +39,17 @@ _layout = [
("err", 1, DIR_S_TO_M) ("err", 1, DIR_S_TO_M)
] ]
CTI_BURST_NONE = 0b000 CTI_BURST_NONE = 0b000
CTI_BURST_CONSTANT = 0b001 CTI_BURST_CONSTANT = 0b001
CTI_BURST_INCREMENTING = 0b010 CTI_BURST_INCREMENTING = 0b010
CTI_BURST_END = 0b111 CTI_BURST_END = 0b111
class Interface(Record): class Interface(Record):
def __init__(self, data_width=32, adr_width=30, bursting=False): def __init__(self, data_width=32, adr_width=30, bursting=False):
self.data_width = data_width self.data_width = data_width
self.adr_width = adr_width self.adr_width = adr_width
self.bursting = bursting self.bursting = bursting
Record.__init__(self, set_layout_parameters(_layout, Record.__init__(self, set_layout_parameters(_layout,
adr_width = adr_width, adr_width = adr_width,
data_width = data_width, data_width = data_width,
@ -362,19 +362,21 @@ class SRAM(Module):
read_only = False read_only = False
### ###
adr_burst = Signal()
if self.bus.bursting: if self.bus.bursting:
adr_wrap_mask = Array((0b0000, 0b0011, 0b0111, 0b1111)) adr_wrap_mask = Array((0b0000, 0b0011, 0b0111, 0b1111))
adr_wrap_max = adr_wrap_mask[-1].bit_length() adr_wrap_max = adr_wrap_mask[-1].bit_length()
adr_burst_wrap = Signal() adr_burst_wrap = Signal()
adr_burst_end = Signal() adr_latched = Signal()
adr_burst = Signal()
adr_latched = Signal()
adr_counter = Signal(len(self.bus.adr)) adr_counter = Signal(len(self.bus.adr))
adr_counter_base = Signal(len(self.bus.adr))
adr_counter_offset = Signal(adr_wrap_max) adr_counter_offset = Signal(adr_wrap_max)
adr_offset_lsb = Signal(adr_wrap_max) adr_offset_lsb = Signal(adr_wrap_max)
adr_offset_msb = Signal(len(self.bus.adr)) adr_offset_msb = Signal(len(self.bus.adr))
adr_next = Signal(len(self.bus.adr)) adr_next = Signal(len(self.bus.adr))
@ -388,7 +390,12 @@ class SRAM(Module):
# unsupported burst cycle # unsupported burst cycle
"default": adr_burst.eq(0) "default": adr_burst.eq(0)
}), }),
adr_burst_wrap.eq(self.bus.bte[0] | self.bus.bte[1]) adr_burst_wrap.eq(self.bus.bte[0] | self.bus.bte[1]),
adr_counter_base.eq(
Cat(self.bus.adr & ~adr_wrap_mask[self.bus.bte],
self.bus.adr[adr_wrap_max:]
)
)
] ]
# latch initial address - initial address without wrapping bits and wrap offset # latch initial address - initial address without wrapping bits and wrap offset
@ -400,19 +407,10 @@ class SRAM(Module):
adr_counter.eq(adr_counter + 1) adr_counter.eq(adr_counter + 1)
).Else( ).Else(
adr_counter_offset.eq(self.bus.adr & adr_wrap_mask[self.bus.bte]), adr_counter_offset.eq(self.bus.adr & adr_wrap_mask[self.bus.bte]),
If(self.bus.we, adr_counter.eq(adr_counter_base + Cat(~self.bus.we,
adr_counter.eq( Replicate(0, len(adr_counter)-1)
Cat(self.bus.adr & ~adr_wrap_mask[self.bus.bte], )
self.bus.adr[adr_wrap_max:] )
)
),
).Else(
adr_counter.eq(
Cat(self.bus.adr & ~adr_wrap_mask[self.bus.bte],
self.bus.adr[adr_wrap_max:]
) + 1
),
)
), ),
If(self.bus.cti == CTI_BURST_END, If(self.bus.cti == CTI_BURST_END,
adr_latched.eq(0), adr_latched.eq(0),
@ -434,6 +432,9 @@ class SRAM(Module):
adr_next.eq(adr_offset_msb + adr_offset_lsb) adr_next.eq(adr_offset_msb + adr_offset_lsb)
] ]
else: # self.ram.bursting == False
self.comb += adr_burst.eq(0)
### ###
# memory # memory
@ -445,18 +446,11 @@ class SRAM(Module):
self.comb += [port.we[i].eq(self.bus.cyc & self.bus.stb & self.bus.we & self.bus.sel[i]) self.comb += [port.we[i].eq(self.bus.cyc & self.bus.stb & self.bus.we & self.bus.sel[i])
for i in range(bus_data_width//8)] for i in range(bus_data_width//8)]
# address and data # address and data
self.comb += port.adr.eq(self.bus.adr[:len(port.adr)])
if self.bus.bursting: if self.bus.bursting:
self.comb += [ self.comb += If(adr_burst & adr_latched,
If(adr_burst & adr_latched, port.adr.eq(adr_next[:len(port.adr)]),
port.adr.eq(adr_next[:len(port.adr)]), )
).Else(
port.adr.eq(self.bus.adr[:len(port.adr)]),
),
]
else:
self.comb += [
port.adr.eq(self.bus.adr[:len(port.adr)]),
]
self.comb += [ self.comb += [
self.bus.dat_r.eq(port.dat_r) self.bus.dat_r.eq(port.dat_r)
] ]
@ -465,16 +459,9 @@ class SRAM(Module):
# generate ack # generate ack
self.sync += [ self.sync += [
self.bus.ack.eq(0) self.bus.ack.eq(0),
If(self.bus.cyc & self.bus.stb & (~self.bus.ack | adr_burst), self.bus.ack.eq(1))
] ]
if self.bus.bursting:
self.sync += [
If(self.bus.cyc & self.bus.stb & (~self.bus.ack | adr_burst), self.bus.ack.eq(1))
]
else:
self.sync += [
If(self.bus.cyc & self.bus.stb & ~self.bus.ack, self.bus.ack.eq(1))
]
# Wishbone To CSR ---------------------------------------------------------------------------------- # Wishbone To CSR ----------------------------------------------------------------------------------

View File

@ -59,14 +59,14 @@ class TestWishbone(unittest.TestCase):
def test_sram_burst(self): def test_sram_burst(self):
def generator(dut): def generator(dut):
yield from dut.wb.write(0x0000, 0x01234567, cti=0b010) yield from dut.wb.write(0x0000, 0x01234567, cti=wishbone.CTI_BURST_INCREMENTING)
yield from dut.wb.write(0x0001, 0x89abcdef, cti=0b010) yield from dut.wb.write(0x0001, 0x89abcdef, cti=wishbone.CTI_BURST_INCREMENTING)
yield from dut.wb.write(0x0002, 0xdeadbeef, cti=0b010) yield from dut.wb.write(0x0002, 0xdeadbeef, cti=wishbone.CTI_BURST_INCREMENTING)
yield from dut.wb.write(0x0003, 0xc0ffee00, cti=0b111) yield from dut.wb.write(0x0003, 0xc0ffee00, cti=wishbone.CTI_BURST_END)
self.assertEqual((yield from dut.wb.read(0x0000, cti=0b010)), 0x01234567) self.assertEqual((yield from dut.wb.read(0x0000, cti=wishbone.CTI_BURST_INCREMENTING)), 0x01234567)
self.assertEqual((yield from dut.wb.read(0x0001, cti=0b010)), 0x89abcdef) self.assertEqual((yield from dut.wb.read(0x0001, cti=wishbone.CTI_BURST_INCREMENTING)), 0x89abcdef)
self.assertEqual((yield from dut.wb.read(0x0002, cti=0b010)), 0xdeadbeef) self.assertEqual((yield from dut.wb.read(0x0002, cti=wishbone.CTI_BURST_INCREMENTING)), 0xdeadbeef)
self.assertEqual((yield from dut.wb.read(0x0003, cti=0b111)), 0xc0ffee00) self.assertEqual((yield from dut.wb.read(0x0003, cti=wishbone.CTI_BURST_END)), 0xc0ffee00)
class DUT(Module): class DUT(Module):
def __init__(self): def __init__(self):
@ -80,14 +80,14 @@ class TestWishbone(unittest.TestCase):
def test_sram_burst_wrap(self): def test_sram_burst_wrap(self):
def generator(dut): def generator(dut):
bte = 0b01 bte = 0b01
yield from dut.wb.write(0x0001, 0x01234567, cti=0b010, bte=bte) yield from dut.wb.write(0x0001, 0x01234567, cti=wishbone.CTI_BURST_INCREMENTING, bte=bte)
yield from dut.wb.write(0x0002, 0x89abcdef, cti=0b010, bte=bte) yield from dut.wb.write(0x0002, 0x89abcdef, cti=wishbone.CTI_BURST_INCREMENTING, bte=bte)
yield from dut.wb.write(0x0003, 0xdeadbeef, cti=0b010, bte=bte) yield from dut.wb.write(0x0003, 0xdeadbeef, cti=wishbone.CTI_BURST_INCREMENTING, bte=bte)
yield from dut.wb.write(0x0000, 0xc0ffee00, cti=0b111, bte=bte) yield from dut.wb.write(0x0000, 0xc0ffee00, cti=wishbone.CTI_BURST_END, bte=bte)
self.assertEqual((yield from dut.wb.read(0x0001, cti=0b010, bte=bte)), 0x01234567) self.assertEqual((yield from dut.wb.read(0x0001, cti=wishbone.CTI_BURST_INCREMENTING, bte=bte)), 0x01234567)
self.assertEqual((yield from dut.wb.read(0x0002, cti=0b010, bte=bte)), 0x89abcdef) self.assertEqual((yield from dut.wb.read(0x0002, cti=wishbone.CTI_BURST_INCREMENTING, bte=bte)), 0x89abcdef)
self.assertEqual((yield from dut.wb.read(0x0003, cti=0b010, bte=bte)), 0xdeadbeef) self.assertEqual((yield from dut.wb.read(0x0003, cti=wishbone.CTI_BURST_INCREMENTING, bte=bte)), 0xdeadbeef)
self.assertEqual((yield from dut.wb.read(0x0000, cti=0b111, bte=bte)), 0xc0ffee00) self.assertEqual((yield from dut.wb.read(0x0000, cti=wishbone.CTI_BURST_END, bte=bte)), 0xc0ffee00)
class DUT(Module): class DUT(Module):
def __init__(self): def __init__(self):
@ -100,14 +100,14 @@ class TestWishbone(unittest.TestCase):
def test_sram_burst_constant(self): def test_sram_burst_constant(self):
def generator(dut): def generator(dut):
yield from dut.wb.write(0x0001, 0x01234567, cti=0b001) yield from dut.wb.write(0x0001, 0x01234567, cti=wishbone.CTI_BURST_CONSTANT)
yield from dut.wb.write(0x0002, 0x89abcdef, cti=0b001) yield from dut.wb.write(0x0002, 0x89abcdef, cti=wishbone.CTI_BURST_CONSTANT)
yield from dut.wb.write(0x0003, 0xdeadbeef, cti=0b001) yield from dut.wb.write(0x0003, 0xdeadbeef, cti=wishbone.CTI_BURST_CONSTANT)
yield from dut.wb.write(0x0000, 0xc0ffee00, cti=0b111) yield from dut.wb.write(0x0000, 0xc0ffee00, cti=wishbone.CTI_BURST_END)
self.assertEqual((yield from dut.wb.read(0x0001, cti=0b001)), 0x01234567) self.assertEqual((yield from dut.wb.read(0x0001, cti=wishbone.CTI_BURST_CONSTANT)), 0x01234567)
self.assertEqual((yield from dut.wb.read(0x0002, cti=0b001)), 0x89abcdef) self.assertEqual((yield from dut.wb.read(0x0002, cti=wishbone.CTI_BURST_CONSTANT)), 0x89abcdef)
self.assertEqual((yield from dut.wb.read(0x0003, cti=0b001)), 0xdeadbeef) self.assertEqual((yield from dut.wb.read(0x0003, cti=wishbone.CTI_BURST_CONSTANT)), 0xdeadbeef)
self.assertEqual((yield from dut.wb.read(0x0000, cti=0b111)), 0xc0ffee00) self.assertEqual((yield from dut.wb.read(0x0000, cti=wishbone.CTI_BURST_END)), 0xc0ffee00)
class DUT(Module): class DUT(Module):
def __init__(self): def __init__(self):