Source code for edalize.xsim

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

import os
import logging

from collections import OrderedDict
from edalize.edatool import Edatool

logger = logging.getLogger(__name__)


[docs]class Xsim(Edatool): argtypes = ["plusarg", "vlogdefine", "vlogparam", "generic"] MAKEFILE_TEMPLATE = """#Auto generated by Edalize include config.mk all: xsim.dir/$(TARGET)/xsimk xsim.dir/$(TARGET)/xsimk: xelab $(TOPLEVEL) -prj $(TARGET).prj -snapshot $(TARGET) $(VLOG_DEFINES) $(VLOG_INCLUDES) $(GEN_PARAMS) $(XELAB_OPTIONS) run: xsim.dir/$(TARGET)/xsimk xsim -R $(XSIM_OPTIONS) $(TARGET) $(EXTRA_OPTIONS) run-gui: xsim.dir/$(TARGET)/xsimk xsim --gui $(XSIM_OPTIONS) $(TARGET) $(EXTRA_OPTIONS) """ CONFIG_MK_TEMPLATE = """#Auto generated by Edalize TARGET = {target} TOPLEVEL = {toplevel} VLOG_DEFINES = {vlog_defines} VLOG_INCLUDES = {vlog_includes} GEN_PARAMS = {gen_params} XELAB_OPTIONS = {xelab_options} XSIM_OPTIONS = {xsim_options} """
[docs] @classmethod def get_doc(cls, api_ver): if api_ver == 0: return { "description": "XSim simulator from the Xilinx Vivado suite", "members": [ { "name": "compilation_mode", "type": "String", "desc": "Common or separate compilation, sep - for separate compilation, common - for common compilation", } ], "lists": [ { "name": "xelab_options", "type": "String", "desc": "Additional options for compilation with xelab", }, { "name": "xsim_options", "type": "String", "desc": "Additional run options for XSim", }, ], }
[docs] def configure_main(self): self._write_config_files() # Check if any VPI modules are present and display warning if len(self.vpi_modules) > 0: modules = [m["name"] for m in self.vpi_modules] logger.error("VPI modules not supported by Xsim: %s" % ", ".join(modules))
def _write_config_files(self): mfc = self.tool_options.get("compilation_mode") == "common" with open(os.path.join(self.work_root, self.name + ".prj"), "w") as f: mfcu = [] (src_files, self.incdirs) = self._get_fileset_files() for src_file in src_files: cmd = "" if src_file.file_type.startswith("verilogSource"): cmd = "verilog" elif src_file.file_type == "vhdlSource-2008": cmd = "vhdl2008" elif src_file.file_type.startswith("vhdlSource"): cmd = "vhdl" elif src_file.file_type.startswith("systemVerilogSource"): if mfc: mfcu.append(src_file.name) else: cmd = "sv" elif src_file.file_type in ["user"]: pass else: _s = "{} has unknown file type '{}'" logger.warning(_s.format(src_file.name, src_file.file_type)) if cmd: if src_file.logical_name: lib = src_file.logical_name else: lib = "work" f.write("{} {} {}\n".format(cmd, lib, src_file.name)) if mfc: f.write("sv work " + " ".join(mfcu)) with open(os.path.join(self.work_root, "config.mk"), "w") as f: vlog_defines = " ".join( [ "--define {}={}".format(k, self._param_value_str(v)) for k, v, in self.vlogdefine.items() ] ) vlog_includes = " ".join(["-i " + k for k in self.incdirs]) # Both parameters and generics use the same --generic_top argument # so warn if there are overlapping values common_vals = set(self.vlogparam).intersection(set(self.generic)) if common_vals != set(): _s = "Common values for vlogparam and generic: {}" logger.warning(_s.format(common_vals)) gen_param = OrderedDict(self.vlogparam) gen_param.update(self.generic) gen_param_args = " ".join( [ '--generic_top "{}={}"'.format(k, self._param_value_str(v)) for k, v in gen_param.items() ] ) xelab_options = " ".join(self.tool_options.get("xelab_options", [])) xsim_options = " ".join(self.tool_options.get("xsim_options", [])) f.write( self.CONFIG_MK_TEMPLATE.format( target=self.name, toplevel=self.toplevel, vlog_defines=vlog_defines, vlog_includes=vlog_includes, gen_params=gen_param_args, xelab_options=xelab_options, xsim_options=xsim_options, ) ) with open(os.path.join(self.work_root, "Makefile"), "w") as f: f.write(self.MAKEFILE_TEMPLATE)
[docs] def run_main(self): args = ["run"] # Plusargs if self.plusarg: _s = "--testplusarg {}={}" args.append( "EXTRA_OPTIONS=" + " ".join([_s.format(k, v) for k, v in self.plusarg.items()]) ) self._run_tool("make", args)