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

SystemVerilog Layer模块输出为1而非11的问题排查与修正请求

SystemVerilog加权求和模块输出错误排查与修正

问题描述

编写实现输入与对应权重加权求和的Layer模块,测试时输出为1.0000而非预期的11.0000。使用Icarus Verilog仿真,编译命令为iverilog -g2012 -o output layer.sv main.sv,仿真命令为vvp output。

原模块代码

module Layer #(parameter num_inps=2)(out, inps, ws, clk, rst);
    output reg out;
    input real inps[num_inps];
    input logic clk, rst;
    input real ws[num_inps];
    real temp[num_inps];
    genvar i;
    generate
        for(i=0; i<num_inps; i++) begin
            assign temp[i] = inps[i] * ws[i];
        end
    endgenerate
    always @( posedge clk, posedge rst) begin : res
        if (rst==1) begin
            out = 0;
        end
        else begin
            out = 0;
            begin
                for(int j=0; j<num_inps; j++) begin
                    out = out + temp[j];
                end
            end
        end
    end
endmodule

原测试平台代码

module main_tb();
real out;
real inps[2], ws[2];
logic clk, rst;
Layer l1(out, inps, ws, clk, rst);
initial begin
    $dumpfile("ow.vcd");
    $dumpvars(0, l1);
    inps[0] = 1.0;
    inps[1] = 2.0;
    ws[0] = 5.0;
    ws[1] = 3.0;
    rst = 0;
    clk = 0;
    #10
    clk = 1;
    #10
    clk = 0;
    $display(out);
    #10
    $finish;
end
endmodule

错误原因

  1. 输出变量类型未明确声明:模块中output reg out;未指定数据类型,默认是单bit的reg(等价于reg [0:0] out),无法存储实数类型的加权求和结果。当实数赋值给单bit变量时,会被截断为最低位二进制值(5.0和3.0的二进制最低位均为1),最终累加结果为1,测试平台中real类型的out读取到该值后显示为1.0000。
  2. 初始化值类型不匹配:always块中用整数0初始化实数结果,虽然会隐式转换,但建议显式使用实数0.0以避免歧义。

修正后的代码

Layer模块

module Layer #(parameter num_inps=2)(out, inps, ws, clk, rst);
    output reg real out; // 明确声明为real类型的时序输出
    input real inps[num_inps];
    input logic clk, rst;
    input real ws[num_inps];
    real temp[num_inps];
    genvar i;
    generate
        for(i=0; i<num_inps; i++) begin
            assign temp[i] = inps[i] * ws[i];
        end
    endgenerate
    always @( posedge clk, posedge rst) begin : res
        if (rst) begin
            out = 0.0; // 显式用实数初始化
        end
        else begin
            out = 0.0;
            for(int j=0; j<num_inps; j++) begin
                out = out + temp[j];
            end
        end
    end
endmodule

测试平台(优化版)

module main_tb();
real out;
real inps[2], ws[2];
logic clk, rst;
// 使用命名端口连接,提升代码可读性与维护性
Layer #(.num_inps(2)) l1(
    .out(out),
    .inps(inps),
    .ws(ws),
    .clk(clk),
    .rst(rst)
);
initial begin
    $dumpfile("ow.vcd");
    $dumpvars(0, l1);
    inps[0] = 1.0;
    inps[1] = 2.0;
    ws[0] = 5.0;
    ws[1] = 3.0;
    rst = 0;
    clk = 0;
    #10
    clk = 1;
    #10
    clk = 0;
    $display("输出结果:%f", out); // 格式化输出,便于查看
    #10
    $finish;
end
endmodule

验证结果

执行原编译与仿真命令后,将输出预期的输出结果:11.000000。

内容的提问来源于stack exchange,提问作者kushurox TW

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 13:22:18