重定向与更新接口

重定向与更新请求是 FTQ 发往 BPU 的两大信息类型,本节中讲述了这两种请求接口的具体结构。

分支预测重定向(BranchPredictionRedirect)

接口定义:src/main/scala/xiangshan/frontend/FrontendBundle.scala

接口类型:BranchPredictionRedirect

该接口定义了分支预测单元的重定向请求,主要用于重定向分支预测器的状态。

BranchPredictionRedirct 接口继承自 Redirct 接口,所含信号较多,BPU 重定向只会用到其中一部分接口,文档描述的结构中只包含 BPU 用到的接口内容。

重定向请求有两种来源,与 IFU 预译码信息对比生成的重定向请求,后端执行过程中的重定向请求。

在重定向请求中,关键信息是cfiUpdate即控制流指令信息。这一信息对应着一条指令,也就是BPU发生预测错误的指令。举例来说,如果 BPU 在预测块中指示第三条指令为普通指令不发生跳转,但预译码显示第三条指令是一条无条件跳转指令,必定会跳转。在这种情况下,BPU 发生了预测错误,FTQ 产生了重定向请求。在重定向请求中,cfiUpdate 将会对应这条无条件跳转指令。

cfiUpdate 中的信息可大致分为三种类型的信息:

  1. 对应指令的信息及执行情况。其中会说明该指令在预测块中位于那个槽 (shift) 及 pc; 会指示这条指令的类型相关信息 (pd);还有这条指令的执行情况,例如跳转目标、是否跳转等
  2. 历史维护相关信息。重定向请求中包含了该条指令所处的预测块对应的分支历史信息,以帮助BPU恢复分支历史信息。foleded_hist 代表全局折叠历史,histPtr 代表全局历史指针,而其余信息则是维护分支历史的辅助信息。要详细了解这些信息的含义,请参阅 BPU顶层模块
  3. RAS维护相关信息。详细含义请参阅 RAS 子预测器文档。

level 信息的含义是,重定向是否包含本条指令,如果不包含,重定向请求的接收方将认为这条指令已经被执行了,下次预测将从下一条指令开始。BPU 顶层会默认不包含本条指令,收到重定向请求后,会将本条指令的执行情况统计到分支历史当中。

以下为重定向接口的详细信号列表:

  • level: 重定向请求是否包括本位置,低表示在本位置后重定向,高表示在本位置重定向。

    • 接口类型: UInt(1.W)
  • cfiUpdate: 控制流指令更新信息

    • 接口类型: CfiUpdateInfo

    • 接口列表

      • pc: 重定向请求对应的指令 PC
        • 接口类型: UInt(VaddrBits.W)
      • pd: 重定向指令的预译码信息
        • isRVC: 是否是压缩指令
          • 接口类型: Bool
        • isCall: 是否是函数调用
          • 接口类型: Bool
        • isRet: 是否是函数返回
          • 接口类型: Bool
      • target: 重定向请求指令的目标地址。
        • 接口类型: UInt(VaddrBits.W)
      • taken: 重定向请求指令是否发生跳转。
        • 接口类型: Bool
      • shift: 重定向请求指令位于哪个槽,如果是普通指令则为0.
        • 接口类型: UInt((log2Ceil(numBr)+1).W)
      • addIntoHist: 重定向请求指令执行信息是否要加入分支历史。
        • 接口类型: Bool

      • folded_hist: 重定向请求对应的折叠历史。
        • 接口类型: AllFoldedHistories(foldedGHistInfos)
      • afhob: 重定向请求指令对应的分支历史最老位。
        • 接口类型: AllAheadFoldedHistoryOldestBits(foldedGHistInfos)
      • lastBrNumOH: 重定向请求对应的上次跳转位置。
        • 接口类型: UInt((numBr+1).W)
      • histPtr: 重定向请求需要恢复的全局历史指针。
        • 接口类型: CGHPtr

      • ssp: 重定向请求指令对应的 RAS 推测栈栈顶在提交栈位置的指针。
        • 接口类型: UInt(log2Up(RasSize).W)
      • sctr: 重定向请求指令对应的 RAS 推测栈栈顶递归计数 Counter。
        • 接口类型: UInt(log2Up(RasCtrSize).W)
      • TOSW: 重定向请求指令对应的 RAS 推测栈(队列)写指针。
        • 接口类型: CGHPtr
      • TOSR: 重定向请求指令对应的 RAS 推测栈(队列)读指针。
        • 接口类型: CGHPtr
      • NOS: 重定向请求指令的 RAS 栈顶 Counter。
        • 接口类型: CGHPtr

分支预测更新(BranchPredictionUpdate)

接口定义: src/main/scala/xiangshan/frontend/FrontendBundle.scala

该接口定义了分支预测器的更新请求,主要用于更新分支预测器的状态,文档只列出了在 BPU 中使用的接口。

更新请求与每一个分支预测块一一对应,当 FTQ 中的一个分支预测块被执行过以后,FTQ 将会为这个分支预测块产生一个更新请求,来指导预测器进行训练,因此更新请求中的一个重要职责就是向 BPU 反馈指令的真实执行情况。当然在香山分支预测单元中,更新请求还会负责 FTB 项的更新

更新请求中的信息可大致分为四类:

  • PC 表示预测块的起始地址,指示了该更新请求对应哪个分支预测块
  • FTB 项更新信息 更新通道中会含有一个 FTB 项结构 (ftb_entry),输出 FTQ 新生成的 FTB 项,并且还会指示是否与旧的 FTB 项相同 (old_entry)
  • 指令真实执行情况信息 更新通道中会指示该分支预测块中分支指令和无条件跳转指令的执行情况,还会给出控制流指令(即发生跳转的指令)的地址以及最终跳转目标。
  • 与该预测块对应的预测器相关数据 包含 spec_info 以及 meta 信息。(具体请参阅BPU全局接口文档)

更新请求的接口列表如下:

  • pc 更新请求的pc (预测块起始地址)
    • 接口类型:UInt(VAddrBits.W)

  • ftb_entry 更新后的ftb项
    • 接口类型:new FTBEntry()
    • 接口列表:详见(FTBEntry
  • old_entry 更新后的 FTB 项是否与旧的 FTB 项相同
    • 接口类型:Bool()

  • br_taken_mask 预测块内每个slot内指令是否跳转
    • 接口类型:Vec(numBr, Bool())
  • mispred_mask 预测块内预测错误的掩码。第一、二位分别代表两个条件分支指令是否预测错误,第三位指示无条件跳转指令是否预测错误。
    • 接口类型:Vec(numBr+1, Bool())
  • jmp_taken 预测块内无条件跳转指令被触发
    • 接口类型:Bool()
  • cfi_idx 控制流指令在预测块中的索引
    • 接口类型:ValidUndirectioned(UInt(log2Ceil(PredictWidth).W))
  • full_target 预测块的跳转目标(下一个预测块的起始地址)
    • 接口类型:UInt(VAddrBits.W)

  • spec_info 该预测块对应的 last_stage_spec_info
    • 接口类型:new SpeculativeInfo
    • 接口列表:(只用到了 foled_hist 一项)
      • folded_hist 全局折叠历史
        • 接口类型:AllFolededHistories(foldedGHistInfos)
  • meta 该预测块对应的 last_stage_meta 信息
    • 接口类型:UInt(MaxMetaLength.W)
最后修改 October 27, 2024: Fix typo (e95831c)