P6流水线CPU设计文档
设计整体概述
预计实现指令集 :
add、sub、and、or、nor、xor、slt、sltu、
ori、Lui、addi、andi、
lw、lh、lhu、lb、lbu、sw、sh、sb、
mult、multu、div、divu、mfhi、mflo、mthi、mtlo、
beq、bne、nop、j、jr、jal、jalr
R型指令:add、sub、and、or、nor、xor、slt、sltu、
opcode
rs
rt
rd
shamt
funct
6
5
5
5
5
6
I型指令:lui、ori、andi、addi、lw、lh、lhu、lb、lbu、sw、sh、sb、beq、bne、
opcode
rs
rt
offset
6
5
5
16
乘除器操作指令:mult、multu、div、divu、mfhi、mflo、mthi、mtlo
其中,nop指令为空指令,不执行任何操作,add、sub不考虑溢出,故实际执行addu和subu
实现功能 :实现五级流水线CPU,通过F、D、E、M、W五个阶段实现指令的执行,其中F阶段为取指,D阶段为译码,E阶段为执行,M阶段为访存,W阶段为写回,各阶段均通过流水线寄存器实现流水线操作,通过转发和阻塞机制解决冒险问题。
顶层设计图 :
整体架构参考了PPT上的设计
命名格式 :模块命名采用所在级_模块名
方式,模块内部信号名采取来源_功能
方式命名,顶层信号采用所在级_模块名_信号名
方式命名。
数据通路模块设计
在采取IM与DM外置后,数据设计模块相较P5有了一定的变化,同时增加BE与DE模块,满足修改后的内存存取要求,增加了乘除器模块,用于实现乘除法相关指令。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 module mips ( input wire [0 :0 ] clk, input wire [0 :0 ] reset, input wire [31 :0 ] i_inst_rdata, input wire [31 :0 ] m_data_rdata, output wire [31 :0 ] i_inst_addr, output wire [31 :0 ] m_data_addr, output wire [31 :0 ] m_data_wdata, output wire [3 :0 ] m_data_byteen, output wire [31 :0 ] m_inst_addr, output wire [0 :0 ] w_grf_we, output wire [4 :0 ] w_grf_addr, output wire [31 :0 ] w_grf_wdata, output wire [31 :0 ] w_inst_addr ); endmodule ;
F级:取指Fetch
F_IFU 指令单元
定义 :模块内部包含PC
程序计数器、IM
指令存储器以在外部实现,因此只负责根据NPC
传入的PC值,依照控制信号选择PC值。
端口定义
信号名
方向
位宽
说明
D_Next_PC
I
32
NPC
模块输出的下一条指令地址
clk
I
1
时钟信号
reset
I
1
复位信号
stop
I
1
停机信号
F_PC
O
32
输出F级PC值,流入D级寄存器
F_PC8
O
32
PC
加8的值,用于分支延迟槽指令
实现从文件中读取指令的功能
2. 实现功能
序号
功能
描述
1
同步复位
当reset
信号为1且处于时钟上升沿时,PC
置0x00003000
2
停机
当stop信号为1时,PC
和指令保持不变
3
取指
当stop信号为0时,在clk上升沿得到的下一条指令地址PC,传入顶层模块到i_inst_addr读取指令
PC
初始化为0x00003000
外接IM具体实现
1 2 assign i_inst_addr = F_PC;assign F_Instr = i_inst_rdata;
D级:译码decode
D_REG D级流水线寄存器
定义 :用于在时钟上升沿将F级的指令和PC值传递到D级,并在复位重置寄存器值,并在停机信号为1时保持不变
端口定义
信号名
方向
位宽
说明
clk
I
1
时钟信号
reset
I
1
复位信号
stall
I
1
停机信号
F_Instr
I
32
F级的32位指令
F_PC
I
32
F级的PC值
F_PC8
I
32
F级的PC+8值
D_Instr
O
32
D级的32位指令
D_PC
O
32
D级的PC值
D_PC8
O
32
D级的PC+8值
实现功能
序号
功能
描述
1
同步复位
当reset
信号为1且处于时钟上升沿时,D_Instr
置0,D_PC
置PC_Reset
,D_PC8
置PC_Reset + 4
2
停机
当stall
信号为1时,保持D_Instr
、D_PC
和D_PC8
的值不变
3
正常传递
当stall
信号为0时,在时钟上升沿将F_Instr
、F_PC
和F_PC8
的值传递到D_Instr
、D_PC
和D_PC8
D_NPC 指令计算单元
定义 :根据当前PC值、指令类型和条件分支结果,计算下一条指令的PC值。
端口定义
信号名
方向
位宽
说明
F_PC
I
32
当前指令的PC值
Instr_index
I
26
跳转指令的目标地址
offset
I
16
分支指令的偏移量
rs
I
32
寄存器rs的值
NPCSel
I
3
下一条指令PC选择信号
CMPOut
I
1
比较结果信号
D_Next_PC
O
32
计算得到的下一条指令的PC值
实现功能
序号
功能
描述
1
计算分支地址
根据当前PC值和偏移量计算分支指令的目标地址
2
计算跳转地址
根据当前PC值和指令索引计算跳转指令的目标地址
3
选择下一条指令PC
根据NPCSel信号选择下一条指令的PC值,支持顺序执行、分支、跳转和寄存器跳转
选择信号
位宽
数值
描述
BranchType
3
3’b011
B型跳转,与CMPOut共同决定跳转
JrType
3
3’b010
JR型跳转
JumpType
3
3’b001
J型跳转
D_EXT 指令扩展
定义 :根据控制信号,对输入的16位立即数进行零扩展或符号扩展。
端口定义
信号名
方向
位宽
说明
offset
I
16
16位立即数
ExtOp
I
1
扩展选择信号,0为零扩展,1为符号扩展
Extend
O
32
扩展后的32位立即数
实现功能
序号
功能
描述
1
符号扩展
当ExtOp
信号为1时,Extend
输出符号扩展后的32位立即数
2
零扩展
当ExtOp
信号为0时,Extend
输出零扩展后的32位立即数
D_CMP 比较器
定义 :根据控制信号,对输入的两个数进行比较,输出比较结果。
端口定义
信号名
方向
位宽
说明
RD1
I
32
读寄存器1数据
RD2
I
32
读寄存器2数据
CMPOp
I
3
比较操作选择信号
CMPOut
O
1
比较结果输出
实现功能
序号
功能
描述
1
相等比较
当CMPOp
信号为CMP_BEQ
时,若RD1
等于RD2
,CMPOut
输出1,否则输出0
2
不等比较
当CMPOp
信号为CMP_BNE
时,若RD1
不等于RD2
,CMPOut
输出1,否则输出0
3
小于等于零
当CMPOp
信号为CMP_BLEZ
时,若RD1
小于等于0,CMPOut
输出1,否则输出0
4
大于零
当CMPOp
信号为CMP_BGTZ
时,若RD1
大于0,CMPOut
输出1,否则输出0
GRF 寄存器堆
定义 :根据读写信号,对寄存器堆进行读写操作。
端口定义
信号名
方向
位宽
说明
A1
I
5
读寄存器1地址
A2
I
5
读寄存器2地址
RegAddr
I
5
写寄存器地址
RegData
I
32
写数据
clk
I
1
时钟信号
reset
I
1
复位信号
RegWrite
I
1
写使能信号
PC
I
32
当前PC地址,用于输出
RD1
O
32
读寄存器1数据
RD2
O
32
读寄存器2数据
输出寄存器堆中寄存器写入输出到官方mips_tb.v
,具体实现如下
1 2 3 4 assign w_grf_we = W_RegWrite;assign w_grf_addr = W_RegAddr;assign w_grf_wdata = W_RegData;assign w_inst_addr = W_PC;
实现功能
序号
功能
描述
1
复位
当reset为1时,将所有寄存器置为0
2
读
当RegWrite为0时,将A1、A2对应的寄存器数据输出到RD1、RD2
3
写
当RegWrite为1时,当RegAddr不为0时,在时钟上升沿将RegAddr对应的寄存器写入RegData
A1、A2分别读取Rs、Rt寄存器,RegAddress根据RegDst选择Rt或R),RegData根据MemRead选择ALU的运算结果或I型指令的立即数
内部转发
当RegWrite
为1时,若D级读取的寄存器和W级写入的寄存器相同且不为0,则将RegAddr
对应的寄存器的值输出到RD1
或RD2
。
1 2 3 4 assign RD1 = (A1 == RegAddr && RegWrite && RegAddr != 0 ) ? RegData : GRF_reg[A1]; assign RD2 = (A2 == RegAddr && RegWrite && RegAddr != 0 ) ? RegData : GRF_reg[A2];
E级:执行Execute
E_REG E级流水线寄存器
定义 :存储E级流水线寄存器的数据。
端口定义
信号名
方向
位宽
说明
clk
I
1
时钟信号
reset
I
1
复位信号
clr
I
1
清除信号
D_Instr
I
32
D级指令
D_PC
I
32
D级PC值
D_PC8
I
32
D级PC+8值
D_A1
I
5
D级寄存器地址1
D_A2
I
5
D级寄存器地址2
D_RD1
I
32
D级寄存器数据1
D_RD2
I
32
D级寄存器数据2
D_Rt
I
5
D级Rt寄存器地址
D_Rd
I
5
D级Rd寄存器地址
ALUOp_D
I
4
D级ALU操作码
D_Tnew
I
2
D级新指令周期
ALUBSrcSel_D
I
1
D级ALU B源选择信号
RegWrite_D
I
1
D级寄存器写使能信号
MemWrite_D
I
1
D级内存写使能信号
RegDataSel_D
I
3
D级寄存器数据选择信号
RegDstSel_D
I
3
D级寄存器目标选择信号
D_Extend
I
32
D级扩展数据
E_Instr
O
32
E级指令
E_PC
O
32
E级PC值
E_PC8
O
32
E级PC+8值
E_A1
O
5
E级寄存器地址1
E_A2
O
5
E级寄存器地址2
E_RD1
O
32
E级寄存器数据1
E_RD2
O
32
E级寄存器数据2
E_Rt
O
5
E级Rt寄存器地址
E_Rd
O
5
E级Rd寄存器地址
ALUOp_E
O
4
E级ALU操作码
E_Tnew
O
2
E级新指令周期
ALUBSrcSel_E
O
1
E级ALU B源选择信号
RegWrite_E
O
1
E级寄存器写使能信号
MemWrite_E
O
1
E级内存写使能信号
RegDataSel_E
O
3
E级寄存器数据选择信号
RegDstSel_E
O
3
E级寄存器目标选择信号
E_Extend
O
32
E级扩展数据
实现功能
序号
功能
描述
1
同步复位
当reset
信号为1或clr
信号为1时,所有输出信号清空,对于暂停操作而言相当于插入nop指令
2
正常传递
在时钟上升沿,将D级输入信号传递到E级输出信号
ALU 算术逻辑单元
定义 :根据控制信号,对输入的两个数进行算术或逻辑运算。
端口定义
信号名
方向
位宽
说明
A
I
32
输入操作数A
B
I
32
输入操作数B
ALU_Op
I
4
ALU操作码
ALU_Res
O
32
运算结果
实现功能
根据ALU_Op的值,对输入的A和B进行相应的算术或逻辑运算,并将结果输出到ALU_Res。
序号
功能
描述
1
ADD
A + B
2
SUB
A - B
3
AND
A & B
4
OR
A | B
5
XOR
A ^ B
6
LUI
加载到高位
7
XOR
A ^ B
8
NOR
~(A | B)
9
SLT
$signed (A) < $signed (B) ? 1 : 0 ,比较部分单独完成
10
SLTU
A < B ? 1 : 0
MDU 乘除单元
定义 :根据控制信号,对输入的两个数进行乘法或除法运算。
端口定义
信号名
方向
位宽
说明
A
I
32
输入操作数A
B
I
32
输入操作数B
MDUOp
I
4
MDU操作码
clk
I
1
时钟信号
reset
I
1
复位信号
start
I
1
开始状态信号
MDURes
O
32
运算结果
Hi
O
32
高位结果
Lo
O
32
低位结果
busy
O
1
忙状态信号
实现功能
根据MDUOp的值,对输入的A和B进行相应的乘法或除法运算,并将结果输出到Hi和Lo寄存器,同时输出忙信号表示运算状态。
序号
功能
描述
1
MULT
有符号乘法,结果存储在Hi和Lo中
2
MULTU
无符号乘法,结果存储在Hi和Lo中
3
DIV
有符号除法,商存储在Lo中,余数存储在Hi中
4
DIVU
无符号除法,商存储在Lo中,余数存储在Hi中
5
MTHI
将A的值存储到Hi中
6
MTLO
将A的值存储到Lo中
7
MFHI
将Hi的值输出到MDURes
8
MFLO
将Lo的值输出到MDURes
设置临时变量hitemp和loemp,分别存储Hi和Lo的值,根据计数逻辑在完成乘除运算后,将hitemp和loemp的值赋值给Hi和Lo。
M级:存储Memory
M_REG M级流水线寄存器
定义 :存储M级流水线寄存器的数据。
端口定义
信号名
方向
位宽
说明
clk
I
1
时钟信号
reset
I
1
复位信号
E_Instr
I
32
E级指令
E_PC
I
32
E级PC值
E_PC8
I
32
E级PC+8值
E_A1
I
5
E级寄存器地址1
E_A2
I
5
E级寄存器地址2
E_RegAddr
I
5
E级寄存器写地址
E_RD1
I
32
E级寄存器数据1
E_RD2
I
32
E级寄存器数据2
MemWrite_E
I
1
E级内存写使能信号
RegWrite_E
I
1
E级寄存器写使能信号
RegDataSel_E
I
3
E级寄存器数据选择信号
E_ALU_Res
I
32
E级ALU运算结果
E_MDURes
I
32
E级MDU运算结果
E_Tnew
I
2
E级新指令周期
E_ALU_Fwd_MUXOut
I
32
E级ALU转发MUX输出
M_Instr
O
32
M级指令
M_PC
O
32
M级PC值
M_PC8
O
32
M级PC+8值
M_A1
O
5
M级寄存器地址1
M_A2
O
5
M级寄存器地址2
M_RegAddr
O
5
M级寄存器写地址
M_RD1
O
32
M级寄存器数据1
M_RD2
O
32
M级寄存器数据2
MemWrite_M
O
1
M级内存写使能信号
RegWrite_M
O
1
M级寄存器写使能信号
RegDataSel_M
O
3
M级寄存器数据选择信号
M_ALU_Res
O
32
M级ALU运算结果
M_Tnew
O
2
M级新指令周期
M_ALU_Fwd_MUXOut
O
32
M级ALU转发MUX输出
实现功能
序号
功能
描述
1
同步复位
当reset
信号为1时,所有输出信号清空,对于暂停操作而言相当于插入nop指令
2
正常传递
在时钟上升沿,将E级输入信号传递到M级输出信号
M_DM 数据存储器
由于内存外置,故原DM模块实现转移到BE和DE中
M_BE 缓存写回模块
定义 :根据读写信号和地址,对数据进行字节、半字或字的写操作。
端口定义
信号名
方向
位宽
说明
LSOp
I
3
读写操作选择信号
BEAddr
I
32
缓存写回地址
BE_WD_In
I
32
缓存写回输入数据
MemWrite
I
1
内存写使能信号
byteen
O
4
字节使能信号
BE_WD_Out
O
32
缓存写回输出数据
实现功能
序号
功能
描述
1
字写操作
当LSOp
为Ls_Word
时,byteen
为4'b1111
,BE_WD_Out
为BE_WD_In
2
半字写操作
当LSOp
为Ls_Half
时,根据BEAddr
的值选择高16位或低16位进行写操作
3
字节写操作
当LSOp
为Ls_Byte
时,根据BEAddr
的值选择相应的字节进行写操作
4
默认操作
当MemWrite
为0或LSOp
为其他值时,byteen
为4'b0000
,BE_WD_Out
为32'h00000000
M_DE 缓存读模块
定义 :根据读信号和地址,对数据进行字节、半字或字的读操作。
端口定义
信号名
方向
位宽
说明
LSOp
I
3
读操作选择信号
DEAddr
I
32
缓存读出地址
DE_m_data_rdata
I
32
缓存读出输入数据
DE_RD
O
32
缓存读出输出数据
实现功能
序号
操作
功能
1
字读操作
当LSOp
为Ls_Word
时,DE_RD
为DE_m_data_rdata
2
半字读操作
当LSOp
为Ls_Half
时,根据DEAddr
的值选择高16位或低16位进行读操作
3
字节读操作
当LSOp
为Ls_Byte
时,根据DEAddr
的值选择相应的字节进行读操作
4
半字无符号读操作
当LSOp
为Ls_Half_Unsigned
时,根据DEAddr
的值选择高16位或低16位进行无符号读操作
5
字节无符号读操作
当LSOp
为Ls_Byte_Unsigned
时,根据DEAddr
的值选择相应的字节进行无符号读操作
6
默认操作
当LSOp
为其他值时,DE_RD
为32'h00000000
W级:写回WriteBack
W_REG W级流水线寄存器
定义 :存储W级流水线寄存器的数据。
端口定义
信号名
方向
位宽
说明
clk
I
1
时钟信号
reset
I
1
复位信号
M_Instr
I
32
M级指令
M_PC
I
32
M级PC值
M_PC8
I
32
M级PC+8值
M_A1
I
5
M级寄存器地址1
M_A2
I
5
M级寄存器地址2
M_RegAddr
I
5
M级寄存器写地址
M_RD1
I
32
M级寄存器数据1
M_RD2
I
32
M级寄存器数据2
M_ALU_Res
I
32
M级ALU运算结果
M_MDURes
I
32
M级ALU运算结果
M_DM_RD
I
32
M级数据存储器读数据
RegWrite_M
I
1
M级寄存器写使能信号
RegDataSel_M
I
3
M级寄存器数据选择信号
M_Tnew
I
2
M级新指令周期
W_Instr
O
32
W级指令
W_PC
O
32
W级PC值
W_PC8
O
32
W级PC+8值
W_A1
O
5
W级寄存器地址1
W_A2
O
5
W级寄存器地址2
W_RegAddr
O
5
W级寄存器写地址
W_RD1
O
32
W级寄存器数据1
W_RD2
O
32
W级寄存器数据2
W_ALU_Res
O
32
W级ALU运算结果
W_DM_RD
O
32
W级数据存储器读数据
RegWrite_W
O
1
W级寄存器写使能信号
RegDataSel_W
O
3
W级寄存器数据选择信号
W_Tnew
O
2
W级新指令周期
实现功能
序号
功能
描述
1
同步复位
当reset
信号为1时,所有输出信号清空,对于暂停操作而言相当于插入nop指令
2
正常传递
在时钟上升沿,将M级输入信号传递到W级输出信号
MCU 控制单元
定义
MCU 控制单元用于生成控制信号,控制其他模块的行为。
端口定义
信号名
方向
位宽
说明
Op
I
6
操作码
Func
I
6
功能码
RegDstSel
O
3
寄存器目标选择信号
ALUBSrcSel
O
1
ALU_B源选择信号
RegDataSel
O
3
寄存器数据选择信号
RegWrite_D
O
1
寄存器写使能信号
MemWrite_D
O
1
内存写使能信号
NPCSel
O
3
下一条指令PC选择信号
ExtOp_D
O
1
扩展操作选择信号
CMPOp
O
3
比较操作选择信号
ALU_Op
O
4
ALU操作码
MDUOp
O
4
MDU操作码
MDU_Start
O
1
MDU启动信号
LSOp
O
3
存储操作码
Tuse_rs
O
2
rs使用需要周期数
Tuse_rt
O
2
rt使用需要周期数
Tnew_D
O
2
产生数据所用周期数
实现功能
序号
功能
描述
1
指令译码
根据操作码和功能码生成对应的控制信号
2
控制信号生成
生成寄存器目标选择信号、ALU B源选择信号、寄存器数据选择信号等
3
冒险时间生成
生成rs和rt的使用时间以及新指令周期
信号生成说明
将所有指令译码后根据类型分为cal_r
、cal_i
、ld
、st
、md
、mt
、mf
、b_type
、j_type
,对于共性控制信号直接按照类型生成
多路选择器说明
RegDstSel :寄存器目标选择信号,用于选择写入寄存器的目标寄存器。
类型
方向
位宽
说明
RaType
I
32
写回ra寄存器
RdType
I
32
写回rd寄存器
RtType
I
32
写回rt寄存器
ALUBSel :ALU B源选择信号,用于选择ALU B输入端的源。
类型
方向
位宽
说明
E_ALU_Fwd_MUXOut
I
32
寄存器值
EXT
I
32
扩展后的立即数
RegDataSel :寄存器数据选择信号,用于选择写入寄存器的数据源。
类型
方向
位宽
说明
FromMDU
I
32
来自MDU
FromPC
I
32
来自PC8
FromALU
I
32
来自ALU
FromDM
I
32
来自DM
HCU 冒险控制单元
定义 :冒险控制单元用于检测流水线中的数据冒险,并生成相应的转发和停顿信号。
端口定义
信号名
方向
位宽
说明
Tuse_rs
I
2
rs使用需要周期数
Tuse_rt
I
2
rt使用需要周期数
Tnew_E
I
2
E级产生数据需要周期
Tnew_M
I
2
M级产生数据需要周期
Tnew_W
I
2
W级产生数据需要周期
D_A1
I
5
D级寄存器地址1
D_A2
I
5
D级寄存器地址2
D_MDUOp
I
4
D级MDU操作控制信号
E_A1
I
5
E级寄存器地址1
E_A2
I
5
E级寄存器地址2
E_A3
I
5
E级寄存器写地址
E_Start
I
1
E级MDU状态
E_Busy
I
1
E级MDU状态
M_A2
I
5
M级寄存器地址2
M_A3
I
5
M级寄存器写地址
W_A3
I
5
W级寄存器写地址
RegWrite_E
I
1
E级寄存器写使能信号
RegWrite_M
I
1
M级寄存器写使能信号
RegWrite_W
I
1
W级寄存器写使能信号
CMP_RD1_Fwd_D
O
3
比较器RD1转发信号
CMP_RD2_Fwd_D
O
3
比较器RD2转发信号
ALU_A_Fwd_E
O
3
ALU A转发信号
ALU_B_Fwd_E
O
3
ALU B转发信号
DM_WD_Fwd_M
O
3
数据存储器写数据转发信号
stall
O
1
停顿信号
实现功能
序号
功能
描述
1
停顿检测
根据寄存器地址和使用周期数,检测是否需要停顿
2
转发信号生成
生成比较器、ALU和数据存储器的转发信号
3
停顿信号生成
生成流水线停顿信号
暂停Stall
使用A-T法判断,当address相同时,若D级的Tuse_rs或Tuse_rt
比E、M、W级的Tnew小,则说明在D级需要使用寄存器中数据时,E、M、W级相应的寄存器数据还未准备好,需要暂停流水线。
1 2 3 4 5 6 7 8 9 E_Stall_Rs = (E_A3 == D_A1) && (D_A1 != 5'b0 ) && (Tnew_E > Tuse_rs) && RegWrite_E; E_Stall_Rt = (E_A3 == D_A2) && (D_A2 != 5'b0 ) && (Tnew_E > Tuse_rt) && RegWrite_E; M_Stall_Rs = (M_A3 == D_A1) && (D_A1 != 5'b0 ) && (Tnew_M > Tuse_rs) && RegWrite_M; M_Stall_Rt = (M_A3 == D_A2) && (D_A2 != 5'b0 ) && (Tnew_M > Tuse_rt) && RegWrite_M; E_stall_md = D_MDUOp != `MDU_NONE && (E_Busy || E_Start); stall = E_Stall_Rs || E_Stall_Rt || M_Stall_Rs || M_Stall_Rt;
转发Foward
执行暴力转发,使用A-T法判断,当address相同且D级的Tuse_rs或Tuse_rt大于E、M级相应的Tnew时,说明D级需要使用的数据在E、M级中,需要转发。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 assign CMP_RD1_Fwd_D = (M_A3 == D_A1 && RegWrite_M && D_A1) ? `FWD_MEM : (W_A3 == D_A1 && RegWrite_W && D_A1) ? `FWD_WB : `FWD_GRF; assign CMP_RD2_Fwd_D = (M_A3 == D_A2 && RegWrite_M && D_A2) ? `FWD_MEM : (W_A3 == D_A2 && RegWrite_W && D_A2) ? `FWD_WB : `FWD_GRF; assign ALU_A_Fwd_E = (M_A3 == E_A1 && RegWrite_M && E_A1) ? `FWD_MEM : (W_A3 == E_A1 && RegWrite_W && E_A1) ? `FWD_WB : `FWD_GRF; assign ALU_B_Fwd_E = (M_A3 == E_A2 && RegWrite_M && E_A2) ? `FWD_MEM : (W_A3 == E_A2 && RegWrite_W && E_A2) ? `FWD_WB : `FWD_GRF; assign DM_WD_Fwd_M = (W_A3 == M_A2 && RegWrite_W && M_A2) ? `FWD_WB : `FWD_GRF;
顶层模块
测试方案
P6思考题
为什么需要有单独的乘除法部件而不是整合进 ALU?为何需要有独立的 HI、LO 寄存器?
乘除法运算的复杂度远高于加减法运算,因此需要单独的乘除法部件。另外由于其复杂性,乘除法运算需要多个时钟周期,因而使用单独的乘除器可以避免阻塞整个流水线,让其他非乘除法指令继续执行,提升CPU性能。
采用独立的HI、LO寄存器可以保存乘除法运算的结果,保证在乘除器运算时,其他指令可以正常执行,同时也可以避免数据冲突。
真实的流水线 CPU 是如何使用实现乘除法的?请查阅相关资料进行简单说明。
真实的流水线CPU通常使用硬件乘除器来实现乘除法运算。乘法通常有若干个较小的组合逻辑的乘法单元组成,然后每个周期计算特定的几位,依次累加起来,采取流水的方式,每个周期计算一次,从而实现乘法运算。除法运算则采取试算的方式,每次试算一位,然后根据试算结果调整被除数,直到除尽为止。
请结合自己的实现分析,你是如何处理 Busy 信号带来的周期阻塞的?
busy作为乘除器模块的一种状态,当busy或者乘除器模块输出的start状态为1时,传入冒险控制器模块,若此时D级的指令为乘除法指令,则将阻塞D级指令。
请问采用字节使能信号的方式处理写指令有什么好处?(提示:从清晰性、统一性等角度考虑)
清晰性:通过字节使能信号,可以明确地知道哪些字节被写入,哪些字节保持不变,从而避免了数据冲突。
统一性:字节使能信号的使用,使得写指令的处理方式更加统一,将32位数据根据需求执行对应的写入操作,无需传入额外控制信号。
请思考,我们在按字节读和按字节写时,实际从 DM 获得的数据和向 DM 写入的数据是否是一字节?在什么情况下我们按字节读和按字节写的效率会高于按字读和按字写呢?
不是,而是一字,这是因为我们的DM实现的按字读写,需要对于读写的数据进行拆分或拼接;当我们涉及的数据均为单个字节时,按字节读写效率更高,因为不需要进行拆分或拼接,直接读写即可。
为了对抗复杂性你采取了哪些抽象和规范手段?这些手段在译码和处理数据冲突的时候有什么样的特点与帮助?
P6设计沿用了P5,将支持的指令集根据类型区分,从而将新增指令归类提取,译码时控制信号与Tnew、Tuse可直接加到对应的分类中,基本不需要再进行额外处理。
对于数据冲突处理,暂停与转发控制只需要增加乘除法指令的阻塞控制即可,而乘除法指令本身也可以分为md、mf、mt。
在本实验中你遇到了哪些不同指令类型组合产生的冲突?你又是如何解决的?相应的测试样例是什么样的?
由于P6相较于P5增加了乘除法指令,而乘除槽的存在使得对于md类型的指令,乘除槽内出现的乘除法指令将会出现冒险,而我们没法通过转发的方式解决,因而只能暂停流水线。
1 2 3 4 5 6 7 8 9 10 11 12 13 lui $t0,0x1234 lui $t2,0xffff ori $t0,$t0,0x6789 ori $t1,$t1,0xabcd mult $t0,$t1 mfhi $s0 mflo $s1 mult $t0,$t2 mfhi $s0 mflo $s1 multu $t0,$t2 mfhi $s0 mflo $s1
如果你是手动构造的样例,请说明构造策略,说明你的测试程序如何保证覆盖了所有需要测试的情况;如果你是完全随机生成的测试样例,请思考完全随机的测试程序有何不足之处;如果你在生成测试样例时采用了特殊的策略,比如构造连续数据冒险序列,请你描述一下你使用的策略如何结合了随机性达到强测的效果。
使用其他同学的P5数据生成器,增加了P6新增的指令生成部分,对于完全随机生成的测试样例,可能导致数据冲突处理完全依靠随机性,因而我在生成测试数据时,采取了针对性指令生成,即只生成某些类型指令,增大其生成概率,从而检测处理冲突的正确性。