aboutsummaryrefslogtreecommitdiff
path: root/rv64cpu/docs
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-11-07 04:31:31 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-11-07 04:31:31 +0800
commita7d5b2468553c6d3570ca2aa45c27cb93e26cb88 (patch)
tree7031b1fac52e4f858c4e92041485135242768f7b /rv64cpu/docs
parent4ca723bc9dc1b9db1bd03e3b3db0c58079c3f3c4 (diff)
parent3b0b67af63af86c5ec9b2a63defa06b70923b2e3 (diff)
downloadrcc-project-a7d5b2468553c6d3570ca2aa45c27cb93e26cb88.tar.gz
rcc-project-a7d5b2468553c6d3570ca2aa45c27cb93e26cb88.tar.xz
Merge remote-tracking branch 'rv64cpu-import/master'
Diffstat (limited to 'rv64cpu/docs')
-rw-r--r--rv64cpu/docs/architecture.md204
-rw-r--r--rv64cpu/docs/isa_support.md224
-rw-r--r--rv64cpu/docs/memory_map.md113
-rw-r--r--rv64cpu/docs/naming_convention.md197
-rw-r--r--rv64cpu/docs/pipeline_diagram.md156
5 files changed, 894 insertions, 0 deletions
diff --git a/rv64cpu/docs/architecture.md b/rv64cpu/docs/architecture.md
new file mode 100644
index 0000000..9df23d4
--- /dev/null
+++ b/rv64cpu/docs/architecture.md
@@ -0,0 +1,204 @@
+# Microarchitecture Design Document
+
+## Overview
+
+| Parameter | Value |
+|---|---|
+| ISA | RV64GCZicsr_Zifencei (I+M+A+F+D+C) |
+| Pipeline | 5-stage in-order single-issue (IF → ID → EX → MEM → WB) |
+| Privilege Levels | M / S / U |
+| Virtual Memory | Sv39 (39-bit VA, 56-bit PA, three-level page table) |
+| Bus | AXI4-Full (Cache) + AXI4-Lite (Peripherals) |
+| Cache | I-Cache 4KB + D-Cache 4KB (direct-mapped, upgradeable to set-associative) |
+| Debug | JTAG Debug (reserved) |
+
+---
+
+## Pipeline Timing
+
+```
+Cycle: 1 2 3 4 5 6 7
+ ┌─────┬─────┬─────┬─────┬─────┐
+Instr 1 │ IF │ ID │ EX │ MEM │ WB │
+ └─────┼─────┼─────┼─────┼─────┼─────┐
+Instr 2 │ IF │ ID │ EX │ MEM │ WB │
+ └─────┼─────┼─────┼─────┼─────┼─────┐
+Instr 3 │ IF │ ID │ EX │ MEM │ WB │
+ └─────┴─────┴─────┴─────┴─────┘
+```
+
+### Stage Functions
+
+| Stage | Module | Description |
+|---|---|---|
+| **IF** | `if_stage.sv` | PC generation, iTLB virtual-to-physical translation, I-Cache read, instruction alignment, branch prediction interface |
+| **ID** | `id_stage.sv` | Instruction decode (`decoder.sv`), register file read (`regfile.sv`), immediate extension, CSR read, control signal generation |
+| **EX** | `ex_stage.sv` | ALU operations (`alu.sv`), branch resolution (`branch_unit.sv`), multiply/divide (`muldiv.sv`), FPU operations (`fpu.sv`), effective address calculation |
+| **MEM** | `mem_stage.sv` | dTLB virtual-to-physical translation, D-Cache read/write, load data alignment/sign extension, exception detection |
+| **WB** | `wb_stage.sv` | Register file writeback, CSR writeback, final exception/interrupt handling |
+
+### Hazard Handling (`hazard_unit.sv`)
+
+| Type | Strategy |
+|---|---|
+| RAW Data Hazard | EX→EX forwarding, MEM→EX forwarding |
+| Load-use | Stall 1 cycle (insert bubble at IF/ID stage) |
+| Control Hazard | Static not-taken prediction; branch resolved at EX stage, flush IF/ID on misprediction |
+| Structural Hazard | Eliminated by separate I-Cache / D-Cache |
+| FPU Long Latency | Stall EX stage until FPU result ready (or multi-cycle EX) |
+
+---
+
+## Privilege Level Architecture
+
+### Mode Switching
+
+```mermaid
+stateDiagram-v2
+ [*] --> M_Mode : Reset
+ M_Mode --> S_Mode : mret (mstatus.MPP=S)
+ M_Mode --> U_Mode : mret (mstatus.MPP=U)
+ S_Mode --> M_Mode : ecall / exception / interrupt (not delegated)
+ S_Mode --> U_Mode : sret (sstatus.SPP=U)
+ U_Mode --> S_Mode : ecall / exception / interrupt (delegated)
+ U_Mode --> M_Mode : ecall / exception / interrupt (not delegated)
+```
+
+### CSR Register List
+
+#### M-Mode CSRs
+| CSR | Address | Purpose |
+|---|---|---|
+| `mstatus` | 0x300 | Global status (MIE, MPIE, MPP, FS, etc.) |
+| `misa` | 0x301 | ISA capability descriptor (RV64IMAFD) |
+| `medeleg` | 0x302 | Exception delegation to S-mode |
+| `mideleg` | 0x303 | Interrupt delegation to S-mode |
+| `mie` | 0x304 | Interrupt enable |
+| `mtvec` | 0x305 | Trap vector base address |
+| `mscratch` | 0x340 | M-mode scratch register |
+| `mepc` | 0x341 | Exception PC |
+| `mcause` | 0x342 | Trap cause |
+| `mtval` | 0x343 | Trap value |
+| `mip` | 0x344 | Interrupt pending |
+| `mcycle` | 0xB00 | Cycle counter |
+| `minstret` | 0xB02 | Retired instruction counter |
+| `mvendorid` | 0xF11 | Vendor ID |
+| `marchid` | 0xF12 | Architecture ID |
+| `mimpid` | 0xF13 | Implementation ID |
+| `mhartid` | 0xF14 | Hart ID |
+
+#### S-Mode CSRs
+| CSR | Address | Purpose |
+|---|---|---|
+| `sstatus` | 0x100 | S-mode status (subset of mstatus) |
+| `sie` | 0x104 | S-mode interrupt enable |
+| `stvec` | 0x105 | S-mode trap vector |
+| `sscratch` | 0x140 | S-mode scratch register |
+| `sepc` | 0x141 | S-mode exception PC |
+| `scause` | 0x142 | S-mode trap cause |
+| `stval` | 0x143 | S-mode trap value |
+| `sip` | 0x144 | S-mode interrupt pending |
+| `satp` | 0x180 | Page table base address + MODE (Sv39) |
+
+---
+
+## MMU (Sv39)
+
+### Address Translation
+
+```
+63 39 38 30 29 21 20 12 11 0
+┌──────────┬────────────┬────────────┬────────────┬────────────┐
+│ (sign) │ VPN[2] │ VPN[1] │ VPN[0] │ Offset │
+│ 25 bits │ 9 bits │ 9 bits │ 9 bits │ 12 bits │
+└──────────┴────────────┴────────────┴────────────┴────────────┘
+ 39-bit Virtual Address
+```
+
+- **iTLB** (IF stage): 16-entry fully associative, for instruction fetch virtual-to-physical translation
+- **dTLB** (MEM stage): 16-entry fully associative, for Load/Store virtual-to-physical translation
+- **PTW** (`ptw.sv`): On TLB miss, hardware walks the three-level page table, reading page table entries via D-Cache
+- **sfence.vma**: Flush TLB (all entries or selective by ASID/VPN)
+
+### Module Organization
+
+```
+mmu/
+├── mmu_top.sv ← Top-level: arbitrates iTLB/dTLB PTW requests
+├── tlb.sv ← Parameterized TLB: ENTRIES, ASSOC, ASID support
+└── ptw.sv ← Page Table Walker: three-level lookup state machine
+```
+
+---
+
+## FPU Architecture (F+D Extensions)
+
+### Module Organization
+
+```
+rtl/core/fpu/
+├── fpu_top.sv ← FPU top-level (dispatch + result selection)
+├── fp_regfile.sv ← Floating-point register file f0-f31 (64-bit)
+├── fp_add.sv ← Addition/subtraction unit
+├── fp_mul.sv ← Multiplication unit
+├── fp_div_sqrt.sv ← Division/square root (multi-cycle)
+├── fp_fma.sv ← Fused multiply-add (optional, high performance)
+├── fp_conv.sv ← Format conversion (int↔fp, f32↔f64)
+├── fp_cmp.sv ← Compare/classify (FEQ/FLT/FLE/FCLASS)
+└── include/
+ └── fp_pkg.sv ← Floating-point types, rounding modes, exception flags
+```
+
+> **Note**: FPU operations typically require multiple cycles (especially division/square root), requiring FPU long-latency stall handling in hazard_unit. CSRs `fcsr` / `frm` / `fflags` are implemented in `csr_unit.sv`.
+
+---
+
+## Cache Subsystem
+
+See [memory_map.md](memory_map.md) for address mapping.
+
+| Parameter | I-Cache | D-Cache |
+|---|---|---|
+| Capacity | 4 KB | 4 KB |
+| Line Size | 64 B (8 × 64-bit) | 64 B |
+| Associativity | Direct-mapped (initial) | Direct-mapped (initial) |
+| Write Policy | N/A | Write-back + write-allocate |
+| Refill Bus | AXI4-Full Burst | AXI4-Full Burst |
+
+### Cache Line Calculation
+
+- 4 KB / 64 B = 64 lines
+- Tag = PA[55:12], Index = PA[11:6], Offset = PA[5:0]
+
+---
+
+## Bus Interconnect
+
+```
+┌────────────────┐ ┌────────────────┐
+│ I-Cache │ │ D-Cache │
+│ AXI4 Master │ │ AXI4 Master │
+└───────┬────────┘ └───────┬────────┘
+ │ │
+ └──────┐ ┌──────────┘
+ ▼ ▼
+ ┌──────────────┐
+ │ AXI4 Arbiter │
+ └──────┬───────┘
+ ▼
+ ┌──────────────┐
+ │ AXI4 Xbar │ ← Address decode
+ └──┬───┬───┬───┘
+ │ │ │
+ ┌──────┘ │ └──────┐
+ ▼ ▼ ▼
+┌───────┐ ┌───────────┐ ┌─────────────────┐
+│ SRAM │ │AXI4→Lite │ │ (Expandable │
+│ Ctrl │ │ Bridge │ │ Slave) │
+└───────┘ └─────┬─────┘ └─────────────────┘
+ │
+ ┌───┬───┴───┬───┐
+ ▼ ▼ ▼ ▼
+ CLINT PLIC UART GPIO
+ (AXI4-Lite Slaves)
+```
diff --git a/rv64cpu/docs/isa_support.md b/rv64cpu/docs/isa_support.md
new file mode 100644
index 0000000..0173a58
--- /dev/null
+++ b/rv64cpu/docs/isa_support.md
@@ -0,0 +1,224 @@
+# ISA Support Matrix
+
+## Target ISA String
+
+```
+RV64GCZicsr_Zifencei
+```
+
+Equivalent to `RV64IMAFDCZicsr_Zifencei`
+
+---
+
+## Extension Implementation Status
+
+| Extension | Full Name | Status | Description |
+|---|---|---|---|
+| **I** | Base Integer (RV64I) | 🟢 Implemented | Strict ACT4 compliance suite passes (`rv64i`) |
+| **M** | Multiply/Divide | 🟢 Implemented | Strict ACT4 compliance suite passes (`rv64im`) |
+| **A** | Atomic | 🟢 Implemented | Strict ACT4 compliance suite passes (`rv64ia`) |
+| **F** | Single-Precision Float | 🟢 Implemented | Strict ACT4 compliance suite passes (`rv64if`) |
+| **D** | Double-Precision Float | 🟢 Implemented | Strict ACT4 compliance suite passes (`rv64id`) |
+| **C** | Compressed | 🟢 Implemented | Strict ACT4 compliance suite passes (`rv64ic`) |
+| **Zicsr** | CSR Instructions | 🟢 Implemented | Full CSR unit with delegation, FCSR, and dedicated testbench ([rtl/core/csr_unit.sv](rtl/core/csr_unit.sv), [tb/unit/tb_csr.cc](tb/unit/tb_csr.cc)) |
+| **Zifencei** | Instruction Fence | 🟢 Implemented | Included in strict ACT4 passing suites |
+
+Privilege-related tests (`S`, `Sm`) also pass through `rv64priv` strict suite.
+
+---
+
+## Recent Progress Highlights (2026-04)
+
+- `riscv-arch-test` ACT4 flow integrated in `scripts/run_compliance.py`.
+- Dedicated `tb/compliance/compliance_runner.cc` executes ELF tests and dumps signatures.
+- Strict suite passes with reference comparison enabled (`--require-reference`):
+ - `rv64i` (51/51)
+ - `rv64im` (64/64)
+ - `rv64ia` (51/51)
+ - `rv64ic` (51/51)
+ - `rv64if` (133/133)
+ - `rv64id` (165/165)
+ - `rv64priv` (2/2)
+ - `rv64full` aggregate (262/262)
+
+## Detailed Instruction Tables
+
+The detailed per-instruction checklist sections below are retained as reference,
+but are not the primary source of truth for completion status at this stage.
+Current completion is determined by strict ACT4 suite pass results listed above.
+
+---
+
+## RV64I Instruction List
+
+### R-type Arithmetic/Logic
+| Instruction | Operation | Status |
+|---|---|---|
+| ADD | rd = rs1 + rs2 | ⬜ |
+| SUB | rd = rs1 - rs2 | ⬜ |
+| AND | rd = rs1 & rs2 | ⬜ |
+| OR | rd = rs1 \| rs2 | ⬜ |
+| XOR | rd = rs1 ^ rs2 | ⬜ |
+| SLL | rd = rs1 << rs2[5:0] | ⬜ |
+| SRL | rd = rs1 >> rs2[5:0] (logical) | ⬜ |
+| SRA | rd = rs1 >> rs2[5:0] (arith) | ⬜ |
+| SLT | rd = (rs1 < rs2) ? 1 : 0 (signed) | ⬜ |
+| SLTU | rd = (rs1 < rs2) ? 1 : 0 (unsigned) | ⬜ |
+
+### R-type RV64 Word Operations
+| Instruction | Operation | Status |
+|---|---|---|
+| ADDW | rd = sext((rs1+rs2)[31:0]) | ⬜ |
+| SUBW | rd = sext((rs1-rs2)[31:0]) | ⬜ |
+| SLLW | rd = sext((rs1 << rs2[4:0])[31:0]) | ⬜ |
+| SRLW | rd = sext((rs1[31:0] >> rs2[4:0])) | ⬜ |
+| SRAW | rd = sext((rs1[31:0] >>> rs2[4:0])) | ⬜ |
+
+### I-type Immediate Arithmetic
+| Instruction | Operation | Status |
+|---|---|---|
+| ADDI | rd = rs1 + imm | ⬜ |
+| ANDI | rd = rs1 & imm | ⬜ |
+| ORI | rd = rs1 \| imm | ⬜ |
+| XORI | rd = rs1 ^ imm | ⬜ |
+| SLLI | rd = rs1 << shamt[5:0] | ⬜ |
+| SRLI | rd = rs1 >> shamt[5:0] (logical) | ⬜ |
+| SRAI | rd = rs1 >> shamt[5:0] (arith) | ⬜ |
+| SLTI | rd = (rs1 < imm) ? 1 : 0 (signed) | ⬜ |
+| SLTIU | rd = (rs1 < imm) ? 1 : 0 (unsigned) | ⬜ |
+| ADDIW | rd = sext((rs1+imm)[31:0]) | ⬜ |
+| SLLIW | rd = sext((rs1 << shamt[4:0])[31:0]) | ⬜ |
+| SRLIW | rd = sext((rs1[31:0] >> shamt[4:0])) | ⬜ |
+| SRAIW | rd = sext((rs1[31:0] >>> shamt[4:0])) | ⬜ |
+
+### Load
+| Instruction | Width | Sign Extension | Status |
+|---|---|---|---|
+| LB | 8-bit | Signed | ⬜ |
+| LBU | 8-bit | Zero-extended | ⬜ |
+| LH | 16-bit | Signed | ⬜ |
+| LHU | 16-bit | Zero-extended | ⬜ |
+| LW | 32-bit | Signed | ⬜ |
+| LWU | 32-bit | Zero-extended | ⬜ |
+| LD | 64-bit | — | ⬜ |
+
+### Store
+| Instruction | Width | Status |
+|---|---|---|
+| SB | 8-bit | ⬜ |
+| SH | 16-bit | ⬜ |
+| SW | 32-bit | ⬜ |
+| SD | 64-bit | ⬜ |
+
+### Branch
+| Instruction | Condition | Status |
+|---|---|---|
+| BEQ | rs1 == rs2 | ⬜ |
+| BNE | rs1 != rs2 | ⬜ |
+| BLT | rs1 < rs2 (signed) | ⬜ |
+| BGE | rs1 >= rs2 (signed) | ⬜ |
+| BLTU | rs1 < rs2 (unsigned) | ⬜ |
+| BGEU | rs1 >= rs2 (unsigned) | ⬜ |
+
+### Upper Immediate / Jump
+| Instruction | Operation | Status |
+|---|---|---|
+| LUI | rd = imm << 12 | ⬜ |
+| AUIPC | rd = pc + (imm << 12) | ⬜ |
+| JAL | rd = pc+4; pc = pc + imm | ⬜ |
+| JALR | rd = pc+4; pc = (rs1 + imm) & ~1 | ⬜ |
+
+### System
+| Instruction | Status |
+|---|---|
+| ECALL | ⬜ |
+| EBREAK | ⬜ |
+| MRET | ⬜ |
+| SRET | ⬜ |
+| WFI | ⬜ |
+| FENCE | ⬜ |
+| FENCE.I | ⬜ |
+| SFENCE.VMA | ⬜ |
+
+---
+
+## M Extension (Multiply/Divide)
+
+| Instruction | Operation | Status |
+|---|---|---|
+| MUL | rd = (rs1 × rs2)[63:0] | ⬜ |
+| MULH | rd = (rs1 × rs2)[127:64] signed | ⬜ |
+| MULHSU | rd = (rs1 × rs2)[127:64] signed×unsigned | ⬜ |
+| MULHU | rd = (rs1 × rs2)[127:64] unsigned | ⬜ |
+| DIV | rd = rs1 / rs2 signed | ⬜ |
+| DIVU | rd = rs1 / rs2 unsigned | ⬜ |
+| REM | rd = rs1 % rs2 signed | ⬜ |
+| REMU | rd = rs1 % rs2 unsigned | ⬜ |
+| MULW | rd = sext((rs1×rs2)[31:0]) | ⬜ |
+| DIVW / DIVUW | 32-bit division | ⬜ |
+| REMW / REMUW | 32-bit remainder | ⬜ |
+
+---
+
+## A Extension (Atomic Instructions)
+
+| Instruction | Status |
+|---|---|
+| LR.W / LR.D | ⬜ |
+| SC.W / SC.D | ⬜ |
+| AMOSWAP.W/D | ⬜ |
+| AMOADD.W/D | ⬜ |
+| AMOAND.W/D | ⬜ |
+| AMOOR.W/D | ⬜ |
+| AMOXOR.W/D | ⬜ |
+| AMOMAX[U].W/D | ⬜ |
+| AMOMIN[U].W/D | ⬜ |
+
+---
+
+## F/D Extension (Floating-Point)
+
+| Category | F (32-bit) Instructions | D (64-bit) Instructions | Status |
+|---|---|---|---|
+| Load/Store | FLW, FSW | FLD, FSD | ⬜ |
+| Arithmetic | FADD.S, FSUB.S, FMUL.S, FDIV.S, FSQRT.S | FADD.D, ... | ⬜ |
+| Fused Multiply-Add | FMADD.S, FMSUB.S, FNMADD.S, FNMSUB.S | FMADD.D, ... | ⬜ |
+| Sign Manipulation | FSGNJ[N/X].S | FSGNJ[N/X].D | ⬜ |
+| Compare | FEQ.S, FLT.S, FLE.S | FEQ.D, FLT.D, FLE.D | ⬜ |
+| Classify | FCLASS.S | FCLASS.D | ⬜ |
+| Conversion | FCVT.W/WU/L/LU.S, FCVT.S.W/WU/L/LU | FCVT.*.D | ⬜ |
+| F↔D Conversion | — | FCVT.S.D, FCVT.D.S | ⬜ |
+| Move | FMV.X.W, FMV.W.X | FMV.X.D, FMV.D.X | ⬜ |
+| MIN/MAX | FMIN.S, FMAX.S | FMIN.D, FMAX.D | ⬜ |
+
+### Floating-Point CSRs
+| CSR | Address | Description |
+|---|---|---|
+| `fflags` | 0x001 | Floating-point exception flags (NV, DZ, OF, UF, NX) |
+| `frm` | 0x002 | Floating-point rounding mode |
+| `fcsr` | 0x003 | fflags + frm combined |
+
+---
+
+## C Extension (Compressed Instructions)
+
+16-bit encoded subset of common instructions, improving code density. Requires handling 16/32-bit mixed instruction stream alignment at the IF stage.
+
+| Quadrant | Selected Instructions | Status |
+|---|---|---|
+| C0 | C.LW, C.LD, C.SW, C.SD, C.ADDI4SPN | ⬜ |
+| C1 | C.ADDI, C.LI, C.LUI, C.SRLI, C.SRAI, C.ANDI, C.SUB, C.XOR, C.OR, C.AND, C.J, C.BEQZ, C.BNEZ | ⬜ |
+| C2 | C.SLLI, C.LDSP, C.LWSP, C.JR, C.MV, C.JALR, C.ADD, C.SDSP, C.SWSP | ⬜ |
+
+---
+
+## Zicsr Instructions
+
+| Instruction | Operation | Status |
+|---|---|---|
+| CSRRW | t=CSR; CSR=rs1; rd=t | ⬜ |
+| CSRRS | t=CSR; CSR=t\|rs1; rd=t | ⬜ |
+| CSRRC | t=CSR; CSR=t&~rs1; rd=t | ⬜ |
+| CSRRWI | t=CSR; CSR=zimm; rd=t | ⬜ |
+| CSRRSI | t=CSR; CSR=t\|zimm; rd=t | ⬜ |
+| CSRRCI | t=CSR; CSR=t&~zimm; rd=t | ⬜ |
diff --git a/rv64cpu/docs/memory_map.md b/rv64cpu/docs/memory_map.md
new file mode 100644
index 0000000..9bf529b
--- /dev/null
+++ b/rv64cpu/docs/memory_map.md
@@ -0,0 +1,113 @@
+# Memory Map
+
+## Physical Address Space
+
+```
+0xFFFF_FFFF_FFFF_FFFF ┌─────────────────────────┐
+ │ │
+ │ (unused) │
+ │ │
+0x0000_0000_1000_2000 ├─────────────────────────┤
+ │ GPIO 4 KB │
+0x0000_0000_1000_1000 ├─────────────────────────┤
+ │ UART0 4 KB │
+0x0000_0000_1000_0000 ├─────────────────────────┤
+ │ │
+ │ (unused) │
+ │ │
+0x0000_0000_0C00_0000 ├─────────────────────────┤
+ │ PLIC 64 MB │
+0x0000_0000_0BFF_FFFF ├─────────────────────────┤
+ │ │
+ │ (unused) │
+ │ │
+0x0000_0000_0200_FFFF ├─────────────────────────┤
+ │ CLINT 64 KB │
+0x0000_0000_0200_0000 ├─────────────────────────┤
+ │ │
+ │ (unused) │
+ │ │
+0x0000_0000_0FFF_FFFF ├─────────────────────────┤
+ │ │
+ │ SRAM / RAM ~256 MB │
+ │ (Boot ROM at lowest │
+ │ 64KB) │
+ │ │
+0x0000_0000_0000_0000 └─────────────────────────┘
+```
+
+## Address Decode Table
+
+| Start Address | End Address | Size | Peripheral | Bus | Description |
+|---|---|---|---|---|---|
+| `0x0000_0000` | `0x0FFF_FFFF` | 256 MB | SRAM Controller | AXI4-Full | Boot ROM (0x0~0xFFFF) + RAM |
+| `0x0200_0000` | `0x0200_FFFF` | 64 KB | CLINT | AXI4-Lite | mtime, mtimecmp, MSIP |
+| `0x0C00_0000` | `0x0FFF_FFFF` | 64 MB | PLIC | AXI4-Lite | External interrupt controller |
+| `0x1000_0000` | `0x1000_0FFF` | 4 KB | UART0 | AXI4-Lite | 16550 compatible |
+| `0x1000_1000` | `0x1000_1FFF` | 4 KB | GPIO | AXI4-Lite | General-purpose I/O |
+
+> **Note**: The address ranges for CLINT and PLIC follow the RISC-V community recommended layout, compatible with Linux/OpenSBI.
+
+## CLINT Register Layout
+
+| Offset | Register | Description |
+|---|---|---|
+| `0x0000` | `msip[0]` | Machine software interrupt pending |
+| `0x4000` | `mtimecmp[0]` | Machine timer compare value (64-bit) |
+| `0xBFF8` | `mtime` | Machine timer current value (64-bit) |
+
+## PLIC Register Layout (Simplified)
+
+| Offset | Register | Description |
+|---|---|---|
+| `0x000000` | `priority[1..N]` | Interrupt source priority |
+| `0x001000` | `pending[0..N/32]` | Interrupt pending bitfield |
+| `0x002000` | `enable[ctx][0..N/32]` | Interrupt enable bitfield |
+| `0x200000` | `threshold[ctx]` | Priority threshold |
+| `0x200004` | `claim/complete[ctx]` | Interrupt claim/complete |
+
+## UART0 Register Layout (16550)
+
+| Offset | Register | Read/Write | Description |
+|---|---|---|---|
+| `0x00` | RBR / THR | R / W | Receive/transmit data |
+| `0x01` | IER | R/W | Interrupt enable |
+| `0x02` | IIR / FCR | R / W | Interrupt identification / FIFO control |
+| `0x03` | LCR | R/W | Line control |
+| `0x05` | LSR | R | Line status |
+
+## Linker Script Correspondence
+
+The MEMORY regions in `sw/common/link.ld` correspond to this table:
+- `ROM`: `0x0000_0000`, 64 KB
+- `RAM`: `0x0001_0000`, 256 MB - 64 KB
+
+## Address Decode Implementation
+
+The address decode logic in RTL is located in `rtl/soc/mem_map.sv` and `rtl/bus/axi4_xbar.sv`.
+
+Constants are defined in `mem_map.sv`:
+
+```systemverilog
+package mem_map_pkg;
+ // SRAM
+ localparam logic [63:0] SRAM_BASE = 64'h0000_0000;
+ localparam logic [63:0] SRAM_SIZE = 64'h1000_0000; // 256 MB
+
+ // CLINT
+ localparam logic [63:0] CLINT_BASE = 64'h0200_0000;
+ localparam logic [63:0] CLINT_SIZE = 64'h0001_0000; // 64 KB
+
+ // PLIC
+ localparam logic [63:0] PLIC_BASE = 64'h0C00_0000;
+ localparam logic [63:0] PLIC_SIZE = 64'h0400_0000; // 64 MB
+
+ // UART0
+ localparam logic [63:0] UART0_BASE = 64'h1000_0000;
+ localparam logic [63:0] UART0_SIZE = 64'h0000_1000; // 4 KB
+
+ // GPIO
+ localparam logic [63:0] GPIO_BASE = 64'h1000_1000;
+ localparam logic [63:0] GPIO_SIZE = 64'h0000_1000; // 4 KB
+endpackage
+```
diff --git a/rv64cpu/docs/naming_convention.md b/rv64cpu/docs/naming_convention.md
new file mode 100644
index 0000000..830c5e5
--- /dev/null
+++ b/rv64cpu/docs/naming_convention.md
@@ -0,0 +1,197 @@
+# RTL Signal Naming Convention
+
+This document defines the naming rules for all SystemVerilog signals, ports, types,
+and modules in the Richard-CPU project. Follow these rules when writing new RTL or
+modifying existing code.
+
+## 1. General Rules
+
+| Rule | Example |
+|---|---|
+| All names use `snake_case` (lowercase + underscores) | `alu_result`, `rs1_addr` |
+| Names should be descriptive; avoid single-letter names except loop indices | `i` in `for(int i = ...)` is acceptable |
+| Abbreviations are allowed **only** from the approved list (Section 7) | `addr` not `address`, `imm` not `immediate` |
+| No trailing numbers for disambiguation; use descriptive suffixes instead | `read_port_a` not `read_port_1` |
+
+### 1.1 Semantic Clarity Priority
+
+When multiple names are technically valid, prefer the name with the clearest
+semantic meaning:
+
+1. Prefer full words over unclear abbreviations unless listed in Section 7.
+2. Prefer domain-accurate nouns over generic placeholders.
+3. Prefer names that communicate role and timing (source, destination, stage).
+
+Examples:
+- `interrupt_cause` is preferred over `int_cause`
+- `trap_target_pc` is preferred over `trap_next_value`
+- `csr_write_data` is preferred over `csr_write_val`
+
+## 2. Module & Package Names
+
+| Item | Rule | Example |
+|---|---|---|
+| Module | `snake_case`, named after function | `alu`, `regfile`, `decoder`, `if_stage` |
+| Package | `snake_case` ending in `_pkg` | `rv64_pkg` |
+| Typedef | `snake_case` ending in `_t` | `alu_op_t`, `opcode_t` |
+| Enum members | `UPPER_SNAKE_CASE` with a common prefix | `ALU_ADD`, `OPCODE_LUI` |
+| Parameters / localparams | `UPPER_SNAKE_CASE` | `XLEN`, `INST_WIDTH` |
+
+## 3. Port & Signal Names
+
+### 3.1 Standard Suffixes
+
+Use these suffixes consistently to indicate the **role** of a signal:
+
+| Suffix | Meaning | Example |
+|---|---|---|
+| `_addr` | Address (register index or memory address) | `rs1_addr`, `rd_addr` |
+| `_data` | Data bus (generic read/write payload) | `mem_rdata`, `mem_wdata` |
+| `_rdata` | Read data (output from a storage element) | `rs1_rdata`, `rs2_rdata` |
+| `_wdata` | Write data (input to a storage element) | `rd_wdata` |
+| `_op` | Operation selector (typically an enum or funct3) | `alu_op`, `branch_op`, `csr_op` |
+| `_sel` | Mux select signal | `alu_src1_sel`, `wb_sel` |
+| `_en` | Enable (active-high gating signal) | `reg_write_en`, `mem_read_en` |
+| `_val` | **Deprecated — do not use for new code.** Use `_rdata`/`_wdata`/`_data` instead | — |
+
+Additional clarity rules:
+- `*_value` is allowed for architectural/state snapshots when `*_data` would be
+ ambiguous. Example: `csr_mstatus_value`.
+- For storage read/write payloads, always prefer `_rdata`/`_wdata`/`_data` over
+ `_value`.
+- `_flag` is deprecated for new boolean signals. Use `is_<noun>`, `has_<noun>`,
+ or `<adjective>_<noun>`.
+
+### 3.2 Standard Prefixes
+
+| Prefix | Meaning | Example |
+|---|---|---|
+| `is_` | Boolean flag indicating instruction type or state | `is_load`, `is_branch`, `is_csr` |
+| `has_` | Boolean flag indicating a condition is met | `has_exception`, `has_interrupt` |
+
+### 3.3 Rules for Boolean / Control Signals
+
+All single-bit control signals should follow **one** of these patterns:
+
+| Pattern | When to Use | Example |
+|---|---|---|
+| `is_<noun>` | Classifying an instruction or state | `is_load`, `is_jump`, `is_ecall` |
+| `<noun>_en` | Enabling a write or action | `reg_write_en`, `mem_write_en` |
+| `<adjective>_<noun>` | Describing a property | `illegal_instr`, `branch_taken` |
+
+> **Consistency rule**: For write-enable signals on storage elements (register file,
+> memory, CSR), always use the `_en` suffix. Example: `reg_write_en`, not `reg_write`.
+
+Additional boolean rules:
+- Avoid suffix-only boolean naming such as `*_flag` and `*_bool` in new code.
+- `has_` is for condition presence (`has_interrupt`), `is_` is for classification
+ (`is_interrupt` for a classified event or type).
+
+### 3.4 Clock & Reset
+
+| Signal | Name | Description |
+|---|---|---|
+| Clock | `clk` | Single system clock |
+| Reset | `rst_n` (preferred) or `rst` | Active-low (`rst_n`) is preferred; if active-high, use `rst` |
+
+> Current codebase uses active-high `rst`. If you later switch to active-low, rename
+> to `rst_n` everywhere in a single commit.
+
+## 4. Pipeline Stage Prefixes
+
+When signals cross pipeline stages, prefix them with the stage abbreviation:
+
+| Stage | Prefix | Example |
+|---|---|---|
+| Instruction Fetch | `if_` | `if_pc`, `if_instr` |
+| Instruction Decode | `id_` | `id_rs1_addr`, `id_imm` |
+| Execute | `ex_` | `ex_alu_result`, `ex_branch_taken` |
+| Memory Access | `mem_` | `mem_rdata`, `mem_addr` |
+| Write Back | `wb_` | `wb_rd_wdata`, `wb_rd_addr` |
+
+Inter-stage pipeline registers use a combined prefix: `id_ex_reg_write_en`,
+`ex_mem_alu_result`.
+
+## 5. ALU Port Naming
+
+The ALU is a **generic compute unit**. Its inputs are not always register values —
+they may come from the PC or an immediate after mux selection. Use neutral names:
+
+| Port | Current (non-conforming) | Recommended |
+|---|---|---|
+| Operand 1 input | `rs1_val` | `operand_a` |
+| Operand 2 input | `rs2_val` | `operand_b` |
+| Result output | `alu_res` | `alu_result` |
+
+## 6. Register File Port Naming
+
+| Port | Name | Description |
+|---|---|---|
+| Read address 1 | `rs1_addr` | Source register 1 index |
+| Read data 1 | `rs1_rdata` | Source register 1 data output |
+| Read address 2 | `rs2_addr` | Source register 2 index |
+| Read data 2 | `rs2_rdata` | Source register 2 data output |
+| Write address | `rd_addr` | Destination register index |
+| Write data | `rd_wdata` | Destination register data input |
+| Write enable | `reg_write_en` | Write enable (active high) |
+
+## 7. Approved Abbreviations
+
+Only these abbreviations are permitted. All other words should be spelled in full.
+
+| Abbreviation | Full Form |
+|---|---|
+| `addr` | address |
+| `alu` | arithmetic logic unit |
+| `clk` | clock |
+| `csr` | control and status register |
+| `en` | enable |
+| `ex` | execute (pipeline stage only) |
+| `fpu` | floating-point unit |
+| `id` | instruction decode (pipeline stage only) |
+| `if` | instruction fetch (pipeline stage only) |
+| `imm` | immediate |
+| `instr` | instruction |
+| `mem` | memory |
+| `mmu` | memory management unit |
+| `mux` | multiplexer |
+| `op` | operation |
+| `pc` | program counter |
+| `rd` | destination register |
+| `rdata` | read data |
+| `reg` | register |
+| `res` | **Deprecated — use `result`** |
+| `rs1` / `rs2` | source register 1 / 2 |
+| `rst` | reset |
+| `sel` | select |
+| `tlb` | translation lookaside buffer |
+| `val` | **Deprecated — use `rdata`/`wdata`/`data`** |
+| `wb` | write back (pipeline stage only) |
+| `wdata` | write data |
+
+Not approved for new code:
+- `int` (use `interrupt`)
+- `flag` suffix for booleans (use Section 3.3 patterns)
+
+## 7.1 Architecture-Defined Bit Names (Exception)
+
+Some names come directly from ISA-defined bit semantics and are allowed in narrow
+scopes even if they are single-letter:
+
+- PTE-like permission bits: `u`, `r`, `w`, `x`, `a`, `d`, `g`
+
+Scope limits:
+1. Allowed only inside tightly scoped structs, packed fields, or helper function
+ parameters tied to ISA semantics.
+2. For module ports and cross-module buses, prefer descriptive names such as
+ `pte_user`, `pte_read`, `pte_write`, `pte_exec`, `pte_accessed`, `pte_dirty`,
+ `pte_global`.
+
+## 8. Current Codebase Non-Conformances
+
+The following table lists signals in the existing codebase that do not yet follow
+this convention. These should be renamed during the next refactoring pass.
+
+| File | Current Name | Recommended Name | Reason |
+|---|---|---|---|
+|None|None|None|None|
diff --git a/rv64cpu/docs/pipeline_diagram.md b/rv64cpu/docs/pipeline_diagram.md
new file mode 100644
index 0000000..e2f6bdb
--- /dev/null
+++ b/rv64cpu/docs/pipeline_diagram.md
@@ -0,0 +1,156 @@
+# Pipeline Timing and Datapath
+
+## Five-Stage Pipeline Datapath
+
+```
+ ┌────────────────────────────────────────────────────────────────┐
+ │ HAZARD UNIT │
+ │ Forward A/B, Stall, Flush, FPU interlock │
+ └──┬─────────┬──────────┬──────────┬──────────┬────────────────┘
+ │ │ │ │ │
+ ┌─────▼──┐ ┌───▼───┐ ┌────▼───┐ ┌───▼────┐ ┌──▼─────┐
+ │ IF │ │ ID │ │ EX │ │ MEM │ │ WB │
+ │ │ │ │ │ │ │ │ │ │
+ ┌──────┐ │ PC Gen │ │Decode │ │ ALU │ │D-Cache │ │ Write │
+ │ iTLB ├───►│ ↓ │ │ ↓ │ │ Branch │ │ LSU │ │ Back │
+ │ │ │I-Cache │ │RegFile│ │ MulDiv │ │ dTLB │ │ │
+ └──────┘ │ Fetch │ │ Read │ │ FPU │ │ │ │ │
+ │ │ │ ImmEx │ │ │ │ │ │ │
+ └───┬────┘ └───┬───┘ └────┬───┘ └───┬────┘ └───┬────┘
+ │ │ │ │ │
+ ┌───▼──────────▼──┐ ┌─────▼──────────▼──┐ ┌────▼─────┐
+ │ IF/ID Reg │ │ EX/MEM Reg │ │ MEM/WB │
+ │ │ │ │ │ Reg │
+ └────────────────┘ └────────────────────┘ └──────────┘
+ ↑
+ ┌───────┴───────┐
+ │ CSR Unit │
+ │ Trap Ctrl │
+ └───────────────┘
+```
+
+---
+
+## Inter-Stage Registers
+
+### IF/ID Register
+
+| Field | Width | Description |
+|---|---|---|
+| `pc` | 64 | Current instruction PC |
+| `instr` | 32 | Fetched instruction |
+| `valid` | 1 | Instruction valid |
+| `exception` | 1 | IF stage exception (e.g., instruction page fault) |
+| `exc_code` | 4 | Exception code |
+| `predicted_taken` | 1 | Branch prediction result |
+| `predicted_target` | 64 | Predicted target address |
+
+### ID/EX Register
+
+| Field | Width | Description |
+|---|---|---|
+| `pc` | 64 | |
+| `rs1_data` | 64 | Register source 1 value |
+| `rs2_data` | 64 | Register source 2 value |
+| `rs3_data` | 64 | FPU source 3 value (FMA) |
+| `imm` | 64 | Sign-extended immediate |
+| `rd_addr` | 5 | Destination register address |
+| `rs1_addr` | 5 | Source 1 address (for forwarding) |
+| `rs2_addr` | 5 | Source 2 address (for forwarding) |
+| `ctrl` | struct | Control signal bundle (ALU op, mem r/w, branch type, etc.) |
+| `valid` | 1 | |
+| `is_fp` | 1 | Floating-point instruction flag |
+
+### EX/MEM Register
+
+| Field | Width | Description |
+|---|---|---|
+| `pc` | 64 | |
+| `alu_result` | 64 | ALU/FPU computation result |
+| `rs2_data` | 64 | Store data |
+| `rd_addr` | 5 | |
+| `ctrl_mem` | struct | Memory access control (read/write, size, sign_ext) |
+| `ctrl_wb` | struct | Writeback control (reg_write, wb_sel) |
+| `valid` | 1 | |
+
+### MEM/WB Register
+
+| Field | Width | Description |
+|---|---|---|
+| `pc` | 64 | |
+| `alu_result` | 64 | |
+| `mem_data` | 64 | Data read from D-Cache |
+| `rd_addr` | 5 | |
+| `ctrl_wb` | struct | Writeback control |
+| `valid` | 1 | |
+
+---
+
+## Forwarding Paths
+
+```
+ EX Stage MEM Stage WB Stage
+ ┌────────┐ ┌─────────┐ ┌────────┐
+ │ ALU │ │alu_result│ │ wb_data│
+ │ result ├────────┐ │ or ├────────┐ │ │
+ └────────┘ │ │ mem_data │ │ └────┬───┘
+ │ └─────────┘ │ │
+ ┌─────▼──────────────────────▼────────▼─┐
+ │ Forward MUX │
+ │ sel = hazard_unit.forward_a/b │
+ └─────────────────┬─────────────────────┘
+ │
+ ▼
+ EX Stage rs1/rs2 input
+```
+
+| Forwarding Source | Condition |
+|---|---|
+| EX→EX | `ex_mem.rd == id_ex.rs1/rs2` and `ex_mem.reg_write` |
+| MEM→EX | `mem_wb.rd == id_ex.rs1/rs2` and `mem_wb.reg_write` and no EX forwarding |
+| Load-use | `id_ex.mem_read` and `id_ex.rd == if_id.rs1/rs2` → **stall** |
+
+---
+
+## Branch Handling Timing
+
+```
+Cycle: 1 2 3 4 5
+ ┌─────┬─────┬─────┬─────┬─────┐
+Branch │ IF │ ID │ EX │ MEM │ WB │ ← Branch resolved at EX stage
+ └─────┼─────┼─────┼─────┼─────┘
+Instr+1 │ IF │ ID │ ██ │ ← Misprediction: flush (2-cycle penalty)
+ └─────┼─────┼─────┘
+Instr+2 │ IF │ ██ │ ← flush
+ └─────┴─────┘
+Target │ IF │ ID │ EX │ ... ← Correct path begins
+ └─────┴─────┴─────┘
+```
+
+---
+
+## Cache Miss Timing
+
+```
+Cycle: 1 2 3 4 5 6 7 8 ... N N+1
+ ┌────┬────┬────┬────────────────────────────┬────┬────┐
+Instr │ IF │ ID │ EX │ MEM (D-Cache MISS) │ │ WB │
+ └────┴────┴────┤ Stall pipeline... ├────┴────┘
+ │ AXI4 Burst read (8 beats)│
+ │ Fill cache line │
+ └─────────────────────────────┘
+```
+
+---
+
+## TLB Miss → PTW Timing
+
+```
+Cycle: 1 2 3 ... N N+1 N+2
+ ┌────┬────────────────────────┬────┬────┐
+Instr │ IF │ iTLB MISS → PTW walk │ IF │ ID │ ...
+ └────┤ (3-level page table ├────┴────┘
+ │ × memory latency) │
+ │ Pipeline stalled │
+ └────────────────────────┘
+```