mirror of
https://github.com/enjoy-digital/litedram.git
synced 2025-01-04 09:52:25 -05:00
litedram_gen: add ecp5 support
This commit is contained in:
parent
dc16d971ad
commit
340a796129
5 changed files with 149 additions and 30 deletions
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
# General ------------------------------------------------------------------
|
# General ------------------------------------------------------------------
|
||||||
|
"platform": "xilinx", # Platform type
|
||||||
"cpu": "vexriscv", # Type of CPU used for init/calib (vexriscv, lm32)
|
"cpu": "vexriscv", # Type of CPU used for init/calib (vexriscv, lm32)
|
||||||
"speedgrade": -1, # FPGA speedgrade
|
"speedgrade": -1, # FPGA speedgrade
|
||||||
"memtype": "DDR3", # DRAM type
|
"memtype": "DDR3", # DRAM type
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
# General ------------------------------------------------------------------
|
# General ------------------------------------------------------------------
|
||||||
|
"platform": "xilinx", # Platform type
|
||||||
"cpu": "vexriscv", # Type of CPU used for init/calib (vexriscv, lm32)
|
"cpu": "vexriscv", # Type of CPU used for init/calib (vexriscv, lm32)
|
||||||
"speedgrade": -2, # FPGA speedgrade
|
"speedgrade": -2, # FPGA speedgrade
|
||||||
"memtype": "DDR3", # DRAM type
|
"memtype": "DDR3", # DRAM type
|
||||||
|
|
||||||
# PHY ----------------------------------------------------------------------
|
# PHY ----------------------------------------------------------------------
|
||||||
"cmd_delay": 0, # Command additional delay (in taps)
|
"cmd_delay": 0, # Command additional delay (in taps)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
# General ------------------------------------------------------------------
|
# General ------------------------------------------------------------------
|
||||||
|
"platform": "xilinx", # Platform type
|
||||||
"cpu": "vexriscv", # Type of CPU used for init/calib (vexriscv, lm32)
|
"cpu": "vexriscv", # Type of CPU used for init/calib (vexriscv, lm32)
|
||||||
"speedgrade": -1, # FPGA speedgrade
|
"speedgrade": -1, # FPGA speedgrade
|
||||||
"memtype": "DDR2", # DRAM type
|
"memtype": "DDR2", # DRAM type
|
||||||
|
|
45
examples/versa_ecp5.yml
Normal file
45
examples/versa_ecp5.yml
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
# This file is Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
|
# License: BSD
|
||||||
|
|
||||||
|
{
|
||||||
|
# General ------------------------------------------------------------------
|
||||||
|
"platform": "ecp5", # Platform type
|
||||||
|
"cpu": None, # Type of CPU used for init/calib (vexriscv, lm32)
|
||||||
|
|
||||||
|
# PHY ----------------------------------------------------------------------
|
||||||
|
"sdram_module": "MT41K64M16", # SDRAM modules of the board or SO-DIMM
|
||||||
|
"sdram_module_nb": 2, # Number of byte groups
|
||||||
|
"sdram_rank_nb": 1, # Number of ranks
|
||||||
|
"sdram_phy": "ECP5DDRPHY", # Type of FPGA PHY
|
||||||
|
|
||||||
|
# Frequency ----------------------------------------------------------------
|
||||||
|
"input_clk_freq": 100e6, # Input clock frequency
|
||||||
|
"sys_clk_freq": 50e6, # System clock frequency (DDR_clk = 4 x sys_clk)
|
||||||
|
"init_clk_freq": 25e6, # Init clock frequency
|
||||||
|
|
||||||
|
# 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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
# CSR Port -----------------------------------------------------------------
|
||||||
|
"csr_expose": "False", # Expose CSR bus as I/Os
|
||||||
|
"csr_align" : 32, # CSR alignment
|
||||||
|
}
|
129
litedram/gen.py
Normal file → Executable file
129
litedram/gen.py
Normal file → Executable file
|
@ -16,7 +16,8 @@ for some use cases it could be interesting to generate a standalone verilog file
|
||||||
The standalone core is generated from a YAML configuration file that allows the user to generate
|
The standalone core is generated from a YAML configuration file that allows the user to generate
|
||||||
easily a custom configuration of the core.
|
easily a custom configuration of the core.
|
||||||
|
|
||||||
Current version of the generator is limited to Xilinx 7-Series FPGA for DDR2/DDR3 memories.
|
Current version of the generator is limited to Xilinx 7-Series FPGA for
|
||||||
|
DDR2/DDR3 memories and the versa ECP5-5G.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
@ -31,6 +32,7 @@ from migen.genlib.resetsync import AsyncResetSynchronizer
|
||||||
|
|
||||||
from litex.build.generic_platform import *
|
from litex.build.generic_platform import *
|
||||||
from litex.build.xilinx import XilinxPlatform
|
from litex.build.xilinx import XilinxPlatform
|
||||||
|
from litex.boards.platforms import versa_ecp5
|
||||||
|
|
||||||
from litex.soc.cores.clock import *
|
from litex.soc.cores.clock import *
|
||||||
from litex.soc.integration.soc_sdram import *
|
from litex.soc.integration.soc_sdram import *
|
||||||
|
@ -247,6 +249,50 @@ class LiteDRAMCRG(Module):
|
||||||
iodelay_pll.create_clkout(self.cd_iodelay, core_config["iodelay_clk_freq"])
|
iodelay_pll.create_clkout(self.cd_iodelay, core_config["iodelay_clk_freq"])
|
||||||
self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_iodelay)
|
self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_iodelay)
|
||||||
|
|
||||||
|
class LatticeDRAMCRG(Module):
|
||||||
|
def __init__(self, platform, core_config):
|
||||||
|
self.clock_domains.cd_init = ClockDomain()
|
||||||
|
self.clock_domains.cd_por = ClockDomain(reset_less=True)
|
||||||
|
self.clock_domains.cd_sys = ClockDomain()
|
||||||
|
self.clock_domains.cd_sys2x = ClockDomain()
|
||||||
|
self.clock_domains.cd_sys2x_i = ClockDomain(reset_less=True)
|
||||||
|
|
||||||
|
# # #
|
||||||
|
|
||||||
|
self.stop = Signal()
|
||||||
|
|
||||||
|
# clk / rst
|
||||||
|
clk100 = platform.request("clk100")
|
||||||
|
rst_n = platform.request("rst_n")
|
||||||
|
platform.add_period_constraint(clk100, 10.0)
|
||||||
|
|
||||||
|
# power on reset
|
||||||
|
por_count = Signal(16, reset=2**16-1)
|
||||||
|
por_done = Signal()
|
||||||
|
self.comb += self.cd_por.clk.eq(ClockSignal())
|
||||||
|
self.comb += por_done.eq(por_count == 0)
|
||||||
|
self.sync.por += If(~por_done, por_count.eq(por_count - 1))
|
||||||
|
|
||||||
|
# pll
|
||||||
|
self.submodules.pll = pll = ECP5PLL()
|
||||||
|
pll.register_clkin(clk100, core_config['sys_clk_freq'])
|
||||||
|
pll.create_clkout(self.cd_sys2x_i, 2*core_config["sys_clk_freq"])
|
||||||
|
pll.create_clkout(self.cd_init, core_config['init_clk_freq'])
|
||||||
|
self.specials += [
|
||||||
|
Instance("ECLKSYNCB",
|
||||||
|
i_ECLKI=self.cd_sys2x_i.clk,
|
||||||
|
i_STOP=self.stop,
|
||||||
|
o_ECLKO=self.cd_sys2x.clk),
|
||||||
|
Instance("CLKDIVF",
|
||||||
|
p_DIV="2.0",
|
||||||
|
i_ALIGNWD=0,
|
||||||
|
i_CLKI=self.cd_sys2x.clk,
|
||||||
|
i_RST=self.cd_sys2x.rst,
|
||||||
|
o_CDIVX=self.cd_sys.clk),
|
||||||
|
AsyncResetSynchronizer(self.cd_init, ~por_done | ~pll.locked | ~rst_n),
|
||||||
|
AsyncResetSynchronizer(self.cd_sys, ~por_done | ~pll.locked | ~rst_n)
|
||||||
|
]
|
||||||
|
|
||||||
# LiteDRAMCoreControl ------------------------------------------------------------------------------
|
# LiteDRAMCoreControl ------------------------------------------------------------------------------
|
||||||
|
|
||||||
class LiteDRAMCoreControl(Module, AutoCSR):
|
class LiteDRAMCoreControl(Module, AutoCSR):
|
||||||
|
@ -278,10 +324,10 @@ class LiteDRAMCore(SoCSDRAM):
|
||||||
kwargs["with_uart"] = False
|
kwargs["with_uart"] = False
|
||||||
kwargs["with_timer"] = False
|
kwargs["with_timer"] = False
|
||||||
kwargs["with_ctrl"] = False
|
kwargs["with_ctrl"] = False
|
||||||
kwargs["with_wishbone"] = (cpu_type != None)
|
kwargs["with_wishbone"] = False
|
||||||
else:
|
else:
|
||||||
kwargs["l2_size"] = 0
|
kwargs["l2_size"] = 0
|
||||||
kwargs["min_l2_data_width"] = 0
|
kwargs["min_l2_data_width"] = 0
|
||||||
|
|
||||||
# SoCSDRAM ---------------------------------------------------------------------------------
|
# SoCSDRAM ---------------------------------------------------------------------------------
|
||||||
SoCSDRAM.__init__(self, platform, sys_clk_freq,
|
SoCSDRAM.__init__(self, platform, sys_clk_freq,
|
||||||
|
@ -290,32 +336,50 @@ class LiteDRAMCore(SoCSDRAM):
|
||||||
**kwargs)
|
**kwargs)
|
||||||
|
|
||||||
# CRG --------------------------------------------------------------------------------------
|
# CRG --------------------------------------------------------------------------------------
|
||||||
self.submodules.crg = LiteDRAMCRG(platform, core_config)
|
|
||||||
|
|
||||||
# DRAM -------------------------------------------------------------------------------------
|
if core_config["platform"] == "ecp5":
|
||||||
platform.add_extension(get_dram_ios(core_config))
|
crg = LatticeDRAMCRG(platform, core_config)
|
||||||
assert core_config["memtype"] in ["DDR2", "DDR3"]
|
self.submodules.crg = crg
|
||||||
self.submodules.ddrphy = core_config["sdram_phy"](
|
|
||||||
platform.request("ddram"),
|
self.submodules.ddrphy = core_config["sdram_phy"](
|
||||||
memtype=core_config["memtype"],
|
platform.request("ddram"),
|
||||||
nphases=4 if core_config["memtype"] == "DDR3" else 2,
|
sys_clk_freq=sys_clk_freq)
|
||||||
sys_clk_freq=sys_clk_freq,
|
self.comb += crg.stop.eq(self.ddrphy.init.stop)
|
||||||
iodelay_clk_freq=core_config["iodelay_clk_freq"],
|
sdram_module = core_config["sdram_module"](sys_clk_freq, "1:2")
|
||||||
cmd_latency=core_config["cmd_latency"])
|
|
||||||
self.add_constant("CMD_DELAY", core_config["cmd_delay"])
|
controller_settings = controller_settings=ControllerSettings(
|
||||||
if core_config["memtype"] == "DDR3":
|
cmd_buffer_depth=core_config["cmd_buffer_depth"])
|
||||||
self.ddrphy.settings.add_electrical_settings(
|
self.register_sdram(self.ddrphy,
|
||||||
rtt_nom=core_config["rtt_nom"],
|
sdram_module.geom_settings,
|
||||||
rtt_wr=core_config["rtt_wr"],
|
sdram_module.timing_settings,
|
||||||
ron=core_config["ron"])
|
controller_settings=controller_settings)
|
||||||
sdram_module = core_config["sdram_module"](sys_clk_freq,
|
else:
|
||||||
"1:4" if core_config["memtype"] == "DDR3" else "1:2")
|
self.submodules.crg = LiteDRAMCRG(platform, core_config)
|
||||||
controller_settings = controller_settings=ControllerSettings(
|
|
||||||
cmd_buffer_depth=core_config["cmd_buffer_depth"])
|
# DRAM -------------------------------------------------------------------------------------
|
||||||
self.register_sdram(self.ddrphy,
|
platform.add_extension(get_dram_ios(core_config))
|
||||||
sdram_module.geom_settings,
|
assert core_config["memtype"] in ["DDR2", "DDR3"]
|
||||||
sdram_module.timing_settings,
|
self.submodules.ddrphy = core_config["sdram_phy"](
|
||||||
controller_settings=controller_settings)
|
platform.request("ddram"),
|
||||||
|
memtype=core_config["memtype"],
|
||||||
|
nphases=4 if core_config["memtype"] == "DDR3" else 2,
|
||||||
|
sys_clk_freq=sys_clk_freq,
|
||||||
|
iodelay_clk_freq=core_config["iodelay_clk_freq"],
|
||||||
|
cmd_latency=core_config["cmd_latency"])
|
||||||
|
self.add_constant("CMD_DELAY", core_config["cmd_delay"])
|
||||||
|
if core_config["memtype"] == "DDR3":
|
||||||
|
self.ddrphy.settings.add_electrical_settings(
|
||||||
|
rtt_nom=core_config["rtt_nom"],
|
||||||
|
rtt_wr=core_config["rtt_wr"],
|
||||||
|
ron=core_config["ron"])
|
||||||
|
sdram_module = core_config["sdram_module"](sys_clk_freq,
|
||||||
|
"1:4" if core_config["memtype"] == "DDR3" else "1:2")
|
||||||
|
controller_settings = controller_settings=ControllerSettings(
|
||||||
|
cmd_buffer_depth=core_config["cmd_buffer_depth"])
|
||||||
|
self.register_sdram(self.ddrphy,
|
||||||
|
sdram_module.geom_settings,
|
||||||
|
sdram_module.timing_settings,
|
||||||
|
controller_settings=controller_settings)
|
||||||
|
|
||||||
# DRAM Initialization ----------------------------------------------------------------------
|
# DRAM Initialization ----------------------------------------------------------------------
|
||||||
self.submodules.ddrctrl = LiteDRAMCoreControl()
|
self.submodules.ddrctrl = LiteDRAMCoreControl()
|
||||||
|
@ -502,6 +566,13 @@ def main():
|
||||||
|
|
||||||
# Generate core --------------------------------------------------------------------------------
|
# Generate core --------------------------------------------------------------------------------
|
||||||
platform = Platform()
|
platform = Platform()
|
||||||
|
if core_config["platform"] == "ecp5":
|
||||||
|
platform = versa_ecp5.Platform(toolchain="trellis")
|
||||||
|
elif core_config["platform"] == "xilinx":
|
||||||
|
platform = XilinxPlatform("", io=[], toolchain="vivado")
|
||||||
|
else:
|
||||||
|
raise ValueError("Unknown platform specified in {}".format(args.config));
|
||||||
|
|
||||||
soc = LiteDRAMCore(platform, core_config, integrated_rom_size=0x6000, integrated_sram_size=0x1000)
|
soc = LiteDRAMCore(platform, core_config, integrated_rom_size=0x6000, integrated_sram_size=0x1000)
|
||||||
builder = Builder(soc, output_dir="build", compile_gateware=False)
|
builder = Builder(soc, output_dir="build", compile_gateware=False)
|
||||||
vns = builder.build(build_name="litedram_core", regular_comb=False)
|
vns = builder.build(build_name="litedram_core", regular_comb=False)
|
||||||
|
|
Loading…
Reference in a new issue