Misc internal coverage hole and related bug fixes

This commit is contained in:
Wilson Snyder 2020-12-09 19:16:00 -05:00
parent 5e7b0d526d
commit 7d05be802d
19 changed files with 281 additions and 96 deletions

View File

@ -29,69 +29,27 @@
#define VLCOVGEN_ITEM(string_parsed_by_vlcovgen)
// clang-format off
VLCOVGEN_ITEM("name=>'col0_name', short=>'C0', group=>1, default=>undef, descr=>'The column title for the header line of this column'")
VLCOVGEN_ITEM("name=>'col1_name', short=>'C1', group=>1, default=>undef, ")
VLCOVGEN_ITEM("name=>'col2_name', short=>'C2', group=>1, default=>undef, ")
VLCOVGEN_ITEM("name=>'col3_name', short=>'C3', group=>1, default=>undef, ")
VLCOVGEN_ITEM("name=>'column', short=>'n', group=>1, default=>0, descr=>'Column number for the item. Used to disambiguate multiple coverage points on the same line number'")
VLCOVGEN_ITEM("name=>'filename', short=>'f', group=>1, default=>undef, descr=>'Filename of the item'")
VLCOVGEN_ITEM("name=>'groupdesc', short=>'d', group=>1, default=>'', descr=>'Description of the covergroup this item belongs to'")
VLCOVGEN_ITEM("name=>'groupname', short=>'g', group=>1, default=>'', descr=>'Group name of the covergroup this item belongs to'")
VLCOVGEN_ITEM("name=>'groupcmt', short=>'O', group=>1, default=>'', ")
VLCOVGEN_ITEM("name=>'linescov', short=>'S', group=>1, default=>'', descr=>'List of comma-separated lines covered'")
VLCOVGEN_ITEM("name=>'per_instance',short=>'P', group=>1, default=>0, descr=>'True if every hierarchy is independently counted; otherwise all hierarchies will be combined into a single count'")
VLCOVGEN_ITEM("name=>'row0_name', short=>'R0', group=>1, default=>undef, descr=>'The row title for the header line of this row'")
VLCOVGEN_ITEM("name=>'row1_name', short=>'R1', group=>1, default=>undef, ")
VLCOVGEN_ITEM("name=>'row2_name', short=>'R2', group=>1, default=>undef, ")
VLCOVGEN_ITEM("name=>'row3_name', short=>'R3', group=>1, default=>undef, ")
VLCOVGEN_ITEM("name=>'table', short=>'T', group=>1, default=>undef, descr=>'The name of the table for automatically generated tables'")
VLCOVGEN_ITEM("name=>'thresh', short=>'s', group=>1, default=>undef, ")
VLCOVGEN_ITEM("name=>'thresh', short=>'s', group=>1, default=>undef, descr=>'Number of hits to consider covered (aka at_least)'")
VLCOVGEN_ITEM("name=>'type', short=>'t', group=>1, default=>'', descr=>'Type of coverage (block, line, fsm, etc)'")
// Bin attributes
VLCOVGEN_ITEM("name=>'col0', short=>'c0', group=>0, default=>undef, descr=>'The (enumeration) value name for this column in a table cross' ")
VLCOVGEN_ITEM("name=>'col1', short=>'c1', group=>0, default=>undef, ")
VLCOVGEN_ITEM("name=>'col2', short=>'c2', group=>0, default=>undef, ")
VLCOVGEN_ITEM("name=>'col3', short=>'c3', group=>0, default=>undef, ")
VLCOVGEN_ITEM("name=>'comment', short=>'o', group=>0, default=>'', descr=>'Textual description for the item'")
VLCOVGEN_ITEM("name=>'hier', short=>'h', group=>0, default=>'', descr=>'Hierarchy path name for the item'")
VLCOVGEN_ITEM("name=>'limit', short=>'L', group=>0, default=>undef, ")
VLCOVGEN_ITEM("name=>'lineno', short=>'l', group=>0, default=>0, descr=>'Line number for the item'")
VLCOVGEN_ITEM("name=>'row0', short=>'r0', group=>0, default=>undef, descr=>'The (enumeration) value name for this row in a table cross'")
VLCOVGEN_ITEM("name=>'row1', short=>'r1', group=>0, default=>undef, ")
VLCOVGEN_ITEM("name=>'row2', short=>'r2', group=>0, default=>undef, ")
VLCOVGEN_ITEM("name=>'row3', short=>'r3', group=>0, default=>undef, ")
VLCOVGEN_ITEM("name=>'weight', short=>'w', group=>0, default=>undef, descr=>'For totaling items, weight of this item'")
// clang-format on
// VLCOVGEN_CIK_AUTO_EDIT_BEGIN
#define VL_CIK_COL0 "c0"
#define VL_CIK_COL0_NAME "C0"
#define VL_CIK_COL1 "c1"
#define VL_CIK_COL1_NAME "C1"
#define VL_CIK_COL2 "c2"
#define VL_CIK_COL2_NAME "C2"
#define VL_CIK_COL3 "c3"
#define VL_CIK_COL3_NAME "C3"
#define VL_CIK_COLUMN "n"
#define VL_CIK_COMMENT "o"
#define VL_CIK_FILENAME "f"
#define VL_CIK_GROUPCMT "O"
#define VL_CIK_GROUPDESC "d"
#define VL_CIK_GROUPNAME "g"
#define VL_CIK_HIER "h"
#define VL_CIK_LIMIT "L"
#define VL_CIK_LINENO "l"
#define VL_CIK_LINESCOV "S"
#define VL_CIK_PER_INSTANCE "P"
#define VL_CIK_ROW0 "r0"
#define VL_CIK_ROW0_NAME "R0"
#define VL_CIK_ROW1 "r1"
#define VL_CIK_ROW1_NAME "R1"
#define VL_CIK_ROW2 "r2"
#define VL_CIK_ROW2_NAME "R2"
#define VL_CIK_ROW3 "r3"
#define VL_CIK_ROW3_NAME "R3"
#define VL_CIK_TABLE "T"
#define VL_CIK_THRESH "s"
#define VL_CIK_TYPE "t"
#define VL_CIK_WEIGHT "w"
@ -106,34 +64,13 @@ class VerilatedCovKey final {
public:
static std::string shortKey(const std::string& key) VL_PURE {
// VLCOVGEN_SHORT_AUTO_EDIT_BEGIN
if (key == "col0") return VL_CIK_COL0;
if (key == "col0_name") return VL_CIK_COL0_NAME;
if (key == "col1") return VL_CIK_COL1;
if (key == "col1_name") return VL_CIK_COL1_NAME;
if (key == "col2") return VL_CIK_COL2;
if (key == "col2_name") return VL_CIK_COL2_NAME;
if (key == "col3") return VL_CIK_COL3;
if (key == "col3_name") return VL_CIK_COL3_NAME;
if (key == "column") return VL_CIK_COLUMN;
if (key == "comment") return VL_CIK_COMMENT;
if (key == "filename") return VL_CIK_FILENAME;
if (key == "groupcmt") return VL_CIK_GROUPCMT;
if (key == "groupdesc") return VL_CIK_GROUPDESC;
if (key == "groupname") return VL_CIK_GROUPNAME;
if (key == "hier") return VL_CIK_HIER;
if (key == "limit") return VL_CIK_LIMIT;
if (key == "lineno") return VL_CIK_LINENO;
if (key == "linescov") return VL_CIK_LINESCOV;
if (key == "per_instance") return VL_CIK_PER_INSTANCE;
if (key == "row0") return VL_CIK_ROW0;
if (key == "row0_name") return VL_CIK_ROW0_NAME;
if (key == "row1") return VL_CIK_ROW1;
if (key == "row1_name") return VL_CIK_ROW1_NAME;
if (key == "row2") return VL_CIK_ROW2;
if (key == "row2_name") return VL_CIK_ROW2_NAME;
if (key == "row3") return VL_CIK_ROW3;
if (key == "row3_name") return VL_CIK_ROW3_NAME;
if (key == "table") return VL_CIK_TABLE;
if (key == "thresh") return VL_CIK_THRESH;
if (key == "type") return VL_CIK_TYPE;
if (key == "weight") return VL_CIK_WEIGHT;

View File

@ -216,7 +216,6 @@ protected:
double timeRes() const { return m_timeRes; }
double timeUnit() const { return m_timeUnit; }
std::string timeResStr() const;
std::string timeUnitStr() const;
void traceInit() VL_MT_UNSAFE;

View File

@ -47,7 +47,7 @@ static double timescaleToDouble(const char* unitp) {
unitp = endp;
for (; *unitp && isspace(*unitp); unitp++) {}
switch (*unitp) {
case 's': value *= 1e1; break;
case 's': value *= 1e0; break;
case 'm': value *= 1e-3; break;
case 'u': value *= 1e-6; break;
case 'n': value *= 1e-9; break;
@ -70,7 +70,7 @@ static std::string doubleToTimescale(double value) {
else if (value >= 1e-18) { suffixp = "as"; value *= 1e18; }
// clang-format on
char valuestr[100];
sprintf(valuestr, "%3.0f%s", value, suffixp);
sprintf(valuestr, "%0.0f%s", value, suffixp);
return valuestr; // Gets converted to string, so no ref to stack
}
@ -374,10 +374,6 @@ template <> std::string VerilatedTrace<VL_DERIVED_T>::timeResStr() const {
return doubleToTimescale(m_timeRes);
}
template <> std::string VerilatedTrace<VL_DERIVED_T>::timeUnitStr() const {
return doubleToTimescale(m_timeUnit);
}
//=========================================================================
// External interface to client code
@ -643,4 +639,39 @@ static inline void cvtQDataToStr(char* dstp, QData value) {
#define cvtEDataToStr cvtIDataToStr
//=============================================================================
#ifdef VERILATED_VCD_TEST
void verilated_trace_imp_selftest() {
#define SELF_CHECK(got, exp) \
do { \
if ((got) != (exp)) VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: selftest\n"); \
} while (0)
#define SELF_CHECK_TS(scale) \
SELF_CHECK(doubleToTimescale(timescaleToDouble(scale)), std::string{scale});
SELF_CHECK_TS("1s");
SELF_CHECK_TS("100ms");
SELF_CHECK_TS("10ms");
SELF_CHECK_TS("1ms");
SELF_CHECK_TS("100us");
SELF_CHECK_TS("10us");
SELF_CHECK_TS("1us");
SELF_CHECK_TS("100ns");
SELF_CHECK_TS("10ns");
SELF_CHECK_TS("1ns");
SELF_CHECK_TS("100ps");
SELF_CHECK_TS("10ps");
SELF_CHECK_TS("1ps");
SELF_CHECK_TS("100fs");
SELF_CHECK_TS("10fs");
SELF_CHECK_TS("1fs");
SELF_CHECK_TS("100as");
SELF_CHECK_TS("10as");
SELF_CHECK_TS("1as");
}
#endif
#endif // VL_CPPCHECK

View File

@ -777,6 +777,8 @@ void VerilatedVcd::fullDouble(vluint32_t code, const double newval) {
#ifdef VERILATED_VCD_TEST
#include <iostream>
extern void verilated_trace_imp_selftest();
vluint32_t v1, v2, s1, s2[3];
vluint32_t tri96[3];
vluint32_t tri96__tri[3];
@ -843,6 +845,8 @@ void vcdChange(void*, VerilatedVcd* vcdp) {
// clang-format off
void vcdTestMain(const char* filenamep) {
verilated_trace_imp_selftest();
v1 = v2 = s1 = 0;
s2[0] = s2[1] = s2[2] = 0;
tri96[2] = tri96[1] = tri96[0] = 0;

View File

@ -184,7 +184,7 @@ inline std::ostream& operator<<(std::ostream& lhs, const OrderMoveDomScope& rhs)
// Order information stored under each AstNode::user1p()...
// Types of vertex we can create
enum WhichVertex : uint8_t { WV_STD, WV_PRE, WV_PORD, WV_POST, WV_SETL, WV_MAX };
enum WhichVertex : uint8_t { WV_STD, WV_PRE, WV_PORD, WV_POST, WV_MAX };
class OrderUser final {
// Stored in AstVarScope::user1p, a list of all the various vertices
@ -205,7 +205,6 @@ public:
case WV_PRE: vertexp = new OrderVarPreVertex(graphp, scopep, varscp); break;
case WV_PORD: vertexp = new OrderVarPordVertex(graphp, scopep, varscp); break;
case WV_POST: vertexp = new OrderVarPostVertex(graphp, scopep, varscp); break;
case WV_SETL: vertexp = new OrderVarSettleVertex(graphp, scopep, varscp); break;
default: varscp->v3fatalSrc("Bad case");
}
m_vertexp[type] = vertexp;
@ -1569,8 +1568,6 @@ void OrderVisitor::processEdgeReport() {
name += " {POST}";
} else if (dynamic_cast<OrderVarPordVertex*>(itp)) {
name += " {PORD}";
} else if (dynamic_cast<OrderVarSettleVertex*>(itp)) {
name += " {STL}";
}
std::ostringstream os;
os.setf(std::ios::left);

View File

@ -26,7 +26,6 @@
// OrderVarPreVertex
// OrderVarPostVertex
// OrderVarPordVertex
// OrderVarSettleVertex
//
// V3GraphEdge
// OrderEdge
@ -296,24 +295,6 @@ public:
virtual string dotColor() const override { return "NavyBlue"; }
virtual bool domainMatters() override { return false; }
};
class OrderVarSettleVertex final : public OrderVarVertex {
OrderVarSettleVertex(V3Graph* graphp, const OrderVarSettleVertex& old)
: OrderVarVertex{graphp, old} {}
public:
OrderVarSettleVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
: OrderVarVertex{graphp, scopep, varScp} {}
virtual ~OrderVarSettleVertex() override = default;
virtual OrderVarSettleVertex* clone(V3Graph* graphp) const override {
return new OrderVarSettleVertex(graphp, *this);
}
virtual OrderVEdgeType type() const override { return OrderVEdgeType::VERTEX_VARSETTLE; }
virtual string name() const override {
return (cvtToHex(varScp()) + " STL\\n " + varScp()->name());
}
virtual string dotColor() const override { return "PowderBlue"; }
virtual bool domainMatters() override { return false; }
};
//######################################################################
//--- Following only under the move graph, not the main graph

View File

@ -5549,8 +5549,9 @@ private:
case AstType::atMulS: newp = new AstMul(fl, lhsp, rhsp); break;
case AstType::atShiftR: newp = new AstShiftRS(fl, lhsp, rhsp); break;
case AstType::atShiftRS: newp = new AstShiftR(fl, lhsp, rhsp); break;
default: // LCOV_EXCL_LINE
nodep->v3fatalSrc("Node needs sign change, but bad case: " << nodep); break;
default: // LCOV_EXCL_LINE
nodep->v3fatalSrc("Node needs sign change, but bad case: " << nodep);
break;
}
UINFO(6, " ReplaceWithUOrSVersion: " << nodep << " w/ " << newp << endl);
nodep->replaceWith(newp);

View File

@ -21,6 +21,9 @@ module t ();
$finish;
end
import "DPI-C" context function void dpic_final();
final dpic_final();
endmodule
module sub (input integer inst);
@ -32,6 +35,15 @@ module sub (input integer inst);
int result;
// Exports here are only to cover the export dumper of Verilated::internalsDump
export "DPI-C" function dpix_void;
function void dpix_void;
endfunction
export "DPI-C" function dpix_result;
function int dpix_result;
return result;
endfunction
task test1;
// Check line numbering
`ifndef verilator // Not all sims support SV2009 `__LINE__, and some that do fail the specific-line test

View File

@ -82,6 +82,8 @@ int dpic_line() {
extern int Dpic_Unique;
int Dpic_Unique = 0; // Address used for uniqueness
extern int Dpic_Value;
int Dpic_Value = 0; // Address used for testing
int dpic_save(int value) {
svScope scope = svGetScope();
@ -96,6 +98,21 @@ int dpic_save(int value) {
int i;
} vp;
// Load the value here, and below, to test we can reinsert correctly
if (svPutUserData(scope, &Dpic_Unique, &Dpic_Value)) {
printf("%%Warning: svPutUserData failed (initial)\n");
return 0;
}
if (void* userp = svGetUserData(scope, &Dpic_Unique)) {
if (userp != &Dpic_Value) {
printf("%%Warning: svGetUserData failed (initial wrong data)\n");
return 0;
}
} else {
printf("%%Warning: svGetUserData failed (initial)\n");
return 0;
}
vp.i = value;
if (vp.i) {}
if (svPutUserData(scope, &Dpic_Unique, vp.ptr)) {
@ -132,3 +149,13 @@ unsigned dpic_getcontext() {
scope, svGetNameFromScope(scope));
return (unsigned)(uintptr_t)scope;
}
void dpic_final() {
static int s_once = 0;
if (s_once++) return;
printf("%s:\n", __func__);
#ifdef VERILATOR
// Cover VerilatedImp::userDump
Verilated::internalsDump();
#endif
}

View File

@ -0,0 +1,28 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2010 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
#include <iostream>
#include <verilated.h>
#include <verilated_save.h>
#include VM_PREFIX_INCLUDE
//======================================================================
unsigned int main_time = 0;
double sc_time_stamp() { return main_time; }
int main(int argc, char* argv[]) {
auto topp = new VM_PREFIX;
// We aren't calling Verilated::commandArgs(argc, argv)
topp->eval();
exit(0);
}

View File

@ -0,0 +1,2 @@
%Error: unknown:0: %Error: Verilog called $test$plusargs or $value$plusargs without testbench C first calling Verilated::commandArgs(argc,argv).
Aborting...

View File

@ -0,0 +1,24 @@
#!/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 => ["--savable --exe $Self->{t_dir}/t_runflag_uninit_bad.cpp"],
make_main => 0,
);
execute(
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -0,0 +1,11 @@
// 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;
initial $display($test$plusargs("MYFLAG"));
endmodule

View File

@ -0,0 +1,48 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2010 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
#include <iostream>
#include <verilated.h>
#include <verilated_save.h>
#include VM_PREFIX_INCLUDE
//======================================================================
#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; \
exit(10); \
} \
} while (0)
//======================================================================
unsigned int main_time = 0;
double sc_time_stamp() { return main_time; }
int main(int argc, char* argv[]) {
// No need to make a model: topp = new VM_PREFIX;
Verilated::debug(0);
{
VerilatedSave os;
os.open("/No_such_file_as_this");
CHECK_RESULT_HEX(os.isOpen(), false);
}
{
VerilatedRestore os;
os.open("/No_such_file_as_this");
CHECK_RESULT_HEX(os.isOpen(), false);
}
exit(0);
}

View File

@ -0,0 +1,2 @@
%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...

View File

@ -0,0 +1,22 @@
#!/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 => ["--savable --exe $Self->{t_dir}/t_savable_open_bad2.cpp"],
make_main => 0,
);
execute(
);
ok(1);
1;

View File

@ -0,0 +1,10 @@
// 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;
endmodule

View File

@ -0,0 +1,24 @@
#!/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
scenarios(vltmt => 1);
compile(
verilator_flags2 => ['--cc --threads 1024'],
);
execute(
check_finished => 1,
);
file_grep($Self->{run_log_filename}, qr/System has .* CPUs but.*--threads 1024/);
ok(1);
1;

View File

@ -0,0 +1,25 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2017 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc;
always @ (posedge clk) begin
cyc <= cyc + 1;
if (cyc!=0) begin
if (cyc==10) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
end
endmodule