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
|
@ -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-")
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -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(" ")
|
||||||
|
|
Loading…
Reference in New Issue