phy/lpddr5/simphy: use the same serialization scheme in S7 PHY to serve as reference

This commit is contained in:
Jędrzej Boczar 2021-09-06 12:46:09 +02:00 committed by Alessandro Comodi
parent 6b2a1bc47c
commit aad7cce8c5
2 changed files with 19 additions and 9 deletions

View File

@ -57,7 +57,7 @@ class LPDDR5SimPHY(SimSerDesMixin, LPDDR5PHY):
delay = lambda sig, cycles: delayed(self, sig, cycles=cycles) delay = lambda sig, cycles: delayed(self, sig, cycles=cycles)
ddr_ck = dict(clkdiv="sys", clk="sys2x") ddr_ck = dict(clkdiv="sys", clk="sys2x")
ddr_ck_180 = dict(clkdiv="sys", clk="sys2x_180") ddr_ca = dict(clkdiv="sys", clk="sys4x")
ddr_wck = dict(clkdiv="sys", clk={2: "sys4x", 4: "sys8x"}[wck_ck_ratio]) ddr_wck = dict(clkdiv="sys", clk={2: "sys4x", 4: "sys8x"}[wck_ck_ratio])
ddr_wck_180 = dict(clkdiv="sys", clk={2: "sys4x_180", 4: "sys8x_180"}[wck_ck_ratio]) ddr_wck_180 = dict(clkdiv="sys", clk={2: "sys4x_180", 4: "sys8x_180"}[wck_ck_ratio])
@ -69,22 +69,31 @@ class LPDDR5SimPHY(SimSerDesMixin, LPDDR5PHY):
if aligned_reset_zero: if aligned_reset_zero:
ddr_ck["reset_cnt"] = 0 ddr_ck["reset_cnt"] = 0
ddr_ca["reset_cnt"] = 0
ddr_wck["reset_cnt"] = 0 ddr_wck["reset_cnt"] = 0
self.comb += self.pads.reset_n.eq(delay(self.out.reset_n, cycles=Serializer.LATENCY)) self.comb += self.pads.reset_n.eq(delay(self.out.reset_n, cycles=Serializer.LATENCY))
# CK signals # CK signals
self.ser(i=self.out.ck, o=self.pads.ck, name='ck', **ddr_ck) self.ser(i=self.out.ck, o=self.pads.ck, name='ck', **ddr_ck)
# CS (SDR) is delayed by 180 deg to be center aligned with CK (+1CK to match serializer latencies)
# 1.5 sys = 1 sys + 1 sys2x # CS (SDR) is delayed by 180 deg to be center aligned with CK
self.sync.sys2x += self.pads.cs.eq(delay(self.out.cs, cycles=Serializer.LATENCY)) # Use ConstBitSlip to shift it, then serialize that 2-bit signal as DDR (like with CK)
cs_2bit = Signal(2)
cs_2bit_d = Signal(2)
self.comb += cs_2bit.eq(Replicate(self.out.cs, 2))
self.submodules += ConstBitSlip(dw=2, slp=1, cycles=1, register=False, i=cs_2bit, o=cs_2bit_d)
self.ser(i=cs_2bit_d, o=self.pads.cs, name='cs', **ddr_ck)
# To center align CA (DDR) with CK it has to be delayed by 270 deg CK (+90 deg relative to CS) # To center align CA (DDR) with CK it has to be delayed by 270 deg CK (+90 deg relative to CS)
for i in range(7): for i in range(7):
# Bitslip is used to get the additional +180 deg (slipping 2-bit CA signal by 1 bit with register=False) # To achieve 270 deg shift we use ConstBitSlip with slp=3 and dw=4.
ca_delayed = Signal(2) # For this to work we first widen CA to 4 bits and use sys4x when serializing.
self.submodules += ConstBitSlip(dw=2, slp=1, cycles=1, register=False, i=self.out.ca[i], o=ca_delayed) ca_4bit = Signal(4)
# Getting the +90 deg by serializing on ddr_ck_180 (which shifts by 90 deg of CK) ca_4bit_d = Signal(4)
self.ser(**cdc(ca_delayed, ddr_ck_180), o=self.pads.ca[i], name=f'ca{i}', **ddr_ck_180) self.comb += ca_4bit.eq(Cat([Replicate(bit, 2) for bit in self.out.ca[i]]))
self.submodules += ConstBitSlip(dw=4, slp=3, cycles=1, register=False, i=ca_4bit, o=ca_4bit_d)
self.ser(i=ca_4bit_d, o=self.pads.ca[i], name=f'ca{i}', **ddr_ca)
# WCK # WCK
for i in range(self.databits//8): for i in range(self.databits//8):

View File

@ -55,6 +55,7 @@ def get_clocks(sys_clk_freq, wck_ck_ratio, dfi_converter_ratio):
"phy": dfi_converter_ratio, "phy": dfi_converter_ratio,
"ck": dfi_converter_ratio, "ck": dfi_converter_ratio,
"ck_ddr": 2*dfi_converter_ratio, "ck_ddr": 2*dfi_converter_ratio,
"ca_ddr": 4*dfi_converter_ratio,
"wck_ddr": 2*wck_ck_ratio*dfi_converter_ratio, "wck_ddr": 2*wck_ck_ratio*dfi_converter_ratio,
} }
clocks = {"sys": dict(freq_hz=sys_clk_freq)} clocks = {"sys": dict(freq_hz=sys_clk_freq)}