mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Fix complex user type problem with --x-assign (#5543)
This commit is contained in:
parent
7ccc93d9df
commit
76fe224e7c
@ -1333,9 +1333,10 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||||||
} else {
|
} else {
|
||||||
findvarp->combineType(nodep);
|
findvarp->combineType(nodep);
|
||||||
findvarp->fileline()->modifyStateInherit(nodep->fileline());
|
findvarp->fileline()->modifyStateInherit(nodep->fileline());
|
||||||
if (nodep->getChildDTypep()->numeric().isSigned()
|
UASSERT_OBJ(nodep->subDTypep(), nodep, "Var has no type");
|
||||||
&& !findvarp->getChildDTypep()->numeric().isSigned()) {
|
if (nodep->subDTypep()->numeric().isSigned()
|
||||||
findvarp->getChildDTypep()->numeric(VSigning{true});
|
&& !findvarp->subDTypep()->numeric().isSigned()) {
|
||||||
|
findvarp->subDTypep()->numeric(VSigning{true});
|
||||||
}
|
}
|
||||||
AstBasicDType* const bdtypep
|
AstBasicDType* const bdtypep
|
||||||
= VN_CAST(findvarp->childDTypep(), BasicDType);
|
= VN_CAST(findvarp->childDTypep(), BasicDType);
|
||||||
|
@ -48,6 +48,7 @@ class UnknownVisitor final : public VNVisitor {
|
|||||||
// AstNode::user2p() -> AstIf* Inserted if assignment for conditional
|
// AstNode::user2p() -> AstIf* Inserted if assignment for conditional
|
||||||
const VNUser1InUse m_inuser1;
|
const VNUser1InUse m_inuser1;
|
||||||
const VNUser2InUse m_inuser2;
|
const VNUser2InUse m_inuser2;
|
||||||
|
static const std::string m_xrandPrefix;
|
||||||
|
|
||||||
// STATE
|
// STATE
|
||||||
AstNodeModule* m_modp = nullptr; // Current module
|
AstNodeModule* m_modp = nullptr; // Current module
|
||||||
@ -58,7 +59,7 @@ class UnknownVisitor final : public VNVisitor {
|
|||||||
bool m_allowXUnique = true; // Allow unique assignments
|
bool m_allowXUnique = true; // Allow unique assignments
|
||||||
VDouble0 m_statUnkVars; // Statistic tracking
|
VDouble0 m_statUnkVars; // Statistic tracking
|
||||||
V3UniqueNames m_lvboundNames; // For generating unique temporary variable names
|
V3UniqueNames m_lvboundNames; // For generating unique temporary variable names
|
||||||
V3UniqueNames m_xrandNames; // For generating unique temporary variable names
|
std::unique_ptr<V3UniqueNames> m_xrandNames; // For generating unique temporary variable names
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
|
|
||||||
@ -141,14 +142,16 @@ class UnknownVisitor final : public VNVisitor {
|
|||||||
VL_RESTORER(m_modp);
|
VL_RESTORER(m_modp);
|
||||||
VL_RESTORER(m_constXCvt);
|
VL_RESTORER(m_constXCvt);
|
||||||
VL_RESTORER(m_allowXUnique);
|
VL_RESTORER(m_allowXUnique);
|
||||||
|
auto xrandNames = std::make_unique<V3UniqueNames>(m_xrandPrefix);
|
||||||
{
|
{
|
||||||
m_modp = nodep;
|
m_modp = nodep;
|
||||||
m_constXCvt = true;
|
m_constXCvt = true;
|
||||||
// Class X randomization causes Vxrand in strange places, so disable
|
// Class X randomization causes Vxrand in strange places, so disable
|
||||||
if (VN_IS(nodep, Class)) m_allowXUnique = false;
|
if (VN_IS(nodep, Class)) m_allowXUnique = false;
|
||||||
m_lvboundNames.reset();
|
m_lvboundNames.reset();
|
||||||
m_xrandNames.reset();
|
xrandNames.swap(m_xrandNames);
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
|
xrandNames.swap(m_xrandNames);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void visit(AstAssignDly* nodep) override {
|
void visit(AstAssignDly* nodep) override {
|
||||||
@ -345,7 +348,7 @@ class UnknownVisitor final : public VNVisitor {
|
|||||||
// We use the special XTEMP type so it doesn't break pure functions
|
// We use the special XTEMP type so it doesn't break pure functions
|
||||||
UASSERT_OBJ(m_modp, nodep, "X number not under module");
|
UASSERT_OBJ(m_modp, nodep, "X number not under module");
|
||||||
AstVar* const newvarp
|
AstVar* const newvarp
|
||||||
= new AstVar{nodep->fileline(), VVarType::XTEMP, m_xrandNames.get(nodep),
|
= new AstVar{nodep->fileline(), VVarType::XTEMP, m_xrandNames->get(nodep),
|
||||||
VFlagLogicPacked{}, nodep->width()};
|
VFlagLogicPacked{}, nodep->width()};
|
||||||
newvarp->lifetime(VLifetime::STATIC);
|
newvarp->lifetime(VLifetime::STATIC);
|
||||||
++m_statUnkVars;
|
++m_statUnkVars;
|
||||||
@ -517,7 +520,7 @@ public:
|
|||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
explicit UnknownVisitor(AstNetlist* nodep)
|
explicit UnknownVisitor(AstNetlist* nodep)
|
||||||
: m_lvboundNames{"__Vlvbound"}
|
: m_lvboundNames{"__Vlvbound"}
|
||||||
, m_xrandNames{"__Vxrand"} {
|
, m_xrandNames{std::make_unique<V3UniqueNames>(m_xrandPrefix)} {
|
||||||
iterate(nodep);
|
iterate(nodep);
|
||||||
}
|
}
|
||||||
~UnknownVisitor() override { //
|
~UnknownVisitor() override { //
|
||||||
@ -525,6 +528,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const std::string UnknownVisitor::m_xrandPrefix = "__Vxrand";
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
// Unknown class functions
|
// Unknown class functions
|
||||||
|
|
||||||
|
18
test_regress/t/t_user_type_xassign.py
Executable file
18
test_regress/t/t_user_type_xassign.py
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2024 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.
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile()
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
43
test_regress/t/t_user_type_xassign.v
Normal file
43
test_regress/t/t_user_type_xassign.v
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// DESCRIPTION: Verilator: Demonstrate complex user typea problem with --x-assign
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2024 by Wilson Snyder.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
module t (/*AUTOARG*/
|
||||||
|
// Inputs
|
||||||
|
clk
|
||||||
|
);
|
||||||
|
|
||||||
|
input clk;
|
||||||
|
|
||||||
|
typedef logic [31:0] int_t;
|
||||||
|
typedef int_t [6:0] bar_t;
|
||||||
|
bar_t the_bar;
|
||||||
|
|
||||||
|
logic [31:0] thing_one;
|
||||||
|
always_comb begin
|
||||||
|
for (int sel = 0; sel < 1; sel++)
|
||||||
|
thing_one = the_bar[sel];
|
||||||
|
end
|
||||||
|
|
||||||
|
virtual class SomeClass;
|
||||||
|
static function logic compare(int a, int b);
|
||||||
|
return a > b;
|
||||||
|
endfunction
|
||||||
|
endclass
|
||||||
|
|
||||||
|
logic [31:0] thing_two;
|
||||||
|
always_comb begin
|
||||||
|
for (int sel_a = 0; sel_a < 1; sel_a++)
|
||||||
|
thing_two = the_bar[sel_a];
|
||||||
|
end
|
||||||
|
|
||||||
|
// finish report
|
||||||
|
always @ (posedge clk) begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
Loading…
Reference in New Issue
Block a user