Skip to content

Commit

Permalink
schedule comments ++
Browse files Browse the repository at this point in the history
  • Loading branch information
Dolu1990 committed Jan 15, 2025
1 parent eff2821 commit dfaaa79
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 45 deletions.
6 changes: 0 additions & 6 deletions src/main/scala/vexiiriscv/schedule/Dispatch.scala

This file was deleted.

34 changes: 18 additions & 16 deletions src/main/scala/vexiiriscv/schedule/DispatchPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,24 @@ import vexiiriscv.riscv.{MicroOp, RD, RegfileSpec, RfAccess, RfRead, RfResource}
import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer

/*
How to check if a instruction can schedule :
- If one of the pipeline which implement its micro op is free
- There is no inflight non-bypassed RF write to one of the source operand
- There is no scheduling fence
- For credit based execution, check there is enough credit
Schedule euristic :
- In priority order, go through the slots
- Check which pipeline could schedule it (free && compatible)
- Select the pipeline which the highest priority (to avoid using the one which can do load and store, for instance)
- If the slot can't be schedule, disable all following ones with same HART_ID
*/
/**
* The role of the dispatch plugin is to :
* - Collect the instruction exiting the decode pipeline,
* - Figuring out on which execution lane they could be scheduled (checking for dependencies). If none, then wait for some.
* - Issue instructions on execution lanes
*
* How to check if a instruction can schedule :
* - If one of the pipeline which implement its micro op is free
* - There is no inflight non-bypassed RF write to one of the source operand
* - There is no scheduling fence
* - ...
*
* Schedule heuristic :
* - In priority order, go through the slots
* - Check which pipeline could schedule it (free && compatible)
* - Select the pipeline which the highest priority (to avoid using the one which can do load and store, for instance)
* - If the slot can't be schedule, disable all following ones with same HART_ID
*/

class DispatchPlugin(var dispatchAt : Int,
var trapLayer : LaneLayer,
Expand All @@ -43,10 +48,7 @@ class DispatchPlugin(var dispatchAt : Int,


val hmKeys = mutable.LinkedHashSet[Payload[_ <: Data]]()

// val fenceYoungerOps = mutable.LinkedHashSet[MicroOp]()
val fenceOlderOps = mutable.LinkedHashSet[MicroOp]()
// def fenceYounger(op : MicroOp) = fenceYoungerOps += op
def fenceOlder(op : MicroOp) = fenceOlderOps += op
def haltDispatchWhen(cond : Bool) = api.haltDispatch.setWhen(cond)

Expand Down
13 changes: 5 additions & 8 deletions src/main/scala/vexiiriscv/schedule/ReschedulePlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,19 @@ import vexiiriscv.misc.PipelineBuilderPlugin
import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer

/**
* The ReschedulePlugin act as a arbiter for all the different plugins which want to reschedule what the CPU should execute,
* aswell as a registry for all the plugins which need to know if the CPU is being flushed until a given point in the pipeline.
*
*/
class ReschedulePlugin extends FiberPlugin with ScheduleService {
val flushPortsShared = mutable.LinkedHashMap[Nameable, Flow[FlushCmd]]()
val flushPorts = ArrayBuffer[Flow[FlushCmd]]()
val trapPorts = ArrayBuffer[Flow[TrapCmd]]()
val ctrls = ArrayBuffer[CtrlSpec]()

case class CtrlSpec(ctrl : CtrlLink)

// override def newPcPort(age: Int, aggregationPriority: Int = 0) = host[PcService].createJumpInterface(age, aggregationPriority)
override def newFlushPort(age: Int, laneAgeWidth : Int, withUopId : Boolean) = flushPorts.addRet(Flow(FlushCmd(age, laneAgeWidth, withUopId)))
// override def sharedFlushPort(age: Int, laneAgeWidth: Int, withUopId: Boolean, key : Nameable) = {
// flushPortsShared.getOrElseUpdate(key, {
// newFlushPort(age, laneAgeWidth, withUopId).setCompositeName(key, "flushPort")
// })
// }
override def newTrapPort(age : Int, causeWidth : Int = 4) = trapPorts.addRet(Flow(TrapCmd(age, Global.PC_WIDTH, Global.TVAL_WIDTH, causeWidth, Global.TRAP_ARG_WIDTH)))
override def isFlushedAt(age: Int, hartId: UInt, laneAge : UInt): Option[Bool] = {
elaborationLock.await()
val filtred = flushPorts.filter(p => p.age >= age)
Expand Down
22 changes: 7 additions & 15 deletions src/main/scala/vexiiriscv/schedule/Service.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import vexiiriscv.decode.Decode
import vexiiriscv.execute.Execute
import vexiiriscv.fetch.JumpCmd

/**
* This contains the integer constant which allows to compute identifier for a given point in the pipeline.
* This id can then be used with the ReschedulePlugin to querry/register flushes
*/
object Ages {
val STAGE = 10
val NOT_PREDICTION = 1
Expand All @@ -20,26 +24,14 @@ object Ages {

case class FlushCmd(age : Int, laneAgeWidth : Int, withUopId : Boolean) extends Bundle{
val hartId = Global.HART_ID()
val uopId = withUopId generate Decode.UOP_ID()
val laneAge = UInt(laneAgeWidth bits)
val self = Bool()
}

case class TrapCmd(age : Int, pcWidth : Int, tvalWidth : Int, causeWidth : Int, trapArgWidth : Int) extends Bundle {
val cause = UInt(causeWidth bits)
val tval = Bits(tvalWidth bits)
val arg = Bits(trapArgWidth bits)
val skipCommit = Bool() //Want to skip commit for exceptions, but not for [jump, ebreak, redo]
val uopId = withUopId generate Decode.UOP_ID() //Used for debugging/tracking
val laneAge = UInt(laneAgeWidth bits) //Used to know the order between lanes of the same pipeline (decode/execute lanes)
val self = Bool() //True if the flush source is killing itself
}

trait ScheduleService {
def newFlushPort(age: Int, laneAgeWidth: Int, withUopId: Boolean): Flow[FlushCmd]
// def sharedFlushPort(age: Int, laneAgeWidth: Int, withUopId: Boolean, key : Nameable): Flow[FlushCmd]
// def newPcPort(age : Int, aggregationPriority : Int = 0) : Flow[JumpCmd]
def newTrapPort(age : Int, causeWidth : Int = 4) : Flow[TrapCmd]
def isFlushedAt(age: Int, hartId : UInt, laneAge : UInt): Option[Bool]
// def addCtrl(age : Int, ctrl : CtrlLink) : Unit

val elaborationLock = Retainer()
}

Expand Down

0 comments on commit dfaaa79

Please sign in to comment.