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:
@@ -0,0 +1,49 @@
|
||||
# Phase 0.1 - SystemVerilog Package
|
||||
|
||||
## Context
|
||||
|
||||
The package is the shared type layer for the project. It prevents every module from
|
||||
inventing its own encodings and signal names.
|
||||
|
||||
## Goals
|
||||
|
||||
- Define enums for ALU operations, branch types, memory sizes, and instruction classes.
|
||||
- Define structs for stage outputs and memory request/response payloads.
|
||||
- Make later extension possible without rewriting every module boundary.
|
||||
|
||||
## New Concepts
|
||||
|
||||
- Packed struct: a struct with a defined bit layout, suitable for wires and registers.
|
||||
- Typedef: named type alias used to make RTL readable.
|
||||
- Import: SystemVerilog mechanism for using package definitions in modules.
|
||||
- Encoding: the bit pattern used for enum values in synthesized hardware.
|
||||
|
||||
## How To Think About It
|
||||
|
||||
The package is not a dumping ground. It should contain stable contracts and shared
|
||||
definitions. If a signal is private to one module, keep it private.
|
||||
|
||||
## Learning Tasks
|
||||
|
||||
- List every planned stage boundary and define what information must cross it.
|
||||
- Separate architectural information, such as register addresses, from local control.
|
||||
- Decide naming conventions before writing dependent modules.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- Relying on implicit enum widths and later discovering mismatched synthesis behavior.
|
||||
- Putting handshake `ready` signals inside one-way payload structs.
|
||||
- Adding fields "just in case" without knowing who drives or consumes them.
|
||||
|
||||
## Tooling And Testing
|
||||
|
||||
- Compile the package alone and then with one tiny importing module.
|
||||
- Inspect elaboration messages; type errors here are usually design-contract errors.
|
||||
- Keep comments on fields short but precise about direction and ownership.
|
||||
|
||||
## References
|
||||
|
||||
- SystemVerilog packages and typedefs: https://verificationguide.com/systemverilog/systemverilog-package/
|
||||
- LowRISC SystemVerilog style: https://github.com/lowRISC/style-guides/blob/master/VerilogCodingStyle.md
|
||||
- RISC-V unprivileged ISA: https://riscv.org/technical/specifications/
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
# Phase 0.2 - Block Diagram
|
||||
|
||||
## Context
|
||||
|
||||
The block diagram is the visual source of truth for the datapath. It should show what
|
||||
talks to what, what is registered, and what can stall.
|
||||
|
||||
## Goals
|
||||
|
||||
- Draw fetch, decode, register file, ALU, M unit, memory/LSU, and writeback.
|
||||
- Label stage-boundary structs from the package.
|
||||
- Mark clocked state, combinational paths, handshakes, and reset behavior.
|
||||
|
||||
## New Concepts
|
||||
|
||||
- Datapath: the route operands and results take through the CPU.
|
||||
- Control path: signals that choose operations, mux inputs, stalls, and traps.
|
||||
- Mux: hardware selector that chooses one of several inputs.
|
||||
- Stall: deliberately holding state while waiting for a multi-cycle event.
|
||||
|
||||
## How To Think About It
|
||||
|
||||
Draw movement of information, not just boxes. A useful hardware diagram answers: where is
|
||||
state stored, what changes each clock, what can wait, and what happens on an exception?
|
||||
|
||||
## Learning Tasks
|
||||
|
||||
- Use arrows for data flow and separate arrows for control when helpful.
|
||||
- Mark every register or memory with a clock edge symbol.
|
||||
- Identify the longest combinational path you expect in early phases.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- Drawing BRAM like a zero-latency array.
|
||||
- Forgetting that multi-cycle units need explicit state and stall control.
|
||||
- Hiding reset and trap paths because they are visually inconvenient.
|
||||
|
||||
## Tooling And Testing
|
||||
|
||||
- Keep the diagram in `docs/` and update it when interfaces change.
|
||||
- Compare waveform signal names against the diagram after each integration phase.
|
||||
- Use the diagram as a checklist when adding ILA probes.
|
||||
|
||||
## References
|
||||
|
||||
- nand2tetris CPU/data-path intuition: https://www.nand2tetris.org/
|
||||
- RISC-V reader for datapath examples: http://www.riscvbook.com/
|
||||
- Vivado ILA overview: https://docs.xilinx.com/
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# Phase 0 - Architecture Contract
|
||||
|
||||
## Context
|
||||
|
||||
Before writing RTL, define the vocabulary of the CPU: stage boundaries, signal bundles,
|
||||
enums, reset behavior, memory map, and debug expectations. This is similar to defining an
|
||||
internal kernel ABI before implementing subsystems.
|
||||
|
||||
## Goals
|
||||
|
||||
- Establish `rv32_pkg.sv` as the shared contract for the design.
|
||||
- Decide what signals cross between fetch, decode, execute, memory, and writeback.
|
||||
- Create a block diagram that can guide implementation and later refactors.
|
||||
|
||||
## New Concepts
|
||||
|
||||
- RTL: register-transfer level description of hardware behavior.
|
||||
- Package: SystemVerilog namespace for shared types, constants, enums, and structs.
|
||||
- Struct: named bundle of related signals; useful for stage outputs and bus payloads.
|
||||
- Enum: symbolic encoding for choices such as ALU operation or branch type.
|
||||
- Combinational logic: output depends only on current inputs.
|
||||
- Sequential logic: output/state changes on a clock edge.
|
||||
|
||||
## How To Think About It
|
||||
|
||||
You are designing interfaces between hardware blocks, not function signatures. Every
|
||||
field becomes wires or registers, so changing it later can ripple through the whole
|
||||
datapath. Bias toward clarity and explicitness, not clever compression.
|
||||
|
||||
## Learning Tasks
|
||||
|
||||
- Sketch the datapath by hand and label every stage boundary.
|
||||
- Write down which signals are data, control, status, or exception metadata.
|
||||
- Decide which fields are needed now and which are placeholders for later phases.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- Overfitting the package to Phase 1 and then reworking it repeatedly.
|
||||
- Mixing unrelated control signals into loose wires instead of structured bundles.
|
||||
- Treating the diagram as disposable; it should be updated as the design changes.
|
||||
|
||||
## Tooling And Testing
|
||||
|
||||
- Use the package in the smallest possible test module to confirm Vivado accepts it.
|
||||
- Keep package dependencies acyclic; shared types should not import implementation modules.
|
||||
- Run syntax checks early, before several modules depend on a broken type.
|
||||
|
||||
## References
|
||||
|
||||
- SystemVerilog IEEE overview: https://www.accellera.org/downloads/standards/systemverilog
|
||||
- LowRISC style guide: https://github.com/lowRISC/style-guides/blob/master/VerilogCodingStyle.md
|
||||
- RISC-V specifications: https://riscv.org/technical/specifications/
|
||||
|
||||
Reference in New Issue
Block a user