流水线逻辑
f_pc: 当前要取什么
f_predPC: 下条取什么
bubble: 预测错误情况下是取消错误指令
有以下几种情形
选择分支
直接跳转,预测错误再改正
下条地址 -> D_valP -> E_valA -> M_valA
int f_pc = [
# 发现分支预测错误,本不应该跳。现在继续下条指令。
# M_valA由D_valP传递得
M_icode == IJXX && !M_Cnd : M_valA;
W_icode == IRET : W_valM;
1 : F_predPC;
];
int f_predPC = [
# ICALL直接跳
# JXX 先直接跳,预测错了再执行JXX下一条指令
f_icode in { IJXX, ICALL } : f_valC;
1 : f_valP;
];
# !e_Cnd 表示不能跳呀, 前面猜错了,故要bubble
bool D_bubble =
(E_icode == IJXX && !e_Cnd) ||
#其他省略
bool E_bubble =
(E_icode == IJXX && !e_Cnd) ||
#其他省略
不选择分支
先不跳转,预测错误再跳转
跳转地址 -> D_valC -> E_valC -> M_valE
int f_pc = [
# M_valE由E中A+B得到
M_icode == IJXX && !M_Cnd : M_valE;
W_icode == IRET : W_valM;
1 : F_predPC;
];
int f_predPC = [
# IJXX先不跳转
f_icode == ICALL : f_valC;
1 : f_valP;
];
# E 流水线寄存器 A是E_valC,B是0。
# 先把跳转地址准备好,万一预测错误了
int aluA = [
E_icode == IJXX : E_valC;#跳转地址
# 其他指令省略
];
int aluB = [
E_icode == IJXX : 0;
# 其他指令省略
];
# e_Cnd 说明是要能跳呀, 前面猜错了,故要bubble
bool D_bubble =
(E_icode == IJXX && e_Cnd) || 0 #其他指令省略
bool E_bubble =
(E_icode == IJXX && e_Cnd) || 0 #其他指令省略
无条件跳转
属于选择分支,直接跳转,而且肯定不会预测错,废话。
f_pc,D_icode,E_icode中的IJXX要改成IJXX && f_ifun != UNCOND
f_predPC中的IJXX要改成IJXX && f_ifun == UNCOND
前(后)向分支
前向分支:下条指令在分支指令前
后向分支:下条指令在分支指令后
谁在前就先执行谁
int f_pc = [
# 等同[不选择分支]预测错误了,应该要跳转
M_icode == IJXX && M_ifun != UNCOND && M_valE > M_valA && M_Cnd : M_valE;
# 等同[选择分支]预测错误了,不应要跳转
M_icode == IJXX && M_ifun != UNCOND && M_valE <=M_valA && !M_Cnd : M_valA;
# 省略
];
int f_predPC = [
# 无条件跳转肯定是不管前支不是后支
f_icode == IJXX && f_ifun == UNCOND : f_valC;
# 谁在前就先执行谁
f_icode == IJXX && f_valC <= f_valP : f_valC;
f_icode in { ICALL } : f_valC;
1 : f_valP;
];
bool D_bubble =
(E_icode == IJXX && E_ifun != UNCOND && E_valC > E_valA && e_Cnd) ||
(E_icode == IJXX && E_ifun != UNCOND && E_valC <=E_valA && !e_Cnd) ||
0 ;# 省略
bool E_bubble 同
总结
无非两种情况,跳与不跳
如何选择跳与不跳? f_predPC预测下条指令
预测错了,正确指令在哪? M_Cnd(e_Cnd)反馈f_pc ( ps:M_Cnd = e_Cnd )
M的正确指令哪里来? PC取了一个地址后会把另一个地址一直传到E,由E判断后给M
预测错了,错误指令在怎么取消? 逻辑控制中的bubble