xref: /XiangShan/src/main/scala/top/BusPerfMonitor.scala (revision 73be64b3fc882a759f70d0852ba42d09c2a44af6)
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