From 675f183dd212e491562de0f78d589ee4c02d4b4a Mon Sep 17 00:00:00 2001 From: Colin Schmidt Date: Tue, 20 Jun 2017 08:21:01 -0700 Subject: [PATCH] refactor ICache to be reusable by other frontends (#808) * refactor ICache to be reusable by other frontends specifically one that would like to change the fetch width and number of bytes in an instruction --- src/main/scala/rocket/Frontend.scala | 7 ++++--- src/main/scala/rocket/ICache.scala | 19 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/main/scala/rocket/Frontend.scala b/src/main/scala/rocket/Frontend.scala index 8d66e719..9a87409f 100644 --- a/src/main/scala/rocket/Frontend.scala +++ b/src/main/scala/rocket/Frontend.scala @@ -45,9 +45,9 @@ class FrontendIO(implicit p: Parameters) extends CoreBundle()(p) { val perf = new FrontendPerfEvents().asInput } -class Frontend(hartid: Int)(implicit p: Parameters) extends LazyModule { +class Frontend(val icacheParams: ICacheParams, hartid: Int)(implicit p: Parameters) extends LazyModule { lazy val module = new FrontendModule(this) - val icache = LazyModule(new ICache(latency = 2, hartid)) + val icache = LazyModule(new ICache(icacheParams, hartid)) val masterNode = TLOutputNode() val slaveNode = TLInputNode() @@ -70,6 +70,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) val io = new FrontendBundle(outer) implicit val edge = outer.masterNode.edgesOut.head val icache = outer.icache.module + require(fetchWidth*coreInstBytes == outer.icacheParams.fetchBytes) val tlb = Module(new TLB(log2Ceil(coreInstBytes*fetchWidth), nTLBEntries)) val fq = withReset(reset || io.cpu.req.valid) { Module(new ShiftQueue(new FrontendResp, 4, flow = true)) } @@ -183,7 +184,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) /** Mix-ins for constructing tiles that have an ICache-based pipeline frontend */ trait HasICacheFrontend extends CanHavePTW with HasTileLinkMasterPort { val module: HasICacheFrontendModule - val frontend = LazyModule(new Frontend(hartid: Int)) + val frontend = LazyModule(new Frontend(tileParams.icache.get, hartid: Int)) val hartid: Int tileBus.node := frontend.masterNode nPTWPorts += 1 diff --git a/src/main/scala/rocket/ICache.scala b/src/main/scala/rocket/ICache.scala index feb1142f..b4bb7aa2 100644 --- a/src/main/scala/rocket/ICache.scala +++ b/src/main/scala/rocket/ICache.scala @@ -21,7 +21,9 @@ case class ICacheParams( tagECC: Code = new IdentityCode, dataECC: Code = new IdentityCode, itimAddr: Option[BigInt] = None, - blockBytes: Int = 64) extends L1CacheParams { + blockBytes: Int = 64, + latency: Int = 2, + fetchBytes: Int = 4) extends L1CacheParams { def replacement = new RandomReplacement(nWays) } @@ -33,15 +35,13 @@ class ICacheReq(implicit p: Parameters) extends CoreBundle()(p) with HasL1ICache val addr = UInt(width = vaddrBits) } -class ICache(val latency: Int, val hartid: Int)(implicit p: Parameters) extends LazyModule - with HasRocketCoreParameters { +class ICache(val icacheParams: ICacheParams, val hartid: Int)(implicit p: Parameters) extends LazyModule { lazy val module = new ICacheModule(this) val masterNode = TLClientNode(TLClientParameters(name = s"Core ${hartid} ICache")) - val icacheParams = tileParams.icache.get val size = icacheParams.nSets * icacheParams.nWays * icacheParams.blockBytes val slaveNode = icacheParams.itimAddr.map { itimAddr => - val wordBytes = coreInstBytes * fetchWidth + val wordBytes = icacheParams.fetchBytes TLManagerNode(Seq(TLManagerPortParameters( Seq(TLManagerParameters( address = Seq(AddressSet(itimAddr, size-1)), @@ -64,7 +64,7 @@ class ICacheBundle(outer: ICache) extends CoreBundle()(outer.p) { val s1_kill = Bool(INPUT) // delayed one cycle w.r.t. req val s2_kill = Bool(INPUT) // delayed two cycles; prevents I$ miss emission - val resp = Valid(UInt(width = coreInstBits * fetchWidth)) + val resp = Valid(UInt(width = outer.icacheParams.fetchBytes*8)) val invalidate = Bool(INPUT) val tl_out = outer.masterNode.bundleOut val tl_in = outer.slaveNode.map(_.bundleIn) @@ -79,6 +79,8 @@ object GetPropertyByHartId { class ICacheModule(outer: ICache) extends LazyModuleImp(outer) with HasL1ICacheParameters { + override val cacheParams = outer.icacheParams // Use the local parameters + val io = new ICacheBundle(outer) val edge_out = outer.masterNode.edgesOut.head val tl_out = io.tl_out.head @@ -89,7 +91,6 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer) val dECC = cacheParams.dataECC require(isPow2(nSets) && isPow2(nWays)) - require(isPow2(coreInstBytes)) require(!usingVM || pgIdxBits >= untagBits) val scratchpadOn = RegInit(false.B) @@ -161,7 +162,7 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer) } val s1_tag_disparity = Wire(Vec(nWays, Bool())) - val wordBits = coreInstBits * fetchWidth + val wordBits = outer.icacheParams.fetchBytes*8 val s1_dout = Wire(Vec(nWays, UInt(width = dECC.width(wordBits)))) val s0_slaveAddr = tl_in.map(_.a.bits.address).getOrElse(0.U) @@ -204,7 +205,7 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer) } // output signals - outer.latency match { + outer.icacheParams.latency match { case 1 => require(tECC.isInstanceOf[uncore.util.IdentityCode]) require(dECC.isInstanceOf[uncore.util.IdentityCode])