xref: /XiangShan/src/main/scala/device/RocketDebugWrapper.scala (revision 20957846171de148318edbfc667a5748881f7e03)
1/***************************************************************************************
2* Copyright (c) 2021-2025 Beijing Institute of Open Source Chip (BOSC)
3* Copyright (c) 2020-2025 Institute of Computing Technology, Chinese Academy of Sciences
4* Copyright (c) 2020-2021 Peng Cheng Laboratory
5*
6* XiangShan is licensed under Mulan PSL v2.
7* You can use this software according to the terms and conditions of the Mulan PSL v2.
8* You may obtain a copy of Mulan PSL v2 at:
9*          http://license.coscl.org.cn/MulanPSL2
10*
11* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
12* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
13* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
14*
15* See the Mulan PSL v2 for more details.
16***************************************************************************************/
17
18package device
19
20import chisel3._
21import xiangshan._
22import chisel3.experimental.{ExtModule, IntParam, noPrefix}
23import chisel3.util._
24import chisel3.util.HasExtModuleResource
25import org.chipsalliance.cde.config.{Field, Parameters}
26import freechips.rocketchip.subsystem._
27import freechips.rocketchip.amba.apb._
28import freechips.rocketchip.diplomacy._
29import freechips.rocketchip.jtag._
30import freechips.rocketchip.util._
31import freechips.rocketchip.prci.{ClockSinkNode, ClockSinkParameters}
32import freechips.rocketchip.tilelink._
33import freechips.rocketchip.devices.debug.{DebugCustomXbar, DebugIO, DebugTransportModuleJTAG, JtagDTMConfig, PSDIO, ResetCtrlIO, SystemJTAGIO, TLDebugModule}
34import freechips.rocketchip.devices.debug._
35
36// this file uses code from rocketchip Periphery.scala
37// to simplify the code we remove options for apb, cjtag and dmi
38// this module creates wrapped dm and dtm
39
40
41class DebugModule(numCores: Int)(implicit p: Parameters) extends LazyModule {
42
43  val debug = LazyModule(new TLDebugModule(8)(p))
44
45//  debug.node := TLFragmenter() := peripheralXbar
46  val debugCustomXbarOpt = p(DebugModuleKey).map(params => LazyModule( new DebugCustomXbar(outputRequiresInput = false)))
47  debug.dmInner.dmInner.customNode := debugCustomXbarOpt.get.node
48
49//  debug.dmInner.dmInner.sb2tlOpt.foreach { sb2tl  =>
50//    l2xbar := TLBuffer() := TLWidthWidget(1) := sb2tl.node
51//  }
52  class DebugModuleIO extends Bundle {
53    val resetCtrl = new ResetCtrlIO(numCores)(p)
54    val debugIO = new DebugIO()(p)
55    val clock = Input(Clock())
56    val reset = Input(Reset())
57  }
58
59  class DebugModuleImp(wrapper: LazyModule) extends LazyRawModuleImp(wrapper) {
60    val io = IO(new DebugModuleIO)
61    debug.module.io.tl_reset := io.reset // this should be TL reset
62    debug.module.io.tl_clock := io.clock // this should be TL clock
63    withClock(io.clock) {
64      debug.module.io.hartIsInReset := RegNext(io.resetCtrl.hartIsInReset)
65    }
66    io.resetCtrl.hartResetReq.foreach { rcio => debug.module.io.hartResetReq.foreach { rcdm => rcio := rcdm }}
67
68    io.debugIO.clockeddmi.foreach { dbg => debug.module.io.dmi.get <> dbg } // not connected in current case since we use dtm
69    debug.module.io.debug_reset := io.debugIO.reset
70    debug.module.io.debug_clock := io.debugIO.clock
71    io.debugIO.ndreset := debug.module.io.ctrl.ndreset
72    io.debugIO.dmactive := debug.module.io.ctrl.dmactive
73    debug.module.io.ctrl.dmactiveAck := io.debugIO.dmactiveAck
74    io.debugIO.extTrigger.foreach { x => debug.module.io.extTrigger.foreach {y => x <> y}}
75    debug.module.io.ctrl.debugUnavail.foreach { _ := false.B }
76
77    val dtm = io.debugIO.systemjtag.map(instantiateJtagDTM(_))
78
79    def instantiateJtagDTM(sj: SystemJTAGIO): DebugTransportModuleJTAG = {
80      val c = new JtagDTMKeyDefault
81      val dtm = Module(new DebugTransportModuleJTAG(p(DebugModuleKey).get.nDMIAddrSize, c))
82      dtm.io.jtag <> sj.jtag
83
84      io.debugIO.disableDebug.foreach { x => dtm.io.jtag.TMS := sj.jtag.TMS | x }  // force TMS high when debug is disabled
85
86      dtm.io.jtag_clock  := sj.jtag.TCK
87      dtm.io.jtag_reset  := sj.reset
88      dtm.io.jtag_mfr_id := sj.mfr_id
89      dtm.io.jtag_part_number := sj.part_number
90      dtm.io.jtag_version := sj.version
91      dtm.rf_reset := sj.reset
92      debug.module.io.dmi.get.dmi <> dtm.io.dmi
93      debug.module.io.dmi.get.dmiClock := sj.jtag.TCK
94      debug.module.io.dmi.get.dmiReset := sj.reset
95      dtm
96    }
97  }
98
99  lazy val module = new DebugModuleImp(this)
100}
101
102case object EnableJtag extends Field[Bool]
103
104class SimJTAG(tickDelay: Int = 50)(implicit val p: Parameters) extends ExtModule(Map("TICK_DELAY" -> IntParam(tickDelay)))
105  with HasExtModuleResource {
106
107  val clock = IO(Input(Clock()))
108  val reset = IO(Input(Reset()))
109  val jtag = IO(new JTAGIO(hasTRSTn = true))
110  val enable = IO(Input(Bool()))
111  val init_done = IO(Input(Bool()))
112  val exit = IO(Output(UInt(32.W)))
113
114  def connect(dutio: JTAGIO, tbclock: Clock, tbreset: Reset, done: Bool, tbsuccess: Bool) = {
115    if (!dutio.TRSTn.isEmpty) {
116      dutio.TRSTn.get := jtag.TRSTn.getOrElse(false.B) || !tbreset.asBool
117    }
118    dutio.TCK := jtag.TCK
119    dutio.TMS := jtag.TMS
120    dutio.TDI := jtag.TDI
121    jtag.TDO := dutio.TDO
122
123    clock := tbclock
124    reset := tbreset
125
126    enable    := p(EnableJtag)
127    init_done := done
128
129    // Success is determined by the gdbserver
130    // which is controlling this simulation.
131    tbsuccess := exit === 1.U
132    when (exit >= 2.U) {
133      printf("*** FAILED *** (exit code = %d)\n", exit >> 1.U)
134      stop()
135    }
136  }
137}
138