Skip to content

CQUT-OpenProject/JSJZCYL_Quartus-CPU

Repository files navigation

Quartus-CPU

基于 FPGA 的单周期 CPU 设计与实现

项目简介

设计单周期 CPU,支持下图中的所有指令

指令格式表

文档

详细的项目需求和实现说明请参阅:

运行程序

应教师要求,CPU 运行的测试程序不能为“指令覆盖型”(说人话就是不能太简单..)。于是重写了一个程序,实现了4个元素的冒泡排序,并附带自校验。下面介绍程序的运行原理。

RAM 布局:

地址范围 变量名 说明
MEM[0x10] N 数组长度=4
MEM[0x11] checksum_before 排序前求和
MEM[0x12] checksum_after 排序后求和
MEM[0x13] i 外层循环计数
MEM[0x14] j 内层循环计数
MEM[0x15] limit 内层循环上界=3-i
MEM[0x20..0x23] A[0..3] 数组元素

寄存器布局:

寄存器 用途及说明
R0 基址
R1 数组指针 ptr(指向 0x20 起)
R2 通用:N / i / j / a / checksum / 常量
R3 通用:sum / b / 比较标志 / 临时混合值
  • 阶段 1:在 RAM 写入 N 与 4 个待排序数:[7, -3, 12, 0]
    • 写入 N=4
      • 向 R2 写入 4
      • 向 MEM[0x10](数组长度)写入 R2
    • 写入数组元素
      • 向 R3 写入 7
      • 向 MEM[0x20](数组元素 A[0])写入 R3
      • 向 R3 写入 -3
      • 向 MEM[0x21](数组元素 A[1])写入 R3
      • 向 R3 写入 12
      • 向 MEM[0x22](数组元素 A[2])写入 R3
      • 向 R3 写入 0
      • 向 MEM[0x23](数组元素 A[3])写入 R3
      • 【此时 A = [0x0007, 0xFFFD, 0x000C, 0x0000](即 [7, -3, 12, 0])】
  • 阶段 2:计算排序前的 checksum
    • sum 清零
      • 向 R3 写入 0
    • 遍历 4 次累加
      • 将 R1 置为 0x20(数组起始地址)
      • 读取 A[0] 到 R2
      • R3 加上 R2
      • R1 加 1(指向下一个元素)
      • 读取 A[1] 到 R2
      • R3 加上 R2
      • R1 加 1(指向下一个元素)
      • 读取 A[2] 到 R2
      • R3 加上 R2
      • R1 加 1(指向下一个元素)
      • 读取 A[3] 到 R2
      • R3 加上 R2
    • 保存 checksum_before
      • 将 R3(checksum)写入 MEM[0x11]
      • 【此时 checksum_before = 16】
  • 阶段 3:冒泡排序(按有符号升序排序)
    • 初始化 i=0
      • 向 R2 写入 0(i 初始化)
      • 向 MEM[0x13] 写入 i
    • 外层循环
      • 读取 i 到 R3
      • 向 R2 写入 3
      • 若 i==3 跳到 0x33(51)(排序完成)
      • 向 R2 写入 3
      • R2 减 i
      • 向 MEM[0x15] 写入 R2
      • 初始化 j=0
      • 向 R2 写入 0(j 初始化)
      • 向 MEM[0x14] 写入 j
      • 将 R1 置为 0x20(数组起始地址)
    • 内层循环
      • 读取 A[j] 到 R2
      • 读取 A[j+1] 到 R3
      • 若 A[j]>A[j+1] 跳到 0x27(39) 执行交换
      • 跳过交换:无条件跳到 0x29(41)
      • 交换 A[j] 与 A[j+1]
        • 向 MEM[ptr] 写入 R3
        • 向 MEM[ptr+1] 写入 R2
      • 指针与计数推进
        • R1 加 1(ptr++)
        • 读取 j,j 加 1 后写回 MEM[0x14]
        • 读取 limit,若 j != limit 跳回 0x23(35)
    • 外层循环推进
      • 读取 i,i 加 1 后写回 MEM[0x13]
      • 无条件跳回 0x1A(26)
    • 排序结果:A = [-3, 0, 7, 12]
  • 阶段 4:计算排序后的 checksum_after
    • 将 R1 置为 0x20(数组起始地址)
    • sum2 清零(R3=0)
    • 依次累加 A[0..3] 至 R3
    • 将 checksum_after 写入 MEM[0x12]
  • 阶段 5:校验 checksum 一致性
    • 读取 checksum_before 与 checksum_after
    • 若不相等跳转 FAIL
  • 阶段 6:校验数组有序性(相邻元素比较)
    • 依次读取 (A[0],A[1])、(A[1],A[2])、(A[2],A[3])
    • 使用 slt 判断 b < a,则跳转 FAIL
  • 阶段 7:混合指令覆盖(不影响结果,用于检测剩余指令是否能成功运作)
    • 以 sum2 为输入,执行 and/andi/or/sllv/srlv/srav/sub
  • 阶段 8:输出结果并停机
    • PASS:输出 0x0AAA 后 halt
    • FAIL:输出 0x0EEE 后 halt

许可

本项目使用开源许可证 - 详见 LICENSE

About

《计算机组成原理》课程设计

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors