Additional lcov code coverage.
This commit is contained in:
parent
a4b9745e6e
commit
7e54ff1b37
|
@ -285,6 +285,7 @@ IData VL_RANDOM_I(int obits) VL_MT_SAFE {
|
|||
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
|
||||
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)) {
|
||||
|
|
|
@ -318,8 +318,8 @@ public: // But internals only - called from VerilatedModule's
|
|||
if (VL_LIKELY(funcnum < scopep->m_funcnumMax)) {
|
||||
// m_callbacksp must be declared, as Max'es are > 0
|
||||
return scopep->m_callbacksp[funcnum];
|
||||
} else {
|
||||
return scopep->exportFindError(funcnum);
|
||||
} else { // LCOV_EXCL_LINE
|
||||
return scopep->exportFindError(funcnum); // LCOV_EXCL_LINE
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -53,6 +53,7 @@ sub test {
|
|||
if ($Opt_Stage <= 1) {
|
||||
print "Stage 1: make examples (with coverage on)\n";
|
||||
run("make examples");
|
||||
run("make test_regress");
|
||||
}
|
||||
|
||||
my $cc_dir = "nodist/obj_dir/coverage";
|
||||
|
@ -68,7 +69,7 @@ sub test {
|
|||
}
|
||||
foreach my $dir (sort keys %dirs) {
|
||||
(my $outname = $dir) =~ s![^a-zA-Z0-9]+!_!g;
|
||||
run("cd $cc_dir/info ; lcov -c -d ../../../$dir -o app_test_${outname}.info");
|
||||
run("cd $cc_dir/info ; lcov -c -d ../../../../$dir -o app_test_${outname}.info");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,7 +146,7 @@ sub clone_sources {
|
|||
chomp $line;
|
||||
if ($line !~ m!// LCOV_EXCL_LINE!
|
||||
&& $line =~ /$Exclude_Line_Regexp/) {
|
||||
$line .= " //code_coverage: // LCOV_EXCL_LINE\n";
|
||||
$line .= " //code_coverage: // LCOV_EXCL_LINE";
|
||||
$excluded_lines++;
|
||||
#print "$infile:$lineno: $line";
|
||||
} else {
|
||||
|
@ -164,9 +165,11 @@ sub cleanup_abs_paths {
|
|||
my $fh = IO::File->new("<$infile") or die "%Error: $! $infile,";
|
||||
my @lines;
|
||||
while (defined(my $line = $fh->getline)) {
|
||||
if ($line =~ m!^SF:/!) {
|
||||
if ($line =~ m!^SF:!) {
|
||||
$line =~ s!$ENV{VERILATOR_ROOT}/!!;
|
||||
$line =~ s!$cc_dir/!!;
|
||||
$line =~ s!obj_dbg/verilog.y$!verilog.y!;
|
||||
#print "Remaining SF: ",$line;
|
||||
}
|
||||
push @lines, $line;
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ private:
|
|||
// Move the active's contents to the other active
|
||||
UINFO(4," merge active "<<sensesp<<" into "<<wantp<<endl);
|
||||
if (nodep->sensesStorep()) {
|
||||
if (sensesp != nodep->sensesStorep()) {
|
||||
if (VL_UNCOVERABLE(sensesp != nodep->sensesStorep())) {
|
||||
nodep->v3fatalSrc("sensesStore should have been deleted earlier if different");
|
||||
}
|
||||
sensesp->unlinkFrBack();
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
// Called by operator delete on any node - only if VL_LEAK_CHECKS
|
||||
if (debug()>=9) cout<<"-nodeDel: "<<cvtToHex(nodep)<<endl;
|
||||
NodeMap::iterator iter = s_nodes.find(nodep);
|
||||
if (iter==s_nodes.end() || !(iter->second & FLAG_ALLOCATED)) {
|
||||
if (VL_UNCOVERABLE(iter==s_nodes.end() || !(iter->second & FLAG_ALLOCATED))) {
|
||||
reinterpret_cast<const AstNode*>(nodep)
|
||||
->v3fatalSrc("Deleting AstNode object that was never tracked or already deleted");
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ public:
|
|||
// Called by operator new on any node - only if VL_LEAK_CHECKS
|
||||
if (debug()>=9) cout<<"-nodeNew: "<<cvtToHex(nodep)<<endl;
|
||||
NodeMap::iterator iter = s_nodes.find(nodep);
|
||||
if (iter !=s_nodes.end() && (iter->second & FLAG_ALLOCATED)) {
|
||||
if (VL_UNCOVERABLE(iter !=s_nodes.end() && (iter->second & FLAG_ALLOCATED))) {
|
||||
nodep->v3fatalSrc("Newing AstNode object that is already allocated");
|
||||
}
|
||||
if (iter == s_nodes.end()) {
|
||||
|
@ -96,17 +96,17 @@ public:
|
|||
if (!linkable) return; // save some time, else the map will get huge!
|
||||
#endif
|
||||
NodeMap::iterator iter = s_nodes.find(nodep);
|
||||
if (iter == s_nodes.end()) {
|
||||
if (VL_UNCOVERABLE(iter == s_nodes.end())) {
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
nodep->v3fatalSrc("AstNode is in tree, but not allocated");
|
||||
#endif
|
||||
} else {
|
||||
if (!(iter->second & FLAG_ALLOCATED)) {
|
||||
if (VL_UNCOVERABLE(!(iter->second & FLAG_ALLOCATED))) {
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
nodep->v3fatalSrc("AstNode is in tree, but not allocated");
|
||||
#endif
|
||||
}
|
||||
if (iter->second & FLAG_IN_TREE) {
|
||||
if (VL_UNCOVERABLE(iter->second & FLAG_IN_TREE)) {
|
||||
nodep->v3fatalSrc("AstNode is already in tree at another location");
|
||||
}
|
||||
}
|
||||
|
@ -230,34 +230,35 @@ public:
|
|||
class BrokenCheckVisitor : public AstNVisitor {
|
||||
private:
|
||||
void checkWidthMin(const AstNode* nodep) {
|
||||
if (nodep->width() != nodep->widthMin()
|
||||
&& v3Global.widthMinUsage()==VWidthMinUsage::MATCHES_WIDTH) {
|
||||
if (VL_UNCOVERABLE(nodep->width() != nodep->widthMin()
|
||||
&& v3Global.widthMinUsage()==VWidthMinUsage::MATCHES_WIDTH)) {
|
||||
nodep->v3fatalSrc("Width != WidthMin");
|
||||
}
|
||||
}
|
||||
void processAndIterate(AstNode* nodep) {
|
||||
BrokenTable::setUnder(nodep, true);
|
||||
if (const char* whyp=nodep->broken()) {
|
||||
const char* whyp = nodep->broken();
|
||||
if (VL_UNCOVERABLE(whyp)) {
|
||||
nodep->v3fatalSrc("Broken link in node (or something without maybePointedTo): "<<whyp);
|
||||
}
|
||||
if (nodep->dtypep()) {
|
||||
if (!nodep->dtypep()->brokeExists()) {
|
||||
if (VL_UNCOVERABLE(!nodep->dtypep()->brokeExists())) {
|
||||
nodep->v3fatalSrc("Broken link in node->dtypep() to "
|
||||
<<cvtToHex(nodep->dtypep()));
|
||||
} else if (!VN_IS(nodep->dtypep(), NodeDType)) {
|
||||
} else if (VL_UNCOVERABLE(!VN_IS(nodep->dtypep(), NodeDType))) {
|
||||
nodep->v3fatalSrc("Non-dtype link in node->dtypep() to "
|
||||
<<cvtToHex(nodep->dtypep()));
|
||||
}
|
||||
}
|
||||
if (v3Global.assertDTypesResolved()) {
|
||||
if (nodep->hasDType()) {
|
||||
if (!nodep->dtypep()) nodep->v3fatalSrc(
|
||||
if (VL_UNCOVERABLE(!nodep->dtypep())) nodep->v3fatalSrc(
|
||||
"No dtype on node with hasDType(): "<<nodep->prettyTypeName());
|
||||
} else {
|
||||
if (nodep->dtypep()) nodep->v3fatalSrc(
|
||||
if (VL_UNCOVERABLE(nodep->dtypep())) nodep->v3fatalSrc(
|
||||
"DType on node without hasDType(): "<<nodep->prettyTypeName());
|
||||
}
|
||||
if (nodep->getChildDTypep()) nodep->v3fatalSrc(
|
||||
if (VL_UNCOVERABLE(nodep->getChildDTypep())) nodep->v3fatalSrc(
|
||||
"childDTypep() non-null on node after should have removed");
|
||||
if (const AstNodeDType* dnodep = VN_CAST(nodep, NodeDType)) checkWidthMin(dnodep);
|
||||
}
|
||||
|
@ -267,10 +268,10 @@ private:
|
|||
}
|
||||
virtual void visit(AstNodeAssign* nodep) {
|
||||
processAndIterate(nodep);
|
||||
if (v3Global.assertDTypesResolved()
|
||||
&& nodep->brokeLhsMustBeLvalue()
|
||||
&& VN_IS(nodep->lhsp(), NodeVarRef)
|
||||
&& !VN_CAST(nodep->lhsp(), NodeVarRef)->lvalue()) {
|
||||
if (VL_UNCOVERABLE(v3Global.assertDTypesResolved()
|
||||
&& nodep->brokeLhsMustBeLvalue()
|
||||
&& VN_IS(nodep->lhsp(), NodeVarRef)
|
||||
&& !VN_CAST(nodep->lhsp(), NodeVarRef)->lvalue())) {
|
||||
nodep->v3fatalSrc("Assignment LHS is not an lvalue");
|
||||
}
|
||||
}
|
||||
|
@ -291,9 +292,9 @@ public:
|
|||
void V3Broken::brokenAll(AstNetlist* nodep) {
|
||||
//UINFO(9,__FUNCTION__<<": "<<endl);
|
||||
static bool inBroken = false;
|
||||
if (inBroken) {
|
||||
if (VL_UNCOVERABLE(inBroken)) {
|
||||
// A error called by broken can recurse back into broken; avoid this
|
||||
UINFO(1,"Broken called under broken, skipping recursion.\n");
|
||||
UINFO(1,"Broken called under broken, skipping recursion.\n"); // LCOV_EXCL_LINE
|
||||
} else {
|
||||
inBroken = true;
|
||||
BrokenTable::prepForTree();
|
||||
|
|
|
@ -109,7 +109,7 @@ AstNodeDType* V3ParseGrammar::createArray(AstNodeDType* basep,
|
|||
if (prevp) nrangep->unlinkFrBack();
|
||||
AstRange* rangep = VN_CAST(nrangep, Range);
|
||||
if (!rangep) {
|
||||
if (!VN_IS(nrangep, UnsizedRange)) {
|
||||
if (VL_UNCOVERABLE(!VN_IS(nrangep, UnsizedRange))) {
|
||||
nrangep->v3fatalSrc("Expected range or unsized range");
|
||||
}
|
||||
arrayp = new AstUnsizedArrayDType
|
||||
|
|
|
@ -219,7 +219,7 @@ private:
|
|||
nodeap->bodysp()->unlinkFrBackWithNext()->deleteTree();
|
||||
nodeap->addStmtp(stmtsp);
|
||||
if (debug()>=6) nodeap->dumpTree(cout, " table_new: ");
|
||||
} else {
|
||||
} else { // LCOV_EXCL_LINE
|
||||
nodep->v3fatalSrc("Creating table under unknown node type");
|
||||
}
|
||||
|
||||
|
@ -316,7 +316,7 @@ private:
|
|||
|
||||
// Simulate
|
||||
simvis.mainTableEmulate(nodep);
|
||||
if (!simvis.optimizable()) {
|
||||
if (VL_UNCOVERABLE(!simvis.optimizable())) {
|
||||
simvis.whyNotNodep()->v3fatalSrc("Optimizable cleared, even though earlier test run said not: "
|
||||
<<simvis.whyNotMessage());
|
||||
}
|
||||
|
@ -348,8 +348,9 @@ private:
|
|||
}
|
||||
|
||||
{ // Set changed table
|
||||
if (inValue != inValueNextInitArray++)
|
||||
if (VL_UNCOVERABLE(inValue != inValueNextInitArray++)) {
|
||||
nodep->v3fatalSrc("InitArray requires us to have the values in inValue order");
|
||||
}
|
||||
AstNode* setp = new AstConst(nodep->fileline(), outputChgMask);
|
||||
VN_CAST(chgVscp->varp()->valuep(), InitArray)->addValuep(setp);
|
||||
}
|
||||
|
|
|
@ -227,9 +227,11 @@ private:
|
|||
subp = newSubNeg(subp, fromRange.lo());
|
||||
}
|
||||
}
|
||||
if (!fromRange.elements() || (adtypep->width() % fromRange.elements())!=0)
|
||||
if (VL_UNCOVERABLE(!fromRange.elements()
|
||||
|| (adtypep->width() % fromRange.elements())!=0)) {
|
||||
adtypep->v3fatalSrc("Array extraction with width miscomputed "
|
||||
<<adtypep->width()<<"/"<<fromRange.elements());
|
||||
}
|
||||
int elwidth = adtypep->width() / fromRange.elements();
|
||||
AstSel* newp
|
||||
= new AstSel(nodep->fileline(),
|
||||
|
@ -316,9 +318,11 @@ private:
|
|||
else if (AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) {
|
||||
// SELEXTRACT(array, msb, lsb) -> SEL(array,
|
||||
// lsb*width-of-subindex, width-of-subindex*(msb-lsb))
|
||||
if (!fromRange.elements() || (adtypep->width() % fromRange.elements())!=0)
|
||||
if (VL_UNCOVERABLE(!fromRange.elements()
|
||||
|| (adtypep->width() % fromRange.elements())!=0)) {
|
||||
adtypep->v3fatalSrc("Array extraction with width miscomputed "
|
||||
<<adtypep->width()<<"/"<<fromRange.elements());
|
||||
}
|
||||
if (fromRange.littleEndian()) {
|
||||
// Below code assumes big bit endian; just works out if we swap
|
||||
int x = msb; msb = lsb; lsb = x;
|
||||
|
@ -478,7 +482,7 @@ private:
|
|||
|
||||
//--------------------
|
||||
// Default
|
||||
virtual void visit(AstNode* nodep) {
|
||||
virtual void visit(AstNode* nodep) { // LCOV_EXCL_LINE
|
||||
// See notes above; we never iterate
|
||||
nodep->v3fatalSrc("Shouldn't iterate in V3WidthSel");
|
||||
}
|
||||
|
|
|
@ -76,9 +76,9 @@ public:
|
|||
cout<<" Covered, Rank, RankPts, Filename"<<endl;
|
||||
}
|
||||
void dump(bool bucketsToo) {
|
||||
if (testrun() || computrons()!=0.0) {
|
||||
cout<<" "<<std::setw(8)<<std::setfill('0')<<testrun()
|
||||
<<", "<<std::setw(7)<<std::setfill(' ')<<computrons()<<",";
|
||||
if (testrun() || computrons()!=0.0) { // currently unused // LCOV_EXCL_LINE
|
||||
cout<<" "<<std::setw(8)<<std::setfill('0')<<testrun() // LCOV_EXCL_LINE
|
||||
<<", "<<std::setw(7)<<std::setfill(' ')<<computrons()<<","; // LCOV_EXCL_LINE
|
||||
}
|
||||
cout<<" "<<std::setw(7)<<std::setfill(' ')<<bucketsCovered()
|
||||
<<", "<<std::setw(7)<<std::setfill(' ')<<rank()
|
||||
|
|
|
@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
|||
scenarios(vlt_all => 1);
|
||||
|
||||
compile(
|
||||
v_flags2 => ["--debugi 9"],
|
||||
v_flags2 => ["--debug --debugi 9"],
|
||||
tee => 0,
|
||||
verilator_make_gcc => 0,
|
||||
make_top_shell => 0,
|
||||
|
|
|
@ -3,7 +3,18 @@
|
|||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2008 by Wilson Snyder.
|
||||
|
||||
module t;
|
||||
module t (/*AUTOARG*/
|
||||
// Outputs
|
||||
o,
|
||||
// Inputs
|
||||
i
|
||||
);
|
||||
|
||||
// Need some logic to get mtask debug fully covered
|
||||
input i;
|
||||
output wire o;
|
||||
assign o = i;
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
Intentional stop
|
||||
%Error: t/t_stop_bad.v:9: Verilog $stop
|
||||
Aborting...
|
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
fails => 1,
|
||||
check_finished => 0,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
|
||||
1;
|
|
@ -0,0 +1,11 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2019 by Wilson Snyder.
|
||||
|
||||
module t;
|
||||
initial begin
|
||||
$write("Intentional stop\n");
|
||||
$stop;
|
||||
end
|
||||
endmodule
|
|
@ -22,6 +22,8 @@ module t;
|
|||
if (i!==0) $stop;
|
||||
i = $system("exit 10");
|
||||
if (i!==10) $stop;
|
||||
i = $system("exit 20"); // Wide
|
||||
if (i!==20) $stop;
|
||||
`endif
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/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.
|
||||
|
||||
scenarios(dist => 1);
|
||||
|
||||
foreach my $basename ("t_vlcov_data_a.dat",
|
||||
"t_vlcov_data_b.dat",
|
||||
"t_vlcov_data_c.dat",
|
||||
"t_vlcov_data_d.dat",
|
||||
) {
|
||||
run(cmd => ["../bin/verilator_coverage",
|
||||
"t/${basename}",
|
||||
"--debugi 9",
|
||||
],
|
||||
tee => $Self->{verbose},
|
||||
);
|
||||
}
|
||||
|
||||
ok(1);
|
||||
1;
|
|
@ -0,0 +1,2 @@
|
|||
%Error: Can't read t/t_NOT_FOUND
|
||||
%Error: Command Failed
|
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/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.
|
||||
|
||||
scenarios(dist => 1);
|
||||
|
||||
run(fails => 1,
|
||||
cmd => ["../bin/verilator_coverage",
|
||||
"t/t_NOT_FOUND",],
|
||||
logfile => $Self->{run_log_filename},
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
Loading…
Reference in New Issue