Skip to content

Commit

Permalink
Make sure dbus commands are not canceled before acknowledgement
Browse files Browse the repository at this point in the history
  • Loading branch information
martonbognar committed Mar 2, 2025
1 parent 6b40cd6 commit 5928d76
Showing 1 changed file with 37 additions and 9 deletions.
46 changes: 37 additions & 9 deletions src/main/scala/riscv/plugins/memory/DynamicMemoryBackbone.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ class DynamicMemoryBackbone(stageCount: Int)(implicit config: Config)
busValid := False

when(
currentlyInserting.payload.stageIndex === index && currentlyInserting.valid && !activeFlush
currentlyInserting.payload.stageIndex === index && currentlyInserting.valid && !activeFlush && !busId2StageIndex(
nextId
).invalidated
) {
internalReadDBus.cmd.ready := True
}
Expand All @@ -94,7 +96,7 @@ class DynamicMemoryBackbone(stageCount: Int)(implicit config: Config)
sameCycleReturn := True
busId2StageIndex(unifiedInternalDBus.rsp.id).rspReceived := True
busId2StageIndex(unifiedInternalDBus.rsp.id).cmdSent := False // free up slot
busValid := True
busValid := !busId2StageIndex(unifiedInternalDBus.rsp.id).invalidated
}
when(
busId2StageIndex(unifiedInternalDBus.rsp.id).cmdSent && busId2StageIndex(
Expand All @@ -103,9 +105,7 @@ class DynamicMemoryBackbone(stageCount: Int)(implicit config: Config)
) {
busId2StageIndex(unifiedInternalDBus.rsp.id).rspReceived := True
busId2StageIndex(unifiedInternalDBus.rsp.id).cmdSent := False // free up slot
when(!busId2StageIndex(unifiedInternalDBus.rsp.id).invalidated) {
busValid := True
}
busValid := !busId2StageIndex(unifiedInternalDBus.rsp.id).invalidated
}
}

Expand All @@ -122,14 +122,35 @@ class DynamicMemoryBackbone(stageCount: Int)(implicit config: Config)
).rsp.ready
}

private var context = when(False) {}

// TODO: is it possible to do the following with an arbiter instead of this manual mess?

private val cmds = fullDBusCmds :+ internalWriteDBus.cmd

internalWriteDBus.cmd.ready := unifiedInternalDBus.cmd.ready && unifiedInternalDBus.cmd.write

// this makes sure that once we assert a command, it stays on the bus until it's acknowledged
private val cmdBuffer = Reg(Flow(MemBusCmd(config.dbusConfig)))
private val currentlySendingIndex = Reg(Flow(UInt(config.dbusConfig.idWidth bits)))

private var context = when(cmdBuffer.valid) {
unifiedInternalDBus.cmd.payload := cmdBuffer.payload
unifiedInternalDBus.cmd.valid := True
when(unifiedInternalDBus.cmd.ready) {
currentlySendingIndex.setIdle()
cmdBuffer.setIdle()
when(!cmdBuffer.write) {
busId2StageIndex(nextId).stageIndex := currentlySendingIndex.payload
when(!sameCycleReturn) {
busId2StageIndex(nextId).cmdSent := True
}
busId2StageIndex(nextId).rspReceived := False
currentlyInserting.valid := True
currentlyInserting.payload.stageIndex := currentlySendingIndex.payload
}
nextId.increment()
}
}

cmds.zipWithIndex.foreach { case (cmd, index) =>
context =
context.elsewhen(cmd.valid && ((!busId2StageIndex(nextId).cmdSent) || cmd.write)) {
Expand All @@ -139,18 +160,25 @@ class DynamicMemoryBackbone(stageCount: Int)(implicit config: Config)
unifiedInternalDBus.cmd.write := cmd.write
unifiedInternalDBus.cmd.wdata := cmd.wdata
unifiedInternalDBus.cmd.wmask := cmd.wmask
when(!cmd.write) {
busId2StageIndex(nextId).invalidated := activeFlush
}
when(unifiedInternalDBus.cmd.ready) {
currentlySendingIndex.setIdle()
cmdBuffer.setIdle()
when(!cmd.write) {
nextId.increment()
busId2StageIndex(nextId).stageIndex := U(index).resized
when(!sameCycleReturn) {
busId2StageIndex(nextId).cmdSent := True
}
busId2StageIndex(nextId).rspReceived := False
busId2StageIndex(nextId).invalidated := activeFlush
currentlyInserting.valid := True
currentlyInserting.payload.stageIndex := index
}
nextId.increment()
} otherwise {
cmdBuffer.push(unifiedInternalDBus.cmd)
currentlySendingIndex.push(index)
}
}
}
Expand Down

0 comments on commit 5928d76

Please sign in to comment.