Source code for edalize.ise

# Copyright edalize contributors
# Licensed under the 2-Clause BSD License, see LICENSE for details.
# SPDX-License-Identifier: BSD-2-Clause

import os.path

from edalize.edatool import Edatool


[docs] class Ise(Edatool): argtypes = ["vlogdefine", "vlogparam", "generic"] MAKEFILE_TEMPLATE = """#Auto generated by Edalize include config.mk all: $(TOPLEVEL).bit $(TOPLEVEL).bit: $(NAME)_run.tcl $(NAME).xise $(EDALIZE_LAUNCHER) xtclsh $^ $(NAME).xise: $(NAME).tcl $(EDALIZE_LAUNCHER) xtclsh $< """ TCL_RUN_FILE_TEMPLATE = """#Auto generated by Edalize project open $::argv process run "Generate Programming File" """ TCL_FILE_TEMPLATE = """#Auto generated by Edalize proc project_new_exist_ok name {{ if {{ [catch {{ project new $name }}] }} {{ project open $name }} }} proc xfile_add_exist_ok name {{ if {{ [catch {{ xfile get [file tail $name] name }}] }} {{ xfile add $name }} }} project_new_exist_ok {design} project set family "{family}" project set device {device} project set package {package} project set speed {speed} project set "Generate Detailed MAP Report" true """ PGM_FILE_TEMPLATE = """ # Batch script for programming the device using a JTAG interface. # Used with: # $ impact -batch {pgm_file} setMode -bscan setCable -port auto identify assignFile -p {board_device_index} -file {bit_file} program -p {board_device_index} saveCDF -file {cdf_file} quit """
[docs] @classmethod def get_doc(cls, api_ver): if api_ver == 0: return { "description": "Xilinx ISE Design Suite", "members": [ { "name": "family", "type": "String", "desc": "FPGA family (e.g. spartan6)", }, { "name": "device", "type": "String", "desc": "FPGA device (e.g. xc6slx45)", }, { "name": "package", "type": "String", "desc": "FPGA package (e.g. csg324)", }, { "name": "speed", "type": "Integer", "desc": "FPGA speed grade (e.g. -2)", }, { "name": "board_device_index", "type": "Integer", "desc": "Specifies the FPGA's device number in the JTAG chain, starting at 1", }, { "name": "pgm", "type": "String", "desc": "Programming tool. Default is 'none', set to 'ise' to program the FPGA in the run stage.", }, ], }
[docs] def configure_main(self): for i in ["family", "device", "package", "speed"]: if not i in self.tool_options: raise RuntimeError("Missing required option '{}'".format(i)) self._write_tcl_file() with open(os.path.join(self.work_root, "Makefile"), "w") as f: f.write(self.MAKEFILE_TEMPLATE) with open(os.path.join(self.work_root, "config.mk"), "w") as f: f.write("NAME := {}\n".format(self.name)) f.write("TOPLEVEL := {}\n".format(self.toplevel)) with open(os.path.join(self.work_root, self.name + "_run.tcl"), "w") as f: f.write(self.TCL_RUN_FILE_TEMPLATE)
def _write_tcl_file(self): tcl_file = open(os.path.join(self.work_root, self.name + ".tcl"), "w") tcl_file.write( self.TCL_FILE_TEMPLATE.format( design=self.name, family=self.tool_options["family"], device=self.tool_options["device"], package=self.tool_options["package"], speed=self.tool_options["speed"], ) ) if self.vlogdefine: s = 'project set "Verilog Macros" "{}" -process "Synthesize - XST"\n' tcl_file.write( s.format( "|".join( [ k + "=" + self._param_value_str(v) for k, v in self.vlogdefine.items() ] ) ) ) if self.vlogparam or self.generic: genparam = self.vlogparam.copy() genparam.update(self.generic) s = 'project set "Generics, Parameters" "{}" -process "Synthesize - XST"\n' tcl_file.write( s.format( "|".join( [ k + "=" + self._param_value_str(v, '\\"') for k, v in genparam.items() ] ) ) ) (src_files, incdirs) = self._get_fileset_files( force_slash=True ) # ISE tcl doesn't like '\', so '/' is forced if incdirs: tcl_file.write( 'project set "Verilog Include Directories" "{}" -process "Synthesize - XST"\n'.format( "|".join(incdirs) ) ) _libraries = [] for f in src_files: if f.file_type == "tclSource": tcl_file.write("source {}\n".format(f.name)) elif f.file_type.startswith("verilogSource"): tcl_file.write("xfile add {}\n".format(f.name)) elif f.file_type == "UCF": tcl_file.write("xfile_add_exist_ok {}\n".format(f.name)) elif f.file_type == "BMM": tcl_file.write("xfile add {}\n".format(f.name)) elif f.file_type.startswith("vhdlSource"): if f.logical_name: if not f.logical_name in _libraries: tcl_file.write("lib_vhdl new {}\n".format(f.logical_name)) _libraries.append(f.logical_name) _s = "xfile add {} -lib_vhdl {}\n" tcl_file.write(_s.format(f.name, f.logical_name)) else: tcl_file.write("xfile add {}\n".format(f.name)) elif f.file_type == "user": pass tcl_file.write('project set top "{}"\n'.format(self.toplevel)) tcl_file.close()
[docs] def run_main(self): if ("pgm" not in self.tool_options) or (self.tool_options["pgm"] != "ise"): return pgm_file_name = os.path.join(self.work_root, self.name + ".pgm") self._write_pgm_file(pgm_file_name) self._run_tool("impact", ["-batch", pgm_file_name])
def _write_pgm_file(self, pgm_file_name): pgm_file = open(pgm_file_name, "w") pgm_file.write( self.PGM_FILE_TEMPLATE.format( pgm_file=pgm_file_name, bit_file=os.path.join(self.work_root, self.toplevel + ".bit"), cdf_file=os.path.join(self.work_root, self.toplevel + ".cdf"), board_device_index=self.tool_options.get("board_device_index", "1"), ) ) pgm_file.close()