Generate file with waivers (#2354)

This adds the flag --generate-waivefile <filename>. This will generate
a verilator config file with the proper lint_off statemens to turn off
warnings emitted during this particular run.

This feature can be used to start with using Verilator as linter and
systematically capture all known lint warning for further
elimination. It hopefully helps people turning of -Wno-fatal or
-Wno-lint and gradually improve their code base.

Signed-off-by: Stefan Wallentowitz <stefan.wallentowitz@hm.edu>
This commit is contained in:
Stefan Wallentowitz 2020-05-26 20:38:14 +02:00 committed by GitHub
parent 68a2ed6776
commit dc90e6c3c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 233 additions and 1 deletions

View File

@ -5,6 +5,9 @@ The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 4.035 devel
** Add --waiver-output flag that writes a verilator config file (.vlt) with
waivers to the warnings emitted during a Verilator run.
*** Support verilator_coverage --write-info for lcov HTML reports.
**** Support multi channel descriptor I/O (#2190) [Stephen Henry]

View File

@ -399,6 +399,7 @@ detailed descriptions in L</"VERILATION ARGUMENTS"> for more information.
+verilog2001ext+<ext> Synonym for +1364-2001ext+<ext>
--version Displays program version and exits
--vpi Enable VPI compiles
--waiver-output <filename> Create a waiver file based on the linter warnings
-Wall Enable all style warnings
-Werror-<message> Convert warnings to errors
-Wfuture-<message> Disable unknown message warnings
@ -1606,6 +1607,17 @@ Displays program version and exits.
Enable use of VPI and linking against the verilated_vpi.cpp files.
=item --waiver-output <filename>
Generate a waiver file which contains all waiver statements to suppress the
warnings emitted during this Verilator run. This is in particular useful as
a starting point for solving linter warnings or suppressing them
systematically.
The generated file is in the Verilator Configuration format, see
L</"CONFIGURATION FILES">, and can directly be consumed by Verilator. The
standard file extension is .vlt.
=item -Wall
Enable all code style warnings, including code style warnings that are

View File

@ -246,6 +246,7 @@ RAW_OBJS = \
V3Undriven.o \
V3Unknown.o \
V3Unroll.o \
V3Waiver.o \
V3Width.o \
V3WidthSel.o \

View File

@ -28,6 +28,7 @@
# include "V3Config.h"
# include "V3File.h"
#endif
#include "V3Waiver.h"
// clang-format on
#include <algorithm>
@ -366,6 +367,7 @@ void FileLine::v3errorEnd(std::ostringstream& sstr, const string& locationStr) {
} else if (!V3Error::errorContexted()) {
nsstr << warnContextPrimary();
}
if (!m_waive) { V3Waiver::addEntry(V3Error::errorCode(), filename(), sstr.str()); }
V3Error::v3errorEnd(nsstr, lstr.str());
}

View File

@ -1197,6 +1197,9 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
parseOptsFile(fl, parseFileArg(optdir, argv[i]), false);
} else if (!strcmp(sw, "-gdb")) {
// Used only in perl shell
} else if (!strcmp(sw, "-waiver-output") && (i + 1) < argc) {
shift;
m_waiverOutput = argv[i];
} else if (!strcmp(sw, "-rr")) {
// Used only in perl shell
} else if (!strcmp(sw, "-gdbbt")) {
@ -1627,6 +1630,7 @@ V3Options::V3Options() {
m_makeDir = "obj_dir";
m_bin = "";
m_flags = "";
m_waiverOutput = "";
m_l2Name = "";
m_unusedRegexp = "*unused*";
m_xAssign = "fast";

View File

@ -317,6 +317,7 @@ private:
string m_protectLib; // main switch: --protect-lib {lib_name}
string m_topModule; // main switch: --top-module
string m_unusedRegexp; // main switch: --unused-regexp
string m_waiverOutput; // main switch: --waiver-output {filename}
string m_xAssign; // main switch: --x-assign
string m_xInitial; // main switch: --x-initial
string m_xmlOutput; // main switch: --xml-output
@ -522,6 +523,8 @@ public:
}
string topModule() const { return m_topModule; }
string unusedRegexp() const { return m_unusedRegexp; }
string waiverOutput() const { return m_waiverOutput; }
bool isWaiverOutput() const { return !m_waiverOutput.empty(); }
string xAssign() const { return m_xAssign; }
string xInitial() const { return m_xInitial; }
string xmlOutput() const { return m_xmlOutput; }

57
src/V3Waiver.cpp Normal file
View File

@ -0,0 +1,57 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Emit waivers into a config file
//
// Code available from: https://verilator.org
//
//*************************************************************************
//
// 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
//
//*************************************************************************
#include "verilatedos.h"
#include "V3File.h"
#include "V3Waiver.h"
#include <memory>
#include <fstream>
#include <sstream>
void V3Waiver::addEntry(V3ErrorCode errorCode, const std::string& filename,
const std::string& str) {
std::stringstream entry;
entry << "lint_off -rule " << errorCode.ascii() << " -file \"*" << filename << "\" -match \""
<< str << "\"";
s_waiverList.push_back(entry.str());
}
void V3Waiver::write(const std::string& filename) {
const vl_unique_ptr<std::ofstream> ofp(V3File::new_ofstream(filename));
if (ofp->fail()) v3fatal("Can't write " << filename);
*ofp << "// DESCR"
"IPTION: Verilator output: Waivers generated with --waiver-output"
<< std::endl
<< endl;
*ofp << "`verilator_config" << endl << endl;
*ofp << "// Below you find suggested waivers. You have three options:" << endl;
*ofp << "// 1. Fix the reason for the linter warning" << endl;
*ofp << "// 2. Keep the waiver permanently if you are sure this is okay" << endl;
*ofp << "// 3. Keep the waiver temporarily to suppress the output" << endl << endl;
if (s_waiverList.size() == 0) { *ofp << "// No waivers needed - great!" << endl; }
for (V3Waiver::WaiverList::const_iterator it = s_waiverList.begin(); it != s_waiverList.end();
++it) {
*ofp << "// " << *it << std::endl << endl;
}
}
V3Waiver::WaiverList V3Waiver::s_waiverList;

35
src/V3Waiver.h Normal file
View File

@ -0,0 +1,35 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Emit Waivers
//
// Code available from: https://verilator.org
//
//*************************************************************************
//
// Copyright 2003-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
//
//*************************************************************************
#ifndef _V3WAIVER_H_
#define _V3WAIVER_H_ 1
#include "V3Error.h"
#include <vector>
#include <string>
class V3Waiver {
// TYPES
typedef std::vector<std::string> WaiverList;
static WaiverList s_waiverList;
public:
static void addEntry(V3ErrorCode errorCode, const string& filename, const std::string& str);
static void write(const std::string& filename);
};
#endif // Guard

View File

@ -93,6 +93,7 @@
#include "V3Undriven.h"
#include "V3Unknown.h"
#include "V3Unroll.h"
#include "V3Waiver.h"
#include "V3Width.h"
#include <ctime>
@ -542,6 +543,14 @@ static void verilate(const string& argString) {
// Final steps
V3Global::dumpCheckGlobalTree("final", 990, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Error::abortIfErrors();
if (v3Global.opt.isWaiverOutput()) {
// Create waiver output, must be just before we exit on warnings
V3Waiver::write(v3Global.opt.waiverOutput());
}
V3Error::abortIfWarnings();
if (v3Global.opt.makeDepend().isTrue()) {

View File

@ -0,0 +1,13 @@
// DESCRIPTION: Verilator output: Waivers generated with --waiver-output
`verilator_config
// Below you find suggested waivers. You have three options:
// 1. Fix the reason for the linter warning
// 2. Keep the waiver permanently if you are sure this is okay
// 3. Keep the waiver temporarily to suppress the output
// lint_off -rule WIDTH -file "*t/t_waiveroutput.v" -match "Operator ASSIGN expects 1 bits on the Assign RHS, but Assign RHS's CONST '2'h3' generates 2 bits."
// lint_off -rule UNUSED -file "*t/t_waiveroutput.v" -match "Signal is not used: 'width_warn'"

View File

@ -0,0 +1,30 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2012 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);
my $out_filename = "$Self->{obj_dir}/$Self->{name}_waiver_gen.vlt";
my $waiver_filename = "$Self->{obj_dir}/$Self->{name}_waiver.vlt";
compile(
v_flags2 => ['--waiver-output', $out_filename],
fails => 1,
);
files_identical("$out_filename", $Self->{golden_filename});
run(cmd=>["sed 's/\\/\\/ lint_off/lint_off/g' $out_filename > $waiver_filename"]);
compile(
v_flags2 => [$waiver_filename],
);
ok(1);
1;

View File

@ -0,0 +1,10 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2012 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t_waiveroutput;
reg width_warn = 2'b11; // Width warning - must be line 18
endmodule

View File

@ -0,0 +1,10 @@
// DESCRIPTION: Verilator output: Waivers generated with --waiver-output
`verilator_config
// Below you find suggested waivers. You have three options:
// 1. Fix the reason for the linter warning
// 2. Keep the waiver permanently if you are sure this is okay
// 3. Keep the waiver temporarily to suppress the output
// No waivers needed - great!

View File

@ -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 2012 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);
my $out_filename = "$Self->{obj_dir}/$Self->{name}_waiver_gen.vlt";
my $waiver_filename = "t/$Self->{name}.vlt";
top_filename("t/t_waiveroutput.v");
compile(
v_flags2 => [$waiver_filename, '--waiver-output', $out_filename],
);
files_identical("$out_filename", $Self->{golden_filename});
ok(1);
1;

View File

@ -0,0 +1,12 @@
// DESCRIPTION: Verilator output: Waivers generated with --waiver-output
`verilator_config
// Below you find suggested waivers. You have three options:
// 1. Fix the reason for the linter warning
// 2. Keep the waiver permanently if you are sure this is okay
// 3. Keep the waiver temporarily to suppress the output
lint_off -rule WIDTH -file "*t/t_waiveroutput.v" -match "Operator ASSIGN expects 1 bits on the Assign RHS, but Assign RHS's CONST '2'h3' generates 2 bits."
lint_off -rule UNUSED -file "*t/t_waiveroutput.v" -match "Signal is not used: 'width_warn'"

View File

@ -10,11 +10,17 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(vlt => 1);
my $waiver_filename = "$Self->{obj_dir}/$Self->{name}_waiver.vlt";
lint(
verilator_flags2 => ["--lint-only --language 1364-2001"],
verilator_flags2 => ["--lint-only --language 1364-2001 --waiver-output ${waiver_filename}"],
fails => 1,
expect_filename => $Self->{golden_filename},
);
if (-e $waiver_filename) {
error("Waiver file generated, not expected..");
}
ok(1);
1;