Fix BRANCH_TARGET with RVC patch

This commit is contained in:
Charles Papon 2020-02-22 11:53:47 +01:00
parent 41008551c1
commit 5ea0b57d1b
2 changed files with 26 additions and 30 deletions

View File

@ -421,18 +421,15 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
} }
} }
def stage1ToInjectorPipe[T <: Data](input : T): (T,T) ={ def stage1ToInjectorPipe[T <: Data](input : T): (T, T, T) ={
val iBusRspContext = iBusRsp.stages.drop(1).dropRight(1).foldLeft(input)((data,stage) => RegNextWhen(data, stage.output.ready)) val iBusRspContext = iBusRsp.stages.drop(1).dropRight(1).foldLeft(input)((data,stage) => RegNextWhen(data, stage.output.ready))
// val decompressorContext = ifGen(compressedGen)(new Area{
// val lastContext = RegNextWhen(iBusRspContext, decompressor.input.fire) val iBusRspContextOutput = cloneOf(input)
// val output = decompressor.bufferValid ? lastContext | iBusRspContext iBusRspContextOutput := iBusRspContext
// }) val injectorContext = Delay(iBusRspContextOutput, cycleCount=if(injectorStage) 1 else 0, when=injector.decodeInput.ready)
val decompressorContext = cloneOf(input)
decompressorContext := iBusRspContext
val injectorContext = Delay(if(compressedGen) decompressorContext else iBusRspContext, cycleCount=if(injectorStage) 1 else 0, when=injector.decodeInput.ready)
val injectorContextWire = cloneOf(input) //Allow combinatorial override val injectorContextWire = cloneOf(input) //Allow combinatorial override
injectorContextWire := injectorContext injectorContextWire := injectorContext
(ifGen(compressedGen)(decompressorContext), injectorContextWire) (iBusRspContext, iBusRspContextOutput, injectorContextWire)
} }
val predictor = prediction match { val predictor = prediction match {
@ -458,7 +455,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
fetchContext.line := historyCache.readSync((fetchPc.output.payload >> 2).resized, iBusRsp.stages(0).output.ready || fetcherflushIt) fetchContext.line := historyCache.readSync((fetchPc.output.payload >> 2).resized, iBusRsp.stages(0).output.ready || fetcherflushIt)
object PREDICTION_CONTEXT extends Stageable(DynamicContext()) object PREDICTION_CONTEXT extends Stageable(DynamicContext())
decode.insert(PREDICTION_CONTEXT) := stage1ToInjectorPipe(fetchContext)._2 decode.insert(PREDICTION_CONTEXT) := stage1ToInjectorPipe(fetchContext)._3
val decodeContextPrediction = decode.input(PREDICTION_CONTEXT).line.history.msb val decodeContextPrediction = decode.input(PREDICTION_CONTEXT).line.history.msb
val branchStage = decodePrediction.stage val branchStage = decodePrediction.stage
@ -534,21 +531,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
fetchContext.hit := hit fetchContext.hit := hit
fetchContext.line := line fetchContext.line := line
val (decompressorContext, injectorContext) = stage1ToInjectorPipe(fetchContext) val (decompressorContext, decompressorContextOutput, injectorContext) = stage1ToInjectorPipe(fetchContext)
if(compressedGen) {
//prediction hit on the right instruction into words
decompressorContext.hit clearWhen(decompressorContext.line.last2Bytes && (decompressor.bufferValid || (decompressor.isRvc && !decompressor.throw2Bytes)))
decodePc.predictionPcLoad.valid := injectorContext.line.branchWish.msb && injectorContext.hit && !injectorContext.hazard && injector.decodeInput.fire
decodePc.predictionPcLoad.payload := injectorContext.line.target
//Clean the RVC buffer when a prediction was made
when(decompressorContext.line.branchWish.msb && decompressorContext.hit && !decompressorContext.hazard && decompressor.output.fire){
decompressor.bufferValid := False
decompressor.throw2BytesReg := False
decompressor.input.ready := True //Drop the remaining byte if any
}
}
object PREDICTION_CONTEXT extends Stageable(PredictionResult()) object PREDICTION_CONTEXT extends Stageable(PredictionResult())
pipeline.decode.insert(PREDICTION_CONTEXT) := injectorContext pipeline.decode.insert(PREDICTION_CONTEXT) := injectorContext
@ -580,7 +563,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
historyWrite.valid clearWhen(branchContext.hazard || !branchStage.arbitration.isFiring) historyWrite.valid clearWhen(branchContext.hazard || !branchStage.arbitration.isFiring)
val predictionFailure = ifGen(compressedGen)(new Area{ val compressor = compressedGen generate new Area{
val predictionBranch = decompressorContext.hit && !decompressorContext.hazard && decompressorContext.line.branchWish(1) val predictionBranch = decompressorContext.hit && !decompressorContext.hazard && decompressorContext.line.branchWish(1)
val unalignedWordIssue = iBusRsp.output.valid && predictionBranch && decompressor.throw2Bytes && !decompressor.isInputHighRvc val unalignedWordIssue = iBusRsp.output.valid && predictionBranch && decompressor.throw2Bytes && !decompressor.isInputHighRvc
@ -591,7 +574,20 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
iBusRsp.redoFetch := True iBusRsp.redoFetch := True
} }
})
//Do not trigger prediction hit when it is one for the upper RVC word and we aren't there yet
decompressorContextOutput.hit clearWhen(decompressorContext.line.last2Bytes && !decompressor.throw2Bytes)
decodePc.predictionPcLoad.valid := injectorContext.line.branchWish.msb && injectorContext.hit && !injectorContext.hazard && injector.decodeInput.fire
decodePc.predictionPcLoad.payload := injectorContext.line.target
//Clean the RVC buffer when a prediction was made
when(decompressorContext.line.branchWish.msb && decompressorContextOutput.hit && !decompressorContext.hazard && decompressor.output.fire){
decompressor.bufferValid := False
decompressor.throw2BytesReg := False
decompressor.input.ready := True //Drop the remaining byte if any
}
}
} }
} }

View File

@ -620,7 +620,7 @@ class TestIndividualFeatures extends FunSuite {
test(prefix + name + "_test") { test(prefix + name + "_test") {
println("START TEST " + prefix + name) println("START TEST " + prefix + name)
val debug = true val debug = true
val stdCmd = (s"make clean run WITH_USER_IO=no REDO=10 TRACE=${if(debug) "yes" else "no"} TRACE_START=9999924910246l STOP_ON_ERROR=no FLOW_INFO=no STOP_ON_ERROR=no DHRYSTONE=yes COREMARK=${sys.env.getOrElse("VEXRISCV_REGRESSION_COREMARK", "yes")} THREAD_COUNT=${sys.env.getOrElse("VEXRISCV_REGRESSION_THREAD_COUNT", 1)} ") + s" SEED=${testSeed} " val stdCmd = (s"make clean run WITH_USER_IO=no REDO=10 TRACE=${if(debug) "yes" else "no"} TRACE_START=9999924910246l FLOW_INFO=no STOP_ON_ERROR=no DHRYSTONE=yes COREMARK=${sys.env.getOrElse("VEXRISCV_REGRESSION_COREMARK", "yes")} THREAD_COUNT=${sys.env.getOrElse("VEXRISCV_REGRESSION_THREAD_COUNT", 1)} ") + s" SEED=${testSeed} "
val testCmd = stdCmd + (positionsToApply).map(_.testParam).mkString(" ") val testCmd = stdCmd + (positionsToApply).map(_.testParam).mkString(" ")
println(testCmd) println(testCmd)
val str = doCmd(testCmd) val str = doCmd(testCmd)
@ -633,8 +633,8 @@ class TestIndividualFeatures extends FunSuite {
// //
// val testId = Some(mutable.HashSet(3,4,9,11,13,16,18,19,20,21)) // val testId = Some(mutable.HashSet(3,4,9,11,13,16,18,19,20,21))
// val testId = Some(mutable.HashSet(11)) // val testId = Some(mutable.HashSet(11))
// val testId = Some(mutable.HashSet(4, 11)) // val testId = Some(mutable.HashSet(6))
// val seed = 6592877339343561798l // val seed = 9095713085965080531l
val rand = new Random(seed) val rand = new Random(seed)