From b283b48368a3a7f507110c6699db3a6c7ce01677 Mon Sep 17 00:00:00 2001 From: Kaleb Barrett Date: Thu, 30 Jan 2020 00:39:11 -0600 Subject: [PATCH] Implemented PLUSARGS for FLI The FLI does not offer any utility to easily grab the argc/argv from the simulator. I use Questa's included TCL interpreter C API to access the TCL 'argv' variable. The 'argv' variable references the outer vsim call's arguments due to how the current makefiles are setup, so the PLUSARGS variable was added back to the outer call. PLUSARGS must also remain on the inner call for the VPI implementation to work. --- cocotb/share/lib/fli/FliCbHdl.cpp | 56 ++++++++++++++++++- .../makefiles/simulators/Makefile.questa | 2 +- .../source/newsfragments/1256.feature.rst | 1 + 3 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 documentation/source/newsfragments/1256.feature.rst diff --git a/cocotb/share/lib/fli/FliCbHdl.cpp b/cocotb/share/lib/fli/FliCbHdl.cpp index 3352dfa67f..60425592a7 100644 --- a/cocotb/share/lib/fli/FliCbHdl.cpp +++ b/cocotb/share/lib/fli/FliCbHdl.cpp @@ -26,6 +26,10 @@ ******************************************************************************/ #include "FliImpl.h" +#include "mti.h" +#undef DLLEXPORT // redefinition in tcl.h causes warning +#include "tcl.h" +#include /** * @name cleanup callback @@ -140,6 +144,55 @@ int FliStartupCbHdl::arm_callback() return 0; } + +static void get_args(gpi_sim_info_t *info) +{ + /* Necessary to implement PLUSARGS + There is no function available on the FLI to obtain argc+argv directly from the + simulator. To work around this we use the TCL interpreter that ships with Questa, + some TCL commands, and the TCL variable `argv` to obtain the simulator argc/argv. + */ + info->argc = 0; + info->argv = NULL; + + Tcl_Interp* interp = reinterpret_cast(mti_Interp()); + + // get argc + if (mti_Cmd("llength $argv") != TCL_OK) { + return; + } + unsigned long argc_u = strtoul(interp->result, NULL, 10); + Tcl_ResetResult(interp); + if (argc_u > std::numeric_limits::max()) { + return; + } + int argc = static_cast(argc_u); + if (argc_u == 0) { + return; + } + + // allocate storage for argv + char** argv = new char*[argc]; + + // get each argv and copy into internal storage + for (int i = 0; i < argc; i++) { + std::string cmd = "lindex $argv " + std::to_string(i); + if (mti_Cmd(cmd.c_str()) != TCL_OK) { + return; + } + argv[i] = new char[strlen(interp->result)+1]; + strcpy(argv[i], interp->result); + Tcl_ResetResult(interp); + } + + // set only if all operations succeed + info->argc = argc; + info->argv = argv; + + // argv storage leaks here +} + + int FliStartupCbHdl::run_callback() { gpi_sim_info_t sim_info; @@ -168,8 +221,7 @@ int FliStartupCbHdl::run_callback() // copy in sim_info.product - sim_info.argc = 0; - sim_info.argv = NULL; + get_args(&sim_info); sim_info.product = &product[0]; sim_info.version = &version[0]; diff --git a/cocotb/share/makefiles/simulators/Makefile.questa b/cocotb/share/makefiles/simulators/Makefile.questa index db02f3f5ce..f0a80b03bd 100644 --- a/cocotb/share/makefiles/simulators/Makefile.questa +++ b/cocotb/share/makefiles/simulators/Makefile.questa @@ -148,7 +148,7 @@ $(COCOTB_RESULTS_FILE): $(SIM_BUILD)/runsim.do $(COCOTB_LIBS) $(INT_LIBS) set -o pipefail; $(LIB_LOAD) MODULE=$(MODULE) TESTCASE=$(TESTCASE) TOPLEVEL=$(TOPLEVEL) COCOTB_SIM=1 \ GPI_EXTRA=$(GPI_EXTRA) TOPLEVEL_LANG=$(TOPLEVEL_LANG) PYTHONPATH=$(LIB_DIR):$(PWD):$(NEW_PYTHONPATH) \ - $(CMD) $(RUN_ARGS) -do $(SIM_BUILD)/runsim.do 2>&1 | tee $(SIM_BUILD)/sim.log + $(CMD) $(RUN_ARGS) -do $(SIM_BUILD)/runsim.do $(PLUSARGS) 2>&1 | tee $(SIM_BUILD)/sim.log # check that the file was actually created, since we can't set an exit code from cocotb test -f $(COCOTB_RESULTS_FILE) diff --git a/documentation/source/newsfragments/1256.feature.rst b/documentation/source/newsfragments/1256.feature.rst new file mode 100644 index 0000000000..94cf1e6c4e --- /dev/null +++ b/documentation/source/newsfragments/1256.feature.rst @@ -0,0 +1 @@ +Questa now supports :envvar:`PLUSARGS`. This requires that ``tcl.h`` be present on the system. This is likely included in your installation of Questa. Otherwise, specify ``CXXFLAGS=-I/path/to/tcl/includedir``.