diff options
Diffstat (limited to 'rv64cpu/docs')
| -rw-r--r-- | rv64cpu/docs/architecture.md | 204 | ||||
| -rw-r--r-- | rv64cpu/docs/isa_support.md | 224 | ||||
| -rw-r--r-- | rv64cpu/docs/memory_map.md | 113 | ||||
| -rw-r--r-- | rv64cpu/docs/naming_convention.md | 197 | ||||
| -rw-r--r-- | rv64cpu/docs/pipeline_diagram.md | 156 |
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 │ + └────────────────────────┘ +``` |
