From 5493c55ab0b618d3af7f725caaa7eafe954842c5 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Fri, 3 Mar 2023 09:06:20 +0100 Subject: [PATCH] Alows Fetcher to have multiple debug injection ports --- .../scala/vexriscv/VexRiscvBmbGenerator.scala | 31 ++++++++++++------- .../scala/vexriscv/plugin/CsrPlugin.scala | 2 +- .../scala/vexriscv/plugin/DebugPlugin.scala | 2 +- src/main/scala/vexriscv/plugin/Fetcher.scala | 20 +++++++++--- 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/main/scala/vexriscv/VexRiscvBmbGenerator.scala b/src/main/scala/vexriscv/VexRiscvBmbGenerator.scala index 7468c85..2754d39 100644 --- a/src/main/scala/vexriscv/VexRiscvBmbGenerator.scala +++ b/src/main/scala/vexriscv/VexRiscvBmbGenerator.scala @@ -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,12 +154,9 @@ 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 => { - assert(plugin.debugBus != null, "You need to enable CsrPluginConfig.withPrivilegedDebug") - debugRiscv <> plugin.debugBus - } - case _ => + if(withRiscvDebug.get) { + assert(plugin.debugBus != null, "You need to enable CsrPluginConfig.withPrivilegedDebug") + debugRiscv <> plugin.debugBus } } case plugin: DebugPlugin => plugin.debugClockDomain { @@ -160,7 +169,7 @@ case class VexRiscvBmbGenerator()(implicit interconnectSmp: BmbInterconnectGener withDebug.get match { case DEBUG_JTAG => jtag <> plugin.io.bus.fromJtag() case DEBUG_JTAG_CTRL => jtagInstructionCtrl <> plugin.io.bus.fromJtagInstructionCtrl(jtagClockDomain, 0) - case DEBUG_BUS => debugBus <> plugin.io.bus + case DEBUG_BUS => debugBus <> plugin.io.bus case DEBUG_BMB => debugBmb >> plugin.io.bus.fromBmb() } } diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index a53363c..c1b6bec 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -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") } diff --git a/src/main/scala/vexriscv/plugin/DebugPlugin.scala b/src/main/scala/vexriscv/plugin/DebugPlugin.scala index d62c4de..485e380 100644 --- a/src/main/scala/vexriscv/plugin/DebugPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DebugPlugin.scala @@ -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]) diff --git a/src/main/scala/vexriscv/plugin/Fetcher.scala b/src/main/scala/vexriscv/plugin/Fetcher.scala index f793084..e9b40f5 100644 --- a/src/main/scala/vexriscv/plugin/Fetcher.scala +++ b/src/main/scala/vexriscv/plugin/Fetcher.scala @@ -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){