diff --git a/litespi/common.py b/litespi/common.py index c856645..a95840b 100644 --- a/litespi/common.py +++ b/litespi/common.py @@ -7,6 +7,10 @@ from migen import * from migen.genlib.cdc import MultiReg +from litex.gen import * +from litex.gen.genlib.misc import WaitTimer +from litex.build.io import SDROutput + # Core <-> PHY Layouts ----------------------------------------------------------------------------- """ @@ -41,3 +45,21 @@ def __init__(self, src, dst, clock_domain): self.comb += dst.eq(src) else: self.specials += MultiReg(src, dst, clock_domain) + +# LiteSPI CS Control ------------------------------------------------------------------------------- + +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)) & self.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..c9e244f 100644 --- a/litespi/phy/generic_ddr.py +++ b/litespi/phy/generic_ddr.py @@ -73,16 +73,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 +134,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..ba887b9 100644 --- a/litespi/phy/generic_sdr.py +++ b/litespi/phy/generic_sdr.py @@ -92,16 +92,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 +156,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),