Alows Fetcher to have multiple debug injection ports

This commit is contained in:
Dolu1990 2023-03-03 09:06:20 +01:00
parent 5f67075e30
commit 5493c55ab0
4 changed files with 37 additions and 18 deletions

View File

@ -16,7 +16,6 @@ object VexRiscvBmbGenerator{
val DEBUG_JTAG_CTRL = 2 val DEBUG_JTAG_CTRL = 2
val DEBUG_BUS = 3 val DEBUG_BUS = 3
val DEBUG_BMB = 4 val DEBUG_BMB = 4
val DEBUG_RISCV = 5
} }
case class VexRiscvBmbGenerator()(implicit interconnectSmp: BmbInterconnectGenerator = null) extends Area { case class VexRiscvBmbGenerator()(implicit interconnectSmp: BmbInterconnectGenerator = null) extends Area {
@ -24,6 +23,7 @@ case class VexRiscvBmbGenerator()(implicit interconnectSmp: BmbInterconnectGener
val config = Handle[VexRiscvConfig] val config = Handle[VexRiscvConfig]
val withDebug = Handle[Int] val withDebug = Handle[Int]
val withRiscvDebug = Handle[Boolean]
val debugClockDomain = Handle[ClockDomain] val debugClockDomain = Handle[ClockDomain]
val debugReset = Handle[Bool] val debugReset = Handle[Bool]
val debugAskReset = Handle[() => Unit] val debugAskReset = Handle[() => Unit]
@ -42,6 +42,7 @@ case class VexRiscvBmbGenerator()(implicit interconnectSmp: BmbInterconnectGener
def disableDebug() = { def disableDebug() = {
withDebug.load(DEBUG_NONE) withDebug.load(DEBUG_NONE)
withRiscvDebug.load(false)
} }
def enableJtag(debugCd : ClockDomainResetGenerator, resetCd : ClockDomainResetGenerator) : Unit = debugCd.rework{ def enableJtag(debugCd : ClockDomainResetGenerator, resetCd : ClockDomainResetGenerator) : Unit = debugCd.rework{
@ -49,6 +50,7 @@ case class VexRiscvBmbGenerator()(implicit interconnectSmp: BmbInterconnectGener
val resetBridge = resetCd.asyncReset(debugReset, ResetSensitivity.HIGH) val resetBridge = resetCd.asyncReset(debugReset, ResetSensitivity.HIGH)
debugAskReset.loadNothing() debugAskReset.loadNothing()
withDebug.load(DEBUG_JTAG) withDebug.load(DEBUG_JTAG)
if(!withRiscvDebug.isLoaded) withRiscvDebug.load(false)
} }
def enableJtagInstructionCtrl(debugCd : ClockDomainResetGenerator, resetCd : ClockDomainResetGenerator) : Unit = debugCd.rework{ def enableJtagInstructionCtrl(debugCd : ClockDomainResetGenerator, resetCd : ClockDomainResetGenerator) : Unit = debugCd.rework{
@ -56,6 +58,7 @@ case class VexRiscvBmbGenerator()(implicit interconnectSmp: BmbInterconnectGener
val resetBridge = resetCd.asyncReset(debugReset, ResetSensitivity.HIGH) val resetBridge = resetCd.asyncReset(debugReset, ResetSensitivity.HIGH)
debugAskReset.loadNothing() debugAskReset.loadNothing()
withDebug.load(DEBUG_JTAG_CTRL) withDebug.load(DEBUG_JTAG_CTRL)
if(!withRiscvDebug.isLoaded) withRiscvDebug.load(false)
} }
def enableDebugBus(debugCd : ClockDomainResetGenerator, resetCd : ClockDomainResetGenerator) : Unit = debugCd.rework{ def enableDebugBus(debugCd : ClockDomainResetGenerator, resetCd : ClockDomainResetGenerator) : Unit = debugCd.rework{
@ -63,14 +66,23 @@ case class VexRiscvBmbGenerator()(implicit interconnectSmp: BmbInterconnectGener
val resetBridge = resetCd.asyncReset(debugReset, ResetSensitivity.HIGH) val resetBridge = resetCd.asyncReset(debugReset, ResetSensitivity.HIGH)
debugAskReset.loadNothing() debugAskReset.loadNothing()
withDebug.load(DEBUG_BUS) withDebug.load(DEBUG_BUS)
if(!withRiscvDebug.isLoaded) withRiscvDebug.load(false)
} }
def enableRiscvDebug(debugCd : Handle[ClockDomain], resetCd : ClockDomainResetGenerator) : Unit = debugCd.on{ def enableRiscvDebug(debugCd : Handle[ClockDomain], resetCd : ClockDomainResetGenerator) : Unit = debugCd.on{
this.debugClockDomain.load(debugCd) this.debugClockDomain.load(debugCd)
debugAskReset.loadNothing() debugAskReset.loadNothing()
withDebug.load(DEBUG_RISCV) withRiscvDebug.load(true)
if(!withDebug.isLoaded) withDebug.load(DEBUG_NONE)
} }
// def enableRiscvAndBusDebugPlus(debugCd : Handle[ClockDomain], resetCd : ClockDomainResetGenerator) : Unit = debugCd.on{
// this.debugClockDomain.load(debugCd)
// val resetBridge = resetCd.asyncReset(debugReset, ResetSensitivity.HIGH)
// debugAskReset.loadNothing()
// withRiscvDebug.load(true)
// }
val debugBmbAccessSource = Handle[BmbAccessCapabilities] val debugBmbAccessSource = Handle[BmbAccessCapabilities]
val debugBmbAccessRequirements = Handle[BmbAccessParameter] val debugBmbAccessRequirements = Handle[BmbAccessParameter]
def enableDebugBmb(debugCd : Handle[ClockDomain], resetCd : ClockDomainResetGenerator, mapping : AddressMapping)(implicit debugMaster : BmbImplicitDebugDecoder = null) : Unit = debugCd.on{ def enableDebugBmb(debugCd : Handle[ClockDomain], resetCd : ClockDomainResetGenerator, mapping : AddressMapping)(implicit debugMaster : BmbImplicitDebugDecoder = null) : Unit = debugCd.on{
@ -78,6 +90,7 @@ case class VexRiscvBmbGenerator()(implicit interconnectSmp: BmbInterconnectGener
val resetBridge = resetCd.asyncReset(debugReset, ResetSensitivity.HIGH) val resetBridge = resetCd.asyncReset(debugReset, ResetSensitivity.HIGH)
debugAskReset.loadNothing() debugAskReset.loadNothing()
withDebug.load(DEBUG_BMB) withDebug.load(DEBUG_BMB)
if(!withRiscvDebug.isLoaded) withRiscvDebug.load(false)
val slaveModel = debugCd on interconnectSmp.addSlave( val slaveModel = debugCd on interconnectSmp.addSlave(
accessSource = debugBmbAccessSource, accessSource = debugBmbAccessSource,
accessCapabilities = debugBmbAccessSource.derivate(DebugExtensionBus.getBmbAccessParameter(_)), accessCapabilities = debugBmbAccessSource.derivate(DebugExtensionBus.getBmbAccessParameter(_)),
@ -93,13 +106,12 @@ case class VexRiscvBmbGenerator()(implicit interconnectSmp: BmbInterconnectGener
val jtagInstructionCtrl = withDebug.produce(withDebug.get == DEBUG_JTAG_CTRL generate JtagTapInstructionCtrl()) val jtagInstructionCtrl = withDebug.produce(withDebug.get == DEBUG_JTAG_CTRL generate JtagTapInstructionCtrl())
val debugBus = withDebug.produce(withDebug.get == DEBUG_BUS generate DebugExtensionBus()) val debugBus = withDebug.produce(withDebug.get == DEBUG_BUS generate DebugExtensionBus())
val debugBmb = Handle[Bmb] val debugBmb = Handle[Bmb]
val debugRiscv = withDebug.produce(withDebug.get == DEBUG_RISCV generate DebugHartBus()) val debugRiscv = withRiscvDebug.produce(withRiscvDebug.get generate DebugHartBus())
val jtagClockDomain = Handle[ClockDomain] val jtagClockDomain = Handle[ClockDomain]
val logic = Handle(new Area { val logic = Handle(new Area {
withDebug.get match { withDebug.get match {
case DEBUG_NONE => case DEBUG_NONE =>
case DEBUG_RISCV =>
case _ => config.add(new DebugPlugin(debugClockDomain, hardwareBreakpointCount)) case _ => config.add(new DebugPlugin(debugClockDomain, hardwareBreakpointCount))
} }
@ -142,13 +154,10 @@ case class VexRiscvBmbGenerator()(implicit interconnectSmp: BmbInterconnectGener
timerInterrupt load plugin.timerInterrupt timerInterrupt load plugin.timerInterrupt
softwareInterrupt load plugin.softwareInterrupt softwareInterrupt load plugin.softwareInterrupt
if (plugin.config.supervisorGen) externalSupervisorInterrupt load plugin.externalInterruptS if (plugin.config.supervisorGen) externalSupervisorInterrupt load plugin.externalInterruptS
withDebug.get match { if(withRiscvDebug.get) {
case DEBUG_RISCV => {
assert(plugin.debugBus != null, "You need to enable CsrPluginConfig.withPrivilegedDebug") assert(plugin.debugBus != null, "You need to enable CsrPluginConfig.withPrivilegedDebug")
debugRiscv <> plugin.debugBus debugRiscv <> plugin.debugBus
} }
case _ =>
}
} }
case plugin: DebugPlugin => plugin.debugClockDomain { case plugin: DebugPlugin => plugin.debugClockDomain {
if(debugAskReset.get != null) when(RegNext(plugin.io.resetOut)) { if(debugAskReset.get != null) when(RegNext(plugin.io.resetOut)) {

View File

@ -641,7 +641,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
xretAwayFromMachine = False xretAwayFromMachine = False
injectionPort = withPrivilegedDebug generate pipeline.service(classOf[IBusFetcher]).getInjectionPort() injectionPort = withPrivilegedDebug generate pipeline.service(classOf[IBusFetcher]).getInjectionPort().setCompositeName(this, "injectionPort")
debugMode = withPrivilegedDebug generate Bool().setName("debugMode") debugMode = withPrivilegedDebug generate Bool().setName("debugMode")
debugBus = withPrivilegedDebug generate slave(DebugHartBus()).setName("debugBus") debugBus = withPrivilegedDebug generate slave(DebugHartBus()).setName("debugBus")
} }

View File

@ -209,7 +209,7 @@ class DebugPlugin(var debugClockDomain : ClockDomain, hardwareBreakpointCount :
decoderService.addDefault(IS_EBREAK, False) decoderService.addDefault(IS_EBREAK, False)
decoderService.add(EBREAK,List(IS_EBREAK -> True)) decoderService.add(EBREAK,List(IS_EBREAK -> True))
injectionPort = pipeline.service(classOf[IBusFetcher]).getInjectionPort() injectionPort = pipeline.service(classOf[IBusFetcher]).getInjectionPort().setCompositeName(this, "injectionPort")
if(pipeline.serviceExist(classOf[ReportService])){ if(pipeline.serviceExist(classOf[ReportService])){
val report = pipeline.service(classOf[ReportService]) val report = pipeline.service(classOf[ReportService])

View File

@ -42,10 +42,9 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
override def withRvc(): Boolean = compressedGen override def withRvc(): Boolean = compressedGen
var injectionPort : Stream[Bits] = null val injectionPorts = ArrayBuffer[Stream[Bits]]()
override def getInjectionPort() = { override def getInjectionPort() = {
injectionPort = Stream(Bits(32 bits)) injectionPorts.addRet(Stream(Bits(32 bits)))
injectionPort
} }
def pcRegReusedForSecondStage = allowPcRegReusedForSecondStage && prediction != DYNAMIC_TARGET //TODO might not be required for DYNAMIC_TARGET def pcRegReusedForSecondStage = allowPcRegReusedForSecondStage && prediction != DYNAMIC_TARGET //TODO might not be required for DYNAMIC_TARGET
var predictionJumpInterface : Flow[UInt] = null var predictionJumpInterface : Flow[UInt] = null
@ -354,9 +353,20 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
decode.insert(INSTRUCTION) := decodeInput.rsp.inst decode.insert(INSTRUCTION) := decodeInput.rsp.inst
if (compressedGen) decode.insert(IS_RVC) := decodeInput.isRvc if (compressedGen) decode.insert(IS_RVC) := decodeInput.isRvc
if (injectionPort != null) { if (injectionPorts.nonEmpty) {
Component.current.addPrePopTask(() => { Component.current.addPrePopTask(() => new Composite(this, "port"){
val state = RegInit(U"000") val state = RegInit(U"000")
val injectionPort = injectionPorts.size match {
case 1 => injectionPorts.head
case _ => {
val p = Stream(Bits(32 bits))
//assume only one port is used at the time
p.valid := injectionPorts.map(_.valid).orR
p.payload := OHMux(injectionPorts.map(_.valid), injectionPorts.map(_.payload))
injectionPorts.foreach(_.ready := p.ready)
p
}
}
injectionPort.ready := False injectionPort.ready := False
if(decodePcGen){ if(decodePcGen){