From d98c7426054fdf2c65576ff2fbb6727d6a29b693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Thu, 14 Nov 2024 13:34:18 +0100 Subject: [PATCH] phy: use common cs control for sdr and ddr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit use common cs control for sdr and ddr Signed-off-by: Fin Maaß --- litespi/cscontrol.py | 27 +++++++++++++++++++++++++++ litespi/phy/generic_ddr.py | 16 ++++------------ litespi/phy/generic_sdr.py | 16 +++------------- 3 files changed, 34 insertions(+), 25 deletions(-) create mode 100644 litespi/cscontrol.py diff --git a/litespi/cscontrol.py b/litespi/cscontrol.py new file mode 100644 index 0000000..a63aa45 --- /dev/null +++ b/litespi/cscontrol.py @@ -0,0 +1,27 @@ +# +# This file is part of LiteSPI +# +# Copyright (c) 2024 Fin Maaß +# SPDX-License-Identifier: BSD-2-Clause + +from migen import * + +from litex.gen import * +from litex.gen.genlib.misc import WaitTimer +from litex.build.io import SDROutput + +class LiteSPICSControl(LiteXModule): + def __init__(self, pads, cs, cs_delay): + self.enable = enable = Signal() + cs_n = Signal().like(pads.cs_n) + + self.timer = timer = WaitTimer(cs_delay + 1) # Ensure cs_delay cycles between XFers. + + self.comb += timer.wait.eq(cs != 0) + self.comb += enable.eq(timer.done) + self.comb += cs_n.eq(~(Replicate(enable, len(pads.cs_n)) & cs)) + + self.specials += SDROutput( + i = cs_n, + o = pads.cs_n + ) diff --git a/litespi/phy/generic_ddr.py b/litespi/phy/generic_ddr.py index b9c1316..414fd98 100644 --- a/litespi/phy/generic_ddr.py +++ b/litespi/phy/generic_ddr.py @@ -12,10 +12,11 @@ from litespi.common import * from litespi.clkgen import DDRLiteSPIClkGen +from litespi.cscontrol import LiteSPICSControl from litex.soc.interconnect import stream -from litex.build.io import DDRTristate, SDROutput +from litex.build.io import DDRTristate # LiteSPI DDR PHY Core ----------------------------------------------------------------------------- @@ -73,16 +74,7 @@ def __init__(self, pads, flash, cs_delay, extra_latency=0): self.clkgen = clkgen = DDRLiteSPIClkGen(pads) # 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 != 0) - self.comb += cs_enable.eq(cs_timer.done) - cs_n = Signal().like(pads.cs_n) - self.comb += cs_n.eq(~(Replicate(cs_enable, len(pads.cs_n)) & self.cs)) - self.specials += SDROutput( - i = cs_n, - o = pads.cs_n - ) + self.cs_control = cs_control = LiteSPICSControl(pads, self.cs, cs_delay) dq_o = Array([Signal(len(pads.dq)) for _ in range(2)]) dq_i = Array([Signal(len(pads.dq)) for _ in range(2)]) @@ -143,7 +135,7 @@ def __init__(self, pads, flash, cs_delay, extra_latency=0): # Stop Clk. NextValue(clkgen.en, 0), # Wait for CS and a CMD from the Core. - If(cs_enable & sink.valid, + If(cs_control.enable & sink.valid, # Load Shift Register Count/Data Out. NextValue(sr_cnt, sink.len - sink.width), sr_out_load.eq(1), diff --git a/litespi/phy/generic_sdr.py b/litespi/phy/generic_sdr.py index a9091bf..f3c528b 100644 --- a/litespi/phy/generic_sdr.py +++ b/litespi/phy/generic_sdr.py @@ -9,10 +9,9 @@ from litex.gen import * -from litex.gen.genlib.misc import WaitTimer - from litespi.common import * from litespi.clkgen import LiteSPIClkGen +from litespi.cscontrol import LiteSPICSControl from litex.soc.interconnect import stream from litex.soc.interconnect.csr import * @@ -92,16 +91,7 @@ def __init__(self, pads, flash, device, clock_domain, default_divisor, cs_delay) self.comb += clkgen.div.eq(spi_clk_divisor) # 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 != 0) - self.comb += cs_enable.eq(cs_timer.done) - cs_n = Signal().like(pads.cs_n) - self.comb += cs_n.eq(~(Replicate(cs_enable, len(pads.cs_n)) & self.cs)) - self.specials += SDROutput( - i = cs_n, - o = pads.cs_n - ) + self.cs_control = cs_control = LiteSPICSControl(pads, self.cs, cs_delay) if hasattr(pads, "mosi"): dq_o = Signal() @@ -165,7 +155,7 @@ def __init__(self, pads, flash, device, clock_domain, default_divisor, cs_delay) self.fsm = fsm = FSM(reset_state="WAIT-CMD-DATA") fsm.act("WAIT-CMD-DATA", # Wait for CS and a CMD from the Core. - If(cs_enable & sink.valid, + If(cs_control.enable & sink.valid, # Load Shift Register Count/Data Out. NextValue(sr_cnt, sink.len - sink.width), NextValue(dq_oe, sink.mask),