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:
parent
ff1f0170dc
commit
675f183dd2
@ -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
|
||||||
|
@ -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])
|
||||||
|
Loading…
Reference in New Issue
Block a user