FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

SonicBOOMのデザインを読み解く (全体バス構成とフロントエンド概要2)

SonicBOOMのデザインを読み解く続き。フロントエンドデザインを波形を見ながら読み解いていくことにする。最初のブート部分の波形を表示すると以下のようになる。

f:id:msyksphinz:20201220205725p:plain

まず、F0ステージからICacheへのリクエストを出し、F2ステージにレスポンスが無ければキャッシュミスしたものとみなす。F3ステージではキューが置かれており、ここにはとりあえずフェッチしてきた命令が挿入される。

  // **** F3 ****
  // --------------------------------------------------------
  val f3_clear = WireInit(false.B)
  val f3 = withReset(reset.toBool || f3_clear) {
    Module(new Queue(new FrontendResp, 1, pipe=true, flow=false)) }
...
  f3.io.enq.valid   := (s2_valid && !f2_clear &&
    (icache.io.resp.valid || ((s2_tlb_resp.ae.inst || s2_tlb_resp.pf.inst) && !s2_tlb_miss))
  )
  f3.io.enq.bits.pc := s2_vpc
  f3.io.enq.bits.data  := Mux(s2_xcpt, 0.U, icache.io.resp.bits.data)
  f3.io.enq.bits.ghist := s2_ghist
  f3.io.enq.bits.mask := fetchMask(s2_vpc)
  f3.io.enq.bits.xcpt := s2_tlb_resp
  f3.io.enq.bits.fsrc := s2_fsrc
  f3.io.enq.bits.tsrc := s2_tsrc

一方で、F4のキューはCompressed命令を展開して再度格納する。F3のキューは同時に2命令(64ビット)だったものが、F4のキューは同時に4命令(16ビット命令を最大まで展開したもの)を格納することができるようになっている。

      if (w == 0) {
        val inst0 = Cat(bank_data(15,0), f3_prev_half)
        val inst1 = bank_data(31,0)
        val exp_inst0 = ExpandRVC(inst0)
        val exp_inst1 = ExpandRVC(inst1)
        val pc0 = (f3_aligned_pc + (i << log2Ceil(coreInstBytes)).U - 2.U)
        val pc1 = (f3_aligned_pc + (i << log2Ceil(coreInstBytes)).U)
    
        val bpd_decoder0 = Module(new BranchDecode)
        bpd_decoder0.io.inst := exp_inst0
    ...
            bpd_decoder.io.inst := exp_inst
            bpd_decoder.io.pc   := pc
    
            bank_insts(w)                := inst
            f3_fetch_bundle.insts(i)     := inst
            f3_fetch_bundle.exp_insts(i) := exp_inst
            bpu.io.pc                    := pc
            brsigs                       := bpd_decoder.io.out
            if (w == 1) {

そしてfb(Fetch Buffer)ではこれらの展開した命令を格納している。

ftqも同様のタイミングでキューに命令を挿入している。一方でキューから取り出すタイミングは命令がコミットされたタイミングだ。

  // -------------------------------------------------------
  // **** To Core (F5) ****
  // -------------------------------------------------------

  io.cpu.fetchpacket <> fb.io.deq
  io.cpu.get_pc <> ftq.io.get_ftq_pc
  ftq.io.deq := io.cpu.commit
  ftq.io.brupdate := io.cpu.brupdate
...