BOOMv3のIssue Unitの構成を読み解いて、自作CPUの性能向上の役に立てる。
MSHRの構成についてみてみる。BOOMv3のMSHRはDCache内に接続されている。
val mshrs = Module(new BoomMSHRFile) mshrs.io.clear_all := io.lsu.force_order mshrs.io.brupdate := io.lsu.brupdate mshrs.io.exception := io.lsu.exception mshrs.io.rob_pnr_idx := io.lsu.rob_pnr_idx mshrs.io.rob_head_idx := io.lsu.rob_head_idx
インタフェースはmemWidth
だけ定義されており、これに対してリクエストを挿入している。
// Miss handling for (w <- 0 until memWidth) { mshrs.io.req(w).valid := s2_valid(w) && !s2_hit(w) && !s2_nack_hit(w) && !s2_nack_victim(w) && !s2_nack_data(w) && !s2_nack_wb(w) && s2_type.isOneOf(t_lsu, t_prefetch) && !IsKilledByBranch(io.lsu.brupdate, s2_req(w).uop) && !(io.lsu.exception && s2_req(w).uop.uses_ldq) && (isPrefetch(s2_req(w).uop.mem_cmd) || isRead(s2_req(w).uop.mem_cmd) || isWrite(s2_req(w).uop.mem_cmd))
class BoomMSHRFile(implicit edge: TLEdgeOut, p: Parameters) extends BoomModule()(p) with HasL1HellaCacheParameters { val io = IO(new Bundle { val req = Flipped(Vec(memWidth, Decoupled(new BoomDCacheReqInternal))) // Req from s2 of DCache pipe val req_is_probe = Input(Vec(memWidth, Bool())) val resp = Decoupled(new BoomDCacheResp) val secondary_miss = Output(Vec(memWidth, Bool())) ...
MSHRのエントリは以下のように定義されている。ここから先はChiselのコードを見てもよく分からんなあ?
val mshrs = (0 until cfg.nMSHRs) map { i => val mshr = Module(new BoomMSHR) mshr.io.id := i.U(log2Ceil(cfg.nMSHRs).W) for (w <- 0 until memWidth) { idx_matches(w)(i) := mshr.io.idx.valid && mshr.io.idx.bits === io.req(w).bits.addr(untagBits-1,blockOffBits) tag_matches(w)(i) := mshr.io.tag.valid && mshr.io.tag.bits === io.req(w).bits.addr >> untagBits way_matches(w)(i) := mshr.io.way.valid && mshr.io.way.bits === io.req(w).bits.way_en } wb_tag_list(i) := mshr.io.wb_req.bits.tag mshr.io.req_pri_val := (i.U === mshr_alloc_idx) && pri_val when (i.U === mshr_alloc_idx) { pri_rdy := mshr.io.req_pri_rdy }