Add lint_off -match waivers (#2102)

* Add more directives to configuration files

Allow to set the same directives in configuration files that can also
be set by comment attributes (such as /* verilator public */ etc).

* Add support for lint messsage waivers

Add configuration file switch '-match' for lint_off. It takes a string
with wildcards allowed and warnings will be matched against it (if
rule and file also match). If it matches, the warning is waived.

Fixes #1649 and #1514 
Closes #2072
This commit is contained in:
Stefan Wallentowitz 2020-01-12 10:03:17 +01:00 committed by GitHub
parent 98fb7ec193
commit fad465abf1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
89 changed files with 1676 additions and 294 deletions

View File

@ -5,6 +5,10 @@ The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 4.027 devel
** Support attributes (public, isolate_assignments, etc.) in configuration files.
** Add -match to lint_off to waive warnings. [Philipp Wagner]
**** Add error on misused define. [Topa Tota]

View File

@ -2769,6 +2769,8 @@ purposes.
=item lint_off [-rule <message>] [-file "<filename>" [-lines <line> [ - <line>]]]
=item lint_off [-rule <message>] [-file "<filename>"] [-match "<string>"]
Enable/disables the specified lint warning, in the specified filename (or
wildcard with '*' or '?', or all files if omitted) and range of line
numbers (or all lines if omitted).
@ -2780,6 +2782,10 @@ If the -rule is omitted, all lint warnings (see list in -Wno-lint) are
enabled/disabled. This will override all later lint warning enables for
the specified region.
If -match is set the linter warnings are matched against this (wildcard)
string and are waived in case they match iff rule and file (with wildcard)
also match.
In previous versions -rule was named -msg. The latter is deprecated, but
still works with a deprecation info, it may be removed in future versions.
@ -2794,6 +2800,124 @@ and range of line numbers (or all lines if omitted).
For tracing_off, cells below any module in the files/ranges specified will
also not be traced.
=item clock_enable -module "<modulename>" -signal "<signame>"
Indicate the signal is used to gate a clock, and the user takes responsibility
for insuring there are no races related to it.
Same as /*verilator clock_enable*/, see L</"LANGUAGE EXTENSIONS"> for
more information and an example.
=item clocker -module "<modulename>" [-task "<taskname>"] -signal "<signame>"
=item clocker -module "<modulename>" [-function "<funcname>"] -signal "<signame>"
=item no_clocker -module "<modulename>" [-task "<taskname>"] -signal "<signame>"
=item no_clocker -module "<modulename>" [-function "<funcname>"] -signal "<signame>"
Indicate the signal is used as clock or not. This information is used by
Verilator to mark the signal as clocker and propagate the clocker attribute
automatically to derived signals. See C<--clk> for more information.
Same as /*verilator clocker*/, see L</"LANGUAGE EXTENSIONS"> for more
information.
=item coverage_block_off -module "<modulename>" -block "<blockname>"
=item coverage_block_off -file "<filename>" -line <lineno>
Specifies the entire begin/end block should be ignored for coverage
analysis purposes. Can either be specified as a named block or as a
filename and line number.
Same as /*verilator coverage_block_off*/, see L</"LANGUAGE
EXTENSIONS"> for more information.
=item full_case -file "<filename>" -lines <lineno>
=item parallel_case -file "<filename>" -lines <lineno>
Same as "//synopsys full_case" and "//synopsys parallel_case". When
these synthesis directives are discovered, Verilator will either
formally prove the directive to be true, or failing that, will insert
the appropriate code to detect failing cases at simulation runtime and
print an "Assertion failed" error message.
=item inline -module "<modulename>"
Specifies the module may be inlined into any modules that use this
module. This is useful to speed up simulation runtime with some small
loss of trace visibility and modularity. Note signals under inlined
submodules will be named I<submodule>__DOT__I<subsignal> as C++ does
not allow "." in signal names. When tracing such signals the tracing
routines will replace the __DOT__ with the period.
Same as /*verilator inline_module*/, see L</"LANGUAGE EXTENSIONS"> for
more information.
=item isolate_assignments -module "<modulename>" [-task "<taskname>"] -signal "<signame>"
=item isolate_assignments -module "<modulename>" [-function "<funcname>"] -signal "<signame>"
=item isolate_assignments -module "<modulename>" -function "<fname>"
Used to indicate the assignments to this signal in any blocks should be
isolated into new blocks. When there is a large combinatorial block that
is resulting in a UNOPTFLAT warning, attaching this to the signal causing
a false loop may clear up the problem.
Same as /* verilator isolate_assignments */, see L</"LANGUAGE
EXTENSIONS"> for more information.
=item no_inline -module "<modulename>"
Specifies the module should not be inlined into any modules that use
this module. This is useful especially at the top level module to
reduce the size of the interface class, to aid compile time at a small
performance loss.
Same as /*verilator no_inline_module*/, see L</"LANGUAGE EXTENSIONS">
for more information.
=item no_inline [-module "<modulename>"] -task "<taskname>"
=item no_inline [-module "<modulename>"] -function "<funcname>"
Specify the function or task should not be inlined into where it is
used. This may reduce the size of the final executable when a task is
used a very large number of times. For this flag to work, the task
and tasks below it must be pure; they cannot reference any variables
outside the task itself.
Same as /*verilator no_inline_task*/, see L</"LANGUAGE EXTENSIONS">
for more information.
=item sc_bv -module "<modulename>" [-task "<taskname>"] -signal "<signame>"
=item sc_bv -module "<modulename>" [-function "<funcname>"] -signal "<signame>"
Sets the port to be of sc_bv<I<width>> type, instead of bool, vluint32_t or
vluint64_t. This may be useful if the port width is parameterized and
different of such modules interface a templated module (such as a transactor)
or for other reasons. In general you should avoid using this attribute when
not necessary as with increasing usage of sc_bv the performance decreases
significantly.
Same as /*verilator sc_bv*/, see L</"LANGUAGE EXTENSIONS"> for more
information.
=item sformat [-module "<modulename>"] [-task "<taskname>"] -signal "<signame>"
=item sformat [-module "<modulename>"] [-function "<funcname>"] -signal "<signame>"
Final input of a function or task "input string" to indicate the
function or task should pass all remaining arguments through
$sformatf. This allows creation of DPI functions with $display like
behavior. See the test_regress/t/t_dpi_display.v file for an example.
Same as /*verilator sformat*/, see L</"LANGUAGE EXTENSIONS"> for more
information.
=back
@ -2929,7 +3053,8 @@ per the C standard (it's unspecified in Verilog).
Specifies the entire begin/end block should be ignored for coverage
analysis. Must be inside a basic block, e.g. within a begin/end pair.
Same as /* verilator coverage_block_off */.
Same as /* verilator coverage_block_off */ and C<coverage_block_off> in
L</"CONFIGURATION FILES">.
=item `systemc_header
@ -3021,6 +3146,9 @@ scheduling algorithm, sometimes required for correct clock behavior, and
always improving performance. It's also a good idea to enable the
IMPERFECTSCH warning, to insure all clock enables are properly recognized.
Same as C<clock_enable> in configuration files, see L</"CONFIGURATION
FILES"> for more information.
=item /*verilator clocker*/
=item /*verilator no_clocker*/
@ -3030,11 +3158,17 @@ not. This information is used by Verilator to mark the signal as clocker
and propagate the clocker attribute automatically to derived signals. See
C<--clk> for more information.
Same as C<clocker> and C<no_clocker> in configuration files, see
L</"CONFIGURATION FILES"> for more information.
=item /*verilator coverage_block_off*/
Specifies the entire begin/end block should be ignored for coverage
analysis purposes.
Same as C<coverage_block_off> in configuration files, see
L</"CONFIGURATION FILES"> for more information.
=item /*verilator coverage_off*/
Specifies that following lines of code should have coverage disabled.
@ -3055,6 +3189,9 @@ submodules will be named I<submodule>__DOT__I<subsignal> as C++ does not
allow "." in signal names. When tracing such signals the tracing routines
will replace the __DOT__ with the period.
Same as C<inline> in configuration files, see L</"CONFIGURATION FILES">
for more information.
=item /*verilator isolate_assignments*/
Used after a signal declaration to indicate the assignments to this signal
@ -3091,6 +3228,9 @@ It would then internally break it into (sort of):
end
end
Same as C<isolate_assignments> in configuration files, see
L</"CONFIGURATION FILES"> for more information.
=item /*verilator lint_off I<msg>*/
Disable the specified warning message for any warnings following the comment.
@ -3126,6 +3266,9 @@ modules that use this module. This is useful especially at the top level
module to reduce the size of the interface class, to aid compile time at a
small performance loss.
Same as C<no_inline> in configuration files, see L</"CONFIGURATION
FILES"> for more information.
=item /*verilator no_inline_task*/
Used in a function or task variable definition section to specify the
@ -3134,6 +3277,9 @@ reduce the size of the final executable when a task is used a very large
number of times. For this flag to work, the task and tasks below it must
be pure; they cannot reference any variables outside the task itself.
Same as C<no_inline> in configuration files, see L</"CONFIGURATION
FILES"> for more information.
=item /*verilator public*/ (parameter)
Used after a parameter declaration to indicate the emitted C code should
@ -3161,6 +3307,9 @@ Instead of using public variables, consider instead making a DPI or public
function that accesses the variable. This is nicer as it provides an
obvious entry point that is also compatible across simulators.
Same as C<public> in configuration files, see L</"CONFIGURATION FILES">
for more information.
=item /*verilator public*/ (task/function)
Used inside the declaration section of a function or task declaration to
@ -3183,6 +3332,9 @@ the model will NOT notice changes made to variables in these functions.
You may want to use DPI exports instead, as it's compatible with other
simulators.
Same as C<public> in configuration files, see L</"CONFIGURATION FILES">
for more information.
=item /*verilator public_flat*/ (variable)
Used after an input, output, register, or wire declaration to indicate the
@ -3191,11 +3343,17 @@ signal. This will not declare this module public, which means the name of
the signal or path to it may change based upon the module inlining which
takes place.
Same as C<public_flat> in configuration files, see L</"CONFIGURATION
FILES"> for more information.
=item /*verilator public_flat_rd*/ (variable)
Used after an input, output, register, or wire declaration to indicate the
signal should be declared public_flat (see above), but read-only.
Same as C<public_flat_rd> in configuration files, see L</"CONFIGURATION
FILES"> for more information.
=item /*verilator public_flat_rw @(<edge_list>) */ (variable)
Used after an input, output, register, or wire declaration to indicate the
@ -3204,6 +3362,9 @@ where writes should be considered to have the timing specified by the given
sensitivity edge list. Set for all variables, ports and wires using the
--public-flat-rw switch.
Same as C<public_flat_rw> in configuration files, see L</"CONFIGURATION
FILES"> for more information.
=item /*verilator public_module*/
Used after a module statement to indicate the module should not be inlined
@ -3212,9 +3373,12 @@ Verilator automatically sets this attribute when the module contains any
public signals or `systemc_ directives. Also set for all modules when
using the --public switch.
Same as C<public> in configuration files, see L</"CONFIGURATION FILES">
for more information.
=item /*verilator sc_clock*/
Rarely needed. Used after an input declaration to indicate the signal
Deprecated. Used after an input declaration to indicate the signal
should be declared in SystemC as a sc_clock instead of a bool. This was
needed in SystemC 1.1 and 1.2 only; versions 2.0 and later do not require
clock pins to be sc_clocks and this is no longer needed.
@ -3226,7 +3390,10 @@ type, instead of bool, vluint32_t or vluint64_t. This may be useful if
the port width is parameterized and different of such modules interface
a templated module (such as a transactor) or for other reasons. In general
you should avoid using this attribute when not necessary as with increasing
usage of sc_bv the performance increases significantly.
usage of sc_bv the performance decreases significantly.
Same as C<sc_bv> in configuration files, see L</"CONFIGURATION FILES">
for more information.
=item /*verilator sformat*/
@ -3235,6 +3402,9 @@ indicate the function or task should pass all remaining arguments through
$sformatf. This allows creation of DPI functions with $display like
behavior. See the test_regress/t/t_dpi_display.v file for an example.
Same as C<sformat> in configuration files, see L</"CONFIGURATION FILES">
for more information.
=item /*verilator tag <text...>*/
Attached after a variable or structure member to indicate opaque (to

View File

@ -142,7 +142,10 @@ public:
NO_INLINE_MODULE,
NO_INLINE_TASK,
PUBLIC_MODULE,
PUBLIC_TASK
PUBLIC_TASK,
FULL_CASE,
PARALLEL_CASE,
ENUM_SIZE
};
enum en m_e;
inline AstPragmaType() : m_e(ILLEGAL) {}

View File

@ -30,133 +30,491 @@
#include <string>
//######################################################################
// Resolve wildcards in files, modules, ftasks or variables
class V3ConfigLine {
// Template for a class that serves as a map for entities that can be specified
// as wildcards and are accessed by a resolved name. It rebuilds a name lookup
// cache of resolved entities. Entities stored in this container need an update
// function that takes a reference of this type to join multiple entities into one.
template <typename T> class V3ConfigWildcardResolver {
typedef std::map<string, T> Map;
Map m_mapWildcard; // Wildcard strings to entities
Map m_mapResolved; // Resolved strings to converged entities
typename Map::iterator m_last; // Last access, will probably hit again
public:
int m_lineno; // Line number to make change at
V3ErrorCode m_code; // Error code
bool m_on; // True to enable 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_lineno<rh.m_lineno) return true;
if (m_lineno>rh.m_lineno) return false;
if (m_code<rh.m_code) return true;
if (m_code>rh.m_code) return false;
V3ConfigWildcardResolver() { m_last = m_mapResolved.end(); }
/// Update into maps from other
void update(const V3ConfigWildcardResolver& other) {
typename Map::const_iterator it;
for (it = other.m_mapResolved.begin(); it != other.m_mapResolved.end(); ++it) {
m_mapResolved[it->first].update(it->second);
}
for (it = other.m_mapWildcard.begin(); it != other.m_mapWildcard.end(); ++it) {
m_mapWildcard[it->first].update(it->second);
}
}
// Access and create a (wildcard) entity
T& at(const string& name) {
// Don't store into wildcards if the name is not a wildcard string
return m_mapWildcard[name];
}
// Access an entity and resolve wildcards that match it
T* resolve(const string& name) {
// Lookup if recently accessed matches
if (VL_LIKELY(m_last != m_mapResolved.end()) && VL_LIKELY(m_last->first == name)) {
return &m_last->second;
}
// Lookup if it was resolved before, typically not
typename Map::iterator it = m_mapResolved.find(name);
if (VL_UNLIKELY(it != m_mapResolved.end())) { return &it->second; }
T* newp = NULL;
// Cannot be resolved, create if matched
// Update this entity with all matches in the wildcards
for (it = m_mapWildcard.begin(); it != m_mapWildcard.end(); ++it) {
if (VString::wildmatch(name, it->first)) {
if (!newp) {
newp = &m_mapResolved[name]; // Emplace and get pointer
}
newp->update(it->second);
}
}
return newp;
}
// Flush on update
void flush() { m_mapResolved.clear(); }
};
// Only public_flat_rw has the sensitity tree
class V3ConfigVarAttr {
public:
AstAttrType m_type; // Type of attribute
AstSenTree* m_sentreep; // Sensitivity tree for public_flat_rw
V3ConfigVarAttr(AstAttrType type, AstSenTree* sentreep)
: m_type(type)
, m_sentreep(sentreep) {}
};
// Overload vector with the required update function and to apply all entries
class V3ConfigVar : public std::vector<V3ConfigVarAttr> {
public:
// Update from other by copying all attributes
void update(const V3ConfigVar& node) {
reserve(size() + node.size());
insert(end(), node.begin(), node.end());
}
// Apply all attributes to the variable
void apply(AstVar* varp) {
for (const_iterator it = begin(); it != end(); ++it) {
AstNode* newp = new AstAttrOf(varp->fileline(), it->m_type);
varp->addAttrsp(newp);
if (it->m_type == AstAttrType::VAR_PUBLIC_FLAT_RW && it->m_sentreep) {
newp->addNext(new AstAlwaysPublic(varp->fileline(), it->m_sentreep, NULL));
}
}
}
};
typedef V3ConfigWildcardResolver<V3ConfigVar> V3ConfigVarResolver;
//######################################################################
// Function or task: Have variables and properties
class V3ConfigFTask {
V3ConfigVarResolver m_vars; // Variables in function/task
bool m_isolate; // Isolate function return
bool m_noinline; // Don't inline function/task
bool m_public; // Public function/task
public:
V3ConfigFTask()
: m_isolate(false)
, m_noinline(false)
, m_public(false) {}
void update(const V3ConfigFTask& f) {
// Don't overwrite true with false
if (f.m_isolate) m_isolate = true;
if (f.m_noinline) m_noinline = true;
if (f.m_public) m_public = true;
m_vars.update(f.m_vars);
}
V3ConfigVarResolver& vars() { return m_vars; }
void setIsolate(bool set) { m_isolate = set; }
void setNoInline(bool set) { m_noinline = set; }
void setPublic(bool set) { m_public = set; }
void apply(AstNodeFTask* ftaskp) {
if (m_noinline)
ftaskp->addStmtsp(new AstPragma(ftaskp->fileline(), AstPragmaType::NO_INLINE_TASK));
if (m_public)
ftaskp->addStmtsp(new AstPragma(ftaskp->fileline(), AstPragmaType::PUBLIC_TASK));
// Only functions can have isolate (return value)
if (VN_IS(ftaskp, Func)) ftaskp->attrIsolateAssign(m_isolate);
}
};
typedef V3ConfigWildcardResolver<V3ConfigFTask> V3ConfigFTaskResolver;
//######################################################################
// Modules have tasks, variables, named blocks and properties
class V3ConfigModule {
typedef std::unordered_set<string> StringSet;
V3ConfigFTaskResolver m_tasks; // Functions/tasks in module
V3ConfigVarResolver m_vars; // Variables in module
StringSet m_coverageOffBlocks; // List of block names for coverage_off
bool m_inline; // Whether to force the inline
bool m_inlineValue; // The inline value (on/off)
bool m_public; // Public module
public:
V3ConfigModule()
: m_inline(false)
, m_inlineValue(false)
, m_public(false) {}
void update(const V3ConfigModule& m) {
m_tasks.update(m.m_tasks);
m_vars.update(m.m_vars);
for (StringSet::const_iterator it = m.m_coverageOffBlocks.begin();
it != m.m_coverageOffBlocks.end(); ++it) {
m_coverageOffBlocks.insert(*it);
}
if (!m_inline) {
m_inline = m.m_inline;
m_inlineValue = m.m_inlineValue;
}
if (!m_public) m_public = m.m_public;
}
V3ConfigFTaskResolver& ftasks() { return m_tasks; }
V3ConfigVarResolver& vars() { return m_vars; }
void addCoverageBlockOff(const string& name) { m_coverageOffBlocks.insert(name); }
void setInline(bool set) {
m_inline = true;
m_inlineValue = set;
}
void setPublic(bool set) { m_public = set; }
void apply(AstNodeModule* modp) {
if (m_inline) {
AstPragmaType type
= m_inlineValue ? AstPragmaType::INLINE_MODULE : AstPragmaType::NO_INLINE_MODULE;
AstNode* nodep = new AstPragma(modp->fileline(), type);
modp->addStmtp(nodep);
}
if (m_public) {
AstNode* nodep = new AstPragma(modp->fileline(), AstPragmaType::PUBLIC_MODULE);
modp->addStmtp(nodep);
}
}
void applyBlock(AstBegin* nodep) {
AstPragmaType pragma = AstPragmaType::COVERAGE_BLOCK_OFF;
if (!nodep->unnamed()) {
for (StringSet::const_iterator it = m_coverageOffBlocks.begin();
it != m_coverageOffBlocks.end(); ++it) {
if (VString::wildmatch(nodep->name(), *it)) {
nodep->addStmtsp(new AstPragma(nodep->fileline(), pragma));
}
}
}
}
};
typedef V3ConfigWildcardResolver<V3ConfigModule> V3ConfigModuleResolver;
//######################################################################
// Files have:
// - Line ignores (lint/coverage/tracing on/off)
// - Line attributes: Attributes attached to lines
// lint/coverage/tracing on/off
class V3ConfigIgnoresLine {
public:
int m_lineno; // Line number to make change at
V3ErrorCode m_code; // Error code
bool m_on; // True to enable message
V3ConfigIgnoresLine(V3ErrorCode code, int lineno, bool on)
: m_lineno(lineno)
, m_code(code)
, m_on(on) {}
~V3ConfigIgnoresLine() {}
inline bool operator<(const V3ConfigIgnoresLine& rh) const {
if (m_lineno < rh.m_lineno) return true;
if (m_lineno > rh.m_lineno) return false;
if (m_code < rh.m_code) return true;
if (m_code > rh.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);
return (m_on > rh.m_on);
}
};
std::ostream& operator<<(std::ostream& os, V3ConfigLine rhs) {
return os<<rhs.m_lineno<<", "<<rhs.m_code<<", "<<rhs.m_on; }
std::ostream& operator<<(std::ostream& os, V3ConfigIgnoresLine rhs) {
return os << rhs.m_lineno << ", " << rhs.m_code << ", " << rhs.m_on;
}
class V3ConfigIgnores {
typedef std::multiset<V3ConfigLine> IgnLines; // list of {line,code,on}
typedef std::map<string,IgnLines> IgnFiles; // {filename} => list of {line,code,on}
// Some attributes are attached to entities of the occur on a fileline
// and multiple attributes can be attached to a line
typedef std::bitset<AstPragmaType::ENUM_SIZE> V3ConfigLineAttribute;
// MEMBERS
string m_lastFilename; // Last filename looked up
int m_lastLineno; // Last linenumber looked up
// File entity
class V3ConfigFile {
typedef std::map<int, V3ConfigLineAttribute> LineAttrMap; // Map line->bitset of attributes
typedef std::multiset<V3ConfigIgnoresLine> IgnLines; // list of {line,code,on}
typedef std::pair<V3ErrorCode, string> WaiverSetting; // Waive code if string matches
typedef std::vector<WaiverSetting> Waivers; // List of {code,wildcard string}
IgnLines::const_iterator m_lastIt; // Point with next linenumber > current line number
IgnLines::const_iterator m_lastEnd; // Point with end()
LineAttrMap m_lineAttrs; // Atributes to line mapping
IgnLines m_ignLines; // Ignore line settings
Waivers m_waivers; // Waive messages
IgnFiles m_ignWilds; // Ignores for each wildcarded filename
IgnFiles m_ignFiles; // Ignores for each non-wildcarded filename
struct {
int lineno; // Last line number
IgnLines::const_iterator it; // Point with next linenumber > current line number
} m_lastIgnore; // Last ignore line run
static V3ConfigIgnores s_singleton; // Singleton (not via local static, as that's slow)
V3ConfigIgnores() { m_lastLineno = -1; }
~V3ConfigIgnores() {}
// METHODS
inline IgnLines* findWilds(const string& wildname) {
IgnFiles::iterator it = m_ignWilds.find(wildname);
if (it != m_ignWilds.end()) {
return &(it->second);
} else {
m_ignWilds.insert(make_pair(wildname, IgnLines()));
it = m_ignWilds.find(wildname);
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.
IgnFiles::iterator it = m_ignFiles.find(filename);
if (it == m_ignFiles.end()) {
// Haven't seen this filename before
m_ignFiles.insert(make_pair(filename, IgnLines()));
it = m_ignFiles.find(filename);
// Make new list for this file of all matches
for (IgnFiles::iterator fnit = m_ignWilds.begin(); fnit != m_ignWilds.end(); ++fnit) {
if (VString::wildmatch(filename.c_str(), fnit->first.c_str())) {
for (IgnLines::iterator lit = fnit->second.begin();
lit != fnit->second.end(); ++lit) {
it->second.insert(*lit);
}
}
}
}
m_lastIt = it->second.begin();
m_lastEnd = it->second.end();
// Match a given line and attribute to the map, line 0 is any
bool lineMatch(int lineno, AstPragmaType type) {
if (m_lineAttrs.find(0) != m_lineAttrs.end() && m_lineAttrs[0][type]) return true;
if (m_lineAttrs.find(lineno) == m_lineAttrs.end()) return false;
return m_lineAttrs[lineno][type];
}
public:
inline static V3ConfigIgnores& singleton() { return s_singleton; }
V3ConfigFile() { m_lastIgnore = {-1, m_ignLines.begin()}; }
void addIgnore(V3ErrorCode code, const string& wildname, int lineno, bool on) {
// Insert
IgnLines* linesp = findWilds(wildname);
UINFO(9,"config addIgnore "<<wildname<<":"<<lineno<<", "<<code<<", "<<on<<endl);
linesp->insert(V3ConfigLine(code, lineno, on));
// Flush the match cache, due to a change in the rules.
m_ignFiles.clear();
m_lastFilename = " ";
void update(const V3ConfigFile& file) {
// Copy in all Attributes
for (LineAttrMap::const_iterator it = file.m_lineAttrs.begin();
it != file.m_lineAttrs.end(); ++it) {
m_lineAttrs[it->first] |= it->second;
}
// Copy in all ignores
for (IgnLines::const_iterator it = file.m_ignLines.begin(); it != file.m_ignLines.end();
++it) {
m_ignLines.insert(*it);
}
// Update the iterator after the list has changed
m_lastIgnore.it = m_ignLines.begin();
m_waivers.reserve(m_waivers.size() + file.m_waivers.size());
m_waivers.insert(m_waivers.end(), file.m_waivers.begin(), file.m_waivers.end());
}
void addLineAttribute(int lineno, AstPragmaType attr) { m_lineAttrs[lineno].set(attr); }
void addIgnore(V3ErrorCode code, int lineno, bool on) {
m_ignLines.insert(V3ConfigIgnoresLine(code, lineno, on));
m_lastIgnore.it = m_ignLines.begin();
}
void addWaiver(V3ErrorCode code, const string& match) {
m_waivers.push_back(make_pair(code, match));
}
void applyBlock(AstBegin* nodep) {
// Apply to block at this line
AstPragmaType pragma = AstPragmaType::COVERAGE_BLOCK_OFF;
if (lineMatch(nodep->fileline()->lineno(), pragma)) {
nodep->addStmtsp(new AstPragma(nodep->fileline(), pragma));
}
}
void applyCase(AstCase* nodep) {
// Apply to this case at this line
int lineno = nodep->fileline()->lineno();
if (lineMatch(lineno, AstPragmaType::FULL_CASE)) nodep->fullPragma(true);
if (lineMatch(lineno, AstPragmaType::PARALLEL_CASE)) nodep->parallelPragma(true);
}
inline void applyIgnores(FileLine* filelinep) {
// HOT routine, called each parsed token line
if (m_lastLineno != filelinep->lastLineno()
|| m_lastFilename != filelinep->filename()) {
//UINFO(9," ApplyIgnores for "<<filelinep->ascii()<<endl);
if (VL_UNLIKELY(m_lastFilename != filelinep->filename())) {
absBuild(filelinep->filename());
m_lastFilename = filelinep->filename();
}
// HOT routine, called each parsed token line of this filename
if (m_lastIgnore.lineno != filelinep->lineno()) {
// UINFO(9," ApplyIgnores for "<<filelinep->ascii()<<endl);
// Process all on/offs for lines up to and including the current line
int curlineno = filelinep->lastLineno();
for (; m_lastIt != m_lastEnd; ++m_lastIt) {
if (m_lastIt->m_lineno > curlineno) break;
//UINFO(9," Hit "<<*m_lastIt<<endl);
filelinep->warnOn(m_lastIt->m_code, m_lastIt->m_on);
for (; m_lastIgnore.it != m_ignLines.end(); ++m_lastIgnore.it) {
if (m_lastIgnore.it->m_lineno > curlineno) break;
// UINFO(9," Hit "<<*m_lastIt<<endl);
filelinep->warnOn(m_lastIgnore.it->m_code, m_lastIgnore.it->m_on);
}
if (0 && debug() >= 9) {
for (IgnLines::const_iterator it=m_lastIt; it != m_lastEnd; ++it) {
UINFO(9," NXT "<<*it<<endl);
for (IgnLines::const_iterator it = m_lastIgnore.it; it != m_ignLines.end(); ++it) {
UINFO(9, " NXT " << *it << endl);
}
}
m_lastLineno = filelinep->lastLineno();
m_lastIgnore.lineno = filelinep->lastLineno();
}
}
bool waive(V3ErrorCode code, const string& match) {
for (Waivers::const_iterator it = m_waivers.begin(); it != m_waivers.end(); ++it) {
if (((it->first == code) || (it->first == V3ErrorCode::I_LINT))
&& VString::wildmatch(match, it->second)) return true;
}
return false;
}
};
V3ConfigIgnores V3ConfigIgnores::s_singleton;
typedef V3ConfigWildcardResolver<V3ConfigFile> V3ConfigFileResolver;
//######################################################################
// Resolve modules and files in the design
class V3ConfigResolver {
V3ConfigModuleResolver m_modules; // Access to module names (with wildcards)
V3ConfigFileResolver m_files; // Access to file names (with wildcards)
static V3ConfigResolver s_singleton; // Singleton (not via local static, as that's slow)
V3ConfigResolver() {}
~V3ConfigResolver() {}
public:
inline static V3ConfigResolver& s() { return s_singleton; }
V3ConfigModuleResolver& modules() { return m_modules; }
V3ConfigFileResolver& files() { return m_files; }
};
V3ConfigResolver V3ConfigResolver::s_singleton;
//######################################################################
// V3Config
void V3Config::addCaseFull(const string& filename, int lineno) {
V3ConfigFile& file = V3ConfigResolver::s().files().at(filename);
file.addLineAttribute(lineno, AstPragmaType::FULL_CASE);
}
void V3Config::addCaseParallel(const string& filename, int lineno) {
V3ConfigFile& file = V3ConfigResolver::s().files().at(filename);
file.addLineAttribute(lineno, AstPragmaType::PARALLEL_CASE);
}
void V3Config::addCoverageBlockOff(const string& filename, int lineno) {
V3ConfigFile& file = V3ConfigResolver::s().files().at(filename);
file.addLineAttribute(lineno, AstPragmaType::COVERAGE_BLOCK_OFF);
}
void V3Config::addCoverageBlockOff(const string& module, const string& blockname) {
V3ConfigResolver::s().modules().at(module).addCoverageBlockOff(blockname);
}
void V3Config::addIgnore(V3ErrorCode code, bool on, const string& filename, int min, int max) {
if (filename=="*") {
FileLine::globalWarnOff(code,!on);
if (filename == "*") {
FileLine::globalWarnOff(code, !on);
} else {
V3ConfigIgnores::singleton().addIgnore(code, filename, min, on);
if (max) V3ConfigIgnores::singleton().addIgnore(code, filename, max, !on);
V3ConfigResolver::s().files().at(filename).addIgnore(code, min, on);
if (max) V3ConfigResolver::s().files().at(filename).addIgnore(code, max, !on);
V3ConfigResolver::s().files().flush();
}
}
void V3Config::applyIgnores(FileLine* filelinep) {
V3ConfigIgnores::singleton().applyIgnores(filelinep);
void V3Config::addInline(FileLine* fl, const string& module, const string& ftask, bool on) {
if (ftask.empty()) {
V3ConfigResolver::s().modules().at(module).setInline(on);
} else {
if (!on) {
fl->v3error("no_inline not supported for tasks" << endl);
} else {
V3ConfigResolver::s().modules().at(module).ftasks().at(ftask).setNoInline(on);
}
}
}
void V3Config::addVarAttr(FileLine* fl, const string& module, const string& ftask,
const string& var, AstAttrType attr, AstSenTree* sensep) {
// Semantics: sensep only if public_flat_rw
if ((attr != AstAttrType::VAR_PUBLIC_FLAT_RW) && sensep) {
sensep->v3error("sensitivity not expected for attribute" << endl);
return;
}
// Semantics: Most of the attributes operate on signals
if (var.empty()) {
if (attr == AstAttrType::VAR_ISOLATE_ASSIGNMENTS) {
if (ftask.empty()) {
fl->v3error("isolate_assignments only applies to signals or functions/tasks"
<< endl);
} else {
V3ConfigResolver::s().modules().at(module).ftasks().at(ftask).setIsolate(true);
}
} else if (attr == AstAttrType::VAR_PUBLIC) {
if (ftask.empty()) {
// public module, this is the only exception from var here
V3ConfigResolver::s().modules().at(module).setPublic(true);
} else {
V3ConfigResolver::s().modules().at(module).ftasks().at(ftask).setPublic(true);
}
} else {
fl->v3error("missing -signal" << endl);
}
} else {
V3ConfigModule& mod = V3ConfigResolver::s().modules().at(module);
if (ftask.empty()) {
mod.vars().at(var).push_back(V3ConfigVarAttr(attr, sensep));
} else {
mod.ftasks().at(ftask).vars().at(var).push_back({attr, sensep});
}
}
}
void V3Config::addWaiver(V3ErrorCode code, const string& filename, const string& match) {
V3ConfigResolver::s().files().at(filename).addWaiver(code, match);
}
void V3Config::applyCase(AstCase* nodep) {
const string& filename = nodep->fileline()->filename();
V3ConfigFile* filep = V3ConfigResolver::s().files().resolve(filename);
if (filep) filep->applyCase(nodep);
}
void V3Config::applyCoverageBlock(AstNodeModule* modulep, AstBegin* nodep) {
const string& filename = nodep->fileline()->filename();
V3ConfigFile* filep = V3ConfigResolver::s().files().resolve(filename);
if (filep) filep->applyBlock(nodep);
const string& modname = modulep->name();
V3ConfigModule* modp = V3ConfigResolver::s().modules().resolve(modname);
if (modp) modp->applyBlock(nodep);
}
void V3Config::applyIgnores(FileLine* filelinep) {
const string& filename = filelinep->filename();
V3ConfigFile* filep = V3ConfigResolver::s().files().resolve(filename);
if (filep) filep->applyIgnores(filelinep);
}
void V3Config::applyModule(AstNodeModule* modulep) {
const string& modname = modulep->name();
V3ConfigModule* modp = V3ConfigResolver::s().modules().resolve(modname);
if (modp) modp->apply(modulep);
}
void V3Config::applyFTask(AstNodeModule* modulep, AstNodeFTask* ftaskp) {
const string& modname = modulep->name();
V3ConfigModule* modp = V3ConfigResolver::s().modules().resolve(modname);
if (!modp) return;
V3ConfigFTask* ftp = modp->ftasks().resolve(ftaskp->name());
if (ftp) ftp->apply(ftaskp);
}
void V3Config::applyVarAttr(AstNodeModule* modulep, AstNodeFTask* ftaskp, AstVar* varp) {
V3ConfigVar* vp;
V3ConfigModule* modp = V3ConfigResolver::s().modules().resolve(modulep->name());
if (!modp) return;
if (ftaskp) {
V3ConfigFTask* ftp = modp->ftasks().resolve(ftaskp->name());
if (!ftp) return;
vp = ftp->vars().resolve(varp->name());
} else {
vp = modp->vars().resolve(varp->name());
}
if (vp) vp->apply(varp);
}
bool V3Config::waive(FileLine* filelinep, V3ErrorCode code, const string& message) {
V3ConfigFile* filep = V3ConfigResolver::s().files().resolve(filelinep->filename());
if (!filep) return false;
return filep->waive(code, message);
}

View File

@ -26,13 +26,27 @@
#include "V3Error.h"
#include "V3FileLine.h"
#include "V3Ast.h"
//######################################################################
class V3Config {
public:
static void addCaseFull(const string& file, int lineno);
static void addCaseParallel(const string& file, int lineno);
static void addCoverageBlockOff(const string& file, int lineno);
static void addCoverageBlockOff(const string& module, const string& blockname);
static void addIgnore(V3ErrorCode code, bool on, const string& filename, int min, int max);
static void addWaiver(V3ErrorCode code, const string& filename, const string& msg);
static void addInline(FileLine* fl, const string& module, const string& ftask, bool on);
static void addVarAttr(FileLine* fl, const string& module, const string& ftask, const string& signal, AstAttrType type, AstSenTree* nodep);
static void applyCase(AstCase* nodep);
static void applyCoverageBlock(AstNodeModule* modulep, AstBegin* nodep);
static void applyIgnores(FileLine* filelinep);
static void applyModule(AstNodeModule* nodep);
static void applyFTask(AstNodeModule* modulep, AstNodeFTask* ftaskp);
static void applyVarAttr(AstNodeModule* modulep, AstNodeFTask* ftaskp, AstVar* varp);
static bool waive(FileLine* filelinep, V3ErrorCode code, const string& match);
};
#endif // Guard

View File

@ -131,7 +131,10 @@ class EmitXmlFileVisitor : public AstNVisitor {
}
puts(" origName="); putsQuoted(nodep->origName());
// Attributes
if (nodep->attrClocker()) puts(" clocker=\"true\"");
if (nodep->attrClocker() == VVarAttrClocker::CLOCKER_YES)
puts(" clocker=\"true\"");
else if (nodep->attrClocker() == VVarAttrClocker::CLOCKER_NO)
puts(" clocker=\"false\"");
if (nodep->attrClockEn()) puts(" clock_enable=\"true\"");
if (nodep->attrIsolateAssign()) puts(" isolate_assignments=\"true\"");
if (nodep->isSigPublic()) puts(" public=\"true\"");

View File

@ -341,7 +341,10 @@ void FileLine::v3errorEnd(std::ostringstream& str, const string& locationStr) {
if (!locationStr.empty()) {
lstr<<std::setw(ascii().length())<<" "<<": "<<locationStr;
}
if (warnIsOff(V3Error::errorCode())) V3Error::suppressThisWarning();
if (warnIsOff(V3Error::errorCode())
|| V3Config::waive(this, V3Error::errorCode(), str.str())) {
V3Error::suppressThisWarning();
}
else if (!V3Error::errorContexted()) nsstr<<warnContextPrimary();
V3Error::v3errorEnd(nsstr, lstr.str());
}

View File

@ -28,6 +28,7 @@
#include "V3Global.h"
#include "V3LinkParse.h"
#include "V3Ast.h"
#include "V3Config.h"
#include <algorithm>
#include <cstdarg>
@ -106,6 +107,8 @@ private:
// VISITs
virtual void visit(AstNodeFTask* nodep) {
V3Config::applyFTask(m_modp, nodep);
if (!nodep->user1SetOnce()) { // Process only once.
cleanFileline(nodep);
m_ftaskp = nodep;
@ -189,6 +192,9 @@ private:
return;
}
// Maybe this variable has a signal attribute
V3Config::applyVarAttr(m_modp, m_ftaskp, nodep);
if (v3Global.opt.publicFlatRW()) {
switch (nodep->varType()) {
case AstVarType::VAR:
@ -438,6 +444,8 @@ private:
}
virtual void visit(AstNodeModule* nodep) {
V3Config::applyModule(nodep);
// Module: Create sim table for entire module and iterate
cleanFileline(nodep);
//
@ -474,6 +482,17 @@ private:
visitIterateNoValueMod(nodep);
}
virtual void visit(AstBegin* nodep) {
V3Config::applyCoverageBlock(m_modp, nodep);
cleanFileline(nodep);
iterateChildren(nodep);
}
virtual void visit(AstCase* nodep) {
V3Config::applyCase(nodep);
cleanFileline(nodep);
iterateChildren(nodep);
}
virtual void visit(AstNode* nodep) {
// Default: Just iterate
cleanFileline(nodep);

View File

@ -62,6 +62,7 @@ struct V3ParseBisonYYSType {
VSignedState signstate;
V3ImportProperty iprop;
V3ErrorCode::en errcodeen;
AstAttrType::en attrtypeen;
AstNode* nodep;

View File

@ -74,6 +74,14 @@ bool VString::wildmatch(const char* s, const char* p) {
return (*s == '\0');
}
bool VString::wildmatch(const string& s, const string& p) {
return wildmatch(s.c_str(), p.c_str());
}
bool VString::isWildcard(const string &p) {
return ((p.find("*") != string::npos) || (p.find("?") != string::npos));
}
string VString::dot(const string& a, const string& dot, const string& b) {
if (b=="") return a;
if (a=="") return b;

View File

@ -63,6 +63,10 @@ public:
// METHODS (generic string utilities)
// Return true if p with ? or *'s matches s
static bool wildmatch(const char* s, const char* p);
// Return true if p with ? or *'s matches s
static bool wildmatch(const string& s, const string& p);
// Return true if this is a wildcard string (contains * or ?)
static bool isWildcard(const string &p);
// Return {a}{dot}{b}, omitting dot if a or b are empty
static string dot(const string& a, const string& dot, const string& b);
// Convert string to lowercase (tolower)

View File

@ -135,17 +135,45 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
{ws} { FL_FWD; FL_BRK; } /* otherwise ignore white-space */
{crnl} { FL_FWD; FL_BRK; } /* Count line numbers */
"clock_enable" { FL; return yVLT_CLOCK_ENABLE; }
"clocker" { FL; return yVLT_CLOCKER; }
"coverage_block_off" { FL; return yVLT_COVERAGE_BLOCK_OFF; }
"coverage_off" { FL; return yVLT_COVERAGE_OFF; }
"coverage_on" { FL; return yVLT_COVERAGE_ON; }
"full_case" { FL; return yVLT_FULL_CASE; }
"inline" { FL; return yVLT_INLINE; }
"isolate_assignments" { FL; return yVLT_ISOLATE_ASSIGNMENTS; }
"lint_off" { FL; return yVLT_LINT_OFF; }
"lint_on" { FL; return yVLT_LINT_ON; }
"no_clocker" { FL; return yVLT_NO_CLOCKER; }
"no_inline" { FL; return yVLT_NO_INLINE; }
"parallel_case" { FL; return yVLT_PARALLEL_CASE; }
"public" { FL; return yVLT_PUBLIC; }
"public_flat" { FL; return yVLT_PUBLIC_FLAT; }
"public_flat_rd" { FL; return yVLT_PUBLIC_FLAT_RD; }
"public_flat_rw" { FL; return yVLT_PUBLIC_FLAT_RW; }
"public_module" { FL; return yVLT_PUBLIC_MODULE; }
"sc_bv" { FL; return yVLT_SC_BV; }
"sformat" { FL; return yVLT_SFORMAT; }
"tracing_off" { FL; return yVLT_TRACING_OFF; }
"tracing_on" { FL; return yVLT_TRACING_ON; }
-?"-block" { FL; return yVLT_D_BLOCK; }
-?"-file" { FL; return yVLT_D_FILE; }
-?"-function" { FL; return yVLT_D_FUNCTION; }
-?"-lines" { FL; return yVLT_D_LINES; }
-?"-match" { FL; return yVLT_D_MATCH; }
-?"-module" { FL; return yVLT_D_MODULE; }
-?"-msg" { FL; return yVLT_D_MSG; }
-?"-rule" { FL; return yVLT_D_RULE; }
-?"-task" { FL; return yVLT_D_TASK; }
-?"-var" { FL; return yVLT_D_VAR; }
/* Reachable by attr_event_control */
"edge" { FL; return yEDGE; }
"negedge" { FL; return yNEGEDGE; }
"or" { FL; return yOR; }
"posedge" { FL; return yPOSEDGE; }
}
/************************************************************************/

View File

@ -273,17 +273,39 @@ class AstSenTree;
%token<strp> yaSCCTOR "`systemc_implementation BLOCK"
%token<strp> yaSCDTOR "`systemc_imp_header BLOCK"
%token<fl> yVLT_COVERAGE_OFF "coverage_off"
%token<fl> yVLT_COVERAGE_ON "coverage_on"
%token<fl> yVLT_LINT_OFF "lint_off"
%token<fl> yVLT_LINT_ON "lint_on"
%token<fl> yVLT_TRACING_OFF "tracing_off"
%token<fl> yVLT_TRACING_ON "tracing_on"
%token<fl> yVLT_CLOCKER "clocker"
%token<fl> yVLT_CLOCK_ENABLE "clock_enable"
%token<fl> yVLT_COVERAGE_BLOCK_OFF "coverage_block_off"
%token<fl> yVLT_COVERAGE_OFF "coverage_off"
%token<fl> yVLT_COVERAGE_ON "coverage_on"
%token<fl> yVLT_FULL_CASE "full_case"
%token<fl> yVLT_INLINE "inline"
%token<fl> yVLT_ISOLATE_ASSIGNMENTS "isolate_assignments"
%token<fl> yVLT_LINT_OFF "lint_off"
%token<fl> yVLT_LINT_ON "lint_on"
%token<fl> yVLT_NO_CLOCKER "no_clocker"
%token<fl> yVLT_NO_INLINE "no_inline"
%token<fl> yVLT_PARALLEL_CASE "parallel_case"
%token<fl> yVLT_PUBLIC "public"
%token<fl> yVLT_PUBLIC_FLAT "public_flat"
%token<fl> yVLT_PUBLIC_FLAT_RD "public_flat_rd"
%token<fl> yVLT_PUBLIC_FLAT_RW "public_flat_rw"
%token<fl> yVLT_PUBLIC_MODULE "public_module"
%token<fl> yVLT_SC_BV "sc_bv"
%token<fl> yVLT_SFORMAT "sformat"
%token<fl> yVLT_TRACING_OFF "tracing_off"
%token<fl> yVLT_TRACING_ON "tracing_on"
%token<fl> yVLT_D_FILE "--file"
%token<fl> yVLT_D_LINES "--lines"
%token<fl> yVLT_D_MSG "--msg"
%token<fl> yVLT_D_RULE "--rule"
%token<fl> yVLT_D_BLOCK "--block"
%token<fl> yVLT_D_FILE "--file"
%token<fl> yVLT_D_FUNCTION "--function"
%token<fl> yVLT_D_LINES "--lines"
%token<fl> yVLT_D_MODULE "--module"
%token<fl> yVLT_D_MATCH "--match"
%token<fl> yVLT_D_MSG "--msg"
%token<fl> yVLT_D_RULE "--rule"
%token<fl> yVLT_D_TASK "--task"
%token<fl> yVLT_D_VAR "--var"
%token<strp> yaD_IGNORE "${ignored-bbox-sys}"
%token<strp> yaD_DPI "${dpi-sys}"
@ -737,6 +759,7 @@ class AstSenTree;
// Blank lines for type insertion
// Blank lines for type insertion
// Blank lines for type insertion
// Blank lines for type insertion
%start source_text
@ -2460,6 +2483,11 @@ cellpinItemE<pinp>: // IEEE: named_port_connection + empty
//************************************************
// EventControl lists
attr_event_controlE<sentreep>:
/* empty */ { $$ = NULL; }
| attr_event_control { $$ = $1; }
;
attr_event_control<sentreep>: // ==IEEE: event_control
'@' '(' event_expression ')' { $$ = new AstSenTree($1,$3); }
| '@' '(' '*' ')' { $$ = NULL; }
@ -5582,14 +5610,45 @@ memberQualOne<nodep>: // IEEE: property_qualifier + method_qualifier
// VLT Files
vltItem:
vltOffFront { V3Config::addIgnore($1,false,"*",0,0); }
| vltOffFront yVLT_D_FILE yaSTRING { V3Config::addIgnore($1,false,*$3,0,0); }
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM { V3Config::addIgnore($1,false,*$3,$5->toUInt(),$5->toUInt()+1); }
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM { V3Config::addIgnore($1,false,*$3,$5->toUInt(),$7->toUInt()+1); }
| vltOnFront { V3Config::addIgnore($1,true,"*",0,0); }
| vltOnFront yVLT_D_FILE yaSTRING { V3Config::addIgnore($1,true,*$3,0,0); }
| vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM { V3Config::addIgnore($1,true,*$3,$5->toUInt(),$5->toUInt()+1); }
| vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM { V3Config::addIgnore($1,true,*$3,$5->toUInt(),$7->toUInt()+1); }
vltOffFront { V3Config::addIgnore($1, false, "*", 0, 0); }
| vltOffFront yVLT_D_FILE yaSTRING
{ V3Config::addIgnore($1, false, *$3, 0, 0); }
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM
{ V3Config::addIgnore($1, false, *$3, $5->toUInt(), $5->toUInt()+1); }
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM
{ V3Config::addIgnore($1, false, *$3, $5->toUInt(), $7->toUInt()+1); }
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_MATCH yaSTRING
{ if (($1==V3ErrorCode::I_COVERAGE) || ($1==V3ErrorCode::I_TRACING)) {
$<fl>1->v3error("Argument -match only supported for lint_off"<<endl);
} else {
V3Config::addWaiver($1,*$3,*$5);
}}
| vltOnFront { V3Config::addIgnore($1, true, "*", 0, 0); }
| vltOnFront yVLT_D_FILE yaSTRING
{ V3Config::addIgnore($1, true, *$3, 0, 0); }
| vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM
{ V3Config::addIgnore($1, true, *$3, $5->toUInt(), $5->toUInt()+1); }
| vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM
{ V3Config::addIgnore($1, true, *$3, $5->toUInt(), $7->toUInt()+1); }
| vltVarAttrFront vltDModuleE vltDFTaskE vltVarAttrVarE attr_event_controlE
{ V3Config::addVarAttr($<fl>1, *$2, *$3, *$4, $1, $5); }
| vltInlineFront vltDModuleE vltDFTaskE
{ V3Config::addInline($<fl>1, *$2, *$3, $1); }
| yVLT_COVERAGE_BLOCK_OFF yVLT_D_FILE yaSTRING
{ V3Config::addCoverageBlockOff(*$3, 0); }
| yVLT_COVERAGE_BLOCK_OFF yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM
{ V3Config::addCoverageBlockOff(*$3, $5->toUInt()); }
| yVLT_COVERAGE_BLOCK_OFF yVLT_D_MODULE yaSTRING yVLT_D_BLOCK yaSTRING
{ V3Config::addCoverageBlockOff(*$3, *$5); }
| yVLT_FULL_CASE yVLT_D_FILE yaSTRING
{ V3Config::addCaseFull(*$3, 0); }
| yVLT_FULL_CASE yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM
{ V3Config::addCaseFull(*$3, $5->toUInt()); }
| yVLT_PARALLEL_CASE yVLT_D_FILE yaSTRING
{ V3Config::addCaseParallel(*$3, 0); }
| yVLT_PARALLEL_CASE yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM
{ V3Config::addCaseParallel(*$3, $5->toUInt()); }
;
vltOffFront<errcodeen>:
@ -5618,6 +5677,40 @@ vltOnFront<errcodeen>:
if ($$ == V3ErrorCode::EC_ERROR) { $1->v3error("Unknown Error Code: "<<*$3<<endl); } }
;
vltDModuleE<strp>:
/* empty */ { static string unit = "__024unit"; $$ = &unit; }
| yVLT_D_MODULE str { $$ = $2; }
;
vltDFTaskE<strp>:
/* empty */ { static string empty = ""; $$ = &empty; }
| yVLT_D_FUNCTION str { $$ = $2; }
| yVLT_D_TASK str { $$ = $2; }
;
vltInlineFront<cbool>:
yVLT_INLINE { $$ = true; }
| yVLT_NO_INLINE { $$ = false; }
;
vltVarAttrVarE<strp>:
/* empty */ { static string empty = ""; $$ = &empty; }
| yVLT_D_VAR str { $$ = $2; }
;
vltVarAttrFront<attrtypeen>:
yVLT_CLOCK_ENABLE { $$ = AstAttrType::VAR_CLOCK_ENABLE; }
| yVLT_CLOCKER { $$ = AstAttrType::VAR_CLOCKER; }
| yVLT_ISOLATE_ASSIGNMENTS { $$ = AstAttrType::VAR_ISOLATE_ASSIGNMENTS; }
| yVLT_NO_CLOCKER { $$ = AstAttrType::VAR_NO_CLOCKER; }
| yVLT_PUBLIC { $$ = AstAttrType::VAR_PUBLIC; v3Global.dpi(true); }
| yVLT_PUBLIC_FLAT { $$ = AstAttrType::VAR_PUBLIC_FLAT; v3Global.dpi(true); }
| yVLT_PUBLIC_FLAT_RD { $$ = AstAttrType::VAR_PUBLIC_FLAT_RD; v3Global.dpi(true); }
| yVLT_PUBLIC_FLAT_RW { $$ = AstAttrType::VAR_PUBLIC_FLAT_RW; v3Global.dpi(true); }
| yVLT_SC_BV { $$ = AstAttrType::VAR_SC_BV; }
| yVLT_SFORMAT { $$ = AstAttrType::VAR_SFORMAT; }
;
//**********************************************************************
%%
// For implementation functions see V3ParseGrammar.cpp

View File

@ -26,7 +26,11 @@ module t (/*AUTOARG*/
always @* begin
// Note not all tools support directives on casez's
`ifdef ATTRIBUTES
case ({a,b_fc}) // synopsys full_case
`else
case ({a,b_fc})
`endif
2'b0_0: ;
2'b0_1: ;
2'b1_0: ;
@ -41,7 +45,15 @@ module t (/*AUTOARG*/
end
always @* begin
`ifdef ATTRIBUTES
case (1'b1) // synopsys full_case parallel_case
`else
`ifdef FAILING_FULL
case (1'b1) // synopsys parallel_case
`else
case (1'b1) // synopsys parallel_full
`endif
`endif
a: ;
b_pc: ;
endcase

View File

@ -12,7 +12,7 @@ scenarios(simulator => 1);
top_filename("t/t_assert_synth.v");
compile(
v_flags2 => ['+define+FAILING_FULL'],
v_flags2 => ['+define+FAILING_FULL +define+ATTRIBUTES'],
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);
@ -21,7 +21,7 @@ execute(
check_finished => 0,
fails => $Self->{vlt_all},
expect =>
'%Error: t_assert_synth.v:\d+: Assertion failed in top.t: synthesis full_case'
'%Error: t_assert_synth.v:30: Assertion failed in top.t: synthesis full_case'
);
ok(1);

View File

@ -0,0 +1,8 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Stefan Wallentowitz.
`verilator_config
full_case -file "t/t_assert_synth.v" -lines 32

View File

@ -0,0 +1,3 @@
[40] %Error: t_assert_synth.v:32: Assertion failed in top.t: synthesis full_case, but non-match found
%Error: t/t_assert_synth.v:32: Verilog $stop
Aborting...

View File

@ -0,0 +1,27 @@
#!/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(simulator => 1);
top_filename("t/t_assert_synth.v");
compile(
v_flags2 => ['+define+FAILING_FULL', "t/t_assert_synth_full.vlt"],
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);
execute(
check_finished => 0,
fails => $Self->{vlt_all},
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -12,7 +12,7 @@ scenarios(simulator => 1);
top_filename("t/t_assert_synth.v");
compile(
v_flags2 => ['+define+FAILING_PARALLEL'],
v_flags2 => ['+define+FAILING_PARALLEL', '+define+ATTRIBUTES'],
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);

View File

@ -0,0 +1,8 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Stefan Wallentowitz.
`verilator_config
parallel_case -file "t/t_assert_synth.v" -lines 54

View File

@ -0,0 +1,28 @@
#!/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(simulator => 1);
top_filename("t/t_assert_synth.v");
compile(
v_flags2 => ['+define+FAILING_PARALLEL', "t/t_assert_synth_parallel.vlt"],
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);
execute(
check_finished => 0,
fails => $Self->{vlt_all},
expect =>
'%Error: t_assert_synth.v:\d+: Assertion failed in top.t: synthesis parallel_case'
);
ok(1);
1;

View File

@ -9,9 +9,18 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(simulator => 1);
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
verilator_flags2 => ["+define+ATTRIBUTES"],
);
if ($Self->{vlt_all}) {
file_grep("$out_filename", qr/\<var fl="d74" name="clk0" dtype_id="1" dir="input" vartype="logic" origName="clk0" clocker="true" public="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="d75" name="clk1" dtype_id="1" dir="input" vartype="logic" origName="clk1" clocker="true" public="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="d76" name="clk2" dtype_id="1" dir="input" vartype="logic" origName="clk2" clocker="true" public="true"\/\>/i);
}
execute(
check_finished => 1,
);

View File

@ -70,9 +70,15 @@ module t2(
endmodule
module t(
`ifdef ATTRIBUTES
input clk0 /*verilator clocker*/,
input clk1 /*verilator clocker*/,
input clk2 /*verilator clocker*/,
`else
input clk0,
input clk1,
input clk2,
`endif
input data_in
);

View File

@ -0,0 +1,9 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Stefan Wallentowitz.
`verilator_config
clocker -module "t" -var "clk*"
no_clocker -module "t" -var "data_in"

View File

@ -0,0 +1,31 @@
#!/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(simulator => 1);
top_filename("t/t_clk_concat.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
verilator_flags2 => ["t/t_clk_concat.vlt"],
);
if ($Self->{vlt_all}) {
file_grep("$out_filename", qr/\<var fl="e78" name="clk0" dtype_id="1" dir="input" vartype="logic" origName="clk0" clocker="true" public="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="e79" name="clk1" dtype_id="1" dir="input" vartype="logic" origName="clk1" clocker="true" public="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="e80" name="clk2" dtype_id="1" dir="input" vartype="logic" origName="clk2" clocker="true" public="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="e82" name="data_in" dtype_id="1" dir="input" vartype="logic" origName="data_in" clocker="false" public="true"\/\>/i);
}
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -9,7 +9,10 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(simulator => 1);
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
verilator_flags2 => ["+define+ATTRIBUTES=1"],
);
execute(

View File

@ -83,7 +83,9 @@
if (toggle) begin
// CHECK_COVER_MISSING(-1)
// This doesn't even get added
`ifdef ATTRIBUTE
// verilator coverage_block_off
`endif
$write("");
end
end
@ -107,10 +109,12 @@
// CHECK_COVER(-1,"top.t.b*",2)
// t.b1 and t.b2 collapse to a count of 2
end
if (toggle) begin
if (toggle) begin : block
// CHECK_COVER_MISSING(-1)
// This doesn't
`ifdef ATTRIBUTE
// verilator coverage_block_off
`endif
$write("");
end
end

View File

@ -82,7 +82,9 @@ module alpha (/*AUTOARG*/
if (toggle) begin
// CHECK_COVER_MISSING(-1)
// This doesn't even get added
`ifdef ATTRIBUTE
// verilator coverage_block_off
`endif
$write("");
end
end
@ -106,10 +108,12 @@ module beta (/*AUTOARG*/
// CHECK_COVER(-1,"top.t.b*",2)
// t.b1 and t.b2 collapse to a count of 2
end
if (toggle) begin
if (toggle) begin : block
// CHECK_COVER_MISSING(-1)
// This doesn't
`ifdef ATTRIBUTE
// verilator coverage_block_off
`endif
$write("");
end
end

View File

@ -0,0 +1,9 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Stefan Wallentowitz.
`verilator_config
coverage_block_off -file "t/t_cover_line.v" -lines 82
coverage_block_off -module "beta" -block "block"

View File

@ -12,7 +12,7 @@ scenarios(simulator => 1);
top_filename("t/t_cover_line.v");
compile(
verilator_flags2 => ['--cc --coverage-line'],
verilator_flags2 => ['--cc --coverage-line +define+ATTRIBUTE'],
);
execute(

View File

@ -0,0 +1,33 @@
#!/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(simulator => 1);
top_filename("t/t_cover_line.v");
compile(
verilator_flags2 => ['--cc', '--coverage-line', "t/t_cover_line.vlt"],
);
execute(
check_finished => 1,
);
# Read the input .v file and do any CHECK_COVER requests
inline_checks();
run(cmd => ["../bin/verilator_coverage",
"--annotate", "$Self->{obj_dir}/annotated",
"$Self->{obj_dir}/coverage.dat",
]);
files_identical("$Self->{obj_dir}/annotated/t_cover_line.v", "t/t_cover_line.out");
ok(1);
1;

View File

@ -12,7 +12,7 @@ scenarios(simulator => 1);
top_filename("t/t_cover_line.v");
compile(
verilator_flags2 => ['--sc --coverage-line'],
verilator_flags2 => ['--sc --coverage-line +define+ATTRIBUTE'],
);
execute(

View File

@ -1,51 +1,51 @@
$version Generated by VerilatedVcd $end
$date Thu Oct 24 09:45:30 2019
$date Sun Dec 29 13:11:10 2019
$end
$timescale 1ns $end
$scope module top $end
$var wire 1 1 clk $end
$var wire 1 5! clk $end
$scope module t $end
$var wire 1 1 clk $end
$var wire 32 $ cyc [31:0] $end
$var wire 8 % cyc_copy [7:0] $end
$var wire 1 5! clk $end
$var wire 32 + cyc [31:0] $end
$var wire 8 3 cyc_copy [7:0] $end
$var wire 1 # toggle $end
$var wire 32 ) vlCoverageLineTrace_t_cover_line__44_if [31:0] $end
$var wire 32 & vlCoverageLineTrace_t_cover_line__47_if [31:0] $end
$var wire 32 ' vlCoverageLineTrace_t_cover_line__50_elsif [31:0] $end
$var wire 32 ( vlCoverageLineTrace_t_cover_line__57_elsif [31:0] $end
$var wire 32 S vlCoverageLineTrace_t_cover_line__44_if [31:0] $end
$var wire 32 ; vlCoverageLineTrace_t_cover_line__47_if [31:0] $end
$var wire 32 C vlCoverageLineTrace_t_cover_line__50_elsif [31:0] $end
$var wire 32 K vlCoverageLineTrace_t_cover_line__57_elsif [31:0] $end
$scope module a1 $end
$var wire 1 1 clk $end
$var wire 1 5! clk $end
$var wire 1 # toggle $end
$var wire 32 * vlCoverageLineTrace_t_cover_line__78_if [31:0] $end
$var wire 32 [ vlCoverageLineTrace_t_cover_line__78_if [31:0] $end
$upscope $end
$scope module a2 $end
$var wire 1 1 clk $end
$var wire 1 5! clk $end
$var wire 1 # toggle $end
$var wire 32 + vlCoverageLineTrace_t_cover_line__78_if [31:0] $end
$var wire 32 c vlCoverageLineTrace_t_cover_line__78_if [31:0] $end
$upscope $end
$scope module b1 $end
$var wire 1 1 clk $end
$var wire 1 5! clk $end
$var wire 1 # toggle $end
$var wire 32 2 vlCoverageLineTrace_t_cover_line__101_if [31:0] $end
$var wire 32 - vlCoverageLineTrace_t_cover_line__105_if [31:0] $end
$var wire 32 =! vlCoverageLineTrace_t_cover_line__103_if [31:0] $end
$var wire 32 s vlCoverageLineTrace_t_cover_line__107_if [31:0] $end
$upscope $end
$scope module b2 $end
$var wire 1 1 clk $end
$var wire 1 5! clk $end
$var wire 1 # toggle $end
$var wire 32 3 vlCoverageLineTrace_t_cover_line__101_if [31:0] $end
$var wire 32 . vlCoverageLineTrace_t_cover_line__105_if [31:0] $end
$var wire 32 E! vlCoverageLineTrace_t_cover_line__103_if [31:0] $end
$var wire 32 { vlCoverageLineTrace_t_cover_line__107_if [31:0] $end
$upscope $end
$scope module o1 $end
$var wire 1 1 clk $end
$var wire 1 5! clk $end
$var wire 1 # toggle $end
$var wire 32 , vlCoverageLineTrace_t_cover_line__162_if [31:0] $end
$var wire 32 k vlCoverageLineTrace_t_cover_line__166_if [31:0] $end
$upscope $end
$scope module t1 $end
$var wire 1 1 clk $end
$var wire 1 5! clk $end
$var wire 1 # toggle $end
$var wire 32 / vlCoverageLineTrace_t_cover_line__134_if [31:0] $end
$var wire 32 0 vlCoverageLineTrace_t_cover_line__137_if [31:0] $end
$var wire 32 %! vlCoverageLineTrace_t_cover_line__138_if [31:0] $end
$var wire 32 -! vlCoverageLineTrace_t_cover_line__141_if [31:0] $end
$upscope $end
$upscope $end
$upscope $end
@ -54,99 +54,99 @@ $enddefinitions $end
#0
0#
b00000000000000000000000000000001 $
b00000001 %
b00000000000000000000000000000000 &
b00000000000000000000000000000000 '
b00000000000000000000000000000000 (
b00000000000000000000000000000000 )
b00000000000000000000000000000000 *
b00000000000000000000000000000000 +
b00000000000000000000000000000000 ,
b00000000000000000000000000000000 -
b00000000000000000000000000000000 .
b00000000000000000000000000000000 /
b00000000000000000000000000000000 0
01
b00000000000000000000000000000000 2
b00000000000000000000000000000000 3
b00000000000000000000000000000001 +
b00000001 3
b00000000000000000000000000000000 ;
b00000000000000000000000000000000 C
b00000000000000000000000000000000 K
b00000000000000000000000000000000 S
b00000000000000000000000000000000 [
b00000000000000000000000000000000 c
b00000000000000000000000000000000 k
b00000000000000000000000000000000 s
b00000000000000000000000000000000 {
b00000000000000000000000000000000 %!
b00000000000000000000000000000000 -!
05!
b00000000000000000000000000000000 =!
b00000000000000000000000000000000 E!
#10
b00000000000000000000000000000010 $
b00000010 %
b00000000000000000000000000000001 )
11
b00000000000000000000000000000010 +
b00000010 3
b00000000000000000000000000000001 S
15!
#15
01
05!
#20
b00000000000000000000000000000011 $
b00000011 %
b00000000000000000000000000000010 )
11
b00000000000000000000000000000011 +
b00000011 3
b00000000000000000000000000000010 S
15!
#25
01
05!
#30
1#
b00000000000000000000000000000100 $
b00000100 %
b00000000000000000000000000000001 &
b00000000000000000000000000000011 )
11
b00000000000000000000000000000100 +
b00000100 3
b00000000000000000000000000000001 ;
b00000000000000000000000000000011 S
15!
#35
01
05!
#40
0#
b00000000000000000000000000000101 $
b00000101 %
b00000000000000000000000000000100 )
b00000000000000000000000000000001 *
b00000000000000000000000000000001 +
b00000000000000000000000000000001 ,
b00000000000000000000000000000001 -
b00000000000000000000000000000001 .
b00000000000000000000000000000001 /
11
b00000000000000000000000000000101 +
b00000101 3
b00000000000000000000000000000100 S
b00000000000000000000000000000001 [
b00000000000000000000000000000001 c
b00000000000000000000000000000001 k
b00000000000000000000000000000001 s
b00000000000000000000000000000001 {
b00000000000000000000000000000001 %!
15!
#45
01
05!
#50
b00000000000000000000000000000110 $
b00000110 %
b00000000000000000000000000000001 '
b00000000000000000000000000000101 )
b00000000000000000000000000000001 0
11
b00000000000000000000000000000110 +
b00000110 3
b00000000000000000000000000000001 C
b00000000000000000000000000000101 S
b00000000000000000000000000000001 -!
15!
#55
01
05!
#60
b00000000000000000000000000000111 $
b00000111 %
b00000000000000000000000000000110 )
11
b00000000000000000000000000000111 +
b00000111 3
b00000000000000000000000000000110 S
15!
#65
01
05!
#70
b00000000000000000000000000001000 $
b00001000 %
b00000000000000000000000000000111 )
11
b00000000000000000000000000001000 +
b00001000 3
b00000000000000000000000000000111 S
15!
#75
01
05!
#80
b00000000000000000000000000001001 $
b00001001 %
b00000000000000000000000000001000 )
11
b00000000000000000000000000001001 +
b00001001 3
b00000000000000000000000000001000 S
15!
#85
01
05!
#90
b00000000000000000000000000001010 $
b00001010 %
b00000000000000000000000000001001 )
11
b00000000000000000000000000001010 +
b00001010 3
b00000000000000000000000000001001 S
15!
#95
01
05!
#100
b00000000000000000000000000001011 $
b00001011 %
b00000000000000000000000000000001 (
b00000000000000000000000000001010 )
11
b00000000000000000000000000001011 +
b00001011 3
b00000000000000000000000000000001 K
b00000000000000000000000000001010 S
15!

View File

@ -12,7 +12,7 @@ scenarios(simulator => 1);
top_filename("t/t_cover_line.v");
compile(
verilator_flags2 => ['--cc --coverage-line --trace --trace-coverage'],
verilator_flags2 => ['--cc --coverage-line --trace --trace-coverage +define+ATTRIBUTE'],
);
execute(

View File

@ -9,13 +9,17 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(simulator => 1);
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
verilator_flags2 => ["--stats"],
verilator_flags2 => ["--stats $Self->{t_dir}/t_dedupe_clk_gate.vlt"],
);
if ($Self->{vlt_all}) {
file_grep("$out_filename", qr/\<var fl="e43" name="t.f0.clock_gate.clken_latched" dtype_id="1" vartype="logic" origName="clken_latched" clock_enable="true"\/\>/i);
file_grep($Self->{stats}, qr/Optimizations, Gate sigs deduped\s+(\d+)/i, 4);
}
ok(1);
1;

View File

@ -40,7 +40,7 @@ endmodule
module clock_gate_latch (gated_clk, clk, clken);
output gated_clk;
input clk, clken;
reg clken_latched /*verilator clock_enable*/;
reg clken_latched;
assign gated_clk = clk & clken_latched ;
wire clkb = ~clk;

View File

@ -0,0 +1,3 @@
`verilator_config
clock_enable -module "clock_gate_latch" -var "clken_latched"

View File

@ -13,7 +13,7 @@
//
//*************************************************************************
#include "Vt_dpi_var.h"
#include VM_PREFIX_INCLUDE
#include "verilated.h"
#include "svdpi.h"

View File

@ -8,13 +8,21 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Version 2.0.
scenarios(simulator => 1);
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
make_top_shell => 0,
make_main => 0,
verilator_flags2 => ["--exe --no-l2name $Self->{t_dir}/t_dpi_var.cpp"],
verilator_flags2 => ["-DATTRIBUTES --exe --no-l2name $Self->{t_dir}/t_dpi_var.cpp"],
);
if ($Self->{vlt_all}) {
file_grep("$out_filename", qr/\<var fl="d55" name="formatted" dtype_id="4" dir="input" vartype="string" origName="formatted" sformat="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="d76" name="t.sub.in" dtype_id="3" vartype="int" origName="in" public="true" public_flat_rd="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="d77" name="t.sub.fr_a" dtype_id="3" vartype="int" origName="fr_a" public="true" public_flat_rd="true" public_flat_rw="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="d78" name="t.sub.fr_b" dtype_id="3" vartype="int" origName="fr_b" public="true" public_flat_rd="true" public_flat_rw="true"\/\>/i);
}
execute(
check_finished => 1,
);

View File

@ -51,7 +51,11 @@ module t (/*AUTOARG*/
endmodule
`ifdef ATTRIBUTES
import "DPI-C" context function void mon_scope_name (input string formatted /*verilator sformat*/ );
`else
import "DPI-C" context function void mon_scope_name (input string formatted);
`endif
import "DPI-C" context function void mon_register_b(string name, int isOut);
import "DPI-C" context function void mon_register_done();
import "DPI-C" context function void mon_eval();
@ -68,9 +72,15 @@ module sub (/*AUTOARG*/
void mon_register_a(const char* namep, void* sigp, bool isOut);
`verilog
`ifdef ATTRIBUTES
input int in /*verilator public_flat_rd*/;
output int fr_a /*verilator public_flat_rw @(posedge t.monclk)*/;
output int fr_b /*verilator public_flat_rw @(posedge t.monclk)*/;
`else
input int in;
output int fr_a;
output int fr_b;
`endif
output int fr_chk;
always @* fr_chk = in + 1;

View File

@ -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 Stefan Wallentowitz.
`verilator_config
sformat -task "mon_scope_name" -var "formatted"
public_flat_rd -module "sub" -var "in"
public_flat_rw -module "sub" -var "fr_a" @(posedge t.monclk)
public_flat_rw -module "sub" -var "fr_b" @(posedge t.monclk)

33
test_regress/t/t_dpi_var_vlt.pl Executable file
View File

@ -0,0 +1,33 @@
#!/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);
top_filename("t/t_dpi_var.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
make_top_shell => 0,
make_main => 0,
verilator_flags2 => ["--exe --no-l2name $Self->{t_dir}/t_dpi_var.vlt $Self->{t_dir}/t_dpi_var.cpp"],
);
if ($Self->{vlt_all}) {
file_grep("$out_filename", qr/\<var fl="e57" name="formatted" dtype_id="4" dir="input" vartype="string" origName="formatted" sformat="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="e80" name="t.sub.in" dtype_id="3" vartype="int" origName="in" public="true" public_flat_rd="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="e81" name="t.sub.fr_a" dtype_id="3" vartype="int" origName="fr_a" public="true" public_flat_rd="true" public_flat_rw="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="e82" name="t.sub.fr_b" dtype_id="3" vartype="int" origName="fr_b" public="true" public_flat_rd="true" public_flat_rw="true"\/\>/i);
}
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -52,17 +52,22 @@ module t (/*AUTOARG*/
endmodule
`ifdef USE_INLINE_MID
`define INLINE_MODULE /*verilator inline_module*/
`define INLINE_MID_MODULE /*verilator no_inline_module*/
`else
`ifdef USE_INLINE
`ifdef ATTRIBUTES
`ifdef USE_INLINE_MID
`define INLINE_MODULE /*verilator inline_module*/
`define INLINE_MID_MODULE /*verilator inline_module*/
`define INLINE_MID_MODULE /*verilator no_inline_module*/
`else
`define INLINE_MODULE /*verilator public_module*/
`define INLINE_MID_MODULE /*verilator public_module*/
`ifdef USE_INLINE
`define INLINE_MODULE /*verilator inline_module*/
`define INLINE_MID_MODULE /*verilator inline_module*/
`else
`define INLINE_MODULE /*verilator public_module*/
`define INLINE_MID_MODULE /*verilator public_module*/
`endif
`endif
`else
`define INLINE_MODULE
`define INLINE_MID_MODULE
`endif
module global_mod;

View File

@ -10,11 +10,19 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(simulator => 1);
top_filename("t/t_func_dotted.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
v_flags2 => ['+define+NOUSE_INLINE',],
v_flags2 => ['+define+ATTRIBUTES', '+define+NOUSE_INLINE',],
);
if ($Self->{vlt_all}) {
file_grep("$out_filename", qr/\<module fl="d83" name="ma" origName="ma" public="true"\>/i);
file_grep("$out_filename", qr/\<module fl="d98" name="mb" origName="mb" public="true"\>/i);
file_grep("$out_filename", qr/\<module fl="d126" name="mc" origName="mc" public="true"\>/i);
file_grep("$out_filename", qr/\<module fl="d126" name="mc__PB1" origName="mc" public="true"\>/i);
}
execute(
check_finished => 1,
);

View File

@ -0,0 +1,9 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Stefan Wallentowitz.
`verilator_config
public -module "global_mod"
public -module "m*"

View File

@ -0,0 +1,31 @@
#!/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(simulator => 1);
top_filename("t/t_func_dotted.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
v_flags2 => ["$Self->{t_dir}/t_func_dotted_inl0.vlt"],
);
if ($Self->{vlt_all}) {
file_grep("$out_filename", qr/\<module fl="e83" name="ma" origName="ma" public="true"\>/i);
file_grep("$out_filename", qr/\<module fl="e98" name="mb" origName="mb" public="true"\>/i);
file_grep("$out_filename", qr/\<module fl="e126" name="mc" origName="mc" public="true"\>/i);
file_grep("$out_filename", qr/\<module fl="e126" name="mc__PB1" origName="mc" public="true"\>/i);
}
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -10,11 +10,18 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(simulator => 1);
top_filename("t/t_func_dotted.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
v_flags2 => ['+define+USE_INLINE',],
v_flags2 => ['+define+ATTRIBUTES', '+define+USE_INLINE',],
);
if ($Self->{vlt_all}) {
file_grep_not("$out_filename", qr/ma0/i);
file_grep_not("$out_filename", qr/mb0/i);
file_grep_not("$out_filename", qr/mc0/i);
}
execute(
check_finished => 1,
);

View File

@ -0,0 +1,9 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Stefan Wallentowitz.
`verilator_config
inline -module "global_mod"
inline -module "m*"

View File

@ -0,0 +1,30 @@
#!/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(simulator => 1);
top_filename("t/t_func_dotted.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
v_flags2 => ["t/t_func_dotted_inl1.vlt",],
);
if ($Self->{vlt_all}) {
file_grep_not("$out_filename", qr/ma0/i);
file_grep_not("$out_filename", qr/mb0/i);
file_grep_not("$out_filename", qr/mc0/i);
}
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -10,11 +10,17 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(simulator => 1);
top_filename("t/t_func_dotted.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
v_flags2 => ['+define+USE_INLINE_MID',],
v_flags2 => ['+define+ATTRIBUTES', '+define+USE_INLINE_MID',],
);
if ($Self->{vlt_all}) {
file_grep("$out_filename", qr/\<instance fl="d86" name="t.ma0.mb0" defName="mb" origName="mb0"\/\>/i);
file_grep("$out_filename", qr/\<module fl="d98" name="mb" origName="mb"\>/i);
}
execute(
check_finished => 1,
);

View File

@ -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 Stefan Wallentowitz.
`verilator_config
inline -module "global_mod"
inline -module "ma"
no_inline -module "mb"
inline -module "mc"

View File

@ -0,0 +1,29 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2019 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);
top_filename("t/t_func_dotted.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
v_flags2 => ["t/t_func_dotted_inl2.vlt",],
);
if ($Self->{vlt_all}) {
file_grep("$out_filename", qr/\<instance fl="e86" name="t.ma0.mb0" defName="mb" origName="mb0"\/\>/i);
file_grep("$out_filename", qr/\<module fl="e98" name="mb" origName="mb"\>/i);
}
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -47,58 +47,40 @@ module t (/*AUTOARG*/
endmodule
`ifdef USE_INLINE
`define INLINE_MODULE /*verilator inline_module*/
`else
`define INLINE_MODULE /*verilator public_module*/
`endif
`ifdef USE_PUBLIC
`define PUBLIC /*verilator public*/
`else
`define PUBLIC
`endif
module ps (input printclk);
`INLINE_MODULE
// Check that %m stays correct across inlines
always @ (posedge printclk) $write("[%0t] %m: Clocked\n", $time);
endmodule
module l1 (input [7:0] a, output [7:0] z `PUBLIC);
`INLINE_MODULE
wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC;
module l1 (input [7:0] a, output [7:0] z);
wire [7:0] z0; wire [7:0] z1;
assign z = z0+z1;
l2 u0 (a, z0); l2 u1 (a, z1);
endmodule
module l2 (input [7:0] a, output [7:0] z `PUBLIC);
`INLINE_MODULE
wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC;
module l2 (input [7:0] a, output [7:0] z);
wire [7:0] z0; wire [7:0] z1;
assign z = z0+z1;
wire [7:0] a1 = a+8'd1;
l3 u0 (a, z0); l3 u1 (a1, z1);
endmodule
module l3 (input [7:0] a, output [7:0] z `PUBLIC);
`INLINE_MODULE
wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC;
module l3 (input [7:0] a, output [7:0] z);
wire [7:0] z0; wire [7:0] z1;
assign z = z0+z1;
wire [7:0] a1 = a+8'd1;
l4 u0 (a, z0); l4 u1 (a1, z1);
endmodule
module l4 (input [7:0] a, output [7:0] z `PUBLIC);
`INLINE_MODULE
wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC;
module l4 (input [7:0] a, output [7:0] z);
wire [7:0] z0; wire [7:0] z1;
assign z = z0+z1;
wire [7:0] a1 = a+8'd1;
l5 #(1) u0 (a, z0); l5 #(2) u1 (a1, z1);
endmodule
module l5 (input [7:0] a, output [7:0] z `PUBLIC);
`INLINE_MODULE
module l5 (input [7:0] a, output [7:0] z);
parameter PARAM = 5;
wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC;
wire [7:0] z0; wire [7:0] z1;
assign z = a;
endmodule

View File

@ -10,10 +10,20 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(simulator => 1);
top_filename("t/t_inst_tree.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
v_flags2 => ['+define+NOUSE_INLINE', '+define+NOUSE_PUBLIC'],
);
v_flags2 => ["$Self->{t_dir}/$Self->{name}.vlt"],
);
if ($Self->{vlt_all}) {
file_grep("$out_filename", qr/\<module fl="e55" name="l1" origName="l1"\>/i);
file_grep("$out_filename", qr/\<module fl="e61" name="l2" origName="l2"\>/i);
file_grep("$out_filename", qr/\<module fl="e68" name="l3" origName="l3"\>/i);
file_grep("$out_filename", qr/\<module fl="e75" name="l4" origName="l4"\>/i);
file_grep("$out_filename", qr/\<module fl="e82" name="l5__P2" origName="l5"\>/i);
file_grep("$out_filename", qr/\<module fl="e82" name="l5__P1" origName="l5"\>/i);
}
execute(
check_finished => 1,

View File

@ -0,0 +1,8 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Stefan Wallentowitz.
`verilator_config
no_inline -module "l*"

View File

@ -13,7 +13,7 @@ top_filename("t/t_inst_tree.v");
my $default_vltmt_threads = $Self->get_default_vltmt_threads();
compile(
verilator_flags2 => ['+define+NOUSE_INLINE', '+define+USE_PUBLIC', '--stats',
verilator_flags2 => ['--stats', "$Self->{t_dir}/$Self->{name}.vlt",
# Force 3 threads even if we have fewer cores
$Self->{vltmt} ? "--threads $default_vltmt_threads" : ""]
);

View File

@ -0,0 +1,9 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Stefan Wallentowitz.
`verilator_config
no_inline -module "l*"
public -module "l*" -var "z*"

View File

@ -12,7 +12,8 @@ scenarios(simulator => 1);
top_filename("t/t_inst_tree.v");
compile(
verilator_flags2 => ['+define+NOUSE_INLINE', '+define+USE_PUBLIC', '--stats', '--norelative-cfuncs',
verilator_flags2 => ['--stats', '--norelative-cfuncs',
"$Self->{t_dir}/t_inst_tree_inl0_pub1.vlt",
$Self->wno_unopthreads_for_few_cores()]
);

View File

@ -10,11 +10,18 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(simulator => 1);
top_filename("t/t_inst_tree.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
v_flags2 => ['+define+USE_INLINE', '+define+NOUSE_PUBLIC'],
v_flags2 => ["$Self->{t_dir}/t_inst_tree_inl1_pub0.vlt"],
);
if ($Self->{vlt_all}) {
file_grep("$out_filename", qr/\<var fl="e69" name="t.u.u0.u0.z1" dtype_id="3" vartype="logic" origName="z1"\/\>/i);
file_grep("$out_filename", qr/\<var fl="e69" name="t.u.u0.u1.z1" dtype_id="3" vartype="logic" origName="z1"\/\>/i);
file_grep("$out_filename", qr/\<var fl="e69" name="t.u.u1.u0.z0" dtype_id="3" vartype="logic" origName="z0"\/\>/i);
}
execute(
check_finished => 1,
expect =>

View File

@ -0,0 +1,8 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Stefan Wallentowitz.
`verilator_config
inline -module "l*"

View File

@ -10,12 +10,19 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(simulator => 1);
top_filename("t/t_inst_tree.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
v_flags2 => ['+define+USE_INLINE', '+define+USE_PUBLIC',
v_flags2 => ["t/$Self->{name}.vlt",
$Self->wno_unopthreads_for_few_cores()]
);
if ($Self->{vlt_all}) {
file_grep("$out_filename", qr/\<var fl="e69" name="u.u0.u0.z0" dtype_id="3" vartype="logic" origName="z0" public="true" public_flat_rd="true" public_flat_rw="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="e84" name="u.u0.u0.u0.u0.z1" dtype_id="3" vartype="logic" origName="z1" public="true" public_flat_rd="true" public_flat_rw="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="e82" name="u.u0.u1.u0.u0.z" dtype_id="3" vartype="logic" origName="z" public="true" public_flat_rd="true" public_flat_rw="true"\/\>/i);
}
execute(
check_finished => 1,
expect =>

View File

@ -0,0 +1,9 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Stefan Wallentowitz.
`verilator_config
inline -module "l*"
public -module "l*" -var "z*"

View File

@ -33,12 +33,18 @@ module glbl();
`ifdef PUB_FUNC
reg GSR;
task setGSR;
`ifdef ATTRIBUTES
/* verilator public */
`endif
input value;
GSR = value;
endtask
`else
`ifdef ATTRIBUTES
reg GSR /*verilator public*/;
`else
reg GSR;
`endif
`endif
endmodule

View File

@ -8,9 +8,14 @@
#include <verilated.h>
#include <verilated_vcd_c.h>
#include "Vt_trace_public_func.h"
#include "Vt_trace_public_func_t.h"
#include "Vt_trace_public_func_glbl.h"
#include VM_PREFIX_INCLUDE
#ifdef T_TRACE_PUBLIC_FUNC_VLT
# include "Vt_trace_public_func_vlt_t.h"
# include "Vt_trace_public_func_vlt_glbl.h"
#else
# include "Vt_trace_public_func_t.h"
# include "Vt_trace_public_func_glbl.h"
#endif
unsigned long long main_time = 0;
double sc_time_stamp() { return (double)main_time; }
@ -18,7 +23,7 @@ double sc_time_stamp() { return (double)main_time; }
const unsigned long long dt_2 = 3;
int main(int argc, char** argv, char** env) {
Vt_trace_public_func* top = new Vt_trace_public_func("top");
VM_PREFIX* top = new VM_PREFIX("top");
Verilated::debug(0);
Verilated::traceEverOn(true);

View File

@ -14,7 +14,7 @@ top_filename("t/t_trace_public.v");
compile(
make_top_shell => 0,
make_main => 0,
v_flags2 => ["-DPUB_FUNC --trace --exe $Self->{t_dir}/$Self->{name}.cpp"],
v_flags2 => ["-DATTRIBUTES -DPUB_FUNC --trace --exe $Self->{t_dir}/$Self->{name}.cpp"],
);
execute(

View File

@ -0,0 +1,8 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Stefan Wallentowitz.
`verilator_config
public -module "glbl" -function "setGSR"

View File

@ -0,0 +1,28 @@
#!/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(vlt_all => 1);
top_filename("t/t_trace_public.v");
compile(
make_top_shell => 0,
make_main => 0,
v_flags2 => ["-DPUB_FUNC --trace --exe $Self->{t_dir}/t_trace_public_func.cpp $Self->{t_dir}/t_trace_public_func.vlt"],
);
execute(
check_finished => 1,
);
vcd_identical("$Self->{obj_dir}/simx.vcd",
"t/t_trace_public.out");
ok(1);
1;

View File

@ -8,9 +8,14 @@
#include <verilated.h>
#include <verilated_vcd_c.h>
#include "Vt_trace_public_sig.h"
#include "Vt_trace_public_sig_t.h"
#include "Vt_trace_public_sig_glbl.h"
#include VM_PREFIX_INCLUDE
#ifdef T_TRACE_PUBLIC_SIG_VLT
# include "Vt_trace_public_sig_vlt_t.h"
# include "Vt_trace_public_sig_vlt_glbl.h"
#else
# include "Vt_trace_public_sig_t.h"
# include "Vt_trace_public_sig_glbl.h"
#endif
unsigned long long main_time = 0;
double sc_time_stamp() { return (double)main_time; }
@ -18,7 +23,7 @@ double sc_time_stamp() { return (double)main_time; }
const unsigned long long dt_2 = 3;
int main(int argc, char** argv, char** env) {
Vt_trace_public_sig* top = new Vt_trace_public_sig("top");
VM_PREFIX* top = new VM_PREFIX("top");
Verilated::debug(0);
Verilated::traceEverOn(true);

View File

@ -14,7 +14,7 @@ top_filename("t/t_trace_public.v");
compile(
make_top_shell => 0,
make_main => 0,
v_flags2 => ["--trace --exe $Self->{t_dir}/$Self->{name}.cpp"],
v_flags2 => ["-DATTRIBUTES --trace --exe $Self->{t_dir}/$Self->{name}.cpp"],
);
execute(

View File

@ -0,0 +1,8 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Stefan Wallentowitz.
`verilator_config
public -module "glbl" -var "GSR"

View File

@ -0,0 +1,36 @@
#!/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(vlt_all => 1);
top_filename("t/t_trace_public.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
make_top_shell => 0,
make_main => 0,
v_flags2 => ["--trace --exe $Self->{t_dir}/t_trace_public_sig.cpp $Self->{t_dir}/t_trace_public_sig.vlt"],
);
if ($Self->{vlt_all}) {
file_grep("$out_filename", qr/\<var fl="e46" name="GSR" dtype_id="1" vartype="logic" origName="GSR" public="true" public_flat_rd="true" public_flat_rw="true"\/\>/i);
}
execute(
check_finished => 1,
);
vcd_identical("$Self->{obj_dir}/simx.vcd",
"t/t_trace_public.out");
# vcd_identical doesn't detect "$var a.b;" vs "$scope module a; $var b;"
file_grep("$Self->{obj_dir}/simx.vcd", qr/module glbl/i);
ok(1);
1;

View File

@ -94,10 +94,17 @@ module file (/*AUTOARG*/
endcase
end
`ifdef ISOLATE
function [31:16] get_31_16 /* verilator isolate_assignments*/;
input [31:0] t_crc /* verilator isolate_assignments*/;
get_31_16 = t_crc[31:16];
endfunction
`else
function [31:16] get_31_16;
input [31:0] t_crc;
get_31_16 = t_crc[31:16];
endfunction
`endif
task set_b_d;
`ifdef ISOLATE

View File

@ -5,6 +5,6 @@
t/t_unopt_combo.v:23: Example path: t.c
t/t_unopt_combo.v:80: Example path: ALWAYS
t/t_unopt_combo.v:22: Example path: t.b
t/t_unopt_combo.v:116: Example path: ALWAYS
t/t_unopt_combo.v:123: Example path: ALWAYS
t/t_unopt_combo.v:23: Example path: t.c
%Error: Exiting due to

View File

@ -12,6 +12,7 @@ scenarios(simulator => 1);
top_filename("t/t_unopt_combo.v");
compile(
v_flags2 => ['+define+ATTRIBUTES'],
fails => $Self->{vlt_all},
expect_filename => $Self->{golden_filename},
);

View File

@ -10,13 +10,19 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(simulator => 1);
top_filename("t/t_unopt_combo.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
verilator_flags2 => ['+define+ISOLATE --stats'],
verilator_flags2 => ["+define+ISOLATE --stats"],
);
if ($Self->{vlt_all}) {
file_grep($Self->{stats}, qr/Optimizations, isolate_assignments blocks\s+5/i);
file_grep("$out_filename", qr/\<var fl="d22" name="t.b" dtype_id="4" vartype="logic" origName="b" isolate_assignments="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="d98" name="__Vfunc_t.file.get_31_16__0__Vfuncout" dtype_id="5" vartype="logic" origName="__Vfunc_t__DOT__file__DOT__get_31_16__0__Vfuncout" isolate_assignments="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="d99" name="__Vfunc_t.file.get_31_16__0__t_crc" dtype_id="4" vartype="logic" origName="__Vfunc_t__DOT__file__DOT__get_31_16__0__t_crc" isolate_assignments="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="d111" name="__Vtask_t.file.set_b_d__1__t_crc" dtype_id="4" vartype="logic" origName="__Vtask_t__DOT__file__DOT__set_b_d__1__t_crc" isolate_assignments="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="d112" name="__Vtask_t.file.set_b_d__1__t_c" dtype_id="4" vartype="logic" origName="__Vtask_t__DOT__file__DOT__set_b_d__1__t_c" isolate_assignments="true"\/\>/i);
}
execute(

View File

@ -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 Stefan Wallentowitz.
`verilator_config
isolate_assignments -module "file" -var "b"
isolate_assignments -module "file" -task "set_b_d" -var "t_c*"
isolate_assignments -module "file" -function "get_31_16" -var "t_crc"
isolate_assignments -module "file" -function "get_31_16"

View File

@ -0,0 +1,32 @@
#!/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);
top_filename("t/t_unopt_combo.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile(
verilator_flags2 => ["--stats $Self->{t_dir}/t_unopt_combo_isolate.vlt"],
);
if ($Self->{vlt_all}) {
file_grep($Self->{stats}, qr/Optimizations, isolate_assignments blocks\s+5/i);
file_grep("$out_filename", qr/\<var fl="e22" name="t.b" dtype_id="4" vartype="logic" origName="b" isolate_assignments="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="e103" name="__Vfunc_t.file.get_31_16__0__Vfuncout" dtype_id="5" vartype="logic" origName="__Vfunc_t__DOT__file__DOT__get_31_16__0__Vfuncout" isolate_assignments="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="e104" name="__Vfunc_t.file.get_31_16__0__t_crc" dtype_id="4" vartype="logic" origName="__Vfunc_t__DOT__file__DOT__get_31_16__0__t_crc" isolate_assignments="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="e114" name="__Vtask_t.file.set_b_d__1__t_crc" dtype_id="4" vartype="logic" origName="__Vtask_t__DOT__file__DOT__set_b_d__1__t_crc" isolate_assignments="true"\/\>/i);
file_grep("$out_filename", qr/\<var fl="e115" name="__Vtask_t.file.set_b_d__1__t_c" dtype_id="4" vartype="logic" origName="__Vtask_t__DOT__file__DOT__set_b_d__1__t_c" isolate_assignments="true"\/\>/i);
}
execute(
);
ok(1);
1;

View File

@ -12,7 +12,7 @@ scenarios(vlt_all => 1);
top_filename("t/t_var_pinsizes.v");
compile(
verilator_flags2 => ["-sc -pins-bv 1 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
verilator_flags2 => ["-sc -pins-bv 1 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp $Self->{t_dir}/t_var_pinsizes.vlt"],
make_main => 0,
);
@ -25,6 +25,8 @@ if ($Self->{vlt_all}) {
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1_vlt;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16_vlt;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ o1;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<8>\s> \s+ o8;/x);
@ -34,6 +36,8 @@ if ($Self->{vlt_all}) {
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1_vlt;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16_vlt;/x);
}
execute();

View File

@ -12,7 +12,7 @@ scenarios(vlt_all => 1);
top_filename("t/t_var_pinsizes.v");
compile(
verilator_flags2 => ["-sc -pins-bv 2 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
verilator_flags2 => ["-sc -pins-bv 2 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp $Self->{t_dir}/t_var_pinsizes.vlt"],
make_main => 0,
);
@ -25,6 +25,8 @@ compile(
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1_vlt;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16_vlt;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<bool> \s+ o1;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<8>\s> \s+ o8;/x);
@ -34,6 +36,8 @@ compile(
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1_vlt;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16_vlt;/x);
}
execute();

View File

@ -12,7 +12,7 @@ scenarios(vlt_all => 1);
top_filename("t/t_var_pinsizes.v");
compile(
verilator_flags2 => ["-sc -no-pins64 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
verilator_flags2 => ["-sc -no-pins64 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp $Self->{t_dir}/t_var_pinsizes.vlt"],
make_main => 0,
);
@ -25,6 +25,8 @@ compile(
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1_vlt;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16_vlt;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<bool> \s+ o1;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint32_t> \s+ o8;/x);
@ -34,6 +36,8 @@ compile(
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1_vlt;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16_vlt;/x);
}
execute();

View File

@ -12,7 +12,7 @@ scenarios(vlt_all => 1);
top_filename("t/t_var_pinsizes.v");
compile(
verilator_flags2 => ["-sc -pins64 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
verilator_flags2 => ["-sc -pins64 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp $Self->{t_dir}/t_var_pinsizes.vlt"],
make_main => 0,
);
@ -25,6 +25,8 @@ if ($Self->{vlt_all}) {
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1_vlt;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16_vlt;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<bool> \s+ o1;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint32_t> \s+ o8;/x);
@ -34,6 +36,8 @@ if ($Self->{vlt_all}) {
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1_vlt;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16_vlt;/x);
}
execute();

View File

@ -8,9 +8,9 @@
module t (/*AUTOARG*/
// Outputs
o1, o8, o16, o32, o64, o65, o128, o513, o1a2, o94a3, obv1, obv16,
o1, o8, o16, o32, o64, o65, o128, o513, o1a2, o94a3, obv1, obv16, obv1_vlt, obv16_vlt,
// Inputs
clk, i1, i8, i16, i32, i64, i65, i128, i513, i1a2, i94a3, ibv1, ibv16
clk, i1, i8, i16, i32, i64, i65, i128, i513, i1a2, i94a3, ibv1, ibv16, ibv1_vlt, ibv16_vlt
);
input clk;
@ -38,10 +38,14 @@ module t (/*AUTOARG*/
output logic [93:0] o94a3 [2:0];
input [0:0] ibv1 /*verilator sc_bv*/;
input [15:0] ibv16 /*verilator sc_bv*/;
input [15:0] ibv16 /*verilator sc_bv*/;
input [0:0] ibv1_vlt;
input [15:0] ibv16_vlt;
output logic [0:0] obv1 /*verilator sc_bv*/;
output logic [15:0] obv16 /*verilator sc_bv*/;
output logic [0:0] obv1_vlt;
output logic [15:0] obv16_vlt;
always @ (posedge clk) begin
o1 <= i1;
@ -54,6 +58,8 @@ module t (/*AUTOARG*/
o513 <= i513;
obv1 <= ibv1;
obv16 <= ibv16;
obv1_vlt <= ibv1_vlt;
obv16_vlt <= ibv16_vlt;
o1a2 <= i1a2;
o94a3 <= i94a3;
end

View File

@ -0,0 +1,10 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Stefan Wallentowitz.
`verilator_config
sc_bv -module "t" -var "ibv1_vlt"
sc_bv -module "*" -var "ibv16_vlt"
sc_bv -module "*" -var "obv*_vlt"

View File

@ -0,0 +1,7 @@
%Error: t/t_vlt_syntax_bad.vlt:8: sensitivity not expected for attribute
public -module "t" @(posedge clk)
^
%Error: t/t_vlt_syntax_bad.vlt:9: isolate_assignments only applies to signals or functions/tasks
isolate_assignments -module "t"
^~~~~~~~~~~~~~~~~~~
%Error: Exiting due to

View File

@ -0,0 +1,19 @@
#!/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(vlt_all => 1);
compile(
verilator_flags2 => ["t/t_vlt_syntax_bad.vlt"],
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -0,0 +1,2 @@
module t;
endmodule

View File

@ -0,0 +1,9 @@
// 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
public -module "t" @(posedge clk)
isolate_assignments -module "t"

View File

@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(vlt => 1);
lint(
verilator_flags2 => ["--lint-only t/t_vlt_warn.vlt"],
verilator_flags2 => ["--lint-only t/t_vlt_warn.vlt -Wall"],
);
ok(1);

View File

@ -5,13 +5,16 @@
`verilator_config
lint_off -rule DEPRECATED -file "t/t_vlt_warn.vlt" -lines 12
lint_off -rule DEPRECATED -file "t/t_vlt_warn.vlt" -lines 13
lint_off -rule CASEINCOMPLETE -file "t/t_vlt_warn.v"
lint_off -rule WIDTH -file "t/t_vlt_warn.v" -lines 18
lint_off -rule DECLFILENAME -file "*/t_vlt_warn.v"
// Test wildcard filenames
lint_off -msg WIDTH -file "*/t_vlt_warn.v" -lines 19-19
// Test global disables
lint_off -file "*/t_vlt_warn.v" -lines 20-20
// Test match
lint_off -rule UNUSED -file "*/t_vlt_warn.v" -match "Signal is not used: 'width_warn*'"
coverage_off -file "t/t_vlt_warn.v"
// Test --flag is also accepted