From 62fd8fad3650d5f53e0e4127f45a172d657731c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Thu, 24 Oct 2024 17:55:43 +0200 Subject: [PATCH] support multiple cs_n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit support multiple cs_n Signed-off-by: Fin Maaß --- litespi/__init__.py | 15 ++++++++++----- litespi/core/mmap.py | 7 +++++-- litespi/crossbar.py | 6 +++--- litespi/phy/generic_ddr.py | 12 ++++++++---- litespi/phy/generic_sdr.py | 11 ++++++----- 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/litespi/__init__.py b/litespi/__init__.py index 27797fd..63fda54 100644 --- a/litespi/__init__.py +++ b/litespi/__init__.py @@ -71,17 +71,21 @@ class LiteSPI(LiteXModule): def __init__(self, phy, clock_domain="sys", with_mmap=True, mmap_endianness="big", with_master=True, master_tx_fifo_depth=1, master_rx_fifo_depth=1, - with_csr=True, with_mmap_write=False): + with_csr=True, with_mmap_write=False, mmap_cs_mask=1): - self.crossbar = crossbar = LiteSPICrossbar(clock_domain) + cs_width=len(phy.cs) + + self.crossbar = crossbar = LiteSPICrossbar(clock_domain, cs_width) self.comb += phy.cs.eq(crossbar.cs) if with_mmap: self.mmap = mmap = LiteSPIMMAP(flash=phy.flash, endianness=mmap_endianness, with_csr=with_csr, - with_write=with_mmap_write) - port_mmap = crossbar.get_port(mmap.cs) + with_write=with_mmap_write, + cs_width=cs_width, + cs_mask=mmap_cs_mask) + port_mmap = crossbar.get_port(mmap.cs, mmap.request) self.bus = mmap.bus self.comb += [ port_mmap.source.connect(mmap.sink), @@ -92,7 +96,8 @@ def __init__(self, phy, clock_domain="sys", if with_master: self.master = master = LiteSPIMaster( tx_fifo_depth = master_tx_fifo_depth, - rx_fifo_depth = master_rx_fifo_depth) + rx_fifo_depth = master_rx_fifo_depth, + cs_width = cs_width) port_master = crossbar.get_port(master.cs) self.comb += [ port_master.source.connect(master.sink), diff --git a/litespi/core/mmap.py b/litespi/core/mmap.py index eccd6e3..1b2ec48 100644 --- a/litespi/core/mmap.py +++ b/litespi/core/mmap.py @@ -75,11 +75,12 @@ class LiteSPIMMAP(LiteXModule): write_config : CSRStorage Optional register holding configuration bits for the write mode. """ - def __init__(self, flash, clock_domain="sys", endianness="big", with_csr=True, with_write=False): + def __init__(self, flash, clock_domain="sys", endianness="big", with_csr=True, with_write=False, cs_width=1, cs_mask=1): self.source = source = stream.Endpoint(spi_core2phy_layout) self.sink = sink = stream.Endpoint(spi_phy2core_layout) self.bus = bus = wishbone.Interface() - self.cs = cs = Signal() + self.cs = Signal(cs_width) + self.request = cs = Signal() self.offset = offset = Signal(len(bus.adr)) # Burst Control. @@ -123,6 +124,8 @@ def __init__(self, flash, clock_domain="sys", endianness="big", with_csr=True, w self.byte_count = byte_count = Signal(2, reset_less=True) self.data_write = Signal(32) + self.comb += If(self.request, self.cs.eq(cs_mask)) + # FSM. self.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", diff --git a/litespi/crossbar.py b/litespi/crossbar.py index 206297a..679fa0e 100644 --- a/litespi/crossbar.py +++ b/litespi/crossbar.py @@ -27,7 +27,7 @@ def __init__(self): class LiteSPICrossbar(Module): - def __init__(self, cd): + def __init__(self, cd, cs_width=1): self.cd = cd self.users = [] self.master = LiteSPIMasterPort() @@ -41,7 +41,7 @@ def __init__(self, cd): self.master.source.connect(self.tx_cdc.sink), ] - self.cs = Signal() + self.cs = Signal(cs_width) self.user_cs = [] self.user_request = [] @@ -59,7 +59,7 @@ def get_port(self, cs, request = None): if request is None: request = Signal() - self.comb += request.eq(cs) + self.comb += request.eq(cs != 0) self.users.append(internal_port) self.user_cs.append(self.cs.eq(cs)) diff --git a/litespi/phy/generic_ddr.py b/litespi/phy/generic_ddr.py index b440161..7d4dfd0 100644 --- a/litespi/phy/generic_ddr.py +++ b/litespi/phy/generic_ddr.py @@ -15,7 +15,7 @@ from litex.soc.interconnect import stream -from litex.build.io import DDRTristate +from litex.build.io import DDRTristate, SDROutput # LiteSPI DDR PHY Core ----------------------------------------------------------------------------- @@ -54,7 +54,7 @@ class LiteSPIDDRPHYCore(LiteXModule): def __init__(self, pads, flash, cs_delay, extra_latency=0): self.source = source = stream.Endpoint(spi_phy2core_layout) self.sink = sink = stream.Endpoint(spi_core2phy_layout) - self.cs = Signal() + self.cs = Signal().like(pads.cs_n) if hasattr(pads, "miso"): bus_width = 1 @@ -75,9 +75,13 @@ def __init__(self, pads, flash, cs_delay, extra_latency=0): # CS control. self.cs_timer = cs_timer = WaitTimer(cs_delay + 1) # Ensure cs_delay cycles between XFers. cs_enable = Signal() - self.comb += cs_timer.wait.eq(self.cs) + self.comb += cs_timer.wait.eq(self.cs != 0) self.comb += cs_enable.eq(cs_timer.done) - self.comb += pads.cs_n.eq(~cs_enable) + for i in range(len(pads.cs_n)): + self.specials += SDROutput( + i = ~(cs_enable & self.cs[i]), + o = pads.cs_n[i] + ) # I/Os. data_bits = 32 diff --git a/litespi/phy/generic_sdr.py b/litespi/phy/generic_sdr.py index 166018c..de1a0a6 100644 --- a/litespi/phy/generic_sdr.py +++ b/litespi/phy/generic_sdr.py @@ -63,7 +63,7 @@ class LiteSPISDRPHYCore(LiteXModule): def __init__(self, pads, flash, device, clock_domain, default_divisor, cs_delay): self.source = source = stream.Endpoint(spi_phy2core_layout) self.sink = sink = stream.Endpoint(spi_core2phy_layout) - self.cs = Signal() + self.cs = Signal().like(pads.cs_n) self._spi_clk_divisor = spi_clk_divisor = Signal(8) self._default_divisor = default_divisor @@ -94,11 +94,12 @@ def __init__(self, pads, flash, device, clock_domain, default_divisor, cs_delay) # CS control. self.cs_timer = cs_timer = WaitTimer(cs_delay + 1) # Ensure cs_delay cycles between XFers. cs_enable = Signal() - self.comb += cs_timer.wait.eq(self.cs) + self.comb += cs_timer.wait.eq(self.cs != 0) self.comb += cs_enable.eq(cs_timer.done) - self.specials += SDROutput( - i = ~cs_enable, - o = pads.cs_n + for i in range(len(pads.cs_n)): + self.specials += SDROutput( + i = ~(cs_enable & self.cs[i]), + o = pads.cs_n[i] ) if hasattr(pads, "mosi"):