targets/versa_ecp5: integrate DDR3
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 25 Feb 2019 14:27:08 +0000 (15:27 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 25 Feb 2019 14:27:08 +0000 (15:27 +0100)
litex/boards/targets/versa_ecp5.py

index 8a551d49fa3afc24d30564ee0482157a6cc3fa19..85c0b1cffbbe90294bb8c2af0a7b820097136996 100755 (executable)
@@ -8,59 +8,88 @@ from migen.genlib.resetsync import AsyncResetSynchronizer
 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 --------------------------------------------------------------------------------------------