Commit 25b64c33 authored by Florent Kermarrec's avatar Florent Kermarrec

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);
}
parent 541e2f1c
......@@ -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):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment