1
0

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
This commit is contained in:
Colin Schmidt 2017-06-20 08:21:01 -07:00 committed by GitHub
parent ff1f0170dc
commit 675f183dd2
2 changed files with 14 additions and 12 deletions

View File

@ -45,9 +45,9 @@ class FrontendIO(implicit p: Parameters) extends CoreBundle()(p) {
val perf = new FrontendPerfEvents().asInput 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) 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 masterNode = TLOutputNode()
val slaveNode = TLInputNode() val slaveNode = TLInputNode()
@ -70,6 +70,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
val io = new FrontendBundle(outer) val io = new FrontendBundle(outer)
implicit val edge = outer.masterNode.edgesOut.head implicit val edge = outer.masterNode.edgesOut.head
val icache = outer.icache.module val icache = outer.icache.module
require(fetchWidth*coreInstBytes == outer.icacheParams.fetchBytes)
val tlb = Module(new TLB(log2Ceil(coreInstBytes*fetchWidth), nTLBEntries)) 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)) } 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 */ /** Mix-ins for constructing tiles that have an ICache-based pipeline frontend */
trait HasICacheFrontend extends CanHavePTW with HasTileLinkMasterPort { trait HasICacheFrontend extends CanHavePTW with HasTileLinkMasterPort {
val module: HasICacheFrontendModule val module: HasICacheFrontendModule
val frontend = LazyModule(new Frontend(hartid: Int)) val frontend = LazyModule(new Frontend(tileParams.icache.get, hartid: Int))
val hartid: Int val hartid: Int
tileBus.node := frontend.masterNode tileBus.node := frontend.masterNode
nPTWPorts += 1 nPTWPorts += 1

View File

@ -21,7 +21,9 @@ case class ICacheParams(
tagECC: Code = new IdentityCode, tagECC: Code = new IdentityCode,
dataECC: Code = new IdentityCode, dataECC: Code = new IdentityCode,
itimAddr: Option[BigInt] = None, 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) def replacement = new RandomReplacement(nWays)
} }
@ -33,15 +35,13 @@ class ICacheReq(implicit p: Parameters) extends CoreBundle()(p) with HasL1ICache
val addr = UInt(width = vaddrBits) val addr = UInt(width = vaddrBits)
} }
class ICache(val latency: Int, val hartid: Int)(implicit p: Parameters) extends LazyModule class ICache(val icacheParams: ICacheParams, val hartid: Int)(implicit p: Parameters) extends LazyModule {
with HasRocketCoreParameters {
lazy val module = new ICacheModule(this) lazy val module = new ICacheModule(this)
val masterNode = TLClientNode(TLClientParameters(name = s"Core ${hartid} ICache")) val masterNode = TLClientNode(TLClientParameters(name = s"Core ${hartid} ICache"))
val icacheParams = tileParams.icache.get
val size = icacheParams.nSets * icacheParams.nWays * icacheParams.blockBytes val size = icacheParams.nSets * icacheParams.nWays * icacheParams.blockBytes
val slaveNode = icacheParams.itimAddr.map { itimAddr => val slaveNode = icacheParams.itimAddr.map { itimAddr =>
val wordBytes = coreInstBytes * fetchWidth val wordBytes = icacheParams.fetchBytes
TLManagerNode(Seq(TLManagerPortParameters( TLManagerNode(Seq(TLManagerPortParameters(
Seq(TLManagerParameters( Seq(TLManagerParameters(
address = Seq(AddressSet(itimAddr, size-1)), 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 s1_kill = Bool(INPUT) // delayed one cycle w.r.t. req
val s2_kill = Bool(INPUT) // delayed two cycles; prevents I$ miss emission 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 invalidate = Bool(INPUT)
val tl_out = outer.masterNode.bundleOut val tl_out = outer.masterNode.bundleOut
val tl_in = outer.slaveNode.map(_.bundleIn) val tl_in = outer.slaveNode.map(_.bundleIn)
@ -79,6 +79,8 @@ object GetPropertyByHartId {
class ICacheModule(outer: ICache) extends LazyModuleImp(outer) class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
with HasL1ICacheParameters { with HasL1ICacheParameters {
override val cacheParams = outer.icacheParams // Use the local parameters
val io = new ICacheBundle(outer) val io = new ICacheBundle(outer)
val edge_out = outer.masterNode.edgesOut.head val edge_out = outer.masterNode.edgesOut.head
val tl_out = io.tl_out.head val tl_out = io.tl_out.head
@ -89,7 +91,6 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
val dECC = cacheParams.dataECC val dECC = cacheParams.dataECC
require(isPow2(nSets) && isPow2(nWays)) require(isPow2(nSets) && isPow2(nWays))
require(isPow2(coreInstBytes))
require(!usingVM || pgIdxBits >= untagBits) require(!usingVM || pgIdxBits >= untagBits)
val scratchpadOn = RegInit(false.B) 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 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 s1_dout = Wire(Vec(nWays, UInt(width = dECC.width(wordBits))))
val s0_slaveAddr = tl_in.map(_.a.bits.address).getOrElse(0.U) 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 // output signals
outer.latency match { outer.icacheParams.latency match {
case 1 => case 1 =>
require(tECC.isInstanceOf[uncore.util.IdentityCode]) require(tECC.isInstanceOf[uncore.util.IdentityCode])
require(dECC.isInstanceOf[uncore.util.IdentityCode]) require(dECC.isInstanceOf[uncore.util.IdentityCode])