targets/versa_ecp5: integrate DDR3
This commit is contained in:
parent
3dd529e40b
commit
5f29a12ee7
|
@ -8,59 +8,88 @@ 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)
|
||||||
sdram_module.geom_settings,
|
self.add_constant("ECP5DDRPHY", None)
|
||||||
sdram_module.timing_settings)
|
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.timing_settings)
|
||||||
|
|
||||||
# Build --------------------------------------------------------------------------------------------
|
# Build --------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue