Skip to content

Repository files navigation

FPGA_8bit_CPU

一个基于 FPGA 实现的简易 8 位多周期 CPU 项目。

这个 CPU 采用 Verilog 编写,包含 4 个 8 位通用寄存器、8 位程序计数器(PC)、16 位指令寄存器(IR)、256×16 指令 ROM、256×8 数据 RAM、ALU、标志寄存器(Z/C)以及多周期控制器。项目还接入了开发板上的 数码管和 LED,可以直接在硬件上观察 CPU 的执行过程和内部状态。

从工程文件可以看出,本项目已经配置好了完整的 FPGA 工程,顶层模块为 cpu_top,并包含对应的约束文件和示例程序。


1. 项目功能

实现了一个小型教学型 CPU,具备以下特点:

  • 8 位数据通路
  • 16 位定长指令
  • 4 个 8 位通用寄存器 R0 ~ R3
  • 8 位地址空间
    • 指令 ROM:256 × 16 bit
    • 数据 RAM:256 × 8 bit
  • 支持算术、逻辑、移位、数据搬运、访存、跳转和停机指令
  • 采用 多周期控制器(FSM) 执行指令
  • 支持 连续运行 / 单步执行 两种调试模式
  • 可通过数码管和 LED 观察寄存器、PC、ALU、RAM 等内部状态

2. 系统结构

顶层模块为 cpu_top.v 控制器采用多周期有限状态机,主要状态包括:

  • FETCH:取指,同时 PC <- PC + 1
  • DECODE:译码
  • EXEC:执行 ALU 运算或跳转判断
  • MEM:进行存储器访问
  • WRITEBACK:将结果写回寄存器,并在需要时更新标志位
  • HALT:停机

3. 指令系统

所有指令均为 16 位,格式如下:

[15:12] opcode
[11:10] rd
[ 9: 8] rs
[ 7: 0] imm8 / addr

其中:

  • opcode:操作码
  • rd:目标寄存器编号
  • rs:源寄存器编号
  • imm8/addr:8 位立即数或地址

寄存器编号约定:

  • 00 -> R0
  • 01 -> R1
  • 10 -> R2
  • 11 -> R3
Opcode 指令 语义 说明
0x0 LDI rd, imm8 R[rd] <- imm 将 8 位立即数写入寄存器
0x1 MOV rd, rs R[rd] <- R[rs] 寄存器间数据传送
0x2 LOAD rd, [addr] R[rd] <- MEM[addr] 从 RAM 读取数据到寄存器
0x3 STORE rs, [addr] MEM[addr] <- R[rs] 将寄存器数据写入 RAM
0x4 ADD rd, rs R[rd] <- R[rd] + R[rs] 加法,结果写回 rd
0x5 SUB rd, rs R[rd] <- R[rd] - R[rs] 减法,结果写回 rd
0x6 AND rd, rs R[rd] <- R[rd] & R[rs] 按位与
0x7 OR rd, rs R[rd] <- R[rd] | R[rs] 按位或
0x8 XOR rd, rs R[rd] <- R[rd] ^ R[rs] 按位异或
0x9 NOT rd R[rd] <- ~R[rd] 按位取反
0xA SHL rd R[rd] <- R[rd] << 1 左移 1 位
0xB SHR rd R[rd] <- R[rd] >> 1 右移 1 位
0xC JMP addr PC <- addr 无条件跳转
0xD JZ addr Z==1,则 PC <- addr Z=1 时跳转
0xE JC addr C==1,则 PC <- addr C=1 时跳转
0xF HLT 停机 停机

详细请见指令集


4. 主要模块说明

cpu_top.v

顶层模块,负责:

  • 复位与时钟分频
  • 单步按键消抖
  • 连接 PC、ROM、IR、寄存器堆、ALU、RAM 和控制器
  • 选择数码管显示内容
  • 输出 LED 调试状态

control_unit.v

多周期控制器,内部使用有限状态机,根据当前状态和 opcode 产生:

  • ir_load
  • pc_load
  • pc_src
  • reg_we
  • mem_we
  • flags_we
  • alu_op
  • wb_sel
  • halt

pc.v

程序计数器模块,支持复位和条件装载。

ir.v

指令寄存器,在取指阶段锁存 ROM 输出。

register_file.v

4×8 bit 寄存器堆,支持双读单写。

alu.v

实现如下 ALU 操作:

  • ADD
  • SUB
  • AND
  • OR
  • XOR
  • NOT
  • SHL
  • SHR
  • PASS

instr_rom.v

指令 ROM,容量 256×16,通过:

$readmemh("prog.mem", rom);

从外部文件加载程序。

data_ram.v

数据 RAM,容量 256×8,采用同步写、组合读方式。

digital_show.v

数码管扫描显示模块,用于显示 CPU 调试信息。


5. 开发板交互方式

按键 / 开关定义

根据顶层模块定义:

  • key[0]:复位键,低电平有效
  • key[1]:单步执行按键(已做同步和消抖)
  • SW[3]:运行模式选择
    • 0:连续慢速运行(约 100Hz)
    • 1:单步执行
  • SW[2:0]:数码管显示内容选择

数码管显示内容(SW[2:0]

SW[2:0] 显示内容
000 4 个寄存器的值 {R3,R2,R1,R0}
001 当前指令字段拆分:PC / opcode / rd / rs / imm8
010 R0 的值(适合十进制观察)
011 寄存器堆两个读口数据 rdata1 / rdata2
100 Z/C 标志位 + ALU 输出
101 当前 imm8 地址及 RAM 读出数据
110 next_pc
111 当前写回数据 rf_wdata

LED 显示说明

led_data[3:0] 的功能与运行模式有关:

  • SW[3] = 0(连续运行)时:
    • LED 显示 R0 的低 4 位
  • SW[3] = 1(单步调试)时:
    • LED 显示 {halt, mem_we, reg_we, pc_load}
    • 便于观察控制器状态

6. 工程文件结构

根据当前仓库内容,工程主要文件如下:

FPGA_8bit_CPU/
├─ cpu_top.v          # 顶层模块
├─ control_unit.v     # 多周期控制器
├─ pc.v               # 程序计数器
├─ ir.v               # 指令寄存器
├─ register_file.v    # 寄存器堆
├─ alu.v              # 算术逻辑单元
├─ instr_rom.v        # 指令 ROM
├─ data_ram.v         # 数据 RAM
└─ digital_show.v     # 数码管显示模块

7. 如何运行项目

  1. 使用工程文件 sm_scan.al 打开项目
  2. 检查源文件和约束文件是否完整导入
  3. 确保 prog.mem 与工程位于正确路径下,能够被 instr_rom.v 成功加载
  4. 进行综合、布局布线并生成比特流
  5. 下载到开发板运行

如果你想测试自己的程序,只需要修改 prog.mem 中的 16 位机器码内容,然后重新综合下载即可。


8. 示例程序

显示斐波那契数列:

0400
0801
0001
1200
1D00
4E00
E000
1600
1B00
C003
地址 汇编指令 机器码
00 LDI R1, 0x00 0400
01 LDI R2, 0x01 0801
02 LDI R0, 0x01 0001
03 MOV R0, R2 1200
04 MOV R3, R1 1D00
05 ADD R3, R2 4E00
06 JC 0x00 E000
07 MOV R1, R2 1600
08 MOV R2, R3 1B00
09 JMP 0x03 C003
; R1 = a
; R2 = b
; R0 = 显示值
; R3 = 临时寄存器

START:
    LDI  R1, 0x00      ; a = 0
    LDI  R2, 0x01      ; b = 1
    LDI  R0, 0x01      ; 先显示第一个 1

LOOP:
    MOV  R0, R2        ; 显示当前项 b
    MOV  R3, R1        ; R3 = a
    ADD  R3, R2        ; R3 = a + b
    JC   START         ; 若溢出,则重新开始

    MOV  R1, R2        ; a = b
    MOV  R2, R3        ; b = a + b
    JMP  LOOP


About

Complete 8-bit microprocessor implementation in Verilog

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages