diff --git a/Changes b/Changes index c16f57290..f3ecce13a 100644 --- a/Changes +++ b/Changes @@ -35,6 +35,8 @@ indicates the contributor was also the author of the fix; Thanks! *** Add experimental --pipe-filter to filter all Verilog input. +*** Add experimental config files to filter warnings outside of the source. + *** Speed compiles by avoiding including the STL iostream header. Application programs may need to include it themselves to avoid errors. diff --git a/bin/verilator b/bin/verilator index 8fcbffc79..5a2a8dd36 100755 --- a/bin/verilator +++ b/bin/verilator @@ -182,6 +182,8 @@ C++, and linked with the Verilated files. The resulting executable will perform the actual simulation. +To get started, jump down to "EXAMPLE C++ EXECUTION". + =head1 ARGUMENT SUMMARY This is a short summary of the arguments to Verilator. See the detailed @@ -1186,7 +1188,7 @@ Lower modules are not pure SystemC code. This is a feature, as using the SystemC pin interconnect scheme everywhere would reduce performance by an order of magnitude. -=head1 DPI (DIRECT PROGRAMMING INTERFACE) +=head1 DIRECT PROGRAMMING INTERFACE (DPI) Verilator supports SystemVerilog Direct Programming Interface import and export statements. Only the SystemVerilog form ("DPI-C") is supported, not @@ -1288,21 +1290,61 @@ The target system may also require edits to the Makefiles, the simple Makefiles produced by Verilator presume the target system is the same type as the build system. +=head1 CONFIGURATION FILES + +In addition to the command line, warnings and other features may be +controlled by configuration files, typically named with the .vlt +extension. An example: + + `verilator_config + lint_off -msg WIDTH + lint_off -msg CASEX -file "silly_vendor_code.v" + +This disables WIDTH warnings globally, and CASEX for a specific file. + +Configuration files are parsed after the normal Verilog preprocessing, so +`ifdefs, `defines, and comments may be used as if it were normal Verilog +code. + +The grammar of configuration commands is as follows: + +=over 4 + +=item `verilator_config + +Take remaining text up the the next `verilog mode switch and treat it as +Verilator configuration commands. + +=item coverage_off [-file "" [-lines [ - ]]] + +Disable coverage for the specified filename (or all files if ommitted) and +range of line numbers (or all lines if ommitted). Often used to ignore an +entire module for coverage analysis purposes. + +=item lint_off -msg [-file "" [-lines [ - ]]] + +Disables the specified lint warning in the specified filename (or all files +if ommitted) and range of line numbers (or all lines if ommitted). + +=item tracing_off [-file "" [-lines [ - ]]] + +Disable waveform tracing for all future signals declared in the specified +filename (or all files if ommitted) and range of line numbers (or all lines +if ommitted). + +=back + =head1 VERILOG 2001 (IEEE 1364-2001) SUPPORT -Verilator supports almost all Verilog 2001 language features. This -includes signed numbers, "always @*", comma separated sensitivity lists, -generate statements, multidimensional arrays, localparam, and C-style -declarations inside port lists. +Verilator supports most Verilog 2001 language features. This includes +signed numbers, "always @*", generate statements, multidimensional arrays, +localparam, and C-style declarations inside port lists. =head1 VERILOG 2005 (IEEE 1364-2005) SUPPORT -Verilator supports the `begin_keywords and `end_keywords compiler -directives. - -Verilator supports $clog2. - -Verilator partially supports the uwire keyword. +Verilator supports most Verilog 2005 language features. This includes the +`begin_keywords and `end_keywords compiler directives, $clog2, and the +uwire keyword. =head1 SYSTEMVERILOG 2005 (IEEE 1800-2005) SUPPORT @@ -1489,6 +1531,11 @@ code. The VERILATOR, verilator and verilator3 defines are set by default so you may `ifdef around compiler specific constructs. +=item `verilator_config + +Take remaining text up the the next `verilog mode switch and treat it as +Verilator configuration commands. + =item `verilog Switch back to processing Verilog code after a `systemc_... mode switch. diff --git a/src/Makefile_obj.in b/src/Makefile_obj.in index 07e9d626d..a729a4f51 100644 --- a/src/Makefile_obj.in +++ b/src/Makefile_obj.in @@ -161,6 +161,7 @@ RAW_OBJS = \ V3ClkGater.o \ V3Clock.o \ V3Combine.o \ + V3Config.o \ V3Const__gen.o \ V3Coverage.o \ V3CoverageJoin.o \ diff --git a/src/V3Config.cpp b/src/V3Config.cpp new file mode 100644 index 000000000..d2cce953c --- /dev/null +++ b/src/V3Config.cpp @@ -0,0 +1,145 @@ +//************************************************************************* +// DESCRIPTION: Verilator: Configuration Files +// +// Code available from: http://www.veripool.org/verilator +// +// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli +// +//************************************************************************* +// +// Copyright 2010-2010 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. +// +// Verilator is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +//************************************************************************* + +#include "config_build.h" +#include "verilatedos.h" +#include +#include +#include + +#include "V3Global.h" +#include "V3Config.h" + +//###################################################################### + +class V3ConfigLine { +public: + int m_lineno; // Line number to make change at + V3ErrorCode m_code; // Error code + bool m_on; // True to enaable message + V3ConfigLine(V3ErrorCode code, int lineno, bool on) + : m_lineno(lineno), m_code(code), m_on(on) {} + ~V3ConfigLine() {} + inline bool operator< (const V3ConfigLine& rh) const { + if (m_linenorh.m_lineno) return false; + if (m_coderh.m_code) return false; + // Always turn "on" before "off" so that overlapping lines will end up finally with the error "off" + return (m_on>rh.m_on); + } +}; +ostream& operator<<(ostream& os, V3ConfigLine rhs) { return os< IgnLines; // list of {line,code,on} + typedef map IgnFiles; // {filename} => list of {line,code,on} + + // MEMBERS + string m_lastFilename; // Last filename looked up + int m_lastLineno; // Last linenumber looked up + + IgnLines::const_iterator m_lastIt; // Point with next linenumber > current line number + IgnLines::const_iterator m_lastEnd; // Point with end() + + IgnFiles m_ignFiles; // Ignores for each filename + + static V3ConfigIgnores s_singleton; // Singleton (not via local static, as that's slow) + + V3ConfigIgnores() { m_lastLineno = -1; } + ~V3ConfigIgnores() {} + + // METHODS + inline IgnLines* findLines(const string& filename) { + IgnFiles::iterator it = m_ignFiles.find(filename); + if (it != m_ignFiles.end()) { + return &(it->second); + } else { + m_ignFiles.insert(make_pair(filename, IgnLines())); + it = m_ignFiles.find(filename); + return &(it->second); + } + } + inline void absBuild(const string& filename) { + // Given a filename, find all wildcard matches against it and build + // hash with the specific filename. This avoids having to wildmatch + // more than once against any filename. + IgnLines* linesp = findLines(filename); + m_lastIt = linesp->begin(); + m_lastEnd = linesp->end(); + } + +public: + inline static V3ConfigIgnores& singleton() { return s_singleton; } + + void addIgnore(V3ErrorCode code, string filename, int lineno, bool on) { + // Insert + IgnLines* linesp = findLines(filename); + UINFO(9,"config addIgnore "<insert(V3ConfigLine(code, lineno, on)); + if (m_lastFilename == filename) { + // Flush the match cache, due to a change in the rules. + m_lastFilename = " "; + } + } + inline void applyIgnores(FileLine* filelinep) { + // HOT routine, called each parsed token line + if (m_lastLineno != filelinep->lineno() + || m_lastFilename != filelinep->filename()) { + //UINFO(9," ApplyIgnores for "<ascii()<filename())) { + absBuild(filelinep->filename()); + m_lastFilename = filelinep->filename(); + } + // Process all on/offs for lines up to and including the current line + int curlineno = filelinep->lineno(); + for (; m_lastIt != m_lastEnd; ++m_lastIt) { + if (m_lastIt->m_lineno > curlineno) break; + //UINFO(9," Hit "<<*m_lastIt<warnOn(m_lastIt->m_code, m_lastIt->m_on); + } + if (0 && debug() >= 9) { + for (IgnLines::const_iterator it=m_lastIt; it != m_lastEnd; ++it) { + UINFO(9," NXT "<<*it<lineno(); + } + } +}; + +V3ConfigIgnores V3ConfigIgnores::s_singleton; + +//###################################################################### +// V3Config + +void V3Config::addIgnore(V3ErrorCode code, string filename, int min, int max) { + if (filename=="*") { + FileLine::globalWarnOff(code,true); + } else { + V3ConfigIgnores::singleton().addIgnore(code, filename, min, false); + if (max) V3ConfigIgnores::singleton().addIgnore(code, filename, max, true); + } +} + +void V3Config::applyIgnores(FileLine* filelinep) { + V3ConfigIgnores::singleton().applyIgnores(filelinep); +} diff --git a/src/V3Config.h b/src/V3Config.h new file mode 100644 index 000000000..e88077e15 --- /dev/null +++ b/src/V3Config.h @@ -0,0 +1,38 @@ +// -*- C++ -*- +//************************************************************************* +// DESCRIPTION: Verilator: Configuration Files +// +// Code available from: http://www.veripool.org/verilator +// +// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli +// +//************************************************************************* +// +// Copyright 2010-2010 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. +// +// Verilator is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +//************************************************************************* + +#ifndef _V3CONFIG_H_ +#define _V3CONFIG_H_ 1 +#include "config_build.h" +#include "verilatedos.h" +#include +#include "V3Error.h" + +//###################################################################### + +class V3Config { +public: + static void addIgnore(V3ErrorCode code, string filename, int min, int max); + static void applyIgnores(FileLine* filelinep); +}; + +#endif // Guard diff --git a/src/V3Error.cpp b/src/V3Error.cpp index 65a3402e1..ca0a28cc5 100644 --- a/src/V3Error.cpp +++ b/src/V3Error.cpp @@ -28,6 +28,7 @@ # include "V3Ast.h" # include "V3Global.h" # include "V3Stats.h" +# include "V3Config.h" #endif //====================================================================== @@ -126,6 +127,9 @@ FileLine* FileLine::copyOrSameFileLine() { // Return this, or a copy of this // There are often more than one token per line, thus we use the // same pointer as long as we're on the same line, file & warn state. +#ifndef _V3ERROR_NO_GLOBAL_ + V3Config::applyIgnores(this); // Toggle warnings based on global config file +#endif static FileLine* lastNewp = NULL; if (lastNewp && *lastNewp == *this) { // Compares lineno, filename, etc return lastNewp; diff --git a/src/V3Error.h b/src/V3Error.h index 7d2a68ab4..aea6accdb 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -248,13 +248,13 @@ public: static void* operator new(size_t size); static void operator delete(void* obj, size_t size); #endif - static FileLine& defaultFileLine() { return s_defaultFileLine; } int lineno () const { return m_lineno; } string ascii() const; const string filename () const { return m_filename; } const string filebasename () const; const string profileFuncname() const; - void warnOff(V3ErrorCode code, bool flag) { m_warnOn.set(code,!flag); } // Turn on/off warning messages on this line. + void warnOn(V3ErrorCode code, bool flag) { m_warnOn.set(code,flag); } // Turn on/off warning messages on this line. + void warnOff(V3ErrorCode code, bool flag) { warnOn(code,!flag); } bool warnOff(const string& code, bool flag); // Returns 1 if ok bool warnIsOff(V3ErrorCode code) const; void warnLintOff(bool flag); @@ -263,9 +263,14 @@ public: // Specific flag ACCESSORS/METHODS bool coverageOn() const { return m_warnOn.test(V3ErrorCode::I_COVERAGE); } - void coverageOn(bool flag) { m_warnOn.set(V3ErrorCode::I_COVERAGE,flag); } + void coverageOn(bool flag) { warnOn(V3ErrorCode::I_COVERAGE,flag); } bool tracingOn() const { return m_warnOn.test(V3ErrorCode::I_TRACING); } - void tracingOn(bool flag) { m_warnOn.set(V3ErrorCode::I_TRACING,flag); } + void tracingOn(bool flag) { warnOn(V3ErrorCode::I_TRACING,flag); } + + // METHODS - Global + static void globalWarnLintOff(bool flag) { s_defaultFileLine.warnLintOff(flag); } + static void globalWarnOff(V3ErrorCode code, bool flag) { s_defaultFileLine.warnOff(code, flag); } + static bool globalWarnOff(const string& code, bool flag) { return s_defaultFileLine.warnOff(code, flag); } // METHODS - Called from netlist // Merge warning disables from another fileline diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 4bf2ea915..7dc067eb2 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -748,22 +748,22 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) { } else if ( !strncmp (sw, "-Wno-",5) ) { if (!strcmp (sw, "-Wno-lint")) { - FileLine::defaultFileLine().warnLintOff(true); + FileLine::globalWarnLintOff(true); } else { string msg = sw+strlen("-Wno-"); - if (!(FileLine::defaultFileLine().warnOff(msg, true))) { + if (!(FileLine::globalWarnOff(msg, true))) { fl->v3fatal("Unknown warning specified: "<v3fatal("Unknown warning specified: "<.|\n {BEGIN STATE_VERILOG_RECENT; yyless(0); } + /************************************************************************/ + /* Verilator control files */ +{ + {ws} { } /* otherwise ignore white-space */ + {crnl} { NEXTLINE(); } /* Count line numbers */ + + "coverage_off" { FL; return yVLT_COVERAGE_OFF; } + "lint_off" { FL; return yVLT_LINT_OFF; } + "tracing_off" { FL; return yVLT_TRACING_OFF; } + + -?"-file" { FL; return yVLT_D_FILE; } + -?"-lines" { FL; return yVLT_D_LINES; } + -?"-msg" { FL; return yVLT_D_MSG; } +} + + /************************************************************************/ /* Verilog 1995 */ { {ws} { } /* otherwise ignore white-space */ @@ -723,7 +739,7 @@ escid \\[^ \t\f\r\n]+ } /* Identifiers and numbers */ -{ +{ {escid} { FL; yylval.strp = PARSEP->newString (AstNode::encodeName(string(yytext+1))); // +1 to skip the backslash return yaID__LEX; @@ -813,7 +829,7 @@ escid \\[^ \t\f\r\n]+ /* Preprocessor */ /* Common for all SYSC header states */ /* OPTIMIZE: we return one per line, make it one for the entire block */ -{ +{ "`accelerate" { } // Verilog-XL compatibility "`autoexpand_vectornets" { } // Verilog-XL compatibility "`celldefine" { PARSEP->inCellDefine(true); } @@ -861,6 +877,7 @@ escid \\[^ \t\f\r\n]+ "`systemc_imp_header" { BEGIN SYSCIMPH; } "`systemc_implementation" { BEGIN SYSCIMP; } "`systemc_interface" { BEGIN SYSCINT; } + "`verilator_config" { BEGIN VLT; } "`verilog" { BEGIN PARSEP->lastVerilogState(); } } @@ -881,7 +898,7 @@ escid \\[^ \t\f\r\n]+ /************************************************************************/ /* Default rules - leave last */ -{ +{ "`"[a-zA-Z_0-9]+ { FL; yyerrorf("Define or directive not defined: %s",yytext); } "//"[^\n]* { } /* throw away single line comments */ . { FL; return yytext[0]; } /* return single char ops. */ diff --git a/src/verilog.y b/src/verilog.y index faad7dfbb..240771f5e 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -28,6 +28,7 @@ #include "V3Ast.h" #include "V3Global.h" +#include "V3Config.h" #include "V3ParseImp.h" // Defines YYTYPE; before including bison header #define YYERROR_VERBOSE 1 @@ -211,6 +212,14 @@ class AstSenTree; %token yaSCCTOR "`systemc_implementation BLOCK" %token yaSCDTOR "`systemc_imp_header BLOCK" +%token yVLT_COVERAGE_OFF "coverage_off" +%token yVLT_LINT_OFF "lint_off" +%token yVLT_TRACING_OFF "tracing_off" + +%token yVLT_D_FILE "--file" +%token yVLT_D_LINES "--lines" +%token yVLT_D_MSG "--msg" + %token yaD_IGNORE "${ignored-bbox-sys}" %token yaD_DPI "${dpi-sys}" @@ -578,6 +587,8 @@ description: // ==IEEE: description | package_item { if ($1) GRAMMARP->unitPackage($1->fileline())->addStmtp($1); } //UNSUP bind_directive { } // unsupported // IEEE: config_declaration + // Verilator only + | vltItem { } | error { } ; @@ -2980,6 +2991,24 @@ pslExpr: | yTRUE { $$ = new AstPslBool($1, new AstConst($1, AstConst::LogicTrue())); } ; +//********************************************************************** +// VLT Files + +vltItem: + vltOffFront { V3Config::addIgnore($1,"*",0,0); } + | vltOffFront yVLT_D_FILE yaSTRING { V3Config::addIgnore($1,*$3,0,0); } + | vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM { V3Config::addIgnore($1,*$3,$5->toUInt(),$5->toUInt()+1); } + | vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM { V3Config::addIgnore($1,*$3,$5->toUInt(),$7->toUInt()+1); } + ; + +vltOffFront: + yVLT_COVERAGE_OFF { $$ = V3ErrorCode::I_COVERAGE; } + | yVLT_TRACING_OFF { $$ = V3ErrorCode::I_TRACING; } + | yVLT_LINT_OFF yVLT_D_MSG yaID__ETC + { $$ = V3ErrorCode((*$3).c_str()); + if ($$ == V3ErrorCode::ERROR) { $1->v3error("Unknown Error Code: "<<*$3< 0, + make_main => 0, + verilator_make_gcc => 0, + v_flags2 => ["--lint-only t/t_vlt_warn.vlt"], + ) if $Self->{v3}; + +ok(1); +1; diff --git a/test_regress/t/t_vlt_warn.v b/test_regress/t/t_vlt_warn.v new file mode 100644 index 000000000..97559d71e --- /dev/null +++ b/test_regress/t/t_vlt_warn.v @@ -0,0 +1,29 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2010 by Wilson Snyder. + +// Try inline config +`ifdef verilator + `verilator_config + lint_off -msg CASEX -file "t/t_vlt_warn.v" + `verilog +`endif + + + + + +module t; + reg width_warn_var_line18 = 2'b11; // Width warning - must be line 18 + reg width_warn2_var_line19 = 2'b11; // Width warning - must be line 19 + + initial begin + casex (1'b1) + 1'b0: $stop; + endcase + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_vlt_warn.vlt b/test_regress/t/t_vlt_warn.vlt new file mode 100644 index 000000000..6c8eda2a6 --- /dev/null +++ b/test_regress/t/t_vlt_warn.vlt @@ -0,0 +1,14 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2010 by Wilson Snyder. + +`verilator_config + +lint_off -msg CASEINCOMPLETE -file "t/t_vlt_warn.v" +lint_off -msg WIDTH -file "t/t_vlt_warn.v" -lines 18 +lint_off -msg WIDTH -file "t/t_vlt_warn.v" -lines 19-19 + +coverage_off -file "t/t_vlt_warn.v" +// Test --flag is also accepted +tracing_off --file "t/t_vlt_warn.v"