mirror of
https://github.com/verilator/verilator.git
synced 2025-07-30 15:36:11 +00:00
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:
parent
98fb7ec193
commit
fad465abf1
4
Changes
4
Changes
@ -5,6 +5,10 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
* Verilator 4.027 devel
|
||||
|
||||
** Support attributes (public, isolate_assignments, etc.) in configuration files.
|
||||
|
||||
** Add -match to lint_off to waive warnings. [Philipp Wagner]
|
||||
|
||||
**** Add error on misused define. [Topa Tota]
|
||||
|
||||
|
||||
|
176
bin/verilator
176
bin/verilator
@ -2769,6 +2769,8 @@ purposes.
|
||||
|
||||
=item lint_off [-rule <message>] [-file "<filename>" [-lines <line> [ - <line>]]]
|
||||
|
||||
=item lint_off [-rule <message>] [-file "<filename>"] [-match "<string>"]
|
||||
|
||||
Enable/disables the specified lint warning, in the specified filename (or
|
||||
wildcard with '*' or '?', or all files if omitted) and range of line
|
||||
numbers (or all lines if omitted).
|
||||
@ -2780,6 +2782,10 @@ If the -rule is omitted, all lint warnings (see list in -Wno-lint) are
|
||||
enabled/disabled. This will override all later lint warning enables for
|
||||
the specified region.
|
||||
|
||||
If -match is set the linter warnings are matched against this (wildcard)
|
||||
string and are waived in case they match iff rule and file (with wildcard)
|
||||
also match.
|
||||
|
||||
In previous versions -rule was named -msg. The latter is deprecated, but
|
||||
still works with a deprecation info, it may be removed in future versions.
|
||||
|
||||
@ -2794,6 +2800,124 @@ and range of line numbers (or all lines if omitted).
|
||||
For tracing_off, cells below any module in the files/ranges specified will
|
||||
also not be traced.
|
||||
|
||||
=item clock_enable -module "<modulename>" -signal "<signame>"
|
||||
|
||||
Indicate the signal is used to gate a clock, and the user takes responsibility
|
||||
for insuring there are no races related to it.
|
||||
|
||||
Same as /*verilator clock_enable*/, see L</"LANGUAGE EXTENSIONS"> for
|
||||
more information and an example.
|
||||
|
||||
=item clocker -module "<modulename>" [-task "<taskname>"] -signal "<signame>"
|
||||
|
||||
=item clocker -module "<modulename>" [-function "<funcname>"] -signal "<signame>"
|
||||
|
||||
=item no_clocker -module "<modulename>" [-task "<taskname>"] -signal "<signame>"
|
||||
|
||||
=item no_clocker -module "<modulename>" [-function "<funcname>"] -signal "<signame>"
|
||||
|
||||
Indicate the signal is used as clock or not. This information is used by
|
||||
Verilator to mark the signal as clocker and propagate the clocker attribute
|
||||
automatically to derived signals. See C<--clk> for more information.
|
||||
|
||||
Same as /*verilator clocker*/, see L</"LANGUAGE EXTENSIONS"> for more
|
||||
information.
|
||||
|
||||
=item coverage_block_off -module "<modulename>" -block "<blockname>"
|
||||
|
||||
=item coverage_block_off -file "<filename>" -line <lineno>
|
||||
|
||||
Specifies the entire begin/end block should be ignored for coverage
|
||||
analysis purposes. Can either be specified as a named block or as a
|
||||
filename and line number.
|
||||
|
||||
Same as /*verilator coverage_block_off*/, see L</"LANGUAGE
|
||||
EXTENSIONS"> for more information.
|
||||
|
||||
=item full_case -file "<filename>" -lines <lineno>
|
||||
|
||||
=item parallel_case -file "<filename>" -lines <lineno>
|
||||
|
||||
Same as "//synopsys full_case" and "//synopsys parallel_case". When
|
||||
these synthesis directives are discovered, Verilator will either
|
||||
formally prove the directive to be true, or failing that, will insert
|
||||
the appropriate code to detect failing cases at simulation runtime and
|
||||
print an "Assertion failed" error message.
|
||||
|
||||
=item inline -module "<modulename>"
|
||||
|
||||
Specifies the module may be inlined into any modules that use this
|
||||
module. This is useful to speed up simulation runtime with some small
|
||||
loss of trace visibility and modularity. Note signals under inlined
|
||||
submodules will be named I<submodule>__DOT__I<subsignal> as C++ does
|
||||
not allow "." in signal names. When tracing such signals the tracing
|
||||
routines will replace the __DOT__ with the period.
|
||||
|
||||
Same as /*verilator inline_module*/, see L</"LANGUAGE EXTENSIONS"> for
|
||||
more information.
|
||||
|
||||
=item isolate_assignments -module "<modulename>" [-task "<taskname>"] -signal "<signame>"
|
||||
|
||||
=item isolate_assignments -module "<modulename>" [-function "<funcname>"] -signal "<signame>"
|
||||
|
||||
=item isolate_assignments -module "<modulename>" -function "<fname>"
|
||||
|
||||
Used to indicate the assignments to this signal in any blocks should be
|
||||
isolated into new blocks. When there is a large combinatorial block that
|
||||
is resulting in a UNOPTFLAT warning, attaching this to the signal causing
|
||||
a false loop may clear up the problem.
|
||||
|
||||
Same as /* verilator isolate_assignments */, see L</"LANGUAGE
|
||||
EXTENSIONS"> for more information.
|
||||
|
||||
=item no_inline -module "<modulename>"
|
||||
|
||||
Specifies the module should not be inlined into any modules that use
|
||||
this module. This is useful especially at the top level module to
|
||||
reduce the size of the interface class, to aid compile time at a small
|
||||
performance loss.
|
||||
|
||||
Same as /*verilator no_inline_module*/, see L</"LANGUAGE EXTENSIONS">
|
||||
for more information.
|
||||
|
||||
=item no_inline [-module "<modulename>"] -task "<taskname>"
|
||||
|
||||
=item no_inline [-module "<modulename>"] -function "<funcname>"
|
||||
|
||||
Specify the function or task should not be inlined into where it is
|
||||
used. This may reduce the size of the final executable when a task is
|
||||
used a very large number of times. For this flag to work, the task
|
||||
and tasks below it must be pure; they cannot reference any variables
|
||||
outside the task itself.
|
||||
|
||||
Same as /*verilator no_inline_task*/, see L</"LANGUAGE EXTENSIONS">
|
||||
for more information.
|
||||
|
||||
=item sc_bv -module "<modulename>" [-task "<taskname>"] -signal "<signame>"
|
||||
|
||||
=item sc_bv -module "<modulename>" [-function "<funcname>"] -signal "<signame>"
|
||||
|
||||
Sets the port to be of sc_bv<I<width>> type, instead of bool, vluint32_t or
|
||||
vluint64_t. This may be useful if the port width is parameterized and
|
||||
different of such modules interface a templated module (such as a transactor)
|
||||
or for other reasons. In general you should avoid using this attribute when
|
||||
not necessary as with increasing usage of sc_bv the performance decreases
|
||||
significantly.
|
||||
|
||||
Same as /*verilator sc_bv*/, see L</"LANGUAGE EXTENSIONS"> for more
|
||||
information.
|
||||
|
||||
=item sformat [-module "<modulename>"] [-task "<taskname>"] -signal "<signame>"
|
||||
|
||||
=item sformat [-module "<modulename>"] [-function "<funcname>"] -signal "<signame>"
|
||||
|
||||
Final input of a function or task "input string" to indicate the
|
||||
function or task should pass all remaining arguments through
|
||||
$sformatf. This allows creation of DPI functions with $display like
|
||||
behavior. See the test_regress/t/t_dpi_display.v file for an example.
|
||||
|
||||
Same as /*verilator sformat*/, see L</"LANGUAGE EXTENSIONS"> for more
|
||||
information.
|
||||
|
||||
=back
|
||||
|
||||
@ -2929,7 +3053,8 @@ per the C standard (it's unspecified in Verilog).
|
||||
|
||||
Specifies the entire begin/end block should be ignored for coverage
|
||||
analysis. Must be inside a basic block, e.g. within a begin/end pair.
|
||||
Same as /* verilator coverage_block_off */.
|
||||
Same as /* verilator coverage_block_off */ and C<coverage_block_off> in
|
||||
L</"CONFIGURATION FILES">.
|
||||
|
||||
=item `systemc_header
|
||||
|
||||
@ -3021,6 +3146,9 @@ scheduling algorithm, sometimes required for correct clock behavior, and
|
||||
always improving performance. It's also a good idea to enable the
|
||||
IMPERFECTSCH warning, to insure all clock enables are properly recognized.
|
||||
|
||||
Same as C<clock_enable> in configuration files, see L</"CONFIGURATION
|
||||
FILES"> for more information.
|
||||
|
||||
=item /*verilator clocker*/
|
||||
|
||||
=item /*verilator no_clocker*/
|
||||
@ -3030,11 +3158,17 @@ not. This information is used by Verilator to mark the signal as clocker
|
||||
and propagate the clocker attribute automatically to derived signals. See
|
||||
C<--clk> for more information.
|
||||
|
||||
Same as C<clocker> and C<no_clocker> in configuration files, see
|
||||
L</"CONFIGURATION FILES"> for more information.
|
||||
|
||||
=item /*verilator coverage_block_off*/
|
||||
|
||||
Specifies the entire begin/end block should be ignored for coverage
|
||||
analysis purposes.
|
||||
|
||||
Same as C<coverage_block_off> in configuration files, see
|
||||
L</"CONFIGURATION FILES"> for more information.
|
||||
|
||||
=item /*verilator coverage_off*/
|
||||
|
||||
Specifies that following lines of code should have coverage disabled.
|
||||
@ -3055,6 +3189,9 @@ submodules will be named I<submodule>__DOT__I<subsignal> as C++ does not
|
||||
allow "." in signal names. When tracing such signals the tracing routines
|
||||
will replace the __DOT__ with the period.
|
||||
|
||||
Same as C<inline> in configuration files, see L</"CONFIGURATION FILES">
|
||||
for more information.
|
||||
|
||||
=item /*verilator isolate_assignments*/
|
||||
|
||||
Used after a signal declaration to indicate the assignments to this signal
|
||||
@ -3091,6 +3228,9 @@ It would then internally break it into (sort of):
|
||||
end
|
||||
end
|
||||
|
||||
Same as C<isolate_assignments> in configuration files, see
|
||||
L</"CONFIGURATION FILES"> for more information.
|
||||
|
||||
=item /*verilator lint_off I<msg>*/
|
||||
|
||||
Disable the specified warning message for any warnings following the comment.
|
||||
@ -3126,6 +3266,9 @@ modules that use this module. This is useful especially at the top level
|
||||
module to reduce the size of the interface class, to aid compile time at a
|
||||
small performance loss.
|
||||
|
||||
Same as C<no_inline> in configuration files, see L</"CONFIGURATION
|
||||
FILES"> for more information.
|
||||
|
||||
=item /*verilator no_inline_task*/
|
||||
|
||||
Used in a function or task variable definition section to specify the
|
||||
@ -3134,6 +3277,9 @@ reduce the size of the final executable when a task is used a very large
|
||||
number of times. For this flag to work, the task and tasks below it must
|
||||
be pure; they cannot reference any variables outside the task itself.
|
||||
|
||||
Same as C<no_inline> in configuration files, see L</"CONFIGURATION
|
||||
FILES"> for more information.
|
||||
|
||||
=item /*verilator public*/ (parameter)
|
||||
|
||||
Used after a parameter declaration to indicate the emitted C code should
|
||||
@ -3161,6 +3307,9 @@ Instead of using public variables, consider instead making a DPI or public
|
||||
function that accesses the variable. This is nicer as it provides an
|
||||
obvious entry point that is also compatible across simulators.
|
||||
|
||||
Same as C<public> in configuration files, see L</"CONFIGURATION FILES">
|
||||
for more information.
|
||||
|
||||
=item /*verilator public*/ (task/function)
|
||||
|
||||
Used inside the declaration section of a function or task declaration to
|
||||
@ -3183,6 +3332,9 @@ the model will NOT notice changes made to variables in these functions.
|
||||
You may want to use DPI exports instead, as it's compatible with other
|
||||
simulators.
|
||||
|
||||
Same as C<public> in configuration files, see L</"CONFIGURATION FILES">
|
||||
for more information.
|
||||
|
||||
=item /*verilator public_flat*/ (variable)
|
||||
|
||||
Used after an input, output, register, or wire declaration to indicate the
|
||||
@ -3191,11 +3343,17 @@ signal. This will not declare this module public, which means the name of
|
||||
the signal or path to it may change based upon the module inlining which
|
||||
takes place.
|
||||
|
||||
Same as C<public_flat> in configuration files, see L</"CONFIGURATION
|
||||
FILES"> for more information.
|
||||
|
||||
=item /*verilator public_flat_rd*/ (variable)
|
||||
|
||||
Used after an input, output, register, or wire declaration to indicate the
|
||||
signal should be declared public_flat (see above), but read-only.
|
||||
|
||||
Same as C<public_flat_rd> in configuration files, see L</"CONFIGURATION
|
||||
FILES"> for more information.
|
||||
|
||||
=item /*verilator public_flat_rw @(<edge_list>) */ (variable)
|
||||
|
||||
Used after an input, output, register, or wire declaration to indicate the
|
||||
@ -3204,6 +3362,9 @@ where writes should be considered to have the timing specified by the given
|
||||
sensitivity edge list. Set for all variables, ports and wires using the
|
||||
--public-flat-rw switch.
|
||||
|
||||
Same as C<public_flat_rw> in configuration files, see L</"CONFIGURATION
|
||||
FILES"> for more information.
|
||||
|
||||
=item /*verilator public_module*/
|
||||
|
||||
Used after a module statement to indicate the module should not be inlined
|
||||
@ -3212,9 +3373,12 @@ Verilator automatically sets this attribute when the module contains any
|
||||
public signals or `systemc_ directives. Also set for all modules when
|
||||
using the --public switch.
|
||||
|
||||
Same as C<public> in configuration files, see L</"CONFIGURATION FILES">
|
||||
for more information.
|
||||
|
||||
=item /*verilator sc_clock*/
|
||||
|
||||
Rarely needed. Used after an input declaration to indicate the signal
|
||||
Deprecated. Used after an input declaration to indicate the signal
|
||||
should be declared in SystemC as a sc_clock instead of a bool. This was
|
||||
needed in SystemC 1.1 and 1.2 only; versions 2.0 and later do not require
|
||||
clock pins to be sc_clocks and this is no longer needed.
|
||||
@ -3226,7 +3390,10 @@ type, instead of bool, vluint32_t or vluint64_t. This may be useful if
|
||||
the port width is parameterized and different of such modules interface
|
||||
a templated module (such as a transactor) or for other reasons. In general
|
||||
you should avoid using this attribute when not necessary as with increasing
|
||||
usage of sc_bv the performance increases significantly.
|
||||
usage of sc_bv the performance decreases significantly.
|
||||
|
||||
Same as C<sc_bv> in configuration files, see L</"CONFIGURATION FILES">
|
||||
for more information.
|
||||
|
||||
=item /*verilator sformat*/
|
||||
|
||||
@ -3235,6 +3402,9 @@ indicate the function or task should pass all remaining arguments through
|
||||
$sformatf. This allows creation of DPI functions with $display like
|
||||
behavior. See the test_regress/t/t_dpi_display.v file for an example.
|
||||
|
||||
Same as C<sformat> in configuration files, see L</"CONFIGURATION FILES">
|
||||
for more information.
|
||||
|
||||
=item /*verilator tag <text...>*/
|
||||
|
||||
Attached after a variable or structure member to indicate opaque (to
|
||||
|
@ -142,7 +142,10 @@ public:
|
||||
NO_INLINE_MODULE,
|
||||
NO_INLINE_TASK,
|
||||
PUBLIC_MODULE,
|
||||
PUBLIC_TASK
|
||||
PUBLIC_TASK,
|
||||
FULL_CASE,
|
||||
PARALLEL_CASE,
|
||||
ENUM_SIZE
|
||||
};
|
||||
enum en m_e;
|
||||
inline AstPragmaType() : m_e(ILLEGAL) {}
|
||||
|
544
src/V3Config.cpp
544
src/V3Config.cpp
@ -30,133 +30,491 @@
|
||||
#include <string>
|
||||
|
||||
//######################################################################
|
||||
// Resolve wildcards in files, modules, ftasks or variables
|
||||
|
||||
class V3ConfigLine {
|
||||
// Template for a class that serves as a map for entities that can be specified
|
||||
// as wildcards and are accessed by a resolved name. It rebuilds a name lookup
|
||||
// cache of resolved entities. Entities stored in this container need an update
|
||||
// function that takes a reference of this type to join multiple entities into one.
|
||||
template <typename T> class V3ConfigWildcardResolver {
|
||||
typedef std::map<string, T> Map;
|
||||
|
||||
Map m_mapWildcard; // Wildcard strings to entities
|
||||
Map m_mapResolved; // Resolved strings to converged entities
|
||||
typename Map::iterator m_last; // Last access, will probably hit again
|
||||
public:
|
||||
int m_lineno; // Line number to make change at
|
||||
V3ErrorCode m_code; // Error code
|
||||
bool m_on; // True to enable message
|
||||
V3ConfigLine(V3ErrorCode code, int lineno, bool on)
|
||||
: m_lineno(lineno), m_code(code), m_on(on) {}
|
||||
~V3ConfigLine() {}
|
||||
inline bool operator< (const V3ConfigLine& rh) const {
|
||||
if (m_lineno<rh.m_lineno) return true;
|
||||
if (m_lineno>rh.m_lineno) return false;
|
||||
if (m_code<rh.m_code) return true;
|
||||
if (m_code>rh.m_code) return false;
|
||||
V3ConfigWildcardResolver() { m_last = m_mapResolved.end(); }
|
||||
|
||||
/// Update into maps from other
|
||||
void update(const V3ConfigWildcardResolver& other) {
|
||||
typename Map::const_iterator it;
|
||||
for (it = other.m_mapResolved.begin(); it != other.m_mapResolved.end(); ++it) {
|
||||
m_mapResolved[it->first].update(it->second);
|
||||
}
|
||||
for (it = other.m_mapWildcard.begin(); it != other.m_mapWildcard.end(); ++it) {
|
||||
m_mapWildcard[it->first].update(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
// Access and create a (wildcard) entity
|
||||
T& at(const string& name) {
|
||||
// Don't store into wildcards if the name is not a wildcard string
|
||||
return m_mapWildcard[name];
|
||||
}
|
||||
// Access an entity and resolve wildcards that match it
|
||||
T* resolve(const string& name) {
|
||||
// Lookup if recently accessed matches
|
||||
if (VL_LIKELY(m_last != m_mapResolved.end()) && VL_LIKELY(m_last->first == name)) {
|
||||
return &m_last->second;
|
||||
}
|
||||
// Lookup if it was resolved before, typically not
|
||||
typename Map::iterator it = m_mapResolved.find(name);
|
||||
if (VL_UNLIKELY(it != m_mapResolved.end())) { return &it->second; }
|
||||
|
||||
T* newp = NULL;
|
||||
// Cannot be resolved, create if matched
|
||||
|
||||
// Update this entity with all matches in the wildcards
|
||||
for (it = m_mapWildcard.begin(); it != m_mapWildcard.end(); ++it) {
|
||||
if (VString::wildmatch(name, it->first)) {
|
||||
if (!newp) {
|
||||
newp = &m_mapResolved[name]; // Emplace and get pointer
|
||||
}
|
||||
newp->update(it->second);
|
||||
}
|
||||
}
|
||||
return newp;
|
||||
}
|
||||
// Flush on update
|
||||
void flush() { m_mapResolved.clear(); }
|
||||
};
|
||||
|
||||
// Only public_flat_rw has the sensitity tree
|
||||
class V3ConfigVarAttr {
|
||||
public:
|
||||
AstAttrType m_type; // Type of attribute
|
||||
AstSenTree* m_sentreep; // Sensitivity tree for public_flat_rw
|
||||
V3ConfigVarAttr(AstAttrType type, AstSenTree* sentreep)
|
||||
: m_type(type)
|
||||
, m_sentreep(sentreep) {}
|
||||
};
|
||||
|
||||
// Overload vector with the required update function and to apply all entries
|
||||
class V3ConfigVar : public std::vector<V3ConfigVarAttr> {
|
||||
public:
|
||||
// Update from other by copying all attributes
|
||||
void update(const V3ConfigVar& node) {
|
||||
reserve(size() + node.size());
|
||||
insert(end(), node.begin(), node.end());
|
||||
}
|
||||
// Apply all attributes to the variable
|
||||
void apply(AstVar* varp) {
|
||||
for (const_iterator it = begin(); it != end(); ++it) {
|
||||
AstNode* newp = new AstAttrOf(varp->fileline(), it->m_type);
|
||||
varp->addAttrsp(newp);
|
||||
if (it->m_type == AstAttrType::VAR_PUBLIC_FLAT_RW && it->m_sentreep) {
|
||||
newp->addNext(new AstAlwaysPublic(varp->fileline(), it->m_sentreep, NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef V3ConfigWildcardResolver<V3ConfigVar> V3ConfigVarResolver;
|
||||
|
||||
//######################################################################
|
||||
// Function or task: Have variables and properties
|
||||
|
||||
class V3ConfigFTask {
|
||||
V3ConfigVarResolver m_vars; // Variables in function/task
|
||||
bool m_isolate; // Isolate function return
|
||||
bool m_noinline; // Don't inline function/task
|
||||
bool m_public; // Public function/task
|
||||
|
||||
public:
|
||||
V3ConfigFTask()
|
||||
: m_isolate(false)
|
||||
, m_noinline(false)
|
||||
, m_public(false) {}
|
||||
void update(const V3ConfigFTask& f) {
|
||||
// Don't overwrite true with false
|
||||
if (f.m_isolate) m_isolate = true;
|
||||
if (f.m_noinline) m_noinline = true;
|
||||
if (f.m_public) m_public = true;
|
||||
m_vars.update(f.m_vars);
|
||||
}
|
||||
|
||||
V3ConfigVarResolver& vars() { return m_vars; }
|
||||
|
||||
void setIsolate(bool set) { m_isolate = set; }
|
||||
void setNoInline(bool set) { m_noinline = set; }
|
||||
void setPublic(bool set) { m_public = set; }
|
||||
|
||||
void apply(AstNodeFTask* ftaskp) {
|
||||
if (m_noinline)
|
||||
ftaskp->addStmtsp(new AstPragma(ftaskp->fileline(), AstPragmaType::NO_INLINE_TASK));
|
||||
if (m_public)
|
||||
ftaskp->addStmtsp(new AstPragma(ftaskp->fileline(), AstPragmaType::PUBLIC_TASK));
|
||||
// Only functions can have isolate (return value)
|
||||
if (VN_IS(ftaskp, Func)) ftaskp->attrIsolateAssign(m_isolate);
|
||||
}
|
||||
};
|
||||
|
||||
typedef V3ConfigWildcardResolver<V3ConfigFTask> V3ConfigFTaskResolver;
|
||||
|
||||
//######################################################################
|
||||
// Modules have tasks, variables, named blocks and properties
|
||||
|
||||
class V3ConfigModule {
|
||||
typedef std::unordered_set<string> StringSet;
|
||||
|
||||
V3ConfigFTaskResolver m_tasks; // Functions/tasks in module
|
||||
V3ConfigVarResolver m_vars; // Variables in module
|
||||
StringSet m_coverageOffBlocks; // List of block names for coverage_off
|
||||
bool m_inline; // Whether to force the inline
|
||||
bool m_inlineValue; // The inline value (on/off)
|
||||
bool m_public; // Public module
|
||||
|
||||
public:
|
||||
V3ConfigModule()
|
||||
: m_inline(false)
|
||||
, m_inlineValue(false)
|
||||
, m_public(false) {}
|
||||
|
||||
void update(const V3ConfigModule& m) {
|
||||
m_tasks.update(m.m_tasks);
|
||||
m_vars.update(m.m_vars);
|
||||
for (StringSet::const_iterator it = m.m_coverageOffBlocks.begin();
|
||||
it != m.m_coverageOffBlocks.end(); ++it) {
|
||||
m_coverageOffBlocks.insert(*it);
|
||||
}
|
||||
if (!m_inline) {
|
||||
m_inline = m.m_inline;
|
||||
m_inlineValue = m.m_inlineValue;
|
||||
}
|
||||
if (!m_public) m_public = m.m_public;
|
||||
}
|
||||
|
||||
V3ConfigFTaskResolver& ftasks() { return m_tasks; }
|
||||
V3ConfigVarResolver& vars() { return m_vars; }
|
||||
|
||||
void addCoverageBlockOff(const string& name) { m_coverageOffBlocks.insert(name); }
|
||||
void setInline(bool set) {
|
||||
m_inline = true;
|
||||
m_inlineValue = set;
|
||||
}
|
||||
void setPublic(bool set) { m_public = set; }
|
||||
|
||||
void apply(AstNodeModule* modp) {
|
||||
if (m_inline) {
|
||||
AstPragmaType type
|
||||
= m_inlineValue ? AstPragmaType::INLINE_MODULE : AstPragmaType::NO_INLINE_MODULE;
|
||||
AstNode* nodep = new AstPragma(modp->fileline(), type);
|
||||
modp->addStmtp(nodep);
|
||||
}
|
||||
if (m_public) {
|
||||
AstNode* nodep = new AstPragma(modp->fileline(), AstPragmaType::PUBLIC_MODULE);
|
||||
modp->addStmtp(nodep);
|
||||
}
|
||||
}
|
||||
|
||||
void applyBlock(AstBegin* nodep) {
|
||||
AstPragmaType pragma = AstPragmaType::COVERAGE_BLOCK_OFF;
|
||||
if (!nodep->unnamed()) {
|
||||
for (StringSet::const_iterator it = m_coverageOffBlocks.begin();
|
||||
it != m_coverageOffBlocks.end(); ++it) {
|
||||
if (VString::wildmatch(nodep->name(), *it)) {
|
||||
nodep->addStmtsp(new AstPragma(nodep->fileline(), pragma));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef V3ConfigWildcardResolver<V3ConfigModule> V3ConfigModuleResolver;
|
||||
|
||||
//######################################################################
|
||||
// Files have:
|
||||
// - Line ignores (lint/coverage/tracing on/off)
|
||||
// - Line attributes: Attributes attached to lines
|
||||
|
||||
// lint/coverage/tracing on/off
|
||||
class V3ConfigIgnoresLine {
|
||||
public:
|
||||
int m_lineno; // Line number to make change at
|
||||
V3ErrorCode m_code; // Error code
|
||||
bool m_on; // True to enable message
|
||||
V3ConfigIgnoresLine(V3ErrorCode code, int lineno, bool on)
|
||||
: m_lineno(lineno)
|
||||
, m_code(code)
|
||||
, m_on(on) {}
|
||||
~V3ConfigIgnoresLine() {}
|
||||
inline bool operator<(const V3ConfigIgnoresLine& rh) const {
|
||||
if (m_lineno < rh.m_lineno) return true;
|
||||
if (m_lineno > rh.m_lineno) return false;
|
||||
if (m_code < rh.m_code) return true;
|
||||
if (m_code > rh.m_code) return false;
|
||||
// Always turn "on" before "off" so that overlapping lines will end
|
||||
// up finally with the error "off"
|
||||
return (m_on>rh.m_on);
|
||||
return (m_on > rh.m_on);
|
||||
}
|
||||
};
|
||||
std::ostream& operator<<(std::ostream& os, V3ConfigLine rhs) {
|
||||
return os<<rhs.m_lineno<<", "<<rhs.m_code<<", "<<rhs.m_on; }
|
||||
std::ostream& operator<<(std::ostream& os, V3ConfigIgnoresLine rhs) {
|
||||
return os << rhs.m_lineno << ", " << rhs.m_code << ", " << rhs.m_on;
|
||||
}
|
||||
|
||||
class V3ConfigIgnores {
|
||||
typedef std::multiset<V3ConfigLine> IgnLines; // list of {line,code,on}
|
||||
typedef std::map<string,IgnLines> IgnFiles; // {filename} => list of {line,code,on}
|
||||
// Some attributes are attached to entities of the occur on a fileline
|
||||
// and multiple attributes can be attached to a line
|
||||
typedef std::bitset<AstPragmaType::ENUM_SIZE> V3ConfigLineAttribute;
|
||||
|
||||
// MEMBERS
|
||||
string m_lastFilename; // Last filename looked up
|
||||
int m_lastLineno; // Last linenumber looked up
|
||||
// File entity
|
||||
class V3ConfigFile {
|
||||
typedef std::map<int, V3ConfigLineAttribute> LineAttrMap; // Map line->bitset of attributes
|
||||
typedef std::multiset<V3ConfigIgnoresLine> IgnLines; // list of {line,code,on}
|
||||
typedef std::pair<V3ErrorCode, string> WaiverSetting; // Waive code if string matches
|
||||
typedef std::vector<WaiverSetting> Waivers; // List of {code,wildcard string}
|
||||
|
||||
IgnLines::const_iterator m_lastIt; // Point with next linenumber > current line number
|
||||
IgnLines::const_iterator m_lastEnd; // Point with end()
|
||||
LineAttrMap m_lineAttrs; // Atributes to line mapping
|
||||
IgnLines m_ignLines; // Ignore line settings
|
||||
Waivers m_waivers; // Waive messages
|
||||
|
||||
IgnFiles m_ignWilds; // Ignores for each wildcarded filename
|
||||
IgnFiles m_ignFiles; // Ignores for each non-wildcarded filename
|
||||
struct {
|
||||
int lineno; // Last line number
|
||||
IgnLines::const_iterator it; // Point with next linenumber > current line number
|
||||
} m_lastIgnore; // Last ignore line run
|
||||
|
||||
static V3ConfigIgnores s_singleton; // Singleton (not via local static, as that's slow)
|
||||
|
||||
V3ConfigIgnores() { m_lastLineno = -1; }
|
||||
~V3ConfigIgnores() {}
|
||||
|
||||
// METHODS
|
||||
inline IgnLines* findWilds(const string& wildname) {
|
||||
IgnFiles::iterator it = m_ignWilds.find(wildname);
|
||||
if (it != m_ignWilds.end()) {
|
||||
return &(it->second);
|
||||
} else {
|
||||
m_ignWilds.insert(make_pair(wildname, IgnLines()));
|
||||
it = m_ignWilds.find(wildname);
|
||||
return &(it->second);
|
||||
}
|
||||
}
|
||||
inline void absBuild(const string& filename) {
|
||||
// Given a filename, find all wildcard matches against it and build
|
||||
// hash with the specific filename. This avoids having to wildmatch
|
||||
// more than once against any filename.
|
||||
IgnFiles::iterator it = m_ignFiles.find(filename);
|
||||
if (it == m_ignFiles.end()) {
|
||||
// Haven't seen this filename before
|
||||
m_ignFiles.insert(make_pair(filename, IgnLines()));
|
||||
it = m_ignFiles.find(filename);
|
||||
// Make new list for this file of all matches
|
||||
for (IgnFiles::iterator fnit = m_ignWilds.begin(); fnit != m_ignWilds.end(); ++fnit) {
|
||||
if (VString::wildmatch(filename.c_str(), fnit->first.c_str())) {
|
||||
for (IgnLines::iterator lit = fnit->second.begin();
|
||||
lit != fnit->second.end(); ++lit) {
|
||||
it->second.insert(*lit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_lastIt = it->second.begin();
|
||||
m_lastEnd = it->second.end();
|
||||
// Match a given line and attribute to the map, line 0 is any
|
||||
bool lineMatch(int lineno, AstPragmaType type) {
|
||||
if (m_lineAttrs.find(0) != m_lineAttrs.end() && m_lineAttrs[0][type]) return true;
|
||||
if (m_lineAttrs.find(lineno) == m_lineAttrs.end()) return false;
|
||||
return m_lineAttrs[lineno][type];
|
||||
}
|
||||
|
||||
public:
|
||||
inline static V3ConfigIgnores& singleton() { return s_singleton; }
|
||||
V3ConfigFile() { m_lastIgnore = {-1, m_ignLines.begin()}; }
|
||||
|
||||
void addIgnore(V3ErrorCode code, const string& wildname, int lineno, bool on) {
|
||||
// Insert
|
||||
IgnLines* linesp = findWilds(wildname);
|
||||
UINFO(9,"config addIgnore "<<wildname<<":"<<lineno<<", "<<code<<", "<<on<<endl);
|
||||
linesp->insert(V3ConfigLine(code, lineno, on));
|
||||
// Flush the match cache, due to a change in the rules.
|
||||
m_ignFiles.clear();
|
||||
m_lastFilename = " ";
|
||||
void update(const V3ConfigFile& file) {
|
||||
// Copy in all Attributes
|
||||
for (LineAttrMap::const_iterator it = file.m_lineAttrs.begin();
|
||||
it != file.m_lineAttrs.end(); ++it) {
|
||||
m_lineAttrs[it->first] |= it->second;
|
||||
}
|
||||
// Copy in all ignores
|
||||
for (IgnLines::const_iterator it = file.m_ignLines.begin(); it != file.m_ignLines.end();
|
||||
++it) {
|
||||
m_ignLines.insert(*it);
|
||||
}
|
||||
// Update the iterator after the list has changed
|
||||
m_lastIgnore.it = m_ignLines.begin();
|
||||
m_waivers.reserve(m_waivers.size() + file.m_waivers.size());
|
||||
m_waivers.insert(m_waivers.end(), file.m_waivers.begin(), file.m_waivers.end());
|
||||
}
|
||||
void addLineAttribute(int lineno, AstPragmaType attr) { m_lineAttrs[lineno].set(attr); }
|
||||
void addIgnore(V3ErrorCode code, int lineno, bool on) {
|
||||
m_ignLines.insert(V3ConfigIgnoresLine(code, lineno, on));
|
||||
m_lastIgnore.it = m_ignLines.begin();
|
||||
}
|
||||
void addWaiver(V3ErrorCode code, const string& match) {
|
||||
m_waivers.push_back(make_pair(code, match));
|
||||
}
|
||||
|
||||
void applyBlock(AstBegin* nodep) {
|
||||
// Apply to block at this line
|
||||
AstPragmaType pragma = AstPragmaType::COVERAGE_BLOCK_OFF;
|
||||
if (lineMatch(nodep->fileline()->lineno(), pragma)) {
|
||||
nodep->addStmtsp(new AstPragma(nodep->fileline(), pragma));
|
||||
}
|
||||
}
|
||||
void applyCase(AstCase* nodep) {
|
||||
// Apply to this case at this line
|
||||
int lineno = nodep->fileline()->lineno();
|
||||
if (lineMatch(lineno, AstPragmaType::FULL_CASE)) nodep->fullPragma(true);
|
||||
if (lineMatch(lineno, AstPragmaType::PARALLEL_CASE)) nodep->parallelPragma(true);
|
||||
}
|
||||
inline void applyIgnores(FileLine* filelinep) {
|
||||
// HOT routine, called each parsed token line
|
||||
if (m_lastLineno != filelinep->lastLineno()
|
||||
|| m_lastFilename != filelinep->filename()) {
|
||||
//UINFO(9," ApplyIgnores for "<<filelinep->ascii()<<endl);
|
||||
if (VL_UNLIKELY(m_lastFilename != filelinep->filename())) {
|
||||
absBuild(filelinep->filename());
|
||||
m_lastFilename = filelinep->filename();
|
||||
}
|
||||
// HOT routine, called each parsed token line of this filename
|
||||
if (m_lastIgnore.lineno != filelinep->lineno()) {
|
||||
// UINFO(9," ApplyIgnores for "<<filelinep->ascii()<<endl);
|
||||
// Process all on/offs for lines up to and including the current line
|
||||
int curlineno = filelinep->lastLineno();
|
||||
for (; m_lastIt != m_lastEnd; ++m_lastIt) {
|
||||
if (m_lastIt->m_lineno > curlineno) break;
|
||||
//UINFO(9," Hit "<<*m_lastIt<<endl);
|
||||
filelinep->warnOn(m_lastIt->m_code, m_lastIt->m_on);
|
||||
for (; m_lastIgnore.it != m_ignLines.end(); ++m_lastIgnore.it) {
|
||||
if (m_lastIgnore.it->m_lineno > curlineno) break;
|
||||
// UINFO(9," Hit "<<*m_lastIt<<endl);
|
||||
filelinep->warnOn(m_lastIgnore.it->m_code, m_lastIgnore.it->m_on);
|
||||
}
|
||||
if (0 && debug() >= 9) {
|
||||
for (IgnLines::const_iterator it=m_lastIt; it != m_lastEnd; ++it) {
|
||||
UINFO(9," NXT "<<*it<<endl);
|
||||
for (IgnLines::const_iterator it = m_lastIgnore.it; it != m_ignLines.end(); ++it) {
|
||||
UINFO(9, " NXT " << *it << endl);
|
||||
}
|
||||
}
|
||||
m_lastLineno = filelinep->lastLineno();
|
||||
m_lastIgnore.lineno = filelinep->lastLineno();
|
||||
}
|
||||
}
|
||||
bool waive(V3ErrorCode code, const string& match) {
|
||||
for (Waivers::const_iterator it = m_waivers.begin(); it != m_waivers.end(); ++it) {
|
||||
if (((it->first == code) || (it->first == V3ErrorCode::I_LINT))
|
||||
&& VString::wildmatch(match, it->second)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
V3ConfigIgnores V3ConfigIgnores::s_singleton;
|
||||
typedef V3ConfigWildcardResolver<V3ConfigFile> V3ConfigFileResolver;
|
||||
|
||||
//######################################################################
|
||||
// Resolve modules and files in the design
|
||||
|
||||
class V3ConfigResolver {
|
||||
V3ConfigModuleResolver m_modules; // Access to module names (with wildcards)
|
||||
V3ConfigFileResolver m_files; // Access to file names (with wildcards)
|
||||
|
||||
static V3ConfigResolver s_singleton; // Singleton (not via local static, as that's slow)
|
||||
V3ConfigResolver() {}
|
||||
~V3ConfigResolver() {}
|
||||
|
||||
public:
|
||||
inline static V3ConfigResolver& s() { return s_singleton; }
|
||||
|
||||
V3ConfigModuleResolver& modules() { return m_modules; }
|
||||
V3ConfigFileResolver& files() { return m_files; }
|
||||
};
|
||||
|
||||
V3ConfigResolver V3ConfigResolver::s_singleton;
|
||||
|
||||
//######################################################################
|
||||
// V3Config
|
||||
|
||||
void V3Config::addCaseFull(const string& filename, int lineno) {
|
||||
V3ConfigFile& file = V3ConfigResolver::s().files().at(filename);
|
||||
file.addLineAttribute(lineno, AstPragmaType::FULL_CASE);
|
||||
}
|
||||
|
||||
void V3Config::addCaseParallel(const string& filename, int lineno) {
|
||||
V3ConfigFile& file = V3ConfigResolver::s().files().at(filename);
|
||||
file.addLineAttribute(lineno, AstPragmaType::PARALLEL_CASE);
|
||||
}
|
||||
|
||||
void V3Config::addCoverageBlockOff(const string& filename, int lineno) {
|
||||
V3ConfigFile& file = V3ConfigResolver::s().files().at(filename);
|
||||
file.addLineAttribute(lineno, AstPragmaType::COVERAGE_BLOCK_OFF);
|
||||
}
|
||||
|
||||
void V3Config::addCoverageBlockOff(const string& module, const string& blockname) {
|
||||
V3ConfigResolver::s().modules().at(module).addCoverageBlockOff(blockname);
|
||||
}
|
||||
|
||||
void V3Config::addIgnore(V3ErrorCode code, bool on, const string& filename, int min, int max) {
|
||||
if (filename=="*") {
|
||||
FileLine::globalWarnOff(code,!on);
|
||||
if (filename == "*") {
|
||||
FileLine::globalWarnOff(code, !on);
|
||||
} else {
|
||||
V3ConfigIgnores::singleton().addIgnore(code, filename, min, on);
|
||||
if (max) V3ConfigIgnores::singleton().addIgnore(code, filename, max, !on);
|
||||
V3ConfigResolver::s().files().at(filename).addIgnore(code, min, on);
|
||||
if (max) V3ConfigResolver::s().files().at(filename).addIgnore(code, max, !on);
|
||||
V3ConfigResolver::s().files().flush();
|
||||
}
|
||||
}
|
||||
|
||||
void V3Config::applyIgnores(FileLine* filelinep) {
|
||||
V3ConfigIgnores::singleton().applyIgnores(filelinep);
|
||||
void V3Config::addInline(FileLine* fl, const string& module, const string& ftask, bool on) {
|
||||
if (ftask.empty()) {
|
||||
V3ConfigResolver::s().modules().at(module).setInline(on);
|
||||
} else {
|
||||
if (!on) {
|
||||
fl->v3error("no_inline not supported for tasks" << endl);
|
||||
} else {
|
||||
V3ConfigResolver::s().modules().at(module).ftasks().at(ftask).setNoInline(on);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void V3Config::addVarAttr(FileLine* fl, const string& module, const string& ftask,
|
||||
const string& var, AstAttrType attr, AstSenTree* sensep) {
|
||||
// Semantics: sensep only if public_flat_rw
|
||||
if ((attr != AstAttrType::VAR_PUBLIC_FLAT_RW) && sensep) {
|
||||
sensep->v3error("sensitivity not expected for attribute" << endl);
|
||||
return;
|
||||
}
|
||||
// Semantics: Most of the attributes operate on signals
|
||||
if (var.empty()) {
|
||||
if (attr == AstAttrType::VAR_ISOLATE_ASSIGNMENTS) {
|
||||
if (ftask.empty()) {
|
||||
fl->v3error("isolate_assignments only applies to signals or functions/tasks"
|
||||
<< endl);
|
||||
} else {
|
||||
V3ConfigResolver::s().modules().at(module).ftasks().at(ftask).setIsolate(true);
|
||||
}
|
||||
} else if (attr == AstAttrType::VAR_PUBLIC) {
|
||||
if (ftask.empty()) {
|
||||
// public module, this is the only exception from var here
|
||||
V3ConfigResolver::s().modules().at(module).setPublic(true);
|
||||
} else {
|
||||
V3ConfigResolver::s().modules().at(module).ftasks().at(ftask).setPublic(true);
|
||||
}
|
||||
} else {
|
||||
fl->v3error("missing -signal" << endl);
|
||||
}
|
||||
} else {
|
||||
V3ConfigModule& mod = V3ConfigResolver::s().modules().at(module);
|
||||
if (ftask.empty()) {
|
||||
mod.vars().at(var).push_back(V3ConfigVarAttr(attr, sensep));
|
||||
} else {
|
||||
mod.ftasks().at(ftask).vars().at(var).push_back({attr, sensep});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void V3Config::addWaiver(V3ErrorCode code, const string& filename, const string& match) {
|
||||
V3ConfigResolver::s().files().at(filename).addWaiver(code, match);
|
||||
}
|
||||
|
||||
void V3Config::applyCase(AstCase* nodep) {
|
||||
const string& filename = nodep->fileline()->filename();
|
||||
V3ConfigFile* filep = V3ConfigResolver::s().files().resolve(filename);
|
||||
if (filep) filep->applyCase(nodep);
|
||||
}
|
||||
|
||||
void V3Config::applyCoverageBlock(AstNodeModule* modulep, AstBegin* nodep) {
|
||||
const string& filename = nodep->fileline()->filename();
|
||||
V3ConfigFile* filep = V3ConfigResolver::s().files().resolve(filename);
|
||||
if (filep) filep->applyBlock(nodep);
|
||||
const string& modname = modulep->name();
|
||||
V3ConfigModule* modp = V3ConfigResolver::s().modules().resolve(modname);
|
||||
if (modp) modp->applyBlock(nodep);
|
||||
}
|
||||
|
||||
void V3Config::applyIgnores(FileLine* filelinep) {
|
||||
const string& filename = filelinep->filename();
|
||||
V3ConfigFile* filep = V3ConfigResolver::s().files().resolve(filename);
|
||||
if (filep) filep->applyIgnores(filelinep);
|
||||
}
|
||||
|
||||
void V3Config::applyModule(AstNodeModule* modulep) {
|
||||
const string& modname = modulep->name();
|
||||
V3ConfigModule* modp = V3ConfigResolver::s().modules().resolve(modname);
|
||||
if (modp) modp->apply(modulep);
|
||||
}
|
||||
|
||||
void V3Config::applyFTask(AstNodeModule* modulep, AstNodeFTask* ftaskp) {
|
||||
const string& modname = modulep->name();
|
||||
V3ConfigModule* modp = V3ConfigResolver::s().modules().resolve(modname);
|
||||
if (!modp) return;
|
||||
V3ConfigFTask* ftp = modp->ftasks().resolve(ftaskp->name());
|
||||
if (ftp) ftp->apply(ftaskp);
|
||||
}
|
||||
|
||||
void V3Config::applyVarAttr(AstNodeModule* modulep, AstNodeFTask* ftaskp, AstVar* varp) {
|
||||
V3ConfigVar* vp;
|
||||
V3ConfigModule* modp = V3ConfigResolver::s().modules().resolve(modulep->name());
|
||||
if (!modp) return;
|
||||
if (ftaskp) {
|
||||
V3ConfigFTask* ftp = modp->ftasks().resolve(ftaskp->name());
|
||||
if (!ftp) return;
|
||||
vp = ftp->vars().resolve(varp->name());
|
||||
} else {
|
||||
vp = modp->vars().resolve(varp->name());
|
||||
}
|
||||
if (vp) vp->apply(varp);
|
||||
}
|
||||
|
||||
bool V3Config::waive(FileLine* filelinep, V3ErrorCode code, const string& message) {
|
||||
V3ConfigFile* filep = V3ConfigResolver::s().files().resolve(filelinep->filename());
|
||||
if (!filep) return false;
|
||||
return filep->waive(code, message);
|
||||
}
|
||||
|
@ -26,13 +26,27 @@
|
||||
|
||||
#include "V3Error.h"
|
||||
#include "V3FileLine.h"
|
||||
#include "V3Ast.h"
|
||||
|
||||
//######################################################################
|
||||
|
||||
class V3Config {
|
||||
public:
|
||||
static void addCaseFull(const string& file, int lineno);
|
||||
static void addCaseParallel(const string& file, int lineno);
|
||||
static void addCoverageBlockOff(const string& file, int lineno);
|
||||
static void addCoverageBlockOff(const string& module, const string& blockname);
|
||||
static void addIgnore(V3ErrorCode code, bool on, const string& filename, int min, int max);
|
||||
static void addWaiver(V3ErrorCode code, const string& filename, const string& msg);
|
||||
static void addInline(FileLine* fl, const string& module, const string& ftask, bool on);
|
||||
static void addVarAttr(FileLine* fl, const string& module, const string& ftask, const string& signal, AstAttrType type, AstSenTree* nodep);
|
||||
static void applyCase(AstCase* nodep);
|
||||
static void applyCoverageBlock(AstNodeModule* modulep, AstBegin* nodep);
|
||||
static void applyIgnores(FileLine* filelinep);
|
||||
static void applyModule(AstNodeModule* nodep);
|
||||
static void applyFTask(AstNodeModule* modulep, AstNodeFTask* ftaskp);
|
||||
static void applyVarAttr(AstNodeModule* modulep, AstNodeFTask* ftaskp, AstVar* varp);
|
||||
static bool waive(FileLine* filelinep, V3ErrorCode code, const string& match);
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
|
@ -131,7 +131,10 @@ class EmitXmlFileVisitor : public AstNVisitor {
|
||||
}
|
||||
puts(" origName="); putsQuoted(nodep->origName());
|
||||
// Attributes
|
||||
if (nodep->attrClocker()) puts(" clocker=\"true\"");
|
||||
if (nodep->attrClocker() == VVarAttrClocker::CLOCKER_YES)
|
||||
puts(" clocker=\"true\"");
|
||||
else if (nodep->attrClocker() == VVarAttrClocker::CLOCKER_NO)
|
||||
puts(" clocker=\"false\"");
|
||||
if (nodep->attrClockEn()) puts(" clock_enable=\"true\"");
|
||||
if (nodep->attrIsolateAssign()) puts(" isolate_assignments=\"true\"");
|
||||
if (nodep->isSigPublic()) puts(" public=\"true\"");
|
||||
|
@ -341,7 +341,10 @@ void FileLine::v3errorEnd(std::ostringstream& str, const string& locationStr) {
|
||||
if (!locationStr.empty()) {
|
||||
lstr<<std::setw(ascii().length())<<" "<<": "<<locationStr;
|
||||
}
|
||||
if (warnIsOff(V3Error::errorCode())) V3Error::suppressThisWarning();
|
||||
if (warnIsOff(V3Error::errorCode())
|
||||
|| V3Config::waive(this, V3Error::errorCode(), str.str())) {
|
||||
V3Error::suppressThisWarning();
|
||||
}
|
||||
else if (!V3Error::errorContexted()) nsstr<<warnContextPrimary();
|
||||
V3Error::v3errorEnd(nsstr, lstr.str());
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "V3Global.h"
|
||||
#include "V3LinkParse.h"
|
||||
#include "V3Ast.h"
|
||||
#include "V3Config.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdarg>
|
||||
@ -106,6 +107,8 @@ private:
|
||||
|
||||
// VISITs
|
||||
virtual void visit(AstNodeFTask* nodep) {
|
||||
V3Config::applyFTask(m_modp, nodep);
|
||||
|
||||
if (!nodep->user1SetOnce()) { // Process only once.
|
||||
cleanFileline(nodep);
|
||||
m_ftaskp = nodep;
|
||||
@ -189,6 +192,9 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
// Maybe this variable has a signal attribute
|
||||
V3Config::applyVarAttr(m_modp, m_ftaskp, nodep);
|
||||
|
||||
if (v3Global.opt.publicFlatRW()) {
|
||||
switch (nodep->varType()) {
|
||||
case AstVarType::VAR:
|
||||
@ -438,6 +444,8 @@ private:
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
V3Config::applyModule(nodep);
|
||||
|
||||
// Module: Create sim table for entire module and iterate
|
||||
cleanFileline(nodep);
|
||||
//
|
||||
@ -474,6 +482,17 @@ private:
|
||||
visitIterateNoValueMod(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstBegin* nodep) {
|
||||
V3Config::applyCoverageBlock(m_modp, nodep);
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstCase* nodep) {
|
||||
V3Config::applyCase(nodep);
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep) {
|
||||
// Default: Just iterate
|
||||
cleanFileline(nodep);
|
||||
|
@ -62,6 +62,7 @@ struct V3ParseBisonYYSType {
|
||||
VSignedState signstate;
|
||||
V3ImportProperty iprop;
|
||||
V3ErrorCode::en errcodeen;
|
||||
AstAttrType::en attrtypeen;
|
||||
|
||||
AstNode* nodep;
|
||||
|
||||
|
@ -74,6 +74,14 @@ bool VString::wildmatch(const char* s, const char* p) {
|
||||
return (*s == '\0');
|
||||
}
|
||||
|
||||
bool VString::wildmatch(const string& s, const string& p) {
|
||||
return wildmatch(s.c_str(), p.c_str());
|
||||
}
|
||||
|
||||
bool VString::isWildcard(const string &p) {
|
||||
return ((p.find("*") != string::npos) || (p.find("?") != string::npos));
|
||||
}
|
||||
|
||||
string VString::dot(const string& a, const string& dot, const string& b) {
|
||||
if (b=="") return a;
|
||||
if (a=="") return b;
|
||||
|
@ -63,6 +63,10 @@ public:
|
||||
// METHODS (generic string utilities)
|
||||
// Return true if p with ? or *'s matches s
|
||||
static bool wildmatch(const char* s, const char* p);
|
||||
// Return true if p with ? or *'s matches s
|
||||
static bool wildmatch(const string& s, const string& p);
|
||||
// Return true if this is a wildcard string (contains * or ?)
|
||||
static bool isWildcard(const string &p);
|
||||
// Return {a}{dot}{b}, omitting dot if a or b are empty
|
||||
static string dot(const string& a, const string& dot, const string& b);
|
||||
// Convert string to lowercase (tolower)
|
||||
|
@ -135,17 +135,45 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
|
||||
{ws} { FL_FWD; FL_BRK; } /* otherwise ignore white-space */
|
||||
{crnl} { FL_FWD; FL_BRK; } /* Count line numbers */
|
||||
|
||||
"clock_enable" { FL; return yVLT_CLOCK_ENABLE; }
|
||||
"clocker" { FL; return yVLT_CLOCKER; }
|
||||
"coverage_block_off" { FL; return yVLT_COVERAGE_BLOCK_OFF; }
|
||||
"coverage_off" { FL; return yVLT_COVERAGE_OFF; }
|
||||
"coverage_on" { FL; return yVLT_COVERAGE_ON; }
|
||||
"full_case" { FL; return yVLT_FULL_CASE; }
|
||||
"inline" { FL; return yVLT_INLINE; }
|
||||
"isolate_assignments" { FL; return yVLT_ISOLATE_ASSIGNMENTS; }
|
||||
"lint_off" { FL; return yVLT_LINT_OFF; }
|
||||
"lint_on" { FL; return yVLT_LINT_ON; }
|
||||
"no_clocker" { FL; return yVLT_NO_CLOCKER; }
|
||||
"no_inline" { FL; return yVLT_NO_INLINE; }
|
||||
"parallel_case" { FL; return yVLT_PARALLEL_CASE; }
|
||||
"public" { FL; return yVLT_PUBLIC; }
|
||||
"public_flat" { FL; return yVLT_PUBLIC_FLAT; }
|
||||
"public_flat_rd" { FL; return yVLT_PUBLIC_FLAT_RD; }
|
||||
"public_flat_rw" { FL; return yVLT_PUBLIC_FLAT_RW; }
|
||||
"public_module" { FL; return yVLT_PUBLIC_MODULE; }
|
||||
"sc_bv" { FL; return yVLT_SC_BV; }
|
||||
"sformat" { FL; return yVLT_SFORMAT; }
|
||||
"tracing_off" { FL; return yVLT_TRACING_OFF; }
|
||||
"tracing_on" { FL; return yVLT_TRACING_ON; }
|
||||
|
||||
-?"-block" { FL; return yVLT_D_BLOCK; }
|
||||
-?"-file" { FL; return yVLT_D_FILE; }
|
||||
-?"-function" { FL; return yVLT_D_FUNCTION; }
|
||||
-?"-lines" { FL; return yVLT_D_LINES; }
|
||||
-?"-match" { FL; return yVLT_D_MATCH; }
|
||||
-?"-module" { FL; return yVLT_D_MODULE; }
|
||||
-?"-msg" { FL; return yVLT_D_MSG; }
|
||||
-?"-rule" { FL; return yVLT_D_RULE; }
|
||||
-?"-task" { FL; return yVLT_D_TASK; }
|
||||
-?"-var" { FL; return yVLT_D_VAR; }
|
||||
|
||||
/* Reachable by attr_event_control */
|
||||
"edge" { FL; return yEDGE; }
|
||||
"negedge" { FL; return yNEGEDGE; }
|
||||
"or" { FL; return yOR; }
|
||||
"posedge" { FL; return yPOSEDGE; }
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
129
src/verilog.y
129
src/verilog.y
@ -273,17 +273,39 @@ class AstSenTree;
|
||||
%token<strp> yaSCCTOR "`systemc_implementation BLOCK"
|
||||
%token<strp> yaSCDTOR "`systemc_imp_header BLOCK"
|
||||
|
||||
%token<fl> yVLT_COVERAGE_OFF "coverage_off"
|
||||
%token<fl> yVLT_COVERAGE_ON "coverage_on"
|
||||
%token<fl> yVLT_LINT_OFF "lint_off"
|
||||
%token<fl> yVLT_LINT_ON "lint_on"
|
||||
%token<fl> yVLT_TRACING_OFF "tracing_off"
|
||||
%token<fl> yVLT_TRACING_ON "tracing_on"
|
||||
%token<fl> yVLT_CLOCKER "clocker"
|
||||
%token<fl> yVLT_CLOCK_ENABLE "clock_enable"
|
||||
%token<fl> yVLT_COVERAGE_BLOCK_OFF "coverage_block_off"
|
||||
%token<fl> yVLT_COVERAGE_OFF "coverage_off"
|
||||
%token<fl> yVLT_COVERAGE_ON "coverage_on"
|
||||
%token<fl> yVLT_FULL_CASE "full_case"
|
||||
%token<fl> yVLT_INLINE "inline"
|
||||
%token<fl> yVLT_ISOLATE_ASSIGNMENTS "isolate_assignments"
|
||||
%token<fl> yVLT_LINT_OFF "lint_off"
|
||||
%token<fl> yVLT_LINT_ON "lint_on"
|
||||
%token<fl> yVLT_NO_CLOCKER "no_clocker"
|
||||
%token<fl> yVLT_NO_INLINE "no_inline"
|
||||
%token<fl> yVLT_PARALLEL_CASE "parallel_case"
|
||||
%token<fl> yVLT_PUBLIC "public"
|
||||
%token<fl> yVLT_PUBLIC_FLAT "public_flat"
|
||||
%token<fl> yVLT_PUBLIC_FLAT_RD "public_flat_rd"
|
||||
%token<fl> yVLT_PUBLIC_FLAT_RW "public_flat_rw"
|
||||
%token<fl> yVLT_PUBLIC_MODULE "public_module"
|
||||
%token<fl> yVLT_SC_BV "sc_bv"
|
||||
%token<fl> yVLT_SFORMAT "sformat"
|
||||
%token<fl> yVLT_TRACING_OFF "tracing_off"
|
||||
%token<fl> yVLT_TRACING_ON "tracing_on"
|
||||
|
||||
%token<fl> yVLT_D_FILE "--file"
|
||||
%token<fl> yVLT_D_LINES "--lines"
|
||||
%token<fl> yVLT_D_MSG "--msg"
|
||||
%token<fl> yVLT_D_RULE "--rule"
|
||||
%token<fl> yVLT_D_BLOCK "--block"
|
||||
%token<fl> yVLT_D_FILE "--file"
|
||||
%token<fl> yVLT_D_FUNCTION "--function"
|
||||
%token<fl> yVLT_D_LINES "--lines"
|
||||
%token<fl> yVLT_D_MODULE "--module"
|
||||
%token<fl> yVLT_D_MATCH "--match"
|
||||
%token<fl> yVLT_D_MSG "--msg"
|
||||
%token<fl> yVLT_D_RULE "--rule"
|
||||
%token<fl> yVLT_D_TASK "--task"
|
||||
%token<fl> yVLT_D_VAR "--var"
|
||||
|
||||
%token<strp> yaD_IGNORE "${ignored-bbox-sys}"
|
||||
%token<strp> yaD_DPI "${dpi-sys}"
|
||||
@ -737,6 +759,7 @@ class AstSenTree;
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
|
||||
%start source_text
|
||||
|
||||
@ -2460,6 +2483,11 @@ cellpinItemE<pinp>: // IEEE: named_port_connection + empty
|
||||
//************************************************
|
||||
// EventControl lists
|
||||
|
||||
attr_event_controlE<sentreep>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| attr_event_control { $$ = $1; }
|
||||
;
|
||||
|
||||
attr_event_control<sentreep>: // ==IEEE: event_control
|
||||
'@' '(' event_expression ')' { $$ = new AstSenTree($1,$3); }
|
||||
| '@' '(' '*' ')' { $$ = NULL; }
|
||||
@ -5582,14 +5610,45 @@ memberQualOne<nodep>: // IEEE: property_qualifier + method_qualifier
|
||||
// VLT Files
|
||||
|
||||
vltItem:
|
||||
vltOffFront { V3Config::addIgnore($1,false,"*",0,0); }
|
||||
| vltOffFront yVLT_D_FILE yaSTRING { V3Config::addIgnore($1,false,*$3,0,0); }
|
||||
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM { V3Config::addIgnore($1,false,*$3,$5->toUInt(),$5->toUInt()+1); }
|
||||
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM { V3Config::addIgnore($1,false,*$3,$5->toUInt(),$7->toUInt()+1); }
|
||||
| vltOnFront { V3Config::addIgnore($1,true,"*",0,0); }
|
||||
| vltOnFront yVLT_D_FILE yaSTRING { V3Config::addIgnore($1,true,*$3,0,0); }
|
||||
| vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM { V3Config::addIgnore($1,true,*$3,$5->toUInt(),$5->toUInt()+1); }
|
||||
| vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM { V3Config::addIgnore($1,true,*$3,$5->toUInt(),$7->toUInt()+1); }
|
||||
|
||||
vltOffFront { V3Config::addIgnore($1, false, "*", 0, 0); }
|
||||
| vltOffFront yVLT_D_FILE yaSTRING
|
||||
{ V3Config::addIgnore($1, false, *$3, 0, 0); }
|
||||
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM
|
||||
{ V3Config::addIgnore($1, false, *$3, $5->toUInt(), $5->toUInt()+1); }
|
||||
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM
|
||||
{ V3Config::addIgnore($1, false, *$3, $5->toUInt(), $7->toUInt()+1); }
|
||||
| vltOffFront yVLT_D_FILE yaSTRING yVLT_D_MATCH yaSTRING
|
||||
{ if (($1==V3ErrorCode::I_COVERAGE) || ($1==V3ErrorCode::I_TRACING)) {
|
||||
$<fl>1->v3error("Argument -match only supported for lint_off"<<endl);
|
||||
} else {
|
||||
V3Config::addWaiver($1,*$3,*$5);
|
||||
}}
|
||||
| vltOnFront { V3Config::addIgnore($1, true, "*", 0, 0); }
|
||||
| vltOnFront yVLT_D_FILE yaSTRING
|
||||
{ V3Config::addIgnore($1, true, *$3, 0, 0); }
|
||||
| vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM
|
||||
{ V3Config::addIgnore($1, true, *$3, $5->toUInt(), $5->toUInt()+1); }
|
||||
| vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM
|
||||
{ V3Config::addIgnore($1, true, *$3, $5->toUInt(), $7->toUInt()+1); }
|
||||
| vltVarAttrFront vltDModuleE vltDFTaskE vltVarAttrVarE attr_event_controlE
|
||||
{ V3Config::addVarAttr($<fl>1, *$2, *$3, *$4, $1, $5); }
|
||||
| vltInlineFront vltDModuleE vltDFTaskE
|
||||
{ V3Config::addInline($<fl>1, *$2, *$3, $1); }
|
||||
| yVLT_COVERAGE_BLOCK_OFF yVLT_D_FILE yaSTRING
|
||||
{ V3Config::addCoverageBlockOff(*$3, 0); }
|
||||
| yVLT_COVERAGE_BLOCK_OFF yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM
|
||||
{ V3Config::addCoverageBlockOff(*$3, $5->toUInt()); }
|
||||
| yVLT_COVERAGE_BLOCK_OFF yVLT_D_MODULE yaSTRING yVLT_D_BLOCK yaSTRING
|
||||
{ V3Config::addCoverageBlockOff(*$3, *$5); }
|
||||
| yVLT_FULL_CASE yVLT_D_FILE yaSTRING
|
||||
{ V3Config::addCaseFull(*$3, 0); }
|
||||
| yVLT_FULL_CASE yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM
|
||||
{ V3Config::addCaseFull(*$3, $5->toUInt()); }
|
||||
| yVLT_PARALLEL_CASE yVLT_D_FILE yaSTRING
|
||||
{ V3Config::addCaseParallel(*$3, 0); }
|
||||
| yVLT_PARALLEL_CASE yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM
|
||||
{ V3Config::addCaseParallel(*$3, $5->toUInt()); }
|
||||
;
|
||||
|
||||
vltOffFront<errcodeen>:
|
||||
@ -5618,6 +5677,40 @@ vltOnFront<errcodeen>:
|
||||
if ($$ == V3ErrorCode::EC_ERROR) { $1->v3error("Unknown Error Code: "<<*$3<<endl); } }
|
||||
;
|
||||
|
||||
vltDModuleE<strp>:
|
||||
/* empty */ { static string unit = "__024unit"; $$ = &unit; }
|
||||
| yVLT_D_MODULE str { $$ = $2; }
|
||||
;
|
||||
|
||||
vltDFTaskE<strp>:
|
||||
/* empty */ { static string empty = ""; $$ = ∅ }
|
||||
| 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 = ""; $$ = ∅ }
|
||||
| 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
|
||||
|
@ -26,7 +26,11 @@ module t (/*AUTOARG*/
|
||||
|
||||
always @* begin
|
||||
// Note not all tools support directives on casez's
|
||||
`ifdef ATTRIBUTES
|
||||
case ({a,b_fc}) // synopsys full_case
|
||||
`else
|
||||
case ({a,b_fc})
|
||||
`endif
|
||||
2'b0_0: ;
|
||||
2'b0_1: ;
|
||||
2'b1_0: ;
|
||||
@ -41,7 +45,15 @@ module t (/*AUTOARG*/
|
||||
end
|
||||
|
||||
always @* begin
|
||||
`ifdef ATTRIBUTES
|
||||
case (1'b1) // synopsys full_case parallel_case
|
||||
`else
|
||||
`ifdef FAILING_FULL
|
||||
case (1'b1) // synopsys parallel_case
|
||||
`else
|
||||
case (1'b1) // synopsys parallel_full
|
||||
`endif
|
||||
`endif
|
||||
a: ;
|
||||
b_pc: ;
|
||||
endcase
|
||||
|
@ -12,7 +12,7 @@ scenarios(simulator => 1);
|
||||
top_filename("t/t_assert_synth.v");
|
||||
|
||||
compile(
|
||||
v_flags2 => ['+define+FAILING_FULL'],
|
||||
v_flags2 => ['+define+FAILING_FULL +define+ATTRIBUTES'],
|
||||
verilator_flags2 => ['--assert'],
|
||||
nc_flags2 => ['+assert'],
|
||||
);
|
||||
@ -21,7 +21,7 @@ execute(
|
||||
check_finished => 0,
|
||||
fails => $Self->{vlt_all},
|
||||
expect =>
|
||||
'%Error: t_assert_synth.v:\d+: Assertion failed in top.t: synthesis full_case'
|
||||
'%Error: t_assert_synth.v:30: Assertion failed in top.t: synthesis full_case'
|
||||
);
|
||||
|
||||
ok(1);
|
||||
|
8
test_regress/t/t_assert_synth_full.vlt
Normal file
8
test_regress/t/t_assert_synth_full.vlt
Normal 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
|
3
test_regress/t/t_assert_synth_full_vlt.out
Normal file
3
test_regress/t/t_assert_synth_full_vlt.out
Normal 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...
|
27
test_regress/t/t_assert_synth_full_vlt.pl
Executable file
27
test_regress/t/t_assert_synth_full_vlt.pl
Executable 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;
|
@ -12,7 +12,7 @@ scenarios(simulator => 1);
|
||||
top_filename("t/t_assert_synth.v");
|
||||
|
||||
compile(
|
||||
v_flags2 => ['+define+FAILING_PARALLEL'],
|
||||
v_flags2 => ['+define+FAILING_PARALLEL', '+define+ATTRIBUTES'],
|
||||
verilator_flags2 => ['--assert'],
|
||||
nc_flags2 => ['+assert'],
|
||||
);
|
||||
|
8
test_regress/t/t_assert_synth_parallel.vlt
Normal file
8
test_regress/t/t_assert_synth_parallel.vlt
Normal 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
|
28
test_regress/t/t_assert_synth_parallel_vlt.pl
Executable file
28
test_regress/t/t_assert_synth_parallel_vlt.pl
Executable 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;
|
@ -9,9 +9,18 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ["+define+ATTRIBUTES"],
|
||||
);
|
||||
|
||||
if ($Self->{vlt_all}) {
|
||||
file_grep("$out_filename", qr/\<var fl="d74" name="clk0" dtype_id="1" dir="input" vartype="logic" origName="clk0" clocker="true" public="true"\/\>/i);
|
||||
file_grep("$out_filename", qr/\<var fl="d75" name="clk1" dtype_id="1" dir="input" vartype="logic" origName="clk1" clocker="true" public="true"\/\>/i);
|
||||
file_grep("$out_filename", qr/\<var fl="d76" name="clk2" dtype_id="1" dir="input" vartype="logic" origName="clk2" clocker="true" public="true"\/\>/i);
|
||||
}
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
@ -70,9 +70,15 @@ module t2(
|
||||
endmodule
|
||||
|
||||
module t(
|
||||
`ifdef ATTRIBUTES
|
||||
input clk0 /*verilator clocker*/,
|
||||
input clk1 /*verilator clocker*/,
|
||||
input clk2 /*verilator clocker*/,
|
||||
`else
|
||||
input clk0,
|
||||
input clk1,
|
||||
input clk2,
|
||||
`endif
|
||||
input data_in
|
||||
);
|
||||
|
||||
|
9
test_regress/t/t_clk_concat.vlt
Normal file
9
test_regress/t/t_clk_concat.vlt
Normal 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"
|
31
test_regress/t/t_clk_concat_vlt.pl
Executable file
31
test_regress/t/t_clk_concat_vlt.pl
Executable 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;
|
@ -9,7 +9,10 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ["+define+ATTRIBUTES=1"],
|
||||
);
|
||||
|
||||
execute(
|
||||
|
@ -83,7 +83,9 @@
|
||||
if (toggle) begin
|
||||
// CHECK_COVER_MISSING(-1)
|
||||
// This doesn't even get added
|
||||
`ifdef ATTRIBUTE
|
||||
// verilator coverage_block_off
|
||||
`endif
|
||||
$write("");
|
||||
end
|
||||
end
|
||||
@ -107,10 +109,12 @@
|
||||
// CHECK_COVER(-1,"top.t.b*",2)
|
||||
// t.b1 and t.b2 collapse to a count of 2
|
||||
end
|
||||
if (toggle) begin
|
||||
if (toggle) begin : block
|
||||
// CHECK_COVER_MISSING(-1)
|
||||
// This doesn't
|
||||
`ifdef ATTRIBUTE
|
||||
// verilator coverage_block_off
|
||||
`endif
|
||||
$write("");
|
||||
end
|
||||
end
|
||||
|
@ -82,7 +82,9 @@ module alpha (/*AUTOARG*/
|
||||
if (toggle) begin
|
||||
// CHECK_COVER_MISSING(-1)
|
||||
// This doesn't even get added
|
||||
`ifdef ATTRIBUTE
|
||||
// verilator coverage_block_off
|
||||
`endif
|
||||
$write("");
|
||||
end
|
||||
end
|
||||
@ -106,10 +108,12 @@ module beta (/*AUTOARG*/
|
||||
// CHECK_COVER(-1,"top.t.b*",2)
|
||||
// t.b1 and t.b2 collapse to a count of 2
|
||||
end
|
||||
if (toggle) begin
|
||||
if (toggle) begin : block
|
||||
// CHECK_COVER_MISSING(-1)
|
||||
// This doesn't
|
||||
`ifdef ATTRIBUTE
|
||||
// verilator coverage_block_off
|
||||
`endif
|
||||
$write("");
|
||||
end
|
||||
end
|
||||
|
9
test_regress/t/t_cover_line.vlt
Normal file
9
test_regress/t/t_cover_line.vlt
Normal 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"
|
@ -12,7 +12,7 @@ scenarios(simulator => 1);
|
||||
top_filename("t/t_cover_line.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ['--cc --coverage-line'],
|
||||
verilator_flags2 => ['--cc --coverage-line +define+ATTRIBUTE'],
|
||||
);
|
||||
|
||||
execute(
|
||||
|
33
test_regress/t/t_cover_line_cc_vlt.pl
Executable file
33
test_regress/t/t_cover_line_cc_vlt.pl
Executable 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;
|
@ -12,7 +12,7 @@ scenarios(simulator => 1);
|
||||
top_filename("t/t_cover_line.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ['--sc --coverage-line'],
|
||||
verilator_flags2 => ['--sc --coverage-line +define+ATTRIBUTE'],
|
||||
);
|
||||
|
||||
execute(
|
||||
|
@ -1,51 +1,51 @@
|
||||
$version Generated by VerilatedVcd $end
|
||||
$date Thu Oct 24 09:45:30 2019
|
||||
$date Sun Dec 29 13:11:10 2019
|
||||
$end
|
||||
$timescale 1ns $end
|
||||
|
||||
$scope module top $end
|
||||
$var wire 1 1 clk $end
|
||||
$var wire 1 5! clk $end
|
||||
$scope module t $end
|
||||
$var wire 1 1 clk $end
|
||||
$var wire 32 $ cyc [31:0] $end
|
||||
$var wire 8 % cyc_copy [7:0] $end
|
||||
$var wire 1 5! clk $end
|
||||
$var wire 32 + cyc [31:0] $end
|
||||
$var wire 8 3 cyc_copy [7:0] $end
|
||||
$var wire 1 # toggle $end
|
||||
$var wire 32 ) vlCoverageLineTrace_t_cover_line__44_if [31:0] $end
|
||||
$var wire 32 & vlCoverageLineTrace_t_cover_line__47_if [31:0] $end
|
||||
$var wire 32 ' vlCoverageLineTrace_t_cover_line__50_elsif [31:0] $end
|
||||
$var wire 32 ( vlCoverageLineTrace_t_cover_line__57_elsif [31:0] $end
|
||||
$var wire 32 S vlCoverageLineTrace_t_cover_line__44_if [31:0] $end
|
||||
$var wire 32 ; vlCoverageLineTrace_t_cover_line__47_if [31:0] $end
|
||||
$var wire 32 C vlCoverageLineTrace_t_cover_line__50_elsif [31:0] $end
|
||||
$var wire 32 K vlCoverageLineTrace_t_cover_line__57_elsif [31:0] $end
|
||||
$scope module a1 $end
|
||||
$var wire 1 1 clk $end
|
||||
$var wire 1 5! clk $end
|
||||
$var wire 1 # toggle $end
|
||||
$var wire 32 * vlCoverageLineTrace_t_cover_line__78_if [31:0] $end
|
||||
$var wire 32 [ vlCoverageLineTrace_t_cover_line__78_if [31:0] $end
|
||||
$upscope $end
|
||||
$scope module a2 $end
|
||||
$var wire 1 1 clk $end
|
||||
$var wire 1 5! clk $end
|
||||
$var wire 1 # toggle $end
|
||||
$var wire 32 + vlCoverageLineTrace_t_cover_line__78_if [31:0] $end
|
||||
$var wire 32 c vlCoverageLineTrace_t_cover_line__78_if [31:0] $end
|
||||
$upscope $end
|
||||
$scope module b1 $end
|
||||
$var wire 1 1 clk $end
|
||||
$var wire 1 5! clk $end
|
||||
$var wire 1 # toggle $end
|
||||
$var wire 32 2 vlCoverageLineTrace_t_cover_line__101_if [31:0] $end
|
||||
$var wire 32 - vlCoverageLineTrace_t_cover_line__105_if [31:0] $end
|
||||
$var wire 32 =! vlCoverageLineTrace_t_cover_line__103_if [31:0] $end
|
||||
$var wire 32 s vlCoverageLineTrace_t_cover_line__107_if [31:0] $end
|
||||
$upscope $end
|
||||
$scope module b2 $end
|
||||
$var wire 1 1 clk $end
|
||||
$var wire 1 5! clk $end
|
||||
$var wire 1 # toggle $end
|
||||
$var wire 32 3 vlCoverageLineTrace_t_cover_line__101_if [31:0] $end
|
||||
$var wire 32 . vlCoverageLineTrace_t_cover_line__105_if [31:0] $end
|
||||
$var wire 32 E! vlCoverageLineTrace_t_cover_line__103_if [31:0] $end
|
||||
$var wire 32 { vlCoverageLineTrace_t_cover_line__107_if [31:0] $end
|
||||
$upscope $end
|
||||
$scope module o1 $end
|
||||
$var wire 1 1 clk $end
|
||||
$var wire 1 5! clk $end
|
||||
$var wire 1 # toggle $end
|
||||
$var wire 32 , vlCoverageLineTrace_t_cover_line__162_if [31:0] $end
|
||||
$var wire 32 k vlCoverageLineTrace_t_cover_line__166_if [31:0] $end
|
||||
$upscope $end
|
||||
$scope module t1 $end
|
||||
$var wire 1 1 clk $end
|
||||
$var wire 1 5! clk $end
|
||||
$var wire 1 # toggle $end
|
||||
$var wire 32 / vlCoverageLineTrace_t_cover_line__134_if [31:0] $end
|
||||
$var wire 32 0 vlCoverageLineTrace_t_cover_line__137_if [31:0] $end
|
||||
$var wire 32 %! vlCoverageLineTrace_t_cover_line__138_if [31:0] $end
|
||||
$var wire 32 -! vlCoverageLineTrace_t_cover_line__141_if [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
@ -54,99 +54,99 @@ $enddefinitions $end
|
||||
|
||||
#0
|
||||
0#
|
||||
b00000000000000000000000000000001 $
|
||||
b00000001 %
|
||||
b00000000000000000000000000000000 &
|
||||
b00000000000000000000000000000000 '
|
||||
b00000000000000000000000000000000 (
|
||||
b00000000000000000000000000000000 )
|
||||
b00000000000000000000000000000000 *
|
||||
b00000000000000000000000000000000 +
|
||||
b00000000000000000000000000000000 ,
|
||||
b00000000000000000000000000000000 -
|
||||
b00000000000000000000000000000000 .
|
||||
b00000000000000000000000000000000 /
|
||||
b00000000000000000000000000000000 0
|
||||
01
|
||||
b00000000000000000000000000000000 2
|
||||
b00000000000000000000000000000000 3
|
||||
b00000000000000000000000000000001 +
|
||||
b00000001 3
|
||||
b00000000000000000000000000000000 ;
|
||||
b00000000000000000000000000000000 C
|
||||
b00000000000000000000000000000000 K
|
||||
b00000000000000000000000000000000 S
|
||||
b00000000000000000000000000000000 [
|
||||
b00000000000000000000000000000000 c
|
||||
b00000000000000000000000000000000 k
|
||||
b00000000000000000000000000000000 s
|
||||
b00000000000000000000000000000000 {
|
||||
b00000000000000000000000000000000 %!
|
||||
b00000000000000000000000000000000 -!
|
||||
05!
|
||||
b00000000000000000000000000000000 =!
|
||||
b00000000000000000000000000000000 E!
|
||||
#10
|
||||
b00000000000000000000000000000010 $
|
||||
b00000010 %
|
||||
b00000000000000000000000000000001 )
|
||||
11
|
||||
b00000000000000000000000000000010 +
|
||||
b00000010 3
|
||||
b00000000000000000000000000000001 S
|
||||
15!
|
||||
#15
|
||||
01
|
||||
05!
|
||||
#20
|
||||
b00000000000000000000000000000011 $
|
||||
b00000011 %
|
||||
b00000000000000000000000000000010 )
|
||||
11
|
||||
b00000000000000000000000000000011 +
|
||||
b00000011 3
|
||||
b00000000000000000000000000000010 S
|
||||
15!
|
||||
#25
|
||||
01
|
||||
05!
|
||||
#30
|
||||
1#
|
||||
b00000000000000000000000000000100 $
|
||||
b00000100 %
|
||||
b00000000000000000000000000000001 &
|
||||
b00000000000000000000000000000011 )
|
||||
11
|
||||
b00000000000000000000000000000100 +
|
||||
b00000100 3
|
||||
b00000000000000000000000000000001 ;
|
||||
b00000000000000000000000000000011 S
|
||||
15!
|
||||
#35
|
||||
01
|
||||
05!
|
||||
#40
|
||||
0#
|
||||
b00000000000000000000000000000101 $
|
||||
b00000101 %
|
||||
b00000000000000000000000000000100 )
|
||||
b00000000000000000000000000000001 *
|
||||
b00000000000000000000000000000001 +
|
||||
b00000000000000000000000000000001 ,
|
||||
b00000000000000000000000000000001 -
|
||||
b00000000000000000000000000000001 .
|
||||
b00000000000000000000000000000001 /
|
||||
11
|
||||
b00000000000000000000000000000101 +
|
||||
b00000101 3
|
||||
b00000000000000000000000000000100 S
|
||||
b00000000000000000000000000000001 [
|
||||
b00000000000000000000000000000001 c
|
||||
b00000000000000000000000000000001 k
|
||||
b00000000000000000000000000000001 s
|
||||
b00000000000000000000000000000001 {
|
||||
b00000000000000000000000000000001 %!
|
||||
15!
|
||||
#45
|
||||
01
|
||||
05!
|
||||
#50
|
||||
b00000000000000000000000000000110 $
|
||||
b00000110 %
|
||||
b00000000000000000000000000000001 '
|
||||
b00000000000000000000000000000101 )
|
||||
b00000000000000000000000000000001 0
|
||||
11
|
||||
b00000000000000000000000000000110 +
|
||||
b00000110 3
|
||||
b00000000000000000000000000000001 C
|
||||
b00000000000000000000000000000101 S
|
||||
b00000000000000000000000000000001 -!
|
||||
15!
|
||||
#55
|
||||
01
|
||||
05!
|
||||
#60
|
||||
b00000000000000000000000000000111 $
|
||||
b00000111 %
|
||||
b00000000000000000000000000000110 )
|
||||
11
|
||||
b00000000000000000000000000000111 +
|
||||
b00000111 3
|
||||
b00000000000000000000000000000110 S
|
||||
15!
|
||||
#65
|
||||
01
|
||||
05!
|
||||
#70
|
||||
b00000000000000000000000000001000 $
|
||||
b00001000 %
|
||||
b00000000000000000000000000000111 )
|
||||
11
|
||||
b00000000000000000000000000001000 +
|
||||
b00001000 3
|
||||
b00000000000000000000000000000111 S
|
||||
15!
|
||||
#75
|
||||
01
|
||||
05!
|
||||
#80
|
||||
b00000000000000000000000000001001 $
|
||||
b00001001 %
|
||||
b00000000000000000000000000001000 )
|
||||
11
|
||||
b00000000000000000000000000001001 +
|
||||
b00001001 3
|
||||
b00000000000000000000000000001000 S
|
||||
15!
|
||||
#85
|
||||
01
|
||||
05!
|
||||
#90
|
||||
b00000000000000000000000000001010 $
|
||||
b00001010 %
|
||||
b00000000000000000000000000001001 )
|
||||
11
|
||||
b00000000000000000000000000001010 +
|
||||
b00001010 3
|
||||
b00000000000000000000000000001001 S
|
||||
15!
|
||||
#95
|
||||
01
|
||||
05!
|
||||
#100
|
||||
b00000000000000000000000000001011 $
|
||||
b00001011 %
|
||||
b00000000000000000000000000000001 (
|
||||
b00000000000000000000000000001010 )
|
||||
11
|
||||
b00000000000000000000000000001011 +
|
||||
b00001011 3
|
||||
b00000000000000000000000000000001 K
|
||||
b00000000000000000000000000001010 S
|
||||
15!
|
||||
|
@ -12,7 +12,7 @@ scenarios(simulator => 1);
|
||||
top_filename("t/t_cover_line.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ['--cc --coverage-line --trace --trace-coverage'],
|
||||
verilator_flags2 => ['--cc --coverage-line --trace --trace-coverage +define+ATTRIBUTE'],
|
||||
);
|
||||
|
||||
execute(
|
||||
|
@ -9,13 +9,17 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ["--stats"],
|
||||
verilator_flags2 => ["--stats $Self->{t_dir}/t_dedupe_clk_gate.vlt"],
|
||||
);
|
||||
|
||||
if ($Self->{vlt_all}) {
|
||||
file_grep("$out_filename", qr/\<var fl="e43" name="t.f0.clock_gate.clken_latched" dtype_id="1" vartype="logic" origName="clken_latched" clock_enable="true"\/\>/i);
|
||||
file_grep($Self->{stats}, qr/Optimizations, Gate sigs deduped\s+(\d+)/i, 4);
|
||||
}
|
||||
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
@ -40,7 +40,7 @@ endmodule
|
||||
module clock_gate_latch (gated_clk, clk, clken);
|
||||
output gated_clk;
|
||||
input clk, clken;
|
||||
reg clken_latched /*verilator clock_enable*/;
|
||||
reg clken_latched;
|
||||
assign gated_clk = clk & clken_latched ;
|
||||
|
||||
wire clkb = ~clk;
|
||||
|
3
test_regress/t/t_dedupe_clk_gate.vlt
Normal file
3
test_regress/t/t_dedupe_clk_gate.vlt
Normal file
@ -0,0 +1,3 @@
|
||||
`verilator_config
|
||||
|
||||
clock_enable -module "clock_gate_latch" -var "clken_latched"
|
@ -13,7 +13,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#include "Vt_dpi_var.h"
|
||||
#include VM_PREFIX_INCLUDE
|
||||
#include "verilated.h"
|
||||
#include "svdpi.h"
|
||||
|
||||
|
@ -8,13 +8,21 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
# Version 2.0.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
|
||||
|
||||
compile(
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
verilator_flags2 => ["--exe --no-l2name $Self->{t_dir}/t_dpi_var.cpp"],
|
||||
verilator_flags2 => ["-DATTRIBUTES --exe --no-l2name $Self->{t_dir}/t_dpi_var.cpp"],
|
||||
);
|
||||
|
||||
if ($Self->{vlt_all}) {
|
||||
file_grep("$out_filename", qr/\<var fl="d55" name="formatted" dtype_id="4" dir="input" vartype="string" origName="formatted" sformat="true"\/\>/i);
|
||||
file_grep("$out_filename", qr/\<var fl="d76" name="t.sub.in" dtype_id="3" vartype="int" origName="in" public="true" public_flat_rd="true"\/\>/i);
|
||||
file_grep("$out_filename", qr/\<var fl="d77" name="t.sub.fr_a" dtype_id="3" vartype="int" origName="fr_a" public="true" public_flat_rd="true" public_flat_rw="true"\/\>/i);
|
||||
file_grep("$out_filename", qr/\<var fl="d78" name="t.sub.fr_b" dtype_id="3" vartype="int" origName="fr_b" public="true" public_flat_rd="true" public_flat_rw="true"\/\>/i);
|
||||
}
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
@ -51,7 +51,11 @@ module t (/*AUTOARG*/
|
||||
|
||||
endmodule
|
||||
|
||||
`ifdef ATTRIBUTES
|
||||
import "DPI-C" context function void mon_scope_name (input string formatted /*verilator sformat*/ );
|
||||
`else
|
||||
import "DPI-C" context function void mon_scope_name (input string formatted);
|
||||
`endif
|
||||
import "DPI-C" context function void mon_register_b(string name, int isOut);
|
||||
import "DPI-C" context function void mon_register_done();
|
||||
import "DPI-C" context function void mon_eval();
|
||||
@ -68,9 +72,15 @@ module sub (/*AUTOARG*/
|
||||
void mon_register_a(const char* namep, void* sigp, bool isOut);
|
||||
`verilog
|
||||
|
||||
`ifdef ATTRIBUTES
|
||||
input int in /*verilator public_flat_rd*/;
|
||||
output int fr_a /*verilator public_flat_rw @(posedge t.monclk)*/;
|
||||
output int fr_b /*verilator public_flat_rw @(posedge t.monclk)*/;
|
||||
`else
|
||||
input int in;
|
||||
output int fr_a;
|
||||
output int fr_b;
|
||||
`endif
|
||||
output int fr_chk;
|
||||
|
||||
always @* fr_chk = in + 1;
|
||||
|
11
test_regress/t/t_dpi_var.vlt
Normal file
11
test_regress/t/t_dpi_var.vlt
Normal 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
33
test_regress/t/t_dpi_var_vlt.pl
Executable 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;
|
@ -52,17 +52,22 @@ module t (/*AUTOARG*/
|
||||
|
||||
endmodule
|
||||
|
||||
`ifdef USE_INLINE_MID
|
||||
`define INLINE_MODULE /*verilator inline_module*/
|
||||
`define INLINE_MID_MODULE /*verilator no_inline_module*/
|
||||
`else
|
||||
`ifdef USE_INLINE
|
||||
`ifdef ATTRIBUTES
|
||||
`ifdef USE_INLINE_MID
|
||||
`define INLINE_MODULE /*verilator inline_module*/
|
||||
`define INLINE_MID_MODULE /*verilator inline_module*/
|
||||
`define INLINE_MID_MODULE /*verilator no_inline_module*/
|
||||
`else
|
||||
`define INLINE_MODULE /*verilator public_module*/
|
||||
`define INLINE_MID_MODULE /*verilator public_module*/
|
||||
`ifdef USE_INLINE
|
||||
`define INLINE_MODULE /*verilator inline_module*/
|
||||
`define INLINE_MID_MODULE /*verilator inline_module*/
|
||||
`else
|
||||
`define INLINE_MODULE /*verilator public_module*/
|
||||
`define INLINE_MID_MODULE /*verilator public_module*/
|
||||
`endif
|
||||
`endif
|
||||
`else
|
||||
`define INLINE_MODULE
|
||||
`define INLINE_MID_MODULE
|
||||
`endif
|
||||
|
||||
module global_mod;
|
||||
|
@ -10,11 +10,19 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_func_dotted.v");
|
||||
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
|
||||
|
||||
compile(
|
||||
v_flags2 => ['+define+NOUSE_INLINE',],
|
||||
v_flags2 => ['+define+ATTRIBUTES', '+define+NOUSE_INLINE',],
|
||||
);
|
||||
|
||||
if ($Self->{vlt_all}) {
|
||||
file_grep("$out_filename", qr/\<module fl="d83" name="ma" origName="ma" public="true"\>/i);
|
||||
file_grep("$out_filename", qr/\<module fl="d98" name="mb" origName="mb" public="true"\>/i);
|
||||
file_grep("$out_filename", qr/\<module fl="d126" name="mc" origName="mc" public="true"\>/i);
|
||||
file_grep("$out_filename", qr/\<module fl="d126" name="mc__PB1" origName="mc" public="true"\>/i);
|
||||
}
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
9
test_regress/t/t_func_dotted_inl0.vlt
Normal file
9
test_regress/t/t_func_dotted_inl0.vlt
Normal 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*"
|
31
test_regress/t/t_func_dotted_inl0_vlt.pl
Executable file
31
test_regress/t/t_func_dotted_inl0_vlt.pl
Executable 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;
|
@ -10,11 +10,18 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_func_dotted.v");
|
||||
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
|
||||
|
||||
compile(
|
||||
v_flags2 => ['+define+USE_INLINE',],
|
||||
v_flags2 => ['+define+ATTRIBUTES', '+define+USE_INLINE',],
|
||||
);
|
||||
|
||||
if ($Self->{vlt_all}) {
|
||||
file_grep_not("$out_filename", qr/ma0/i);
|
||||
file_grep_not("$out_filename", qr/mb0/i);
|
||||
file_grep_not("$out_filename", qr/mc0/i);
|
||||
}
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
9
test_regress/t/t_func_dotted_inl1.vlt
Normal file
9
test_regress/t/t_func_dotted_inl1.vlt
Normal 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*"
|
30
test_regress/t/t_func_dotted_inl1_vlt.pl
Executable file
30
test_regress/t/t_func_dotted_inl1_vlt.pl
Executable 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;
|
@ -10,11 +10,17 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_func_dotted.v");
|
||||
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
|
||||
|
||||
compile(
|
||||
v_flags2 => ['+define+USE_INLINE_MID',],
|
||||
v_flags2 => ['+define+ATTRIBUTES', '+define+USE_INLINE_MID',],
|
||||
);
|
||||
|
||||
if ($Self->{vlt_all}) {
|
||||
file_grep("$out_filename", qr/\<instance fl="d86" name="t.ma0.mb0" defName="mb" origName="mb0"\/\>/i);
|
||||
file_grep("$out_filename", qr/\<module fl="d98" name="mb" origName="mb"\>/i);
|
||||
}
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
11
test_regress/t/t_func_dotted_inl2.vlt
Normal file
11
test_regress/t/t_func_dotted_inl2.vlt
Normal 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"
|
29
test_regress/t/t_func_dotted_inl2_vlt.pl
Executable file
29
test_regress/t/t_func_dotted_inl2_vlt.pl
Executable 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;
|
@ -47,58 +47,40 @@ module t (/*AUTOARG*/
|
||||
|
||||
endmodule
|
||||
|
||||
`ifdef USE_INLINE
|
||||
`define INLINE_MODULE /*verilator inline_module*/
|
||||
`else
|
||||
`define INLINE_MODULE /*verilator public_module*/
|
||||
`endif
|
||||
|
||||
`ifdef USE_PUBLIC
|
||||
`define PUBLIC /*verilator public*/
|
||||
`else
|
||||
`define PUBLIC
|
||||
`endif
|
||||
|
||||
module ps (input printclk);
|
||||
`INLINE_MODULE
|
||||
// Check that %m stays correct across inlines
|
||||
always @ (posedge printclk) $write("[%0t] %m: Clocked\n", $time);
|
||||
endmodule
|
||||
|
||||
module l1 (input [7:0] a, output [7:0] z `PUBLIC);
|
||||
`INLINE_MODULE
|
||||
wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC;
|
||||
module l1 (input [7:0] a, output [7:0] z);
|
||||
wire [7:0] z0; wire [7:0] z1;
|
||||
assign z = z0+z1;
|
||||
l2 u0 (a, z0); l2 u1 (a, z1);
|
||||
endmodule
|
||||
|
||||
module l2 (input [7:0] a, output [7:0] z `PUBLIC);
|
||||
`INLINE_MODULE
|
||||
wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC;
|
||||
module l2 (input [7:0] a, output [7:0] z);
|
||||
wire [7:0] z0; wire [7:0] z1;
|
||||
assign z = z0+z1;
|
||||
wire [7:0] a1 = a+8'd1;
|
||||
l3 u0 (a, z0); l3 u1 (a1, z1);
|
||||
endmodule
|
||||
|
||||
module l3 (input [7:0] a, output [7:0] z `PUBLIC);
|
||||
`INLINE_MODULE
|
||||
wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC;
|
||||
module l3 (input [7:0] a, output [7:0] z);
|
||||
wire [7:0] z0; wire [7:0] z1;
|
||||
assign z = z0+z1;
|
||||
wire [7:0] a1 = a+8'd1;
|
||||
l4 u0 (a, z0); l4 u1 (a1, z1);
|
||||
endmodule
|
||||
|
||||
module l4 (input [7:0] a, output [7:0] z `PUBLIC);
|
||||
`INLINE_MODULE
|
||||
wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC;
|
||||
module l4 (input [7:0] a, output [7:0] z);
|
||||
wire [7:0] z0; wire [7:0] z1;
|
||||
assign z = z0+z1;
|
||||
wire [7:0] a1 = a+8'd1;
|
||||
l5 #(1) u0 (a, z0); l5 #(2) u1 (a1, z1);
|
||||
endmodule
|
||||
|
||||
module l5 (input [7:0] a, output [7:0] z `PUBLIC);
|
||||
`INLINE_MODULE
|
||||
module l5 (input [7:0] a, output [7:0] z);
|
||||
parameter PARAM = 5;
|
||||
wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC;
|
||||
wire [7:0] z0; wire [7:0] z1;
|
||||
assign z = a;
|
||||
endmodule
|
||||
|
@ -10,10 +10,20 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_inst_tree.v");
|
||||
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
|
||||
|
||||
compile(
|
||||
v_flags2 => ['+define+NOUSE_INLINE', '+define+NOUSE_PUBLIC'],
|
||||
);
|
||||
v_flags2 => ["$Self->{t_dir}/$Self->{name}.vlt"],
|
||||
);
|
||||
|
||||
if ($Self->{vlt_all}) {
|
||||
file_grep("$out_filename", qr/\<module fl="e55" name="l1" origName="l1"\>/i);
|
||||
file_grep("$out_filename", qr/\<module fl="e61" name="l2" origName="l2"\>/i);
|
||||
file_grep("$out_filename", qr/\<module fl="e68" name="l3" origName="l3"\>/i);
|
||||
file_grep("$out_filename", qr/\<module fl="e75" name="l4" origName="l4"\>/i);
|
||||
file_grep("$out_filename", qr/\<module fl="e82" name="l5__P2" origName="l5"\>/i);
|
||||
file_grep("$out_filename", qr/\<module fl="e82" name="l5__P1" origName="l5"\>/i);
|
||||
}
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
|
8
test_regress/t/t_inst_tree_inl0_pub0.vlt
Normal file
8
test_regress/t/t_inst_tree_inl0_pub0.vlt
Normal 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*"
|
@ -13,7 +13,7 @@ top_filename("t/t_inst_tree.v");
|
||||
|
||||
my $default_vltmt_threads = $Self->get_default_vltmt_threads();
|
||||
compile(
|
||||
verilator_flags2 => ['+define+NOUSE_INLINE', '+define+USE_PUBLIC', '--stats',
|
||||
verilator_flags2 => ['--stats', "$Self->{t_dir}/$Self->{name}.vlt",
|
||||
# Force 3 threads even if we have fewer cores
|
||||
$Self->{vltmt} ? "--threads $default_vltmt_threads" : ""]
|
||||
);
|
||||
|
9
test_regress/t/t_inst_tree_inl0_pub1.vlt
Normal file
9
test_regress/t/t_inst_tree_inl0_pub1.vlt
Normal 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*"
|
@ -12,7 +12,8 @@ scenarios(simulator => 1);
|
||||
top_filename("t/t_inst_tree.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ['+define+NOUSE_INLINE', '+define+USE_PUBLIC', '--stats', '--norelative-cfuncs',
|
||||
verilator_flags2 => ['--stats', '--norelative-cfuncs',
|
||||
"$Self->{t_dir}/t_inst_tree_inl0_pub1.vlt",
|
||||
$Self->wno_unopthreads_for_few_cores()]
|
||||
);
|
||||
|
||||
|
@ -10,11 +10,18 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_inst_tree.v");
|
||||
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
|
||||
|
||||
compile(
|
||||
v_flags2 => ['+define+USE_INLINE', '+define+NOUSE_PUBLIC'],
|
||||
v_flags2 => ["$Self->{t_dir}/t_inst_tree_inl1_pub0.vlt"],
|
||||
);
|
||||
|
||||
if ($Self->{vlt_all}) {
|
||||
file_grep("$out_filename", qr/\<var fl="e69" name="t.u.u0.u0.z1" dtype_id="3" vartype="logic" origName="z1"\/\>/i);
|
||||
file_grep("$out_filename", qr/\<var fl="e69" name="t.u.u0.u1.z1" dtype_id="3" vartype="logic" origName="z1"\/\>/i);
|
||||
file_grep("$out_filename", qr/\<var fl="e69" name="t.u.u1.u0.z0" dtype_id="3" vartype="logic" origName="z0"\/\>/i);
|
||||
}
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
expect =>
|
||||
|
8
test_regress/t/t_inst_tree_inl1_pub0.vlt
Normal file
8
test_regress/t/t_inst_tree_inl1_pub0.vlt
Normal 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*"
|
@ -10,12 +10,19 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_inst_tree.v");
|
||||
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
|
||||
|
||||
compile(
|
||||
v_flags2 => ['+define+USE_INLINE', '+define+USE_PUBLIC',
|
||||
v_flags2 => ["t/$Self->{name}.vlt",
|
||||
$Self->wno_unopthreads_for_few_cores()]
|
||||
);
|
||||
|
||||
if ($Self->{vlt_all}) {
|
||||
file_grep("$out_filename", qr/\<var fl="e69" name="u.u0.u0.z0" dtype_id="3" vartype="logic" origName="z0" public="true" public_flat_rd="true" public_flat_rw="true"\/\>/i);
|
||||
file_grep("$out_filename", qr/\<var fl="e84" name="u.u0.u0.u0.u0.z1" dtype_id="3" vartype="logic" origName="z1" public="true" public_flat_rd="true" public_flat_rw="true"\/\>/i);
|
||||
file_grep("$out_filename", qr/\<var fl="e82" name="u.u0.u1.u0.u0.z" dtype_id="3" vartype="logic" origName="z" public="true" public_flat_rd="true" public_flat_rw="true"\/\>/i);
|
||||
}
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
expect =>
|
||||
|
9
test_regress/t/t_inst_tree_inl1_pub1.vlt
Normal file
9
test_regress/t/t_inst_tree_inl1_pub1.vlt
Normal 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*"
|
@ -33,12 +33,18 @@ module glbl();
|
||||
`ifdef PUB_FUNC
|
||||
reg GSR;
|
||||
task setGSR;
|
||||
`ifdef ATTRIBUTES
|
||||
/* verilator public */
|
||||
`endif
|
||||
input value;
|
||||
GSR = value;
|
||||
endtask
|
||||
`else
|
||||
`ifdef ATTRIBUTES
|
||||
reg GSR /*verilator public*/;
|
||||
`else
|
||||
reg GSR;
|
||||
`endif
|
||||
`endif
|
||||
endmodule
|
||||
|
||||
|
@ -8,9 +8,14 @@
|
||||
#include <verilated.h>
|
||||
#include <verilated_vcd_c.h>
|
||||
|
||||
#include "Vt_trace_public_func.h"
|
||||
#include "Vt_trace_public_func_t.h"
|
||||
#include "Vt_trace_public_func_glbl.h"
|
||||
#include VM_PREFIX_INCLUDE
|
||||
#ifdef T_TRACE_PUBLIC_FUNC_VLT
|
||||
# include "Vt_trace_public_func_vlt_t.h"
|
||||
# include "Vt_trace_public_func_vlt_glbl.h"
|
||||
#else
|
||||
# include "Vt_trace_public_func_t.h"
|
||||
# include "Vt_trace_public_func_glbl.h"
|
||||
#endif
|
||||
|
||||
unsigned long long main_time = 0;
|
||||
double sc_time_stamp() { return (double)main_time; }
|
||||
@ -18,7 +23,7 @@ double sc_time_stamp() { return (double)main_time; }
|
||||
const unsigned long long dt_2 = 3;
|
||||
|
||||
int main(int argc, char** argv, char** env) {
|
||||
Vt_trace_public_func* top = new Vt_trace_public_func("top");
|
||||
VM_PREFIX* top = new VM_PREFIX("top");
|
||||
|
||||
Verilated::debug(0);
|
||||
Verilated::traceEverOn(true);
|
||||
|
@ -14,7 +14,7 @@ top_filename("t/t_trace_public.v");
|
||||
compile(
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
v_flags2 => ["-DPUB_FUNC --trace --exe $Self->{t_dir}/$Self->{name}.cpp"],
|
||||
v_flags2 => ["-DATTRIBUTES -DPUB_FUNC --trace --exe $Self->{t_dir}/$Self->{name}.cpp"],
|
||||
);
|
||||
|
||||
execute(
|
||||
|
8
test_regress/t/t_trace_public_func.vlt
Normal file
8
test_regress/t/t_trace_public_func.vlt
Normal 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"
|
28
test_regress/t/t_trace_public_func_vlt.pl
Executable file
28
test_regress/t/t_trace_public_func_vlt.pl
Executable 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;
|
@ -8,9 +8,14 @@
|
||||
#include <verilated.h>
|
||||
#include <verilated_vcd_c.h>
|
||||
|
||||
#include "Vt_trace_public_sig.h"
|
||||
#include "Vt_trace_public_sig_t.h"
|
||||
#include "Vt_trace_public_sig_glbl.h"
|
||||
#include VM_PREFIX_INCLUDE
|
||||
#ifdef T_TRACE_PUBLIC_SIG_VLT
|
||||
# include "Vt_trace_public_sig_vlt_t.h"
|
||||
# include "Vt_trace_public_sig_vlt_glbl.h"
|
||||
#else
|
||||
# include "Vt_trace_public_sig_t.h"
|
||||
# include "Vt_trace_public_sig_glbl.h"
|
||||
#endif
|
||||
|
||||
unsigned long long main_time = 0;
|
||||
double sc_time_stamp() { return (double)main_time; }
|
||||
@ -18,7 +23,7 @@ double sc_time_stamp() { return (double)main_time; }
|
||||
const unsigned long long dt_2 = 3;
|
||||
|
||||
int main(int argc, char** argv, char** env) {
|
||||
Vt_trace_public_sig* top = new Vt_trace_public_sig("top");
|
||||
VM_PREFIX* top = new VM_PREFIX("top");
|
||||
|
||||
Verilated::debug(0);
|
||||
Verilated::traceEverOn(true);
|
||||
|
@ -14,7 +14,7 @@ top_filename("t/t_trace_public.v");
|
||||
compile(
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
v_flags2 => ["--trace --exe $Self->{t_dir}/$Self->{name}.cpp"],
|
||||
v_flags2 => ["-DATTRIBUTES --trace --exe $Self->{t_dir}/$Self->{name}.cpp"],
|
||||
);
|
||||
|
||||
execute(
|
||||
|
8
test_regress/t/t_trace_public_sig.vlt
Normal file
8
test_regress/t/t_trace_public_sig.vlt
Normal 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"
|
36
test_regress/t/t_trace_public_sig_vlt.pl
Executable file
36
test_regress/t/t_trace_public_sig_vlt.pl
Executable 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;
|
@ -94,10 +94,17 @@ module file (/*AUTOARG*/
|
||||
endcase
|
||||
end
|
||||
|
||||
`ifdef ISOLATE
|
||||
function [31:16] get_31_16 /* verilator isolate_assignments*/;
|
||||
input [31:0] t_crc /* verilator isolate_assignments*/;
|
||||
get_31_16 = t_crc[31:16];
|
||||
endfunction
|
||||
`else
|
||||
function [31:16] get_31_16;
|
||||
input [31:0] t_crc;
|
||||
get_31_16 = t_crc[31:16];
|
||||
endfunction
|
||||
`endif
|
||||
|
||||
task set_b_d;
|
||||
`ifdef ISOLATE
|
||||
|
@ -5,6 +5,6 @@
|
||||
t/t_unopt_combo.v:23: Example path: t.c
|
||||
t/t_unopt_combo.v:80: Example path: ALWAYS
|
||||
t/t_unopt_combo.v:22: Example path: t.b
|
||||
t/t_unopt_combo.v:116: Example path: ALWAYS
|
||||
t/t_unopt_combo.v:123: Example path: ALWAYS
|
||||
t/t_unopt_combo.v:23: Example path: t.c
|
||||
%Error: Exiting due to
|
||||
|
@ -12,6 +12,7 @@ scenarios(simulator => 1);
|
||||
top_filename("t/t_unopt_combo.v");
|
||||
|
||||
compile(
|
||||
v_flags2 => ['+define+ATTRIBUTES'],
|
||||
fails => $Self->{vlt_all},
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
@ -10,13 +10,19 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_unopt_combo.v");
|
||||
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ['+define+ISOLATE --stats'],
|
||||
verilator_flags2 => ["+define+ISOLATE --stats"],
|
||||
);
|
||||
|
||||
if ($Self->{vlt_all}) {
|
||||
file_grep($Self->{stats}, qr/Optimizations, isolate_assignments blocks\s+5/i);
|
||||
file_grep("$out_filename", qr/\<var fl="d22" name="t.b" dtype_id="4" vartype="logic" origName="b" isolate_assignments="true"\/\>/i);
|
||||
file_grep("$out_filename", qr/\<var fl="d98" name="__Vfunc_t.file.get_31_16__0__Vfuncout" dtype_id="5" vartype="logic" origName="__Vfunc_t__DOT__file__DOT__get_31_16__0__Vfuncout" isolate_assignments="true"\/\>/i);
|
||||
file_grep("$out_filename", qr/\<var fl="d99" name="__Vfunc_t.file.get_31_16__0__t_crc" dtype_id="4" vartype="logic" origName="__Vfunc_t__DOT__file__DOT__get_31_16__0__t_crc" isolate_assignments="true"\/\>/i);
|
||||
file_grep("$out_filename", qr/\<var fl="d111" name="__Vtask_t.file.set_b_d__1__t_crc" dtype_id="4" vartype="logic" origName="__Vtask_t__DOT__file__DOT__set_b_d__1__t_crc" isolate_assignments="true"\/\>/i);
|
||||
file_grep("$out_filename", qr/\<var fl="d112" name="__Vtask_t.file.set_b_d__1__t_c" dtype_id="4" vartype="logic" origName="__Vtask_t__DOT__file__DOT__set_b_d__1__t_c" isolate_assignments="true"\/\>/i);
|
||||
}
|
||||
|
||||
execute(
|
||||
|
11
test_regress/t/t_unopt_combo_isolate.vlt
Normal file
11
test_regress/t/t_unopt_combo_isolate.vlt
Normal 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"
|
32
test_regress/t/t_unopt_combo_isolate_vlt.pl
Executable file
32
test_regress/t/t_unopt_combo_isolate_vlt.pl
Executable 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;
|
@ -12,7 +12,7 @@ scenarios(vlt_all => 1);
|
||||
top_filename("t/t_var_pinsizes.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ["-sc -pins-bv 1 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
|
||||
verilator_flags2 => ["-sc -pins-bv 1 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp $Self->{t_dir}/t_var_pinsizes.vlt"],
|
||||
make_main => 0,
|
||||
);
|
||||
|
||||
@ -25,6 +25,8 @@ if ($Self->{vlt_all}) {
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1_vlt;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16_vlt;/x);
|
||||
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ o1;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<8>\s> \s+ o8;/x);
|
||||
@ -34,6 +36,8 @@ if ($Self->{vlt_all}) {
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1_vlt;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16_vlt;/x);
|
||||
}
|
||||
|
||||
execute();
|
||||
|
@ -12,7 +12,7 @@ scenarios(vlt_all => 1);
|
||||
top_filename("t/t_var_pinsizes.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ["-sc -pins-bv 2 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
|
||||
verilator_flags2 => ["-sc -pins-bv 2 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp $Self->{t_dir}/t_var_pinsizes.vlt"],
|
||||
make_main => 0,
|
||||
);
|
||||
|
||||
@ -25,6 +25,8 @@ compile(
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1_vlt;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16_vlt;/x);
|
||||
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<bool> \s+ o1;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<8>\s> \s+ o8;/x);
|
||||
@ -34,6 +36,8 @@ compile(
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1_vlt;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16_vlt;/x);
|
||||
}
|
||||
|
||||
execute();
|
||||
|
@ -12,7 +12,7 @@ scenarios(vlt_all => 1);
|
||||
top_filename("t/t_var_pinsizes.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ["-sc -no-pins64 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
|
||||
verilator_flags2 => ["-sc -no-pins64 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp $Self->{t_dir}/t_var_pinsizes.vlt"],
|
||||
make_main => 0,
|
||||
);
|
||||
|
||||
@ -25,6 +25,8 @@ compile(
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1_vlt;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16_vlt;/x);
|
||||
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<bool> \s+ o1;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint32_t> \s+ o8;/x);
|
||||
@ -34,6 +36,8 @@ compile(
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1_vlt;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16_vlt;/x);
|
||||
}
|
||||
|
||||
execute();
|
||||
|
@ -12,7 +12,7 @@ scenarios(vlt_all => 1);
|
||||
top_filename("t/t_var_pinsizes.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ["-sc -pins64 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
|
||||
verilator_flags2 => ["-sc -pins64 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp $Self->{t_dir}/t_var_pinsizes.vlt"],
|
||||
make_main => 0,
|
||||
);
|
||||
|
||||
@ -25,6 +25,8 @@ if ($Self->{vlt_all}) {
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1_vlt;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16_vlt;/x);
|
||||
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<bool> \s+ o1;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint32_t> \s+ o8;/x);
|
||||
@ -34,6 +36,8 @@ if ($Self->{vlt_all}) {
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1_vlt;/x);
|
||||
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16_vlt;/x);
|
||||
}
|
||||
|
||||
execute();
|
||||
|
@ -8,9 +8,9 @@
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Outputs
|
||||
o1, o8, o16, o32, o64, o65, o128, o513, o1a2, o94a3, obv1, obv16,
|
||||
o1, o8, o16, o32, o64, o65, o128, o513, o1a2, o94a3, obv1, obv16, obv1_vlt, obv16_vlt,
|
||||
// Inputs
|
||||
clk, i1, i8, i16, i32, i64, i65, i128, i513, i1a2, i94a3, ibv1, ibv16
|
||||
clk, i1, i8, i16, i32, i64, i65, i128, i513, i1a2, i94a3, ibv1, ibv16, ibv1_vlt, ibv16_vlt
|
||||
);
|
||||
|
||||
input clk;
|
||||
@ -38,10 +38,14 @@ module t (/*AUTOARG*/
|
||||
output logic [93:0] o94a3 [2:0];
|
||||
|
||||
input [0:0] ibv1 /*verilator sc_bv*/;
|
||||
input [15:0] ibv16 /*verilator sc_bv*/;
|
||||
input [15:0] ibv16 /*verilator sc_bv*/;
|
||||
input [0:0] ibv1_vlt;
|
||||
input [15:0] ibv16_vlt;
|
||||
|
||||
output logic [0:0] obv1 /*verilator sc_bv*/;
|
||||
output logic [15:0] obv16 /*verilator sc_bv*/;
|
||||
output logic [0:0] obv1_vlt;
|
||||
output logic [15:0] obv16_vlt;
|
||||
|
||||
always @ (posedge clk) begin
|
||||
o1 <= i1;
|
||||
@ -54,6 +58,8 @@ module t (/*AUTOARG*/
|
||||
o513 <= i513;
|
||||
obv1 <= ibv1;
|
||||
obv16 <= ibv16;
|
||||
obv1_vlt <= ibv1_vlt;
|
||||
obv16_vlt <= ibv16_vlt;
|
||||
o1a2 <= i1a2;
|
||||
o94a3 <= i94a3;
|
||||
end
|
||||
|
10
test_regress/t/t_var_pinsizes.vlt
Normal file
10
test_regress/t/t_var_pinsizes.vlt
Normal 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"
|
7
test_regress/t/t_vlt_syntax_bad.out
Normal file
7
test_regress/t/t_vlt_syntax_bad.out
Normal 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
|
19
test_regress/t/t_vlt_syntax_bad.pl
Executable file
19
test_regress/t/t_vlt_syntax_bad.pl
Executable 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;
|
2
test_regress/t/t_vlt_syntax_bad.v
Normal file
2
test_regress/t/t_vlt_syntax_bad.v
Normal file
@ -0,0 +1,2 @@
|
||||
module t;
|
||||
endmodule
|
9
test_regress/t/t_vlt_syntax_bad.vlt
Normal file
9
test_regress/t/t_vlt_syntax_bad.vlt
Normal 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"
|
@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
scenarios(vlt => 1);
|
||||
|
||||
lint(
|
||||
verilator_flags2 => ["--lint-only t/t_vlt_warn.vlt"],
|
||||
verilator_flags2 => ["--lint-only t/t_vlt_warn.vlt -Wall"],
|
||||
);
|
||||
|
||||
ok(1);
|
||||
|
@ -5,13 +5,16 @@
|
||||
|
||||
`verilator_config
|
||||
|
||||
lint_off -rule DEPRECATED -file "t/t_vlt_warn.vlt" -lines 12
|
||||
lint_off -rule DEPRECATED -file "t/t_vlt_warn.vlt" -lines 13
|
||||
lint_off -rule CASEINCOMPLETE -file "t/t_vlt_warn.v"
|
||||
lint_off -rule WIDTH -file "t/t_vlt_warn.v" -lines 18
|
||||
lint_off -rule DECLFILENAME -file "*/t_vlt_warn.v"
|
||||
// Test wildcard filenames
|
||||
lint_off -msg WIDTH -file "*/t_vlt_warn.v" -lines 19-19
|
||||
// Test global disables
|
||||
lint_off -file "*/t_vlt_warn.v" -lines 20-20
|
||||
// Test match
|
||||
lint_off -rule UNUSED -file "*/t_vlt_warn.v" -match "Signal is not used: 'width_warn*'"
|
||||
|
||||
coverage_off -file "t/t_vlt_warn.v"
|
||||
// Test --flag is also accepted
|
||||
|
Loading…
Reference in New Issue
Block a user