diff --git a/CLAUDE.md b/CLAUDE.md index 5ad8f51..7664155 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,20 +13,20 @@ See ROADMAP.md for the full phased plan. - Language: SystemVerilog (not Verilog). Use SV features: packages, structs, enums, always_comb, always_ff, logic (not reg/wire). -- All inter-stage signals are defined as structs in `rtl/pkg/rv32_pkg.sv`. Always - import this package. When adding new functionality, extend the existing structs - rather than adding loose wires. +- All inter-stage signals are defined as structs in `FPGA/rtl/pkg/rv32_pkg.sv`. + Always import this package. When adding new functionality, extend the existing + structs rather than adding loose wires. - Module naming: `rv32_` (e.g., `rv32_alu`, `rv32_decode`, `rv32_regfile`). - File naming: one module per file, filename matches module name. -- Testbenches: `tb/tb_.sv`. Use Vivado simulator. +- Testbenches: `FPGA/tb/tb_.sv`. Use Vivado simulator. - Clock: single clock domain, active rising edge, signal named `clk`. Target frequency: 50 MHz (derived from the Arty's 100 MHz oscillator via MMCM/2). - Reset: synchronous active-high, signal named `rst`. The Arty's `CK_RST` button is active-low; the top-level wraps it through a 2-FF synchronizer and inverts to produce the internal `rst`. The rest of the design only sees synchronous active-high. -- BRAM init files: `mem/*.mem` in hex format, one 32-bit word per line. -- Firmware source: `fw/` directory. Built with `riscv64-unknown-elf-gcc` +- BRAM init files: `FPGA/mem/*.mem` in hex format, one 32-bit word per line. +- Firmware source: `Software/fw/` directory. Built with `riscv64-unknown-elf-gcc` (multilib build required). March string evolves with the implemented ISA: - Phase 8 (pre-CSR bare-metal): `-march=rv32im -mabi=ilp32` - Phase 12+ (CSRs/Zifencei decoded): `-march=rv32im_zicsr_zifencei -mabi=ilp32` @@ -37,18 +37,35 @@ See ROADMAP.md for the full phased plan. ## Directory Structure ``` -rtl/ — synthesizable source - pkg/ — packages (rv32_pkg.sv) - core/ — CPU core modules (ALU, M unit, decoder, regfile, datapath) - periph/ — peripherals (UART, timer, PLIC, etc.) - top/ — top-level and SoC integration -tb/ — testbenches (tb_.sv) -mem/ — BRAM init files (.mem) -fw/ — firmware source (C, assembly, linker scripts) -constraints/ — Vivado XDC constraint files -docs/ — block diagrams, notes +FPGA/ — everything that ends up on the FPGA + rtl/ — synthesizable source + pkg/ — packages (rv32_pkg.sv) + core/ — CPU core modules (ALU, M unit, decoder, regfile, datapath) + periph/ — peripherals (UART, timer, PLIC, etc.) + top/ — top-level and SoC integration + tb/ — testbenches (tb_.sv) + constraints/ — Vivado XDC constraint files + mem/ — BRAM init files (.mem) + vivado/ — Vivado project workspace (regenerated, not committed) + only create_project.tcl is committed; .xpr and + *.runs / *.cache / *.hw / *.sim / *.gen / *.srcs / + *.ip_user_files are git-ignored +Software/ — software that runs on the CPU + fw/ — bare-metal firmware, crt0, linker scripts (Phase 8+) + bios/ — BIOS / monitor + ELF loader (Phase 9, 10) + kernel/ — tiny custom kernel, later Linux artifacts (Phase 11, 19, 20) +Docs/ — block diagrams, architectural notes ``` +The Vivado project lives in `FPGA/vivado/`, not at the repo root. The `.xpr` +itself is **not** committed — `create_project.tcl` is the source of truth, and +each developer regenerates the project locally with +`vivado -mode batch -source FPGA/vivado/create_project.tcl`. RTL and testbench +files are added to the project as **references** to `../rtl/...` and +`../tb/...` so the actual source of truth stays in version control. All +generated state (`*.xpr`, `*.runs/`, `*.cache/`, `*.hw/`, `*.sim/`, +`*.ip_user_files/`, `*.gen/`, `*.srcs/`) is git-ignored. + ## ISA Target End target: **RV32IMA + Zicsr + Zifencei + M/S/U privilege + Sv32** (Linux-capable). diff --git a/Docs/README.md b/Docs/README.md new file mode 100644 index 0000000..73dd61e --- /dev/null +++ b/Docs/README.md @@ -0,0 +1,6 @@ +# Docs/ + +Architectural notes and the Phase 0.2 block diagram. The diagram is the +visual source of truth for the datapath — draw on paper first, then capture a +digital copy here (e.g. `block-diagram.drawio` exported to SVG/PNG) once it +stabilizes. Update it whenever a stage-boundary struct or bus instance changes. diff --git a/FPGA/README.md b/FPGA/README.md new file mode 100644 index 0000000..287e7e1 --- /dev/null +++ b/FPGA/README.md @@ -0,0 +1,4 @@ +# FPGA/ + +Everything that ends up on the FPGA: SystemVerilog source, testbenches, +constraints, memory init files, and the Vivado project. diff --git a/FPGA/constraints/README.md b/FPGA/constraints/README.md new file mode 100644 index 0000000..8e629a4 --- /dev/null +++ b/FPGA/constraints/README.md @@ -0,0 +1,4 @@ +# FPGA/constraints/ + +Vivado XDC constraint files: pin assignments for the Arty A7, clock +definitions, and timing constraints. diff --git a/FPGA/mem/README.md b/FPGA/mem/README.md new file mode 100644 index 0000000..55c1233 --- /dev/null +++ b/FPGA/mem/README.md @@ -0,0 +1,4 @@ +# FPGA/mem/ + +BRAM init files (`.mem`) in hex format, one 32-bit word per line. Loaded by +`$readmemh` into instruction/data BRAM at elaboration. diff --git a/FPGA/rtl/README.md b/FPGA/rtl/README.md new file mode 100644 index 0000000..1f8e651 --- /dev/null +++ b/FPGA/rtl/README.md @@ -0,0 +1,4 @@ +# FPGA/rtl/ + +Synthesizable SystemVerilog source. One module per file, filename matches +module name (e.g. `rv32_alu.sv`). diff --git a/FPGA/rtl/core/README.md b/FPGA/rtl/core/README.md new file mode 100644 index 0000000..8529ebc --- /dev/null +++ b/FPGA/rtl/core/README.md @@ -0,0 +1,4 @@ +# FPGA/rtl/core/ + +CPU core modules: ALU, M unit, decoder, register file, fetch, LSU, datapath, +and (later) CSR file and MMU. Module names follow `rv32_`. diff --git a/FPGA/rtl/periph/README.md b/FPGA/rtl/periph/README.md new file mode 100644 index 0000000..9b21632 --- /dev/null +++ b/FPGA/rtl/periph/README.md @@ -0,0 +1,4 @@ +# FPGA/rtl/periph/ + +Memory-mapped peripherals: UART (Phase 7), CLINT timer (Phase 13), PLIC +(Phase 14), and any future devices. Each peripheral is a slave on the D-bus. diff --git a/FPGA/rtl/pkg/README.md b/FPGA/rtl/pkg/README.md new file mode 100644 index 0000000..a7fac7c --- /dev/null +++ b/FPGA/rtl/pkg/README.md @@ -0,0 +1,4 @@ +# FPGA/rtl/pkg/ + +Shared SystemVerilog packages — the type contract for the design. +`rv32_pkg.sv` (enums, stage-boundary structs, bus payloads) lives here. diff --git a/FPGA/rtl/top/README.md b/FPGA/rtl/top/README.md new file mode 100644 index 0000000..5eeb903 --- /dev/null +++ b/FPGA/rtl/top/README.md @@ -0,0 +1,5 @@ +# FPGA/rtl/top/ + +Top-level modules and SoC integration: clock/reset wrapping (MMCM, reset +synchronizer), bus arbitration, address decode, and the board-level top that +maps to the Arty A7 pins. diff --git a/FPGA/tb/README.md b/FPGA/tb/README.md new file mode 100644 index 0000000..b65acb5 --- /dev/null +++ b/FPGA/tb/README.md @@ -0,0 +1,4 @@ +# FPGA/tb/ + +SystemVerilog testbenches, one per module under test. Naming: `tb_.sv`. +Run with the Vivado simulator (xsim). diff --git a/FPGA/vivado/.gitignore b/FPGA/vivado/.gitignore new file mode 100644 index 0000000..0375d2e --- /dev/null +++ b/FPGA/vivado/.gitignore @@ -0,0 +1,34 @@ +# Vivado-generated project state. The committed source of truth is +# create_project.tcl — everything below (including the .xpr itself, which +# embeds machine-specific paths) is regenerated by running that script. + +# The project file itself — regenerated from create_project.tcl +*.xpr + +# Project-wide generated directories (named after the .xpr basename) +*.cache/ +*.hw/ +*.sim/ +*.runs/ +*.ip_user_files/ +*.gen/ +*.srcs/ + +# Vivado scratch / temp +.Xil/ +xsim.dir/ + +# Logs, journals, autosave backups +*.jou +*.log +*.str +*.backup.* +*.wdb +*.pb +vivado*.jou +vivado*.log + +# Webtalk telemetry +webtalk*.jou +webtalk*.log +usage_statistics_webtalk.* diff --git a/FPGA/vivado/README.md b/FPGA/vivado/README.md new file mode 100644 index 0000000..c4658cd --- /dev/null +++ b/FPGA/vivado/README.md @@ -0,0 +1,19 @@ +# FPGA/vivado/ + +The Vivado project workspace. The committed source of truth is +`create_project.tcl`; the project file (`FPGA-Core.xpr`) and all of Vivado's +generated state (`*.runs/`, `*.cache/`, `*.hw/`, `*.sim/`, `*.ip_user_files/`, +`*.gen/`, `*.srcs/`) are git-ignored — `.xpr` files embed machine-specific +paths and are regenerated locally. + +RTL and testbench files are added to the project as **references** to +`../rtl/...` / `../tb/...` so the actual source of truth stays in version +control, not inside the project file. + +To generate the project, run from the repo root: + +```sh +vivado -mode batch -source FPGA/vivado/create_project.tcl +``` + +Then open the resulting `FPGA/vivado/FPGA-Core.xpr` in the Vivado GUI. diff --git a/FPGA/vivado/create_project.tcl b/FPGA/vivado/create_project.tcl new file mode 100644 index 0000000..03e5034 --- /dev/null +++ b/FPGA/vivado/create_project.tcl @@ -0,0 +1,43 @@ +# create_project.tcl — generate FPGA/vivado/FPGA-Core.xpr +# +# Usage (from the repo root): +# vivado -mode batch -source FPGA/vivado/create_project.tcl +# +# Or from inside FPGA/vivado/: +# vivado -mode batch -source create_project.tcl +# +# Then open the resulting .xpr in the Vivado GUI. To regenerate from scratch, +# delete FPGA-Core.xpr and its sibling *.cache / *.runs / *.hw / *.sim / +# *.ip_user_files / *.gen directories, then re-run. + +set script_dir [file normalize [file dirname [info script]]] +set fpga_dir [file normalize "$script_dir/.."] +set proj_name "FPGA-Core" +set part "xc7a100tcsg324-1" + +if {[file exists "$script_dir/$proj_name.xpr"]} { + puts "Project already exists: $script_dir/$proj_name.xpr" + puts "Delete it (and its sibling *.cache, *.runs, ... dirs) first." + return +} + +create_project $proj_name $script_dir -part $part + +set_property target_language Verilog [current_project] +set_property simulator_language Mixed [current_project] + +# RTL and testbenches are added as references (not copied) so the source of +# truth stays in git, not inside the .xpr. Passing a directory makes Vivado +# recursively pick up all HDL files under it. +add_files "$fpga_dir/rtl" +add_files -fileset sim_1 "$fpga_dir/tb" + +set xdc_files [glob -nocomplain "$fpga_dir/constraints/*.xdc"] +if {[llength $xdc_files] > 0} { + add_files -fileset constrs_1 $xdc_files +} + +update_compile_order -fileset sources_1 +update_compile_order -fileset sim_1 + +puts "Created $script_dir/$proj_name.xpr" diff --git a/README.md b/README.md index 794fd29..c157566 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,19 @@ Requires: - `riscv-tests` (for compliance verification from Phase 8.5) - Serial terminal (minicom/picocom/PuTTY) at 115200 8N1 -Open `FPGA-Core.xpr` in Vivado. Synthesis and implementation target the xc7a100tcsg324-1. +FPGA sources (RTL, testbenches, constraints, BRAM init files, and the Vivado +project script) live under `FPGA/`. Software that runs on the core (firmware, +BIOS, kernels) lives under `Software/`. The Vivado project itself is **not** +committed — generate it from the script and then open it: + +```sh +vivado -mode batch -source FPGA/vivado/create_project.tcl +# then open FPGA/vivado/FPGA-Core.xpr in the Vivado GUI +``` + +Synthesis and implementation target the xc7a100tcsg324-1. RTL sources in +`FPGA/rtl/` and testbenches in `FPGA/tb/` are added to the project as +references — do not let Vivado copy them in. ## Roadmap diff --git a/Software/README.md b/Software/README.md new file mode 100644 index 0000000..1e33acb --- /dev/null +++ b/Software/README.md @@ -0,0 +1,5 @@ +# Software/ + +Software that runs on the CPU: bare-metal firmware, BIOS, and kernels. +Built with the RISC-V GCC toolchain (`riscv64-unknown-elf-gcc`). The `march` +string evolves with the implemented ISA — see `CLAUDE.md`. diff --git a/Software/bios/README.md b/Software/bios/README.md new file mode 100644 index 0000000..56c0f35 --- /dev/null +++ b/Software/bios/README.md @@ -0,0 +1,6 @@ +# Software/bios/ + +BIOS / monitor: an interactive ROM program that talks over UART to peek/poke +memory, dump registers, and load programs into RAM. Includes the ELF loader. + +**Phases:** 9 (BIOS monitor), 10 (ELF loader over UART). diff --git a/Software/fw/README.md b/Software/fw/README.md new file mode 100644 index 0000000..6a18ce4 --- /dev/null +++ b/Software/fw/README.md @@ -0,0 +1,6 @@ +# Software/fw/ + +Bare-metal firmware: `crt0.S`, linker script, and the first C programs that +run on the CPU. Also where `riscv-tests` integration lives. + +**Phases:** 8 (GCC toolchain, first C program, `riscv-tests`). diff --git a/Software/kernel/README.md b/Software/kernel/README.md new file mode 100644 index 0000000..f056db4 --- /dev/null +++ b/Software/kernel/README.md @@ -0,0 +1,7 @@ +# Software/kernel/ + +Kernels that run on the core. Starts as a tiny custom kernel for learning +trap/scheduling/syscalls; later hosts the Linux device tree, OpenSBI, and +mainline Linux build artifacts. + +**Phases:** 11 (tiny kernel), 19 (Linux boot contract), 20 (Linux). diff --git a/Tutorial/phase-00-architecture-contract/phase-00-02-block-diagram.md b/Tutorial/phase-00-architecture-contract/phase-00-02-block-diagram.md index 82b6b11..3ae27ae 100644 --- a/Tutorial/phase-00-architecture-contract/phase-00-02-block-diagram.md +++ b/Tutorial/phase-00-architecture-contract/phase-00-02-block-diagram.md @@ -37,7 +37,7 @@ state stored, what changes each clock, what can wait, and what happens on an exc ## Tooling And Testing -- Keep the diagram in `docs/` and update it when interfaces change. +- 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.