[HDLBits] Cs450/history shift
Branch direction predictors are often structured as tables of counters indexed by the program counter and branch history. The branch history is a sequence of "taken" or "not taken" results from recent branches.
分支方向预测器通常被构造为由程序计数器和分支历史记录索引的计数器表。分支历史记录是来自最近分支的 “taken” 或 “not taken” 结果序列。
In hardware, the branch history register can be implemented as a N-bit shift register. After each conditional branch direction is predicted, its predicted direction is shifted into the shift register. The shift register thus holds the most recent N branch results.
在硬件中,branch history register 可以实现为 N-bit shift register。预测每个 conditional branch direction 后,其预测方向将移至 shift register。因此,移位寄存器保存了最新的 N 分支结果。
Branch history register with surrounding hardware. This exercise builds the branch history register, inside the blue dashed rectangle.
分支历史记录与周围的硬件一起注册。本练习在蓝色虚线矩形内构建分支历史寄存器。
This diagram shows branch mispredictions being signalled by the branch execution unit, but depending on the processor design, this could also be at retirement or some other point.
此图显示了分支执行单元发出的分支预测错误信号,但根据处理器设计,这也可能是在停用或其他时间点。
Additional complexity arises due to pipeline flushes because branch predictions are done speculatively. When a branch misprediction occurs, the processor state needs to be rolled back to the state immediately after the mispredicted branch. This includes rolling back the global history register, which may contain predicted branch results that were shifted-in by branches younger than the mispredicted branch, but now need to be discarded.
由于管道刷新,会产生额外的复杂性,因为分支预测是推测性的。当发生分支预测错误时,处理器状态需要立即回滚到预测错误的分支之后的状态。这包括回滚全局历史记录寄存器,其中可能包含预测的分支结果,这些结果是由比错误预测的分支更年轻的分支移入的,但现在需要丢弃。
We assume here that there is hardware outside of the branch predictor that remembers the state of the branch history register that was used to predict each branch, which is saved for later use for branch predictor training and pipeline flushes. When a branch misprediction occurs, this hardware informs the branch predictor that a branch has mispredicted, the direction the branch should have taken, and the state of the branch history register corresponding to the point in the program immediately before the mispredicted branch.
我们在这里假设分支预测器之外有硬件,它记住了用于预测每个分支的分支历史寄存器的状态,该寄存器被保存起来供以后用于分支预测器训练和管道刷新。当发生分支预测错误时,此硬件会通知分支预测器分支预测错误、分支应采取的方向以及与程序中预测错误的分支之前的点相对应的分支历史寄存器的状态。
Of course, since the processor restarts to the point after the mispredicted branch, the branch history register after the pipeline flush needs to have the actual direction of the mispredicted branch appended.
当然,由于处理器会重新启动到预测错误的分支之后的点,因此管道刷新后的分支历史记录需要附加预测错误的分支的实际方向。
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.
构建 32 位全局历史移位寄存器,包括支持回滚状态以响应由分支预测错误引起的管道刷新。
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.)
进行分支预测时 (predict_valid
= 1),从 LSB 端移入 predict_taken
以更新预测分支的分支历史记录。(predict_history[0]
是最年轻的分支的方向。
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
).
当发生分支预测错误时 (train_mispredicted
= 1),请在预测错误的分支完成后加载分支历史记录寄存器。这是预测错误的分支 (train_history
) 与分支的实际结果 (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.
predict_history
是分支历史记录寄存器的值。
areset
is an asynchronous reset that resets the history counter to zero.
areset
是一种异步 reset,它将 history counter 重置为零。
module top_module(input clk,input areset,input predict_valid,input predict_taken,output [31:0] predict_history,input train_mispredicted,input train_taken,input [31:0] train_history
);reg [31:0] pre_his;assign predict_history = pre_his;//预测always@(posedge clk or posedge areset) beginif(areset) beginpre_his <= 0;end//回滚优先else if(train_mispredicted) beginpre_his <= {train_history[30:0],train_taken};endelse if(predict_valid) beginpre_his <= {pre_his[30:0],predict_taken};endendendmodule
题干很难看懂,但逻辑很简单。