本项目为 “一生一芯” (ysyx) 计划的主工作区 (Workspace)。“一生一芯”旨在让学生通过动手实践,从零开始设计一个功能完整的真实 RISC-V 处理器芯片,并能在其上运行操作系统与复杂的应用程序(例如 RT-Thread、红白机模拟器 FCEUX 等),最终完成流片验证。
本项目涵盖了计算机系统底层构建的各个环节,包括:指令集模拟器 (NEMU)、裸机运行时系统 (Abstract Machine)、RTL 硬件设计 (NPC),以及最终的系统集成 (ysyxSoC) 与 FPGA 仿真/上板 (nvboard)。
整个系统由多个紧密协作的子项目构成:
ysyx-workbench
├── abstract-machine # 抽象计算机 (Abstract-Machine),为不同架构提供统一的裸机运行时环境 (HAL)
│ ├── am # 硬件抽象层代码 (TRM, IOE, CTE, VME 等)
│ ├── klib # 极简版的 C 基础运行库 (如 string.h, stdio.h 实现)
│ └── scripts # 各架构的编译、打包与链接脚本 (linker scripts)
├── am-kernels # 基于 AM 开发的各类应用程序和测试集
│ ├── benchmarks # 性能基准测试集 (如 microbench, coremark 等)
│ └── tests # 验证测试用例 (主要运行针对硬件设计的 cpu-tests)
├── fceux-am # 移植到 AM 上的红白机 (NES) 模拟器,用来作为处理器的高负载测试
├── nemu # Nju EMUlator,一款简单指令集模拟器(使用 C/C++ 开发)
│ ├── src # NEMU 核心源码
│ │ ├── cpu # 模拟器的解码、执行引擎核心
│ │ ├── device # 模拟串口、定时器、VGA 等虚拟外设
│ │ ├── isa # 架构相关的指令集定义 (如 riscv32、riscv64)
│ │ └── monitor # 简易调试器 (sdb) 及表达式求值、监视点等基础设施
│ └── ... # 在本项目中作为处理器设计的"黄金参考模型" (Golden Model),用于 DiffTest
├── npc # New Processor Core,自己使用 RTL 设计的 RISC-V 处理器核
│ ├── csrc # C/C++ 仿真代码:包含 Verilator 仿真的 main 函数、DiffTest 接入、内存读写等测试脚手架
│ ├── vsrc # RTL 源码 (Verilog):包含处理器各级流水线、寄存器堆、总线接口等硬件设计的源码
│ └── Makefile # NPC 的主控编译仿真脚本
├── nvboard # 虚拟 FPGA 开发板环境 (基于 C++ 与 SDL)
│ ├── board # 虚拟板布局及引脚配置
│ ├── example # 点灯、数码管、拨码开关等小实验参考代码
│ └── src # 在 PC 上实现 VGA 屏幕、七段数码管、键盘等外设交互的仿真模拟底层
├── rt-thread-am # 移植到 AM 上的 RT-Thread 实时操作系统源码
├── ysyxSoC # 基于一生一芯框架构建的完整 SoC (System on Chip)
│ ├── perip # 存放各类外设 IP 的硬件源码(如 spi、uart、sdram、flash 控制器等)
│ ├── src # SoC 顶层连线与系统互联逻辑实现 (通常为 Chisel 或 Verilog 生成代码)
│ └── rocket-chip # 框架依赖的基础设施和系统总线生成器组件
├── .github # CI/CD 自动化测试脚本
├── init.sh # 子项目初始化与更新脚本
├── Makefile # 顶层构建脚本,负责统筹配置
└── run_cpu_tests.sh # 自动化批量运行 CPU 测试集的脚本
处理器微架构核心逻辑 (npc/vsrc) 完全采用 Verilog 语言构建。基于目前源码,设计已通过模块化划分为经典的系统流水线与状态转移架构。以下为主要 .v 文件的职责说明:
IFU.v(取指单元): 负责程序计数器 (PC) 的更新与指令的获取。内部维护了 AXI4 总线读通道的主机状态机,支持通过 AXI4 协议读取指令并缓冲。包含对无跳跃、无条件/条件分支等各种 PC 跳变的决策逻辑。IDU.v(译码单元): 解析IFU取入的32位 RISC-V 指令。利用丰富的硬连线解码组合逻辑甄别 I/R/S/B/U/J 等指令集类型,并提取相应的立即数 (imm)、寄存器索引 (rs1/rs2/rd)、ALU运算码 (alu_op) 以及内存读写信号 (mem_op)。EXU.v(执行单元): 作为运算和系统管理的枢纽,调用底层的ALU进行真正的算术或逻辑操作,并整理出分支比较验证结果 (compare_result) 以及访存的基地址数据。MEMU.v(访存单元): 负责 Load/Store 指令与外部存储或外设的交互。该模块实现了完整的 AXI4 主设备 (Master) 读写状态机控制接口,依据译码传来的mem_op,精准处理 1/2/4 字节数据的存取、不同位宽掩码偏移、以及符号填充 (signed/unsigned load) 逻辑。WBU.v(写回单元): 归口整理EXU发送过来的运算结果或MEMU读取回来的数据,将其路由并发回给通用寄存器堆从而完成指令效果的最终可见性提交。
alu.v(算术逻辑单元): 纯粹的数据处理工厂。包含了 64位有符号/无符号乘法、除法求余指令支持,同时处理所有的移位、位掩码求值与条件对比 (beq/bge等) 计算判定。regfile.v(通用寄存器堆): 维护着 RISC-Vx0-x31共 32 个通用寄存器。内部通过 DPI-C 向仿真测试平台透出了 C 语言探针接口 (set_gpr_ptr()),为 DiffTest 提供了黄金比对数据源。csr.v(控制状态寄存器): 构建了与特权级异常处理强相关的mstatus(处理器状态)、mepc(异常/中断返回PC)、mcause(陷阱诱因)、mtvec(陷阱入口表) 等状态寄存器存储,支持软件中断或系统调用 (ecall/ebreak)。
xbar.sv(AXI4 总线交叉开关/互联矩阵): 这是实现片上通信仲裁的最核心总线集线器 (Crossbar)。它仲裁IFU与MEMU两大主机设备的访存诉求,通过地址空间匹配 (如判定区间是否为CLINT/UART/SDRAM等) 将控制流动态倒换路由给相应的外设 Slave 从机,并处理读写优先级。clint_axi_lite_slave.v(核心本地中断器/系统计时器): 一个标准的 AXI4 从设备,内部维护了 64 位的系统运行嘀嗒计数器mtime。硬件依靠这个基础核心每周期定基准自增节拍,以支持如rt-thread此类依赖操作系统的时钟管理任务。
- RTL 仿真与测试 (Simulation & Testing):
- 使用 Verilator 或 Icarus Verilog 对
npc进行 C++ 级别的周期精确仿真。 abstract-machine会将被测 C 程序交叉编译成 RISC-V 机器码 (通常是.bin镜像),并将镜像加载到仿真器的内存 (Memory) 中执行。
- 使用 Verilator 或 Icarus Verilog 对
- 差分测试 (Differential Testing - DiffTest):
- 每当
npc(RTL 处理器) 执行完一条指令后,其寄存器状态会被提交给nemu(C 语言模拟器)。 nemu同样执行该条指令,并比对双方的寄存器和内存状态。若出现不一致(如实现错误的指令行为),系统立刻报错中断,极大地提升了硬件 Debug 效率。
- 每当
- 系统集成 (SoC Integration):
- CPU (npc) 将其访存接口封装为 AXI4 或 APB 标准总线协议。
- 通过
ysyxSoC将 CPU 同内存 (SDRAM / SRAM) 以及外设 (UART, SPI Flash, PS2键盘, VGA 显示器) 通过总线连接。
以下是从底层硬件设计到上层软件集成的工作区状态总结
- NEMU 模拟器开发:
- 完成了 RISC-V 32/64 基础指令集的支持。
- 完成了简易调试器 (sdb) 的开发(单步调试、断点、表达式求值求值、监视点等)。
- 完善了异常处理与外设访问 (串口、定时器) 支持。
- Abstract Machine (AM) 支持:
- 完成了基础的 C 运行库 (klib)。
- 支持了 CTE (上下文管理) 与陷入中断机制,成功运行了
yield-os等调度测试。
- NPC (RISC-V 硬件核) 设计:
- RTL 完成指令集覆盖,并通过了基础测试用例 (
cpu-tests)。 - 完成了单周期/多周期基本架构,支持各种边界处理(如
sp-alignment对齐异常和非对齐访问处理等)。 - DiffTest 框架已成功接入并协助定位硬件 Bug。
- RTL 完成指令集覆盖,并通过了基础测试用例 (
- 测试分析平台:
- 引入了 ABI 兼容性静态分析与测试二进制打包流程,可通过自动化脚本批量验证正确性。
- ysyxSoC 集成与外设联调
[🔥 当前高优先级进行中]:- SDRAM 控制器: 正在开发和调试通过 AXI4 协议接入 SDRAM 的时序逻辑(见
sdram_axi_core.v,sdram.v)。 - 内存映射 (Memory Map): 正在持续调整链接脚本 (
linker-ysyxsoc.ld) 以及最底层的硬件测试桩程序 (char-test.c) 进行外设的读写打通。
- SDRAM 控制器: 正在开发和调试通过 AXI4 协议接入 SDRAM 的时序逻辑(见
- 完成 SDRAM AXI 接口调试: 确保 CPU 通过 AXI 总线能正确无误地向 SDRAM 发起单次读写与 Burst 突发传输。修复并验证
char-test.c的读写结果。 - Flash / SPI 控制器对接: 实现 XIP (Execute In Place) 执行模型,使得 CPU 可直接从 SPI Flash 中取指运行固件。
- 统一外部中断 (PLIC / CLINT): 处理外部设备 (如串口接收、定时器) 到 CPU 的中断路由机制。
- 实现高速缓存 (Cache): 设计并接入 I-Cache 和 D-Cache,减小总线竞争并优化 CPI (Cycles Per Instruction)。
- 运行 RT-Thread 操作系统: 在真实的 RTL 仿真环境下,成功引导启动 RT-Thread 并进行多线程调度切换。
- 运行大型游戏 (FCEUX / 仙剑奇侠传): 打通 VGA 和 PS/2 外设的数据通路,确保渲染帧率与操作响应符合预期。
- ** nvboard 仿真应用**: 将开发板引脚、按键开关等映射至虚拟板进行物理交互体验。
- 后端逻辑综合验证 (Synthesis): 使用 Yosys 等工具评估逻辑门电路资源与关键路径,保证时钟频率满足流片 / FPGA 要求。
- FPGA 实机上板: 生成 Bitstream 并烧写至物理 FPGA 开发板,运行完整系统验证。
如果刚克隆本项目,需要初始化并拉取相应的子模块内容(例如 nemu、npc 等):
bash init.sh subproject-name进入 nemu 目录并首次配置编译:
cd nemu
make menuconfig # 选择系统架构 (RISCV64 / RISCV32)
make # 编译生成可执行文件编写的 RTL 设计被实例化在 npc 下。在根目录下或 npc 目录下,可以通过 AM 使得代码在仿真器或 NEMU 上运行:
# 进入 cpu-tests 的其中一个测试目录,比如 dummy
cd am-kernels/tests/cpu-tests
# 使用预编译好的环境变量运行到 npc 或 nemu 模型上
make ARCH=riscv64-npc run
# 批量执行系统内置自动化脚本
./run_cpu_tests.sh