forked from github/verilator
Add vpiTimeUnit and allow to specify time as string, bug1636.
Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
parent
39950d16d0
commit
3ac6745658
2
Changes
2
Changes
@ -12,6 +12,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
**** Update FST trace API for better performance.
|
||||
|
||||
**** Add vpiTimeUnit and allow to specify time as string, bug1636. [Stefan Wallentowitz]
|
||||
|
||||
**** Fix little endian cell ranges, bug1631. [Julien Margetts]
|
||||
|
||||
|
||||
|
@ -1837,6 +1837,30 @@ IData VL_ATOI_N(const std::string& str, int base) VL_PURE {
|
||||
return static_cast<IData>(v);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Timescale conversion
|
||||
|
||||
// Helper function for conversion of timescale strings
|
||||
// Converts (1|10|100)(s|ms|us|ns|ps|fs) to power of then
|
||||
int VL_TIME_STR_CONVERT(const char* strp) {
|
||||
int scale = 0;
|
||||
if (!strp) return 0;
|
||||
if (*strp++ != '1') return 0;
|
||||
while (*strp == '0') { scale++; strp++; }
|
||||
switch (*strp++) {
|
||||
case 's': break;
|
||||
case 'm': scale -= 3; break;
|
||||
case 'u': scale -= 6; break;
|
||||
case 'n': scale -= 9; break;
|
||||
case 'p': scale -= 12; break;
|
||||
case 'f': scale -= 15; break;
|
||||
default: return 0;
|
||||
}
|
||||
if ((scale < 0) && (*strp++ != 's')) return 0;
|
||||
if (*strp) return 0;
|
||||
return scale;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Verilated:: Methods
|
||||
|
||||
|
@ -737,8 +737,21 @@ extern void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp);
|
||||
//=========================================================================
|
||||
// Pli macros
|
||||
|
||||
extern int VL_TIME_STR_CONVERT(const char* strp) VL_PURE;
|
||||
|
||||
#ifndef VL_TIME_PRECISION
|
||||
# define VL_TIME_PRECISION (-12) ///< Timescale units only for for VPI return - picoseconds
|
||||
# ifdef VL_TIME_PRECISION_STR
|
||||
# define VL_TIME_PRECISION VL_TIME_STR_CONVERT(VL_STRINGIFY(VL_TIME_PRECISION_STR))
|
||||
# else
|
||||
# define VL_TIME_PRECISION (-12) ///< Timescale units only for for VPI return - picoseconds
|
||||
# endif
|
||||
#endif
|
||||
#ifndef VL_TIME_UNIT
|
||||
# ifdef VL_TIME_UNIT_STR
|
||||
# define VL_TIME_UNIT VL_TIME_STR_CONVERT(VL_STRINGIFY(VL_TIME_PRECISION_STR))
|
||||
# else
|
||||
# define VL_TIME_UNIT (-12) ///< Timescale units only for for VPI return - picoseconds
|
||||
# endif
|
||||
#endif
|
||||
#ifndef VL_TIME_MULTIPLIER
|
||||
# define VL_TIME_MULTIPLIER 1
|
||||
|
@ -1224,6 +1224,9 @@ PLI_INT32 vpi_get(PLI_INT32 property, vpiHandle object) {
|
||||
case vpiTimePrecision: {
|
||||
return VL_TIME_PRECISION;
|
||||
}
|
||||
case vpiTimeUnit: {
|
||||
return VL_TIME_UNIT;
|
||||
}
|
||||
case vpiType: {
|
||||
VerilatedVpio* vop = VerilatedVpio::castp(object);
|
||||
if (VL_UNLIKELY(!vop)) return 0;
|
||||
|
@ -432,6 +432,12 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
||||
# define VL_STRCASECMP strcasecmp
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
// Stringify macros
|
||||
|
||||
#define VL_STRINGIFY(x) VL_STRINGIFY2(x)
|
||||
#define VL_STRINGIFY2(x) #x
|
||||
|
||||
//=========================================================================
|
||||
|
||||
#endif // Guard
|
||||
|
@ -5,9 +5,6 @@
|
||||
#include "verilated.h"
|
||||
#include "verilated_vcd_c.h"
|
||||
|
||||
#define STRINGIFY(x) STRINGIFY2(x)
|
||||
#define STRINGIFY2(x) #x
|
||||
|
||||
Vt_order_multidriven* vcore;
|
||||
VerilatedVcdC* vcd;
|
||||
vluint64_t vtime;
|
||||
@ -46,7 +43,7 @@ int main() {
|
||||
vcd = new VerilatedVcdC;
|
||||
|
||||
vcore->trace(vcd, 99);
|
||||
vcd->open(STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
vcd->open(VL_STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
|
||||
vcore->i_clk_wr = 0;
|
||||
vcore->i_clk_rd = 0;
|
||||
|
@ -13,9 +13,6 @@
|
||||
|
||||
#include "Vt_scope_map.h"
|
||||
|
||||
#define STRINGIFY(x) STRINGIFY2(x)
|
||||
#define STRINGIFY2(x) #x
|
||||
|
||||
using namespace std;
|
||||
|
||||
unsigned long long main_time = 0;
|
||||
@ -31,7 +28,7 @@ int main(int argc, char** argv, char** env) {
|
||||
|
||||
VerilatedVcdC* tfp = new VerilatedVcdC;
|
||||
top->trace(tfp, 99);
|
||||
tfp->open(STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
tfp->open(VL_STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
|
||||
top->CLK = 0;
|
||||
top->eval();
|
||||
|
53
test_regress/t/t_timescale.cpp
Normal file
53
test_regress/t/t_timescale.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
|
||||
#include <verilated.h>
|
||||
|
||||
#include VM_PREFIX_INCLUDE
|
||||
|
||||
unsigned long long main_time = 0;
|
||||
double sc_time_stamp() { return (double)main_time; }
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define FILENM "t_timescale.cpp"
|
||||
|
||||
#define CHECK_RESULT(got, exp) \
|
||||
if ((got) != (exp)) { \
|
||||
cout << dec << "%Error: " << FILENM << ":" << __LINE__ << ": GOT = " << (got) \
|
||||
<< " EXP = " << (exp) << endl; \
|
||||
return __LINE__; \
|
||||
}
|
||||
|
||||
int main(int argc, char** argv, char** env) {
|
||||
VM_PREFIX* top = new VM_PREFIX("top");
|
||||
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("100s"), 2);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("10s"), 1);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("1s"), 0);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("100ms"), -1);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("10ms"), -2);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("1ms"), -3);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("100us"), -4);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("10us"), -5);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("1us"), -6);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("100ns"), -7);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("10ns"), -8);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("1ns"), -9);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("100ps"), -10);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("10ps"), -11);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("1ps"), -12);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("100fs"), -13);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("10fs"), -14);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("1fs"), -15);
|
||||
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("1.5s"), 0);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("1s "), 0);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("1ss"), 0);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT("s"), 0);
|
||||
CHECK_RESULT(VL_TIME_STR_CONVERT(0), 0);
|
||||
|
||||
top->final();
|
||||
printf("*-* All Finished *-*\n");
|
||||
return 0;
|
||||
}
|
23
test_regress/t/t_timescale.pl
Executable file
23
test_regress/t/t_timescale.pl
Executable file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
scenarios(vlt_all => 1);
|
||||
|
||||
compile(
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
v_flags2 => ["--exe $Self->{t_dir}/t_timescale.cpp"],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
3
test_regress/t/t_timescale.v
Normal file
3
test_regress/t/t_timescale.v
Normal file
@ -0,0 +1,3 @@
|
||||
module t;
|
||||
|
||||
endmodule
|
@ -10,15 +10,12 @@
|
||||
|
||||
#include VM_PREFIX_INCLUDE
|
||||
|
||||
#define STRINGIFY(x) STRINGIFY2(x)
|
||||
#define STRINGIFY2(x) #x
|
||||
|
||||
unsigned long long main_time = 0;
|
||||
double sc_time_stamp() { return (double)main_time; }
|
||||
|
||||
const char* trace_name() {
|
||||
static char name[1000];
|
||||
VL_SNPRINTF(name, 1000, STRINGIFY(TEST_OBJ_DIR) "/simpart_%04d.vcd", (int)main_time);
|
||||
VL_SNPRINTF(name, 1000, VL_STRINGIFY(TEST_OBJ_DIR) "/simpart_%04d.vcd", (int)main_time);
|
||||
return name;
|
||||
}
|
||||
|
||||
|
@ -12,9 +12,6 @@
|
||||
#include "Vt_trace_public_func_t.h"
|
||||
#include "Vt_trace_public_func_glbl.h"
|
||||
|
||||
#define STRINGIFY(x) STRINGIFY2(x)
|
||||
#define STRINGIFY2(x) #x
|
||||
|
||||
unsigned long long main_time = 0;
|
||||
double sc_time_stamp() { return (double)main_time; }
|
||||
|
||||
@ -28,7 +25,7 @@ int main(int argc, char** argv, char** env) {
|
||||
|
||||
VerilatedVcdC* tfp = new VerilatedVcdC;
|
||||
top->trace(tfp, 99);
|
||||
tfp->open(STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
tfp->open(VL_STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
|
||||
while (main_time <= 20) {
|
||||
top->CLK = (main_time / dt_2) % 2;
|
||||
|
@ -12,9 +12,6 @@
|
||||
#include "Vt_trace_public_sig_t.h"
|
||||
#include "Vt_trace_public_sig_glbl.h"
|
||||
|
||||
#define STRINGIFY(x) STRINGIFY2(x)
|
||||
#define STRINGIFY2(x) #x
|
||||
|
||||
unsigned long long main_time = 0;
|
||||
double sc_time_stamp() { return (double)main_time; }
|
||||
|
||||
@ -28,7 +25,7 @@ int main(int argc, char** argv, char** env) {
|
||||
|
||||
VerilatedVcdC* tfp = new VerilatedVcdC;
|
||||
top->trace(tfp, 99);
|
||||
tfp->open(STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
tfp->open(VL_STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
|
||||
while (main_time <= 20) {
|
||||
top->CLK = (main_time / dt_2) % 2;
|
||||
|
@ -10,9 +10,6 @@
|
||||
|
||||
#include VM_PREFIX_INCLUDE
|
||||
|
||||
#define STRINGIFY(x) STRINGIFY2(x)
|
||||
#define STRINGIFY2(x) #x
|
||||
|
||||
unsigned long long main_time = 0;
|
||||
double sc_time_stamp() { return ((double)main_time) / VL_TIME_MULTIPLIER; }
|
||||
|
||||
@ -28,7 +25,7 @@ int main(int argc, char** argv, char** env) {
|
||||
|
||||
top->trace(tfp, 99);
|
||||
|
||||
tfp->open(STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
tfp->open(VL_STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
|
||||
top->clk = 0;
|
||||
|
||||
|
@ -47,9 +47,6 @@ using namespace std;
|
||||
|
||||
unsigned int main_time = false;
|
||||
|
||||
#define STRINGIFY(x) STRINGIFY2(x)
|
||||
#define STRINGIFY2(x) #x
|
||||
|
||||
//======================================================================
|
||||
|
||||
#define CHECK_RESULT_VH(got, exp) \
|
||||
@ -257,7 +254,7 @@ int main(int argc, char** argv, char** env) {
|
||||
VL_PRINTF("Enabling waves...\n");
|
||||
VerilatedVcdC* tfp = new VerilatedVcdC;
|
||||
topp->trace(tfp, 99);
|
||||
tfp->open(STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
tfp->open(VL_STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
#endif
|
||||
|
||||
topp->eval();
|
||||
|
@ -47,9 +47,6 @@ using namespace std;
|
||||
|
||||
unsigned int main_time = false;
|
||||
|
||||
#define STRINGIFY(x) STRINGIFY2(x)
|
||||
#define STRINGIFY2(x) #x
|
||||
|
||||
//======================================================================
|
||||
|
||||
#define CHECK_RESULT_VH(got, exp) \
|
||||
@ -227,7 +224,7 @@ int main(int argc, char** argv, char** env) {
|
||||
VL_PRINTF("Enabling waves...\n");
|
||||
VerilatedVcdC* tfp = new VerilatedVcdC;
|
||||
topp->trace(tfp, 99);
|
||||
tfp->open(STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
tfp->open(VL_STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
#endif
|
||||
|
||||
topp->eval();
|
||||
|
@ -86,6 +86,7 @@ unsigned int callback_count_start_of_sim = 0;
|
||||
|
||||
#define CHECK_RESULT_CSTR_STRIP(got, exp) CHECK_RESULT_CSTR(got + strspn(got, " "), exp)
|
||||
|
||||
// We cannot replace those with VL_STRINGIFY, not available when PLI is build
|
||||
#define STRINGIFY(x) STRINGIFY2(x)
|
||||
#define STRINGIFY2(x) #x
|
||||
|
||||
|
@ -35,9 +35,6 @@
|
||||
unsigned int main_time = false;
|
||||
unsigned int callback_count = false;
|
||||
|
||||
#define STRINGIFY(x) STRINGIFY2(x)
|
||||
#define STRINGIFY2(x) #x
|
||||
|
||||
//======================================================================
|
||||
|
||||
#define CHECK_RESULT_VH(got, exp) \
|
||||
@ -163,7 +160,7 @@ int main(int argc, char** argv, char** env) {
|
||||
VL_PRINTF("Enabling waves...\n");
|
||||
VerilatedVcdC* tfp = new VerilatedVcdC;
|
||||
topp->trace(tfp, 99);
|
||||
tfp->open(STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
tfp->open(VL_STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
#endif
|
||||
|
||||
topp->eval();
|
||||
|
@ -90,6 +90,7 @@ unsigned int callback_count_strs_max = 500;
|
||||
|
||||
#define CHECK_RESULT_CSTR_STRIP(got, exp) CHECK_RESULT_CSTR(got + strspn(got, " "), exp)
|
||||
|
||||
// We cannot replace those with VL_STRINGIFY, not available when PLI is build
|
||||
#define STRINGIFY(x) STRINGIFY2(x)
|
||||
#define STRINGIFY2(x) #x
|
||||
|
||||
|
@ -85,9 +85,6 @@ unsigned int callback_count_start_of_sim = 0;
|
||||
|
||||
#define CHECK_RESULT_CSTR_STRIP(got, exp) CHECK_RESULT_CSTR(got + strspn(got, " "), exp)
|
||||
|
||||
#define STRINGIFY(x) STRINGIFY2(x)
|
||||
#define STRINGIFY2(x) #x
|
||||
|
||||
//======================================================================
|
||||
|
||||
#ifdef IS_VPI
|
||||
@ -166,12 +163,12 @@ int main(int argc, char** argv, char** env) {
|
||||
VL_PRINTF("Enabling waves...\n");
|
||||
VerilatedVcdC* tfp = new VerilatedVcdC;
|
||||
topp->trace(tfp, 99);
|
||||
tfp->open(STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
tfp->open(VL_STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
#endif
|
||||
|
||||
// Load and initialize the PLI application
|
||||
{
|
||||
const char* filenamep = STRINGIFY(TEST_OBJ_DIR) "/libvpi.so";
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user