BUAA-CO-p5-课下

BUAA-CO-p5-课下

命名规范

首先确定元件、线的命名方式

  • 流水级名称采用教程的简称,以此为:F D E M W
  • 元件命名,采用流水级简称_元件名命名;实例化时采用小写元件名
  • 流水线寄存器,采用两端流水级简称_REG命名;实例化时采用_小写两端简称_reg
  • 每级CTRL采用流水级简称_CTRL(采用分布式译码)
  • 每级控制信号采用流水级简称_信号名

结构

F级

input: D_NPC(我的设计将NPC的选择放在了D级)

output: F_PC, F_Instr

F_IFU

信号名 I/O 功能
clk I 时钟信号
reset I 同步复位
PCEn I PC使能
NPC[31:0] I 选好了的NPC
PC[31:0] O 当前PC
Instr[31:0] O 指令

D级

元件:GRF, EXT, CMP, NPC

input: F_PC, F_Instr

output: D_rs_data, D_rt_data; D_imm32; D_NPC; D_PC, D_Instr;

FD_REG

信号名 I/O 功能
clk I 时钟信号
reset I 同步复位
FD_REG_En I 写使能(用于冻结)
F_PC[31:0] I F级输入PC
F_Instr[31:0] I F级输入Instr
D_PC[31:0] O D级使用的PC
D_Instr[31:0] O D级使用的Instr

D_GRF

  • 参考学长的博客,删除RegWr信号,改为“若不写入,则写入地址为0”
  • 删除P4中GRFWrite模块,直接在顶层模块中进行多路选择

其他接口与P4无区别,这里不列表格了

D_EXT

信号名 I/O 功能
EXTOp I 接收来自D_CTRL的控制信号
Imm16[15:0] I 16位立即数
Imm32[31:0] O 32位扩展后的立即数

D_CMP

去除P4 ALU中的eq_zero端口,改为D级中的此模块

信号名 I/O 功能
CMP_rs[31:0] I 转发后的$rs
CMP_rt[31:0] I 转发后的$rt
CMPOp[1:0] I 比较方式的选择信号,可拓展
Branch O 是否跳转

D_NPC

信号名 I/O 功能
NPCOp[2:0] I NPC控制信号
D_PC[31:0] I D级PC,用于branch型跳转
F_PC[31:0] I F级PC,用于default
NPC_rs[31:0] I 转发后的$rs, 用于jr型
Branch I 是否进行branch
NPC[31:0] O 处理后的NPC

E级

元件:ALU

input: D_rs_data, D_rt_data, D_imm32; D_PC, D_Instr

output: E_ALU_result, E_rt_data, E_PC, E_Instr

DE_REG

信号名 I/O 功能
clk I 时钟信号
reset I 同步复位
D_rs_data[31:0] I D级$rs
D_rt_data[31:0] I D级$rt
D_imm32[31:0] I 扩展后32位立即数
D_PC[31:0] I D级PC
D_Instr[31:0] I D级指令
E_rs_data[31:0] O E级使用的$rs
E_rt_data[31:0] O E级使用的$rt
E_imm32[31:0] O E级使用的32位立即数
E_PC[31:0] O E级PC
E_Instr[31:0] O E级指令

E_ALU

信号名 I/O 功能
A[31:0] I A端口
B[31:0] I B端口
ALUOp[2:0] I 计算模式选择
ALUresult[31:0] O 计算结果

M级

元件:DM

input: E_ALUresult, E_rt_data; E_PC, E_Instr

output: M_ALUresult, M_RD; M_PC, M_Instr

EM_REG

信号名 I/O 功能
clk I 时钟信号
reset I 同步复位
E_ALUresult[31:0] I E级ALU计算结果
E_rt_data[31:0] I E级接收转发后的$rt
E_PC[31:0] I E级PC
E_Instr[31:0] I E级指令
M_ALUresult[31:0] O M级使用的ALU计算结果
M_rt_data[31:0] O M级使用的$rt
M_PC[31:0] O M级PC
M_Instr[31:0] O M级指令

M_DM

信号名 I/O 功能
clk I 时钟信号
reset I 同步复位
MemWr I 写使能
Addr[31:0] I 写入地址
Data[31:0] I 写入数据
RD[31:0] O 读出数据

后续可增加DMOp接口,对更多种类的load指令进行扩展

W级

input: M_ALUresult, M_RD; M_PC, M_Instr

WM_REG

信号名 I/O 功能
clk I 时钟信号
reset I 同步复位
M_RD[31:0] I M级DM读出数据
M_ALUresult[31:0] I M级传递的ALU计算结果
M_PC[31:0] I M级PC
M_Instr[31:0] I M级指令
W_RD[31:0] O W级使用的DM读出
W_ALUresult[31:0] O W级使用的ALU计算结果
W_PC[31:0] O W级PC
W_Instr[31:0] O W级指令

冒险的解决

AT法

TuseT_{use} :经过多少个时钟周期就必须要使用相应的数据

注意,一条指令可以有多条。如 Tuse_rsT_{use\_rs}Tuse_rtT_{use\_rt}

TnewT_{new} :某个流水级中的某条指令,还需要多少个周期才能将结果写入流水级寄存器

对于不产生新数据的指令,我们认为 TnewT_{new} 始终为0

数据冒险

旁路转发

X_AN == Y_AM && X_AN != 5'b0 && M_T_NEW == 2'b00 && RegWrite_Y == 1

读寄存器编号和写寄存器编号相同 && 寄存器编号不为0 && 转发流水级的 Tnew=0T_{new}=0 && GRF写使能为1

若GRF写使能为0,YA置0即可

为解决同一时钟周期写和读同一寄存器的问题,将GRF改为下跳沿写入

回传:根据GRFWDOp选择每一级的回传数据

  • jal旁路转发:
    • A1 = A2 = 31

阻塞一级

  1. 冻结FD_REG,即将FD_REG_En置0
  2. 清除DE_REG,全部置0(同步复位即可)
  3. 禁止PC继续计数,即将PCEn置0

阻塞第二级:

  1. 冻结FD_REG
  2. 清除DE_REG
  3. PCEn置0
    (让E级的nop往下传,给E级一个新的nop)
作者

OWPETER

发布于

2024-11-12

更新于

2024-12-02

许可协议

评论