diff --git a/src/V3LanguageWords.h b/src/V3LanguageWords.h index a11a6a222..907095605 100644 --- a/src/V3LanguageWords.h +++ b/src/V3LanguageWords.h @@ -48,7 +48,7 @@ public: private: static Singleton& s() { - static Singleton s_s; + static Singleton s_s; // LCOV_EXCL_BR_LINE return s_s; } }; diff --git a/src/V3PreLex.l b/src/V3PreLex.l index d706fc07c..aa331c629 100644 --- a/src/V3PreLex.l +++ b/src/V3PreLex.l @@ -595,11 +595,11 @@ string V3PreLex::cleanDbgStrg(const string& in) { } void V3PreLex::unused() { - if (0) { + if (VL_UNCOVERABLE(false)) { // LCOV_EXCL_START // Prevent unused warnings yy_top_state(); yyerror((char*)""); - } + } // LCOV_EXCL_STOP } /*################################################################### diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 39d51bb70..16fd4c94e 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -549,9 +549,9 @@ static void verilate(const string& argString) { } // Undocumented debugging - cannot be a switch as then command line // would mismatch forcing non-identicalness when we set it - if (!V3Os::getenvStr("VERILATOR_DEBUG_SKIP_IDENTICAL", "").empty()) { + if (!V3Os::getenvStr("VERILATOR_DEBUG_SKIP_IDENTICAL", "").empty()) { // LCOV_EXCL_START v3fatalSrc("VERILATOR_DEBUG_SKIP_IDENTICAL w/ --skip-identical: Changes found\n"); - } + } // LCOV_EXCL_STOP //--FRONTEND------------------ diff --git a/test_regress/t/t_cover_lib.pl b/test_regress/t/t_cover_lib.pl new file mode 100755 index 000000000..9d7305ac5 --- /dev/null +++ b/test_regress/t/t_cover_lib.pl @@ -0,0 +1,31 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(vlt => 1); + +compile( + v_flags2 => ["--coverage t/t_cover_lib_c.cpp"], + verilator_flags2 => ["--exe -Wall -Wno-DECLFILENAME"], + make_flags => 'CPPFLAGS_ADD=-DTEST_OBJ_DIR="'.$Self->{obj_dir}.'"', + make_top_shell => 0, + make_main => 0, + ); + +execute( + check_finished => 1, + ); + +files_identical_sorted("$Self->{obj_dir}/coverage1.dat", "t/t_cover_lib_1.out"); +files_identical_sorted("$Self->{obj_dir}/coverage2.dat", "t/t_cover_lib_2.out"); +files_identical_sorted("$Self->{obj_dir}/coverage3.dat", "t/t_cover_lib_3.out"); +files_identical_sorted("$Self->{obj_dir}/coverage4.dat", "t/t_cover_lib_4.out"); + +ok(1); +1; diff --git a/test_regress/t/t_cover_lib.v b/test_regress/t/t_cover_lib.v new file mode 100644 index 000000000..1d95829b9 --- /dev/null +++ b/test_regress/t/t_cover_lib.v @@ -0,0 +1,10 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2017 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. +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +module t (/*AUTOARG*/); +endmodule diff --git a/test_regress/t/t_cover_lib_1.out b/test_regress/t/t_cover_lib_1.out new file mode 100644 index 000000000..d757bf25a --- /dev/null +++ b/test_regress/t/t_cover_lib_1.out @@ -0,0 +1,4 @@ +# SystemC::Coverage-3 +C 'f../../t/t_cover_lib_c.cppl44pagesp_user/t_cover_lib_cokept_onehmain' 100 +C 'f../../t/t_cover_lib_c.cppl45pagesp_user/t_cover_lib_cokept_twohmain' 210 +C 'f../../t/t_cover_lib_c.cppl46pagesp_user/t_cover_lib_colost_threehmain' 220 diff --git a/test_regress/t/t_cover_lib_2.out b/test_regress/t/t_cover_lib_2.out new file mode 100644 index 000000000..42ec9a18e --- /dev/null +++ b/test_regress/t/t_cover_lib_2.out @@ -0,0 +1,3 @@ +# SystemC::Coverage-3 +C 'f../../t/t_cover_lib_c.cppl44pagesp_user/t_cover_lib_cokept_onehmain' 100 +C 'f../../t/t_cover_lib_c.cppl45pagesp_user/t_cover_lib_cokept_twohmain' 210 diff --git a/test_regress/t/t_cover_lib_3.out b/test_regress/t/t_cover_lib_3.out new file mode 100644 index 000000000..78bddf206 --- /dev/null +++ b/test_regress/t/t_cover_lib_3.out @@ -0,0 +1,3 @@ +# SystemC::Coverage-3 +C 'f../../t/t_cover_lib_c.cppl44pagesp_user/t_cover_lib_cokept_onehmain' 0 +C 'f../../t/t_cover_lib_c.cppl45pagesp_user/t_cover_lib_cokept_twohmain' 0 diff --git a/test_regress/t/t_cover_lib_4.out b/test_regress/t/t_cover_lib_4.out new file mode 100644 index 000000000..8b8f255e5 --- /dev/null +++ b/test_regress/t/t_cover_lib_4.out @@ -0,0 +1 @@ +# SystemC::Coverage-3 diff --git a/test_regress/t/t_cover_lib_c.cpp b/test_regress/t/t_cover_lib_c.cpp new file mode 100644 index 000000000..8b288fad9 --- /dev/null +++ b/test_regress/t/t_cover_lib_c.cpp @@ -0,0 +1,62 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// +// Copyright 2009-2017 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. +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 +// +//************************************************************************* + +#include +#include +#include +#include "svdpi.h" + +#include "verilated_cov.h" + +#include VM_PREFIX_INCLUDE + +double sc_time_stamp() { return 0; } + +//====================================================================== + +int failure = 0; + +#define CHECK_RESULT_HEX(got, exp) \ + do { \ + if ((got) != (exp)) { \ + std::cout << std::dec << "%Error: " << __FILE__ << ":" << __LINE__ << std::hex \ + << ": GOT=" << (got) << " EXP=" << (exp) << std::endl; \ + failure = __LINE__; \ + } \ + } while (0) + +//====================================================================== + +const char* name() { return "main"; } + +int main() { + vluint32_t covers[1]; + vluint64_t coverw[2]; + + VL_COVER_INSERT(&covers[0], "comment", "kept_one"); + VL_COVER_INSERT(&coverw[0], "comment", "kept_two"); + VL_COVER_INSERT(&coverw[1], "comment", "lost_three"); + + covers[0] = 100; + coverw[0] = 210; + coverw[1] = 220; + + VerilatedCov::write(VL_STRINGIFY(TEST_OBJ_DIR) "/coverage1.dat"); + VerilatedCov::clearNonMatch("kept_"); + VerilatedCov::write(VL_STRINGIFY(TEST_OBJ_DIR) "/coverage2.dat"); + VerilatedCov::zero(); + VerilatedCov::write(VL_STRINGIFY(TEST_OBJ_DIR) "/coverage3.dat"); + VerilatedCov::clear(); + VerilatedCov::write(VL_STRINGIFY(TEST_OBJ_DIR) "/coverage4.dat"); + + printf("*-* All Finished *-*\n"); + exit(failure ? 10 : 0); +} diff --git a/test_regress/t/t_debug_emitv.out b/test_regress/t/t_debug_emitv.out index 39df56002..72286aad6 100644 --- a/test_regress/t/t_debug_emitv.out +++ b/test_regress/t/t_debug_emitv.out @@ -78,6 +78,8 @@ module Vt_debug_emitv; end t.sum = __Vfunc_t.sub.f__3__Vfuncout; $display("[%0t] sum = %~", $timet.sum, t.sum); + $display("a?= $d%d", ($c(32'sh1) ? $c(32'sh14) + : $c(32'sh1e))); $c(;); $display("%d", $c(0)); $fopen(72'h2f6465762f6e756c6c); @@ -165,7 +167,9 @@ module Vt_debug_emitv; t.str = $sformatf("cyc=%~", t.cyc); ; $display("str = %@", t.str); - $display("[%t] [%^]", $time$realtime, $realtime); + $display("%% [%t] [%^] to=%o td=%d", $time$realtime + $time$time, $realtime$time$time, $time + $time, $time); $sscanf(40'h666f6f3d35, "foo=%d", t.i); ; if ((32'sh5 != t.i)) begin diff --git a/test_regress/t/t_debug_emitv.v b/test_regress/t/t_debug_emitv.v index 67aa6bca8..d1ae29ee0 100644 --- a/test_regress/t/t_debug_emitv.v +++ b/test_regress/t/t_debug_emitv.v @@ -87,6 +87,7 @@ module t (/*AUTOARG*/ sub.inc(fo, sum); sum = sub.f(sum); $display("[%0t] sum = %d", $time, sum); + $display("a?= $d", $c(1) ? $c32(20) : $c32(30)); $c(";"); $display("%d", $c("0")); @@ -136,7 +137,7 @@ module t (/*AUTOARG*/ str = $sformatf("cyc=%d", cyc); $display("str = %s", str); - $display("[%t] [%t]", $time, $realtime); + $display("%% [%t] [%t] to=%o td=%d", $time, $realtime, $time, $time); $sscanf("foo=5", "foo=%d", i); if (i != 5) $stop; end diff --git a/test_regress/t/t_dpi_context_c.cpp b/test_regress/t/t_dpi_context_c.cpp index 3204c9bea..1447ab083 100644 --- a/test_regress/t/t_dpi_context_c.cpp +++ b/test_regress/t/t_dpi_context_c.cpp @@ -74,6 +74,7 @@ int dpic_line() { printf("%%Warning: svGetCallerInfo failed\n"); return 0; } + if (svGetCallerInfo(nullptr, nullptr)) {} // Check doesn't segflt return lineno; } diff --git a/test_regress/t/t_dpi_export_context2_bad.cpp b/test_regress/t/t_dpi_export_context2_bad.cpp index b71f678d7..77ce4668c 100644 --- a/test_regress/t/t_dpi_export_context2_bad.cpp +++ b/test_regress/t/t_dpi_export_context2_bad.cpp @@ -30,6 +30,15 @@ int main(int argc, char* argv[]) { return 1; } int dpii_task() { + + // Check DPI warnings + svScope scope = svGetScope(); // Will warn + if (scope) {} // Unused + const char* filenamep = ""; + int lineno = 0; + svGetCallerInfo(&filenamep, &lineno); // Will warn + if (filenamep && lineno) {} // Unused + dpix_task(); return 0; } diff --git a/test_regress/t/t_dpi_export_context2_bad.out b/test_regress/t/t_dpi_export_context2_bad.out index dc2091af3..c01b0dec6 100644 --- a/test_regress/t/t_dpi_export_context2_bad.out +++ b/test_regress/t/t_dpi_export_context2_bad.out @@ -1,2 +1,4 @@ +%Warning: DPI C Function called by Verilog DPI import with missing 'context' keyword. +%Warning: DPI C Function called by Verilog DPI import with missing 'context' keyword. %Error: unknown:0: Testbench C called 'dpix_task' but scope wasn't set, perhaps due to dpi import call without 'context', or missing svSetScope. See IEEE 1800-2017 35.5.3. Aborting... diff --git a/test_regress/t/t_dpi_import_c.cpp b/test_regress/t/t_dpi_import_c.cpp index ebcbedef1..5a174cd67 100644 --- a/test_regress/t/t_dpi_import_c.cpp +++ b/test_regress/t/t_dpi_import_c.cpp @@ -189,7 +189,9 @@ int dpii_t_void() { return svIsDisabledState(); } int dpii_t_void_context() { return svIsDisabledState(); } int dpii_t_int(int i, int* o) { *o = i; - return svIsDisabledState(); // Tasks generally need this + bool disabled = svIsDisabledState(); // Tasks generally need this + svAckDisabledState(); + return disabled; } #endif diff --git a/test_regress/t/t_dpi_lib_c.cpp b/test_regress/t/t_dpi_lib_c.cpp index bb214c594..b800b17fc 100644 --- a/test_regress/t/t_dpi_lib_c.cpp +++ b/test_regress/t/t_dpi_lib_c.cpp @@ -74,14 +74,32 @@ void dpii_lib_bit_check() { CHECK_RESULT_HEX(bv[1], 0xa7a6a5ad); CHECK_RESULT_HEX(bv[2], 0xabaaa9a8); - svBitVecVal btmp[1]; + svBitVecVal btmp[2]; svGetPartselBit(btmp, bv, 40, 8); CHECK_RESULT_HEX(btmp[0], 0xa5); + svGetPartselBit(btmp, bv, 32, 32); + CHECK_RESULT_HEX(btmp[0], 0xa7a6a5ad); + svGetPartselBit(btmp, bv, 48, 40); + CHECK_RESULT_HEX(btmp[0], 0xa9a8a7a6); + CHECK_RESULT_HEX(btmp[1], 0xaa); + btmp[0] = 0xa5; svPutPartselBit(bv, btmp[0], 48, 8); CHECK_RESULT_HEX(bv[0], 0xa3a2a1a0); CHECK_RESULT_HEX(bv[1], 0xa7a5a5ad); CHECK_RESULT_HEX(bv[2], 0xabaaa9a8); + + btmp[0] = 0x11223344; + svPutPartselBit(bv, btmp[0], 32, 32); + CHECK_RESULT_HEX(bv[0], 0xa3a2a1a0); + CHECK_RESULT_HEX(bv[1], 0x11223344); + CHECK_RESULT_HEX(bv[2], 0xabaaa9a8); + + btmp[0] = 0x99887766; + svPutPartselBit(bv, btmp[0], 24, 24); + CHECK_RESULT_HEX(bv[0], 0x66a2a1a0); + CHECK_RESULT_HEX(bv[1], 0x11228877); + CHECK_RESULT_HEX(bv[2], 0xabaaa9a8); } void dpii_lib_logic_check() { @@ -112,11 +130,21 @@ void dpii_lib_logic_check() { CHECK_RESULT_HEX(lv[1].bval, 0xc7c6c5c8); CHECK_RESULT_HEX(lv[2].bval, 0xcbcac9c8); - svLogicVecVal ltmp[1]; + svLogicVecVal ltmp[2]; svGetPartselLogic(ltmp, lv, 40, 8); CHECK_RESULT_HEX(ltmp[0].aval, 0xb5); CHECK_RESULT_HEX(ltmp[0].bval, 0xc5); + svGetPartselLogic(ltmp, lv, 32, 32); + CHECK_RESULT_HEX(ltmp[0].aval, 0xb7b6b5bd); + CHECK_RESULT_HEX(ltmp[0].bval, 0xc7c6c5c8); + svGetPartselLogic(ltmp, lv, 48, 40); + CHECK_RESULT_HEX(ltmp[0].aval, 0xb9b8b7b6); + CHECK_RESULT_HEX(ltmp[0].bval, 0xc9c8c7c6); + CHECK_RESULT_HEX(ltmp[1].aval, 0xba); + CHECK_RESULT_HEX(ltmp[1].bval, 0xca); + ltmp[0].aval = 0xb5; + ltmp[0].bval = 0xc5; svPutPartselLogic(lv, ltmp[0], 48, 8); CHECK_RESULT_HEX(lv[0].aval, 0xb3b2b1b0); CHECK_RESULT_HEX(lv[1].aval, 0xb7b5b5bd); @@ -124,6 +152,26 @@ void dpii_lib_logic_check() { CHECK_RESULT_HEX(lv[0].bval, 0xc3c2c1c0); CHECK_RESULT_HEX(lv[1].bval, 0xc7c5c5c8); CHECK_RESULT_HEX(lv[2].bval, 0xcbcac9c8); + + ltmp[0].aval = 0x11223344; + ltmp[0].bval = 0x81828384; + svPutPartselLogic(lv, ltmp[0], 32, 32); + CHECK_RESULT_HEX(lv[0].aval, 0xb3b2b1b0); + CHECK_RESULT_HEX(lv[1].aval, 0x11223344); + CHECK_RESULT_HEX(lv[2].aval, 0xbbbab9b8); + CHECK_RESULT_HEX(lv[0].bval, 0xc3c2c1c0); + CHECK_RESULT_HEX(lv[1].bval, 0x81828384); + CHECK_RESULT_HEX(lv[2].bval, 0xcbcac9c8); + + ltmp[0].aval = 0x99887766; + ltmp[0].bval = 0x89888786; + svPutPartselLogic(lv, ltmp[0], 24, 24); + CHECK_RESULT_HEX(lv[0].aval, 0x66b2b1b0); + CHECK_RESULT_HEX(lv[1].aval, 0x11228877); + CHECK_RESULT_HEX(lv[2].aval, 0xbbbab9b8); + CHECK_RESULT_HEX(lv[0].bval, 0x86c2c1c0); + CHECK_RESULT_HEX(lv[1].bval, 0x81828887); + CHECK_RESULT_HEX(lv[2].bval, 0xcbcac9c8); } //====================================================================== diff --git a/test_regress/t/t_vlcov_debugi.pl b/test_regress/t/t_vlcov_debugi.pl index 8cc5f0d57..71b7b030c 100755 --- a/test_regress/t/t_vlcov_debugi.pl +++ b/test_regress/t/t_vlcov_debugi.pl @@ -17,6 +17,7 @@ foreach my $basename ("t_vlcov_data_a.dat", ) { run(cmd => ["../bin/verilator_coverage", "t/${basename}", + "--debug", "--debugi 9", ], tee => $Self->{verbose}, diff --git a/test_regress/t/t_vlcov_merge.pl b/test_regress/t/t_vlcov_merge.pl index cfac15b48..bf62addf8 100755 --- a/test_regress/t/t_vlcov_merge.pl +++ b/test_regress/t/t_vlcov_merge.pl @@ -11,6 +11,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(dist => 1); run(cmd => ["../bin/verilator_coverage", + "--no-unlink", "--nounlink", "--write", "$Self->{obj_dir}/coverage.dat", "t/t_vlcov_data_a.dat", "t/t_vlcov_data_b.dat", @@ -20,6 +21,10 @@ run(cmd => ["../bin/verilator_coverage", verilator_run => 1, ); +# Not deleted e.g. parsed --no-unlink properly +files_identical("$Self->{t_dir}/t_vlcov_data_a.dat", + "$Self->{t_dir}/t_vlcov_data_a.dat"); + # Older clib's didn't properly sort maps, but the coverage data doesn't # really care about ordering. So avoid false failures by sorting. files_identical_sorted("$Self->{obj_dir}/coverage.dat", $Self->{golden_filename}); diff --git a/test_regress/t/t_vlcov_unlink.pl b/test_regress/t/t_vlcov_unlink.pl new file mode 100755 index 000000000..51b2e7d0c --- /dev/null +++ b/test_regress/t/t_vlcov_unlink.pl @@ -0,0 +1,32 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003-2009 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. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +use File::Copy; + +scenarios(dist => 1); + +my $tmp = "$Self->{obj_dir}/copied.dat"; +File::Copy::copy("$Self->{t_dir}/t_vlcov_data_a.dat", $tmp); + +run(cmd => ["../bin/verilator_coverage", + "--unlink", + $tmp, + "--write", "$Self->{obj_dir}/output.dat"], + verilator_run => 1, + ); + +files_identical("$Self->{obj_dir}/output.dat", "t/t_vlcov_data_a.dat"); + +# --unlink should have removed it +!-r $tmp or error("Not unlinked"); + +ok(1); + +1; diff --git a/test_regress/t/t_vpi_var.cpp b/test_regress/t/t_vpi_var.cpp index 0b067dab6..205345bde 100644 --- a/test_regress/t/t_vpi_var.cpp +++ b/test_regress/t/t_vpi_var.cpp @@ -106,9 +106,15 @@ int _mon_check_mcd() { status = vpi_mcd_printf(mcd, (PLI_BYTE8*)"hello %s", "vpi_mcd_printf"); CHECK_RESULT(status, strlen("hello vpi_mcd_printf")); + status = vpi_mcd_printf(0, (PLI_BYTE8*)"empty"); + CHECK_RESULT(status, 0); + status = vpi_mcd_flush(mcd); CHECK_RESULT(status, 0); + status = vpi_mcd_flush(0); + CHECK_RESULT(status, 1); + status = vpi_mcd_close(mcd); // Icarus says 'error' on ones we're not using, so check only used ones return 0. CHECK_RESULT(status & mcd, 0); @@ -421,6 +427,8 @@ int _mon_check_string() { vpi_get_value(vh1, &v); if (vpi_chk_error(&e)) { printf("%%vpi_chk_error : %s\n", e.message); } + (void)vpi_chk_error(nullptr); + CHECK_RESULT_CSTR_STRIP(v.value.str, text_test_obs[i].initial); v.value.str = (PLI_BYTE8*)text_test_obs[i].value;