Fix dynamic branch prediction correction on misspredicted fetch which are done on a 32 bits instruction crossing two words in configs which have at least 2 cycle latency fetch

This commit is contained in:
Charles Papon 2019-06-14 08:13:22 +02:00
parent d603de1bfe
commit 617f4742cd
3 changed files with 37 additions and 16 deletions

View File

@ -28,7 +28,7 @@ case class Masked(value : BigInt,care : BigInt){
def mergeOneBitDifSmaller(x: Masked) = { def mergeOneBitDifSmaller(x: Masked) = {
val bit = value - x.value val bit = value - x.value
val ret = new Masked(value &~ bit, care & ~bit) val ret = new Masked(value &~ bit, care & ~bit)
// ret.isPrime = isPrime || x.isPrime // ret.isPrime = isPrime || x.isPrime
isPrime = false isPrime = false
x.isPrime = false x.isPrime = false
ret ret
@ -44,7 +44,10 @@ case class Masked(value : BigInt,care : BigInt){
def toString(bitCount : Int) = (0 until bitCount).map(i => if(care.testBit(i)) (if(value.testBit(i)) "1" else "0") else "-").reverseIterator.reduce(_+_) def toString(bitCount : Int) = (0 until bitCount).map(i => if(care.testBit(i)) (if(value.testBit(i)) "1" else "0") else "-").reverseIterator.reduce(_+_)
} }
class DecoderSimplePlugin(catchIllegalInstruction : Boolean = false, forceLegalInstructionComputation : Boolean = false) extends Plugin[VexRiscv] with DecoderService { class DecoderSimplePlugin(catchIllegalInstruction : Boolean = false,
throwIllegalInstruction : Boolean = false,
assertIllegalInstruction : Boolean = false,
forceLegalInstructionComputation : Boolean = false) extends Plugin[VexRiscv] with DecoderService {
override def add(encoding: Seq[(MaskedLiteral, Seq[(Stageable[_ <: BaseType], Any)])]): Unit = encoding.foreach(e => this.add(e._1,e._2)) override def add(encoding: Seq[(MaskedLiteral, Seq[(Stageable[_ <: BaseType], Any)])]): Unit = encoding.foreach(e => this.add(e._1,e._2))
override def add(key: MaskedLiteral, values: Seq[(Stageable[_ <: BaseType], Any)]): Unit = { override def add(key: MaskedLiteral, values: Seq[(Stageable[_ <: BaseType], Any)]): Unit = {
val instructionModel = encodings.getOrElseUpdate(key,ArrayBuffer[(Stageable[_ <: BaseType], BaseType)]()) val instructionModel = encodings.getOrElseUpdate(key,ArrayBuffer[(Stageable[_ <: BaseType], BaseType)]())
@ -78,6 +81,10 @@ class DecoderSimplePlugin(catchIllegalInstruction : Boolean = false, forceLegalI
} }
} }
val detectLegalInstructions = catchIllegalInstruction || throwIllegalInstruction || forceLegalInstructionComputation || assertIllegalInstruction
object ASSERT_ERROR extends Stageable(Bool)
override def build(pipeline: VexRiscv): Unit = { override def build(pipeline: VexRiscv): Unit = {
import pipeline.config._ import pipeline.config._
import pipeline.decode._ import pipeline.decode._
@ -86,7 +93,7 @@ class DecoderSimplePlugin(catchIllegalInstruction : Boolean = false, forceLegalI
val stupidDecoder = false val stupidDecoder = false
if(stupidDecoder){ if(stupidDecoder){
if (catchIllegalInstruction || forceLegalInstructionComputation) insert(LEGAL_INSTRUCTION) := False if (detectLegalInstructions) insert(LEGAL_INSTRUCTION) := False
for(stageable <- stageables){ for(stageable <- stageables){
if(defaults.contains(stageable)){ if(defaults.contains(stageable)){
insert(stageable).assignFrom(defaults(stageable)) insert(stageable).assignFrom(defaults(stageable))
@ -96,7 +103,7 @@ class DecoderSimplePlugin(catchIllegalInstruction : Boolean = false, forceLegalI
} }
for((key, tasks) <- encodings){ for((key, tasks) <- encodings){
when(input(INSTRUCTION) === key){ when(input(INSTRUCTION) === key){
if (catchIllegalInstruction || forceLegalInstructionComputation) insert(LEGAL_INSTRUCTION) := True if (detectLegalInstructions) insert(LEGAL_INSTRUCTION) := True
for((stageable, value) <- tasks){ for((stageable, value) <- tasks){
insert(stageable).assignFrom(value) insert(stageable).assignFrom(value)
} }
@ -145,8 +152,15 @@ class DecoderSimplePlugin(catchIllegalInstruction : Boolean = false, forceLegalI
// logic implementation // logic implementation
val decodedBits = Bits(stageables.foldLeft(0)(_ + _.dataType.getBitsWidth) bits) val decodedBits = Bits(stageables.foldLeft(0)(_ + _.dataType.getBitsWidth) bits)
decodedBits := Symplify(input(INSTRUCTION), spec, decodedBits.getWidth) decodedBits := Symplify(input(INSTRUCTION), spec, decodedBits.getWidth)
if (catchIllegalInstruction || forceLegalInstructionComputation) insert(LEGAL_INSTRUCTION) := Symplify.logicOf(input(INSTRUCTION), SymplifyBit.getPrimeImplicantsByTrueAndDontCare(spec.unzip._1.toSeq, Nil, 32)) if (detectLegalInstructions) insert(LEGAL_INSTRUCTION) := Symplify.logicOf(input(INSTRUCTION), SymplifyBit.getPrimeImplicantsByTrueAndDontCare(spec.unzip._1.toSeq, Nil, 32))
if (throwIllegalInstruction) {
input(LEGAL_INSTRUCTION) //Fill the request for later (prePopTask)
Component.current.addPrePopTask(() => arbitration.isValid clearWhen(!input(LEGAL_INSTRUCTION)))
}
if(assertIllegalInstruction){
val reg = RegInit(False) setWhen(arbitration.isValid) clearWhen(arbitration.isRemoved || !arbitration.isStuck)
insert(ASSERT_ERROR) := arbitration.isValid || reg
}
//Unpack decodedBits and insert fields in the pipeline //Unpack decodedBits and insert fields in the pipeline
offset = 0 offset = 0
@ -162,6 +176,10 @@ class DecoderSimplePlugin(catchIllegalInstruction : Boolean = false, forceLegalI
decodeExceptionPort.code := 2 decodeExceptionPort.code := 2
decodeExceptionPort.badAddr := input(INSTRUCTION).asUInt decodeExceptionPort.badAddr := input(INSTRUCTION).asUInt
} }
if(assertIllegalInstruction){
pipeline.stages.tail.foreach(s => s.output(ASSERT_ERROR) clearWhen(s.arbitration.isRemoved))
assert(!pipeline.stages.last.output(ASSERT_ERROR))
}
} }
def bench(toplevel : VexRiscv): Unit ={ def bench(toplevel : VexRiscv): Unit ={
@ -345,14 +363,14 @@ object SymplifyBit{
def main(args: Array[String]) { def main(args: Array[String]) {
{ {
// val default = Masked(0, 0xF) // val default = Masked(0, 0xF)
// val primeImplicants = List(4, 8, 10, 11, 12, 15).map(v => Masked(v, 0xF)) // val primeImplicants = List(4, 8, 10, 11, 12, 15).map(v => Masked(v, 0xF))
// val dcImplicants = List(9, 14).map(v => Masked(v, 0xF).setPrime(false)) // val dcImplicants = List(9, 14).map(v => Masked(v, 0xF).setPrime(false))
// val reducedPrimeImplicants = getPrimeImplicantsByTrueAndDontCare(primeImplicants, dcImplicants, 4) // val reducedPrimeImplicants = getPrimeImplicantsByTrueAndDontCare(primeImplicants, dcImplicants, 4)
// println("UUT") // println("UUT")
// println(reducedPrimeImplicants.map(_.toString(4)).mkString("\n")) // println(reducedPrimeImplicants.map(_.toString(4)).mkString("\n"))
// println("REF") // println("REF")
// println("-100\n10--\n1--0\n1-1-") // println("-100\n10--\n1--0\n1-1-")
} }
{ {

View File

@ -596,6 +596,7 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
historyWrite.data.branchWish := 0 historyWrite.data.branchWish := 0
decode.arbitration.isValid := False decode.arbitration.isValid := False
decode.arbitration.flushNext := True
dynamicTargetFailureCorrection.valid := True dynamicTargetFailureCorrection.valid := True
} }
}) })

View File

@ -514,7 +514,8 @@ class DecoderDimension extends VexRiscvDimension("Decoder") {
val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL) val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL)
new VexRiscvPosition("") { new VexRiscvPosition("") {
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new DecoderSimplePlugin( override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new DecoderSimplePlugin(
catchIllegalInstruction = catchAll catchIllegalInstruction = catchAll,
throwIllegalInstruction = false
) )
// override def isCompatibleWith(positions: Seq[ConfigPosition[VexRiscvConfig]]) = catchAll == positions.exists(_.isInstanceOf[CatchAllPosition]) // override def isCompatibleWith(positions: Seq[ConfigPosition[VexRiscvConfig]]) = catchAll == positions.exists(_.isInstanceOf[CatchAllPosition])
@ -587,6 +588,7 @@ class TestIndividualFeatures extends FunSuite {
test(prefix + name + "_test") { test(prefix + name + "_test") {
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 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 testCmd = stdCmd + (positionsToApply).map(_.testParam).mkString(" ") val testCmd = stdCmd + (positionsToApply).map(_.testParam).mkString(" ")