VexRiscv/backup

54 lines
1.6 KiB
Plaintext
Raw Normal View History

2017-03-08 16:17:48 -05:00
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
})
}
}