BUAA-CO-p5-课下
注意:本CPU采用分布式译码
命名规范
首先确定元件、线的命名方式
- 流水级名称采用教程的简称,以此为:
F D E M W - 元件命名,采用
流水级简称_元件名命名;实例化时采用小写元件名 - 流水线寄存器,采用
两端流水级简称_REG命名;实例化时采用_小写两端简称_reg - 每级CTRL采用
流水级简称_CTRL(采用分布式译码) - 每级控制信号采用
流水级简称_信号名
结构
F级
input: D_NPC(我的设计将NPC的选择放在了D级)
output: F_PC, F_Instr
本篇中的 input与 output均代表某一流水级的输入输出内容,其作用仅为方便设计
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法
注意,一条指令可以有多条。如
对于不产生新数据的指令,我们认为
数据冒险
旁路转发
X_AN == Y_AM && X_AN != 5'b0 && M_T_NEW == 2'b00 && RegWrite_Y == 1
读寄存器编号和写寄存器编号相同 && 寄存器编号不为0 && 转发流水级的
若GRF写使能为0,YA置0即可
为解决同一时钟周期写和读同一寄存器的问题,将GRF改为下跳沿写入
下跳沿写入是刘旭东老师在课上给的方法,但会发现该方法在P7失效,故在此推荐内部转发
回传:根据GRFWDOp选择每一级的回传数据
阻塞一级
- 冻结
FD_REG,即将FD_REG_En置0 - 清除
DE_REG,全部置0(同步复位即可) - 禁止PC继续计数,即将
PCEn置0
阻塞第二级:
- 冻结
FD_REG - 清除
DE_REG PCEn置0
(让E级的nop往下传,给E级一个新的nop)
- Title: BUAA-CO-p5-课下
- Author: OWPETER
- Created at : 2024-11-12 20:44:43
- Updated at : 2025-01-25 21:13:33
- Link: https://owpeter.github.io/2024/11/12/CO/CO-p5-beforeclass/
- License: This work is licensed under CC BY-NC-SA 4.0.