Merge pull request #105 from ximinity/gen_ecp5
WIP: litedram_gen: add ecp5 support
This commit is contained in:
commit
b1f087959b
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue