Skip to content

P6

实验内容

实验一 :控制器设计实验

整体方案设计

  • 根据指令与控制信号的对应关系绘制电路图

电路图

  • 对opcode进行分类转化为一位标志
  • image-20231217224019792
  • ALUctr的设计
  • image-20231217224036583

  • image-20231217224219607

仿真测试

  • 部分解码示例
  • lui
  • image-20231217224420777

  • slli

  • image-20231217224453344

  • beq

  • image-20231217224719380

  • sw

  • image-20231217224742519

错误现象及分析

  • 在完成实验的过程中,没有遇到任何错误。

实验二 :单周期 CPU 设计实验

整体方案设计

  • 将控制器加入实验5的数据通路,代替手动输入控制信号

电路图

  • image-20231217225103412

仿真测试

  • 执行实验五的程序,并逐步比对探测量

  • 得到表格与实验5一致

  • 序号 汇编指令 PC BusW 立即数 寄存器堆 数据寄存器
    1 lui x5,-1 00000000 fffff000 fffff000 x5:fffff000
    2 addi x5,x5,100 00000004 fffff064 00000064 x5:fffff064
    3 sw x5,0(x0) 00000008 00000000 00000000 0:fffff064
    4 srai x6,x5,3 0000000c fffffe0c 00000403 X6:fffffe0c
    5 sw x6,4(x0) 00000010 00000004 000000004 1:fffffe0c
    6 lh x7,4(x0) 00000014 fffffe0c 00000004 X7:fffffe0c
    7 xori x8,x7,-1 00000018 000001f3 ffffffff X8:000001f3
    8 sw x8,8(x0) 0000001c 00000008 00000008 2:000001f3
    9 slt x9,x8,x7 00000020 00000000 00000007 X9:00000000
    10 sw x9,x12(x0) 00000024 00000000c 0000000c 3:00000000
    11 bne x9,x0,label2 00000028 00000000 ffffffd8
    12 jarl x10,x0,48 0000002c 00000030 00000030 X10:00000030
    13 sw x10,16(x0) 00000030 00000010 00000010 4:00000030
    14 auipc x11,100 00000034 00064034 00064000 X11:00064034

错误现象及分析

  • 在完成实验的过程中,没有遇到任何错误。

实验三 :用累加和程序验证 CPU 设计

实验过程

  • 将汇编程序制作为asm文件并导入到RARS
  • image-20231217165246027
  • 在RARS中模拟执行程序
  • image-20231217165413154

  • 将RARS编译得到的机器码导入到rom,并将参数64写入到ram,之后执行程序

  • image-20231217170244076
  • 程序执行结果,即00000013ba
  • image-20231217170229566

错误现象及分析

  • 在完成实验的过程中,没有遇到任何错误。

实验四:用冒泡排序程序进行 CPU 设计验证

实验过程

  • 同样使用RARS得到冒泡排序汇编程序对应的机器码,输入到ROM及RAM中,并进行计算

  • image-20231217180922823

  • RAM中的排序结果

  • image-20231217180907888

错误现象及分析

  • 出现排序不会终止的问题,经过单步调试发现bgeu执行异常,进一步发现CF标志位错误
  • 检查电路发现直接将CF连接到了COUT,修改为COUT和CIN的异或,解决问题,完成实验
  • image-20231217230217482

实验五 :C 程序汇编测试

实验过程

  • 将数据导入指令寄存器以及ram,然后开始运行程序
  • 检查排序的反汇编代码
  • image-20231219084350796
  • 可以发现全局变量a的存储地址为00000134,并且这段反汇编中以字节编址,而电路中4个字节编址,因此将地址除以4得到004d

  • 完成运行之后,在寄存器检查结果

  • image-20231219084621654
  • image-20231219084729555
  • image-20231219085226347
  • 得到结果:21, 33, 39, 76, 87, 170, 190, 200, 400, 800, 910, 913, 1212, 2455, 3114, 5215, 7711, 8716, 18000, 30000

错误现象及分析

  • 在完成实验的过程中,没有遇到任何错误。

思考题

在累加和计算程序中,添加溢出判读语句,并把最大的不溢出累计和以及累加序数保存到数据存储器中输出。

  • ```asm main: lw a0, 0(x0) # 从数据存储器地址 0x0000 单元中读取参数 n 到寄存器 a0 addi a2, x0, 1 # 循环变量 i,存放在 a2,初值为 1 add a3, x0, x0 # 累计和存放在 a3,初值为 0 add a4, x0, x0 # 用于存放最后一个不溢出的累计和 add a5, x0, x0 # 用于存放最后一个不溢出的序数

loop: add a4, a3, x0 # 保存当前的累加和 add a5, a2, x0 # 保存当前的序数 add a3, a3, a2 # 将 a3=a3+i blt a3, a4, finish # 如果 a3 < a4,则发生了溢出,跳转到 finish beq a2, a0, finish # 若 i=n,则跳出循环 addi a2, a2, 1 # i++ jal x0, loop # 无条件跳转到 loop 执行

finish: sw a4, 4(x0) # 将最后一个不溢出的累加和保存 sw a5, 8(x0) # 将最后一个不溢出的序数保存

end: jal x0, end # 无条件跳转到 end ```

  • a4 寄存器用于存储最后一个不溢出的累加和。

  • a5 寄存器用于存储最后一个不溢出的序数

如果分支跳转指令不在 ALU 内部使用减法运算来实现,而是在 ALU 外使用独立比较器来实现,说说单周期 CPU 的电路原理图中需要做哪些修改?

  • 增加独立的比较器:需要在CPU的电路中添加一个比较器组件,它专门用于比较两个寄存器的值。
  • 控制逻辑修改:原先通过调整ALUCtr控制加法器的操作模式,现在应该改为控制是否使用比较器,以及比较的模式,因此还需要对控制单元需要进行修改,以便在遇到分支指令时,不再通过ALU进行比较,而是通过这个独立比较器。
  • 数据路径调整:原来ALU的输入现在需要连接到新的比较器,数据除了需要连接到原先的ALU,还需要额外连接到新添加的比较器。
  • 比较结果的使用:比较器的输出将直接用于决定是否进行分支。还需要通过比较器的结果生成NxAScr以及NxtBScr控制信号,还必须有0扩展器以便将比较之后的结果写入回到寄存器。

实现单周期 CPU 后,如何实现键盘输入、TTY 输出部件等输入输出设备的数据访问,构建完整的计算机系统。

  • 设计或集成I/O接口
  • 为每个设备定义接口,并将其集成到计算机系统中。这些接口允许CPU与外部设备通信。
  • 接口又缓冲区以及控制寄存器组成
  • 当CPU读取一个映射到I/O设备的内存地址时,实际上是从设备的缓冲区或状态寄存器读取数据。
  • 当CPU写入一个映射到I/O设备的内存地址时,实际上是向设备发送数据或控制信号。
  • 实现内存映射I/O
  • 特定的内存地址被映射到I/O设备的控制寄存器或数据缓冲区。
  • CPU可以通过读写这些特定的内存地址来与I/O设备交互。
  • 实现中断处理
  • 中断:I/O设备可以通过中断来通知CPU有新的数据可用或设备已准备好接收数据。
  • 轮询:CPU定期检查I/O设备的状态,了解是否有新数据或设备是否准备好。
  • 驱动程序:
  • 驱动程序是运行在CPU上的软件,负责管理与特定I/O设备的交互。
  • 驱动程序控制如何操作设备的硬件接口,包括如何发送命令和解释状态。

如果需要实现 5 级流水线 RV32I CPU,则如何在单周期 CPU 基础上进行修改?

  • 对CPU阶段进行划分:
  • 取指:从程序存储器中获取指令。
  • 译码:分析指令并准备必要的操作数。
  • 执行:执行算术或逻辑运算,或计算地址。
  • 存储器访问:进行数据的加载或存储。
  • 写回:将结果写回寄存器。
  • 引入流水线寄存器:
  • 在每个阶段之间插入流水线寄存器来存储每个阶段的中间结果。
  • 修改控制逻辑:需要实现更多的控制信号
  • 实现冲突检测和处理:
  • 数据冲突:这可以通过数据前递、暂停来解决。
  • 控制冲突:引入分支预测、在确定分支目标前暂停流水线。
  • 还需要设计一个危险检测单元来识别并处理冲突,确保正确的执行顺序。
  • 调整时序和同步
  • 由于引入了流水线,整个CPU的时序需要重新设计,以确保所有阶段都能在各自的时钟周期内正确同步。