diff --git a/src/main/scala/SpinalRiscv/Plugin/BranchPlugin.scala b/src/main/scala/SpinalRiscv/Plugin/BranchPlugin.scala index 2ae4fd7..40a453e 100644 --- a/src/main/scala/SpinalRiscv/Plugin/BranchPlugin.scala +++ b/src/main/scala/SpinalRiscv/Plugin/BranchPlugin.scala @@ -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 diff --git a/src/main/scala/SpinalRiscv/Plugin/DBusSimplePlugin.scala b/src/main/scala/SpinalRiscv/Plugin/DBusSimplePlugin.scala index 459dec0..4e2fa70 100644 --- a/src/main/scala/SpinalRiscv/Plugin/DBusSimplePlugin.scala +++ b/src/main/scala/SpinalRiscv/Plugin/DBusSimplePlugin.scala @@ -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._ diff --git a/src/main/scala/SpinalRiscv/Plugin/DivPlugin.scala b/src/main/scala/SpinalRiscv/Plugin/DivPlugin.scala index dd54826..07d1115 100644 --- a/src/main/scala/SpinalRiscv/Plugin/DivPlugin.scala +++ b/src/main/scala/SpinalRiscv/Plugin/DivPlugin.scala @@ -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._ diff --git a/src/main/scala/SpinalRiscv/Plugin/IBusSimplePlugin.scala b/src/main/scala/SpinalRiscv/Plugin/IBusSimplePlugin.scala index 3eb8fa8..999f8ff 100644 --- a/src/main/scala/SpinalRiscv/Plugin/IBusSimplePlugin.scala +++ b/src/main/scala/SpinalRiscv/Plugin/IBusSimplePlugin.scala @@ -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 } diff --git a/src/main/scala/SpinalRiscv/Plugin/MulPlugin.scala b/src/main/scala/SpinalRiscv/Plugin/MulPlugin.scala index 98b66ef..5ca085d 100644 --- a/src/main/scala/SpinalRiscv/Plugin/MulPlugin.scala +++ b/src/main/scala/SpinalRiscv/Plugin/MulPlugin.scala @@ -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) diff --git a/src/main/scala/SpinalRiscv/Plugin/PcManagerSimplePlugin.scala b/src/main/scala/SpinalRiscv/Plugin/PcManagerSimplePlugin.scala index d8735bc..f586538 100644 --- a/src/main/scala/SpinalRiscv/Plugin/PcManagerSimplePlugin.scala +++ b/src/main/scala/SpinalRiscv/Plugin/PcManagerSimplePlugin.scala @@ -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 } } } \ No newline at end of file diff --git a/src/main/scala/SpinalRiscv/Plugin/RegFilePlugin.scala b/src/main/scala/SpinalRiscv/Plugin/RegFilePlugin.scala index 30fa2d9..0b1ffd8 100644 --- a/src/main/scala/SpinalRiscv/Plugin/RegFilePlugin.scala +++ b/src/main/scala/SpinalRiscv/Plugin/RegFilePlugin.scala @@ -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) diff --git a/src/main/scala/SpinalRiscv/Services.scala b/src/main/scala/SpinalRiscv/Services.scala index 5339d9d..f552b48 100644 --- a/src/main/scala/SpinalRiscv/Services.scala +++ b/src/main/scala/SpinalRiscv/Services.scala @@ -3,7 +3,7 @@ package SpinalRiscv import spinal.core._ import spinal.lib._ -trait PcManagerService{ +trait JumpService{ def createJumpInterface(stage : Stage) : Flow[UInt] } diff --git a/src/main/scala/SpinalRiscv/Stage.scala b/src/main/scala/SpinalRiscv/Stage.scala index a0f1ab3..07f5121 100644 --- a/src/main/scala/SpinalRiscv/Stage.scala +++ b/src/main/scala/SpinalRiscv/Stage.scala @@ -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)) -// ) -// } -//} +} \ No newline at end of file diff --git a/src/test/cpp/testA/main.cpp b/src/test/cpp/testA/main.cpp index d596dcb..64cdc80 100644 --- a/src/test/cpp/testA/main.cpp +++ b/src/test/cpp/testA/main.cpp @@ -358,7 +358,7 @@ public: } virtual void postReset() { - top->VexRiscv->prefetch_PcManagerSimplePlugin_pc = 0x800000bcu; + top->VexRiscv->prefetch_PcManagerSimplePlugin_pcReg = 0x800000bcu; } virtual void checks(){