parent
c840ffb0ae
commit
1a07af57a3
|
|
@ -900,8 +900,9 @@ public:
|
|||
const AstBasicDType* basicp() const { return m_basicp; }
|
||||
// Make a plan for variables after split
|
||||
// when skipUnused==true, split variable for unread bits will not be created.
|
||||
std::vector<SplitNewVar> splitPlan(bool skipUnused) const {
|
||||
std::vector<SplitNewVar> splitPlan(const AstVar* varp, bool skipUnused) const {
|
||||
UASSERT(m_dedupDone, "dedup() must be called before");
|
||||
AstNodeDType* const dtypep = varp->dtypeSkipRefp();
|
||||
std::vector<SplitNewVar> plan;
|
||||
std::vector<std::pair<int, bool>> points; // <bit location, is end>
|
||||
points.reserve(m_lhs.size() * 2 + 2); // 2 points will be added per one PackedVarRefEntry
|
||||
|
|
@ -909,9 +910,17 @@ public:
|
|||
points.emplace_back(ref.lsb(), false); // Start of a region
|
||||
points.emplace_back(ref.msb() + 1, true); // End of a region
|
||||
}
|
||||
int bit_hi, bit_lo;
|
||||
if (basicp() == dtypep) {
|
||||
bit_hi = basicp()->hi();
|
||||
bit_lo = basicp()->lo();
|
||||
} else { // packed struct, packed array. lo is 0
|
||||
bit_hi = dtypep->width() - 1;
|
||||
bit_lo = 0;
|
||||
}
|
||||
if (skipUnused && !m_rhs.empty()) { // Range to be read must be kept, so add points here
|
||||
int lsb = m_basicp->hi() + 1;
|
||||
int msb = m_basicp->lo() - 1;
|
||||
int lsb = bit_hi + 1;
|
||||
int msb = bit_lo - 1;
|
||||
for (const PackedVarRefEntry& ref : m_rhs) {
|
||||
lsb = std::min(lsb, ref.lsb());
|
||||
msb = std::max(msb, ref.msb());
|
||||
|
|
@ -921,8 +930,8 @@ public:
|
|||
points.emplace_back(msb + 1, true);
|
||||
}
|
||||
if (!skipUnused) { // All bits are necessary
|
||||
points.emplace_back(m_basicp->lo(), false);
|
||||
points.emplace_back(m_basicp->hi() + 1, true);
|
||||
points.emplace_back(bit_lo, false);
|
||||
points.emplace_back(bit_hi + 1, true);
|
||||
}
|
||||
std::sort(points.begin(), points.end(), SortByFirst());
|
||||
|
||||
|
|
@ -1154,7 +1163,7 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl {
|
|||
<< " which has " << ref.lhs().size() << " lhs refs and "
|
||||
<< ref.rhs().size() << " rhs refs will be split.\n");
|
||||
std::vector<SplitNewVar> vars
|
||||
= ref.splitPlan(!varp->isTrace()); // If traced, all bit must be kept
|
||||
= ref.splitPlan(varp, !varp->isTrace()); // If traced, all bit must be kept
|
||||
if (vars.empty()) continue;
|
||||
if (vars.size() == 1 && vars.front().bitwidth() == varp->width())
|
||||
continue; // No split
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
#!/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(verilator_flags2=['--trace'])
|
||||
|
||||
test.execute()
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2025
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t(/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
bug5782 u_bug5782(.data_out());
|
||||
|
||||
endmodule
|
||||
|
||||
// #5782 internal error with --trace. Bit range is not properly handled.
|
||||
module bug5782 (
|
||||
output logic [31:0][15:0] data_out
|
||||
);
|
||||
logic [31:0][15:0] data [8] /*verilator split_var*/;
|
||||
always begin
|
||||
data_out = data[7];
|
||||
end
|
||||
endmodule
|
||||
Loading…
Reference in New Issue