lpddr4/s7phy: remove OE delay CSRs, use fixed, tested values
This commit is contained in:
parent
ba57791c1d
commit
f3a0a7d038
|
@ -26,12 +26,10 @@ class S7LPDDR4PHY(DoubleRateLPDDR4PHY):
|
||||||
**kwargs
|
**kwargs
|
||||||
)
|
)
|
||||||
|
|
||||||
self.submodules.sys2x_delay = ClockDomainsRenamer("sys2x")(Module())
|
|
||||||
|
|
||||||
# Parameters -------------------------------------------------------------------------------
|
# Parameters -------------------------------------------------------------------------------
|
||||||
# Calculate value of taps needed to shift a signal by 90 degrees.
|
# Calculate value of taps needed to shift a signal by 90 degrees.
|
||||||
# Using iodelay_clk_freq of 300MHz/400MHz is only valid for -3 and -2/2E speed grades.
|
# Using iodelay_clk_freq of 300MHz/400MHz is only valid for -3 and -2/2E speed grades.
|
||||||
# FIXME: this should be named sys16x, but using sys8x due to a name hard-coded in BIOS
|
# Note: this should be named sys16x, but using sys8x due to a name hard-coded in BIOS
|
||||||
assert iodelay_clk_freq in [200e6, 300e6, 400e6]
|
assert iodelay_clk_freq in [200e6, 300e6, 400e6]
|
||||||
iodelay_tap_average = 1 / (2*32 * iodelay_clk_freq)
|
iodelay_tap_average = 1 / (2*32 * iodelay_clk_freq)
|
||||||
half_sys8x_taps = math.floor(self.tck / (4 * iodelay_tap_average))
|
half_sys8x_taps = math.floor(self.tck / (4 * iodelay_tap_average))
|
||||||
|
@ -73,22 +71,21 @@ class S7LPDDR4PHY(DoubleRateLPDDR4PHY):
|
||||||
wdly_dqs_rst = cdc(self._wdly_dqs_rst.re)
|
wdly_dqs_rst = cdc(self._wdly_dqs_rst.re)
|
||||||
wdly_dqs_inc = cdc(self._wdly_dqs_inc.re)
|
wdly_dqs_inc = cdc(self._wdly_dqs_inc.re)
|
||||||
|
|
||||||
# with DATA_RATE_TQ=BUF tristate is asynchronous, so we need to delay it
|
# In theory we should only need to delay by 2 cycles, but sometimes it happened that
|
||||||
class OEDelay(Module, AutoCSR):
|
# DQ/DMI were transmitted incomplete due to OE being asserted too late/released too
|
||||||
def __init__(self, oe, reset):
|
# early. For this reason we add OE margin extending it 1 cycle before and 1 after.
|
||||||
self.o = Signal()
|
# For DQS we already have margin so there should be no need for this.
|
||||||
self.mask = CSRStorage(4, reset=reset)
|
def oe_delay_data(oe):
|
||||||
delay = Array([Signal() for _ in range(4)])
|
oe_d = Signal()
|
||||||
|
delay = TappedDelayLine(oe, 3)
|
||||||
|
self.submodules += ClockDomainsRenamer("sys2x")(delay)
|
||||||
|
self.comb += oe_d.eq(reduce(or_, delay.taps))
|
||||||
|
return oe_d
|
||||||
|
|
||||||
self.comb += delay[0].eq(oe)
|
def oe_delay_dqs(oe):
|
||||||
self.sync += delay[1].eq(delay[0])
|
delay = TappedDelayLine(oe, 2)
|
||||||
self.sync += delay[2].eq(delay[1])
|
self.submodules += ClockDomainsRenamer("sys2x")(delay)
|
||||||
self.sync += delay[3].eq(delay[2])
|
return delay.output
|
||||||
self.comb += self.o.eq(reduce(or_, [dly & self.mask.storage[i] for i, dly in enumerate(delay)]))
|
|
||||||
|
|
||||||
self.submodules.dqs_oe_delay = ClockDomainsRenamer("sys2x")(OEDelay(self.out.dqs_oe, reset=0b0110))
|
|
||||||
self.submodules.dq_oe_delay = ClockDomainsRenamer("sys2x")(OEDelay(self.out.dq_oe, reset=0b1110))
|
|
||||||
self.submodules.dmi_oe_delay = ClockDomainsRenamer("sys2x")(OEDelay(self.out.dmi_oe, reset=0b1110))
|
|
||||||
|
|
||||||
# Serialization ----------------------------------------------------------------------------
|
# Serialization ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -101,7 +98,6 @@ class S7LPDDR4PHY(DoubleRateLPDDR4PHY):
|
||||||
self.odelaye2(din=clk_ser, dout=clk_dly, rst=cdly_rst, inc=cdly_inc)
|
self.odelaye2(din=clk_ser, dout=clk_dly, rst=cdly_rst, inc=cdly_inc)
|
||||||
self.obufds(din=clk_dly, dout=self.pads.clk_p, dout_b=self.pads.clk_n)
|
self.obufds(din=clk_dly, dout=self.pads.clk_p, dout_b=self.pads.clk_n)
|
||||||
|
|
||||||
# FIXME: probably no need to serialize those
|
|
||||||
for cmd in ["cke", "odt", "reset_n"]:
|
for cmd in ["cke", "odt", "reset_n"]:
|
||||||
cmd_ser = Signal()
|
cmd_ser = Signal()
|
||||||
self.oserdese2_sdr(din=getattr(self.out, cmd), dout=cmd_ser, clk="sys8x")
|
self.oserdese2_sdr(din=getattr(self.out, cmd), dout=cmd_ser, clk="sys8x")
|
||||||
|
@ -127,7 +123,7 @@ class S7LPDDR4PHY(DoubleRateLPDDR4PHY):
|
||||||
self.oserdese2_ddr(
|
self.oserdese2_ddr(
|
||||||
din = self.out.dqs_o[byte],
|
din = self.out.dqs_o[byte],
|
||||||
dout_fb = dqs_ser,
|
dout_fb = dqs_ser,
|
||||||
tin = ~self.dqs_oe_delay.o,
|
tin = ~oe_delay_dqs(self.out.dqs_oe),
|
||||||
tout = dqs_t,
|
tout = dqs_t,
|
||||||
clk = "sys8x", # TODO: if odelay is not avaiable need to use sys8x_90
|
clk = "sys8x", # TODO: if odelay is not avaiable need to use sys8x_90
|
||||||
)
|
)
|
||||||
|
@ -165,7 +161,7 @@ class S7LPDDR4PHY(DoubleRateLPDDR4PHY):
|
||||||
self.oserdese2_ddr(
|
self.oserdese2_ddr(
|
||||||
din = self.out.dmi_o[byte],
|
din = self.out.dmi_o[byte],
|
||||||
dout_fb = dmi_ser,
|
dout_fb = dmi_ser,
|
||||||
tin = ~self.dmi_oe_delay.o,
|
tin = ~oe_delay_data(self.out.dmi_oe),
|
||||||
tout = dmi_t,
|
tout = dmi_t,
|
||||||
clk = "sys8x",
|
clk = "sys8x",
|
||||||
)
|
)
|
||||||
|
@ -191,8 +187,8 @@ class S7LPDDR4PHY(DoubleRateLPDDR4PHY):
|
||||||
dq_i_dly = Signal()
|
dq_i_dly = Signal()
|
||||||
self.oserdese2_ddr(
|
self.oserdese2_ddr(
|
||||||
din = self.out.dq_o[bit],
|
din = self.out.dq_o[bit],
|
||||||
dout_fb = dq_ser, # TODO: compare: S7DDRPHY uses OQ not OFB
|
dout_fb = dq_ser,
|
||||||
tin = ~self.dq_oe_delay.o,
|
tin = ~oe_delay_data(self.out.dmi_oe),
|
||||||
tout = dq_t,
|
tout = dq_t,
|
||||||
clk = "sys8x",
|
clk = "sys8x",
|
||||||
)
|
)
|
||||||
|
@ -220,9 +216,6 @@ class S7LPDDR4PHY(DoubleRateLPDDR4PHY):
|
||||||
clk = "sys8x"
|
clk = "sys8x"
|
||||||
)
|
)
|
||||||
|
|
||||||
def delayed_sys2x(self, sig, **kwargs):
|
|
||||||
return delayed(self.sys2x_delay, sig, **kwargs)
|
|
||||||
|
|
||||||
def idelaye2(self, *, din, dout, init=0, rst=None, inc=None):
|
def idelaye2(self, *, din, dout, init=0, rst=None, inc=None):
|
||||||
assert not ((rst is None) ^ (inc is None))
|
assert not ((rst is None) ^ (inc is None))
|
||||||
fixed = rst is None
|
fixed = rst is None
|
||||||
|
@ -327,7 +320,7 @@ class S7LPDDR4PHY(DoubleRateLPDDR4PHY):
|
||||||
|
|
||||||
params = dict(
|
params = dict(
|
||||||
p_SERDES_MODE = "MASTER",
|
p_SERDES_MODE = "MASTER",
|
||||||
p_INTERFACE_TYPE = "NETWORKING", # TODO: try using MEMORY mode?
|
p_INTERFACE_TYPE = "NETWORKING",
|
||||||
p_DATA_WIDTH = data_width,
|
p_DATA_WIDTH = data_width,
|
||||||
p_DATA_RATE = "DDR",
|
p_DATA_RATE = "DDR",
|
||||||
p_NUM_CE = 1,
|
p_NUM_CE = 1,
|
||||||
|
|
Loading…
Reference in New Issue