phy/usddrphy: add write leveling bitslip support on dq/dm/dqs (similar to s7ddrphy).

This commit is contained in:
Florent Kermarrec 2020-10-08 19:50:18 +02:00
parent 1d450bac57
commit 5d528cbad0
1 changed files with 27 additions and 6 deletions

View File

@ -81,6 +81,9 @@ class USDDRPHY(Module, AutoCSR):
self._wdly_dqs_rst = CSR() self._wdly_dqs_rst = CSR()
self._wdly_dqs_inc = CSR() self._wdly_dqs_inc = CSR()
self._wdly_dq_bitslip_rst = CSR()
self._wdly_dq_bitslip = CSR()
self._rdphase = CSRStorage(2, reset=rdphase) self._rdphase = CSRStorage(2, reset=rdphase)
self._wrphase = CSRStorage(2, reset=wrphase) self._wrphase = CSRStorage(2, reset=wrphase)
@ -97,7 +100,7 @@ class USDDRPHY(Module, AutoCSR):
cl = cl, cl = cl,
cwl = cwl, cwl = cwl,
read_latency = cl_sys_latency + 5, read_latency = cl_sys_latency + 5,
write_latency = cwl_sys_latency, write_latency = cwl_sys_latency - 1,
cmd_latency = cmd_latency, cmd_latency = cmd_latency,
cmd_delay = cmd_delay, cmd_delay = cmd_delay,
) )
@ -228,8 +231,8 @@ class USDDRPHY(Module, AutoCSR):
dqs_postamble = Signal() dqs_postamble = Signal()
dqs_oe_delay = TappedDelayLine(ntaps=1) dqs_oe_delay = TappedDelayLine(ntaps=1)
dqs_pattern = DQSPattern( dqs_pattern = DQSPattern(
preamble = dqs_preamble, #preamble = dqs_preamble, # FIXME
postamble = dqs_postamble, #postamble = dqs_postamble, # FIXME
wlevel_en = self._wlevel_en.storage, wlevel_en = self._wlevel_en.storage,
wlevel_strobe = self._wlevel_strobe.re) wlevel_strobe = self._wlevel_strobe.re)
self.submodules += dqs_oe_delay, dqs_pattern self.submodules += dqs_oe_delay, dqs_pattern
@ -247,6 +250,12 @@ class USDDRPHY(Module, AutoCSR):
dqs_taps_done.eq(1), dqs_taps_done.eq(1),
self._half_sys8x_taps.status.eq(dqs_taps) self._half_sys8x_taps.status.eq(dqs_taps)
) )
dqs_bitslip = BitSlip(8,
i = dqs_pattern.o,
rst = self._dly_sel.storage[i] & self._wdly_dq_bitslip_rst.re,
slp = self._dly_sel.storage[i] & self._wdly_dq_bitslip.re,
cycles = 1)
self.submodules += dqs_bitslip
if x4_dimm_mode: if x4_dimm_mode:
dqs_pads = ((pads.dqs_p[i*2], pads.dqs_n[i*2]), (pads.dqs_p[i*2 + 1], pads.dqs_n[i*2 + 1])) dqs_pads = ((pads.dqs_p[i*2], pads.dqs_n[i*2]), (pads.dqs_p[i*2 + 1], pads.dqs_n[i*2 + 1]))
else: else:
@ -267,7 +276,7 @@ class USDDRPHY(Module, AutoCSR):
i_CLK = ClockSignal("sys4x"), i_CLK = ClockSignal("sys4x"),
i_CLKDIV = ClockSignal(), i_CLKDIV = ClockSignal(),
i_T = ~dqs_oe_delay.output, i_T = ~dqs_oe_delay.output,
i_D = dqs_pattern.o, i_D = dqs_bitslip.o,
o_OQ = dqs_nodelay, o_OQ = dqs_nodelay,
o_T_OUT = dqs_t, o_T_OUT = dqs_t,
@ -303,6 +312,12 @@ class USDDRPHY(Module, AutoCSR):
for i in range(databits//8): for i in range(databits//8):
if hasattr(pads, "dm"): if hasattr(pads, "dm"):
dm_o_nodelay = Signal() dm_o_nodelay = Signal()
dm_o_bitslip = BitSlip(8,
i = Cat(*[dfi.phases[n//2].wrdata_mask[n%2*databits//8+i] for n in range(8)]),
rst = self._dly_sel.storage[i] & self._wdly_dq_bitslip_rst.re,
slp = self._dly_sel.storage[i] & self._wdly_dq_bitslip.re,
cycles = 1)
self.submodules += dm_o_bitslip
self.specials += [ self.specials += [
Instance("OSERDESE3", Instance("OSERDESE3",
p_SIM_DEVICE = device, p_SIM_DEVICE = device,
@ -314,7 +329,7 @@ class USDDRPHY(Module, AutoCSR):
i_RST = ResetSignal() | self._rst.storage, i_RST = ResetSignal() | self._rst.storage,
i_CLK = ClockSignal("sys4x"), i_CLK = ClockSignal("sys4x"),
i_CLKDIV = ClockSignal(), i_CLKDIV = ClockSignal(),
i_D = Cat(*[dfi.phases[n//2].wrdata_mask[n%2*databits//8+i] for n in range(8)]), i_D = dm_o_bitslip.o,
o_OQ = dm_o_nodelay, o_OQ = dm_o_nodelay,
), ),
Instance("ODELAYE3", Instance("ODELAYE3",
@ -348,6 +363,12 @@ class USDDRPHY(Module, AutoCSR):
dq_i_nodelay = Signal() dq_i_nodelay = Signal()
dq_i_delayed = Signal() dq_i_delayed = Signal()
dq_t = Signal() dq_t = Signal()
dq_o_bitslip = BitSlip(8,
i = Cat(*[dfi.phases[n//2].wrdata[n%2*databits+i] for n in range(8)]),
rst = self._dly_sel.storage[i//8] & self._wdly_dq_bitslip_rst.re,
slp = self._dly_sel.storage[i//8] & self._wdly_dq_bitslip.re,
cycles = 1)
self.submodules += dq_o_bitslip
self.specials += Instance("OSERDESE3", self.specials += Instance("OSERDESE3",
p_SIM_DEVICE = device, p_SIM_DEVICE = device,
p_DATA_WIDTH = 8, p_DATA_WIDTH = 8,
@ -358,7 +379,7 @@ class USDDRPHY(Module, AutoCSR):
i_RST = ResetSignal() | self._rst.storage, i_RST = ResetSignal() | self._rst.storage,
i_CLK = ClockSignal("sys4x"), i_CLK = ClockSignal("sys4x"),
i_CLKDIV = ClockSignal(), i_CLKDIV = ClockSignal(),
i_D = Cat(*[dfi.phases[n//2].wrdata[n%2*databits+i] for n in range(8)]), i_D = dq_o_bitslip.o,
i_T = ~dq_oe_delay.output, i_T = ~dq_oe_delay.output,
o_OQ = dq_o_nodelay, o_OQ = dq_o_nodelay,
o_T_OUT = dq_t, o_T_OUT = dq_t,