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