Fix streaming dynamic arrays with different element types failing to compile (#8434) (#8435)

This commit is contained in:
Kristof Marien
2026-09-21 20:57:03 -04:00
committed by GitHub
parent 9ca90f414c
commit a50aea7709
3 changed files with 80 additions and 8 deletions
+24 -8
View File
@@ -2948,8 +2948,8 @@ inline void VL_ZERO_INIT_QUEUE_ELEM(VlWide<N_Words>& elem) {
for (size_t j = 0; j < N_Words; ++j) { elem.at(j) = 0; }
}
// This specialization works for both VlQueue<CData> (and similar) as well
// as VlQueue<VlWide<N>>.
// These overloads work for both VlQueue<CData> (and similar) as well
// as VlQueue<VlWide<N>>, including queues with different element types.
template <typename T>
inline void VL_COPY_Q(VlQueue<T>& q, const VlQueue<T>& from, int /*lbits*/, int srcElementBits,
int dstElementBits) {
@@ -2971,16 +2971,32 @@ inline void VL_COPY_Q(VlQueue<T>& q, const VlQueue<T>& from, int /*lbits*/, int
}
}
// This specialization works for both VlQueue<CData> (and similar) as well
// as VlQueue<VlWide<N>>.
template <typename T>
inline void VL_REVCOPY_Q(VlQueue<T>& q, const VlQueue<T>& from, int lbits, int srcElementBits,
int dstElementBits) {
// Keep the same-type overload separate for its direct-copy optimization and alias handling;
// differently typed queues cannot alias.
template <typename T_Dst, typename T_Src>
inline typename std::enable_if<!std::is_same<T_Dst, T_Src>::value>::type
VL_COPY_Q(VlQueue<T_Dst>& q, const VlQueue<T_Src>& from, int /*lbits*/, int srcElementBits,
int dstElementBits) {
const size_t srcTotalBits = from.size() * srcElementBits;
const size_t dstSize = (srcTotalBits + dstElementBits - 1) / dstElementBits;
q.renew(dstSize);
for (size_t i = 0; i < dstSize; ++i) { VL_ZERO_INIT_QUEUE_ELEM(q.atWrite(i)); }
for (size_t bitIndex = 0; bitIndex < srcTotalBits; ++bitIndex) {
VL_SET_QUEUE_BIT(q, dstElementBits, bitIndex,
VL_GET_QUEUE_BIT(from, srcElementBits, bitIndex));
}
}
// This works for both VlQueue<CData> (and similar) as well as VlQueue<VlWide<N>>,
// including queues with different element types.
template <typename T_Dst, typename T_Src>
inline void VL_REVCOPY_Q(VlQueue<T_Dst>& q, const VlQueue<T_Src>& from, int lbits,
int srcElementBits, int dstElementBits) {
const size_t srcTotalBits = from.size() * srcElementBits;
const size_t dstSize = (srcTotalBits + dstElementBits - 1) / dstElementBits;
// Always make a copy to handle the case where q and from are the same queue
VlQueue<T> srcCopy = from;
VlQueue<T_Src> srcCopy = from;
// Initialize all elements to zero using appropriate method
q.renew(dstSize);
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 Wilson Snyder
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
test.compile()
test.execute()
test.passes()
@@ -0,0 +1,38 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2026 by Verilator Authors.
// SPDX-FileCopyrightText: 2026 Wilson Snyder
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define checkh(gotv, expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
// verilog_format: on
module t;
bit source_bits[];
int unsigned destination_words[];
initial begin
source_bits = new[37];
source_bits[0] = 1;
source_bits[2] = 1;
source_bits[5] = 1;
source_bits[31] = 1;
source_bits[36] = 1;
destination_words = {>>{source_bits}};
`checkh(destination_words.size(), 2);
`checkh(destination_words[0], 32'ha4000001);
`checkh(destination_words[1], 32'h08000000);
destination_words = {<<{source_bits}};
`checkh(destination_words.size(), 2);
`checkh(destination_words[0], 32'h84000001);
`checkh(destination_words[1], 32'h28000000);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule