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