P3单周期CPU设计文档

设计整体概述

  1. 预计实现指令集:add、sub、ori、Lui、lw、sw、beq、nop
  • R型指令:add、sub、ori
opcode rs rt rd shamt funct
6 5 5 5 5 6
  • I型指令:lui、lw、sw、beq
opcode rs rt offset
6 5 5 16
  • J型指令:暂无
opcode instr_inde
6 26

其中,nop指令为空指令,不执行任何操作,add、sub不考虑溢出,故实际执行addu和subu

  1. 实现功能:实现单周期CPU,能够执行上述指令集,采用模块化设计,顶层模块包含控制器CU和数据通路模块ALUIFUNPCGRFDMExt共七个子模块,预留了J型指令的NPC接口
  2. 顶层设计图

数据通路模块设计

IFU 指令单元

  1. 定义:模块内部包含PC程序计数器、IM指令存储器子模块,负责根据PC的值从指令存储器中读取指令,输出到数据总线。
  2. 端口定义
信号名 方向 位宽 说明
Next_PC I 32 NPC模块输出的下一条指令地址
clk I 1 时钟信号
reset I 1 复位信号
stop I 1 停机信号
RD O 32 IM取得的指令
PC O 32 PC模块输出地址,传入NPC模块用于得到下一条指令地址

  1. 实现功能
序号 功能 描述
1 复位 当reset信号为1时,PC置0x00003000
2 停机 当stop信号为1时,PC保持不变
3 取指 当stop信号为0时,根据PC在clk上升沿得到的下一条指令地址,从IM读取指令

PC通过寄存器实现,初始化为0x00003000
IM`通过ROM实现,取PC[13:2]作为地址,减去0x00003000后读取指令

NPC 指令地址生成单元

  1. 定义:根据当前PC地址和控制信号,生成下一条指令地址。
  2. 端口定义
信号名 方向 位宽 说明
PC I 32 当前指令地址
instr_index I 32 J型指令的立即数
offset I 16 I型指令的立即数
rs I 32 jr指令的寄存器
branch I 1 是否执行I型指令跳转
jump I 1 是否执行J型指令跳转
jr I 1 是否执行jr指令跳转
Next_PC O 32 下一条指令地址
PC+4 O 32 当前指令地址+4,可用于拓展Jal指令

  1. 实现功能
序号 功能 描述
1 PC+4 当branch、jump、jr组成的control信号为3’b000时,Next_PC输出PC+4
2 I型跳转 当branch、jump、jr组成的control信号为3’b100时,Next_PC输出PC_jump

GRF 寄存器堆

  1. 定义:根据读写信号,对寄存器堆进行读写操作。
  2. 端口定义
信号名 方向 位宽 说明
clk I 1 时钟信号
reset I 1 复位信号
WE I 1 写使能信号
A1 I 5 读寄存器1地址
A2 I 5 读寄存器2地址
A3 I 5 写寄存器地址
WD I 32 写数据
RD1 O 32 读寄存器1数据
RD2 O 32 读寄存器2数据

  1. 实现功能
序号 功能 描述
1 复位 当reset为1时,将所有寄存器置为0
2 当WE为0时,将A1、A2对应的寄存器数据输出到RD1、RD2
3 当WE为1时,在时钟上升沿将A3对应的寄存器写入WD

A1、A2分别读取Rs、Rt寄存器,A3写入RegAddress(根据RegDst选择Rt或Rd),WD写入RegData(根据MemRead选择ALU的运算结果或I型指令的立即数)

ALU 算术逻辑单元

  1. 定义:根据控制信号,对输入的两个数进行算术或逻辑运算。
  2. 端口定义
信号名 方向 位宽 说明
A I 32 操作数1
B I 32 操作数2
ALU_Op I 3 ALU控制信号
ALU_Res O 32 ALU运算结果
cmp_equal O 1 A、B是否相等

  1. 实现功能
序号 功能 描述
1 加法 当ALU_Op为3’b000时,ALU_Res输出A+B
2 减法 当ALU_Op为3’b001时,ALU_Res输出A-B
3 当ALU_Op为3’b010时,ALU_Res输出A&B
4 当ALU_Op为3’b011时,ALU_Res输出A丨B
5 异或 当ALU_Op为3’b100时,ALU_Res输出A^B
6 低位补0 当ALU_Op为3’b101时,ALU_Res输出B[15:0] + 016(实现lui指令)
7 相等 cmp_equal输出A是否等于B

Ext 指令扩展单元

  1. 定义:根据控制信号,对输入的16位立即数进行零扩展或符号扩展。
  2. 端口定义
信号名 方向 位宽 说明
offset I 16 16位立即数
sel I 1 扩展选择信号,0为零扩展,1为符号扩展
extend O 32 扩展后的32位立即数
  1. 实现功能
序号 功能 描述
1 零扩展 当sel为0时,extend输出 016 + offset[15:0]
2 符号扩展 当sel为1时,extend输出 offset[15] ? 116 + offset[15:0] : 016 + offset[15:0]

DM 数据存储器

  1. 定义:使用RAM实现,根据控制信号,对输入的地址和数据进行读写操作。
  2. 端口定义
信号名 方向 位宽 说明
address I 32 32位地址
WD I 32 32位数据
WE I 1 读/写控制信号,0为读,1为写
clk I 1 时钟信号

  1. 实现功能
序号 功能 描述
1 当WE为0时,输出地址对应的32位数据
2 当WE为1时,将WD写入地址对应的32位数据

CU 控制单元

  1. 定义:利用ANDLogicORLogic生成控制信号,控制其他模块的行为。

  2. 端口定义
    控制单元需要读取指令的Op字段和Func字段,识别生成对应指令的控制信号。

信号名 方向 位宽 说明
Op I 6 instr[31:26]
Func I 6 instr[5:0]
RegDst O 1 GRF写地址选择信号,0为Rt,1为Rd
ALUSrc O 1 ALU源选择信号,0为RD2,1为拓展后的offset
RegWrite O 1 GRF写使能信号
MemWrite O 1 DM写使能信号
is_Branch O 1 I型跳转指令
ExtOp O 1 扩展操作选择信号, 0为零拓展,1为符号拓展
ALU_Op O 3 三位ALU操作码,3’b000为加法,3’b001为减法,3’b010为与,3’b011为或,3’b100为异或

  1. 实现功能
  • ANDLogic模块
    • 定义:根据输入信号,识别对应指令。
    • 端口定义
      信号名 方向 位宽 说明
      Op I 6 instr[31:26]
      Func I 6 instr[5:0]
      add O 1 add指令
      sub O 1 sub指令
      ori O 1 ori指令
      lw O 1 lw指令
      sw O 1 sw指令
      beq O 1 beq指令
      lui O 1 lui指令

指令 Op [25:21] [20:16] [15:11] [10:6] [5:0]
add 000000 rs rt rd 00000 100000
sub 000000 rs rt rd 00000 100010
ori 001101 rs rt immediate immediate immediate
lw 100011 base rt offset offset offset
sw 101011 base rt offset offset offset
beq 000100 rs rt offset offset offset
lui 001111 00000 rt immediate immediate immediate
  • ORLogic模块
    • 定义:根据输入的对应指令,生成其他模块的操作信号。
    • 端口定义
      信号名 方向 位宽 说明
      add I 1 add指令
      sub I 1 sub指令
      ori I 1 ori指令
      lw I 1 lw指令
      sw I 1 sw指令
      RegDst O 1 GRF写地址选择信号,0为Rt,1为Rd
      ALUSrc O 1 ALU源选择信号,0为RD2,1为拓展后的offset
      MemRead O 1 GRF数据选择信号,0为ALU_Res,1为内存读取数据
      RegWrite O 1 GRF写使能信号
      MemWrite O 1 DM写使能信号
      is_Branch O 1 I型跳转指令
      ExtOp O 1 扩展操作选择信号, 0为零拓展,1为符号拓展
      ALU_Op O 3 三位ALU操作码,由真值表生成


- 功能实现:根据每种指令的对应操作,在输出前将指令信号进行或运算,得到其他模块的操作信号。

测试方案

思考题

  1. 上面我们介绍了通过 FSM 理解单周期 CPU 的基本方法。请大家指出单周期 CPU 所用到的模块中,哪些发挥状态存储功能,哪些发挥状态转移功能。

GRF、DM实现了状态存储功能,通过寄存器存储当前状态,IFU、Ext、NPC、ALU、CU实现了状态转移功能,利用组合逻辑电路实现状态转移。

  1. 现在我们的模块中 IM 使用 ROM, DM 使用 RAM, GRF 使用 Register,这种做法合理吗? 请给出分析,若有改进意见也请一并给出。

极为合理且正确,IM模块类比于是输入,应当是只读的,DM是内存部分,需要大量存储空间,因此使用RAM,GRF是通用寄存器堆,使用32个寄存器可以提高读写速度。

  1. 在上述提示的模块之外,你是否在实际实现时设计了其他的模块?如果是的话,请给出介绍和设计的思路。

添加了NPC模块,用于计PC的值,实现方法见上。

  1. 事实上,实现 nop 空指令,我们并不需要将它加入控制信号真值表,为什么?

由于nop并未对其他模块进行操作,因此不需要添加控制信号,只需要保证CU模块对于nop对应的Op和Func没有任何输出,就能保证不对其他模块进行操作。

  1. 阅读 Pre 的 “MIPS 指令集及汇编语言”一节中给出的测试样例,评价其强度(可从各个指令的覆盖情况,单一指令各种行为的覆盖情况等方面分析),并指出具体的不足之处。
    测试样例代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
ori $a0, $0, 123
ori $a1, $a0, 456
lui $a2, 123 # 符号位为 0
lui $a3, 0xffff # 符号位为 1
ori $a3, $a3, 0xffff # $a3 = -1
add $s0, $a0, $a2 # 正正
add $s1, $a0, $a3 # 正负
add $s2, $a3, $a3 # 负负
ori $t0, $0, 0x0000
sw $a0, 0($t0)
sw $a1, 4($t0)
sw $a2, 8($t0)
sw $a3, 12($t0)
sw $s0, 16($t0)
sw $s1, 20($t0)
sw $s2, 24($t0)
lw $a0, 0($t0)
lw $a1, 12($t0)
sw $a0, 28($t0)
sw $a1, 32($t0)
ori $a0, $0, 1
ori $a1, $0, 2
ori $a2, $0, 1
beq $a0, $a1, loop1 # 不相等
beq $a0, $a2, loop2 # 相等
loop1:sw $a0, 36($t0)
loop2:sw $a1, 40($t0)

显然强度是不够的(不够暴力),在代码数据量和覆盖率方面都有待提高,并没有测试到所有的通用寄存器和边界情况,测试数据也不够全面。