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