Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use BundleBridge to propagate tile input "constants" #2521

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
77efb0b
bundlebridge: restore separate makeIO implementation to avoid extra _…
hcook Jun 12, 2020
d05c867
subsystem: use bundlebridge to propagate tile constants
hcook Jun 3, 2020
50d5628
tile: use bridged constants inside diplomatic tile units
hcook Jun 13, 2020
7a2f9ac
tile: further apply lazy val requirement checking pattern
hcook Jun 13, 2020
29076d5
tile: remove obviated HasExternallyDrivenTileConstants mixin
hcook Jun 13, 2020
08dd1db
subsystem: continue to standardize ROM attachment
hcook Jun 13, 2020
2b08829
subsystem: use BundleBridgeNexus.safeRegNext in hart prefix node
hcook Jun 13, 2020
adf94eb
tile: BaseTile.traceAuxNode supplied default
hcook Jun 15, 2020
e32d62d
groundtest: update to deal with tile input constant defaults
hcook Jun 16, 2020
f3bff00
subsystem: import spelling error rebase
hcook Jun 18, 2020
f97bebe
Update src/main/scala/devices/tilelink/BootROM.scala
hcook Jun 18, 2020
57b5299
Update src/main/scala/subsystem/HasTiles.scala
hcook Jun 18, 2020
894aa25
Update src/main/scala/devices/tilelink/BootROM.scala
hcook Jun 18, 2020
453c256
Update src/main/scala/subsystem/HasTiles.scala
hcook Jun 18, 2020
7879d0e
Update src/main/scala/system/ExampleRocketSystem.scala
hcook Jun 18, 2020
02de37d
Update src/main/scala/tile/BaseTile.scala
hcook Jun 18, 2020
2c3ef73
Update src/main/scala/tile/BaseTile.scala
hcook Jun 18, 2020
023db65
Update src/main/scala/tile/BaseTile.scala
hcook Jun 18, 2020
f4cd02a
BootROM.attach scaladoc comment
hcook Jun 18, 2020
d66c374
HasTiles: more scaladoc and better scaladoc style
hcook Jun 18, 2020
ed7ee6d
bundlebridge: expose inputRequiresOutput
hcook Jun 18, 2020
198e67b
HasTiles: inputRequiresOutput=true for both new nexus nodes
hcook Jun 18, 2020
3ad024d
staticIdForMetadata => staticIdForMetadataUseOnly
hcook Jun 18, 2020
d86fe67
tile: hartIdLen and resetVectorLen are now members of HasCoreParams n…
hcook Jun 18, 2020
5afae45
subsystem: tile port params can insert chains of buffers
hcook Jun 19, 2020
2403535
util: DataToAugmentedData.getElements
hcook Jun 19, 2020
b2ce2a9
bundlebridge: better dir inference on makeIO
hcook Jun 19, 2020
232828c
tile: rely on bundlebridge direction inference for reset vector
hcook Jun 19, 2020
fabfdb1
BaseTile: scaladoc for staticIdForMetadataUseOnly
hcook Jun 19, 2020
f69161d
Update src/main/scala/subsystem/HasTiles.scala
hcook Jun 19, 2020
ea8b6ee
Update src/main/scala/subsystem/HasTiles.scala
hcook Jun 19, 2020
d99f1b0
HartPrefixKey => InsertTimingClosureRegistersOnHartIds
hcook Jun 22, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 31 additions & 21 deletions src/main/scala/devices/tilelink/BootROM.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package freechips.rocketchip.devices.tilelink

import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.subsystem.{BaseSubsystem, HasResetVectorWire}
import freechips.rocketchip.subsystem.{BaseSubsystem, HierarchicalLocation, HasTiles, TLBusWrapperLocation, CBUS}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._
Expand All @@ -16,9 +16,8 @@ import java.nio.file.{Files, Paths}
case class BootROMParams(
address: BigInt = 0x10000,
size: Int = 0x10000,
hang: BigInt = 0x10040,
hang: BigInt = 0x10040, // The hang parameter is used as the power-on reset vector
contentFileName: String)
case object BootROMParams extends Field[BootROMParams]

class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], executable: Boolean = true, beatBytes: Int = 4,
resources: Seq[Resource] = new SimpleDevice("rom", Seq("sifive,rom0")).reg("mem"))(implicit p: Parameters) extends LazyModule
Expand Down Expand Up @@ -58,25 +57,36 @@ class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], exec
}
}

/** Adds a boot ROM that contains the DTB describing the system's subsystem. */
trait HasPeripheryBootROM { this: BaseSubsystem =>
val dtb: DTB
private val params = p(BootROMParams)
private lazy val contents = {
val romdata = Files.readAllBytes(Paths.get(params.contentFileName))
val rom = ByteBuffer.wrap(romdata)
rom.array() ++ dtb.contents
}
def resetVector: BigInt = params.hang
case class BootROMLocated(loc: HierarchicalLocation) extends Field[Option[BootROMParams]](None)

val bootrom = LazyModule(new TLROM(params.address, params.size, contents, true, cbus.beatBytes))
object BootROM {
/** BootROM.attach not only instantiates a TLROM and attaches it to the tilelink interconnect
* at a configurable location, but also drives the tiles' reset vectors to point
* at its 'hang' address parameter value.
*/
def attach(params: BootROMParams, subsystem: BaseSubsystem with HasTiles, where: TLBusWrapperLocation)
hcook marked this conversation as resolved.
Show resolved Hide resolved
(implicit p: Parameters): TLROM = {
val cbus = subsystem.locateTLBusWrapper(where)
val bootROMResetVectorSourceNode = BundleBridgeSource[UInt]()
lazy val contents = {
val romdata = Files.readAllBytes(Paths.get(params.contentFileName))
val rom = ByteBuffer.wrap(romdata)
rom.array() ++ subsystem.dtb.contents
}

bootrom.node := cbus.coupleTo("bootrom"){ TLFragmenter(cbus) := _ }
}
val bootrom = subsystem {
LazyModule(new TLROM(params.address, params.size, contents, true, cbus.beatBytes))
}

/** Subsystem will power-on running at 0x10040 (BootROM) */
trait HasPeripheryBootROMModuleImp extends LazyModuleImp
with HasResetVectorWire {
val outer: HasPeripheryBootROM
global_reset_vector := outer.resetVector.U
bootrom.node := cbus.coupleTo("bootrom"){ TLFragmenter(cbus) := _ }
// Drive the `subsystem` reset vector to the `hang` address of this Boot ROM.
subsystem.tileResetVectorNode := bootROMResetVectorSourceNode
hcook marked this conversation as resolved.
Show resolved Hide resolved
InModuleBody {
val reset_vector_source = bootROMResetVectorSourceNode.bundle
require(reset_vector_source.getWidth >= params.hang.bitLength,
s"BootROM defined with a reset vector (${params.hang})too large for physical address space (${reset_vector_source.getWidth})")
bootROMResetVectorSourceNode.bundle := params.hang.U
}
bootrom
}
}
7 changes: 6 additions & 1 deletion src/main/scala/devices/tilelink/MaskROM.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package freechips.rocketchip.devices.tilelink
import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.subsystem.{Attachable, HierarchicalLocation, TLBusWrapperLocation, CBUS}
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._

Expand Down Expand Up @@ -56,8 +57,12 @@ class TLMaskROM(c: MaskROMParams)(implicit p: Parameters) extends LazyModule {
}
}

case class MaskROMLocated(loc: HierarchicalLocation) extends Field[Seq[MaskROMParams]](Nil)

object MaskROM {
def attach(params: MaskROMParams, bus: TLBusWrapper)(implicit p: Parameters): TLMaskROM = {
def attach(params: MaskROMParams, subsystem: Attachable, where: TLBusWrapperLocation)
(implicit p: Parameters): TLMaskROM = {
val bus = subsystem.locateTLBusWrapper(where)
val maskROM = LazyModule(new TLMaskROM(params))
maskROM.node := bus.coupleTo("MaskROM") {
TLFragmenter(maskROM.beatBytes, bus.blockBytes) :*= TLWidthWidget(bus) := _
Expand Down
55 changes: 38 additions & 17 deletions src/main/scala/diplomacy/BundleBridge.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ package freechips.rocketchip.diplomacy
import chisel3._
import chisel3.internal.sourceinfo.SourceInfo
import chisel3.experimental.{DataMirror,IO}
import chisel3.experimental.DataMirror.internal.chiselTypeClone
import freechips.rocketchip.config.{Parameters,Field}
import freechips.rocketchip.util.DataToAugmentedData

case class BundleBridgeParams[T <: Data](genOpt: Option[() => T])

Expand Down Expand Up @@ -42,16 +44,34 @@ case class BundleBridgeSink[T <: Data](genOpt: Option[() => T] = None)
{
def bundle: T = in(0)._1

def makeIO()(implicit valName: ValName): T = makeIOs()(valName).head
def makeIO(name: String): T = makeIOs()(ValName(name)).head
private def inferOutput = bundle.getElements.forall { elt =>
DataMirror.directionOf(elt) == ActualDirection.Unspecified
}

def makeIO()(implicit valName: ValName): T = {
val io: T = IO(if (inferOutput) Output(chiselTypeOf(bundle)) else chiselTypeClone(bundle))
io.suggestName(valName.name)
io <> bundle
io
}
def makeIO(name: String): T = makeIO()(ValName(name))
}

case class BundleBridgeSource[T <: Data](genOpt: Option[() => T] = None)(implicit valName: ValName) extends SourceNode(new BundleBridgeImp[T])(Seq(BundleBridgeParams(genOpt)))
{
def bundle: T = out(0)._1

def makeIO()(implicit valName: ValName): T = makeIOs()(valName).head
def makeIO(name: String): T = makeIOs()(ValName(name)).head
hcook marked this conversation as resolved.
Show resolved Hide resolved
private def inferInput = bundle.getElements.forall { elt =>
DataMirror.directionOf(elt) == ActualDirection.Unspecified
}

def makeIO()(implicit valName: ValName): T = {
val io: T = IO(if (inferInput) Input(chiselTypeOf(bundle)) else Flipped(chiselTypeClone(bundle)))
io.suggestName(valName.name)
bundle <> io
Copy link

@DecodeTheEncoded DecodeTheEncoded Feb 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just felt confused here. By code reading, I felt like the direction of makeIO of BundleBridgeSourceNode is Input, While the direction of makeIO of BundleBridgeSinkNode is Output. I felt like this is strange, the source node only has output bundles and the sink only has input right? Why this is opposite here. Also, if inferInput is false in the makeIO of BundleBridgeSource, why we need to Flipped the orignal direction, while inside the BundleBridgeSink, there is no Flipped? it is wired. Seems like the io after calling makeIO in corresponding node is opposite with its original IO, why?
@hcook @mwachs5 @jackkoenig

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just felt confused here. By code reading, I felt like the direction of makeIO of BundleBridgeSourceNode is Input, While the direction of makeIO of BundleBridgeSinkNode is Output. I felt like this is strange, the source node only has output bundles and the sink only has input right? Why this is opposite here. Also, if inferInput is false in the makeIO of BundleBridgeSource, why we need to Flipped the orignal direction, while inside the BundleBridgeSink, there is no Flipped? it is wired. Seems like the io after calling makeIO in corresponding node is opposite with its original IO, why?
@hcook @mwachs5 @jackkoenig

I answer (more or less) this question in stackoverflow https://stackoverflow.com/questions/66963837/how-to-understand-the-flip-in-autobundle-and-in-makeios

io
}
def makeIO(name: String): T = makeIO()(ValName(name))

private var doneSink = false
def makeSink()(implicit p: Parameters) = {
Expand All @@ -72,21 +92,23 @@ case object BundleBridgeSource {
case class BundleBridgeIdentityNode[T <: Data]()(implicit valName: ValName) extends IdentityNode(new BundleBridgeImp[T])()
case class BundleBridgeEphemeralNode[T <: Data]()(implicit valName: ValName) extends EphemeralNode(new BundleBridgeImp[T])()

case class BundleBridgeNexusNode[T <: Data](default: Option[() => T] = None)
case class BundleBridgeNexusNode[T <: Data](default: Option[() => T] = None,
inputRequiresOutput: Boolean = false) // when false, connecting a source does not mandate connecting a sink
(implicit valName: ValName)
extends NexusNode(new BundleBridgeImp[T])(
dFn = seq => seq.headOption.getOrElse(BundleBridgeParams(default)),
uFn = seq => seq.headOption.getOrElse(BundleBridgeParams(default)),
inputRequiresOutput = false, // enables publishers with no subscribers
inputRequiresOutput = inputRequiresOutput,
outputRequiresInput = !default.isDefined)

class BundleBridgeNexus[T <: Data](
inputFn: Seq[T] => T,
outputFn: (T, Int) => Seq[T],
default: Option[() => T] = None
default: Option[() => T] = None,
inputRequiresOutput: Boolean = false
) (implicit p: Parameters) extends LazyModule
{
val node = BundleBridgeNexusNode[T](default)
val node = BundleBridgeNexusNode[T](default, inputRequiresOutput)

lazy val module = new LazyModuleImp(this) {
val defaultWireOpt = default.map(_())
Expand All @@ -95,11 +117,7 @@ class BundleBridgeNexus[T <: Data](
inputs.foreach { i => require(DataMirror.checkTypeEquivalence(i, inputs.head),
s"${node.context} requires all inputs have equivalent Chisel Data types, but got\n$i\nvs\n${inputs.head}")
}
def getElements(x: Data): Seq[Element] = x match {
case e: Element => Seq(e)
case a: Aggregate => a.getElements.flatMap(getElements)
}
inputs.flatMap(getElements).foreach { elt => DataMirror.directionOf(elt) match {
inputs.flatMap(_.getElements).foreach { elt => DataMirror.directionOf(elt) match {
case ActualDirection.Output => ()
case ActualDirection.Unspecified => ()
case _ => require(false, s"${node.context} can only be used with Output-directed Bundles")
Expand Down Expand Up @@ -145,22 +163,25 @@ object BundleBridgeNexus {
def apply[T <: Data](
inputFn: Seq[T] => T = orReduction[T](false) _,
outputFn: (T, Int) => Seq[T] = fillN[T](false) _,
default: Option[() => T] = None
default: Option[() => T] = None,
inputRequiresOutput: Boolean = false
)(implicit p: Parameters, valName: ValName): BundleBridgeNexusNode[T] = {
val broadcast = LazyModule(new BundleBridgeNexus[T](inputFn, outputFn, default))
val broadcast = LazyModule(new BundleBridgeNexus[T](inputFn, outputFn, default, inputRequiresOutput))
broadcast.node
}
}

object BundleBroadcast {
def apply[T <: Data](
name: Option[String] = None,
registered: Boolean = false
registered: Boolean = false,
inputRequiresOutput: Boolean = false // when false, connecting a source does not mandate connecting a sink
)(implicit p: Parameters, valName: ValName): BundleBridgeNexusNode[T] = {
val finalName = name.map(ValName(_)).getOrElse(valName)
BundleBridgeNexus.apply[T](
inputFn = BundleBridgeNexus.requireOne[T](registered) _,
outputFn = BundleBridgeNexus.fillN[T](registered) _)(
outputFn = BundleBridgeNexus.fillN[T](registered) _,
inputRequiresOutput = inputRequiresOutput)(
p, finalName)
}
}
1 change: 1 addition & 0 deletions src/main/scala/groundtest/Configs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class GroundTestBaseConfig extends Config(
case DebugModuleKey => None
case CLINTKey => None
case PLICKey => None
case SubsystemExternalResetVectorKey => true
})
)

Expand Down
3 changes: 0 additions & 3 deletions src/main/scala/groundtest/GroundTestSubsystem.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ class GroundTestSubsystem(implicit p: Parameters)

class GroundTestSubsystemModuleImp[+L <: GroundTestSubsystem](_outer: L) extends BaseSubsystemModuleImp(_outer) {
val success = IO(Bool(OUTPUT))

outer.tiles.zipWithIndex.map { case(t, i) => t.module.constants.hartid := UInt(i) }

val status = dontTouch(DebugCombiner(outer.tiles.collect { case t: GroundTestTile => t.module.status }))
success := outer.tileCeaseSinkNode.in.head._1.asUInt.andR
}
2 changes: 2 additions & 0 deletions src/main/scala/groundtest/Tile.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ abstract class GroundTestTile(
else new NonBlockingDCache(hartId))
}

dcacheOpt.foreach { _.hartIdSinkNode := hartIdNode }

override lazy val module = new GroundTestTileModuleImp(this)
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/groundtest/TraceGen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,7 @@ class TraceGenTile private(
class TraceGenTileModuleImp(outer: TraceGenTile) extends GroundTestTileModuleImp(outer) {

val tracegen = Module(new TraceGenerator(outer.params))
tracegen.io.hartid := constants.hartid
tracegen.io.hartid := outer.hartIdSinkNode.bundle

outer.dcacheOpt foreach { dcache =>
val dcacheIF = Module(new SimpleHellaCacheIF())
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/rocket/DCache.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class DCacheMetadataReq(implicit p: Parameters) extends L1HellaCacheBundle()(p)
val data = UInt(width = cacheParams.tagCode.width(new L1Metadata().getWidth))
}

class DCache(hartid: Int, val crossing: ClockCrossingType)(implicit p: Parameters) extends HellaCache(hartid)(p) {
class DCache(staticIdForMetadataUseOnly: Int, val crossing: ClockCrossingType)(implicit p: Parameters) extends HellaCache(staticIdForMetadataUseOnly)(p) {
override lazy val module = new DCacheModule(this)
override def getOMSRAMs(): Seq[OMSRAM] = Seq(module.dcacheImpl.omSRAM) ++ module.dcacheImpl.data.data_arrays.map(_._2)
}
Expand Down Expand Up @@ -251,7 +251,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
val s1_victim_way = Wire(init = replacer.way)
val (s1_hit_way, s1_hit_state, s1_meta, s1_victim_meta) =
if (usingDataScratchpad) {
val baseAddr = p(LookupByHartId)(_.dcache.flatMap(_.scratch.map(_.U)), io.hartid)
val baseAddr = p(LookupByHartId)(_.dcache.flatMap(_.scratch.map(_.U)), io_hartid)
val inScratchpad = s1_paddr >= baseAddr && s1_paddr < baseAddr + nSets * cacheBlockBytes
val hitState = Mux(inScratchpad, ClientMetadata.maximum, ClientMetadata.onReset)
val dummyMeta = L1Metadata(UInt(0), ClientMetadata.onReset)
Expand Down
16 changes: 9 additions & 7 deletions src/main/scala/rocket/Frontend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ class FrontendIO(implicit p: Parameters) extends CoreBundle()(p) {
val perf = new FrontendPerfEvents().asInput
}

class Frontend(val icacheParams: ICacheParams, hartid: Int)(implicit p: Parameters) extends LazyModule {
class Frontend(val icacheParams: ICacheParams, staticIdForMetadataUseOnly: Int)(implicit p: Parameters) extends LazyModule {
lazy val module = new FrontendModule(this)
val icache = LazyModule(new ICache(icacheParams, hartid))
val icache = LazyModule(new ICache(icacheParams, staticIdForMetadataUseOnly))
val masterNode = icache.masterNode
val slaveNode = icache.slaveNode
val resetVectorSinkNode = BundleBridgeSink[UInt](Some(() => Output(UInt(masterNode.edges.out.head.bundle.addressBits.W))))
jackkoenig marked this conversation as resolved.
Show resolved Hide resolved
}

class FrontendBundle(val outer: Frontend) extends CoreBundle()(outer.p)
with HasExternallyDrivenTileConstants {
class FrontendBundle(val outer: Frontend) extends CoreBundle()(outer.p) {
val cpu = new FrontendIO().flip
val ptw = new TLBPTWIO()
val errors = new ICacheErrors
Expand All @@ -78,6 +78,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
with HasRocketCoreParameters
with HasL1ICacheParameters {
val io = IO(new FrontendBundle(outer))
val io_reset_vector = outer.resetVectorSinkNode.bundle
implicit val edge = outer.masterNode.edges.out(0)
val icache = outer.icache.module
require(fetchWidth*coreInstBytes == outer.icacheParams.fetchBytes)
Expand Down Expand Up @@ -108,7 +109,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
s1_valid := s0_valid
val s1_pc = Reg(UInt(width=vaddrBitsExtended))
val s1_speculative = Reg(Bool())
val s2_pc = RegInit(t = UInt(width = vaddrBitsExtended), alignPC(io.reset_vector))
val s2_pc = RegInit(t = UInt(width = vaddrBitsExtended), alignPC(io_reset_vector))
val s2_btb_resp_valid = if (usingBTB) Reg(Bool()) else false.B
val s2_btb_resp_bits = Reg(new BTBResp)
val s2_btb_taken = s2_btb_resp_valid && s2_btb_resp_bits.taken
Expand Down Expand Up @@ -153,7 +154,6 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
tlb.io.sfence := io.cpu.sfence
tlb.io.kill := !s2_valid

icache.io.hartid := io.hartid
icache.io.req.valid := s0_valid
icache.io.req.bits.addr := io.cpu.npc
icache.io.invalidate := io.cpu.flush_icache
Expand Down Expand Up @@ -349,9 +349,11 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
/** Mix-ins for constructing tiles that have an ICache-based pipeline frontend */
trait HasICacheFrontend extends CanHavePTW { this: BaseTile =>
val module: HasICacheFrontendModule
val frontend = LazyModule(new Frontend(tileParams.icache.get, hartId))
val frontend = LazyModule(new Frontend(tileParams.icache.get, staticIdForMetadataUseOnly))
tlMasterXbar.node := frontend.masterNode
connectTLSlave(frontend.slaveNode, tileParams.core.fetchBytes)
frontend.icache.hartIdSinkNode := hartIdNode
frontend.resetVectorSinkNode := resetVectorNode
nPTWPorts += 1

// This should be a None in the case of not having an ITIM address, when we
Expand Down
15 changes: 9 additions & 6 deletions src/main/scala/rocket/HellaCache.scala
Original file line number Diff line number Diff line change
Expand Up @@ -175,17 +175,17 @@ class HellaCacheIO(implicit p: Parameters) extends CoreBundle()(p) {

/** Base classes for Diplomatic TL2 HellaCaches */

abstract class HellaCache(hartid: Int)(implicit p: Parameters) extends LazyModule
abstract class HellaCache(staticIdForMetadataUseOnly: Int)(implicit p: Parameters) extends LazyModule
with HasNonDiplomaticTileParameters {
protected val cfg = tileParams.dcache.get

protected def cacheClientParameters = cfg.scratch.map(x => Seq()).getOrElse(Seq(TLMasterParameters.v1(
name = s"Core ${hartid} DCache",
name = s"Core ${staticIdForMetadataUseOnly} DCache",
sourceId = IdRange(0, 1 max cfg.nMSHRs),
supportsProbe = TransferSizes(cfg.blockBytes, cfg.blockBytes))))

protected def mmioClientParameters = Seq(TLMasterParameters.v1(
name = s"Core ${hartid} DCache MMIO",
name = s"Core ${staticIdForMetadataUseOnly} DCache MMIO",
sourceId = IdRange(firstMMIO, firstMMIO + cfg.nMMIOs),
requestFifo = true))

Expand All @@ -196,6 +196,8 @@ abstract class HellaCache(hartid: Int)(implicit p: Parameters) extends LazyModul
minLatency = 1,
requestFields = tileParams.core.useVM.option(Seq()).getOrElse(Seq(AMBAProtField())))))

val hartIdSinkNode = BundleBridgeSink[UInt]()

val module: HellaCacheModule

def flushOnFenceI = cfg.scratch.isEmpty && !node.edges.out(0).manager.managers.forall(m => !m.supportsAcquireT || !m.executable || m.regionType >= RegionType.TRACKED || m.regionType <= RegionType.IDEMPOTENT)
Expand All @@ -208,7 +210,6 @@ abstract class HellaCache(hartid: Int)(implicit p: Parameters) extends LazyModul
}

class HellaCacheBundle(val outer: HellaCache)(implicit p: Parameters) extends CoreBundle()(p) {
val hartid = UInt(INPUT, hartIdLen)
val cpu = (new HellaCacheIO).flip
val ptw = new TLBPTWIO()
val errors = new DCacheErrors
Expand All @@ -219,6 +220,7 @@ class HellaCacheModule(outer: HellaCache) extends LazyModuleImp(outer)
implicit val edge = outer.node.edges.out(0)
val (tl_out, _) = outer.node.out(0)
val io = IO(new HellaCacheBundle(outer))
val io_hartid = outer.hartIdSinkNode.bundle
dontTouch(io.cpu.resp) // Users like to monitor these fields even if the core ignores some signals
dontTouch(io.cpu.s1_data)

Expand All @@ -237,9 +239,9 @@ case object BuildHellaCache extends Field[BaseTile => Parameters => HellaCache](
object HellaCacheFactory {
def apply(tile: BaseTile)(p: Parameters): HellaCache = {
if (tile.tileParams.dcache.get.nMSHRs == 0)
new DCache(tile.hartId, tile.crossing)(p)
new DCache(tile.staticIdForMetadataUseOnly, tile.crossing)(p)
else
new NonBlockingDCache(tile.hartId)(p)
new NonBlockingDCache(tile.staticIdForMetadataUseOnly)(p)
}
}

Expand All @@ -252,6 +254,7 @@ trait HasHellaCache { this: BaseTile =>
lazy val dcache: HellaCache = LazyModule(p(BuildHellaCache)(this)(p))

tlMasterXbar.node := dcache.node
dcache.hartIdSinkNode := hartIdNode
}

trait HasHellaCacheModule {
Expand Down
Loading