Пример #1
0
    def CreateFlashImage(self,
                         bitstreams: dict,
                         outFile: str,
                         flashSizeMb: int,
                         interface: str = "SPIx1"):
        """
        Create a flash image containing multiple bitstreams

        :param bitstreams: Dictionary containing bitstream paths as value and addresses as key. example {0x0100 : bla.bit}
        :param outFile: Output file to write
        :param flashSizeMb: Size of the flash in MB
        :param interface: configuration interface to use (see Vivado help for write_cfgmem for details)
        :return: None
        """
        with TempFile("__viv.tcl") as f:
            bsStringParts = [
                "up {:08x} {}".format(size, path)
                for size, path in bitstreams.items()
            ]
            bsString = " ".join(bsStringParts)
            string = "write_cfgmem -force -disablebitswap -size {fsize} -format BIN -loadbit \"{bitstreams}\" -interface {itf} {file}"
            f.write(
                string.format(fsize=flashSizeMb,
                              bitstreams=bsString,
                              itf=interface,
                              file=outFile))
            f.flush()
            # Execute Vivado
            self._RunVivado(".", "-source __viv.tcl")
Пример #2
0
    def PackageBdAsIp(self,
                      workDir: str,
                      xprName: str,
                      bdName: str,
                      outputDir: str,
                      vendor: str = "NoVendor",
                      addrBlockRenaming: Dict[str, str] = None):
        """
        Package a block design inside a vivado project as IP. This is useful for building hierarchial projects.

        :param workDir: Working directory for the project (directory the .xpr file is in)
        :param xprName: Name of the XPR file (including extension) to build
        :param bdName: Name of the BD to package
        :param outputDir: Directory to put the IP-Core into
        :param vendor: Vendor name to use
        :param addrBlockRenaming: Dictionary containing new names for address blocks based on their base address in the form {"0x1000":"NewName"}.
                                  This is required because Vivado by default just names the blocks Reg0, Reg1, etc. which
                                  is not very helpful when defining the address map of the core.
        :return: None
        """

        outAbs = os.path.abspath(outputDir).replace(
            "\\", "/")  #Vivado always requires linux paths
        #Build
        with TempWorkDir(workDir):
            #Create vivado tcl
            tcl = ""
            tcl += "open_project {}\n".format(xprName)
            tcl += "ipx::package_project -vendor {} -root_dir {} -library user -taxonomy /UserIP -module {} -import_files -force\n".format(
                vendor, outAbs, bdName)
            if addrBlockRenaming is not None:
                tcl += "set allBlocks [ipx::get_address_blocks -of_objects [ipx::get_memory_maps * -of_objects [ipx::current_core]] *]\n"
                for addr, name in addrBlockRenaming.items():
                    tcl += "foreach block $allBlocks {\n" + \
                           "  scan [get_property BASE_ADDRESS $block] %x blkAddr\n"+ \
                           "  if {{ {thisAddr} == $blkAddr}} {{\n".format(thisAddr=int(addr)) + \
                           "    set_property NAME {{{}}} $block\n".format(name) + \
                           "  }\n" + \
                           "}\n"
            tcl += "ipx::create_xgui_files [ipx::current_core]\n" + \
                   "ipx::update_checksums [ipx::current_core]\n" + \
                   "ipx::save_core [ipx::current_core]\n"
            tcl += "close_project\n"
            with TempFile("__viv.tcl") as f:
                f.write(tcl)
                f.flush()
                # Execute Vivado
                try:
                    self._RunVivado(".", "-source __viv.tcl")
                except:
                    shutil.copy(
                        "__viv.tcl",
                        "__failedViv.tcl",
                    )
                    raise
Пример #3
0
    def BuildXpr(self, workDir: str, xprName: str, generateBd: bool = False):
        """
        Build an XPR project

        :param workDir: Working directory for the project (directory the .xpr file is in)
        :param xprName: Name of the XPR file (including extension) to build
        :param generateBd: If true, all block diagrams in the design are (re-)generated. The re-generation is forced, so
                           they are even re-generated if they are unchanged. Note that re-generatino of BDs is required
                           after checking out an XPR project from a version control system.
        """
        #Clear whs/wns to make sure no old values are read if the compilation fails
        self.whs = None
        self.wns = None
        #Build
        with TempWorkDir(workDir):
            #Create vivado tcl
            tcl = ""
            tcl += "open_project {}\n".format(xprName)
            #Run Implementation
            tcl += "update_compile_order -fileset sources_1\n"
            if generateBd:
                tcl += "generate_target -force all [get_files -regexp .*bd]\n"
            tcl += "set_param general.maxThreads 1\n"  #Workaround for multithreading bug in the xilinx tools (DRC hangs)
            tcl += "reset_run synth_1\n"
            tcl += "launch_runs impl_1 -to_step write_bitstream -jobs 4\n"
            tcl += "wait_on_run impl_1\n"
            #Print Worst-case slacks
            tcl += "puts \"RESULT-WNS: [get_property STATS.WNS [current_run]]\"\n"
            tcl += "puts \"RESULT-WHS: [get_property STATS.WHS [current_run]]\"\n"
            tcl += "close_project\n"
            with TempFile("__viv.tcl") as f:
                f.write(tcl)
                f.flush()
                #Execute Vivado
                self._RunVivado(".", "-source __viv.tcl")
            #Parse Log File
            with open("vivado.log", "r") as f:
                for line in f.readlines():
                    if line.startswith("CRITICAL WARNING:"):
                        self.criticalWarnings.append(line)
                    if line.startswith("ERROR:"):
                        self.errors.append(line)
                    if line.startswith("RESULT-WNS:"):
                        #An empty string may be returned if the compilation failed
                        try:
                            self.wns = float(line.split(":")[1].strip())
                        except:
                            self.wns = None
                    if line.startswith("RESULT-WHS:"):
                        # An empty string may be returned if the compilation failed
                        try:
                            self.whs = float(line.split(":")[1].strip())
                        except:
                            self.wns = None
Пример #4
0
 def _RunSdk(self, tclString : str, debug : bool = False):
     with TempWorkDir(self.workspace):
         with TempFile("__sdk.tcl") as f:
             #Write Temporary TCL
             f.write("setws .\n")    #Set workspace
             f.write(tclString)
             f.flush()
             if not debug:
                 call = ExtAppCall(".", "{}  __sdk.tcl".format(self._xsctCmd))
                 call.run_sync()
                 self._UpdateStdOut(call)
             else:
                 os.system("{}  __sdk.tcl".format(self._xsctCmd))
    def ExportXsa(self, workDir : str, xprName : str, xsaPath : str):
        """
        Export XSA file

        :param workDir: Working directory for the project (directory the .xpr file is in)
        :param xprName: Name of the XPR file (including extension) to export the .xsa file for
        :param xsaPath: Path of the XSA file to create
        """
        xsaAbs = os.path.abspath(xsaPath).replace("\\", "/")
        with TempWorkDir(workDir):
            tcl = ""
            tcl += "open_project {}\n".format(xprName)
            tcl += "write_hw_platform -fixed -include_bit -force -file {}\n".format(xsaAbs)
            tcl += "close_project\n"
            with TempFile("__viv.tcl") as f:
                f.write(tcl)
                f.flush()
                #Execute Vivado
                self._RunVivado(".", "-source __viv.tcl")
    def ExportHdf(self, workDir : str, xprName : str, hdfPath : str):
        """
        Export HDF file

        :param workDir: Working directory for the project (directory the .xpr file is in)
        :param xprName: Name of the XPR file (including extension) to export the .hdf file for
        :param hdfPath: Path of the HDF file to create
        """
        hdfAbs = os.path.abspath(hdfPath).replace("\\", "/")
        with TempWorkDir(workDir):
            tcl = ""
            tcl += "open_project {}\n".format(xprName)
            tcl += "set PRJ_NAME [get_property NAME [current_project ]]\n"
            tcl += "set TOP_NAME [get_property TOP [current_fileset]]\n"
            tcl += "file copy -force ./$PRJ_NAME.runs/impl_1/$TOP_NAME.sysdef {}\n".format(hdfAbs)
            tcl += "close_project\n"
            with TempFile("__viv.tcl") as f:
                f.write(tcl)
                f.flush()
                #Execute Vivado
                self._RunVivado(".", "-source __viv.tcl")