phy/gensdrphy: add half-rate PHY

This commit is contained in:
Jędrzej Boczar 2020-06-05 10:01:09 +02:00
parent edd5e0ec78
commit 7f55e2e2c5
2 changed files with 74 additions and 1 deletions

View File

@ -1,4 +1,4 @@
from litedram.phy.gensdrphy import GENSDRPHY from litedram.phy.gensdrphy import GENSDRPHY, HalfRateGENSDRPHY
from litedram.phy.s6ddrphy import S6HalfRateDDRPHY, S6QuarterRateDDRPHY from litedram.phy.s6ddrphy import S6HalfRateDDRPHY, S6QuarterRateDDRPHY
from litedram.phy.s7ddrphy import V7DDRPHY, K7DDRPHY, A7DDRPHY from litedram.phy.s7ddrphy import V7DDRPHY, K7DDRPHY, A7DDRPHY

View File

@ -1,4 +1,5 @@
# This file is Copyright (c) 2012-2020 Florent Kermarrec <florent@enjoy-digital.fr> # This file is Copyright (c) 2012-2020 Florent Kermarrec <florent@enjoy-digital.fr>
# This file is Copyright (c) 2020 Antmicro <www.antmicro.com>
# License: BSD # License: BSD
# 1:1 frequency-ratio Generic SDR PHY # 1:1 frequency-ratio Generic SDR PHY
@ -78,3 +79,75 @@ class GENSDRPHY(Module):
rddata_en = Signal(cl + cmd_latency) rddata_en = Signal(cl + cmd_latency)
self.sync += rddata_en.eq(Cat(dfi.p0.rddata_en, rddata_en)) self.sync += rddata_en.eq(Cat(dfi.p0.rddata_en, rddata_en))
self.sync += dfi.p0.rddata_valid.eq(rddata_en[-1]) self.sync += dfi.p0.rddata_valid.eq(rddata_en[-1])
# Half-rate Generic SDR PHY ------------------------------------------------------------------------
class HalfRateGENSDRPHY(Module):
def __init__(self, pads, cl=2, cmd_latency=1):
pads = PHYPadsCombiner(pads)
addressbits = len(pads.a)
bankbits = len(pads.ba)
nranks = 1 if not hasattr(pads, "cs_n") else len(pads.cs_n)
databits = len(pads.dq)
nphases = 2
# FullRate PHY -----------------------------------------------------------------------------
full_rate_phy = GENSDRPHY(pads, cl, cmd_latency)
self.submodules += ClockDomainsRenamer("sys2x")(full_rate_phy)
# PHY settings -----------------------------------------------------------------------------
self.settings = PhySettings(
phytype = "HalfRateGENSDRPHY",
memtype = "SDR",
databits = databits,
dfi_databits = databits,
nranks = nranks,
nphases = nphases,
rdphase = 0,
wrphase = 1,
rdcmdphase = 1,
wrcmdphase = 0,
cl = cl,
read_latency = (cl + cmd_latency)//2 + 1,
write_latency = 0
)
# DFI adaptation ---------------------------------------------------------------------------
self.dfi = dfi = Interface(addressbits, bankbits, nranks, databits, nphases)
# Select active sys2x phase
# sys ----____----____
# phase_sel 0 1 0 1
# sys2x --__--__--__--__
phase_sel = Signal(reset=1)
self.sync.sys2x += phase_sel.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
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(2*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),
dfi.phases[1].rddata.eq(full_rate_phy.dfi.phases[0].rddata),
dfi.phases[1].rddata_valid.eq(full_rate_phy.dfi.phases[0].rddata_valid),
]