# Multiply/Divide Unit (MDU) Research

## Status

Stub document. No XH-1 design decisions are committed. This document surveys established techniques and frames the design space for the XH-1 multiplier/divider; it does not invent measurements, benchmarks, or fabricated citations.

## Abstract

The multiply/divide unit (MDU) is responsible for executing the RISC-V `M`-extension instructions (and, optionally, the `B`-extension bitmanipulation and the proposed vector crypto/poly extensions) on each XH-1 core. In a 128-core machine replicated across a tiled fabric, the MDU is a notable contributor to per-core area and to the critical path, while rarely being the limiter of sustained throughput. This document reviews the design space (array vs. tree multipliers, radix selection, division algorithms, divide latency hiding, fused MAC, early-exit/lower-result handling, and the treatment of `MULH/MULHU/MULHSU`) and surfaces the trade-offs that interact with the rest of the XH-1 core and with multi-core scalability.

## Research Question

What MDU microarchitecture for the XH-1 core best balances the following, given that the core is replicated 128 times on die and shares die-wide resources through a tiled fabric?

- Per-operation latency for signed/unsigned multiply, multiply-high, and signed/unsigned divide/remainder.
- Sustained throughput (cycles/issue) at 1 MDU per core.
- Area per core (silicon cost × 128).
- Worst-case power and energy per operation.
- Critical-path impact on the core's clock period.
- Verification complexity (correctness across the 128-bit, signed/unsigned, divide-by-zero, and overflow corner cases of the RISC-V `M` extension).
- Software implications: predictable timing, RV64 vs. RV32 register-file layout for `MULH*`, and constant-time considerations for cryptographic code.

## Background

### RISC-V `M` Extension Requirements

The RISC-V `M` extension defines a small, orthogonal set of operations, all operating on the base integer register width (XLEN = 32 for RV32, 64 for RV64):

- `MUL` / `MULW` — lower-XLEN bits of a product.
- `MULH` — upper XLEN bits, signed × signed.
- `MULHU` — upper XLEN bits, unsigned × unsigned.
- `MULHSU` — upper XLEN bits, signed × unsigned.
- `DIV` / `DIVU` / `DIVW` / `DIVUW` — signed/unsigned quotient, truncated toward zero.
- `REM` / `REMU` / `REMW` / `REMUW` — remainder, sign follows the dividend.
- For RV64, the `W` variants operate on 32-bit values and sign-extend the 32-bit result to 64 bits.

`MULH*` is the operation that forces the hardware to compute a 2·XLEN-bit product; this is the dominant cost in the multiply datapath. The `MUL` lower result is normally a free byproduct of that same 2·XLEN product.

The `M` extension specifies architectural behavior (truncation, signed/unsigned interaction, divide-by-zero) but does not prescribe a microarchitecture, latency, or throughput. This makes `M` a high-leverage, ISA-allowed design decision.

### Why `M` Matters on XH-1

In a tiled 128-core processor, each core typically has its own integer `M` unit rather than a shared, chip-wide multiply unit. The reasons are:

- The wire delay of routing two 64-bit operands to a shared unit at die-crossing distance is incompatible with low-latency operation.
- Multiplication is on the critical path of many kernels (FFT inner loops, matrix arithmetic, hash functions, address computation in some interpreters).
- Local replication, while more silicon, is the conventional answer.

The MDU therefore contributes to the area of *every* tile. The product of its area cost and 128 is a first-order driver of die cost.

## Existing Approaches

### Multiplication

- **Carry-save adder (CSA) array.** A simple, dense, rectangular array of full adders that reduces partial-product bits over XLEN/2 stages. Latency scales linearly with operand width. Easy to layout; long critical path.
- **Wallace tree.** A logarithmic-depth reduction tree using CSAs; faster than an array but irregular in shape, which complicates physical design at large widths.
- **Dadda tree.** A variant of Wallace that uses a slightly larger first stage to reduce the number of subsequent reductions. Often compared in the literature as a near-equivalent point in the area/time design space.
- **Booth-recoded multiplier.** Recodes one operand (radix 4, radix 8, or higher) to halve or quarter the partial-product count. Radix-4 Booth is the workhorse in many cores; radix-8 reduces PP count further at the cost of harder selection logic and tripling the addition tree. Recoding is most useful when the operand width is large.
- **"Two-cycle" or "pipelined" iterative multiplier.** Uses a small, fixed datapath and iterates over the operand width. Saves area but increases latency to many cycles; throughput is one multiply every N cycles unless multiple independent multiplies are interleaved.
- **Fused multiply–add (FMA).** Single instruction producing `a*b + c` with one rounding. Standard in vector/GPPU ISAs; not part of base scalar RISC-V `M`, but a candidate addition. RISC-V does define `Zfa` (floating point) and vendor extensions may include integer FMA.
- **"MUL + MULH" single 2·XLEN-bit product.** A unified datapath that produces the full double-width product, from which both `MUL` and `MULH*` are sliced. Standard approach; reduces logic vs. two separate multipliers but requires a wide (2·XLEN-bit) adder at the end.

### Division

- **Non-restoring and restoring shift/subtract divider.** A 2·XLEN-iteration loop that produces one quotient bit per cycle; latency scales linearly with operand width. Simple but slow.
- **SRT divider (radix-2, radix-4, radix-8, radix-16).** A redundant representation (carry-save) of the partial remainder allows selection of a small set of quotient digits per cycle. Latency scales as 2·XLEN / log2(radix) cycles. SRT is the dominant technique for high-performance scalar cores; it has a well-known hard corner case around the most negative dividend divided by −1.
- **Newton–Raphson reciprocal + multiply.** Two multiplications of the reciprocal approximation, then a final multiply by the dividend. Latency roughly 2–3 multiplies, with small additional control. The classic micro-architectural fast-path: high throughput, but long tail latency and large area (needs a multiplier and a ROM of initial approximations). Inappropriate as the *only* divider in a scalar core that needs a deterministic `DIV` latency for compiler-emitted code; often used in vector/GPU contexts.
- **Goldschmidt division.** Iterative convergence, similar trade-offs to Newton–Raphson but with different numerical subtleties.
- **Lookup-table-based constant division.** Replacing division by a small set of "magic numbers" (Hacker's Delight style) at compile time. *Software-side*; not a hardware option, but interacts with the hardware because the `M` ISA is not required for software to be efficient if the compiler can reduce the division to a multiply-shift. The hardware must still service any `DIV` it does see.
- **"Divider bypass" / radix-2^k with table-driven selection.** Industry workhorse: a redundant (carry-save) partial remainder plus a small quotient-digit selector table per radix step. Closely related to SRT.

### Multiply-Accumulate and Fused Operations

- **Fused MAC.** `a*b + c` in one cycle of the MAC pipeline, sharing the partial-product reduction tree with a free accumulator adder.
- **Multiply-add with rounding** is a floating-point concept; integer fused MAC is occasionally added as a vendor extension.

## Alternative Designs

The design space reduces to a small set of choices:

1. **Unified 2·XLEN-bit multiplier for `MUL` + `MULH*`.** This is the common choice for RV64.
2. **Separate small multiplier for `MUL`/`MULW`, separate datapath for `MULH*`.** Avoids paying for the full 2·XLEN product on every multiply, at the cost of a wider muxes and a longer `MULH*` critical path.
3. **Array vs. tree.** A rectangular CSA array (small, slow) vs. a Wallace/Dadda tree (fast, irregular) vs. a Booth-recoded array (moderate area, moderate speed).
4. **Iterative vs. combinational multiplier.** Iterative saves area but introduces multi-cycle latency and an extra pipeline stage (or stall) on `MULH*`.
5. **Division algorithm.** SRT radix-2/4/8 vs. shift/subtract vs. Newton–Raphson vs. software-emulated via reciprocal multiply.
6. **Pipelined MDU vs. non-pipelined.** Issue one MDU instruction per cycle (pipelined), one per N cycles (unpipelined with repeat-in-flight not allowed), or some hybrid.
7. **32-bit `W` variants.** Either share the XLEN-wide datapath and sign-extend at the end (no real saving) or use a 32-bit-wide fast path (area saved but a second critical path to verify).
8. **Constant-time guarantees.** Some software (notably cryptographic) requires `MULH*` and `DIV*` to be data-independent in time. This constrains early-exit and early-out optimizations.

## Comparison

The trade-space can be characterized along a small number of axes. Without committing to a specific process node or to fabricated measurements, the qualitative relationships are:

- **Latency vs. area (multiply).** A combinational Wallace or Booth-radix-4 tree is faster than a CSA array of equivalent width at the cost of irregular layout. An iterative multiplier is smallest in area but slowest in latency (linear in operand width per multiply).
- **Latency vs. area (divide).** Radix-4 SRT divides in roughly half the cycles of radix-2 SRT at modest area increase; radix-8 trades more selector-table area for a further 2× reduction in iterations. Newton–Raphson is fastest in *latency* on a fully pipelined multiplier but requires the core to already have a fast multiplier and adds a reciprocal ROM.
- **Throughput vs. latency.** Pipelined designs match the issue rate of the core but cost a register stage and additional bypassing; unpipelined designs cost only one execution slot but force back-to-back `MUL`s to serialize.
- **Verification cost.** A small iterative multiplier is the easiest to formally reason about (one bit-slice repeated). A high-radix SRT with a partial-remainder selector and overlapped radix steps is the hardest.

The combinations that are *not* useful tend to be those that pay for a high-radix divider while leaving a slow multiplier next to it (the divider tail latency is masked by the slow multiplier, but the area is paid).

## Advantages

- A unified 2·XLEN-bit multiplier lets `MUL` and `MULH*` share the partial-product reduction tree, removing duplicated logic.
- A pipelined MDU removes a back-to-back multiply hazard at the cost of a single register stage, which is essentially free in any pipeline that already has a multi-cycle execution unit.
- SRT division is well-studied, has well-known implementation recipes, and matches the area budget of most scalar cores.
- A non-pipelined iterative divider is the smallest possible area for a working `DIV` and is acceptable when software rarely emits `DIV`.

## Disadvantages

- A 64×64 → 128 CSA array is roughly proportional to `XLEN^2` and is a noticeable per-core cost in any high-density core; on a 128-core die, this multiplies.
- Newton–Raphson division has long, variable latency that is hard to expose to the front end without reservation-station machinery that the rest of the core may not need.
- SRT radix ≥ 4 has a notorious most-negative-dividend divided by −1 corner case; correctly handling this requires either an extra cycle or a small fix-up datapath, both of which need verification.
- Early-exit optimizations (e.g., detecting a small result and short-circuiting a wide multiply) introduce data-dependent latency, which is a correctness hazard for some software and a verification hazard in any case.
- A `W`-variant fast path that bypasses the upper 32 bits of the multiplier introduces a second timing path through the MDU.

## XH-1 Considerations

- **XLEN.** The repository context has not been provided. If the XH-1 core is RV64, the MDU is a 64×64 → 128 datapath with a 64-bit signed/unsigned unit. If RV32, the MDU is 32×32 → 64. The `MULH*` requirement for RV64 is the dominant datapath driver and is the main reason the MDU is non-trivial in area.
- **Pipeline depth.** The MDU's latency interacts with the core's pipeline. If the core is in-order with a single execution stage, an iterative multiplier is mandatory. If the core is in-order with multiple execution stages, a pipelined MDU fits naturally. If the core is out-of-order, the MDU's result is a producer into the register file through the wakeup/select path; latency is largely hidden, but area and worst-case occupancy still matter.
- **Scalar-only context.** Unless the XH-1 core also implements a vector unit that needs higher-throughput `MUL`/`MUL`+`ADD`, the MDU is a single-issue scalar unit; this means a non-pipelined design with a throughput of 1 per N cycles is architecturally acceptable if the compiler can be guided to use shifts and adds for short multiplies.
- **Bypassing.** A pipelined MDU that issues one multiply per cycle needs a writeback port and a bypass network entry; this interacts with the register file. A non-pipelined iterative MDU needs only a writeback port and uses the issue queue's dependency tracking.
- **Reset and OS save/restore.** A divide that takes > 50 cycles can be problematic on context switch if not interruptible. Most simple cores either don't accept interrupts mid-divide (it must complete) or save the partial-remainder registers. This is a design decision for the MDU.

## 128-Core Scalability

- **Replication cost.** The MDU's per-core area cost is multiplied by 128. For a unified 64×64 → 128 tree, the per-core cost is meaningful; for an iterative 32-bit-equivalent datapath, it is small.
- **Shared unit rejected.** A single die-wide MDU serving all 128 cores is generally not used for `M` operations because (a) the wire delay of moving two 64-bit operands to a central point at 128-core die dimensions is too long to keep MDU latency low, and (b) contention on a single MDU among 128 cores would make `MUL` throughput effectively a global bottleneck. This is a standard assumption; ASSUMPTION: the XH-1 is a tiled fabric where the cost of a global MDU exceeds the cost of replication.
- **Variability.** Per-core MDUs make timing variability a per-tile concern. The chip-wide clock has to accommodate the slowest tile's MDU, so a fast core with a small MDU is paid for by every other tile.
- **Power gating.** Per-core MDUs are excellent candidates for clock- or power-gating when a tile is idle. A 128-core die can shut down 100+ MDUs during low utilization. This is a meaningful power-saving lever.

## Performance Considerations

- **Latency targets.** Without a specific frequency target for XH-1, latency cannot be quoted in nanoseconds. In cycle terms:
  - An iterative 64-bit multiplier on a 3 GHz in-order core: 32–64 cycles, depending on radix.
  - A pipelined 64-bit multiplier: 1–3 cycles issue-to-writeback, depending on pipeline depth.
  - An SRT-4 64-bit divider: ~32 quotient digits + a few cycles of fixup.
  - An SRT-8 64-bit divider: ~16–20 cycles.
  - Newton–Raphson: 2 multiplies + a couple of fixup cycles; *latency* can be lower than SRT if the multiplier is fast, *throughput* is the same.
- **Compiler guidance.** Modern compilers reduce `DIV` by a constant to a multiply-shift sequence; the runtime `DIV` is most often a *variable* divide. This argues for a real divider, but a slow one is acceptable.
- **Software-emulated `DIV`.** A `DIV` can be replaced by a software Newton–Raphson routine in a few hundred instructions. This is a fallback the OS can use; it argues that the *minimum acceptable* MDU can be slow.

## Area Considerations

ASSUMPTION: rough relative area figures (not fabrication-specific):

- A 64×64 → 128 CSA array, bit-serial style: large, rectangular, ~`XLEN^2` full adders. Comparable to a wide register file in cost.
- A 64×64 → 128 Booth-radix-4 array: about half the partial products, larger selector muxes per PP; net smaller than naive array, larger than tree.
- A 64×64 → 128 Wallace/Dadda tree: smaller than array, irregular layout.
- A radix-4 SRT-4 divider: similar order of magnitude to a small multiplier; mostly selector logic and a small ROM.
- A Newton–Raphson reciprocal unit: negligible hardware beyond a fast multiplier; needs a small ROM of initial approximations.

For a 128-core replication, the multiplier's area contribution per tile is the first-order concern; the divider's is a second-order concern.

## Power and Energy Considerations

- **Switching activity.** Multiplication has high switching activity because every partial product is recomputed every cycle in a non-pipelined iterative design, while a fully combinational design has a single very-wide switching event. Energy is generally dominated by the partial-product reduction tree; the choice of array vs. tree changes both energy per op and the energy profile.
- **Clock gating.** A pipelined MDU can clock-gate stages when no multiply is in flight; an iterative MDU only switches the active stage. Both are effective.
- **Power gating.** A 128-core die will spend meaningful time with some tiles idle. Power-gating the MDU on idle tiles is a strong lever.
- **Divide energy.** A long, slow divider is in the *wrong* energy regime: it spends many cycles driving the same datapath at full toggle rate. A faster divider that finishes in fewer cycles can be *lower* energy per `DIV` even though it is larger. PROPOSAL: prefer a higher-radix divider if `DIV` latency matters; prefer a slow divider only if `DIV` is rare and the area is paid for something else.
- **Constant-time software.** Software that needs data-independent timing (crypto) requires the MDU to not take data-dependent shortcuts. This is a *correctness* property for the MDU; it does not change the energy cost of the data-dependent MDU but it rules out early-exit optimizations that would change the energy/latency profile.

## Implementation Considerations

- **Radix choice.** Radix-4 is the workhorse; radix-8 doubles the selector complexity for ~25% area. For an XLEN-64 design, radix-4 with carry-save partial remainder is the conventional balance.
- **Carry-save throughout.** Keeping the partial remainder in carry-save form throughout the divide avoids a wide carry-propagate adder and removes a long wire on the critical path.
- **On-the-fly quotient conversion.** The quotient emerges in a redundant form and must be converted to binary on the fly; this is a known microarchitectural module with well-understood area and timing.
- **Most-negative / -1 corner.** Must be handled explicitly. The standard fix: detect the corner case before the final iteration and produce the architectural result directly.
- **Divide-by-zero.** The architectural behavior is to return `-1` (signed) or `2^XLEN-1` (unsigned) for the quotient, and the dividend as the remainder. Hardware cost: a small fixup mux.
- **MULH*Bypass.** If `MULH*` is rarely used by compiled code, the MDU can be optimized for the `MUL` case and pay a small extra latency on `MULH*`. PROPOSAL: profile, but the ISA does not allow architectural shortcuts, only microarchitectural.
- **Physical design.** A 2·XLEN-bit datapath at 64 bits is wide. Routing of the partial-product matrix to the reduction tree is the dominant physical-design challenge. Floorplanning should be done early.

## Verification Considerations

- **Cross-product with `MULH*`.** The signed/unsigned interaction of the upper-product instruction is the most common source of bugs in DIY MDUs. Cross-product of all four operand sign modes (`±×±` for `MULH`, `±×u` for `MULHSU`, `u×u` for `MULHU`, `±×±` for `MUL`) at all bit patterns at the boundaries (0, 1, −1, 2^XLEN-1, 2^(XLEN-1)) is necessary.
- **Divide corner cases.** Quotient-remainder correctness at: divide-by-zero, most-negative-dividend by −1, 0/anything, anything/1, anything/-1 (signed and unsigned). The −1 case is the dominant bug class.
- **Constant-time verification.** If the XH-1 documentation claims constant-time `MULH*` or `DIV`, that property must be verified at the gate level against the implementation. This is non-trivial; it is a *recommendation* that the XH-1 either explicitly claim constant-time and verify it, or explicitly not claim it.
- **Formal verification.** SRT quotient-digit selection is a small enough state machine to be formally verified; the surrounding microarchitecture (operand sign extension, the −1 corner) usually is not, and is covered by directed tests.
- **128-core replication.** The verification cost of the *per-core* MDU is fixed by the design; the verification cost of the *system* does not multiply because all 128 cores are equivalent. A single strong verification of one core is sufficient.
- **Reset, debug, OS save/restore.** A long-running iterative `DIV` interacts with the OS's context-switch decision. If the MDU exposes internal state to the OS, the OS must save it; if it does not, the OS must wait for the divide to complete. The chosen model must be documented and tested.

## Software Considerations

- **Compiler.** Modern GCC/LLVM emit `MUL`/`MULH*` for native multiplies and emit `DIV`/`REM` for variable division. By-constant division is reduced to a multiply-shift sequence. The MDU must service what the compiler emits, but does not need to be a hero.
- **Runtimes.** `muldi3`, `divdi3`, etc. in libgcc are used when the hardware `M` is unavailable. The presence of `M` removes the need for these; the MDU must be correct enough that software is happy to use it.
- **Cryptographic code.** Side-channel-resistant code (lattice crypto, big-integer arithmetic) wants constant-time multiplies and divides, and often wants the *high* half of a product. A working `MULH*` is a hard requirement for any software doing 128-bit arithmetic on a 64-bit machine.
- **Vector and tensor code.** Inner loops in BLAS and ML kernels use `MUL` and `FMA` heavily; the MDU is a contributor, but in an XH-1 scalar core context it is not the dominant execution unit.
- **Operating system.** The OS's context-switch code does not generally divide; interrupts during a long `DIV` are the only software-visible oddity. A documented, predictable `DIV` latency is what the OS wants.

## Recommendation

**INSUFFICIENT EVIDENCE** to recommend a specific MDU microarchitecture.

The repository context does not establish whether the XH-1 core is in-order or out-of-order, RV32 or RV64, scalar-only or with vector, or what its target frequency and process node are. These are the inputs that determine whether a small iterative multiplier, a pipelined Booth multiplier, or a high-radix SRT divider is the right answer.

What can be recommended with the evidence available:

- RECOMMENDATION: pick one operand width (32 or 64) and a corresponding unified 2·XLEN-bit multiplier that serves both `MUL` and `MULH*`. This is a well-known cost-effective choice; the alternative of separate datapaths is rarely worth the verification cost.
- RECOMMATION: avoid Newton–Raphson as the *only* divider. It is excellent in throughput-oriented contexts and inappropriate for a scalar core that must expose a deterministic `DIV` latency to the compiler.
- RECOMMATION: implement the SRT most-negative / −1 corner case explicitly and verify it formally; this is the single most common bug in homemade MDUs.
- RECOMMATION: do not optimize for early-exit on `MULH*` or `DIV` unless the XH-1 is willing to give up the constant-time property that cryptographic software expects.
- RECOMMATION: power-gate the MDU on idle tiles. On a 128-core die this is a meaningful contributor to idle power.

## Confidence

- FACT: high confidence in the RISC-V `M` ISA's required operations and corner-case behavior. This is normative and stable.
- ASSUMPTION: the XH-1 is a tiled 128-core fabric where global MDU sharing is rejected. Reasonable but not stated by the repository.
- ASSUMPTION: latency and area figures are in qualitative, not quantitative, terms. The relative orderings are well-known; the absolute numbers are not.
- PROPOSAL: the recommendations above are *not* the only valid choices; they are the conservative ones given the missing context.
- OPEN: whether the XH-1 core is in-order, out-of-order, RV32, or RV64.

## Open Questions

1. Is the XH-1 core in-order or out-of-order? This determines whether an iterative MDU's long latency is acceptable or whether a pipelined MDU is needed.
2. Is the XH-1 core RV32 or RV64? This determines whether the MDU is 32×32 or 64×64 and whether `MULH*` exists as a single instruction or only as paired 32-bit halves.
3. What is the target clock frequency and the process node? These determine whether a combinational multiplier fits in one cycle or must be pipelined.
4. Does the XH-1 implement an integer `FMA` or fused MAC? If so, it changes the MDU's role from a producer of products to a producer of products-and-sums, and a different datapath (an extra carry-propagate accumulator) is required.
5. Does the XH-1 implement any bitmanipulation (`B` extension) or cryptography extensions that consume the MDU? In particular, `Zbkb` (bitmanip for crypto) uses `MULH*` heavily; the MDU's `MULH*` throughput matters if those extensions are present.
6. Is constant-time execution a documented property of the XH-1? This constrains MDU microarchitecture.
7. What is the interrupt latency target? A non-interruptible long `DIV` may be unacceptable; an interruptible one requires exposing internal state.
8. Is there a vector unit sharing the MDU? A scalar-only context lets the MDU be single-issue; a shared MDU changes the throughput requirements.
9. How is the XH-1 floorplanned? A 128-core die imposes physical-design constraints on the MDU footprint.
10. What is the software stack's expected division-heavy workload? Cryptographic and big-integer code is `MULH*`-heavy; HPC is `MUL`/FMA-heavy; general-purpose is `DIV`-light. Without an application target, the right balance is unknown.

## Sources

INSUFFICIENT EVIDENCE.

This document deliberately does not invent citations. The RISC-V `M` extension's required operations, corner cases, and architectural behaviors are normative in the *Unprivileged ISA Specification* (RISC-V International), but a specific section and version are not cited here because the XH-1 repository does not pin a version.

Established microarchitectural references that would normally be cited — descriptions of SRT division, Booth recoding, Wallace and Dadda trees, on-the-fly quotient conversion, and the most-negative / −1 corner case fixup — appear in standard computer-arithmetic textbooks and in well-known survey papers, but no specific work is cited here because fabricating a paper title or page number would violate the project's "never invent citations" rule.

Where this document makes quantitative claims (e.g., "an SRT-4 64-bit divider takes ~32 cycles"), the numbers are qualitative estimates, not measured values; the surrounding text says so. If the XH-1 project requires numbers backed by a specific source, the relevant literature should be located and cited by the project's documentation owner.
