原题地址:https://hdlbits.01xz.net/wiki/Cs450/history_shift
Description
Build a 32-bit global history shift register, including support for rolling back state in response to a pipeline flush caused by a branch misprediction.
When a branch prediction is made (predict_valid
= 1), shift in predict_taken
from the LSB side to update the branch history for the predicted branch. (predict_history[0]
is the direction of the youngest branch.)
When a branch misprediction occurs (train_mispredicted
= 1), load the branch history register with the history after the completion of the mispredicted branch. This is the history before the mispredicted branch (train_history
) concatenated with the actual result of the branch (train_taken
).
If both a prediction and misprediction occur at the same time, the misprediction takes precedence, because the pipeline flush will also flush out the branch that is currently making a prediction.
predict_history
is the value of the branch history register.
areset
is an asynchronous reset that resets the history counter to zero.
module top_module(
input clk,
input areset,
input predict_valid,
input [6:0] predict_pc,
output predict_taken,
output [6:0] predict_history,
input train_valid,
input train_taken,
input train_mispredicted,
input [6:0] train_history,
input [6:0] train_pc
);
reg [1:0] PHT[127:0]; //128个2位PHT
integer i;
always@(posedge clk or posedge areset) begin
if(areset) begin
predict_history <= 0;
for(i=0;i<128;i=i+1)
PHT[i] <= 2'b01;
end
else begin
if(train_valid & train_mispredicted)
predict_history <= {train_history[5:0],train_taken}; //预测结果有无,选择实际输入
else if(predict_valid)
predict_history <= {predict_history[5:0],predict_taken}; //预测结果正确,直接使用
else
predict_history <= predict_history;
if(train_valid) begin //更新对应地址PHT饱和寄存器状态值,影响PHT的值,进而影响predict_taken
if(train_taken)
PHT[train_history ^ train_pc]<=(PHT[train_history ^ train_pc]==2'b11) ? 2'b11 : (PHT[train_history ^ train_pc]+1); //选中的饱和寄存器值+1,2'b11保持
else
PHT[train_history ^ train_pc]<=(PHT[train_history ^ train_pc]==2'b00) ? 2'b00 : (PHT[train_history ^ train_pc]-1); //选中的饱和寄存器值减1,2'00保持
end
end
end
assign predict_taken=PHT[predict_history ^ predict_pc][1]; //根据地址读取对应PHT的值
endmodule
个人理解:predict_history ^ predict_pc 是PHT的读取地址,predict时用于读取taken状态
train_history ^ train_pc 时PHT的写入地址,用于实际运行到对应地址后,根据实际结果来更新PHT数据
predict和实际运行是同步运行的,读写地址一般不一致