mirror of
https://github.com/enjoy-digital/litedram.git
synced 2025-01-04 09:52:25 -05:00
multirank: one cs_n/cke/odt/clk per rank
This commit is contained in:
parent
3e17d18b0c
commit
37f1decfb2
6 changed files with 37 additions and 62 deletions
|
@ -69,9 +69,12 @@ def get_dram_ios(core_config):
|
||||||
"X "*2*core_config["sdram_module_nb"])),
|
"X "*2*core_config["sdram_module_nb"])),
|
||||||
Subsignal("dqs_n", Pins(
|
Subsignal("dqs_n", Pins(
|
||||||
"X "*2*core_config["sdram_module_nb"])),
|
"X "*2*core_config["sdram_module_nb"])),
|
||||||
Subsignal("clk_p", Pins("X")),
|
Subsignal("clk_p", Pins(
|
||||||
Subsignal("clk_n", Pins("X")),
|
"X "*core_config["sdram_rank_nb"])),
|
||||||
Subsignal("cke", Pins("X")),
|
Subsignal("clk_n", Pins(
|
||||||
|
"X "*core_config["sdram_rank_nb"])),
|
||||||
|
Subsignal("cke", Pins(
|
||||||
|
"X "*core_config["sdram_rank_nb"])),
|
||||||
Subsignal("odt", Pins(
|
Subsignal("odt", Pins(
|
||||||
"X "*core_config["sdram_rank_nb"])),
|
"X "*core_config["sdram_rank_nb"])),
|
||||||
Subsignal("reset_n", Pins("X"))
|
Subsignal("reset_n", Pins("X"))
|
||||||
|
|
|
@ -94,12 +94,11 @@ class _Steerer(Module):
|
||||||
return cmd.valid & getattr(cmd, attr)
|
return cmd.valid & getattr(cmd, attr)
|
||||||
|
|
||||||
for phase, sel in zip(dfi.phases, self.sel):
|
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)
|
nranks = len(phase.cs_n)
|
||||||
rankbits = log2_int(nranks)
|
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"):
|
if hasattr(phase, "odt"):
|
||||||
self.comb += phase.odt.eq(2**rankbits - 1) # FIXME: dynamic drive for multi-rank
|
self.comb += phase.odt.eq(2**rankbits - 1) # FIXME: dynamic drive for multi-rank
|
||||||
if rankbits:
|
if rankbits:
|
||||||
|
|
|
@ -55,6 +55,7 @@ class DFIInjector(Module, AutoCSR):
|
||||||
).Else(
|
).Else(
|
||||||
inti.connect(self.master)
|
inti.connect(self.master)
|
||||||
)
|
)
|
||||||
self.comb += [phase.cke.eq(self._control.storage[1]) for phase in inti.phases]
|
for i in range(nranks):
|
||||||
self.comb += [phase.odt.eq(self._control.storage[2]) for phase in inti.phases if hasattr(phase, "odt")]
|
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")]
|
self.comb += [phase.reset_n.eq(self._control.storage[3]) for phase in inti.phases if hasattr(phase, "reset_n")]
|
||||||
|
|
|
@ -7,11 +7,11 @@ def phase_cmd_description(addressbits, bankbits, nranks):
|
||||||
("address", addressbits, DIR_M_TO_S),
|
("address", addressbits, DIR_M_TO_S),
|
||||||
("bank", bankbits, DIR_M_TO_S),
|
("bank", bankbits, DIR_M_TO_S),
|
||||||
("cas_n", 1, 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),
|
("ras_n", 1, DIR_M_TO_S),
|
||||||
("we_n", 1, DIR_M_TO_S),
|
("we_n", 1, DIR_M_TO_S),
|
||||||
("cke", 1, DIR_M_TO_S),
|
("cke", nranks, DIR_M_TO_S),
|
||||||
("odt", 1, DIR_M_TO_S),
|
("odt", nranks, DIR_M_TO_S),
|
||||||
("reset_n", 1, DIR_M_TO_S)
|
("reset_n", 1, DIR_M_TO_S)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -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_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]
|
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"):
|
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 += \
|
self.specials += \
|
||||||
Instance("OSERDESE2",
|
Instance("OSERDESE2",
|
||||||
p_DATA_WIDTH=2*nphases, p_TRISTATE_WIDTH=1,
|
p_DATA_WIDTH=2*nphases, p_TRISTATE_WIDTH=1,
|
||||||
p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
|
p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
|
||||||
p_SERDES_MODE="MASTER",
|
p_SERDES_MODE="MASTER",
|
||||||
|
|
||||||
o_OQ=pads.cs_n[i],
|
o_OQ=getattr(pads, name)[i],
|
||||||
i_OCE=1,
|
i_OCE=1,
|
||||||
i_RST=ResetSignal(),
|
i_RST=ResetSignal(),
|
||||||
i_CLK=ClockSignal(ddr_clk), i_CLKDIV=ClockSignal(),
|
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_D1=getattr(self.dfi.phases[0], name)[i], i_D2=getattr(self.dfi.phases[0], name)[i],
|
||||||
i_D3=self.dfi.phases[1].cs_n[i], i_D4=self.dfi.phases[1].cs_n[i],
|
i_D3=getattr(self.dfi.phases[1], name)[i], i_D4=getattr(self.dfi.phases[1], name)[i],
|
||||||
i_D5=self.dfi.phases[2].cs_n[i], i_D6=self.dfi.phases[2].cs_n[i],
|
i_D5=getattr(self.dfi.phases[2], name)[i], i_D6=getattr(self.dfi.phases[2], name)[i],
|
||||||
i_D7=self.dfi.phases[3].cs_n[i], i_D8=self.dfi.phases[3].cs_n[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
|
# DQS and DM
|
||||||
oe_dqs = Signal()
|
oe_dqs = Signal()
|
||||||
|
|
|
@ -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_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]
|
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"):
|
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 += \
|
self.specials += \
|
||||||
Instance("OSERDESE2",
|
Instance("OSERDESE2",
|
||||||
p_DATA_WIDTH=2*nphases, p_TRISTATE_WIDTH=1,
|
p_DATA_WIDTH=2*nphases, p_TRISTATE_WIDTH=1,
|
||||||
p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
|
p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
|
||||||
p_SERDES_MODE="MASTER",
|
p_SERDES_MODE="MASTER",
|
||||||
|
|
||||||
o_OQ=pads.cs_n[i],
|
o_OQ=getattr(pads, name)[i],
|
||||||
i_OCE=1,
|
i_OCE=1,
|
||||||
i_RST=ResetSignal(),
|
i_RST=ResetSignal(),
|
||||||
i_CLK=ClockSignal(ddr_clk), i_CLKDIV=ClockSignal(),
|
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_D1=getattr(self.dfi.phases[0], name)[i], i_D2=getattr(self.dfi.phases[0], name)[i],
|
||||||
i_D3=self.dfi.phases[1].cs_n[i], i_D4=self.dfi.phases[1].cs_n[i],
|
i_D3=getattr(self.dfi.phases[1], name)[i], i_D4=getattr(self.dfi.phases[1], name)[i],
|
||||||
i_D5=self.dfi.phases[2].cs_n[i], i_D6=self.dfi.phases[2].cs_n[i],
|
i_D5=getattr(self.dfi.phases[2], name)[i], i_D6=getattr(self.dfi.phases[2], name)[i],
|
||||||
i_D7=self.dfi.phases[3].cs_n[i], i_D8=self.dfi.phases[3].cs_n[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
|
# DQS and DM
|
||||||
oe_dqs = Signal()
|
oe_dqs = Signal()
|
||||||
|
|
Loading…
Reference in a new issue