54 lines
1.6 KiB
Plaintext
54 lines
1.6 KiB
Plaintext
class PcManagerSimple(resetVector : BigInt,pcWidth : Int,fastFetchCmdPcCalculation : Boolean) extends Plugin[SpinalRiscv] with PcManagerService{
|
|
import StandardStageables._
|
|
|
|
//FetchService interface
|
|
case class JumpInfo(pc: UInt, cond: Bool, stage: Stage)
|
|
val jumpInfos = ArrayBuffer[JumpInfo]()
|
|
override def jumpTo(pc: UInt, cond: Bool, stage: Stage): Unit = jumpInfos += JumpInfo(pc,cond,stage)
|
|
|
|
override def build(pipeline: SpinalRiscv): Unit = {
|
|
import pipeline.prefetch
|
|
|
|
prefetch.plug(new Area {
|
|
import prefetch._
|
|
|
|
//PC calculation without Jump
|
|
val pcReg = Reg(UInt(pcWidth bit)) init(resetVector)
|
|
val inc = RegInit(False)
|
|
val pc = if(fastFetchCmdPcCalculation){
|
|
val pcPlus4 = pcReg + 4
|
|
pcPlus4.addAttribute("keep")
|
|
Mux(inc,pcPlus4,pcReg)
|
|
}else{
|
|
pcReg + (inc ? U(4) | U(0))
|
|
}
|
|
|
|
//Stage always valid
|
|
arbitration.isValid := True
|
|
|
|
//FetchService hardware implementation
|
|
val jumpInfoSorted = jumpInfos.sortWith((a,b) => pipeline.indexOf(a.stage) > pipeline.indexOf(b.stage))
|
|
val jumpRequestValids = jumpInfoSorted.map(_.cond)
|
|
val jumpRequestPcs = jumpInfoSorted.map(_.pc)
|
|
|
|
val pcLoad = Flow(pcReg)
|
|
pcLoad.valid := jumpInfos.foldLeft(False)(_ || _.cond)
|
|
pcLoad.payload := MuxOH(jumpRequestValids,jumpRequestPcs)
|
|
|
|
//Register managments
|
|
when(pcLoad.valid){
|
|
pc := pcLoad.payload
|
|
inc := False
|
|
pcReg := pc
|
|
}
|
|
|
|
when(arbitration.isFiring){
|
|
inc := True
|
|
pcReg := pc
|
|
}
|
|
|
|
//Pipeline insertions
|
|
insert(PC) := pc
|
|
})
|
|
}
|
|
} |