phy/gensdrphy: add half-rate PHY
This commit is contained in:
parent
edd5e0ec78
commit
7f55e2e2c5
|
@ -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
|
||||||
|
|
|
@ -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),
|
||||||
|
]
|
||||||
|
|
Loading…
Reference in New Issue