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:
parent
d603de1bfe
commit
617f4742cd
|
@ -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 ={
|
||||
|
|
|
@ -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
|
||||
}
|
||||
})
|
||||
|
|
|
@ -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(" ")
|
||||
|
|
Loading…
Reference in New Issue