phy/gensdrphy/HalfRateGENSDRPHY: review/simplify and reduce read_latency by 1.

This commit is contained in:
Florent Kermarrec 2020-07-24 11:07:15 +02:00
parent f51052f8b7
commit c01e86865f
1 changed files with 26 additions and 44 deletions

View File

@ -92,6 +92,18 @@ class HalfRateGENSDRPHY(Module):
full_rate_phy = GENSDRPHY(pads, cl, cmd_latency)
self.submodules += ClockDomainsRenamer("sys2x")(full_rate_phy)
# Clocking ---------------------------------------------------------------------------------
# Select active sys2x phase:
# sys_clk ----____----____
# sys2x_clk --__--__--__--__
# phase_sel 0 1 0 1
phase_sel = Signal()
phase_sys = Signal()
phase_sys2x = Signal()
self.sync += phase_sys.eq(phase_sys2x)
self.sync.sys2x += phase_sys2x.eq(~phase_sel)
self.sync.sys2x += phase_sel.eq(~phase_sel & (phase_sys2x ^ phase_sys))
# PHY settings -----------------------------------------------------------------------------
self.settings = PhySettings(
phytype = "HalfRateGENSDRPHY",
@ -105,59 +117,29 @@ class HalfRateGENSDRPHY(Module):
rdcmdphase = 1,
wrcmdphase = 1,
cl = cl,
read_latency = (cl + cmd_latency)//2 + 2, # FIXME: should be possible to have 1 cycle less latency
read_latency = (cl + cmd_latency)//2 + 1,
write_latency = 0
)
# DFI adaptation ---------------------------------------------------------------------------
self.dfi = dfi = Interface(addressbits, bankbits, nranks, databits, nphases)
self.comb += Case(phase_sel, {
0: dfi.phases[0].connect(full_rate_phy.dfi.phases[0], omit={"rddata", "rddata_valid", "wrdata_en"}),
1: dfi.phases[1].connect(full_rate_phy.dfi.phases[0], omit={"rddata", "rddata_valid", "wrdata_en"}),
})
# Clock ------------------------------------------------------------------------------------
# select active sys2x phase
# sys_clk ----____----____
# phase_sel 0 1 0 1
self.phase_sel = phase_sel = Signal()
phase_sys2x = Signal.like(phase_sel)
phase_sys = Signal.like(phase_sys2x)
self.sync += phase_sys.eq(phase_sys2x)
self.sync.sys2x += [
If(phase_sys2x == phase_sys,
phase_sel.eq(0),
).Else(
phase_sel.eq(~phase_sel)
),
phase_sys2x.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
# Write Datapath
wr_data_en = dfi.phases[self.settings.wrphase].wrdata_en & (phase_sel == 0)
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(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),
# Read Datapath
rddata_d = Signal(databits)
self.sync.sys2x += rddata_d.eq(full_rate_phy.dfi.phases[0].rddata)
self.comb += [
dfi.phases[0].rddata.eq(rddata_d),
dfi.phases[0].rddata_valid.eq(full_rate_phy.dfi.phases[0].rddata_valid),
dfi.phases[1].rddata.eq(full_rate_phy.dfi.phases[0].rddata),
dfi.phases[1].rddata_valid.eq(rddata_valid),
dfi.phases[1].rddata_valid.eq(full_rate_phy.dfi.phases[0].rddata_valid),
]