phy/usddrphy: simplify/cleanup write control path, add DQS Pre/Postamble support.

This commit is contained in:
Florent Kermarrec 2020-04-16 12:15:50 +02:00
parent 1462a4375b
commit 57b16c231c
1 changed files with 21 additions and 14 deletions

View File

@ -274,9 +274,14 @@ class USDDRPHY(Module, AutoCSR):
# DQS and DM ------------------------------------------------------------------------------- # DQS and DM -------------------------------------------------------------------------------
oe_dqs = Signal() oe_dqs = Signal()
dqs_serdes_pattern = Signal(8) dqs_preamble = Signal()
dqs_postamble = Signal()
dqs_serdes_pattern = Signal(8, reset=0b01010101)
self.comb += [ self.comb += [
dqs_serdes_pattern.eq(0b01010101), dqs_serdes_pattern.eq(0b01010101),
If(dqs_preamble | dqs_postamble,
dqs_serdes_pattern.eq(0b0000000)
),
If(self._wlevel_en.storage, If(self._wlevel_en.storage,
dqs_serdes_pattern.eq(0b00000000), dqs_serdes_pattern.eq(0b00000000),
If(self._wlevel_strobe.re, If(self._wlevel_strobe.re,
@ -507,20 +512,22 @@ class USDDRPHY(Module, AutoCSR):
self.sync += [phase.rddata_valid.eq(rddata_en[-1] | self._wlevel_en.storage) for phase in dfi.phases] self.sync += [phase.rddata_valid.eq(rddata_en[-1] | self._wlevel_en.storage) for phase in dfi.phases]
# Write Control Path ----------------------------------------------------------------------- # Write Control Path -----------------------------------------------------------------------
oe = Signal() # Creates a shift register of write commands coming from the DFI interface. This shift register
last_wrdata_en = Signal(cwl_sys_latency + 2) # is used to control DQ/DQS tristates. The DQ/DQS tristates are controlled for 3 sys_clk cycles:
wrphase = dfi.phases[self.settings.wrphase] # Write (1) + Pre/Postamble (2).
self.sync += last_wrdata_en.eq(Cat(wrphase.wrdata_en, last_wrdata_en)) wrdata_en = Signal(cwl_sys_latency + 3)
self.comb += oe.eq( wrdata_en_last = Signal.like(wrdata_en)
last_wrdata_en[cwl_sys_latency + -1] | self.comb += wrdata_en.eq(Cat(dfi.phases[self.settings.wrphase].wrdata_en, wrdata_en_last))
last_wrdata_en[cwl_sys_latency + 0] | self.sync += wrdata_en_last.eq(wrdata_en)
last_wrdata_en[cwl_sys_latency + 1]) self.sync += oe_dq.eq(wrdata_en[cwl_sys_latency:] != 0b000)
self.comb += If(self._wlevel_en.storage, oe_dqs.eq(1)).Else(oe_dqs.eq(oe_dq))
# Write DQS Postamble/Preamble Control Path ------------------------------------------------
# Generates DQS Preamble 1 cycle before the first write and Postamble 1 cycle after the last
# write.
self.sync += [ self.sync += [
If(self._wlevel_en.storage, dqs_preamble.eq( wrdata_en[cwl_sys_latency:-1] == 0b10),
oe_dqs.eq(1), oe_dq.eq(0) dqs_postamble.eq(wrdata_en[cwl_sys_latency+1:] == 0b01),
).Else(
oe_dqs.eq(oe), oe_dq.eq(oe)
)
] ]
# Xilinx Ultrascale Plus DDR3/DDR4 PHY ------------------------------------------------------------- # Xilinx Ultrascale Plus DDR3/DDR4 PHY -------------------------------------------------------------