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