mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
sdram/phy/s6ddrphy: add DDR3 support
This commit is contained in:
parent
52fba05e26
commit
c03ef526eb
1 changed files with 51 additions and 27 deletions
|
@ -9,7 +9,9 @@
|
||||||
# 5 cycles later, along with the assertion
|
# 5 cycles later, along with the assertion
|
||||||
# of dfi_rddata_valid.
|
# of dfi_rddata_valid.
|
||||||
#
|
#
|
||||||
# This PHY only supports CAS Latency 3.
|
# This PHY only supports CAS latency 3 for DDR, LPDDR, DDR2
|
||||||
|
# and CAS latency 5/CAS write latency 6 for DDR3.
|
||||||
|
#
|
||||||
# Read commands must be sent on phase 0.
|
# Read commands must be sent on phase 0.
|
||||||
# Write commands must be sent on phase 1.
|
# Write commands must be sent on phase 1.
|
||||||
#
|
#
|
||||||
|
@ -23,13 +25,28 @@ from misoclib.mem import sdram
|
||||||
|
|
||||||
class S6DDRPHY(Module):
|
class S6DDRPHY(Module):
|
||||||
def __init__(self, pads, module, rd_bitslip, wr_bitslip, dqs_ddr_alignment):
|
def __init__(self, pads, module, rd_bitslip, wr_bitslip, dqs_ddr_alignment):
|
||||||
if module.memtype not in ["DDR", "LPDDR", "DDR2"]:
|
if module.memtype not in ["DDR", "LPDDR", "DDR2", "DDR3"]:
|
||||||
raise NotImplementedError("S6DDRPHY only supports DDR, LPDDR and DDR2")
|
raise NotImplementedError("S6DDRPHY only supports DDR, LPDDR, DDR2 and DDR3")
|
||||||
addressbits = flen(pads.a)
|
addressbits = flen(pads.a)
|
||||||
bankbits = flen(pads.ba)
|
bankbits = flen(pads.ba)
|
||||||
databits = flen(pads.dq)
|
databits = flen(pads.dq)
|
||||||
nphases = 2
|
nphases = 2
|
||||||
|
|
||||||
|
if module.memtype == "DDR3":
|
||||||
|
self.settings = sdram.PhySettings(
|
||||||
|
memtype="DDR3",
|
||||||
|
dfi_databits=2*databits,
|
||||||
|
nphases=nphases,
|
||||||
|
rdphase=0,
|
||||||
|
wrphase=1,
|
||||||
|
rdcmdphase=1,
|
||||||
|
wrcmdphase=0,
|
||||||
|
cl=5,
|
||||||
|
cwl=6,
|
||||||
|
read_latency=6,
|
||||||
|
write_latency=2
|
||||||
|
)
|
||||||
|
else:
|
||||||
self.settings = sdram.PhySettings(
|
self.settings = sdram.PhySettings(
|
||||||
memtype=module.memtype,
|
memtype=module.memtype,
|
||||||
dfi_databits=2*databits,
|
dfi_databits=2*databits,
|
||||||
|
@ -42,6 +59,7 @@ class S6DDRPHY(Module):
|
||||||
read_latency=5,
|
read_latency=5,
|
||||||
write_latency=0
|
write_latency=0
|
||||||
)
|
)
|
||||||
|
|
||||||
self.module = module
|
self.module = module
|
||||||
|
|
||||||
self.dfi = Interface(addressbits, bankbits, 2*databits, nphases)
|
self.dfi = Interface(addressbits, bankbits, 2*databits, nphases)
|
||||||
|
@ -88,6 +106,8 @@ class S6DDRPHY(Module):
|
||||||
r_dfi = Array(Record(phase_cmd_description(addressbits, bankbits)) for i in range(nphases))
|
r_dfi = Array(Record(phase_cmd_description(addressbits, bankbits)) for i in range(nphases))
|
||||||
for n, phase in enumerate(self.dfi.phases):
|
for n, phase in enumerate(self.dfi.phases):
|
||||||
sd_sdram_half += [
|
sd_sdram_half += [
|
||||||
|
r_dfi[n].reset_n.eq(phase.reset_n),
|
||||||
|
r_dfi[n].odt.eq(phase.odt),
|
||||||
r_dfi[n].address.eq(phase.address),
|
r_dfi[n].address.eq(phase.address),
|
||||||
r_dfi[n].bank.eq(phase.bank),
|
r_dfi[n].bank.eq(phase.bank),
|
||||||
r_dfi[n].cs_n.eq(phase.cs_n),
|
r_dfi[n].cs_n.eq(phase.cs_n),
|
||||||
|
@ -106,8 +126,10 @@ class S6DDRPHY(Module):
|
||||||
pads.cas_n.eq(r_dfi[phase_sel].cas_n),
|
pads.cas_n.eq(r_dfi[phase_sel].cas_n),
|
||||||
pads.we_n.eq(r_dfi[phase_sel].we_n)
|
pads.we_n.eq(r_dfi[phase_sel].we_n)
|
||||||
]
|
]
|
||||||
if hasattr(pads, "cs_n"):
|
# optional pads
|
||||||
sd_sdram_half += pads.cs_n.eq(r_dfi[phase_sel].cs_n)
|
for name in "reset_n", "cs_n", "odt":
|
||||||
|
if hasattr(pads, name):
|
||||||
|
sd_sdram_half += getattr(pads, name).eq(getattr(r_dfi[phase_sel], name))
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bitslip
|
# Bitslip
|
||||||
|
@ -332,24 +354,26 @@ class S6DDRPHY(Module):
|
||||||
i_SHIFTIN4=0,
|
i_SHIFTIN4=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
#
|
|
||||||
# ODT
|
|
||||||
#
|
|
||||||
# ODT not yet supported
|
|
||||||
if hasattr(pads, "odt"):
|
|
||||||
self.comb += pads.odt.eq(0)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# DQ/DQS/DM control
|
# DQ/DQS/DM control
|
||||||
#
|
#
|
||||||
|
if module.memtype == "DDR3":
|
||||||
|
r_drive_dq = Signal(self.settings.cwl-1)
|
||||||
|
sd_sdram_half += r_drive_dq.eq(Cat(d_dfi[self.settings.wrphase].wrdata_en, r_drive_dq))
|
||||||
|
self.comb += drive_dq.eq(r_drive_dq[self.settings.cwl-2])
|
||||||
|
else:
|
||||||
self.comb += drive_dq.eq(d_dfi[self.settings.wrphase].wrdata_en)
|
self.comb += drive_dq.eq(d_dfi[self.settings.wrphase].wrdata_en)
|
||||||
|
|
||||||
d_dfi_wrdata_en = Signal()
|
d_dfi_wrdata_en = Signal()
|
||||||
sd_sys += d_dfi_wrdata_en.eq(d_dfi[self.settings.wrphase].wrdata_en)
|
sd_sys += d_dfi_wrdata_en.eq(d_dfi[self.settings.wrphase].wrdata_en)
|
||||||
|
|
||||||
r_dfi_wrdata_en = Signal(2)
|
r_dfi_wrdata_en = Signal(max(self.settings.cwl, self.settings.cl))
|
||||||
sd_sdram_half += r_dfi_wrdata_en.eq(Cat(d_dfi_wrdata_en, r_dfi_wrdata_en[0]))
|
sd_sdram_half += r_dfi_wrdata_en.eq(Cat(d_dfi_wrdata_en, r_dfi_wrdata_en))
|
||||||
|
|
||||||
|
if module.memtype == "DDR3":
|
||||||
|
self.comb += drive_dqs.eq(r_dfi_wrdata_en[self.settings.cwl-1])
|
||||||
|
else:
|
||||||
self.comb += drive_dqs.eq(r_dfi_wrdata_en[1])
|
self.comb += drive_dqs.eq(r_dfi_wrdata_en[1])
|
||||||
|
|
||||||
rddata_sr = Signal(self.settings.read_latency)
|
rddata_sr = Signal(self.settings.read_latency)
|
||||||
|
|
Loading…
Reference in a new issue