phy/usddrphy: add Ultrascale Plus support.
Similar to Ultrascale, but SIM_DEVICE needs to be changes to "ULTRASCALE_PLUS".
This commit is contained in:
parent
b8339886da
commit
752e006cf9
4
README
4
README
|
@ -3,7 +3,7 @@
|
||||||
/ /__/ / __/ -_) // / , _/ __ |/ /|_/ /
|
/ /__/ / __/ -_) // / , _/ __ |/ /|_/ /
|
||||||
/____/_/\__/\__/____/_/|_/_/ |_/_/ /_/
|
/____/_/\__/\__/____/_/|_/_/ |_/_/ /_/
|
||||||
|
|
||||||
Copyright 2015-2019 / EnjoyDigital
|
Copyright 2015-2020 / EnjoyDigital
|
||||||
|
|
||||||
A small footprint and configurable DRAM core
|
A small footprint and configurable DRAM core
|
||||||
powered by Migen & LiteX
|
powered by Migen & LiteX
|
||||||
|
@ -27,7 +27,7 @@ PHY:
|
||||||
- Generic SDRAM PHY (vendor agnostic, tested on Xilinx, Altera, Lattice)
|
- Generic SDRAM PHY (vendor agnostic, tested on Xilinx, Altera, Lattice)
|
||||||
- Spartan6 DDR/LPDDR/DDR2/DDR3 PHY (1:2 or 1:4 frequency ratio)
|
- Spartan6 DDR/LPDDR/DDR2/DDR3 PHY (1:2 or 1:4 frequency ratio)
|
||||||
- Spartan7/Artix7/Kintex7/Virtex7 DDR2/DDR3 PHY (1:2 or 1:4 frequency ratio)
|
- Spartan7/Artix7/Kintex7/Virtex7 DDR2/DDR3 PHY (1:2 or 1:4 frequency ratio)
|
||||||
- Kintex/Virtex Ultrascale DDR3/DDR4 PHY (1:4 frequency ratio)
|
- Kintex/Virtex Ultrascale (Plus) DDR3/DDR4 PHY (1:4 frequency ratio)
|
||||||
- ECP5 DDR3 PHY (1:2 frequency ratio)
|
- ECP5 DDR3 PHY (1:2 frequency ratio)
|
||||||
Core:
|
Core:
|
||||||
- Fully pipelined, high performance.
|
- Fully pipelined, high performance.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# This file is Copyright (c) 2015-2020 Florent Kermarrec <florent@enjoy-digital.fr>
|
# This file is Copyright (c) 2015-2020 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
# License: BSD
|
# License: BSD
|
||||||
|
|
||||||
# 1:4 frequency-ratio DDR3/DDR4 PHY for Kintex/Virtex Ultrascale
|
# 1:4 frequency-ratio DDR3/DDR4 PHY for Kintex/Virtex Ultrascale (Plus)
|
||||||
# DDR3: 800, 1066, 1333 and 1600 MT/s
|
# DDR3: 800, 1066, 1333 and 1600 MT/s
|
||||||
# DDR4: 1600 MT/s
|
# DDR4: 1600 MT/s
|
||||||
|
|
||||||
|
@ -15,14 +15,15 @@ from litex.soc.interconnect.csr import *
|
||||||
from litedram.common import *
|
from litedram.common import *
|
||||||
from litedram.phy.dfi import *
|
from litedram.phy.dfi import *
|
||||||
|
|
||||||
# Xilinx Ultrascale DDR3/DDR4 PHY ------------------------------------------------------------------
|
# Xilinx Ultrascale (Plus) DDR3/DDR4 PHY -----------------------------------------------------------
|
||||||
|
|
||||||
class USDDRPHY(Module, AutoCSR):
|
class USDDRPHY(Module, AutoCSR):
|
||||||
def __init__(self, pads,
|
def __init__(self, pads,
|
||||||
memtype = "DDR3",
|
memtype = "DDR3",
|
||||||
sys_clk_freq = 100e6,
|
sys_clk_freq = 100e6,
|
||||||
iodelay_clk_freq = 200e6,
|
iodelay_clk_freq = 200e6,
|
||||||
cmd_latency = 0):
|
cmd_latency = 0,
|
||||||
|
sim_device = "ULTRASCALE"):
|
||||||
tck = 2/(2*4*sys_clk_freq)
|
tck = 2/(2*4*sys_clk_freq)
|
||||||
addressbits = len(pads.a)
|
addressbits = len(pads.a)
|
||||||
if memtype == "DDR4":
|
if memtype == "DDR4":
|
||||||
|
@ -32,6 +33,7 @@ class USDDRPHY(Module, AutoCSR):
|
||||||
databits = len(pads.dq)
|
databits = len(pads.dq)
|
||||||
nphases = 4
|
nphases = 4
|
||||||
assert databits%8 == 0
|
assert databits%8 == 0
|
||||||
|
assert sim_device in ["ULTRASCALE", "ULTRASCALE_PLUS"]
|
||||||
|
|
||||||
if hasattr(pads, "ten"):
|
if hasattr(pads, "ten"):
|
||||||
self.comb += pads.ten.eq(0)
|
self.comb += pads.ten.eq(0)
|
||||||
|
@ -96,6 +98,7 @@ class USDDRPHY(Module, AutoCSR):
|
||||||
clk_o_delayed = Signal()
|
clk_o_delayed = Signal()
|
||||||
self.specials += [
|
self.specials += [
|
||||||
Instance("OSERDESE3",
|
Instance("OSERDESE3",
|
||||||
|
p_SIM_DEVICE = sim_device,
|
||||||
p_DATA_WIDTH = 8,
|
p_DATA_WIDTH = 8,
|
||||||
p_INIT = 0,
|
p_INIT = 0,
|
||||||
p_IS_RST_INVERTED = 0,
|
p_IS_RST_INVERTED = 0,
|
||||||
|
@ -108,6 +111,7 @@ class USDDRPHY(Module, AutoCSR):
|
||||||
o_OQ = clk_o_nodelay,
|
o_OQ = clk_o_nodelay,
|
||||||
),
|
),
|
||||||
Instance("ODELAYE3",
|
Instance("ODELAYE3",
|
||||||
|
p_SIM_DEVICE = sim_device,
|
||||||
p_CASCADE = "NONE",
|
p_CASCADE = "NONE",
|
||||||
p_UPDATE_MODE = "ASYNC",
|
p_UPDATE_MODE = "ASYNC",
|
||||||
p_REFCLK_FREQUENCY = iodelay_clk_freq/1e6,
|
p_REFCLK_FREQUENCY = iodelay_clk_freq/1e6,
|
||||||
|
@ -134,6 +138,7 @@ class USDDRPHY(Module, AutoCSR):
|
||||||
a_o_nodelay = Signal()
|
a_o_nodelay = Signal()
|
||||||
self.specials += [
|
self.specials += [
|
||||||
Instance("OSERDESE3",
|
Instance("OSERDESE3",
|
||||||
|
p_SIM_DEVICE = sim_device,
|
||||||
p_DATA_WIDTH = 8,
|
p_DATA_WIDTH = 8,
|
||||||
p_INIT = 0,
|
p_INIT = 0,
|
||||||
p_IS_RST_INVERTED = 0,
|
p_IS_RST_INVERTED = 0,
|
||||||
|
@ -149,6 +154,7 @@ class USDDRPHY(Module, AutoCSR):
|
||||||
o_OQ = a_o_nodelay,
|
o_OQ = a_o_nodelay,
|
||||||
),
|
),
|
||||||
Instance("ODELAYE3",
|
Instance("ODELAYE3",
|
||||||
|
p_SIM_DEVICE = sim_device,
|
||||||
p_CASCADE = "NONE",
|
p_CASCADE = "NONE",
|
||||||
p_UPDATE_MODE = "ASYNC",
|
p_UPDATE_MODE = "ASYNC",
|
||||||
p_REFCLK_FREQUENCY = iodelay_clk_freq/1e6,
|
p_REFCLK_FREQUENCY = iodelay_clk_freq/1e6,
|
||||||
|
@ -175,6 +181,7 @@ class USDDRPHY(Module, AutoCSR):
|
||||||
ba_o_nodelay = Signal()
|
ba_o_nodelay = Signal()
|
||||||
self.specials += [
|
self.specials += [
|
||||||
Instance("OSERDESE3",
|
Instance("OSERDESE3",
|
||||||
|
p_SIM_DEVICE = sim_device,
|
||||||
p_DATA_WIDTH = 8,
|
p_DATA_WIDTH = 8,
|
||||||
p_INIT = 0,
|
p_INIT = 0,
|
||||||
p_IS_RST_INVERTED = 0,
|
p_IS_RST_INVERTED = 0,
|
||||||
|
@ -191,6 +198,7 @@ class USDDRPHY(Module, AutoCSR):
|
||||||
o_OQ = ba_o_nodelay,
|
o_OQ = ba_o_nodelay,
|
||||||
),
|
),
|
||||||
Instance("ODELAYE3",
|
Instance("ODELAYE3",
|
||||||
|
p_SIM_DEVICE = sim_device,
|
||||||
p_CASCADE = "NONE",
|
p_CASCADE = "NONE",
|
||||||
p_UPDATE_MODE = "ASYNC",
|
p_UPDATE_MODE = "ASYNC",
|
||||||
p_REFCLK_FREQUENCY = iodelay_clk_freq/1e6,
|
p_REFCLK_FREQUENCY = iodelay_clk_freq/1e6,
|
||||||
|
@ -218,6 +226,7 @@ class USDDRPHY(Module, AutoCSR):
|
||||||
x_o_nodelay = Signal()
|
x_o_nodelay = Signal()
|
||||||
self.specials += [
|
self.specials += [
|
||||||
Instance("OSERDESE3",
|
Instance("OSERDESE3",
|
||||||
|
p_SIM_DEVICE = sim_device,
|
||||||
p_DATA_WIDTH = 8,
|
p_DATA_WIDTH = 8,
|
||||||
p_INIT = 0,
|
p_INIT = 0,
|
||||||
p_IS_RST_INVERTED = 0,
|
p_IS_RST_INVERTED = 0,
|
||||||
|
@ -234,6 +243,7 @@ class USDDRPHY(Module, AutoCSR):
|
||||||
o_OQ = x_o_nodelay,
|
o_OQ = x_o_nodelay,
|
||||||
),
|
),
|
||||||
Instance("ODELAYE3",
|
Instance("ODELAYE3",
|
||||||
|
p_SIM_DEVICE = sim_device,
|
||||||
p_CASCADE = "NONE",
|
p_CASCADE = "NONE",
|
||||||
p_UPDATE_MODE = "ASYNC",
|
p_UPDATE_MODE = "ASYNC",
|
||||||
p_REFCLK_FREQUENCY = iodelay_clk_freq/1e6,
|
p_REFCLK_FREQUENCY = iodelay_clk_freq/1e6,
|
||||||
|
@ -266,6 +276,7 @@ class USDDRPHY(Module, AutoCSR):
|
||||||
dm_o_nodelay = Signal()
|
dm_o_nodelay = Signal()
|
||||||
self.specials += [
|
self.specials += [
|
||||||
Instance("OSERDESE3",
|
Instance("OSERDESE3",
|
||||||
|
p_SIM_DEVICE = sim_device,
|
||||||
p_DATA_WIDTH = 8,
|
p_DATA_WIDTH = 8,
|
||||||
p_INIT = 0,
|
p_INIT = 0,
|
||||||
p_IS_RST_INVERTED = 0,
|
p_IS_RST_INVERTED = 0,
|
||||||
|
@ -282,6 +293,7 @@ class USDDRPHY(Module, AutoCSR):
|
||||||
o_OQ = dm_o_nodelay,
|
o_OQ = dm_o_nodelay,
|
||||||
),
|
),
|
||||||
Instance("ODELAYE3",
|
Instance("ODELAYE3",
|
||||||
|
p_SIM_DEVICE = sim_device,
|
||||||
p_CASCADE = "NONE",
|
p_CASCADE = "NONE",
|
||||||
p_UPDATE_MODE = "ASYNC",
|
p_UPDATE_MODE = "ASYNC",
|
||||||
p_REFCLK_FREQUENCY = iodelay_clk_freq/1e6,
|
p_REFCLK_FREQUENCY = iodelay_clk_freq/1e6,
|
||||||
|
@ -317,6 +329,7 @@ class USDDRPHY(Module, AutoCSR):
|
||||||
)
|
)
|
||||||
self.specials += [
|
self.specials += [
|
||||||
Instance("OSERDESE3",
|
Instance("OSERDESE3",
|
||||||
|
p_SIM_DEVICE = sim_device,
|
||||||
p_DATA_WIDTH = 8,
|
p_DATA_WIDTH = 8,
|
||||||
p_INIT = 0,
|
p_INIT = 0,
|
||||||
p_IS_RST_INVERTED = 0,
|
p_IS_RST_INVERTED = 0,
|
||||||
|
@ -336,6 +349,7 @@ class USDDRPHY(Module, AutoCSR):
|
||||||
|
|
||||||
),
|
),
|
||||||
Instance("ODELAYE3",
|
Instance("ODELAYE3",
|
||||||
|
p_SIM_DEVICE = sim_device,
|
||||||
p_CASCADE = "NONE",
|
p_CASCADE = "NONE",
|
||||||
p_UPDATE_MODE = "ASYNC",
|
p_UPDATE_MODE = "ASYNC",
|
||||||
p_REFCLK_FREQUENCY = iodelay_clk_freq/1e6,
|
p_REFCLK_FREQUENCY = iodelay_clk_freq/1e6,
|
||||||
|
@ -381,6 +395,7 @@ class USDDRPHY(Module, AutoCSR):
|
||||||
self.submodules += dq_bitslip
|
self.submodules += dq_bitslip
|
||||||
self.specials += [
|
self.specials += [
|
||||||
Instance("OSERDESE3",
|
Instance("OSERDESE3",
|
||||||
|
p_SIM_DEVICE = sim_device,
|
||||||
p_DATA_WIDTH = 8,
|
p_DATA_WIDTH = 8,
|
||||||
p_INIT = 0,
|
p_INIT = 0,
|
||||||
p_IS_RST_INVERTED = 0,
|
p_IS_RST_INVERTED = 0,
|
||||||
|
@ -399,6 +414,7 @@ class USDDRPHY(Module, AutoCSR):
|
||||||
o_T_OUT = dq_t,
|
o_T_OUT = dq_t,
|
||||||
),
|
),
|
||||||
Instance("ISERDESE3",
|
Instance("ISERDESE3",
|
||||||
|
p_SIM_DEVICE = sim_device,
|
||||||
p_IS_CLK_INVERTED = 0,
|
p_IS_CLK_INVERTED = 0,
|
||||||
p_IS_CLK_B_INVERTED = 1,
|
p_IS_CLK_B_INVERTED = 1,
|
||||||
p_DATA_WIDTH = 8,
|
p_DATA_WIDTH = 8,
|
||||||
|
@ -411,6 +427,7 @@ class USDDRPHY(Module, AutoCSR):
|
||||||
o_Q = dq_bitslip.i,
|
o_Q = dq_bitslip.i,
|
||||||
),
|
),
|
||||||
Instance("ODELAYE3",
|
Instance("ODELAYE3",
|
||||||
|
p_SIM_DEVICE = sim_device,
|
||||||
p_CASCADE = "NONE",
|
p_CASCADE = "NONE",
|
||||||
p_UPDATE_MODE = "ASYNC",
|
p_UPDATE_MODE = "ASYNC",
|
||||||
p_REFCLK_FREQUENCY = iodelay_clk_freq/1e6,
|
p_REFCLK_FREQUENCY = iodelay_clk_freq/1e6,
|
||||||
|
@ -428,6 +445,7 @@ class USDDRPHY(Module, AutoCSR):
|
||||||
o_DATAOUT = dq_o_delayed,
|
o_DATAOUT = dq_o_delayed,
|
||||||
),
|
),
|
||||||
Instance("IDELAYE3",
|
Instance("IDELAYE3",
|
||||||
|
p_SIM_DEVICE = sim_device,
|
||||||
p_CASCADE = "NONE",
|
p_CASCADE = "NONE",
|
||||||
p_UPDATE_MODE = "ASYNC",
|
p_UPDATE_MODE = "ASYNC",
|
||||||
p_REFCLK_FREQUENCY = iodelay_clk_freq/1e6,
|
p_REFCLK_FREQUENCY = iodelay_clk_freq/1e6,
|
||||||
|
|
Loading…
Reference in New Issue