mirror of
https://github.com/verilator/verilator.git
synced 2025-04-05 04:02:37 +00:00
Tests: Refactor t_vpi_time_cb to avoid shared object
This commit is contained in:
parent
44478a53c2
commit
2feb46fc5d
@ -1011,6 +1011,7 @@ sub compile {
|
||||
cmd=>[($ENV{VERILATOR_VCS}||"vcs"),
|
||||
@{$param{vcs_flags}},
|
||||
@{$param{vcs_flags2}},
|
||||
($opt_verbose ? " -CFLAGS -DTEST_VERBOSE=1":""),
|
||||
@{$param{v_flags}},
|
||||
@{$param{v_flags2}},
|
||||
$param{top_filename},
|
||||
|
@ -12,7 +12,7 @@
|
||||
#ifndef TEST_CHECK_H_
|
||||
#define TEST_CHECK_H_
|
||||
|
||||
extern bool errors;
|
||||
extern int errors;
|
||||
|
||||
#ifdef TEST_VERBOSE
|
||||
static bool verbose = true;
|
||||
@ -23,12 +23,13 @@ static bool verbose = false;
|
||||
//======================================================================
|
||||
|
||||
// Use cout to avoid issues with %d/%lx etc
|
||||
#define TEST_CHECK(got, exp) \
|
||||
if ((got) != (exp)) { \
|
||||
#define TEST_CHECK(got, exp, test) \
|
||||
if (!(test)) { \
|
||||
std::cout << std::dec << "%Error: " << __FILE__ << ":" << __LINE__ << ": GOT = " << (got) \
|
||||
<< " EXP = " << (exp) << std::endl; \
|
||||
errors = true; \
|
||||
++errors; \
|
||||
}
|
||||
#define TEST_CHECK_EQ(got, exp) TEST_CHECK(got, exp, ((got) == (exp)));
|
||||
|
||||
#define TEST_VERBOSE_PRINTF(format, ...) \
|
||||
do { \
|
||||
|
@ -20,11 +20,8 @@
|
||||
|
||||
#include "TestCheck.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <iostream>
|
||||
|
||||
bool errors = false;
|
||||
|
||||
unsigned int main_time = 0;
|
||||
|
||||
//======================================================================
|
||||
@ -52,31 +49,20 @@ int main(int argc, char** argv, char** env) {
|
||||
tfp->open(VL_STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
#endif
|
||||
|
||||
// Load and initialize the PLI application
|
||||
{
|
||||
const char* filenamep = VL_STRINGIFY(TEST_OBJ_DIR) "/libvpi.so";
|
||||
void* lib = dlopen(filenamep, RTLD_LAZY);
|
||||
void* bootstrap = dlsym(lib, "vpi_compat_bootstrap");
|
||||
if (!bootstrap) {
|
||||
std::string msg = std::string("%Error: Could not dlopen ") + filenamep;
|
||||
vl_fatal(__FILE__, __LINE__, "main", msg.c_str());
|
||||
}
|
||||
((void (*)(void))bootstrap)();
|
||||
}
|
||||
|
||||
VerilatedVpi::callCbs(cbStartOfSimulation);
|
||||
|
||||
topp->eval();
|
||||
topp->clk = 0;
|
||||
main_time += 1;
|
||||
|
||||
while (vl_time_stamp64() < sim_time && !Verilated::gotFinish()) {
|
||||
main_time += 1;
|
||||
topp->eval();
|
||||
VerilatedVpi::callValueCbs();
|
||||
VerilatedVpi::callTimedCbs();
|
||||
TEST_CHECK(VerilatedVpi::cbNextDeadline(), main_time + 1);
|
||||
topp->clk = !topp->clk;
|
||||
if (main_time > 20) { // Else haven't registered callbacks
|
||||
TEST_CHECK_EQ(VerilatedVpi::cbNextDeadline(), main_time + 1);
|
||||
}
|
||||
if ((main_time % 5) == 0) topp->clk = !topp->clk;
|
||||
// mon_do();
|
||||
#if VM_TRACE
|
||||
if (tfp) tfp->dump(main_time);
|
||||
|
@ -10,19 +10,16 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
$Self->{pli_filename} = "t_vpi_time_cb_c.cpp";
|
||||
|
||||
compile(
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
make_pli => 1,
|
||||
sim_time => 2100,
|
||||
v_flags2 => ["t/t_vpi_time_cb_c.cpp"],
|
||||
iv_flags2 => ["-g2005-sv -DWAVES -DIVERILOG"],
|
||||
verilator_flags2 => ["-CFLAGS '-DVL_DEBUG -ggdb' --exe --vpi --no-l2name $Self->{t_dir}/t_vpi_time_cb.cpp -LDFLAGS '-ldl -rdynamic'"],
|
||||
verilator_flags2 => ["-CFLAGS '-DVL_DEBUG -ggdb' --exe --vpi --no-l2name $Self->{t_dir}/t_vpi_time_cb.cpp"],
|
||||
);
|
||||
|
||||
execute(
|
||||
use_libvpi => 1,
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
|
@ -6,6 +6,9 @@
|
||||
// Version 2.0.
|
||||
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import "DPI-C" function void dpii_init();
|
||||
import "DPI-C" function void dpii_final();
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
@ -19,15 +22,18 @@ module t (/*AUTOARG*/
|
||||
// Test loop
|
||||
initial begin
|
||||
count = 0;
|
||||
dpii_init();
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
`ifdef TEST_VERBOSE
|
||||
$display("[%0t] clk", $time);
|
||||
$display("[%0t] clk @ count %0d", $time, count);
|
||||
`endif
|
||||
count <= count + 2;
|
||||
if (count == 1000) begin
|
||||
if (count == 200) begin
|
||||
$display("Final section");
|
||||
// See C++ code: $write("*-* All Finished *-*\n");
|
||||
dpii_final();
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
@ -20,16 +20,17 @@
|
||||
#include "TestSimulator.h"
|
||||
#include "TestVpi.h"
|
||||
|
||||
bool errors = false;
|
||||
int errors = 0;
|
||||
|
||||
unsigned int callback_count_time1 = 3;
|
||||
unsigned int callback_count_time2 = 4;
|
||||
unsigned int callback_count_start_of_sim = 0;
|
||||
unsigned int callback_count1 = 0;
|
||||
unsigned int callback_count2 = 0;
|
||||
unsigned int callback_time1 = 0;
|
||||
unsigned int callback_time2 = 0;
|
||||
|
||||
//======================================================================
|
||||
|
||||
static int _never_cb(p_cb_data cb_data) {
|
||||
TEST_CHECK(0, 1); // Should never get called
|
||||
TEST_CHECK_EQ(0, 1); // Should never get called
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -38,8 +39,9 @@ static int _time_cb1(p_cb_data cb_data) {
|
||||
t.type = vpiSimTime;
|
||||
vpi_get_time(0, &t);
|
||||
TEST_VERBOSE_PRINTF("time_cb1: %d\n", t.low);
|
||||
TEST_CHECK(callback_count_time1, t.low);
|
||||
callback_count_time1++;
|
||||
++callback_count1;
|
||||
if (callback_time1) TEST_CHECK_EQ(callback_time1, t.low);
|
||||
callback_time1 = t.low + 1; // Next call
|
||||
|
||||
t_cb_data cb_data_n;
|
||||
bzero(&cb_data_n, sizeof(cb_data_n));
|
||||
@ -51,7 +53,7 @@ static int _time_cb1(p_cb_data cb_data) {
|
||||
cb_data_n.time = &t;
|
||||
cb_data_n.cb_rtn = _time_cb1;
|
||||
TestVpiHandle cb_data_n1_h = vpi_register_cb(&cb_data_n);
|
||||
TEST_CHECK(vpi_get(vpiType, cb_data_n1_h), vpiCallback);
|
||||
TEST_CHECK_EQ(vpi_get(vpiType, cb_data_n1_h), vpiCallback);
|
||||
}
|
||||
{
|
||||
// Test cancelling a callback
|
||||
@ -69,12 +71,13 @@ static int _time_cb1(p_cb_data cb_data) {
|
||||
}
|
||||
|
||||
static int _time_cb2(p_cb_data cb_data) {
|
||||
// One-shot
|
||||
s_vpi_time t;
|
||||
t.type = vpiSimTime;
|
||||
vpi_get_time(0, &t);
|
||||
TEST_VERBOSE_PRINTF("time_cb2: %d\n", t.low);
|
||||
TEST_CHECK(callback_count_time2, t.low);
|
||||
callback_count_time2++;
|
||||
if (callback_time2) TEST_CHECK_EQ(callback_time2, t.low);
|
||||
++callback_count2;
|
||||
|
||||
t_cb_data cb_data_n;
|
||||
bzero(&cb_data_n, sizeof(cb_data_n));
|
||||
@ -86,12 +89,12 @@ static int _time_cb2(p_cb_data cb_data) {
|
||||
cb_data_n.time = &t;
|
||||
cb_data_n.cb_rtn = _time_cb2;
|
||||
TestVpiHandle cb_data_n2_h = vpi_register_cb(&cb_data_n);
|
||||
TEST_CHECK(vpi_get(vpiType, cb_data_n2_h), vpiCallback);
|
||||
TEST_CHECK_EQ(vpi_get(vpiType, cb_data_n2_h), vpiCallback);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _start_of_sim_cb(p_cb_data cb_data) {
|
||||
TEST_VERBOSE_PRINTF("-_start_of_sim_cb\n");
|
||||
extern "C" void dpii_init() {
|
||||
TEST_VERBOSE_PRINTF("-dpii_init()\n");
|
||||
|
||||
t_cb_data cb_data_n1, cb_data_n2;
|
||||
bzero(&cb_data_n1, sizeof(cb_data_n1));
|
||||
@ -105,7 +108,7 @@ static int _start_of_sim_cb(p_cb_data cb_data) {
|
||||
cb_data_n1.time = &t1;
|
||||
cb_data_n1.cb_rtn = _time_cb1;
|
||||
TestVpiHandle cb_data_n1_h = vpi_register_cb(&cb_data_n1);
|
||||
TEST_CHECK(vpi_get(vpiType, cb_data_n1_h), vpiCallback);
|
||||
TEST_CHECK_EQ(vpi_get(vpiType, cb_data_n1_h), vpiCallback);
|
||||
|
||||
cb_data_n2.reason = cbAfterDelay;
|
||||
t2.type = vpiSimTime;
|
||||
@ -114,45 +117,20 @@ static int _start_of_sim_cb(p_cb_data cb_data) {
|
||||
cb_data_n2.time = &t2;
|
||||
cb_data_n2.cb_rtn = _time_cb2;
|
||||
TestVpiHandle cb_data_n2_h = vpi_register_cb(&cb_data_n2);
|
||||
callback_count_start_of_sim++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _end_of_sim_cb(p_cb_data cb_data) {
|
||||
TEST_CHECK(callback_count_start_of_sim, 1);
|
||||
if (!errors) fprintf(stdout, "*-* All Finished *-*\n");
|
||||
return 0;
|
||||
}
|
||||
extern "C" void dpii_final() {
|
||||
TEST_VERBOSE_PRINTF("-dpii_final()\n");
|
||||
|
||||
extern "C" void vpi_compat_bootstrap(void) {
|
||||
t_cb_data cb_data;
|
||||
bzero(&cb_data, sizeof(cb_data));
|
||||
{
|
||||
TEST_VERBOSE_PRINTF("register _start_of_sim_cb_h\n");
|
||||
cb_data.reason = cbStartOfSimulation;
|
||||
cb_data.time = 0;
|
||||
cb_data.cb_rtn = _start_of_sim_cb;
|
||||
TestVpiHandle _start_of_sim_cb_h = vpi_register_cb(&cb_data);
|
||||
}
|
||||
{
|
||||
TEST_VERBOSE_PRINTF("register _end_of_sim_cb_h\n");
|
||||
cb_data.reason = cbEndOfSimulation;
|
||||
cb_data.time = 0;
|
||||
cb_data.cb_rtn = _end_of_sim_cb;
|
||||
TestVpiHandle _end_of_sim_cb_h = vpi_register_cb(&cb_data);
|
||||
}
|
||||
{
|
||||
// Test cancelling a callback
|
||||
cb_data.reason = cbStartOfSimulation;
|
||||
cb_data.time = 0;
|
||||
cb_data.cb_rtn = _never_cb;
|
||||
TestVpiHandle cb_h = vpi_register_cb(&cb_data);
|
||||
vpi_remove_cb(cb_h);
|
||||
cb_h.freed();
|
||||
// Allow some slop as cb might be before/after this call
|
||||
TEST_CHECK(callback_count1, 1010,
|
||||
(callback_count1 >= 1000 && callback_count1 <= 1020));
|
||||
TEST_CHECK(callback_count2, 1010,
|
||||
(callback_count2 >= 1000 && callback_count2 <= 1020));
|
||||
|
||||
if (errors) {
|
||||
vpi_control(vpiStop);
|
||||
} else {
|
||||
printf("*-* All Finished *-*\n");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef IVERILOG
|
||||
// icarus entry
|
||||
void (*vlog_startup_routines[])() = {vpi_compat_bootstrap, 0};
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user