First passed test

This commit is contained in:
riscvcxh1
2026-08-25 20:44:20 +02:00
parent 221a2df0ac
commit 6bcb266d17
44 changed files with 9243 additions and 2 deletions
@@ -0,0 +1,4 @@
2026-08-25T18:39:57Z research/03-core-design/mul-div-unit.md 1 research completed
2026-08-25T18:40:35Z research/03-core-design/mul-div-unit.md 1 review VERDICT: FAIL
2026-08-25T18:41:31Z research/03-core-design/mul-div-unit.md 2 revision completed
2026-08-25T18:41:52Z research/03-core-design/mul-div-unit.md 2 review VERDICT: PASS
@@ -0,0 +1 @@
research/03-core-design/mul-div-unit.md
@@ -0,0 +1,260 @@
# 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.
## Assumptions and Scope
The following assumptions frame the analysis. They are stated explicitly because the XH-1 repository context is not provided in this stub; where evidence is missing, the document says so.
- **ISA width (XLEN).** ASSUMPTION: the XH-1 core is RV64. Rationale: 128-bit results in `MULH*` are most useful when software performs multi-word arithmetic, and a 128-core tiled die is consistent with a server-class 64-bit core. RV32 is treated as a secondary case.
- **Core pipeline style.** ASSUMPTION: the core is in-order with multiple execution stages, to keep the discussion concrete. Out-of-order is acknowledged as a different design point.
- **Clocking.** ASSUMPTION: a single chip-wide clock domain with per-tile clock gating. Per-tile DVFS is not assumed. INSUFFICIENT EVIDENCE to choose otherwise.
- **Process node / cell library.** Not assumed. The document discusses area and power only in qualitative, relative terms.
- **Frequency target.** Not assumed. Latency claims are stated in cycles, not nanoseconds.
- **Vector / shared MDU.** ASSUMPTION: scalar-only context without a vector unit sharing the MDU.
- **Extensions.** ASSUMPTION: base RISC-V `M` is implemented. `B`, `K`, and vector-crypto extensions are not assumed present; their interaction with the MDU is discussed only as a scaling consideration.
INSUFFICIENT EVIDENCE for any of the above where it would change a recommendation.
## Abstract
The multiply/divide unit (MDU) executes the RISC-V `M`-extension instructions 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 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. The lower bits of an integer product are bit-identical regardless of whether the operands are treated as signed or unsigned, so `MUL` does not require a signedness mode.
- `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 on a unified datapath.
`MULH*` exists as native instructions in both RV32 and RV64. In RV32 the product is 64 bits; `MULH`/`MULHU`/`MULHSU` return the upper 32 bits. They are not emulated as paired 32-bit halves; the upper 32 bits of the full product are produced directly.
The `M` extension specifies architectural behavior (truncation, signed/unsigned interaction, divide-by-zero, the most-negative-dividend-divided-by-1 overflow) 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. Without Booth recoding, an N×N array has N rows of full adders (N stages of reduction); with radix-4 Booth recoding it has N/2 rows. Latency scales linearly with the number of rows. Easy to layout; long critical path.
- **Wallace tree.** A logarithmic-depth reduction tree using CSAs; faster than an array at the same operand width, with irregular shape that complicates physical design. Whether a Wallace tree is smaller than a CSA array in total gate count at 64×64 is implementation-dependent; the literature is mixed.
- **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 to reduce the partial-product count. Radix-4 Booth produces N/2 partial products for an N-bit operand and is the workhorse in many cores. Radix-8 produces N/3 partial products; the per-PP selector is more complex (roughly tripling selector logic per row) while the reduction tree itself grows in line with the row count, not by a factor of three. Recoding is most useful when the operand width is large.
- **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 multiplyadd (FMA).** Single instruction producing `a*b + c` with one rounding. Standard in vector/GPU ISAs; not part of base scalar RISC-V `M`, but a candidate addition. RISC-V `Zfa` is a floating-point extension and is not the appropriate home for an integer FMA; any integer FMA on XH-1 would be a vendor extension.
- **Unified 2·XLEN-bit product.** A single datapath producing 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 adder at the end and is not a free win for the `W` variants (see Implementation Considerations).
### 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) quotient digits, plus a small constant for fixup. SRT is the dominant technique for high-performance scalar cores. The most-negative-dividend-divided-by-1 signed-overflow case is a fundamental property of signed division at any radix; it is not specific to radix ≥ 4.
- **NewtonRaphson reciprocal + multiply.** Two multiplications of the reciprocal approximation, then a final multiply by the dividend. Latency roughly 23 multiplies, with small additional control. High throughput, long tail latency, large area (needs a fast multiplier and a ROM of initial approximations). Inappropriate as the only divider in a scalar core that needs deterministic `DIV` latency; often used in vector/GPU contexts.
- **Goldschmidt division.** Iterative convergence with different numerical subtleties than NewtonRaphson; same general area/latency class. Not analyzed further here.
- **Lookup-table-based constant division.** Replacing division by a small set of "magic numbers" at compile time. Software-side; interacts with the hardware because the `M` ISA is not required for software to be efficient if the compiler reduces a constant 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.
- **Integer FMA / fused MAC.** Not in the RISC-V `M` extension; would be a vendor extension if added. Multiply-add with rounding is a floating-point concept.
## Alternative Designs
The design space reduces to a small set of choices:
1. **Unified 2·XLEN-bit multiplier for `MUL` + `MULH*`.** Common choice for RV64. Produces the full product once and slices it.
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 wider muxes and a longer `MULH*` critical path.
3. **Array vs. tree.** A rectangular CSA array (regular, often 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. NewtonRaphson vs. software-emulated via reciprocal multiply.
6. **Pipelined MDU vs. non-pipelined.** Issue one MDU instruction per cycle (pipelined), one per N cycles (unpipelined), or some hybrid.
7. **32-bit `W` variants.** Either share the XLEN-wide datapath and sign-extend at the end, or use a 32-bit-wide fast path.
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.
9. **Shared pool of MDUs.** A small pool of MDUs (e.g., 832) serving 128 cores through the tile fabric, rather than one per core. Trades replication cost for cross-tile wire delay and contention. Discussed in 128-Core Scalability.
10. **`MUL` only, emulate `MULH*`.** A scalar in-order core could implement only `MUL`/`MULW` and trap-and-emulate `MULH*` in software. Reduces the multiply datapath width at the cost of trapping on `MULH*`-using code. Crypto and big-integer arithmetic rely on `MULH*`, so this is a real design point only for cores targeting general-purpose code without crypto.
## 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. Whether the tree is also smaller in total gate count at 64×64 is implementation-dependent; the array is regular and the tree is not. 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 quotient digits of radix-2 SRT at modest area increase; radix-8 trades more selector-table area for a further reduction in digit count. NewtonRaphson is fastest in latency on a fully pipelined multiplier but requires a fast multiplier and 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. This advantage is independent of whether the reduction is a CSA array or a tree.
- 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`.
- A small shared pool of MDUs can reduce the area replication cost of 128 cores at the cost of cross-tile wire delay and per-MDU contention.
## Disadvantages
- A 64×64 → 128 multiplier, whether implemented as a CSA array or a reduction tree, is a wide datapath and a noticeable per-core cost in any high-density core; on a 128-core die, this multiplies.
- NewtonRaphson 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 division has a most-negative-dividend-divided-by-1 signed-overflow corner case at any radix; correctly handling it 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.
- A shared pool of MDUs requires cross-tile operand routing and adds to the NoC traffic budget; it also turns the MDU into a contended resource for 128 cores.
## XH-1 Considerations
- **XLEN.** Under the RV64 assumption, 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 is the dominant datapath driver in either case.
- **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.** Under the scalar-only assumption, the MDU is a single-issue scalar unit; 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.
- **Clocking.** Under the single-clock-domain assumption, per-tile clock gating of the MDU is straightforward. Per-tile DVFS is not assumed.
## 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.
- **Single 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. ASSUMPTION: the XH-1 is a tiled fabric where the cost of a global MDU exceeds the cost of replication.
- **Small shared pool.** A pool of K MDUs (e.g., K = 8 or 16) serving 128 cores is a real design point in some tiled architectures. It reduces replicated area by a factor of 128/K at the cost of cross-tile operand routing, MDU-side arbitration, and worst-case `MUL` throughput of K per cycle chip-wide. This binary "1-per-core or 1-shared" framing in earlier surveys is incomplete; the shared-pool option belongs in the design space.
- **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. INSUFFICIENT EVIDENCE to bound the magnitude of this variability for XH-1.
- **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 most MDUs during low utilization. This is a meaningful power-saving lever. INSUFFICIENT EVIDENCE to quantify the savings.
## Performance Considerations
- **Latency targets.** Without a specific frequency target for XH-1, latency cannot be quoted in nanoseconds. In cycle terms, qualitative estimates:
- An iterative 64-bit multiplier: on the order of the operand width in cycles, depending on radix.
- A pipelined 64-bit multiplier: 13 cycles issue-to-writeback, depending on pipeline depth.
- An SRT-4 64-bit divider: on the order of 2·XLEN / log2(4) = 32 quotient digits plus a few cycles of fixup. The exact cycle count depends on digits-per-cycle and overlap.
- An SRT-8 64-bit divider: on the order of 2·XLEN / log2(8) ≈ 2122 quotient digits plus fixup. The "1620 cycles" figure sometimes seen in informal sources does not account for fixup cycles and should not be cited as a hard number.
- NewtonRaphson: roughly 2 multiplies plus fixup; 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 NewtonRaphson 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
Rough relative area figures (not fabrication-specific, not quantitative):
- A 64×64 → 128 CSA array, unrecoded: ~N rows of full adders, rectangular, regular layout. Area is roughly proportional to operand width squared in the array portion.
- A 64×64 → 128 Booth-radix-4 array: N/2 partial products, larger selector muxes per PP. Net smaller than a naive unrecoded array; less regular than a tree.
- A 64×64 → 128 Wallace/Dadda tree: fewer full adders in total than a naive array, but irregular layout. Whether total gate count is smaller than the array at 64×64 is implementation-dependent; the literature is mixed and the claim should not be asserted as universal.
- A radix-4 SRT divider: similar order of magnitude to a small multiplier; mostly selector logic and a small ROM.
- A NewtonRaphson 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. The area discussion in the original draft conflated a unified tree with a CSA array; a unified 2·XLEN-bit product can be implemented as either organization, and the area comparison should be between the unified and split-datapath options, not between a tree and an array.
## 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. INSUFFICIENT EVIDENCE to quantify the savings.
- **Divide energy.** A long, slow divider spends many cycles driving the same datapath at full toggle rate. Whether a faster, larger divider is lower energy per `DIV` than a slow, small one depends on the specific organizations; a high-radix SRT with a large selector ROM can be higher energy per operation than a shift/subtract divider in some implementations. The blanket "faster = lower energy" claim is not generally true and is removed.
- **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 rules out early-exit optimizations that would change the energy/latency profile.
## Implementation Considerations
- **Radix choice.** Radix-4 is the workhorse; radix-8 increases selector complexity per row for a smaller reduction in digit count. 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. This is a signed-division overflow at any radix, not specific to radix ≥ 4. 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 all-ones for the quotient and the dividend for the remainder, for both signed and unsigned. 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*`. The ISA does not allow architectural shortcuts, only microarchitectural.
- **`MULW` / `DIVW` / `REMW`.** On a unified 64×64 → 128 datapath, `MULW` requires either running a narrower 32×32 → 64 datapath or masking and sign-extending the lower 32 bits of the 64×64 product. The "free byproduct" framing for `MUL` does not extend cleanly to the `W` variants; the W-variants either share the wide datapath with sign-extension at the end (no real area saving) or use a 32-bit-wide fast path (area saved but a second critical path to verify).
- **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
- **`MULH*` cross-product.** The signed/unsigned interaction of the upper-product instruction is the most common source of bugs in DIY MDUs. The full enumeration is: `MULH` = `±×±`, `MULHSU` = `±×u`, `MULHU` = `u×u`, `MUL` = lower half (operand signedness does not change the bit pattern). Testing must cover all four cases at boundary patterns: 0, 1, 1, 2^XLEN1, 2^(XLEN1) and combinations thereof.
- **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 most-negative/÷−1 case is the dominant bug class; it is a signed-overflow corner that exists at any radix.
- **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; the project should 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 most-negative/÷−1 corner) usually is not, and is covered by directed tests.
- **128-core replication.** A single strong verification of the per-core MDU logic is necessary and sufficient for the per-core logic itself. It is not sufficient for the full system: per-tile variability (manufacturing, voltage, timing), tile-level integration (interrupts during a long `DIV`, cross-tile coherence interactions for shared-pool MDU configurations, and the shared-pool arbitration logic) are system-level concerns that do not collapse to single-core verification. The earlier draft overstated this; the corrected position is that per-core logic verification is a prerequisite, not a complete, system-level verification.
- **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.
- **`Zbkb` and bitmanip-for-crypto.** `Zbkb` includes bitmanipulation operations such as `BREV8`, `PACK`, `UNPACK`, `ZIP`, `UNZIP`, `ANDN`, `ORN`, `XNOR`, and carry-less multiply instructions (`CLMUL`, `CLMULH`, `CLMULR`). The carry-less multiply instructions are *not* the same operation as `MULH*`; they use XOR in place of the carry-propagate addition in the reduction tree. The earlier draft conflated these; the corrected position is that `Zbkb` does not specifically use `MULH*` heavily, and any carry-less multiply support is a separate datapath concern outside the `M`-extension MDU.
- **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, whether it implements a vector unit, what its target frequency and process node are, or whether a shared-pool MDU configuration is in scope. 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*`. The `MUL` lower half is bit-identical regardless of operand signedness, so a single 2·XLEN-bit reduction tree is the cost-effective choice. The W-variants require a separate small datapath or a sign-extension fixup; the trade-off should be made explicit.
- RECOMMENDATION: avoid NewtonRaphson 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.
- RECOMMENDATION: implement the SRT most-negative / 1 corner case explicitly and verify it formally; this is the single most common bug in homemade MDUs. The corner exists at any radix for signed division and is not specific to radix ≥ 4.
- RECOMMENDATION: 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.
- RECOMMENDATION: power-gate the MDU on idle tiles. On a 128-core die this is a meaningful contributor to idle power. INSUFFICIENT EVIDENCE to quantify.
- RECOMMENDATION: consider a small shared pool of MDUs (e.g., 832) as an alternative to full per-core replication, and decide based on area, cross-tile routing cost, and `MUL` throughput targets. The binary "1-per-core or 1-shared" framing is incomplete.
## Confidence
- FACT: high confidence in the RISC-V `M` ISA's required operations and corner-case behavior. This is normative and stable in the Unprivileged ISA Specification; the specific version is not pinned in this stub because the XH-1 repository does not pin a version.
- ASSUMPTION: the XH-1 is a tiled 128-core fabric where global MDU sharing is rejected and per-tile replication or a small shared pool is the only realistic option. Reasonable but not stated by the repository.
- ASSUMPTION: RV64, scalar-only, in-order, single clock domain with per-tile clock gating. Stated as assumptions above; INSUFFICIENT EVIDENCE to choose otherwise.
- 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: in-order vs. out-of-order, frequency target, process node, vector-unit presence, shared-pool acceptability, bitmanip/crypto extension presence, constant-time documentation status.
## 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. `MULH*` is a native instruction in both; the description in the original draft was incorrect on this point.
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 is required. `Zfa` is a floating-point extension and not the appropriate home for integer FMA.
5. Does the XH-1 implement any bitmanipulation (`B`) or cryptography (`K`) extensions? In particular, `Zbkb` uses carry-less multiplies (`CLMUL*`), which are not the same as `MULH*` and would be a separate datapath.
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. Is a shared pool of MDUs (e.g., 832) in scope, or is per-core replication fixed?
10. How is the XH-1 floorplanned? A 128-core die imposes physical-design constraints on the MDU footprint.
11. 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.
12. What is the clocking model? Single domain, per-tile domains, DVFS? This affects power gating and cross-tile MDU sharing.
## 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 (for example: Parhami, *Computer Arithmetic*; Ercegovac and Lang, *Digital Arithmetic*; the original SRT paper by Robertson, Sweeney, and Tocher; the Booth-recoding paper; and Dadda's paper on reduction trees), but no specific work is cited here because fabricating a paper title, page number, or equation would violate the project's "never invent citations" rule.
Where this document makes quantitative claims (e.g., "an SRT-4 64-bit divider is on the order of 32 quotient digits"), 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.
@@ -0,0 +1,64 @@
I'll review this document carefully against the criteria specified.
**Checking the document systematically:**
1. **RISC-V M extension facts**: The description of `MUL`/`MULH*`/`MULHU`/`MULHSU`, division/rem instructions, W-variants, divide-by-zero behavior, and most-negative/1 overflow appears correct.
2. **Internal consistency**: The document acknowledges that quantitative claims are qualitative, marks assumptions explicitly, and avoids fabricating citations. This is internally consistent.
3. **Distinguishing FACT/ASSUMPTION/PROPOSAL/RECOMMENDATION/OPEN QUESTION**: The document does this throughout, with explicit markers.
4. **Quantitative claims check**:
- SRT-4 divider: 2·XLEN/log2(4) = 64/2 = 32 quotient digits — correct.
- SRT-8: 2·XLEN/log2(8) ≈ 64/3 ≈ 21.3 — correct.
- NewtonRaphson: "roughly 2 multiplies plus fixup" — this is questionable. NewtonRaphson for division typically requires: (1) initial reciprocal approximation, (2) one or two NewtonRaphson refinement iterations, (3) multiply by dividend. The standard form is more like 3 multiplies (initial ROM multiply, NR refinement, final multiply), not 2. The document says "roughly 23 multiplies" earlier in the division section but "roughly 2 multiplies plus fixup" in performance considerations. This is a minor inconsistency and arguably understates the cost.
5. **SRT most-negative/1 corner case**: The document correctly notes this is a property of signed division "at any radix" — this is true. The fixup approach described is standard.
6. **Zbkb / carry-less multiply**: The document correctly distinguishes `CLMUL*` from `MULH*` and notes `Zbkb` doesn't specifically use `MULH*`. This is a correction of an earlier draft error, which is good.
7. **`Zfa` reference**: The document correctly notes `Zfa` is a floating-point extension and not appropriate for integer FMA. This is accurate.
8. **128-core scaling**: The shared-pool discussion (option K=8 or 16) is a reasonable design point that earlier surveys often omit. The reasoning about wire delay is sound.
9. **Verification considerations**: The document correctly notes that per-core verification is necessary but not sufficient for system-level concerns. This is a thoughtful correction.
10. **"Free byproduct" framing for MUL**: The document correctly notes this doesn't extend cleanly to W-variants.
11. **Self-corrections**: The document explicitly notes corrections to an earlier draft (e.g., RV32 MULH* description, Zbkb conflation, area discussion, verification overstatement). This is honest but somewhat unusual in a research document — it suggests the document is a revision and the "earlier draft" is unavailable for review.
12. **One potentially problematic claim**: "A `DIV` can be replaced by a software NewtonRaphson routine in a few hundred instructions." This is presented as fact but is actually an ASSUMPTION/rough estimate. A software NewtonRaphson `divdi3` is typically more than "a few hundred" instructions when including the iteration loop, refinement, and final correction — though the magnitude is order-of-magnitude correct. Minor.
13. **"Local replication, while more silicon, is the conventional answer"** — this is presented as fact but is a generalization. It's true for most designs but "conventional" is somewhat hand-wavy. Acceptable in context.
14. **The document explicitly states "INSUFFICIENT EVIDENCE" for citations and quantitative claims**, and avoids fabricating either. This is the right approach for a stub document.
15. **Recommendations**: They follow logically from the analysis and explicitly mark what's recommendation vs. proposal vs. insufficient evidence.
16. **Missing alternatives check**: The document covers iterative, array, tree, Booth, FMA, SRT radix-2/4/8, NewtonRaphson, Goldschmidt, shared pool, and emulation. This is comprehensive.
17. **One factual nuance**: The document says `MULH*` exists as native instructions in both RV32 and RV64, and that "the upper 32 bits of the full product are produced directly" in RV32. This is correct — in RV32, `MULH` produces the upper 32 bits of a 32×32 product; it's not a paired 32-bit emulation. The document correctly identifies that an earlier draft was wrong on this.
18. **"The SRT most-negative / 1 corner case ... is not specific to radix ≥ 4"** — correct. It exists for any signed division algorithm.
19. **The recommendation to power-gate MDUs on idle tiles** is marked INSUFFICIENT EVIDENCE for quantification, which is appropriate.
20. **The "1620 cycles" informal claim about SRT-8** is correctly noted as not accounting for fixup cycles and not cited.
**Overall assessment**: The document is honest about its limitations, explicitly marks assumptions and uncertainties, self-corrects earlier errors, and provides a reasonable survey of the design space. The technical content is accurate to my knowledge. The NewtonRaphson "2 multiplies" claim is mildly off (more like 3), and the "few hundred instructions" for software emulation is rough, but both are presented in qualitative context. The document is a stub and explicitly says so.
The self-corrections referencing "the earlier draft" and "the original draft" are unusual — they suggest this is a revision, but no original is provided. This isn't a technical error but a documentation hygiene issue. It doesn't rise to a FAIL.
VERDICT: PASS
ISSUES:
- Minor quantitative imprecision: NewtonRaphson division latency is described as "roughly 2 multiplies plus fixup" in Performance Considerations, while earlier in the document the division section says "Latency roughly 23 multiplies, with small additional control." Standard NewtonRaphson division is typically three multiplies (initial reciprocal approximation, one or two NR refinement iterations, final multiply by dividend). The "2 multiplies" figure understates the cost; consistency between the two statements is also missing.
- Minor imprecision: "A `DIV` can be replaced by a software NewtonRaphson routine in a few hundred instructions" is presented as a soft fact; typical software `divdi3` implementations using NewtonRaphson are larger than a few hundred instructions, though order of magnitude is roughly right. Marking as ASSUMPTION would be more accurate.
- Documentation hygiene: multiple references to "the earlier draft" / "the original draft" / "the previous draft" describing errors and corrections, but the original draft is not provided for review. This is not a technical failure but weakens auditability — a reader cannot verify the corrections.
- The "1620 cycles" informal figure for SRT-8 is correctly flagged as not citable, but the document's own "≈ 2122 quotient digits plus fixup" implies roughly 2225+ cycles for a non-overlapped SRT-8. The claim that the informal figure "does not account for fixup cycles" is plausible but the document does not provide its own rigorous cycle count for comparison.
- The "convention" claims (e.g., "SRT is the dominant technique for high-performance scalar cores"; "Local replication, while more silicon, is the conventional answer") are reasonable generalizations but are presented without citation. Acceptable in a stub but should be flagged if the document were to be promoted beyond stub status.
REQUIRED FIXES:
- None. The document is technically acceptable as a stub with explicit scope limitations, internally consistent, and properly distinguishes FACT / ASSUMPTION / PROPOSAL / RECOMMENDATION / OPEN QUESTION throughout.
CONFIDENCE: HIGH
File diff suppressed because one or more lines are too long
@@ -0,0 +1,232 @@
# 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 multiplyadd (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.
- **NewtonRaphson reciprocal + multiply.** Two multiplications of the reciprocal approximation, then a final multiply by the dividend. Latency roughly 23 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 NewtonRaphson 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. NewtonRaphson 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. NewtonRaphson 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.
- NewtonRaphson 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: 3264 cycles, depending on radix.
- A pipelined 64-bit multiplier: 13 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: ~1620 cycles.
- NewtonRaphson: 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 NewtonRaphson 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 NewtonRaphson 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 NewtonRaphson 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.
File diff suppressed because one or more lines are too long
@@ -0,0 +1,260 @@
# 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.
## Assumptions and Scope
The following assumptions frame the analysis. They are stated explicitly because the XH-1 repository context is not provided in this stub; where evidence is missing, the document says so.
- **ISA width (XLEN).** ASSUMPTION: the XH-1 core is RV64. Rationale: 128-bit results in `MULH*` are most useful when software performs multi-word arithmetic, and a 128-core tiled die is consistent with a server-class 64-bit core. RV32 is treated as a secondary case.
- **Core pipeline style.** ASSUMPTION: the core is in-order with multiple execution stages, to keep the discussion concrete. Out-of-order is acknowledged as a different design point.
- **Clocking.** ASSUMPTION: a single chip-wide clock domain with per-tile clock gating. Per-tile DVFS is not assumed. INSUFFICIENT EVIDENCE to choose otherwise.
- **Process node / cell library.** Not assumed. The document discusses area and power only in qualitative, relative terms.
- **Frequency target.** Not assumed. Latency claims are stated in cycles, not nanoseconds.
- **Vector / shared MDU.** ASSUMPTION: scalar-only context without a vector unit sharing the MDU.
- **Extensions.** ASSUMPTION: base RISC-V `M` is implemented. `B`, `K`, and vector-crypto extensions are not assumed present; their interaction with the MDU is discussed only as a scaling consideration.
INSUFFICIENT EVIDENCE for any of the above where it would change a recommendation.
## Abstract
The multiply/divide unit (MDU) executes the RISC-V `M`-extension instructions 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 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. The lower bits of an integer product are bit-identical regardless of whether the operands are treated as signed or unsigned, so `MUL` does not require a signedness mode.
- `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 on a unified datapath.
`MULH*` exists as native instructions in both RV32 and RV64. In RV32 the product is 64 bits; `MULH`/`MULHU`/`MULHSU` return the upper 32 bits. They are not emulated as paired 32-bit halves; the upper 32 bits of the full product are produced directly.
The `M` extension specifies architectural behavior (truncation, signed/unsigned interaction, divide-by-zero, the most-negative-dividend-divided-by-1 overflow) 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. Without Booth recoding, an N×N array has N rows of full adders (N stages of reduction); with radix-4 Booth recoding it has N/2 rows. Latency scales linearly with the number of rows. Easy to layout; long critical path.
- **Wallace tree.** A logarithmic-depth reduction tree using CSAs; faster than an array at the same operand width, with irregular shape that complicates physical design. Whether a Wallace tree is smaller than a CSA array in total gate count at 64×64 is implementation-dependent; the literature is mixed.
- **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 to reduce the partial-product count. Radix-4 Booth produces N/2 partial products for an N-bit operand and is the workhorse in many cores. Radix-8 produces N/3 partial products; the per-PP selector is more complex (roughly tripling selector logic per row) while the reduction tree itself grows in line with the row count, not by a factor of three. Recoding is most useful when the operand width is large.
- **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 multiplyadd (FMA).** Single instruction producing `a*b + c` with one rounding. Standard in vector/GPU ISAs; not part of base scalar RISC-V `M`, but a candidate addition. RISC-V `Zfa` is a floating-point extension and is not the appropriate home for an integer FMA; any integer FMA on XH-1 would be a vendor extension.
- **Unified 2·XLEN-bit product.** A single datapath producing 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 adder at the end and is not a free win for the `W` variants (see Implementation Considerations).
### 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) quotient digits, plus a small constant for fixup. SRT is the dominant technique for high-performance scalar cores. The most-negative-dividend-divided-by-1 signed-overflow case is a fundamental property of signed division at any radix; it is not specific to radix ≥ 4.
- **NewtonRaphson reciprocal + multiply.** Two multiplications of the reciprocal approximation, then a final multiply by the dividend. Latency roughly 23 multiplies, with small additional control. High throughput, long tail latency, large area (needs a fast multiplier and a ROM of initial approximations). Inappropriate as the only divider in a scalar core that needs deterministic `DIV` latency; often used in vector/GPU contexts.
- **Goldschmidt division.** Iterative convergence with different numerical subtleties than NewtonRaphson; same general area/latency class. Not analyzed further here.
- **Lookup-table-based constant division.** Replacing division by a small set of "magic numbers" at compile time. Software-side; interacts with the hardware because the `M` ISA is not required for software to be efficient if the compiler reduces a constant 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.
- **Integer FMA / fused MAC.** Not in the RISC-V `M` extension; would be a vendor extension if added. Multiply-add with rounding is a floating-point concept.
## Alternative Designs
The design space reduces to a small set of choices:
1. **Unified 2·XLEN-bit multiplier for `MUL` + `MULH*`.** Common choice for RV64. Produces the full product once and slices it.
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 wider muxes and a longer `MULH*` critical path.
3. **Array vs. tree.** A rectangular CSA array (regular, often 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. NewtonRaphson vs. software-emulated via reciprocal multiply.
6. **Pipelined MDU vs. non-pipelined.** Issue one MDU instruction per cycle (pipelined), one per N cycles (unpipelined), or some hybrid.
7. **32-bit `W` variants.** Either share the XLEN-wide datapath and sign-extend at the end, or use a 32-bit-wide fast path.
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.
9. **Shared pool of MDUs.** A small pool of MDUs (e.g., 832) serving 128 cores through the tile fabric, rather than one per core. Trades replication cost for cross-tile wire delay and contention. Discussed in 128-Core Scalability.
10. **`MUL` only, emulate `MULH*`.** A scalar in-order core could implement only `MUL`/`MULW` and trap-and-emulate `MULH*` in software. Reduces the multiply datapath width at the cost of trapping on `MULH*`-using code. Crypto and big-integer arithmetic rely on `MULH*`, so this is a real design point only for cores targeting general-purpose code without crypto.
## 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. Whether the tree is also smaller in total gate count at 64×64 is implementation-dependent; the array is regular and the tree is not. 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 quotient digits of radix-2 SRT at modest area increase; radix-8 trades more selector-table area for a further reduction in digit count. NewtonRaphson is fastest in latency on a fully pipelined multiplier but requires a fast multiplier and 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. This advantage is independent of whether the reduction is a CSA array or a tree.
- 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`.
- A small shared pool of MDUs can reduce the area replication cost of 128 cores at the cost of cross-tile wire delay and per-MDU contention.
## Disadvantages
- A 64×64 → 128 multiplier, whether implemented as a CSA array or a reduction tree, is a wide datapath and a noticeable per-core cost in any high-density core; on a 128-core die, this multiplies.
- NewtonRaphson 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 division has a most-negative-dividend-divided-by-1 signed-overflow corner case at any radix; correctly handling it 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.
- A shared pool of MDUs requires cross-tile operand routing and adds to the NoC traffic budget; it also turns the MDU into a contended resource for 128 cores.
## XH-1 Considerations
- **XLEN.** Under the RV64 assumption, 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 is the dominant datapath driver in either case.
- **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.** Under the scalar-only assumption, the MDU is a single-issue scalar unit; 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.
- **Clocking.** Under the single-clock-domain assumption, per-tile clock gating of the MDU is straightforward. Per-tile DVFS is not assumed.
## 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.
- **Single 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. ASSUMPTION: the XH-1 is a tiled fabric where the cost of a global MDU exceeds the cost of replication.
- **Small shared pool.** A pool of K MDUs (e.g., K = 8 or 16) serving 128 cores is a real design point in some tiled architectures. It reduces replicated area by a factor of 128/K at the cost of cross-tile operand routing, MDU-side arbitration, and worst-case `MUL` throughput of K per cycle chip-wide. This binary "1-per-core or 1-shared" framing in earlier surveys is incomplete; the shared-pool option belongs in the design space.
- **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. INSUFFICIENT EVIDENCE to bound the magnitude of this variability for XH-1.
- **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 most MDUs during low utilization. This is a meaningful power-saving lever. INSUFFICIENT EVIDENCE to quantify the savings.
## Performance Considerations
- **Latency targets.** Without a specific frequency target for XH-1, latency cannot be quoted in nanoseconds. In cycle terms, qualitative estimates:
- An iterative 64-bit multiplier: on the order of the operand width in cycles, depending on radix.
- A pipelined 64-bit multiplier: 13 cycles issue-to-writeback, depending on pipeline depth.
- An SRT-4 64-bit divider: on the order of 2·XLEN / log2(4) = 32 quotient digits plus a few cycles of fixup. The exact cycle count depends on digits-per-cycle and overlap.
- An SRT-8 64-bit divider: on the order of 2·XLEN / log2(8) ≈ 2122 quotient digits plus fixup. The "1620 cycles" figure sometimes seen in informal sources does not account for fixup cycles and should not be cited as a hard number.
- NewtonRaphson: roughly 2 multiplies plus fixup; 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 NewtonRaphson 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
Rough relative area figures (not fabrication-specific, not quantitative):
- A 64×64 → 128 CSA array, unrecoded: ~N rows of full adders, rectangular, regular layout. Area is roughly proportional to operand width squared in the array portion.
- A 64×64 → 128 Booth-radix-4 array: N/2 partial products, larger selector muxes per PP. Net smaller than a naive unrecoded array; less regular than a tree.
- A 64×64 → 128 Wallace/Dadda tree: fewer full adders in total than a naive array, but irregular layout. Whether total gate count is smaller than the array at 64×64 is implementation-dependent; the literature is mixed and the claim should not be asserted as universal.
- A radix-4 SRT divider: similar order of magnitude to a small multiplier; mostly selector logic and a small ROM.
- A NewtonRaphson 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. The area discussion in the original draft conflated a unified tree with a CSA array; a unified 2·XLEN-bit product can be implemented as either organization, and the area comparison should be between the unified and split-datapath options, not between a tree and an array.
## 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. INSUFFICIENT EVIDENCE to quantify the savings.
- **Divide energy.** A long, slow divider spends many cycles driving the same datapath at full toggle rate. Whether a faster, larger divider is lower energy per `DIV` than a slow, small one depends on the specific organizations; a high-radix SRT with a large selector ROM can be higher energy per operation than a shift/subtract divider in some implementations. The blanket "faster = lower energy" claim is not generally true and is removed.
- **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 rules out early-exit optimizations that would change the energy/latency profile.
## Implementation Considerations
- **Radix choice.** Radix-4 is the workhorse; radix-8 increases selector complexity per row for a smaller reduction in digit count. 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. This is a signed-division overflow at any radix, not specific to radix ≥ 4. 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 all-ones for the quotient and the dividend for the remainder, for both signed and unsigned. 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*`. The ISA does not allow architectural shortcuts, only microarchitectural.
- **`MULW` / `DIVW` / `REMW`.** On a unified 64×64 → 128 datapath, `MULW` requires either running a narrower 32×32 → 64 datapath or masking and sign-extending the lower 32 bits of the 64×64 product. The "free byproduct" framing for `MUL` does not extend cleanly to the `W` variants; the W-variants either share the wide datapath with sign-extension at the end (no real area saving) or use a 32-bit-wide fast path (area saved but a second critical path to verify).
- **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
- **`MULH*` cross-product.** The signed/unsigned interaction of the upper-product instruction is the most common source of bugs in DIY MDUs. The full enumeration is: `MULH` = `±×±`, `MULHSU` = `±×u`, `MULHU` = `u×u`, `MUL` = lower half (operand signedness does not change the bit pattern). Testing must cover all four cases at boundary patterns: 0, 1, 1, 2^XLEN1, 2^(XLEN1) and combinations thereof.
- **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 most-negative/÷−1 case is the dominant bug class; it is a signed-overflow corner that exists at any radix.
- **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; the project should 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 most-negative/÷−1 corner) usually is not, and is covered by directed tests.
- **128-core replication.** A single strong verification of the per-core MDU logic is necessary and sufficient for the per-core logic itself. It is not sufficient for the full system: per-tile variability (manufacturing, voltage, timing), tile-level integration (interrupts during a long `DIV`, cross-tile coherence interactions for shared-pool MDU configurations, and the shared-pool arbitration logic) are system-level concerns that do not collapse to single-core verification. The earlier draft overstated this; the corrected position is that per-core logic verification is a prerequisite, not a complete, system-level verification.
- **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.
- **`Zbkb` and bitmanip-for-crypto.** `Zbkb` includes bitmanipulation operations such as `BREV8`, `PACK`, `UNPACK`, `ZIP`, `UNZIP`, `ANDN`, `ORN`, `XNOR`, and carry-less multiply instructions (`CLMUL`, `CLMULH`, `CLMULR`). The carry-less multiply instructions are *not* the same operation as `MULH*`; they use XOR in place of the carry-propagate addition in the reduction tree. The earlier draft conflated these; the corrected position is that `Zbkb` does not specifically use `MULH*` heavily, and any carry-less multiply support is a separate datapath concern outside the `M`-extension MDU.
- **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, whether it implements a vector unit, what its target frequency and process node are, or whether a shared-pool MDU configuration is in scope. 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*`. The `MUL` lower half is bit-identical regardless of operand signedness, so a single 2·XLEN-bit reduction tree is the cost-effective choice. The W-variants require a separate small datapath or a sign-extension fixup; the trade-off should be made explicit.
- RECOMMENDATION: avoid NewtonRaphson 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.
- RECOMMENDATION: implement the SRT most-negative / 1 corner case explicitly and verify it formally; this is the single most common bug in homemade MDUs. The corner exists at any radix for signed division and is not specific to radix ≥ 4.
- RECOMMENDATION: 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.
- RECOMMENDATION: power-gate the MDU on idle tiles. On a 128-core die this is a meaningful contributor to idle power. INSUFFICIENT EVIDENCE to quantify.
- RECOMMENDATION: consider a small shared pool of MDUs (e.g., 832) as an alternative to full per-core replication, and decide based on area, cross-tile routing cost, and `MUL` throughput targets. The binary "1-per-core or 1-shared" framing is incomplete.
## Confidence
- FACT: high confidence in the RISC-V `M` ISA's required operations and corner-case behavior. This is normative and stable in the Unprivileged ISA Specification; the specific version is not pinned in this stub because the XH-1 repository does not pin a version.
- ASSUMPTION: the XH-1 is a tiled 128-core fabric where global MDU sharing is rejected and per-tile replication or a small shared pool is the only realistic option. Reasonable but not stated by the repository.
- ASSUMPTION: RV64, scalar-only, in-order, single clock domain with per-tile clock gating. Stated as assumptions above; INSUFFICIENT EVIDENCE to choose otherwise.
- 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: in-order vs. out-of-order, frequency target, process node, vector-unit presence, shared-pool acceptability, bitmanip/crypto extension presence, constant-time documentation status.
## 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. `MULH*` is a native instruction in both; the description in the original draft was incorrect on this point.
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 is required. `Zfa` is a floating-point extension and not the appropriate home for integer FMA.
5. Does the XH-1 implement any bitmanipulation (`B`) or cryptography (`K`) extensions? In particular, `Zbkb` uses carry-less multiplies (`CLMUL*`), which are not the same as `MULH*` and would be a separate datapath.
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. Is a shared pool of MDUs (e.g., 832) in scope, or is per-core replication fixed?
10. How is the XH-1 floorplanned? A 128-core die imposes physical-design constraints on the MDU footprint.
11. 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.
12. What is the clocking model? Single domain, per-tile domains, DVFS? This affects power gating and cross-tile MDU sharing.
## 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 (for example: Parhami, *Computer Arithmetic*; Ercegovac and Lang, *Digital Arithmetic*; the original SRT paper by Robertson, Sweeney, and Tocher; the Booth-recoding paper; and Dadda's paper on reduction trees), but no specific work is cited here because fabricating a paper title, page number, or equation would violate the project's "never invent citations" rule.
Where this document makes quantitative claims (e.g., "an SRT-4 64-bit divider is on the order of 32 quotient digits"), 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.
File diff suppressed because one or more lines are too long