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
相关产品推荐
相关产品推荐

