From ce161b83e31bd6e1f1e703e595b796b80168538a Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 29 Jul 2015 15:03:13 -0700 Subject: [PATCH] Chisel3 compatibility: avoid subword assignment --- rocket/src/main/scala/btb.scala | 18 ++++++++++-------- rocket/src/main/scala/ptw.scala | 9 +++++---- rocket/src/main/scala/tlb.scala | 28 ++++++++++++++-------------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/rocket/src/main/scala/btb.scala b/rocket/src/main/scala/btb.scala index 33f5b468..3d1108a3 100644 --- a/rocket/src/main/scala/btb.scala +++ b/rocket/src/main/scala/btb.scala @@ -133,7 +133,7 @@ class BTB(updates_out_of_order: Boolean = false) extends Module with BTBParamete val invalidate = Bool(INPUT) } - val idxValid = Reg(init=UInt(0, entries)) + val idxValid = Reg(Vec(Bool(), entries)) val idxs = Mem(UInt(width=matchBits), entries) val idxPages = Mem(UInt(width=log2Up(nPages)), entries) val tgts = Mem(UInt(width=matchBits), entries) @@ -143,8 +143,8 @@ class BTB(updates_out_of_order: Boolean = false) extends Module with BTBParamete val idxPagesOH = idxPages.map(UIntToOH(_)(nPages-1,0)) val tgtPagesOH = tgtPages.map(UIntToOH(_)(nPages-1,0)) - val useRAS = Reg(UInt(width = entries)) - val isJump = Reg(UInt(width = entries)) + val useRAS = Reg(Vec(Bool(), entries)) + val isJump = Reg(Vec(Bool(), entries)) val brIdx = Mem(UInt(width=log2Up(params(FetchWidth))), entries) private def page(addr: UInt) = addr >> matchBits @@ -152,11 +152,12 @@ class BTB(updates_out_of_order: Boolean = false) extends Module with BTBParamete val p = page(addr) Vec(pages.map(_ === p)).toBits & pageValid } - private def tagMatch(addr: UInt, pgMatch: UInt): UInt = { + private def tagMatch(addr: UInt, pgMatch: UInt): Vec[Bool] = { val idx = addr(matchBits-1,0) val idxMatch = idxs.map(_ === idx).toBits val idxPageMatch = idxPagesOH.map(_ & pgMatch).map(_.orR).toBits - idxValid & idxMatch & idxPageMatch + Vec(for (i <- 0 until entries) + yield idxValid(i) && idxMatch(i) && idxPageMatch(i)) } val r_btb_update = Pipe(io.btb_update) @@ -198,11 +199,12 @@ class BTB(updates_out_of_order: Boolean = false) extends Module with BTBParamete val nextRepl = Counter(!updateHit, entries)._1 val waddr = - if (updates_out_of_order) Mux(updateHits.orR, OHToUInt(updateHits), nextRepl) + if (updates_out_of_order) Mux(updateHits.reduce(_||_), OHToUInt(updateHits), nextRepl) else Mux(updateHit, r_btb_update.bits.prediction.bits.entry, nextRepl) // invalidate entries if we stomp on pages they depend upon - idxValid := idxValid & ~Vec.tabulate(entries)(i => (pageReplEn & (idxPagesOH(i) | tgtPagesOH(i))).orR).toBits + for (i <- 0 until idxValid.size) + when ((pageReplEn & (idxPagesOH(i) | tgtPagesOH(i))).orR) { idxValid(i) := false } idxValid(waddr) := Bool(true) idxs(waddr) := r_btb_update.bits.pc @@ -237,7 +239,7 @@ class BTB(updates_out_of_order: Boolean = false) extends Module with BTBParamete pageValid := 0 } - io.resp.valid := hits.orR + io.resp.valid := hits.reduce(_||_) io.resp.bits.taken := io.resp.valid io.resp.bits.target := Cat(Mux1H(Mux1H(hits, tgtPagesOH), pages), Mux1H(hits, tgts)) io.resp.bits.entry := OHToUInt(hits) diff --git a/rocket/src/main/scala/ptw.scala b/rocket/src/main/scala/ptw.scala index 69fbf57e..518656a4 100644 --- a/rocket/src/main/scala/ptw.scala +++ b/rocket/src/main/scala/ptw.scala @@ -85,20 +85,21 @@ class PTW(n: Int) extends CoreModule val (pte_cache_hit, pte_cache_data) = { val size = log2Up(pgLevels * 2) val plru = new PseudoLRU(size) - val valid = Reg(init = Bits(0, size)) + val valid = Reg(init=Vec(Bool(), size)) + val validBits = valid.toBits val tags = Mem(UInt(width = paddrBits), size) val data = Mem(UInt(width = ppnBits), size) - val hits = Vec(tags.map(_ === pte_addr)).toBits & valid + val hits = Vec(tags.map(_ === pte_addr)).toBits & validBits val hit = hits.orR when (io.mem.resp.valid && pte.table() && !hit) { - val r = Mux(valid.andR, plru.replace, PriorityEncoder(~valid)) + val r = Mux(validBits.andR, plru.replace, PriorityEncoder(~validBits)) valid(r) := true tags(r) := pte_addr data(r) := pte.ppn } when (hit && state === s_req) { plru.access(OHToUInt(hits)) } - when (io.dpath.invalidate) { valid := 0 } + when (reset || io.dpath.invalidate) { valid.foreach(_ := false) } (hit, Mux1H(hits, data)) } diff --git a/rocket/src/main/scala/tlb.scala b/rocket/src/main/scala/tlb.scala index a5d87943..cd357fbb 100644 --- a/rocket/src/main/scala/tlb.scala +++ b/rocket/src/main/scala/tlb.scala @@ -119,18 +119,18 @@ class TLB extends TLBModule { val tag_hit_addr = OHToUInt(tag_cam.io.hits) // permission bit arrays - val valid_array = Reg(Bits()) // PTE is valid (not equivalent to CAM tag valid bit!) - val ur_array = Reg(Bits()) // user read permission - val uw_array = Reg(Bits()) // user write permission - val ux_array = Reg(Bits()) // user execute permission - val sr_array = Reg(Bits()) // supervisor read permission - val sw_array = Reg(Bits()) // supervisor write permission - val sx_array = Reg(Bits()) // supervisor execute permission - val dirty_array = Reg(Bits()) // PTE dirty bit + val valid_array = Reg(Vec(Bool(), entries)) // PTE is valid (not equivalent to CAM tag valid bit!) + val ur_array = Reg(Vec(Bool(), entries)) // user read permission + val uw_array = Reg(Vec(Bool(), entries)) // user write permission + val ux_array = Reg(Vec(Bool(), entries)) // user execute permission + val sr_array = Reg(Vec(Bool(), entries)) // supervisor read permission + val sw_array = Reg(Vec(Bool(), entries)) // supervisor write permission + val sx_array = Reg(Vec(Bool(), entries)) // supervisor execute permission + val dirty_array = Reg(Vec(Bool(), entries)) // PTE dirty bit when (io.ptw.resp.valid) { val pte = io.ptw.resp.bits.pte tag_ram(r_refill_waddr) := pte.ppn - valid_array := valid_array.bitSet(r_refill_waddr, !io.ptw.resp.bits.error) + valid_array(r_refill_waddr) := !io.ptw.resp.bits.error ur_array(r_refill_waddr) := pte.ur() && !io.ptw.resp.bits.error uw_array(r_refill_waddr) := pte.uw() && !io.ptw.resp.bits.error ux_array(r_refill_waddr) := pte.ux() && !io.ptw.resp.bits.error @@ -151,14 +151,14 @@ class TLB extends TLBModule { val priv_uses_vm = priv <= PRV_S val req_xwr = Cat(!r_req.store, r_req.store, !(r_req.instruction || r_req.store)) - val r_array = Mux(priv_s, sr_array, ur_array) - val w_array = Mux(priv_s, sw_array, uw_array) - val x_array = Mux(priv_s, sx_array, ux_array) + val r_array = Mux(priv_s, sr_array.toBits, ur_array.toBits) + val w_array = Mux(priv_s, sw_array.toBits, uw_array.toBits) + val x_array = Mux(priv_s, sx_array.toBits, ux_array.toBits) val vm_enabled = io.ptw.status.vm(3) && priv_uses_vm val bad_va = io.req.bits.vpn(vpnBits) != io.req.bits.vpn(vpnBits-1) // it's only a store hit if the dirty bit is set - val tag_hits = tag_cam.io.hits & (dirty_array | ~(io.req.bits.store.toSInt & w_array)) + val tag_hits = tag_cam.io.hits & (dirty_array.toBits | ~(io.req.bits.store.toSInt & w_array)) val tag_hit = tag_hits.orR val tlb_hit = vm_enabled && tag_hit val tlb_miss = vm_enabled && !tag_hit && !bad_va @@ -177,7 +177,7 @@ class TLB extends TLBModule { // clear invalid entries on access, or all entries on a TLB flush tag_cam.io.clear := io.ptw.invalidate || io.req.fire() - tag_cam.io.clear_mask := ~valid_array | (tag_cam.io.hits & ~tag_hits) + tag_cam.io.clear_mask := ~valid_array.toBits | (tag_cam.io.hits & ~tag_hits) when (io.ptw.invalidate) { tag_cam.io.clear_mask := SInt(-1) } io.ptw.req.valid := state === s_request