1package top 2 3import chipsalliance.rocketchip.config.Parameters 4import freechips.rocketchip.diplomacy.{AdapterNode, LazyModule, LazyModuleImp} 5import freechips.rocketchip.tilelink._ 6import chisel3._ 7import chisel3.util._ 8import utils.{XSPerfAccumulate, XSPerfPrint} 9 10class BusPerfMonitor()(implicit p: Parameters) extends LazyModule { 11 val node = TLAdapterNode() 12 lazy val module = new BusPerfMonitorImp(this) 13} 14 15class BusPerfMonitorImp(outer: BusPerfMonitor) 16 extends LazyModuleImp(outer) 17{ 18 19 outer.node.in.zip(outer.node.out).foreach{ 20 case ((in, edgeIn), (out, edgeOut)) => 21 out <> in 22 } 23 24 def PERF_CHN[T <: TLChannel](clientName: String, chn: DecoupledIO[T]) = { 25 26 val channelName = chn.bits.channelName.replaceAll(" ", "_").replaceAll("'", "") 27 XSPerfAccumulate(s"${clientName}_${channelName}_fire", chn.fire()) 28 XSPerfAccumulate(s"${clientName}_${channelName}_stall", chn.valid && !chn.ready) 29 30 val ops = chn.bits match { 31 case _: TLBundleA => TLMessages.a.map(_._1) 32 case _: TLBundleB => TLMessages.b.map(_._1) 33 case _: TLBundleC => TLMessages.c.map(_._1) 34 case _: TLBundleD => TLMessages.d.map(_._1) 35 case _: TLBundleE => Nil 36 } 37 38 for((op_raw, i) <- ops.zipWithIndex){ 39 val op = s"${op_raw}".replaceAll(" ", "_") 40 chn.bits match { 41 case a: TLBundleA => 42 XSPerfAccumulate(s"${clientName}_${channelName}_${op}_fire", 43 i.U === a.opcode && chn.fire() 44 ) 45 XSPerfAccumulate(s"${clientName}_${channelName}_${op}_stall", 46 i.U === a.opcode && chn.valid && !chn.ready 47 ) 48 case b: TLBundleB => 49 XSPerfAccumulate(s"${clientName}_${channelName}_${op}_fire", 50 i.U === b.opcode && chn.fire() 51 ) 52 XSPerfAccumulate(s"${clientName}_${channelName}_${op}_stall", 53 i.U === b.opcode && chn.valid && !chn.ready 54 ) 55 case c: TLBundleC => 56 XSPerfAccumulate(s"${clientName}_${channelName}_${op}_fire", 57 i.U === c.opcode && chn.fire() 58 ) 59 XSPerfAccumulate(s"${clientName}_${channelName}_${op}_stall", 60 i.U === c.opcode && chn.valid && !chn.ready 61 ) 62 case d: TLBundleD => 63 XSPerfAccumulate(s"${clientName}_${channelName}_${op}_fire", 64 i.U === d.opcode && chn.fire() 65 ) 66 XSPerfAccumulate(s"${clientName}_${channelName}_${op}_stall", 67 i.U === d.opcode && chn.valid && !chn.ready 68 ) 69 } 70 } 71 } 72 73 for(((in, edgeIn), i) <- outer.node.in.zipWithIndex) { 74 val clientName = s"${edgeIn.master.masters.head.name}_bank_$i" 75 PERF_CHN(clientName, in.a) 76 PERF_CHN(clientName, in.d) 77 if(in.params.hasBCE){ 78 PERF_CHN(clientName, in.b) 79 PERF_CHN(clientName, in.c) 80 PERF_CHN(clientName, in.e) 81 } 82 } 83} 84 85object BusPerfMonitor { 86 def apply(enable: Boolean = false)(implicit p: Parameters) = { 87 if(enable){ 88 val busPMU = LazyModule(new BusPerfMonitor()) 89 busPMU.node 90 } else { 91 TLTempNode() 92 } 93 } 94} 95