Skip to content

Commit d3bc37a

Browse files
committed
phy: start cs timer already when cs is falling
start cs timer already when cs is falling, instead of when it's going to be used. Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
1 parent e2ba7ad commit d3bc37a

5 files changed

Lines changed: 33 additions & 17 deletions

File tree

litespi/cscontrol.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,33 @@
1111
from litex.build.io import SDROutput
1212

1313
class LiteSPICSControl(LiteXModule):
14-
def __init__(self, pads, cs, cs_delay):
14+
def __init__(self, pads, cs, cs_delay=10, with_sdr_cs=True, **kwargs):
1515
self.enable = enable = Signal()
1616
cs_n = Signal().like(pads.cs_n)
17+
last_cs = Signal()
1718

1819
self.timer = timer = WaitTimer(cs_delay + 1) # Ensure cs_delay cycles between XFers.
19-
20-
self.comb += timer.wait.eq(cs != 0)
21-
self.comb += enable.eq(timer.done)
20+
21+
if len(pads.cs_n) > 1:
22+
# Remember last active CS when multiple CS lines are used, so we only wait when
23+
# the same CS line is active again
24+
last_active_cs = Signal(len(cs))
25+
self.sync += If(enable, last_active_cs.eq(cs))
26+
27+
enable_cond = timer.done | (last_active_cs != cs)
28+
else:
29+
enable_cond = timer.done
30+
31+
self.sync += last_cs.eq(cs != 0)
32+
33+
self.comb += timer.wait.eq(~((cs == 0) & last_cs)) # Reset wait on falling edge of cs
34+
self.comb += enable.eq((cs != 0) & enable_cond)
2235
self.comb += cs_n.eq(~(Replicate(enable, len(pads.cs_n)) & cs))
2336

24-
self.specials += SDROutput(
25-
i = cs_n,
26-
o = pads.cs_n
27-
)
37+
if with_sdr_cs:
38+
self.specials += SDROutput(
39+
i = cs_n,
40+
o = pads.cs_n
41+
)
42+
else:
43+
self.comb += pads.cs_n.eq(cs_n)

litespi/phy/generic.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ class LiteSPIPHY(LiteXModule):
5757
Flash CS signal from ``LiteSPIPHYCore``.
5858
"""
5959

60-
def __init__(self, pads, flash, device="xc7", clock_domain="sys", default_divisor=9, cs_delay=10, rate="1:1", **kwargs):
60+
def __init__(self, pads, flash, device="xc7", clock_domain="sys", rate="1:1", **kwargs):
6161
assert rate in ["1:1", "1:2"]
6262
if rate == "1:1":
63-
phy = LiteSPISDRPHYCore(pads, flash, device, clock_domain, default_divisor, cs_delay, **kwargs)
63+
phy = LiteSPISDRPHYCore(pads, flash, device, clock_domain, **kwargs)
6464
if rate == "1:2":
65-
phy = LiteSPIDDRPHYCore2(pads, flash, clock_domain, default_divisor, cs_delay, **kwargs)
65+
phy = LiteSPIDDRPHYCore2(pads, flash, clock_domain, **kwargs)
6666

6767
self.flash = flash
6868

litespi/phy/generic_ddr.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class LiteSPIDDRPHYCore(LiteXModule):
5252
cs : Signal(), in
5353
Flash CS signal.
5454
"""
55-
def __init__(self, pads, flash, cs_delay, extra_latency=0, **kwargs):
55+
def __init__(self, pads, flash, extra_latency=0, **kwargs):
5656
self.source = source = stream.Endpoint(spi_phy2core_layout)
5757
self.sink = sink = stream.Endpoint(spi_core2phy_layout)
5858
self.cs = Signal().like(pads.cs_n)
@@ -74,7 +74,7 @@ def __init__(self, pads, flash, cs_delay, extra_latency=0, **kwargs):
7474
self.clkgen = clkgen = DDRLiteSPIClkGen(pads)
7575

7676
# CS control.
77-
self.cs_control = cs_control = LiteSPICSControl(pads, self.cs, cs_delay)
77+
self.cs_control = cs_control = LiteSPICSControl(pads, self.cs, **kwargs)
7878

7979
dq_o = Array([Signal(len(pads.dq)) for _ in range(2)])
8080
dq_i = Array([Signal(len(pads.dq)) for _ in range(2)])

litespi/phy/generic_ddr_with_clk.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class LiteSPIDDRPHYCore2(LiteXModule):
5656
clk_divisor : CSRStorage
5757
Register which holds a clock divisor value applied to clkgen.
5858
"""
59-
def __init__(self, pads, flash, clock_domain, default_divisor, cs_delay, extra_latency=0, **kwargs):
59+
def __init__(self, pads, flash, clock_domain, default_divisor=9, extra_latency=0, **kwargs):
6060
self.source = source = stream.Endpoint(spi_phy2core_layout)
6161
self.sink = sink = stream.Endpoint(spi_core2phy_layout)
6262
self.cs = Signal().like(pads.cs_n)
@@ -89,7 +89,7 @@ def __init__(self, pads, flash, clock_domain, default_divisor, cs_delay, extra_l
8989
self.clkgen = clkgen = LiteSPIClkGen2(pads, div_width=len(sink.clk_div), extra_latency=2*extra_latency)
9090

9191
# CS control.
92-
self.cs_control = cs_control = LiteSPICSControl(pads, self.cs, cs_delay)
92+
self.cs_control = cs_control = LiteSPICSControl(pads, self.cs, **kwargs)
9393

9494
# Only Clk Divisor when not active or when set by core.
9595
self.sync += [

litespi/phy/generic_sdr.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class LiteSPISDRPHYCore(LiteXModule):
5959
clk_divisor : CSRStorage
6060
Register which holds a clock divisor value applied to clkgen.
6161
"""
62-
def __init__(self, pads, flash, device, clock_domain, default_divisor, cs_delay, extra_latency=0, **kwargs):
62+
def __init__(self, pads, flash, device, clock_domain, default_divisor=9, extra_latency=0, **kwargs):
6363
self.source = source = stream.Endpoint(spi_phy2core_layout)
6464
self.sink = sink = stream.Endpoint(spi_core2phy_layout)
6565
self.cs = Signal().like(pads.cs_n)
@@ -90,7 +90,7 @@ def __init__(self, pads, flash, device, clock_domain, default_divisor, cs_delay,
9090
self.clkgen = clkgen = LiteSPIClkGen(pads, device, div_width=len(sink.clk_div), extra_latency=extra_latency)
9191

9292
# CS control.
93-
self.cs_control = cs_control = LiteSPICSControl(pads, self.cs, cs_delay)
93+
self.cs_control = cs_control = LiteSPICSControl(pads, self.cs, **kwargs)
9494

9595
# Only Clk Divisor when not active or when set by core.
9696
self.sync += [

0 commit comments

Comments
 (0)