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 XSPerfAccumulate(s"$clientName ${chn.bits.channelName} fire", chn.fire()) 27 XSPerfAccumulate(s"$clientName ${chn.bits.channelName} stall", chn.valid && !chn.ready) 28 29 val ops = chn.bits match { 30 case _: TLBundleA => TLMessages.a.map(_._1) 31 case _: TLBundleB => TLMessages.b.map(_._1) 32 case _: TLBundleC => TLMessages.c.map(_._1) 33 case _: TLBundleD => TLMessages.d.map(_._1) 34 case _: TLBundleE => Nil 35 } 36 for((op, i) <- ops.zipWithIndex){ 37 chn.bits match { 38 case a: TLBundleA => 39 XSPerfAccumulate(s"$clientName ${chn.bits.channelName} $op fire", 40 i.U === a.opcode && chn.fire() 41 ) 42 XSPerfAccumulate(s"$clientName ${chn.bits.channelName} $op stall", 43 i.U === a.opcode && chn.valid && !chn.ready 44 ) 45 case b: TLBundleB => 46 XSPerfAccumulate(s"$clientName ${chn.bits.channelName} $op fire", 47 i.U === b.opcode && chn.fire() 48 ) 49 XSPerfAccumulate(s"$clientName ${chn.bits.channelName} $op stall", 50 i.U === b.opcode && chn.valid && !chn.ready 51 ) 52 case c: TLBundleC => 53 XSPerfAccumulate(s"$clientName ${chn.bits.channelName} $op fire", 54 i.U === c.opcode && chn.fire() 55 ) 56 XSPerfAccumulate(s"$clientName ${chn.bits.channelName} $op stall", 57 i.U === c.opcode && chn.valid && !chn.ready 58 ) 59 case d: TLBundleD => 60 XSPerfAccumulate(s"$clientName ${chn.bits.channelName} $op fire", 61 i.U === d.opcode && chn.fire() 62 ) 63 XSPerfAccumulate(s"$clientName ${chn.bits.channelName} $op stall", 64 i.U === d.opcode && chn.valid && !chn.ready 65 ) 66 } 67 } 68 } 69 70 for(((in, edgeIn), i) <- outer.node.in.zipWithIndex) { 71 val clientName = s"${edgeIn.master.masters.head.name}_bank_$i" 72 PERF_CHN(clientName, in.a) 73 PERF_CHN(clientName, in.d) 74 if(in.params.hasBCE){ 75 PERF_CHN(clientName, in.b) 76 PERF_CHN(clientName, in.c) 77 PERF_CHN(clientName, in.e) 78 } 79 } 80} 81 82object BusPerfMonitor { 83 def apply(enable: Boolean = false)(implicit p: Parameters) = { 84 if(enable){ 85 val busPMU = LazyModule(new BusPerfMonitor()) 86 busPMU.node 87 } else { 88 TLTempNode() 89 } 90 } 91} 92