parent
51058f851e
commit
787682d4f6
|
@ -6,7 +6,7 @@ import spinal.core._
|
|||
import spinal.lib._
|
||||
|
||||
trait BranchPrediction
|
||||
object DISABLE extends BranchPrediction
|
||||
object NONE extends BranchPrediction
|
||||
object STATIC extends BranchPrediction
|
||||
object DYNAMIC extends BranchPrediction
|
||||
|
||||
|
@ -58,13 +58,13 @@ class BranchPlugin(earlyBranch : Boolean,prediction : BranchPrediction,historyRa
|
|||
BGEU -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B, SRC_LESS_UNSIGNED -> True))
|
||||
))
|
||||
|
||||
val pcManagerService = pipeline.service(classOf[PcManagerService])
|
||||
val pcManagerService = pipeline.service(classOf[JumpService])
|
||||
jumpInterface = pcManagerService.createJumpInterface(pipeline.execute)
|
||||
if(prediction != DISABLE) predictionJumpInterface = pcManagerService.createJumpInterface(pipeline.decode)
|
||||
if(prediction != NONE) predictionJumpInterface = pcManagerService.createJumpInterface(pipeline.decode)
|
||||
}
|
||||
|
||||
override def build(pipeline: VexRiscv): Unit = prediction match {
|
||||
case `DISABLE` => buildWithoutPrediction(pipeline)
|
||||
case NONE => buildWithoutPrediction(pipeline)
|
||||
case `STATIC` => buildWithPrediction(pipeline)
|
||||
case `DYNAMIC` => buildWithPrediction(pipeline)
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ class BranchPlugin(earlyBranch : Boolean,prediction : BranchPrediction,historyRa
|
|||
import pipeline._
|
||||
import pipeline.config._
|
||||
|
||||
//Do branch calculations (conditions + target PC)
|
||||
execute plug new Area {
|
||||
import execute._
|
||||
|
||||
|
@ -101,6 +102,7 @@ class BranchPlugin(earlyBranch : Boolean,prediction : BranchPrediction,historyRa
|
|||
insert(BRANCH_CALC) := branch_src1 + branch_src2
|
||||
}
|
||||
|
||||
//Apply branchs (JAL,JALR, Bxx)
|
||||
val branchStage = if(earlyBranch) execute else memory
|
||||
branchStage plug new Area {
|
||||
import branchStage._
|
||||
|
@ -140,7 +142,8 @@ class BranchPlugin(earlyBranch : Boolean,prediction : BranchPrediction,historyRa
|
|||
fetch.insert(HISTORY_LINE) := writePortReg.data
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Branch JAL, predict Bxx and branch it
|
||||
decode plug new Area{
|
||||
import decode._
|
||||
val imm = IMM(input(INSTRUCTION))
|
||||
|
@ -158,6 +161,7 @@ class BranchPlugin(earlyBranch : Boolean,prediction : BranchPrediction,historyRa
|
|||
}
|
||||
}
|
||||
|
||||
//Do real branch calculation
|
||||
execute plug new Area {
|
||||
import execute._
|
||||
|
||||
|
@ -194,9 +198,9 @@ class BranchPlugin(earlyBranch : Boolean,prediction : BranchPrediction,historyRa
|
|||
insert(BRANCH_CALC) := branch_src1 + branch_src2
|
||||
}
|
||||
|
||||
val branchStage = if(earlyBranch) execute else memory
|
||||
|
||||
// Apply branch corrections
|
||||
// branch JALR or JAL/Bxx prediction miss corrections
|
||||
val branchStage = if(earlyBranch) execute else memory
|
||||
branchStage plug new Area {
|
||||
import branchStage._
|
||||
jumpInterface.valid := input(BRANCH_DO) && arbitration.isFiring
|
||||
|
|
|
@ -75,6 +75,7 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{
|
|||
import pipeline._
|
||||
import pipeline.config._
|
||||
|
||||
//Emit dCmd request
|
||||
execute plug new Area{
|
||||
import execute._
|
||||
|
||||
|
@ -95,6 +96,7 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{
|
|||
insert(MEMORY_ADDRESS_LOW) := dCmd.address(1 downto 0)
|
||||
}
|
||||
|
||||
//Collect dRsp read responses
|
||||
memory plug new Area {
|
||||
import memory._
|
||||
|
||||
|
@ -103,6 +105,7 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{
|
|||
assert(!(input(MEMORY_ENABLE) && (!input(INSTRUCTION)(5)) && arbitration.isStuck),"DBusSimplePlugin doesn't allow memory stage stall when read happend")
|
||||
}
|
||||
|
||||
//Reformat read responses, REGFILE_WRITE_DATA overriding
|
||||
writeBack plug new Area {
|
||||
import writeBack._
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ class DivPlugin extends Plugin[VexRiscv]{
|
|||
|
||||
val divider = new MixedDivider(32, 32, true) //cmd >-> rsp
|
||||
|
||||
//Send request to the divider component
|
||||
execute plug new Area {
|
||||
import execute._
|
||||
|
||||
|
@ -51,6 +52,7 @@ class DivPlugin extends Plugin[VexRiscv]{
|
|||
}
|
||||
}
|
||||
|
||||
//Collect response from the divider component, REGFILE_WRITE_DATA overriding
|
||||
memory plug new Area{
|
||||
import memory._
|
||||
|
||||
|
|
|
@ -21,12 +21,14 @@ class IBusSimplePlugin(interfaceKeepData : Boolean) extends Plugin[VexRiscv]{
|
|||
import pipeline._
|
||||
import pipeline.config._
|
||||
|
||||
//Emit iCmd request
|
||||
require(interfaceKeepData)
|
||||
iCmd = master(Stream(IBusSimpleCmd())).setName("iCmd")
|
||||
iCmd.valid := prefetch.arbitration.isValid && !prefetch.arbitration.isStuckByOthers
|
||||
iCmd.pc := prefetch.output(PC)
|
||||
prefetch.arbitration.haltIt setWhen(!iCmd.ready)
|
||||
|
||||
//Insert iRsp into INSTRUCTION
|
||||
iRsp = in(IBusSimpleRsp()).setName("iRsp")
|
||||
fetch.insert(INSTRUCTION) := iRsp.inst
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ class MulPlugin extends Plugin[VexRiscv]{
|
|||
import pipeline.config._
|
||||
|
||||
|
||||
|
||||
//Do partial multiplication, four times 16 bits * 16 bits
|
||||
execute plug new Area {
|
||||
import execute._
|
||||
val aSigned,bSigned = Bool
|
||||
|
@ -78,12 +78,13 @@ class MulPlugin extends Plugin[VexRiscv]{
|
|||
insert(MUL_HH) := aHigh * bHigh
|
||||
}
|
||||
|
||||
|
||||
//First aggregation of partial multiplication
|
||||
memory plug new Area {
|
||||
import memory._
|
||||
insert(MUL_LOW) := S(0, MUL_HL.dataType.getWidth + 16 + 2 bit) + (False ## input(MUL_LL)).asSInt + (input(MUL_LH) << 16) + (input(MUL_HL) << 16)
|
||||
}
|
||||
|
||||
//Final aggregation of partial multiplications, REGFILE_WRITE_DATA overriding
|
||||
writeBack plug new Area {
|
||||
import writeBack._
|
||||
val result = input(MUL_LOW) + (input(MUL_HH) << 32)
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package SpinalRiscv.Plugin
|
||||
|
||||
import SpinalRiscv.{PcManagerService, Stage, VexRiscv}
|
||||
import SpinalRiscv.{JumpService, Stage, VexRiscv}
|
||||
import spinal.core._
|
||||
import spinal.lib._
|
||||
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
|
||||
class PcManagerSimplePlugin(resetVector : BigInt,fastPcCalculation : Boolean) extends Plugin[VexRiscv] with PcManagerService{
|
||||
class PcManagerSimplePlugin(resetVector : BigInt,fastPcCalculation : Boolean) extends Plugin[VexRiscv] with JumpService{
|
||||
|
||||
|
||||
//FetchService interface
|
||||
|
@ -29,19 +29,19 @@ class PcManagerSimplePlugin(resetVector : BigInt,fastPcCalculation : Boolean) ex
|
|||
arbitration.isValid := True
|
||||
|
||||
//PC calculation without Jump
|
||||
val pc = Reg(UInt(pcWidth bits)) init(resetVector) addAttribute("verilator public")
|
||||
val pcReg = Reg(UInt(pcWidth bits)) init(resetVector) addAttribute("verilator public")
|
||||
val inc = RegInit(False)
|
||||
val pcNext = if(fastPcCalculation){
|
||||
val pcPlus4 = pc + U(4)
|
||||
val pc = if(fastPcCalculation){
|
||||
val pcPlus4 = pcReg + U(4)
|
||||
pcPlus4.addAttribute("keep")
|
||||
Mux(inc,pcPlus4,pc)
|
||||
Mux(inc,pcPlus4,pcReg)
|
||||
}else{
|
||||
pc + Mux(inc,U(4),U(0))
|
||||
pcReg + Mux[UInt](inc,4,0)
|
||||
}
|
||||
|
||||
val samplePcNext = False
|
||||
|
||||
//FetchService hardware implementation
|
||||
//JumpService hardware implementation
|
||||
val jump = if(jumpInfos.length != 0) new Area {
|
||||
val sortedByStage = jumpInfos.sortWith((a, b) => pipeline.indexOf(a.stage) > pipeline.indexOf(b.stage))
|
||||
val valids = sortedByStage.map(_.interface.valid)
|
||||
|
@ -51,11 +51,11 @@ class PcManagerSimplePlugin(resetVector : BigInt,fastPcCalculation : Boolean) ex
|
|||
pcLoad.valid := jumpInfos.foldLeft(False)(_ || _.interface.valid)
|
||||
pcLoad.payload := MuxOH(valids, pcs)
|
||||
|
||||
//Register managments
|
||||
//application of the selected jump request
|
||||
when(pcLoad.valid) {
|
||||
inc := False
|
||||
samplePcNext := True
|
||||
pcNext := pcLoad.payload
|
||||
pc := pcLoad.payload
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,10 +64,9 @@ class PcManagerSimplePlugin(resetVector : BigInt,fastPcCalculation : Boolean) ex
|
|||
samplePcNext := True
|
||||
}
|
||||
|
||||
when(samplePcNext) { pc := pcNext }
|
||||
when(samplePcNext) { pcReg := pc }
|
||||
|
||||
//Pipeline insertions
|
||||
insert(PC) := pcNext
|
||||
insert(PC) := pc
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,6 +27,7 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind) extends Plugin[VexRiscv]
|
|||
val regFile = Mem(Bits(32 bits),32) addAttribute("verilator public")
|
||||
}
|
||||
|
||||
//Read register file
|
||||
decode plug new Area{
|
||||
import decode._
|
||||
|
||||
|
@ -35,9 +36,6 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind) extends Plugin[VexRiscv]
|
|||
decode.input(REGFILE_WRITE_VALID) := False
|
||||
}
|
||||
|
||||
val rs1 = input(INSTRUCTION)(Riscv.rs1Range).asUInt
|
||||
val rs2 = input(INSTRUCTION)(Riscv.rs2Range).asUInt
|
||||
|
||||
//read register file
|
||||
val srcInstruction = regFileReadyKind match{
|
||||
case `ASYNC` => input(INSTRUCTION)
|
||||
|
@ -56,6 +54,7 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind) extends Plugin[VexRiscv]
|
|||
insert(REG2) := rs2Data
|
||||
}
|
||||
|
||||
//Write register file
|
||||
writeBack plug new Area {
|
||||
import writeBack._
|
||||
|
||||
|
@ -64,7 +63,7 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind) extends Plugin[VexRiscv]
|
|||
regFileWrite.address := input(INSTRUCTION)(rdRange).asUInt
|
||||
regFileWrite.data := input(REGFILE_WRITE_DATA)
|
||||
|
||||
//CPU will write constant register zero in the first cycle
|
||||
//CPU will initialise constant register zero in the first cycle
|
||||
regFileWrite.valid setWhen(RegNext(False) init(True))
|
||||
inputInit[Bits](REGFILE_WRITE_DATA, 0)
|
||||
inputInit[Bits](INSTRUCTION, 0)
|
||||
|
|
|
@ -3,7 +3,7 @@ package SpinalRiscv
|
|||
import spinal.core._
|
||||
import spinal.lib._
|
||||
|
||||
trait PcManagerService{
|
||||
trait JumpService{
|
||||
def createJumpInterface(stage : Stage) : Flow[UInt]
|
||||
}
|
||||
|
||||
|
|
|
@ -64,25 +64,4 @@ class Stage() extends Area{
|
|||
|
||||
def inputInit[T <: BaseType](stageable : Stageable[T],initValue : T) =
|
||||
Component.current.addPrePopTask(() => inputsDefault(stageable.asInstanceOf[Stageable[Data]]).asInstanceOf[T].getDrivingReg.init(initValue))
|
||||
}
|
||||
|
||||
|
||||
//object StageMain{
|
||||
//
|
||||
// object OpEnum extends SpinalEnum{
|
||||
// val AND,OR = newElement()
|
||||
// }
|
||||
// object OP extends Stageable(OpEnum())
|
||||
// object SRC1 extends Stageable(Bits(32 bits))
|
||||
// object SRC2 extends Stageable(Bits(32 bits))
|
||||
// object RESULT extends Stageable(Bits(32 bits))
|
||||
// def main(args: Array[String]) {
|
||||
// val E = List.fill(2)(new Stage(9))
|
||||
// val E0 = E(0)
|
||||
// import E0._
|
||||
// output(RESULT) := E(0).input(OP).mux(
|
||||
// OpEnum.AND -> (E(0).input(SRC1) & E(0).input(SRC2)),
|
||||
// OpEnum.OR -> (E(0).input(SRC1) | E(0).input(SRC2))
|
||||
// )
|
||||
// }
|
||||
//}
|
||||
}
|
|
@ -358,7 +358,7 @@ public:
|
|||
}
|
||||
|
||||
virtual void postReset() {
|
||||
top->VexRiscv->prefetch_PcManagerSimplePlugin_pc = 0x800000bcu;
|
||||
top->VexRiscv->prefetch_PcManagerSimplePlugin_pcReg = 0x800000bcu;
|
||||
}
|
||||
|
||||
virtual void checks(){
|
||||
|
|
Loading…
Reference in New Issue