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_BUS = 3
val DEBUG_BMB = 4
val DEBUG_RISCV = 5
}
case class VexRiscvBmbGenerator()(implicit interconnectSmp: BmbInterconnectGenerator = null) extends Area {
@ -24,6 +23,7 @@ case class VexRiscvBmbGenerator()(implicit interconnectSmp: BmbInterconnectGener
val config = Handle[VexRiscvConfig]
val withDebug = Handle[Int]
val withRiscvDebug = Handle[Boolean]
val debugClockDomain = Handle[ClockDomain]
val debugReset = Handle[Bool]
val debugAskReset = Handle[() => Unit]
@ -42,6 +42,7 @@ case class VexRiscvBmbGenerator()(implicit interconnectSmp: BmbInterconnectGener
def disableDebug() = {
withDebug.load(DEBUG_NONE)
withRiscvDebug.load(false)
}
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)
debugAskReset.loadNothing()
withDebug.load(DEBUG_JTAG)
if(!withRiscvDebug.isLoaded) withRiscvDebug.load(false)
}
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)
debugAskReset.loadNothing()
withDebug.load(DEBUG_JTAG_CTRL)
if(!withRiscvDebug.isLoaded) withRiscvDebug.load(false)
}
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)
debugAskReset.loadNothing()
withDebug.load(DEBUG_BUS)
if(!withRiscvDebug.isLoaded) withRiscvDebug.load(false)
}
def enableRiscvDebug(debugCd : Handle[ClockDomain], resetCd : ClockDomainResetGenerator) : Unit = debugCd.on{
this.debugClockDomain.load(debugCd)
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 debugBmbAccessRequirements = Handle[BmbAccessParameter]
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)
debugAskReset.loadNothing()
withDebug.load(DEBUG_BMB)
if(!withRiscvDebug.isLoaded) withRiscvDebug.load(false)
val slaveModel = debugCd on interconnectSmp.addSlave(
accessSource = debugBmbAccessSource,
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 debugBus = withDebug.produce(withDebug.get == DEBUG_BUS generate DebugExtensionBus())
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 logic = Handle(new Area {
withDebug.get match {
case DEBUG_NONE =>
case DEBUG_RISCV =>
case _ => config.add(new DebugPlugin(debugClockDomain, hardwareBreakpointCount))
}
@ -142,13 +154,10 @@ case class VexRiscvBmbGenerator()(implicit interconnectSmp: BmbInterconnectGener
timerInterrupt load plugin.timerInterrupt
softwareInterrupt load plugin.softwareInterrupt
if (plugin.config.supervisorGen) externalSupervisorInterrupt load plugin.externalInterruptS
withDebug.get match {
case DEBUG_RISCV => {
if(withRiscvDebug.get) {
assert(plugin.debugBus != null, "You need to enable CsrPluginConfig.withPrivilegedDebug")
debugRiscv <> plugin.debugBus
}
case _ =>
}
}
case plugin: DebugPlugin => plugin.debugClockDomain {
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
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")
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.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])){
val report = pipeline.service(classOf[ReportService])

View File

@ -42,10 +42,9 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
override def withRvc(): Boolean = compressedGen
var injectionPort : Stream[Bits] = null
val injectionPorts = ArrayBuffer[Stream[Bits]]()
override def getInjectionPort() = {
injectionPort = Stream(Bits(32 bits))
injectionPort
injectionPorts.addRet(Stream(Bits(32 bits)))
}
def pcRegReusedForSecondStage = allowPcRegReusedForSecondStage && prediction != DYNAMIC_TARGET //TODO might not be required for DYNAMIC_TARGET
var predictionJumpInterface : Flow[UInt] = null
@ -354,9 +353,20 @@ abstract class IBusFetcherImpl(val resetVector : BigInt,
decode.insert(INSTRUCTION) := decodeInput.rsp.inst
if (compressedGen) decode.insert(IS_RVC) := decodeInput.isRvc
if (injectionPort != null) {
Component.current.addPrePopTask(() => {
if (injectionPorts.nonEmpty) {
Component.current.addPrePopTask(() => new Composite(this, "port"){
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
if(decodePcGen){