2016-11-28 01:16:37 +01:00
|
|
|
// See LICENSE.SiFive for license details.
|
2016-08-16 07:03:03 +02:00
|
|
|
|
|
|
|
#include <fesvr/dtm.h>
|
|
|
|
#include <vpi_user.h>
|
|
|
|
#include <svdpi.h>
|
|
|
|
|
|
|
|
dtm_t* dtm;
|
|
|
|
|
2016-08-31 01:49:39 +02:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
// Remove args that will confuse dtm, such as those that require two tokens, like VCS code coverage "-cm line+cond"
|
|
|
|
std::vector<std::string> filter_argv_for_dtm(int argc, char** argv)
|
|
|
|
{
|
|
|
|
std::vector<std::string> out;
|
|
|
|
for (int i = 1; i < argc; ++i) { // start with 1 to skip my executable name
|
|
|
|
if (!strncmp(argv[i], "-cm", 3)) {
|
|
|
|
++i; // skip this one and the next one
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
out.push_back(argv[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-16 07:03:03 +02:00
|
|
|
extern "C" int debug_tick
|
|
|
|
(
|
|
|
|
unsigned char* debug_req_valid,
|
|
|
|
unsigned char debug_req_ready,
|
|
|
|
int* debug_req_bits_addr,
|
|
|
|
int* debug_req_bits_op,
|
|
|
|
long long* debug_req_bits_data,
|
|
|
|
unsigned char debug_resp_valid,
|
|
|
|
unsigned char* debug_resp_ready,
|
|
|
|
int debug_resp_bits_resp,
|
|
|
|
long long debug_resp_bits_data
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (!dtm) {
|
|
|
|
s_vpi_vlog_info info;
|
|
|
|
if (!vpi_get_vlog_info(&info))
|
|
|
|
abort();
|
2016-08-31 01:49:39 +02:00
|
|
|
dtm = new dtm_t(filter_argv_for_dtm(info.argc, info.argv));
|
2016-08-16 07:03:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
dtm_t::resp resp_bits;
|
|
|
|
resp_bits.resp = debug_resp_bits_resp;
|
|
|
|
resp_bits.data = debug_resp_bits_data;
|
|
|
|
|
|
|
|
dtm->tick
|
|
|
|
(
|
|
|
|
debug_req_ready,
|
|
|
|
debug_resp_valid,
|
|
|
|
resp_bits
|
|
|
|
);
|
|
|
|
|
|
|
|
*debug_resp_ready = dtm->resp_ready();
|
|
|
|
*debug_req_valid = dtm->req_valid();
|
|
|
|
*debug_req_bits_addr = dtm->req_bits().addr;
|
|
|
|
*debug_req_bits_op = dtm->req_bits().op;
|
|
|
|
*debug_req_bits_data = dtm->req_bits().data;
|
|
|
|
|
|
|
|
return dtm->done() ? (dtm->exit_code() << 1 | 1) : 0;
|
|
|
|
}
|