Merge pull request #1039 from freechipsproject/tile-crossing-params
Improvements wrt connecting RocketTiles to SystemBus
This commit is contained in:
commit
b64609bfe8
@ -71,31 +71,32 @@ class WithNSmallCores(n: Int) extends Config((site, here, up) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithNTinyCores(n: Int) extends Config((site, here, up) => {
|
class With1TinyCore extends Config((site, here, up) => {
|
||||||
case XLen => 32
|
case XLen => 32
|
||||||
case RocketTilesKey => {
|
case RocketTilesKey => List(RocketTileParams(
|
||||||
val tiny = RocketTileParams(
|
core = RocketCoreParams(
|
||||||
core = RocketCoreParams(
|
useVM = false,
|
||||||
useVM = false,
|
fpu = None,
|
||||||
fpu = None,
|
mulDiv = Some(MulDivParams(mulUnroll = 8))),
|
||||||
mulDiv = Some(MulDivParams(mulUnroll = 8))),
|
btb = None,
|
||||||
btb = None,
|
dcache = Some(DCacheParams(
|
||||||
dcache = Some(DCacheParams(
|
rowBits = site(SystemBusKey).beatBits,
|
||||||
rowBits = site(SystemBusKey).beatBits,
|
nSets = 256, // 16Kb scratchpad
|
||||||
nSets = 256, // 16Kb scratchpad
|
nWays = 1,
|
||||||
nWays = 1,
|
nTLBEntries = 4,
|
||||||
nTLBEntries = 4,
|
nMSHRs = 0,
|
||||||
nMSHRs = 0,
|
blockBytes = site(CacheBlockBytes),
|
||||||
blockBytes = site(CacheBlockBytes),
|
scratch = Some(0x80000000L))),
|
||||||
scratch = Some(0x80000000L))),
|
icache = Some(ICacheParams(
|
||||||
icache = Some(ICacheParams(
|
rowBits = site(SystemBusKey).beatBits,
|
||||||
rowBits = site(SystemBusKey).beatBits,
|
nSets = 64,
|
||||||
nSets = 64,
|
nWays = 1,
|
||||||
nWays = 1,
|
nTLBEntries = 4,
|
||||||
nTLBEntries = 4,
|
blockBytes = site(CacheBlockBytes)))))
|
||||||
blockBytes = site(CacheBlockBytes))))
|
case RocketCrossingKey => List(RocketCrossingParams(
|
||||||
List.tabulate(n)(i => tiny.copy(hartid = i))
|
crossingType = SynchronousCrossing(),
|
||||||
}
|
master = TileMasterPortParams(cork = Some(true))
|
||||||
|
))
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithNBanksPerMemChannel(n: Int) extends Config((site, here, up) => {
|
class WithNBanksPerMemChannel(n: Int) extends Config((site, here, up) => {
|
||||||
@ -153,10 +154,8 @@ class WithBufferlessBroadcastHub extends Config((site, here, up) => {
|
|||||||
class WithStatelessBridge extends Config((site, here, up) => {
|
class WithStatelessBridge extends Config((site, here, up) => {
|
||||||
case BankedL2Key => up(BankedL2Key, site).copy(coherenceManager = { coreplex =>
|
case BankedL2Key => up(BankedL2Key, site).copy(coherenceManager = { coreplex =>
|
||||||
implicit val p = coreplex.p
|
implicit val p = coreplex.p
|
||||||
val cork = LazyModule(new TLCacheCork(unsafe = true))
|
|
||||||
val ww = LazyModule(new TLWidthWidget(coreplex.sbusBeatBytes))
|
val ww = LazyModule(new TLWidthWidget(coreplex.sbusBeatBytes))
|
||||||
ww.node :*= cork.node
|
(ww.node, ww.node, () => None)
|
||||||
(cork.node, ww.node, () => None)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -242,15 +241,21 @@ class WithBootROMFile(bootROMFile: String) extends Config((site, here, up) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
class WithSynchronousRocketTiles extends Config((site, here, up) => {
|
class WithSynchronousRocketTiles extends Config((site, here, up) => {
|
||||||
case RocketCrossing => SynchronousCrossing()
|
case RocketCrossingKey => up(RocketCrossingKey, site) map { r =>
|
||||||
|
r.copy(crossingType = SynchronousCrossing())
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithAynchronousRocketTiles(depth: Int, sync: Int) extends Config((site, here, up) => {
|
class WithAynchronousRocketTiles(depth: Int, sync: Int) extends Config((site, here, up) => {
|
||||||
case RocketCrossing => AsynchronousCrossing(depth, sync)
|
case RocketCrossingKey => up(RocketCrossingKey, site) map { r =>
|
||||||
|
r.copy(crossingType = AsynchronousCrossing(depth, sync))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithRationalRocketTiles extends Config((site, here, up) => {
|
class WithRationalRocketTiles extends Config((site, here, up) => {
|
||||||
case RocketCrossing => RationalCrossing()
|
case RocketCrossingKey => up(RocketCrossingKey, site) map { r =>
|
||||||
|
r.copy(crossingType = RationalCrossing())
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithEdgeDataBits(dataBits: Int) extends Config((site, here, up) => {
|
class WithEdgeDataBits(dataBits: Int) extends Config((site, here, up) => {
|
||||||
|
@ -31,6 +31,30 @@ class PeripheryBus(params: PeripheryBusParams)(implicit p: Parameters) extends T
|
|||||||
TLFragmenter(params.beatBytes, maxXferBytes)(outwardBufNode)
|
TLFragmenter(params.beatBytes, maxXferBytes)(outwardBufNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def toSyncSlaves(adapt: () => TLNodeChain, name: Option[String]): TLOutwardNode = SinkCardinality { implicit p =>
|
||||||
|
val adapters = adapt()
|
||||||
|
adapters.in :=? outwardBufNode
|
||||||
|
adapters.out
|
||||||
|
}
|
||||||
|
|
||||||
|
def toAsyncSlaves(sync: Int, adapt: () => TLNodeChain, name: Option[String]): TLAsyncOutwardNode = SinkCardinality { implicit p =>
|
||||||
|
val adapters = adapt()
|
||||||
|
val source = LazyModule(new TLAsyncCrossingSource(sync))
|
||||||
|
name.foreach{ n => source.suggestName(s"${busName}_${n}_TLAsyncCrossingSource")}
|
||||||
|
adapters.in :=? outwardNode
|
||||||
|
source.node :=? adapters.out
|
||||||
|
source.node
|
||||||
|
}
|
||||||
|
|
||||||
|
def toRationalSlaves(adapt: () => TLNodeChain, name: Option[String]): TLRationalOutwardNode = SinkCardinality { implicit p =>
|
||||||
|
val adapters = adapt()
|
||||||
|
val source = LazyModule(new TLRationalCrossingSource())
|
||||||
|
name.foreach{ n => source.suggestName(s"${busName}_${n}_TLRationalCrossingSource")}
|
||||||
|
adapters.in :=? outwardNode
|
||||||
|
source.node :=? adapters.out
|
||||||
|
source.node
|
||||||
|
}
|
||||||
|
|
||||||
val fromSystemBus: TLInwardNode = {
|
val fromSystemBus: TLInwardNode = {
|
||||||
val atomics = LazyModule(new TLAtomicAutomata(arithmetic = params.arithmetic))
|
val atomics = LazyModule(new TLAtomicAutomata(arithmetic = params.arithmetic))
|
||||||
inwardBufNode := atomics.node
|
inwardBufNode := atomics.node
|
||||||
|
@ -11,8 +11,74 @@ import freechips.rocketchip.tile._
|
|||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
|
case class TLNodeChain(in: TLInwardNode, out: TLOutwardNode)
|
||||||
|
|
||||||
|
// TODO: how specific are these to RocketTiles?
|
||||||
|
case class TileMasterPortParams(
|
||||||
|
addBuffers: Int = 0,
|
||||||
|
blockerCtrlAddr: Option[BigInt] = None,
|
||||||
|
cork: Option[Boolean] = None) {
|
||||||
|
def adapterChain(coreplex: HasPeripheryBus)
|
||||||
|
(implicit p: Parameters): () => TLNodeChain = {
|
||||||
|
|
||||||
|
val blockerParams = blockerCtrlAddr.map(BasicBusBlockerParams(_, coreplex.pbus.beatBytes, coreplex.sbus.beatBytes, deadlock = true))
|
||||||
|
|
||||||
|
val tile_master_cork = cork.map(u => (LazyModule(new TLCacheCork(unsafe = u))))
|
||||||
|
val tile_master_blocker = blockerParams.map(bp => LazyModule(new BasicBusBlocker(bp)))
|
||||||
|
val tile_master_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.allUncacheable))
|
||||||
|
val tile_master_buffer = LazyModule(new TLBufferChain(addBuffers))
|
||||||
|
|
||||||
|
tile_master_blocker.foreach { _.controlNode := coreplex.pbus.toVariableWidthSlaves }
|
||||||
|
|
||||||
|
val nodes = List(
|
||||||
|
Some(tile_master_buffer.node),
|
||||||
|
Some(tile_master_fixer.node),
|
||||||
|
tile_master_blocker.map(_.node),
|
||||||
|
tile_master_cork.map(_.node)
|
||||||
|
).flatMap(b=>b)
|
||||||
|
|
||||||
|
nodes.init zip nodes.tail foreach { case(front, back) => front :=* back }
|
||||||
|
|
||||||
|
() => TLNodeChain(in = nodes.last, out = nodes.head)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case class TileSlavePortParams(
|
||||||
|
addBuffers: Int = 0,
|
||||||
|
blockerCtrlAddr: Option[BigInt] = None) {
|
||||||
|
def adapterChain(coreplex: HasPeripheryBus)
|
||||||
|
(implicit p: Parameters): () => TLNodeChain = {
|
||||||
|
|
||||||
|
val blockerParams = blockerCtrlAddr.map(BasicBusBlockerParams(_, coreplex.pbus.beatBytes, coreplex.sbus.beatBytes))
|
||||||
|
|
||||||
|
val tile_slave_blocker = blockerParams.map(bp => LazyModule(new BasicBusBlocker(bp)))
|
||||||
|
val tile_slave_buffer = LazyModule(new TLBufferChain(addBuffers))
|
||||||
|
|
||||||
|
tile_slave_blocker.foreach { _.controlNode := coreplex.pbus.toVariableWidthSlaves }
|
||||||
|
|
||||||
|
val nodes = List(
|
||||||
|
Some(tile_slave_buffer.node),
|
||||||
|
tile_slave_blocker.map(_.node)
|
||||||
|
).flatMap(b=>b)
|
||||||
|
|
||||||
|
nodes.init zip nodes.tail foreach { case(front, back) => front :=* back }
|
||||||
|
|
||||||
|
() => TLNodeChain(in = nodes.last, out = nodes.head)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case class RocketCrossingParams(
|
||||||
|
crossingType: CoreplexClockCrossing = SynchronousCrossing(),
|
||||||
|
master: TileMasterPortParams = TileMasterPortParams(),
|
||||||
|
slave: TileSlavePortParams = TileSlavePortParams()) {
|
||||||
|
def knownRatio: Option[Int] = crossingType match {
|
||||||
|
case RationalCrossing(_) => Some(2)
|
||||||
|
case _ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case object RocketTilesKey extends Field[Seq[RocketTileParams]](Nil)
|
case object RocketTilesKey extends Field[Seq[RocketTileParams]](Nil)
|
||||||
case object RocketCrossing extends Field[CoreplexClockCrossing](SynchronousCrossing())
|
case object RocketCrossingKey extends Field[Seq[RocketCrossingParams]](List(RocketCrossingParams()))
|
||||||
|
|
||||||
trait HasRocketTiles extends HasTiles
|
trait HasRocketTiles extends HasTiles
|
||||||
with HasPeripheryBus
|
with HasPeripheryBus
|
||||||
@ -21,35 +87,43 @@ trait HasRocketTiles extends HasTiles
|
|||||||
with HasPeripheryDebug {
|
with HasPeripheryDebug {
|
||||||
val module: HasRocketTilesModuleImp
|
val module: HasRocketTilesModuleImp
|
||||||
|
|
||||||
private val crossing = p(RocketCrossing)
|
|
||||||
protected val tileParams = p(RocketTilesKey)
|
protected val tileParams = p(RocketTilesKey)
|
||||||
|
private val NumRocketTiles = tileParams.size
|
||||||
|
private val crossingParams = p(RocketCrossingKey)
|
||||||
|
private val crossings = crossingParams.size match {
|
||||||
|
case 1 => List.fill(NumRocketTiles) { crossingParams.head }
|
||||||
|
case NumRocketTiles => crossingParams
|
||||||
|
case _ => throw new Exception("RocketCrossingKey.size must == 1 or == RocketTilesKey.size")
|
||||||
|
}
|
||||||
|
|
||||||
// Make a wrapper for each tile that will wire it to coreplex devices and crossbars,
|
// Make a wrapper for each tile that will wire it to coreplex devices and crossbars,
|
||||||
// according to the specified type of clock crossing.
|
// according to the specified type of clock crossing.
|
||||||
val tiles: Seq[BaseTile] = localIntNodes.zip(tileParams).map { case (lip, tp) =>
|
private val crossingTuples = localIntNodes.zip(tileParams).zip(crossings)
|
||||||
|
val tiles: Seq[BaseTile] = crossingTuples.map { case ((lip, tp), crossing) =>
|
||||||
val pWithExtra = p.alterPartial {
|
val pWithExtra = p.alterPartial {
|
||||||
case TileKey => tp
|
case TileKey => tp
|
||||||
case BuildRoCC => tp.rocc
|
case BuildRoCC => tp.rocc
|
||||||
case SharedMemoryTLEdge => sharedMemoryTLEdge
|
case SharedMemoryTLEdge => sharedMemoryTLEdge
|
||||||
|
case RocketCrossingKey => List(crossing)
|
||||||
}
|
}
|
||||||
|
|
||||||
val wrapper = crossing match {
|
val wrapper = crossing.crossingType match {
|
||||||
case SynchronousCrossing(params) => {
|
case SynchronousCrossing(params) => {
|
||||||
val wrapper = LazyModule(new SyncRocketTile(tp)(pWithExtra))
|
val wrapper = LazyModule(new SyncRocketTile(tp)(pWithExtra))
|
||||||
sbus.fromSyncTiles(params, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
sbus.fromSyncTiles(params, crossing.master.adapterChain(this), tp.name) :=* wrapper.masterNode
|
||||||
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toSyncSlaves(tp.name, tp.externalSlaveBuffers) }
|
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toSyncSlaves(crossing.slave.adapterChain(this), tp.name) }
|
||||||
wrapper
|
wrapper
|
||||||
}
|
}
|
||||||
case AsynchronousCrossing(depth, sync) => {
|
case AsynchronousCrossing(depth, sync) => {
|
||||||
val wrapper = LazyModule(new AsyncRocketTile(tp)(pWithExtra))
|
val wrapper = LazyModule(new AsyncRocketTile(tp)(pWithExtra))
|
||||||
sbus.fromAsyncTiles(depth, sync, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
sbus.fromAsyncTiles(depth, sync, crossing.master.adapterChain(this), tp.name) :=* wrapper.masterNode
|
||||||
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toAsyncSlaves(sync, tp.name, tp.externalSlaveBuffers) }
|
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toAsyncSlaves(sync, crossing.slave.adapterChain(this), tp.name) }
|
||||||
wrapper
|
wrapper
|
||||||
}
|
}
|
||||||
case RationalCrossing(direction) => {
|
case RationalCrossing(direction) => {
|
||||||
val wrapper = LazyModule(new RationalRocketTile(tp)(pWithExtra))
|
val wrapper = LazyModule(new RationalRocketTile(tp)(pWithExtra))
|
||||||
sbus.fromRationalTiles(direction, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
sbus.fromRationalTiles(direction, crossing.master.adapterChain(this), tp.name) :=* wrapper.masterNode
|
||||||
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toRationalSlaves(tp.name, tp.externalSlaveBuffers) }
|
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toRationalSlaves(crossing.slave.adapterChain(this), tp.name) }
|
||||||
wrapper
|
wrapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,6 @@ class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWr
|
|||||||
protected def inwardSplitNode: TLInwardNode = master_splitter.node
|
protected def inwardSplitNode: TLInwardNode = master_splitter.node
|
||||||
protected def outwardSplitNode: TLOutwardNode = master_splitter.node
|
protected def outwardSplitNode: TLOutwardNode = master_splitter.node
|
||||||
|
|
||||||
private val tile_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.allUncacheable))
|
|
||||||
tile_fixer.suggestName(s"${busName}_tile_TLFIFOFixer")
|
|
||||||
master_splitter.node :=* tile_fixer.node
|
|
||||||
|
|
||||||
private val port_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all))
|
private val port_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all))
|
||||||
port_fixer.suggestName(s"${busName}_port_TLFIFOFixer")
|
port_fixer.suggestName(s"${busName}_port_TLFIFOFixer")
|
||||||
@ -55,33 +52,33 @@ class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWr
|
|||||||
|
|
||||||
def fromFrontBus: TLInwardNode = master_splitter.node
|
def fromFrontBus: TLInwardNode = master_splitter.node
|
||||||
|
|
||||||
def fromSyncTiles(params: BufferParams, addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = {
|
def fromSyncTiles(params: BufferParams, adapt: () => TLNodeChain, name: Option[String] = None): TLInwardNode = {
|
||||||
val tile_buf = LazyModule(new TLBuffer(params))
|
val adapters = adapt() // wanted to be called inside SystemBus scope
|
||||||
name.foreach { n => tile_buf.suggestName(s"${busName}_${n}_TLBuffer") }
|
val tile_sink = LazyModule(new TLBuffer(params))
|
||||||
val (in, out) = bufferChain(addBuffers, name = name)
|
name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLBuffer") }
|
||||||
|
|
||||||
tile_fixer.node :=* out
|
adapters.in :=* tile_sink.node
|
||||||
in :=* tile_buf.node
|
master_splitter.node :=* adapters.out
|
||||||
tile_buf.node
|
|
||||||
}
|
|
||||||
|
|
||||||
def fromRationalTiles(dir: RationalDirection, addBuffers: Int = 0, name: Option[String] = None): TLRationalInwardNode = {
|
|
||||||
val tile_sink = LazyModule(new TLRationalCrossingSink(direction = dir))
|
|
||||||
name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLRationalCrossingSink") }
|
|
||||||
val (in, out) = bufferChain(addBuffers, name = name)
|
|
||||||
|
|
||||||
tile_fixer.node :=* out
|
|
||||||
in :=* tile_sink.node
|
|
||||||
tile_sink.node
|
tile_sink.node
|
||||||
}
|
}
|
||||||
|
|
||||||
def fromAsyncTiles(depth: Int, sync: Int, addBuffers: Int = 0, name: Option[String] = None): TLAsyncInwardNode = {
|
def fromRationalTiles(dir: RationalDirection, adapt: () => TLNodeChain, name: Option[String] = None): TLRationalInwardNode = {
|
||||||
|
val adapters = adapt() // wanted to be called inside SystemBus scope
|
||||||
|
val tile_sink = LazyModule(new TLRationalCrossingSink(direction = dir))
|
||||||
|
name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLRationalCrossingSink") }
|
||||||
|
|
||||||
|
adapters.in :=* tile_sink.node
|
||||||
|
master_splitter.node :=* adapters.out
|
||||||
|
tile_sink.node
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromAsyncTiles(depth: Int, sync: Int, adapt: () => TLNodeChain, name: Option[String] = None): TLAsyncInwardNode = {
|
||||||
|
val adapters = adapt() // wanted to be called inside SystemBus scope
|
||||||
val tile_sink = LazyModule(new TLAsyncCrossingSink(depth, sync))
|
val tile_sink = LazyModule(new TLAsyncCrossingSink(depth, sync))
|
||||||
name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLAsyncCrossingSink") }
|
name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLAsyncCrossingSink") }
|
||||||
val (in, out) = bufferChain(addBuffers, name = name)
|
|
||||||
|
|
||||||
tile_fixer.node :=* out
|
adapters.in :=* tile_sink.node
|
||||||
in :=* tile_sink.node
|
master_splitter.node :=* adapters.out
|
||||||
tile_sink.node
|
tile_sink.node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,23 +9,6 @@ import freechips.rocketchip.regmapper._
|
|||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
case class BusBlockerParams(
|
|
||||||
controlAddress: BigInt,
|
|
||||||
controlBeatBytes: Int,
|
|
||||||
deviceBeatBytes: Int,
|
|
||||||
pmpRegisters: Int)
|
|
||||||
{
|
|
||||||
val page = 4096
|
|
||||||
val pageBits = log2Ceil(page)
|
|
||||||
val size = (((pmpRegisters * 8) + page - 1) / page) * page
|
|
||||||
|
|
||||||
require (pmpRegisters > 0)
|
|
||||||
require (controlAddress > 0)
|
|
||||||
require (controlAddress % size == 0)
|
|
||||||
require (controlBeatBytes > 0 && isPow2(controlBeatBytes))
|
|
||||||
require (deviceBeatBytes > 0 && isPow2(deviceBeatBytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
case class DevicePMPParams(addressBits: Int, pageBits: Int)
|
case class DevicePMPParams(addressBits: Int, pageBits: Int)
|
||||||
class DevicePMP(params: DevicePMPParams) extends GenericParameterizedBundle(params)
|
class DevicePMP(params: DevicePMPParams) extends GenericParameterizedBundle(params)
|
||||||
{
|
{
|
||||||
@ -71,6 +54,28 @@ object DevicePMP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** BusBlocker uses a set of DevicePMP registers to control whether
|
||||||
|
* accesses of certain types are allowed to proceed or bypassed to
|
||||||
|
* a /dev/null device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
case class BusBlockerParams(
|
||||||
|
controlAddress: BigInt,
|
||||||
|
controlBeatBytes: Int,
|
||||||
|
deviceBeatBytes: Int,
|
||||||
|
pmpRegisters: Int)
|
||||||
|
{
|
||||||
|
val page = 4096
|
||||||
|
val pageBits = log2Ceil(page)
|
||||||
|
val size = (((pmpRegisters * 8) + page - 1) / page) * page
|
||||||
|
|
||||||
|
require (pmpRegisters > 0)
|
||||||
|
require (controlAddress > 0)
|
||||||
|
require (controlAddress % size == 0)
|
||||||
|
require (controlBeatBytes > 0 && isPow2(controlBeatBytes))
|
||||||
|
require (deviceBeatBytes > 0 && isPow2(deviceBeatBytes))
|
||||||
|
}
|
||||||
|
|
||||||
class BusBlocker(params: BusBlockerParams)(implicit p: Parameters) extends TLBusBypassBase(params.deviceBeatBytes)
|
class BusBlocker(params: BusBlockerParams)(implicit p: Parameters) extends TLBusBypassBase(params.deviceBeatBytes)
|
||||||
{
|
{
|
||||||
val device = new SimpleDevice("bus-blocker", Seq("sifive,bus-blocker0"))
|
val device = new SimpleDevice("bus-blocker", Seq("sifive,bus-blocker0"))
|
||||||
@ -100,3 +105,37 @@ class BusBlocker(params: BusBlockerParams)(implicit p: Parameters) extends TLBus
|
|||||||
bar.module.io.bypass := !allow
|
bar.module.io.bypass := !allow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** BasicBusBlocker uses a single bit register to control whether
|
||||||
|
* accesses of all types are allowed to proceed or bypassed to
|
||||||
|
* a /dev/null device. It has a second bit register to report
|
||||||
|
* whether any requests are pending on either path.
|
||||||
|
*/
|
||||||
|
|
||||||
|
case class BasicBusBlockerParams(
|
||||||
|
controlAddress: BigInt,
|
||||||
|
controlBeatBytes: Int,
|
||||||
|
deviceBeatBytes: Int,
|
||||||
|
deadlock: Boolean = false)
|
||||||
|
|
||||||
|
class BasicBusBlocker(params: BasicBusBlockerParams)(implicit p: Parameters)
|
||||||
|
extends TLBusBypassBase(params.deviceBeatBytes, params.deadlock)
|
||||||
|
{
|
||||||
|
val device = new SimpleDevice("basic-bus-blocker", Seq("sifive,basic-bus-blocker0"))
|
||||||
|
|
||||||
|
val controlNode = TLRegisterNode(
|
||||||
|
address = Seq(AddressSet(params.controlAddress, 0xFFF)),
|
||||||
|
device = device,
|
||||||
|
beatBytes = params.controlBeatBytes)
|
||||||
|
|
||||||
|
lazy val module = new LazyModuleImp(this) {
|
||||||
|
val allow = RegInit(true.B)
|
||||||
|
val pending = RegNext(bar.module.io.pending)
|
||||||
|
|
||||||
|
controlNode.regmap(
|
||||||
|
0 -> Seq(RegField (32, allow)),
|
||||||
|
4 -> Seq(RegField.r(32, pending)))
|
||||||
|
|
||||||
|
bar.module.io.bypass := !allow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -10,7 +10,7 @@ import freechips.rocketchip.tilelink._
|
|||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
import scala.math.min
|
import scala.math.min
|
||||||
|
|
||||||
abstract class TLBusBypassBase(beatBytes: Int)(implicit p: Parameters) extends LazyModule
|
abstract class TLBusBypassBase(beatBytes: Int, deadlock: Boolean = false)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
protected val nodeIn = TLIdentityNode()
|
protected val nodeIn = TLIdentityNode()
|
||||||
protected val nodeOut = TLIdentityNode()
|
protected val nodeOut = TLIdentityNode()
|
||||||
@ -18,7 +18,8 @@ abstract class TLBusBypassBase(beatBytes: Int)(implicit p: Parameters) extends L
|
|||||||
|
|
||||||
protected val bar = LazyModule(new TLBusBypassBar)
|
protected val bar = LazyModule(new TLBusBypassBar)
|
||||||
protected val everything = Seq(AddressSet(0, BigInt("ffffffffffffffffffffffffffffffff", 16))) // 128-bit
|
protected val everything = Seq(AddressSet(0, BigInt("ffffffffffffffffffffffffffffffff", 16))) // 128-bit
|
||||||
protected val error = LazyModule(new TLError(ErrorParams(everything), beatBytes))
|
protected val error = if (deadlock) LazyModule(new DeadlockDevice(ErrorParams(everything), beatBytes))
|
||||||
|
else LazyModule(new TLError(ErrorParams(everything), beatBytes))
|
||||||
|
|
||||||
// order matters
|
// order matters
|
||||||
bar.node := nodeIn
|
bar.node := nodeIn
|
||||||
@ -48,6 +49,7 @@ class TLBusBypassBar(implicit p: Parameters) extends LazyModule
|
|||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
val bypass = Bool(INPUT)
|
val bypass = Bool(INPUT)
|
||||||
|
val pending = Bool(OUTPUT)
|
||||||
})
|
})
|
||||||
|
|
||||||
val (in, edge) = node.in(0)
|
val (in, edge) = node.in(0)
|
||||||
@ -59,6 +61,8 @@ class TLBusBypassBar(implicit p: Parameters) extends LazyModule
|
|||||||
val flight = RegInit(UInt(0, width = log2Ceil(3*edge.client.endSourceId+1)))
|
val flight = RegInit(UInt(0, width = log2Ceil(3*edge.client.endSourceId+1)))
|
||||||
val bypass = RegInit(io.bypass) // synchronous reset required
|
val bypass = RegInit(io.bypass) // synchronous reset required
|
||||||
|
|
||||||
|
io.pending := (flight > 0.U)
|
||||||
|
|
||||||
val (a_first, a_last, _) = edge.firstlast(in.a)
|
val (a_first, a_last, _) = edge.firstlast(in.a)
|
||||||
val (b_first, b_last, _) = edge.firstlast(in.b)
|
val (b_first, b_last, _) = edge.firstlast(in.b)
|
||||||
val (c_first, c_last, _) = edge.firstlast(in.c)
|
val (c_first, c_last, _) = edge.firstlast(in.c)
|
||||||
|
@ -13,17 +13,13 @@ import scala.math.min
|
|||||||
case class ErrorParams(address: Seq[AddressSet], maxTransfer: Int = 4096)
|
case class ErrorParams(address: Seq[AddressSet], maxTransfer: Int = 4096)
|
||||||
case object ErrorParams extends Field[ErrorParams]
|
case object ErrorParams extends Field[ErrorParams]
|
||||||
|
|
||||||
/** Adds a /dev/null slave that generates TL error response messages */
|
abstract class DevNullDevice(params: ErrorParams, beatBytes: Int = 4)
|
||||||
class TLError(params: ErrorParams, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
|
(device: SimpleDevice)
|
||||||
{
|
(implicit p: Parameters) extends LazyModule {
|
||||||
val address = params.address
|
|
||||||
|
|
||||||
val device = new SimpleDevice("error-device", Seq("sifive,error0"))
|
|
||||||
|
|
||||||
val xfer = TransferSizes(1, params.maxTransfer)
|
val xfer = TransferSizes(1, params.maxTransfer)
|
||||||
val node = TLManagerNode(Seq(TLManagerPortParameters(
|
val node = TLManagerNode(Seq(TLManagerPortParameters(
|
||||||
Seq(TLManagerParameters(
|
Seq(TLManagerParameters(
|
||||||
address = address,
|
address = params.address,
|
||||||
resources = device.reg("mem"),
|
resources = device.reg("mem"),
|
||||||
regionType = RegionType.UNCACHED,
|
regionType = RegionType.UNCACHED,
|
||||||
supportsAcquireT = xfer,
|
supportsAcquireT = xfer,
|
||||||
@ -38,7 +34,12 @@ class TLError(params: ErrorParams, beatBytes: Int = 4)(implicit p: Parameters) e
|
|||||||
beatBytes = beatBytes,
|
beatBytes = beatBytes,
|
||||||
endSinkId = 1, // can receive GrantAck
|
endSinkId = 1, // can receive GrantAck
|
||||||
minLatency = 1))) // no bypass needed for this device
|
minLatency = 1))) // no bypass needed for this device
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Adds a /dev/null slave that generates TL error response messages */
|
||||||
|
class TLError(params: ErrorParams, beatBytes: Int = 4)(implicit p: Parameters)
|
||||||
|
extends DevNullDevice(params, beatBytes)(new SimpleDevice("error-device", Seq("sifive,error0")))
|
||||||
|
{
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
import TLMessages._
|
import TLMessages._
|
||||||
import TLPermissions._
|
import TLPermissions._
|
||||||
@ -88,6 +89,23 @@ class TLError(params: ErrorParams, beatBytes: Int = 4)(implicit p: Parameters) e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Adds a /dev/null slave that does not raise ready for any incoming traffic.
|
||||||
|
* !!! WARNING: This device WILL cause your bus to deadlock for as long as you
|
||||||
|
* continue to send traffic to it !!!
|
||||||
|
*/
|
||||||
|
class DeadlockDevice(params: ErrorParams, beatBytes: Int = 4)(implicit p: Parameters)
|
||||||
|
extends DevNullDevice(params, beatBytes)(new SimpleDevice("deadlock-device", Seq("sifive,deadlock0")))
|
||||||
|
{
|
||||||
|
lazy val module = new LazyModuleImp(this) {
|
||||||
|
val (in, _) = node.in(0)
|
||||||
|
in.a.ready := Bool(false)
|
||||||
|
in.b.valid := Bool(false)
|
||||||
|
in.c.ready := Bool(false)
|
||||||
|
in.d.valid := Bool(false)
|
||||||
|
in.e.ready := Bool(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
trait HasSystemErrorSlave extends HasSystemBus {
|
trait HasSystemErrorSlave extends HasSystemBus {
|
||||||
private val params = p(ErrorParams)
|
private val params = p(ErrorParams)
|
||||||
val error = LazyModule(new TLError(params, sbus.beatBytes))
|
val error = LazyModule(new TLError(params, sbus.beatBytes))
|
||||||
|
@ -25,7 +25,9 @@ class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex
|
|||||||
})
|
})
|
||||||
)}
|
)}
|
||||||
|
|
||||||
tiles.flatMap(_.dcacheOpt).foreach { sbus.fromSyncTiles(BufferParams.default) :=* _.node }
|
tiles.flatMap(_.dcacheOpt).foreach {
|
||||||
|
sbus.fromSyncTiles(BufferParams.default, TileMasterPortParams().adapterChain(this)) :=* _.node
|
||||||
|
}
|
||||||
|
|
||||||
val pbusRAM = LazyModule(new TLRAM(AddressSet(testRamAddr, 0xffff), false, pbus.beatBytes))
|
val pbusRAM = LazyModule(new TLRAM(AddressSet(testRamAddr, 0xffff), false, pbus.beatBytes))
|
||||||
pbusRAM.node := pbus.toVariableWidthSlaves
|
pbusRAM.node := pbus.toVariableWidthSlaves
|
||||||
|
@ -7,7 +7,7 @@ import Chisel._
|
|||||||
import freechips.rocketchip.config._
|
import freechips.rocketchip.config._
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.coreplex._
|
import freechips.rocketchip.coreplex._
|
||||||
import freechips.rocketchip.rocket.{HellaCache, RocketCoreParams}
|
import freechips.rocketchip.rocket.{DCache, RocketCoreParams}
|
||||||
import freechips.rocketchip.tile._
|
import freechips.rocketchip.tile._
|
||||||
import scala.collection.mutable.ListBuffer
|
import scala.collection.mutable.ListBuffer
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ case object GroundTestTilesKey extends Field[Seq[GroundTestTileParams]]
|
|||||||
|
|
||||||
abstract class GroundTestTile(params: GroundTestTileParams)(implicit p: Parameters) extends BaseTile(params)(p) {
|
abstract class GroundTestTile(params: GroundTestTileParams)(implicit p: Parameters) extends BaseTile(params)(p) {
|
||||||
val slave = None
|
val slave = None
|
||||||
val dcacheOpt = params.dcache.map { dc => LazyModule(HellaCache(0, dc.nMSHRs == 0)) }
|
val dcacheOpt = params.dcache.map { dc => LazyModule(new DCache(0)) }
|
||||||
|
|
||||||
override lazy val module = new GroundTestTileModule(this, () => new GroundTestTileBundle(this))
|
override lazy val module = new GroundTestTileModule(this, () => new GroundTestTileBundle(this))
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ package freechips.rocketchip.rocket
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import Chisel.ImplicitConversions._
|
import Chisel.ImplicitConversions._
|
||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.Parameters
|
||||||
import freechips.rocketchip.coreplex.{RationalCrossing, RocketCrossing, RocketTilesKey}
|
import freechips.rocketchip.coreplex.{RocketTilesKey}
|
||||||
import freechips.rocketchip.diplomacy.{AddressSet, RegionType}
|
import freechips.rocketchip.diplomacy.{AddressSet, RegionType}
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
@ -64,7 +64,7 @@ class DCacheMetadataReq(implicit p: Parameters) extends L1HellaCacheBundle()(p)
|
|||||||
val data = new L1Metadata
|
val data = new L1Metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
class DCache(hartid: Int, val scratch: () => Option[AddressSet] = () => None)(implicit p: Parameters) extends HellaCache(hartid)(p) {
|
class DCache(hartid: Int, val scratch: () => Option[AddressSet] = () => None, val bufferUncachedRequests: Option[Int] = None)(implicit p: Parameters) extends HellaCache(hartid)(p) {
|
||||||
override lazy val module = new DCacheModule(this)
|
override lazy val module = new DCacheModule(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,14 +91,12 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
|
|||||||
dataArb.io.out.ready := true
|
dataArb.io.out.ready := true
|
||||||
metaArb.io.out.ready := true
|
metaArb.io.out.ready := true
|
||||||
|
|
||||||
val rational = p(RocketCrossing) match {
|
|
||||||
case RationalCrossing(_) => true
|
|
||||||
case _ => false
|
|
||||||
}
|
|
||||||
|
|
||||||
val q_depth = if (rational) (2 min maxUncachedInFlight-1) else 0
|
|
||||||
val tl_out_a = Wire(tl_out.a)
|
val tl_out_a = Wire(tl_out.a)
|
||||||
tl_out.a <> (if (q_depth == 0) tl_out_a else Queue(tl_out_a, q_depth, flow = true))
|
tl_out.a <> outer.bufferUncachedRequests
|
||||||
|
.map(_ min maxUncachedInFlight-1)
|
||||||
|
.map(Queue(tl_out_a, _, flow = true))
|
||||||
|
.getOrElse(tl_out_a)
|
||||||
|
|
||||||
val (tl_out_c, release_queue_empty) =
|
val (tl_out_c, release_queue_empty) =
|
||||||
if (cacheParams.acquireBeforeRelease) {
|
if (cacheParams.acquireBeforeRelease) {
|
||||||
val q = Module(new Queue(tl_out.c.bits, cacheDataBeats, flow = true))
|
val q = Module(new Queue(tl_out.c.bits, cacheDataBeats, flow = true))
|
||||||
@ -392,7 +390,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
|
|||||||
val access_address = s2_req.addr
|
val access_address = s2_req.addr
|
||||||
val a_size = mtSize(s2_req.typ)
|
val a_size = mtSize(s2_req.typ)
|
||||||
val a_data = Fill(beatWords, pstore1_data)
|
val a_data = Fill(beatWords, pstore1_data)
|
||||||
val acquire = if (edge.manager.anySupportAcquireB) {
|
val acquire = if (edge.manager.anySupportAcquireT) {
|
||||||
edge.AcquireBlock(UInt(0), acquire_address, lgCacheBlockBytes, s2_grow_param)._2 // Cacheability checked by tlb
|
edge.AcquireBlock(UInt(0), acquire_address, lgCacheBlockBytes, s2_grow_param)._2 // Cacheability checked by tlb
|
||||||
} else {
|
} else {
|
||||||
Wire(new TLBundleA(edge.bundle))
|
Wire(new TLBundleA(edge.bundle))
|
||||||
@ -595,7 +593,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
|
|||||||
when (releaseDone) { release_state := s_probe_write_meta }
|
when (releaseDone) { release_state := s_probe_write_meta }
|
||||||
}
|
}
|
||||||
when (release_state.isOneOf(s_voluntary_writeback, s_voluntary_write_meta)) {
|
when (release_state.isOneOf(s_voluntary_writeback, s_voluntary_write_meta)) {
|
||||||
if (edge.manager.anySupportAcquireB)
|
if (edge.manager.anySupportAcquireT)
|
||||||
tl_out_c.bits := edge.Release(fromSource = 0.U,
|
tl_out_c.bits := edge.Release(fromSource = 0.U,
|
||||||
toAddress = 0.U,
|
toAddress = 0.U,
|
||||||
lgSize = lgCacheBlockBytes,
|
lgSize = lgCacheBlockBytes,
|
||||||
@ -711,7 +709,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
|
|||||||
metaArb.io.in(5).bits.way_en := ~UInt(0, nWays)
|
metaArb.io.in(5).bits.way_en := ~UInt(0, nWays)
|
||||||
metaArb.io.in(5).bits.data := metaArb.io.in(4).bits.data
|
metaArb.io.in(5).bits.data := metaArb.io.in(4).bits.data
|
||||||
// Only flush D$ on FENCE.I if some cached executable regions are untracked.
|
// Only flush D$ on FENCE.I if some cached executable regions are untracked.
|
||||||
if (!edge.manager.managers.forall(m => !m.supportsAcquireB || !m.executable || m.regionType >= RegionType.TRACKED)) {
|
if (!edge.manager.managers.forall(m => !m.supportsAcquireT || !m.executable || m.regionType >= RegionType.TRACKED)) {
|
||||||
when (tl_out_a.fire() && !s2_uncached) { flushed := false }
|
when (tl_out_a.fire() && !s2_uncached) { flushed := false }
|
||||||
when (flushing) {
|
when (flushing) {
|
||||||
s1_victim_way := flushCounter >> log2Up(nSets)
|
s1_victim_way := flushCounter >> log2Up(nSets)
|
||||||
|
@ -192,12 +192,6 @@ class HellaCacheModule(outer: HellaCache) extends LazyModuleImp(outer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object HellaCache {
|
|
||||||
def apply(hartid: Int, blocking: Boolean, scratch: () => Option[AddressSet] = () => None)(implicit p: Parameters) = {
|
|
||||||
if (blocking) new DCache(hartid, scratch) else new NonBlockingDCache(hartid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Mix-ins for constructing tiles that have a HellaCache */
|
/** Mix-ins for constructing tiles that have a HellaCache */
|
||||||
|
|
||||||
trait HasHellaCache extends HasTileLinkMasterPort with HasTileParameters {
|
trait HasHellaCache extends HasTileLinkMasterPort with HasTileParameters {
|
||||||
@ -206,7 +200,11 @@ trait HasHellaCache extends HasTileLinkMasterPort with HasTileParameters {
|
|||||||
def findScratchpadFromICache: Option[AddressSet]
|
def findScratchpadFromICache: Option[AddressSet]
|
||||||
val hartid: Int
|
val hartid: Int
|
||||||
var nDCachePorts = 0
|
var nDCachePorts = 0
|
||||||
val dcache = LazyModule(HellaCache(hartid, tileParams.dcache.get.nMSHRs == 0, findScratchpadFromICache _))
|
val dcache: HellaCache = LazyModule(
|
||||||
|
if(tileParams.dcache.get.nMSHRs == 0) {
|
||||||
|
new DCache(hartid, findScratchpadFromICache _, p(RocketCrossingKey).head.knownRatio)
|
||||||
|
} else { new NonBlockingDCache(hartid) })
|
||||||
|
|
||||||
tileBus.node := dcache.node
|
tileBus.node := dcache.node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ class TLB(instruction: Boolean, lgMaxSize: Int, nEntries: Int)(implicit edge: TL
|
|||||||
val legal_address = edge.manager.findSafe(mpu_physaddr).reduce(_||_)
|
val legal_address = edge.manager.findSafe(mpu_physaddr).reduce(_||_)
|
||||||
def fastCheck(member: TLManagerParameters => Boolean) =
|
def fastCheck(member: TLManagerParameters => Boolean) =
|
||||||
legal_address && edge.manager.fastProperty(mpu_physaddr, member, (b:Boolean) => Bool(b))
|
legal_address && edge.manager.fastProperty(mpu_physaddr, member, (b:Boolean) => Bool(b))
|
||||||
val cacheable = fastCheck(_.supportsAcquireB) && (instruction || !usingDataScratchpad)
|
val cacheable = fastCheck(_.supportsAcquireT) && (instruction || !usingDataScratchpad)
|
||||||
val homogeneous = TLBPageLookup(edge.manager.managers, xLen, p(CacheBlockBytes), BigInt(1) << pgIdxBits)(mpu_physaddr).homogeneous
|
val homogeneous = TLBPageLookup(edge.manager.managers, xLen, p(CacheBlockBytes), BigInt(1) << pgIdxBits)(mpu_physaddr).homogeneous
|
||||||
val prot_r = fastCheck(_.supportsGet) && pmp.io.r
|
val prot_r = fastCheck(_.supportsGet) && pmp.io.r
|
||||||
val prot_w = fastCheck(_.supportsPutFull) && pmp.io.w
|
val prot_w = fastCheck(_.supportsPutFull) && pmp.io.w
|
||||||
|
@ -46,7 +46,6 @@ object TLBPageLookup
|
|||||||
require (!m.supportsAcquireT || m.supportsAcquireT .contains(xferSizes), s"MemoryMap region ${m.name} only supports ${m.supportsAcquireT} AcquireT, but must support ${xferSizes}")
|
require (!m.supportsAcquireT || m.supportsAcquireT .contains(xferSizes), s"MemoryMap region ${m.name} only supports ${m.supportsAcquireT} AcquireT, but must support ${xferSizes}")
|
||||||
require (!m.supportsLogical || m.supportsLogical .contains(amoSizes), s"MemoryMap region ${m.name} only supports ${m.supportsLogical} Logical, but must support ${amoSizes}")
|
require (!m.supportsLogical || m.supportsLogical .contains(amoSizes), s"MemoryMap region ${m.name} only supports ${m.supportsLogical} Logical, but must support ${amoSizes}")
|
||||||
require (!m.supportsArithmetic || m.supportsArithmetic.contains(amoSizes), s"MemoryMap region ${m.name} only supports ${m.supportsArithmetic} Arithmetic, but must support ${amoSizes}")
|
require (!m.supportsArithmetic || m.supportsArithmetic.contains(amoSizes), s"MemoryMap region ${m.name} only supports ${m.supportsArithmetic} Arithmetic, but must support ${amoSizes}")
|
||||||
require (m.supportsAcquireT || !m.supportsAcquireB, s"MemoryMap region ${m.name} supports AcquireB (cached read) but not AcquireT (cached write)... and rocket assumes this")
|
|
||||||
|
|
||||||
(m.address, TLBFixedPermissions(
|
(m.address, TLBFixedPermissions(
|
||||||
e = Seq(RegionType.PUT_EFFECTS, RegionType.GET_EFFECTS) contains m.regionType,
|
e = Seq(RegionType.PUT_EFFECTS, RegionType.GET_EFFECTS) contains m.regionType,
|
||||||
|
@ -66,7 +66,7 @@ class DualCoreConfig extends Config(
|
|||||||
class TinyConfig extends Config(
|
class TinyConfig extends Config(
|
||||||
new WithNMemoryChannels(0) ++
|
new WithNMemoryChannels(0) ++
|
||||||
new WithStatelessBridge ++
|
new WithStatelessBridge ++
|
||||||
new WithNTinyCores(1) ++
|
new With1TinyCore ++
|
||||||
new BaseConfig)
|
new BaseConfig)
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,9 +22,7 @@ case class RocketTileParams(
|
|||||||
trace: Boolean = false,
|
trace: Boolean = false,
|
||||||
hcfOnUncorrectable: Boolean = false,
|
hcfOnUncorrectable: Boolean = false,
|
||||||
name: Option[String] = Some("tile"),
|
name: Option[String] = Some("tile"),
|
||||||
hartid: Int = 0,
|
hartid: Int = 0) extends TileParams {
|
||||||
externalMasterBuffers: Int = 0,
|
|
||||||
externalSlaveBuffers: Int = 0) extends TileParams {
|
|
||||||
require(icache.isDefined)
|
require(icache.isDefined)
|
||||||
require(dcache.isDefined)
|
require(dcache.isDefined)
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,7 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM
|
|||||||
val d_d = Wire(in.d)
|
val d_d = Wire(in.d)
|
||||||
d_d <> out.d
|
d_d <> out.d
|
||||||
d_d.bits.source := out.d.bits.source >> 1
|
d_d.bits.source := out.d.bits.source >> 1
|
||||||
|
if (unsafe) { d_d.bits.sink := UInt(0) }
|
||||||
|
|
||||||
when (out.d.bits.opcode === AccessAckData && out.d.bits.source(0)) {
|
when (out.d.bits.opcode === AccessAckData && out.d.bits.source(0)) {
|
||||||
d_d.bits.opcode := GrantData
|
d_d.bits.opcode := GrantData
|
||||||
|
Loading…
Reference in New Issue
Block a user