From 37f1decfb2784bb911735d3c8c1e93e916ce3b7d Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Sun, 9 Sep 2018 14:30:29 +0200 Subject: [PATCH] multirank: one cs_n/cke/odt/clk per rank --- examples/litedram_gen.py | 9 ++++--- litedram/core/multiplexer.py | 7 +++--- litedram/dfii.py | 5 ++-- litedram/phy/dfi.py | 6 ++--- litedram/phy/s7ddrphy.py | 36 ++++++++------------------- litedram/phy/s7ddrphy_halfrate_bl8.py | 36 ++++++++------------------- 6 files changed, 37 insertions(+), 62 deletions(-) diff --git a/examples/litedram_gen.py b/examples/litedram_gen.py index eec2f13..2b7b1e7 100755 --- a/examples/litedram_gen.py +++ b/examples/litedram_gen.py @@ -69,9 +69,12 @@ def get_dram_ios(core_config): "X "*2*core_config["sdram_module_nb"])), Subsignal("dqs_n", Pins( "X "*2*core_config["sdram_module_nb"])), - Subsignal("clk_p", Pins("X")), - Subsignal("clk_n", Pins("X")), - Subsignal("cke", Pins("X")), + Subsignal("clk_p", Pins( + "X "*core_config["sdram_rank_nb"])), + Subsignal("clk_n", Pins( + "X "*core_config["sdram_rank_nb"])), + Subsignal("cke", Pins( + "X "*core_config["sdram_rank_nb"])), Subsignal("odt", Pins( "X "*core_config["sdram_rank_nb"])), Subsignal("reset_n", Pins("X")) diff --git a/litedram/core/multiplexer.py b/litedram/core/multiplexer.py index a731518..2783a02 100644 --- a/litedram/core/multiplexer.py +++ b/litedram/core/multiplexer.py @@ -94,12 +94,11 @@ class _Steerer(Module): return cmd.valid & getattr(cmd, attr) for phase, sel in zip(dfi.phases, self.sel): - self.comb += phase.cke.eq(1) - if hasattr(phase, "reset_n"): - self.comb += phase.reset_n.eq(1) - nranks = len(phase.cs_n) rankbits = log2_int(nranks) + if hasattr(phase, "reset_n"): + self.comb += phase.reset_n.eq(1) + self.comb += phase.cke.eq(2**rankbits - 1) if hasattr(phase, "odt"): self.comb += phase.odt.eq(2**rankbits - 1) # FIXME: dynamic drive for multi-rank if rankbits: diff --git a/litedram/dfii.py b/litedram/dfii.py index 1e0e5c0..af86726 100644 --- a/litedram/dfii.py +++ b/litedram/dfii.py @@ -55,6 +55,7 @@ class DFIInjector(Module, AutoCSR): ).Else( inti.connect(self.master) ) - self.comb += [phase.cke.eq(self._control.storage[1]) for phase in inti.phases] - self.comb += [phase.odt.eq(self._control.storage[2]) for phase in inti.phases if hasattr(phase, "odt")] + for i in range(nranks): + self.comb += [phase.cke[i].eq(self._control.storage[1]) for phase in inti.phases] + self.comb += [phase.odt[i].eq(self._control.storage[2]) for phase in inti.phases if hasattr(phase, "odt")] self.comb += [phase.reset_n.eq(self._control.storage[3]) for phase in inti.phases if hasattr(phase, "reset_n")] diff --git a/litedram/phy/dfi.py b/litedram/phy/dfi.py index 8eef84a..63f4a3b 100644 --- a/litedram/phy/dfi.py +++ b/litedram/phy/dfi.py @@ -7,11 +7,11 @@ def phase_cmd_description(addressbits, bankbits, nranks): ("address", addressbits, DIR_M_TO_S), ("bank", bankbits, DIR_M_TO_S), ("cas_n", 1, DIR_M_TO_S), - ("cs_n", nranks, DIR_M_TO_S), + ("cs_n", nranks, DIR_M_TO_S), ("ras_n", 1, DIR_M_TO_S), ("we_n", 1, DIR_M_TO_S), - ("cke", 1, DIR_M_TO_S), - ("odt", 1, DIR_M_TO_S), + ("cke", nranks, DIR_M_TO_S), + ("odt", nranks, DIR_M_TO_S), ("reset_n", 1, DIR_M_TO_S) ] diff --git a/litedram/phy/s7ddrphy.py b/litedram/phy/s7ddrphy.py index 895b87f..b5e2877 100644 --- a/litedram/phy/s7ddrphy.py +++ b/litedram/phy/s7ddrphy.py @@ -161,42 +161,28 @@ class S7DDRPHY(Module, AutoCSR): i_D5=self.dfi.phases[2].bank[i], i_D6=self.dfi.phases[2].bank[i], i_D7=self.dfi.phases[3].bank[i], i_D8=self.dfi.phases[3].bank[i] ) + controls = ["ras_n", "cas_n", "we_n", "cke", "odt"] + if hasattr(pads, "reset_n"): + controls.append("reset_n") if hasattr(pads, "cs_n"): - for i in range(nranks): + controls.append("reset_n") + for name in controls: + for i in range(len(getattr(pads, name))): self.specials += \ Instance("OSERDESE2", p_DATA_WIDTH=2*nphases, p_TRISTATE_WIDTH=1, p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF", p_SERDES_MODE="MASTER", - o_OQ=pads.cs_n[i], + o_OQ=getattr(pads, name)[i], i_OCE=1, i_RST=ResetSignal(), i_CLK=ClockSignal(ddr_clk), i_CLKDIV=ClockSignal(), - i_D1=self.dfi.phases[0].cs_n[i], i_D2=self.dfi.phases[0].cs_n[i], - i_D3=self.dfi.phases[1].cs_n[i], i_D4=self.dfi.phases[1].cs_n[i], - i_D5=self.dfi.phases[2].cs_n[i], i_D6=self.dfi.phases[2].cs_n[i], - i_D7=self.dfi.phases[3].cs_n[i], i_D8=self.dfi.phases[3].cs_n[i] + i_D1=getattr(self.dfi.phases[0], name)[i], i_D2=getattr(self.dfi.phases[0], name)[i], + i_D3=getattr(self.dfi.phases[1], name)[i], i_D4=getattr(self.dfi.phases[1], name)[i], + i_D5=getattr(self.dfi.phases[2], name)[i], i_D6=getattr(self.dfi.phases[2], name)[i], + i_D7=getattr(self.dfi.phases[3], name)[i], i_D8=getattr(self.dfi.phases[3], name)[i] ) - controls = ["ras_n", "cas_n", "we_n", "cke", "odt"] - if hasattr(pads, "reset_n"): - controls.append("reset_n") - for name in controls: - self.specials += \ - Instance("OSERDESE2", - p_DATA_WIDTH=2*nphases, p_TRISTATE_WIDTH=1, - p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF", - p_SERDES_MODE="MASTER", - - o_OQ=getattr(pads, name), - i_OCE=1, - i_RST=ResetSignal(), - i_CLK=ClockSignal(ddr_clk), i_CLKDIV=ClockSignal(), - i_D1=getattr(self.dfi.phases[0], name), i_D2=getattr(self.dfi.phases[0], name), - i_D3=getattr(self.dfi.phases[1], name), i_D4=getattr(self.dfi.phases[1], name), - i_D5=getattr(self.dfi.phases[2], name), i_D6=getattr(self.dfi.phases[2], name), - i_D7=getattr(self.dfi.phases[3], name), i_D8=getattr(self.dfi.phases[3], name) - ) # DQS and DM oe_dqs = Signal() diff --git a/litedram/phy/s7ddrphy_halfrate_bl8.py b/litedram/phy/s7ddrphy_halfrate_bl8.py index d34094e..f84f4ab 100644 --- a/litedram/phy/s7ddrphy_halfrate_bl8.py +++ b/litedram/phy/s7ddrphy_halfrate_bl8.py @@ -162,42 +162,28 @@ class S7DDRPHY(Module, AutoCSR): i_D5=self.dfi.phases[2].bank[i], i_D6=self.dfi.phases[2].bank[i], i_D7=self.dfi.phases[3].bank[i], i_D8=self.dfi.phases[3].bank[i] ) + controls = ["ras_n", "cas_n", "we_n", "cke", "odt"] + if hasattr(pads, "reset_n"): + controls.append("reset_n") if hasattr(pads, "cs_n"): - for i in range(nranks): + controls.append("reset_n") + for name in controls: + for i in range(len(getattr(pads, name))): self.specials += \ Instance("OSERDESE2", p_DATA_WIDTH=2*nphases, p_TRISTATE_WIDTH=1, p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF", p_SERDES_MODE="MASTER", - o_OQ=pads.cs_n[i], + o_OQ=getattr(pads, name)[i], i_OCE=1, i_RST=ResetSignal(), i_CLK=ClockSignal(ddr_clk), i_CLKDIV=ClockSignal(), - i_D1=self.dfi.phases[0].cs_n[i], i_D2=self.dfi.phases[0].cs_n[i], - i_D3=self.dfi.phases[1].cs_n[i], i_D4=self.dfi.phases[1].cs_n[i], - i_D5=self.dfi.phases[2].cs_n[i], i_D6=self.dfi.phases[2].cs_n[i], - i_D7=self.dfi.phases[3].cs_n[i], i_D8=self.dfi.phases[3].cs_n[i] + i_D1=getattr(self.dfi.phases[0], name)[i], i_D2=getattr(self.dfi.phases[0], name)[i], + i_D3=getattr(self.dfi.phases[1], name)[i], i_D4=getattr(self.dfi.phases[1], name)[i], + i_D5=getattr(self.dfi.phases[2], name)[i], i_D6=getattr(self.dfi.phases[2], name)[i], + i_D7=getattr(self.dfi.phases[3], name)[i], i_D8=getattr(self.dfi.phases[3], name)[i] ) - controls = ["ras_n", "cas_n", "we_n", "cke", "odt"] - if hasattr(pads, "reset_n"): - controls.append("reset_n") - for name in controls: - self.specials += \ - Instance("OSERDESE2", - p_DATA_WIDTH=2*nphases, p_TRISTATE_WIDTH=1, - p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF", - p_SERDES_MODE="MASTER", - - o_OQ=getattr(pads, name), - i_OCE=1, - i_RST=ResetSignal(), - i_CLK=ClockSignal(ddr_clk), i_CLKDIV=ClockSignal(), - i_D1=getattr(self.dfi.phases[0], name), i_D2=getattr(self.dfi.phases[0], name), - i_D3=getattr(self.dfi.phases[1], name), i_D4=getattr(self.dfi.phases[1], name), - i_D5=getattr(self.dfi.phases[2], name), i_D6=getattr(self.dfi.phases[2], name), - i_D7=getattr(self.dfi.phases[3], name), i_D8=getattr(self.dfi.phases[3], name) - ) # DQS and DM oe_dqs = Signal()