From 0dac9a74671d629231cebd6ceeca80aa4aa6f120 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Fri, 8 Aug 2014 12:23:02 -0700 Subject: [PATCH] Full conversion to params. Compiles but does not elaborate. --- rocket/src/main/scala/arbiter.scala | 6 +- rocket/src/main/scala/btb.scala | 112 +++---- rocket/src/main/scala/core.scala | 35 +-- rocket/src/main/scala/csr.scala | 75 +++-- rocket/src/main/scala/ctrl.scala | 18 +- rocket/src/main/scala/dpath.scala | 41 ++- rocket/src/main/scala/dpath_alu.scala | 12 +- rocket/src/main/scala/icache.scala | 160 +++++----- rocket/src/main/scala/multiplier.scala | 18 +- rocket/src/main/scala/nbdcache.scala | 410 ++++++++++++------------- rocket/src/main/scala/ptw.scala | 31 +- rocket/src/main/scala/rocc.scala | 26 +- rocket/src/main/scala/tile.scala | 91 +++--- rocket/src/main/scala/tlb.scala | 20 +- rocket/src/main/scala/util.scala | 5 - 15 files changed, 500 insertions(+), 560 deletions(-) diff --git a/rocket/src/main/scala/arbiter.scala b/rocket/src/main/scala/arbiter.scala index 5f4ee53e..917cb816 100644 --- a/rocket/src/main/scala/arbiter.scala +++ b/rocket/src/main/scala/arbiter.scala @@ -3,11 +3,11 @@ package rocket import Chisel._ import uncore._ -class HellaCacheArbiter(n: Int)(implicit conf: RocketConfiguration) extends Module +class HellaCacheArbiter(n: Int) extends Module { val io = new Bundle { - val requestor = Vec.fill(n){new HellaCacheIO()(conf.dcache)}.flip - val mem = new HellaCacheIO()(conf.dcache) + val requestor = Vec.fill(n){new HellaCacheIO}.flip + val mem = new HellaCacheIO } val r_valid = io.requestor.map(r => Reg(next=r.req.valid)) diff --git a/rocket/src/main/scala/btb.scala b/rocket/src/main/scala/btb.scala index cab8bfc7..4cecf1d7 100644 --- a/rocket/src/main/scala/btb.scala +++ b/rocket/src/main/scala/btb.scala @@ -3,61 +3,63 @@ package rocket import Chisel._ import Util._ import Node._ +import uncore._ -case class BTBConfig(as: uncore.AddressSpaceConfiguration, entries: Int, nras: Int = 0) { - val matchBits = as.pgIdxBits - val pages0 = 1 max log2Up(entries) // is this sensible? - val pages = (pages0+1)/2*2 // control logic assumes 2 divides pages - val opaqueBits = log2Up(entries) - val nbht = 1 << log2Up(entries * 2) -} +case object Entries 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] -class RAS(implicit conf: BTBConfig) { +class RAS(nras: Int) { def push(addr: UInt): Unit = { - when (count < conf.nras) { count := count + 1 } - val nextPos = Mux(Bool(isPow2(conf.nras)) || pos > 0, pos+1, UInt(0)) + when (count < nras) { count := count + 1 } + val nextPos = Mux(Bool(isPow2(nras)) || pos > 0, pos+1, UInt(0)) stack(nextPos) := addr pos := nextPos } def peek: UInt = stack(pos) def pop: Unit = when (!isEmpty) { count := count - 1 - pos := Mux(Bool(isPow2(conf.nras)) || pos > 0, pos-1, UInt(conf.nras-1)) + pos := Mux(Bool(isPow2(nras)) || pos > 0, pos-1, UInt(nras-1)) } def clear: Unit = count := UInt(0) def isEmpty: Bool = count === UInt(0) - private val count = Reg(init=UInt(0,log2Up(conf.nras+1))) - private val pos = Reg(init=UInt(0,log2Up(conf.nras))) - private val stack = Vec.fill(conf.nras){Reg(UInt())} + private val count = Reg(init=UInt(0,log2Up(nras+1))) + private val pos = Reg(init=UInt(0,log2Up(nras))) + private val stack = Vec.fill(nras){Reg(UInt())} } -class BHTResp(implicit conf: BTBConfig) extends Bundle { - val index = UInt(width = log2Up(conf.nbht).max(1)) +class BHTResp extends Bundle { + val index = UInt(width = log2Up(params(NBHT)).max(1)) val value = UInt(width = 2) } -class BHT(implicit conf: BTBConfig) { +class BHT(nbht: Int) { + val nbhtbits = log2Up(nbht) def get(addr: UInt): BHTResp = { val res = new BHTResp - res.index := addr(log2Up(conf.nbht)+1,2) ^ history + res.index := addr(nbhtbits+1,2) ^ history res.value := table(res.index) res } def update(d: BHTResp, taken: Bool): Unit = { table(d.index) := Cat(taken, (d.value(1) & d.value(0)) | ((d.value(1) | d.value(0)) & taken)) - history := Cat(taken, history(log2Up(conf.nbht)-1,1)) + history := Cat(taken, history(nbhtbits-1,1)) } - private val table = Mem(UInt(width = 2), conf.nbht) - val history = Reg(UInt(width = log2Up(conf.nbht))) + private val table = Mem(UInt(width = 2), nbht) + val history = Reg(UInt(width = nbhtbits)) } -class BTBUpdate(implicit val conf: BTBConfig) extends BundleWithConf { +class BTBUpdate extends Bundle { val prediction = Valid(new BTBResp) - val pc = UInt(width = conf.as.vaddrBits) - val target = UInt(width = conf.as.vaddrBits) - val returnAddr = UInt(width = conf.as.vaddrBits) + val pc = UInt(width = params(VAddrBits)) + val target = UInt(width = params(VAddrBits)) + val returnAddr = UInt(width = params(VAddrBits)) val taken = Bool() val isJump = Bool() val isCall = Bool() @@ -65,42 +67,42 @@ class BTBUpdate(implicit val conf: BTBConfig) extends BundleWithConf { val incorrectTarget = Bool() } -class BTBResp(implicit val conf: BTBConfig) extends BundleWithConf { +class BTBResp extends Bundle { val taken = Bool() - val target = UInt(width = conf.as.vaddrBits) - val entry = UInt(width = conf.opaqueBits) + val target = UInt(width = params(VAddrBits)) + val entry = UInt(width = params(OpaqueBits)) val bht = new BHTResp } // fully-associative branch target buffer -class BTB(implicit conf: BTBConfig) extends Module { +class BTB extends Module { val io = new Bundle { - val req = UInt(INPUT, conf.as.vaddrBits) + val req = UInt(INPUT, params(VAddrBits)) val resp = Valid(new BTBResp) val update = Valid(new BTBUpdate).flip val invalidate = Bool(INPUT) } - val idxValid = Reg(init=UInt(0, conf.entries)) - val idxs = Mem(UInt(width=conf.matchBits), conf.entries) - val idxPages = Mem(UInt(width=log2Up(conf.pages)), conf.entries) - val tgts = Mem(UInt(width=conf.matchBits), conf.entries) - val tgtPages = Mem(UInt(width=log2Up(conf.pages)), conf.entries) - val pages = Mem(UInt(width=conf.as.vaddrBits-conf.matchBits), conf.pages) - val pageValid = Reg(init=UInt(0, conf.pages)) - val idxPagesOH = idxPages.map(UIntToOH(_)(conf.pages-1,0)) - val tgtPagesOH = tgtPages.map(UIntToOH(_)(conf.pages-1,0)) + 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 useRAS = Reg(UInt(width = conf.entries)) - val isJump = Reg(UInt(width = conf.entries)) + val useRAS = Reg(UInt(width = params(Entries))) + val isJump = Reg(UInt(width = params(Entries))) - private def page(addr: UInt) = addr >> conf.matchBits + private def page(addr: UInt) = addr >> params(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(conf.matchBits-1,0) + val idx = addr(params(MatchBits)-1,0) val idxMatch = idxs.map(_ === idx).toBits val idxPageMatch = idxPagesOH.map(_ & pgMatch).map(_.orR).toBits idxValid & idxMatch & idxPageMatch @@ -121,7 +123,7 @@ class BTB(implicit conf: BTBConfig) extends Module { } val updateHit = update.bits.prediction.valid - val updateValid = update.bits.incorrectTarget || updateHit && Bool(conf.nbht > 0) + val updateValid = update.bits.incorrectTarget || updateHit && Bool(params(NBHT) > 0) val updateTarget = updateValid && update.bits.incorrectTarget val useUpdatePageHit = updatePageHit.orR @@ -134,20 +136,20 @@ class BTB(implicit conf: BTBConfig) 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(conf.pages-2,0) << 1 | idxPageUpdateOH(conf.pages-1)) + val tgtPageRepl = Mux(samePage, idxPageUpdateOH, idxPageUpdateOH(params(Pages)-2,0) << 1 | idxPageUpdateOH(params(Pages)-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, conf.pages)._1) + idxPageRepl := UIntToOH(Counter(update.valid && doPageRepl, params(Pages))._1) when (update.valid && !(updateValid && !updateTarget)) { - val nextRepl = Counter(!updateHit && updateValid, conf.entries)._1 + val nextRepl = Counter(!updateHit && updateValid, params(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(conf.entries)(i => (pageReplEn & (idxPagesOH(i) | tgtPagesOH(i))).orR).toBits + idxValid := idxValid & ~Vec.tabulate(params(Entries))(i => (pageReplEn & (idxPagesOH(i) | tgtPagesOH(i))).orR).toBits idxValid(waddr) := updateValid when (updateTarget) { @@ -160,11 +162,11 @@ class BTB(implicit conf: BTBConfig) extends Module { isJump(waddr) := update.bits.isJump } - require(conf.pages % 2 == 0) - val idxWritesEven = (idxPageUpdateOH & Fill(conf.pages/2, UInt(1,2))).orR + require(params(Pages) % 2 == 0) + val idxWritesEven = (idxPageUpdateOH & Fill(params(Pages)/2, UInt(1,2))).orR def writeBank(i: Int, mod: Int, en: Bool, data: UInt) = - for (i <- i until conf.pages by mod) + for (i <- i until params(Pages) by mod) when (en && pageReplEn(i)) { pages(i) := data } writeBank(0, 2, Mux(idxWritesEven, doIdxPageRepl, doTgtPageRepl), @@ -185,16 +187,16 @@ class BTB(implicit conf: BTBConfig) extends Module { io.resp.bits.target := Cat(Mux1H(Mux1H(hits, tgtPagesOH), pages), Mux1H(hits, tgts)) io.resp.bits.entry := OHToUInt(hits) - if (conf.nbht > 0) { - val bht = new BHT + if (params(NBHT) > 0) { + val bht = new BHT(params(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 (conf.nras > 0) { - val ras = new RAS + if (params(NRAS) > 0) { + val ras = new RAS(params(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 a172e0ec..c9ec77a7 100644 --- a/rocket/src/main/scala/core.scala +++ b/rocket/src/main/scala/core.scala @@ -5,39 +5,26 @@ import Util._ import uncore.HTIFIO case object FPUParams extends Field[PF] -case object HasFPU extends Field[Boolean] +case object BuildFPU extends Field[Option[() => FPU]] -class RocketIO(implicit conf: RocketConfiguration) extends Bundle +class RocketIO extends Bundle { - val host = new HTIFIO(params[Int]("nClients")) - val imem = new CPUFrontendIO()(conf.icache) - val dmem = new HellaCacheIO()(conf.dcache) - val ptw = new DatapathPTWIO()(conf.as).flip + val host = new HTIFIO + val imem = new CPUFrontendIO + val dmem = new HellaCacheIO + val ptw = new DatapathPTWIO().flip val rocc = new RoCCInterface().flip } -class Core(implicit conf: RocketConfiguration) extends Module +class Core extends Module { - //xprlen - //hasfpu - //hasrocc - //fastloadword - //fastloadbyte - //as <- unfolded - - //fpuparams - - val io = new RocketIO - //nClients - - //icache - //dcache + val io = new RocketIO - val ctrl = Module(new Control) + val ctrl = Module(new Control) val dpath = Module(new Datapath) - if (!params(HasFPU)) { - val fpu = Module(new FPU,params(FPUParams)) + if (!params(BuildFPU).isEmpty) { + val fpu = Module(params(BuildFPU).get(),params(FPUParams)) 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 52e7f7fc..c15a3389 100644 --- a/rocket/src/main/scala/csr.scala +++ b/rocket/src/main/scala/csr.scala @@ -3,8 +3,7 @@ package rocket import Chisel._ import Util._ import Node._ -import uncore.HTIFIO -import uncore.AddressSpaceConfiguration +import uncore._ import scala.math._ class Status extends Bundle { @@ -33,58 +32,58 @@ object CSR val C = Bits(3,2) } -class CSRFileIO(implicit conf: RocketConfiguration) extends Bundle { - val host = new HTIFIO(conf.tl.ln.nClients) +class CSRFileIO extends Bundle { + val host = new HTIFIO val rw = new Bundle { val addr = UInt(INPUT, 12) val cmd = Bits(INPUT, CSR.SZ) - val rdata = Bits(OUTPUT, conf.xprlen) - val wdata = Bits(INPUT, conf.xprlen) + val rdata = Bits(OUTPUT, params(XprLen)) + val wdata = Bits(INPUT, params(XprLen)) } val status = new Status().asOutput - val ptbr = UInt(OUTPUT, conf.as.paddrBits) - val evec = UInt(OUTPUT, conf.as.vaddrBits+1) + val ptbr = UInt(OUTPUT, params(PAddrBits)) + val evec = UInt(OUTPUT, params(VAddrBits)+1) val exception = Bool(INPUT) - val retire = UInt(INPUT, log2Up(1+conf.retireWidth)) - val uarch_counters = Vec.fill(16)(UInt(INPUT, log2Up(1+conf.retireWidth))) - val cause = UInt(INPUT, conf.xprlen) + val retire = UInt(INPUT, log2Up(1+params(RetireWidth))) + val uarch_counters = Vec.fill(16)(UInt(INPUT, log2Up(1+params(RetireWidth)))) + val cause = UInt(INPUT, params(XprLen)) val badvaddr_wen = Bool(INPUT) - val pc = UInt(INPUT, conf.as.vaddrBits+1) + val pc = UInt(INPUT, params(VAddrBits)+1) val sret = Bool(INPUT) val fatc = Bool(OUTPUT) val replay = Bool(OUTPUT) - val time = UInt(OUTPUT, conf.xprlen) + val time = UInt(OUTPUT, params(XprLen)) val fcsr_rm = Bits(OUTPUT, FPConstants.RM_SZ) val fcsr_flags = Valid(Bits(width = FPConstants.FLAGS_SZ)).flip val rocc = new RoCCInterface().flip } -class CSRFile(implicit conf: RocketConfiguration) extends Module +class CSRFile extends Module { val io = new CSRFileIO - val reg_epc = Reg(Bits(width = conf.as.vaddrBits+1)) - val reg_badvaddr = Reg(Bits(width = conf.as.vaddrBits)) - val reg_evec = Reg(Bits(width = conf.as.vaddrBits)) + val reg_epc = Reg(Bits(width = params(VAddrBits)+1)) + val reg_badvaddr = Reg(Bits(width = params(VAddrBits))) + val reg_evec = Reg(Bits(width = params(VAddrBits))) val reg_compare = Reg(Bits(width = 32)) - val reg_cause = Reg(Bits(width = conf.xprlen)) - val reg_tohost = Reg(init=Bits(0, conf.xprlen)) - val reg_fromhost = Reg(init=Bits(0, conf.xprlen)) - val reg_sup0 = Reg(Bits(width = conf.xprlen)) - val reg_sup1 = Reg(Bits(width = conf.xprlen)) - val reg_ptbr = Reg(UInt(width = conf.as.paddrBits)) + val reg_cause = Reg(Bits(width = params(XprLen))) + val reg_tohost = Reg(init=Bits(0, params(XprLen))) + val reg_fromhost = Reg(init=Bits(0, params(XprLen))) + val reg_sup0 = Reg(Bits(width = params(XprLen))) + val reg_sup1 = Reg(Bits(width = params(XprLen))) + val reg_ptbr = Reg(UInt(width = params(PAddrBits))) val reg_stats = Reg(init=Bool(false)) val reg_status = Reg(new Status) // reset down below - val reg_time = WideCounter(conf.xprlen) - val reg_instret = WideCounter(conf.xprlen, io.retire) - val reg_uarch_counters = io.uarch_counters.map(WideCounter(conf.xprlen, _)) + val reg_time = WideCounter(params(XprLen)) + val reg_instret = WideCounter(params(XprLen), io.retire) + val reg_uarch_counters = io.uarch_counters.map(WideCounter(params(XprLen), _)) val reg_fflags = Reg(UInt(width = 5)) val reg_frm = Reg(UInt(width = 3)) val r_irq_timer = Reg(init=Bool(false)) val r_irq_ipi = Reg(init=Bool(true)) - val irq_rocc = Bool(!conf.rocc.isEmpty) && io.rocc.interrupt + val irq_rocc = Bool(!params(BuildRoCC).isEmpty) && io.rocc.interrupt val cpu_req_valid = io.rw.cmd != CSR.N val host_pcr_req_valid = Reg(Bool()) // don't reset @@ -130,7 +129,7 @@ class CSRFile(implicit conf: RocketConfiguration) extends Module when (io.badvaddr_wen) { val wdata = io.rw.wdata - val (upper, lower) = Split(wdata, conf.as.vaddrBits) + val (upper, lower) = Split(wdata, params(VAddrBits)) val sign = Mux(lower.toSInt < SInt(0), upper.andR, upper.orR) reg_badvaddr := Cat(sign, lower).toSInt } @@ -161,12 +160,12 @@ class CSRFile(implicit conf: RocketConfiguration) 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(conf.as.paddrBits-1, conf.as.pgIdxBits) << conf.as.pgIdxBits + val read_ptbr = reg_ptbr(params(PAddrBits)-1, params(PgIdxBits)) << params(PgIdxBits) val read_mapping = collection.mutable.LinkedHashMap[Int,Bits]( - CSRs.fflags -> (if (!params(HasFPU)) reg_fflags else UInt(0)), - CSRs.frm -> (if (!params(HasFPU)) reg_frm else UInt(0)), - CSRs.fcsr -> (if (!params(HasFPU)) Cat(reg_frm, reg_fflags) else UInt(0)), + CSRs.fflags -> (if (!params(BuildFPU).isEmpty) reg_fflags else UInt(0)), + CSRs.frm -> (if (!params(BuildFPU).isEmpty) reg_frm else UInt(0)), + CSRs.fcsr -> (if (!params(BuildFPU).isEmpty) Cat(reg_frm, reg_fflags) else UInt(0)), CSRs.cycle -> reg_time, CSRs.time -> reg_time, CSRs.instret -> reg_instret, @@ -206,15 +205,15 @@ class CSRFile(implicit conf: RocketConfiguration) extends Module reg_status.s64 := true reg_status.u64 := true reg_status.zero := 0 - if (!conf.vm) reg_status.vm := false - if (conf.rocc.isEmpty) reg_status.er := false - if (params(HasFPU)) reg_status.ef := false + if (!params(UseVM)) reg_status.vm := false + if (params(BuildRoCC).isEmpty) reg_status.er := false + if (params(BuildFPU).isEmpty) reg_status.ef := false } when (decoded_addr(CSRs.fflags)) { reg_fflags := wdata } when (decoded_addr(CSRs.frm)) { reg_frm := wdata } when (decoded_addr(CSRs.fcsr)) { reg_fflags := wdata; reg_frm := wdata >> reg_fflags.getWidth } - when (decoded_addr(CSRs.epc)) { reg_epc := wdata(conf.as.vaddrBits,0).toSInt } - when (decoded_addr(CSRs.evec)) { reg_evec := wdata(conf.as.vaddrBits-1,0).toSInt } + when (decoded_addr(CSRs.epc)) { reg_epc := wdata(params(VAddrBits),0).toSInt } + when (decoded_addr(CSRs.evec)) { reg_evec := wdata(params(VAddrBits)-1,0).toSInt } when (decoded_addr(CSRs.count)) { reg_time := wdata.toUInt } when (decoded_addr(CSRs.compare)) { reg_compare := wdata(31,0).toUInt; r_irq_timer := Bool(false) } when (decoded_addr(CSRs.fromhost)) { when (reg_fromhost === UInt(0) || !host_pcr_req_fire) { reg_fromhost := wdata } } @@ -222,7 +221,7 @@ class CSRFile(implicit conf: RocketConfiguration) extends Module when (decoded_addr(CSRs.clear_ipi)){ r_irq_ipi := wdata(0) } when (decoded_addr(CSRs.sup0)) { reg_sup0 := wdata } when (decoded_addr(CSRs.sup1)) { reg_sup1 := wdata } - when (decoded_addr(CSRs.ptbr)) { reg_ptbr := Cat(wdata(conf.as.paddrBits-1, conf.as.pgIdxBits), Bits(0, conf.as.pgIdxBits)).toUInt } + when (decoded_addr(CSRs.ptbr)) { reg_ptbr := Cat(wdata(params(PAddrBits)-1, params(PgIdxBits)), Bits(0, params(PgIdxBits))).toUInt } when (decoded_addr(CSRs.stats)) { reg_stats := wdata(0) } } diff --git a/rocket/src/main/scala/ctrl.scala b/rocket/src/main/scala/ctrl.scala index 54d89eef..1073019c 100644 --- a/rocket/src/main/scala/ctrl.scala +++ b/rocket/src/main/scala/ctrl.scala @@ -6,7 +6,7 @@ import uncore.constants.MemoryOpConstants._ import ALU._ import Util._ -class CtrlDpathIO(implicit conf: RocketConfiguration) extends Bundle +class CtrlDpathIO extends Bundle { // outputs to datapath val sel_pc = UInt(OUTPUT, 3) @@ -305,19 +305,19 @@ object RoCCDecode extends DecodeConstants CUSTOM3_RD_RS1_RS2->List(Y, N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,Y,CSR.N,N,N,N,N,N,N)) } -class Control(implicit conf: RocketConfiguration) extends Module +class Control extends Module { val io = new Bundle { val dpath = new CtrlDpathIO - val imem = new CPUFrontendIO()(conf.icache) - val dmem = new HellaCacheIO()(conf.dcache) + val imem = new CPUFrontendIO + val dmem = new HellaCacheIO val fpu = new CtrlFPUIO val rocc = new RoCCInterface().flip } var decode_table = XDecode.table - if (params(HasFPU)) decode_table ++= FDecode.table - if (params[Boolean]("HasRoCC")) decode_table ++= RoCCDecode.table + if (!params(BuildFPU).isEmpty) decode_table ++= FDecode.table + if (!params(BuildRoCC).isEmpty) decode_table ++= RoCCDecode.table val cs = DecodeLogic(io.dpath.inst, XDecode.decode_default, decode_table) @@ -411,13 +411,13 @@ class Control(implicit conf: RocketConfiguration) extends Module val fp_csrs = CSRs.fcsr :: CSRs.frm :: CSRs.fflags :: Nil val legal_csrs = collection.mutable.LinkedHashSet(CSRs.all:_*) - if (params(HasFPU)) + if(params(BuildFPU).isEmpty) legal_csrs --= fp_csrs val id_csr_addr = io.dpath.inst(31,20) val isLegalCSR = Vec.tabulate(1 << id_csr_addr.getWidth)(i => Bool(legal_csrs contains i)) val id_csr_en = id_csr != CSR.N - val id_csr_fp = Bool(!params(HasFPU)) && id_csr_en && DecodeLogic(id_csr_addr, fp_csrs, CSRs.all.toSet -- fp_csrs) + val id_csr_fp = Bool(!params(BuildFPU).isEmpty) && id_csr_en && DecodeLogic(id_csr_addr, fp_csrs, CSRs.all.toSet -- fp_csrs) val id_csr_wen = id_raddr1 != UInt(0) || !Vec(CSR.S, CSR.C).contains(id_csr) val id_csr_invalid = id_csr_en && !isLegalCSR(id_csr_addr) val id_csr_privileged = id_csr_en && @@ -623,7 +623,7 @@ class Control(implicit conf: RocketConfiguration) extends Module val sboard = new Scoreboard(32) sboard.clear(io.dpath.ll_wen, io.dpath.ll_waddr) - val id_stall_fpu = if (!params(HasFPU)) { + val id_stall_fpu = if (!params(BuildFPU).isEmpty) { val fp_sboard = new Scoreboard(32) fp_sboard.set((wb_dcache_miss && wb_reg_fp_wen || io.fpu.sboard_set) && !replay_wb, io.dpath.wb_waddr) fp_sboard.clear(io.dpath.fp_sboard_clr, io.dpath.fp_sboard_clra) diff --git a/rocket/src/main/scala/dpath.scala b/rocket/src/main/scala/dpath.scala index ea6b59cf..e932b1dd 100644 --- a/rocket/src/main/scala/dpath.scala +++ b/rocket/src/main/scala/dpath.scala @@ -3,17 +3,16 @@ package rocket import Chisel._ import Instructions._ import Util._ -import uncore.HTIFIO +import uncore._ -class Datapath(implicit conf: RocketConfiguration) extends Module +class Datapath extends Module { - implicit val as = conf.as val io = new Bundle { - val host = new HTIFIO(conf.tl.ln.nClients) - val ctrl = (new CtrlDpathIO).flip - val dmem = new HellaCacheIO()(conf.dcache) - val ptw = (new DatapathPTWIO).flip - val imem = new CPUFrontendIO()(conf.icache) + val host = new HTIFIO + val ctrl = new CtrlDpathIO().flip + val dmem = new HellaCacheIO + val ptw = new DatapathPTWIO().flip + val imem = new CPUFrontendIO val fpu = new DpathFPUIO val rocc = new RoCCInterface().flip } @@ -122,8 +121,8 @@ class Datapath(implicit conf: RocketConfiguration) extends Module bypass(BYP_0) := Bits(0) bypass(BYP_EX) := mem_reg_wdata bypass(BYP_MEM) := wb_reg_wdata - bypass(BYP_DC) := (if (conf.fastLoadByte) io.dmem.resp.bits.data_subword - else if (conf.fastLoadWord) io.dmem.resp.bits.data + bypass(BYP_DC) := (if(params(FastLoadByte)) io.dmem.resp.bits.data_subword + else if(params(FastLoadWord)) io.dmem.resp.bits.data else wb_reg_wdata) val ex_rs = for (i <- 0 until id_rs.size) @@ -144,8 +143,8 @@ class Datapath(implicit conf: RocketConfiguration) extends Module alu.io.in1 := ex_op1 // multiplier and divider - val div = Module(new MulDiv(mulUnroll = if (conf.fastMulDiv) 8 else 1, - earlyOut = conf.fastMulDiv)) + val div = Module(new MulDiv(mulUnroll = if(params(FastMulDiv)) 8 else 1, + earlyOut = params(FastMulDiv))) div.io.req.valid := io.ctrl.div_mul_val div.io.req.bits.dw := ex_reg_ctrl_fn_dw div.io.req.bits.fn := ex_reg_ctrl_fn_alu @@ -158,10 +157,10 @@ class Datapath(implicit conf: RocketConfiguration) extends Module io.fpu.fromint_data := ex_rs(0) def vaSign(a0: UInt, ea: Bits) = { - // efficient means to compress 64-bit VA into conf.as.vaddrBits+1 bits - // (VA is bad if VA(conf.as.vaddrBits) != VA(conf.as.vaddrBits-1)) - val a = a0 >> conf.as.vaddrBits-1 - val e = ea(conf.as.vaddrBits,conf.as.vaddrBits-1) + // efficient means to compress 64-bit VA into params(VAddrBits)+1 bits + // (VA is bad if VA(params(VAddrBits)) != VA(params(VAddrBits)-1)) + val a = a0 >> params(VAddrBits)-1 + val e = ea(params(VAddrBits),params(VAddrBits)-1) Mux(a === UInt(0) || a === UInt(1), e != UInt(0), Mux(a === SInt(-1) || a === SInt(-2), e === SInt(-1), e(0))) @@ -169,10 +168,10 @@ class Datapath(implicit conf: RocketConfiguration) extends Module // D$ request interface (registered inside D$ module) // other signals (req_val, req_rdy) connect to control module - io.dmem.req.bits.addr := Cat(vaSign(ex_rs(0), alu.io.adder_out), alu.io.adder_out(conf.as.vaddrBits-1,0)).toUInt + io.dmem.req.bits.addr := Cat(vaSign(ex_rs(0), alu.io.adder_out), alu.io.adder_out(params(VAddrBits)-1,0)).toUInt io.dmem.req.bits.tag := Cat(io.ctrl.ex_waddr, io.ctrl.ex_fp_val) require(io.dmem.req.bits.tag.getWidth >= 6) - require(conf.dcacheReqTagBits >= 6) + require(params(DcacheReqTagBits) >= 6) // processor control regfile read val pcr = Module(new CSRFile) @@ -214,7 +213,7 @@ class Datapath(implicit conf: RocketConfiguration) extends Module ll_wdata := div.io.resp.bits.data io.ctrl.ll_waddr := div.io.resp.bits.tag io.ctrl.ll_wen := div.io.resp.fire() - if (!conf.rocc.isEmpty) { + if (!params(BuildRoCC).isEmpty) { io.rocc.resp.ready := io.ctrl.ll_ready when (io.rocc.resp.fire()) { div.io.resp.ready := Bool(false) @@ -225,7 +224,7 @@ class Datapath(implicit conf: RocketConfiguration) extends Module } when (dmem_resp_replay && dmem_resp_xpu) { div.io.resp.ready := Bool(false) - if (!conf.rocc.isEmpty) + if (!params(BuildRoCC).isEmpty) io.rocc.resp.ready := Bool(false) io.ctrl.ll_waddr := dmem_resp_waddr io.ctrl.ll_wen := Bool(true) @@ -240,7 +239,7 @@ class Datapath(implicit conf: RocketConfiguration) extends Module val mem_br_target = mem_reg_pc + Mux(io.ctrl.mem_branch && io.ctrl.mem_br_taken, imm(IMM_SB, mem_reg_inst), Mux(!io.ctrl.mem_jalr && !io.ctrl.mem_branch, imm(IMM_UJ, mem_reg_inst), SInt(4))) - val mem_npc = Mux(io.ctrl.mem_jalr, Cat(vaSign(mem_reg_wdata, mem_reg_wdata), mem_reg_wdata(conf.as.vaddrBits-1,0)), mem_br_target) + val mem_npc = Mux(io.ctrl.mem_jalr, Cat(vaSign(mem_reg_wdata, mem_reg_wdata), mem_reg_wdata(params(VAddrBits)-1,0)), mem_br_target) io.ctrl.mem_misprediction := mem_npc != Mux(io.ctrl.ex_valid, ex_reg_pc, id_pc) io.ctrl.mem_rs1_ra := mem_reg_inst(19,15) === 1 val mem_int_wdata = Mux(io.ctrl.mem_jalr, mem_br_target, mem_reg_wdata) diff --git a/rocket/src/main/scala/dpath_alu.scala b/rocket/src/main/scala/dpath_alu.scala index 4d9c54cb..f2d565cd 100644 --- a/rocket/src/main/scala/dpath_alu.scala +++ b/rocket/src/main/scala/dpath_alu.scala @@ -41,16 +41,16 @@ object ALU } import ALU._ -class ALUIO(implicit conf: RocketConfiguration) extends Bundle { +class ALUIO extends Bundle { val dw = Bits(INPUT, SZ_DW) val fn = Bits(INPUT, SZ_ALU_FN) - val in2 = UInt(INPUT, conf.xprlen) - val in1 = UInt(INPUT, conf.xprlen) - val out = UInt(OUTPUT, conf.xprlen) - val adder_out = UInt(OUTPUT, conf.xprlen) + val in2 = UInt(INPUT, params(XprLen)) + val in1 = UInt(INPUT, params(XprLen)) + val out = UInt(OUTPUT, params(XprLen)) + val adder_out = UInt(OUTPUT, params(XprLen)) } -class ALU(implicit conf: RocketConfiguration) extends Module +class ALU extends Module { val io = new ALUIO diff --git a/rocket/src/main/scala/icache.scala b/rocket/src/main/scala/icache.scala index a9308086..0db261a1 100644 --- a/rocket/src/main/scala/icache.scala +++ b/rocket/src/main/scala/icache.scala @@ -4,62 +4,39 @@ import Chisel._ import uncore._ import Util._ -case class ICacheConfig(sets: Int, assoc: Int, - ibytes: Int = 4, rowbytes: Int = 16, - ntlb: Int = 8, - tl: TileLinkConfiguration, - as: AddressSpaceConfiguration, - btb: BTBConfig, - code: Code = new IdentityCode) -{ - val w = 1 +case object InstBytes extends Field[Int] +case object CoreBTBParams extends Field[PF] - val dm = assoc == 1 - val lines = sets * assoc - val idxbits = log2Up(sets) - val offbits = log2Up(tl.dataBits/8) - val rowbits = rowbytes*8 - val rowoffbits = log2Up(rowbytes) - val untagbits = idxbits + offbits - val tagbits = as.paddrBits - untagbits - val refillcycles = tl.dataBits/rowbits - - require(isPow2(sets) && isPow2(assoc)) - require(isPow2(w) && isPow2(ibytes)) - require(as.pgIdxBits >= untagbits) +class FrontendReq extends Bundle { + val pc = UInt(width = params(VAddrBits)+1) } -class FrontendReq()(implicit val conf: ICacheConfig) extends BundleWithConf { - val pc = UInt(width = conf.as.vaddrBits+1) -} - -class FrontendResp(implicit val conf: ICacheConfig) extends BundleWithConf { - val pc = UInt(width = conf.as.vaddrBits+1) // ID stage PC - val data = Bits(width = conf.ibytes*8) +class FrontendResp extends Bundle { + val pc = UInt(width = params(VAddrBits)+1) // ID stage PC + val data = Bits(width = params(InstBytes)*8) val xcpt_ma = Bool() val xcpt_if = Bool() } -class CPUFrontendIO(implicit conf: ICacheConfig) extends Bundle { +class CPUFrontendIO extends Bundle { val req = Valid(new FrontendReq) val resp = Decoupled(new FrontendResp).flip - val btb_resp = Valid(new BTBResp()(conf.btb)).flip - val btb_update = Valid(new BTBUpdate()(conf.btb)) - val ptw = new TLBPTWIO()(conf.as).flip + val btb_resp = Valid(new BTBResp).flip + val btb_update = Valid(new BTBUpdate) + val ptw = new TLBPTWIO().flip val invalidate = Bool(OUTPUT) } -class Frontend(implicit c: ICacheConfig) extends Module +class Frontend extends Module { - implicit val (tl, as) = (c.tl, c.as) val io = new Bundle { - val cpu = new CPUFrontendIO()(c).flip + val cpu = new CPUFrontendIO().flip val mem = new UncachedTileLinkIO } - val btb = Module(new BTB()(c.btb)) + val btb = Module(new BTB, params(CoreBTBParams)) val icache = Module(new ICache) - val tlb = Module(new TLB(c.ntlb)) + val tlb = Module(new TLB(params(NTLBEntries))) val s1_pc_ = Reg(UInt()) val s1_pc = s1_pc_ & SInt(-2) // discard LSB of PC (throughout the pipeline) @@ -70,14 +47,14 @@ class Frontend(implicit c: ICacheConfig) extends Module val s2_btb_resp_bits = Reg(btb.io.resp.bits.clone) val s2_xcpt_if = Reg(init=Bool(false)) - val msb = c.as.vaddrBits-1 + val msb = params(VAddrBits)-1 val btbTarget = Cat(btb.io.resp.bits.target(msb), btb.io.resp.bits.target) - val pcp4_0 = s1_pc + UInt(c.ibytes) + val pcp4_0 = s1_pc + UInt(params(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 & c.rowbytes) === (s1_pc & c.rowbytes)) + val s0_same_block = !icmiss && !io.cpu.req.valid && !btb.io.resp.bits.taken && ((pcp4 & params(RowBytes)) === (s1_pc & params(RowBytes))) val stall = io.cpu.resp.valid && !io.cpu.resp.ready when (!stall) { @@ -97,13 +74,13 @@ class Frontend(implicit c: ICacheConfig) extends Module s2_valid := Bool(false) } - btb.io.req := s1_pc & SInt(-c.ibytes) + btb.io.req := s1_pc & SInt(-params(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(c.as.pgIdxBits) + tlb.io.req.bits.vpn := s1_pc >> UInt(params(PgIdxBits)) tlb.io.req.bits.asid := UInt(0) tlb.io.req.bits.passthrough := Bool(false) tlb.io.req.bits.instruction := Bool(true) @@ -117,35 +94,38 @@ class Frontend(implicit c: ICacheConfig) 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(-c.ibytes) // discard PC LSBs - io.cpu.resp.bits.data := icache.io.resp.bits.datablock >> (s2_pc(log2Up(c.rowbytes)-1,log2Up(c.ibytes)) << log2Up(c.ibytes*8)) - io.cpu.resp.bits.xcpt_ma := s2_pc(log2Up(c.ibytes)-1,0) != UInt(0) + 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.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(implicit val conf: ICacheConfig) extends BundleWithConf { - val idx = UInt(width = conf.as.pgIdxBits) - val ppn = UInt(width = conf.as.ppnBits) // delayed one cycle +class ICacheReq extends Bundle { + val idx = UInt(width = params(PgIdxBits)) + val ppn = UInt(width = params(PPNBits)) // delayed one cycle val kill = Bool() // delayed one cycle } -class ICacheResp(implicit val conf: ICacheConfig) extends BundleWithConf { - val data = Bits(width = conf.ibytes*8) - val datablock = Bits(width = conf.rowbits) +class ICacheResp extends Bundle { + val data = Bits(width = params(InstBytes)*8) + val datablock = Bits(width = params(RowBits)) } -class ICache(implicit c: ICacheConfig) extends Module +class ICache extends Module { - implicit val (tl, ln) = (c.tl, c.tl.ln) + 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) val invalidate = Bool(INPUT) val mem = new UncachedTileLinkIO } + require(isPow2(nSets) && isPow2(nWays)) + require(isPow2(params(InstBytes))) + require(params(PgIdxBits) >= params(UntagBits)) val s_ready :: s_request :: s_refill_wait :: s_refill :: Nil = Enum(UInt(), 4) val state = Reg(init=s_ready) @@ -154,13 +134,13 @@ class ICache(implicit c: ICacheConfig) extends Module val rdy = Bool() val s2_valid = Reg(init=Bool(false)) - val s2_addr = Reg(UInt(width = c.as.paddrBits)) + val s2_addr = Reg(UInt(width = params(PAddrBits))) val s2_any_tag_hit = Bool() val s1_valid = Reg(init=Bool(false)) - val s1_pgoff = Reg(UInt(width = c.as.pgIdxBits)) + val s1_pgoff = Reg(UInt(width = params(PgIdxBits))) val s1_addr = Cat(io.req.bits.ppn, s1_pgoff).toUInt - val s1_tag = s1_addr(c.tagbits+c.untagbits-1,c.untagbits) + val s1_tag = s1_addr(params(TagBits)+params(UntagBits)-1,params(UntagBits)) val s0_valid = io.req.valid || s1_valid && stall val s0_pgoff = Mux(s1_valid && stall, s1_pgoff, io.req.bits.idx) @@ -175,9 +155,9 @@ class ICache(implicit c: ICacheConfig) extends Module s2_addr := s1_addr } - val s2_tag = s2_addr(c.tagbits+c.untagbits-1,c.untagbits) - val s2_idx = s2_addr(c.untagbits-1,c.offbits) - val s2_offset = s2_addr(c.offbits-1,0) + 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_hit = s2_valid && s2_any_tag_hit val s2_miss = s2_valid && !s2_any_tag_hit rdy := state === s_ready && !s2_miss @@ -187,8 +167,8 @@ class ICache(implicit c: ICacheConfig) extends Module var refill_valid = io.mem.grant.valid var refill_bits = io.mem.grant.bits def doRefill(g: Grant): Bool = Bool(true) - if(c.refillcycles > 1) { - val ser = Module(new FlowThroughSerializer(io.mem.grant.bits, c.refillcycles, doRefill)) + if(params(RefillCycles) > 1) { + val ser = Module(new FlowThroughSerializer(io.mem.grant.bits, params(RefillCycles), doRefill)) ser.io.in <> io.mem.grant refill_cnt = ser.io.cnt refill_done = ser.io.done @@ -200,21 +180,21 @@ class ICache(implicit c: ICacheConfig) extends Module } //assert(!c.tlco.isVoluntary(refill_bits.payload) || !refill_valid, "UncachedRequestors shouldn't get voluntary grants.") - val repl_way = if (c.dm) UInt(0) else LFSR16(s2_miss)(log2Up(c.assoc)-1,0) - val enc_tagbits = c.code.width(c.tagbits) - val tag_array = Mem(Bits(width = enc_tagbits*c.assoc), c.sets, seqRead = true) + val repl_way = if (params(IsDM)) UInt(0) else LFSR16(s2_miss)(log2Up(nWays)-1,0) + val entagbits = ecc.width(params(TagBits)) + val tag_array = Mem(Bits(width = entagbits*nWays), nSets, seqRead = true) val tag_raddr = Reg(UInt()) when (refill_done) { - val wmask = FillInterleaved(enc_tagbits, if (c.dm) Bits(1) else UIntToOH(repl_way)) - val tag = c.code.encode(s2_tag).toUInt - tag_array.write(s2_idx, Fill(c.assoc, tag), wmask) + val wmask = FillInterleaved(entagbits, if (params(IsDM)) Bits(1) else UIntToOH(repl_way)) + val tag = ecc.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(c.untagbits-1,c.offbits) + tag_raddr := s0_pgoff(params(UntagBits)-1,params(OffBits)) } - val vb_array = Reg(init=Bits(0, c.lines)) + val vb_array = Reg(init=Bits(0, nSets*nWays)) when (refill_done && !invalidated) { vb_array := vb_array.bitSet(Cat(repl_way, s2_idx), Bool(true)) } @@ -222,59 +202,59 @@ class ICache(implicit c: ICacheConfig) extends Module vb_array := Bits(0) invalidated := Bool(true) } - val s2_disparity = Vec.fill(c.assoc){Bool()} - for (i <- 0 until c.assoc) + val s2_disparity = Vec.fill(nWays){Bool()} + for (i <- 0 until nWays) when (s2_valid && s2_disparity(i)) { vb_array := vb_array.bitSet(Cat(UInt(i), s2_idx), Bool(false)) } - val s1_tag_match = Vec.fill(c.assoc){Bool()} - val s2_tag_hit = Vec.fill(c.assoc){Bool()} - val s2_dout = Vec.fill(c.assoc){Reg(Bits())} + val s1_tag_match = Vec.fill(nWays){Bool()} + val s2_tag_hit = Vec.fill(nWays){Bool()} + val s2_dout = Vec.fill(nWays){Reg(Bits())} - for (i <- 0 until c.assoc) { - val s1_vb = vb_array(Cat(UInt(i), s1_pgoff(c.untagbits-1,c.offbits))).toBool + for (i <- 0 until nWays) { + val s1_vb = vb_array(Cat(UInt(i), s1_pgoff(params(UntagBits)-1,params(OffBits)))).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)(enc_tagbits*(i+1)-1, enc_tagbits*i) + 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 := c.code.decode(tag_out).error + s2_tag_disparity := ecc.decode(tag_out).error s2_tag_match := s1_tag_match(i) } - s1_tag_match(i) := tag_out(c.tagbits-1,0) === s1_tag + s1_tag_match(i) := tag_out(params(TagBits)-1,0) === s1_tag s2_tag_hit(i) := s2_vb && s2_tag_match - s2_disparity(i) := s2_vb && (s2_tag_disparity || c.code.decode(s2_dout(i)).error) + s2_disparity(i) := s2_vb && (s2_tag_disparity || ecc.decode(s2_dout(i)).error) } s2_any_tag_hit := s2_tag_hit.reduceLeft(_||_) && !s2_disparity.reduceLeft(_||_) - for (i <- 0 until c.assoc) { - val data_array = Mem(Bits(width = c.code.width(c.rowbits)), c.sets*c.refillcycles, seqRead = true) + for (i <- 0 until nWays) { + val data_array = Mem(Bits(width = ecc.width(params(RowBits))), nSets*params(RefillCycles), seqRead = true) val s1_raddr = Reg(UInt()) when (refill_valid && repl_way === UInt(i)) { - val e_d = c.code.encode(refill_bits.payload.data) - if(c.refillcycles > 1) data_array(Cat(s2_idx,refill_cnt)) := e_d + val e_d = ecc.encode(refill_bits.payload.data) + if(params(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(c.untagbits-1,c.offbits-(if(c.refillcycles > 1) refill_cnt.getWidth else 0)) + s1_raddr := s0_pgoff(params(UntagBits)-1,params(OffBits)-(if(params(RefillCycles) > 1) refill_cnt.getWidth else 0)) } // if s1_tag_match is critical, replace with partial tag check - when (s1_valid && rdy && !stall && (Bool(c.dm) || s1_tag_match(i))) { s2_dout(i) := data_array(s1_raddr) } + when (s1_valid && rdy && !stall && (Bool(params(IsDM)) || s1_tag_match(i))) { s2_dout(i) := data_array(s1_raddr) } } - val s2_dout_word = s2_dout.map(x => (x >> (s2_offset(log2Up(c.rowbytes)-1,log2Up(c.ibytes)) << log2Up(c.ibytes*8)))(c.ibytes*8-1,0)) + 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)) io.resp.bits.data := Mux1H(s2_tag_hit, s2_dout_word) io.resp.bits.datablock := Mux1H(s2_tag_hit, s2_dout) val ack_q = Module(new Queue(new LogicalNetworkIO(new Finish), 1)) - ack_q.io.enq.valid := refill_done && tl.co.requiresAckForGrant(refill_bits.payload.g_type) + ack_q.io.enq.valid := refill_done && co.requiresAckForGrant(refill_bits.payload.g_type) ack_q.io.enq.bits.payload.master_xact_id := refill_bits.payload.master_xact_id ack_q.io.enq.bits.header.dst := refill_bits.header.src // 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(tl.co.getUncachedReadAcquireType, s2_addr >> UInt(c.offbits), UInt(0)) + io.mem.acquire.bits.payload := Acquire(co.getUncachedReadAcquireType, s2_addr >> UInt(params(OffBits)), UInt(0)) io.mem.finish <> ack_q.io.deq // control state machine diff --git a/rocket/src/main/scala/multiplier.scala b/rocket/src/main/scala/multiplier.scala index 4f43bd41..02cf199c 100644 --- a/rocket/src/main/scala/multiplier.scala +++ b/rocket/src/main/scala/multiplier.scala @@ -4,26 +4,26 @@ import Chisel._ import ALU._ import Util._ -class MultiplierReq(implicit val conf: RocketConfiguration) extends BundleWithConf { +class MultiplierReq extends Bundle { val fn = Bits(width = SZ_ALU_FN) val dw = Bits(width = SZ_DW) - val in1 = Bits(width = conf.xprlen) - val in2 = Bits(width = conf.xprlen) - val tag = UInt(width = conf.nxprbits) + val in1 = Bits(width = params(XprLen)) + val in2 = Bits(width = params(XprLen)) + val tag = UInt(width = params(NXprBits)) } -class MultiplierResp(implicit val conf: RocketConfiguration) extends BundleWithConf { - val data = Bits(width = conf.xprlen) - val tag = UInt(width = conf.nxprbits) +class MultiplierResp extends Bundle { + val data = Bits(width = params(XprLen)) + val tag = UInt(width = params(NXprBits)) } -class MultiplierIO(implicit conf: RocketConfiguration) extends Bundle { +class MultiplierIO extends Bundle { val req = Decoupled(new MultiplierReq).flip val kill = Bool(INPUT) val resp = Decoupled(new MultiplierResp) } -class MulDiv(mulUnroll: Int = 1, earlyOut: Boolean = false)(implicit conf: RocketConfiguration) extends Module { +class MulDiv(mulUnroll: Int = 1, earlyOut: Boolean = false) extends Module { val io = new MultiplierIO val w = io.req.bits.in1.getWidth val mulw = (w+mulUnroll-1)/mulUnroll*mulUnroll diff --git a/rocket/src/main/scala/nbdcache.scala b/rocket/src/main/scala/nbdcache.scala index e7851298..0a33d01d 100644 --- a/rocket/src/main/scala/nbdcache.scala +++ b/rocket/src/main/scala/nbdcache.scala @@ -4,47 +4,25 @@ import Chisel._ import uncore._ import Util._ -case class DCacheConfig(val sets: Int, val ways: Int, - nmshr: Int, nrpq: Int, nsdq: Int, ntlb: Int, - val tl: TileLinkConfiguration, - val as: AddressSpaceConfiguration, - reqtagbits: Int, databits: Int, - rowwords: Int = 2, - code: Code = new IdentityCode, - narrowRead: Boolean = true) extends CacheConfig { - def states = tl.co.nClientStates - def lines = sets*ways - def dm = ways == 1 - def offbits = log2Up(tl.dataBits/8) - def ppnbits = as.ppnBits - def vpnbits = as.vpnBits - def pgidxbits = as.pgIdxBits - def maxaddrbits = ppnbits.max(vpnbits+1) + pgidxbits - def paddrbits = as.paddrBits - def lineaddrbits = paddrbits - offbits - def idxbits = log2Up(sets) - def waybits = log2Up(ways) - def untagbits = offbits + idxbits - def tagbits = lineaddrbits - idxbits - def databytes = databits/8 - def wordoffbits = log2Up(databytes) - def rowbits = rowwords*databits - def rowbytes = rowwords*databytes - def rowoffbits = log2Up(rowbytes) - def refillcycles = tl.dataBits/(rowbits) - def isNarrowRead = narrowRead && databits*ways % rowbits == 0 - val statebits = log2Up(states) - val encdatabits = code.width(databits) - val encrowbits = rowwords*encdatabits - val lrsc_cycles = 32 // ISA requires 16-insn LRSC sequences to succeed - - require(states > 0) - require(isPow2(sets)) - require(isPow2(ways)) // TODO: relax this - require(rowbits <= tl.dataBits) - require(lineaddrbits == tl.addrBits) - require(untagbits <= pgidxbits) -} +//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] class StoreGen(typ: Bits, addr: Bits, dat: Bits) { @@ -78,69 +56,68 @@ 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 MSHRReq(implicit val cacheconf: DCacheConfig) extends HellaCacheReq { +class MSHRReq extends HellaCacheReq { val tag_match = Bool() val old_meta = new L1Metadata - val way_en = Bits(width = cacheconf.ways) + val way_en = Bits(width = params(NWays)) } -class Replay(implicit conf: DCacheConfig) extends HellaCacheReq { - val sdq_id = UInt(width = log2Up(conf.nsdq)) +class Replay extends HellaCacheReq { + val sdq_id = UInt(width = log2Up(params(StoreDataQueueDepth))) } -class DataReadReq(implicit val conf: DCacheConfig) extends BundleWithConf { - val way_en = Bits(width = conf.ways) - val addr = Bits(width = conf.untagbits) +class DataReadReq extends Bundle { + val way_en = Bits(width = params(NWays)) + val addr = Bits(width = params(UntagBits)) } -class DataWriteReq(implicit conf: DCacheConfig) extends DataReadReq { - val wmask = Bits(width = conf.rowwords) - val data = Bits(width = conf.encrowbits) +class DataWriteReq extends DataReadReq { + val wmask = Bits(width = params(RowWords)) + val data = Bits(width = params(EncRowBits)) } -class L1MetaReadReq(implicit conf: DCacheConfig) extends MetaReadReq { - val tag = Bits(width = conf.tagbits) +class L1MetaReadReq extends MetaReadReq { + val tag = Bits(width = params(TagBits)) } -class L1MetaWriteReq(implicit conf: DCacheConfig) extends +class L1MetaWriteReq extends MetaWriteReq[L1Metadata](new L1Metadata) object L1Metadata { - def apply(tag: Bits, coh: ClientMetadata)(implicit conf: DCacheConfig) = { + def apply(tag: Bits, coh: ClientMetadata) = { val meta = new L1Metadata meta.tag := tag meta.coh := coh meta } } -class L1Metadata(implicit val conf: DCacheConfig) extends Metadata { - val coh = conf.tl.co.clientMetadataOnFlush.clone +class L1Metadata extends Metadata { + val coh = params(TLCoherence).clientMetadataOnFlush.clone } -class InternalProbe(implicit conf: TileLinkConfiguration) extends Probe()(conf) - with HasClientTransactionId +class InternalProbe extends Probe with HasClientTransactionId -class WritebackReq(implicit val conf: DCacheConfig) extends BundleWithConf { - val tag = Bits(width = conf.tagbits) - val idx = Bits(width = conf.idxbits) - val way_en = Bits(width = conf.ways) - val client_xact_id = Bits(width = conf.tl.clientXactIdBits) - val master_xact_id = Bits(width = conf.tl.masterXactIdBits) - val r_type = UInt(width = conf.tl.co.releaseTypeWidth) +class WritebackReq extends Bundle { + val tag = Bits(width = params(TagBits)) + val idx = Bits(width = params(IdxBits)) + val way_en = Bits(width = params(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) } -class MSHR(id: Int)(implicit conf: DCacheConfig) extends Module { - implicit val (tl, ln) = (conf.tl, conf.tl.ln) +class MSHR(id: Int) extends Module { + val co = params(TLCoherence) val io = new Bundle { val req_pri_val = Bool(INPUT) val req_pri_rdy = Bool(OUTPUT) val req_sec_val = Bool(INPUT) val req_sec_rdy = Bool(OUTPUT) val req_bits = new MSHRReq().asInput - val req_sdq_id = UInt(INPUT, log2Up(conf.nsdq)) + val req_sdq_id = UInt(INPUT, log2Up(params(StoreDataQueueDepth))) val idx_match = Bool(OUTPUT) - val tag = Bits(OUTPUT, conf.tagbits) + val tag = Bits(OUTPUT, params(TagBits)) val mem_req = Decoupled(new Acquire) val mem_resp = new DataWriteReq().asOutput @@ -158,25 +135,25 @@ class MSHR(id: Int)(implicit conf: DCacheConfig) extends Module { val acquire_type = Reg(UInt()) val release_type = Reg(UInt()) - val line_state = Reg(new ClientMetadata()(tl.co)) - val refill_count = Reg(UInt(width = log2Up(conf.refillcycles))) // TODO: zero-width wire + val line_state = Reg(new ClientMetadata()(co)) + val refill_count = Reg(UInt(width = log2Up(params(RefillCycles)))) // TODO: zero-width wire val req = Reg(new MSHRReq()) val req_cmd = io.req_bits.cmd - val req_idx = req.addr(conf.untagbits-1,conf.offbits) - val idx_match = req_idx === io.req_bits.addr(conf.untagbits-1,conf.offbits) - 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) && !tl.co.needsTransactionOnSecondaryMiss(req_cmd, io.mem_req.bits)) + 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 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(conf.refillcycles)) + require(isPow2(params(RefillCycles))) val reply = io.mem_grant.valid && io.mem_grant.bits.payload.client_xact_id === UInt(id) - val refill_done = reply && (if(conf.refillcycles > 1) refill_count.andR else Bool(true)) + val refill_done = reply && (if(params(RefillCycles) > 1) refill_count.andR else Bool(true)) val wb_done = reply && (state === s_wb_resp) - val meta_on_flush = tl.co.clientMetadataOnFlush - val meta_on_grant = tl.co.clientMetadataOnGrant(io.mem_grant.bits.payload, io.mem_req.bits) - val meta_on_hit = tl.co.clientMetadataOnHit(req_cmd, io.req_bits.old_meta.coh) + val meta_on_flush = co.clientMetadataOnFlush + val meta_on_grant = co.clientMetadataOnGrant(io.mem_grant.bits.payload, io.mem_req.bits) + val meta_on_hit = co.clientMetadataOnHit(req_cmd, io.req_bits.old_meta.coh) - val rpq = Module(new Queue(new Replay, conf.nrpq)) + val rpq = Module(new Queue(new Replay, params(ReplayQueueDepth))) rpq.io.enq.valid := (io.req_pri_val && io.req_pri_rdy || io.req_sec_val && sec_rdy) && !isPrefetch(req_cmd) rpq.io.enq.bits := io.req_bits rpq.io.enq.bits.sdq_id := io.req_sdq_id @@ -195,7 +172,7 @@ class MSHR(id: Int)(implicit conf: DCacheConfig) extends Module { when (state === s_refill_resp) { when (refill_done) { state := s_meta_write_req } when (reply) { - if(conf.refillcycles > 1) refill_count := refill_count + UInt(1) + if(params(RefillCycles) > 1) refill_count := refill_count + UInt(1) line_state := meta_on_grant } } @@ -213,29 +190,29 @@ class MSHR(id: Int)(implicit conf: DCacheConfig) extends Module { } when (io.req_sec_val && io.req_sec_rdy) { // s_wb_req, s_wb_resp, s_refill_req - acquire_type := tl.co.getAcquireTypeOnSecondaryMiss(req_cmd, meta_on_flush, io.mem_req.bits) + acquire_type := co.getAcquireTypeOnSecondaryMiss(req_cmd, meta_on_flush, io.mem_req.bits) } when (io.req_pri_val && io.req_pri_rdy) { line_state := meta_on_flush refill_count := UInt(0) - acquire_type := tl.co.getAcquireTypeOnPrimaryMiss(req_cmd, meta_on_flush) - release_type := tl.co.getReleaseTypeOnVoluntaryWriteback() //TODO downgrades etc + acquire_type := co.getAcquireTypeOnPrimaryMiss(req_cmd, meta_on_flush) + release_type := co.getReleaseTypeOnVoluntaryWriteback() //TODO downgrades etc req := io.req_bits when (io.req_bits.tag_match) { - when (tl.co.isHit(req_cmd, io.req_bits.old_meta.coh)) { // set dirty bit + when (co.isHit(req_cmd, io.req_bits.old_meta.coh)) { // set dirty bit state := s_meta_write_req line_state := meta_on_hit }.otherwise { // upgrade permissions state := s_refill_req } }.otherwise { // writback if necessary and refill - state := Mux(tl.co.needsWriteback(io.req_bits.old_meta.coh), s_wb_req, s_meta_clear) + state := Mux(co.needsWriteback(io.req_bits.old_meta.coh), s_wb_req, s_meta_clear) } } val ackq = Module(new Queue(new LogicalNetworkIO(new Finish), 1)) - ackq.io.enq.valid := (wb_done || refill_done) && tl.co.requiresAckForGrant(io.mem_grant.bits.payload.g_type) + ackq.io.enq.valid := (wb_done || refill_done) && co.requiresAckForGrant(io.mem_grant.bits.payload.g_type) ackq.io.enq.bits.payload.master_xact_id := io.mem_grant.bits.payload.master_xact_id ackq.io.enq.bits.header.dst := io.mem_grant.bits.header.src val can_finish = state === s_invalid || state === s_refill_req || state === s_refill_resp @@ -245,8 +222,8 @@ class MSHR(id: Int)(implicit conf: DCacheConfig) extends Module { io.idx_match := (state != s_invalid) && idx_match io.mem_resp := req - io.mem_resp.addr := (if(conf.refillcycles > 1) Cat(req_idx, refill_count) else req_idx) << conf.rowoffbits - io.tag := req.addr >> conf.untagbits + 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.req_pri_rdy := state === s_invalid io.req_sec_rdy := sec_rdy && rpq.io.enq.ready @@ -267,7 +244,7 @@ class MSHR(id: Int)(implicit conf: DCacheConfig) extends Module { io.wb_req.bits.way_en := req.way_en io.wb_req.bits.client_xact_id := Bits(id) io.wb_req.bits.master_xact_id := Bits(0) // DNC - io.wb_req.bits.r_type := tl.co.getReleaseTypeOnVoluntaryWriteback() + io.wb_req.bits.r_type := co.getReleaseTypeOnVoluntaryWriteback() io.mem_req.valid := state === s_refill_req && ackq.io.enq.ready io.mem_req.bits.a_type := acquire_type @@ -282,7 +259,7 @@ class MSHR(id: Int)(implicit conf: DCacheConfig) 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(conf.offbits-1,0)).toUInt + io.replay.bits.addr := Cat(io.tag, req_idx, rpq.io.deq.bits.addr(params(OffBits)-1,0)).toUInt when (!io.meta_read.ready) { rpq.io.deq.ready := Bool(false) @@ -290,8 +267,7 @@ class MSHR(id: Int)(implicit conf: DCacheConfig) extends Module { } } -class MSHRFile(implicit conf: DCacheConfig) extends Module { - implicit val (tl, ln) = (conf.tl, conf.tl.ln) +class MSHRFile extends Module { val io = new Bundle { val req = Decoupled(new MSHRReq).flip val secondary_miss = Bool(OUTPUT) @@ -309,26 +285,26 @@ class MSHRFile(implicit conf: DCacheConfig) extends Module { val fence_rdy = Bool(OUTPUT) } - val sdq_val = Reg(init=Bits(0, conf.nsdq)) - val sdq_alloc_id = PriorityEncoder(~sdq_val(conf.nsdq-1,0)) + val sdq_val = Reg(init=Bits(0, params(StoreDataQueueDepth))) + val sdq_alloc_id = PriorityEncoder(~sdq_val(params(StoreDataQueueDepth)-1,0)) val sdq_rdy = !sdq_val.andR val sdq_enq = io.req.valid && io.req.ready && isWrite(io.req.bits.cmd) - val sdq = Mem(io.req.bits.data, conf.nsdq) + val sdq = Mem(io.req.bits.data, params(StoreDataQueueDepth)) when (sdq_enq) { sdq(sdq_alloc_id) := io.req.bits.data } - val idxMatch = Vec.fill(conf.nmshr){Bool()} - val tagList = Vec.fill(conf.nmshr){Bits()} - val tag_match = Mux1H(idxMatch, tagList) === io.req.bits.addr >> conf.untagbits + 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 wbTagList = Vec.fill(conf.nmshr){Bits()} - val memRespMux = Vec.fill(conf.nmshr){new DataWriteReq} - val meta_read_arb = Module(new Arbiter(new L1MetaReadReq, conf.nmshr)) - val meta_write_arb = Module(new Arbiter(new L1MetaWriteReq, conf.nmshr)) - val mem_req_arb = Module(new Arbiter(new Acquire, conf.nmshr)) - val mem_finish_arb = Module(new Arbiter(new LogicalNetworkIO(new Finish), conf.nmshr)) - val wb_req_arb = Module(new Arbiter(new WritebackReq, conf.nmshr)) - val replay_arb = Module(new Arbiter(new Replay, conf.nmshr)) - val alloc_arb = Module(new Arbiter(Bool(), conf.nmshr)) + val wbTagList = Vec.fill(params(NMSHRs)){Bits()} + val memRespMux = Vec.fill(params(NMSHRs)){new DataWriteReq} + val meta_read_arb = Module(new Arbiter(new L1MetaReadReq, params(NMSHRs))) + val meta_write_arb = Module(new Arbiter(new L1MetaWriteReq, params(NMSHRs))) + val mem_req_arb = Module(new Arbiter(new Acquire, params(NMSHRs))) + val mem_finish_arb = Module(new Arbiter(new LogicalNetworkIO(new Finish), params(NMSHRs))) + val wb_req_arb = Module(new Arbiter(new WritebackReq, params(NMSHRs))) + val replay_arb = Module(new Arbiter(new Replay, params(NMSHRs))) + val alloc_arb = Module(new Arbiter(Bool(), params(NMSHRs))) var idx_match = Bool(false) var pri_rdy = Bool(false) @@ -337,7 +313,7 @@ class MSHRFile(implicit conf: DCacheConfig) extends Module { io.fence_rdy := true io.probe_rdy := true - for (i <- 0 to conf.nmshr-1) { + for (i <- 0 until params(NMSHRs)) { val mshr = Module(new MSHR(i)) idxMatch(i) := mshr.io.idx_match @@ -386,26 +362,25 @@ class MSHRFile(implicit conf: DCacheConfig) extends Module { io.replay <> replay_arb.io.out when (io.replay.valid || sdq_enq) { - sdq_val := sdq_val & ~(UIntToOH(io.replay.bits.sdq_id) & Fill(conf.nsdq, free_sdq)) | - PriorityEncoderOH(~sdq_val(conf.nsdq-1,0)) & Fill(conf.nsdq, sdq_enq) + sdq_val := sdq_val & ~(UIntToOH(io.replay.bits.sdq_id) & Fill(params(StoreDataQueueDepth), free_sdq)) | + PriorityEncoderOH(~sdq_val(params(StoreDataQueueDepth)-1,0)) & Fill(params(StoreDataQueueDepth), sdq_enq) } } -class WritebackUnit(implicit conf: DCacheConfig) extends Module { - implicit val tl = conf.tl +class WritebackUnit extends Module { 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, conf.encrowbits) + val data_resp = Bits(INPUT, params(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(conf.refillcycles+1))) + val cnt = Reg(init = UInt(0, width = log2Up(params(RefillCycles)+1))) val req = Reg(new WritebackReq) io.release.valid := false @@ -416,8 +391,8 @@ class WritebackUnit(implicit conf: DCacheConfig) extends Module { r1_data_req_fired := true cnt := cnt + 1 } - if(conf.refillcycles > 1) { // Coalescing buffer inserted - when (!r1_data_req_fired && !r2_data_req_fired && cnt === conf.refillcycles) { + if(params(RefillCycles) > 1) { // Coalescing buffer inserted + when (!r1_data_req_fired && !r2_data_req_fired && cnt === params(RefillCycles)) { io.release.valid := true active := !io.release.ready } @@ -440,7 +415,7 @@ class WritebackUnit(implicit conf: DCacheConfig) extends Module { req := io.req.bits } - val fire = active && cnt < UInt(conf.refillcycles) + val fire = active && cnt < UInt(params(RefillCycles)) io.req.ready := !active // We reissue the meta read as it sets up the muxing for s2_data_muxed @@ -450,20 +425,20 @@ class WritebackUnit(implicit conf: DCacheConfig) extends Module { io.data_req.valid := fire io.data_req.bits.way_en := req.way_en - if(conf.refillcycles > 1) { - io.data_req.bits.addr := Cat(req.idx, cnt(log2Up(conf.refillcycles)-1,0)) << conf.rowoffbits + if(params(RefillCycles) > 1) { + io.data_req.bits.addr := Cat(req.idx, cnt(log2Up(params(RefillCycles))-1,0)) << params(RowOffBits) } else { - io.data_req.bits.addr := req.idx << conf.rowoffbits + io.data_req.bits.addr := req.idx << params(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(conf.refillcycles > 1) { + if(params(RefillCycles) > 1) { val data_buf = Reg(Bits()) when(active && r2_data_req_fired) { - data_buf := Cat(io.data_resp, data_buf(conf.refillcycles*conf.encrowbits-1, conf.encrowbits)) + data_buf := Cat(io.data_resp, data_buf(params(RefillCycles)*params(EncRowBits)-1, params(EncRowBits))) } io.release.bits.data := data_buf } else { @@ -472,22 +447,22 @@ class WritebackUnit(implicit conf: DCacheConfig) extends Module { } -class ProbeUnit(implicit conf: DCacheConfig) extends Module { - implicit val tl = conf.tl +class ProbeUnit extends Module { + val co = params(TLCoherence) 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, conf.ways) + val way_en = Bits(INPUT, params(NWays)) val mshr_rdy = Bool(INPUT) - val line_state = new ClientMetadata()(tl.co).asInput + val line_state = new ClientMetadata()(co).asInput } val s_reset :: s_invalid :: s_meta_read :: s_meta_resp :: s_mshr_req :: s_release :: s_writeback_req :: s_writeback_resp :: s_meta_write :: Nil = Enum(UInt(), 9) val state = Reg(init=s_invalid) - val line_state = Reg(tl.co.clientMetadataOnFlush.clone) + val line_state = Reg(co.clientMetadataOnFlush.clone) val way_en = Reg(Bits()) val req = Reg(new InternalProbe) val hit = way_en.orR @@ -504,7 +479,7 @@ class ProbeUnit(implicit conf: DCacheConfig) extends Module { when (state === s_release && io.rep.ready) { state := s_invalid when (hit) { - state := Mux(tl.co.needsWriteback(line_state), s_writeback_req, s_meta_write) + state := Mux(co.needsWriteback(line_state), s_writeback_req, s_meta_write) } } when (state === s_mshr_req) { @@ -528,65 +503,65 @@ class ProbeUnit(implicit conf: DCacheConfig) extends Module { } io.req.ready := state === s_invalid - io.rep.valid := state === s_release && !(hit && tl.co.needsWriteback(line_state)) - io.rep.bits := Release(tl.co.getReleaseTypeOnProbe(req, Mux(hit, line_state, tl.co.clientMetadataOnFlush)), req.addr, req.client_xact_id, req.master_xact_id) + io.rep.valid := state === s_release && !(hit && co.needsWriteback(line_state)) + io.rep.bits := Release(co.getReleaseTypeOnProbe(req, Mux(hit, line_state, co.clientMetadataOnFlush)), req.addr, req.client_xact_id, req.master_xact_id) io.meta_read.valid := state === s_meta_read io.meta_read.bits.idx := req.addr - io.meta_read.bits.tag := req.addr >> conf.idxbits + io.meta_read.bits.tag := req.addr >> params(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 := tl.co.clientMetadataOnProbe(req, line_state) - io.meta_write.bits.data.tag := req.addr >> UInt(conf.idxbits) + io.meta_write.bits.data.coh := co.clientMetadataOnProbe(req, line_state) + io.meta_write.bits.data.tag := req.addr >> UInt(params(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(conf.idxbits) - io.wb_req.bits.r_type := tl.co.getReleaseTypeOnProbe(req, Mux(hit, line_state, tl.co.clientMetadataOnFlush)) + io.wb_req.bits.tag := req.addr >> UInt(params(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(implicit conf: DCacheConfig) extends Module { +class DataArray extends Module { val io = new Bundle { val read = Decoupled(new DataReadReq).flip val write = Decoupled(new DataWriteReq).flip - val resp = Vec.fill(conf.ways){Bits(OUTPUT, conf.encrowbits)} + val resp = Vec.fill(params(NWays)){Bits(OUTPUT, params(EncRowBits))} } - val waddr = io.write.bits.addr >> conf.rowoffbits - val raddr = io.read.bits.addr >> conf.rowoffbits + val waddr = io.write.bits.addr >> params(RowOffBits) + val raddr = io.read.bits.addr >> params(RowOffBits) - if (conf.isNarrowRead) { - for (w <- 0 until conf.ways by conf.rowwords) { - val wway_en = io.write.bits.way_en(w+conf.rowwords-1,w) - val rway_en = io.read.bits.way_en(w+conf.rowwords-1,w) - val resp = Vec.fill(conf.rowwords){Bits(width = conf.encrowbits)} + 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))} val r_raddr = RegEnable(io.read.bits.addr, io.read.valid) for (p <- 0 until resp.size) { - val array = Mem(Bits(width=conf.encrowbits), conf.sets*conf.refillcycles, seqRead = true) + val array = Mem(Bits(width=params(EncRowBits)), params(NSets)*params(RefillCycles), seqRead = true) when (wway_en.orR && io.write.valid && io.write.bits.wmask(p)) { - val data = Fill(conf.rowwords, io.write.bits.data(conf.encdatabits*(p+1)-1,conf.encdatabits*p)) - val mask = FillInterleaved(conf.encdatabits, wway_en) + val data = Fill(params(RowWords), io.write.bits.data(params(EncDataBits)*(p+1)-1,params(EncDataBits)*p)) + val mask = FillInterleaved(params(EncDataBits), wway_en) array.write(waddr, data, mask) } resp(p) := array(RegEnable(raddr, rway_en.orR && io.read.valid)) } - for (dw <- 0 until conf.rowwords) { - val r = Vec(resp.map(_(conf.encdatabits*(dw+1)-1,conf.encdatabits*dw))) + for (dw <- 0 until params(RowWords)) { + val r = Vec(resp.map(_(params(EncDataBits)*(dw+1)-1,params(EncDataBits)*dw))) val resp_mux = if (r.size == 1) r - else Vec(r(r_raddr(conf.rowoffbits-1,conf.wordoffbits)), r.tail:_*) + else Vec(r(r_raddr(params(RowOffBits)-1,params(WordOffBits))), r.tail:_*) io.resp(w+dw) := resp_mux.toBits } } } else { - val wmask = FillInterleaved(conf.encdatabits, io.write.bits.wmask) - for (w <- 0 until conf.ways) { - val array = Mem(Bits(width=conf.encrowbits), conf.sets*conf.refillcycles, seqRead = true) + 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) when (io.write.bits.way_en(w) && io.write.valid) { array.write(waddr, io.write.bits.data, wmask) } @@ -598,17 +573,17 @@ class DataArray(implicit conf: DCacheConfig) extends Module { io.write.ready := Bool(true) } -class AMOALU(implicit conf: DCacheConfig) extends Module { +class AMOALU extends Module { val io = new Bundle { - val addr = Bits(INPUT, conf.offbits) + val addr = Bits(INPUT, params(OffBits)) val cmd = Bits(INPUT, 4) val typ = Bits(INPUT, 3) - val lhs = Bits(INPUT, conf.databits) - val rhs = Bits(INPUT, conf.databits) - val out = Bits(OUTPUT, conf.databits) + val lhs = Bits(INPUT, params(CoreDataBits)) + val rhs = Bits(INPUT, params(CoreDataBits)) + val out = Bits(OUTPUT, params(CoreDataBits)) } - require(conf.databits == 64) + require(params(CoreDataBits) == 64) val storegen = new StoreGen(io.typ, io.addr, io.rhs) val rhs = storegen.wordData @@ -639,27 +614,27 @@ class AMOALU(implicit conf: DCacheConfig) extends Module { io.out := wmask & out | ~wmask & io.lhs } -class HellaCacheReq(implicit val conf: DCacheConfig) extends BundleWithConf { +class HellaCacheReq extends Bundle { val kill = Bool() val typ = Bits(width = MT_SZ) val phys = Bool() - val addr = UInt(width = conf.maxaddrbits) - val data = Bits(width = conf.databits) - val tag = Bits(width = conf.reqtagbits) + 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(implicit val conf: DCacheConfig) extends BundleWithConf { +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 = conf.databits) - val data_subword = Bits(width = conf.databits) - val tag = Bits(width = conf.reqtagbits) + 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 = conf.maxaddrbits) - val store_data = Bits(width = conf.databits) + val addr = UInt(width = params(MaxAddrBits)) + val store_data = Bits(width = params(CoreDataBits)) } class AlignmentExceptions extends Bundle { @@ -673,26 +648,33 @@ class HellaCacheExceptions extends Bundle { } // interface between D$ and processor/DTLB -class HellaCacheIO(implicit conf: DCacheConfig) extends Bundle { +class HellaCacheIO extends Bundle { val req = Decoupled(new HellaCacheReq) val resp = Valid(new HellaCacheResp).flip - val replay_next = Valid(Bits(width = conf.reqtagbits)).flip + val replay_next = Valid(Bits(width = params(CoreReqTagBits))).flip val xcpt = (new HellaCacheExceptions).asInput - val ptw = new TLBPTWIO()(conf.as).flip + val ptw = new TLBPTWIO().flip val ordered = Bool(INPUT) } -class HellaCache(implicit conf: DCacheConfig) extends Module { - implicit val (tl, ln) = (conf.tl, conf.tl.ln) +class HellaCache extends Module { + val co = params(TLCoherence) val io = new Bundle { val cpu = (new HellaCacheIO).flip val mem = new TileLinkIO } - val indexmsb = conf.untagbits-1 - val indexlsb = conf.offbits + require(params(LRSCCycles) >= 32) // ISA requires 16-insn LRSC sequences to succeed + require(isPow2(params(NSets))) + require(isPow2(params(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 = log2Up(conf.databytes) + val offsetlsb = params(WordOffBits) val wb = Module(new WritebackUnit) val prober = Module(new ProbeUnit) @@ -721,12 +703,12 @@ class HellaCache(implicit conf: DCacheConfig) extends Module { val s1_sc = s1_req.cmd === M_XSC val s1_readwrite = s1_read || s1_write || isPrefetch(s1_req.cmd) - val dtlb = Module(new TLB(conf.ntlb)(conf.as)) + val dtlb = Module(new TLB(params(NTLBEntries))) dtlb.io.ptw <> io.cpu.ptw 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 >> conf.pgidxbits + dtlb.io.req.bits.vpn := s1_req.addr >> params(PgIdxBits) dtlb.io.req.bits.instruction := Bool(false) when (!dtlb.io.req.ready && !io.cpu.req.bits.phys) { io.cpu.req.ready := Bool(false) } @@ -734,11 +716,11 @@ class HellaCache(implicit conf: DCacheConfig) 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) << conf.offbits + s1_req.addr := Cat(wb.io.meta_read.bits.tag, wb.io.meta_read.bits.idx) << params(OffBits) 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) << conf.offbits + s1_req.addr := Cat(prober.io.meta_read.bits.tag, prober.io.meta_read.bits.idx) << params(OffBits) s1_req.phys := Bool(true) } when (mshrs.io.replay.valid) { @@ -747,7 +729,7 @@ class HellaCache(implicit conf: DCacheConfig) extends Module { when (s2_recycle) { s1_req := s2_req } - val s1_addr = Cat(dtlb.io.resp.ppn, s1_req.addr(conf.pgidxbits-1,0)) + val s1_addr = Cat(dtlb.io.resp.ppn, s1_req.addr(params(PgIdxBits)-1,0)) when (s1_clk_en) { s2_req.kill := s1_req.kill @@ -773,7 +755,7 @@ class HellaCache(implicit conf: DCacheConfig) extends Module { io.cpu.xcpt.pf.st := s1_write && dtlb.io.resp.xcpt_st // tags - def onReset = L1Metadata(UInt(0), ClientMetadata(UInt(0))(tl.co)) + def onReset = L1Metadata(UInt(0), ClientMetadata(UInt(0))(co)) val meta = Module(new MetadataArray(onReset _)) val metaReadArb = Module(new Arbiter(new MetaReadReq, 5)) val metaWriteArb = Module(new Arbiter(new L1MetaWriteReq, 2)) @@ -787,12 +769,12 @@ class HellaCache(implicit conf: DCacheConfig) 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 conf.rowwords).map(i => conf.code.encode(writeArb.io.out.bits.data(conf.databits*(i+1)-1,conf.databits*i))) + 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))) 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 >> conf.offbits + metaReadArb.io.in(4).bits.idx := io.cpu.req.bits.addr >> params(OffBits) when (!metaReadArb.io.in(4).ready) { io.cpu.req.ready := Bool(false) } // data read for new requests @@ -803,34 +785,34 @@ class HellaCache(implicit conf: DCacheConfig) extends Module { // recycled requests metaReadArb.io.in(0).valid := s2_recycle - metaReadArb.io.in(0).bits.idx := s2_req.addr >> conf.offbits + metaReadArb.io.in(0).bits.idx := s2_req.addr >> params(OffBits) 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 conf.ways).map(f)) - val s1_tag_eq_way = wayMap((w: Int) => meta.io.resp(w).tag === (s1_addr >> conf.untagbits)).toBits - val s1_tag_match_way = wayMap((w: Int) => s1_tag_eq_way(w) && tl.co.isValid(meta.io.resp(w).coh)).toBits + 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 + 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 val s2_tag_match_way = RegEnable(s1_tag_match_way, s1_clk_en) val s2_tag_match = s2_tag_match_way.orR val s2_hit_state = Mux1H(s2_tag_match_way, wayMap((w: Int) => RegEnable(meta.io.resp(w).coh, s1_clk_en))) - val s2_hit = s2_tag_match && tl.co.isHit(s2_req.cmd, s2_hit_state) && s2_hit_state === tl.co.clientMetadataOnHit(s2_req.cmd, s2_hit_state) + val s2_hit = s2_tag_match && co.isHit(s2_req.cmd, s2_hit_state) && s2_hit_state === co.clientMetadataOnHit(s2_req.cmd, s2_hit_state) // load-reserved/store-conditional val lrsc_count = Reg(init=UInt(0)) 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 >> conf.offbits) + val s2_lrsc_addr_match = lrsc_valid && lrsc_addr === (s2_req.addr >> params(OffBits)) 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 := conf.lrsc_cycles-1 } - lrsc_addr := s2_req.addr >> conf.offbits + when (!lrsc_valid) { lrsc_count := params(LRSCCycles)-1 } + lrsc_addr := s2_req.addr >> params(OffBits) } when (s2_sc) { lrsc_count := 0 @@ -838,21 +820,21 @@ class HellaCache(implicit conf: DCacheConfig) extends Module { } when (io.cpu.ptw.sret) { lrsc_count := 0 } - val s2_data = Vec.fill(conf.ways){Bits(width = conf.encrowbits)} - for (w <- 0 until conf.ways) { - val regs = Vec.fill(conf.rowwords){Reg(Bits(width = conf.encdatabits))} + 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 en1 = s1_clk_en && s1_tag_eq_way(w) for (i <- 0 until regs.size) { - val en = en1 && (Bool(i == 0 || !conf.isNarrowRead) || s1_writeback) - when (en) { regs(i) := data.io.resp(w) >> conf.encdatabits*i } + val en = en1 && ((Bool(i == 0) || !params(DoNarrowRead)) || s1_writeback) + when (en) { regs(i) := data.io.resp(w) >> params(EncDataBits)*i } } s2_data(w) := regs.toBits } val s2_data_muxed = Mux1H(s2_tag_match_way, s2_data) - val s2_data_decoded = (0 until conf.rowwords).map(i => conf.code.decode(s2_data_muxed(conf.encdatabits*(i+1)-1,conf.encdatabits*i))) + 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_corrected = Vec(s2_data_decoded.map(_.corrected)).toBits val s2_data_uncorrected = Vec(s2_data_decoded.map(_.uncorrected)).toBits - val s2_word_idx = if (conf.isNarrowRead) UInt(0) else s2_req.addr(log2Up(conf.rowwords*conf.databytes)-1,3) + val s2_word_idx = if (params(DoNarrowRead)) UInt(0) else s2_req.addr(log2Up(params(RowWords)*params(CoreDataBytes))-1,3) val s2_data_correctable = Vec(s2_data_decoded.map(_.correctable)).toBits()(s2_word_idx) // store/amo hits @@ -865,15 +847,15 @@ class HellaCache(implicit conf: DCacheConfig) extends Module { } writeArb.io.in(0).bits.addr := s3_req.addr - writeArb.io.in(0).bits.wmask := UInt(1) << (if(conf.rowoffbits > offsetlsb) - s3_req.addr(conf.rowoffbits-1,offsetlsb).toUInt + writeArb.io.in(0).bits.wmask := UInt(1) << (if(params(RowOffBits) > offsetlsb) + s3_req.addr(params(RowOffBits)-1,offsetlsb).toUInt else UInt(0)) - writeArb.io.in(0).bits.data := Fill(conf.rowwords, s3_req.data) + writeArb.io.in(0).bits.data := Fill(params(RowWords), s3_req.data) writeArb.io.in(0).valid := s3_valid writeArb.io.in(0).bits.way_en := s3_way // replacement policy - val replacer = new RandomReplacement + val replacer = params(Replacer)() val s1_replaced_way_en = UIntToOH(replacer.way) val s2_replaced_way_en = UIntToOH(RegEnable(replacer.way, s1_clk_en)) val s2_repl_meta = Mux1H(s2_replaced_way_en, wayMap((w: Int) => RegEnable(meta.io.resp(w), s1_clk_en && s1_replaced_way_en(w))).toSeq) @@ -914,9 +896,9 @@ class HellaCache(implicit conf: DCacheConfig) extends Module { prober.io.mshr_rdy := mshrs.io.probe_rdy // refills - def doRefill(g: Grant): Bool = tl.co.messageUpdatesDataArray(g) - val refill = if(conf.refillcycles > 1) { - val ser = Module(new FlowThroughSerializer(io.mem.grant.bits, conf.refillcycles, doRefill)) + 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)) ser.io.in <> io.mem.grant ser.io.out } else io.mem.grant @@ -926,7 +908,7 @@ class HellaCache(implicit conf: DCacheConfig) 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(conf.encrowbits-1,0) + writeArb.io.in(1).bits.data := refill.bits.payload.data(params(EncRowBits)-1,0) readArb.io.out.ready := !refill.valid || refill.ready // insert bubble if refill gets blocked readArb.io.out <> data.io.read @@ -947,8 +929,8 @@ class HellaCache(implicit conf: DCacheConfig) 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 >> conf.wordoffbits === r._2.addr >> conf.wordoffbits) && isWrite(r._2.cmd), r._3)) - val s2_store_bypass_data = Reg(Bits(width = conf.databits)) + ).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))) val s2_store_bypass = Reg(Bool()) when (s1_clk_en) { s2_store_bypass := false @@ -959,7 +941,7 @@ class HellaCache(implicit conf: DCacheConfig) extends Module { } // load data subword mux/sign extension - val s2_data_word_prebypass = s2_data_uncorrected >> Cat(s2_word_idx, Bits(0,log2Up(conf.databits))) + val s2_data_word_prebypass = s2_data_uncorrected >> Cat(s2_word_idx, Bits(0,log2Up(params(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) @@ -1006,7 +988,7 @@ class HellaCache(implicit conf: DCacheConfig) extends Module { } // exposes a sane decoupled request interface -class SimpleHellaCacheIF(implicit conf: DCacheConfig) extends Module +class SimpleHellaCacheIF extends Module { val io = new Bundle { val requestor = new HellaCacheIO().flip diff --git a/rocket/src/main/scala/ptw.scala b/rocket/src/main/scala/ptw.scala index 1b42af49..abe534a6 100644 --- a/rocket/src/main/scala/ptw.scala +++ b/rocket/src/main/scala/ptw.scala @@ -4,39 +4,38 @@ import Chisel._ import uncore._ import Util._ -class PTWResp()(implicit val conf: AddressSpaceConfiguration) extends BundleWithConf { +class PTWResp extends Bundle { val error = Bool() - val ppn = UInt(width = conf.ppnBits) - val perm = Bits(width = conf.permBits) + val ppn = UInt(width = params(PPNBits)) + val perm = Bits(width = params(PermBits)) } -class TLBPTWIO()(implicit val conf: AddressSpaceConfiguration) extends BundleWithConf { - val req = Decoupled(UInt(width = conf.vpnBits)) +class TLBPTWIO extends Bundle { + val req = Decoupled(UInt(width = params(VPNBits))) val resp = Valid(new PTWResp).flip val status = new Status().asInput val invalidate = Bool(INPUT) val sret = Bool(INPUT) } -class DatapathPTWIO()(implicit val conf: AddressSpaceConfiguration) extends BundleWithConf { - val ptbr = UInt(INPUT, conf.paddrBits) +class DatapathPTWIO extends Bundle { + val ptbr = UInt(INPUT, params(PAddrBits)) val invalidate = Bool(INPUT) val sret = Bool(INPUT) val status = new Status().asInput } -class PTW(n: Int)(implicit conf: RocketConfiguration) extends Module +class PTW(n: Int) extends Module { - implicit val as = conf.as val io = new Bundle { val requestor = Vec.fill(n){new TLBPTWIO}.flip - val mem = new HellaCacheIO()(conf.dcache) + val mem = new HellaCacheIO val dpath = new DatapathPTWIO } val levels = 3 - val bitsPerLevel = conf.as.vpnBits/levels - require(conf.as.vpnBits == levels * bitsPerLevel) + val bitsPerLevel = params(VPNBits)/levels + require(params(VPNBits) == levels * bitsPerLevel) val s_ready :: s_req :: s_wait :: s_done :: s_error :: Nil = Enum(UInt(), 5) val state = Reg(init=s_ready) @@ -48,14 +47,14 @@ class PTW(n: Int)(implicit conf: RocketConfiguration) extends Module val vpn_idx = Vec((0 until levels).map(i => (r_req_vpn >> (levels-i-1)*bitsPerLevel)(bitsPerLevel-1,0)))(count) - val arb = Module(new RRArbiter(UInt(width = conf.as.vpnBits), n)) + val arb = Module(new RRArbiter(UInt(width = params(VPNBits)), n)) arb.io.in <> io.requestor.map(_.req) arb.io.out.ready := state === s_ready when (arb.io.out.fire()) { r_req_vpn := arb.io.out.bits r_req_dest := arb.io.chosen - r_pte := Cat(io.dpath.ptbr(conf.as.paddrBits-1,conf.as.pgIdxBits), io.mem.resp.bits.data(conf.as.pgIdxBits-1,0)) + r_pte := Cat(io.dpath.ptbr(params(PAddrBits)-1,params(PgIdxBits)), io.mem.resp.bits.data(params(PgIdxBits)-1,0)) } when (io.mem.resp.valid) { @@ -66,13 +65,13 @@ class PTW(n: Int)(implicit conf: RocketConfiguration) extends Module io.mem.req.bits.phys := Bool(true) io.mem.req.bits.cmd := M_XRD io.mem.req.bits.typ := MT_D - io.mem.req.bits.addr := Cat(r_pte(conf.as.paddrBits-1,conf.as.pgIdxBits), vpn_idx).toUInt << log2Up(conf.xprlen/8) + io.mem.req.bits.addr := Cat(r_pte(params(PAddrBits)-1,params(PgIdxBits)), vpn_idx).toUInt << log2Up(params(XprLen)/8) io.mem.req.bits.kill := Bool(false) 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 >> conf.as.pgIdxBits + val r_resp_ppn = io.mem.req.bits.addr >> 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/rocc.scala b/rocket/src/main/scala/rocc.scala index c1ce0694..c0d8decb 100644 --- a/rocket/src/main/scala/rocc.scala +++ b/rocket/src/main/scala/rocc.scala @@ -17,48 +17,46 @@ class RoCCInstruction extends Bundle val opcode = Bits(width = 7) } -class RoCCCommand(implicit val conf: RocketConfiguration) extends BundleWithConf +class RoCCCommand extends Bundle { val inst = new RoCCInstruction - val rs1 = Bits(width = conf.xprlen) - val rs2 = Bits(width = conf.xprlen) + val rs1 = Bits(width = params(XprLen)) + val rs2 = Bits(width = params(XprLen)) } -class RoCCResponse(implicit val conf: RocketConfiguration) extends BundleWithConf +class RoCCResponse extends Bundle { val rd = Bits(width = 5) - val data = Bits(width = conf.xprlen) + val data = Bits(width = params(XprLen)) } -class RoCCInterface(implicit val conf: RocketConfiguration) extends BundleWithConf +class RoCCInterface extends Bundle { - implicit val as = conf.as val cmd = Decoupled(new RoCCCommand).flip val resp = Decoupled(new RoCCResponse) - val mem = new HellaCacheIO()(conf.dcache) + val mem = new HellaCacheIO val busy = Bool(OUTPUT) val s = Bool(INPUT) val interrupt = Bool(OUTPUT) // These should be handled differently, eventually - val imem = new UncachedTileLinkIO()(conf.tl) + val imem = new UncachedTileLinkIO val iptw = new TLBPTWIO val dptw = new TLBPTWIO val pptw = new TLBPTWIO val exception = Bool(INPUT) } -abstract class RoCC(conf: RocketConfiguration) extends Module +abstract class RoCC extends Module { - val io = new RoCCInterface()(conf) - + val io = new RoCCInterface io.mem.req.bits.phys := Bool(true) // don't perform address translation } -class AccumulatorExample(conf: RocketConfiguration) extends RoCC(conf) +class AccumulatorExample extends RoCC { val n = 4 - val regfile = Mem(UInt(width = conf.xprlen), n) + val regfile = Mem(UInt(width = params(XprLen)), n) val busy = Vec.fill(n){Reg(init=Bool(false))} val cmd = Queue(io.cmd) diff --git a/rocket/src/main/scala/tile.scala b/rocket/src/main/scala/tile.scala index f882acf1..fa048908 100644 --- a/rocket/src/main/scala/tile.scala +++ b/rocket/src/main/scala/tile.scala @@ -4,50 +4,46 @@ import Chisel._ import uncore._ import Util._ -case class RocketConfiguration(tl: TileLinkConfiguration, as: AddressSpaceConfiguration, - icache: ICacheConfig, dcache: DCacheConfig, - rocc: Option[RocketConfiguration => RoCC] = None, - retireWidth: Int = 1, - vm: Boolean = true, - fastLoadWord: Boolean = true, - fastLoadByte: Boolean = false, - fastMulDiv: Boolean = true) -{ - val dcacheReqTagBits = 7 // enforce compliance with require() - val xprlen = 64 - val nxpr = 32 - val nxprbits = log2Up(nxpr) - if (fastLoadByte) require(fastLoadWord) -} +case object NDCachePorts extends Field[Int] +case object NTilePorts extends Field[Int] +case object BuildRoCC extends Field[Option[() => RoCC]] +case object RetireWidth extends Field[Int] +case object UseVM extends Field[Boolean] +case object FastLoadWord extends Field[Boolean] +case object FastLoadByte extends Field[Boolean] +case object FastMulDiv extends Field[Boolean] +case object DcacheReqTagBits extends Field[Int] +case object XprLen extends Field[Int] +case object NXpr extends Field[Int] +case object NXprBits extends Field[Int] +case object RocketDCacheParams extends Field[PF] +case object RocketFrontendParams extends Field[PF] -class Tile(resetSignal: Bool = null)(confIn: RocketConfiguration) extends Module(_reset = resetSignal) -{ - val memPorts = 2 + (!confIn.rocc.isEmpty).toInt // Number of ports to outer memory system from tile: 1 from I$, 1 from D$, maybe 1 from Rocc - val dcachePortId = 0 - val icachePortId = 1 - val roccPortId = 2 - val dcachePorts = 2 + (!confIn.rocc.isEmpty).toInt // Number of ports into D$: 1 from core, 1 from PTW, maybe 1 from RoCC - implicit val tlConf = confIn.tl - implicit val lnConf = confIn.tl.ln - implicit val icConf = confIn.icache - implicit val dcConf = confIn.dcache.copy(reqtagbits = confIn.dcacheReqTagBits + log2Up(dcachePorts), databits = confIn.xprlen) - implicit val conf = confIn.copy(dcache = dcConf) - require(conf.retireWidth == 1) // for now... +class Tile(resetSignal: Bool = null) extends Module(_reset = resetSignal) { + + if(params(FastLoadByte)) require(params(FastLoadWord)) + require(params(RetireWidth) == 1) // for now... val io = new Bundle { val tilelink = new TileLinkIO - val host = new HTIFIO(lnConf.nClients) + val host = new HTIFIO } + // Mimic client id extension done by UncachedTileLinkIOArbiter for Acquires from either client) - val core = Module(new Core) + val optionalRoCC = params(BuildRoCC) + + params.alter(params(RocketFrontendParams)) // Used in icache, Core val icache = Module(new Frontend) + params.alter(params(RocketDCacheParams)) // Used in dcache, PTW, RoCCm Core val dcache = Module(new HellaCache) - val ptw = Module(new PTW(if (confIn.rocc.isEmpty) 2 else 5)) // 2 ports, 1 from I$, 1 from D$, maybe 3 from RoCC + val ptw = Module(new PTW(if(optionalRoCC.isEmpty) 2 else 5)) + // 2 ports, 1 from I$, 1 from D$, maybe 3 from RoCC + val core = Module(new Core) - val dcacheArb = Module(new HellaCacheArbiter(dcachePorts)) - dcacheArb.io.requestor(0) <> ptw.io.mem - dcacheArb.io.requestor(1) <> core.io.dmem - dcache.io.cpu <> dcacheArb.io.mem + val dcArb = Module(new HellaCacheArbiter(params(NDCachePorts))) + dcArb.io.requestor(0) <> ptw.io.mem + dcArb.io.requestor(1) <> core.io.dmem + dcArb.io.mem <> dcache.io.cpu ptw.io.requestor(0) <> icache.io.cpu.ptw ptw.io.requestor(1) <> dcache.io.cpu.ptw @@ -56,28 +52,31 @@ class Tile(resetSignal: Bool = null)(confIn: RocketConfiguration) extends Module core.io.imem <> icache.io.cpu core.io.ptw <> ptw.io.dpath - val memArb = Module(new UncachedTileLinkIOArbiterThatAppendsArbiterId(memPorts)) - memArb.io.in(dcachePortId) <> dcache.io.mem - memArb.io.in(icachePortId) <> icache.io.mem + val memArb = Module(new UncachedTileLinkIOArbiterThatAppendsArbiterId(params(NTilePorts))) + val dcPortId = 0 + memArb.io.in(dcPortId) <> dcache.io.mem + memArb.io.in(1) <> icache.io.mem - if (!conf.rocc.isEmpty) { - val rocc = Module((conf.rocc.get)(conf)) + if(!optionalRoCC.isEmpty) { + val rocc = Module(optionalRoCC.get()) val dcIF = Module(new SimpleHellaCacheIF) dcIF.io.requestor <> rocc.io.mem core.io.rocc <> rocc.io - dcacheArb.io.requestor(2) <> dcIF.io.cache - memArb.io.in(roccPortId) <> rocc.io.imem + dcArb.io.requestor(2) <> dcIF.io.cache + memArb.io.in(2) <> rocc.io.imem ptw.io.requestor(2) <> rocc.io.iptw ptw.io.requestor(3) <> rocc.io.dptw ptw.io.requestor(4) <> rocc.io.pptw } - + io.tilelink.acquire <> memArb.io.out.acquire - memArb.io.out.grant <> io.tilelink.grant + io.tilelink.grant <> memArb.io.out.grant io.tilelink.finish <> memArb.io.out.finish - dcache.io.mem.probe <> io.tilelink.probe + // Probes and releases routed directly to coherent dcache + io.tilelink.probe <> dcache.io.mem.probe + // Mimic client id extension done by UncachedTileLinkIOArbiter for Acquires from either client) io.tilelink.release.valid := dcache.io.mem.release.valid dcache.io.mem.release.ready := io.tilelink.release.ready io.tilelink.release.bits := dcache.io.mem.release.bits - io.tilelink.release.bits.payload.client_xact_id := Cat(dcache.io.mem.release.bits.payload.client_xact_id, UInt(dcachePortId, log2Up(memPorts))) // Mimic client id extension done by UncachedTileLinkIOArbiter for Acquires from either client) + io.tilelink.release.bits.payload.client_xact_id := Cat(dcache.io.mem.release.bits.payload.client_xact_id, UInt(dcPortId, log2Up(params(NTilePorts)))) } diff --git a/rocket/src/main/scala/tlb.scala b/rocket/src/main/scala/tlb.scala index 62b757bb..97d735b2 100644 --- a/rocket/src/main/scala/tlb.scala +++ b/rocket/src/main/scala/tlb.scala @@ -1,7 +1,7 @@ package rocket import Chisel._ -import uncore.AddressSpaceConfiguration +import uncore._ import scala.math._ class CAMIO(entries: Int, addr_bits: Int, tag_bits: Int) extends Bundle { @@ -64,26 +64,26 @@ class PseudoLRU(n: Int) } } -class TLBReq()(implicit val conf: AddressSpaceConfiguration) extends BundleWithConf +class TLBReq extends Bundle { - val asid = UInt(width = conf.asidBits) - val vpn = UInt(width = conf.vpnBits+1) + val asid = UInt(width = params(ASIdBits)) + val vpn = UInt(width = params(VPNBits)+1) val passthrough = Bool() val instruction = Bool() } -class TLBResp(entries: Int)(implicit val conf: AddressSpaceConfiguration) extends BundleWithConf +class TLBResp(entries: Int) extends Bundle { // lookup responses val miss = Bool(OUTPUT) val hit_idx = UInt(OUTPUT, entries) - val ppn = UInt(OUTPUT, conf.ppnBits) + val ppn = UInt(OUTPUT, params(PPNBits)) val xcpt_ld = Bool(OUTPUT) val xcpt_st = Bool(OUTPUT) val xcpt_if = Bool(OUTPUT) } -class TLB(entries: Int)(implicit conf: AddressSpaceConfiguration) extends Module +class TLB(entries: Int) extends Module { val io = new Bundle { val req = Decoupled(new TLBReq).flip @@ -96,7 +96,7 @@ class TLB(entries: Int)(implicit conf: AddressSpaceConfiguration) extends Module val r_refill_tag = Reg(UInt()) val r_refill_waddr = Reg(UInt()) - val tag_cam = Module(new RocketCAM(entries, conf.asidBits+conf.vpnBits)) + val tag_cam = Module(new RocketCAM(entries, params(ASIdBits)+params(VPNBits))) val tag_ram = Mem(io.ptw.resp.bits.ppn.clone, entries) val lookup_tag = Cat(io.req.bits.asid, io.req.bits.vpn).toUInt @@ -133,7 +133,7 @@ class TLB(entries: Int)(implicit conf: AddressSpaceConfiguration) extends Module val plru = new PseudoLRU(entries) val repl_waddr = Mux(has_invalid_entry, invalid_entry, plru.replace) - val bad_va = io.req.bits.vpn(conf.vpnBits) != io.req.bits.vpn(conf.vpnBits-1) + val bad_va = io.req.bits.vpn(params(VPNBits)) != io.req.bits.vpn(params(VPNBits)-1) val tlb_hit = io.ptw.status.vm && tag_hit val tlb_miss = io.ptw.status.vm && !tag_hit && !bad_va @@ -146,7 +146,7 @@ class TLB(entries: Int)(implicit conf: AddressSpaceConfiguration) extends Module io.resp.xcpt_st := bad_va || tlb_hit && !Mux(io.ptw.status.s, (sw_array & tag_cam.io.hits).orR, (uw_array & tag_cam.io.hits).orR) io.resp.xcpt_if := bad_va || tlb_hit && !Mux(io.ptw.status.s, (sx_array & tag_cam.io.hits).orR, (ux_array & tag_cam.io.hits).orR) io.resp.miss := tlb_miss - io.resp.ppn := Mux(io.ptw.status.vm && !io.req.bits.passthrough, Mux1H(tag_cam.io.hits, tag_ram), io.req.bits.vpn(conf.ppnBits-1,0)) + io.resp.ppn := Mux(io.ptw.status.vm && !io.req.bits.passthrough, Mux1H(tag_cam.io.hits, tag_ram), io.req.bits.vpn(params(PPNBits)-1,0)) io.resp.hit_idx := tag_cam.io.hits io.ptw.req.valid := state === s_request diff --git a/rocket/src/main/scala/util.scala b/rocket/src/main/scala/util.scala index e52b2e4d..0fc0805f 100644 --- a/rocket/src/main/scala/util.scala +++ b/rocket/src/main/scala/util.scala @@ -27,11 +27,6 @@ object Util { import Util._ -abstract trait BundleWithConf extends Bundle { - val conf: AnyRef - override def clone = this.getClass.getConstructors.head.newInstance(conf).asInstanceOf[this.type] -} - object Str { def apply(s: String): UInt = {