Guarantee one-hotness of BTB entries
This commit is contained in:
		@@ -147,6 +147,7 @@ class BTB(implicit p: Parameters) extends BtbModule {
 | 
				
			|||||||
  val tgts = Reg(Vec(entries, UInt(width=matchBits)))
 | 
					  val tgts = Reg(Vec(entries, UInt(width=matchBits)))
 | 
				
			||||||
  val tgtPages = Reg(Vec(entries, UInt(width=log2Up(nPages))))
 | 
					  val tgtPages = Reg(Vec(entries, UInt(width=log2Up(nPages))))
 | 
				
			||||||
  val pages = Reg(Vec(nPages, UInt(width=vaddrBits-matchBits)))
 | 
					  val pages = Reg(Vec(nPages, UInt(width=vaddrBits-matchBits)))
 | 
				
			||||||
 | 
					  val pageValid = Reg(init = UInt(0, nPages))
 | 
				
			||||||
  val idxPagesOH = idxPages.map(UIntToOH(_)(nPages-1,0))
 | 
					  val idxPagesOH = idxPages.map(UIntToOH(_)(nPages-1,0))
 | 
				
			||||||
  val tgtPagesOH = tgtPages.map(UIntToOH(_)(nPages-1,0))
 | 
					  val tgtPagesOH = tgtPages.map(UIntToOH(_)(nPages-1,0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -157,12 +158,12 @@ class BTB(implicit p: Parameters) extends BtbModule {
 | 
				
			|||||||
  private def page(addr: UInt) = addr >> matchBits
 | 
					  private def page(addr: UInt) = addr >> matchBits
 | 
				
			||||||
  private def pageMatch(addr: UInt) = {
 | 
					  private def pageMatch(addr: UInt) = {
 | 
				
			||||||
    val p = page(addr)
 | 
					    val p = page(addr)
 | 
				
			||||||
    pages.map(_ === p).toBits
 | 
					    pageValid & pages.map(_ === p).toBits
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  private def tagMatch(addr: UInt, pgMatch: UInt) = {
 | 
					  private def tagMatch(addr: UInt, pgMatch: UInt) = {
 | 
				
			||||||
    val idxMatch = idxs.map(_ === addr(matchBits-1,0))
 | 
					    val idxMatch = idxs.map(_ === addr(matchBits-1,0)).toBits
 | 
				
			||||||
    val idxPageMatch = idxPagesOH.map(_ & pgMatch).map(_.orR)
 | 
					    val idxPageMatch = idxPagesOH.map(_ & pgMatch).map(_.orR).toBits
 | 
				
			||||||
    (idxPageMatch zip idxMatch) map { case (p, i) => p && i }
 | 
					    idxMatch & idxPageMatch
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val r_btb_update = Pipe(io.btb_update)
 | 
					  val r_btb_update = Pipe(io.btb_update)
 | 
				
			||||||
@@ -172,16 +173,20 @@ class BTB(implicit p: Parameters) extends BtbModule {
 | 
				
			|||||||
  val hitsVec = tagMatch(io.req.bits.addr, pageHit)
 | 
					  val hitsVec = tagMatch(io.req.bits.addr, pageHit)
 | 
				
			||||||
  val hits = hitsVec.toBits
 | 
					  val hits = hitsVec.toBits
 | 
				
			||||||
  val updatePageHit = pageMatch(r_btb_update.bits.pc)
 | 
					  val updatePageHit = pageMatch(r_btb_update.bits.pc)
 | 
				
			||||||
  val updateHits = tagMatch(r_btb_update.bits.pc, updatePageHit)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val updateHit = r_btb_update.bits.prediction.valid
 | 
					  val updateHits = tagMatch(r_btb_update.bits.pc, updatePageHit)
 | 
				
			||||||
  val nextRepl = Reg(UInt(width = log2Ceil(entries)))
 | 
					  val updateHit = if (updatesOutOfOrder) updateHits.orR else r_btb_update.bits.prediction.valid
 | 
				
			||||||
  when (r_btb_update.valid && !updateHit) { nextRepl := Mux(nextRepl === entries-1 && Bool(!isPow2(entries)), 0,  nextRepl + 1) }
 | 
					  val updateHitAddr = if (updatesOutOfOrder) OHToUInt(updateHits) else r_btb_update.bits.prediction.bits.entry
 | 
				
			||||||
  val nextPageRepl = Reg(UInt(width = log2Ceil(nPages)))
 | 
					
 | 
				
			||||||
 | 
					  // guarantee one-hotness of idx after reset
 | 
				
			||||||
 | 
					  val resetting = Reg(init = Bool(true))
 | 
				
			||||||
 | 
					  val (nextRepl, wrap) = Counter(resetting || (r_btb_update.valid && !updateHit), entries)
 | 
				
			||||||
 | 
					  when (wrap) { resetting := false }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val useUpdatePageHit = updatePageHit.orR
 | 
					  val useUpdatePageHit = updatePageHit.orR
 | 
				
			||||||
  val usePageHit = pageHit.orR
 | 
					  val usePageHit = pageHit.orR
 | 
				
			||||||
  val doIdxPageRepl = !useUpdatePageHit
 | 
					  val doIdxPageRepl = !useUpdatePageHit
 | 
				
			||||||
 | 
					  val nextPageRepl = Reg(UInt(width = log2Ceil(nPages)))
 | 
				
			||||||
  val idxPageRepl = Mux(usePageHit, Cat(pageHit(nPages-2,0), pageHit(nPages-1)), UIntToOH(nextPageRepl))
 | 
					  val idxPageRepl = Mux(usePageHit, Cat(pageHit(nPages-2,0), pageHit(nPages-1)), UIntToOH(nextPageRepl))
 | 
				
			||||||
  val idxPageUpdateOH = Mux(useUpdatePageHit, updatePageHit, idxPageRepl)
 | 
					  val idxPageUpdateOH = Mux(useUpdatePageHit, updatePageHit, idxPageRepl)
 | 
				
			||||||
  val idxPageUpdate = OHToUInt(idxPageUpdateOH)
 | 
					  val idxPageUpdate = OHToUInt(idxPageUpdateOH)
 | 
				
			||||||
@@ -199,18 +204,15 @@ class BTB(implicit p: Parameters) extends BtbModule {
 | 
				
			|||||||
    nextPageRepl := Mux(next >= nPages, next(0), next)
 | 
					    nextPageRepl := Mux(next >= nPages, next(0), next)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  when (r_btb_update.valid) {
 | 
					  when (r_btb_update.valid || resetting) {
 | 
				
			||||||
    assert(io.req.bits.addr === r_btb_update.bits.target, "BTB request != I$ target")
 | 
					    assert(resetting || io.req.bits.addr === r_btb_update.bits.target, "BTB request != I$ target")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    val waddr =
 | 
					    val waddr = Mux(updateHit && !resetting, updateHitAddr, nextRepl)
 | 
				
			||||||
      if (updatesOutOfOrder) Mux(updateHits.reduce(_|_), OHToUInt(updateHits), nextRepl)
 | 
					    val mask = UIntToOH(waddr)
 | 
				
			||||||
      else Mux(updateHit, r_btb_update.bits.prediction.bits.entry, nextRepl)
 | 
					    idxs(waddr) := Mux(resetting, Cat(r_btb_update.bits.pc >> log2Ceil(entries), nextRepl), r_btb_update.bits.pc)
 | 
				
			||||||
 | 
					 | 
				
			||||||
    idxs(waddr) := r_btb_update.bits.pc
 | 
					 | 
				
			||||||
    tgts(waddr) := update_target
 | 
					    tgts(waddr) := update_target
 | 
				
			||||||
    idxPages(waddr) := idxPageUpdate
 | 
					    idxPages(waddr) := idxPageUpdate
 | 
				
			||||||
    tgtPages(waddr) := tgtPageUpdate
 | 
					    tgtPages(waddr) := tgtPageUpdate
 | 
				
			||||||
    val mask = UIntToOH(waddr)
 | 
					 | 
				
			||||||
    useRAS := Mux(r_btb_update.bits.isReturn, useRAS | mask, useRAS & ~mask)
 | 
					    useRAS := Mux(r_btb_update.bits.isReturn, useRAS | mask, useRAS & ~mask)
 | 
				
			||||||
    isJump := Mux(r_btb_update.bits.isJump, isJump | mask, isJump & ~mask)
 | 
					    isJump := Mux(r_btb_update.bits.isJump, isJump | mask, isJump & ~mask)
 | 
				
			||||||
    if (fetchWidth > 1)
 | 
					    if (fetchWidth > 1)
 | 
				
			||||||
@@ -227,6 +229,7 @@ class BTB(implicit p: Parameters) extends BtbModule {
 | 
				
			|||||||
      Mux(idxWritesEven, page(r_btb_update.bits.pc), page(update_target)))
 | 
					      Mux(idxWritesEven, page(r_btb_update.bits.pc), page(update_target)))
 | 
				
			||||||
    writeBank(1, 2, Mux(idxWritesEven, tgtPageReplEn, idxPageReplEn),
 | 
					    writeBank(1, 2, Mux(idxWritesEven, tgtPageReplEn, idxPageReplEn),
 | 
				
			||||||
      Mux(idxWritesEven, page(update_target), page(r_btb_update.bits.pc)))
 | 
					      Mux(idxWritesEven, page(update_target), page(r_btb_update.bits.pc)))
 | 
				
			||||||
 | 
					    pageValid := pageValid | tgtPageReplEn | idxPageReplEn
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  io.resp.valid := hits.orR
 | 
					  io.resp.valid := hits.orR
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user