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