build/xilinx/vivado: enable xpm libraries
[litex.git] / litex / build / xilinx / vivado.py
index 034dcc70142887cd2b1aaad3c17414ad2994f4b2..10a795bd7665533e1f88f5a63179b51621ddf803 100644 (file)
@@ -63,7 +63,20 @@ def _run_vivado(build_name, vivado_path, source, ver=None):
         command = build_script_file
     else:
         build_script_contents = "# Autogenerated by LiteX\nset -e\n"
-        settings = common.settings(vivado_path, ver)
+
+        # For backwards compatibility with ISE paths, also
+        # look for a version in a subdirectory named "Vivado"
+        # under the current directory.
+        paths_to_try = [vivado_path, os.path.join(vivado_path, "Vivado")]
+        for p in paths_to_try:
+            try:
+                settings = common.settings(p, ver)
+            except OSError:
+                continue
+            break
+        else:
+            raise OSError("Unable to locate Vivado directory or settings.")
+
         build_script_contents += "source " + settings + "\n"
         build_script_contents += "vivado -mode batch -source " + build_name + ".tcl\n"
         build_script_file = "build_" + build_name + ".sh"
@@ -93,9 +106,10 @@ class XilinxVivadoToolchain:
         self.clocks = dict()
         self.false_paths = set()
 
-    def _build_batch(self, platform, sources, edifs, build_name):
+    def _build_batch(self, platform, sources, edifs, ips, build_name):
         tcl = []
         tcl.append("create_project -force -name {} -part {}".format(build_name, platform.device))
+        tcl.append("set_property XPM_LIBRARIES {XPM_CDC XPM_MEMORY} [current_project]")
         for filename, language, library in sources:
             filename_tcl = "{" + filename + "}"
             tcl.append("add_files " + filename_tcl)
@@ -104,6 +118,16 @@ class XilinxVivadoToolchain:
         for filename in edifs:
             filename_tcl = "{" + filename + "}"
             tcl.append("read_edif " + filename_tcl)
+
+        for filename in ips:
+            filename_tcl = "{" + filename + "}"
+            ip = os.path.splitext(os.path.basename(filename))[0]
+            tcl.append("read_ip " + filename_tcl)
+            tcl.append("upgrade_ip [get_ips {}]".format(ip))
+            tcl.append("generate_target all [get_ips {}]".format(ip))
+            tcl.append("synth_ip [get_ips {}] -force".format(ip))
+            tcl.append("get_files -all -of_objects [get_files {}]".format(filename_tcl))
+
         tcl.append("read_xdc {}.xdc".format(build_name))
         tcl.extend(c.format(build_name=build_name) for c in self.pre_synthesis_commands)
         # "-include_dirs {}" crashes Vivado 2016.4
@@ -182,9 +206,9 @@ class XilinxVivadoToolchain:
             toolchain_path=None, source=True, run=True, **kwargs):
         if toolchain_path is None:
             if sys.platform == "win32":
-                toolchain_path = "C:\\Xilinx"
+                toolchain_path = "C:\\Xilinx\\Vivado"
             elif sys.platform == "cygwin":
-                toolchain_path = "/cygdrive/c/Xilinx"
+                toolchain_path = "/cygdrive/c/Xilinx/Vivado"
             else:
                 toolchain_path = "/opt/Xilinx/Vivado"
         os.makedirs(build_dir, exist_ok=True)
@@ -200,9 +224,10 @@ class XilinxVivadoToolchain:
         named_sc, named_pc = platform.resolve_signals(v_output.ns)
         v_file = build_name + ".v"
         v_output.write(v_file)
-        sources = platform.sources | {(v_file, "verilog", "work")}
+        sources = platform.sources + [(v_file, "verilog", "work")]
         edifs = platform.edifs
-        self._build_batch(platform, sources, edifs, build_name)
+        ips = platform.ips
+        self._build_batch(platform, sources, edifs, ips, build_name)
         tools.write_to_file(build_name + ".xdc", _build_xdc(named_sc, named_pc))
         if run:
             _run_vivado(build_name, toolchain_path, source)