Add a mark at simulation end for vcd/lxt/lxt2 files.
This patch adds marks at simulation end if needed and enabled (on and not over the limit) for vcd/lxt/lxt2 files. End of simulation callbacks also now have the correct simulation time. The default file names for lxt and lxt2 now match the vcd file except for the extension. lx2 is also an alias for lxt2 and the default lxt2 file extension is lx2. This matches what GTKWave expects. Any lxt2 diagnostic output print LXT2 instead of LXT to make it clear which dumper you are using.
This commit is contained in:
parent
d6f6df829e
commit
17960013e5
|
|
@ -157,6 +157,7 @@ static PLI_UINT64 vcd_cur_time = 0;
|
||||||
static int dump_is_off = 0;
|
static int dump_is_off = 0;
|
||||||
static long dump_limit = 0;
|
static long dump_limit = 0;
|
||||||
static int dump_is_full = 0;
|
static int dump_is_full = 0;
|
||||||
|
static int finish_status = 0;
|
||||||
|
|
||||||
|
|
||||||
static void show_this_item(struct vcd_info*info)
|
static void show_this_item(struct vcd_info*info)
|
||||||
|
|
@ -291,6 +292,22 @@ static PLI_INT32 dumpvars_cb(p_cb_data cause)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PLI_INT32 finish_cb(p_cb_data cause)
|
||||||
|
{
|
||||||
|
if (finish_status != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
finish_status = 1;
|
||||||
|
|
||||||
|
dumpvars_time = timerec_to_time64(cause->time);
|
||||||
|
|
||||||
|
if (!dump_is_off && !dump_is_full && dumpvars_time != vcd_cur_time) {
|
||||||
|
lt_set_time64(dump_file, dumpvars_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
inline static int install_dumpvars_callback(void)
|
inline static int install_dumpvars_callback(void)
|
||||||
{
|
{
|
||||||
struct t_cb_data cb;
|
struct t_cb_data cb;
|
||||||
|
|
@ -316,6 +333,11 @@ inline static int install_dumpvars_callback(void)
|
||||||
|
|
||||||
vpi_register_cb(&cb);
|
vpi_register_cb(&cb);
|
||||||
|
|
||||||
|
cb.reason = cbEndOfSimulation;
|
||||||
|
cb.cb_rtn = finish_cb;
|
||||||
|
|
||||||
|
vpi_register_cb(&cb);
|
||||||
|
|
||||||
dumpvars_status = 1;
|
dumpvars_status = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -463,7 +485,7 @@ static PLI_INT32 sys_dumpfile_calltf(PLI_BYTE8*name)
|
||||||
vpi_free_object(argv);
|
vpi_free_object(argv);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
path = strdup("dumpfile.lxt");
|
path = strdup("dump.lxt");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dump_file)
|
if (dump_file)
|
||||||
|
|
@ -743,7 +765,7 @@ static PLI_INT32 sys_dumpvars_calltf(PLI_BYTE8*name)
|
||||||
vpiHandle argv;
|
vpiHandle argv;
|
||||||
|
|
||||||
if (dump_file == 0) {
|
if (dump_file == 0) {
|
||||||
open_dumpfile("dumpfile.lxt");
|
open_dumpfile("dump.lxt");
|
||||||
if (dump_file == 0)
|
if (dump_file == 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,7 @@ static PLI_UINT64 vcd_cur_time = 0;
|
||||||
static int dump_is_off = 0;
|
static int dump_is_off = 0;
|
||||||
static long dump_limit = 0;
|
static long dump_limit = 0;
|
||||||
static int dump_is_full = 0;
|
static int dump_is_full = 0;
|
||||||
|
static int finish_status = 0;
|
||||||
|
|
||||||
|
|
||||||
static void show_this_item(struct vcd_info*info)
|
static void show_this_item(struct vcd_info*info)
|
||||||
|
|
@ -293,6 +294,21 @@ static PLI_INT32 dumpvars_cb(p_cb_data cause)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PLI_INT32 finish_cb(p_cb_data cause)
|
||||||
|
{
|
||||||
|
if (finish_status != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
finish_status = 1;
|
||||||
|
|
||||||
|
dumpvars_time = timerec_to_time64(cause->time);
|
||||||
|
if (!dump_is_off && !dump_is_full && dumpvars_time != vcd_cur_time) {
|
||||||
|
lxt2_wr_set_time64(dump_file, dumpvars_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
inline static int install_dumpvars_callback(void)
|
inline static int install_dumpvars_callback(void)
|
||||||
{
|
{
|
||||||
struct t_cb_data cb;
|
struct t_cb_data cb;
|
||||||
|
|
@ -318,6 +334,11 @@ inline static int install_dumpvars_callback(void)
|
||||||
|
|
||||||
vpi_register_cb(&cb);
|
vpi_register_cb(&cb);
|
||||||
|
|
||||||
|
cb.reason = cbEndOfSimulation;
|
||||||
|
cb.cb_rtn = finish_cb;
|
||||||
|
|
||||||
|
vpi_register_cb(&cb);
|
||||||
|
|
||||||
dumpvars_status = 1;
|
dumpvars_status = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -419,14 +440,14 @@ static void open_dumpfile(const char*path)
|
||||||
|
|
||||||
if (dump_file == 0) {
|
if (dump_file == 0) {
|
||||||
vpi_mcd_printf(1,
|
vpi_mcd_printf(1,
|
||||||
"LXT Error: Unable to open %s for output.\n",
|
"LXT2 Error: Unable to open %s for output.\n",
|
||||||
path);
|
path);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
int prec = vpi_get(vpiTimePrecision, 0);
|
int prec = vpi_get(vpiTimePrecision, 0);
|
||||||
|
|
||||||
vpi_mcd_printf(1,
|
vpi_mcd_printf(1,
|
||||||
"LXT info: dumpfile %s opened for output.\n",
|
"LXT2 info: dumpfile %s opened for output.\n",
|
||||||
path);
|
path);
|
||||||
|
|
||||||
assert(prec >= -15);
|
assert(prec >= -15);
|
||||||
|
|
@ -455,7 +476,7 @@ static PLI_INT32 sys_dumpfile_calltf(PLI_BYTE8*name)
|
||||||
if (vpi_get(vpiType, item) != vpiConstant
|
if (vpi_get(vpiType, item) != vpiConstant
|
||||||
|| vpi_get(vpiConstType, item) != vpiStringConst) {
|
|| vpi_get(vpiConstType, item) != vpiStringConst) {
|
||||||
vpi_mcd_printf(1,
|
vpi_mcd_printf(1,
|
||||||
"LXT Error:"
|
"LXT2 Error:"
|
||||||
" %s parameter must be a string constant\n",
|
" %s parameter must be a string constant\n",
|
||||||
name);
|
name);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -468,7 +489,7 @@ static PLI_INT32 sys_dumpfile_calltf(PLI_BYTE8*name)
|
||||||
vpi_free_object(argv);
|
vpi_free_object(argv);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
path = strdup("dumpfile.lxt");
|
path = strdup("dump.lx2");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dump_file)
|
if (dump_file)
|
||||||
|
|
@ -686,7 +707,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
vpi_mcd_printf(1,
|
vpi_mcd_printf(1,
|
||||||
"LXT info:"
|
"LXT2 info:"
|
||||||
" scanning scope %s, %u levels\n",
|
" scanning scope %s, %u levels\n",
|
||||||
fullname, depth);
|
fullname, depth);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -696,7 +717,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
||||||
vcd_names_add(&lxt_tab, fullname);
|
vcd_names_add(&lxt_tab, fullname);
|
||||||
else
|
else
|
||||||
vpi_mcd_printf(1,
|
vpi_mcd_printf(1,
|
||||||
"LXT warning:"
|
"LXT2 warning:"
|
||||||
" ignoring signals"
|
" ignoring signals"
|
||||||
" in previously scanned scope %s\n",
|
" in previously scanned scope %s\n",
|
||||||
fullname);
|
fullname);
|
||||||
|
|
@ -719,7 +740,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
vpi_mcd_printf(1,
|
vpi_mcd_printf(1,
|
||||||
"LXT Error: $lxtdumpvars: Unsupported parameter "
|
"LXT2 Error: $lxtdumpvars: Unsupported parameter "
|
||||||
"type (%d)\n", vpi_get(vpiType, item));
|
"type (%d)\n", vpi_get(vpiType, item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -760,7 +781,7 @@ static PLI_INT32 sys_dumpvars_calltf(PLI_BYTE8*name)
|
||||||
vpiHandle argv;
|
vpiHandle argv;
|
||||||
|
|
||||||
if (dump_file == 0) {
|
if (dump_file == 0) {
|
||||||
open_dumpfile("dumpfile.lxt");
|
open_dumpfile("dump.lx2");
|
||||||
if (dump_file == 0)
|
if (dump_file == 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,18 @@ static void sys_lxt_or_vcd_register()
|
||||||
} else if (strcmp(vlog_info.argv[idx],"-lxt2-none") == 0) {
|
} else if (strcmp(vlog_info.argv[idx],"-lxt2-none") == 0) {
|
||||||
dumper = "none";
|
dumper = "none";
|
||||||
|
|
||||||
|
} else if (strcmp(vlog_info.argv[idx],"-lx2") == 0) {
|
||||||
|
dumper = "lxt2";
|
||||||
|
|
||||||
|
} else if (strcmp(vlog_info.argv[idx],"-lx2-space") == 0) {
|
||||||
|
dumper = "lxt2";
|
||||||
|
|
||||||
|
} else if (strcmp(vlog_info.argv[idx],"-lx2-speed") == 0) {
|
||||||
|
dumper = "lxt2";
|
||||||
|
|
||||||
|
} else if (strcmp(vlog_info.argv[idx],"-lx2-none") == 0) {
|
||||||
|
dumper = "none";
|
||||||
|
|
||||||
} else if (strcmp(vlog_info.argv[idx],"-vcd") == 0) {
|
} else if (strcmp(vlog_info.argv[idx],"-vcd") == 0) {
|
||||||
dumper = "vcd";
|
dumper = "vcd";
|
||||||
|
|
||||||
|
|
@ -132,6 +144,12 @@ static void sys_lxt_or_vcd_register()
|
||||||
else if (strcmp(dumper, "LXT2") == 0)
|
else if (strcmp(dumper, "LXT2") == 0)
|
||||||
sys_lxt2_register();
|
sys_lxt2_register();
|
||||||
|
|
||||||
|
else if (strcmp(dumper, "lx2") == 0)
|
||||||
|
sys_lxt2_register();
|
||||||
|
|
||||||
|
else if (strcmp(dumper, "LX2") == 0)
|
||||||
|
sys_lxt2_register();
|
||||||
|
|
||||||
else if (strcmp(dumper, "none") == 0)
|
else if (strcmp(dumper, "none") == 0)
|
||||||
sys_vcdoff_register();
|
sys_vcdoff_register();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ PLI_UINT64 vcd_cur_time = 0;
|
||||||
static int dump_is_off = 0;
|
static int dump_is_off = 0;
|
||||||
static long dump_limit = 0;
|
static long dump_limit = 0;
|
||||||
static int dump_is_full = 0;
|
static int dump_is_full = 0;
|
||||||
|
static int finish_status = 0;
|
||||||
|
|
||||||
static char *truncate_bitvec(char *s)
|
static char *truncate_bitvec(char *s)
|
||||||
{
|
{
|
||||||
|
|
@ -251,6 +252,22 @@ static PLI_INT32 dumpvars_cb(p_cb_data cause)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PLI_INT32 finish_cb(p_cb_data cause)
|
||||||
|
{
|
||||||
|
if (finish_status != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
finish_status = 1;
|
||||||
|
|
||||||
|
dumpvars_time = timerec_to_time64(cause->time);
|
||||||
|
|
||||||
|
if (!dump_is_off && !dump_is_full && dumpvars_time != vcd_cur_time) {
|
||||||
|
fprintf(dump_file, "#%" PLI_UINT64_FMT "\n", dumpvars_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
inline static int install_dumpvars_callback(void)
|
inline static int install_dumpvars_callback(void)
|
||||||
{
|
{
|
||||||
struct t_cb_data cb;
|
struct t_cb_data cb;
|
||||||
|
|
@ -276,6 +293,11 @@ inline static int install_dumpvars_callback(void)
|
||||||
|
|
||||||
vpi_register_cb(&cb);
|
vpi_register_cb(&cb);
|
||||||
|
|
||||||
|
cb.reason = cbEndOfSimulation;
|
||||||
|
cb.cb_rtn = finish_cb;
|
||||||
|
|
||||||
|
vpi_register_cb(&cb);
|
||||||
|
|
||||||
dumpvars_status = 1;
|
dumpvars_status = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -338,6 +338,7 @@ void vpiPostsim(void) {
|
||||||
while (EndOfSimulation) {
|
while (EndOfSimulation) {
|
||||||
cur = EndOfSimulation;
|
cur = EndOfSimulation;
|
||||||
EndOfSimulation = cur->next;
|
EndOfSimulation = cur->next;
|
||||||
|
vpip_time_to_timestruct(cur->cb_data.time, schedule_simtime());
|
||||||
(cur->cb_data.cb_rtn)(&cur->cb_data);
|
(cur->cb_data.cb_rtn)(&cur->cb_data);
|
||||||
delete_vpi_callback(cur);
|
delete_vpi_callback(cur);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ The \fB-lxt-none\fP variant actually suppresses all waveform
|
||||||
output. This can make long simulations run faster.
|
output. This can make long simulations run faster.
|
||||||
|
|
||||||
.TP 8
|
.TP 8
|
||||||
.B -lxt2
|
.B -lxt2\fR|\fP-lx2
|
||||||
The LXT2 format is slower then LXT (faster then VCD) but takes less
|
The LXT2 format is slower then LXT (faster then VCD) but takes less
|
||||||
space, and is written out incrementally. Thus, you can view lxt2 files
|
space, and is written out incrementally. Thus, you can view lxt2 files
|
||||||
while a simulation is still running (or paused) or if your simulation
|
while a simulation is still running (or paused) or if your simulation
|
||||||
|
|
@ -102,7 +102,7 @@ The vvp command also accepts some environment variables that control
|
||||||
its behavior. These can be used to make semi-permanent changes.
|
its behavior. These can be used to make semi-permanent changes.
|
||||||
|
|
||||||
.TP 8
|
.TP 8
|
||||||
.B IVERILOG_DUMPER=\fIlxt|lxt2|vcd|none\fP
|
.B IVERILOG_DUMPER=\fIlxt|lxt2|lx2|vcd|none\fP
|
||||||
This selects the output format for the waveform output. Normally,
|
This selects the output format for the waveform output. Normally,
|
||||||
waveforms are dumped in vcd format, but this variable can be used to
|
waveforms are dumped in vcd format, but this variable can be used to
|
||||||
select lxt format, which is far more compact, though limited to
|
select lxt format, which is far more compact, though limited to
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue