Skip to content

Commit 0e83377

Browse files
Merge pull request #89 from VOGL-electronic/phy_sdr_extra_latency
phy: sdr: implement extra_latency
2 parents 5d28d03 + e24afb3 commit 0e83377

File tree

4 files changed

+34
-22
lines changed

4 files changed

+34
-22
lines changed

litespi/clkgen.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class LiteSPIClkGen(LiteXModule):
6565
en : Signal(), in
6666
Clock enable input, output clock will be generated if set to 1, 0 resets the core.
6767
"""
68-
def __init__(self, pads, device, cnt_width=8):
68+
def __init__(self, pads, device, cnt_width=8, extra_latency=0):
6969
self.div = div = Signal(cnt_width)
7070
self.posedge = posedge = Signal()
7171
self.negedge = negedge = Signal()
@@ -80,14 +80,15 @@ def __init__(self, pads, device, cnt_width=8):
8080
]
8181

8282
# Delayed edge to account for IO register delays.
83-
self.posedge_reg = posedge_reg = Signal()
83+
posedge_reg = Signal(1 + 1 + int(extra_latency))
8484
self.posedge_reg2 = posedge_reg2 = Signal()
8585

8686
self.sync += [
87-
posedge_reg.eq(posedge),
88-
posedge_reg2.eq(posedge_reg),
87+
posedge_reg.eq(Cat(posedge_reg[1:], posedge)),
8988
]
9089

90+
self.comb += posedge_reg2.eq(posedge_reg[:1])
91+
9192
self.sync += [
9293
If(en | en_int,
9394
If(cnt < div,

litespi/phy/generic.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ class LiteSPIPHY(LiteXModule):
4141
rate : str
4242
Rate: 1:1 SDR, 1:2 DDR.
4343
44-
extra_latency : int (1:2 rate)
45-
Compensate for additional DDROutput/Input latency
44+
extra_latency : int
45+
Compensate for additional Output/Input latency
4646
4747
Attributes
4848
----------
@@ -56,12 +56,12 @@ class LiteSPIPHY(LiteXModule):
5656
Flash CS signal from ``LiteSPIPHYCore``.
5757
"""
5858

59-
def __init__(self, pads, flash, device="xc7", clock_domain="sys", default_divisor=9, cs_delay=10, rate="1:1", extra_latency=0, **kwargs):
59+
def __init__(self, pads, flash, device="xc7", clock_domain="sys", default_divisor=9, cs_delay=10, rate="1:1", **kwargs):
6060
assert rate in ["1:1", "1:2"]
6161
if rate == "1:1":
62-
phy = LiteSPISDRPHYCore(pads, flash, device, clock_domain, default_divisor, cs_delay)
62+
phy = LiteSPISDRPHYCore(pads, flash, device, clock_domain, default_divisor, cs_delay, **kwargs)
6363
if rate == "1:2":
64-
phy = LiteSPIDDRPHYCore(pads, flash, cs_delay, extra_latency)
64+
phy = LiteSPIDDRPHYCore(pads, flash, cs_delay, **kwargs)
6565

6666
self.flash = flash
6767

litespi/phy/generic_ddr.py

Lines changed: 1 addition & 1 deletion
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):
55+
def __init__(self, pads, flash, cs_delay, 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)

litespi/phy/generic_sdr.py

Lines changed: 23 additions & 12 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):
62+
def __init__(self, pads, flash, device, clock_domain, default_divisor, cs_delay, 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)
@@ -87,7 +87,7 @@ def __init__(self, pads, flash, device, clock_domain, default_divisor, cs_delay)
8787
assert not flash.ddr
8888

8989
# Clock Generator.
90-
self.clkgen = clkgen = LiteSPIClkGen(pads, device)
90+
self.clkgen = clkgen = LiteSPIClkGen(pads, device, extra_latency=extra_latency)
9191

9292
# CS control.
9393
self.cs_control = cs_control = LiteSPICSControl(pads, self.cs, cs_delay)
@@ -119,7 +119,8 @@ def __init__(self, pads, flash, device, clock_domain, default_divisor, cs_delay)
119119
)
120120

121121
# Data Shift Registers.
122-
sr_cnt = Signal(8, reset_less=True)
122+
sr_out_cnt = Signal(len(sink.len), reset_less=True)
123+
sr_in_cnt = Signal(len(sink.len), reset_less=True)
123124
sr_out_load = Signal()
124125
sr_out_shift = Signal()
125126
sr_out = Signal().like(sink.data)
@@ -159,7 +160,8 @@ def __init__(self, pads, flash, device, clock_domain, default_divisor, cs_delay)
159160
# Wait for CS and a CMD from the Core.
160161
If(cs_control.enable & sink.valid,
161162
# Load Shift Register Count/Data Out.
162-
NextValue(sr_cnt, sink.len - sink.width),
163+
NextValue(sr_out_cnt, sink.len - sink.width),
164+
NextValue(sr_in_cnt, sink.len),
163165
NextValue(dq_oe, sink.mask),
164166
sr_out_load.eq(1),
165167
# Start XFER.
@@ -177,25 +179,34 @@ def __init__(self, pads, flash, device, clock_domain, default_divisor, cs_delay)
177179
If(clkgen.negedge, sr_out_shift.eq(1)),
178180

179181
# Shift Register Count Update/Check.
182+
If(clkgen.posedge_reg2,
183+
NextValue(sr_in_cnt, sr_in_cnt - sink.width),
184+
),
180185
If(self.clkgen.negedge,
181-
NextValue(sr_cnt, sr_cnt - sink.width),
186+
NextValue(sr_out_cnt, sr_out_cnt - sink.width),
182187
# End XFer.
183-
If(sr_cnt == 0,
188+
If(sr_out_cnt == 0,
184189
NextState("XFER-END"),
185190
),
186191
),
187192

188193
)
189194
fsm.act("XFER-END",
190-
# Last data already captured in XFER when divisor > 0 so only capture for divisor == 0.
191-
If((spi_clk_divisor > 0) | clkgen.posedge_reg2,
192-
# Accept CMD.
195+
If(sr_in_cnt == 0,
193196
sink.ready.eq(1),
194-
# Capture last data (only for spi_clk_divisor == 0).
195-
sr_in_shift.eq(spi_clk_divisor == 0),
196197
# Send Status/Data to Core.
197198
NextState("SEND-STATUS-DATA"),
198-
)
199+
).Else(
200+
sr_in_shift.eq(clkgen.posedge_reg2),
201+
If(clkgen.posedge_reg2,
202+
NextValue(sr_in_cnt, sr_in_cnt - sink.width),
203+
If(sr_in_cnt == sink.width,
204+
sink.ready.eq(1),
205+
# Send Status/Data to Core.
206+
NextState("SEND-STATUS-DATA"),
207+
),
208+
),
209+
),
199210
)
200211
self.comb += source.data.eq(sr_in)
201212
fsm.act("SEND-STATUS-DATA",

0 commit comments

Comments
 (0)