diff --git a/Changes b/Changes index e5c1ca47c..4844fa77d 100644 --- a/Changes +++ b/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] diff --git a/bin/verilator b/bin/verilator index dd6a572d3..eeee6923b 100755 --- a/bin/verilator +++ b/bin/verilator @@ -2769,6 +2769,8 @@ purposes. =item lint_off [-rule ] [-file "" [-lines [ - ]]] +=item lint_off [-rule ] [-file ""] [-match ""] + 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 "" -signal "" + +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 for +more information and an example. + +=item clocker -module "" [-task ""] -signal "" + +=item clocker -module "" [-function ""] -signal "" + +=item no_clocker -module "" [-task ""] -signal "" + +=item no_clocker -module "" [-function ""] -signal "" + +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 for more +information. + +=item coverage_block_off -module "" -block "" + +=item coverage_block_off -file "" -line + +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 for more information. + +=item full_case -file "" -lines + +=item parallel_case -file "" -lines + +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 "" + +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__DOT__I 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 for +more information. + +=item isolate_assignments -module "" [-task ""] -signal "" + +=item isolate_assignments -module "" [-function ""] -signal "" + +=item isolate_assignments -module "" -function "" + +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 for more information. + +=item no_inline -module "" + +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 +for more information. + +=item no_inline [-module ""] -task "" + +=item no_inline [-module ""] -function "" + +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 +for more information. + +=item sc_bv -module "" [-task ""] -signal "" + +=item sc_bv -module "" [-function ""] -signal "" + +Sets the port to be of sc_bv> 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 for more +information. + +=item sformat [-module ""] [-task ""] -signal "" + +=item sformat [-module ""] [-function ""] -signal "" + +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 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 in +L. =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 in configuration files, see L 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 and C in configuration files, see +L for more information. + =item /*verilator coverage_block_off*/ Specifies the entire begin/end block should be ignored for coverage analysis purposes. +Same as C in configuration files, see +L 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__DOT__I 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 in configuration files, see L +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 in configuration files, see +L for more information. + =item /*verilator lint_off I*/ 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 in configuration files, see L 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 in configuration files, see L 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 in configuration files, see L +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 in configuration files, see L +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 in configuration files, see L 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 in configuration files, see L for more information. + =item /*verilator public_flat_rw @() */ (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 in configuration files, see L 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 in configuration files, see L +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 in configuration files, see L +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 in configuration files, see L +for more information. + =item /*verilator tag */ Attached after a variable or structure member to indicate opaque (to diff --git a/src/V3Ast.h b/src/V3Ast.h index 1c0057f4c..d500b3fd7 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -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) {} diff --git a/src/V3Config.cpp b/src/V3Config.cpp index 6179860c4..8a1568d60 100644 --- a/src/V3Config.cpp +++ b/src/V3Config.cpp @@ -30,133 +30,491 @@ #include //###################################################################### +// 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 class V3ConfigWildcardResolver { + typedef std::map 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_linenorh.m_lineno) return false; - if (m_coderh.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 { +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 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 V3ConfigFTaskResolver; + +//###################################################################### +// Modules have tasks, variables, named blocks and properties + +class V3ConfigModule { + typedef std::unordered_set 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 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< IgnLines; // list of {line,code,on} - typedef std::map 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 V3ConfigLineAttribute; - // MEMBERS - string m_lastFilename; // Last filename looked up - int m_lastLineno; // Last linenumber looked up +// File entity +class V3ConfigFile { + typedef std::map LineAttrMap; // Map line->bitset of attributes + typedef std::multiset IgnLines; // list of {line,code,on} + typedef std::pair WaiverSetting; // Waive code if string matches + typedef std::vector 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 "<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 "<ascii()<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 "<ascii()<lastLineno(); - for (; m_lastIt != m_lastEnd; ++m_lastIt) { - if (m_lastIt->m_lineno > curlineno) break; - //UINFO(9," Hit "<<*m_lastIt<warnOn(m_lastIt->m_code, m_lastIt->m_on); + for (; m_lastIgnore.it != m_ignLines.end(); ++m_lastIgnore.it) { + if (m_lastIgnore.it->m_lineno > curlineno) break; + // UINFO(9," Hit "<<*m_lastIt<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<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 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); } diff --git a/src/V3Config.h b/src/V3Config.h index 4c6ad4417..cdd4b9c78 100644 --- a/src/V3Config.h +++ b/src/V3Config.h @@ -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 diff --git a/src/V3EmitXml.cpp b/src/V3EmitXml.cpp index 00191ee1f..86985506a 100644 --- a/src/V3EmitXml.cpp +++ b/src/V3EmitXml.cpp @@ -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\""); diff --git a/src/V3FileLine.cpp b/src/V3FileLine.cpp index e7d45e3d8..b6cceec76 100644 --- a/src/V3FileLine.cpp +++ b/src/V3FileLine.cpp @@ -341,7 +341,10 @@ void FileLine::v3errorEnd(std::ostringstream& str, const string& locationStr) { if (!locationStr.empty()) { lstr< #include @@ -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); diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index 9b1929a5a..aeb74b67f 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -62,6 +62,7 @@ struct V3ParseBisonYYSType { VSignedState signstate; V3ImportProperty iprop; V3ErrorCode::en errcodeen; + AstAttrType::en attrtypeen; AstNode* nodep; diff --git a/src/V3String.cpp b/src/V3String.cpp index 0a4bba3c8..ea6a9ed2b 100644 --- a/src/V3String.cpp +++ b/src/V3String.cpp @@ -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; diff --git a/src/V3String.h b/src/V3String.h index e473b2b77..889038777 100644 --- a/src/V3String.h +++ b/src/V3String.h @@ -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) diff --git a/src/verilog.l b/src/verilog.l index c25b64d8e..a1ca07e26 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -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; } } /************************************************************************/ diff --git a/src/verilog.y b/src/verilog.y index 902a2a5be..2a7d882e1 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -273,17 +273,39 @@ class AstSenTree; %token yaSCCTOR "`systemc_implementation BLOCK" %token yaSCDTOR "`systemc_imp_header BLOCK" -%token yVLT_COVERAGE_OFF "coverage_off" -%token yVLT_COVERAGE_ON "coverage_on" -%token yVLT_LINT_OFF "lint_off" -%token yVLT_LINT_ON "lint_on" -%token yVLT_TRACING_OFF "tracing_off" -%token yVLT_TRACING_ON "tracing_on" +%token yVLT_CLOCKER "clocker" +%token yVLT_CLOCK_ENABLE "clock_enable" +%token yVLT_COVERAGE_BLOCK_OFF "coverage_block_off" +%token yVLT_COVERAGE_OFF "coverage_off" +%token yVLT_COVERAGE_ON "coverage_on" +%token yVLT_FULL_CASE "full_case" +%token yVLT_INLINE "inline" +%token yVLT_ISOLATE_ASSIGNMENTS "isolate_assignments" +%token yVLT_LINT_OFF "lint_off" +%token yVLT_LINT_ON "lint_on" +%token yVLT_NO_CLOCKER "no_clocker" +%token yVLT_NO_INLINE "no_inline" +%token yVLT_PARALLEL_CASE "parallel_case" +%token yVLT_PUBLIC "public" +%token yVLT_PUBLIC_FLAT "public_flat" +%token yVLT_PUBLIC_FLAT_RD "public_flat_rd" +%token yVLT_PUBLIC_FLAT_RW "public_flat_rw" +%token yVLT_PUBLIC_MODULE "public_module" +%token yVLT_SC_BV "sc_bv" +%token yVLT_SFORMAT "sformat" +%token yVLT_TRACING_OFF "tracing_off" +%token yVLT_TRACING_ON "tracing_on" -%token yVLT_D_FILE "--file" -%token yVLT_D_LINES "--lines" -%token yVLT_D_MSG "--msg" -%token yVLT_D_RULE "--rule" +%token yVLT_D_BLOCK "--block" +%token yVLT_D_FILE "--file" +%token yVLT_D_FUNCTION "--function" +%token yVLT_D_LINES "--lines" +%token yVLT_D_MODULE "--module" +%token yVLT_D_MATCH "--match" +%token yVLT_D_MSG "--msg" +%token yVLT_D_RULE "--rule" +%token yVLT_D_TASK "--task" +%token yVLT_D_VAR "--var" %token yaD_IGNORE "${ignored-bbox-sys}" %token 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: // IEEE: named_port_connection + empty //************************************************ // EventControl lists +attr_event_controlE: + /* empty */ { $$ = NULL; } + | attr_event_control { $$ = $1; } + ; + attr_event_control: // ==IEEE: event_control '@' '(' event_expression ')' { $$ = new AstSenTree($1,$3); } | '@' '(' '*' ')' { $$ = NULL; } @@ -5582,14 +5610,45 @@ memberQualOne: // 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)) { + $1->v3error("Argument -match only supported for lint_off"<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($1, *$2, *$3, *$4, $1, $5); } + | vltInlineFront vltDModuleE vltDFTaskE + { V3Config::addInline($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: @@ -5618,6 +5677,40 @@ vltOnFront: if ($$ == V3ErrorCode::EC_ERROR) { $1->v3error("Unknown Error Code: "<<*$3<: + /* empty */ { static string unit = "__024unit"; $$ = &unit; } + | yVLT_D_MODULE str { $$ = $2; } + ; + +vltDFTaskE: + /* empty */ { static string empty = ""; $$ = ∅ } + | yVLT_D_FUNCTION str { $$ = $2; } + | yVLT_D_TASK str { $$ = $2; } + ; + +vltInlineFront: + yVLT_INLINE { $$ = true; } + | yVLT_NO_INLINE { $$ = false; } + ; + +vltVarAttrVarE: + /* empty */ { static string empty = ""; $$ = ∅ } + | yVLT_D_VAR str { $$ = $2; } + ; + +vltVarAttrFront: + 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 diff --git a/test_regress/t/t_assert_synth.v b/test_regress/t/t_assert_synth.v index 8506ca13a..d48d5ccb0 100644 --- a/test_regress/t/t_assert_synth.v +++ b/test_regress/t/t_assert_synth.v @@ -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 diff --git a/test_regress/t/t_assert_synth_full.pl b/test_regress/t/t_assert_synth_full.pl index e59b20408..eb9239199 100755 --- a/test_regress/t/t_assert_synth_full.pl +++ b/test_regress/t/t_assert_synth_full.pl @@ -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); diff --git a/test_regress/t/t_assert_synth_full.vlt b/test_regress/t/t_assert_synth_full.vlt new file mode 100644 index 000000000..e2615f828 --- /dev/null +++ b/test_regress/t/t_assert_synth_full.vlt @@ -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 diff --git a/test_regress/t/t_assert_synth_full_vlt.out b/test_regress/t/t_assert_synth_full_vlt.out new file mode 100644 index 000000000..ad5ebd09f --- /dev/null +++ b/test_regress/t/t_assert_synth_full_vlt.out @@ -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... diff --git a/test_regress/t/t_assert_synth_full_vlt.pl b/test_regress/t/t_assert_synth_full_vlt.pl new file mode 100755 index 000000000..eb2eb54ae --- /dev/null +++ b/test_regress/t/t_assert_synth_full_vlt.pl @@ -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; diff --git a/test_regress/t/t_assert_synth_parallel.pl b/test_regress/t/t_assert_synth_parallel.pl index ef491ab7d..628288ac8 100755 --- a/test_regress/t/t_assert_synth_parallel.pl +++ b/test_regress/t/t_assert_synth_parallel.pl @@ -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'], ); diff --git a/test_regress/t/t_assert_synth_parallel.vlt b/test_regress/t/t_assert_synth_parallel.vlt new file mode 100644 index 000000000..d25ddaf06 --- /dev/null +++ b/test_regress/t/t_assert_synth_parallel.vlt @@ -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 diff --git a/test_regress/t/t_assert_synth_parallel_vlt.pl b/test_regress/t/t_assert_synth_parallel_vlt.pl new file mode 100755 index 000000000..c9cd46167 --- /dev/null +++ b/test_regress/t/t_assert_synth_parallel_vlt.pl @@ -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; diff --git a/test_regress/t/t_clk_concat.pl b/test_regress/t/t_clk_concat.pl index 1be18a66c..abe880617 100755 --- a/test_regress/t/t_clk_concat.pl +++ b/test_regress/t/t_clk_concat.pl @@ -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/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); +} + execute( check_finished => 1, ); diff --git a/test_regress/t/t_clk_concat.v b/test_regress/t/t_clk_concat.v index caba2a926..afb1d26b1 100644 --- a/test_regress/t/t_clk_concat.v +++ b/test_regress/t/t_clk_concat.v @@ -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 ); diff --git a/test_regress/t/t_clk_concat.vlt b/test_regress/t/t_clk_concat.vlt new file mode 100644 index 000000000..c6af77881 --- /dev/null +++ b/test_regress/t/t_clk_concat.vlt @@ -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" diff --git a/test_regress/t/t_clk_concat_vlt.pl b/test_regress/t/t_clk_concat_vlt.pl new file mode 100755 index 000000000..965daacd9 --- /dev/null +++ b/test_regress/t/t_clk_concat_vlt.pl @@ -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/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); +} + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_clk_first.pl b/test_regress/t/t_clk_first.pl index 89a4e77d9..91433482b 100755 --- a/test_regress/t/t_clk_first.pl +++ b/test_regress/t/t_clk_first.pl @@ -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( diff --git a/test_regress/t/t_cover_line.out b/test_regress/t/t_cover_line.out index 31873558e..3071c13a7 100644 --- a/test_regress/t/t_cover_line.out +++ b/test_regress/t/t_cover_line.out @@ -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 diff --git a/test_regress/t/t_cover_line.v b/test_regress/t/t_cover_line.v index 7cb84decf..9c633a5dd 100644 --- a/test_regress/t/t_cover_line.v +++ b/test_regress/t/t_cover_line.v @@ -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 diff --git a/test_regress/t/t_cover_line.vlt b/test_regress/t/t_cover_line.vlt new file mode 100644 index 000000000..2018150fb --- /dev/null +++ b/test_regress/t/t_cover_line.vlt @@ -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" diff --git a/test_regress/t/t_cover_line_cc.pl b/test_regress/t/t_cover_line_cc.pl index 867e16ea4..560dc831d 100755 --- a/test_regress/t/t_cover_line_cc.pl +++ b/test_regress/t/t_cover_line_cc.pl @@ -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( diff --git a/test_regress/t/t_cover_line_cc_vlt.pl b/test_regress/t/t_cover_line_cc_vlt.pl new file mode 100755 index 000000000..c2201d7b4 --- /dev/null +++ b/test_regress/t/t_cover_line_cc_vlt.pl @@ -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; diff --git a/test_regress/t/t_cover_line_sc.pl b/test_regress/t/t_cover_line_sc.pl index cde76f21f..fbe062a41 100755 --- a/test_regress/t/t_cover_line_sc.pl +++ b/test_regress/t/t_cover_line_sc.pl @@ -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( diff --git a/test_regress/t/t_cover_line_trace.out b/test_regress/t/t_cover_line_trace.out index bbe500237..e1fbd2120 100644 --- a/test_regress/t/t_cover_line_trace.out +++ b/test_regress/t/t_cover_line_trace.out @@ -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! diff --git a/test_regress/t/t_cover_line_trace.pl b/test_regress/t/t_cover_line_trace.pl index 40ff27284..0b6b4e958 100755 --- a/test_regress/t/t_cover_line_trace.pl +++ b/test_regress/t/t_cover_line_trace.pl @@ -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( diff --git a/test_regress/t/t_dedupe_clk_gate.pl b/test_regress/t/t_dedupe_clk_gate.pl index 8bbe70d24..99b5982d1 100755 --- a/test_regress/t/t_dedupe_clk_gate.pl +++ b/test_regress/t/t_dedupe_clk_gate.pl @@ -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/\/i); file_grep($Self->{stats}, qr/Optimizations, Gate sigs deduped\s+(\d+)/i, 4); } + ok(1); 1; diff --git a/test_regress/t/t_dedupe_clk_gate.v b/test_regress/t/t_dedupe_clk_gate.v index 81cbc2af2..75196346a 100644 --- a/test_regress/t/t_dedupe_clk_gate.v +++ b/test_regress/t/t_dedupe_clk_gate.v @@ -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; diff --git a/test_regress/t/t_dedupe_clk_gate.vlt b/test_regress/t/t_dedupe_clk_gate.vlt new file mode 100644 index 000000000..6e2a77ef9 --- /dev/null +++ b/test_regress/t/t_dedupe_clk_gate.vlt @@ -0,0 +1,3 @@ +`verilator_config + +clock_enable -module "clock_gate_latch" -var "clken_latched" diff --git a/test_regress/t/t_dpi_var.cpp b/test_regress/t/t_dpi_var.cpp index 36a545d49..ce2fb5916 100644 --- a/test_regress/t/t_dpi_var.cpp +++ b/test_regress/t/t_dpi_var.cpp @@ -13,7 +13,7 @@ // //************************************************************************* -#include "Vt_dpi_var.h" +#include VM_PREFIX_INCLUDE #include "verilated.h" #include "svdpi.h" diff --git a/test_regress/t/t_dpi_var.pl b/test_regress/t/t_dpi_var.pl index 699b48d9e..652a9657f 100755 --- a/test_regress/t/t_dpi_var.pl +++ b/test_regress/t/t_dpi_var.pl @@ -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/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); +} + execute( check_finished => 1, ); diff --git a/test_regress/t/t_dpi_var.v b/test_regress/t/t_dpi_var.v index 8c42c420d..4f9236a09 100644 --- a/test_regress/t/t_dpi_var.v +++ b/test_regress/t/t_dpi_var.v @@ -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; diff --git a/test_regress/t/t_dpi_var.vlt b/test_regress/t/t_dpi_var.vlt new file mode 100644 index 000000000..063a2284b --- /dev/null +++ b/test_regress/t/t_dpi_var.vlt @@ -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) diff --git a/test_regress/t/t_dpi_var_vlt.pl b/test_regress/t/t_dpi_var_vlt.pl new file mode 100755 index 000000000..bc0af71ca --- /dev/null +++ b/test_regress/t/t_dpi_var_vlt.pl @@ -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/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); +} + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_func_dotted.v b/test_regress/t/t_func_dotted.v index 4c985ea75..892626ad0 100644 --- a/test_regress/t/t_func_dotted.v +++ b/test_regress/t/t_func_dotted.v @@ -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; diff --git a/test_regress/t/t_func_dotted_inl0.pl b/test_regress/t/t_func_dotted_inl0.pl index af2faf33f..de41c1dc4 100755 --- a/test_regress/t/t_func_dotted_inl0.pl +++ b/test_regress/t/t_func_dotted_inl0.pl @@ -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/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); +} + execute( check_finished => 1, ); diff --git a/test_regress/t/t_func_dotted_inl0.vlt b/test_regress/t/t_func_dotted_inl0.vlt new file mode 100644 index 000000000..eef5ae669 --- /dev/null +++ b/test_regress/t/t_func_dotted_inl0.vlt @@ -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*" diff --git a/test_regress/t/t_func_dotted_inl0_vlt.pl b/test_regress/t/t_func_dotted_inl0_vlt.pl new file mode 100755 index 000000000..b8c833d2c --- /dev/null +++ b/test_regress/t/t_func_dotted_inl0_vlt.pl @@ -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/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); +} + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_func_dotted_inl1.pl b/test_regress/t/t_func_dotted_inl1.pl index 0f9ea98bd..2f3b869d0 100755 --- a/test_regress/t/t_func_dotted_inl1.pl +++ b/test_regress/t/t_func_dotted_inl1.pl @@ -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, ); diff --git a/test_regress/t/t_func_dotted_inl1.vlt b/test_regress/t/t_func_dotted_inl1.vlt new file mode 100644 index 000000000..e81ace1ff --- /dev/null +++ b/test_regress/t/t_func_dotted_inl1.vlt @@ -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*" diff --git a/test_regress/t/t_func_dotted_inl1_vlt.pl b/test_regress/t/t_func_dotted_inl1_vlt.pl new file mode 100755 index 000000000..51a92a162 --- /dev/null +++ b/test_regress/t/t_func_dotted_inl1_vlt.pl @@ -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; diff --git a/test_regress/t/t_func_dotted_inl2.pl b/test_regress/t/t_func_dotted_inl2.pl index fc71dbbca..9784092cd 100755 --- a/test_regress/t/t_func_dotted_inl2.pl +++ b/test_regress/t/t_func_dotted_inl2.pl @@ -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/\/i); + file_grep("$out_filename", qr/\/i); +} + execute( check_finished => 1, ); diff --git a/test_regress/t/t_func_dotted_inl2.vlt b/test_regress/t/t_func_dotted_inl2.vlt new file mode 100644 index 000000000..68d53c3e6 --- /dev/null +++ b/test_regress/t/t_func_dotted_inl2.vlt @@ -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" diff --git a/test_regress/t/t_func_dotted_inl2_vlt.pl b/test_regress/t/t_func_dotted_inl2_vlt.pl new file mode 100755 index 000000000..32a36011f --- /dev/null +++ b/test_regress/t/t_func_dotted_inl2_vlt.pl @@ -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/\/i); + file_grep("$out_filename", qr/\/i); +} + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_inst_tree.v b/test_regress/t/t_inst_tree.v index 9065d6b59..44530ccd8 100644 --- a/test_regress/t/t_inst_tree.v +++ b/test_regress/t/t_inst_tree.v @@ -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 diff --git a/test_regress/t/t_inst_tree_inl0_pub0.pl b/test_regress/t/t_inst_tree_inl0_pub0.pl index b9f879e8b..2ee859437 100755 --- a/test_regress/t/t_inst_tree_inl0_pub0.pl +++ b/test_regress/t/t_inst_tree_inl0_pub0.pl @@ -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/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); +} execute( check_finished => 1, diff --git a/test_regress/t/t_inst_tree_inl0_pub0.vlt b/test_regress/t/t_inst_tree_inl0_pub0.vlt new file mode 100644 index 000000000..dabc18533 --- /dev/null +++ b/test_regress/t/t_inst_tree_inl0_pub0.vlt @@ -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*" diff --git a/test_regress/t/t_inst_tree_inl0_pub1.pl b/test_regress/t/t_inst_tree_inl0_pub1.pl index 7b3bc4634..9ba3d3b56 100755 --- a/test_regress/t/t_inst_tree_inl0_pub1.pl +++ b/test_regress/t/t_inst_tree_inl0_pub1.pl @@ -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" : ""] ); diff --git a/test_regress/t/t_inst_tree_inl0_pub1.vlt b/test_regress/t/t_inst_tree_inl0_pub1.vlt new file mode 100644 index 000000000..cddd66b4a --- /dev/null +++ b/test_regress/t/t_inst_tree_inl0_pub1.vlt @@ -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*" diff --git a/test_regress/t/t_inst_tree_inl0_pub1_norelcfuncs.pl b/test_regress/t/t_inst_tree_inl0_pub1_norelcfuncs.pl index cc3e9ca48..fce7d84dc 100755 --- a/test_regress/t/t_inst_tree_inl0_pub1_norelcfuncs.pl +++ b/test_regress/t/t_inst_tree_inl0_pub1_norelcfuncs.pl @@ -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()] ); diff --git a/test_regress/t/t_inst_tree_inl1_pub0.pl b/test_regress/t/t_inst_tree_inl1_pub0.pl index fe266c45e..c30155c2b 100755 --- a/test_regress/t/t_inst_tree_inl1_pub0.pl +++ b/test_regress/t/t_inst_tree_inl1_pub0.pl @@ -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/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); +} + execute( check_finished => 1, expect => diff --git a/test_regress/t/t_inst_tree_inl1_pub0.vlt b/test_regress/t/t_inst_tree_inl1_pub0.vlt new file mode 100644 index 000000000..177a14d24 --- /dev/null +++ b/test_regress/t/t_inst_tree_inl1_pub0.vlt @@ -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*" diff --git a/test_regress/t/t_inst_tree_inl1_pub1.pl b/test_regress/t/t_inst_tree_inl1_pub1.pl index 6c9349d72..abd93f9a5 100755 --- a/test_regress/t/t_inst_tree_inl1_pub1.pl +++ b/test_regress/t/t_inst_tree_inl1_pub1.pl @@ -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/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); +} + execute( check_finished => 1, expect => diff --git a/test_regress/t/t_inst_tree_inl1_pub1.vlt b/test_regress/t/t_inst_tree_inl1_pub1.vlt new file mode 100644 index 000000000..8d917e7d4 --- /dev/null +++ b/test_regress/t/t_inst_tree_inl1_pub1.vlt @@ -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*" diff --git a/test_regress/t/t_trace_public.v b/test_regress/t/t_trace_public.v index 1f848a876..06080d229 100644 --- a/test_regress/t/t_trace_public.v +++ b/test_regress/t/t_trace_public.v @@ -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 diff --git a/test_regress/t/t_trace_public_func.cpp b/test_regress/t/t_trace_public_func.cpp index cf5606ed5..d5e055111 100644 --- a/test_regress/t/t_trace_public_func.cpp +++ b/test_regress/t/t_trace_public_func.cpp @@ -8,9 +8,14 @@ #include #include -#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); diff --git a/test_regress/t/t_trace_public_func.pl b/test_regress/t/t_trace_public_func.pl index a8fa99330..1a9d8c57a 100755 --- a/test_regress/t/t_trace_public_func.pl +++ b/test_regress/t/t_trace_public_func.pl @@ -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( diff --git a/test_regress/t/t_trace_public_func.vlt b/test_regress/t/t_trace_public_func.vlt new file mode 100644 index 000000000..15b96feeb --- /dev/null +++ b/test_regress/t/t_trace_public_func.vlt @@ -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" diff --git a/test_regress/t/t_trace_public_func_vlt.pl b/test_regress/t/t_trace_public_func_vlt.pl new file mode 100755 index 000000000..a7f553931 --- /dev/null +++ b/test_regress/t/t_trace_public_func_vlt.pl @@ -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; diff --git a/test_regress/t/t_trace_public_sig.cpp b/test_regress/t/t_trace_public_sig.cpp index 457c76560..983a5449a 100644 --- a/test_regress/t/t_trace_public_sig.cpp +++ b/test_regress/t/t_trace_public_sig.cpp @@ -8,9 +8,14 @@ #include #include -#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); diff --git a/test_regress/t/t_trace_public_sig.pl b/test_regress/t/t_trace_public_sig.pl index 7d69b207c..f06a83b83 100755 --- a/test_regress/t/t_trace_public_sig.pl +++ b/test_regress/t/t_trace_public_sig.pl @@ -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( diff --git a/test_regress/t/t_trace_public_sig.vlt b/test_regress/t/t_trace_public_sig.vlt new file mode 100644 index 000000000..ec8647b5d --- /dev/null +++ b/test_regress/t/t_trace_public_sig.vlt @@ -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" diff --git a/test_regress/t/t_trace_public_sig_vlt.pl b/test_regress/t/t_trace_public_sig_vlt.pl new file mode 100755 index 000000000..68c888339 --- /dev/null +++ b/test_regress/t/t_trace_public_sig_vlt.pl @@ -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/\/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; diff --git a/test_regress/t/t_unopt_combo.v b/test_regress/t/t_unopt_combo.v index f923d97e7..8e74883f2 100644 --- a/test_regress/t/t_unopt_combo.v +++ b/test_regress/t/t_unopt_combo.v @@ -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 diff --git a/test_regress/t/t_unopt_combo_bad.out b/test_regress/t/t_unopt_combo_bad.out index 67138f1b5..6c675c42b 100644 --- a/test_regress/t/t_unopt_combo_bad.out +++ b/test_regress/t/t_unopt_combo_bad.out @@ -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 diff --git a/test_regress/t/t_unopt_combo_bad.pl b/test_regress/t/t_unopt_combo_bad.pl index 6ba52ae7a..81bf42fa9 100755 --- a/test_regress/t/t_unopt_combo_bad.pl +++ b/test_regress/t/t_unopt_combo_bad.pl @@ -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}, ); diff --git a/test_regress/t/t_unopt_combo_isolate.pl b/test_regress/t/t_unopt_combo_isolate.pl index 1e27afc3d..d43183607 100755 --- a/test_regress/t/t_unopt_combo_isolate.pl +++ b/test_regress/t/t_unopt_combo_isolate.pl @@ -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/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); } execute( diff --git a/test_regress/t/t_unopt_combo_isolate.vlt b/test_regress/t/t_unopt_combo_isolate.vlt new file mode 100644 index 000000000..44546c5a9 --- /dev/null +++ b/test_regress/t/t_unopt_combo_isolate.vlt @@ -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" diff --git a/test_regress/t/t_unopt_combo_isolate_vlt.pl b/test_regress/t/t_unopt_combo_isolate_vlt.pl new file mode 100755 index 000000000..855ac8b0e --- /dev/null +++ b/test_regress/t/t_unopt_combo_isolate_vlt.pl @@ -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/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); + file_grep("$out_filename", qr/\/i); +} + +execute( + ); + +ok(1); +1; diff --git a/test_regress/t/t_var_pins_sc1.pl b/test_regress/t/t_var_pins_sc1.pl index c635d6614..3a41be17d 100755 --- a/test_regress/t/t_var_pins_sc1.pl +++ b/test_regress/t/t_var_pins_sc1.pl @@ -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\s> \s+ i65;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1_vlt;/x); + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16_vlt;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o1;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o8;/x); @@ -34,6 +36,8 @@ if ($Self->{vlt_all}) { file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1_vlt;/x); + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16_vlt;/x); } execute(); diff --git a/test_regress/t/t_var_pins_sc2.pl b/test_regress/t/t_var_pins_sc2.pl index e6b123d1f..2d1d53916 100755 --- a/test_regress/t/t_var_pins_sc2.pl +++ b/test_regress/t/t_var_pins_sc2.pl @@ -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\s> \s+ i65;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1_vlt;/x); + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16_vlt;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o1;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o8;/x); @@ -34,6 +36,8 @@ compile( file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1_vlt;/x); + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16_vlt;/x); } execute(); diff --git a/test_regress/t/t_var_pins_sc32.pl b/test_regress/t/t_var_pins_sc32.pl index 5d8bb92d0..800adf220 100755 --- a/test_regress/t/t_var_pins_sc32.pl +++ b/test_regress/t/t_var_pins_sc32.pl @@ -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\s> \s+ i65;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1_vlt;/x); + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16_vlt;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o1;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o8;/x); @@ -34,6 +36,8 @@ compile( file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1_vlt;/x); + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16_vlt;/x); } execute(); diff --git a/test_regress/t/t_var_pins_sc64.pl b/test_regress/t/t_var_pins_sc64.pl index c7fa7c26d..0182586e2 100755 --- a/test_regress/t/t_var_pins_sc64.pl +++ b/test_regress/t/t_var_pins_sc64.pl @@ -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\s> \s+ i65;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1_vlt;/x); + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16_vlt;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o1;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o8;/x); @@ -34,6 +36,8 @@ if ($Self->{vlt_all}) { file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1_vlt;/x); + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16_vlt;/x); } execute(); diff --git a/test_regress/t/t_var_pinsizes.v b/test_regress/t/t_var_pinsizes.v index 1ed04a606..e8e47533f 100644 --- a/test_regress/t/t_var_pinsizes.v +++ b/test_regress/t/t_var_pinsizes.v @@ -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 diff --git a/test_regress/t/t_var_pinsizes.vlt b/test_regress/t/t_var_pinsizes.vlt new file mode 100644 index 000000000..7febde1d9 --- /dev/null +++ b/test_regress/t/t_var_pinsizes.vlt @@ -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" diff --git a/test_regress/t/t_vlt_syntax_bad.out b/test_regress/t/t_vlt_syntax_bad.out new file mode 100644 index 000000000..a33d90118 --- /dev/null +++ b/test_regress/t/t_vlt_syntax_bad.out @@ -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 diff --git a/test_regress/t/t_vlt_syntax_bad.pl b/test_regress/t/t_vlt_syntax_bad.pl new file mode 100755 index 000000000..b53b7da4d --- /dev/null +++ b/test_regress/t/t_vlt_syntax_bad.pl @@ -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; diff --git a/test_regress/t/t_vlt_syntax_bad.v b/test_regress/t/t_vlt_syntax_bad.v new file mode 100644 index 000000000..6370f0978 --- /dev/null +++ b/test_regress/t/t_vlt_syntax_bad.v @@ -0,0 +1,2 @@ +module t; +endmodule diff --git a/test_regress/t/t_vlt_syntax_bad.vlt b/test_regress/t/t_vlt_syntax_bad.vlt new file mode 100644 index 000000000..51140ca01 --- /dev/null +++ b/test_regress/t/t_vlt_syntax_bad.vlt @@ -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" diff --git a/test_regress/t/t_vlt_warn.pl b/test_regress/t/t_vlt_warn.pl index f363c7cbe..078632d69 100755 --- a/test_regress/t/t_vlt_warn.pl +++ b/test_regress/t/t_vlt_warn.pl @@ -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); diff --git a/test_regress/t/t_vlt_warn.vlt b/test_regress/t/t_vlt_warn.vlt index 4e94fb4cb..3aaac32bb 100644 --- a/test_regress/t/t_vlt_warn.vlt +++ b/test_regress/t/t_vlt_warn.vlt @@ -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