Add phase-by-phase tutorial notes

Add a Tutorial tree that mirrors the roadmap from Phase 0 through Linux bring-up.
Each phase and subphase gets a short learning note with consistent sections for
context, goals, new concepts, mental model, learning tasks, pitfalls, tooling,
testing, and references.

The tutorial material is intentionally explanatory rather than implementation
code. It gives a systems-oriented learner enough FPGA, SystemVerilog, RISC-V,
firmware, and Linux bring-up context to approach each roadmap phase without
turning the notes into copy-paste RTL.
This commit is contained in:
2026-04-28 12:11:23 +02:00
parent 8edfc86027
commit b008b37d49
43 changed files with 2110 additions and 0 deletions
@@ -0,0 +1,49 @@
# Phase 1.1 - Combinational ALU
## Context
The ALU is the easiest place to learn the difference between software expressions and
hardware behavior. Every operation is hardware that exists in parallel behind a selector.
## Goals
- Implement RV32I arithmetic, logic, comparison, and shift operations.
- Verify every operation independently.
- Learn how signedness works in SystemVerilog.
## New Concepts
- Signedness: whether bits are interpreted as two's-complement signed values.
- Shift amount: RISC-V uses only the low 5 bits for RV32 shifts.
- Overflow: addition overflow is usually ignored for RV32I arithmetic results.
- Combinational completeness: every output is assigned for every input path.
## How To Think About It
The same 32-bit vector can be signed or unsigned depending on the operation. Make the
interpretation explicit in your design notes and tests.
## Learning Tasks
- Make a table of each ALU op, its operands, and expected result semantics.
- Hand-check edge cases such as `0`, `-1`, `INT_MIN`, and `INT_MAX`.
- Compare arithmetic right shift with logical right shift.
## Pitfalls
- Accidentally creating latches by not assigning outputs in every case.
- Using host-language intuition for signed comparisons.
- Forgetting that `slt` and `sltu` are different instructions.
## Tooling And Testing
- Use a small self-checking testbench before opening a waveform.
- Add waveform inspection for failing tests only; do not debug by staring first.
- Include cases where signed and unsigned answers differ.
## References
- RISC-V unprivileged ISA: https://riscv.org/technical/specifications/
- SystemVerilog signed arithmetic notes: https://www.chipverify.com/systemverilog/systemverilog-data-types
- Verilator warnings guide: https://verilator.org/guide/latest/warnings.html
@@ -0,0 +1,49 @@
# 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/
@@ -0,0 +1,50 @@
# Phase 1.3 - ALU + M Unit On FPGA With VIO
## Context
After simulation, place the arithmetic blocks on real hardware and interact with them
through Vivado VIO. This teaches the difference between simulated correctness and
synthesized hardware behavior.
## Goals
- Learn how to instantiate debug IP around simple modules.
- Confirm arithmetic blocks synthesize and meet the 50 MHz target.
- Practice observing handshake behavior in hardware.
## New Concepts
- VIO: Vivado Virtual Input/Output IP, controlled over JTAG.
- JTAG: debug/control link used by Vivado Hardware Manager.
- Timing closure: proving signals settle before the next clock edge.
- Synthesis: compiling RTL into FPGA primitives.
## How To Think About It
This is not about exhaustive validation. It is about learning the FPGA tool loop:
synthesize, implement, program, poke signals, observe results, and read timing reports.
## Learning Tasks
- Identify which signals are useful to drive and which are useful to observe.
- Read the timing summary and locate the worst path.
- Compare VIO observations with simulator waveforms.
## Pitfalls
- Letting Vivado optimize away debug signals before VIO/ILA can observe them.
- Confusing VIO interaction latency with the design's actual clock-cycle behavior.
- Ignoring timing warnings because the manual test "seemed to work."
## Tooling And Testing
- Use VIO for low-bandwidth manual checks, not automated compliance.
- Keep a short lab notebook: bitstream, clock, operands, expected, observed.
- Learn where Vivado reports resource use for LUTs, FFs, DSPs, and BRAMs.
## References
- Vivado Design Suite documentation: https://docs.xilinx.com/
- Vivado debug IP overview: https://docs.xilinx.com/
- Digilent Arty A7 reference: https://digilent.com/reference/programmable-logic/arty-a7/reference-manual
+49
View File
@@ -0,0 +1,49 @@
# Phase 1 - ALU + M Unit
## Context
This phase builds the arithmetic core of the CPU. The ALU handles simple single-cycle
operations; the M unit handles multiplication and division with an explicit handshake.
## Goals
- Build and verify a combinational RV32I ALU.
- Build and verify a multi-cycle RV32M unit.
- Learn simulation-first hardware development before system integration.
## New Concepts
- ALU: arithmetic logic unit; performs integer arithmetic, comparisons, shifts, and logic.
- DSP slice: FPGA hard block optimized for multiplication and arithmetic.
- Multi-cycle unit: block that takes several clocks to produce a result.
- Handshake: protocol using signals such as start, busy, done, valid, or ready.
## How To Think About It
The ALU is pure combinational decision logic. The M unit is a small protocol machine. Do
not force division into the ALU just because it is mathematically an arithmetic operation.
## Learning Tasks
- Understand signed versus unsigned interpretation of the same 32 bits.
- Work through RISC-V division edge cases by hand.
- Draw the M-unit state machine before writing RTL.
## Pitfalls
- Implementing a combinational divider and then fighting timing forever.
- Treating signed comparisons as unsigned or vice versa.
- Dropping `done` or accepting a new `start` at the wrong time.
## Tooling And Testing
- Start with small deterministic test vectors, then add randomized checks.
- Use waveform inspection to confirm handshake timing, not only final results.
- Synthesize early to see whether multiply infers DSP resources.
## References
- RISC-V unprivileged ISA, integer and M extension chapters: https://riscv.org/technical/specifications/
- AMD/Xilinx DSP48 documentation: https://docs.xilinx.com/
- Project F FPGA arithmetic articles: https://projectf.io/posts/