单周期 CPU 的设计思路

熟悉了我们需要实现的 8 条指令之后,我们就需要设计 CPU 的数据通路。

基本的数据通路图

我在最终设计的数据通路图中,主要的硬件元件包括:

  • 指令存储器:Instruction Memory
  • 数据存储器:Data Memory
  • 寄存器堆:Register File
  • 程序计数器:Program Counter
  • 专用于处理跳转指令的 NPC:Next Program Counter
  • 控制单元:Control Unit
  • 算术逻辑单元:ALU
  • 符号扩展、移位二合一模块:Extend Module
  • 多处多路选择器:Multiplexer

值得注意的是:单周期 CPU 在实际实现的过程中并不需要指令寄存器(IR)。

具体数据通路图大致如下:

其中,主要的逻辑控制信号 Control Signals(蓝色)有:

信号 功能
RegWrite 写寄存器使能信号
MemWrite 读数据存储器使能信号
ALUOp ALU 控制信号(区分算术指令,比如 ADDSUB 等)
RegSrc 选择将 ALU 计算结果、数据存储器输出或 Extend 模块输出写入寄存器
RegDst 写入寄存器 rt 、rd 二选一
ALUSrc 选择 ALU 源操作数来自寄存器或符号扩展的立即数(区分算术指令结果与 LWSW 指令结果)
NPCOp 决定下一指令地址 NPC,或为 PC + 4,或为 BEQ 目标指令或 J 目标指令
ExtOp Extend 模块控制信号源(LUI 移位 16 位、有无符号扩展)

由于需要:

  • 实现 BEQJ,立即数的位数不一样,因此 15 - 0 位的 imm16 代表 BEQ 指令的偏移量,25 - 0 位的 imm26 代表 J 指令的偏移量
  • 实现 BEQ,需要将 rs、rt 寄存器的值相减得到并判断是否为 0,因此引入 Zero 控制信号,用来判断是否跳转

对于 Extend 模块,由于我们需要实现:

  • LUI:将 rt 高 16 位填入 imm16,低 16 位置零。需要左移 16 位操作
  • ADDIU:需要对 rs 有符号扩展为 32 位
  • LWSW:需要对 imm16 进行无符号扩展为 32 位

因此将这三个功能统一放置在 Extend 模块进行处理,并利用控制信号 ExtOp 进行控制。

主要控制逻辑的真值表

其中,对于 ALU 算术指令,我们只需要实现加法和减法,ALUOp 功能表如下(为了方便后续扩展,我设计的 ALUOp 有三位):

ALUOp[2:0] 功能 描述
000 Default 缺省值
001 Y=A+B
010 Y=A-B

对于 Extend 模块(用于统一进行符号扩展或移位操作),ExtOp 功能表如下:

ExtOp[1:0] 功能 指令
00 Default 缺省值
01 将 16 位立即数 imm 向左移位 16 位 LUI
10 立即数 imm 有符号扩展至 32 位 ADDIU
11 立即数 offset 无符号扩展至 32 位 LW、SW

对于 RegSrc 信号,我们需要选择写入寄存器的源:

RegSrc[1:0] 功能 指令
00 Default 缺省值
01 来自 ALU ADDIU、ADD、SUB
10 来自 Data Memory LW
11 来自 Extend 模块输出 LUI

对于 NPC 模块,NPCOp 信号需要决定我们执行正常下一条取值(PC + 4)、BEQ 跳转或 J 跳转:

NPCOp[2:0] 功能 指令
000 Default 缺省值
001 普通跳转 正常指令
010 J 型直接跳转 J
011 BEQ 型跳转 BEQ
Last Updated: 9/7/2019, 3:52:23 PM