Commentary: Fix non-grammar
This commit is contained in:
parent
be429ce956
commit
d87035d187
|
|
@ -149,7 +149,7 @@ if ($opt_gdb) {
|
||||||
. verilator_bin()
|
. verilator_bin()
|
||||||
. " " . join(' ', @quoted_sw));
|
. " " . join(' ', @quoted_sw));
|
||||||
} else {
|
} else {
|
||||||
# Normal, non gdb
|
# Normal, non-gdb
|
||||||
run(ulimit_stack_unlimited() . aslr(1) . verilator_bin() . " " . join(' ', @quoted_sw));
|
run(ulimit_stack_unlimited() . aslr(1) . verilator_bin() . " " . join(' ', @quoted_sw));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ if (! GetOptions (
|
||||||
pod2usage(-exitstatus => 2, -verbose => 0);
|
pod2usage(-exitstatus => 2, -verbose => 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Normal, non gdb
|
# Normal, non-gdb
|
||||||
run(verilator_coverage_bin()
|
run(verilator_coverage_bin()
|
||||||
. " " . join(' ', @Opt_Verilator_Sw));
|
. " " . join(' ', @Opt_Verilator_Sw));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1249,10 +1249,10 @@ void AstNode::checkTreeIter(const AstNode* prevBackp) const VL_MT_STABLE {
|
||||||
break;
|
break;
|
||||||
case VNTypeInfo::OP_USED:
|
case VNTypeInfo::OP_USED:
|
||||||
UASSERT_OBJ(nodep, this,
|
UASSERT_OBJ(nodep, this,
|
||||||
typeInfo.m_namep << " must have non nullptr " << opName << "()");
|
typeInfo.m_namep << " must have non-nullptr " << opName << "()");
|
||||||
UASSERT_OBJ(!nodep->nextp(), this,
|
UASSERT_OBJ(!nodep->nextp(), this,
|
||||||
typeInfo.m_namep << "::" << opName
|
typeInfo.m_namep << "::" << opName
|
||||||
<< "() cannot have a non nullptr nextp()");
|
<< "() cannot have a non-nullptr nextp()");
|
||||||
nodep->checkTreeIter(this);
|
nodep->checkTreeIter(this);
|
||||||
break;
|
break;
|
||||||
case VNTypeInfo::OP_LIST:
|
case VNTypeInfo::OP_LIST:
|
||||||
|
|
|
||||||
16
src/V3Ast.h
16
src/V3Ast.h
|
|
@ -932,7 +932,7 @@ public:
|
||||||
virtual bool isSame(const AstNode* samep) const {
|
virtual bool isSame(const AstNode* samep) const {
|
||||||
return type() == samep->type() && sameNode(samep);
|
return type() == samep->type() && sameNode(samep);
|
||||||
}
|
}
|
||||||
// Iff has a data type; dtype() must be non null
|
// Iff has a data type; dtype() must be non-null
|
||||||
virtual bool hasDType() const VL_MT_SAFE { return false; }
|
virtual bool hasDType() const VL_MT_SAFE { return false; }
|
||||||
// Iff has a non-null childDTypep(), as generic node function
|
// Iff has a non-null childDTypep(), as generic node function
|
||||||
virtual AstNodeDType* getChildDTypep() const { return nullptr; }
|
virtual AstNodeDType* getChildDTypep() const { return nullptr; }
|
||||||
|
|
@ -1005,7 +1005,7 @@ public:
|
||||||
// For use via the VN_IS macro only, or in templated code
|
// For use via the VN_IS macro only, or in templated code
|
||||||
template <typename T_TargetType, typename T_Node>
|
template <typename T_TargetType, typename T_Node>
|
||||||
static bool is(const T_Node* nodep) VL_MT_SAFE {
|
static bool is(const T_Node* nodep) VL_MT_SAFE {
|
||||||
static_assert(std::is_base_of<AstNode, T_Node>::value, "VN_IS called on non AstNode");
|
static_assert(std::is_base_of<AstNode, T_Node>::value, "VN_IS called on non-AstNode");
|
||||||
static_assert(!uselessCast<T_TargetType, T_Node>(),
|
static_assert(!uselessCast<T_TargetType, T_Node>(),
|
||||||
"Unnecessary VN_IS, node known to have target type.");
|
"Unnecessary VN_IS, node known to have target type.");
|
||||||
static_assert(!impossibleCast<T_TargetType, T_Node>(),
|
static_assert(!impossibleCast<T_TargetType, T_Node>(),
|
||||||
|
|
@ -1016,7 +1016,7 @@ public:
|
||||||
// For use via the VN_CAST macro only, or in templated code
|
// For use via the VN_CAST macro only, or in templated code
|
||||||
template <typename T_TargetType, typename T_Node>
|
template <typename T_TargetType, typename T_Node>
|
||||||
static T_TargetType* cast(T_Node* nodep) VL_MT_SAFE {
|
static T_TargetType* cast(T_Node* nodep) VL_MT_SAFE {
|
||||||
static_assert(std::is_base_of<AstNode, T_Node>::value, "VN_CAST called on non AstNode");
|
static_assert(std::is_base_of<AstNode, T_Node>::value, "VN_CAST called on non-AstNode");
|
||||||
static_assert(!uselessCast<T_TargetType, T_Node>(),
|
static_assert(!uselessCast<T_TargetType, T_Node>(),
|
||||||
"Unnecessary VN_CAST, node known to have target type.");
|
"Unnecessary VN_CAST, node known to have target type.");
|
||||||
static_assert(!impossibleCast<T_TargetType, T_Node>(),
|
static_assert(!impossibleCast<T_TargetType, T_Node>(),
|
||||||
|
|
@ -1027,7 +1027,7 @@ public:
|
||||||
}
|
}
|
||||||
template <typename T_TargetType, typename T_Node>
|
template <typename T_TargetType, typename T_Node>
|
||||||
static const T_TargetType* cast(const T_Node* nodep) VL_MT_SAFE {
|
static const T_TargetType* cast(const T_Node* nodep) VL_MT_SAFE {
|
||||||
static_assert(std::is_base_of<AstNode, T_Node>::value, "VN_CAST called on non AstNode");
|
static_assert(std::is_base_of<AstNode, T_Node>::value, "VN_CAST called on non-AstNode");
|
||||||
static_assert(!uselessCast<T_TargetType, T_Node>(),
|
static_assert(!uselessCast<T_TargetType, T_Node>(),
|
||||||
"Unnecessary VN_CAST, node known to have target type.");
|
"Unnecessary VN_CAST, node known to have target type.");
|
||||||
static_assert(!impossibleCast<T_TargetType, T_Node>(),
|
static_assert(!impossibleCast<T_TargetType, T_Node>(),
|
||||||
|
|
@ -1040,7 +1040,7 @@ public:
|
||||||
// For use via the VN_AS macro only, or in templated code
|
// For use via the VN_AS macro only, or in templated code
|
||||||
template <typename T_TargetType, typename T_Node>
|
template <typename T_TargetType, typename T_Node>
|
||||||
static T_TargetType* as(T_Node* nodep) VL_PURE {
|
static T_TargetType* as(T_Node* nodep) VL_PURE {
|
||||||
static_assert(std::is_base_of<AstNode, T_Node>::value, "VN_AS called on non AstNode");
|
static_assert(std::is_base_of<AstNode, T_Node>::value, "VN_AS called on non-AstNode");
|
||||||
static_assert(!uselessCast<T_TargetType, T_Node>(),
|
static_assert(!uselessCast<T_TargetType, T_Node>(),
|
||||||
"Unnecessary VN_AS, node known to have target type.");
|
"Unnecessary VN_AS, node known to have target type.");
|
||||||
static_assert(!impossibleCast<T_TargetType, T_Node>(),
|
static_assert(!impossibleCast<T_TargetType, T_Node>(),
|
||||||
|
|
@ -1052,7 +1052,7 @@ public:
|
||||||
}
|
}
|
||||||
template <typename T_TargetType, typename T_Node>
|
template <typename T_TargetType, typename T_Node>
|
||||||
static const T_TargetType* as(const T_Node* nodep) VL_PURE {
|
static const T_TargetType* as(const T_Node* nodep) VL_PURE {
|
||||||
static_assert(std::is_base_of<AstNode, T_Node>::value, "VN_AS called on non AstNode");
|
static_assert(std::is_base_of<AstNode, T_Node>::value, "VN_AS called on non-AstNode");
|
||||||
static_assert(!uselessCast<T_TargetType, T_Node>(),
|
static_assert(!uselessCast<T_TargetType, T_Node>(),
|
||||||
"Unnecessary VN_AS, node known to have target type.");
|
"Unnecessary VN_AS, node known to have target type.");
|
||||||
static_assert(!impossibleCast<T_TargetType, T_Node>(),
|
static_assert(!impossibleCast<T_TargetType, T_Node>(),
|
||||||
|
|
@ -1066,7 +1066,7 @@ public:
|
||||||
// For use via privateAs or the VN_DBG_AS macro only
|
// For use via privateAs or the VN_DBG_AS macro only
|
||||||
template <typename T_TargetType, typename T_Node>
|
template <typename T_TargetType, typename T_Node>
|
||||||
static T_TargetType* unsafePrivateAs(T_Node* nodep) VL_PURE {
|
static T_TargetType* unsafePrivateAs(T_Node* nodep) VL_PURE {
|
||||||
static_assert(std::is_base_of<AstNode, T_Node>::value, "VN_DBG_AS called on non AstNode");
|
static_assert(std::is_base_of<AstNode, T_Node>::value, "VN_DBG_AS called on non-AstNode");
|
||||||
static_assert(!uselessCast<T_TargetType, T_Node>(),
|
static_assert(!uselessCast<T_TargetType, T_Node>(),
|
||||||
"Unnecessary VN_DBG_AS, node known to have target type.");
|
"Unnecessary VN_DBG_AS, node known to have target type.");
|
||||||
static_assert(!impossibleCast<T_TargetType, T_Node>(),
|
static_assert(!impossibleCast<T_TargetType, T_Node>(),
|
||||||
|
|
@ -1075,7 +1075,7 @@ public:
|
||||||
}
|
}
|
||||||
template <typename T_TargetType, typename T_Node>
|
template <typename T_TargetType, typename T_Node>
|
||||||
static const T_TargetType* unsafePrivateAs(const T_Node* nodep) VL_PURE {
|
static const T_TargetType* unsafePrivateAs(const T_Node* nodep) VL_PURE {
|
||||||
static_assert(std::is_base_of<AstNode, T_Node>::value, "VN_DBG_AS called on non AstNode");
|
static_assert(std::is_base_of<AstNode, T_Node>::value, "VN_DBG_AS called on non-AstNode");
|
||||||
static_assert(!uselessCast<T_TargetType, T_Node>(),
|
static_assert(!uselessCast<T_TargetType, T_Node>(),
|
||||||
"Unnecessary VN_DBG_AS, node known to have target type.");
|
"Unnecessary VN_DBG_AS, node known to have target type.");
|
||||||
static_assert(!impossibleCast<T_TargetType, T_Node>(),
|
static_assert(!impossibleCast<T_TargetType, T_Node>(),
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ void AstBasicDType::init(VBasicDTypeKwd kwd, VSigning numer, int wantwidth, int
|
||||||
AstRange* rangep) {
|
AstRange* rangep) {
|
||||||
// wantwidth=0 means figure it out, but if a widthmin is >=0
|
// wantwidth=0 means figure it out, but if a widthmin is >=0
|
||||||
// we allow width 0 so that {{0{x}},y} works properly
|
// we allow width 0 so that {{0{x}},y} works properly
|
||||||
// wantwidthmin=-1: default, use wantwidth if it is non zero
|
// wantwidthmin=-1: default, use wantwidth if it is non-zero
|
||||||
m.m_keyword = kwd;
|
m.m_keyword = kwd;
|
||||||
// Implicitness: // "parameter X" is implicit and sized from initial
|
// Implicitness: // "parameter X" is implicit and sized from initial
|
||||||
// value, "parameter reg x" not
|
// value, "parameter reg x" not
|
||||||
|
|
|
||||||
|
|
@ -2913,7 +2913,7 @@ class ConstVisitor final : public VNVisitor {
|
||||||
void replaceSelIntoBiop(AstSel* nodep) {
|
void replaceSelIntoBiop(AstSel* nodep) {
|
||||||
// SEL(BUFIF1(a,b),1,bit) => BUFIF1(SEL(a,1,bit),SEL(b,1,bit))
|
// SEL(BUFIF1(a,b),1,bit) => BUFIF1(SEL(a,1,bit),SEL(b,1,bit))
|
||||||
AstNodeBiop* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), NodeBiop);
|
AstNodeBiop* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), NodeBiop);
|
||||||
UASSERT_OBJ(fromp, nodep, "Called on non biop");
|
UASSERT_OBJ(fromp, nodep, "Called on non-biop");
|
||||||
AstNodeExpr* const lsbp = nodep->lsbp()->unlinkFrBack();
|
AstNodeExpr* const lsbp = nodep->lsbp()->unlinkFrBack();
|
||||||
//
|
//
|
||||||
AstNodeExpr* const bilhsp = fromp->lhsp()->unlinkFrBack();
|
AstNodeExpr* const bilhsp = fromp->lhsp()->unlinkFrBack();
|
||||||
|
|
@ -2928,7 +2928,7 @@ class ConstVisitor final : public VNVisitor {
|
||||||
void replaceSelIntoUniop(AstSel* nodep) {
|
void replaceSelIntoUniop(AstSel* nodep) {
|
||||||
// SEL(NOT(a),1,bit) => NOT(SEL(a,bit))
|
// SEL(NOT(a),1,bit) => NOT(SEL(a,bit))
|
||||||
AstNodeUniop* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), NodeUniop);
|
AstNodeUniop* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), NodeUniop);
|
||||||
UASSERT_OBJ(fromp, nodep, "Called on non biop");
|
UASSERT_OBJ(fromp, nodep, "Called on non-biop");
|
||||||
AstNodeExpr* const lsbp = nodep->lsbp()->unlinkFrBack();
|
AstNodeExpr* const lsbp = nodep->lsbp()->unlinkFrBack();
|
||||||
//
|
//
|
||||||
AstNodeExpr* const bilhsp = fromp->lhsp()->unlinkFrBack();
|
AstNodeExpr* const bilhsp = fromp->lhsp()->unlinkFrBack();
|
||||||
|
|
@ -3877,7 +3877,7 @@ class ConstVisitor final : public VNVisitor {
|
||||||
|
|
||||||
// In the future maybe support more complicated match & replace:
|
// In the future maybe support more complicated match & replace:
|
||||||
// ("AstOr {%a, AstAnd{AstNot{%b}, %c}} if %a.width1 if %a==%b", "AstOr{%a,%c}; %b.delete");
|
// ("AstOr {%a, AstAnd{AstNot{%b}, %c}} if %a.width1 if %a==%b", "AstOr{%a,%c}; %b.delete");
|
||||||
// Lhs/rhs would be implied; for non math operations you'd need $lhsp etc.
|
// Lhs/rhs would be implied; for non-math operations you'd need $lhsp etc.
|
||||||
|
|
||||||
// v--- * * This op done on Verilog or C+++ mode, in all non-m_doConst stages
|
// v--- * * This op done on Verilog or C+++ mode, in all non-m_doConst stages
|
||||||
// v--- *1* These ops are always first, as we warn before replacing
|
// v--- *1* These ops are always first, as we warn before replacing
|
||||||
|
|
|
||||||
|
|
@ -270,15 +270,15 @@ public:
|
||||||
VDouble0 synthAlways; // Number of always blocks successfully synthesized
|
VDouble0 synthAlways; // Number of always blocks successfully synthesized
|
||||||
VDouble0 synthAssign; // Number of continuous assignments successfully synthesized
|
VDouble0 synthAssign; // Number of continuous assignments successfully synthesized
|
||||||
// Unsuccessful
|
// Unsuccessful
|
||||||
VDouble0 nonSynConv; // Non synthesizable: non representable (above)
|
VDouble0 nonSynConv; // Non-synthesizable: non-representable (above)
|
||||||
VDouble0 nonSynExtWrite; // Non synthesizable: has externally written variable
|
VDouble0 nonSynExtWrite; // Non-synthesizable: has externally written variable
|
||||||
VDouble0 nonSynLoop; // Non synthesizable: loop in CFG
|
VDouble0 nonSynLoop; // Non-synthesizable: loop in CFG
|
||||||
VDouble0 nonSynStmt; // Non synthesizable: unsupported statement
|
VDouble0 nonSynStmt; // Non-synthesizable: unsupported statement
|
||||||
VDouble0 nonSynMultidrive; // Non synthesizable: multidriven value within statement
|
VDouble0 nonSynMultidrive; // Non-synthesizable: multidriven value within statement
|
||||||
VDouble0 nonSynArray; // Non synthesizable: array type unhandled
|
VDouble0 nonSynArray; // Non-synthesizable: array type unhandled
|
||||||
VDouble0 nonSynLatch; // Non synthesizable: maybe latch
|
VDouble0 nonSynLatch; // Non-synthesizable: maybe latch
|
||||||
VDouble0 nonSynJoinInput; // Non synthesizable: needing to join input variable
|
VDouble0 nonSynJoinInput; // Non-synthesizable: needing to join input variable
|
||||||
VDouble0 nonSynFalseWrite; // Non synthesizable: does not write output
|
VDouble0 nonSynFalseWrite; // Non-synthesizable: does not write output
|
||||||
// Reverted
|
// Reverted
|
||||||
VDouble0 revertNonSyn; // Reverted due to being driven from non-synthesizable vertex
|
VDouble0 revertNonSyn; // Reverted due to being driven from non-synthesizable vertex
|
||||||
VDouble0 revertMultidrive; // Reverted due to multiple drivers
|
VDouble0 revertMultidrive; // Reverted due to multiple drivers
|
||||||
|
|
|
||||||
|
|
@ -1365,7 +1365,7 @@ class V3DfgPeephole final : public DfgVisitor {
|
||||||
hasCrossSink |= selMsb >= lLsb && rMsb >= selLsb;
|
hasCrossSink |= selMsb >= lLsb && rMsb >= selLsb;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Ignore non observable variable sinks. These will be eliminated.
|
// Ignore non-observable variable sinks. These will be eliminated.
|
||||||
if (const DfgVarPacked* const varp = sink.cast<DfgVarPacked>()) {
|
if (const DfgVarPacked* const varp = sink.cast<DfgVarPacked>()) {
|
||||||
if (!varp->hasSinks() && !varp->isObserved()) return false;
|
if (!varp->hasSinks() && !varp->isObserved()) return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1829,7 +1829,7 @@ class V3DfgPeephole final : public DfgVisitor {
|
||||||
// Otherwise remove if there is only one sink that is not a removable variable
|
// Otherwise remove if there is only one sink that is not a removable variable
|
||||||
bool foundOne = false;
|
bool foundOne = false;
|
||||||
const bool keep = vtxp->srcp()->foreachSink([&](DfgVertex& sink) {
|
const bool keep = vtxp->srcp()->foreachSink([&](DfgVertex& sink) {
|
||||||
// Ignore non observable variable sinks. These can be eliminated.
|
// Ignore non-observable variable sinks. These can be eliminated.
|
||||||
if (const DfgVertexVar* const varp = sink.cast<DfgVertexVar>()) {
|
if (const DfgVertexVar* const varp = sink.cast<DfgVertexVar>()) {
|
||||||
if (!varp->hasSinks() && !varp->isObserved()) return false;
|
if (!varp->hasSinks() && !varp->isObserved()) return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -251,7 +251,7 @@ class V3DfgPushDownSels final {
|
||||||
// METHODS - Vertex processing
|
// METHODS - Vertex processing
|
||||||
|
|
||||||
static bool ignoredSink(const DfgVertex& sink) {
|
static bool ignoredSink(const DfgVertex& sink) {
|
||||||
// Ignore non observable variable sinks. These will be eliminated.
|
// Ignore non-observable variable sinks. These will be eliminated.
|
||||||
if (const DfgVarPacked* const varp = sink.cast<DfgVarPacked>()) {
|
if (const DfgVarPacked* const varp = sink.cast<DfgVarPacked>()) {
|
||||||
if (!varp->hasSinks() && !varp->isObserved()) return true;
|
if (!varp->hasSinks() && !varp->isObserved()) return true;
|
||||||
}
|
}
|
||||||
|
|
@ -303,7 +303,7 @@ class V3DfgPushDownSels final {
|
||||||
|
|
||||||
// Iterate sinks, collect selects, check if should be optimized
|
// Iterate sinks, collect selects, check if should be optimized
|
||||||
selps.clear();
|
selps.clear();
|
||||||
DfgVertex* sinkp = nullptr; // The only non DfgSel sink (ignoring some DfgVars)
|
DfgVertex* sinkp = nullptr; // The only non-DfgSel sink (ignoring some DfgVars)
|
||||||
const bool multipleNonSelSinks = catp->foreachSink([&](DfgVertex& sink) {
|
const bool multipleNonSelSinks = catp->foreachSink([&](DfgVertex& sink) {
|
||||||
// Collect selects
|
// Collect selects
|
||||||
if (DfgSel* const selp = sink.cast<DfgSel>()) {
|
if (DfgSel* const selp = sink.cast<DfgSel>()) {
|
||||||
|
|
@ -312,14 +312,14 @@ class V3DfgPushDownSels final {
|
||||||
}
|
}
|
||||||
// Skip ignored sinks
|
// Skip ignored sinks
|
||||||
if (ignoredSink(sink)) return false;
|
if (ignoredSink(sink)) return false;
|
||||||
// If already found a non DfgSel sink, return true
|
// If already found a non-DfgSel sink, return true
|
||||||
if (sinkp) return true;
|
if (sinkp) return true;
|
||||||
// Save the non DfgSel sink
|
// Save the non-DfgSel sink
|
||||||
sinkp = &sink;
|
sinkp = &sink;
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
// It it has multiple non DfgSel sinks, it will need a temporary, so don't bother
|
// It it has multiple non-DfgSel sinks, it will need a temporary, so don't bother
|
||||||
if (multipleNonSelSinks) continue;
|
if (multipleNonSelSinks) continue;
|
||||||
// We only add DfgConcats to the work list that drive a select.
|
// We only add DfgConcats to the work list that drive a select.
|
||||||
UASSERT_OBJ(!selps.empty(), catp, "Should have selects");
|
UASSERT_OBJ(!selps.empty(), catp, "Should have selects");
|
||||||
|
|
|
||||||
|
|
@ -464,7 +464,7 @@ class DfgLogic final : public DfgVertexVariadic {
|
||||||
std::vector<DfgVertex*> m_synth; // Vertices this logic was synthesized into
|
std::vector<DfgVertex*> m_synth; // Vertices this logic was synthesized into
|
||||||
bool m_selectedForSynthesis = false; // Logic selected for synthesis
|
bool m_selectedForSynthesis = false; // Logic selected for synthesis
|
||||||
bool m_nonSynthesizable = false; // Logic is not synthesizeable (by DfgSynthesis)
|
bool m_nonSynthesizable = false; // Logic is not synthesizeable (by DfgSynthesis)
|
||||||
bool m_reverted = false; // Logic was synthesized (in part if non synthesizable) then reverted
|
bool m_reverted = false; // Logic was synthesized (in part if non-synthesizable) then reverted
|
||||||
mutable uint8_t m_cachedPure = 0; // Cached purity of the logic
|
mutable uint8_t m_cachedPure = 0; // Cached purity of the logic
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -315,7 +315,7 @@ class HierBlockUsageCollectVisitor final : public VNVisitorConst {
|
||||||
std::vector<V3HierBlock*> m_childrenp;
|
std::vector<V3HierBlock*> m_childrenp;
|
||||||
|
|
||||||
// VISITORSs
|
// VISITORSs
|
||||||
void visit(AstNodeModule*) override {} // Ignore all non AstModule
|
void visit(AstNodeModule*) override {} // Ignore all non-AstModule
|
||||||
void visit(AstModule* nodep) override {
|
void visit(AstModule* nodep) override {
|
||||||
// Visit each module once
|
// Visit each module once
|
||||||
if (nodep->user1SetOnce()) return;
|
if (nodep->user1SetOnce()) return;
|
||||||
|
|
@ -346,7 +346,7 @@ class HierBlockUsageCollectVisitor final : public VNVisitorConst {
|
||||||
for (V3HierBlock* const childp : m_childrenp) new V3GraphEdge{m_graphp, blockp, childp, 1};
|
for (V3HierBlock* const childp : m_childrenp) new V3GraphEdge{m_graphp, blockp, childp, 1};
|
||||||
}
|
}
|
||||||
void visit(AstCell* nodep) override {
|
void visit(AstCell* nodep) override {
|
||||||
// Nothing to do for non AstModules because hierarchical block cannot exist under them.
|
// Nothing to do for non-AstModules because hierarchical block cannot exist under them.
|
||||||
AstModule* const modp = VN_CAST(nodep->modp(), Module);
|
AstModule* const modp = VN_CAST(nodep->modp(), Module);
|
||||||
if (!modp) return;
|
if (!modp) return;
|
||||||
// Depth-first traversal of module hierechy
|
// Depth-first traversal of module hierechy
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ class V3List final {
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
static void prefetch(const T_Base* elementp, const T_Base* fallbackp) {
|
static void prefetch(const T_Base* elementp, const T_Base* fallbackp) {
|
||||||
UDEBUGONLY(UASSERT(fallbackp, "Prefetch fallback pointer must be non nullptr"););
|
UDEBUGONLY(UASSERT(fallbackp, "Prefetch fallback pointer must be non-nullptr"););
|
||||||
// This compiles to a branchless prefetch with cmove, with the address always valid
|
// This compiles to a branchless prefetch with cmove, with the address always valid
|
||||||
VL_PREFETCH_RW(elementp ? elementp : fallbackp);
|
VL_PREFETCH_RW(elementp ? elementp : fallbackp);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -649,7 +649,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const VL_MT_STAB
|
||||||
// Correct number of zero bits/width matters
|
// Correct number of zero bits/width matters
|
||||||
auto pos = vformat.cbegin();
|
auto pos = vformat.cbegin();
|
||||||
UASSERT(pos != vformat.cend() && pos[0] == '%',
|
UASSERT(pos != vformat.cend() && pos[0] == '%',
|
||||||
"$display-like function with non format argument " << *this);
|
"$display-like function with non-format argument " << *this);
|
||||||
++pos;
|
++pos;
|
||||||
bool left = false;
|
bool left = false;
|
||||||
if (pos[0] == '-') {
|
if (pos[0] == '-') {
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
//
|
//
|
||||||
// Ordering constraints are represented by directed edges, where the source of an edge needs to be
|
// Ordering constraints are represented by directed edges, where the source of an edge needs to be
|
||||||
// ordered before the sink of an edge. A constraint can be either hard (must be satisfied),
|
// ordered before the sink of an edge. A constraint can be either hard (must be satisfied),
|
||||||
// represented by a non cutable edge, or a constraint can be soft (ideally should be satisfied, but
|
// represented by a non-cutable edge, or a constraint can be soft (ideally should be satisfied, but
|
||||||
// is ok not to if other hard constraints interfere), represented by a cutable edge. Edges
|
// is ok not to if other hard constraints interfere), represented by a cutable edge. Edges
|
||||||
// otherwise carry no additional information. TODO: what about weight?
|
// otherwise carry no additional information. TODO: what about weight?
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Vertex of each type (if non nullptr)
|
// Vertex of each type (if non-nullptr)
|
||||||
std::array<OrderVarVertex*, static_cast<size_t>(VarVertexType::POST) + 1> m_vertexps;
|
std::array<OrderVarVertex*, static_cast<size_t>(VarVertexType::POST) + 1> m_vertexps;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -2255,7 +2255,7 @@ class Partitioner final {
|
||||||
for (V3GraphEdge& tEdge : top->outEdges()) {
|
for (V3GraphEdge& tEdge : top->outEdges()) {
|
||||||
LogicMTask* const transp = static_cast<LogicMTask*>(tEdge.top()->userp());
|
LogicMTask* const transp = static_cast<LogicMTask*>(tEdge.top()->userp());
|
||||||
// The Move graph is bipartite (logic <-> var), and logic is never
|
// The Move graph is bipartite (logic <-> var), and logic is never
|
||||||
// bypassed, hence 'transp' must be non nullptr.
|
// bypassed, hence 'transp' must be non-nullptr.
|
||||||
UASSERT_OBJ(transp, mVtxp, "This cannot be a bypassed vertex");
|
UASSERT_OBJ(transp, mVtxp, "This cannot be a bypassed vertex");
|
||||||
addEdge(transp);
|
addEdge(transp);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
// V3Reorder transformations:
|
// V3Reorder transformations:
|
||||||
//
|
//
|
||||||
// reorderAll() reorders statements within individual blocks to avoid
|
// reorderAll() reorders statements within individual blocks to avoid
|
||||||
// shwdow variables use by non blocking assignments when possible.
|
// shwdow variables use by non-blocking assignments when possible.
|
||||||
// For exmaple, the left side needs a shadow variable for 'b', the
|
// For exmaple, the left side needs a shadow variable for 'b', the
|
||||||
// right side does not:
|
// right side does not:
|
||||||
// Bad: Good:
|
// Bad: Good:
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ struct LogicReplicas final {
|
||||||
//
|
//
|
||||||
// There are 3 different kinds of triggers
|
// There are 3 different kinds of triggers
|
||||||
// 1. "Sense" triggers, which correspond to a unique SenItem in the design
|
// 1. "Sense" triggers, which correspond to a unique SenItem in the design
|
||||||
// 2. "Extra" triggers, which represent non SenItem based conditions
|
// 2. "Extra" triggers, which represent non-SenItem based conditions
|
||||||
// 3. "Pre" triggers, which are only used in the 'act' region. These are a copy
|
// 3. "Pre" triggers, which are only used in the 'act' region. These are a copy
|
||||||
// of some of the "Sense" triggers but only ever fire during one evaluation
|
// of some of the "Sense" triggers but only ever fire during one evaluation
|
||||||
// of the 'act' loop. They are used for executing AlwaysPre block that
|
// of the 'act' loop. They are used for executing AlwaysPre block that
|
||||||
|
|
|
||||||
|
|
@ -323,7 +323,7 @@ class SubstVisitor final : public VNVisitor {
|
||||||
if (ops > SUBST_MAX_OPS_SUBST) return nullptr;
|
if (ops > SUBST_MAX_OPS_SUBST) return nullptr;
|
||||||
// AstCvtPackedToArray can't be anywhere else than on the RHS of assignment
|
// AstCvtPackedToArray can't be anywhere else than on the RHS of assignment
|
||||||
if (VN_IS(nodep->rhsp(), CvtPackedToArray)) return nullptr;
|
if (VN_IS(nodep->rhsp(), CvtPackedToArray)) return nullptr;
|
||||||
// If non const but want const subtitutions only
|
// If non-const but want const subtitutions only
|
||||||
if (refp->varp()->substConstOnly() && !VN_IS(nodep->rhsp(), Const)) return nullptr;
|
if (refp->varp()->substConstOnly() && !VN_IS(nodep->rhsp(), Const)) return nullptr;
|
||||||
// Otherwise can substitute based on the assignment
|
// Otherwise can substitute based on the assignment
|
||||||
return nodep;
|
return nodep;
|
||||||
|
|
|
||||||
|
|
@ -799,7 +799,7 @@ class TimingControlVisitor final : public VNVisitor {
|
||||||
}
|
}
|
||||||
UASSERT_OBJ(firstStmtp, procp,
|
UASSERT_OBJ(firstStmtp, procp,
|
||||||
procp->prettyNameQ() << " has no non-var statement. 'localizeVars()' is ment "
|
procp->prettyNameQ() << " has no non-var statement. 'localizeVars()' is ment "
|
||||||
"to be called on non empty NodeProcedure/CFunc/Begin");
|
"to be called on non-empty NodeProcedure/CFunc/Begin");
|
||||||
for (AstVar* const varp : varsp) {
|
for (AstVar* const varp : varsp) {
|
||||||
varp->funcLocal(true);
|
varp->funcLocal(true);
|
||||||
firstStmtp->addHereThisAsNext(varp->unlinkFrBack());
|
firstStmtp->addHereThisAsNext(varp->unlinkFrBack());
|
||||||
|
|
|
||||||
|
|
@ -5095,7 +5095,7 @@ class WidthVisitor final : public VNVisitor {
|
||||||
} else {
|
} else {
|
||||||
nodep->v3warn(
|
nodep->v3warn(
|
||||||
E_UNSUPPORTED,
|
E_UNSUPPORTED,
|
||||||
"Unsupported: Assignment pattern applies against non struct/union data type: "
|
"Unsupported: Assignment pattern applies against non-struct/union data type: "
|
||||||
<< dtypep->prettyDTypeNameQ());
|
<< dtypep->prettyDTypeNameQ());
|
||||||
nodep->replaceWith(new AstConst{nodep->fileline(), AstConst::BitFalse{}});
|
nodep->replaceWith(new AstConst{nodep->fileline(), AstConst::BitFalse{}});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -534,7 +534,7 @@ static void process() {
|
||||||
V3Dead::deadifyAll(v3Global.rootp());
|
V3Dead::deadifyAll(v3Global.rootp());
|
||||||
|
|
||||||
// Here down, widthMin() is the Verilog width, and width() is the C++ width
|
// Here down, widthMin() is the Verilog width, and width() is the C++ width
|
||||||
// Bits between widthMin() and width() are irrelevant, but may be non zero.
|
// Bits between widthMin() and width() are irrelevant, but may be non-zero.
|
||||||
v3Global.widthMinUsage(VWidthMinUsage::VERILOG_WIDTH);
|
v3Global.widthMinUsage(VWidthMinUsage::VERILOG_WIDTH);
|
||||||
|
|
||||||
// Make all expressions 32, 64, or 32*N bits
|
// Make all expressions 32, 64, or 32*N bits
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
%Error-UNSUPPORTED: t/t_array_pattern_scalar_bad.v:9:13: Unsupported: Assignment pattern applies against non struct/union data type: 'bit'
|
%Error-UNSUPPORTED: t/t_array_pattern_scalar_bad.v:9:13: Unsupported: Assignment pattern applies against non-struct/union data type: 'bit'
|
||||||
: ... note: In instance 't'
|
: ... note: In instance 't'
|
||||||
9 | bit bad = '{1'b1};
|
9 | bit bad = '{1'b1};
|
||||||
| ^~
|
| ^~
|
||||||
|
|
|
||||||
|
|
@ -628,67 +628,67 @@ module t;
|
||||||
|
|
||||||
function void e_chandle_0d(input chandle val);
|
function void e_chandle_0d(input chandle val);
|
||||||
if (val == null) begin
|
if (val == null) begin
|
||||||
$display("Mismatch non null is expected, but not.");
|
$display("Mismatch non-null is expected, but not.");
|
||||||
$stop;
|
$stop;
|
||||||
end
|
end
|
||||||
endfunction
|
endfunction
|
||||||
function void e_chandle_1d(input chandle val[2]);
|
function void e_chandle_1d(input chandle val[2]);
|
||||||
if (val[0] == null) begin
|
if (val[0] == null) begin
|
||||||
$display("Mismatch non null is expected, but not.");
|
$display("Mismatch non-null is expected, but not.");
|
||||||
$stop;
|
$stop;
|
||||||
end
|
end
|
||||||
if (val[1] == null) begin
|
if (val[1] == null) begin
|
||||||
$display("Mismatch non null is expected, but not.");
|
$display("Mismatch non-null is expected, but not.");
|
||||||
$stop;
|
$stop;
|
||||||
end
|
end
|
||||||
endfunction
|
endfunction
|
||||||
function void e_chandle_2d(input chandle val[3][2]);
|
function void e_chandle_2d(input chandle val[3][2]);
|
||||||
if (val[0][1] == null) begin
|
if (val[0][1] == null) begin
|
||||||
$display("Mismatch non null is expected, but not.");
|
$display("Mismatch non-null is expected, but not.");
|
||||||
$stop;
|
$stop;
|
||||||
end
|
end
|
||||||
if (val[1][1] == null) begin
|
if (val[1][1] == null) begin
|
||||||
$display("Mismatch non null is expected, but not.");
|
$display("Mismatch non-null is expected, but not.");
|
||||||
$stop;
|
$stop;
|
||||||
end
|
end
|
||||||
if (val[2][1] == null) begin
|
if (val[2][1] == null) begin
|
||||||
$display("Mismatch non null is expected, but not.");
|
$display("Mismatch non-null is expected, but not.");
|
||||||
$stop;
|
$stop;
|
||||||
end
|
end
|
||||||
endfunction
|
endfunction
|
||||||
function void e_chandle_3d(input chandle_array_t val);
|
function void e_chandle_3d(input chandle_array_t val);
|
||||||
if (val[0][0][0] == null) begin
|
if (val[0][0][0] == null) begin
|
||||||
$display("Mismatch non null is expected, but not.");
|
$display("Mismatch non-null is expected, but not.");
|
||||||
$stop;
|
$stop;
|
||||||
end
|
end
|
||||||
if (val[1][0][0] == null) begin
|
if (val[1][0][0] == null) begin
|
||||||
$display("Mismatch non null is expected, but not.");
|
$display("Mismatch non-null is expected, but not.");
|
||||||
$stop;
|
$stop;
|
||||||
end
|
end
|
||||||
if (val[2][0][0] == null) begin
|
if (val[2][0][0] == null) begin
|
||||||
$display("Mismatch non null is expected, but not.");
|
$display("Mismatch non-null is expected, but not.");
|
||||||
$stop;
|
$stop;
|
||||||
end
|
end
|
||||||
if (val[3][0][0] == null) begin
|
if (val[3][0][0] == null) begin
|
||||||
$display("Mismatch non null is expected, but not.");
|
$display("Mismatch non-null is expected, but not.");
|
||||||
$stop;
|
$stop;
|
||||||
end
|
end
|
||||||
endfunction
|
endfunction
|
||||||
function void e_chandle_1d1(input chandle val[1]);
|
function void e_chandle_1d1(input chandle val[1]);
|
||||||
if (val[0] == null) begin
|
if (val[0] == null) begin
|
||||||
$display("Mismatch non null is expected, but not.");
|
$display("Mismatch non-null is expected, but not.");
|
||||||
$stop;
|
$stop;
|
||||||
end
|
end
|
||||||
endfunction
|
endfunction
|
||||||
function void e_chandle_2d1(input chandle val[1][1]);
|
function void e_chandle_2d1(input chandle val[1][1]);
|
||||||
if (val[0][0] == null) begin
|
if (val[0][0] == null) begin
|
||||||
$display("Mismatch non null is expected, but not.");
|
$display("Mismatch non-null is expected, but not.");
|
||||||
$stop;
|
$stop;
|
||||||
end
|
end
|
||||||
endfunction
|
endfunction
|
||||||
function void e_chandle_3d1(input chandle_array1_t val);
|
function void e_chandle_3d1(input chandle_array1_t val);
|
||||||
if (val[0][0][0] == null) begin
|
if (val[0][0][0] == null) begin
|
||||||
$display("Mismatch non null is expected, but not.");
|
$display("Mismatch non-null is expected, but not.");
|
||||||
$stop;
|
$stop;
|
||||||
end
|
end
|
||||||
endfunction
|
endfunction
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ module t;
|
||||||
// Test loop
|
// Test loop
|
||||||
initial begin
|
initial begin
|
||||||
// Spec says && || -> and ?: short circuit, no others do.
|
// Spec says && || -> and ?: short circuit, no others do.
|
||||||
// Check both constant & non constants.
|
// Check both constant & non-constants.
|
||||||
dpii_clear();
|
dpii_clear();
|
||||||
check1(`__LINE__, (1'b0 && dpii_inc0(0)), 1'b0);
|
check1(`__LINE__, (1'b0 && dpii_inc0(0)), 1'b0);
|
||||||
check1(`__LINE__, (1'b1 && dpii_inc0(1)), 1'b0);
|
check1(`__LINE__, (1'b1 && dpii_inc0(1)), 1'b0);
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ test.vm_prefix = "Vhier"
|
||||||
test.main_filename = test.obj_dir + "/Vhier__main.cpp"
|
test.main_filename = test.obj_dir + "/Vhier__main.cpp"
|
||||||
test.compile(verilator_flags2=verilator_hier_flags, main_top_name=main_top_name)
|
test.compile(verilator_flags2=verilator_hier_flags, main_top_name=main_top_name)
|
||||||
|
|
||||||
# Compile non hierarchically
|
# Compile non-hierarchically
|
||||||
test.vm_prefix = "Vnonh"
|
test.vm_prefix = "Vnonh"
|
||||||
test.main_filename = test.obj_dir + "/Vnonh__main.cpp"
|
test.main_filename = test.obj_dir + "/Vnonh__main.cpp"
|
||||||
test.compile(verilator_flags2=verilator_common_flags, main_top_name=main_top_name)
|
test.compile(verilator_flags2=verilator_common_flags, main_top_name=main_top_name)
|
||||||
|
|
@ -51,7 +51,7 @@ trace_nonh = test.trace_filename.replace("simx", "nonh")
|
||||||
# Run the hierarchical model
|
# Run the hierarchical model
|
||||||
test.execute(executable=test.obj_dir + "/Vhier")
|
test.execute(executable=test.obj_dir + "/Vhier")
|
||||||
test.run(cmd=["mv", test.trace_filename, trace_hier])
|
test.run(cmd=["mv", test.trace_filename, trace_hier])
|
||||||
# Run the non hierarchical model
|
# Run the non-hierarchical model
|
||||||
test.execute(executable=test.obj_dir + "/Vnonh")
|
test.execute(executable=test.obj_dir + "/Vnonh")
|
||||||
test.run(cmd=["mv", test.trace_filename, trace_nonh])
|
test.run(cmd=["mv", test.trace_filename, trace_nonh])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ test.vm_prefix = "Vhier"
|
||||||
test.main_filename = test.obj_dir + "/Vhier__main.cpp"
|
test.main_filename = test.obj_dir + "/Vhier__main.cpp"
|
||||||
test.compile(verilator_flags2=verilator_hier_flags, main_top_name=main_top_name)
|
test.compile(verilator_flags2=verilator_hier_flags, main_top_name=main_top_name)
|
||||||
|
|
||||||
# Compile non hierarchically
|
# Compile non-hierarchically
|
||||||
test.vm_prefix = "Vnonh"
|
test.vm_prefix = "Vnonh"
|
||||||
test.main_filename = test.obj_dir + "/Vnonh__main.cpp"
|
test.main_filename = test.obj_dir + "/Vnonh__main.cpp"
|
||||||
test.compile(verilator_flags2=verilator_common_flags, main_top_name=main_top_name)
|
test.compile(verilator_flags2=verilator_common_flags, main_top_name=main_top_name)
|
||||||
|
|
@ -51,7 +51,7 @@ trace_nonh = test.trace_filename.replace("simx", "nonh")
|
||||||
# Run the hierarchical model
|
# Run the hierarchical model
|
||||||
test.execute(executable=test.obj_dir + "/Vhier")
|
test.execute(executable=test.obj_dir + "/Vhier")
|
||||||
test.run(cmd=["mv", test.trace_filename, trace_hier])
|
test.run(cmd=["mv", test.trace_filename, trace_hier])
|
||||||
# Run the non hierarchical model
|
# Run the non-hierarchical model
|
||||||
test.execute(executable=test.obj_dir + "/Vnonh")
|
test.execute(executable=test.obj_dir + "/Vnonh")
|
||||||
test.run(cmd=["mv", test.trace_filename, trace_nonh])
|
test.run(cmd=["mv", test.trace_filename, trace_nonh])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ test.vm_prefix = "Vhier"
|
||||||
test.main_filename = test.obj_dir + "/Vhier__main.cpp"
|
test.main_filename = test.obj_dir + "/Vhier__main.cpp"
|
||||||
test.compile(verilator_flags2=verilator_hier_flags, main_top_name=main_top_name)
|
test.compile(verilator_flags2=verilator_hier_flags, main_top_name=main_top_name)
|
||||||
|
|
||||||
# Compile non hierarchically
|
# Compile non-hierarchically
|
||||||
test.vm_prefix = "Vnonh"
|
test.vm_prefix = "Vnonh"
|
||||||
test.main_filename = test.obj_dir + "/Vnonh__main.cpp"
|
test.main_filename = test.obj_dir + "/Vnonh__main.cpp"
|
||||||
test.compile(verilator_flags2=verilator_common_flags, main_top_name=main_top_name)
|
test.compile(verilator_flags2=verilator_common_flags, main_top_name=main_top_name)
|
||||||
|
|
@ -53,7 +53,7 @@ trace_nonh = test.trace_filename.replace("simx", "nonh")
|
||||||
# Run the hierarchical model
|
# Run the hierarchical model
|
||||||
test.execute(executable=test.obj_dir + "/Vhier")
|
test.execute(executable=test.obj_dir + "/Vhier")
|
||||||
test.run(cmd=["mv", test.trace_filename, trace_hier])
|
test.run(cmd=["mv", test.trace_filename, trace_hier])
|
||||||
# Run the non hierarchical model
|
# Run the non-hierarchical model
|
||||||
test.execute(executable=test.obj_dir + "/Vnonh")
|
test.execute(executable=test.obj_dir + "/Vnonh")
|
||||||
test.run(cmd=["mv", test.trace_filename, trace_nonh])
|
test.run(cmd=["mv", test.trace_filename, trace_nonh])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ module t (
|
||||||
gclk = {gclk[N-2:0], gclk[N-1]};
|
gclk = {gclk[N-2:0], gclk[N-1]};
|
||||||
end
|
end
|
||||||
|
|
||||||
// This make the always block requires a 'pre' trigger (and makes it non splitable)
|
// This make the always block requires a 'pre' trigger (and makes it non-splitable)
|
||||||
par <= ^gclk;
|
par <= ^gclk;
|
||||||
|
|
||||||
cyc <= cyc + 32'd1;
|
cyc <= cyc + 32'd1;
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ void _mem_check(const char* name, int size, int left, int right, int words) {
|
||||||
TEST_CHECK_EQ(std::string{value.value.str}, binStr);
|
TEST_CHECK_EQ(std::string{value.value.str}, binStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't care for non verilator
|
// don't care for non-Verilator
|
||||||
// (crashes on Icarus)
|
// (crashes on Icarus)
|
||||||
if (TestSimulator::is_icarus()) {
|
if (TestSimulator::is_icarus()) {
|
||||||
vpi_printf((PLI_BYTE8*)"Skipping property checks for simulator %s\n",
|
vpi_printf((PLI_BYTE8*)"Skipping property checks for simulator %s\n",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue