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.address_width = address_width
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.w = stream.Endpoint(w_lite_description(data_width), name=name)

View File

@ -39,17 +39,17 @@ _layout = [
("err", 1, DIR_S_TO_M)
]
CTI_BURST_NONE = 0b000
CTI_BURST_CONSTANT = 0b001
CTI_BURST_NONE = 0b000
CTI_BURST_CONSTANT = 0b001
CTI_BURST_INCREMENTING = 0b010
CTI_BURST_END = 0b111
CTI_BURST_END = 0b111
class Interface(Record):
def __init__(self, data_width=32, adr_width=30, bursting=False):
self.data_width = data_width
self.adr_width = adr_width
self.bursting = bursting
self.data_width = data_width
self.adr_width = adr_width
self.bursting = bursting
Record.__init__(self, set_layout_parameters(_layout,
adr_width = adr_width,
data_width = data_width,
@ -362,19 +362,21 @@ class SRAM(Module):
read_only = False
###
adr_burst = Signal()
if self.bus.bursting:
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_end = Signal()
adr_burst = Signal()
adr_latched = 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_offset_lsb = Signal(adr_wrap_max)
adr_offset_msb = Signal(len(self.bus.adr))
adr_offset_lsb = Signal(adr_wrap_max)
adr_offset_msb = Signal(len(self.bus.adr))
adr_next = Signal(len(self.bus.adr))
@ -388,7 +390,12 @@ class SRAM(Module):
# unsupported burst cycle
"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
@ -400,19 +407,10 @@ class SRAM(Module):
adr_counter.eq(adr_counter + 1)
).Else(
adr_counter_offset.eq(self.bus.adr & adr_wrap_mask[self.bus.bte]),
If(self.bus.we,
adr_counter.eq(
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
),
)
adr_counter.eq(adr_counter_base + Cat(~self.bus.we,
Replicate(0, len(adr_counter)-1)
)
)
),
If(self.bus.cti == CTI_BURST_END,
adr_latched.eq(0),
@ -434,6 +432,9 @@ class SRAM(Module):
adr_next.eq(adr_offset_msb + adr_offset_lsb)
]
else: # self.ram.bursting == False
self.comb += adr_burst.eq(0)
###
# 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])
for i in range(bus_data_width//8)]
# address and data
self.comb += port.adr.eq(self.bus.adr[:len(port.adr)])
if self.bus.bursting:
self.comb += [
If(adr_burst & adr_latched,
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 += If(adr_burst & adr_latched,
port.adr.eq(adr_next[:len(port.adr)]),
)
self.comb += [
self.bus.dat_r.eq(port.dat_r)
]
@ -465,16 +459,9 @@ class SRAM(Module):
# generate ack
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 ----------------------------------------------------------------------------------

View File

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