soc/interconnect/wishbone: Cleanup in burst cycles support logic
This commit is contained in:
parent
ad46a57403
commit
8c1bc139ab
|
@ -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)
|
||||||
|
|
|
@ -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 ----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Loading…
Reference in New Issue