You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 09:15:29