From 043666672d5ebb20945b0b76d3b0ac89c749841c Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Tue, 24 Mar 2020 14:38:58 +0100 Subject: [PATCH] phy/gensdrphy: sample rddata on sys_clk (assume clk generated to sdram is shifted), add cmd_latency parameter and simplify control logic. --- litedram/phy/gensdrphy.py | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/litedram/phy/gensdrphy.py b/litedram/phy/gensdrphy.py index f80c39d..3616726 100644 --- a/litedram/phy/gensdrphy.py +++ b/litedram/phy/gensdrphy.py @@ -1,18 +1,7 @@ -# This file is Copyright (c) 2012-2019 Florent Kermarrec +# This file is Copyright (c) 2012-2020 Florent Kermarrec # 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])