parent
704423f27f
commit
925edd160e
|
@ -16,6 +16,7 @@ trait IBusFetcher{
|
|||
def incoming() : Bool
|
||||
def pcValid(stage : Stage) : Bool
|
||||
def getInjectionPort() : Stream[Bits]
|
||||
def withRvc() : Boolean
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -37,6 +37,21 @@ case class VexRiscvConfig(){
|
|||
}
|
||||
}
|
||||
|
||||
def withRvc = plugins.find(_.isInstanceOf[IBusFetcher]) match {
|
||||
case Some(x) => x.asInstanceOf[IBusFetcher].withRvc
|
||||
case None => false
|
||||
}
|
||||
|
||||
def withRvf = find(classOf[FpuPlugin]) match {
|
||||
case Some(x) => true
|
||||
case None => false
|
||||
}
|
||||
|
||||
def withRvd = find(classOf[FpuPlugin]) match {
|
||||
case Some(x) => x.p.withDouble
|
||||
case None => false
|
||||
}
|
||||
|
||||
//Default Stageables
|
||||
object IS_RVC extends Stageable(Bool)
|
||||
object BYPASSABLE_EXECUTE_STAGE extends Stageable(Bool)
|
||||
|
@ -103,7 +118,7 @@ case class VexRiscvConfig(){
|
|||
|
||||
|
||||
|
||||
object RVC_GEN extends PipelineThing[Boolean]
|
||||
|
||||
class VexRiscv(val config : VexRiscvConfig) extends Component with Pipeline{
|
||||
type T = VexRiscv
|
||||
import config._
|
||||
|
@ -131,8 +146,6 @@ class VexRiscv(val config : VexRiscvConfig) extends Component with Pipeline{
|
|||
memory.arbitration.removeIt.noBackendCombMerge
|
||||
}
|
||||
execute.arbitration.flushNext.noBackendCombMerge
|
||||
|
||||
this(RVC_GEN) = false
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -181,7 +181,8 @@ object VexRiscvSmpClusterGen {
|
|||
withDouble : Boolean = false,
|
||||
externalFpu : Boolean = true,
|
||||
simHalt : Boolean = false,
|
||||
regfileRead : RegFileReadKind = plugin.ASYNC
|
||||
regfileRead : RegFileReadKind = plugin.ASYNC,
|
||||
rvc : Boolean = false
|
||||
) = {
|
||||
assert(iCacheSize/iCacheWays <= 4096, "Instruction cache ways can't be bigger than 4096 bytes")
|
||||
assert(dCacheSize/dCacheWays <= 4096, "Data cache ways can't be bigger than 4096 bytes")
|
||||
|
@ -197,7 +198,7 @@ object VexRiscvSmpClusterGen {
|
|||
//Uncomment the whole IBusCachedPlugin and comment IBusSimplePlugin if you want cached iBus config
|
||||
new IBusCachedPlugin(
|
||||
resetVector = resetVector,
|
||||
compressedGen = false,
|
||||
compressedGen = rvc,
|
||||
prediction = vexriscv.plugin.NONE,
|
||||
historyRamSizeLog2 = 9,
|
||||
relaxPredictorAddress = true,
|
||||
|
|
|
@ -57,7 +57,7 @@ class BranchPlugin(earlyBranch : Boolean,
|
|||
decodeBranchSrc2 : Boolean = false) extends Plugin[VexRiscv] with PredictionInterface{
|
||||
|
||||
|
||||
def catchAddressMisalignedForReal = catchAddressMisaligned && !pipeline(RVC_GEN)
|
||||
def catchAddressMisalignedForReal = catchAddressMisaligned && !pipeline.config.withRvc
|
||||
lazy val branchStage = if(earlyBranch) pipeline.execute else pipeline.memory
|
||||
|
||||
object BRANCH_CALC extends Stageable(UInt(32 bits))
|
||||
|
@ -114,7 +114,6 @@ class BranchPlugin(earlyBranch : Boolean,
|
|||
|
||||
|
||||
decoderService.addDefault(BRANCH_CTRL, BranchCtrlEnum.INC)
|
||||
val rvc = pipeline(RVC_GEN)
|
||||
decoderService.add(List(
|
||||
JAL(true) -> (jActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.JAL, ALU_CTRL -> AluCtrlEnum.ADD_SUB)),
|
||||
JALR -> (jActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.JALR, ALU_CTRL -> AluCtrlEnum.ADD_SUB, RS1_USE -> True)),
|
||||
|
@ -252,7 +251,7 @@ class BranchPlugin(earlyBranch : Boolean,
|
|||
)
|
||||
|
||||
val imm = IMM(input(INSTRUCTION))
|
||||
val missAlignedTarget = if(pipeline(RVC_GEN)) False else (input(BRANCH_COND_RESULT) && input(BRANCH_CTRL).mux(
|
||||
val missAlignedTarget = if(pipeline.config.withRvc) False else (input(BRANCH_COND_RESULT) && input(BRANCH_CTRL).mux(
|
||||
BranchCtrlEnum.JALR -> (imm.i_sext(1) ^ input(RS1)(1)),
|
||||
BranchCtrlEnum.JAL -> imm.j_sext(1),
|
||||
default -> imm.b_sext(1)
|
||||
|
@ -271,7 +270,7 @@ class BranchPlugin(earlyBranch : Boolean,
|
|||
branch_src1 := input(PC)
|
||||
branch_src2 := ((input(BRANCH_CTRL) === BranchCtrlEnum.JAL) ? imm.j_sext | imm.b_sext).asUInt
|
||||
when(input(PREDICTION_HAD_BRANCHED)){ //Assume the predictor never predict missaligned stuff, this avoid the need to know if the instruction should branch or not
|
||||
branch_src2 := (if(pipeline(RVC_GEN)) Mux(input(IS_RVC), B(2), B(4)) else B(4)).asUInt.resized
|
||||
branch_src2 := (if(pipeline.config.withRvc) Mux(input(IS_RVC), B(2), B(4)) else B(4)).asUInt.resized
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -344,7 +343,7 @@ class BranchPlugin(earlyBranch : Boolean,
|
|||
|
||||
val branchAdder = branch_src1 + input(BRANCH_SRC2)
|
||||
insert(BRANCH_CALC) := branchAdder(31 downto 1) @@ U"0"
|
||||
insert(NEXT_PC) := input(PC) + (if(pipeline(RVC_GEN)) ((input(IS_RVC)) ? U(2) | U(4)) else 4)
|
||||
insert(NEXT_PC) := input(PC) + (if(pipeline.config.withRvc) ((input(IS_RVC)) ? U(2) | U(4)) else 4)
|
||||
insert(TARGET_MISSMATCH) := decode.input(PC) =/= input(BRANCH_CALC)
|
||||
}
|
||||
|
||||
|
@ -357,7 +356,7 @@ class BranchPlugin(earlyBranch : Boolean,
|
|||
fetchPrediction.rsp.wasRight := ! predictionMissmatch
|
||||
fetchPrediction.rsp.finalPc := input(BRANCH_CALC)
|
||||
fetchPrediction.rsp.sourceLastWord := {
|
||||
if(pipeline(RVC_GEN))
|
||||
if(pipeline.config.withRvc)
|
||||
((!input(IS_RVC) && input(PC)(1)) ? input(NEXT_PC) | input(PC))
|
||||
else
|
||||
input(PC)
|
||||
|
|
|
@ -304,7 +304,7 @@ class DebugPlugin(var debugClockDomain : ClockDomain, hardwareBreakpointCount :
|
|||
}
|
||||
|
||||
//Avoid having two C instruction executed in a single step
|
||||
if(pipeline(RVC_GEN)){
|
||||
if(pipeline.config.withRvc){
|
||||
val cleanStep = RegNext(stepIt && decode.arbitration.isFiring) init(False)
|
||||
execute.arbitration.flushNext setWhen(cleanStep)
|
||||
}
|
||||
|
|
|
@ -38,6 +38,9 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
|
|||
var incomingInstruction : Bool = null
|
||||
override def incoming() = incomingInstruction
|
||||
|
||||
|
||||
override def withRvc(): Boolean = compressedGen
|
||||
|
||||
var injectionPort : Stream[Bits] = null
|
||||
override def getInjectionPort() = {
|
||||
injectionPort = Stream(Bits(32 bits))
|
||||
|
@ -63,8 +66,6 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
|
|||
incomingInstruction = False
|
||||
if(resetVector == null) externalResetVector = in(UInt(32 bits).setName("externalResetVector"))
|
||||
|
||||
pipeline(RVC_GEN) = compressedGen
|
||||
|
||||
prediction match {
|
||||
case NONE =>
|
||||
case STATIC | DYNAMIC => {
|
||||
|
@ -261,7 +262,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
|
|||
whenFalse = input.rsp.inst(31 downto 16) ## (throw2Bytes ? input.rsp.inst(31 downto 16) | input.rsp.inst(15 downto 0))
|
||||
)
|
||||
val isRvc = raw(1 downto 0) =/= 3
|
||||
val decompressed = RvcDecompressor(raw(15 downto 0))
|
||||
val decompressed = RvcDecompressor(raw(15 downto 0), pipeline.config.withRvf, pipeline.config.withRvd)
|
||||
output.valid := input.valid && !(throw2Bytes && !bufferValid && !isInputHighRvc)
|
||||
output.pc := input.pc
|
||||
output.isRvc := isRvc
|
||||
|
@ -467,7 +468,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
|
|||
val branchContext = branchStage.input(PREDICTION_CONTEXT)
|
||||
val moreJump = decodePrediction.rsp.wasWrong ^ branchContext.line.history.msb
|
||||
|
||||
historyWrite.address := branchStage.input(PC)(2, historyRamSizeLog2 bits) + (if(pipeline(RVC_GEN))
|
||||
historyWrite.address := branchStage.input(PC)(2, historyRamSizeLog2 bits) + (if(pipeline.config.withRvc)
|
||||
((!branchStage.input(IS_RVC) && branchStage.input(PC)(1)) ? U(1) | U(0))
|
||||
else
|
||||
U(0))
|
||||
|
@ -487,7 +488,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
|
|||
|
||||
decodePrediction.cmd.hadBranch := decode.input(BRANCH_CTRL) === BranchCtrlEnum.JAL || (decode.input(BRANCH_CTRL) === BranchCtrlEnum.B && conditionalBranchPrediction)
|
||||
|
||||
val noPredictionOnMissaligned = (!pipeline(RVC_GEN)) generate new Area{
|
||||
val noPredictionOnMissaligned = (!pipeline.config.withRvc) generate new Area{
|
||||
val missaligned = decode.input(BRANCH_CTRL).mux(
|
||||
BranchCtrlEnum.JAL -> imm.j_sext(1),
|
||||
default -> imm.b_sext(1)
|
||||
|
|
|
@ -11,7 +11,7 @@ import scala.collection.mutable.ArrayBuffer
|
|||
|
||||
class FpuPlugin(externalFpu : Boolean = false,
|
||||
simHalt : Boolean = false,
|
||||
p : FpuParameter) extends Plugin[VexRiscv] with VexRiscvRegressionArg {
|
||||
val p : FpuParameter) extends Plugin[VexRiscv] with VexRiscvRegressionArg {
|
||||
|
||||
object FPU_ENABLE extends Stageable(Bool())
|
||||
object FPU_COMMIT extends Stageable(Bool())
|
||||
|
|
|
@ -7,11 +7,11 @@ object RvcDecompressor{
|
|||
|
||||
def main(args: Array[String]): Unit = {
|
||||
SpinalVerilog(new Component{
|
||||
out(Delay((apply(Delay(in Bits(16 bits),2))),2))
|
||||
out(Delay((apply(Delay(in Bits(16 bits),2), false, false)),2))
|
||||
}.setDefinitionName("Decompressor"))
|
||||
}
|
||||
|
||||
def apply(i : Bits): Bits ={
|
||||
def apply(i : Bits, rvf : Boolean, rvd : Boolean): Bits ={
|
||||
val ret = Bits(32 bits).assignDontCare()
|
||||
|
||||
val rch = B"01" ## i(9 downto 7)
|
||||
|
@ -20,6 +20,8 @@ object RvcDecompressor{
|
|||
val addi5spnImm = B"00" ## i(10 downto 7) ## i(12 downto 11) ## i(5) ## i(6) ## B"00"
|
||||
val lwImm = B"00000" ## i(5) ## i(12 downto 10) ## i(6) ## B"00"
|
||||
def swImm = lwImm
|
||||
val ldImm = B"0000" ## i(6 downto 5) ## i(12 downto 10) ## B"000"
|
||||
def sdImm = ldImm
|
||||
val addImm = B((11 downto 5) -> i(12), (4 downto 0) -> i(6 downto 2))
|
||||
def lImm = addImm
|
||||
val jalImm = B((9 downto 0) -> i(12)) ## i(8) ## i(10 downto 9) ## i(6) ## i(7) ## i(2) ## i(11) ## i(5 downto 3) ## B"0"
|
||||
|
@ -31,11 +33,8 @@ object RvcDecompressor{
|
|||
|
||||
def lwspImm = B"0000" ## i(3 downto 2) ## i(12) ## i(6 downto 4) ## B"00"
|
||||
def swspImm = B"0000" ## i(8 downto 7) ## i(12 downto 9) ## B"00"
|
||||
|
||||
val lfdImm = B"0000" ## i(6 downto 5) ## i(12 downto 10) ## B"000"
|
||||
def sfdImm = lfdImm
|
||||
def lfdspImm = B"000" ## i(4 downto 2) ## i(12) ## i(6 downto 5) ## B"000"
|
||||
def sfdspImm = B"000" ## i(9 downto 7) ## i(12 downto 10) ## B"000"
|
||||
def ldspImm = B"000" ## i(4 downto 2) ## i(12) ## i(6 downto 5) ## B"000"
|
||||
def sdspImm = B"000" ## i(9 downto 7) ## i(12 downto 10) ## B"000"
|
||||
|
||||
|
||||
val x0 = B"00000"
|
||||
|
@ -44,12 +43,12 @@ object RvcDecompressor{
|
|||
|
||||
switch(i(1 downto 0) ## i(15 downto 13)){
|
||||
is(0){ret := addi5spnImm ## B"00010" ## B"000" ## rcl ## B"0010011"} //C.ADDI4SPN -> addi rd0, x2, nzuimm[9:2].
|
||||
is(1){ret := lfdImm ## rch ## B"011" ## rcl ## B"0000111" } //C.FLD (w/ D ext)
|
||||
if(rvd) is(1){ret := ldImm ## rch ## B"011" ## rcl ## B"0000111"} // C.FLD
|
||||
is(2){ret := lwImm ## rch ## B"010" ## rcl ## B"0000011"} //C.LW -> lw rd', offset[6:2](rs1')
|
||||
is(3){ret := lwImm ## rch ## B"010" ## rcl ## B"0000111" } //C.FLW (w/ F ext)
|
||||
is(5){ret := sfdImm(11 downto 5) ## rcl ## rch ## B"011" ## sfdImm(4 downto 0) ## B"0100111" } //C.FSD (w/ D ext)
|
||||
if(rvf) is(3){ret := lwImm ## rch ## B"010" ## rcl ## B"0000111"} // C.FLW
|
||||
if(rvd) is(5){ret := sdImm(11 downto 5) ## rcl ## rch ## B"011" ## sdImm(4 downto 0) ## B"0100111"} // C.FSD
|
||||
is(6){ret := swImm(11 downto 5) ## rcl ## rch ## B"010" ## swImm(4 downto 0) ## B"0100011"} //C.SW -> sw rs2',offset[6:2](rs1')
|
||||
is(7){ret := swImm(11 downto 5) ## rcl ## rch ## B"010" ## swImm(4 downto 0) ## B"0100111" } //C.FSW (w/ F ext)
|
||||
if(rvf) is(7){ret := swImm(11 downto 5) ## rcl ## rch ## B"010" ## swImm(4 downto 0) ## B"0100111"} // C.FSW
|
||||
is(8){ret := addImm ## i(11 downto 7) ## B"000" ## i(11 downto 7) ## B"0010011"} //C.ADDI -> addi rd, rd, nzimm[5:0].
|
||||
is(9){ret := jalImm(20) ## jalImm(10 downto 1) ## jalImm(11) ## jalImm(19 downto 12) ## x1 ## B"1101111"} //C.JAL -> jalr x1, rs1, 0.
|
||||
is(10){ret := lImm ## B"00000" ## B"000" ## i(11 downto 7) ## B"0010011"} //C.LI -> addi rd, x0, imm[5:0].
|
||||
|
@ -85,9 +84,9 @@ object RvcDecompressor{
|
|||
is(14){ ret := bImm(12) ## bImm(10 downto 5) ## x0 ## rch ## B"000" ## bImm(4 downto 1) ## bImm(11) ## B"1100011" }
|
||||
is(15){ ret := bImm(12) ## bImm(10 downto 5) ## x0 ## rch ## B"001" ## bImm(4 downto 1) ## bImm(11) ## B"1100011" }
|
||||
is(16){ ret := B"0000000" ## i(6 downto 2) ## i(11 downto 7) ## B"001" ## i(11 downto 7) ## B"0010011" }
|
||||
is(17){ ret := lfdspImm ## x2 ## B"011" ## i(11 downto 7) ## B"0000111" } // C.FLDSP (w/ D ext)
|
||||
if(rvd) is(17){ret := ldspImm ## x2 ## B"011" ## i(11 downto 7) ## B"0000111" } // C.FLDSP
|
||||
is(18){ ret := lwspImm ## x2 ## B"010" ## i(11 downto 7) ## B"0000011" }
|
||||
is(19){ ret := lwspImm ## x2 ## B"010" ## i(11 downto 7) ## B"0000111" } // C.FLWSP (w/ F ext)
|
||||
if(rvf) is(19){ret := lwspImm ## x2 ## B"010" ## i(11 downto 7) ## B"0000111" } // C.FLWSP
|
||||
is(20) {
|
||||
val add = B"000_0000" ## i(6 downto 2) ## (i(12) ? i(11 downto 7) | x0) ## B"000" ## i(11 downto 7) ## B"0110011" //add => add rd, rd, rs2 mv => add rd, x0, rs2
|
||||
val j = B"0000_0000_0000" ## i(11 downto 7) ## B"000" ## (i(12) ? x1 | x0) ## B"1100111" //jr => jalr x0, rs1, 0. jalr => jalr x1, rs1, 0.
|
||||
|
@ -95,9 +94,10 @@ object RvcDecompressor{
|
|||
val addJ = (i(6 downto 2) === 0) ? j | add
|
||||
ret := (i(12 downto 2) === B"100_0000_0000") ? ebreak | addJ
|
||||
}
|
||||
is(21){ ret := sfdspImm(11 downto 5) ## i(6 downto 2) ## x2 ## B"011" ## sfdspImm(4 downto 0) ## B"0100111" } // C.FSDSP (w/ D ext)
|
||||
|
||||
if(rvd) is(21){ret := sdspImm(11 downto 5) ## i(6 downto 2) ## x2 ## B"011" ## sdspImm(4 downto 0) ## B"0100111" } // C.FSDSP
|
||||
is(22){ ret := swspImm(11 downto 5) ## i(6 downto 2) ## x2 ## B"010" ## swspImm(4 downto 0) ## B"0100011" }
|
||||
is(23){ ret := swspImm(11 downto 5) ## i(6 downto 2) ## x2 ## B"010" ## swspImm(4 downto 0) ## B"0100111" } // C.FSWSP (w/ F ext)
|
||||
if(rvf) is(23){ret := swspImm(11 downto 5) ## i(6 downto 2) ## x2 ## B"010" ## swspImm(4 downto 0) ## B"0100111" } // C.FSwSP
|
||||
}
|
||||
|
||||
ret
|
||||
|
|
|
@ -29,7 +29,7 @@ class SrcPlugin(separatedAddSub : Boolean = false, executeInsertion : Boolean =
|
|||
val imm = Riscv.IMM(input(INSTRUCTION))
|
||||
insert(SRC1) := input(SRC1_CTRL).mux(
|
||||
Src1CtrlEnum.RS -> output(RS1),
|
||||
Src1CtrlEnum.PC_INCREMENT -> (if(pipeline(RVC_GEN)) Mux(input(IS_RVC), B(2), B(4)) else B(4)).resized,
|
||||
Src1CtrlEnum.PC_INCREMENT -> (if(pipeline.config.withRvc) Mux(input(IS_RVC), B(2), B(4)) else B(4)).resized,
|
||||
Src1CtrlEnum.IMU -> imm.u.resized,
|
||||
Src1CtrlEnum.URS1 -> input(INSTRUCTION)(Riscv.rs1Range).resized
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue