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

Verilog算术单元模块输出为'Z'而非数值的问题排查求助

Verilog算术单元输出'Z'问题排查与修复

核心错误点

  1. 全加器逻辑实现错误
    原full_adder用两个半加器级联的方式完全错误,输出的sum和carry不符合全加器的数学逻辑,导致加法计算彻底失效。

  2. 加法链布线逻辑混乱

    • 全加器端口映射错误:原代码将前一级的sum作为下一级全加器的输入,而非将前一级的进位输出作为下一级的进位输入,完全违背加法器级联的基本逻辑。
    • 共享进位信号引发多驱动冲突:所有加法单元共用同一根carry_out wire,多个模块同时驱动同一线网会导致信号冲突,出现不确定值或高阻态。
  3. sum数组大量位悬空
    sum[3]到sum[14]没有任何逻辑驱动,这些位处于高阻'Z'状态,导致整个sum总线包含'Z',赋值给result后输出自然为'Z'。

  4. difference信号未定义
    difference仅声明但未实现任何减法逻辑,若选择减法操作(2'b01)同样会输出'Z'。

  5. fa16连接错误
    将sum[15]同时作为全加器的输入和输出,造成线网短路,逻辑完全无效。

修正后的完整代码

1. 半加器(逻辑正确,保留)

module half_adder (
  input a,
  input b,
  output sum,
  output carry
);
  assign sum = a ^ b;
  assign carry = a & b;
endmodule

2. 修正全加器逻辑

module full_adder (
  input a,
  input b,
  input c_in,
  output sum,
  output carry
);
  // 符合数学逻辑的全加器实现
  assign sum = a ^ b ^ c_in;
  assign carry = (a & b) | (a & c_in) | (b & c_in);
endmodule

3. 重构算术单元模块

module arithmetic_unit (
  input [15:0] a,
  input [15:0] b,
  input [1:0] operation,
  output reg [31:0] result
);
  wire [15:0] sum, difference;
  wire [15:0] add_carry; // 加法链的每一级进位信号

  // 16位加法器级联实现
  half_adder ha_add0 (a[0], b[0], sum[0], add_carry[0]);
  genvar i;
  generate
    for(i=1; i<16; i=i+1) begin : add_stages
      full_adder fa_add (a[i], b[i], add_carry[i-1], sum[i], add_carry[i]);
    end
  endgenerate

  // 补码减法实现:a - b = a + (~b + 1)
  wire [15:0] b_neg = ~b + 1'b1;
  wire [15:0] sub_carry;
  half_adder ha_sub0 (a[0], b_neg[0], difference[0], sub_carry[0]);
  generate
    for(i=1; i<16; i=i+1) begin : sub_stages
      full_adder fa_sub (a[i], b_neg[i], sub_carry[i-1], difference[i], sub_carry[i]);
    end
  endgenerate

  // 组合逻辑使用阻塞赋值更规范
  always @* begin
    case(operation)
      2'b00: result = {16'b0, sum}; // 将16位结果扩展为32位输出
      2'b01: result = {16'b0, difference};
      2'b10: result = a * b; // Verilog原生支持乘法,自动处理位数匹配
      2'b11: result = a / b;
      default: 
        result = 32'b0;
    endcase
  end
endmodule

4. 增强测试平台(覆盖多场景)

module test_arithmetic_unit;
  reg [15:0] a, b;
  reg [1:0] operation;
  wire [31:0] result;

  arithmetic_unit au (a, b, operation, result);

  initial begin
    // 加法测试
    a <= 10;
    b <= 5;
    operation <= 2'b00;
    #10;
    $display("加法: %d + %d = %d", a, b, result);

    // 减法测试
    a <= 10;
    b <= 5;
    operation <= 2'b01;
    #10;
    $display("减法: %d - %d = %d", a, b, result);

    // 乘法测试
    a <= 10;
    b <= 5;
    operation <= 2'b10;
    #10;
    $display("乘法: %d * %d = %d", a, b, result);

    // 除法测试
    a <= 10;
    b <= 5;
    operation <= 2'b11;
    #10;
    $display("除法: %d / %d = %d", a, b, result);

    $finish;
  end
endmodule

关键说明

  • 用generate语句实现16位加法/减法链,避免重复代码,确保每一位都被正确驱动,无悬空信号。
  • 减法通过补码方式复用加法器,减少逻辑冗余。
  • 组合逻辑always @*块使用阻塞赋值=,符合Verilog编码规范,避免不必要的时序问题。
  • 将16位运算结果扩展为32位输出,避免位数截断导致的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 08:37:06