Label roadmap phase difficulty

This commit is contained in:
2026-04-28 13:23:03 +02:00
parent 91ca63cf73
commit 07dd8e21f0
+36 -18
View File
@@ -5,6 +5,24 @@
--- ---
## Scope Guide
Each phase is marked with a learning-scope label:
- **Easy/fun** — good weekend/evening work. These phases have visible progress,
tight feedback loops, and form a complete worthwhile project even if you stop
before the Linux work.
- **Hard stretch** — still rewarding, but expect deeper debugging, more spec
reading, and longer gaps between visible milestones.
- **Overkill/hard** — Linux-capable SoC work. Valuable if you want the full
summit, but too much to treat as the baseline definition of success.
Recommended casual target: reach Phase 8, where GCC-built C runs on your CPU and
`riscv-tests` gives you confidence in the ISA implementation. Everything after
that is enrichment or a long-term expedition.
---
## Memory Map (target — fixed in Phase 0, evolves through Phase 14) ## Memory Map (target — fixed in Phase 0, evolves through Phase 14)
``` ```
@@ -21,7 +39,7 @@ stable across phases.
--- ---
## Phase 0 — Architecture Contract ## Phase 0 — Architecture Contract [Easy/fun]
### 0.1 — SystemVerilog Package ### 0.1 — SystemVerilog Package
What: Create a `.sv` package file with enums (ALU operations, opcode types, branch What: Create a `.sv` package file with enums (ALU operations, opcode types, branch
@@ -49,7 +67,7 @@ source of truth when things get complex.
--- ---
## Phase 1 — ALU + M Unit ## Phase 1 — ALU + M Unit [Easy/fun]
### 1.1 — Combinational ALU + Simulation ### 1.1 — Combinational ALU + Simulation
What: Build a combinational ALU that handles all RV32I arithmetic/logic ops What: Build a combinational ALU that handles all RV32I arithmetic/logic ops
@@ -101,7 +119,7 @@ Future role: VIO familiarity pays off throughout the project.
--- ---
## Phase 2 — Register File ## Phase 2 — Register File [Easy/fun]
### 2.1 — Register File Module + Simulation ### 2.1 — Register File Module + Simulation
What: Build the RISC-V register file — 32 registers, each 32 bits wide. Two read What: Build the RISC-V register file — 32 registers, each 32 bits wide. Two read
@@ -125,7 +143,7 @@ for a register file since the logic is simple.
--- ---
## Phase 3 — Decoder ## Phase 3 — Decoder [Easy/fun]
### 3.1 — Instruction Decoder + Simulation ### 3.1 — Instruction Decoder + Simulation
What: A combinational module that takes a raw 32-bit instruction word and produces What: A combinational module that takes a raw 32-bit instruction word and produces
@@ -152,7 +170,7 @@ decoder and a new field to the struct. The structure of the decoder doesn't chan
--- ---
## Phase 4 — First CPU ("It's Alive") ## Phase 4 — First CPU ("It's Alive") [Easy/fun]
### 4.1 — Fetch + Datapath Integration ### 4.1 — Fetch + Datapath Integration
What: Create an instruction BRAM initialized from a .mem file, mapped at What: Create an instruction BRAM initialized from a .mem file, mapped at
@@ -199,7 +217,7 @@ Knowing how to use it well is arguably the most important FPGA debug skill.
--- ---
## Phase 5 — Branches and Jumps (Control Flow) ## Phase 5 — Branches and Jumps (Control Flow) [Easy/fun]
### 5.1 — Branch Instructions ### 5.1 — Branch Instructions
What: Add a branch comparator (separate from the ALU — it checks rs1 vs rs2 for What: Add a branch comparator (separate from the ALU — it checks rs1 vs rs2 for
@@ -235,7 +253,7 @@ Future role: Final. These instructions don't change.
--- ---
## Phase 6 — Load/Store (Data Memory) ## Phase 6 — Load/Store (Data Memory) [Easy/fun]
### 6.1 — Word Load/Store (lw, sw) ### 6.1 — Word Load/Store (lw, sw)
What: Add a data BRAM mapped at `0x8000_0000` (64 KB) and a load/store unit. What: Add a data BRAM mapped at `0x8000_0000` (64 KB) and a load/store unit.
@@ -323,7 +341,7 @@ errors). ILA on the bus lets you see exactly what's happening each cycle.
--- ---
## Phase 7 — Memory-Mapped UART ## Phase 7 — Memory-Mapped UART [Easy/fun]
### 7.1 — UART TX Module ### 7.1 — UART TX Module
What: A standalone UART transmitter. Baud rate 115200, 8 data bits, no parity, What: A standalone UART transmitter. Baud rate 115200, 8 data bits, no parity,
@@ -392,7 +410,7 @@ screen.
--- ---
## Phase 8 — GCC Toolchain Integration ## Phase 8 — GCC Toolchain Integration [Easy/fun]
### 8.1 — Linker Script + Startup Code ### 8.1 — Linker Script + Startup Code
What: Write a linker script that tells GCC where your instruction memory, data What: Write a linker script that tells GCC where your instruction memory, data
@@ -492,7 +510,7 @@ becomes regression coverage for the rest of the project.
--- ---
## Phase 9 — CSRs + M-Mode Trap Handling ## Phase 9 — CSRs + M-Mode Trap Handling [Hard stretch]
What: Add Control and Status Registers (mstatus, mtvec, mepc, mcause, mtval, mie, What: Add Control and Status Registers (mstatus, mtvec, mepc, mcause, mtval, mie,
mip) and the CSR instructions (csrrw, csrrs, csrrc, csrrwi, csrrsi, csrrci). Add mip) and the CSR instructions (csrrw, csrrs, csrrc, csrrwi, csrrsi, csrrci). Add
@@ -509,7 +527,7 @@ plus S-mode (supervisor mode), which you'll add later.
--- ---
## Phase 10 — Timer ## Phase 10 — Timer [Hard stretch]
What: Implement mtime (a free-running 64-bit counter) and mtimecmp (comparison What: Implement mtime (a free-running 64-bit counter) and mtimecmp (comparison
register). When mtime >= mtimecmp, a timer interrupt fires. register). When mtime >= mtimecmp, a timer interrupt fires.
@@ -520,7 +538,7 @@ validates that the trap handling from Phase 9 actually works end-to-end.
--- ---
## Phase 11 — Interrupt Controller ## Phase 11 — Interrupt Controller [Hard stretch]
What: Build a minimal PLIC (Platform-Level Interrupt Controller) or a simplified What: Build a minimal PLIC (Platform-Level Interrupt Controller) or a simplified
version. Connect UART RX as an interrupt source. Implement interrupt priority and version. Connect UART RX as an interrupt source. Implement interrupt priority and
@@ -532,7 +550,7 @@ the PLIC manages them. This is required for Linux.
--- ---
## Phase 12 — A Extension (Atomics) ## Phase 12 — A Extension (Atomics) [Hard stretch]
What: Implement the RV32A atomic instructions: `lr.w` / `sc.w` (load-reserved / What: Implement the RV32A atomic instructions: `lr.w` / `sc.w` (load-reserved /
store-conditional) and the AMO ops (`amoswap.w`, `amoadd.w`, `amoand.w`, store-conditional) and the AMO ops (`amoswap.w`, `amoadd.w`, `amoand.w`,
@@ -560,7 +578,7 @@ reservation set and bus become more involved.
--- ---
## Phase 13 — Pipeline (Optional but educational) ## Phase 13 — Pipeline (Optional but educational) [Hard stretch]
What: Insert pipeline registers between your stages (fetch|decode|execute| What: Insert pipeline registers between your stages (fetch|decode|execute|
memory|writeback). Handle data hazards (forwarding/stalling) and control memory|writeback). Handle data hazards (forwarding/stalling) and control
@@ -578,7 +596,7 @@ must — and if you do, do it before DRAM/firmware work piles on. Re-running
--- ---
## Phase 14 — SPI Flash Boot + DRAM ## Phase 14 — SPI Flash Boot + DRAM [Overkill/hard]
What: Add an SPI flash controller to boot from the on-board flash (instead What: Add an SPI flash controller to boot from the on-board flash (instead
of BRAM initialization). The Arty A7-100T has a 16 MB Quad-SPI flash; map of BRAM initialization). The Arty A7-100T has a 16 MB Quad-SPI flash; map
@@ -601,7 +619,7 @@ keep.
--- ---
## Phase 15 — S-Mode, U-Mode, Sv32 Virtual Memory ## Phase 15 — S-Mode, U-Mode, Sv32 Virtual Memory [Overkill/hard]
What: Add supervisor and user privilege modes. Implement Sv32 page table What: Add supervisor and user privilege modes. Implement Sv32 page table
walking (two-level page tables, 4 KB pages). Add the `satp` CSR, page-fault walking (two-level page tables, 4 KB pages). Add the `satp` CSR, page-fault
@@ -619,7 +637,7 @@ modes round-trip via `mret` / `sret`.
--- ---
## Phase 16 — Linux Boot Contract (SBI / Device Tree / ABI) ## Phase 16 — Linux Boot Contract (SBI / Device Tree / ABI) [Overkill/hard]
What: Lock down everything Linux expects at the moment of `kernel_entry`. What: Lock down everything Linux expects at the moment of `kernel_entry`.
This is a real subproject, not a footnote inside "port Linux". This is a real subproject, not a footnote inside "port Linux".
@@ -664,7 +682,7 @@ debugging exercise on a known-good ABI surface.
--- ---
## Phase 17 — Linux ## Phase 17 — Linux [Overkill/hard]
What: Build a minimal RISC-V Linux kernel against the device tree and What: Build a minimal RISC-V Linux kernel against the device tree and
boot path defined in Phase 16. Build an initramfs with BusyBox. Load boot path defined in Phase 16. Build an initramfs with BusyBox. Load