mirror of
https://github.com/allexanderbergmns/xh1-research.git
synced 2026-08-26 20:27:02 +00:00
261 lines
34 KiB
Markdown
261 lines
34 KiB
Markdown
# 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 multiply–add (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.
|
||
- **Newton–Raphson reciprocal + multiply.** Two multiplications of the reciprocal approximation, then a final multiply by the dividend. Latency roughly 2–3 multiplies, with small additional control. 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 Newton–Raphson; 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. Newton–Raphson vs. software-emulated via reciprocal multiply.
|
||
6. **Pipelined MDU vs. non-pipelined.** Issue one MDU instruction per cycle (pipelined), one per N cycles (unpipelined), 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., 8–32) 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. Newton–Raphson 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.
|
||
- Newton–Raphson division has long, variable latency that is hard to expose to the front end without reservation-station machinery that the rest of the core may not need.
|
||
- SRT 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: 1–3 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) ≈ 21–22 quotient digits plus fixup. The "16–20 cycles" figure sometimes seen in informal sources does not account for fixup cycles and should not be cited as a hard number.
|
||
- Newton–Raphson: 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 Newton–Raphson routine in a few hundred instructions. This is a fallback the OS can use; it argues that the minimum acceptable MDU can be slow.
|
||
|
||
## Area Considerations
|
||
|
||
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 Newton–Raphson reciprocal unit: negligible hardware beyond a fast multiplier; needs a small ROM of initial approximations.
|
||
|
||
For a 128-core replication, the multiplier's area contribution per tile is the first-order concern; the divider's is a second-order concern. 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^XLEN−1, 2^(XLEN−1) 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 Newton–Raphson as the only divider. It is excellent in throughput-oriented contexts and inappropriate for a scalar core that must expose a deterministic `DIV` latency to the compiler.
|
||
- 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., 8–32) 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., 8–32) 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.
|