targets/versa_ecp5: integrate DDR3

This commit is contained in:
Florent Kermarrec 2019-02-25 15:27:08 +01:00
parent 3dd529e40b
commit 5f29a12ee7
1 changed files with 53 additions and 24 deletions

View File

@ -8,57 +8,86 @@ from migen.genlib.resetsync import AsyncResetSynchronizer
from litex.boards.platforms import versa_ecp5 from litex.boards.platforms import versa_ecp5
from litex.soc.cores.clock import * from litex.soc.cores.clock import *
from litex.soc.integration.soc_core import mem_decoder
from litex.soc.integration.soc_sdram import * from litex.soc.integration.soc_sdram import *
from litex.soc.integration.builder import * from litex.soc.integration.builder import *
from litedram.modules import AS4C32M16 from litedram.modules import MT41K64M16
from litedram.phy import GENSDRPHY from litedram.phy import ECP5DDRPHY, ECP5DDRPHYInit
# CRG ---------------------------------------------------------------------------------------------- # CRG ----------------------------------------------------------------------------------------------
class _CRG(Module): class _CRG(Module):
def __init__(self, platform): def __init__(self, platform, sys_clk_freq):
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_sys = ClockDomain()
self.clock_domains.cd_sys_ps = ClockDomain(reset_less=True) self.clock_domains.cd_sys2x = ClockDomain()
self.clock_domains.cd_sys2x_i = ClockDomain(reset_less=True)
# # # # # #
self.stop = Signal()
# clk / rst # clk / rst
clk100 = platform.request("clk100") clk100 = platform.request("clk100")
rst_n = platform.request("rst_n") 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 # pll
self.submodules.pll = pll = ECP5PLL() self.submodules.pll = pll = ECP5PLL()
self.comb += pll.reset.eq(~rst_n)
pll.register_clkin(clk100, 100e6) pll.register_clkin(clk100, 100e6)
pll.create_clkout(self.cd_sys, 50e6, phase=11) pll.create_clkout(self.cd_sys2x_i, 2*sys_clk_freq)
pll.create_clkout(self.cd_sys_ps, 50e6, phase=20) pll.create_clkout(self.cd_init, 25e6)
# FIXME: AsyncResetSynchronizer needs FD1S3BX support. self.specials += [
#self.specials += AsyncResetSynchronizer(self.cd_sys, rst) Instance("ECLKSYNCB",
self.comb += self.cd_sys.rst.eq(~rst_n) i_ECLKI=self.cd_sys2x_i.clk,
platform.add_period_constraint(self.cd_sys.clk, 20.0) i_STOP=self.stop,
platform.add_period_constraint(self.cd_sys_ps.clk, 20.0) o_ECLKO=self.cd_sys2x.clk),
Instance("CLKDIVF",
# sdram clock p_DIV="2.0",
self.comb += platform.request("sdram_clock").eq(self.cd_sys_ps.clk) 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)
]
# BaseSoC ------------------------------------------------------------------------------------------ # BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCSDRAM): class BaseSoC(SoCSDRAM):
csr_map = {
"ddrphy": 16,
}
csr_map.update(SoCSDRAM.csr_map)
def __init__(self, **kwargs): def __init__(self, **kwargs):
platform = versa_ecp5.Platform(toolchain="trellis") platform = versa_ecp5.Platform(toolchain="diamond")
platform.add_extension(versa_ecp5._ecp5_soc_hat_io)
sys_clk_freq = int(50e6) sys_clk_freq = int(50e6)
SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq,
integrated_rom_size=0x8000, integrated_rom_size=0x8000,
**kwargs) **kwargs)
self.submodules.crg = _CRG(platform) # crg
crg = _CRG(platform, sys_clk_freq)
self.submodules.crg = crg
if not self.integrated_main_ram_size: # sdram
self.submodules.sdrphy = GENSDRPHY(platform.request("sdram")) self.submodules.ddrphy = ECP5DDRPHY(
sdram_module = AS4C32M16(sys_clk_freq, "1:1") platform.request("ddram"),
self.register_sdram(self.sdrphy, sys_clk_freq=sys_clk_freq)
self.add_constant("ECP5DDRPHY", None)
ddrphy_init = ECP5DDRPHYInit(self.crg, self.ddrphy)
self.submodules += ddrphy_init
sdram_module = MT41K64M16(sys_clk_freq, "1:2")
self.register_sdram(self.ddrphy,
sdram_module.geom_settings, sdram_module.geom_settings,
sdram_module.timing_settings) sdram_module.timing_settings)