From deedbe9ffe7a5d75a2f81b9c59e1e5fa78c6e53d Mon Sep 17 00:00:00 2001 From: Lars Asplund Date: Fri, 13 Dec 2024 09:16:36 +0100 Subject: [PATCH] Allow $vunit_tb_path in init file paths. Solves #1075. --- docs/py/opts.rst | 10 +++++----- vunit/sim_if/activehdl.py | 11 ++++++++++- vunit/sim_if/vsim_simulator_mixin.py | 11 +++++++++-- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/docs/py/opts.rst b/docs/py/opts.rst index 5b5c78782..421f1930a 100644 --- a/docs/py/opts.rst +++ b/docs/py/opts.rst @@ -121,7 +121,7 @@ The following simulation options are known. A list of user defined DO/TCL-files that is sourced after the design has been loaded. They will be executed during ``vunit_load``, after the top level has been loaded using the ``vsim`` command. - During script evaluation the ``vunit_tb_path`` variable is defined + During script and file path evaluation the ``vunit_tb_path`` variable is defined as the path of the folder containing the test bench. Additionally, the ``vunit_tb_name`` variable is defined as the name of the test bench. Must be a list of strings. @@ -135,7 +135,7 @@ The following simulation options are known. ``modelsim.init_file.gui`` A user defined TCL-file that is sourced after the design has been loaded in the GUI. For example this can be used to configure the waveform viewer. - During script evaluation the ``vunit_tb_path`` variable is defined + During script and file path evaluation the ``vunit_tb_path`` variable is defined as the path of the folder containing the test bench. Additionally, the ``vunit_tb_name`` variable is defined as the name of the test bench. Must be a string. @@ -166,7 +166,7 @@ The following simulation options are known. A list of user defined DO/TCL-files that is sourced after the design has been loaded. They will be executed during ``vunit_load``, after the top level has been loaded using the ``vsim`` command. - During script evaluation the ``vunit_tb_path`` variable is defined + During script and file path evaluation the ``vunit_tb_path`` variable is defined as the path of the folder containing the test bench. Additionally, the ``vunit_tb_name`` variable is defined as the name of the test bench. Must be a list of strings. @@ -180,7 +180,7 @@ The following simulation options are known. ``rivierapro.init_file.gui`` A user defined TCL-file that is sourced after the design has been loaded in the GUI. For example this can be used to configure the waveform viewer. - During script evaluation the ``vunit_tb_path`` variable is defined + During script and file path evaluation the ``vunit_tb_path`` variable is defined as the path of the folder containing the test bench. Additionally, the ``vunit_tb_name`` variable is defined as the name of the test bench. Must be a string. @@ -197,7 +197,7 @@ The following simulation options are known. ``activehdl.init_file.gui`` A user defined TCL-file that is sourced after the design has been loaded in the GUI. For example this can be used to configure the waveform viewer. - During script evaluation the ``vunit_tb_path`` variable is defined + During script and file path evaluation the ``vunit_tb_path`` variable is defined as the path of the folder containing the test bench. Additionally, the ``vunit_tb_name`` variable is defined as the name of the test bench. Must be a string. diff --git a/vunit/sim_if/activehdl.py b/vunit/sim_if/activehdl.py index 521b8cfae..58dbca6b1 100644 --- a/vunit/sim_if/activehdl.py +++ b/vunit/sim_if/activehdl.py @@ -463,13 +463,22 @@ def _create_user_init_function(self, config): simulator_name.init_file.gui. Also defines the vunit_tb_path and the vunit_tb_name variable. """ + opt_name = self.name + ".init_file.gui" init_file = config.sim_options.get(opt_name, None) + tcl = "proc vunit_user_init {} {\n" if init_file is not None: + # Do not resolve paths starting with $vunit_tb_path but + # leave that to TCL variable expansion + init_file_path = Path(init_file) + if not init_file.startswith("$vunit_tb_path"): + init_file_path = init_file_path.resolve() + init_file_path = fix_path(str(init_file_path)) + tcl += f"set vunit_tb_name {config.design_unit_name}\n" tcl += f"set vunit_tb_path {fix_path(str(Path(config.tb_path).resolve()))}\n" - tcl += f'source "{fix_path(str(Path(init_file).resolve()))!s}"\n' + tcl += f'source "{init_file_path}"\n' tcl += " return 0\n" tcl += "}\n" return tcl diff --git a/vunit/sim_if/vsim_simulator_mixin.py b/vunit/sim_if/vsim_simulator_mixin.py index 8cc127bcf..47f3c6bb2 100644 --- a/vunit/sim_if/vsim_simulator_mixin.py +++ b/vunit/sim_if/vsim_simulator_mixin.py @@ -280,8 +280,15 @@ def _source_tcl_file(file_name, config, message): Create TCL to source a file and catch errors Also defines the vunit_tb_path variable as the config.tb_path and the vunit_tb_name variable as the config.design_unit_name - """ + + # Do not resolve paths starting with $vunit_tb_path but + # leave that to TCL variable expansion + file_name_path = Path(file_name) + if not file_name.startswith("$vunit_tb_path"): + file_name_path = file_name_path.resolve() + file_name_path = fix_path(str(file_name_path)) + template = """ set vunit_tb_path "%s" set vunit_tb_name "%s" @@ -296,7 +303,7 @@ def _source_tcl_file(file_name, config, message): tcl = template % ( fix_path(str(Path(config.tb_path).resolve())), config.design_unit_name, - fix_path(str(Path(file_name).resolve())), + file_name_path, message, ) return tcl