Commentary

This commit is contained in:
Wilson Snyder 2022-03-30 20:17:59 -04:00
parent e02f97854c
commit 33105f017c
34 changed files with 60 additions and 60 deletions

View File

@ -73,7 +73,7 @@ for you.
Performance Performance
=========== ===========
Verilator does not simply convert Verilog HDL to C++ or SystemC. Rather, Verilator does not directly translate Verilog HDL to C++ or SystemC. Rather,
Verilator compiles your code into a much faster optimized and optionally Verilator compiles your code into a much faster optimized and optionally
thread-partitioned model, which is in turn wrapped inside a C++/SystemC thread-partitioned model, which is in turn wrapped inside a C++/SystemC
module. The results are a compiled Verilog model that executes even on a module. The results are a compiled Verilog model that executes even on a

View File

@ -200,7 +200,7 @@ DPI System Task/Functions
------------------------- -------------------------
Verilator extends the DPI format to allow using the same scheme to Verilator extends the DPI format to allow using the same scheme to
efficiently add system functions. Simply use a dollar-sign prefixed system efficiently add system functions. Use a dollar-sign prefixed system
function name for the import, but note it must be escaped. function name for the import, but note it must be escaped.
.. code-block:: sv .. code-block:: sv
@ -508,7 +508,7 @@ structure. If a ``VerilatedContext`` is not created prior to creating a
model, a default global one is created automatically. model, a default global one is created automatically.
The ``Verilated::`` methods, including the ``Verilated::commandArgs`` call The ``Verilated::`` methods, including the ``Verilated::commandArgs`` call
shown above, simply call VerilatedContext methods using the default global shown above, call VerilatedContext methods using the default global
VerilatedContext. (Technically they operate on the last one used by a VerilatedContext. (Technically they operate on the last one used by a
given thread.) If you are using multiple simulation contexts you should given thread.) If you are using multiple simulation contexts you should
not use the Verilated:: methods, and instead always use VerilatedContext not use the Verilated:: methods, and instead always use VerilatedContext

View File

@ -99,10 +99,10 @@ Summary:
.. option:: --bbox-sys .. option:: --bbox-sys
Black box any unknown $system task or function calls. System tasks will Black box any unknown $system task or function calls. System tasks will
simply become no-operations, and system functions will be replaced with become no-operations, and system functions will be replaced with unsized
unsized zero. Arguments to such functions will be parsed, but not zero. Arguments to such functions will be parsed, but not otherwise
otherwise checked. This prevents errors when linting in the presence of checked. This prevents errors when linting in the presence of company
company specific PLI calls. specific PLI calls.
Using this argument will likely cause incorrect simulation. Using this argument will likely cause incorrect simulation.

View File

@ -354,8 +354,8 @@ also use the "import DPI" SystemVerilog feature to call C code (see the
chapter above). There is also limited VPI access to public signals. chapter above). There is also limited VPI access to public signals.
If you want something more complex, since Verilator emits standard C++ If you want something more complex, since Verilator emits standard C++
code, you can simply write your own C++ routines that can access and modify code, you can write your own C++ routines that can access and modify signal
signal values without needing any PLI interface code, and call it with values without needing any PLI interface code, and call it with
$c("{any_c++_statement}"). $c("{any_c++_statement}").
See the :ref:`Connecting` section. See the :ref:`Connecting` section.
@ -482,7 +482,7 @@ by your code or you'll get strange results.
Should a module be in Verilog or SystemC? Should a module be in Verilog or SystemC?
""""""""""""""""""""""""""""""""""""""""" """""""""""""""""""""""""""""""""""""""""
Sometimes there is a block that just interconnects instances, and have a Sometimes there is a block that only interconnects instances, and have a
choice as to if you write it in Verilog or SystemC. Everything else being choice as to if you write it in Verilog or SystemC. Everything else being
equal, best performance is when Verilator sees all of the design. So, look equal, best performance is when Verilator sees all of the design. So, look
at the hierarchy of your design, labeling instances as to if they are at the hierarchy of your design, labeling instances as to if they are

View File

@ -92,7 +92,7 @@ appropriate code to detect failing cases at simulation runtime and print an
Verilator likewise also asserts any "unique" or "priority" SystemVerilog Verilator likewise also asserts any "unique" or "priority" SystemVerilog
keywords on case statement, as well as "unique" on if statements. However, keywords on case statement, as well as "unique" on if statements. However,
"priority if" is currently simply ignored. "priority if" is currently ignored.
.. _Language Limitations: .. _Language Limitations:
@ -174,9 +174,9 @@ Structures and Unions
--------------------- ---------------------
Presently Verilator only supports packed structs and packed unions. Rand Presently Verilator only supports packed structs and packed unions. Rand
and randc tags on members are simply ignored. All structures and unions and randc tags on members are ignored. All structures and unions are
are represented as a single vector, which means that generating one member represented as a single vector, which means that generating one member of a
of a structure from blocking, and another from non-blocking assignments is structure from blocking, and another from non-blocking assignments is
unsupported. unsupported.

View File

@ -433,8 +433,8 @@ directly without any prefix.
If results from multiple simulations are to be used in generating the If results from multiple simulations are to be used in generating the
optimization, multiple simulation's profile.vlt may be concatenated optimization, multiple simulation's profile.vlt may be concatenated
externally, or each of the files may be fed as separate command line externally, or each of the files may be fed as separate command line
options into Verilator. Verilator will simply sum the profile results, so options into Verilator. Verilator will sum the profile results, so a
a longer running test will have proportionally more weight for optimization longer running test will have proportionally more weight for optimization
than a shorter running test. than a shorter running test.
If you provide any profile feedback data to Verilator, and it cannot use If you provide any profile feedback data to Verilator, and it cannot use

View File

@ -12,7 +12,7 @@ Disabling Warnings
Warnings may be disabled in multiple ways: Warnings may be disabled in multiple ways:
#. Disable the warning in the source code. When the warning is printed it #. Disable the warning in the source code. When the warning is printed it
will include a warning code. Simply surround the offending line with a will include a warning code. Surround the offending line with a
:code:`/*verilator&32;lint_off*/` and :code:`/*verilator&32;lint_on*/` :code:`/*verilator&32;lint_off*/` and :code:`/*verilator&32;lint_on*/`
metacomment pair: metacomment pair:
@ -162,7 +162,7 @@ List Of Warnings
always @(posedge clk) foo[0] <= ... always @(posedge clk) foo[0] <= ...
always_comb foo[1] = ... always_comb foo[1] = ...
Simply use a different register for the flop: Instead use a different register for the flop:
.. code-block:: sv .. code-block:: sv
@ -284,7 +284,7 @@ List Of Warnings
.. TODO better example .. TODO better example
Warns that it is simply better style to use casez, and "?" in place of Warns that it is better style to use casez, and "?" in place of
"x"'s. See "x"'s. See
`http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_rev1_1.pdf `http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_rev1_1.pdf
<http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_rev1_1.pdf>`_ <http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_rev1_1.pdf>`_
@ -1212,10 +1212,10 @@ List Of Warnings
.. include:: ../../docs/gen/ex_STMTDLY_msg.rst .. include:: ../../docs/gen/ex_STMTDLY_msg.rst
This is a warning because Verilator does not support delayed statements. This is a warning because Verilator does not support delayed statements.
It will simply ignore all such delays. In many cases ignoring a delay It will ignore all such delays. In many cases ignoring a delay might be
might be harmless, but if the delayed statement is, as in this example, harmless, but if the delayed statement is, as in this example, used to
used to cause some important action at a later time, it might be an cause some important action at a later time, it might be an important
important difference. difference.
Some possible workarounds: Some possible workarounds:

View File

@ -268,11 +268,11 @@ Estimating Logic Costs
To compute the cost of any given path through the graph, Verilator To compute the cost of any given path through the graph, Verilator
estimates an execution cost for each task. Each macro-task has an execution estimates an execution cost for each task. Each macro-task has an execution
cost which is simply the sum of its tasks' costs. We assume that cost which is the sum of its tasks' costs. We assume that communication
communication overhead and synchronization overhead are zero, so the cost overhead and synchronization overhead are zero, so the cost of any given
of any given path through the graph is simply the sum of macro-task path through the graph is the sum of macro-task execution costs. Sarkar
execution costs. Sarkar does almost the same thing, except that he has does almost the same thing, except that he has nonzero estimates for
nonzero estimates for synchronization costs. synchronization costs.
Verilator's cost estimates are assigned by ``InstrCountCostVisitor``. This Verilator's cost estimates are assigned by ``InstrCountCostVisitor``. This
class is perhaps the most fragile piece of the multithread class is perhaps the most fragile piece of the multithread
@ -817,7 +817,7 @@ which you can install using cpan.
There are some traps to avoid when running regression tests There are some traps to avoid when running regression tests
- When checking the MANIFEST, the test will barf on unexpected code in the - When checking the MANIFEST, the test will fail on unexpected code in the
Verilator tree. So make sure to keep any such code outside the tree. Verilator tree. So make sure to keep any such code outside the tree.
- Not all Linux systems install Perldoc by default. This is needed for the - Not all Linux systems install Perldoc by default. This is needed for the
@ -1186,7 +1186,7 @@ anticipated to be ever implemented for the reasons indicated.
IEEE 1800-2017 3.3 modules within modules IEEE 1800-2017 3.3 modules within modules
Little/no tool support, and arguably not a good practice. Little/no tool support, and arguably not a good practice.
IEEE 1800-2017 6.12 "shortreal" IEEE 1800-2017 6.12 "shortreal"
Little/no tool support, and easily simply promoted to real. Little/no tool support, and easily promoted to real.
IEEE 1800-2017 11.11 Min, typ, max IEEE 1800-2017 11.11 Min, typ, max
No SDF support so will always use typical. No SDF support so will always use typical.
IEEE 1800-2017 11.12 "let" IEEE 1800-2017 11.12 "let"

View File

@ -69,7 +69,7 @@ int main(int argc, char** argv, char** env) {
// Historical note, before Verilator 4.200 Verilated::gotFinish() // Historical note, before Verilator 4.200 Verilated::gotFinish()
// was used above in place of contextp->gotFinish(). // was used above in place of contextp->gotFinish().
// Most of the contextp-> calls can use Verilated:: calls instead; // Most of the contextp-> calls can use Verilated:: calls instead;
// the Verilated:: versions simply assume there's a single context // the Verilated:: versions just assume there's a single context
// being used (per thread). It's faster and clearer to use the // being used (per thread). It's faster and clearer to use the
// newer contextp-> versions. // newer contextp-> versions.

View File

@ -1678,7 +1678,7 @@ IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rwp) VL_M
VL_SET_WQ(rwp, VL_CVT_Q_D(temp)); VL_SET_WQ(rwp, VL_CVT_Q_D(temp));
break; break;
} }
default: // Other simulators simply return 0 in these cases and don't error out default: // Other simulators return 0 in these cases and don't error out
return 0; return 0;
} }
_vl_clean_inplace_w(rbits, rwp); _vl_clean_inplace_w(rbits, rwp);

View File

@ -417,7 +417,7 @@ static void _vl_svPutBitArrElem(const svOpenArrayHandle d, svBit value, int narg
} }
//====================================================================== //======================================================================
// DPI accessors that simply call above functions // DPI accessors that call above functions
void* svGetArrElemPtr(const svOpenArrayHandle h, int indx1, ...) { void* svGetArrElemPtr(const svOpenArrayHandle h, int indx1, ...) {
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(h); const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(h);

View File

@ -489,7 +489,7 @@ public:
public: // But only for verilated.cpp public: // But only for verilated.cpp
// Symbol table destruction cleans up the entries for each scope. // Symbol table destruction cleans up the entries for each scope.
static void userEraseScope(const VerilatedScope* scopep) VL_MT_SAFE { static void userEraseScope(const VerilatedScope* scopep) VL_MT_SAFE {
// Slow ok - called once/scope on destruction, so we simply iterate. // Slow ok - called once/scope on destruction, so we only iterate.
const VerilatedLockGuard lock{s().m_userMapMutex}; const VerilatedLockGuard lock{s().m_userMapMutex};
for (auto it = s().m_userMap.begin(); it != s().m_userMap.end();) { for (auto it = s().m_userMap.begin(); it != s().m_userMap.end();) {
if (it->first.first == scopep) { if (it->first.first == scopep) {

View File

@ -610,7 +610,7 @@ def getGcovCoverage(args):
coverage_files = getFilteredCoverageFiles(coverage_files, args.excludepre) coverage_files = getFilteredCoverageFiles(coverage_files, args.excludepre)
logging.info("Found {} coverage files after filtering".format(len(coverage_files))) logging.info("Found {} coverage files after filtering".format(len(coverage_files)))
# We "zero" the "counters" by simply deleting all gcda files # We "zero" the "counters" by deleting all gcda files
if args.zerocounters: if args.zerocounters:
removeFiles(coverage_files) removeFiles(coverage_files)
logging.info("Removed {} .gcda files".format(len(coverage_files))) logging.info("Removed {} .gcda files".format(len(coverage_files)))

View File

@ -262,7 +262,7 @@ private:
if (itemp->isDefault()) has_default = true; if (itemp->isDefault()) has_default = true;
} }
if (nodep->fullPragma() || nodep->priorityPragma()) { if (nodep->fullPragma() || nodep->priorityPragma()) {
// Simply need to add a default if there isn't one already // Need to add a default if there isn't one already
++m_statAsFull; ++m_statAsFull;
if (!has_default) { if (!has_default) {
nodep->addItemsp(new AstCaseItem( nodep->addItemsp(new AstCaseItem(

View File

@ -2562,7 +2562,7 @@ private:
string m_text; string m_text;
protected: protected:
// Node that simply puts text into the output stream // Node that puts text into the output stream
AstNodeText(VNType t, FileLine* fl, const string& textp) AstNodeText(VNType t, FileLine* fl, const string& textp)
: AstNode{t, fl} { : AstNode{t, fl} {
m_text = textp; // Copy it m_text = textp; // Copy it

View File

@ -4927,7 +4927,7 @@ private:
bool m_generate; // Underneath a generate bool m_generate; // Underneath a generate
const bool m_implied; // Not inserted by user const bool m_implied; // Not inserted by user
public: public:
// Node that simply puts name into the output stream // Node that puts name into the output stream
AstBegin(FileLine* fl, const string& name, AstNode* stmtsp, bool generate = false, AstBegin(FileLine* fl, const string& name, AstNode* stmtsp, bool generate = false,
bool implied = false) bool implied = false)
: ASTGEN_SUPER_Begin(fl, name, stmtsp) : ASTGEN_SUPER_Begin(fl, name, stmtsp)
@ -4951,7 +4951,7 @@ class AstFork final : public AstNodeBlock {
private: private:
VJoinType m_joinType; // Join keyword type VJoinType m_joinType; // Join keyword type
public: public:
// Node that simply puts name into the output stream // Node that puts name into the output stream
AstFork(FileLine* fl, const string& name, AstNode* stmtsp) AstFork(FileLine* fl, const string& name, AstNode* stmtsp)
: ASTGEN_SUPER_Fork(fl, name, stmtsp) {} : ASTGEN_SUPER_Fork(fl, name, stmtsp) {}
ASTNODE_NODE_FUNCS(Fork) ASTNODE_NODE_FUNCS(Fork)

View File

@ -117,7 +117,7 @@ public:
}; };
// User pointer allocator classes. T_Node is the type of node the allocator should be applied to // User pointer allocator classes. T_Node is the type of node the allocator should be applied to
// and is simply there for a bit of extra type safety. T_Data is the type of the data structure // and is there for a bit of extra type safety. T_Data is the type of the data structure
// managed by the allocator. // managed by the allocator.
template <class T_Node, class T_Data> template <class T_Node, class T_Data>
class AstUser1Allocator final : public AstUserAllocatorBase<T_Node, T_Data, 1> {}; class AstUser1Allocator final : public AstUserAllocatorBase<T_Node, T_Data, 1> {};

View File

@ -384,7 +384,7 @@ private:
VL_DANGLING(iconstp); VL_DANGLING(iconstp);
condp = AstEq::newTyped(itemp->fileline(), and1p, and2p); condp = AstEq::newTyped(itemp->fileline(), and1p, and2p);
} else { } else {
// Not a caseX mask, we can simply build CASEEQ(cexpr icond) // Not a caseX mask, we can build CASEEQ(cexpr icond)
AstNode* const and1p = cexprp->cloneTree(false); AstNode* const and1p = cexprp->cloneTree(false);
AstNode* const and2p = icondp; AstNode* const and2p = icondp;
condp = AstEq::newTyped(itemp->fileline(), and1p, and2p); condp = AstEq::newTyped(itemp->fileline(), and1p, and2p);

View File

@ -2658,7 +2658,7 @@ private:
// SENTREE(... SENITEM(x), SENGATE(SENITEM(x),*) ...) => SENITEM(x) // SENTREE(... SENITEM(x), SENGATE(SENITEM(x),*) ...) => SENITEM(x)
// Do we need the SENITEM's to be identical? No because we're // Do we need the SENITEM's to be identical? No because we're
// ORing between them; we just need to ensure that the result is at // ORing between them; we just need to ensure that the result is at
// least as frequently activating. So we simply // least as frequently activating. So we
// SENGATE(SENITEM(x)) -> SENITEM(x), then let it collapse with the // SENGATE(SENITEM(x)) -> SENITEM(x), then let it collapse with the
// other SENITEM(x). // other SENITEM(x).
{ {

View File

@ -176,7 +176,7 @@ private:
// newfuncp->addStmtsp(new AstStop(newfuncp->fileline())); // newfuncp->addStmtsp(new AstStop(newfuncp->fileline()));
if (debug() >= 9) newfuncp->dumpTree(cout, " newfunc: "); if (debug() >= 9) newfuncp->dumpTree(cout, " newfunc: ");
} else { } else {
// Only a single function under this name, we can simply rename it // Only a single function under this name, we can rename it
UINFO(6, " Wrapping " << name << " just one " << topFuncp << endl); UINFO(6, " Wrapping " << name << " just one " << topFuncp << endl);
topFuncp->name(name); topFuncp->name(name);
} }

View File

@ -1137,7 +1137,7 @@ public:
} else if (nodep->isWide()) { } else if (nodep->isWide()) {
UASSERT_OBJ(m_wideTempRefp, nodep, "Wide Constant w/ no temp"); UASSERT_OBJ(m_wideTempRefp, nodep, "Wide Constant w/ no temp");
emitConstant(nodep, m_wideTempRefp, ""); emitConstant(nodep, m_wideTempRefp, "");
m_wideTempRefp = nullptr; // We used it, barf if set it a second time m_wideTempRefp = nullptr; // We used it, fail if set it a second time
} else { } else {
emitConstant(nodep, nullptr, ""); emitConstant(nodep, nullptr, "");
} }

View File

@ -178,7 +178,7 @@ public:
} }
} }
void varUsageReplace(AstVarScope* nodep, AstVarRef* varrefp) { void varUsageReplace(AstVarScope* nodep, AstVarRef* varrefp) {
// Variable rvalue. If it references a constant, we can simply replace it // Variable rvalue. If it references a constant, we can replace it
const auto it = m_map.find(nodep); const auto it = m_map.find(nodep);
if (it != m_map.end()) { if (it != m_map.end()) {
if (AstConst* const constp = it->second.constNodep()) { if (AstConst* const constp = it->second.constNodep()) {

View File

@ -259,7 +259,7 @@ public:
// table's import wouldn't warn // table's import wouldn't warn
} else if (VN_IS(nodep, Begin) && VN_IS(fnodep, Begin) } else if (VN_IS(nodep, Begin) && VN_IS(fnodep, Begin)
&& VN_AS(nodep, Begin)->generate()) { && VN_AS(nodep, Begin)->generate()) {
// Begin: ... blocks often replicate under genif/genfor, so simply // Begin: ... blocks often replicate under genif/genfor, so
// suppress duplicate checks. See t_gen_forif.v for an example. // suppress duplicate checks. See t_gen_forif.v for an example.
} else { } else {
UINFO(4, "name " << name << endl); // Not always same as nodep->name UINFO(4, "name " << name << endl); // Not always same as nodep->name

View File

@ -344,7 +344,7 @@ private:
return true; return true;
} }
} }
// Is it simply 'lhs = cond'? // Is it 'lhs = cond'?
if (assignp->rhsp()->sameTree(m_mgCondp)) return true; if (assignp->rhsp()->sameTree(m_mgCondp)) return true;
} }
} }

View File

@ -698,7 +698,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
// To get the number of digits required, we want to compute // To get the number of digits required, we want to compute
// log10(2**mantissabits) and round it up. To be able to handle // log10(2**mantissabits) and round it up. To be able to handle
// a very wide mantissa, we use log2(2**mantissabits)/log2(10), // a very wide mantissa, we use log2(2**mantissabits)/log2(10),
// which is simply (+1.0 is for rounding bias): // which is (+1.0 is for rounding bias):
double dchars = mantissabits / 3.321928094887362 + 1.0; double dchars = mantissabits / 3.321928094887362 + 1.0;
if (issigned) dchars++; // space for sign if (issigned) dchars++; // space for sign
fmtsize = cvtToStr(int(dchars)); fmtsize = cvtToStr(int(dchars));

View File

@ -138,7 +138,7 @@ private:
} }
// Copy blocks into this scope // Copy blocks into this scope
// If this is the first usage of the block ever, we can simply move the reference // If this is the first usage of the block ever, we can move the reference
iterateChildren(nodep); iterateChildren(nodep);
// ***Note m_scopep is passed back to the caller of the routine (above) // ***Note m_scopep is passed back to the caller of the routine (above)

View File

@ -70,7 +70,7 @@ class SimulateVisitor VL_NOT_FINAL : public VNVisitor {
// Test the tree to see if it is conformant // Test the tree to see if it is conformant
// Given a set of input values, find the output values // Given a set of input values, find the output values
// Both are done in this same visitor to reduce risk; if a visitor // Both are done in this same visitor to reduce risk; if a visitor
// is missing, we will simply not apply the optimization, rather then bomb. // is missing, we will not apply the optimization, rather then bomb.
private: private:
// NODE STATE // NODE STATE

View File

@ -142,7 +142,7 @@ private:
struct EdgeListCmp final { struct EdgeListCmp final {
bool operator()(const EdgeList* ap, const EdgeList* bp) const { bool operator()(const EdgeList* ap, const EdgeList* bp) const {
// Simply compare heads // Compare heads
return edgeCmp(bp->back(), ap->back()); return edgeCmp(bp->back(), ap->back());
} }
}; };

View File

@ -1281,7 +1281,7 @@ private:
varScopep->user5(true); // Mark as already added varScopep->user5(true); // Mark as already added
// Note: We are ignoring function locals as they should not be referenced // Note: We are ignoring function locals as they should not be referenced
// anywhere outside of the enclosing AstCFunc, and therefore they are // anywhere outside of the enclosing AstCFunc, and therefore they are
// irrelevant for code ordering. This is simply an optimization to avoid adding // irrelevant for code ordering. This is an optimization to avoid adding
// useless nodes to the ordering graph in V3Order. // useless nodes to the ordering graph in V3Order.
if (varScopep->varp()->isFuncLocal()) return; if (varScopep->varp()->isFuncLocal()) return;
writtenps.push_back(varScopep); writtenps.push_back(varScopep);
@ -1426,7 +1426,7 @@ private:
"Ignoring return value of non-void function (IEEE 1800-2017 13.4.1)"); "Ignoring return value of non-void function (IEEE 1800-2017 13.4.1)");
} }
// outvscp maybe non-nullptr if calling a function in a taskref, // outvscp maybe non-nullptr if calling a function in a taskref,
// but if so we want to simply ignore the function result // but if so we want to ignore the function result
nodep->replaceWith(beginp); nodep->replaceWith(beginp);
} }
// Cleanup // Cleanup

View File

@ -188,7 +188,7 @@ private:
v3Global.rootp()->typeTablep()->addTypesp(nodep); v3Global.rootp()->typeTablep()->addTypesp(nodep);
} }
void visitIterateNodeDType(AstNodeDType* nodep) { void visitIterateNodeDType(AstNodeDType* nodep) {
// Rather than use dtypeChg which may make new nodes, we simply edit in place, // Rather than use dtypeChg which may make new nodes, we edit in place,
// as we don't need to preserve any widthMin's, and every dtype with the same width // as we don't need to preserve any widthMin's, and every dtype with the same width
// gets an identical edit. // gets an identical edit.
if (nodep->user1SetOnce()) return; // Process once if (nodep->user1SetOnce()) return; // Process once

View File

@ -1303,7 +1303,7 @@ port<nodep>: // ==IEEE: port
// // data_declarationVarFront // // data_declarationVarFront
// //
// // Though not type for interfaces, we factor out the port direction and type // // Though not type for interfaces, we factor out the port direction and type
// // so we can simply handle it in one place // // so we can handle it in one place
// //
// // IEEE: interface_port_header port_identifier { unpacked_dimension } // // IEEE: interface_port_header port_identifier { unpacked_dimension }
// // Expanded interface_port_header // // Expanded interface_port_header
@ -5525,7 +5525,7 @@ pexpr<nodep>: // IEEE: property_expr (The name pexpr is important as regexps j
//UNSUP // // IEEE: '(' sexpr {',' sequence_match_item } ')' [ sequence_abbrev ] //UNSUP // // IEEE: '(' sexpr {',' sequence_match_item } ')' [ sequence_abbrev ]
//UNSUP // // As sequence_expr includes expression_or_dist, and boolean_abbrev includes sequence_abbrev: //UNSUP // // As sequence_expr includes expression_or_dist, and boolean_abbrev includes sequence_abbrev:
//UNSUP // // '(' sequence_expr {',' sequence_match_item } ')' [ boolean_abbrev ] //UNSUP // // '(' sequence_expr {',' sequence_match_item } ')' [ boolean_abbrev ]
//UNSUP // // "'(' sexpr ')' boolean_abbrev" matches "[sexpr:'(' expr ')'] boolean_abbrev" so we can simply drop it //UNSUP // // "'(' sexpr ')' boolean_abbrev" matches "[sexpr:'(' expr ')'] boolean_abbrev" so we can drop it
//UNSUP | '(' ~p~sexpr ')' { $<fl>$ = $<fl>1; $$ = ...; } //UNSUP | '(' ~p~sexpr ')' { $<fl>$ = $<fl>1; $$ = ...; }
//UNSUP | '(' ~p~sexpr ',' sequence_match_itemList ')' { } //UNSUP | '(' ~p~sexpr ',' sequence_match_itemList ')' { }
//UNSUP // //UNSUP //

View File

@ -201,7 +201,7 @@ int main() {
logReg(dut->clk, "read c", c, " (after clk)"); logReg(dut->clk, "read c", c, " (after clk)");
// "c" is continuously assigned as the inverse of "a", but in // "c" is continuously assigned as the inverse of "a", but in
// Verilator, that means that it will only change value when "a" // Verilator, that means that it will only change value when "a"
// changes on the posedge of a clock. Put simply, "c" always holds the // changes on the posedge of a clock. That is "c" always holds the
// inverse of the "after clock" value of "a". // inverse of the "after clock" value of "a".
checkResult(c == (1 - a), "Test of scalar wire reading failed."); checkResult(c == (1 - a), "Test of scalar wire reading failed.");
} }
@ -231,7 +231,7 @@ int main() {
// "d" is continuously assigned as the (8-bit) bitwise inverse of "b", // "d" is continuously assigned as the (8-bit) bitwise inverse of "b",
// but in Verilator, that means that it will only change value when // but in Verilator, that means that it will only change value when
// "b" changes on the posedge of a clock. Put simply, "d" always holds // "b" changes on the posedge of a clock. That is "d" always holds
// the inverse of the "after clock" value of "b". // the inverse of the "after clock" value of "b".
checkResult(d == ((~b) & 0xff), "Test of vector wire reading failed."); checkResult(d == ((~b) & 0xff), "Test of vector wire reading failed.");
} }

View File

@ -16,7 +16,7 @@ module testbench;
endfunction; endfunction;
// Downstream signal dependent on clk demonstrates scheduling issue. // Downstream signal dependent on clk demonstrates scheduling issue.
// The '$c("1") &' simply ensures that dependent_clk does not get // The '$c("1") &' ensures that dependent_clk does not get
// replaced with clk early and hence hiding the issue // replaced with clk early and hence hiding the issue
wire dependent_clk = $c1("1") & clk; wire dependent_clk = $c1("1") & clk;

View File

@ -13,7 +13,7 @@ scenarios(vlt => 1);
top_filename("$Self->{obj_dir}/$Self->{name}.v"); top_filename("$Self->{obj_dir}/$Self->{name}.v");
golden_filename("$Self->{obj_dir}/$Self->{name}.out"); golden_filename("$Self->{obj_dir}/$Self->{name}.out");
# Rather then having to maintain a new .v and .out, simply add returns # Rather then having to maintain a new .v and .out, add returns
# to all lines of the existing t_preproc test. # to all lines of the existing t_preproc test.
{ {