from litex.boards.platforms import versa_ecp5
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.builder import *
-from litedram.modules import AS4C32M16
-from litedram.phy import GENSDRPHY
+from litedram.modules import MT41K64M16
+from litedram.phy import ECP5DDRPHY, ECP5DDRPHYInit
# CRG ----------------------------------------------------------------------------------------------
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_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
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()
- self.comb += pll.reset.eq(~rst_n)
pll.register_clkin(clk100, 100e6)
- pll.create_clkout(self.cd_sys, 50e6, phase=11)
- pll.create_clkout(self.cd_sys_ps, 50e6, phase=20)
- # FIXME: AsyncResetSynchronizer needs FD1S3BX support.
- #self.specials += AsyncResetSynchronizer(self.cd_sys, rst)
- self.comb += self.cd_sys.rst.eq(~rst_n)
- platform.add_period_constraint(self.cd_sys.clk, 20.0)
- platform.add_period_constraint(self.cd_sys_ps.clk, 20.0)
-
- # sdram clock
- self.comb += platform.request("sdram_clock").eq(self.cd_sys_ps.clk)
+ pll.create_clkout(self.cd_sys2x_i, 2*sys_clk_freq)
+ pll.create_clkout(self.cd_init, 25e6)
+ 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)
+ ]
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCSDRAM):
+ csr_map = {
+ "ddrphy": 16,
+ }
+ csr_map.update(SoCSDRAM.csr_map)
def __init__(self, **kwargs):
- platform = versa_ecp5.Platform(toolchain="trellis")
- platform.add_extension(versa_ecp5._ecp5_soc_hat_io)
+ platform = versa_ecp5.Platform(toolchain="diamond")
sys_clk_freq = int(50e6)
SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq,
integrated_rom_size=0x8000,
**kwargs)
- self.submodules.crg = _CRG(platform)
-
- if not self.integrated_main_ram_size:
- self.submodules.sdrphy = GENSDRPHY(platform.request("sdram"))
- sdram_module = AS4C32M16(sys_clk_freq, "1:1")
- self.register_sdram(self.sdrphy,
- sdram_module.geom_settings,
- sdram_module.timing_settings)
+ # crg
+ crg = _CRG(platform, sys_clk_freq)
+ self.submodules.crg = crg
+
+ # sdram
+ self.submodules.ddrphy = ECP5DDRPHY(
+ platform.request("ddram"),
+ 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.timing_settings)
# Build --------------------------------------------------------------------------------------------