phy/gensdrphy: sample rddata on sys_clk (assume clk generated to sdram is shifted), add cmd_latency parameter and simplify control logic.

This commit is contained in:
Florent Kermarrec 2020-03-24 14:38:58 +01:00
parent ebdbcacc1d
commit 043666672d
1 changed files with 11 additions and 23 deletions

View File

@ -1,18 +1,7 @@
# This file is Copyright (c) 2012-2019 Florent Kermarrec <florent@enjoy-digital.fr>
# This file is Copyright (c) 2012-2020 Florent Kermarrec <florent@enjoy-digital.fr>
# License: BSD
# 1:1 frequency-ratio Generic SDR PHY
#
# The SDR PHY needs 2 Clock domains:
# - sys_clk : The System Clock domain
# - sys_clk_ps : The System Clock domain with its phase shifted by -3ns at 100Mhz
#
# Assert dfi_wrdata_en and present the data on dfi_wrdata_mask/dfi_wrdata in the
# same cycle as the write command.
#
# Assert dfi_rddata_en in the same cycle as the read command. The data will come
# back on dfi_rddata 4 cycles later, along with the assertion of dfi_rddata_valid.
#
from migen import *
from migen.genlib.record import *
@ -24,12 +13,13 @@ from litedram.phy.dfi import *
# Generic SDR PHY ----------------------------------------------------------------------------------
class GENSDRPHY(Module):
def __init__(self, pads, cl=2):
def __init__(self, pads, cl=2, cmd_latency=1):
pads = PHYPadsCombiner(pads)
addressbits = len(pads.a)
bankbits = len(pads.ba)
nranks = 1 if not hasattr(pads, "cs_n") else len(pads.cs_n)
databits = len(pads.dq)
assert cl in [2, 3]
assert databits%8 == 0
# PHY settings -----------------------------------------------------------------------------
@ -44,7 +34,7 @@ class GENSDRPHY(Module):
rdcmdphase = 0,
wrcmdphase = 0,
cl = cl,
read_latency = cl + 2,
read_latency = cl + cmd_latency,
write_latency = 0
)
@ -80,21 +70,19 @@ class GENSDRPHY(Module):
if hasattr(pads, "dm"):
assert len(pads.dm)*8 == databits
for i in range(len(pads.dm)):
self.sync += \
self.sync += [
pads.dm[i].eq(0),
If(dfi.p0.wrdata_en,
pads.dm[i].eq(dfi.p0.wrdata_mask)
).Else(
pads.dm[i].eq(0)
)
dq_in = Signal(databits)
self.sync.sys_ps += dq_in.eq(dq_i)
self.sync += dfi.p0.rddata.eq(dq_in)
]
self.sync += dfi.p0.rddata.eq(dq_i)
# DQ/DM Control ----------------------------------------------------------------------------
wrdata_en = Signal()
self.sync += wrdata_en.eq(dfi.p0.wrdata_en)
self.comb += dq_oe.eq(wrdata_en)
rddata_en = Signal(cl + 2)
self.sync += rddata_en.eq(Cat(dfi.p0.rddata_en, rddata_en[:cl + 1]))
self.comb += dfi.p0.rddata_valid.eq(rddata_en[cl + 1])
rddata_en = Signal(cl + cmd_latency)
self.sync += rddata_en.eq(Cat(dfi.p0.rddata_en, rddata_en))
self.sync += dfi.p0.rddata_valid.eq(rddata_en[-1])