diff --git a/rocket/src/main/scala/btb.scala b/rocket/src/main/scala/btb.scala index 4cecf1d7..7cf4094f 100644 --- a/rocket/src/main/scala/btb.scala +++ b/rocket/src/main/scala/btb.scala @@ -5,13 +5,18 @@ import Util._ import Node._ import uncore._ -case object Entries extends Field[Int] +case object BTBEntries extends Field[Int] case object NRAS extends Field[Int] -case object MatchBits extends Field[Int] -case object Pages0 extends Field[Int] -case object Pages extends Field[Int] -case object OpaqueBits extends Field[Int] -case object NBHT extends Field[Int] + +abstract trait BTBParameters extends UsesParameters { + val vaddrBits = params(VAddrBits) + val matchBits = params(PgIdxBits) + val entries = params(BTBEntries) + val nRAS = params(NRAS) + val nPages = ((1 max(log2Up(entries)))+1)/2*2 // control logic assumes 2 divides pages + val opaqueBits = log2Up(entries) + val nBHT = 1 << log2Up(entries*2) +} class RAS(nras: Int) { def push(addr: UInt): Unit = { @@ -33,8 +38,8 @@ class RAS(nras: Int) { private val stack = Vec.fill(nras){Reg(UInt())} } -class BHTResp extends Bundle { - val index = UInt(width = log2Up(params(NBHT)).max(1)) +class BHTResp extends Bundle with BTBParameters { + val index = UInt(width = log2Up(nBHT).max(1)) val value = UInt(width = 2) } @@ -55,11 +60,11 @@ class BHT(nbht: Int) { val history = Reg(UInt(width = nbhtbits)) } -class BTBUpdate extends Bundle { +class BTBUpdate extends Bundle with BTBParameters { val prediction = Valid(new BTBResp) - val pc = UInt(width = params(VAddrBits)) - val target = UInt(width = params(VAddrBits)) - val returnAddr = UInt(width = params(VAddrBits)) + val pc = UInt(width = vaddrBits) + val target = UInt(width = vaddrBits) + val returnAddr = UInt(width = vaddrBits) val taken = Bool() val isJump = Bool() val isCall = Bool() @@ -67,42 +72,42 @@ class BTBUpdate extends Bundle { val incorrectTarget = Bool() } -class BTBResp extends Bundle { +class BTBResp extends Bundle with BTBParameters { val taken = Bool() - val target = UInt(width = params(VAddrBits)) - val entry = UInt(width = params(OpaqueBits)) + val target = UInt(width = vaddrBits) + val entry = UInt(width = opaqueBits) val bht = new BHTResp } // fully-associative branch target buffer -class BTB extends Module { +class BTB extends Module with BTBParameters { val io = new Bundle { - val req = UInt(INPUT, params(VAddrBits)) + val req = UInt(INPUT, vaddrBits) val resp = Valid(new BTBResp) val update = Valid(new BTBUpdate).flip val invalidate = Bool(INPUT) } - val idxValid = Reg(init=UInt(0, params(Entries))) - val idxs = Mem(UInt(width=params(MatchBits)), params(Entries)) - val idxPages = Mem(UInt(width=log2Up(params(Pages))), params(Entries)) - val tgts = Mem(UInt(width=params(MatchBits)), params(Entries)) - val tgtPages = Mem(UInt(width=log2Up(params(Pages))), params(Entries)) - val pages = Mem(UInt(width=params(VAddrBits)-params(MatchBits)), params(Pages)) - val pageValid = Reg(init=UInt(0, params(Pages))) - val idxPagesOH = idxPages.map(UIntToOH(_)(params(Pages)-1,0)) - val tgtPagesOH = tgtPages.map(UIntToOH(_)(params(Pages)-1,0)) + val idxValid = Reg(init=UInt(0, entries)) + val idxs = Mem(UInt(width=matchBits), entries) + val idxPages = Mem(UInt(width=log2Up(nPages)), entries) + val tgts = Mem(UInt(width=matchBits), entries) + val tgtPages = Mem(UInt(width=log2Up(nPages)), entries) + val pages = Mem(UInt(width=vaddrBits-matchBits), nPages) + val pageValid = Reg(init=UInt(0, nPages)) + val idxPagesOH = idxPages.map(UIntToOH(_)(nPages-1,0)) + val tgtPagesOH = tgtPages.map(UIntToOH(_)(nPages-1,0)) - val useRAS = Reg(UInt(width = params(Entries))) - val isJump = Reg(UInt(width = params(Entries))) + val useRAS = Reg(UInt(width = entries)) + val isJump = Reg(UInt(width = entries)) - private def page(addr: UInt) = addr >> params(MatchBits) + private def page(addr: UInt) = addr >> matchBits private def pageMatch(addr: UInt) = { val p = page(addr) Vec(pages.map(_ === p)).toBits & pageValid } private def tagMatch(addr: UInt, pgMatch: UInt): UInt = { - val idx = addr(params(MatchBits)-1,0) + val idx = addr(matchBits-1,0) val idxMatch = idxs.map(_ === idx).toBits val idxPageMatch = idxPagesOH.map(_ & pgMatch).map(_.orR).toBits idxValid & idxMatch & idxPageMatch @@ -123,7 +128,7 @@ class BTB extends Module { } val updateHit = update.bits.prediction.valid - val updateValid = update.bits.incorrectTarget || updateHit && Bool(params(NBHT) > 0) + val updateValid = update.bits.incorrectTarget || updateHit && Bool(nBHT > 0) val updateTarget = updateValid && update.bits.incorrectTarget val useUpdatePageHit = updatePageHit.orR @@ -136,20 +141,20 @@ class BTB extends Module { val samePage = page(update.bits.pc) === page(update_target) val usePageHit = (pageHit & ~idxPageReplEn).orR val doTgtPageRepl = updateTarget && !samePage && !usePageHit - val tgtPageRepl = Mux(samePage, idxPageUpdateOH, idxPageUpdateOH(params(Pages)-2,0) << 1 | idxPageUpdateOH(params(Pages)-1)) + val tgtPageRepl = Mux(samePage, idxPageUpdateOH, idxPageUpdateOH(nPages-2,0) << 1 | idxPageUpdateOH(nPages-1)) val tgtPageUpdate = OHToUInt(Mux(usePageHit, pageHit, tgtPageRepl)) val tgtPageReplEn = Mux(doTgtPageRepl, tgtPageRepl, UInt(0)) val doPageRepl = doIdxPageRepl || doTgtPageRepl val pageReplEn = idxPageReplEn | tgtPageReplEn - idxPageRepl := UIntToOH(Counter(update.valid && doPageRepl, params(Pages))._1) + idxPageRepl := UIntToOH(Counter(update.valid && doPageRepl, nPages)._1) when (update.valid && !(updateValid && !updateTarget)) { - val nextRepl = Counter(!updateHit && updateValid, params(Entries))._1 + val nextRepl = Counter(!updateHit && updateValid, entries)._1 val waddr = Mux(updateHit, update.bits.prediction.bits.entry, nextRepl) // invalidate entries if we stomp on pages they depend upon - idxValid := idxValid & ~Vec.tabulate(params(Entries))(i => (pageReplEn & (idxPagesOH(i) | tgtPagesOH(i))).orR).toBits + idxValid := idxValid & ~Vec.tabulate(entries)(i => (pageReplEn & (idxPagesOH(i) | tgtPagesOH(i))).orR).toBits idxValid(waddr) := updateValid when (updateTarget) { @@ -162,11 +167,11 @@ class BTB extends Module { isJump(waddr) := update.bits.isJump } - require(params(Pages) % 2 == 0) - val idxWritesEven = (idxPageUpdateOH & Fill(params(Pages)/2, UInt(1,2))).orR + require(nPages % 2 == 0) + val idxWritesEven = (idxPageUpdateOH & Fill(nPages/2, UInt(1,2))).orR def writeBank(i: Int, mod: Int, en: Bool, data: UInt) = - for (i <- i until params(Pages) by mod) + for (i <- i until nPages by mod) when (en && pageReplEn(i)) { pages(i) := data } writeBank(0, 2, Mux(idxWritesEven, doIdxPageRepl, doTgtPageRepl), @@ -187,16 +192,16 @@ class BTB extends Module { io.resp.bits.target := Cat(Mux1H(Mux1H(hits, tgtPagesOH), pages), Mux1H(hits, tgts)) io.resp.bits.entry := OHToUInt(hits) - if (params(NBHT) > 0) { - val bht = new BHT(params(NBHT)) + if (nBHT > 0) { + val bht = new BHT(nBHT) val res = bht.get(io.req) when (update.valid && updateHit && !update.bits.isJump) { bht.update(update.bits.prediction.bits.bht, update.bits.taken) } when (!res.value(0) && !Mux1H(hits, isJump)) { io.resp.bits.taken := false } io.resp.bits.bht := res } - if (params(NRAS) > 0) { - val ras = new RAS(params(NRAS)) + if (nRAS > 0) { + val ras = new RAS(nRAS) val doPeek = Mux1H(hits, useRAS) when (!ras.isEmpty && doPeek) { io.resp.bits.target := ras.peek diff --git a/rocket/src/main/scala/core.scala b/rocket/src/main/scala/core.scala index c9ec77a7..0b22b42a 100644 --- a/rocket/src/main/scala/core.scala +++ b/rocket/src/main/scala/core.scala @@ -24,7 +24,8 @@ class Core extends Module val dpath = Module(new Datapath) if (!params(BuildFPU).isEmpty) { - val fpu = Module(params(BuildFPU).get(),params(FPUParams)) + val p = Some(params.alter(params(FPUParams))) + val fpu = Module(params(BuildFPU).get())(p) dpath.io.fpu <> fpu.io.dpath ctrl.io.fpu <> fpu.io.ctrl } diff --git a/rocket/src/main/scala/csr.scala b/rocket/src/main/scala/csr.scala index c15a3389..5a2cd7cf 100644 --- a/rocket/src/main/scala/csr.scala +++ b/rocket/src/main/scala/csr.scala @@ -160,7 +160,7 @@ class CSRFile extends Module when (host_pcr_req_fire && !host_pcr_bits.rw && decoded_addr(CSRs.tohost)) { reg_tohost := UInt(0) } val read_impl = Bits(2) - val read_ptbr = reg_ptbr(params(PAddrBits)-1, params(PgIdxBits)) << params(PgIdxBits) + val read_ptbr = reg_ptbr(params(PAddrBits)-1, params(PgIdxBits)) << UInt(params(PgIdxBits)) val read_mapping = collection.mutable.LinkedHashMap[Int,Bits]( CSRs.fflags -> (if (!params(BuildFPU).isEmpty) reg_fflags else UInt(0)), diff --git a/rocket/src/main/scala/ctrl.scala b/rocket/src/main/scala/ctrl.scala index 1073019c..78396897 100644 --- a/rocket/src/main/scala/ctrl.scala +++ b/rocket/src/main/scala/ctrl.scala @@ -43,7 +43,7 @@ class CtrlDpathIO extends Bundle // exception handling val retire = Bool(OUTPUT) val exception = Bool(OUTPUT) - val cause = UInt(OUTPUT, params[Int]("xprlen")) + val cause = UInt(OUTPUT, params(XprLen)) val badvaddr_wen = Bool(OUTPUT) // high for a load/store access fault // inputs from datapath val inst = Bits(INPUT, 32) @@ -401,7 +401,7 @@ class Control extends Module val id_reg_fence = Reg(init=Bool(false)) val sr = io.dpath.status - var id_interrupts = (0 until sr.ip.getWidth).map(i => (sr.im(i) && sr.ip(i), UInt(BigInt(1) << (params[Int]("xprlen")-1) | i))) + var id_interrupts = (0 until sr.ip.getWidth).map(i => (sr.im(i) && sr.ip(i), UInt(BigInt(1) << (params(XprLen)-1) | i))) val (id_interrupt_unmasked, id_interrupt_cause) = checkExceptions(id_interrupts) val id_interrupt = io.dpath.status.ei && id_interrupt_unmasked @@ -437,7 +437,7 @@ class Control extends Module val id_amo_rl = io.dpath.inst(25) val id_fence_next = id_fence || id_amo && id_amo_rl val id_mem_busy = !io.dmem.ordered || ex_reg_mem_val - val id_rocc_busy = Bool(params[Boolean]("HasRoCC")) && + val id_rocc_busy = Bool(!params(BuildRoCC).isEmpty) && (io.rocc.busy || ex_reg_rocc_val || mem_reg_rocc_val || wb_reg_rocc_val) id_reg_fence := id_fence_next || id_reg_fence && id_mem_busy val id_do_fence = id_rocc_busy && id_fence || @@ -690,7 +690,7 @@ class Control extends Module // stall for RAW/WAW hazards on PCRs, LB/LH, and mul/div in memory stage. val mem_mem_cmd_bh = - if (params[Boolean]("fastLoadWord")) Bool(!params[Boolean]("fastLoadByte")) && mem_reg_slow_bypass + if (params(FastLoadWord)) Bool(!params(FastLoadByte)) && mem_reg_slow_bypass else Bool(true) val data_hazard_mem = mem_reg_wen && (id_renx1_not0 && id_raddr1 === io.dpath.mem_waddr || diff --git a/rocket/src/main/scala/icache.scala b/rocket/src/main/scala/icache.scala index 43035d55..aa9af2a9 100644 --- a/rocket/src/main/scala/icache.scala +++ b/rocket/src/main/scala/icache.scala @@ -7,19 +7,27 @@ import Util._ case object InstBytes extends Field[Int] case object CoreBTBParams extends Field[PF] -class FrontendReq extends Bundle { - val pc = UInt(width = params(VAddrBits)+1) +abstract trait FrontendParameters extends CacheParameters { + val instBytes = params(InstBytes) + val co = params(TLCoherence) + val code = params(ECCCode) +} + +abstract class FrontendBundle extends Bundle with FrontendParameters +abstract class FrontendModule extends Module with FrontendParameters + +class FrontendReq extends FrontendBundle { + val pc = UInt(width = vaddrBits+1) } -class FrontendResp extends Bundle { - val pc = UInt(width = params(VAddrBits)+1) // ID stage PC - val data = Bits(width = params(InstBytes)*8) +class FrontendResp extends FrontendBundle { + val pc = UInt(width = vaddrBits+1) // ID stage PC + val data = Bits(width = instBytes*8) val xcpt_ma = Bool() val xcpt_if = Bool() } -class CPUFrontendIO extends Bundle { - params.alter(params(CoreBTBParams)) +class CPUFrontendIO extends FrontendBundle { val req = Valid(new FrontendReq) val resp = Decoupled(new FrontendResp).flip val btb_resp = Valid(new BTBResp).flip @@ -28,14 +36,14 @@ class CPUFrontendIO extends Bundle { val invalidate = Bool(OUTPUT) } -class Frontend extends Module +class Frontend extends FrontendModule { val io = new Bundle { val cpu = new CPUFrontendIO().flip val mem = new UncachedTileLinkIO } - val btb = Module(new BTB, params(CoreBTBParams)) + val btb = Module(new BTB) val icache = Module(new ICache) val tlb = Module(new TLB(params(NTLBEntries))) @@ -48,14 +56,14 @@ class Frontend extends Module val s2_btb_resp_bits = Reg(btb.io.resp.bits.clone) val s2_xcpt_if = Reg(init=Bool(false)) - val msb = params(VAddrBits)-1 + val msb = vaddrBits-1 val btbTarget = Cat(btb.io.resp.bits.target(msb), btb.io.resp.bits.target) - val pcp4_0 = s1_pc + UInt(params(InstBytes)) + val pcp4_0 = s1_pc + UInt(instBytes) val pcp4 = Cat(s1_pc(msb) & pcp4_0(msb), pcp4_0(msb,0)) val icmiss = s2_valid && !icache.io.resp.valid val predicted_npc = Mux(btb.io.resp.bits.taken, btbTarget, pcp4) val npc = Mux(icmiss, s2_pc, predicted_npc).toUInt - val s0_same_block = !icmiss && !io.cpu.req.valid && !btb.io.resp.bits.taken && ((pcp4 & params(RowBytes)) === (s1_pc & params(RowBytes))) + val s0_same_block = !icmiss && !io.cpu.req.valid && !btb.io.resp.bits.taken && ((pcp4 & rowBytes) === (s1_pc & rowBytes)) val stall = io.cpu.resp.valid && !io.cpu.resp.ready when (!stall) { @@ -75,13 +83,13 @@ class Frontend extends Module s2_valid := Bool(false) } - btb.io.req := s1_pc & SInt(-params(InstBytes)) + btb.io.req := s1_pc & SInt(-instBytes) btb.io.update := io.cpu.btb_update btb.io.invalidate := io.cpu.invalidate || io.cpu.ptw.invalidate tlb.io.ptw <> io.cpu.ptw tlb.io.req.valid := !stall && !icmiss - tlb.io.req.bits.vpn := s1_pc >> UInt(params(PgIdxBits)) + tlb.io.req.bits.vpn := s1_pc >> UInt(pgIdxBits) tlb.io.req.bits.asid := UInt(0) tlb.io.req.bits.passthrough := Bool(false) tlb.io.req.bits.instruction := Bool(true) @@ -95,29 +103,28 @@ class Frontend extends Module icache.io.resp.ready := !stall && !s1_same_block io.cpu.resp.valid := s2_valid && (s2_xcpt_if || icache.io.resp.valid) - io.cpu.resp.bits.pc := s2_pc & SInt(-params(InstBytes)) // discard PC LSBs - io.cpu.resp.bits.data := icache.io.resp.bits.datablock >> (s2_pc(log2Up(params(RowBytes))-1,log2Up(params(InstBytes))) << log2Up(params(InstBytes)*8)) - io.cpu.resp.bits.xcpt_ma := s2_pc(log2Up(params(InstBytes))-1,0) != UInt(0) + io.cpu.resp.bits.pc := s2_pc & SInt(-instBytes) // discard PC LSBs + io.cpu.resp.bits.data := icache.io.resp.bits.datablock >> (s2_pc(log2Up(rowBytes)-1,log2Up(instBytes)) << log2Up(instBytes*8)) + io.cpu.resp.bits.xcpt_ma := s2_pc(log2Up(instBytes)-1,0) != UInt(0) io.cpu.resp.bits.xcpt_if := s2_xcpt_if io.cpu.btb_resp.valid := s2_btb_resp_valid io.cpu.btb_resp.bits := s2_btb_resp_bits } -class ICacheReq extends Bundle { - val idx = UInt(width = params(PgIdxBits)) +class ICacheReq extends FrontendBundle { + val idx = UInt(width = pgIdxBits) val ppn = UInt(width = params(PPNBits)) // delayed one cycle val kill = Bool() // delayed one cycle } -class ICacheResp extends Bundle { - val data = Bits(width = params(InstBytes)*8) - val datablock = Bits(width = params(RowBits)) +class ICacheResp extends FrontendBundle { + val data = Bits(width = instBytes*8) + val datablock = Bits(width = rowBits) } -class ICache extends Module +class ICache extends FrontendModule { - val (nSets, nWays, co, ecc) = (params(NSets), params(NWays), params(TLCoherence), params(ECCCode)) val io = new Bundle { val req = Valid(new ICacheReq).flip val resp = Decoupled(new ICacheResp) @@ -125,8 +132,8 @@ class ICache extends Module val mem = new UncachedTileLinkIO } require(isPow2(nSets) && isPow2(nWays)) - require(isPow2(params(InstBytes))) - require(params(PgIdxBits) >= params(UntagBits)) + require(isPow2(instBytes)) + require(pgIdxBits >= untagBits) val s_ready :: s_request :: s_refill_wait :: s_refill :: Nil = Enum(UInt(), 4) val state = Reg(init=s_ready) @@ -135,13 +142,13 @@ class ICache extends Module val rdy = Bool() val s2_valid = Reg(init=Bool(false)) - val s2_addr = Reg(UInt(width = params(PAddrBits))) + val s2_addr = Reg(UInt(width = paddrBits)) val s2_any_tag_hit = Bool() val s1_valid = Reg(init=Bool(false)) - val s1_pgoff = Reg(UInt(width = params(PgIdxBits))) + val s1_pgoff = Reg(UInt(width = pgIdxBits)) val s1_addr = Cat(io.req.bits.ppn, s1_pgoff).toUInt - val s1_tag = s1_addr(params(TagBits)+params(UntagBits)-1,params(UntagBits)) + val s1_tag = s1_addr(tagBits+untagBits-1,untagBits) val s0_valid = io.req.valid || s1_valid && stall val s0_pgoff = Mux(s1_valid && stall, s1_pgoff, io.req.bits.idx) @@ -156,9 +163,9 @@ class ICache extends Module s2_addr := s1_addr } - val s2_tag = s2_addr(params(TagBits)+params(UntagBits)-1,params(UntagBits)) - val s2_idx = s2_addr(params(UntagBits)-1,params(OffBits)) - val s2_offset = s2_addr(params(OffBits)-1,0) + val s2_tag = s2_addr(tagBits+untagBits-1,untagBits) + val s2_idx = s2_addr(untagBits-1,blockOffBits) + val s2_offset = s2_addr(blockOffBits-1,0) val s2_hit = s2_valid && s2_any_tag_hit val s2_miss = s2_valid && !s2_any_tag_hit rdy := state === s_ready && !s2_miss @@ -168,8 +175,8 @@ class ICache extends Module var refill_valid = io.mem.grant.valid var refill_bits = io.mem.grant.bits def doRefill(g: Grant): Bool = Bool(true) - if(params(RefillCycles) > 1) { - val ser = Module(new FlowThroughSerializer(io.mem.grant.bits, params(RefillCycles), doRefill)) + if(refillCycles > 1) { + val ser = Module(new FlowThroughSerializer(io.mem.grant.bits, refillCycles, doRefill)) ser.io.in <> io.mem.grant refill_cnt = ser.io.cnt refill_done = ser.io.done @@ -181,18 +188,18 @@ class ICache extends Module } //assert(!c.tlco.isVoluntary(refill_bits.payload) || !refill_valid, "UncachedRequestors shouldn't get voluntary grants.") - val repl_way = if (params(IsDM)) UInt(0) else LFSR16(s2_miss)(log2Up(nWays)-1,0) - val entagbits = ecc.width(params(TagBits)) + val repl_way = if (isDM) UInt(0) else LFSR16(s2_miss)(log2Up(nWays)-1,0) + val entagbits = code.width(tagBits) val tag_array = Mem(Bits(width = entagbits*nWays), nSets, seqRead = true) val tag_raddr = Reg(UInt()) when (refill_done) { - val wmask = FillInterleaved(entagbits, if (params(IsDM)) Bits(1) else UIntToOH(repl_way)) - val tag = ecc.encode(s2_tag).toUInt + val wmask = FillInterleaved(entagbits, if (isDM) Bits(1) else UIntToOH(repl_way)) + val tag = code.encode(s2_tag).toUInt tag_array.write(s2_idx, Fill(nWays, tag), wmask) } // /*.else*/when (s0_valid) { // uncomment ".else" to infer 6T SRAM .elsewhen (s0_valid) { - tag_raddr := s0_pgoff(params(UntagBits)-1,params(OffBits)) + tag_raddr := s0_pgoff(untagBits-1,blockOffBits) } val vb_array = Reg(init=Bits(0, nSets*nWays)) @@ -212,38 +219,38 @@ class ICache extends Module val s2_dout = Vec.fill(nWays){Reg(Bits())} for (i <- 0 until nWays) { - val s1_vb = vb_array(Cat(UInt(i), s1_pgoff(params(UntagBits)-1,params(OffBits)))).toBool + val s1_vb = vb_array(Cat(UInt(i), s1_pgoff(untagBits-1,blockOffBits))).toBool val s2_vb = Reg(Bool()) val s2_tag_disparity = Reg(Bool()) val s2_tag_match = Reg(Bool()) val tag_out = tag_array(tag_raddr)(entagbits*(i+1)-1, entagbits*i) when (s1_valid && rdy && !stall) { s2_vb := s1_vb - s2_tag_disparity := ecc.decode(tag_out).error + s2_tag_disparity := code.decode(tag_out).error s2_tag_match := s1_tag_match(i) } - s1_tag_match(i) := tag_out(params(TagBits)-1,0) === s1_tag + s1_tag_match(i) := tag_out(tagBits-1,0) === s1_tag s2_tag_hit(i) := s2_vb && s2_tag_match - s2_disparity(i) := s2_vb && (s2_tag_disparity || ecc.decode(s2_dout(i)).error) + s2_disparity(i) := s2_vb && (s2_tag_disparity || code.decode(s2_dout(i)).error) } s2_any_tag_hit := s2_tag_hit.reduceLeft(_||_) && !s2_disparity.reduceLeft(_||_) for (i <- 0 until nWays) { - val data_array = Mem(Bits(width = ecc.width(params(RowBits))), nSets*params(RefillCycles), seqRead = true) + val data_array = Mem(Bits(width = code.width(rowBits)), nSets*refillCycles, seqRead = true) val s1_raddr = Reg(UInt()) when (refill_valid && repl_way === UInt(i)) { - val e_d = ecc.encode(refill_bits.payload.data) - if(params(RefillCycles) > 1) data_array(Cat(s2_idx,refill_cnt)) := e_d + val e_d = code.encode(refill_bits.payload.data) + if(refillCycles > 1) data_array(Cat(s2_idx,refill_cnt)) := e_d else data_array(s2_idx) := e_d } // /*.else*/when (s0_valid) { // uncomment ".else" to infer 6T SRAM .elsewhen (s0_valid) { - s1_raddr := s0_pgoff(params(UntagBits)-1,params(OffBits)-(if(params(RefillCycles) > 1) refill_cnt.getWidth else 0)) + s1_raddr := s0_pgoff(untagBits-1,blockOffBits-(if(refillCycles > 1) refill_cnt.getWidth else 0)) } // if s1_tag_match is critical, replace with partial tag check - when (s1_valid && rdy && !stall && (Bool(params(IsDM)) || s1_tag_match(i))) { s2_dout(i) := data_array(s1_raddr) } + when (s1_valid && rdy && !stall && (Bool(isDM) || s1_tag_match(i))) { s2_dout(i) := data_array(s1_raddr) } } - val s2_dout_word = s2_dout.map(x => (x >> (s2_offset(log2Up(params(RowBytes))-1,log2Up(params(InstBytes))) << log2Up(params(InstBytes)*8)))(params(InstBytes)*8-1,0)) + val s2_dout_word = s2_dout.map(x => (x >> (s2_offset(log2Up(rowBytes)-1,log2Up(instBytes)) << log2Up(instBytes*8)))(instBytes*8-1,0)) io.resp.bits.data := Mux1H(s2_tag_hit, s2_dout_word) io.resp.bits.datablock := Mux1H(s2_tag_hit, s2_dout) @@ -255,7 +262,7 @@ class ICache extends Module // output signals io.resp.valid := s2_hit io.mem.acquire.valid := (state === s_request) && ack_q.io.enq.ready - io.mem.acquire.bits.payload := Acquire(co.getUncachedReadAcquireType, s2_addr >> UInt(params(OffBits)), UInt(0)) + io.mem.acquire.bits.payload := Acquire(co.getUncachedReadAcquireType, s2_addr >> UInt(blockOffBits), UInt(0)) io.mem.finish <> ack_q.io.deq // control state machine diff --git a/rocket/src/main/scala/nbdcache.scala b/rocket/src/main/scala/nbdcache.scala index 0a33d01d..3e54eac9 100644 --- a/rocket/src/main/scala/nbdcache.scala +++ b/rocket/src/main/scala/nbdcache.scala @@ -4,26 +4,35 @@ import Chisel._ import uncore._ import Util._ -//Knobs case object StoreDataQueueDepth extends Field[Int] case object ReplayQueueDepth extends Field[Int] case object NMSHRs extends Field[Int] case object NTLBEntries extends Field[Int] case object CoreReqTagBits extends Field[Int] case object CoreDataBits extends Field[Int] -case object RowWords extends Field[Int] case object ECCCode extends Field[Code] -//Derived -case object MaxAddrBits extends Field[Int] -case object CoreDataBytes extends Field[Int] -case object WordOffBits extends Field[Int] -case object RowBytes extends Field[Int] -case object RowOffBits extends Field[Int] -case object DoNarrowRead extends Field[Int] -case object EncDataBits extends Field[Int] -case object EncRowBits extends Field[Int] case object LRSCCycles extends Field[Int] +abstract trait L1HellaCacheParameters extends CacheParameters { + val indexmsb = untagBits-1 + val indexlsb = blockOffBits + val offsetmsb = indexlsb-1 + val offsetlsb = wordOffBits + + val co = params(TLCoherence) + val code = params(ECCCode) + val coreReqTagBits = params(CoreReqTagBits) + val coreDataBits = params(CoreDataBits) + val maxAddrBits = math.max(params(PPNBits),params(VPNBits)+1) + params(PgIdxBits) + val coreDataBytes = coreDataBits/8 + val doNarrowRead = coreDataBits * nWays % rowBits == 0 + val encDataBits = code.width(coreDataBits) + val encRowBits = encDataBits*rowWords +} + +abstract class L1HellaCacheBundle extends Bundle with L1HellaCacheParameters +abstract class L1HellaCacheModule extends Module with L1HellaCacheParameters + class StoreGen(typ: Bits, addr: Bits, dat: Bits) { val byte = typ === MT_B || typ === MT_BU @@ -56,28 +65,71 @@ class LoadGen(typ: Bits, addr: Bits, dat: Bits, zero: Bool) val byte = Cat(Mux(zero || t.byte, Fill(56, sign && byteShift(7)), half(63,8)), byteShift) } +class HellaCacheReq extends L1HellaCacheBundle { + val kill = Bool() + val typ = Bits(width = MT_SZ) + val phys = Bool() + val addr = UInt(width = maxAddrBits) + val data = Bits(width = coreDataBits) + val tag = Bits(width = coreReqTagBits) + val cmd = Bits(width = M_SZ) +} + +class HellaCacheResp extends L1HellaCacheBundle { + val nack = Bool() // comes 2 cycles after req.fire + val replay = Bool() + val typ = Bits(width = 3) + val has_data = Bool() + val data = Bits(width = coreDataBits) + val data_subword = Bits(width = coreDataBits) + val tag = Bits(width = coreReqTagBits) + val cmd = Bits(width = 4) + val addr = UInt(width = maxAddrBits) + val store_data = Bits(width = coreDataBits) +} + +class AlignmentExceptions extends Bundle { + val ld = Bool() + val st = Bool() +} + +class HellaCacheExceptions extends Bundle { + val ma = new AlignmentExceptions + val pf = new AlignmentExceptions +} + +// interface between D$ and processor/DTLB +class HellaCacheIO extends L1HellaCacheBundle { + val req = Decoupled(new HellaCacheReq) + val resp = Valid(new HellaCacheResp).flip + val replay_next = Valid(Bits(width = coreReqTagBits)).flip + val xcpt = (new HellaCacheExceptions).asInput + val ptw = new TLBPTWIO().flip + val ordered = Bool(INPUT) +} + class MSHRReq extends HellaCacheReq { val tag_match = Bool() val old_meta = new L1Metadata - val way_en = Bits(width = params(NWays)) + val way_en = Bits(width = nWays) } class Replay extends HellaCacheReq { val sdq_id = UInt(width = log2Up(params(StoreDataQueueDepth))) } -class DataReadReq extends Bundle { - val way_en = Bits(width = params(NWays)) - val addr = Bits(width = params(UntagBits)) +class DataReadReq extends L1HellaCacheBundle { + val way_en = Bits(width = nWays) + val addr = Bits(width = untagBits) } class DataWriteReq extends DataReadReq { - val wmask = Bits(width = params(RowWords)) - val data = Bits(width = params(EncRowBits)) + val wmask = Bits(width = rowWords) + val data = Bits(width = encRowBits) } class L1MetaReadReq extends MetaReadReq { - val tag = Bits(width = params(TagBits)) + val tag = Bits(width = tagBits) } class L1MetaWriteReq extends @@ -91,23 +143,22 @@ object L1Metadata { meta } } -class L1Metadata extends Metadata { - val coh = params(TLCoherence).clientMetadataOnFlush.clone +class L1Metadata extends Metadata with L1HellaCacheParameters { + val coh = co.clientMetadataOnFlush.clone } class InternalProbe extends Probe with HasClientTransactionId -class WritebackReq extends Bundle { - val tag = Bits(width = params(TagBits)) - val idx = Bits(width = params(IdxBits)) - val way_en = Bits(width = params(NWays)) +class WritebackReq extends L1HellaCacheBundle { + val tag = Bits(width = tagBits) + val idx = Bits(width = idxBits) + val way_en = Bits(width = nWays) val client_xact_id = Bits(width = params(TLClientXactIdBits)) val master_xact_id = Bits(width = params(TLMasterXactIdBits)) - val r_type = UInt(width = params(TLCoherence).releaseTypeWidth) + val r_type = UInt(width = co.releaseTypeWidth) } -class MSHR(id: Int) extends Module { - val co = params(TLCoherence) +class MSHR(id: Int) extends L1HellaCacheModule { val io = new Bundle { val req_pri_val = Bool(INPUT) val req_pri_rdy = Bool(OUTPUT) @@ -117,7 +168,7 @@ class MSHR(id: Int) extends Module { val req_sdq_id = UInt(INPUT, log2Up(params(StoreDataQueueDepth))) val idx_match = Bool(OUTPUT) - val tag = Bits(OUTPUT, params(TagBits)) + val tag = Bits(OUTPUT, tagBits) val mem_req = Decoupled(new Acquire) val mem_resp = new DataWriteReq().asOutput @@ -136,17 +187,17 @@ class MSHR(id: Int) extends Module { val acquire_type = Reg(UInt()) val release_type = Reg(UInt()) val line_state = Reg(new ClientMetadata()(co)) - val refill_count = Reg(UInt(width = log2Up(params(RefillCycles)))) // TODO: zero-width wire + val refill_count = Reg(UInt(width = log2Up(refillCycles))) // TODO: zero-width wire val req = Reg(new MSHRReq()) val req_cmd = io.req_bits.cmd - val req_idx = req.addr(params(UntagBits)-1,params(OffBits)) - val idx_match = req_idx === io.req_bits.addr(params(UntagBits)-1,params(OffBits)) + val req_idx = req.addr(untagBits-1,blockOffBits) + val idx_match = req_idx === io.req_bits.addr(untagBits-1,blockOffBits) val sec_rdy = idx_match && (state === s_wb_req || state === s_wb_resp || state === s_meta_clear || (state === s_refill_req || state === s_refill_resp) && !co.needsTransactionOnSecondaryMiss(req_cmd, io.mem_req.bits)) - require(isPow2(params(RefillCycles))) + require(isPow2(refillCycles)) val reply = io.mem_grant.valid && io.mem_grant.bits.payload.client_xact_id === UInt(id) - val refill_done = reply && (if(params(RefillCycles) > 1) refill_count.andR else Bool(true)) + val refill_done = reply && (if(refillCycles > 1) refill_count.andR else Bool(true)) val wb_done = reply && (state === s_wb_resp) val meta_on_flush = co.clientMetadataOnFlush @@ -172,7 +223,7 @@ class MSHR(id: Int) extends Module { when (state === s_refill_resp) { when (refill_done) { state := s_meta_write_req } when (reply) { - if(params(RefillCycles) > 1) refill_count := refill_count + UInt(1) + if(refillCycles > 1) refill_count := refill_count + UInt(1) line_state := meta_on_grant } } @@ -222,8 +273,8 @@ class MSHR(id: Int) extends Module { io.idx_match := (state != s_invalid) && idx_match io.mem_resp := req - io.mem_resp.addr := (if(params(RefillCycles) > 1) Cat(req_idx, refill_count) else req_idx) << params(RowOffBits) - io.tag := req.addr >> params(UntagBits) + io.mem_resp.addr := (if(refillCycles > 1) Cat(req_idx, refill_count) else req_idx) << rowOffBits + io.tag := req.addr >> untagBits io.req_pri_rdy := state === s_invalid io.req_sec_rdy := sec_rdy && rpq.io.enq.ready @@ -259,7 +310,7 @@ class MSHR(id: Int) extends Module { io.replay.valid := state === s_drain_rpq && rpq.io.deq.valid io.replay.bits := rpq.io.deq.bits io.replay.bits.phys := Bool(true) - io.replay.bits.addr := Cat(io.tag, req_idx, rpq.io.deq.bits.addr(params(OffBits)-1,0)).toUInt + io.replay.bits.addr := Cat(io.tag, req_idx, rpq.io.deq.bits.addr(blockOffBits-1,0)).toUInt when (!io.meta_read.ready) { rpq.io.deq.ready := Bool(false) @@ -267,7 +318,7 @@ class MSHR(id: Int) extends Module { } } -class MSHRFile extends Module { +class MSHRFile extends L1HellaCacheModule { val io = new Bundle { val req = Decoupled(new MSHRReq).flip val secondary_miss = Bool(OUTPUT) @@ -294,7 +345,7 @@ class MSHRFile extends Module { val idxMatch = Vec.fill(params(NMSHRs)){Bool()} val tagList = Vec.fill(params(NMSHRs)){Bits()} - val tag_match = Mux1H(idxMatch, tagList) === io.req.bits.addr >> params(UntagBits) + val tag_match = Mux1H(idxMatch, tagList) === io.req.bits.addr >> untagBits val wbTagList = Vec.fill(params(NMSHRs)){Bits()} val memRespMux = Vec.fill(params(NMSHRs)){new DataWriteReq} @@ -367,20 +418,19 @@ class MSHRFile extends Module { } } - -class WritebackUnit extends Module { +class WritebackUnit extends L1HellaCacheModule { val io = new Bundle { val req = Decoupled(new WritebackReq()).flip val meta_read = Decoupled(new L1MetaReadReq) val data_req = Decoupled(new DataReadReq()) - val data_resp = Bits(INPUT, params(EncRowBits)) + val data_resp = Bits(INPUT, encRowBits) val release = Decoupled(new Release) } val active = Reg(init=Bool(false)) val r1_data_req_fired = Reg(init=Bool(false)) val r2_data_req_fired = Reg(init=Bool(false)) - val cnt = Reg(init = UInt(0, width = log2Up(params(RefillCycles)+1))) + val cnt = Reg(init = UInt(0, width = log2Up(refillCycles+1))) val req = Reg(new WritebackReq) io.release.valid := false @@ -391,8 +441,8 @@ class WritebackUnit extends Module { r1_data_req_fired := true cnt := cnt + 1 } - if(params(RefillCycles) > 1) { // Coalescing buffer inserted - when (!r1_data_req_fired && !r2_data_req_fired && cnt === params(RefillCycles)) { + if(refillCycles > 1) { // Coalescing buffer inserted + when (!r1_data_req_fired && !r2_data_req_fired && cnt === refillCycles) { io.release.valid := true active := !io.release.ready } @@ -415,7 +465,7 @@ class WritebackUnit extends Module { req := io.req.bits } - val fire = active && cnt < UInt(params(RefillCycles)) + val fire = active && cnt < UInt(refillCycles) io.req.ready := !active // We reissue the meta read as it sets up the muxing for s2_data_muxed @@ -425,20 +475,20 @@ class WritebackUnit extends Module { io.data_req.valid := fire io.data_req.bits.way_en := req.way_en - if(params(RefillCycles) > 1) { - io.data_req.bits.addr := Cat(req.idx, cnt(log2Up(params(RefillCycles))-1,0)) << params(RowOffBits) + if(refillCycles > 1) { + io.data_req.bits.addr := Cat(req.idx, cnt(log2Up(refillCycles)-1,0)) << rowOffBits } else { - io.data_req.bits.addr := req.idx << params(RowOffBits) + io.data_req.bits.addr := req.idx << rowOffBits } io.release.bits.r_type := req.r_type io.release.bits.addr := Cat(req.tag, req.idx).toUInt io.release.bits.client_xact_id := req.client_xact_id io.release.bits.master_xact_id := req.master_xact_id - if(params(RefillCycles) > 1) { + if(refillCycles > 1) { val data_buf = Reg(Bits()) when(active && r2_data_req_fired) { - data_buf := Cat(io.data_resp, data_buf(params(RefillCycles)*params(EncRowBits)-1, params(EncRowBits))) + data_buf := Cat(io.data_resp, data_buf(refillCycles*encRowBits-1, encRowBits)) } io.release.bits.data := data_buf } else { @@ -447,15 +497,14 @@ class WritebackUnit extends Module { } -class ProbeUnit extends Module { - val co = params(TLCoherence) +class ProbeUnit extends L1HellaCacheModule { val io = new Bundle { val req = Decoupled(new InternalProbe).flip val rep = Decoupled(new Release) val meta_read = Decoupled(new L1MetaReadReq) val meta_write = Decoupled(new L1MetaWriteReq) val wb_req = Decoupled(new WritebackReq) - val way_en = Bits(INPUT, params(NWays)) + val way_en = Bits(INPUT, nWays) val mshr_rdy = Bool(INPUT) val line_state = new ClientMetadata()(co).asInput } @@ -508,60 +557,60 @@ class ProbeUnit extends Module { io.meta_read.valid := state === s_meta_read io.meta_read.bits.idx := req.addr - io.meta_read.bits.tag := req.addr >> params(IdxBits) + io.meta_read.bits.tag := req.addr >> idxBits io.meta_write.valid := state === s_meta_write io.meta_write.bits.way_en := way_en io.meta_write.bits.idx := req.addr io.meta_write.bits.data.coh := co.clientMetadataOnProbe(req, line_state) - io.meta_write.bits.data.tag := req.addr >> UInt(params(IdxBits)) + io.meta_write.bits.data.tag := req.addr >> UInt(idxBits) io.wb_req.valid := state === s_writeback_req io.wb_req.bits.way_en := way_en io.wb_req.bits.idx := req.addr - io.wb_req.bits.tag := req.addr >> UInt(params(IdxBits)) + io.wb_req.bits.tag := req.addr >> UInt(idxBits) io.wb_req.bits.r_type := co.getReleaseTypeOnProbe(req, Mux(hit, line_state, co.clientMetadataOnFlush)) io.wb_req.bits.client_xact_id := req.client_xact_id io.wb_req.bits.master_xact_id := req.master_xact_id } -class DataArray extends Module { +class DataArray extends L1HellaCacheModule { val io = new Bundle { val read = Decoupled(new DataReadReq).flip val write = Decoupled(new DataWriteReq).flip - val resp = Vec.fill(params(NWays)){Bits(OUTPUT, params(EncRowBits))} + val resp = Vec.fill(nWays){Bits(OUTPUT, encRowBits)} } - val waddr = io.write.bits.addr >> params(RowOffBits) - val raddr = io.read.bits.addr >> params(RowOffBits) + val waddr = io.write.bits.addr >> rowOffBits + val raddr = io.read.bits.addr >> rowOffBits - if (params(DoNarrowRead)) { - for (w <- 0 until params(NWays) by params(RowWords)) { - val wway_en = io.write.bits.way_en(w+params(RowWords)-1,w) - val rway_en = io.read.bits.way_en(w+params(RowWords)-1,w) - val resp = Vec.fill(params(RowWords)){Bits(width = params(EncRowBits))} + if (doNarrowRead) { + for (w <- 0 until nWays by rowWords) { + val wway_en = io.write.bits.way_en(w+rowWords-1,w) + val rway_en = io.read.bits.way_en(w+rowWords-1,w) + val resp = Vec.fill(rowWords){Bits(width = encRowBits)} val r_raddr = RegEnable(io.read.bits.addr, io.read.valid) for (p <- 0 until resp.size) { - val array = Mem(Bits(width=params(EncRowBits)), params(NSets)*params(RefillCycles), seqRead = true) + val array = Mem(Bits(width=encRowBits), nSets*refillCycles, seqRead = true) when (wway_en.orR && io.write.valid && io.write.bits.wmask(p)) { - val data = Fill(params(RowWords), io.write.bits.data(params(EncDataBits)*(p+1)-1,params(EncDataBits)*p)) - val mask = FillInterleaved(params(EncDataBits), wway_en) + val data = Fill(rowWords, io.write.bits.data(encDataBits*(p+1)-1,encDataBits*p)) + val mask = FillInterleaved(encDataBits, wway_en) array.write(waddr, data, mask) } resp(p) := array(RegEnable(raddr, rway_en.orR && io.read.valid)) } - for (dw <- 0 until params(RowWords)) { - val r = Vec(resp.map(_(params(EncDataBits)*(dw+1)-1,params(EncDataBits)*dw))) + for (dw <- 0 until rowWords) { + val r = Vec(resp.map(_(encDataBits*(dw+1)-1,encDataBits*dw))) val resp_mux = if (r.size == 1) r - else Vec(r(r_raddr(params(RowOffBits)-1,params(WordOffBits))), r.tail:_*) + else Vec(r(r_raddr(rowOffBits-1,wordOffBits)), r.tail:_*) io.resp(w+dw) := resp_mux.toBits } } } else { - val wmask = FillInterleaved(params(EncDataBits), io.write.bits.wmask) - for (w <- 0 until params(NWays)) { - val array = Mem(Bits(width=params(EncRowBits)), params(NSets)*params(RefillCycles), seqRead = true) + val wmask = FillInterleaved(encDataBits, io.write.bits.wmask) + for (w <- 0 until nWays) { + val array = Mem(Bits(width=encRowBits), nSets*refillCycles, seqRead = true) when (io.write.bits.way_en(w) && io.write.valid) { array.write(waddr, io.write.bits.data, wmask) } @@ -573,17 +622,17 @@ class DataArray extends Module { io.write.ready := Bool(true) } -class AMOALU extends Module { +class AMOALU extends L1HellaCacheModule { val io = new Bundle { - val addr = Bits(INPUT, params(OffBits)) + val addr = Bits(INPUT, blockOffBits) val cmd = Bits(INPUT, 4) val typ = Bits(INPUT, 3) - val lhs = Bits(INPUT, params(CoreDataBits)) - val rhs = Bits(INPUT, params(CoreDataBits)) - val out = Bits(OUTPUT, params(CoreDataBits)) + val lhs = Bits(INPUT, coreDataBits) + val rhs = Bits(INPUT, coreDataBits) + val out = Bits(OUTPUT, coreDataBits) } - require(params(CoreDataBits) == 64) + require(coreDataBits == 64) val storegen = new StoreGen(io.typ, io.addr, io.rhs) val rhs = storegen.wordData @@ -614,67 +663,18 @@ class AMOALU extends Module { io.out := wmask & out | ~wmask & io.lhs } -class HellaCacheReq extends Bundle { - val kill = Bool() - val typ = Bits(width = MT_SZ) - val phys = Bool() - val addr = UInt(width = params(MaxAddrBits)) - val data = Bits(width = params(CoreDataBits)) - val tag = Bits(width = params(CoreReqTagBits)) - val cmd = Bits(width = M_SZ) -} - -class HellaCacheResp extends Bundle { - val nack = Bool() // comes 2 cycles after req.fire - val replay = Bool() - val typ = Bits(width = 3) - val has_data = Bool() - val data = Bits(width = params(CoreDataBits)) - val data_subword = Bits(width = params(CoreDataBits)) - val tag = Bits(width = params(CoreReqTagBits)) - val cmd = Bits(width = 4) - val addr = UInt(width = params(MaxAddrBits)) - val store_data = Bits(width = params(CoreDataBits)) -} - -class AlignmentExceptions extends Bundle { - val ld = Bool() - val st = Bool() -} - -class HellaCacheExceptions extends Bundle { - val ma = new AlignmentExceptions - val pf = new AlignmentExceptions -} - -// interface between D$ and processor/DTLB -class HellaCacheIO extends Bundle { - val req = Decoupled(new HellaCacheReq) - val resp = Valid(new HellaCacheResp).flip - val replay_next = Valid(Bits(width = params(CoreReqTagBits))).flip - val xcpt = (new HellaCacheExceptions).asInput - val ptw = new TLBPTWIO().flip - val ordered = Bool(INPUT) -} - -class HellaCache extends Module { - val co = params(TLCoherence) +class HellaCache extends L1HellaCacheModule { val io = new Bundle { val cpu = (new HellaCacheIO).flip val mem = new TileLinkIO } require(params(LRSCCycles) >= 32) // ISA requires 16-insn LRSC sequences to succeed - require(isPow2(params(NSets))) - require(isPow2(params(NWays))) // TODO: relax this + require(isPow2(nSets)) + require(isPow2(nWays)) // TODO: relax this require(params(RowBits) <= params(TLDataBits)) - require(params(PAddrBits)-params(OffBits) == params(TLAddrBits) ) - require(params(UntagBits) <= params(PgIdxBits)) - - val indexmsb = params(UntagBits)-1 - val indexlsb = params(OffBits) - val offsetmsb = indexlsb-1 - val offsetlsb = params(WordOffBits) + require(paddrBits-blockOffBits == params(TLAddrBits) ) + require(untagBits <= pgIdxBits) val wb = Module(new WritebackUnit) val prober = Module(new ProbeUnit) @@ -708,7 +708,7 @@ class HellaCache extends Module { dtlb.io.req.valid := s1_valid_masked && s1_readwrite && !s1_req.phys dtlb.io.req.bits.passthrough := s1_req.phys dtlb.io.req.bits.asid := UInt(0) - dtlb.io.req.bits.vpn := s1_req.addr >> params(PgIdxBits) + dtlb.io.req.bits.vpn := s1_req.addr >> pgIdxBits dtlb.io.req.bits.instruction := Bool(false) when (!dtlb.io.req.ready && !io.cpu.req.bits.phys) { io.cpu.req.ready := Bool(false) } @@ -716,11 +716,11 @@ class HellaCache extends Module { s1_req := io.cpu.req.bits } when (wb.io.meta_read.valid) { - s1_req.addr := Cat(wb.io.meta_read.bits.tag, wb.io.meta_read.bits.idx) << params(OffBits) + s1_req.addr := Cat(wb.io.meta_read.bits.tag, wb.io.meta_read.bits.idx) << blockOffBits s1_req.phys := Bool(true) } when (prober.io.meta_read.valid) { - s1_req.addr := Cat(prober.io.meta_read.bits.tag, prober.io.meta_read.bits.idx) << params(OffBits) + s1_req.addr := Cat(prober.io.meta_read.bits.tag, prober.io.meta_read.bits.idx) << blockOffBits s1_req.phys := Bool(true) } when (mshrs.io.replay.valid) { @@ -729,7 +729,7 @@ class HellaCache extends Module { when (s2_recycle) { s1_req := s2_req } - val s1_addr = Cat(dtlb.io.resp.ppn, s1_req.addr(params(PgIdxBits)-1,0)) + val s1_addr = Cat(dtlb.io.resp.ppn, s1_req.addr(pgIdxBits-1,0)) when (s1_clk_en) { s2_req.kill := s1_req.kill @@ -769,12 +769,12 @@ class HellaCache extends Module { data.io.write.valid := writeArb.io.out.valid writeArb.io.out.ready := data.io.write.ready data.io.write.bits := writeArb.io.out.bits - val wdata_encoded = (0 until params(RowWords)).map(i => params(ECCCode).encode(writeArb.io.out.bits.data(params(CoreDataBits)*(i+1)-1,params(CoreDataBits)*i))) + val wdata_encoded = (0 until rowWords).map(i => code.encode(writeArb.io.out.bits.data(coreDataBits*(i+1)-1,coreDataBits*i))) data.io.write.bits.data := Vec(wdata_encoded).toBits // tag read for new requests metaReadArb.io.in(4).valid := io.cpu.req.valid - metaReadArb.io.in(4).bits.idx := io.cpu.req.bits.addr >> params(OffBits) + metaReadArb.io.in(4).bits.idx := io.cpu.req.bits.addr >> blockOffBits when (!metaReadArb.io.in(4).ready) { io.cpu.req.ready := Bool(false) } // data read for new requests @@ -785,14 +785,14 @@ class HellaCache extends Module { // recycled requests metaReadArb.io.in(0).valid := s2_recycle - metaReadArb.io.in(0).bits.idx := s2_req.addr >> params(OffBits) + metaReadArb.io.in(0).bits.idx := s2_req.addr >> blockOffBits readArb.io.in(0).valid := s2_recycle readArb.io.in(0).bits.addr := s2_req.addr readArb.io.in(0).bits.way_en := SInt(-1) // tag check and way muxing - def wayMap[T <: Data](f: Int => T) = Vec((0 until params(NWays)).map(f)) - val s1_tag_eq_way = wayMap((w: Int) => meta.io.resp(w).tag === (s1_addr >> params(UntagBits))).toBits + def wayMap[T <: Data](f: Int => T) = Vec((0 until nWays).map(f)) + val s1_tag_eq_way = wayMap((w: Int) => meta.io.resp(w).tag === (s1_addr >> untagBits)).toBits val s1_tag_match_way = wayMap((w: Int) => s1_tag_eq_way(w) && co.isValid(meta.io.resp(w).coh)).toBits s1_clk_en := metaReadArb.io.out.valid //TODO: should be metaReadArb.io.out.fire(), but triggers Verilog backend bug val s1_writeback = s1_clk_en && !s1_valid && !s1_replay @@ -806,13 +806,13 @@ class HellaCache extends Module { val lrsc_valid = lrsc_count.orR val lrsc_addr = Reg(UInt()) val (s2_lr, s2_sc) = (s2_req.cmd === M_XLR, s2_req.cmd === M_XSC) - val s2_lrsc_addr_match = lrsc_valid && lrsc_addr === (s2_req.addr >> params(OffBits)) + val s2_lrsc_addr_match = lrsc_valid && lrsc_addr === (s2_req.addr >> blockOffBits) val s2_sc_fail = s2_sc && !s2_lrsc_addr_match when (lrsc_valid) { lrsc_count := lrsc_count - 1 } when (s2_valid_masked && s2_hit || s2_replay) { when (s2_lr) { when (!lrsc_valid) { lrsc_count := params(LRSCCycles)-1 } - lrsc_addr := s2_req.addr >> params(OffBits) + lrsc_addr := s2_req.addr >> blockOffBits } when (s2_sc) { lrsc_count := 0 @@ -820,21 +820,21 @@ class HellaCache extends Module { } when (io.cpu.ptw.sret) { lrsc_count := 0 } - val s2_data = Vec.fill(params(NWays)){Bits(width = params(EncRowBits))} - for (w <- 0 until params(NWays)) { - val regs = Vec.fill(params(RowWords)){Reg(Bits(width = params(EncDataBits)))} + val s2_data = Vec.fill(nWays){Bits(width = encRowBits)} + for (w <- 0 until nWays) { + val regs = Vec.fill(rowWords){Reg(Bits(width = encDataBits))} val en1 = s1_clk_en && s1_tag_eq_way(w) for (i <- 0 until regs.size) { - val en = en1 && ((Bool(i == 0) || !params(DoNarrowRead)) || s1_writeback) - when (en) { regs(i) := data.io.resp(w) >> params(EncDataBits)*i } + val en = en1 && (Bool(i == 0 || !doNarrowRead) || s1_writeback) + when (en) { regs(i) := data.io.resp(w) >> encDataBits*i } } s2_data(w) := regs.toBits } val s2_data_muxed = Mux1H(s2_tag_match_way, s2_data) - val s2_data_decoded = (0 until params(RowWords)).map(i => params(ECCCode).decode(s2_data_muxed(params(EncDataBits)*(i+1)-1,params(EncDataBits)*i))) + val s2_data_decoded = (0 until rowWords).map(i => code.decode(s2_data_muxed(encDataBits*(i+1)-1,encDataBits*i))) val s2_data_corrected = Vec(s2_data_decoded.map(_.corrected)).toBits val s2_data_uncorrected = Vec(s2_data_decoded.map(_.uncorrected)).toBits - val s2_word_idx = if (params(DoNarrowRead)) UInt(0) else s2_req.addr(log2Up(params(RowWords)*params(CoreDataBytes))-1,3) + val s2_word_idx = if(doNarrowRead) UInt(0) else s2_req.addr(log2Up(rowWords*coreDataBytes)-1,3) val s2_data_correctable = Vec(s2_data_decoded.map(_.correctable)).toBits()(s2_word_idx) // store/amo hits @@ -847,10 +847,10 @@ class HellaCache extends Module { } writeArb.io.in(0).bits.addr := s3_req.addr - writeArb.io.in(0).bits.wmask := UInt(1) << (if(params(RowOffBits) > offsetlsb) - s3_req.addr(params(RowOffBits)-1,offsetlsb).toUInt + writeArb.io.in(0).bits.wmask := UInt(1) << (if(rowOffBits > offsetlsb) + s3_req.addr(rowOffBits-1,offsetlsb).toUInt else UInt(0)) - writeArb.io.in(0).bits.data := Fill(params(RowWords), s3_req.data) + writeArb.io.in(0).bits.data := Fill(rowWords, s3_req.data) writeArb.io.in(0).valid := s3_valid writeArb.io.in(0).bits.way_en := s3_way @@ -897,8 +897,8 @@ class HellaCache extends Module { // refills def doRefill(g: Grant): Bool = co.messageUpdatesDataArray(g) - val refill = if(params(RefillCycles) > 1) { - val ser = Module(new FlowThroughSerializer(io.mem.grant.bits, params(RefillCycles), doRefill)) + val refill = if(refillCycles > 1) { + val ser = Module(new FlowThroughSerializer(io.mem.grant.bits, refillCycles, doRefill)) ser.io.in <> io.mem.grant ser.io.out } else io.mem.grant @@ -908,7 +908,7 @@ class HellaCache extends Module { writeArb.io.in(1).valid := refill.valid && doRefill(refill.bits.payload) writeArb.io.in(1).bits := mshrs.io.mem_resp writeArb.io.in(1).bits.wmask := SInt(-1) - writeArb.io.in(1).bits.data := refill.bits.payload.data(params(EncRowBits)-1,0) + writeArb.io.in(1).bits.data := refill.bits.payload.data(encRowBits-1,0) readArb.io.out.ready := !refill.valid || refill.ready // insert bubble if refill gets blocked readArb.io.out <> data.io.read @@ -929,8 +929,8 @@ class HellaCache extends Module { ((s2_valid_masked || s2_replay) && !s2_sc_fail, s2_req, amoalu.io.out), (s3_valid, s3_req, s3_req.data), (s4_valid, s4_req, s4_req.data) - ).map(r => (r._1 && (s1_addr >> params(WordOffBits) === r._2.addr >> params(WordOffBits)) && isWrite(r._2.cmd), r._3)) - val s2_store_bypass_data = Reg(Bits(width = params(CoreDataBits))) + ).map(r => (r._1 && (s1_addr >> wordOffBits === r._2.addr >> wordOffBits) && isWrite(r._2.cmd), r._3)) + val s2_store_bypass_data = Reg(Bits(width = coreDataBits)) val s2_store_bypass = Reg(Bool()) when (s1_clk_en) { s2_store_bypass := false @@ -941,7 +941,7 @@ class HellaCache extends Module { } // load data subword mux/sign extension - val s2_data_word_prebypass = s2_data_uncorrected >> Cat(s2_word_idx, Bits(0,log2Up(params(CoreDataBits)))) + val s2_data_word_prebypass = s2_data_uncorrected >> Cat(s2_word_idx, Bits(0,log2Up(coreDataBits))) val s2_data_word = Mux(s2_store_bypass, s2_store_bypass_data, s2_data_word_prebypass) val loadgen = new LoadGen(s2_req.typ, s2_req.addr, s2_data_word, s2_sc) diff --git a/rocket/src/main/scala/ptw.scala b/rocket/src/main/scala/ptw.scala index abe534a6..db555957 100644 --- a/rocket/src/main/scala/ptw.scala +++ b/rocket/src/main/scala/ptw.scala @@ -71,7 +71,7 @@ class PTW(n: Int) extends Module val resp_val = state === s_done || state === s_error val resp_err = state === s_error || state === s_wait - val r_resp_ppn = io.mem.req.bits.addr >> params(PgIdxBits) + val r_resp_ppn = io.mem.req.bits.addr >> UInt(params(PgIdxBits)) val resp_ppn = Vec((0 until levels-1).map(i => Cat(r_resp_ppn >> bitsPerLevel*(levels-i-1), r_req_vpn(bitsPerLevel*(levels-i-1)-1,0))) :+ r_resp_ppn)(count) for (i <- 0 until io.requestor.size) { diff --git a/rocket/src/main/scala/tile.scala b/rocket/src/main/scala/tile.scala index b7f7e412..d0f49fbe 100644 --- a/rocket/src/main/scala/tile.scala +++ b/rocket/src/main/scala/tile.scala @@ -32,15 +32,16 @@ class Tile(resetSignal: Bool = null) extends Module(_reset = resetSignal) { val optionalRoCC = params(BuildRoCC) - val p = params.alter(params(CoreBTBParams)).alter(params(RocketFrontendParams)) // Used in icache, Core + val p = params.alter(params(RocketFrontendParams)) // Used in icache, Core val icache = Module(new Frontend)(p) //TODO PARAMS: best way to alter both? - params.alter(params(RocketDCacheParams)) // Used in dcache, PTW, RoCCm Core - val dcache = Module(new HellaCache) - val ptw = Module(new PTW(if(optionalRoCC.isEmpty) 2 else 5)) + val p2 = params.alter(params(RocketDCacheParams)) // Used in dcache, PTW, RoCCm Core + val dcache = Module(new HellaCache)(p2) + val ptw = Module(new PTW(if(optionalRoCC.isEmpty) 2 else 5))(p2) // 2 ports, 1 from I$, 1 from D$, maybe 3 from RoCC - val core = Module(new Core) + val p3 = params.alter(params(RocketFrontendParams)).alter(params(RocketDCacheParams)) + val core = Module(new Core)(p3) - val dcArb = Module(new HellaCacheArbiter(params(NDCachePorts))) + val dcArb = Module(new HellaCacheArbiter(params(NDCachePorts)))(p2) dcArb.io.requestor(0) <> ptw.io.mem dcArb.io.requestor(1) <> core.io.dmem dcArb.io.mem <> dcache.io.cpu