Fix complex user type problem with --x-assign (#5543)

This commit is contained in:
Todd Strader 2024-10-18 19:52:25 -04:00 committed by GitHub
parent 7ccc93d9df
commit 76fe224e7c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 74 additions and 7 deletions

View File

@ -1333,9 +1333,10 @@ class LinkDotFindVisitor final : public VNVisitor {
} else {
findvarp->combineType(nodep);
findvarp->fileline()->modifyStateInherit(nodep->fileline());
if (nodep->getChildDTypep()->numeric().isSigned()
&& !findvarp->getChildDTypep()->numeric().isSigned()) {
findvarp->getChildDTypep()->numeric(VSigning{true});
UASSERT_OBJ(nodep->subDTypep(), nodep, "Var has no type");
if (nodep->subDTypep()->numeric().isSigned()
&& !findvarp->subDTypep()->numeric().isSigned()) {
findvarp->subDTypep()->numeric(VSigning{true});
}
AstBasicDType* const bdtypep
= VN_CAST(findvarp->childDTypep(), BasicDType);

View File

@ -48,6 +48,7 @@ class UnknownVisitor final : public VNVisitor {
// AstNode::user2p() -> AstIf* Inserted if assignment for conditional
const VNUser1InUse m_inuser1;
const VNUser2InUse m_inuser2;
static const std::string m_xrandPrefix;
// STATE
AstNodeModule* m_modp = nullptr; // Current module
@ -58,7 +59,7 @@ class UnknownVisitor final : public VNVisitor {
bool m_allowXUnique = true; // Allow unique assignments
VDouble0 m_statUnkVars; // Statistic tracking
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
@ -141,14 +142,16 @@ class UnknownVisitor final : public VNVisitor {
VL_RESTORER(m_modp);
VL_RESTORER(m_constXCvt);
VL_RESTORER(m_allowXUnique);
auto xrandNames = std::make_unique<V3UniqueNames>(m_xrandPrefix);
{
m_modp = nodep;
m_constXCvt = true;
// Class X randomization causes Vxrand in strange places, so disable
if (VN_IS(nodep, Class)) m_allowXUnique = false;
m_lvboundNames.reset();
m_xrandNames.reset();
xrandNames.swap(m_xrandNames);
iterateChildren(nodep);
xrandNames.swap(m_xrandNames);
}
}
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
UASSERT_OBJ(m_modp, nodep, "X number not under module");
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()};
newvarp->lifetime(VLifetime::STATIC);
++m_statUnkVars;
@ -517,7 +520,7 @@ public:
// CONSTRUCTORS
explicit UnknownVisitor(AstNetlist* nodep)
: m_lvboundNames{"__Vlvbound"}
, m_xrandNames{"__Vxrand"} {
, m_xrandNames{std::make_unique<V3UniqueNames>(m_xrandPrefix)} {
iterate(nodep);
}
~UnknownVisitor() override { //
@ -525,6 +528,8 @@ public:
}
};
const std::string UnknownVisitor::m_xrandPrefix = "__Vxrand";
//######################################################################
// Unknown class functions

View 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()

View 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