phy/ecp5ddrphy: improve presentation/readability

This commit is contained in:
Florent Kermarrec 2020-01-25 15:30:00 +01:00
parent bb1b431184
commit e0966e2ed3
1 changed files with 192 additions and 198 deletions

View File

@ -1,5 +1,5 @@
# This file is Copyright (c) 2019 David Shah <dave@ds0.me> # This file is Copyright (c) 2019 David Shah <dave@ds0.me>
# This file is Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr> # This file is Copyright (c) 2019-2020 Florent Kermarrec <florent@enjoy-digital.fr>
# License: BSD # License: BSD
# 1:2 frequency-ratio DDR3 PHY for Lattice's ECP5 # 1:2 frequency-ratio DDR3 PHY for Lattice's ECP5
@ -39,12 +39,12 @@ class ECP5DDRPHYInit(Module):
_lock = Signal() _lock = Signal()
delay = Signal() delay = Signal()
self.specials += Instance("DDRDLLA", self.specials += Instance("DDRDLLA",
i_CLK=ClockSignal("sys2x"), i_CLK = ClockSignal("sys2x"),
i_RST=ResetSignal(), i_RST = ResetSignal(),
i_UDDCNTLN=~update, i_UDDCNTLN = ~update,
i_FREEZE=freeze, i_FREEZE = freeze,
o_DDRDEL=delay, o_DDRDEL = delay,
o_LOCK=_lock o_LOCK = _lock
) )
lock = Signal() lock = Signal()
lock_d = Signal() lock_d = Signal()
@ -141,43 +141,39 @@ class ECP5DDRPHY(Module, AutoCSR):
# Clock ------------------------------------------------------------------------------------ # Clock ------------------------------------------------------------------------------------
for i in range(len(pads.clk_p)): for i in range(len(pads.clk_p)):
sd_clk_se = Signal() sd_clk_se = Signal()
self.specials += [ self.specials += Instance("ODDRX2F",
Instance("ODDRX2F", i_D0 = 0,
i_D0=0, i_D1 = 1,
i_D1=1, i_D2 = 0,
i_D2=0, i_D3 = 1,
i_D3=1, i_ECLK = ClockSignal("sys2x"),
i_ECLK=ClockSignal("sys2x"), i_SCLK = ClockSignal(),
i_SCLK=ClockSignal(), i_RST = ResetSignal("sys2x"),
i_RST=ResetSignal("sys2x"), o_Q = pads.clk_p[i]
o_Q=pads.clk_p[i] )
),
]
# Addresses and Commands ------------------------------------------------------------------- # Addresses and Commands -------------------------------------------------------------------
for i in range(addressbits): for i in range(addressbits):
self.specials += \ self.specials += Instance("ODDRX2F",
Instance("ODDRX2F", i_D0 = dfi.phases[0].address[i],
i_D0=dfi.phases[0].address[i], i_D1 = dfi.phases[0].address[i],
i_D1=dfi.phases[0].address[i], i_D2 = dfi.phases[1].address[i],
i_D2=dfi.phases[1].address[i], i_D3 = dfi.phases[1].address[i],
i_D3=dfi.phases[1].address[i], i_ECLK = ClockSignal("sys2x"),
i_ECLK=ClockSignal("sys2x"), i_SCLK = ClockSignal(),
i_SCLK=ClockSignal(), i_RST = ResetSignal("sys2x"),
i_RST=ResetSignal("sys2x"), o_Q = pads.a[i]
o_Q=pads.a[i]
) )
for i in range(bankbits): for i in range(bankbits):
self.specials += \ self.specials += Instance("ODDRX2F",
Instance("ODDRX2F", i_D0 = dfi.phases[0].bank[i],
i_D0=dfi.phases[0].bank[i], i_D1 = dfi.phases[0].bank[i],
i_D1=dfi.phases[0].bank[i], i_D2 = dfi.phases[1].bank[i],
i_D2=dfi.phases[1].bank[i], i_D3 = dfi.phases[1].bank[i],
i_D3=dfi.phases[1].bank[i], i_ECLK = ClockSignal("sys2x"),
i_ECLK=ClockSignal("sys2x"), i_SCLK = ClockSignal(),
i_SCLK=ClockSignal(), i_RST = ResetSignal("sys2x"),
i_RST=ResetSignal("sys2x"), o_Q = pads.ba[i]
o_Q=pads.ba[i]
) )
controls = ["ras_n", "cas_n", "we_n", "cke", "odt"] controls = ["ras_n", "cas_n", "we_n", "cke", "odt"]
if hasattr(pads, "reset_n"): if hasattr(pads, "reset_n"):
@ -186,16 +182,15 @@ class ECP5DDRPHY(Module, AutoCSR):
controls.append("cs_n") controls.append("cs_n")
for name in controls: for name in controls:
for i in range(len(getattr(pads, name))): for i in range(len(getattr(pads, name))):
self.specials += \ self.specials += Instance("ODDRX2F",
Instance("ODDRX2F", i_D0 = getattr(dfi.phases[0], name)[i],
i_D0=getattr(dfi.phases[0], name)[i], i_D1 = getattr(dfi.phases[0], name)[i],
i_D1=getattr(dfi.phases[0], name)[i], i_D2 = getattr(dfi.phases[1], name)[i],
i_D2=getattr(dfi.phases[1], name)[i], i_D3 = getattr(dfi.phases[1], name)[i],
i_D3=getattr(dfi.phases[1], name)[i], i_ECLK = ClockSignal("sys2x"),
i_ECLK=ClockSignal("sys2x"), i_SCLK = ClockSignal(),
i_SCLK=ClockSignal(), i_RST = ResetSignal("sys2x"),
i_RST=ResetSignal("sys2x"), o_Q = getattr(pads, name)[i]
o_Q=getattr(pads, name)[i]
) )
# DQ --------------------------------------------------------------------------------------- # DQ ---------------------------------------------------------------------------------------
@ -224,46 +219,46 @@ class ECP5DDRPHY(Module, AutoCSR):
datavalid = Signal() datavalid = Signal()
burstdet = Signal() burstdet = Signal()
self.specials += Instance("DQSBUFM", self.specials += Instance("DQSBUFM",
p_DQS_LI_DEL_ADJ="MINUS", p_DQS_LI_DEL_ADJ = "MINUS",
p_DQS_LI_DEL_VAL=1, p_DQS_LI_DEL_VAL = 1,
p_DQS_LO_DEL_ADJ="MINUS", p_DQS_LO_DEL_ADJ = "MINUS",
p_DQS_LO_DEL_VAL=4, p_DQS_LO_DEL_VAL = 4,
# Clocks / Reset # Clocks / Reset
i_SCLK=ClockSignal("sys"), i_SCLK = ClockSignal("sys"),
i_ECLK=ClockSignal("sys2x"), i_ECLK = ClockSignal("sys2x"),
i_RST=ResetSignal("sys2x"), i_RST = ResetSignal("sys2x"),
i_DDRDEL=self.init.delay, i_DDRDEL = self.init.delay,
i_PAUSE=self.init.pause | self._dly_sel.storage[i], i_PAUSE = self.init.pause | self._dly_sel.storage[i],
# Control # Control
# Assert LOADNs to use DDRDEL control # Assert LOADNs to use DDRDEL control
i_RDLOADN=0, i_RDLOADN = 0,
i_RDMOVE=0, i_RDMOVE = 0,
i_RDDIRECTION=1, i_RDDIRECTION = 1,
i_WRLOADN=0, i_WRLOADN = 0,
i_WRMOVE=0, i_WRMOVE = 0,
i_WRDIRECTION=1, i_WRDIRECTION = 1,
# Reads (generate shifted DQS clock for reads) # Reads (generate shifted DQS clock for reads)
i_READ0=dqs_read, i_READ0 = dqs_read,
i_READ1=dqs_read, i_READ1 = dqs_read,
i_READCLKSEL0=rdly[0], i_READCLKSEL0 = rdly[0],
i_READCLKSEL1=rdly[1], i_READCLKSEL1 = rdly[1],
i_READCLKSEL2=rdly[2], i_READCLKSEL2 = rdly[2],
i_DQSI=dqs_i, i_DQSI = dqs_i,
o_DQSR90=dqsr90, o_DQSR90 = dqsr90,
o_RDPNTR0=rdpntr[0], o_RDPNTR0 = rdpntr[0],
o_RDPNTR1=rdpntr[1], o_RDPNTR1 = rdpntr[1],
o_RDPNTR2=rdpntr[2], o_RDPNTR2 = rdpntr[2],
o_WRPNTR0=wrpntr[0], o_WRPNTR0 = wrpntr[0],
o_WRPNTR1=wrpntr[1], o_WRPNTR1 = wrpntr[1],
o_WRPNTR2=wrpntr[2], o_WRPNTR2 = wrpntr[2],
o_DATAVALID=self.datavalid[i], o_DATAVALID = self.datavalid[i],
o_BURSTDET=burstdet, o_BURSTDET = burstdet,
# Writes (generate shifted ECLK clock for writes) # Writes (generate shifted ECLK clock for writes)
o_DQSW270=dqsw270, o_DQSW270 = dqsw270,
o_DQSW=dqsw o_DQSW = dqsw
) )
burstdet_d = Signal() burstdet_d = Signal()
self.sync += [ self.sync += [
@ -293,44 +288,43 @@ class ECP5DDRPHY(Module, AutoCSR):
).Else( ).Else(
dm_o_data_muxed.eq(dm_o_data[:4]) dm_o_data_muxed.eq(dm_o_data[:4])
) )
self.specials += \ self.specials += Instance("ODDRX2DQA",
Instance("ODDRX2DQA", i_D0 = dm_o_data_muxed[0],
i_D0=dm_o_data_muxed[0], i_D1 = dm_o_data_muxed[1],
i_D1=dm_o_data_muxed[1], i_D2 = dm_o_data_muxed[2],
i_D2=dm_o_data_muxed[2], i_D3 = dm_o_data_muxed[3],
i_D3=dm_o_data_muxed[3], i_RST = ResetSignal("sys2x"),
i_RST=ResetSignal("sys2x"), i_DQSW270 = dqsw270,
i_DQSW270=dqsw270, i_ECLK = ClockSignal("sys2x"),
i_ECLK=ClockSignal("sys2x"), i_SCLK = ClockSignal(),
i_SCLK=ClockSignal(), o_Q = pads.dm[i]
o_Q=pads.dm[i]
) )
dqs = Signal() dqs = Signal()
dqs_oe_n = Signal() dqs_oe_n = Signal()
self.specials += \ self.specials += [
Instance("ODDRX2DQSB", Instance("ODDRX2DQSB",
i_D0=dqs_serdes_pattern[0], i_D0 = dqs_serdes_pattern[0],
i_D1=dqs_serdes_pattern[1], i_D1 = dqs_serdes_pattern[1],
i_D2=dqs_serdes_pattern[2], i_D2 = dqs_serdes_pattern[2],
i_D3=dqs_serdes_pattern[3], i_D3 = dqs_serdes_pattern[3],
i_RST=ResetSignal("sys2x"), i_RST = ResetSignal("sys2x"),
i_DQSW=dqsw, i_DQSW = dqsw,
i_ECLK=ClockSignal("sys2x"), i_ECLK = ClockSignal("sys2x"),
i_SCLK=ClockSignal(), i_SCLK = ClockSignal(),
o_Q=dqs o_Q = dqs
) ),
self.specials += \
Instance("TSHX2DQSA", Instance("TSHX2DQSA",
i_T0=~(oe_dqs|dqs_postamble), i_T0 = ~(oe_dqs|dqs_postamble),
i_T1=~(oe_dqs|dqs_preamble), i_T1 = ~(oe_dqs|dqs_preamble),
i_SCLK=ClockSignal(), i_SCLK = ClockSignal(),
i_ECLK=ClockSignal("sys2x"), i_ECLK = ClockSignal("sys2x"),
i_DQSW=dqsw, i_DQSW = dqsw,
i_RST=ResetSignal("sys2x"), i_RST = ResetSignal("sys2x"),
o_Q=dqs_oe_n, o_Q = dqs_oe_n,
) ),
self.specials += Tristate(pads.dqs_p[i], dqs, ~dqs_oe_n, dqs_i) Tristate(pads.dqs_p[i], dqs, ~dqs_oe_n, dqs_i)
]
for j in range(8*i, 8*(i+1)): for j in range(8*i, 8*(i+1)):
dq_o = Signal() dq_o = Signal()
@ -354,45 +348,44 @@ class ECP5DDRPHY(Module, AutoCSR):
).Else( ).Else(
dq_o_data_muxed.eq(dq_o_data[:4]) dq_o_data_muxed.eq(dq_o_data[:4])
) )
self.specials += \ self.specials += [
Instance("ODDRX2DQA", Instance("ODDRX2DQA",
i_D0=dq_o_data_muxed[0], i_D0 = dq_o_data_muxed[0],
i_D1=dq_o_data_muxed[1], i_D1 = dq_o_data_muxed[1],
i_D2=dq_o_data_muxed[2], i_D2 = dq_o_data_muxed[2],
i_D3=dq_o_data_muxed[3], i_D3 = dq_o_data_muxed[3],
i_RST=ResetSignal("sys2x"), i_RST = ResetSignal("sys2x"),
i_DQSW270=dqsw270, i_DQSW270 = dqsw270,
i_ECLK=ClockSignal("sys2x"), i_ECLK = ClockSignal("sys2x"),
i_SCLK=ClockSignal(), i_SCLK = ClockSignal(),
o_Q=dq_o o_Q = dq_o
) ),
self.specials += \
Instance("DELAYF", Instance("DELAYF",
i_A=dq_i, i_A = dq_i,
i_LOADN=1, i_LOADN = 1,
i_MOVE=0, i_MOVE = 0,
i_DIRECTION=0, i_DIRECTION = 0,
o_Z=dq_i_delayed, o_Z = dq_i_delayed,
p_DEL_MODE="DQS_ALIGNED_X2" p_DEL_MODE = "DQS_ALIGNED_X2"
) ),
self.specials += \
Instance("IDDRX2DQA", Instance("IDDRX2DQA",
i_D=dq_i_delayed, i_D = dq_i_delayed,
i_RST=ResetSignal("sys2x"), i_RST = ResetSignal("sys2x"),
i_DQSR90=dqsr90, i_DQSR90 = dqsr90,
i_SCLK=ClockSignal(), i_SCLK = ClockSignal(),
i_ECLK=ClockSignal("sys2x"), i_ECLK = ClockSignal("sys2x"),
i_RDPNTR0=rdpntr[0], i_RDPNTR0 = rdpntr[0],
i_RDPNTR1=rdpntr[1], i_RDPNTR1 = rdpntr[1],
i_RDPNTR2=rdpntr[2], i_RDPNTR2 = rdpntr[2],
i_WRPNTR0=wrpntr[0], i_WRPNTR0 = wrpntr[0],
i_WRPNTR1=wrpntr[1], i_WRPNTR1 = wrpntr[1],
i_WRPNTR2=wrpntr[2], i_WRPNTR2 = wrpntr[2],
o_Q0=dq_i_data[0], o_Q0 = dq_i_data[0],
o_Q1=dq_i_data[1], o_Q1 = dq_i_data[1],
o_Q2=dq_i_data[2], o_Q2 = dq_i_data[2],
o_Q3=dq_i_data[3], o_Q3 = dq_i_data[3],
) )
]
dq_bitslip = BitSlip(4) dq_bitslip = BitSlip(4)
self.comb += dq_bitslip.i.eq(dq_i_data) self.comb += dq_bitslip.i.eq(dq_i_data)
self.sync += \ self.sync += \
@ -412,17 +405,18 @@ class ECP5DDRPHY(Module, AutoCSR):
dfi.phases[1].rddata[0*databits+j].eq(dq_bitslip.o[0]), dfi.phases[1].rddata[1*databits+j].eq(dq_bitslip.o[1]), dfi.phases[1].rddata[0*databits+j].eq(dq_bitslip.o[0]), dfi.phases[1].rddata[1*databits+j].eq(dq_bitslip.o[1]),
dfi.phases[1].rddata[2*databits+j].eq(dq_bitslip.o[2]), dfi.phases[1].rddata[3*databits+j].eq(dq_bitslip.o[3]), dfi.phases[1].rddata[2*databits+j].eq(dq_bitslip.o[2]), dfi.phases[1].rddata[3*databits+j].eq(dq_bitslip.o[3]),
] ]
self.specials += \ self.specials += [
Instance("TSHX2DQA", Instance("TSHX2DQA",
i_T0=~oe_dq, i_T0 = ~oe_dq,
i_T1=~oe_dq, i_T1 = ~oe_dq,
i_SCLK=ClockSignal(), i_SCLK = ClockSignal(),
i_ECLK=ClockSignal("sys2x"), i_ECLK = ClockSignal("sys2x"),
i_DQSW270=dqsw270, i_DQSW270 = dqsw270,
i_RST=ResetSignal("sys2x"), i_RST = ResetSignal("sys2x"),
o_Q=dq_oe_n, o_Q = dq_oe_n,
) ),
self.specials += Tristate(pads.dq[j], dq_o, ~dq_oe_n, dq_i) Tristate(pads.dq[j], dq_o, ~dq_oe_n, dq_i)
]
# Flow control ----------------------------------------------------------------------------- # Flow control -----------------------------------------------------------------------------
# #