基于流水线的 CPU

  1. CPU 数据通路
  2. CPU 控制器

github 项目地址:https://github.com/yishiyu/mipscpu

1. CPU 数据通路

本 CPU 根据《数字设计和计算机体系结构》设计
参考的数据通路如下,同时在这个基础上增加了支持 J 指令的数据通路

2. CPU 控制器

  1. 控制信号
  2. 指令格式
  3. 冒险检测与解决

2.1 控制信号

输出引脚 作用
RegWrite 当前指令需要写入寄存器
MemtoReg 当前指令需要从存储器中获取数据并存入寄存器
MemWrite 当前指令需要写入存储器
ALUCtrl 指定 ALU 运算类型
ALUSrc ALU 中 B 数据来源选择(寄存器/立即数)
RegDst 寄存器写入目的指定,指定需要写入的寄存器(Rt/Rd)
BranchBEQ 当前指令为 BEQ 指令,需要在指令译码阶段判断是否跳转
BranchJ 当前指令为 J 指令,在指令译码阶段完成 J 跳转

2.2 指令格式

根据 MIPS 汇编指令的二进制码转换为对应的 ALU 操作指令
参考网址: CSDN 博客

ALU 操作码 运算 Func 码
000 AND 100100
001 OR 100101
010 ADD 100000
011 SUB 100010
100 SLT 101010
110 NOR 100111
111 XOR 100110

2.3 冒险检测与解决

  1. 已完成的指令

    1. R 型指令
    2. LW 指令
    3. SW 指令
    4. BEQ 指令
    5. J 指令
  2. 未完成指令

    1. ADDI 指令
  3. 已解决的冒险

    1. J 控制冒险
    2. BEQ 控制/数据冒险
    3. RAW 数据冒险(M 阶段和 W 阶段)
  4. 冒险,解决办法和测试指令

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# 1.RAW数据冲突
# 即计算得到的结果需要在送回寄存器之前被其他指令用(以R型指令为例,I型指令同理)
# 1.1 从另一个寄存器转移到另一个寄存器
# 该冲突使用数据旁路解决
LW $1,0($0)
LW $2,1($0)
ADD $3,$0,$0
ADD $4,$0,$0
ADD $5,$0,$0
ADD $6,$0,$0
ADD $7,$0,$0
# ($1,$2寄存器初始化完成,同时流水线中不再使用$1,$2寄存器)
# 开始测试
# 正确结果为$8,$9,$10寄存器中的结果为数据存储器0,1地址数之和
ADD $1,$1,$2
ADD $8,$1,$0
ADD $9,$1,$0
ADD $10,$1,$0
# 1.2 从数据存储器中取数
# 该冲突使用插入一个气泡解决
# 正确结果为$3寄存器中的结果为数据存储器0,1地址数之和
LW $1,0($0)
LW $2,1($0)
ADD $3,$1,$2

# 2. BEQ指令数据冲突
# 得到BEQ指令需要用到但是还没送回RF的数据
# 由于BEQ指令在D阶段就需要用数据,所以不同于R型指令
# 该冲突同时使用数据旁路和出入气泡解决
# 2.1 需要用的数据在 W 阶段==>由于寄存器组支持同时读写所以没有冲突
# 2.2 需要用的数据在 M 阶段==>使用数据旁路解决
# 2.3 需要用的数据在 E 阶段==>插入一个气泡后使用2.2方法解决
LW $1,0($0)
LW $2,1($0)
ADD $3,$0,$0
ADD $4,$0,$0
ADD $5,$0,$0
ADD $6,$0,$0
ADD $7,$0,$0
# ($1,$2寄存器初始化完成,同时流水线中不再使用$1,$2寄存器)
# 正确结果为完成跳转($4寄存器中的值不变)
ADD $3,$1,$0
BEQ $1,$3,4
ADD $4,$3,$0
ADD $5,$3,$0
ADD $6,$3,$0

# 3. 控制冒险
# 即指令执行顺序发生改变
# 3.1 J指令跳转
# 正确结果为$3,$4寄存器中的值未发生改变
LW $1,0($0)
LW $2,1($0)
J 20
LW $3,2($0)
LW $4,3($0)
LW $5,4($0)
LW $6,5($0)
# 3.2 BEQ指令跳转
# 正确结果为$2,$3寄存器中的值发生改变,$4,$5寄存器中的值未发生改变
LW $1,0($0)
BEQ $1,$0,8
LW $2,1($0)
LW $3,2($0)
BEQ $1,$1,8
LW $4,3($0)
LW $5,4($0)
LW $6,5($0)