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 decompressorContext = ifGen(compressedGen)(new Area{
// val lastContext = RegNextWhen(iBusRspContext, decompressor.input.fire)
// val output = decompressor.bufferValid ? lastContext | iBusRspContext
// })
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 iBusRspContextOutput = cloneOf(input)
iBusRspContextOutput := iBusRspContext
val injectorContext = Delay(iBusRspContextOutput, cycleCount=if(injectorStage) 1 else 0, when=injector.decodeInput.ready)
val injectorContextWire = cloneOf(input) //Allow combinatorial override
injectorContextWire := injectorContext
(ifGen(compressedGen)(decompressorContext), injectorContextWire)
(iBusRspContext, iBusRspContextOutput, injectorContextWire)
}
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)
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 branchStage = decodePrediction.stage
@ -534,21 +531,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
fetchContext.hit := hit
fetchContext.line := line
val (decompressorContext, 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
}
}
val (decompressorContext, decompressorContextOutput, injectorContext) = stage1ToInjectorPipe(fetchContext)
object PREDICTION_CONTEXT extends Stageable(PredictionResult())
pipeline.decode.insert(PREDICTION_CONTEXT) := injectorContext
@ -580,7 +563,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
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 unalignedWordIssue = iBusRsp.output.valid && predictionBranch && decompressor.throw2Bytes && !decompressor.isInputHighRvc
@ -591,7 +574,20 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
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") {
println("START TEST " + prefix + name)
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(" ")
println(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(11))
// val testId = Some(mutable.HashSet(4, 11))
// val seed = 6592877339343561798l
// val testId = Some(mutable.HashSet(6))
// val seed = 9095713085965080531l
val rand = new Random(seed)