cores/spi_mmap: add slot post transfer cs_wait
Also remove unused slot_status - maintains CSR alignment now that slot_control is 64 bit (two 32bit registers).
This commit is contained in:
parent
f3b287addd
commit
416f1b4281
|
@ -244,10 +244,10 @@ class SPICtrl(LiteXModule):
|
||||||
default_slot_loopback = 0b1,
|
default_slot_loopback = 0b1,
|
||||||
default_slot_divider = 2,
|
default_slot_divider = 2,
|
||||||
default_enable = 0b1,
|
default_enable = 0b1,
|
||||||
|
default_slot_wait = 0,
|
||||||
):
|
):
|
||||||
self.nslots = nslots
|
self.nslots = nslots
|
||||||
self.slot_controls = []
|
self.slot_controls = []
|
||||||
self.slot_status = []
|
|
||||||
|
|
||||||
version = "SPI0"
|
version = "SPI0"
|
||||||
self._version = CSRStatus(size=32, description="""SPI Module Version.""",
|
self._version = CSRStatus(size=32, description="""SPI Module Version.""",
|
||||||
|
@ -354,13 +354,15 @@ class SPICtrl(LiteXModule):
|
||||||
("``0x0002``", "SPI-Clk = Sys-Clk/2."),
|
("``0x0002``", "SPI-Clk = Sys-Clk/2."),
|
||||||
("``0x0004``", "SPI-Clk = Sys-Clk/4."),
|
("``0x0004``", "SPI-Clk = Sys-Clk/4."),
|
||||||
("``0xxxxx``", "SPI-Clk = Sys-Clk/xxxxx."),
|
("``0xxxxx``", "SPI-Clk = Sys-Clk/xxxxx."),
|
||||||
], reset=default_slot_divider)
|
], reset=default_slot_divider),
|
||||||
|
CSRField("wait", size=16, offset=32, values=[
|
||||||
|
("``0x0000``", "No wait time."),
|
||||||
|
("``0x0001``", "wait = 1 / Sys-Clk."),
|
||||||
|
("``0xxxxx``", "wait = xxxx / Sys-Clk."),
|
||||||
|
], reset=default_slot_wait),
|
||||||
])
|
])
|
||||||
status = CSRStatus(name=f"slot_status{slot}") # CHECKME: Useful?
|
|
||||||
setattr(self, f"slot_control{slot}", control)
|
setattr(self, f"slot_control{slot}", control)
|
||||||
setattr(self, f"slot_status{slot}", status)
|
|
||||||
self.slot_controls.append(control)
|
self.slot_controls.append(control)
|
||||||
self.slot_status.append(status)
|
|
||||||
|
|
||||||
def get_ctrl(self, name, slot=None, cs=None):
|
def get_ctrl(self, name, slot=None, cs=None):
|
||||||
assert not ((slot is None) and (cs is None))
|
assert not ((slot is None) and (cs is None))
|
||||||
|
@ -556,8 +558,15 @@ class SPIEngine(LiteXModule):
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Wait between transfers.
|
||||||
|
ctrl_wait = ctrl.get_ctrl("wait", cs=sink.cs)
|
||||||
|
wait_ticks = Signal.like(ctrl_wait)
|
||||||
|
wait_count = Signal.like(ctrl_wait)
|
||||||
|
self.comb += wait_ticks.eq(ctrl_wait)
|
||||||
|
cs_wait = Signal()
|
||||||
|
|
||||||
# SPI CS. (Use Manual CS to allow back-to-back Xfers).
|
# SPI CS. (Use Manual CS to allow back-to-back Xfers).
|
||||||
self.comb += If(ctrl.engine.fields.enable & sink.valid,
|
self.comb += If(ctrl.engine.fields.enable & sink.valid & ~cs_wait,
|
||||||
spi.cs.eq(sink.cs)
|
spi.cs.eq(sink.cs)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -584,6 +593,20 @@ class SPIEngine(LiteXModule):
|
||||||
source.be.eq(sink.be),
|
source.be.eq(sink.be),
|
||||||
If(source.ready,
|
If(source.ready,
|
||||||
sink.ready.eq(1),
|
sink.ready.eq(1),
|
||||||
|
If(wait_ticks,
|
||||||
|
cs_wait.eq(1),
|
||||||
|
NextValue(wait_count, wait_ticks-1),
|
||||||
|
NextState("WAIT")
|
||||||
|
).Else(
|
||||||
|
NextState("START")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fsm.act("WAIT",
|
||||||
|
If(wait_count,
|
||||||
|
cs_wait.eq(1),
|
||||||
|
NextValue(wait_count, wait_count-1)
|
||||||
|
).Else(
|
||||||
NextState("START")
|
NextState("START")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -139,7 +139,7 @@ class TestSPIMMAP(unittest.TestCase):
|
||||||
|
|
||||||
run_simulation(dut, generator(dut), vcd_name="sim.vcd")
|
run_simulation(dut, generator(dut), vcd_name="sim.vcd")
|
||||||
|
|
||||||
def mmap_test(self, length, bitorder, data, vcd_name=None, sel_override=None):
|
def mmap_test(self, length, bitorder, data, vcd_name=None, sel_override=None, wait=0):
|
||||||
pads = Record([("clk", 1), ("cs_n", 4), ("mosi", 1), ("miso", 1)])
|
pads = Record([("clk", 1), ("cs_n", 4), ("mosi", 1), ("miso", 1)])
|
||||||
dut = SPIMMAP(
|
dut = SPIMMAP(
|
||||||
pads=pads,
|
pads=pads,
|
||||||
|
@ -151,7 +151,7 @@ class TestSPIMMAP(unittest.TestCase):
|
||||||
|
|
||||||
def generator(dut):
|
def generator(dut):
|
||||||
# Minimal setup - spi_mmap ctrl defaults are everything enabled and:
|
# Minimal setup - spi_mmap ctrl defaults are everything enabled and:
|
||||||
# SPI_SLOT_MODE_3, SPI_SLOT_LENGTH_32B, SPI_SLOT_BITORDER_MSB_FIRST, loopback, divider=2,
|
# SPI_SLOT_MODE_3, SPI_SLOT_LENGTH_32B, SPI_SLOT_BITORDER_MSB_FIRST, loopback, divider=2, wait=0
|
||||||
version = yield dut.ctrl._version.status
|
version = yield dut.ctrl._version.status
|
||||||
vprint(f"version: {version}")
|
vprint(f"version: {version}")
|
||||||
vprint(f"slot_count: {(yield dut.ctrl.slot_count.status)}")
|
vprint(f"slot_count: {(yield dut.ctrl.slot_count.status)}")
|
||||||
|
@ -162,6 +162,7 @@ class TestSPIMMAP(unittest.TestCase):
|
||||||
# yield dut.ctrl.slot_control0.fields.loopback.eq(1)
|
# yield dut.ctrl.slot_control0.fields.loopback.eq(1)
|
||||||
# yield dut.ctrl.slot_control0.fields.divider.eq(2)
|
# yield dut.ctrl.slot_control0.fields.divider.eq(2)
|
||||||
# yield dut.ctrl.slot_control0.fields.enable.eq(1)
|
# yield dut.ctrl.slot_control0.fields.enable.eq(1)
|
||||||
|
yield dut.ctrl.slot_control0.fields.wait.eq(wait)
|
||||||
if length == SPI_SLOT_LENGTH_32B:
|
if length == SPI_SLOT_LENGTH_32B:
|
||||||
spi_length = 32
|
spi_length = 32
|
||||||
sel = 0b1111
|
sel = 0b1111
|
||||||
|
@ -284,6 +285,13 @@ class TestSPIMMAP(unittest.TestCase):
|
||||||
data = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]
|
data = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]
|
||||||
self.mmap_test(SPI_SLOT_LENGTH_8B, SPI_SLOT_BITORDER_MSB_FIRST, data, "mmap_8_msb.vcd")
|
self.mmap_test(SPI_SLOT_LENGTH_8B, SPI_SLOT_BITORDER_MSB_FIRST, data, "mmap_8_msb.vcd")
|
||||||
|
|
||||||
|
def test_spi_mmap_8_msb_wait1(self):
|
||||||
|
data = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]
|
||||||
|
self.mmap_test(SPI_SLOT_LENGTH_8B, SPI_SLOT_BITORDER_MSB_FIRST, data, "mmap_8_msb_wait1.vcd", wait=1)
|
||||||
|
|
||||||
|
def test_spi_mmap_8_msb_wait8(self):
|
||||||
|
data = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]
|
||||||
|
self.mmap_test(SPI_SLOT_LENGTH_8B, SPI_SLOT_BITORDER_MSB_FIRST, data, "mmap_8_msb_wait8.vcd", wait=8)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
Loading…
Reference in New Issue