litedram_gen: Add initial SDRAM support (with ULX3S example).
This commit is contained in:
parent
83d18f48c7
commit
317072a198
|
@ -0,0 +1,41 @@
|
||||||
|
#
|
||||||
|
# This file is part of LiteDRAM.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2021 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
{
|
||||||
|
# General ------------------------------------------------------------------
|
||||||
|
"cpu": "serv", # Type of CPU used for init/calib.
|
||||||
|
"memtype": "SDR", # DRAM type.
|
||||||
|
|
||||||
|
# PHY ----------------------------------------------------------------------
|
||||||
|
"sdram_module": "MT48LC16M16", # SDRAM modules of the board or SO-DIMM
|
||||||
|
"sdram_module_nb": 2, # Number of byte groups
|
||||||
|
"sdram_phy": "GENSDRPHY", # Type of FPGA PHY
|
||||||
|
|
||||||
|
# Frequency ----------------------------------------------------------------
|
||||||
|
"sys_clk_freq": 50e6, # System clock frequency (SDR_clk = sys_clk)
|
||||||
|
|
||||||
|
# Core ---------------------------------------------------------------------
|
||||||
|
"cmd_buffer_depth": 16, # Depth of the command buffer
|
||||||
|
|
||||||
|
# User Ports ---------------------------------------------------------------
|
||||||
|
"user_ports": {
|
||||||
|
"axi_0" : {
|
||||||
|
"type": "axi",
|
||||||
|
"id_width": 32,
|
||||||
|
},
|
||||||
|
"wishbone_0" : {
|
||||||
|
"type": "wishbone",
|
||||||
|
},
|
||||||
|
"native_0" : {
|
||||||
|
"type": "native",
|
||||||
|
},
|
||||||
|
"fifo_0" : {
|
||||||
|
"type": "fifo",
|
||||||
|
"base": 0x00000000,
|
||||||
|
"depth": 0x01000000,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
116
litedram/gen.py
116
litedram/gen.py
|
@ -3,7 +3,7 @@
|
||||||
#
|
#
|
||||||
# This file is part of LiteDRAM.
|
# This file is part of LiteDRAM.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2018-2020 Florent Kermarrec <florent@enjoy-digital.fr>
|
# Copyright (c) 2018-2021 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
# Copyright (c) 2020 Stefan Schrijvers <ximin@ximinity.net>
|
# Copyright (c) 2020 Stefan Schrijvers <ximin@ximinity.net>
|
||||||
# SPDX-License-Identifier: BSD-2-Clause
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ The standalone core is generated from a YAML configuration file that allows the
|
||||||
easily a custom configuration of the core.
|
easily a custom configuration of the core.
|
||||||
|
|
||||||
Current version of the generator is limited to:
|
Current version of the generator is limited to:
|
||||||
|
- SDR on all FPGAs.
|
||||||
- DDR3 on Lattice ECP5 FPGAs.
|
- DDR3 on Lattice ECP5 FPGAs.
|
||||||
- DDR2/DDR3 on Xilinx 7-Series FPGAs.
|
- DDR2/DDR3 on Xilinx 7-Series FPGAs.
|
||||||
- DDR4 on Xilinx Ultascale(+) FPGAs.
|
- DDR4 on Xilinx Ultascale(+) FPGAs.
|
||||||
|
@ -91,8 +92,26 @@ def get_common_ios():
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_dram_ios(core_config):
|
def get_dram_ios(core_config):
|
||||||
|
assert core_config["memtype"] in ["SDR", "DDR2", "DDR3", "DDR4"]
|
||||||
|
|
||||||
|
# SDR.
|
||||||
|
if core_config["memtype"] in ["SDR"]:
|
||||||
|
return [
|
||||||
|
("sdram", 0,
|
||||||
|
Subsignal("a", Pins(log2_int(core_config["sdram_module"].nrows))),
|
||||||
|
Subsignal("ba", Pins(log2_int(core_config["sdram_module"].nbanks))),
|
||||||
|
Subsignal("ras_n", Pins(1)),
|
||||||
|
Subsignal("cas_n", Pins(1)),
|
||||||
|
Subsignal("we_n", Pins(1)),
|
||||||
|
Subsignal("cs_n", Pins(1)),
|
||||||
|
Subsignal("dm", Pins(core_config["sdram_module_nb"])),
|
||||||
|
Subsignal("dq", Pins(8*core_config["sdram_module_nb"])),
|
||||||
|
Subsignal("cke", Pins(1))
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
# DDR2 / DDR3.
|
||||||
if core_config["memtype"] in ["DDR2", "DDR3"]:
|
if core_config["memtype"] in ["DDR2", "DDR3"]:
|
||||||
a_width = log2_int(core_config["sdram_module"].nrows)
|
|
||||||
return [
|
return [
|
||||||
("ddram", 0,
|
("ddram", 0,
|
||||||
Subsignal("a", Pins(log2_int(core_config["sdram_module"].nrows))),
|
Subsignal("a", Pins(log2_int(core_config["sdram_module"].nrows))),
|
||||||
|
@ -112,7 +131,8 @@ def get_dram_ios(core_config):
|
||||||
Subsignal("reset_n", Pins(1))
|
Subsignal("reset_n", Pins(1))
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
elif core_config["memtype"] == "DDR4":
|
# DDR4.
|
||||||
|
if core_config["memtype"] == "DDR4":
|
||||||
# On DDR4, A14. A15 and A16 are shared with we_n/cas_n/ras_n
|
# On DDR4, A14. A15 and A16 are shared with we_n/cas_n/ras_n
|
||||||
a_width = min(log2_int(core_config["sdram_module"].nrows), 14)
|
a_width = min(log2_int(core_config["sdram_module"].nrows), 14)
|
||||||
return [
|
return [
|
||||||
|
@ -240,6 +260,18 @@ class Platform(XilinxPlatform):
|
||||||
|
|
||||||
# CRG ----------------------------------------------------------------------------------------------
|
# CRG ----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class LiteDRAMGENSDRPHYCRG(Module):
|
||||||
|
def __init__(self, platform, core_config):
|
||||||
|
assert core_config["memtype"] in ["SDR"]
|
||||||
|
self.clock_domains.cd_sys = ClockDomain()
|
||||||
|
|
||||||
|
# # #
|
||||||
|
|
||||||
|
# Clk / Rst.
|
||||||
|
self.comb += self.cd_sys.clk.eq(platform.request("clk"))
|
||||||
|
self.specials += AsyncResetSynchronizer(self.cd_sys, platform.request("rst"))
|
||||||
|
|
||||||
|
|
||||||
class LiteDRAMECP5DDRPHYCRG(Module):
|
class LiteDRAMECP5DDRPHYCRG(Module):
|
||||||
def __init__(self, platform, core_config):
|
def __init__(self, platform, core_config):
|
||||||
assert core_config["memtype"] in ["DDR3"]
|
assert core_config["memtype"] in ["DDR3"]
|
||||||
|
@ -254,18 +286,18 @@ class LiteDRAMECP5DDRPHYCRG(Module):
|
||||||
self.stop = Signal()
|
self.stop = Signal()
|
||||||
self.reset = Signal()
|
self.reset = Signal()
|
||||||
|
|
||||||
# clk / rst
|
# Clk / Rst.
|
||||||
clk = platform.request("clk")
|
clk = platform.request("clk")
|
||||||
rst = platform.request("rst")
|
rst = platform.request("rst")
|
||||||
|
|
||||||
# power on reset
|
# Power On Reset.
|
||||||
por_count = Signal(16, reset=2**16-1)
|
por_count = Signal(16, reset=2**16-1)
|
||||||
por_done = Signal()
|
por_done = Signal()
|
||||||
self.comb += self.cd_por.clk.eq(clk)
|
self.comb += self.cd_por.clk.eq(clk)
|
||||||
self.comb += por_done.eq(por_count == 0)
|
self.comb += por_done.eq(por_count == 0)
|
||||||
self.sync.por += If(~por_done, por_count.eq(por_count - 1))
|
self.sync.por += If(~por_done, por_count.eq(por_count - 1))
|
||||||
|
|
||||||
# pll
|
# PLL.
|
||||||
self.submodules.pll = pll = ECP5PLL()
|
self.submodules.pll = pll = ECP5PLL()
|
||||||
self.comb += pll.reset.eq(~por_done | rst)
|
self.comb += pll.reset.eq(~por_done | rst)
|
||||||
pll.register_clkin(clk, core_config["input_clk_freq"])
|
pll.register_clkin(clk, core_config["input_clk_freq"])
|
||||||
|
@ -303,10 +335,11 @@ class LiteDRAMS7DDRPHYCRG(Module):
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
|
# Clk / Rst.
|
||||||
clk = platform.request("clk")
|
clk = platform.request("clk")
|
||||||
rst = platform.request("rst")
|
rst = platform.request("rst")
|
||||||
|
|
||||||
# Sys PLL
|
# PLL.
|
||||||
self.submodules.sys_pll = sys_pll = S7PLL(speedgrade=core_config["speedgrade"])
|
self.submodules.sys_pll = sys_pll = S7PLL(speedgrade=core_config["speedgrade"])
|
||||||
self.comb += sys_pll.reset.eq(rst)
|
self.comb += sys_pll.reset.eq(rst)
|
||||||
sys_pll.register_clkin(clk, core_config["input_clk_freq"])
|
sys_pll.register_clkin(clk, core_config["input_clk_freq"])
|
||||||
|
@ -322,7 +355,7 @@ class LiteDRAMS7DDRPHYCRG(Module):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
self.comb += platform.request("pll_locked").eq(sys_pll.locked)
|
self.comb += platform.request("pll_locked").eq(sys_pll.locked)
|
||||||
|
|
||||||
# IODelay Ctrl
|
# IODelay Ctrl.
|
||||||
self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_iodelay)
|
self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_iodelay)
|
||||||
|
|
||||||
class LiteDRAMUSDDRPHYCRG(Module):
|
class LiteDRAMUSDDRPHYCRG(Module):
|
||||||
|
@ -336,17 +369,18 @@ class LiteDRAMUSDDRPHYCRG(Module):
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
|
# Clk / Rst.
|
||||||
clk = platform.request("clk")
|
clk = platform.request("clk")
|
||||||
rst = platform.request("rst")
|
rst = platform.request("rst")
|
||||||
|
|
||||||
# Power On Reset
|
# Power On Reset.
|
||||||
por_count = Signal(32, reset=int(core_config["input_clk_freq"]*100/1e3)) # 100ms
|
por_count = Signal(32, reset=int(core_config["input_clk_freq"]*100/1e3)) # 100ms
|
||||||
por_done = Signal()
|
por_done = Signal()
|
||||||
self.comb += self.cd_por.clk.eq(clk)
|
self.comb += self.cd_por.clk.eq(clk)
|
||||||
self.comb += por_done.eq(por_count == 0)
|
self.comb += por_done.eq(por_count == 0)
|
||||||
self.sync.por += If(~por_done, por_count.eq(por_count - 1))
|
self.sync.por += If(~por_done, por_count.eq(por_count - 1))
|
||||||
|
|
||||||
# Sys PLL
|
# PLL.
|
||||||
self.submodules.sys_pll = sys_pll = USMMCM(speedgrade=core_config["speedgrade"])
|
self.submodules.sys_pll = sys_pll = USMMCM(speedgrade=core_config["speedgrade"])
|
||||||
self.comb += sys_pll.reset.eq(rst)
|
self.comb += sys_pll.reset.eq(rst)
|
||||||
sys_pll.register_clkin(clk, core_config["input_clk_freq"])
|
sys_pll.register_clkin(clk, core_config["input_clk_freq"])
|
||||||
|
@ -361,7 +395,7 @@ class LiteDRAMUSDDRPHYCRG(Module):
|
||||||
i_CE=por_done, i_I=self.cd_sys4x_pll.clk, o_O=self.cd_sys4x.clk),
|
i_CE=por_done, i_I=self.cd_sys4x_pll.clk, o_O=self.cd_sys4x.clk),
|
||||||
]
|
]
|
||||||
|
|
||||||
# IODelay Ctrl
|
# IODelay Ctrl.
|
||||||
self.submodules.idelayctrl = USIDELAYCTRL(self.cd_iodelay, cd_sys=self.cd_sys)
|
self.submodules.idelayctrl = USIDELAYCTRL(self.cd_iodelay, cd_sys=self.cd_sys)
|
||||||
|
|
||||||
class LiteDRAMUSPDDRPHYCRG(Module):
|
class LiteDRAMUSPDDRPHYCRG(Module):
|
||||||
|
@ -375,17 +409,18 @@ class LiteDRAMUSPDDRPHYCRG(Module):
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
|
# Clk / Rst.
|
||||||
clk = platform.request("clk")
|
clk = platform.request("clk")
|
||||||
rst = platform.request("rst")
|
rst = platform.request("rst")
|
||||||
|
|
||||||
# Power On Reset
|
# Power On Reset.
|
||||||
por_count = Signal(32, reset=int(core_config["input_clk_freq"]*100/1e3)) # 100ms
|
por_count = Signal(32, reset=int(core_config["input_clk_freq"]*100/1e3)) # 100ms
|
||||||
por_done = Signal()
|
por_done = Signal()
|
||||||
self.comb += self.cd_por.clk.eq(clk)
|
self.comb += self.cd_por.clk.eq(clk)
|
||||||
self.comb += por_done.eq(por_count == 0)
|
self.comb += por_done.eq(por_count == 0)
|
||||||
self.sync.por += If(~por_done, por_count.eq(por_count - 1))
|
self.sync.por += If(~por_done, por_count.eq(por_count - 1))
|
||||||
|
|
||||||
# Sys PLL
|
# PLL.
|
||||||
self.submodules.sys_pll = sys_pll = USPMMCM(speedgrade=core_config["speedgrade"])
|
self.submodules.sys_pll = sys_pll = USPMMCM(speedgrade=core_config["speedgrade"])
|
||||||
self.comb += sys_pll.reset.eq(rst)
|
self.comb += sys_pll.reset.eq(rst)
|
||||||
sys_pll.register_clkin(clk, core_config["input_clk_freq"])
|
sys_pll.register_clkin(clk, core_config["input_clk_freq"])
|
||||||
|
@ -400,7 +435,7 @@ class LiteDRAMUSPDDRPHYCRG(Module):
|
||||||
i_CE=por_done, i_I=self.cd_sys4x_pll.clk, o_O=self.cd_sys4x.clk),
|
i_CE=por_done, i_I=self.cd_sys4x_pll.clk, o_O=self.cd_sys4x.clk),
|
||||||
]
|
]
|
||||||
|
|
||||||
# IODelay Ctrl
|
# IODelay Ctrl.
|
||||||
self.submodules.idelayctrl = USPIDELAYCTRL(self.cd_iodelay, cd_sys=self.cd_sys)
|
self.submodules.idelayctrl = USPIDELAYCTRL(self.cd_iodelay, cd_sys=self.cd_sys)
|
||||||
|
|
||||||
# LiteDRAMCoreControl ------------------------------------------------------------------------------
|
# LiteDRAMCoreControl ------------------------------------------------------------------------------
|
||||||
|
@ -437,24 +472,28 @@ class LiteDRAMCore(SoCCore):
|
||||||
|
|
||||||
# CRG --------------------------------------------------------------------------------------
|
# CRG --------------------------------------------------------------------------------------
|
||||||
if isinstance(platform, SimPlatform):
|
if isinstance(platform, SimPlatform):
|
||||||
self.submodules.crg = CRG(platform.request("clk"))
|
crg = CRG(platform.request("clk"))
|
||||||
|
elif core_config["sdram_phy"] in [litedram_phys.GENSDRPHY]:
|
||||||
|
crg = LiteDRAMGENSDRPHYCRG(platform, core_config)
|
||||||
elif core_config["sdram_phy"] in [litedram_phys.ECP5DDRPHY]:
|
elif core_config["sdram_phy"] in [litedram_phys.ECP5DDRPHY]:
|
||||||
self.submodules.crg = crg = LiteDRAMECP5DDRPHYCRG(platform, core_config)
|
crg = LiteDRAMECP5DDRPHYCRG(platform, core_config)
|
||||||
elif core_config["sdram_phy"] in [litedram_phys.A7DDRPHY, litedram_phys.K7DDRPHY, litedram_phys.V7DDRPHY]:
|
elif core_config["sdram_phy"] in [litedram_phys.A7DDRPHY, litedram_phys.K7DDRPHY, litedram_phys.V7DDRPHY]:
|
||||||
self.submodules.crg = LiteDRAMS7DDRPHYCRG(platform, core_config)
|
crg = LiteDRAMS7DDRPHYCRG(platform, core_config)
|
||||||
elif core_config["sdram_phy"] in [litedram_phys.USDDRPHY]:
|
elif core_config["sdram_phy"] in [litedram_phys.USDDRPHY]:
|
||||||
self.submodules.crg = LiteDRAMUSDDRPHYCRG(platform, core_config)
|
crg = LiteDRAMUSDDRPHYCRG(platform, core_config)
|
||||||
elif core_config["sdram_phy"] in [litedram_phys.USPDDRPHY]:
|
elif core_config["sdram_phy"] in [litedram_phys.USPDDRPHY]:
|
||||||
self.submodules.crg = LiteDRAMUSPDDRPHYCRG(platform, core_config)
|
crg = LiteDRAMUSPDDRPHYCRG(platform, core_config)
|
||||||
|
self.submodules.crg = crg
|
||||||
|
|
||||||
# DRAM -------------------------------------------------------------------------------------
|
# DRAM -------------------------------------------------------------------------------------
|
||||||
platform.add_extension(get_dram_ios(core_config))
|
platform.add_extension(get_dram_ios(core_config))
|
||||||
sdram_module = core_config["sdram_module"](sys_clk_freq, rate={
|
sdram_module = core_config["sdram_module"](sys_clk_freq, rate={
|
||||||
|
"SDR" : "1:1",
|
||||||
"DDR2": "1:2",
|
"DDR2": "1:2",
|
||||||
"DDR3": "1:4",
|
"DDR3": "1:4",
|
||||||
"DDR4": "1:4"}[core_config["memtype"]])
|
"DDR4": "1:4"}[core_config["memtype"]])
|
||||||
|
|
||||||
# Sim
|
# Sim.
|
||||||
if isinstance(platform, SimPlatform):
|
if isinstance(platform, SimPlatform):
|
||||||
from litex.tools.litex_sim import get_sdram_phy_settings
|
from litex.tools.litex_sim import get_sdram_phy_settings
|
||||||
sdram_clk_freq = int(100e6) # FIXME: use 100MHz timings
|
sdram_clk_freq = int(100e6) # FIXME: use 100MHz timings
|
||||||
|
@ -467,21 +506,26 @@ class LiteDRAMCore(SoCCore):
|
||||||
settings = phy_settings,
|
settings = phy_settings,
|
||||||
clk_freq = sdram_clk_freq)
|
clk_freq = sdram_clk_freq)
|
||||||
|
|
||||||
# ECP5DDRPHY
|
# GENSDRPHY.
|
||||||
|
elif core_config["sdram_phy"] in [litedram_phys.GENSDRPHY]:
|
||||||
|
assert core_config["memtype"] in ["SDR"]
|
||||||
|
self.submodules.sdrphy = sdram_phy = core_config["sdram_phy"](
|
||||||
|
pads = platform.request("sdram"),
|
||||||
|
sys_clk_freq = sys_clk_freq)
|
||||||
|
|
||||||
|
# ECP5DDRPHY.
|
||||||
elif core_config["sdram_phy"] in [litedram_phys.ECP5DDRPHY]:
|
elif core_config["sdram_phy"] in [litedram_phys.ECP5DDRPHY]:
|
||||||
assert core_config["memtype"] in ["DDR3"]
|
assert core_config["memtype"] in ["DDR3"]
|
||||||
self.submodules.ddrphy = core_config["sdram_phy"](
|
self.submodules.ddrphy = sdram_phy = core_config["sdram_phy"](
|
||||||
pads = platform.request("ddram"),
|
pads = platform.request("ddram"),
|
||||||
sys_clk_freq = sys_clk_freq)
|
sys_clk_freq = sys_clk_freq)
|
||||||
self.comb += crg.stop.eq(self.ddrphy.init.stop)
|
self.comb += crg.stop.eq(self.ddrphy.init.stop)
|
||||||
self.comb += crg.reset.eq(self.ddrphy.init.reset)
|
self.comb += crg.reset.eq(self.ddrphy.init.reset)
|
||||||
self.add_constant("ECP5DDRPHY")
|
|
||||||
sdram_module = core_config["sdram_module"](sys_clk_freq, "1:2")
|
|
||||||
|
|
||||||
# S7DDRPHY
|
# S7DDRPHY.
|
||||||
elif core_config["sdram_phy"] in [litedram_phys.A7DDRPHY, litedram_phys.K7DDRPHY, litedram_phys.V7DDRPHY]:
|
elif core_config["sdram_phy"] in [litedram_phys.A7DDRPHY, litedram_phys.K7DDRPHY, litedram_phys.V7DDRPHY]:
|
||||||
assert core_config["memtype"] in ["DDR2", "DDR3"]
|
assert core_config["memtype"] in ["DDR2", "DDR3"]
|
||||||
self.submodules.ddrphy = core_config["sdram_phy"](
|
self.submodules.ddrphy = sdram_phy = core_config["sdram_phy"](
|
||||||
pads = platform.request("ddram"),
|
pads = platform.request("ddram"),
|
||||||
memtype = core_config["memtype"],
|
memtype = core_config["memtype"],
|
||||||
nphases = {"DDR2": 2, "DDR3": 4}[core_config["memtype"]],
|
nphases = {"DDR2": 2, "DDR3": 4}[core_config["memtype"]],
|
||||||
|
@ -494,9 +538,9 @@ class LiteDRAMCore(SoCCore):
|
||||||
rtt_wr = core_config["rtt_wr"],
|
rtt_wr = core_config["rtt_wr"],
|
||||||
ron = core_config["ron"])
|
ron = core_config["ron"])
|
||||||
|
|
||||||
# USDDRPHY
|
# USDDRPHY.
|
||||||
elif core_config["sdram_phy"] in [litedram_phys.USDDRPHY, litedram_phys.USPDDRPHY]:
|
elif core_config["sdram_phy"] in [litedram_phys.USDDRPHY, litedram_phys.USPDDRPHY]:
|
||||||
self.submodules.ddrphy = core_config["sdram_phy"](
|
self.submodules.ddrphy = sdram_phy = core_config["sdram_phy"](
|
||||||
pads = platform.request("ddram"),
|
pads = platform.request("ddram"),
|
||||||
memtype = core_config["memtype"],
|
memtype = core_config["memtype"],
|
||||||
sys_clk_freq = sys_clk_freq,
|
sys_clk_freq = sys_clk_freq,
|
||||||
|
@ -508,12 +552,13 @@ class LiteDRAMCore(SoCCore):
|
||||||
ron = core_config["ron"])
|
ron = core_config["ron"])
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
self.add_csr("ddrphy")
|
|
||||||
|
|
||||||
controller_settings = controller_settings = ControllerSettings(
|
# Controller Settings.
|
||||||
cmd_buffer_depth = core_config["cmd_buffer_depth"])
|
controller_settings = controller_settings = ControllerSettings(cmd_buffer_depth=core_config["cmd_buffer_depth"])
|
||||||
|
|
||||||
|
# Add LiteDRAM Core to SoC.
|
||||||
self.add_sdram("sdram",
|
self.add_sdram("sdram",
|
||||||
phy = self.ddrphy,
|
phy = sdram_phy,
|
||||||
module = sdram_module,
|
module = sdram_module,
|
||||||
origin = self.mem_map["main_ram"],
|
origin = self.mem_map["main_ram"],
|
||||||
size = 0x01000000, # Only expose 16MB to the CPU, enough for Init/Calib.
|
size = 0x01000000, # Only expose 16MB to the CPU, enough for Init/Calib.
|
||||||
|
@ -524,11 +569,12 @@ class LiteDRAMCore(SoCCore):
|
||||||
)
|
)
|
||||||
|
|
||||||
# DRAM Control/Status ----------------------------------------------------------------------
|
# DRAM Control/Status ----------------------------------------------------------------------
|
||||||
|
|
||||||
# Expose calibration status to user.
|
# Expose calibration status to user.
|
||||||
self.submodules.ddrctrl = LiteDRAMCoreControl()
|
self.submodules.ddrctrl = LiteDRAMCoreControl()
|
||||||
self.add_csr("ddrctrl")
|
|
||||||
self.comb += platform.request("init_done").eq(self.ddrctrl.init_done.storage)
|
self.comb += platform.request("init_done").eq(self.ddrctrl.init_done.storage)
|
||||||
self.comb += platform.request("init_error").eq(self.ddrctrl.init_error.storage)
|
self.comb += platform.request("init_error").eq(self.ddrctrl.init_error.storage)
|
||||||
|
|
||||||
# If no CPU, expose a bus control interface to user.
|
# If no CPU, expose a bus control interface to user.
|
||||||
if cpu_type is None:
|
if cpu_type is None:
|
||||||
wb_bus = wishbone.Interface()
|
wb_bus = wishbone.Interface()
|
||||||
|
@ -699,8 +745,10 @@ def main():
|
||||||
# Generate core --------------------------------------------------------------------------------
|
# Generate core --------------------------------------------------------------------------------
|
||||||
if args.sim:
|
if args.sim:
|
||||||
platform = SimPlatform("", io=[])
|
platform = SimPlatform("", io=[])
|
||||||
|
elif core_config["sdram_phy"] in [litedram_phys.GENSDRPHY]:
|
||||||
|
platform = LatticePlatform("LFE5U-45F-6BG381C", io=[], toolchain="trellis") # FIXME: Allow other Vendors/Devices.
|
||||||
elif core_config["sdram_phy"] in [litedram_phys.ECP5DDRPHY]:
|
elif core_config["sdram_phy"] in [litedram_phys.ECP5DDRPHY]:
|
||||||
platform = LatticePlatform("LFE5UM5G-45F-8BG381C", io=[], toolchain="trellis") # FIXME: allow other devices.
|
platform = LatticePlatform("LFE5UM5G-45F-8BG381C", io=[], toolchain="trellis") # FIXME: Allow other Vendors/Devices.
|
||||||
elif core_config["sdram_phy"] in [litedram_phys.A7DDRPHY, litedram_phys.K7DDRPHY, litedram_phys.V7DDRPHY]:
|
elif core_config["sdram_phy"] in [litedram_phys.A7DDRPHY, litedram_phys.K7DDRPHY, litedram_phys.V7DDRPHY]:
|
||||||
platform = XilinxPlatform("", io=[], toolchain="vivado")
|
platform = XilinxPlatform("", io=[], toolchain="vivado")
|
||||||
elif core_config["sdram_phy"] in [litedram_phys.USDDRPHY, litedram_phys.USPDDRPHY]:
|
elif core_config["sdram_phy"] in [litedram_phys.USDDRPHY, litedram_phys.USPDDRPHY]:
|
||||||
|
|
|
@ -18,6 +18,10 @@ def build_config(name):
|
||||||
|
|
||||||
|
|
||||||
class TestExamples(unittest.TestCase):
|
class TestExamples(unittest.TestCase):
|
||||||
|
def test_ulx3s(self):
|
||||||
|
errors = build_config("ulx3s")
|
||||||
|
self.assertEqual(errors, 0)
|
||||||
|
|
||||||
def test_arty(self):
|
def test_arty(self):
|
||||||
errors = build_config("arty")
|
errors = build_config("arty")
|
||||||
self.assertEqual(errors, 0)
|
self.assertEqual(errors, 0)
|
||||||
|
|
Loading…
Reference in New Issue