CPU 设计文档

一、指令类型

  • 解读:将指令按类型分类,并对指令按照功能划分

R类型指令

R类型指令 Op(31~26) Rs(25~21) Rt(20~16) Rd(15~11) Shamt(10~6) Func(5~0)
Add 000000 Rs Rt Rd XXXXX 100000
Sub 000000 Rs Rt Rd XXXXX 100010
And 000000 Rs Rt Rd 00000 100100
Or 000000 Rs Rt Rd 00000 100101
Mult 000000 Rs Rt 00000 00000 011000
Multu 000000 Rs Rt 00000 00000 011001
Div 000000 Rs Rt 00000 00000 011010
Divu 000000 Rs Rt 00000 00000 011011
Mfhi 000000 00000 00000 Rd 00000 010000
Mflo 000000 00000 00000 Rd 00000 010010
Mthi 000000 Rs 00000 00000 00000 010001
Mtlo 000000 Rs 00000 00000 00000 010011
Slt 000000 00000 Rt Rd 00000 101010
Sltu 000000 00000 Rt Rd 00000 101011
Jr 000000 Rs 00000 00000 00000 001000

add:

Alt text

sub:

Alt text

and:

Alt text

or:

Alt text

mult:有符号数

Alt text

multu:无符号数

Alt text

div:

Alt text

divu:

Alt text

mfhi:

Alt text

mflo:

Alt text

mthi:

Alt text

mtlo:

Alt text

slt:

Alt text

sltu:

Alt text

jr:

Alt text

I类型指令

I类型指令 Op(31~26) Rs(25~21) Rt(20~16) immediate or address
Ori 001101 Rs Rt imm16
Lui 001111 00000 Rt imm16
Addi 001000 Rs Rt imm16
Andi 001100 Rs Rt imm16
Lb 100000 Base Rt offset_16
Lh 100001 Base Rt offset_16
Lw 100011 Rs Rt imm16
Sb 101000 Base Rt offset_16
Sh 101001 Base Rt offset_16
Sw 101011 Rs Rt imm16
Beq 000100 Rs Rt imm16
Bne 000101 Rs Rt offset_16

ori:

Alt text

lui:

Alt text

addi:

Alt text

andi:

Alt text

lb:

Alt text

lh:

Alt text

lw:

Alt text

Alt text

sb:

Alt text

sh:

Alt text

sw:

Alt text

beq:

Alt text

bne:

Alt text

J类型指令

J类型指令 Op(31~26) 26 address
j 000010 target
jal 000011 target

jal:

Alt text

二、主要模块

mips(顶层模块)

端口 方向 描述
clk I 时钟信号,控制所有需clk信号输入的模块
reset I 同步复位信号,控制所有需reset信号输入的模块

Conroller(控制器)

控制信号类型及含义

Branch
>

  • `Branch_normal : 0,PC输入选择加法器Add输出(PC+4)
  • `Branch_Beq 1: 若Zero=1,PC输入选择加法器Nadd
  • `Branch_Jal 2: PC输入选择Jal_Adr
  • `Branch_Jr 3: PC输入选择Rdata1
    RegDst

  • `RegDst_Rd: 选择Rd

  • `RegDst_Rt: 选择Rt
  • `RegDst_31:选择31(jal指令)
    RegWirte

1: 表示寄存器堆可写入

MemtoReg
>

  • `MemtoReg_ALU: 选择 ALU 输出
  • `MemtoReg_shift: 选择shift输出
  • `MemtoReg_DM: 选择数据存储器DM输出
  • `MemtoReg_Adder:选择Adder(地址加法器)输出

ALUSrc
>

  • `ALUSrc_ReadData2: 选择寄存器堆的 Read data2 输出
  • `ALUSrc_SiExt: 选择Signext输入
  • `ALUSrc_ZeExt:选择zero_ext输入

ALUOper
>

  • `ALU_add: ALU运算类型 —— +
  • `ALU_sub: ALU运算类型 —— -
  • `ALU_or: ALU运算类型 —— |

MemRead
>

  • 0:表示DM不可写入
  • 1:表示DM可写入

MemWrite
>

  • 0:表示DM不可写入
  • 1:表示DM可写入

shiftSrc
>

  • `shiftSrc_shamt: shamt(shift)选择shamt输入
  • `shiftSrc_0x10:shamt(shift) 选择0x10输入
  • `shiftSrc_0:shamt(shift) 选择0输入

(in.shift根据ALUSrc决定)

Tnew,rs_Tuse,rt_Tuse:根据指令输出
>

  • Tnew: 表示位于E级寄存器的指令经过Tnew个时钟周期可以算出结果并且存储到下一级流水级寄存器中。
  • rs_Tuse,rt_Tuse:表示该指令位于 D 级的时候,再经过多少个时钟周期就必须要使用Rs,Rt地址对应的数据。

Controller (指令实现控制信号的转换)

  • x表示指令实现与该输入无关
指令 Opcode Branch RegDst RegWrite MemtoReg ALUSrc ALUOp MemWrite MemCate shiftSrc Tnew rs_Tuse rt_Tuse
Add/Sub 000000 0 0 1 0 0 2 0 x x 1 1 1
Lw 100011 0 1 1 2 2 0 0 x x 2 1 5
Sw 101011 0 x 0 x 2 0 1 0 x 0 1 2
Beq 000100 1 x 0 x 0 1 0 x x 0 0 0
Ori 001101 0 1 1 0 1 3 0 x x 1 1 5
Lui 001111 0 1 1 1 x x 0 x 1 0 5 5
Nop 000000 0 x 0 x x x 0 x 0 0 5 5
Jal 000011 2 2 1 3 x x 0 x x 0 5 5
Jr 000000 3 x 0 x x x 0 x x 0 0 5

IFU (取指令单元)

端口 方向 描述
Clk I 时钟信号
Reset I 指令存储器(im_reg)所有地址的存储值清零
1: 复位
0:无效
enable_PC I 写使能信号,
1: 可写入数据
0: 不可写入数据(不可更改)
Branch I PC值分支跳转指令判断(4位)
Zero I beq指令判断PC是否跳转条件(1位)
index I 跳转指令的target中间值(26位)
immSiExt I 16位立即数有符号扩展输入(32位)
D_pc I D级指令所对应的PC地址(32位)
ReadData1 O GRF(寄存器堆)中Read register1地址对应寄存器的输出
pc O PC当前值(32位)
instr O PC地址对应IM(指令存储器)的指令输出(32位)

IF_ID(D级寄存器)

端口 方向 描述
clk I 时钟信号
reset I 寄存器存储值清零
1: 复位
0:无效
enable_D I 写使能信号,
1: 可写入数据
0: 不可写入数据(不可更改)
F_pc I F级指令对应的PC地址(32位)
F_instr I F级指令PC地址对应的指令(32位)
D_pc O D级指令对应的PC地址(32位)
D_instr O D级指令PC地址对应的指令(32位)

Stall (暂停信号控制器)

端口 方向 描述
rs_Tuse I D级指令对应的rs_Tuse(4位)
rt_Tuse I D级指令对应的rt_Tuse(4位)
E_Tnew I E级指令对应的Tnew(4位)
M_Tnew I M级指令对应的Tnew(4位)
W_Tnew I W级指令对应的Tnew(4位)
Rs I D级指令对应的Rs(5位)
Rt I D级指令对应的Rt(5位)
E_WriteRes I E级指令执行写入GRF操作时的地址(5位)
M_WriteRes I M级指令执行写入GRF操作时的地址(5位)
W_WriteRes I W级指令执行写入GRF操作时的地址(5位)
E_RegWrite I E级指令是否执行写入GRF操作,
1: 写入
0: 不写入
M_RegWrite I M级指令是否执行写入GRF操作,
1: 写入
0: 不写入
W_RegWrite I W级指令是否执行写入GRF操作,
1: 写入
0: 不写入
enable_PC O IFU模块中的PC寄存器写使能信号,
1: 可写入数据
0: 不可写入数据(不可更改)
enable_D O D级寄存器写使能信号,
1: 可写入数据
0: 不可写入数据(不可更改)
enable_PC O IFU模块中的PC寄存器写使能信号,
1: 可写入数据
0: 不可写入数据(不可更改)
reset_E O E级寄存器存储值清零
1: 复位
0:无效

shift(移位器)

端口 方向 描述
input I 操作数
shamt I 偏移量(5位)
output I 操作数移位后输出

CMP(比较器)

端口 方向 描述
ReadData1 I 操作数1
ReadData2 I 操作数2
Zero O 比较ReadData1和ReadData2,
1: 相等
0: 不相等

GRF(寄存器堆)

端口 方向 描述
Clk I 时钟信号
Reset I 复位信号,将寄存器的值全部清零
1: 复位
0:无效
WE I 写使能信号
1: 可写入数据
0: 不可写入数据
ReadRes1 I 读出地址输入(5位),读出到Read Data1
ReadRes2 I 读出地址输入(5位),读出到Read Data2
WriteRes I 写入地址输入(5位)
WriteData I 写入数据(32位)
WPC I 输入当前pc地址
ReadData1 O Read register1地址对应寄存器的输出
ReadData2 O Read register2地址对应寄存器的输出

ID_EX (E级寄存器)

端口 方向 描述
clk I 时钟信号
reset I 复位信号,将寄存器的值全部清零
1: 复位
0:无效
D_pc I D级指令对应的pc地址
reset_E I E级寄存器的复位信号,将寄存器的值全部清零
1: 复位
0:无效
D_ReadRes1 I D级指令对应的Rs,GRF读出地址(5位)
D_ReadRes2 I D级指令对应的Rt,GRF读出地址(5位)
D_ReadData1 I D级指令D_ReadRes1地址对应寄存器的输出(32位)
D_ReadData2 I D级指令D_ReadRes2地址对应寄存器的输出(32位)
D_WriteRes I D级指令写入GRF的地址(5位)
D_WriteData I D级指令写入GRF的数据(32位)
D_ExtShift I D级指令的extend和shift模块输出(32位)
D_MemtoReg I D级指令存入GRF的数据类型(4位)
D_MemWrite I D级指令是否写入DM
1: 可写入
0:不可写入
D_MemCate I D级指令写入DM的指令类型(4位)
D_ALUOper I D级指令运算类型(4位)
D_RegWrite I D级指令是否可写入GRF
1: 可写入
0:不可写入
D_ALUSrc I D级指令ALU模块的B端口输入数据类型(4位)
D_Tnew I D级指令对应的Tnew(4位)
E_pc I E级指令对应的pc地址
E_ReadRes1 I E级指令对应的Rs,GRF读出地址(5位)
E_ReadRes2 I E级指令对应的Rt,GRF读出地址(5位)
E_ReadData1 I E级指令D_ReadRes1地址对应寄存器的输出(32位)
E_ReadData2 I E级指令D_ReadRes2地址对应寄存器的输出(32位)
E_WriteRes IE级指令写入GRF的地址(5位)
E_WriteData I E级指令写入GRF的数据(32位)
E_ExtShift I E级指令的extend和shift模块输出(32位)
E_MemtoReg I E级指令存入GRF的数据类型(4位)
E_MemWrite I E级指令是否写入DM
1: 可写入
0:不可写入
E_MemCate I E级指令写入DM的指令类型(4位)
E_ALUOper I E级指令运算类型(4位)
E_RegWrite I E级指令是否可写入GRF
1: 可写入
0:不可写入
E_ALUSrc I E级指令ALU模块的B端口输入数据类型(4位)
E_Tnew I E级指令对应的Tnew(4位)

ALU(算数逻辑单位)

端口 方向 描述
A I 操作数1(32位)
B I 操作数2(32位)
ALUOper I ALU功能选择(4位)
Result O 结果输出(32位)

EX_MEM(M级寄存器)

端口 方向 描述
clk I 时钟信号
reset I 复位信号,将寄存器的值全部清零
1: 复位
0:无效
ALU_out I D级指令ALU的输出结果(32位)
E_pc I E级指令对应的pc地址
E_ReadRes1 I E级指令对应的Rs,GRF读出地址(5位)
E_ReadRes2 I E级指令对应的Rt,GRF读出地址(5位)
E_ReadData2 I E级指令D_ReadRes2地址对应寄存器的输出,需转发(32位)
E_WriteRes I E级指令写入GRF的地址(5位)
E_WriteData I E级指令写入GRF的数据(32位)
E_MemtoReg I E级指令存入GRF的数据类型(4位)
E_MemWrite I E级指令是否写入DM
1: 可写入
0:不可写入
E_MemAddress I E级指令写入DM的地址(32位)
E_MemCate I E级指令写入DM的指令类型(4位)
E_RegWrite I E级指令是否可写入GRF
1: 可写入
0:不可写入
E_Tnew I E级指令对应的Tnew(4位)
M_pc O M级指令对应的pc地址
M_ReadRes1 O M级指令对应的Rs,GRF读出地址(5位)
M_ReadRes2 O M级指令对应的Rt,GRF读出地址(5位)
M_ReadData2 O M级指令D_ReadRes2地址对应寄存器的输出(32位)
M_WriteRes O M级指令写入GRF的地址(5位)
M_WriteData O M级指令写入GRF的数据(32位)
M_MemtoReg O M级指令存入GRF的数据类型(4位)
M_MemWrite O M级指令是否写入DM
1: 可写入
0:不可写入
M_MemAddress O M级指令写入DM的地址(32位)
M_MemCate O M级指令写入DM的指令类型(4位)
M_RegWrite O M级指令是否可写入GRF
1: 可写入
0:不可写入
M_Tnew O M级指令对应的Tnew(4位)

DM(数据存储器)

端口 方向 描述
Clk I 时钟信号
pc O M级指令的PC当前值(32位)
Reset I 数据存储器(RAM)所有地址的存储值清零
1: 复位
0:无效
MemWrite I 写使能信号,
1: 可写入数据
0: 不可写入数据
MemCate I 判断向数据储存器写入数据的操作指令类型(4位)
Address I 读写地址(12位)
WriteData I 写入数据(32位)
ReadData_DM O Address地址对应数据储存器(RAM)的储存值输出

MEM_WB

端口 方向 描述
clk I 时钟信号
reset I 复位信号,将寄存器的值全部清零
1: 复位
0:无效
M_pc I M级指令对应的pc地址
M_WriteRes I M级指令写入GRF的地址(5位)
M_WriteData I M级指令写入GRF的数据(32位)
M_MemtoReg I M级指令存入GRF的数据类型(4位)
M_MemWrite I M级指令是否写入DM
1: 可写入
0:不可写入
M_RegWrite I M级指令是否可写入GRF
1: 可写入
0:不可写入
M_Tnew I M级指令对应的Tnew(4位)
ReadData_DM I M级指令Address地址对应数据储存器(RAM)的储存值输出
W_pc O W级指令对应的pc地址
W_WriteRes O W级指令写入GRF的地址(5位)
W_WriteData O W级指令写入GRF的数据(32位)
W_MemtoReg O W级指令存入GRF的数据类型(4位)
W_MemWrite O W级指令是否写入DM
1: 可写入
0:不可写入
W_RegWrite O W级指令是否可写入GRF
1: 可写入
0:不可写入
W_Tnew O W级指令对应的Tnew(4位)

三、数据通路

Alt text

指令 A B PC IM Adr Reg1 Reg2 Wreg Wdata A B DM Adr DM Wdata Sign-ext A B shift ext
Adder: ALU: Nadder: /
R型指令与访存 PC 4 Adder PC Rs Rt Rd ALU Rdata1 Rdata2 / / / / / /! /
Lw PC 4 Adder PC Rs / Rt DM Rdata1 Sign_ext ALU / imm16 / / / /
Sw PC 4 Adder PC Rs Rt / / Rdata1 Sign_ext ALU Rdata2 imm16 / / / /
Beq PC 4 Adder/Nadder PC Rs Rt / / Rdata1 Rdata2 / / imm16 Adder Sign-imm16(左移2) / /
Ori PC 4 Adder PC Rs / Rt ALU Rdata1 zero_ext / / / / / / imm16
Lui PC 4 Adder PC / / Rt shift / / / / / / / imm16 / /
Nop PC 4 Adder PC / Rt Rd shift / / / / / / / Rdata2 /
jal PC 4 Jal_Adr PC / / 31 Adder / / / / / / / / /
jr / / Rdata1 PC Rs / / / / / / / / / / / /

四、测试

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
lui $t0,7434 
lui $t1,3822
lui $t2,5323
lui $t3,2312
ori $t0,2372
ori $t1,1543
ori $t2,4312
ori $t3,2673
addi $a0,$t0,10
andi $a1,$t1,6
mult $t0,$t1
mflo $t3
add $a2,$a0,$t3
mthi $a0
mtlo $a1
add $a2,$a0,$a1
mfhi $t3
multu $t3,$a2
mult $t0,$t1
div $t1,$t2
mflo $a0
mfhi $a1
add $s1,$a0,$a1
divu $s1,$a1
mfhi $a0
add $a2,$a0,$a0
add $a0,$a0,$a1
sub $a1,$a1,$a0
and $a2,$a1,$a0
or $a3,$a2,$a1
slt $s0,$a1,$a2
sub $a1,$a1,$a0
and $a2,$a1,$a0
addi $a1,$s0,13212314
andi $a2,$a1,0xfd42a586
sub $a1,$a3,$t3
sltu $s1,$a1,$a2
sw $a2,0($0)
sh $a1,0($0)
sb $a0,0($0)
mthi $a0
mtlo $a1
add $a2,$a0,$a1
sub $a1,$a1,$a0
and $a2,$a1,$a0
add $a0,$a0,$a1
lw $a2,0($0)
lh $a1,0($0)
lb $a0,0($0)
add $a2,$a0,$a0
add $a0,$a0,$a1
multu $t3,$a2
mult $t0,$t1
sub $a1,$a1,$a0
and $a2,$a1,$a0
or $a3,$a2,$a1
slt $s0,$a1,$a2
  • Mars导出的机械码(储存在code.txt中的文件):
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
3c081d0a
3c090eee
3c0a14cb
3c0b0908
35080944
35290607
354a10d8
356b0a71
2104000a
31250006
01090018
00005812
008b3020
00800011
00a00013
00853020
00005810
01660019
01090018
012a001a
00002012
00002810
00858820
0225001b
00002010
00843020
00852020
00a42822
00a43024
00c53825
00a6802a
00a42822
00a43024
3c0100c9
34219a9a
02012820
3c01fd42
3421a586
00a13024
00eb2822
00a6882b
ac060000
a4050000
a0040000
00800011
00a00013
00853020
00a42822
00a43024
00852020
8c060000
84050000
80040000
00843020
00852020
01660019
01090018
00a42822
00a43024
00c53825
00a6802a

利用$readmemh指令读取code.txt中的机械码指令并储存在IFU_mips模块的指令存储器im_reg(4096个32位寄存器)当中,运行mips顶层模块,通过$display指令检测存入寄存器堆(GRF)和数据存储器(DM)时的pc地址,相应数据以及存入的寄存器或数据存储器地址,将结果与Mars对拍运行时的数据做比对,以此检测Verilog代码编写的单周期CPU是否正确。

五、思考题

Q1

因为进行乘法和除法运算时存在延迟,而其他运算方式在一个周期内即可完成运算,所有独立出一个乘除法部件使其他运算(乘除运算外)不受乘除运算的影响。
在进行乘除法运算时,其他运算并行运行,当乘除法运算结束后,将计算结果存入HI,LO寄存器即可,之后通过mfhi,mflo指令将HI,LO寄存器中的值取出。故使用独立的HI,LO寄存器是为了存储乘除法运算的结果,并方便取出计算结果。

Q2

在流水线 CPU 中,乘法运算和除法运算的执行是分为几个阶段的。对于乘法运算,至少需要3个阶段:取数、乘法和回写结果。在取数阶段,CPU 从内存中读取两个操作数。在乘法阶段,CPU 执行乘法运算,并将结果存储在一个临时寄存器中。最后,在回写结果阶段,CPU 将临时寄存器中的结果写入目标寄存器中,除法指令类似。
在执行乘除法运算时,CPU 需要遵循特定的指令序列。这些指令序列是预先定义好的,用于控制 CPU 的操作和时序。
CPU 还需要遵循特定的时序规则。这些规则规定了每个阶段的时间长度和操作顺序。例如,取数阶段必须在乘法阶段之前完成,除法阶段必须在回写结果阶段之前完成。
真实的流水线 CPU 是通过多个阶段的协同工作和遵循特定的指令序列和时序规则来实现乘除法运算的。

Q3

当E级为乘除法运算时,Start信号置一,一时钟周期后,Start信号复位,Busy信号根据乘除法运算维持一定周期的高位。
通过计数值cnt的方式来,对于乘法运算,当Start信号处于高位时,将D1,D2,MDOper(运算类型)存入临时变量,同时在下一周期满足条件时,将Busy信号置一,同时赋值cnt为5,同时将计算结果(利用D1,D2,MDOPer的临时变量)存入HI,LO临时变量中,在接下来的时钟周期中,若cnt不为1,则进行自减一,若为1,则将cnt置为0,同时将HI,LO临时寄存器的值存入HI,LO寄存器当中,从而完成周期阻塞。

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
always @(*) begin
if(Func == `Func_Mtlo && Opcode == `Op_R)begin
LO <= MT_Data;
end
else if (Func == `Func_Mthi && Opcode == `Op_R) begin
HI <= MT_Data;
end
else if((Opcode == `Op_R) && (Func == `Func_Multu || Func == `Func_Mult || Func == `Func_Divu || Func == `Func_Div)) begin
if(cnt == 0) begin
Start <= 1;
temp_D1 <= D1;
temp_D2 <= D2;
temp_MDOper <= MDOper;
end
else begin
Start <= 0;
end
end
else begin
Start <= 0;
end
end

always @(posedge clk) begin
if(cnt == 0) begin
if(Start) begin
Busy <= 1;
if(temp_MDOper == `MD_Multu || temp_MDOper == `MD_Mult) cnt <= 5;
else if(temp_MDOper == `MD_Divu || temp_MDOper == `MD_Div) cnt <= 10;

if(temp_MDOper == `MD_Multu) begin
{temp_HI, temp_LO} <= temp_D1 * temp_D2;
end
else if(temp_MDOper == `MD_Mult) begin
{temp_HI, temp_LO} <= $signed(temp_D1) * $signed(temp_D2);
end
else if(temp_MDOper == `MD_Div) begin
temp_LO <= $signed(temp_D1) / $signed(temp_D2);
temp_HI <= $signed(temp_D1) % $signed(temp_D2);
end
else if(temp_MDOper == `MD_Divu) begin
temp_LO <= temp_D1 / temp_D2;
temp_HI <= temp_D1 % temp_D2;
end
end
else begin
cnt <= 0;
end
end
else if(cnt == 1) begin
Busy <= 1'b0;
cnt <= 0;
LO <= temp_LO;
HI <= temp_HI;
end
else begin
cnt <= cnt - 1;
end
end

Q4

清晰性:这种处理方式可以直接从信号(二进制)中看出写入数据存储器中的数据位置,并方便为不同写入DM的指令编码写入数据存储器的使能信号。
统一性:每种写入DM的指令都可使用这种使能信号的编码方式。

Q5

不是
当只写入一字节的数据或者读出一字节的数据时

Q6

模块化,将各个功能部件聚合成一个模块,简化每一个模块的复杂度,尽量使他们彼此独立
使用独立译码器,将指令分析和模块的功能分离,让模块只受译码器给出的信号的控制。
wire型数据统一申明
译码器:使用指令驱动型的译码器,利用宏定义的方式命名控制信号,并对相似指令的控制信号进行统一赋值,并将控制信号统一输出。
模块化和使用独立译码后,只要在进入模块前选择其所要使用的控制信号以及数据即可。例如通过转发以及选择信号控制输入数据,仅需判断当前模块所要考虑的数据冲突。
命名方式:使用关键词以及下划线分隔符的方式选择信号,方便进行模块前的输入信号的辨识判断。

Q7

需向寄存器数据类型的指令与需读出寄存器数据类型的指令之间的冲突,例如add,sub,and,or,mult,multu,div,divu,slt,sltbeq,bne指令需要读出Rs,Rt对应寄存器的数据,mtlo,mthi,jr,sw,sh,sb,ori,lui,andi等需要读出Rs对应寄存器的数据,当lw,lh,lb,jal,运算类型,slt,slt(置位),jal等类型的指令未写入寄存器当中时,其会发生数据冲突。
利用转发和暂停来控制冒险冲突
测试样例:

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
lui $t0,7434 
lui $t1,3822
lui $t2,5323
lui $t3,2312
ori $t0,2372
ori $t1,1543
ori $t2,4312
ori $t3,2673
addi $a0,$t0,10
andi $a1,$t1,6
mult $t0,$t1
mflo $t3
add $a2,$a0,$t3
mthi $a0
mtlo $a1
add $a2,$a0,$a1
mfhi $t3
multu $t3,$a2
mult $t0,$t1
div $t1,$t2
mflo $a0
mfhi $a1
add $s1,$a0,$a1
divu $s1,$a1
mfhi $a0
add $a2,$a0,$a0
add $a0,$a0,$a1
sub $a1,$a1,$a0
and $a2,$a1,$a0
or $a3,$a2,$a1
slt $s0,$a1,$a2
sub $a1,$a1,$a0
and $a2,$a1,$a0
addi $a1,$s0,13212314
andi $a2,$a1,0xfd42a586
sub $a1,$a3,$t3
sltu $s1,$a1,$a2
sw $a2,0($0)
sh $a1,0($0)
sb $a0,0($0)
mthi $a0
mtlo $a1
add $a2,$a0,$a1
sub $a1,$a1,$a0
and $a2,$a1,$a0
add $a0,$a0,$a1
lw $a2,0($0)
lh $a1,0($0)
lb $a0,0($0)
add $a2,$a0,$a0
add $a0,$a0,$a1
multu $t3,$a2
mult $t0,$t1
sub $a1,$a1,$a0
and $a2,$a1,$a0
or $a3,$a2,$a1
slt $s0,$a1,$a2

Q8

手动构造:
编写各种类型指令对应的代码,控制利用寄存器的类型,之后将上述代码随机组合。
随机产生的测试程序的不足之处:

其并不能确保包含所有冲突与冒险类型,存在缺漏,需要保证数据量足够大,尽可能的覆盖。