xref: /XiangShan/src/main/scala/device/RocketDebugWrapper.scala (revision c21bff99db38ffd5df19a9459a048e16b7b7cb23)
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.{IntParam, noPrefix}
22import chisel3.util._
23import chisel3.util.HasBlackBoxResource
24import Chisel.BlackBox
25import freechips.rocketchip.config.{Field, Parameters}
26import freechips.rocketchip.subsystem._
27import freechips.rocketchip.amba.apb._
28import freechips.rocketchip.diplomacy._
29import freechips.rocketchip.diplomaticobjectmodel.logicaltree.LogicalModuleTree
30import freechips.rocketchip.jtag._
31import freechips.rocketchip.util._
32import freechips.rocketchip.prci.{ClockSinkParameters, ClockSinkNode}
33import freechips.rocketchip.tilelink._
34import freechips.rocketchip.devices.debug.{JtagDTMConfig, TLDebugModule, DebugCustomXbar, ResetCtrlIO, DebugIO, SystemJTAGIO, DebugTransportModuleJTAG, PSDIO}
35import freechips.rocketchip.diplomaticobjectmodel.logicaltree.GenericLogicalTreeNode
36import freechips.rocketchip.devices.debug._
37
38// this file uses code from rocketchip Periphery.scala
39// to simplify the code we remove options for apb, cjtag and dmi
40// this module creates wrapped dm and dtm
41
42class DebugModule(numCores: Int)(implicit p: Parameters) extends LazyModule {
43
44  val debug = LazyModule(new TLDebugModule(8)(p))
45
46//  debug.node := TLFragmenter() := peripheralXbar
47  val debugCustomXbarOpt = p(DebugModuleKey).map(params => LazyModule( new DebugCustomXbar(outputRequiresInput = false)))
48  debug.dmInner.dmInner.customNode := debugCustomXbarOpt.get.node
49
50//  debug.dmInner.dmInner.sb2tlOpt.foreach { sb2tl  =>
51//    l2xbar := TLBuffer() := TLWidthWidget(1) := sb2tl.node
52//  }
53  val fakeTreeNode = new GenericLogicalTreeNode
54  LogicalModuleTree.add(fakeTreeNode, debug.logicalTreeNode)
55
56  lazy val module = new LazyRawModuleImp(this) {
57    val io = IO(new Bundle{
58      val resetCtrl = new ResetCtrlIO(numCores)(p)
59      val debugIO = new DebugIO()(p)
60      val clock = Input(Bool())
61      val reset = Input(Bool())
62    })
63    debug.module.io.tl_reset := io.reset // this should be TL reset
64    debug.module.io.tl_clock := io.clock.asClock // this should be TL clock
65    debug.module.io.hartIsInReset := io.resetCtrl.hartIsInReset
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
100object XSDebugModuleParams {
101
102  def apply(xlen:Int /*TODO , val configStringAddr: Int*/): DebugModuleParams = {
103    new DebugModuleParams().copy(
104      nAbstractDataWords   = (if (xlen == 32) 1 else if (xlen == 64) 2 else 4),
105      maxSupportedSBAccess = xlen,
106      hasBusMaster = true,
107      baseAddress = BigInt(0x38020000),
108      nScratch = 2
109    )
110  }
111}
112
113case object EnableJtag extends Field[Bool]
114
115class SimJTAG(tickDelay: Int = 50)(implicit val p: Parameters) extends BlackBox(Map("TICK_DELAY" -> IntParam(tickDelay)))
116  with HasBlackBoxResource {
117  val io = IO(new Bundle {
118    val clock = Input(Clock())
119    val reset = Input(Bool())
120    val jtag = new JTAGIO(hasTRSTn = true)
121    val enable = Input(Bool())
122    val init_done = Input(Bool())
123    val exit = Output(UInt(32.W))
124  })
125
126  def connect(dutio: JTAGIO, tbclock: Clock, tbreset: Bool, init_done: Bool, tbsuccess: Bool) = {
127    dutio.TCK := io.jtag.TCK
128    dutio.TMS := io.jtag.TMS
129    dutio.TDI := io.jtag.TDI
130    io.jtag.TDO := dutio.TDO
131
132    io.clock := tbclock
133    io.reset := tbreset
134
135    io.enable    := p(EnableJtag)
136    io.init_done := init_done
137
138    // Success is determined by the gdbserver
139    // which is controlling this simulation.
140    tbsuccess := io.exit === 1.U
141    when (io.exit >= 2.U) {
142      printf("*** FAILED *** (exit code = %d)\n", io.exit >> 1.U)
143      stop(1)
144    }
145  }
146}
147