RVC debug pass tets
This commit is contained in:
parent
0056da1342
commit
acccbf40e2
|
@ -95,19 +95,13 @@ case class DebugExtensionIo() extends Bundle with IMasterSlave{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Allow to avoid instruction cache plugin to be confused by new instruction poping in the pipeline
|
|
||||||
trait InstructionInjector{
|
|
||||||
def isInjecting(stage : Stage) : Bool
|
|
||||||
}
|
|
||||||
|
|
||||||
class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] with InstructionInjector {
|
class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] {
|
||||||
|
|
||||||
var io : DebugExtensionIo = null
|
var io : DebugExtensionIo = null
|
||||||
val injectionAsks = ArrayBuffer[(Stage, Bool)]()
|
val injectionAsks = ArrayBuffer[(Stage, Bool)]()
|
||||||
var isInjectingOnDecode : Bool = null
|
|
||||||
var injectionPort : Stream[Bits] = 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)
|
object IS_EBREAK extends Stageable(Bool)
|
||||||
override def setup(pipeline: VexRiscv): Unit = {
|
override def setup(pipeline: VexRiscv): Unit = {
|
||||||
|
@ -127,7 +121,6 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] w
|
||||||
ALU_CTRL -> AluCtrlEnum.ADD_SUB //Used to get the PC value in busReadDataReg
|
ALU_CTRL -> AluCtrlEnum.ADD_SUB //Used to get the PC value in busReadDataReg
|
||||||
))
|
))
|
||||||
|
|
||||||
isInjectingOnDecode = Bool()
|
|
||||||
injectionPort = pipeline.service(classOf[IBusFetcher]).getInjectionPort()
|
injectionPort = pipeline.service(classOf[IBusFetcher]).getInjectionPort()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +131,6 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] w
|
||||||
|
|
||||||
val logic = debugClockDomain {pipeline plug new Area{
|
val logic = debugClockDomain {pipeline plug new Area{
|
||||||
val iBusFetcher = service(classOf[IBusFetcher])
|
val iBusFetcher = service(classOf[IBusFetcher])
|
||||||
val insertDecodeInstruction = False
|
|
||||||
val firstCycle = RegNext(False) setWhen (io.bus.cmd.ready)
|
val firstCycle = RegNext(False) setWhen (io.bus.cmd.ready)
|
||||||
val secondCycle = RegNext(firstCycle)
|
val secondCycle = RegNext(firstCycle)
|
||||||
val resetIt = RegInit(False)
|
val resetIt = RegInit(False)
|
||||||
|
@ -164,6 +156,9 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] w
|
||||||
io.bus.rsp.data(4) := stepIt
|
io.bus.rsp.data(4) := stepIt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
injectionPort.valid := False
|
||||||
|
injectionPort.payload := io.bus.cmd.data
|
||||||
|
|
||||||
when(io.bus.cmd.valid) {
|
when(io.bus.cmd.valid) {
|
||||||
switch(io.bus.cmd.address(2 downto 2)) {
|
switch(io.bus.cmd.address(2 downto 2)) {
|
||||||
is(0) {
|
is(0) {
|
||||||
|
@ -176,18 +171,14 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] w
|
||||||
}
|
}
|
||||||
is(1) {
|
is(1) {
|
||||||
when(io.bus.cmd.wr) {
|
when(io.bus.cmd.wr) {
|
||||||
insertDecodeInstruction := True
|
injectionPort.valid := True
|
||||||
// decode.arbitration.isValid.getDrivingReg setWhen (firstCycle)
|
io.bus.cmd.ready := injectionPort.ready
|
||||||
// decode.arbitration.haltItself setWhen (secondCycle)
|
|
||||||
// io.bus.cmd.ready := !firstCycle && !secondCycle && execute.arbitration.isValid
|
|
||||||
io.bus.cmd.ready := injectionPort.fire
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
injectionPort.valid := RegNext(insertDecodeInstruction) init(False) clearWhen(injectionPort.fire)
|
|
||||||
injectionPort.payload := RegNext(io.bus.cmd.data)
|
|
||||||
|
|
||||||
|
|
||||||
// Component.current.addPrePopTask(() => {
|
// Component.current.addPrePopTask(() => {
|
||||||
|
@ -232,9 +223,17 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] w
|
||||||
haltIt := True
|
haltIt := True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
when(stepIt && Cat(pipeline.stages.map(_.arbitration.redoIt)).asBits.orR) {
|
when(stepIt && Cat(pipeline.stages.map(_.arbitration.redoIt)).asBits.orR) {
|
||||||
haltIt := False
|
haltIt := False
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Avoid having two C instruction executed in a single step
|
||||||
|
if(pipeline(RVC_GEN)){
|
||||||
|
val cleanStep = RegNext(stepIt && decode.arbitration.isFiring) init(False)
|
||||||
|
decode.arbitration.removeIt setWhen(cleanStep)
|
||||||
|
}
|
||||||
|
|
||||||
io.resetOut := RegNext(resetIt)
|
io.resetOut := RegNext(resetIt)
|
||||||
|
|
||||||
if(serviceExist(classOf[InterruptionInhibitor])) {
|
if(serviceExist(classOf[InterruptionInhibitor])) {
|
||||||
|
@ -248,8 +247,5 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] w
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|
||||||
isInjectingOnDecode := RegNext(logic.insertDecodeInstruction) init(False)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,8 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
||||||
pcReg + 4
|
pcReg + 4
|
||||||
|
|
||||||
if (keepPcPlus4) KeepAttribute(pcPlus)
|
if (keepPcPlus4) KeepAttribute(pcPlus)
|
||||||
when(decode.arbitration.isFiring) {
|
val injectedDecode = False
|
||||||
|
when(decode.arbitration.isFiring && !injectedDecode) {
|
||||||
pcReg := pcPlus
|
pcReg := pcPlus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,31 +251,31 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
||||||
incomingInstruction setWhen(bufferValid && bufferData(1 downto 0) =/= 3)
|
incomingInstruction setWhen(bufferValid && bufferData(1 downto 0) =/= 3)
|
||||||
})
|
})
|
||||||
|
|
||||||
//TODO never colalpse buble of the last stage
|
|
||||||
def condApply[T](that : T, cond : Boolean)(func : (T) => T) = if(cond)func(that) else that
|
def condApply[T](that : T, cond : Boolean)(func : (T) => T) = if(cond)func(that) else that
|
||||||
val injector = new Area {
|
val injector = new Area {
|
||||||
val inputBeforeHalt = condApply(if(decodePcGen) decompressor.output else iBusRsp.output, injectorReadyCutGen)(_.s2mPipe(flush))
|
val inputBeforeHalt = condApply(if (decodePcGen) decompressor.output else iBusRsp.output, injectorReadyCutGen)(_.s2mPipe(flush))
|
||||||
if(injectorReadyCutGen) {
|
if (injectorReadyCutGen) {
|
||||||
iBusRsp.readyForError.clearWhen(inputBeforeHalt.valid)
|
iBusRsp.readyForError.clearWhen(inputBeforeHalt.valid)
|
||||||
incomingInstruction setWhen(inputBeforeHalt.valid)
|
incomingInstruction setWhen (inputBeforeHalt.valid)
|
||||||
}
|
}
|
||||||
val decodeInput = (if(injectorStage){
|
val decodeInput = (if (injectorStage) {
|
||||||
val decodeInput = inputBeforeHalt.m2sPipeWithFlush(killLastStage, collapsBubble = false)
|
val decodeInput = inputBeforeHalt.m2sPipeWithFlush(killLastStage, collapsBubble = false)
|
||||||
decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck, decode.input(INSTRUCTION), inputBeforeHalt.rsp.inst)
|
decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck, decode.input(INSTRUCTION), inputBeforeHalt.rsp.inst)
|
||||||
iBusRsp.readyForError.clearWhen(decodeInput.valid)
|
iBusRsp.readyForError.clearWhen(decodeInput.valid)
|
||||||
incomingInstruction setWhen(decodeInput.valid)
|
incomingInstruction setWhen (decodeInput.valid)
|
||||||
decodeInput
|
decodeInput
|
||||||
} else {
|
} else {
|
||||||
inputBeforeHalt
|
inputBeforeHalt
|
||||||
})
|
})
|
||||||
|
|
||||||
if(decodePcGen){
|
if (decodePcGen) {
|
||||||
decodeNextPcValid := True
|
decodeNextPcValid := True
|
||||||
decodeNextPc := decodePc.pcReg
|
decodeNextPc := decodePc.pcReg
|
||||||
}else {
|
} else {
|
||||||
val lastStageStream = if(injectorStage) inputBeforeHalt
|
val lastStageStream = if (injectorStage) inputBeforeHalt
|
||||||
else if(rspStageGen) iBusRsp.outputBeforeStage
|
else if (rspStageGen) iBusRsp.outputBeforeStage
|
||||||
else if(cmdToRspStageCount > 1)iBusRsp.inputPipeline(cmdToRspStageCount-2)
|
else if (cmdToRspStageCount > 1) iBusRsp.inputPipeline(cmdToRspStageCount - 2)
|
||||||
else throw new Exception("Fetch should at least have two stages")
|
else throw new Exception("Fetch should at least have two stages")
|
||||||
|
|
||||||
// when(fetcherHalt){
|
// when(fetcherHalt){
|
||||||
|
@ -287,25 +288,72 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
||||||
|
|
||||||
decodeInput.ready := !decode.arbitration.isStuck
|
decodeInput.ready := !decode.arbitration.isStuck
|
||||||
decode.arbitration.isValid := decodeInput.valid
|
decode.arbitration.isValid := decodeInput.valid
|
||||||
decode.insert(PC) := (if(decodePcGen) decodePc.pcReg else decodeInput.pc)
|
decode.insert(PC) := (if (decodePcGen) decodePc.pcReg else decodeInput.pc)
|
||||||
decode.insert(INSTRUCTION) := decodeInput.rsp.inst
|
decode.insert(INSTRUCTION) := decodeInput.rsp.inst
|
||||||
decode.insert(INSTRUCTION_READY) := True
|
decode.insert(INSTRUCTION_READY) := True
|
||||||
if(compressedGen) decode.insert(IS_RVC) := decodeInput.isRvc
|
if (compressedGen) decode.insert(IS_RVC) := decodeInput.isRvc
|
||||||
|
|
||||||
// if(catchAccessFault){
|
// if(catchAccessFault){
|
||||||
// decodeExceptionPort.valid := decode.arbitration.isValid && decodeInput.rsp.error
|
// decodeExceptionPort.valid := decode.arbitration.isValid && decodeInput.rsp.error
|
||||||
// decodeExceptionPort.code := 1
|
// decodeExceptionPort.code := 1
|
||||||
// decodeExceptionPort.badAddr := decode.input(PC)
|
// decodeExceptionPort.badAddr := decode.input(PC)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if(injectionPort != null){
|
if (injectionPort != null) {
|
||||||
val state = RegNext(injectionPort.valid) init(False) clearWhen(injectionPort.ready)
|
Component.current.addPrePopTask(() => {
|
||||||
injectionPort.ready := !decode.arbitration.isStuck && state
|
val state = RegInit(U"000")
|
||||||
when(injectionPort.valid) {
|
|
||||||
decode.arbitration.isValid := True
|
injectionPort.ready := False
|
||||||
decode.arbitration.haltItself setWhen(!state)
|
if(decodePcGen){
|
||||||
decode.insert(INSTRUCTION) := injectionPort.payload
|
decodePc.injectedDecode setWhen(state =/= 0)
|
||||||
}
|
}
|
||||||
|
switch(state) {
|
||||||
|
is(0) { //request pipelining
|
||||||
|
when(injectionPort.valid) {
|
||||||
|
state := 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is(1) { //Give time to propagate the payload
|
||||||
|
state := 2
|
||||||
|
}
|
||||||
|
is(2){ //read regfile delay
|
||||||
|
decode.arbitration.isValid := True
|
||||||
|
decode.arbitration.haltItself := True
|
||||||
|
state := 3
|
||||||
|
}
|
||||||
|
is(3){ //Do instruction
|
||||||
|
decode.arbitration.isValid := True
|
||||||
|
when(!decode.arbitration.isStuck) {
|
||||||
|
state := 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is(4){ //request pipelining
|
||||||
|
injectionPort.ready := True
|
||||||
|
state := 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//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(state.pull() =/= 0) {
|
||||||
|
instructionDriver := injectionPort.payload.pull()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Insert the instruction via a mux in the decode stage
|
||||||
|
when(state =/= 0) {
|
||||||
|
decode.input(INSTRUCTION) := RegNext(injectionPort.payload)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,8 +109,8 @@ class IBusSimplePlugin(interfaceKeepData : Boolean, catchAccessFault : Boolean,
|
||||||
catchAccessFault = catchAccessFault,
|
catchAccessFault = catchAccessFault,
|
||||||
resetVector = BigInt(0x80000000l),
|
resetVector = BigInt(0x80000000l),
|
||||||
keepPcPlus4 = false,
|
keepPcPlus4 = false,
|
||||||
decodePcGen = false,
|
decodePcGen = true,
|
||||||
compressedGen = false,
|
compressedGen = true,
|
||||||
cmdToRspStageCount = 1,
|
cmdToRspStageCount = 1,
|
||||||
rspStageGen = false,
|
rspStageGen = false,
|
||||||
injectorReadyCutGen = false,
|
injectorReadyCutGen = false,
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
/disasm.s
|
|
@ -1 +1 @@
|
||||||
.word 0x8067
|
.word 0x812e23
|
||||||
|
|
Loading…
Reference in New Issue