Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
37 changes: 22 additions & 15 deletions src/main/scala/riscv/plugins/Cache.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ class Cache(
busFilter: ((Stage, MemBus, MemBus) => Unit) => Unit,
prefetcher: Option[PrefetchService] = None,
maxPrefetches: Int = 1,
cacheable: (UInt => Bool) = (_ => True)
cacheable: (UInt => Bool) = (_ => True),
delay: Int = 1
Comment thread
martonbognar marked this conversation as resolved.
Resolved
)(implicit config: Config)
extends Plugin[Pipeline] {
private val byteIndexBits = log2Up(config.xlen / 8)
Expand Down Expand Up @@ -104,9 +105,15 @@ class Cache(
private val rspBuffer = Reg(MemBusRsp(internal.config))
private val returningCache = Reg(Bool()).init(False)

// Delay cache response with a fixed delay
// Note that a minimal delay of 1 clock cycle is required to prevent
// combinatorial loops in case of multiple dbus filters.
private val internalRspBuffer = Stream(MemBusRsp(internal.config))
internal.rsp << internalRspBuffer.delay(delay)

// initial state: not sending or acknowledging anything
internal.rsp.valid := False
internal.rsp.payload.assignDontCare()
internalRspBuffer.valid := False
internalRspBuffer.payload.assignDontCare()
internal.cmd.ready := False
external.cmd.valid := False
external.cmd.payload.assignDontCare()
Expand All @@ -126,13 +133,13 @@ class Cache(

private def forwardRspToInternal(): Unit = {
sendingRsp := True
internal.rsp.valid := True
internalRspBuffer.valid := True

internal.rsp.rdata := external.rsp.rdata
internalRspBuffer.rdata := external.rsp.rdata
// the index of 1's in internalIds indicate to which internal ids the response should be forwarded
val internalId = OHToUInt(OHMasking.first(outstandingLoads(external.rsp.id).internalIds))
internal.rsp.id := internalId
when(internal.rsp.ready) {
internalRspBuffer.id := internalId
when(internalRspBuffer.ready) {
// set the bit to 0 once it has been forwarded
outstandingLoads(external.rsp.id).internalIds(internalId) := False
}
Expand Down Expand Up @@ -188,7 +195,7 @@ class Cache(
forwardRspToInternal()
when(
// when there is only one id left to forward, put result in cache and inform external bus we are done
internal.rsp.ready && CountOne(outstandingLoads(external.rsp.id).internalIds) === 1
internalRspBuffer.ready && CountOne(outstandingLoads(external.rsp.id).internalIds) === 1
) {
insertRspInCache(address)
alreadySendingRsp := False
Expand All @@ -206,10 +213,10 @@ class Cache(
rspBuffer.id := internal.cmd.id
rspBuffer.rdata := cacheLine.value
when(!sendingRsp) {
internal.rsp.valid := True
internal.rsp.id := internal.cmd.id
internal.rsp.rdata := cacheLine.value
when(!internal.rsp.ready) {
internalRspBuffer.valid := True
internalRspBuffer.id := internal.cmd.id
internalRspBuffer.rdata := cacheLine.value
when(!internalRspBuffer.ready) {
returningCache := True
}
} otherwise {
Expand All @@ -221,9 +228,9 @@ class Cache(

when(returningCache && !sendingRsp) {
// when not forwarding rsp but have a stored cache hit, return that
internal.rsp.valid := True
internal.rsp.payload := rspBuffer
when(internal.rsp.ready) {
internalRspBuffer.valid := True
internalRspBuffer.payload := rspBuffer
when(internalRspBuffer.ready) {
returningCache := False
}
}
Expand Down
19 changes: 18 additions & 1 deletion src/main/scala/riscv/plugins/memory/DynamicMemoryBackbone.scala
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,24 @@ class DynamicMemoryBackbone(implicit config: Config) extends MemoryBackbone with
}
}

dbusFilter.foreach(_(internalWriteDBusStage, unifiedInternalDBus, externalDBus))
if (dbusFilters.nonEmpty) {
var previous_level = unifiedInternalDBus

dbusFilters.zipWithIndex.foreach { case (f, i) =>
if (i < dbusFilters.size - 1) {
val intermediateDBus =
Stream(MemBus(config.dbusConfig)).setName("intermediate_dbus" + i)
f(internalWriteDBusStage, previous_level, intermediateDBus)

previous_level = intermediateDBus
} else {
f(internalWriteDBusStage, previous_level, externalDBus)
}
}
} else {
unifiedInternalDBus.payload <> externalDBus
}

dbusObservers.foreach(_(internalWriteDBusStage, unifiedInternalDBus))
}
}
Expand Down
12 changes: 2 additions & 10 deletions src/main/scala/riscv/plugins/memory/MemoryBackbone.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ abstract class MemoryBackbone(implicit config: Config) extends Plugin with Memor
var internalWriteDBus: MemBus = null
var internalReadDBusStages: Seq[Stage] = null
var internalWriteDBusStage: Stage = null
var dbusFilter: Option[MemBusFilter] = None
var dbusFilters = mutable.ArrayBuffer[MemBusFilter]()
var ibusFilter: Option[MemBusFilter] = None
val dbusObservers = mutable.ArrayBuffer[MemBusObserver]()

Expand Down Expand Up @@ -45,13 +45,6 @@ abstract class MemoryBackbone(implicit config: Config) extends Plugin with Memor

override def finish(): Unit = {
setupIBus()

// DBUS
if (dbusFilter.isEmpty) {
dbusFilter = Some((_, idbus, edbus) => {
idbus <> edbus
})
}
}

override def getExternalIBus: MemBus = {
Expand Down Expand Up @@ -80,8 +73,7 @@ abstract class MemoryBackbone(implicit config: Config) extends Plugin with Memor
}

override def filterDBus(filter: MemBusFilter): Unit = {
assert(dbusFilter.isEmpty)
dbusFilter = Some(filter)
dbusFilters += filter
}

override def filterIBus(filter: MemBusFilter): Unit = {
Expand Down
20 changes: 19 additions & 1 deletion src/main/scala/riscv/plugins/memory/StaticMemoryBackbone.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,25 @@ class StaticMemoryBackbone(implicit config: Config) extends MemoryBackbone {

pipeline plug new Area {
externalDBus = master(new MemBus(config.dbusConfig)).setName("dbus")
dbusFilter.foreach(_(internalWriteDBusStage, internalWriteDBus, externalDBus))

if (dbusFilters.nonEmpty) {
var previous_level = internalWriteDBus

dbusFilters.zipWithIndex.foreach { case (f, i) =>
if (i < dbusFilters.size - 1) {
val intermediateDBus =
Stream(MemBus(config.dbusConfig)).setName("intermediate_dbus" + i)
f(null, previous_level, intermediateDBus)
Comment thread
martonbognar marked this conversation as resolved.
Resolved

previous_level = intermediateDBus
} else {
f(null, previous_level, externalDBus)
}
}
} else {
internalWriteDBus <> externalDBus
}

dbusObservers.foreach(_(internalWriteDBusStage, internalWriteDBus))
}
}
Expand Down