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

MAC运算模块VCS仿真异常求助:pe_out始终为未知态

问题:VCS仿真MAC运算PE模块时pe_out始终为未知态

我实现了一个完成MAC(乘累加)运算的PE模块,使用VCS仿真时,输出pe_out始终显示为xxxxxxxx(未知态);但用Verilator仿真结果符合预期,且删除代码中的pe_reg <= pe_reg + m_reg语句后,VCS仿真也能正常运行,推测问题出在加法操作环节,但尚未找到解决办法。

PE模块代码

module PE # (
parameter DW = 8
)
(
input clk,
input rst_n,
input  [DW-1 : 0] cin,
input  [DW-1 : 0] w,
output  [DW-1 : 0] cin_out,
output  [DW-1 : 0] w_out,
output [2*DW : 0] pe_out
);

reg [DW-1 : 0] cin_reg;
reg [DW-1 : 0] w_reg;
reg [2*DW : 0] m_reg;
reg [2*DW : 0] pe_reg;


always @(posedge clk) begin
    if(rst_n==1'b0) begin
        pe_reg <= 0;
        cin_reg <= 0;
        w_reg <= 0;
    end
    else begin
        cin_reg <= cin;
        w_reg <= w;
        m_reg <= cin_reg * w_reg;
        pe_reg <= pe_reg + m_reg;
    end
end

assign cin_out = cin_reg;
assign w_out = w_reg;
assign pe_out = pe_reg;

endmodule

测试平台代码

module tb_PE;

reg clk;
reg rst_n;
reg [7:0] cin;
reg [7:0] w;

wire [7:0] cin_out;
wire [7:0] w_out;
wire [16:0] pe_out;
wire [16:0] pe_out_tmp;

initial begin
    clk = 0;
    forever begin
        #10;
        clk = ~clk;
    end
end

initial begin
    rst_n = 1'b1;
    #5;
    rst_n = 1'b0;
    #10;
    rst_n = 1'b1;
    #5;
    cin = 8'h01;
    w = 8'h02;
    #15;
    cin = 8'h03;
    w = 8'h04;
    #20;
    cin = 8'h05;
    w = 8'h03;
    #20;
    cin = 8'h90;
    w = 8'h88;
    #20;
    cin = 8'h65;
    w = 8'h20;
    #100;
    $finish;

    PE PE_U (
        .clk(clk),
        .rst_n(rst_n),
        .cin(cin),
        .w(w),
        .cin_out(cin_out),
        .w_out(w_out),
        .pe_out(pe_out)
    );
end

endmodule

排查指导

  • 补全寄存器复位初始化:
    当前代码中m_reg未在复位块中初始化,虽然复位时cin_reg和w_reg为0,相乘结果应为0,但VCS对未初始化寄存器的检查更严格,建议在复位块中添加m_reg <= 0;,确保所有寄存器在复位时都被明确置0。

  • 调整测试平台模块例化位置:
    测试平台中PE_U的例化放在了initial块内部,部分仿真器对这种嵌套例化的时序解析可能存在问题。建议将模块例化移到所有initial块之外,作为顶层模块的直接语句,避免时序解析异常。

  • 显式指定无符号运算:
    虽然代码中变量默认是无符号类型,但VCS可能在某些场景下对符号扩展处理不同。尝试在乘法和加法操作中显式指定无符号:

    m_reg <= $unsigned(cin_reg) * $unsigned(w_reg);
    pe_reg <= $unsigned(pe_reg) + $unsigned(m_reg);
    

    避免隐式符号转换导致的未知态。

  • 添加调试打印语句:
    在PE模块的always块中添加打印语句,实时输出寄存器值,确认运算过程中是否出现未知态:

    always @(posedge clk) begin
        if(rst_n==1'b0) begin
            pe_reg <= 0;
            cin_reg <= 0;
            w_reg <= 0;
            m_reg <= 0;
        end
        else begin
            cin_reg <= cin;
            w_reg <= w;
            m_reg <= cin_reg * w_reg;
            pe_reg <= pe_reg + m_reg;
            $display("[%0t] cin_reg=0x%h, w_reg=0x%h, m_reg=0x%h, pe_reg=0x%h", $time, cin_reg, w_reg, m_reg, pe_reg);
        end
    end
    

    通过打印信息定位是乘法还是加法环节引入了未知态。

  • 检查VCS编译选项:
    编译时添加-warn uninitialized选项,检查是否存在未初始化的变量;添加-debug_all选项后用DVE调试,查看pe_reg每一位的状态,确认未知态的来源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 01:50:26