基于FPGA从零手写CPU(1)
本人工科研二,做一些项目时,只知道调用库函数或者直接用AI生成代码,却完全摸不透 CPU 到底是怎么跑起来的,思来想去,决定逼自己一把 ——从 0 开始,基于 FPGA 手写一个简单的 CPU,目标先实现最基础的 RV32I 架构。它是整个 RISCV 体系的根,所有扩展指令(M/A/F/D/C 等)都基于它扩展。后续会每周更新,记录每一步的代码、踩坑、调试过程,新手友好,无废话纯实操。分支指令:
基于FPGA从零手写CPU(1)
本人工科研二,做一些项目时,只知道调用库函数或者直接用AI生成代码,却完全摸不透 CPU 到底是怎么跑起来的,思来想去,决定逼自己一把 ——从 0 开始,基于 FPGA 手写一个简单的 CPU,目标先实现最基础的 RV32I 架构。想从0开始基于FPGA手写一个简单的CPU,目前想实现RV32I架构,
我没学过 FPGA 语法,也没系统学过 CPU 设计,所有内容都是靠 AI 辅助 + 查资料一点点梳理的。开这个系列,一是记录自己的学习过程,二是希望能帮到和我一样想搞懂 CPU 底层的新手。
一、RV32I 是什么?
RV32I 是 RISC-V 指令集架构中最基础、最精简、最稳定的整数指令子集,也是整个 RISC-V 体系的 “根”(所有扩展指令如 M/A/F/D/C 都基于它):
- RV:RISCV 架构
- 32:32 位架构
- I:Integer(基础整数指令集)
它是整个 RISCV 体系的根,所有扩展指令(M/A/F/D/C 等)都基于它扩展。
二、RV32I 的核心特点
- 32 位架构地址、寄存器、数据通路全部 32 位,逻辑规整,FPGA 实现简单。
- 只有整数运算不包含乘法、除法、浮点,只做加减、逻辑、移位、跳转、加载存储。模块少、复杂度低,非常适合手写。
- 指令数量极少RV32I 只有 40 条左右基础指令,远少于 ARM、x86。
- 指令格式高度统一只有 6 种固定格式,译码器非常好写,这是最适合 FPGA 实现的原因之一。
- 开源免费无专利、无授权费用,个人、小团队都能自由实现。
三、RV32I 寄存器组织(和 ARM 差别太大了!)
RV32I 包含 32 个 32 位通用寄存器 + 1 个独立 PC 寄存器,和 ARM 架构的核心差异我整理成了新手能懂的版本:
1. 核心寄存器功能(附通俗例子)
|
寄存器 |
别名 |
核心功能 |
新手易懂例子 |
|
x0 |
zero |
恒定为 0,写入无效 |
addi x5, x0, 100 → 直接给 x5 赋值 100 |
|
x1 |
ra |
存储函数返回地址 |
调用函数时自动存返回地址,函数结束跳回 |
|
x2 |
sp |
栈指针(栈向下增长) |
addi sp, sp, -16 → 申请 16 字节栈空间 |
|
x3/x4 |
gp/tp |
全局 / 线程指针 |
gp 优化全局变量访问,tp 管理线程信息 |
|
x10-x17 |
a0-a7 |
函数参数 / 返回值 |
C 代码 sum (5,10) → 5 存 a0、10 存 a1,结果回写 a0 |
|
x5-x7/x28-x31 |
t0-t6 |
临时寄存器 |
子函数可随意修改,调用前需自己备份 |
|
x8/x9/x18-x27 |
s0-s11 |
保存寄存器 |
子函数使用前必须备份,退出前恢复(保证原值) |
2.RV32I vs ARM 核心差异
|
对比维度 |
RV32I(RISC-V) |
ARM(Cortex-M/A32) |
|
通用寄存器数量 |
32 个(x0~x31) |
16 个(R0~R15) |
|
0 号寄存器 |
x0 硬连线为 0 |
R0 是普通寄存器 |
|
PC 寄存器 |
独立(不占通用寄存器) |
R15 就是 PC |
|
链接寄存器 |
x1(软件约定) |
R14(硬件强绑定) |
|
栈指针 |
x2(软件管理) |
R13(硬件自动处理) |
|
状态标志 |
无 |
CPSR/APSR(NZCV 标志) |
四、RV32I 8 大类指令
- 运算指令:add、sub、and、or、xor、sll、srl、sra;
- 立即数运算指令:addi、andi、ori、xori;
- 加载指令:lb、lh、lw、lbu、lhu;
- 存储指令:sb、sh、sw;
- 分支指令:beq、bne、blt、bge、bltu、bgeu;
- 跳转指令:jal、jalr;
- 高位立即数:lui、auipc;
- 系统指令:ecall、ebreak。
- RV32I CPU 五级流水线执行流程
所有 CPU 的核心运行逻辑都绕不开五级流水线,RV32I 完美适配这套流程,新手也能看懂:
1. 五级流水线结构图

2. 逐阶段通俗解释
- 取指 IF:PC 给出地址,从指令内存取 32 位指令码(把 “命令” 拿过来);
- 译码 ID:拆分指令(操作码 / 寄存器号 / 立即数),读寄存器数据(翻译 “命令”);
- 执行 EX:ALU 完成运算(真正 “干活” 的环节);
- 访存 MEM:仅加载 / 存储指令访问数据内存(和内存打交道);
- 写回 WB:把结果写回寄存器堆(存好结果,指令完成)。
一句话总结 CPU 执行逻辑:C 语言编译后的二进制文件就是指令集合,CPU 本质是:PC 读取指令 → 译码 → 执行 → 访存 → 写回,循环往复。
六、我的手写 CPU 计划(从 0 到 1)
- 吃透 RV32I 指令集细节;
- 设计并实现寄存器堆;
- 手写 ALU 运算单元;
- 搭建五级流水线架构;
- 最终在 FPGA 开发板上跑起来。
后续会每周更新,记录每一步的代码、踩坑、调试过程,新手友好,无废话纯实操。
更多推荐

所有评论(0)