Alows Fetcher to have multiple debug injection ports
This commit is contained in:
parent
5f67075e30
commit
5493c55ab0
|
@ -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,12 +154,9 @@ 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 {
|
||||||
|
@ -160,7 +169,7 @@ case class VexRiscvBmbGenerator()(implicit interconnectSmp: BmbInterconnectGener
|
||||||
withDebug.get match {
|
withDebug.get match {
|
||||||
case DEBUG_JTAG => jtag <> plugin.io.bus.fromJtag()
|
case DEBUG_JTAG => jtag <> plugin.io.bus.fromJtag()
|
||||||
case DEBUG_JTAG_CTRL => jtagInstructionCtrl <> plugin.io.bus.fromJtagInstructionCtrl(jtagClockDomain, 0)
|
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()
|
case DEBUG_BMB => debugBmb >> plugin.io.bus.fromBmb()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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])
|
||||||
|
|
|
@ -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){
|
||||||
|
|
Loading…
Reference in New Issue