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