子预测器基类与子预测器接口
Categories:
在香山分支预测单元中,其所有子预测器以及 Composer 的类实现都是继承自子预测器基类(BasePredictor),并且子预测器接口(BasePredictorIO)也是在子预测器基类中进行定义。因此我们可以认为,Compser 和所有子预测器都含有相同的接口。
在子预测的理解及验证当中,我们最直接的外界交互是发生在子预测器接口,以及子预测器基类中定义的一些变量,因此在子预测器的验证之前,强烈建议你阅读并理解本节文档。
子分支预测器接口的大致内容及使用方法,已在香山分支预测单元(BPU)基础设计
中进行了介绍,本节文档将专注于接口的信号细节。
子分支预测器接口 (BasePredictorIO)
接口定义: src/main/scala/xiangshan/frontend/BPU.scala
每个子分支预测器都需要实现该接口,该接口定义了子分支预测器的输入输出接口。
注意:其中某些信号被定义为了 numDup
个数量,其中每个信号完全一样,多个相同信号是为其他因素考虑。
详细的信号列表如下:
-
reset_vector 重置向量,reset 时 BPU 的 pc 会被重置为该值
- 接口类型:
UInt(PAddrBits.W)
- 接口类型:
-
in BPU 向子分支预测器发送的信息
- 接口类型:
DecoupledIO(new BasePredictorInput)
- 信号列表:
- s0_pc s0流水级的pc
- 接口类型:
Vec(numDup, UInt(VAddrBits.W))
- 接口类型:
- folded_hist 全局折叠历史信息
- 接口类型:
Vec(numDup, new AllFoldedHistories(foldedGHistInfos))
- 信号列表:详见(
AllFoldedHistories
)
- 接口类型:
- ghist 全局分支历史信息
- 接口类型:
UInt(HistoryLength.W)
- 接口类型:
- resp_in 全局分支预测信息(包含s1, s2, s3 预测结果信息)
- 接口类型:
BranchPredictionResp
- 信号列表:详见(
BranchPredictionResp
)
- 接口类型:
- s0_pc s0流水级的pc
- 接口类型:
-
out 子分支预测器向 BPU 发送的信息(包含s1, s2, s3 预测结果信息)
- 接口类型:
new BasePredictorOutput
继承自BranchPredictionResp
- 信号列表:详见(
BranchPredictionResp
)
- 接口类型:
-
ctrl BPU 子预测器使能控制信号,主要用于控制各预测器是否开启
- 接口类型:
BPUCtrl
- 接口列表:
- ubtb_enable: UBTB 预测器使能
- 接口类型:
Bool()
- 接口类型:
- btb_enable: BTB 预测器使能
- 接口类型:
Bool()
- 接口类型:
- bim_enable: BIM 预测器使能
- 接口类型:
Bool()
- 接口类型:
- tage_enable: TAGE 预测器使能
- 接口类型:
Bool()
- 接口类型:
- sc_enable: SC 预测器使能
- 接口类型:
Bool()
- 接口类型:
- ras_enable: RAS 预测器使能
- 接口类型:
Bool()
- 接口类型:
- loop_enable: LOOP 预测器使能
- 接口类型:
Bool()
- 接口类型:
- ubtb_enable: UBTB 预测器使能
- 接口类型:
-
s0_fire s0阶段握手成功信号
- 接口类型:
Vec(numDup, Bool())
- 接口类型:
-
s1_fire s1阶段握手成功信号
- 接口类型:
Vec(numDup, Bool())
- 接口类型:
-
s2_fire s2阶段握手成功信号
- 接口类型:
Vec(numDup, Bool())
- 接口类型:
-
s3_fire s3阶段握手成功信号
- 接口类型:
Vec(numDup, Bool())
- 接口类型:
-
s2_redirect s2阶段重定向信号
- 接口类型:
Vec(numDup, Bool())
- 接口类型:
-
s3_redirect s3阶段重定向信号
- 接口类型:
Vec(numDup, Bool())
- 接口类型:
-
s1_ready s1阶段是否准备好接收信息 (方向:由子预测器输出)
- 接口类型:
Bool()
- 接口类型:
-
s2_ready s2阶段是否准备好接收信息 (方向:由子预测器输出)
- 接口类型:
Bool()
- 接口类型:
-
s3_ready s3阶段是否准备好接收信息 (方向:由子预测器输出)
- 接口类型:
Bool()
- 接口类型:
-
update BPU 向子分支预测器转发的更新请求
- 接口类型:
Valid(new BranchPredictionUpdate)
- 信号列表:详见(
BranchPredictionUpdate
)
- 接口类型:
-
redirect BPU 向子分支预测器转发的重定向请求
- 接口类型:
Valid(new BranchPredictionRedirect)
- 信号列表:详见(
BranchPredictionRedirect
)
- 接口类型:
其中,流水线控制信号将会在下面内容中进行进一步的说明。
全局折叠历史 (AllFoldedHistories)
接口定义:src/main/scala/xiangshan/frontend/FrontendBundle.scala
接口类型:AllFoldedHistories(foldedGHistInfos))
全局折叠历史的接口信息仅为一个 FoldedHistory
的列表
- hist 折叠历史列表
- 接口类型:
MixedVec(gen.map{case (l, cl) => new FoldedHistory(l, cl, numBr)})
- 接口类型:
而 FoldedHistory
的接口信息也仅有一项
- folded_hist 单项折叠历史,其位宽为历史压缩后长度。
- 接口类型:
UInt(compLen.W)
- 接口类型:
也就是说,全局折叠历史接口实际上是一个存储了折叠后历史的列表,其中每一项都是一个特定长度的折叠历史。
子预测器基类
在子预测器基类中定义了若干信号,并在每个子预测器中都可以访问到,并在其中还进行了若干连线。
其中多数信号都较容易理解 ,我们需要重点关注的是其中每个流水的 pc,这还会涉及到你对于流水线控制信号的掌握。因此接下来,我们将会介绍在子预测器中需要关注的流水线控制信号的含义,以及 s1_pc, s2_pc, s3_pc 信号的含义。
其中流水线控制信号共分为 3 组:
- fire 信号 (s0, s1, s2, s3)
- redirect 信号 (s2, s3)
- ready 信号 (s1, s2, s3)
子预测器基类中的 pc 信号共有四组,s0_pc_dup
, s1_pc_dup
, s2_pc_dup
, s3_pc_dup
。每组信号中有多个 pc 信号,他们完全相同,为考虑一些其他因素所复制。因此我们可单纯把他们看做 s0_pc
, s1_pc
, s2_pc
, s3_pc
。
他们的用法可参照下图:
他们与流水线控制信号的关系是:
s0_pc
直接由输入接口中的in.s0_pc
连接而来- 当
s0_fire
生效时,下一周期s1_pc
会输出s0_pc
的值 - 当
s1_fire
生效时,下一周期s2_pc
会输出s1_pc
的值 - 当
s2_fire
生效时,下一周期s3_pc
会输出s2_pc
的值
也就是说,fire
信号是会影响到下一个周期的数据是否有效,比如 s0_fire
信号会影响 s1 流水的数据是否有效,s1_fire
信号会影响到 s2 流水的数据是否有效。
而 fire
信号是否有效取决于本流水级数据是否有效 以及 下一流水级是否 ready。例如 s1_fire
信号有效的条件必须包含 s1 阶段数据有效,以及子预测器输出的 s2_ready
信号为有效,此时便可认为,s1 阶段数据处理完成,并且 s2 阶段就绪,下一周期数据将被直接送入 s2 阶段。
因此在子预测器中,以 s1 阶段为例,s1_ready
可以阻塞数据进入 s1 阶段,当 s1_ready
生效时,下一周期 s1 阶段的数据便会生效。而当 s1_fire
有效的同时,说明 s1 阶段数据已经生效,预测器也已经将 s1 阶段的结果生成,下一周期将直接被送入 s2 阶段。
redirect
信号则相对明确。以 s2 为例,当 s2_redirect
有效时,说明 s2_fire
生效的同时 s2 预测结果与上周期 s1 预测结果不同。