RooKie_Z P5 Verilog流水线CPU设计文档

RooKie_Z P5 Verilog流水线CPU设计文档

写在前面

这是RooKie_Z的P5流水线CPU设计文档,在课上测试中本CPU取得了 满分💯的成绩。

总体设计概述

本次要求实现的指令集为add, sub, ori, lw, sw, beq, lui, jal, jr, nop,与P3、P4相同,但是工作量却天差地别,我的黑眼圈也很能说明这点。言归正传,在考虑到更好地满足转发的要求与利于课上进行增量开发的前提下,我对于P4的代码进行了一部分重构,但总体上更改并不大,具体的设计方案参考自高小鹏老师的PPT和CoekJan学长的博客,他们的详尽叙述帮我省下了大量琢磨AT方法的时间。CoekJan,YYDS!!!

五级流水线各级部件

数据通路

添加转发后的数据通路

注:MDU为乘除法单元,供P6使用


关键模块介绍

总体而言,在总体架构不作大的修改的前提下,修改了一部分控制信号,同时添加了流水线各级寄存器和虚拟的阻塞控制单元,对于每一级流水线都设计了相应的译码器。

命名规则

  • 对于各模块文件,均采用对于元件的文件命名,均为流水线层级_元件英文简称,例如D_GRF.vE_ALU.v等,实例化时命名为大写首字母小写英文名,例如AluGrf
  • 对于流水线寄存器文件命名为两边的流水线层级_REG,例如FD_REG.vDE_REG.v,实例化时命名为大写英文层级,例如FD
  • 每一级的控制信号和临时的wire均以本级的名称开头,如E_ALUOpM_DMOp
  • 在流水线中参与流水的信息遵从以下约定(以D级为例)
    • PCInstr命名以流水线层级开头,如D_PCD_Instr
    • 寄存器地址分别为D_rs_addrD_rt_addr,读出数据为D_rsD_rt
    • 转发得到的寄存器数据(直接读取也视为一种转发)记作D_FWD_rs_dataD_FWD_rt_data
    • 即将写入的寄存器地址为E_A3,即将写入的数据记作E_WD,选择信号为E_WDSel

F级(取指)

  • F级不需要转发,阻塞时停止读入指令,置低PC_WE
  • 本级输入来自D级NPC,输出F_PCF_Instr,参与流水

IFU

信号名称 方向 功能描述
NPC[31:0] I 待写入PC的指令地址
clk I 时钟信号
reset I 同步复位信号
PC_WE I PC的写使能
PC O 当前指令地址
Instr[31:0] O 32位的指令值

FD_REG(F/D级流水线寄存器)

信号名称 方向 功能描述
clk I 时钟信号
reset I 同步复位信号
flush I 寄存器刷新信号(阻塞时使用)
F_PC I F级PC的指令地址
F_Instr[31:0] I 时钟信号
D_PC O D级PC的指令地址
D_Instr[31:0] O 32位的指令值

D级(译码)

  • 本级需要处理来自E, M, W级的转发,其中W级为寄存器内部转发,另外两个分别是D_FWD_rs,D_FWD_rt,在CMPNPC中需要用
  • 本级的输入是来自F级的PCInstr,输出是D_rsD_rtD_Ext_OutD_PCD_Instr,这些参与流水,还有输出到F级的NPC
  • 本级元件较多,是最复杂的一级

D_GRF

端口说明
信号名称 方向 功能描述
A1[4:0] I 5位地址输入信号,将其储存的数据读出到RD1
A2[4:0] I 5位地址输入信号,将其储存的数据读出到RD2
A3[4:0] I 5位地址输入信号,将其作为写入数据的目标寄存器
RD1[31:0] O 输出A1指定的寄存器中的32位数据
RD2[31:0] O 输出A2指定的寄存器中的32位数据
WD[31:0] I 32位数据输入信号
clk I 时钟信号
reset I 同步复位信号,将32个寄存器中的数据清零;1:复位;0:无效
  • 这次删去了WE写使能信号,因为如果我们不写寄存器,可以把A3设为0,就相当于不写寄存器了

Ps :这是我灵光一现想到的办法,受了P4课上访存指令的启发,如果有指令要在读出之后针对数据判断是否写入GRF,那么WE信号不仅要一直参与流水,还要用于控制每级的转发与阻塞,利用0寄存器的特点就可以规避这一切的麻烦!!!

控制信号说明

1. D_A3

直接给出待写入寄存器的地址,弃用了在P4中利用A3Sel进行选择的设计,这是因为P5采用分布式译码,每一级都需要A3的信息,因此在CTRL里面直接集成了

2. D_WDSel

控制信号值 功能
WDSel_DMout 选择写入寄存器的数据来自DM
WDSel_ALUout 选择写入寄存器的数据来自ALU运算结果
WDSel_PC8 选择写入寄存器的数据为当前流水线层级中的PC+8

D_EXT

16位二进制数进行零扩展符号扩展到32位

控制信号说明
控制信号值 功能
EXT_unsigned 零扩展
EXT_signed 符号扩展

D_CMP(分支比较)

参考P3中CPU内BranchDefine子电路生成的CMP模块,来生成jump信号,判断分支是否跳转,link是否写入

目前实现了beq, bne, bgtz, bltz等指令

代码实现:
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
`timescale 1ns / 1ps
`include "signal_def.v"

module CMP(
input [31:0] rs,
input [31:0] rt,
input [2:0] CMPOp,
output reg jump
);

wire eq = (rs == rt);
wire ne = !eq;
wire ltz = ($signed(rs) < 0);
wire gtz = ($signed(rs) > 0);
wire eqz = (rs == 0);

always @(*) begin
case (CMPOp)
`CMP_beq: begin
jump = eq ? 1 : 0;
end
`CMP_bne: begin
jump = ne ? 1 : 0;
end
`CMP_bltz: begin
jump = ltz ? 1 : 0;
end
`CMP_bgtz: begin
jump = gtz ? 1 : 0;
end
default: jump = 1'b0;
endcase
end
endmodule

端口说明
端口名称 方向 功能描述
rs[31:0] I 转发后$rs寄存器的值
rt[31:0] I 转发后$rt寄存器的值
CMPOp[2:0] I 控制信号
jump O 指示分支是否跳转

D_NPC(次地址计算)

有了CMP之后,NPC的功能也更加简洁,只需根据NPCOpjump信号输出NPC信号的值就行

实际上NPC横跨了F级和D级两级,因为同时会输入F_PCD_PC,前者正常跳转F_PC+4用,后者则用于流水PC值,后面转发PC+8的时候用

这次我们弃用了P4中直接输出PC+4的设计,转而让PC信号参与流水,在需要转发时计算PC+8

端口说明
端口名称 方向 功能描述
F_PC[31:0] I 32位输入当前F级地址
D_PC[31:0] I 32位输入当前D级地址
imm[31:0] I 32位立即数
jump I 指示b类型指令是否跳转
NPCOp[2:0] I 控制信号
RD1_rs[31:0] I $ra寄存器保存的32位地址
NPC[31:0] O 32位输出次地址
控制信号说明
控制信号值 功能
NPC_pc4 NPC = F_PC+4
NPC_b 执行beq等b类指令
NPC_jal 执行jjal指令
NPC_jalr 执行jalrjr指令

DE_REG(D/E级流水线寄存器)

  • 输入D_PC,D_Instr,D_Ext_Out,此外上一级的$rs$rt的值也要参与流水,即D_FWD_rs,D_FWD_rt需要参与流水,这是由于指令序列sw, nop, add的存在,sw在M级需要使用$rt的数据,但是在E级不会再进行转发(因为在D级已经转发过了),因此需要让正确的$rt值参与流水

  • 输出E_PC,E_Instr,E_Ext_Out,E_rs,E_rtALU需要这些信息

信号名称 方向 功能描述
clk I 时钟信号
reset I 同步复位信号
flush I 寄存器刷新信号(阻塞时使用)
D_PC[31:0] I D级PC的指令地址
D_Instr[31:0] I 32位的指令值
D_Ext_Out[31:0] I 16位立即数经EXT扩展的结果
D_rs[31:0] I 32位的寄存器数据
D_rt[31:0] I 32位的寄存器数据
E_PC[31:0] O E级PC的指令地址
E_Instr[31:0] O 32位的指令值
E_Ext_Out[31:0] O 16位立即数经EXT扩展的结果
E_rs[31:0] O 32位的寄存器数据
E_rt[31:0] O 32位的寄存器数据

E级(执行)

E_ALU

  • 相比于P4,ALU做了很大的变动,添加了ALUSrcA信号选择A运算数的来源,这是为了便于扩展sllsllv类指令的原因取消了shamt信号,shamt信号从ALUSrcB中选择进入ALU
端口说明
信号名称 方向 功能描述
A[31:0] I 32位输入运算数A
B[31:0] I 32位输入运算数B
ALUOp[4:0] I 控制信号
ALUOut[31:0] O 32位输出运算结果
控制信号说明

1. ALUOp

控制信号值 功能
ALU_add 执行加法运算
ALU_sub 执行减法运算
ALU_or 执行逻辑或运算
ALU_lui 执行lui指令

2. ALUSrcA

控制信号值 功能
SrcA_rt 对于sllsllv等移位指令,选择$rt的值
SrcA_rs 对于其他大部分运算指令,采用 $rs的值

3. ALUSrcB

控制信号值 功能
SrcB_rt 选择处理完转发后$rt寄存器中的值进行运算
SrcB_imm 选择立即数进行运算
SrcB_shamt 使用{27'b0, E_ALUshamt}得到32为扩展移位数
SrcB_rs 考虑到sllv指令要求可变的位移数,这里可以选择{27'b0, E_FWD_rs_data[4:0]},即$rs寄存器中的数据作为移位数

EM_REG(E/M级流水线寄存器)

  • 输入E_PC,E_Instr,此外上一级的ALUOut参与流水,即E_ALU_Out,E_Ext_Out需要参与流水,这是因为ALUOut可能是待写入或读取的内存地址另外,上一级的rt值需要参与流水,因此还需要输入E_FWD_rt这是因为sw指令会向内存中写入$rt的数据
  • 输出M_PC,M_Instr,M_ALU_Out,M_DM_Out
信号名称 方向 功能描述
clk I 时钟信号
reset I 同步复位信号
flush I 寄存器刷新信号(阻塞时使用)
E_PC[31:0] I E级PC的指令地址
E_Instr[31:0] I 32位的指令值
E_Ext_Out[31:0] I 16位立即数经EXT扩展的结果
E_rt[31:0] I 32位的寄存器数据
E_ALU_Out[31:0] I 32位的ALU运算结果
M_PC[31:0] O M级PC的指令地址
M_Instr[31:0] O 32位的指令值
M_Ext_Out[31:0] O 16位立即数经EXT扩展的结果
M_ALU_Out[31:0] O 32位的ALU运算结果
M_rt[31:0] O 32位的寄存器数据

M级(储存)

M_DM

端口说明
信号名称 方向 功能描述
Addr[31:0] I 待操作的内存地址
WD[31:0] I 待写入内存的值
clk I 时钟信号
reset I 同步复位信号
DMWr I 写使能信号;1:写入有效;0:写入无效
DMOp[2:0] I 控制信号
DMout[31:0] O 输入地址指向的内存中储存的值
控制信号说明
控制信号值 功能
DM_w 对应lwsw指令,写入或读取整个字
DM_h 对应lhsh指令,写入或读取半字
DM_b 对应lbsb指令,写入或读取整个字
DM_hu 对应lhu指令
DM_bu 对应lbu指令

W级(回写)

MW_REG(M/W级流水线寄存器)

信号名称 方向 功能描述
clk I 时钟信号
reset I 同步复位信号
flush I 寄存器刷新信号(阻塞时使用)
M_PC[31:0] I M级PC的指令地址
M_Instr[31:0] I 32位的指令值
M_DM_Out[31:0] I 从内存中读取的值
M_ALU_Out[31:0] I 32位的ALU运算结果
W_PC[31:0] O W级PC的指令地址
W_Instr[31:0] O 32位的指令值
W_DM_Out[31:0] O 从内存中读取的值
W_ALU_Out[31:0] O 32位的ALU运算结果

数据通路分析

指令 opcode funct NPCOp A3Sel WDSel EXTOp GRFWE ALUSRCB ALUOp DMWr DMOp
add 000000 100000 NPC_PC4 A3Sel_rd WDSel_ALUout X 1 SrcB_rt ALU_add 0 X
sub 000000 100010 NPC_PC4 A3Sel_rd WDSel_ALUout X 1 SrcB_rt ALU_sub 0 X
ori 001101 X NPC_PC4 A3Sel_rt WDSel_ALUout EXT_unsigned 1 SrcB_imm ALU_or 0 X
lw 100011 X NPC_PC4 A3Sel_rt WDSel_DMout EXT_signed 1 SrcB_imm ALU_add 0 DM_w
sw 101011 X NPC_PC4 X WDSel_DMout EXT_signed 0 SrcB_imm ALU_add 1 DM_w
beq 000100 X NPC_branch X X X 0 X X 0 X
lui 001111 X NPC_PC4 A3Sel_rt WDSel_ALUout X 1 SrcB_imm ALU_lui 0 X
jal 000011 X NPC_jal A3Sel_ra WDSel_PC8 X 1 X X 0 X
jr 000000 001000 NPC_jalr X X X 0 X X X X

本CPU采用分布式译码,在每一级均设有译码器,解码出各级所需信息


冲突处理方法

转发(Forwarding)

对于转发,我们直接采用 AT 法 + 暴力转发,首先要搞明白转发到哪,转发什么。 对于每一个流水线层级,我们要能够确定当前这一级正在执行的指令要写什么数据,向哪里写,因此就要维护 GRFWD (解决转发啥)和 GRFA3 (解决转发到哪)这两个值,我们转发需要去关注的也就是这两个数据,这些信号都可以从 Control 里面译码读出来 简单来说就是,我们需要在每一级都知道本级需要从哪读数据,要写到哪,要写啥,现在不知道没事,总之在这条指令从流水线消失之前,我们肯定知道,并且可以根据这些再经过判断做转发。

在每一个需要用转发数据的地方,我们去比较要用的数据的 GPR 地址和前面正在维护的要写的 GRFA3 的地址,如果相同,那就意味着我们要写的寄存器已经被用了,但是这时前面获得的值显然是错误的,这时候直接转发过去就好了

这里还要考虑优先级的问题,流水线寄存器生成的WD越靠近这条指令,得到的数据就越新,我们就越倾向于优先使用这些数据

利用 AT 法,如果不阻塞就意味着一定能够在使用该寄存器的值之前获得正确的值,如果我们要用的时候,这个正确的值还没有算出来,那肯定不行,这时候我们就阻塞,如果能算出来,那么之前转发的错误的值不用去管它,最后总能得到一个正确的值去覆盖原先错误的值

如果我们还不知道要写的值是啥,那这个时候 GRFA3 就给正确的地址, GRFWD 就给 32'bz ,这时还不能做转发,但是如果写的阻塞模块正确,这个值就不可能被转发,因为这种情况如果出现就已经被阻塞在 D 级了

综合考量各种指令序列,我们得到了转发的旁路:

  1. D级需求: E->D(如序列jal-add), M->D(如序列jal-nop-add)(W->D隐藏于GRF的内部转发中);
  2. E级需求: M->E(如序列add-add), W->E(如序列add-nop-add)
  3. M级需求: W->M(如序列add-sw)

具体设计见前文图片

代码实现

W to D:

1
2
3
4
5
// 寄存器内部转发
assign RD1 = (A1 == 5'b00000) ? 32'h0000_0000 :
(A3 == A1 && A1 != 5'b00000) ? WD : grf[A1];
assign RD2 = (A2 == 5'b00000) ? 32'h0000_0000 :
(A3 == A2 && A2 != 5'b00000) ? WD : grf[A2];

D级转发处理

1
2
3
4
5
6
7
8
9
10
//D级写回数据
assign D_FWD_rs_data = (D_rs_addr == 0) ? 0 :
(D_rs_addr == E_A3) ? E_WD :
(D_rs_addr == M_A3) ? M_WD :
D_rs;

assign D_FWD_rt_data = (D_rt_addr == 0) ? 0 :
(D_rt_addr == E_A3) ? E_WD :
(D_rt_addr == M_A3) ? M_WD :
D_rt;

E级转发处理

1
2
3
4
5
6
7
8
9
10
//转发
assign E_FWD_rs_data = (E_rs_addr == 0) ? 0 :
(E_rs_addr == M_A3) ? M_WD :
(E_rs_addr == W_A3) ? W_WD :
E_rs;

assign E_FWD_rt_data = (E_rt_addr == 0) ? 0 :
(E_rt_addr == M_A3) ? M_WD :
(E_rt_addr == W_A3) ? W_WD :
E_rt;

M级转发处理

1
2
3
4
5
6
7
8
//转发
assign M_FWD_rt_data = (M_rt_addr == 0) ? 0 :
(M_rt_addr == W_A3) ? W_WD :
M_rt;

assign M_WD = (M_WDSel == `WDSel_PC8) ? M_PC + 8 :
(M_WDSel == `WDSel_ALUout) ? M_ALU_Out :
32'bz;

阻塞(Stall)

对于阻塞的处理,直接采用教程中的AT方法,设计一个 Stall 模块,专门负责处理阻塞时流水线寄存器的 flushWE 信号就行

只在 D 级进行阻塞,阻塞控制器接受当前 D,E,M 级的指令输入,处理分析指令类别,算出当前D的Tuse,和E、M的Tnew,再进行相应的计算

代码实现:

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
//阻塞逻辑

wire E_stall_rs = ((E_A3 == D_rs_ad) && (D_rs_ad != 0)) && (E_Tnew > D_Tuse_rs);
wire E_stall_rt = ((E_A3 == D_rt_ad) && (D_rt_ad != 0)) && (E_Tnew > D_Tuse_rt);

wire M_stall_rs = ((M_A3 == D_rs_ad) && (D_rs_ad != 0)) && (M_Tnew > D_Tuse_rs);
wire M_stall_rt = ((M_A3 == D_rt_ad) && (D_rt_ad != 0)) && (M_Tnew > D_Tuse_rt);

assign Stall = E_stall_rs | E_stall_rt | M_stall_rs | M_stall_rt;



//清空当前指令信号,即插入nop
wire FD_Flush, DE_Flush, EM_Flush, MW_Flush;

assign FD_WE = !Stall; //不再进新指令
assign DE_WE = 1'b1;
assign EM_WE = 1'b1;
assign MW_WE = 1'b1;

assign PC_WE = !Stall;

assign FD_Flush = 1'b0;
assign DE_Flush = Stall; //阻塞到D级,清空DE寄存器
assign EM_Flush = 1'b0;
assign MW_Flush = 1'b0;

测试方案:

先进行弱测,即跑完了提交窗口的测试数据,没有问题。

单条指令功能测试:

ori测试:

1
2
3
4
ori $t0, $t0, 1
ori $t1, $t1, 0
ori $t3, $t3, 0x7fff
ori $t4, $t3, 0xffff

add测试:

1
2
3
4
ori $t0, $t0, 2
ori $t1, $t1, 0xffff
add $t2, $t0, $t0
add $t3, $t1, $t1

sub测试:

1
2
3
4
5
6
ori $t0, $t0, 2
ori $t1, $t1, 0xffff
sub $t2, $t0, $t0
sub $t3, $t1, $t1
sub $t4, $t1, $t0
sub $t4, $t0, $t1

lui测试:

1
2
lui $t0, 0x7fff
ori $t0, $t0, 0x777f

beq测试:

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
#三次跳转
ori $t3, $t4, 1
beq $3, $t0, A
ori $t1, $t1, 0xffff
A:
beq $0, $t0, B
lui $t1, 0xffff
C:
ori $t1, $t1, 1
lui $t0, 1
B:
beq $t0, $0, C
lui $t2, 0xffff
//后跳
beq $t3, $t0, A
ori $t1, $t1, 0xffff
ori $t2, $t2, 0xffff
A:
lui $t1, 0xffff
//不跳
beq $3, $t0, A
nop
A:
beq $0, $t0, B
nop
C:
lui $t0, 1
B:
beq $t0, $0, C
nop
//前跳
beq $3, $t0, A
nop
B:
lui $t0, 1
A:
beq $0, $t0, B
nop

j,jal,jr测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
jal A
ori $s1, $s1, 0x1111
add $ra, $ra, $t2
ori $s1, $s1, 0x2222
A:
lui $t1, 200

jal A
ori $t0, $t0, 0x1111
sub $t1, $t1, $t0
ori $t2, $t2, 0x1111
beq $t2, $t2, B
nop
A:
jr $ra
add $t3, $t0, $t0
B:

sw,lw测试:

1
2
3
4
5
6
7
8
9
ori $t0, $t0, 4 #t0 = 4
add $t1, $t0, $t0 # t1 = 8
sub $t2, $t0, $t1 # t2 = -4
add $t3, $t2, $t2 #t3 = -8
sub $t4, $t0, $t3 #t4 = c
sw $t4, 16($t4) # add = 1c
sw $t3, -4($t1) # add = 4
lw $t5, 16($t4)
lw $t6, -4($t1)

之后对于各种边界情况和转发阻塞情况,进行覆盖测试:

提供一组超强测样例:

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
.text
init_1:j init_44
lui $0, 58479
init_2:j init_61
lui $26, 40699
init_3:nop
j init_26
ori $29, 12340
init_4:j init_21
lui $9, 18793
init_5:nop
j init_9
ori $13, 19610
init_6:j init_38
ori $28, 17819
init_7:nop
j init_37
ori $27, 17810
init_8:j init_48
ori $14, 1324
init_9:j init_8
lui $14, 20958
init_10:j init_31
lui $4, 28505
init_11:nop
j init_13
ori $23, 24263
init_12:j init_16
ori $12, 2525
init_13:j init_62
lui $24, 49213
init_14:j init_59
ori $6, 27235
init_15:j init_52
ori $16, 28030
init_16:j init_5
lui $13, 39021
init_17:j init_23
lui $20, 45636
init_18:nop
j init_57
ori $7, 34738
init_19:j init_56
lui $22, 48232
init_20:j init_7
lui $27, 21269
init_21:nop
j init_24
ori $9, 60940
init_22:j init_47
lui $19, 24579
init_23:j init_53
ori $20, 23617
init_24:j init_27
lui $10, 4700
init_25:nop
j init_60
ori $5, 25135
init_26:j init_34
lui $30, 14559
init_27:j init_29
ori $10, 45253
init_28:j init_12
lui $12, 55820
init_29:j init_36
lui $11, 49875
init_30:j init_25
lui $5, 35220
init_31:j init_30
ori $4, 7615
init_32:j begin
lui $31, 60984
init_33:j init_43
ori $2, 18084
init_34:j init_63
ori $30, 41019
init_35:j init_15
lui $16, 54272
init_36:nop
j init_28
ori $11, 2111
init_37:j init_6
lui $28, 33755
init_38:j init_3
lui $29, 26291
init_39:nop
j init_2
ori $25, 48740
init_40:j init_42
lui $1, 43965
init_41:nop
j init_19
ori $21, 27953
init_42:nop
j init_50
ori $1, 18337
init_43:j init_54
lui $3, 36555
init_44:j init_40
ori $0, 39840
init_45:j init_22
ori $18, 28396
init_46:j init_4
ori $8, 13173
init_47:nop
j init_17
ori $19, 60189
init_48:j init_49
lui $15, 28446
init_49:nop
j init_35
ori $15, 43996
init_50:j init_33
lui $2, 50534
init_51:j init_45
lui $18, 47692
init_52:j init_58
lui $17, 18098
init_53:j init_41
lui $21, 23125
init_54:nop
j init_10
ori $3, 34935
init_55:j init_39
lui $25, 37200
init_56:j init_64
ori $22, 41245
init_57:j init_46
lui $8, 16690
init_58:nop
j init_51
ori $17, 23659
init_59:j init_18
lui $7, 16431
init_60:j init_14
lui $6, 20586
init_61:j init_20
ori $26, 21724
init_62:j init_55
ori $24, 64211
init_63:j init_32
lui $31, 32491
init_64:j init_11
lui $23, 36591
begin:
ori $11, $11, 39941
sw $11, 0($0)
ori $22, $22, 13378
nop
sw $22, 4($0)
addu $8, $31, $16
nop
nop
sw $8, 8($0)
subu $20, $16, $6
sw $20, 12($0)
addu $9, $15, $7
nop
sw $9, 16($0)
addu $19, $23, $27
nop
nop
sw $19, 20($0)
subu $5, $1, $31
sw $5, 24($0)
addu $22, $6, $26
nop
sw $22, 28($0)
addu $10, $4, $18
nop
nop
sw $10, 32($0)
subu $19, $3, $0
sw $19, 36($0)
subu $22, $24, $1
nop
sw $22, 40($0)
subu $19, $10, $14
nop
nop
sw $19, 44($0)
subu $0, $19, $15
sw $0, 48($0)
ori $21, $21, 728
nop
sw $21, 52($0)
subu $13, $29, $4
nop
nop
sw $13, 56($0)
addu $11, $3, $1
sw $11, 60($0)
addu $27, $19, $11
nop
sw $27, 64($0)
addu $27, $16, $28
nop
nop
sw $27, 68($0)
ori $25, $25, 7272
sw $25, 72($0)
ori $31, $31, 65375
nop
sw $31, 76($0)
ori $13, $13, 65318
nop
nop
sw $13, 80($0)
ori $5, $5, 27677
sw $5, 84($0)
ori $13, $13, 30209
nop
sw $13, 88($0)
subu $16, $28, $20
nop
nop
sw $16, 92($0)
addu $6, $16, $21
sw $6, 96($0)
subu $22, $11, $31
nop
sw $22, 100($0)
subu $25, $23, $19
nop
nop
sw $25, 104($0)
ori $0, $0, 8927
sw $0, 108($0)
ori $24, $24, 21563
nop
sw $24, 112($0)
addu $13, $16, $11
nop
nop
sw $13, 116($0)
subu $14, $12, $27
sw $14, 120($0)
addu $15, $24, $27
nop
sw $15, 124($0)
subu $20, $1, $24
nop
nop
sw $20, 128($0)
subu $13, $28, $15
sw $13, 132($0)
ori $28, $28, 56842
nop
sw $28, 136($0)
addu $31, $6, $23
nop
nop
sw $31, 140($0)
ori $10, $10, 11112
sw $10, 144($0)
addu $21, $23, $9
nop
sw $21, 148($0)
subu $22, $16, $29
nop
nop
sw $22, 152($0)
addu $16, $1, $31
sw $16, 156($0)
subu $12, $15, $28
nop
sw $12, 160($0)
addu $6, $10, $22
nop
nop
sw $6, 164($0)
ori $12, $12, 14691
sw $12, 168($0)
ori $16, $16, 34145
nop
sw $16, 172($0)
ori $11, $11, 18551
nop
nop
sw $11, 176($0)
sw $sp, 180($0)
sw $ra, 184($0)
sw $at, 188($0)
ori $sp, $0, 4060
ori $1, $0, 32
jal foo1
nop
lui $1, 0
ori $1, 0
beq $1, $0, skip_manual1
nop
j dl
nop
skip_manual1:
lui $1, 10994
lui $2, 10994
beq $1, $2, skip_manual2
nop
j dl
nop
skip_manual2:
lui $3, 10995
nop
nop
beq $1, $3, dl
addu $4, $4, $3
lui $1, 0x6183
addu $2, $2, $1
lui $5, 0x8124
addu $4, $5, $1
subu $6, $6, $5
jal skip_manual3
nop
sw $0, 4($0)
skip_manual3:
sw $7, -0x3000($ra)
lw $ra, -0x3000($ra)
ori $ra, $0, 0
jal skip_manual4
nop
sw $0, 8($0)
skip_manual4:
beq $ra, $0, dl
nop
ori $ra, $0, 0
jal skip_manual5
nop
sw $ra, 12($0)
skip_manual5:
nop
beq $ra, $0, dl
nop
ori $4, $0, 4
ori $5, $0, 5
ori $1, $0, 1
addu $4, $4, $1
nop
nop
beq $4, $5, skip_manual6
nop
sw $0, 16($0)
skip_manual6:
ori $1, $0, 1
ori $2, $0, 2
ori $3, $0, 3
ori $4, $0, 4
ori $5, $0, 6
ori $6, $0, 5
subu $5, $5, $1
addu $6, $2, $1
beq $5, $6, dl
nop
jal skip_manual8
nop
skip_manual8:
addu $3, $3, $ra
subu $4, $4, $ra
jal foo
nop
jal fooo
nop
jal foooo
nop
jal fooooo
nop
sw $0, 192($0)
sw $1, 196($0)
sw $2, 200($0)
sw $3, 204($0)
sw $4, 208($0)
sw $5, 212($0)
sw $6, 216($0)
sw $7, 220($0)
sw $8, 224($0)
sw $9, 228($0)
sw $10, 232($0)
sw $11, 236($0)
sw $12, 240($0)
sw $13, 244($0)
sw $14, 248($0)
sw $15, 252($0)
sw $16, 256($0)
sw $17, 260($0)
sw $18, 264($0)
sw $19, 268($0)
sw $20, 272($0)
sw $21, 276($0)
sw $22, 280($0)
sw $23, 284($0)
sw $24, 288($0)
sw $25, 292($0)
sw $26, 296($0)
sw $27, 300($0)
sw $28, 304($0)
sw $29, 308($0)
sw $30, 312($0)
sw $31, 316($0)
lui $31, 63605
jal tag_0
nop
ori $ra, $0, 2
tag_0:sw $ra, 320($0)
addu $14, $13, $7
jal tag_1
nop
ori $ra, $0, 2
tag_1:sw $ra, 324($0)
lw $25, 12($0)
jal tag_2
nop
ori $ra, $0, 2
tag_2:sw $ra, 328($0)
lui $29, 14949
nop
jal tag_3
nop
ori $ra, $0, 2
tag_3:sw $ra, 332($0)
addu $10, $24, $1
nop
jal tag_4
nop
ori $ra, $0, 2
tag_4:sw $ra, 336($0)
lw $12, 164($0)
nop
jal tag_5
nop
ori $ra, $0, 2
tag_5:sw $ra, 340($0)
lui $31, 58593
nop
nop
jal tag_6
nop
ori $ra, $0, 2
tag_6:sw $ra, 344($0)
addu $1, $7, $12
nop
nop
jal tag_7
nop
ori $ra, $0, 2
tag_7:sw $ra, 348($0)
lw $20, 256($0)
nop
nop
jal tag_8
nop
ori $ra, $0, 2
tag_8:sw $ra, 352($0)
lui $17, 19367
jal tag_9
nop
ori $ra, $0, 2
tag_9:sw $ra, 356($0)
addu $8, $11, $11
jal tag_10
nop
ori $ra, $0, 2
tag_10:sw $ra, 360($0)
lw $1, 132($0)
jal tag_11
nop
ori $ra, $0, 2
tag_11:sw $ra, 364($0)
lui $18, 56313
nop
jal tag_12
nop
ori $ra, $0, 2
tag_12:sw $ra, 368($0)
addu $23, $25, $24
nop
jal tag_13
nop
ori $ra, $0, 2
tag_13:sw $ra, 372($0)
lw $20, 368($0)
nop
jal tag_14
nop
ori $ra, $0, 2
tag_14:sw $ra, 376($0)
lui $21, 22951
nop
nop
jal tag_15
nop
ori $ra, $0, 2
tag_15:sw $ra, 380($0)
addu $8, $10, $1
nop
nop
jal tag_16
nop
ori $ra, $0, 2
tag_16:sw $ra, 384($0)
lw $4, 88($0)
nop
nop
jal tag_17
nop
ori $ra, $0, 2
tag_17:sw $ra, 388($0)
ori $4, $0, 12
jal skip_manual7
nop
skip_manual7:
addu $ra, $ra, $4
jr $ra
ori $4, $0, 8
addu $ra, $ra, $4
nop
jr $ra
nop
dl:addu $ra, $0, $0
beq $0, $0, dl
nop
foo: jr $ra
ori $ra, $ra, 0xff
fooo: ori $6, $ra, 0xa
jr $ra
nop
foooo: jr $ra
ori $t8, $ra, 0xff
fooooo: ori $t9, $ra, 0xa
jr $ra
nop
foo1:
sw $a0, 0($sp)
sw $ra, 16($sp)
sw $a1, 4($sp)
sw $a2, 8($sp)
sw $a3, 12($sp)
sw $t0, 20($sp)
sw $t1, 24($sp)
sw $t2, 28($sp)
ori $s1, $0, 84
ori $s2, $0, 220
lw $t0, -40($s1)
lw $t1, -88($s2)
addu $a3, $t0, $t1
addu $a0, $a0, $t0
addu $a1, $a1, $t1
addu $t2, $a0, $a1
ori $a0, $t2, 11072
addu $t2, $t2, $t2
addu $t2, $t2, $t2
ori $a1, $t2, 30986
ori $a2, $a1, 0xf0
nop
beq $a2, $a1, skip1
nop
jal foo2
subu $sp, $sp, $1
skip1: lw $a3, 16($sp)
addu $sp, $sp, $1
nop
jr $a3
nop
foo2:
sw $a0, 0($sp)
sw $a1, 4($sp)
sw $ra, 16($sp)
sw $a2, 8($sp)
sw $a3, 12($sp)
sw $t0, 20($sp)
sw $t1, 24($sp)
sw $t2, 28($sp)
ori $s1, $0, 152
ori $s2, $0, 54
lw $t1, 326($s2)
lw $t0, 160($s1)
addu $a3, $t0, $t1
addu $a0, $a0, $t0
addu $a1, $a1, $t1
addu $t2, $a0, $a1
ori $a0, $t2, 21109
addu $t2, $t2, $t2
addu $t2, $t2, $t2
ori $a1, $t2, 60683
ori $a2, $a1, 0xf0
beq $a2, $a1, skip2
nop
jal foo3
subu $sp, $sp, $1
skip2: lw $a3, 16($sp)
jr $a3
addu $sp, $sp, $1
foo3:
sw $ra, 16($sp)
sw $a0, 0($sp)
sw $a1, 4($sp)
sw $a2, 8($sp)
sw $a3, 12($sp)
sw $t0, 20($sp)
sw $t1, 24($sp)
sw $t2, 28($sp)
ori $s1, $0, 139
ori $s2, $0, 302
lw $t0, -35($s1)
lw $t1, -34($s2)
addu $a3, $t0, $t1
addu $a0, $a0, $t0
addu $a1, $a1, $t1
addu $t2, $a0, $a1
ori $a0, $t2, 29202
addu $t2, $t2, $t2
addu $t2, $t2, $t2
ori $a1, $t2, 43269
ori $a2, $a1, 0xf0
nop
beq $a2, $a1, skip3
nop
jal foo13
subu $sp, $sp, $1
skip3: lw $a3, 16($sp)
addu $sp, $sp, $1
jr $a3
nop
foo4:
sw $a0, 0($sp)
sw $ra, 16($sp)
sw $a1, 4($sp)
sw $a2, 8($sp)
sw $a3, 12($sp)
sw $t0, 20($sp)
sw $t1, 24($sp)
sw $t2, 28($sp)
ori $s1, $0, 297
ori $s2, $0, 96
lw $t1, 104($s2)
lw $t0, -197($s1)
addu $a3, $t0, $t1
addu $a0, $a0, $t0
addu $a1, $a1, $t1
addu $t2, $a0, $a1
ori $a0, $t2, 14171
addu $t2, $t2, $t2
addu $t2, $t2, $t2
ori $a1, $t2, 18179
ori $a2, $a1, 0xf0
beq $a2, $a1, skip4
nop
jal foo11
subu $sp, $sp, $1
skip4: lw $a3, 16($sp)
addu $sp, $sp, $1
nop
jr $a3
nop
foo5:
sw $a0, 0($sp)
sw $a1, 4($sp)
sw $ra, 16($sp)
sw $a2, 8($sp)
sw $a3, 12($sp)
sw $t0, 20($sp)
sw $t1, 24($sp)
sw $t2, 28($sp)
ori $s1, $0, 106
ori $s2, $0, 190
lw $t0, -26($s1)
lw $t1, -82($s2)
addu $a3, $t0, $t1
addu $a0, $a0, $t0
addu $a1, $a1, $t1
addu $t2, $a0, $a1
ori $a0, $t2, 49045
addu $t2, $t2, $t2
addu $t2, $t2, $t2
ori $a1, $t2, 36619
ori $a2, $a1, 0xf0
nop
beq $a2, $a1, skip5
nop
jal foo1
subu $sp, $sp, $1
skip5: lw $a3, 16($sp)
jr $a3
addu $sp, $sp, $1
foo6:
sw $ra, 16($sp)
sw $a0, 0($sp)
sw $a1, 4($sp)
sw $a2, 8($sp)
sw $a3, 12($sp)
sw $t0, 20($sp)
sw $t1, 24($sp)
sw $t2, 28($sp)
ori $s1, $0, 345
ori $s2, $0, 52
lw $t1, -32($s2)
lw $t0, 15($s1)
addu $a3, $t0, $t1
addu $a0, $a0, $t0
addu $a1, $a1, $t1
addu $t2, $a0, $a1
ori $a0, $t2, 25874
addu $t2, $t2, $t2
addu $t2, $t2, $t2
ori $a1, $t2, 45316
ori $a2, $a1, 0xf0
beq $a2, $a1, skip6
nop
jal foo4
subu $sp, $sp, $1
skip6: lw $a3, 16($sp)
addu $sp, $sp, $1
jr $a3
nop
foo7:
sw $a0, 0($sp)
sw $ra, 16($sp)
sw $a1, 4($sp)
sw $a2, 8($sp)
sw $a3, 12($sp)
sw $t0, 20($sp)
sw $t1, 24($sp)
sw $t2, 28($sp)
ori $s1, $0, 319
ori $s2, $0, 212
lw $t0, -167($s1)
lw $t1, 120($s2)
addu $a3, $t0, $t1
addu $a0, $a0, $t0
addu $a1, $a1, $t1
addu $t2, $a0, $a1
ori $a0, $t2, 44079
addu $t2, $t2, $t2
addu $t2, $t2, $t2
ori $a1, $t2, 38407
ori $a2, $a1, 0xf0
nop
beq $a2, $a1, skip7
nop
jal foo10
subu $sp, $sp, $1
skip7: lw $a3, 16($sp)
addu $sp, $sp, $1
nop
jr $a3
nop
foo8:
sw $a0, 0($sp)
sw $a1, 4($sp)
sw $ra, 16($sp)
sw $a2, 8($sp)
sw $a3, 12($sp)
sw $t0, 20($sp)
sw $t1, 24($sp)
sw $t2, 28($sp)
ori $s1, $0, 366
ori $s2, $0, 244
lw $t1, -116($s2)
lw $t0, -290($s1)
addu $a3, $t0, $t1
addu $a0, $a0, $t0
addu $a1, $a1, $t1
addu $t2, $a0, $a1
ori $a0, $t2, 20552
addu $t2, $t2, $t2
addu $t2, $t2, $t2
ori $a1, $t2, 22025
ori $a2, $a1, 0xf0
beq $a2, $a1, skip8
nop
jal foo5
subu $sp, $sp, $1
skip8: lw $a3, 16($sp)
jr $a3
addu $sp, $sp, $1
foo9:
sw $ra, 16($sp)
sw $a0, 0($sp)
sw $a1, 4($sp)
sw $a2, 8($sp)
sw $a3, 12($sp)
sw $t0, 20($sp)
sw $t1, 24($sp)
sw $t2, 28($sp)
ori $s1, $0, 223
ori $s2, $0, 283
lw $t0, 13($s1)
lw $t1, -27($s2)
addu $a3, $t0, $t1
addu $a0, $a0, $t0
addu $a1, $a1, $t1
addu $t2, $a0, $a1
ori $a0, $t2, 28872
addu $t2, $t2, $t2
addu $t2, $t2, $t2
ori $a1, $t2, 52993
ori $a2, $a1, 0xf0
nop
beq $a2, $a1, skip9
nop
jal foo15
subu $sp, $sp, $1
skip9: lw $a3, 16($sp)
addu $sp, $sp, $1
jr $a3
nop
foo10:
sw $a0, 0($sp)
sw $ra, 16($sp)
sw $a1, 4($sp)
sw $a2, 8($sp)
sw $a3, 12($sp)
sw $t0, 20($sp)
sw $t1, 24($sp)
sw $t2, 28($sp)
ori $s1, $0, 228
ori $s2, $0, 255
lw $t1, -155($s2)
lw $t0, 12($s1)
addu $a3, $t0, $t1
addu $a0, $a0, $t0
addu $a1, $a1, $t1
addu $t2, $a0, $a1
ori $a0, $t2, 56866
addu $t2, $t2, $t2
addu $t2, $t2, $t2
ori $a1, $t2, 21770
ori $a2, $a1, 0xf0
beq $a2, $a1, skip10
nop
jal foo12
subu $sp, $sp, $1
skip10: lw $a3, 16($sp)
addu $sp, $sp, $1
nop
jr $a3
nop
foo11:
sw $a0, 0($sp)
sw $a1, 4($sp)
sw $ra, 16($sp)
sw $a2, 8($sp)
sw $a3, 12($sp)
sw $t0, 20($sp)
sw $t1, 24($sp)
sw $t2, 28($sp)
ori $s1, $0, 54
ori $s2, $0, 306
lw $t0, 278($s1)
lw $t1, -238($s2)
addu $a3, $t0, $t1
addu $a0, $a0, $t0
addu $a1, $a1, $t1
addu $t2, $a0, $a1
ori $a0, $t2, 34513
addu $t2, $t2, $t2
addu $t2, $t2, $t2
ori $a1, $t2, 36103
ori $a2, $a1, 0xf0
nop
beq $a2, $a1, skip11
nop
jal foo8
subu $sp, $sp, $1
skip11: lw $a3, 16($sp)
jr $a3
addu $sp, $sp, $1
foo12:
sw $ra, 16($sp)
sw $a0, 0($sp)
sw $a1, 4($sp)
sw $a2, 8($sp)
sw $a3, 12($sp)
sw $t0, 20($sp)
sw $t1, 24($sp)
sw $t2, 28($sp)
ori $s1, $0, 248
ori $s2, $0, 72
lw $t1, 152($s2)
lw $t0, 76($s1)
addu $a3, $t0, $t1
addu $a0, $a0, $t0
addu $a1, $a1, $t1
addu $t2, $a0, $a1
ori $a0, $t2, 1104
addu $t2, $t2, $t2
addu $t2, $t2, $t2
ori $a1, $t2, 24322
ori $a2, $a1, 0xf0
beq $a2, $a1, skip12
nop
jal foo9
subu $sp, $sp, $1
skip12: lw $a3, 16($sp)
addu $sp, $sp, $1
jr $a3
nop
foo13:
sw $a0, 0($sp)
sw $ra, 16($sp)
sw $a1, 4($sp)
sw $a2, 8($sp)
sw $a3, 12($sp)
sw $t0, 20($sp)
sw $t1, 24($sp)
sw $t2, 28($sp)
ori $s1, $0, 386
ori $s2, $0, 194
lw $t0, -82($s1)
lw $t1, -142($s2)
addu $a3, $t0, $t1
addu $a0, $a0, $t0
addu $a1, $a1, $t1
addu $t2, $a0, $a1
ori $a0, $t2, 18477
addu $t2, $t2, $t2
addu $t2, $t2, $t2
ori $a1, $t2, 2816
ori $a2, $a1, 0xf0
nop
beq $a2, $a1, skip13
nop
jal foo7
subu $sp, $sp, $1
skip13: lw $a3, 16($sp)
addu $sp, $sp, $1
nop
jr $a3
nop
foo14:
sw $a0, 0($sp)
sw $a1, 4($sp)
sw $ra, 16($sp)
sw $a2, 8($sp)
sw $a3, 12($sp)
sw $t0, 20($sp)
sw $t1, 24($sp)
sw $t2, 28($sp)
ori $s1, $0, 184
ori $s2, $0, 255
lw $t1, 13($s2)
lw $t0, -88($s1)
addu $a3, $t0, $t1
addu $a0, $a0, $t0
addu $a1, $a1, $t1
addu $t2, $a0, $a1
ori $a0, $t2, 26871
addu $t2, $t2, $t2
addu $t2, $t2, $t2
ori $a1, $t2, 23821
ori $a2, $a1, 0xf0
beq $a2, $a1, skip14
nop
jal foo16
subu $sp, $sp, $1
skip14: lw $a3, 16($sp)
jr $a3
addu $sp, $sp, $1
foo15:
sw $ra, 16($sp)
sw $a0, 0($sp)
sw $a1, 4($sp)
sw $a2, 8($sp)
sw $a3, 12($sp)
sw $t0, 20($sp)
sw $t1, 24($sp)
sw $t2, 28($sp)
ori $s1, $0, 264
ori $s2, $0, 366
lw $t0, -212($s1)
lw $t1, -2($s2)
addu $a3, $t0, $t1
addu $a0, $a0, $t0
addu $a1, $a1, $t1
addu $t2, $a0, $a1
ori $a0, $t2, 36680
addu $t2, $t2, $t2
addu $t2, $t2, $t2
ori $a1, $t2, 1289
ori $a2, $a1, 0xf0
nop
beq $a2, $a1, skip15
nop
jal foo14
subu $sp, $sp, $1
skip15: lw $a3, 16($sp)
addu $sp, $sp, $1
jr $a3
nop
foo16:
sw $a0, 0($sp)
sw $ra, 16($sp)
sw $a1, 4($sp)
sw $a2, 8($sp)
sw $a3, 12($sp)
sw $t0, 20($sp)
sw $t1, 24($sp)
sw $t2, 28($sp)
ori $s1, $0, 39
ori $s2, $0, 301
lw $t1, -17($s2)
lw $t0, 317($s1)
addu $a3, $t0, $t1
addu $a0, $a0, $t0
addu $a1, $a1, $t1
addu $t2, $a0, $a1
ori $a0, $t2, 706
addu $t2, $t2, $t2
addu $t2, $t2, $t2
ori $a1, $t2, 2561
ori $a2, $a1, 0xf0
beq $a2, $a1, skip16
nop
jal foo6
subu $sp, $sp, $1
skip16: lw $a3, 16($sp)
addu $sp, $sp, $1
nop
jr $a3
nop

对拍输出一致或许对吧……


思考题

  1. 我们使用提前分支判断的方法尽早产生结果来减少因不确定而带来的开销,但实际上这种方法并非总能提高效率,请从流水线冒险的角度思考其原因并给出一个指令序列的例子。

    在回答这个问题之前,我们需要知道,在原本的设计中,beq的分支结果应该在E级产生,现在改在D级产生,这就造成了如下所示的问题:

    1
    2
    3
    lw    $t0, 0($0)
    nop
    beq $t1, $t0, label

    原本的设计中,beq在E级,lw在W级,正好转发就可以给到新生成的$t0的值,而现在,beq在D级就要新的$t0的值,来不及转发,被迫暂停了,效率降低。

  2. 因为延迟槽的存在,对于 jal 等需要将指令地址写入寄存器的指令,要写回 PC + 8,请思考为什么这样设计?

    因为延迟槽的存在,跳转指令的后一条必然会执行,所以需要把PC+8写入寄存器,不然jr后延迟槽内的指令又会再执行一次

  3. 我们要求所有转发数据都来源于流水寄存器而不能是功能部件(如 DM、ALU),请思考为什么?

    不妨举一个例子,假设这是各个阶段的时间:

    F D E M W
    50 100 100 150 100

    如果此时D阶段需要E的ALU计算的结果,假设数据刚进入D和E级(即刚刚有效沿到来),我们要ALUOut,所以需要100s等待其出结果,然后过了100s后结果出来了,可以转发给D级了,但是此时还没完,D拿到了这个数据,需要对其进行处理,所以又花了100s。也就是说,为了保证正确性,我们的周期最少是200s,而其实150s就够了(即最大周期M级——150s)。只是因为我们进行了这个错误的设计。

  4. 我们为什么要使用 GPR 内部转发?该如何实现?

    为了保持W级的写入和此时D级的读出是同一个值,规避数据冒险。

    代码实现:

    1
    2
    3
    4
    5
    // 寄存器内部转发
    assign RD1 = (A1 == 5'b00000) ? 32'h0000_0000 :
    (A3 == A1 && A1 != 5'b00000) ? WD : grf[A1];
    assign RD2 = (A2 == 5'b00000) ? 32'h0000_0000 :
    (A3 == A2 && A2 != 5'b00000) ? WD : grf[A2];
  5. 我们转发时数据的需求者和供给者可能来源于哪些位置?共有哪些转发数据通路?

    详见前文转发实现部分

  6. 在课上测试时,我们需要你现场实现新的指令,对于这些新的指令,你可能需要在原有的数据通路上做哪些扩展或修改?提示:你可以对指令进行分类,思考每一类指令可能修改或扩展哪些位置。

    • 高内聚低耦合原理:大多数只需要改变控制信号以及相应的功能模块增加功能,但不排除某些需要修改mips.v内的数据通路
    • 对于计算类:首先改变CTRL,添加相关的wire,注意每个指令的控制信号的对应,之后就直接修改ALU就行了。
    • 对于访存类:改变CTRL,并修改DM增加相应的功能,改变DMOp,并且在mips.v的顶层模块内增添相应控制信号。
    • 对于跳转类:修改CTRL,并在CMP内增添相应功能,同时根据链接条件增添相应check信号。
  7. 简要描述你的译码器架构,并思考该架构的优势以及不足。

    我采用了分布式译码;

    优势当然是实现更加容易实现,不需要考察每一级具体要保留和传递哪些译码上的信息,实现起来比较容易,并且进行增量开发更加容易。

    缺点当然是对于资源浪费严重,而且需要实例化的端口太多了,容易编译错误,而且导线太多,容易犯些隐蔽的错误!!!

    主观上来说,我觉得分布式译码就是一个赖子办法,不具备设计上的美感,集中式译码才能体现对于流水线的理解和设计的能力,奈何我不具备,只好用分布式了……

RooKie_Z P5 Verilog流水线CPU设计文档

https://rookie-zgy1513.github.io/2025/08/10/P5-CPU/

作者

RooKie_Z

发布于

2025-08-10

更新于

2025-08-16

许可协议

评论