diff --git a/include/verilated.cpp b/include/verilated.cpp index 62592476e..cf9a8e909 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -312,7 +312,8 @@ vluint64_t vl_rand64() VL_MT_SAFE { IData VL_RANDOM_I(int obits) VL_MT_SAFE { return vl_rand64() & VL_MASK_I(obits); } QData VL_RANDOM_Q(int obits) VL_MT_SAFE { return vl_rand64() & VL_MASK_Q(obits); } -// VL_RANDOM_W currently unused as $random always 32 bits +// VL_RANDOM_W currently unused as $random always 32 bits, left for backwards compatibility +// LCOV_EXCL_START WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp) VL_MT_SAFE { for (int i = 0; i < VL_WORDS_I(obits); ++i) { if (i < (VL_WORDS_I(obits) - 1)) { @@ -323,6 +324,7 @@ WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp) VL_MT_SAFE { } return outwp; } +// LCOV_EXCL_STOP IData VL_RAND_RESET_I(int obits) VL_MT_SAFE { if (Verilated::randReset() == 0) return 0; diff --git a/include/verilated_cov.cpp b/include/verilated_cov.cpp index 6ca5c8e25..4de2dffb1 100644 --- a/include/verilated_cov.cpp +++ b/include/verilated_cov.cpp @@ -332,10 +332,10 @@ public: m_insertp->m_keys[addKeynum] = valueIndex(key); m_insertp->m_vals[addKeynum] = valueIndex(val); addKeynum++; - if (!legalKey(key)) { + if (VL_UNCOVERABLE(!legalKey(key))) { std::string msg = ("%Error: Coverage keys of one character, or letter+digit are illegal: " - + key); + + key); // LCOV_EXCL_LINE VL_FATAL_MT("", 0, "", msg.c_str()); } } diff --git a/include/verilated_vpi.cpp b/include/verilated_vpi.cpp index 1950d9173..ef21e6924 100644 --- a/include/verilated_vpi.cpp +++ b/include/verilated_vpi.cpp @@ -2072,11 +2072,11 @@ PLI_INT32 vpi_control(PLI_INT32 operation, ...) { _VL_VPI_ERROR_RESET(); switch (operation) { case vpiFinish: { - VL_FINISH_MT(__FILE__, __LINE__, "*VPI*"); + VL_FINISH_MT("", 0, "*VPI*"); return 1; } case vpiStop: { - VL_STOP_MT(__FILE__, __LINE__, "*VPI*"); + VL_STOP_MT("", 0, "*VPI*"); return 1; } } diff --git a/src/V3Broken.cpp b/src/V3Broken.cpp index 777b9cf0a..1ea4e179a 100644 --- a/src/V3Broken.cpp +++ b/src/V3Broken.cpp @@ -161,9 +161,11 @@ public: for (int backs = 0; backs < 2; backs++) { // Those with backp() are probably under one leaking without for (NodeMap::iterator it = s_nodes.begin(); it != s_nodes.end(); ++it) { - if ((it->second & FLAG_ALLOCATED) && !(it->second & FLAG_IN_TREE) - && !(it->second & FLAG_LEAKED) - && (it->first->backp() ? backs == 1 : backs == 0)) { + // LCOV_EXCL_START + if (VL_UNCOVERABLE((it->second & FLAG_ALLOCATED) && !(it->second & FLAG_IN_TREE) + && !(it->second & FLAG_LEAKED) + && (it->first->backp() ? backs == 1 : backs == 0))) { + // Use only AstNode::dump instead of the virtual one, as there // may be varp() and other cross links that are bad. if (v3Global.opt.debugCheck()) { @@ -182,6 +184,7 @@ public: } it->second |= FLAG_LEAKED; } + // LCOV_EXCL_STOP } } } diff --git a/src/V3EmitCMain.cpp b/src/V3EmitCMain.cpp index f74bae3b0..ac05e2048 100644 --- a/src/V3EmitCMain.cpp +++ b/src/V3EmitCMain.cpp @@ -33,7 +33,8 @@ class EmitCMain : EmitCBaseVisitor { // METHODS // VISITORS - virtual void visit(AstNode* nodep) { iterateChildren(nodep); } + // This visitor doesn't really iterate, but exist to appease base class + virtual void visit(AstNode* nodep) { iterateChildren(nodep); } // LCOV_EXCL_LINE public: // CONSTRUCTORS diff --git a/src/V3Options.cpp b/src/V3Options.cpp index f22789acd..547fa8df9 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -330,7 +330,7 @@ void V3Options::fileNfsFlush(const string& filename) { // do a open or opendir on the filename. // Faster to just try both rather than check if a file is a dir. if (DIR* dirp = opendir(filename.c_str())) { - closedir(dirp); + closedir(dirp); // LCOV_EXCL_LINE } else if (int fd = ::open(filename.c_str(), O_RDONLY)) { if (fd > 0) ::close(fd); } diff --git a/src/V3Os.cpp b/src/V3Os.cpp index 6fb2b9088..b4d1aea03 100644 --- a/src/V3Os.cpp +++ b/src/V3Os.cpp @@ -269,8 +269,8 @@ string V3Os::trueRandom(size_t size) { std::ifstream is("/dev/urandom", std::ios::in | std::ios::binary); // This read uses the size of the buffer. // Flawfinder: ignore - if (!is.read(data, size)) { - v3fatal("Could not open /dev/urandom, no source of randomness. " + if (VL_UNCOVERABLE(!is.read(data, size))) { + v3fatal("Could not open /dev/urandom, no source of randomness. " // LCOV_EXCL_LINE "Try specifying a key instead."); } #endif @@ -313,15 +313,12 @@ uint64_t V3Os::memUsageBytes() { FILE* fp = fopen(statmFilename, "r"); if (!fp) return 0; vluint64_t size, resident, share, text, lib, data, dt; // All in pages - if (7 - != fscanf(fp, - "%" VL_PRI64 "u %" VL_PRI64 "u %" VL_PRI64 "u %" VL_PRI64 "u %" VL_PRI64 - "u %" VL_PRI64 "u %" VL_PRI64 "u", - &size, &resident, &share, &text, &lib, &data, &dt)) { - fclose(fp); - return 0; - } + int items = fscanf(fp, + "%" VL_PRI64 "u %" VL_PRI64 "u %" VL_PRI64 "u %" VL_PRI64 "u %" VL_PRI64 + "u %" VL_PRI64 "u %" VL_PRI64 "u", + &size, &resident, &share, &text, &lib, &data, &dt); fclose(fp); + if (VL_UNCOVERABLE(7 != items)) return 0; return (text + data) * getpagesize(); #endif } diff --git a/src/V3ProtectLib.cpp b/src/V3ProtectLib.cpp index 6a2aac6e9..7445cc1c5 100644 --- a/src/V3ProtectLib.cpp +++ b/src/V3ProtectLib.cpp @@ -261,7 +261,7 @@ private: void castPtr(FileLine* fl, AstTextBlock* txtp) { txtp->addText(fl, m_topName - + "_container* handlep__V = " + + "_container* handlep__V = " // LCOV_EXCL_LINE // lcov bug "static_cast<" + m_topName + "_container*>(vhandlep__V);\n"); } diff --git a/src/V3Scoreboard.h b/src/V3Scoreboard.h index 9fffe9dac..3936d831b 100644 --- a/src/V3Scoreboard.h +++ b/src/V3Scoreboard.h @@ -292,7 +292,7 @@ public: typename Key2Val::iterator kvit = m_keys.find(k); if (kvit != m_keys.end()) { if (kvit->second == v) { - return; // Same value already present; stop. + return; // LCOV_EXCL_LINE // Same value already present; stop. } // Must remove element from m_vals[oldValue] removeKeyFromOldVal(k, kvit->second); diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index c77a28bef..2958c5aa0 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -130,10 +130,7 @@ class SliceVisitor : public AstNVisitor { if (!nodep->user1() && !VN_IS(nodep, AssignAlias)) { nodep->user1(true); m_assignError = false; - if (debug() >= 9) { - cout << endl; - nodep->dumpTree(cout, " Deslice-In: "); - } + if (debug() >= 9) nodep->dumpTree(cout, " Deslice-In: "); AstNodeDType* dtp = nodep->lhsp()->dtypep()->skipRefp(); if (AstUnpackArrayDType* arrayp = VN_CAST(dtp, UnpackArrayDType)) { // Left and right could have different msb/lsbs/endianness, but #elements is common @@ -148,10 +145,7 @@ class SliceVisitor : public AstNVisitor { if (debug() >= 9) { newp->dumpTree(cout, "-new "); } newlistp = AstNode::addNextNull(newlistp, newp); } - if (debug() >= 9) { - cout << endl; - nodep->dumpTree(cout, " Deslice-Dn: "); - } + if (debug() >= 9) nodep->dumpTree(cout, " Deslice-Dn: "); nodep->replaceWith(newlistp); VL_DO_DANGLING(nodep->deleteTree(), nodep); // Normal edit iterator will now iterate on all of the expansion assignments diff --git a/test_regress/t/t_debug_graph_test.pl b/test_regress/t/t_debug_graph_test.pl new file mode 100755 index 000000000..5ae25d7f3 --- /dev/null +++ b/test_regress/t/t_debug_graph_test.pl @@ -0,0 +1,20 @@ +#!/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); +$ENV{VERILATOR_TEST_NO_GDB} and skip("Skipping due to VERILATOR_TEST_NO_GDB"); + +lint( + # Check we can call dump() on graph, and other things + v_flags => ["--lint-only --debug --debugi-V3GraphTest 9 --debugi-V3GraphDfa 9"], + ); + +ok(1); +1; diff --git a/test_regress/t/t_debug_graph_test.v b/test_regress/t/t_debug_graph_test.v new file mode 100644 index 000000000..ff9763b1b --- /dev/null +++ b/test_regress/t/t_debug_graph_test.v @@ -0,0 +1,9 @@ +// DESCRIPTION: Verilator: Dotted reference that uses another dotted reference +// as the select expression +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2015 by Todd Strader. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/); +endmodule diff --git a/test_regress/t/t_flag_getenv.pl b/test_regress/t/t_flag_getenv.pl index 9e28d4392..0ca7ba7eb 100755 --- a/test_regress/t/t_flag_getenv.pl +++ b/test_regress/t/t_flag_getenv.pl @@ -12,15 +12,21 @@ scenarios(vlt => 1); $ENV{FOOBARTEST} = "gotit"; -compile( - v_flags2 => ["--getenv FOOBARTEST"], - expect => -'gotit +run( + cmd => ["../bin/verilator --getenv FOOBARTEST"], + expect => 'gotit ', - verilator_make_gmake => 0, - make_top_shell => 0, - make_main => 0, + logfile => "$Self->{obj_dir}/simx.log", + verilator_run => 1, ); +foreach my $var (qw(MAKE PERL SYSTEMC SYSTEMC_ARCH SYSTEMC_LIBDIR VERILATOR_ROOT)) { + run( + cmd => ["../bin/verilator --getenv ${var}"], + logfile => "$Self->{obj_dir}/simx.log", + verilator_run => 1, + ); +} + ok(1); 1; diff --git a/test_regress/t/t_flag_language_bad.pl b/test_regress/t/t_flag_language_bad.pl new file mode 100755 index 000000000..fffa3d721 --- /dev/null +++ b/test_regress/t/t_flag_language_bad.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2008 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( + verilator_flags2 => ['--language 1-2-3-4'], + fails => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_vpi_finish.pl b/test_regress/t/t_vpi_finish.pl new file mode 100755 index 000000000..050052f66 --- /dev/null +++ b/test_regress/t/t_vpi_finish.pl @@ -0,0 +1,23 @@ +#!/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(simulator => 1); + +compile( + v_flags2 => ["--vpi t/t_vpi_finish_c.cpp"], + ); + +execute( + check_finished => 1, + ); + +ok(1); + +1; diff --git a/test_regress/t/t_vpi_finish.v b/test_regress/t/t_vpi_finish.v new file mode 100644 index 000000000..4b211d63c --- /dev/null +++ b/test_regress/t/t_vpi_finish.v @@ -0,0 +1,17 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2020 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*/); + + import "DPI-C" function void dpii_test(); + + initial begin + $write("*-* All Finished *-*\n"); + dpii_test(); // $finish + end +endmodule diff --git a/test_regress/t/t_vpi_finish_c.cpp b/test_regress/t/t_vpi_finish_c.cpp new file mode 100644 index 000000000..14f1e056d --- /dev/null +++ b/test_regress/t/t_vpi_finish_c.cpp @@ -0,0 +1,27 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// +// Copyright 2009-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 +// +//************************************************************************* + +#include +#include +#include "svdpi.h" +#include "vpi_user.h" + +//====================================================================== + +extern "C" { + extern void dpii_test(); +} + +//====================================================================== + +void dpii_test() { + vpi_control(vpiFinish); +} diff --git a/test_regress/t/t_vpi_stop_bad.out b/test_regress/t/t_vpi_stop_bad.out new file mode 100644 index 000000000..4c93b7cd7 --- /dev/null +++ b/test_regress/t/t_vpi_stop_bad.out @@ -0,0 +1,2 @@ +%Error: Verilog $stop +Aborting... diff --git a/test_regress/t/t_vpi_stop_bad.pl b/test_regress/t/t_vpi_stop_bad.pl new file mode 100755 index 000000000..89f7e8b16 --- /dev/null +++ b/test_regress/t/t_vpi_stop_bad.pl @@ -0,0 +1,25 @@ +#!/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(simulator => 1); + +compile( + v_flags2 => ["--vpi t/t_vpi_stop_bad_c.cpp"], + ); + +execute( + fails => 1, + check_finished => 0, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); + +1; diff --git a/test_regress/t/t_vpi_stop_bad.v b/test_regress/t/t_vpi_stop_bad.v new file mode 100644 index 000000000..655f52880 --- /dev/null +++ b/test_regress/t/t_vpi_stop_bad.v @@ -0,0 +1,19 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2020 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*/); + + import "DPI-C" function void dpii_test(); + + initial begin + dpii_test(); + $display("Should have stopped above"); + //$write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_vpi_stop_bad_c.cpp b/test_regress/t/t_vpi_stop_bad_c.cpp new file mode 100644 index 000000000..40f9982d6 --- /dev/null +++ b/test_regress/t/t_vpi_stop_bad_c.cpp @@ -0,0 +1,27 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// +// Copyright 2009-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 +// +//************************************************************************* + +#include +#include +#include "svdpi.h" +#include "vpi_user.h" + +//====================================================================== + +extern "C" { + extern void dpii_test(); +} + +//====================================================================== + +void dpii_test() { + vpi_control(vpiStop); +} diff --git a/test_regress/t/t_vpi_unimpl.cpp b/test_regress/t/t_vpi_unimpl.cpp index dd9eb9fad..63ce3f507 100644 --- a/test_regress/t/t_vpi_unimpl.cpp +++ b/test_regress/t/t_vpi_unimpl.cpp @@ -71,6 +71,7 @@ unsigned int callback_count = 0; int _mon_check_unimpl(p_cb_data cb_data) { static TestVpiHandle cb, clk_h; + vpiHandle handle; if (cb_data) { // this is the callback s_vpi_error_info info; @@ -123,6 +124,33 @@ int _mon_check_unimpl(p_cb_data cb_data) { CHECK_RESULT(callback_count, 16); vpi_handle_by_multi_index(NULL, 0, NULL); CHECK_RESULT(callback_count, 17); + vpi_control(0); + CHECK_RESULT(callback_count, 18); + + s_vpi_time time_s; + time_s.type = 0; + vpi_get_time(NULL, &time_s); + CHECK_RESULT(callback_count, 19); + + handle = vpi_put_value(NULL, NULL, NULL, 0); + CHECK_RESULT(callback_count, 20); + CHECK_RESULT(handle, 0); + + handle = vpi_handle(0, NULL); + CHECK_RESULT(callback_count, 21); + CHECK_RESULT(handle, 0); + + vpi_iterate(0, NULL); + CHECK_RESULT(callback_count, 22); + + handle = vpi_register_cb(NULL); + CHECK_RESULT(callback_count, 23); + CHECK_RESULT(handle, 0); + s_cb_data cb_data_s; + cb_data_s.reason = 0; // Bad + handle = vpi_register_cb(&cb_data_s); + CHECK_RESULT(callback_count, 24); + CHECK_RESULT(handle, 0); } return 0; // Ok } @@ -173,7 +201,9 @@ int main(int argc, char** argv, char** env) { if (tfp) tfp->dump(main_time); #endif } - CHECK_RESULT(callback_count, 17); + if (!callback_count) { + vl_fatal(FILENM, __LINE__, "main", "%Error: never got callbacks"); + } if (!Verilated::gotFinish()) { vl_fatal(FILENM, __LINE__, "main", "%Error: Timeout; never got a $finish"); }