SystemVerilog中wire型数组OR归约操作异常问题咨询
wire型数组OR归约异常问题解析
问题描述
对数组执行OR归约操作时,reg型数组的结果符合预期,但wire型数组仅最后一个元素参与了归约运算,导致结果错误。预期out1与out2结果一致,但实际仿真波形显示两者行为差异明显。
复现代码
module tst_reduction; parameter DATA_WIDTH = 3; parameter SIZE = 4; reg [DATA_WIDTH-1:0] m [SIZE-1:0]; wire [DATA_WIDTH-1:0] m1 [SIZE-1:0]; wire [DATA_WIDTH-1:0] out1; wire [DATA_WIDTH-1:0] out2; assign m1 = m; assign out1 = m.or(); // reg型数组,结果正常 assign out2 = m1.or(); // wire型数组,仅最后一个元素参与运算 integer i, j; initial begin m = {0, 0, 0, 0}; for (i = 0; i < SIZE; i = i + 1) begin for (j = 0; j < 2**DATA_WIDTH; j = j + 1) begin #10; m[i] = j; end; #10; m[i] = 0; end #10; end endmodule
原因分析
这是仿真器对SystemVerilog语法实现的差异问题:
reg型非合并数组的.归约方法(如or())被仿真器正确实现,会遍历所有元素完成运算。- 但对于
wire型非合并数组,部分仿真器未正确支持这种归约方法,内部仅返回数组最后一个元素的值,而非所有元素的OR结果。
正确实现方式
以下两种方法可可靠实现wire型数组的OR归约:
方法1:手动遍历数组实现归约
通过组合逻辑循环遍历所有元素,逐个执行OR运算:
// 替换原out2的assign语句 logic [DATA_WIDTH-1:0] temp_or; always_comb begin temp_or = '0; for (int k = 0; k < SIZE; k++) begin temp_or |= m1[k]; end end assign out2 = temp_or;
方法2:转换为合并数组后归约
先将非合并的wire数组按位提取为一维数组,再对每一位执行归约OR:
// 替换原out2的assign语句 wire [DATA_WIDTH-1:0] out2; generate // 对每一位单独处理 for (int bit_idx = 0; bit_idx < DATA_WIDTH; bit_idx++) begin wire [SIZE-1:0] bit_array; // 提取所有数组元素的第bit_idx位 for (int arr_idx = 0; arr_idx < SIZE; arr_idx++) begin assign bit_array[arr_idx] = m1[arr_idx][bit_idx]; end // 对该位的所有元素执行OR归约 assign out2[bit_idx] = |bit_array; end endgenerate
效果验证
采用上述任意一种方法修改代码后,out2会和out1的行为完全一致,所有数组元素都会参与OR归约运算。
内容的提问来源于stack exchange,提问作者maestro
相关产品推荐
相关产品推荐

