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 * 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] **** 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>" [-lines <line> [ - <line>]]]
=item lint_off [-rule <message>] [-file "<filename>"] [-match "<string>"]
Enable/disables the specified lint warning, in the specified filename (or Enable/disables the specified lint warning, in the specified filename (or
wildcard with '*' or '?', or all files if omitted) and range of line wildcard with '*' or '?', or all files if omitted) and range of line
numbers (or all lines if omitted). 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 enabled/disabled. This will override all later lint warning enables for
the specified region. 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 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. 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 For tracing_off, cells below any module in the files/ranges specified will
also not be traced. 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 =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 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. 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 =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 always improving performance. It's also a good idea to enable the
IMPERFECTSCH warning, to insure all clock enables are properly recognized. 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 clocker*/
=item /*verilator no_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 and propagate the clocker attribute automatically to derived signals. See
C<--clk> for more information. 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*/ =item /*verilator coverage_block_off*/
Specifies the entire begin/end block should be ignored for coverage Specifies the entire begin/end block should be ignored for coverage
analysis purposes. analysis purposes.
Same as C<coverage_block_off> in configuration files, see
L</"CONFIGURATION FILES"> for more information.
=item /*verilator coverage_off*/ =item /*verilator coverage_off*/
Specifies that following lines of code should have coverage disabled. 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 allow "." in signal names. When tracing such signals the tracing routines
will replace the __DOT__ with the period. 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*/ =item /*verilator isolate_assignments*/
Used after a signal declaration to indicate the assignments to this signal 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
end end
Same as C<isolate_assignments> in configuration files, see
L</"CONFIGURATION FILES"> for more information.
=item /*verilator lint_off I<msg>*/ =item /*verilator lint_off I<msg>*/
Disable the specified warning message for any warnings following the comment. 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 module to reduce the size of the interface class, to aid compile time at a
small performance loss. small performance loss.
Same as C<no_inline> in configuration files, see L</"CONFIGURATION
FILES"> for more information.
=item /*verilator no_inline_task*/ =item /*verilator no_inline_task*/
Used in a function or task variable definition section to specify the 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 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. 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) =item /*verilator public*/ (parameter)
Used after a parameter declaration to indicate the emitted C code should 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 function that accesses the variable. This is nicer as it provides an
obvious entry point that is also compatible across simulators. 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) =item /*verilator public*/ (task/function)
Used inside the declaration section of a function or task declaration to 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 You may want to use DPI exports instead, as it's compatible with other
simulators. simulators.
Same as C<public> in configuration files, see L</"CONFIGURATION FILES">
for more information.
=item /*verilator public_flat*/ (variable) =item /*verilator public_flat*/ (variable)
Used after an input, output, register, or wire declaration to indicate the 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 the signal or path to it may change based upon the module inlining which
takes place. takes place.
Same as C<public_flat> in configuration files, see L</"CONFIGURATION
FILES"> for more information.
=item /*verilator public_flat_rd*/ (variable) =item /*verilator public_flat_rd*/ (variable)
Used after an input, output, register, or wire declaration to indicate the Used after an input, output, register, or wire declaration to indicate the
signal should be declared public_flat (see above), but read-only. 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) =item /*verilator public_flat_rw @(<edge_list>) */ (variable)
Used after an input, output, register, or wire declaration to indicate the 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 sensitivity edge list. Set for all variables, ports and wires using the
--public-flat-rw switch. --public-flat-rw switch.
Same as C<public_flat_rw> in configuration files, see L</"CONFIGURATION
FILES"> for more information.
=item /*verilator public_module*/ =item /*verilator public_module*/
Used after a module statement to indicate the module should not be inlined 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 public signals or `systemc_ directives. Also set for all modules when
using the --public switch. using the --public switch.
Same as C<public> in configuration files, see L</"CONFIGURATION FILES">
for more information.
=item /*verilator sc_clock*/ =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 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 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. 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 the port width is parameterized and different of such modules interface
a templated module (such as a transactor) or for other reasons. In general 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 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*/ =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 $sformatf. This allows creation of DPI functions with $display like
behavior. See the test_regress/t/t_dpi_display.v file for an example. 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...>*/ =item /*verilator tag <text...>*/
Attached after a variable or structure member to indicate opaque (to Attached after a variable or structure member to indicate opaque (to

View File

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

View File

@ -30,133 +30,491 @@
#include <string> #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: public:
int m_lineno; // Line number to make change at V3ConfigWildcardResolver() { m_last = m_mapResolved.end(); }
V3ErrorCode m_code; // Error code
bool m_on; // True to enable message /// Update into maps from other
V3ConfigLine(V3ErrorCode code, int lineno, bool on) void update(const V3ConfigWildcardResolver& other) {
: m_lineno(lineno), m_code(code), m_on(on) {} typename Map::const_iterator it;
~V3ConfigLine() {} for (it = other.m_mapResolved.begin(); it != other.m_mapResolved.end(); ++it) {
inline bool operator< (const V3ConfigLine& rh) const { m_mapResolved[it->first].update(it->second);
if (m_lineno<rh.m_lineno) return true; }
if (m_lineno>rh.m_lineno) return false; for (it = other.m_mapWildcard.begin(); it != other.m_mapWildcard.end(); ++it) {
if (m_code<rh.m_code) return true; m_mapWildcard[it->first].update(it->second);
if (m_code>rh.m_code) return false; }
}
// 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 // Always turn "on" before "off" so that overlapping lines will end
// up finally with the error "off" // 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) { std::ostream& operator<<(std::ostream& os, V3ConfigIgnoresLine rhs) {
return os<<rhs.m_lineno<<", "<<rhs.m_code<<", "<<rhs.m_on; } return os << rhs.m_lineno << ", " << rhs.m_code << ", " << rhs.m_on;
}
class V3ConfigIgnores { // Some attributes are attached to entities of the occur on a fileline
typedef std::multiset<V3ConfigLine> IgnLines; // list of {line,code,on} // and multiple attributes can be attached to a line
typedef std::map<string,IgnLines> IgnFiles; // {filename} => list of {line,code,on} typedef std::bitset<AstPragmaType::ENUM_SIZE> V3ConfigLineAttribute;
// MEMBERS // File entity
string m_lastFilename; // Last filename looked up class V3ConfigFile {
int m_lastLineno; // Last linenumber looked up 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 LineAttrMap m_lineAttrs; // Atributes to line mapping
IgnLines::const_iterator m_lastEnd; // Point with end() IgnLines m_ignLines; // Ignore line settings
Waivers m_waivers; // Waive messages
IgnFiles m_ignWilds; // Ignores for each wildcarded filename struct {
IgnFiles m_ignFiles; // Ignores for each non-wildcarded filename 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) // Match a given line and attribute to the map, line 0 is any
bool lineMatch(int lineno, AstPragmaType type) {
V3ConfigIgnores() { m_lastLineno = -1; } if (m_lineAttrs.find(0) != m_lineAttrs.end() && m_lineAttrs[0][type]) return true;
~V3ConfigIgnores() {} if (m_lineAttrs.find(lineno) == m_lineAttrs.end()) return false;
return m_lineAttrs[lineno][type];
// 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();
} }
public: 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) { void update(const V3ConfigFile& file) {
// Insert // Copy in all Attributes
IgnLines* linesp = findWilds(wildname); for (LineAttrMap::const_iterator it = file.m_lineAttrs.begin();
UINFO(9,"config addIgnore "<<wildname<<":"<<lineno<<", "<<code<<", "<<on<<endl); it != file.m_lineAttrs.end(); ++it) {
linesp->insert(V3ConfigLine(code, lineno, on)); m_lineAttrs[it->first] |= it->second;
// Flush the match cache, due to a change in the rules. }
m_ignFiles.clear(); // Copy in all ignores
m_lastFilename = " "; 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) { inline void applyIgnores(FileLine* filelinep) {
// HOT routine, called each parsed token line // HOT routine, called each parsed token line of this filename
if (m_lastLineno != filelinep->lastLineno() if (m_lastIgnore.lineno != filelinep->lineno()) {
|| m_lastFilename != filelinep->filename()) { // UINFO(9," ApplyIgnores for "<<filelinep->ascii()<<endl);
//UINFO(9," ApplyIgnores for "<<filelinep->ascii()<<endl);
if (VL_UNLIKELY(m_lastFilename != filelinep->filename())) {
absBuild(filelinep->filename());
m_lastFilename = filelinep->filename();
}
// Process all on/offs for lines up to and including the current line // Process all on/offs for lines up to and including the current line
int curlineno = filelinep->lastLineno(); int curlineno = filelinep->lastLineno();
for (; m_lastIt != m_lastEnd; ++m_lastIt) { for (; m_lastIgnore.it != m_ignLines.end(); ++m_lastIgnore.it) {
if (m_lastIt->m_lineno > curlineno) break; if (m_lastIgnore.it->m_lineno > curlineno) break;
//UINFO(9," Hit "<<*m_lastIt<<endl); // UINFO(9," Hit "<<*m_lastIt<<endl);
filelinep->warnOn(m_lastIt->m_code, m_lastIt->m_on); filelinep->warnOn(m_lastIgnore.it->m_code, m_lastIgnore.it->m_on);
} }
if (0 && debug() >= 9) { if (0 && debug() >= 9) {
for (IgnLines::const_iterator it=m_lastIt; it != m_lastEnd; ++it) { for (IgnLines::const_iterator it = m_lastIgnore.it; it != m_ignLines.end(); ++it) {
UINFO(9," NXT "<<*it<<endl); 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 // 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) { void V3Config::addIgnore(V3ErrorCode code, bool on, const string& filename, int min, int max) {
if (filename=="*") { if (filename == "*") {
FileLine::globalWarnOff(code,!on); FileLine::globalWarnOff(code, !on);
} else { } else {
V3ConfigIgnores::singleton().addIgnore(code, filename, min, on); V3ConfigResolver::s().files().at(filename).addIgnore(code, min, on);
if (max) V3ConfigIgnores::singleton().addIgnore(code, filename, max, !on); if (max) V3ConfigResolver::s().files().at(filename).addIgnore(code, max, !on);
V3ConfigResolver::s().files().flush();
} }
} }
void V3Config::applyIgnores(FileLine* filelinep) { void V3Config::addInline(FileLine* fl, const string& module, const string& ftask, bool on) {
V3ConfigIgnores::singleton().applyIgnores(filelinep); 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 "V3Error.h"
#include "V3FileLine.h" #include "V3FileLine.h"
#include "V3Ast.h"
//###################################################################### //######################################################################
class V3Config { class V3Config {
public: 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 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 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 #endif // Guard

View File

@ -131,7 +131,10 @@ class EmitXmlFileVisitor : public AstNVisitor {
} }
puts(" origName="); putsQuoted(nodep->origName()); puts(" origName="); putsQuoted(nodep->origName());
// Attributes // 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->attrClockEn()) puts(" clock_enable=\"true\"");
if (nodep->attrIsolateAssign()) puts(" isolate_assignments=\"true\""); if (nodep->attrIsolateAssign()) puts(" isolate_assignments=\"true\"");
if (nodep->isSigPublic()) puts(" public=\"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()) { if (!locationStr.empty()) {
lstr<<std::setw(ascii().length())<<" "<<": "<<locationStr; 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(); else if (!V3Error::errorContexted()) nsstr<<warnContextPrimary();
V3Error::v3errorEnd(nsstr, lstr.str()); V3Error::v3errorEnd(nsstr, lstr.str());
} }

View File

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

View File

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

View File

@ -74,6 +74,14 @@ bool VString::wildmatch(const char* s, const char* p) {
return (*s == '\0'); 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) { string VString::dot(const string& a, const string& dot, const string& b) {
if (b=="") return a; if (b=="") return a;
if (a=="") return b; if (a=="") return b;

View File

@ -63,6 +63,10 @@ public:
// METHODS (generic string utilities) // METHODS (generic string utilities)
// Return true if p with ? or *'s matches s // Return true if p with ? or *'s matches s
static bool wildmatch(const char* s, const char* p); 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 // Return {a}{dot}{b}, omitting dot if a or b are empty
static string dot(const string& a, const string& dot, const string& b); static string dot(const string& a, const string& dot, const string& b);
// Convert string to lowercase (tolower) // 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 */ {ws} { FL_FWD; FL_BRK; } /* otherwise ignore white-space */
{crnl} { FL_FWD; FL_BRK; } /* Count line numbers */ {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_off" { FL; return yVLT_COVERAGE_OFF; }
"coverage_on" { FL; return yVLT_COVERAGE_ON; } "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_off" { FL; return yVLT_LINT_OFF; }
"lint_on" { FL; return yVLT_LINT_ON; } "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_off" { FL; return yVLT_TRACING_OFF; }
"tracing_on" { FL; return yVLT_TRACING_ON; } "tracing_on" { FL; return yVLT_TRACING_ON; }
-?"-block" { FL; return yVLT_D_BLOCK; }
-?"-file" { FL; return yVLT_D_FILE; } -?"-file" { FL; return yVLT_D_FILE; }
-?"-function" { FL; return yVLT_D_FUNCTION; }
-?"-lines" { FL; return yVLT_D_LINES; } -?"-lines" { FL; return yVLT_D_LINES; }
-?"-match" { FL; return yVLT_D_MATCH; }
-?"-module" { FL; return yVLT_D_MODULE; }
-?"-msg" { FL; return yVLT_D_MSG; } -?"-msg" { FL; return yVLT_D_MSG; }
-?"-rule" { FL; return yVLT_D_RULE; } -?"-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> yaSCCTOR "`systemc_implementation BLOCK"
%token<strp> yaSCDTOR "`systemc_imp_header BLOCK" %token<strp> yaSCDTOR "`systemc_imp_header BLOCK"
%token<fl> yVLT_COVERAGE_OFF "coverage_off" %token<fl> yVLT_CLOCKER "clocker"
%token<fl> yVLT_COVERAGE_ON "coverage_on" %token<fl> yVLT_CLOCK_ENABLE "clock_enable"
%token<fl> yVLT_LINT_OFF "lint_off" %token<fl> yVLT_COVERAGE_BLOCK_OFF "coverage_block_off"
%token<fl> yVLT_LINT_ON "lint_on" %token<fl> yVLT_COVERAGE_OFF "coverage_off"
%token<fl> yVLT_TRACING_OFF "tracing_off" %token<fl> yVLT_COVERAGE_ON "coverage_on"
%token<fl> yVLT_TRACING_ON "tracing_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_BLOCK "--block"
%token<fl> yVLT_D_LINES "--lines" %token<fl> yVLT_D_FILE "--file"
%token<fl> yVLT_D_MSG "--msg" %token<fl> yVLT_D_FUNCTION "--function"
%token<fl> yVLT_D_RULE "--rule" %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_IGNORE "${ignored-bbox-sys}"
%token<strp> yaD_DPI "${dpi-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
// Blank lines for type insertion // Blank lines for type insertion
// Blank lines for type insertion
%start source_text %start source_text
@ -2460,6 +2483,11 @@ cellpinItemE<pinp>: // IEEE: named_port_connection + empty
//************************************************ //************************************************
// EventControl lists // EventControl lists
attr_event_controlE<sentreep>:
/* empty */ { $$ = NULL; }
| attr_event_control { $$ = $1; }
;
attr_event_control<sentreep>: // ==IEEE: event_control attr_event_control<sentreep>: // ==IEEE: event_control
'@' '(' event_expression ')' { $$ = new AstSenTree($1,$3); } '@' '(' event_expression ')' { $$ = new AstSenTree($1,$3); }
| '@' '(' '*' ')' { $$ = NULL; } | '@' '(' '*' ')' { $$ = NULL; }
@ -5582,14 +5610,45 @@ memberQualOne<nodep>: // IEEE: property_qualifier + method_qualifier
// VLT Files // VLT Files
vltItem: vltItem:
vltOffFront { V3Config::addIgnore($1,false,"*",0,0); }
| vltOffFront yVLT_D_FILE yaSTRING { V3Config::addIgnore($1,false,*$3,0,0); } vltOffFront { V3Config::addIgnore($1, false, "*", 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
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM { V3Config::addIgnore($1,false,*$3,$5->toUInt(),$7->toUInt()+1); } { V3Config::addIgnore($1, false, *$3, 0, 0); }
| vltOnFront { V3Config::addIgnore($1,true,"*",0,0); } | vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM
| vltOnFront yVLT_D_FILE yaSTRING { V3Config::addIgnore($1,true,*$3,0,0); } { V3Config::addIgnore($1, false, *$3, $5->toUInt(), $5->toUInt()+1); }
| vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM { V3Config::addIgnore($1,true,*$3,$5->toUInt(),$5->toUInt()+1); } | vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM
| vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM { V3Config::addIgnore($1,true,*$3,$5->toUInt(),$7->toUInt()+1); } { 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>: vltOffFront<errcodeen>:
@ -5618,6 +5677,40 @@ vltOnFront<errcodeen>:
if ($$ == V3ErrorCode::EC_ERROR) { $1->v3error("Unknown Error Code: "<<*$3<<endl); } } 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 // For implementation functions see V3ParseGrammar.cpp

View File

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

View File

@ -12,7 +12,7 @@ scenarios(simulator => 1);
top_filename("t/t_assert_synth.v"); top_filename("t/t_assert_synth.v");
compile( compile(
v_flags2 => ['+define+FAILING_FULL'], v_flags2 => ['+define+FAILING_FULL +define+ATTRIBUTES'],
verilator_flags2 => ['--assert'], verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'], nc_flags2 => ['+assert'],
); );
@ -21,7 +21,7 @@ execute(
check_finished => 0, check_finished => 0,
fails => $Self->{vlt_all}, fails => $Self->{vlt_all},
expect => 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); 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"); top_filename("t/t_assert_synth.v");
compile( compile(
v_flags2 => ['+define+FAILING_PARALLEL'], v_flags2 => ['+define+FAILING_PARALLEL', '+define+ATTRIBUTES'],
verilator_flags2 => ['--assert'], verilator_flags2 => ['--assert'],
nc_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); scenarios(simulator => 1);
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile( 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( execute(
check_finished => 1, check_finished => 1,
); );

View File

@ -70,9 +70,15 @@ module t2(
endmodule endmodule
module t( module t(
`ifdef ATTRIBUTES
input clk0 /*verilator clocker*/, input clk0 /*verilator clocker*/,
input clk1 /*verilator clocker*/, input clk1 /*verilator clocker*/,
input clk2 /*verilator clocker*/, input clk2 /*verilator clocker*/,
`else
input clk0,
input clk1,
input clk2,
`endif
input data_in 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); scenarios(simulator => 1);
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile( compile(
verilator_flags2 => ["+define+ATTRIBUTES=1"],
); );
execute( execute(

View File

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

View File

@ -82,7 +82,9 @@ module alpha (/*AUTOARG*/
if (toggle) begin if (toggle) begin
// CHECK_COVER_MISSING(-1) // CHECK_COVER_MISSING(-1)
// This doesn't even get added // This doesn't even get added
`ifdef ATTRIBUTE
// verilator coverage_block_off // verilator coverage_block_off
`endif
$write(""); $write("");
end end
end end
@ -106,10 +108,12 @@ module beta (/*AUTOARG*/
// CHECK_COVER(-1,"top.t.b*",2) // CHECK_COVER(-1,"top.t.b*",2)
// t.b1 and t.b2 collapse to a count of 2 // t.b1 and t.b2 collapse to a count of 2
end end
if (toggle) begin if (toggle) begin : block
// CHECK_COVER_MISSING(-1) // CHECK_COVER_MISSING(-1)
// This doesn't // This doesn't
`ifdef ATTRIBUTE
// verilator coverage_block_off // verilator coverage_block_off
`endif
$write(""); $write("");
end end
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"); top_filename("t/t_cover_line.v");
compile( compile(
verilator_flags2 => ['--cc --coverage-line'], verilator_flags2 => ['--cc --coverage-line +define+ATTRIBUTE'],
); );
execute( 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"); top_filename("t/t_cover_line.v");
compile( compile(
verilator_flags2 => ['--sc --coverage-line'], verilator_flags2 => ['--sc --coverage-line +define+ATTRIBUTE'],
); );
execute( execute(

View File

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

View File

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

View File

@ -9,13 +9,17 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(simulator => 1); scenarios(simulator => 1);
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile( compile(
verilator_flags2 => ["--stats"], verilator_flags2 => ["--stats $Self->{t_dir}/t_dedupe_clk_gate.vlt"],
); );
if ($Self->{vlt_all}) { 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); file_grep($Self->{stats}, qr/Optimizations, Gate sigs deduped\s+(\d+)/i, 4);
} }
ok(1); ok(1);
1; 1;

View File

@ -40,7 +40,7 @@ endmodule
module clock_gate_latch (gated_clk, clk, clken); module clock_gate_latch (gated_clk, clk, clken);
output gated_clk; output gated_clk;
input clk, clken; input clk, clken;
reg clken_latched /*verilator clock_enable*/; reg clken_latched;
assign gated_clk = clk & clken_latched ; assign gated_clk = clk & clken_latched ;
wire clkb = ~clk; 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 "verilated.h"
#include "svdpi.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. # Version 2.0.
scenarios(simulator => 1); scenarios(simulator => 1);
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile( compile(
make_top_shell => 0, make_top_shell => 0,
make_main => 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( execute(
check_finished => 1, check_finished => 1,
); );

View File

@ -51,7 +51,11 @@ module t (/*AUTOARG*/
endmodule endmodule
`ifdef ATTRIBUTES
import "DPI-C" context function void mon_scope_name (input string formatted /*verilator sformat*/ ); 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_b(string name, int isOut);
import "DPI-C" context function void mon_register_done(); import "DPI-C" context function void mon_register_done();
import "DPI-C" context function void mon_eval(); 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); void mon_register_a(const char* namep, void* sigp, bool isOut);
`verilog `verilog
`ifdef ATTRIBUTES
input int in /*verilator public_flat_rd*/; input int in /*verilator public_flat_rd*/;
output int fr_a /*verilator public_flat_rw @(posedge t.monclk)*/; output int fr_a /*verilator public_flat_rw @(posedge t.monclk)*/;
output int fr_b /*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; output int fr_chk;
always @* fr_chk = in + 1; 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 endmodule
`ifdef USE_INLINE_MID `ifdef ATTRIBUTES
`define INLINE_MODULE /*verilator inline_module*/ `ifdef USE_INLINE_MID
`define INLINE_MID_MODULE /*verilator no_inline_module*/
`else
`ifdef USE_INLINE
`define INLINE_MODULE /*verilator inline_module*/ `define INLINE_MODULE /*verilator inline_module*/
`define INLINE_MID_MODULE /*verilator inline_module*/ `define INLINE_MID_MODULE /*verilator no_inline_module*/
`else `else
`define INLINE_MODULE /*verilator public_module*/ `ifdef USE_INLINE
`define INLINE_MID_MODULE /*verilator public_module*/ `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 `endif
`else
`define INLINE_MODULE
`define INLINE_MID_MODULE
`endif `endif
module global_mod; module global_mod;

View File

@ -10,11 +10,19 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(simulator => 1); scenarios(simulator => 1);
top_filename("t/t_func_dotted.v"); top_filename("t/t_func_dotted.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile( 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( execute(
check_finished => 1, 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); scenarios(simulator => 1);
top_filename("t/t_func_dotted.v"); top_filename("t/t_func_dotted.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile( 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( execute(
check_finished => 1, 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); scenarios(simulator => 1);
top_filename("t/t_func_dotted.v"); top_filename("t/t_func_dotted.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile( 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( execute(
check_finished => 1, 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 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); module ps (input printclk);
`INLINE_MODULE
// Check that %m stays correct across inlines // Check that %m stays correct across inlines
always @ (posedge printclk) $write("[%0t] %m: Clocked\n", $time); always @ (posedge printclk) $write("[%0t] %m: Clocked\n", $time);
endmodule endmodule
module l1 (input [7:0] a, output [7:0] z `PUBLIC); module l1 (input [7:0] a, output [7:0] z);
`INLINE_MODULE wire [7:0] z0; wire [7:0] z1;
wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC;
assign z = z0+z1; assign z = z0+z1;
l2 u0 (a, z0); l2 u1 (a, z1); l2 u0 (a, z0); l2 u1 (a, z1);
endmodule endmodule
module l2 (input [7:0] a, output [7:0] z `PUBLIC); module l2 (input [7:0] a, output [7:0] z);
`INLINE_MODULE wire [7:0] z0; wire [7:0] z1;
wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC;
assign z = z0+z1; assign z = z0+z1;
wire [7:0] a1 = a+8'd1; wire [7:0] a1 = a+8'd1;
l3 u0 (a, z0); l3 u1 (a1, z1); l3 u0 (a, z0); l3 u1 (a1, z1);
endmodule endmodule
module l3 (input [7:0] a, output [7:0] z `PUBLIC); module l3 (input [7:0] a, output [7:0] z);
`INLINE_MODULE wire [7:0] z0; wire [7:0] z1;
wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC;
assign z = z0+z1; assign z = z0+z1;
wire [7:0] a1 = a+8'd1; wire [7:0] a1 = a+8'd1;
l4 u0 (a, z0); l4 u1 (a1, z1); l4 u0 (a, z0); l4 u1 (a1, z1);
endmodule endmodule
module l4 (input [7:0] a, output [7:0] z `PUBLIC); module l4 (input [7:0] a, output [7:0] z);
`INLINE_MODULE wire [7:0] z0; wire [7:0] z1;
wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC;
assign z = z0+z1; assign z = z0+z1;
wire [7:0] a1 = a+8'd1; wire [7:0] a1 = a+8'd1;
l5 #(1) u0 (a, z0); l5 #(2) u1 (a1, z1); l5 #(1) u0 (a, z0); l5 #(2) u1 (a1, z1);
endmodule endmodule
module l5 (input [7:0] a, output [7:0] z `PUBLIC); module l5 (input [7:0] a, output [7:0] z);
`INLINE_MODULE
parameter PARAM = 5; parameter PARAM = 5;
wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC; wire [7:0] z0; wire [7:0] z1;
assign z = a; assign z = a;
endmodule endmodule

View File

@ -10,10 +10,20 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(simulator => 1); scenarios(simulator => 1);
top_filename("t/t_inst_tree.v"); top_filename("t/t_inst_tree.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile( 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( execute(
check_finished => 1, 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(); my $default_vltmt_threads = $Self->get_default_vltmt_threads();
compile( 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 # Force 3 threads even if we have fewer cores
$Self->{vltmt} ? "--threads $default_vltmt_threads" : ""] $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"); top_filename("t/t_inst_tree.v");
compile( 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()] $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); scenarios(simulator => 1);
top_filename("t/t_inst_tree.v"); top_filename("t/t_inst_tree.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile( 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( execute(
check_finished => 1, check_finished => 1,
expect => 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); scenarios(simulator => 1);
top_filename("t/t_inst_tree.v"); top_filename("t/t_inst_tree.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile( compile(
v_flags2 => ['+define+USE_INLINE', '+define+USE_PUBLIC', v_flags2 => ["t/$Self->{name}.vlt",
$Self->wno_unopthreads_for_few_cores()] $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( execute(
check_finished => 1, check_finished => 1,
expect => 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 `ifdef PUB_FUNC
reg GSR; reg GSR;
task setGSR; task setGSR;
`ifdef ATTRIBUTES
/* verilator public */ /* verilator public */
`endif
input value; input value;
GSR = value; GSR = value;
endtask endtask
`else `else
`ifdef ATTRIBUTES
reg GSR /*verilator public*/; reg GSR /*verilator public*/;
`else
reg GSR;
`endif
`endif `endif
endmodule endmodule

View File

@ -8,9 +8,14 @@
#include <verilated.h> #include <verilated.h>
#include <verilated_vcd_c.h> #include <verilated_vcd_c.h>
#include "Vt_trace_public_func.h" #include VM_PREFIX_INCLUDE
#include "Vt_trace_public_func_t.h" #ifdef T_TRACE_PUBLIC_FUNC_VLT
#include "Vt_trace_public_func_glbl.h" # 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; unsigned long long main_time = 0;
double sc_time_stamp() { return (double)main_time; } 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; const unsigned long long dt_2 = 3;
int main(int argc, char** argv, char** env) { 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::debug(0);
Verilated::traceEverOn(true); Verilated::traceEverOn(true);

View File

@ -14,7 +14,7 @@ top_filename("t/t_trace_public.v");
compile( compile(
make_top_shell => 0, make_top_shell => 0,
make_main => 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( 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.h>
#include <verilated_vcd_c.h> #include <verilated_vcd_c.h>
#include "Vt_trace_public_sig.h" #include VM_PREFIX_INCLUDE
#include "Vt_trace_public_sig_t.h" #ifdef T_TRACE_PUBLIC_SIG_VLT
#include "Vt_trace_public_sig_glbl.h" # 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; unsigned long long main_time = 0;
double sc_time_stamp() { return (double)main_time; } 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; const unsigned long long dt_2 = 3;
int main(int argc, char** argv, char** env) { 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::debug(0);
Verilated::traceEverOn(true); Verilated::traceEverOn(true);

View File

@ -14,7 +14,7 @@ top_filename("t/t_trace_public.v");
compile( compile(
make_top_shell => 0, make_top_shell => 0,
make_main => 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( 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 endcase
end end
`ifdef ISOLATE
function [31:16] get_31_16 /* verilator isolate_assignments*/; function [31:16] get_31_16 /* verilator isolate_assignments*/;
input [31:0] t_crc /* verilator isolate_assignments*/; input [31:0] t_crc /* verilator isolate_assignments*/;
get_31_16 = t_crc[31:16]; get_31_16 = t_crc[31:16];
endfunction 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; task set_b_d;
`ifdef ISOLATE `ifdef ISOLATE

View File

@ -5,6 +5,6 @@
t/t_unopt_combo.v:23: Example path: t.c t/t_unopt_combo.v:23: Example path: t.c
t/t_unopt_combo.v:80: Example path: ALWAYS t/t_unopt_combo.v:80: Example path: ALWAYS
t/t_unopt_combo.v:22: Example path: t.b 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 t/t_unopt_combo.v:23: Example path: t.c
%Error: Exiting due to %Error: Exiting due to

View File

@ -12,6 +12,7 @@ scenarios(simulator => 1);
top_filename("t/t_unopt_combo.v"); top_filename("t/t_unopt_combo.v");
compile( compile(
v_flags2 => ['+define+ATTRIBUTES'],
fails => $Self->{vlt_all}, fails => $Self->{vlt_all},
expect_filename => $Self->{golden_filename}, 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); scenarios(simulator => 1);
top_filename("t/t_unopt_combo.v"); top_filename("t/t_unopt_combo.v");
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
compile( compile(
verilator_flags2 => ['+define+ISOLATE --stats'], verilator_flags2 => ["+define+ISOLATE --stats"],
); );
if ($Self->{vlt_all}) { if ($Self->{vlt_all}) {
file_grep($Self->{stats}, qr/Optimizations, isolate_assignments blocks\s+5/i); 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( 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"); top_filename("t/t_var_pinsizes.v");
compile( 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, 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<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<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<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<1>\s> \s+ o1;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<8>\s> \s+ o8;/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<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<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<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(); execute();

View File

@ -12,7 +12,7 @@ scenarios(vlt_all => 1);
top_filename("t/t_var_pinsizes.v"); top_filename("t/t_var_pinsizes.v");
compile( 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, 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<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<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<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<bool> \s+ o1;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<8>\s> \s+ o8;/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<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<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<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(); execute();

View File

@ -12,7 +12,7 @@ scenarios(vlt_all => 1);
top_filename("t/t_var_pinsizes.v"); top_filename("t/t_var_pinsizes.v");
compile( 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, 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<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<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<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<bool> \s+ o1;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint32_t> \s+ o8;/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<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<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<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(); execute();

View File

@ -12,7 +12,7 @@ scenarios(vlt_all => 1);
top_filename("t/t_var_pinsizes.v"); top_filename("t/t_var_pinsizes.v");
compile( 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, 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<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<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<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<bool> \s+ o1;/x);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint32_t> \s+ o8;/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<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<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<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(); execute();

View File

@ -8,9 +8,9 @@
module t (/*AUTOARG*/ module t (/*AUTOARG*/
// Outputs // 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 // 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; input clk;
@ -38,10 +38,14 @@ module t (/*AUTOARG*/
output logic [93:0] o94a3 [2:0]; output logic [93:0] o94a3 [2:0];
input [0:0] ibv1 /*verilator sc_bv*/; 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 [0:0] obv1 /*verilator sc_bv*/;
output logic [15:0] obv16 /*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 always @ (posedge clk) begin
o1 <= i1; o1 <= i1;
@ -54,6 +58,8 @@ module t (/*AUTOARG*/
o513 <= i513; o513 <= i513;
obv1 <= ibv1; obv1 <= ibv1;
obv16 <= ibv16; obv16 <= ibv16;
obv1_vlt <= ibv1_vlt;
obv16_vlt <= ibv16_vlt;
o1a2 <= i1a2; o1a2 <= i1a2;
o94a3 <= i94a3; o94a3 <= i94a3;
end 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); scenarios(vlt => 1);
lint( lint(
verilator_flags2 => ["--lint-only t/t_vlt_warn.vlt"], verilator_flags2 => ["--lint-only t/t_vlt_warn.vlt -Wall"],
); );
ok(1); ok(1);

View File

@ -5,13 +5,16 @@
`verilator_config `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 CASEINCOMPLETE -file "t/t_vlt_warn.v"
lint_off -rule WIDTH -file "t/t_vlt_warn.v" -lines 18 lint_off -rule WIDTH -file "t/t_vlt_warn.v" -lines 18
lint_off -rule DECLFILENAME -file "*/t_vlt_warn.v"
// Test wildcard filenames // Test wildcard filenames
lint_off -msg WIDTH -file "*/t_vlt_warn.v" -lines 19-19 lint_off -msg WIDTH -file "*/t_vlt_warn.v" -lines 19-19
// Test global disables // Test global disables
lint_off -file "*/t_vlt_warn.v" -lines 20-20 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" coverage_off -file "t/t_vlt_warn.v"
// Test --flag is also accepted // Test --flag is also accepted