From 17960013e50f6f9177c8c13ffef4222739ca1e6d Mon Sep 17 00:00:00 2001 From: Cary R Date: Thu, 8 Nov 2007 15:56:10 -0800 Subject: [PATCH] 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. --- vpi/sys_lxt.c | 26 ++++++++++++++++++++++++-- vpi/sys_lxt2.c | 37 +++++++++++++++++++++++++++++-------- vpi/sys_table.c | 18 ++++++++++++++++++ vpi/sys_vcd.c | 22 ++++++++++++++++++++++ vvp/vpi_callback.cc | 1 + vvp/vvp.man | 4 ++-- 6 files changed, 96 insertions(+), 12 deletions(-) diff --git a/vpi/sys_lxt.c b/vpi/sys_lxt.c index 7f747c43c..ad4b38a7e 100644 --- a/vpi/sys_lxt.c +++ b/vpi/sys_lxt.c @@ -157,6 +157,7 @@ static PLI_UINT64 vcd_cur_time = 0; static int dump_is_off = 0; static long dump_limit = 0; static int dump_is_full = 0; +static int finish_status = 0; static void show_this_item(struct vcd_info*info) @@ -291,6 +292,22 @@ static PLI_INT32 dumpvars_cb(p_cb_data cause) 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) { struct t_cb_data cb; @@ -316,6 +333,11 @@ inline static int install_dumpvars_callback(void) vpi_register_cb(&cb); + cb.reason = cbEndOfSimulation; + cb.cb_rtn = finish_cb; + + vpi_register_cb(&cb); + dumpvars_status = 1; return 0; } @@ -463,7 +485,7 @@ static PLI_INT32 sys_dumpfile_calltf(PLI_BYTE8*name) vpi_free_object(argv); } else { - path = strdup("dumpfile.lxt"); + path = strdup("dump.lxt"); } if (dump_file) @@ -743,7 +765,7 @@ static PLI_INT32 sys_dumpvars_calltf(PLI_BYTE8*name) vpiHandle argv; if (dump_file == 0) { - open_dumpfile("dumpfile.lxt"); + open_dumpfile("dump.lxt"); if (dump_file == 0) return 0; } diff --git a/vpi/sys_lxt2.c b/vpi/sys_lxt2.c index 15fe17c60..68c6c6546 100644 --- a/vpi/sys_lxt2.c +++ b/vpi/sys_lxt2.c @@ -158,6 +158,7 @@ static PLI_UINT64 vcd_cur_time = 0; static int dump_is_off = 0; static long dump_limit = 0; static int dump_is_full = 0; +static int finish_status = 0; static void show_this_item(struct vcd_info*info) @@ -293,6 +294,21 @@ static PLI_INT32 dumpvars_cb(p_cb_data cause) 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) { struct t_cb_data cb; @@ -318,6 +334,11 @@ inline static int install_dumpvars_callback(void) vpi_register_cb(&cb); + cb.reason = cbEndOfSimulation; + cb.cb_rtn = finish_cb; + + vpi_register_cb(&cb); + dumpvars_status = 1; return 0; } @@ -419,14 +440,14 @@ static void open_dumpfile(const char*path) if (dump_file == 0) { vpi_mcd_printf(1, - "LXT Error: Unable to open %s for output.\n", + "LXT2 Error: Unable to open %s for output.\n", path); return; } else { int prec = vpi_get(vpiTimePrecision, 0); vpi_mcd_printf(1, - "LXT info: dumpfile %s opened for output.\n", + "LXT2 info: dumpfile %s opened for output.\n", path); assert(prec >= -15); @@ -455,7 +476,7 @@ static PLI_INT32 sys_dumpfile_calltf(PLI_BYTE8*name) if (vpi_get(vpiType, item) != vpiConstant || vpi_get(vpiConstType, item) != vpiStringConst) { vpi_mcd_printf(1, - "LXT Error:" + "LXT2 Error:" " %s parameter must be a string constant\n", name); return 0; @@ -468,7 +489,7 @@ static PLI_INT32 sys_dumpfile_calltf(PLI_BYTE8*name) vpi_free_object(argv); } else { - path = strdup("dumpfile.lxt"); + path = strdup("dump.lx2"); } if (dump_file) @@ -686,7 +707,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip) #if 0 vpi_mcd_printf(1, - "LXT info:" + "LXT2 info:" " scanning scope %s, %u levels\n", fullname, depth); #endif @@ -696,7 +717,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip) vcd_names_add(&lxt_tab, fullname); else vpi_mcd_printf(1, - "LXT warning:" + "LXT2 warning:" " ignoring signals" " in previously scanned scope %s\n", fullname); @@ -719,7 +740,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip) default: vpi_mcd_printf(1, - "LXT Error: $lxtdumpvars: Unsupported parameter " + "LXT2 Error: $lxtdumpvars: Unsupported parameter " "type (%d)\n", vpi_get(vpiType, item)); } @@ -760,7 +781,7 @@ static PLI_INT32 sys_dumpvars_calltf(PLI_BYTE8*name) vpiHandle argv; if (dump_file == 0) { - open_dumpfile("dumpfile.lxt"); + open_dumpfile("dump.lx2"); if (dump_file == 0) return 0; } diff --git a/vpi/sys_table.c b/vpi/sys_table.c index 322113733..ceb7e0033 100644 --- a/vpi/sys_table.c +++ b/vpi/sys_table.c @@ -102,6 +102,18 @@ static void sys_lxt_or_vcd_register() } else if (strcmp(vlog_info.argv[idx],"-lxt2-none") == 0) { 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) { dumper = "vcd"; @@ -132,6 +144,12 @@ static void sys_lxt_or_vcd_register() else if (strcmp(dumper, "LXT2") == 0) 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) sys_vcdoff_register(); diff --git a/vpi/sys_vcd.c b/vpi/sys_vcd.c index d965a1f67..6430c8b94 100644 --- a/vpi/sys_vcd.c +++ b/vpi/sys_vcd.c @@ -85,6 +85,7 @@ PLI_UINT64 vcd_cur_time = 0; static int dump_is_off = 0; static long dump_limit = 0; static int dump_is_full = 0; +static int finish_status = 0; static char *truncate_bitvec(char *s) { @@ -251,6 +252,22 @@ static PLI_INT32 dumpvars_cb(p_cb_data cause) 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) { struct t_cb_data cb; @@ -276,6 +293,11 @@ inline static int install_dumpvars_callback(void) vpi_register_cb(&cb); + cb.reason = cbEndOfSimulation; + cb.cb_rtn = finish_cb; + + vpi_register_cb(&cb); + dumpvars_status = 1; return 0; } diff --git a/vvp/vpi_callback.cc b/vvp/vpi_callback.cc index 7f7dccbd7..aadcebf37 100644 --- a/vvp/vpi_callback.cc +++ b/vvp/vpi_callback.cc @@ -338,6 +338,7 @@ void vpiPostsim(void) { while (EndOfSimulation) { cur = EndOfSimulation; EndOfSimulation = cur->next; + vpip_time_to_timestruct(cur->cb_data.time, schedule_simtime()); (cur->cb_data.cb_rtn)(&cur->cb_data); delete_vpi_callback(cur); } diff --git a/vvp/vvp.man b/vvp/vvp.man index 940ee9f1f..3ad520cd5 100644 --- a/vvp/vvp.man +++ b/vvp/vvp.man @@ -90,7 +90,7 @@ The \fB-lxt-none\fP variant actually suppresses all waveform output. This can make long simulations run faster. .TP 8 -.B -lxt2 +.B -lxt2\fR|\fP-lx2 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 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. .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, waveforms are dumped in vcd format, but this variable can be used to select lxt format, which is far more compact, though limited to