From c01e86865f61b030a66c27e59f95778b8af29fea Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 24 Jul 2020 11:07:15 +0200 Subject: [PATCH] phy/gensdrphy/HalfRateGENSDRPHY: review/simplify and reduce read_latency by 1. --- litedram/phy/gensdrphy.py | 70 +++++++++++++++------------------------ 1 file changed, 26 insertions(+), 44 deletions(-) diff --git a/litedram/phy/gensdrphy.py b/litedram/phy/gensdrphy.py index 7f2df98..f95e3b2 100644 --- a/litedram/phy/gensdrphy.py +++ b/litedram/phy/gensdrphy.py @@ -92,6 +92,18 @@ class HalfRateGENSDRPHY(Module): full_rate_phy = GENSDRPHY(pads, cl, cmd_latency) self.submodules += ClockDomainsRenamer("sys2x")(full_rate_phy) + # Clocking --------------------------------------------------------------------------------- + # Select active sys2x phase: + # sys_clk ----____----____ + # sys2x_clk --__--__--__--__ + # phase_sel 0 1 0 1 + phase_sel = Signal() + phase_sys = Signal() + phase_sys2x = Signal() + self.sync += phase_sys.eq(phase_sys2x) + self.sync.sys2x += phase_sys2x.eq(~phase_sel) + self.sync.sys2x += phase_sel.eq(~phase_sel & (phase_sys2x ^ phase_sys)) + # PHY settings ----------------------------------------------------------------------------- self.settings = PhySettings( phytype = "HalfRateGENSDRPHY", @@ -105,59 +117,29 @@ class HalfRateGENSDRPHY(Module): rdcmdphase = 1, wrcmdphase = 1, cl = cl, - read_latency = (cl + cmd_latency)//2 + 2, # FIXME: should be possible to have 1 cycle less latency + read_latency = (cl + cmd_latency)//2 + 1, write_latency = 0 ) # DFI adaptation --------------------------------------------------------------------------- self.dfi = dfi = Interface(addressbits, bankbits, nranks, databits, nphases) + self.comb += Case(phase_sel, { + 0: dfi.phases[0].connect(full_rate_phy.dfi.phases[0], omit={"rddata", "rddata_valid", "wrdata_en"}), + 1: dfi.phases[1].connect(full_rate_phy.dfi.phases[0], omit={"rddata", "rddata_valid", "wrdata_en"}), + }) - # Clock ------------------------------------------------------------------------------------ - - # select active sys2x phase - # sys_clk ----____----____ - # phase_sel 0 1 0 1 - self.phase_sel = phase_sel = Signal() - phase_sys2x = Signal.like(phase_sel) - phase_sys = Signal.like(phase_sys2x) - - self.sync += phase_sys.eq(phase_sys2x) - - self.sync.sys2x += [ - If(phase_sys2x == phase_sys, - phase_sel.eq(0), - ).Else( - phase_sel.eq(~phase_sel) - ), - phase_sys2x.eq(~phase_sel) - ] - - # Commands and address - dfi_omit = set(["rddata", "rddata_valid", "wrdata_en"]) - self.comb += [ - If(~phase_sel, - dfi.phases[0].connect(full_rate_phy.dfi.phases[0], omit=dfi_omit), - ).Else( - dfi.phases[1].connect(full_rate_phy.dfi.phases[0], omit=dfi_omit), - ), - ] - wr_data_en = dfi.phases[self.settings.wrphase].wrdata_en & ~phase_sel + # Write Datapath + wr_data_en = dfi.phases[self.settings.wrphase].wrdata_en & (phase_sel == 0) wr_data_en_d = Signal() self.sync.sys2x += wr_data_en_d.eq(wr_data_en) self.comb += full_rate_phy.dfi.phases[0].wrdata_en.eq(wr_data_en | wr_data_en_d) - # Reads - rddata = Signal(databits) - rddata_valid = Signal() - - self.sync.sys2x += [ - rddata_valid.eq(full_rate_phy.dfi.phases[0].rddata_valid), - rddata.eq(full_rate_phy.dfi.phases[0].rddata) - ] - - self.sync += [ - dfi.phases[0].rddata.eq(rddata), - dfi.phases[0].rddata_valid.eq(rddata_valid), + # Read Datapath + rddata_d = Signal(databits) + self.sync.sys2x += rddata_d.eq(full_rate_phy.dfi.phases[0].rddata) + self.comb += [ + dfi.phases[0].rddata.eq(rddata_d), + dfi.phases[0].rddata_valid.eq(full_rate_phy.dfi.phases[0].rddata_valid), dfi.phases[1].rddata.eq(full_rate_phy.dfi.phases[0].rddata), - dfi.phases[1].rddata_valid.eq(rddata_valid), + dfi.phases[1].rddata_valid.eq(full_rate_phy.dfi.phases[0].rddata_valid), ]