Skip to content

Commit

Permalink
Implemented PLUSARGS for FLI
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ktbarrett authored and imphil committed Feb 17, 2020
1 parent 0a125b3 commit b283b48
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 3 deletions.
56 changes: 54 additions & 2 deletions cocotb/share/lib/fli/FliCbHdl.cpp
Expand Up @@ -26,6 +26,10 @@
******************************************************************************/

#include "FliImpl.h"
#include "mti.h"
#undef DLLEXPORT // redefinition in tcl.h causes warning
#include "tcl.h"
#include <limits>

/**
* @name cleanup callback
Expand Down Expand Up @@ -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<Tcl_Interp*>(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<int>::max()) {
return;
}
int argc = static_cast<int>(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;
Expand Down Expand Up @@ -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];

Expand Down
2 changes: 1 addition & 1 deletion cocotb/share/makefiles/simulators/Makefile.questa
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions 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``.

0 comments on commit b283b48

Please sign in to comment.