The original code called V3Const::constifyParamsEdit() in
V3Width::visit(AstInsideRange*) to fold negative bin bounds
(e.g., NEGATE(100) -> -100) for covergroup bins. Since
constifyParamsEdit uses m_required=true, it errored on any
non-constant expression -- breaking the upstream test
t_constraint_array_index_simple which uses a foreach loop
variable 'i' in an inside constraint expression.
Fix: Remove the unconditional constifyParamsEdit calls from
V3Width::visit(AstInsideRange*). Instead:
- In V3Width: when m_vup is null (covergroup bin context,
not an expression context), use constifyEdit (m_required=false)
to fold constant arithmetic before iterating children.
- In V3Covergroup: call constifyEdit at the two sites that
cast InsideRange bounds to AstConst for bin expansion.
This moves the covergroup-specific concern to the right layer
(V3Covergroup) while keeping V3Width safe for all contexts.
Also update golden files for t_covergroup_trans_3value,
t_covergroup_trans_restart, and t_covergroup_with_sample_args_too_many_bad
whose line numbers shifted by 1 due to the SPDX copyright header
additions in the previous commit.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace Unicode em-dash and curly apostrophe with plain ASCII
equivalents to pass t_dist_whitespace CI check.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Coverage bin counters (__Vcov_* member variables) were being initialized
with VL_SCOPED_RAND_RESET_I because they are plain uint32 members with no
explicit initial value. This caused 0% coverage readings at runtime when
randReset != 0 (as used in CI).
Fix all 5 bin counter AstVar creation sites to set an explicit valuep of
AstConst(0), so V3EmitCFunc emits '= 0U' instead of VL_SCOPED_RAND_RESET_I.
Affects: regular bins, default bins, array bins, transition array bins,
and cross bins.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Commit b4244fc57 accidentally dropped the varp->lifetime(VLifetime::AUTOMATIC_EXPLICIT)
line when reverting V3LinkInc.cpp to a merge base. This caused __Vincrement* temp
variables to have VLifetime::NONE, triggering V3Fork's assertion that all variables
inside fork...join_none blocks have a known lifetime.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two bugs in the covergroup -> AstClass transformation in V3LinkParse:
1. Infinite recursion: when a covergroup has a clocking event (e.g.
`@(posedge clk)`), visit(AstCovergroup*) embeds a sentinel
AstCovergroup node inside the new AstClass to carry the event for
V3Covergroup.cpp. The subsequent iterate(cgClassp) call then visits
the sentinel via visit(AstNodeModule*) -> iterateChildren -> which
hits visit(AstCovergroup*) again, creating another class with another
sentinel, infinitely.
Fix: skip transformation in visit(AstCovergroup*) when already inside
a covergroup class (m_modp->isCovergroup()), so sentinel nodes are
left alone.
2. Wrong fileline column: AstCovergroup was created with the fileline of
the identifier token ($<fl>2, the name position) rather than the
'covergroup' keyword token ($<fl>1). This caused warnings about the
covergroup to point to the name column instead of the keyword column.
Fix: use $<fl>1 (the 'covergroup' keyword fileline) when constructing
AstCovergroup in the parser.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
V3LinkParse's visit(AstCovergroup) creates std:: references and calls
setUsesStdPackage(). The previous removeStd() call happened before
V3LinkParse ran, so it deleted the std package before those references
were created, causing:
%Error: Package/class for ':: reference' not found: 'std'
Move removeStd() to immediately after V3LinkParse::linkParse() inside
process() so the std package is only pruned after all parse-time
transformations have had a chance to declare their std:: usage.
Fixes test failures:
- t_covergroup_option
- t_covergroup_with_sample_args_too_many_bad
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Three node deletions were accidentally dropped from the initial covergroup
commit as collateral damage:
- wait_order (no-stmt variant): restore DEL($3) for vrdList
- expect (no-stmt variant): restore DEL($3) for property_spec
- property_exprCaseIf yIF/yELSE: restore DEL($3) for condition expr
In all three cases $3 is an AstNode* that is not assigned to $$ and would
be leaked without the deletion.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add v3Global.useCovergroup() flag (following the useRandSequence()
pattern) that is set to true when a covergroup_declaration is parsed.
Gate the V3Covergroup::covergroup() pass in Verilator.cpp on this flag
so the pass is skipped entirely for designs with no covergroups.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two bugs fixed:
1. AstCReset: mark as ineligible for coverage expressions via
isExprCoverageEligible() override, preventing verilogForTree
from being called on CReset nodes (which has no V3EmitV handler).
2. generateCrossCode: when a cross references an unknown coverpoint,
don't delete the cross node early. The caller's cleanup loop
(in visit(AstClass*)) is responsible for deleting all coverpoints
and crosses. Early deletion left a dangling pointer in m_coverCrosses
causing a use-after-free segfault.
3. hasUnsupportedEvent path: added coverpoint/cross cleanup before
returning so AST nodes don't reach downstream passes (V3EmitCFunc,
V3MergeCond) which no longer have stub visitors for them.
All 60 covergroup tests now pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The VLifetime::AUTOMATIC_EXPLICIT addition is not required for
functional coverage — all 60 covergroup tests pass without it.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
These changes are not required for functional coverage support and
should not be included in the upstream patch.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>