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

@ -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(_+_)
}
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(key: MaskedLiteral, values: Seq[(Stageable[_ <: BaseType], Any)]): Unit = {
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 = {
import pipeline.config._
import pipeline.decode._
@ -86,7 +93,7 @@ class DecoderSimplePlugin(catchIllegalInstruction : Boolean = false, forceLegalI
val stupidDecoder = false
if(stupidDecoder){
if (catchIllegalInstruction || forceLegalInstructionComputation) insert(LEGAL_INSTRUCTION) := False
if (detectLegalInstructions) insert(LEGAL_INSTRUCTION) := False
for(stageable <- stageables){
if(defaults.contains(stageable)){
insert(stageable).assignFrom(defaults(stageable))
@ -96,7 +103,7 @@ class DecoderSimplePlugin(catchIllegalInstruction : Boolean = false, forceLegalI
}
for((key, tasks) <- encodings){
when(input(INSTRUCTION) === key){
if (catchIllegalInstruction || forceLegalInstructionComputation) insert(LEGAL_INSTRUCTION) := True
if (detectLegalInstructions) insert(LEGAL_INSTRUCTION) := True
for((stageable, value) <- tasks){
insert(stageable).assignFrom(value)
}
@ -145,8 +152,15 @@ class DecoderSimplePlugin(catchIllegalInstruction : Boolean = false, forceLegalI
// logic implementation
val decodedBits = Bits(stageables.foldLeft(0)(_ + _.dataType.getBitsWidth) bits)
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
offset = 0
@ -162,6 +176,10 @@ class DecoderSimplePlugin(catchIllegalInstruction : Boolean = false, forceLegalI
decodeExceptionPort.code := 2
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 ={

View File

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

View File

@ -514,7 +514,8 @@ class DecoderDimension extends VexRiscvDimension("Decoder") {
val catchAll = universes.contains(VexRiscvUniverse.CATCH_ALL)
new VexRiscvPosition("") {
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])
@ -587,6 +588,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 testCmd = stdCmd + (positionsToApply).map(_.testParam).mkString(" ")