Merge pull request #105 from ximinity/gen_ecp5

WIP: litedram_gen: add ecp5 support
This commit is contained in:
enjoy-digital 2020-01-27 17:50:47 +01:00 committed by GitHub
commit b1f087959b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 149 additions and 30 deletions

View File

@ -3,6 +3,7 @@
{
# General ------------------------------------------------------------------
"platform": "xilinx", # Platform type
"cpu": "vexriscv", # Type of CPU used for init/calib (vexriscv, lm32)
"speedgrade": -1, # FPGA speedgrade
"memtype": "DDR3", # DRAM type

View File

@ -3,9 +3,10 @@
{
# General ------------------------------------------------------------------
"platform": "xilinx", # Platform type
"cpu": "vexriscv", # Type of CPU used for init/calib (vexriscv, lm32)
"speedgrade": -2, # FPGA speedgrade
"memtype": "DDR3", # DRAM type
"memtype": "DDR3", # DRAM type
# PHY ----------------------------------------------------------------------
"cmd_delay": 0, # Command additional delay (in taps)

View File

@ -3,6 +3,7 @@
{
# General ------------------------------------------------------------------
"platform": "xilinx", # Platform type
"cpu": "vexriscv", # Type of CPU used for init/calib (vexriscv, lm32)
"speedgrade": -1, # FPGA speedgrade
"memtype": "DDR2", # DRAM type

45
examples/versa_ecp5.yml Normal file
View 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
View 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
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
@ -31,6 +32,7 @@ from migen.genlib.resetsync import AsyncResetSynchronizer
from litex.build.generic_platform import *
from litex.build.xilinx import XilinxPlatform
from litex.boards.platforms import versa_ecp5
from litex.soc.cores.clock 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"])
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 ------------------------------------------------------------------------------
class LiteDRAMCoreControl(Module, AutoCSR):
@ -278,10 +324,10 @@ class LiteDRAMCore(SoCSDRAM):
kwargs["with_uart"] = False
kwargs["with_timer"] = False
kwargs["with_ctrl"] = False
kwargs["with_wishbone"] = (cpu_type != None)
kwargs["with_wishbone"] = False
else:
kwargs["l2_size"] = 0
kwargs["min_l2_data_width"] = 0
kwargs["l2_size"] = 0
kwargs["min_l2_data_width"] = 0
# SoCSDRAM ---------------------------------------------------------------------------------
SoCSDRAM.__init__(self, platform, sys_clk_freq,
@ -290,32 +336,50 @@ class LiteDRAMCore(SoCSDRAM):
**kwargs)
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = LiteDRAMCRG(platform, core_config)
# DRAM -------------------------------------------------------------------------------------
platform.add_extension(get_dram_ios(core_config))
assert core_config["memtype"] in ["DDR2", "DDR3"]
self.submodules.ddrphy = core_config["sdram_phy"](
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)
if core_config["platform"] == "ecp5":
crg = LatticeDRAMCRG(platform, core_config)
self.submodules.crg = crg
self.submodules.ddrphy = core_config["sdram_phy"](
platform.request("ddram"),
sys_clk_freq=sys_clk_freq)
self.comb += crg.stop.eq(self.ddrphy.init.stop)
sdram_module = core_config["sdram_module"](sys_clk_freq, "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)
else:
self.submodules.crg = LiteDRAMCRG(platform, core_config)
# DRAM -------------------------------------------------------------------------------------
platform.add_extension(get_dram_ios(core_config))
assert core_config["memtype"] in ["DDR2", "DDR3"]
self.submodules.ddrphy = core_config["sdram_phy"](
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 ----------------------------------------------------------------------
self.submodules.ddrctrl = LiteDRAMCoreControl()
@ -502,6 +566,13 @@ def main():
# Generate core --------------------------------------------------------------------------------
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)
builder = Builder(soc, output_dir="build", compile_gateware=False)
vns = builder.build(build_name="litedram_core", regular_comb=False)