# Phase 1.2 - Multi-Cycle M Unit ## Context Multiply and divide belong in a dedicated unit because their timing and control behavior are different from simple ALU operations. ## Goals - Implement multiply, high-half multiply, divide, and remainder behavior. - Learn multi-cycle control using `start`, `busy`, and `done`. - Verify all RISC-V-defined edge cases. ## New Concepts - High-half multiply: result uses bits 63:32 of a 64-bit product. - Iterative divider: divider that computes one bit or small group of bits per cycle. - FSM: finite-state machine controlling multi-cycle behavior. - Latency: number of cycles from request to result. ## How To Think About It Treat the M unit like a tiny asynchronous service from the core's perspective. The core asks for work, waits, and resumes only when the result is stable. ## Learning Tasks - Write down the expected result for divide-by-zero and signed overflow. - Draw state transitions for idle, multiply, divide, done, and back-to-back requests. - Decide when inputs are latched and when outputs are valid. ## Pitfalls - Allowing operands to change while an operation is in flight. - Returning C-language division behavior instead of RISC-V behavior. - Forgetting `mulhsu`, which mixes signed and unsigned operands. ## Tooling And Testing - Use long waveform windows to inspect division progress. - Include tests that assert `start` while `busy` and confirm the intended behavior. - Synthesize to confirm multiply maps to DSPs and divide maps to logic/state. ## References - RISC-V M extension spec: https://riscv.org/technical/specifications/ - Project F multiplication: https://projectf.io/posts/multiplication-fpga-dsps/ - Project F division: https://projectf.io/posts/division-in-verilog/