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