From 26e45d1ce464200f817e41c25a0316da96fbe992 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 14 Sep 2020 18:57:20 +0200 Subject: [PATCH] phys: add support for dynamic rd/rdcmd/wr/wrcmd phases. --- litedram/phy/ecp5ddrphy.py | 7 +++++-- litedram/phy/s7ddrphy.py | 7 +++++-- litedram/phy/usddrphy.py | 7 +++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/litedram/phy/ecp5ddrphy.py b/litedram/phy/ecp5ddrphy.py index 304b774..fb59b0e 100644 --- a/litedram/phy/ecp5ddrphy.py +++ b/litedram/phy/ecp5ddrphy.py @@ -8,6 +8,9 @@ # 1:2 frequency-ratio DDR3 PHY for Lattice's ECP5 # DDR3: 800 MT/s +from functools import reduce +from operator import or_ + import math from migen import * @@ -438,7 +441,7 @@ class ECP5DDRPHY(Module, AutoCSR): # interface, the latency is the sum of the ODDRX2DQA, CAS, IDDRX2DQA latencies. rddata_en = Signal(self.settings.read_latency) rddata_en_last = Signal.like(rddata_en) - self.comb += rddata_en.eq(Cat(dfi.phases[self.settings.rdphase].rddata_en, rddata_en_last)) + self.comb += rddata_en.eq(Cat(reduce(or_, [dfi.phases[i].rddata_en for i in range(nphases)]), rddata_en_last)) self.sync += rddata_en_last.eq(rddata_en) self.sync += [phase.rddata_valid.eq(rddata_en[-1]) for phase in dfi.phases] self.comb += dqs_re.eq(rddata_en[cl_sys_latency + 1] | rddata_en[cl_sys_latency + 2]) @@ -452,7 +455,7 @@ class ECP5DDRPHY(Module, AutoCSR): # Writes are then performed in 2 sys_clk cycles and data needs to be selected for each cycle. wrdata_en = Signal(cwl_sys_latency + 4) wrdata_en_last = Signal.like(wrdata_en) - self.comb += wrdata_en.eq(Cat(dfi.phases[self.settings.wrphase].wrdata_en, wrdata_en_last)) + self.comb += wrdata_en.eq(Cat(reduce(or_, [dfi.phases[i].wrdata_en for i in range(nphases)]), wrdata_en_last)) self.sync += wrdata_en_last.eq(wrdata_en) self.comb += dq_oe.eq(wrdata_en[cwl_sys_latency + 1] | wrdata_en[cwl_sys_latency + 2]) self.comb += bl8_chunk.eq(wrdata_en[cwl_sys_latency + 1]) diff --git a/litedram/phy/s7ddrphy.py b/litedram/phy/s7ddrphy.py index 1e548f8..ed48ae8 100644 --- a/litedram/phy/s7ddrphy.py +++ b/litedram/phy/s7ddrphy.py @@ -9,6 +9,9 @@ # DDR2: 400, 533, 667, 800 and 1066 MT/s # DDR3: 800, 1066, 1333 and 1600 MT/s +from functools import reduce +from operator import or_ + import math from migen import * @@ -574,7 +577,7 @@ class S7DDRPHY(Module, AutoCSR): # interface, the latency is the sum of the OSERDESE2, CAS, ISERDESE2 and Bitslip latencies. rddata_en = Signal(self.settings.read_latency) rddata_en_last = Signal.like(rddata_en) - self.comb += rddata_en.eq(Cat(dfi.phases[self.settings.rdphase].rddata_en, rddata_en_last)) + self.comb += rddata_en.eq(Cat(reduce(or_, [dfi.phases[i].rddata_en for i in range(nphases)]), rddata_en_last)) self.sync += rddata_en_last.eq(rddata_en) self.sync += [phase.rddata_valid.eq(rddata_en[-1] | self._wlevel_en.storage) for phase in dfi.phases] @@ -583,7 +586,7 @@ class S7DDRPHY(Module, AutoCSR): # is used to control DQ/DQS tristates. wrdata_en = Signal(cwl_sys_latency + 2) wrdata_en_last = Signal.like(wrdata_en) - self.comb += wrdata_en.eq(Cat(dfi.phases[self.settings.wrphase].wrdata_en, wrdata_en_last)) + self.comb += wrdata_en.eq(Cat(reduce(or_, [dfi.phases[i].wrdata_en for i in range(nphases)]), wrdata_en_last)) self.sync += wrdata_en_last.eq(wrdata_en) self.comb += dq_oe.eq(wrdata_en[cwl_sys_latency]) self.comb += If(self._wlevel_en.storage, dqs_oe.eq(1)).Else(dqs_oe.eq(dq_oe)) diff --git a/litedram/phy/usddrphy.py b/litedram/phy/usddrphy.py index d3f37ac..6bdbebf 100644 --- a/litedram/phy/usddrphy.py +++ b/litedram/phy/usddrphy.py @@ -8,6 +8,9 @@ # DDR3: 800, 1066, 1333 and 1600 MT/s # DDR4: 1600 MT/s +from functools import reduce +from operator import or_ + import math from migen import * @@ -521,7 +524,7 @@ class USDDRPHY(Module, AutoCSR): # interface, the latency is the sum of the OSERDESE3, CAS, ISERDESE3 and Bitslip latencies. rddata_en = Signal(self.settings.read_latency) rddata_en_last = Signal.like(rddata_en) - self.comb += rddata_en.eq(Cat(dfi.phases[self.settings.rdphase].rddata_en, rddata_en_last)) + self.comb += rddata_en.eq(Cat(reduce(or_, [dfi.phases[i].rddata_en for i in range(nphases)]), rddata_en_last)) self.sync += rddata_en_last.eq(rddata_en) self.sync += [phase.rddata_valid.eq(rddata_en[-1] | self._wlevel_en.storage) for phase in dfi.phases] @@ -530,7 +533,7 @@ class USDDRPHY(Module, AutoCSR): # is used to control DQ/DQS tristates. wrdata_en = Signal(cwl_sys_latency + 2) wrdata_en_last = Signal.like(wrdata_en) - self.comb += wrdata_en.eq(Cat(dfi.phases[self.settings.wrphase].wrdata_en, wrdata_en_last)) + self.comb += wrdata_en.eq(Cat(reduce(or_, [dfi.phases[i].wrdata_en for i in range(nphases)]), wrdata_en_last)) self.sync += wrdata_en_last.eq(wrdata_en) self.comb += dq_oe.eq(wrdata_en[cwl_sys_latency]) self.comb += If(self._wlevel_en.storage, dqs_oe.eq(1)).Else(dqs_oe.eq(dq_oe))