· 5 min read

RV32M Multiply/Divide Unit: 3-Cycle Mul, 32-Cycle Div

A multi-cycle RV32M unit implementing pipelined 33×33-bit multiplication (3 cycles) and restoring division with sign correction (32 cycles) — handling divide-by-zero and INT_MIN overflow edge cases.

#risc-v #mul-div #arithmetic #deep-dive

TL;DR

3 周期流水线乘法 + 32 周期恢复余数除法,FSM 控制,处理除零/溢出边界。

1. RV32M Extension

RV32M 在 RV32I 基础整数指令集上新增 8 条指令:

指令操作说明
MULrd = (rs1 × rs2)[31:0]低 32 位乘积
MULHrd = (rs1 × rs2)[63:32]有符号 × 有符号,高 32 位
MULHSUrd = (rs1 × rs2)[63:32]有符号 × 无符号,高 32 位
MULHUrd = (rs1 × rs2)[63:32]无符号 × 无符号,高 32 位
DIVrd = rs1 / rs2有符号除法
DIVUrd = rs1 / rs2无符号除法
REMrd = rs1 % rs2有符号取余
REMUrd = rs1 % rs2无符号取余

2. Multiplier: 3-Cycle Pipelined

Cycle 1 ──▶ a_reg  <= {sign_ext, rs1}
             b_reg  <= {sign_ext, rs2}
             └─ 33-bit sign-extended operands registered

Cycle 2 ──▶ mul_stage1 <= a_reg × b_reg
             └─ 33×33 → 66-bit product, registered

Cycle 3 ──▶ mul_stage2 <= mul_stage1
             └─ output stable, select bits based on MUL/MULH/MULHSU/MULHU

33×33 乘法覆盖所有变体:将两个操作数做符号扩展到 33 位后相乘,再根据指令类型选取 66 位结果的对应字段。

3. Divider: Restoring Division

恢复余数除法 (Restoring Division) 的 FSM:

┌──────────┐     ex_valid & ex_ready
│   IDLE   │──────────────────────────▶┌────────────┐
└──────────┘                           │ CALCULATING │
     ▲                                 └──────┬──────┘
     │  remainder == 0 || quotient == 0       │
     │  或 (cycle_count == 31)                │
     │                                        │
     │          ┌─────────────┐               │
     │◀─────────│   DONE      │◀──────────────┘
     │          └─────────────┘
     │                    │
     └────────────────────┘

每个计算周期:比较 remainder 与 (divisor << shift),若够减则减去并置商位为 1,否则商位为 0。32 位除法需 32 个计算周期。

4. Edge Cases

场景结果
除数 = 0quotient = -1 (0xFFFFFFFF), remainder = dividend
INT_MIN / -1quotient = INT_MIN, remainder = 0(避免有符号溢出)
// 除零处理
if (divisor == 32'b0) begin
    quotient  <= 32'hFFFFFFFF;  // -1
    remainder <= dividend;
end
// INT_MIN / -1 溢出处理
else if (dividend == 32'h80000000 && divisor == 32'hFFFFFFFF) begin
    quotient  <= 32'h80000000;  // INT_MIN
    remainder <= 32'b0;
end

5. Integration with Pipeline

  • 乘法器:3 周期延迟,通过流水线寄存器连续接收新乘法请求
  • 除法器:最多 32 周期延迟,FSM 控制
  • 停顿控制ex_ready 信号在计算未完成时为 0,前端停顿 (stall) 等待结果
  • 写回仲裁:乘法器和除法器共享写回端口,由优先级选择器仲裁

Related Articles:

🔙 Back to Projects