Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modelsim ini options for GUI mode #1024

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions vunit/sim_if/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,28 @@ def fail():
fail()


class DictOfStringOption(Option):
"""
Must be a dictinary of strings
"""

def validate(self, value):
def fail():
raise ValueError(f"Option {self.name!r} must be a dictionary of strings. Got {value!r}")

if not isinstance(value, dict):
fail()

try:
for name, elem in value.items():
if not is_string_not_iterable(name):
fail()
if not is_string_not_iterable(elem):
fail()
except TypeError:
fail()


class VHDLAssertLevelOption(Option):
"""
VHDL assert level
Expand Down
48 changes: 47 additions & 1 deletion vunit/sim_if/modelsim.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@
from pathlib import Path
import os
import logging
from typing import Optional, Set, Union
from configparser import RawConfigParser
from ..exceptions import CompileError
from ..ostools import Process, file_exists
from ..vhdl_standard import VHDL
from . import SimulatorInterface, ListOfStringOption, StringOption
from . import DictOfStringOption
from .vsim_simulator_mixin import VsimSimulatorMixin, fix_path

LOGGER = logging.getLogger(__name__)
Expand All @@ -41,6 +43,7 @@ class ModelSimInterface(VsimSimulatorMixin, SimulatorInterface): # pylint: disa
sim_options = [
ListOfStringOption("modelsim.vsim_flags"),
ListOfStringOption("modelsim.vsim_flags.gui"),
DictOfStringOption("modelsim.vsim_ini.gui"),
ListOfStringOption("modelsim.init_files.after_load"),
ListOfStringOption("modelsim.init_files.before_run"),
StringOption("modelsim.init_file.gui"),
Expand Down Expand Up @@ -233,6 +236,8 @@ def _create_load_function(self, test_suite_name, config, output_path):
Create the vunit_load TCL function that runs the vsim command and loads the design
"""

self._vsim_extra_ini(config)

set_generic_str = " ".join(
(
f"-g/{config.entity_name!s}/{name!s}={encode_generic_value(value)!s}"
Expand Down Expand Up @@ -329,7 +334,7 @@ def _create_run_function():
"""
Create the vunit_run function to run the test bench
"""
return """
tcl = """

proc _vunit_run_failure {} {
catch {
Expand Down Expand Up @@ -359,6 +364,7 @@ def _create_run_function():
restart -f
}
"""
return tcl

def _vsim_extra_args(self, config):
"""
Expand All @@ -372,6 +378,46 @@ def _vsim_extra_args(self, config):

return " ".join(vsim_extra_args)

def _vsim_extra_ini(self, config):
if not self._gui:
return

cfg = parse_modelsimini(self._sim_cfg_file_name)

vsim_extra_ini = {}
vsim_extra_ini = config.sim_options.get("modelsim.vsim_ini.gui", vsim_extra_ini)
for name, val in vsim_extra_ini.items():
cfg.set("vsim", name, val)

write_modelsimini(cfg, self._sim_cfg_file_name)
return

def _create_gui_script(self, common_file_name, config):
cfg = parse_modelsimini(self._sim_cfg_file_name)
vsimcfg = dict(cfg.items("vsim"))
if "shutdownfile" in vsimcfg:
dofile = vsimcfg["shutdownfile"]
self._dostartup_cleanup(dofile)

return super()._create_gui_script(common_file_name, config)

def _dostartup_cleanup(self, dofile : str):
"""
cleanup restore session do-file from vsim command options, since it breaks options invoked
by vunit
"""
if file_exists(dofile):
dofinal = [];
with open(dofile, 'rt') as file_in:
## dofinal = filter(lambda line: not line.startswith("vsim"), file_in )
for line in file_in:
if not line.startswith("vsim"):
dofinal.append(line)

with open(dofile, 'wt') as file_out:
file_out.writelines(dofinal)


def merge_coverage(self, file_name, args=None):
"""
Merge coverage from all test cases
Expand Down