Verilog组合逻辑赋值失效:数组输出始终固定为0
问题:Verilator仿真中数组赋值输出不更新的原因
我用Verilog写了一个简单的dummy模块,功能是将输入数组的值复制到输出数组。
模块代码
module dummy ( input clk, input [7:0] vector1 [3:0], output reg [7:0] vector2 [3:0] ); always @* begin for (integer i = 0; i < 4; i = i + 1) begin vector2[i] = vector1[i]; end end endmodule
初始测试平台代码
module tb0; // Inputs reg clk; reg [7:0] data_in1 [3:0]; wire [7:0] result [3:0]; // Instantiate the module under test dummy uut ( .clk(clk), .vector1(data_in1), .vector2(result) ); // Clock generation always begin #5 clk = ~clk; end initial begin clk = 0; data_in1[0] = 8'h00; data_in1[1] = 8'h00; data_in1[2] = 8'h00; data_in1[3] = 8'h00; #10 data_in1[0] = 8'h0f; #10 data_in1[1] = 8'h04; #10 data_in1[2] = 8'h0e; #10 data_in1[3] = 8'h0a; $monitor("Time = %d: data_in1[1] = %d, data_out[1] = %d", $time, data_in1[1], result[1]); #20 $finish; end endmodule
按预期,data_out[1]初始值为0,20时间单位后应变为8'h04,但仿真时该值始终固定为0。
修改后的测试平台代码
我调整了延迟时间,但问题依旧:
module tb0; // Inputs reg clk; reg [7:0] data_in1 [3:0]; // Output wire [7:0] result [3:0]; // Instantiate the module under test dummy uut ( .clk(clk), .vector1(data_in1), .vector2(result) ); // Clock generation always begin #5 clk = ~clk; // Toggle clock every 5 ns end initial begin $monitor("Time = %d: data_in1[1] = %d, data_out[1] = %d", $time, data_in1[1], result[1]); clk = 0; data_in1[0] = 8'h00; data_in1[1] = 8'h00; data_in1[2] = 8'h00; data_in1[3] = 8'h00; #11 data_in1[0] = 8'h0f; #11 data_in1[1] = 8'h04; #11 data_in1[2] = 8'h0e; #11 data_in1[3] = 8'h0a; #20 $finish; end endmodule
仿真输出
Time = 0: data_in1[1] = 0, data_out[1] = 0 Time = 5: data_in1[1] = 0, data_out[1] = 0 Time = 5: data_in1[1] = 0, data_out[1] = 0 Time = 10: data_in1[1] = 0, data_out[1] = 0 Time = 10: data_in1[1] = 0, data_out[1] = 0 Time = 11: data_in1[1] = 0, data_out[1] = 0 Time = 11: data_in1[1] = 0, data_out[1] = 0 Time = 15: data_in1[1] = 0, data_out[1] = 0 Time = 15: data_in1[1] = 0, data_out[1] = 0 Time = 20: data_in1[1] = 0, data_out[1] = 0 Time = 20: data_in1[1] = 0, data_out[1] = 0 Time = 22: data_in1[1] = 4, data_out[1] = 0 Time = 22: data_in1[1] = 4, data_out[1] = 0 Time = 25: data_in1[1] = 4, data_out[1] = 0 ...
原因分析
问题出在Verilator对**非合并数组(unpacked array)**的敏感列表处理逻辑上:
- 你的
vector1定义为[7:0] vector1 [3:0],属于非合并数组(位宽部分是合并维度,索引部分是非合并维度)。 - Verilator默认情况下,
always @*不会对非合并数组的单个元素变化触发敏感——它只会检测整个数组是否被重新赋值,而不会追踪单个元素的更新。因此当你修改data_in1[1]时,Verilator没有识别到这个变化,always @*块不会执行,vector2自然不会更新。
解决方法
可以通过以下几种方式解决:
- 显式指定敏感列表:把
always @*改成always @(vector1[0], vector1[1], vector1[2], vector1[3]),明确监听每个数组元素的变化。 - 使用合并数组:将输入输出数组定义为合并数组,比如
input [3:0][7:0] vector1、output reg [3:0][7:0] vector2,这样always @*能正确检测到数组内元素的变化。 - 升级Verilator版本:较新版本的Verilator对非合并数组的敏感列表处理更符合Verilog标准,能自动识别单个元素的更新。
内容的提问来源于stack exchange,提问作者Goldenalcheese
相关产品推荐
相关产品推荐

