From 25b64c33741bfd9a3c7e86d09ad5b207ab3d51bf Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 3 Mar 2021 11:29:17 +0100 Subject: [PATCH] phy/usddrphy: Avoid separate ODELAYE3 by avoiding software reset on DQS's ODELAYE3. The fabric is now maintaining an increment counter for each DQS's ODELAY and software use it to revert total increments to 0 (equivalent to a reset). Avoiding the separate ODELAYE3 simplifies design constraints since it was often placed far from the DRAM pads and thus requiring a LOC constraint to avoid timing violations. The software has to use the following sdram_write_leveling_rst_delay function: static void sdram_write_leveling_rst_delay(int module) { /* Select module */ ddrphy_dly_sel_write(1 << module); /* Reset DQ delay */ ddrphy_wdly_dq_rst_write(1); /* Reset DQS delay */ while (ddrphy_wdly_dqs_inc_count_read() != 0) { ddrphy_wdly_dqs_inc_write(1); cdelay(100); } /* Un-select module */ ddrphy_dly_sel_write(0); } --- litedram/phy/usddrphy.py | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/litedram/phy/usddrphy.py b/litedram/phy/usddrphy.py index 0007c82..2fb434e 100644 --- a/litedram/phy/usddrphy.py +++ b/litedram/phy/usddrphy.py @@ -83,6 +83,7 @@ class USDDRPHY(Module, AutoCSR): self._wdly_dq_inc = CSR() self._wdly_dqs_rst = CSR() self._wdly_dqs_inc = CSR() + self._wdly_dqs_inc_count = CSRStatus(9) self._wdly_dq_bitslip_rst = CSR() self._wdly_dq_bitslip = CSR() @@ -126,18 +127,6 @@ class USDDRPHY(Module, AutoCSR): # # # - # tCK reference ---------------------------------------------------------------------------- - self.specials += Instance("ODELAYE3", - p_SIM_DEVICE = device, - p_REFCLK_FREQUENCY = iodelay_clk_freq/1e6, - p_DELAY_FORMAT = "TIME", - p_DELAY_TYPE = "FIXED", - p_DELAY_VALUE = int(tck*1e12/4), - i_CLK = ClockSignal(), - i_EN_VTC = 1, - o_CNTVALUEOUT = self._half_sys8x_taps.status, - ) - # Iterate on pads groups ------------------------------------------------------------------- for pads_group in range(len(pads.groups)): pads.sel_group(pads_group) @@ -296,11 +285,9 @@ class USDDRPHY(Module, AutoCSR): p_IS_CLK_INVERTED = 0, p_IS_RST_INVERTED = 0, p_DELAY_FORMAT = "TIME", - p_DELAY_TYPE = "VAR_LOAD", - p_DELAY_VALUE = 0, - i_RST = ResetSignal("ic") | self._rst.storage, - i_LOAD = self._dly_sel.storage[i] & self._wdly_dqs_rst.re, - i_CNTVALUEIN = self._half_sys8x_taps.status, + p_DELAY_TYPE = "VARIABLE", + p_DELAY_VALUE = int(tck*1e12/4), + o_CNTVALUEOUT = self._half_sys8x_taps.status if (i == 0) and (j == 0) else Signal(), i_CLK = ClockSignal(), i_EN_VTC = self._en_vtc.storage, i_CE = self._dly_sel.storage[i] & self._wdly_dqs_inc.re, @@ -315,6 +302,9 @@ class USDDRPHY(Module, AutoCSR): io_IOB = dqs_n, ) ] + wdly_dqs_inc_count = Signal(9) + self.sync += If(self._dly_sel.storage[i] & self._wdly_dqs_inc.re, wdly_dqs_inc_count.eq(wdly_dqs_inc_count + 1)) + self.comb += If(self._dly_sel.storage[i], self._wdly_dqs_inc_count.status.eq(wdly_dqs_inc_count)) # DM --------------------------------------------------------------------------------------- for i in range(databits//8):