From 190d5c50d9fa76a6408dcda76d8e5568f08907ea Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 20 Sep 2017 13:43:25 -0700 Subject: [PATCH 1/6] Remove deprecated custom-CSR support --- src/main/scala/rocket/CSR.scala | 8 -------- src/main/scala/rocket/RocketCore.scala | 2 -- 2 files changed, 10 deletions(-) diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index c3a05712..a8371c0b 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -190,7 +190,6 @@ class CSRFileIO(implicit p: Parameters) extends CoreBundle val evec = UInt(OUTPUT, vaddrBitsExtended) val exception = Bool(INPUT) val retire = UInt(INPUT, log2Up(1+retireWidth)) - val custom_mrw_csrs = Vec(nCustomMrwCsrs, UInt(INPUT, xLen)) val cause = UInt(INPUT, xLen) val pc = UInt(INPUT, vaddrBitsExtended) val badaddr = UInt(INPUT, vaddrBitsExtended) @@ -438,13 +437,6 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param read_mapping += (CSRs.pmpaddr0 + i) -> pmp.addr } - for (i <- 0 until nCustomMrwCsrs) { - val addr = 0xff0 + i - require(addr < (1 << CSR.ADDRSZ)) - require(!read_mapping.contains(addr), "custom MRW CSR address " + i + " is already in use") - read_mapping += addr -> io.custom_mrw_csrs(i) - } - val decoded_addr = read_mapping map { case (k, v) => k -> (io.rw.addr === k) } val wdata = readModifyWriteCSR(io.rw.cmd, io.rw.rdata, io.rw.wdata) diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index bbed2edd..ae0d251b 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -23,7 +23,6 @@ case class RocketCoreParams( nBreakpoints: Int = 1, nPMPs: Int = 8, nPerfCounters: Int = 0, - nCustomMRWCSRs: Int = 0, nL2TLBEntries: Int = 0, mtvecInit: Option[BigInt] = Some(BigInt(0)), mtvecWritable: Boolean = true, @@ -49,7 +48,6 @@ trait HasRocketCoreParameters extends HasCoreParameters { val nBreakpoints = rocketParams.nBreakpoints val nPMPs = rocketParams.nPMPs val nPerfCounters = rocketParams.nPerfCounters - val nCustomMrwCsrs = rocketParams.nCustomMRWCSRs val mtvecInit = rocketParams.mtvecInit val mtvecWritable = rocketParams.mtvecWritable From ab0821f25b1ceadb40ae58b8e6744963beeeb320 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 20 Sep 2017 14:04:13 -0700 Subject: [PATCH 2/6] Move microarchitecture-neutral params from Rocket to Core This makes some of the units more reusable. --- src/main/scala/rocket/CSR.scala | 8 ++++---- src/main/scala/rocket/PMP.scala | 2 +- src/main/scala/rocket/PTW.scala | 4 ++-- src/main/scala/rocket/RocketCore.scala | 5 ----- src/main/scala/tile/Core.scala | 11 +++++++++++ 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index a8371c0b..989b665a 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -63,7 +63,7 @@ class DCSR extends Bundle { } class MIP(implicit p: Parameters) extends CoreBundle()(p) - with HasRocketCoreParameters { + with HasCoreParameters { val lip = Vec(coreParams.nLocalInterrupts, Bool()) val zero2 = Bool() val debug = Bool() // keep in sync with CSR.debugIntCause @@ -144,7 +144,7 @@ object CSR } class PerfCounterIO(implicit p: Parameters) extends CoreBundle - with HasRocketCoreParameters { + with HasCoreParameters { val eventSel = UInt(OUTPUT, xLen) val inc = UInt(INPUT, log2Ceil(1+retireWidth)) } @@ -161,7 +161,7 @@ class TracedInstruction(implicit p: Parameters) extends CoreBundle { } class CSRFileIO(implicit p: Parameters) extends CoreBundle - with HasRocketCoreParameters { + with HasCoreParameters { val interrupts = new TileInterrupts().asInput val hartid = UInt(INPUT, hartIdLen) val rw = new Bundle { @@ -207,7 +207,7 @@ class CSRFileIO(implicit p: Parameters) extends CoreBundle } class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Parameters) extends CoreModule()(p) - with HasRocketCoreParameters { + with HasCoreParameters { val io = new CSRFileIO val reset_mstatus = Wire(init=new MStatus().fromBits(0)) diff --git a/src/main/scala/rocket/PMP.scala b/src/main/scala/rocket/PMP.scala index 2e277a77..02d69aab 100644 --- a/src/main/scala/rocket/PMP.scala +++ b/src/main/scala/rocket/PMP.scala @@ -127,7 +127,7 @@ class PMPHomogeneityChecker(pmps: Seq[PMP])(implicit p: Parameters) { } class PMPChecker(lgMaxSize: Int)(implicit p: Parameters) extends CoreModule()(p) - with HasRocketCoreParameters { + with HasCoreParameters { val io = new Bundle { val prv = UInt(INPUT, PRV.SZ) val pmp = Vec(nPMPs, new PMP).asInput diff --git a/src/main/scala/rocket/PTW.scala b/src/main/scala/rocket/PTW.scala index 4618715f..70ec7b12 100644 --- a/src/main/scala/rocket/PTW.scala +++ b/src/main/scala/rocket/PTW.scala @@ -24,7 +24,7 @@ class PTWResp(implicit p: Parameters) extends CoreBundle()(p) { } class TLBPTWIO(implicit p: Parameters) extends CoreBundle()(p) - with HasRocketCoreParameters { + with HasCoreParameters { val req = Decoupled(new PTWReq) val resp = Valid(new PTWResp).flip val ptbr = new PTBR().asInput @@ -37,7 +37,7 @@ class PTWPerfEvents extends Bundle { } class DatapathPTWIO(implicit p: Parameters) extends CoreBundle()(p) - with HasRocketCoreParameters { + with HasCoreParameters { val ptbr = new PTBR().asInput val sfence = Valid(new SFenceReq).flip val status = new MStatus().asInput diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index ae0d251b..9e010def 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -45,11 +45,6 @@ trait HasRocketCoreParameters extends HasCoreParameters { val fastLoadWord = rocketParams.fastLoadWord val fastLoadByte = rocketParams.fastLoadByte - val nBreakpoints = rocketParams.nBreakpoints - val nPMPs = rocketParams.nPMPs - val nPerfCounters = rocketParams.nPerfCounters - val mtvecInit = rocketParams.mtvecInit - val mtvecWritable = rocketParams.mtvecWritable val mulDivParams = rocketParams.mulDiv.getOrElse(MulDivParams()) // TODO ask andrew about this diff --git a/src/main/scala/tile/Core.scala b/src/main/scala/tile/Core.scala index da400df9..9decc107 100644 --- a/src/main/scala/tile/Core.scala +++ b/src/main/scala/tile/Core.scala @@ -25,7 +25,12 @@ trait CoreParams { val retireWidth: Int val instBits: Int val nLocalInterrupts: Int + val nPMPs: Int + val nBreakpoints: Int + val nPerfCounters: Int val nL2TLBEntries: Int + val mtvecInit: Option[BigInt] + val mtvecWritable: Boolean val jumpInFrontend: Boolean val tileControlAddr: Option[BigInt] @@ -53,6 +58,12 @@ trait HasCoreParameters extends HasTileParameters { val coreDataBytes = coreDataBits/8 val coreMaxAddrBits = paddrBits max vaddrBitsExtended + val nBreakpoints = coreParams.nBreakpoints + val nPMPs = coreParams.nPMPs + val nPerfCounters = coreParams.nPerfCounters + val mtvecInit = coreParams.mtvecInit + val mtvecWritable = coreParams.mtvecWritable + val coreDCacheReqTagBits = 6 val dcacheReqTagBits = coreDCacheReqTagBits + log2Ceil(dcacheArbPorts) From 09468a272b52e45a92fe98bb348f9d1cd5f2bb5b Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 20 Sep 2017 19:15:36 -0700 Subject: [PATCH 3/6] Add option to remove basic counters (mcycle/minstret) --- src/main/scala/rocket/CSR.scala | 57 ++++++++++++++------------ src/main/scala/rocket/RocketCore.scala | 1 + src/main/scala/tile/Core.scala | 1 + 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index 989b665a..08e88cc1 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -342,8 +342,6 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param CSRs.mimpid -> UInt(0), CSRs.marchid -> UInt(0), CSRs.mvendorid -> UInt(0), - CSRs.mcycle -> reg_cycle, - CSRs.minstret -> reg_instret, CSRs.misa -> reg_misa, CSRs.mstatus -> read_mstatus, CSRs.mtvec -> reg_mtvec, @@ -371,14 +369,34 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param if (usingFPU) read_mapping ++= fp_csrs - for (((e, c), i) <- (reg_hpmevent.padTo(CSR.nHPM, UInt(0)) - zip reg_hpmcounter.map(x => x: UInt).padTo(CSR.nHPM, UInt(0))) zipWithIndex) { - read_mapping += (i + CSR.firstHPE) -> e // mhpmeventN - read_mapping += (i + CSR.firstMHPC) -> c // mhpmcounterN - if (usingUser) read_mapping += (i + CSR.firstHPC) -> c // hpmcounterN + if (coreParams.haveBasicCounters) { + read_mapping += CSRs.mcycle -> reg_cycle + read_mapping += CSRs.minstret -> reg_instret + + for (((e, c), i) <- (reg_hpmevent.padTo(CSR.nHPM, UInt(0)) + zip reg_hpmcounter.map(x => x: UInt).padTo(CSR.nHPM, UInt(0))) zipWithIndex) { + read_mapping += (i + CSR.firstHPE) -> e // mhpmeventN + read_mapping += (i + CSR.firstMHPC) -> c // mhpmcounterN + if (usingUser) read_mapping += (i + CSR.firstHPC) -> c // hpmcounterN + if (xLen == 32) { + read_mapping += (i + CSR.firstMHPCH) -> c // mhpmcounterNh + if (usingUser) read_mapping += (i + CSR.firstHPCH) -> c // hpmcounterNh + } + } + + if (usingUser) { + read_mapping += CSRs.mcounteren -> reg_mcounteren + read_mapping += CSRs.cycle -> reg_cycle + read_mapping += CSRs.instret -> reg_instret + } + if (xLen == 32) { - read_mapping += (i + CSR.firstMHPCH) -> c // mhpmcounterNh - if (usingUser) read_mapping += (i + CSR.firstHPCH) -> c // hpmcounterNh + read_mapping += CSRs.mcycleh -> (reg_cycle >> 32) + read_mapping += CSRs.minstreth -> (reg_instret >> 32) + if (usingUser) { + read_mapping += CSRs.cycleh -> (reg_cycle >> 32) + read_mapping += CSRs.instreth -> (reg_instret >> 32) + } } } @@ -411,21 +429,6 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param read_mapping += CSRs.medeleg -> reg_medeleg } - if (usingUser) { - read_mapping += CSRs.mcounteren -> reg_mcounteren - read_mapping += CSRs.cycle -> reg_cycle - read_mapping += CSRs.instret -> reg_instret - } - - if (xLen == 32) { - read_mapping += CSRs.mcycleh -> (reg_cycle >> 32) - read_mapping += CSRs.minstreth -> (reg_instret >> 32) - if (usingUser) { - read_mapping += CSRs.cycleh -> (reg_cycle >> 32) - read_mapping += CSRs.instreth -> (reg_instret >> 32) - } - } - val pmpCfgPerCSR = xLen / new PMPConfig().getWidth def pmpCfgIndex(i: Int) = (xLen / 32) * (i / pmpCfgPerCSR) if (reg_pmp.nonEmpty) { @@ -629,8 +632,10 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param writeCounter(i + CSR.firstMHPC, c, wdata) when (decoded_addr(i + CSR.firstHPE)) { e := perfEventSets.maskEventSelector(wdata) } } - writeCounter(CSRs.mcycle, reg_cycle, wdata) - writeCounter(CSRs.minstret, reg_instret, wdata) + if (coreParams.haveBasicCounters) { + writeCounter(CSRs.mcycle, reg_cycle, wdata) + writeCounter(CSRs.minstret, reg_instret, wdata) + } if (usingFPU) { when (decoded_addr(CSRs.fflags)) { reg_fflags := wdata } diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index 9e010def..fa6ea5a8 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -23,6 +23,7 @@ case class RocketCoreParams( nBreakpoints: Int = 1, nPMPs: Int = 8, nPerfCounters: Int = 0, + haveBasicCounters: Boolean = true, nL2TLBEntries: Int = 0, mtvecInit: Option[BigInt] = Some(BigInt(0)), mtvecWritable: Boolean = true, diff --git a/src/main/scala/tile/Core.scala b/src/main/scala/tile/Core.scala index 9decc107..21b887af 100644 --- a/src/main/scala/tile/Core.scala +++ b/src/main/scala/tile/Core.scala @@ -28,6 +28,7 @@ trait CoreParams { val nPMPs: Int val nBreakpoints: Int val nPerfCounters: Int + val haveBasicCounters: Boolean val nL2TLBEntries: Int val mtvecInit: Option[BigInt] val mtvecWritable: Boolean From 5cfe070932ca3a50ab4e42835a991241cc42238c Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 20 Sep 2017 19:16:34 -0700 Subject: [PATCH 4/6] Add option to make misa read-only --- src/main/scala/rocket/CSR.scala | 3 ++- src/main/scala/rocket/RocketCore.scala | 1 + src/main/scala/tile/Core.scala | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index 08e88cc1..421b41f7 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -606,7 +606,8 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param when (decoded_addr(CSRs.misa)) { val mask = UInt(isaStringToMask(isaMaskString), xLen) val f = wdata('f' - 'a') - reg_misa := ~(~wdata | (!f << ('d' - 'a'))) & mask | reg_misa & ~mask + if (coreParams.misaWritable) + reg_misa := ~(~wdata | (!f << ('d' - 'a'))) & mask | reg_misa & ~mask } when (decoded_addr(CSRs.mip)) { // MIP should be modified based on the value in reg_mip, not the value diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index fa6ea5a8..f5c4b78f 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -24,6 +24,7 @@ case class RocketCoreParams( nPMPs: Int = 8, nPerfCounters: Int = 0, haveBasicCounters: Boolean = true, + misaWritable: Boolean = true, nL2TLBEntries: Int = 0, mtvecInit: Option[BigInt] = Some(BigInt(0)), mtvecWritable: Boolean = true, diff --git a/src/main/scala/tile/Core.scala b/src/main/scala/tile/Core.scala index 21b887af..a914d6ef 100644 --- a/src/main/scala/tile/Core.scala +++ b/src/main/scala/tile/Core.scala @@ -29,6 +29,7 @@ trait CoreParams { val nBreakpoints: Int val nPerfCounters: Int val haveBasicCounters: Boolean + val misaWritable: Boolean val nL2TLBEntries: Int val mtvecInit: Option[BigInt] val mtvecWritable: Boolean From 2786e42d994c504c1e54810187121ddad604882f Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Fri, 29 Sep 2017 12:30:32 -0700 Subject: [PATCH 5/6] Don't register interrupts in CSRFile They are usually registered outside the tile in a CDC. --- src/main/scala/rocket/CSR.scala | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index 421b41f7..ab136f95 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -222,7 +222,6 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param reset_dcsr.xdebugver := 1 reset_dcsr.prv := PRV.M val reg_dcsr = Reg(init=reset_dcsr) - val reg_debugint = Reg(Bool()) val (supported_interrupts, delegable_interrupts) = { val sup = Wire(new MIP) @@ -304,13 +303,17 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param val hpm_mask = reg_mcounteren & Mux((!usingVM).B || reg_mstatus.prv === PRV.S, delegable_counters.U, reg_scounteren) val mip = Wire(init=reg_mip) + mip.lip := (io.interrupts.lip: Seq[Bool]) + mip.mtip := io.interrupts.mtip + mip.msip := io.interrupts.msip + mip.meip := io.interrupts.meip // seip is the OR of reg_mip.seip and the actual line from the PLIC io.interrupts.seip.foreach { mip.seip := reg_mip.seip || RegNext(_) } mip.rocc := io.rocc_interrupt val read_mip = mip.asUInt & supported_interrupts val pending_interrupts = read_mip & reg_mie - val d_interrupts = reg_debugint << CSR.debugIntCause + val d_interrupts = io.interrupts.debug << CSR.debugIntCause val m_interrupts = Mux(reg_mstatus.prv <= PRV.S || (reg_mstatus.prv === PRV.M && reg_mstatus.mie), pending_interrupts & ~reg_mideleg, UInt(0)) val s_interrupts = Mux(reg_mstatus.prv < PRV.S || (reg_mstatus.prv === PRV.S && reg_mstatus.sie), pending_interrupts & reg_mideleg, UInt(0)) val (anyInterrupt, whichInterrupt) = chooseInterrupt(Seq(s_interrupts, m_interrupts, d_interrupts)) @@ -506,7 +509,7 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param assert(PopCount(insn_ret :: insn_call :: insn_break :: io.exception :: Nil) <= 1, "these conditions must be mutually exclusive") when (insn_wfi && !io.singleStep && !reg_debug) { reg_wfi := true } - when (pending_interrupts.orR || exception || reg_debugint) { reg_wfi := false } + when (pending_interrupts.orR || exception || io.interrupts.debug) { reg_wfi := false } assert(!reg_wfi || io.retire === UInt(0)) when (io.retire(0) || exception) { reg_singleStepped := true } @@ -719,12 +722,6 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param } } - reg_mip.lip := (io.interrupts.lip: Seq[Bool]) - reg_mip.mtip := io.interrupts.mtip - reg_mip.msip := io.interrupts.msip - reg_mip.meip := io.interrupts.meip - reg_debugint := io.interrupts.debug - if (!usingVM) { reg_mideleg := 0 reg_medeleg := 0 From 7bcf28c5853484687828c74ecd9e0750aee8429b Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Fri, 29 Sep 2017 12:31:26 -0700 Subject: [PATCH 6/6] Define fetchBytes in HasCoreParams, not Frontend It is more generally useful. --- src/main/scala/rocket/Frontend.scala | 1 - src/main/scala/tile/Core.scala | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/rocket/Frontend.scala b/src/main/scala/rocket/Frontend.scala index 7319e7ea..408088c3 100644 --- a/src/main/scala/rocket/Frontend.scala +++ b/src/main/scala/rocket/Frontend.scala @@ -75,7 +75,6 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) val icache = outer.icache.module require(fetchWidth*coreInstBytes == outer.icacheParams.fetchBytes) - val fetchBytes = coreInstBytes * fetchWidth val tlb = Module(new TLB(true, log2Ceil(fetchBytes), nTLBEntries)) val fq = withReset(reset || io.cpu.req.valid) { Module(new ShiftQueue(new FrontendResp, 5, flow = true)) } diff --git a/src/main/scala/tile/Core.scala b/src/main/scala/tile/Core.scala index a914d6ef..26e20647 100644 --- a/src/main/scala/tile/Core.scala +++ b/src/main/scala/tile/Core.scala @@ -54,6 +54,7 @@ trait HasCoreParameters extends HasTileParameters { val fetchWidth = coreParams.fetchWidth val decodeWidth = coreParams.decodeWidth + val fetchBytes = coreParams.fetchBytes val coreInstBits = coreParams.instBits val coreInstBytes = coreInstBits/8 val coreDataBits = xLen max fLen