boards/targets: add kcu105
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 5 Nov 2018 09:44:50 +0000 (10:44 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 5 Nov 2018 09:44:50 +0000 (10:44 +0100)
litex/boards/platforms/kcu105.py
litex/boards/targets/kcu105.py [new file with mode: 0755]

index e8a953bad4b23e5bb5d3a3e9e1e6588e88025502..08781cdd1e7d914c782a7e868e5f4cc09b0fc83b 100644 (file)
@@ -103,9 +103,9 @@ _io = [
             IOStandard("SSTL12_DCI")),
         Subsignal("ba", Pins("AF17 AL15"), IOStandard("SSTL12_DCI")),
         Subsignal("bg", Pins("AG15"), IOStandard("SSTL12_DCI")),
-        Subsignal("ras_n", Pins("AF14"), IOStandard("SSTL12_DCI")), # A16
+        Subsignal("ras_n", Pins("AF14"), IOStandard("SSTL12_DCI")),  # A16
         Subsignal("cas_n", Pins("AG14 "), IOStandard("SSTL12_DCI")), # A15
-        Subsignal("we_n", Pins("AD16"), IOStandard("SSTL12_DCI")), # A14
+        Subsignal("we_n", Pins("AD16"), IOStandard("SSTL12_DCI")),   # A14
         Subsignal("cs_n", Pins("AL19"), IOStandard("SSTL12_DCI")),
         Subsignal("act_n", Pins("AH14"), IOStandard("SSTL12_DCI")),
         Subsignal("ten", Pins("AH16"), IOStandard("SSTL12_DCI")),
@@ -131,8 +131,8 @@ _io = [
             IOStandard("DIFF_POD12")),
         Subsignal("dqs_n", Pins("AH21 AJ25 AK20 AP21 AL28 AP30 AJ33 AP34"),
             IOStandard("DIFF_POD12")),
-        Subsignal("clk_p", Pins("AE16"), IOStandard("DIFF_SSTL2_DCI")),
-        Subsignal("clk_n", Pins("AE15"), IOStandard("DIFF_SSTL2_DCI")),
+        Subsignal("clk_p", Pins("AE16"), IOStandard("DIFF_SSTL12_DCI")),
+        Subsignal("clk_n", Pins("AE15"), IOStandard("DIFF_SSTL12_DCI")),
         Subsignal("cke", Pins("AD15"), IOStandard("SSTL12_DCI")),
         Subsignal("odt", Pins("AJ18"), IOStandard("SSTL12_DCI")),
         Subsignal("reset_n", Pins("AL18"), IOStandard("LVCMOS12")),
diff --git a/litex/boards/targets/kcu105.py b/litex/boards/targets/kcu105.py
new file mode 100755 (executable)
index 0000000..1ebf8da
--- /dev/null
@@ -0,0 +1,123 @@
+#!/usr/bin/env python3
+
+import argparse
+
+from migen import *
+
+from litex.boards.platforms import kcu105
+
+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 EDY4016A
+from litedram.phy import kusddrphy
+
+
+class _CRG(Module):
+    def __init__(self, platform):
+        self.clock_domains.cd_sys = ClockDomain()
+        self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
+        self.clock_domains.cd_clk200 = ClockDomain()
+        self.clock_domains.cd_ic = ClockDomain()
+
+        clk125 = platform.request("clk125")
+        clk125_ibufds = Signal()
+        clk125_buffered = Signal()
+        pll_locked = Signal()
+        pll_fb = Signal()
+        pll_sys4x = Signal()
+        pll_clk200 = Signal()
+        self.specials += [
+            Instance("IBUFDS", i_I=clk125.p, i_IB=clk125.n, o_O=clk125_ibufds),
+            Instance("BUFG", i_I=clk125_ibufds, o_O=clk125_buffered),
+            Instance("PLLE2_BASE", name="crg_main_mmcm",
+                p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,
+
+                # VCO @ 1GHz
+                p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=8.0,
+                p_CLKFBOUT_MULT=8, p_DIVCLK_DIVIDE=1,
+                i_CLKIN1=clk125_buffered, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb,
+
+                # 500MHz
+                p_CLKOUT0_DIVIDE=2, p_CLKOUT0_PHASE=0.0, o_CLKOUT0=pll_sys4x,
+
+                # 200MHz
+                p_CLKOUT1_DIVIDE=5, p_CLKOUT1_PHASE=0.0, o_CLKOUT1=pll_clk200,
+            ),
+            Instance("BUFGCE_DIV", name="main_bufgce_div",
+                p_BUFGCE_DIVIDE=4,
+                i_CE=1, i_I=pll_sys4x, o_O=self.cd_sys.clk),
+            Instance("BUFGCE", name="main_bufgce",
+                i_CE=1, i_I=pll_sys4x, o_O=self.cd_sys4x.clk),
+            Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk),
+            AsyncResetSynchronizer(self.cd_clk200, ~pll_locked),
+        ]
+
+        ic_reset_counter = Signal(max=64, reset=63)
+        ic_reset = Signal(reset=1)
+        self.sync.clk200 += \
+            If(ic_reset_counter != 0,
+                ic_reset_counter.eq(ic_reset_counter - 1)
+            ).Else(
+                ic_reset.eq(0)
+            )
+        ic_rdy = Signal()
+        ic_rdy_counter = Signal(max=64, reset=63)
+        self.cd_sys.rst.reset = 1
+        self.comb += self.cd_ic.clk.eq(self.cd_sys.clk)
+        self.sync.ic += [
+            If(ic_rdy,
+                If(ic_rdy_counter != 0,
+                    ic_rdy_counter.eq(ic_rdy_counter - 1)
+                ).Else(
+                    self.cd_sys.rst.eq(0)
+                )
+            )
+        ]
+        self.specials += [
+            Instance("IDELAYCTRL", p_SIM_DEVICE="ULTRASCALE",
+                     i_REFCLK=ClockSignal("clk200"), i_RST=ic_reset,
+                     o_RDY=ic_rdy),
+            AsyncResetSynchronizer(self.cd_ic, ic_reset)
+        ]
+
+
+class BaseSoC(SoCSDRAM):
+    csr_map = {
+        "ddrphy":    16,
+    }
+    csr_map.update(SoCSDRAM.csr_map)
+    def __init__(self, **kwargs):
+        platform = kcu105.Platform()
+        sys_clk_freq = int(125e6)
+        SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq,
+                         integrated_rom_size=0x8000,
+                         integrated_sram_size=0x8000,
+                          **kwargs)
+
+        self.submodules.crg = _CRG(platform)
+
+        # sdram
+        self.submodules.ddrphy = kusddrphy.KUSDDRPHY(platform.request("ddram"), memtype="DDR4", sys_clk_freq=sys_clk_freq)
+        self.add_constant("KUSDDRPHY", None)
+        sdram_module = EDY4016A(sys_clk_freq, "1:4")
+        self.register_sdram(self.ddrphy,
+                            sdram_module.geom_settings,
+                            sdram_module.timing_settings)
+
+
+def main():
+    parser = argparse.ArgumentParser(description="LiteX SoC port to KCU105")
+    builder_args(parser)
+    soc_sdram_args(parser)
+    args = parser.parse_args()
+
+    soc = BaseSoC(**soc_sdram_argdict(args))
+    builder = Builder(soc, **builder_argdict(args))
+    builder.build()
+
+
+if __name__ == "__main__":
+    main()