Reintroduce debug plugin (instruction injector need optimisations)

This commit is contained in:
Dolu1990 2018-05-05 23:05:32 +02:00
parent a50fbf0d7a
commit 294293cb70
4 changed files with 64 additions and 42 deletions

View File

@ -14,6 +14,7 @@ trait JumpService{
trait IBusFetcher{
def haltIt() : Unit
def nextPc() : (Bool, UInt)
def getInjectionPort() : Stream[Bits]
}

View File

@ -35,28 +35,28 @@ object TestsWorkspace {
// resetVector = 0x80000000l,
// relaxedPcCalculation = false
// ),
// new IBusSimplePlugin(
// interfaceKeepData = false,
// catchAccessFault = true
// ),
new IBusCachedPlugin(
config = InstructionCacheConfig(
cacheSize = 1024*16,
bytePerLine = 32,
wayCount = 1,
addressWidth = 32,
cpuDataWidth = 32,
memDataWidth = 32,
catchIllegalAccess = false,
catchAccessFault = true,
catchMemoryTranslationMiss = false,
asyncTagMemory = false,
twoCycleRam = false
)//,
new IBusSimplePlugin(
interfaceKeepData = false,
catchAccessFault = true
),
// new IBusCachedPlugin(
// config = InstructionCacheConfig(
// cacheSize = 1024*16,
// bytePerLine = 32,
// wayCount = 1,
// addressWidth = 32,
// cpuDataWidth = 32,
// memDataWidth = 32,
// catchIllegalAccess = false,
// catchAccessFault = true,
// catchMemoryTranslationMiss = false,
// asyncTagMemory = false,
// twoCycleRam = false
// )//,
// memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
// portTlbSize = 4
// )
),
// ),
// new DBusSimplePlugin(
// catchAddressMisaligned = true,
// catchAccessFault = true,
@ -122,7 +122,7 @@ object TestsWorkspace {
),
// new DivPlugin,
new CsrPlugin(CsrPluginConfig.all(0x80000020l).copy(deterministicInteruptionEntry = false)),
// new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
new BranchPlugin(
earlyBranch = true,
catchAddressMisaligned = true,

View File

@ -105,6 +105,8 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] w
var io : DebugExtensionIo = null
val injectionAsks = ArrayBuffer[(Stage, Bool)]()
var isInjectingOnDecode : Bool = null
var injectionPort : Stream[Bits] = null
override def isInjecting(stage: Stage) : Bool = if(stage == pipeline.decode) isInjectingOnDecode else False
object IS_EBREAK extends Stageable(Bool)
@ -126,6 +128,7 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] w
))
isInjectingOnDecode = Bool()
injectionPort = pipeline.service(classOf[IBusFetcher]).getInjectionPort()
}
@ -174,35 +177,39 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] w
is(1) {
when(io.bus.cmd.wr) {
insertDecodeInstruction := True
//TODO !!!!
decode.arbitration.isValid.getDrivingReg setWhen (firstCycle)
decode.arbitration.haltItself setWhen (secondCycle)
io.bus.cmd.ready := !firstCycle && !secondCycle && execute.arbitration.isValid
// decode.arbitration.isValid.getDrivingReg setWhen (firstCycle)
// decode.arbitration.haltItself setWhen (secondCycle)
// io.bus.cmd.ready := !firstCycle && !secondCycle && execute.arbitration.isValid
io.bus.cmd.ready := injectionPort.fire
}
}
}
}
Component.current.addPrePopTask(() => {
//Check if the decode instruction is driven by a register
val instructionDriver = try {decode.input(INSTRUCTION).getDrivingReg} catch { case _ : Throwable => null}
if(instructionDriver != null){ //If yes =>
//Insert the instruction by writing the "fetch to decode instruction register",
// Work even if it need to cross some hierarchy (caches)
instructionDriver.component.rework {
when(insertDecodeInstruction.pull()) {
instructionDriver := io.bus.cmd.data.pull()
}
}
} else{
//Insert the instruction via a mux in the decode stage
when(RegNext(insertDecodeInstruction)){
decode.input(INSTRUCTION) := RegNext(io.bus.cmd.data)
}
}
})
injectionPort.valid := RegNext(insertDecodeInstruction) init(False) clearWhen(injectionPort.fire)
injectionPort.payload := RegNext(io.bus.cmd.data)
// Component.current.addPrePopTask(() => {
// //Check if the decode instruction is driven by a register
// val instructionDriver = try {decode.input(INSTRUCTION).getDrivingReg} catch { case _ : Throwable => null}
// if(instructionDriver != null){ //If yes =>
// //Insert the instruction by writing the "fetch to decode instruction register",
// // Work even if it need to cross some hierarchy (caches)
// instructionDriver.component.rework {
// when(insertDecodeInstruction.pull()) {
// instructionDriver := io.bus.cmd.data.pull()
// }
// }
// } else{
// //Insert the instruction via a mux in the decode stage
// when(RegNext(insertDecodeInstruction)){
// decode.input(INSTRUCTION) := RegNext(io.bus.cmd.data)
// }
// }
// })
//
when(execute.arbitration.isFiring && execute.input(IS_EBREAK)) {
decode.arbitration.haltByOther := True
decode.arbitration.flushAll := True

View File

@ -31,6 +31,12 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
lazy val decodeNextPc = UInt(32 bits)
def nextPc() = (False, decodeNextPc)
var injectionPort : Stream[Bits] = null
override def getInjectionPort() = {
injectionPort = Stream(Bits(32 bits))
injectionPort
}
var predictionJumpInterface : Flow[UInt] = null
override def haltIt(): Unit = fetcherHalt := True
@ -281,6 +287,14 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
// decodeExceptionPort.code := 1
// decodeExceptionPort.badAddr := decode.input(PC)
// }
if(injectionPort != null){
injectionPort.ready := !decode.arbitration.isStuck
when(injectionPort.valid) {
decode.arbitration.isValid := True
decode.insert(INSTRUCTION) := injectionPort.payload
}
}
}
prediction match {