From 7b16a19522c3d3d9823c4df6631363695d401ac2 Mon Sep 17 00:00:00 2001 From: ngc7331 Date: Tue, 2 Dec 2025 17:03:44 +0800 Subject: [PATCH 1/2] feat(perf): add XSPerfPriorityAccumulate --- src/main/scala/utility/PerfCounterUtils.scala | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/main/scala/utility/PerfCounterUtils.scala b/src/main/scala/utility/PerfCounterUtils.scala index 2a7612b..d81b459 100644 --- a/src/main/scala/utility/PerfCounterUtils.scala +++ b/src/main/scala/utility/PerfCounterUtils.scala @@ -81,6 +81,60 @@ object XSPerfAccumulate extends HasRegularPerfName with XSLogTap { } } +object XSPerfPriorityAccumulate { + /** + * A utility to generate a sequence of XSPerfAccumulate with priority + * @param perfNamePrefix The prefix of the performance counter names + * @param perfValid A common valid signal for all performance counters + * @param perfCntSeq A sequence of (name: String, valid: Bool) or (name: String, valid: Bool, value: UInt) + * @param perfLevel Logging level of these perf counters + * + * @example {{{ + * // accumulate boolean conditions + * XSPerfAccumulate("perf_a", valid && cond_a) + * XSPerfAccumulate("perf_b", valid && !cond_a && cond_b) + * XSPerfAccumulate("perf_c", valid && !cond_a && !cond_b && cond_c) + * // becomes: + * XSPerfPriorityAccumulate("perf", valid, Seq( + * ("a", cond_a), + * ("b", cond_b), + * ("c", cond_c) + * )) + * }}} + * + * @example {{{ + * // accumulate values with conditions + * XSPerfAccumulate("perf_a", Mux(valid && cond_a, value_a, 0.U)) + * XSPerfAccumulate("perf_b", Mux(valid && !cond_a && cond_b, value_b, 0.U)) + * XSPerfAccumulate("perf_c", Mux(valid && !cond_a && !cond_b && cond_c, value_c, 0.U)) + * // becomes: + * XSPerfPriorityAccumulate("perf", valid, Seq( + * ("a", cond_a, value_a), + * ("b", cond_b, value_b), + * ("c", cond_c, value_c) + * )) + * }}} + */ + def apply( + perfNamePrefix: String, + perfValid: Bool, + perfCntSeq: Seq[Product], + perfLevel: XSPerfLevel = XSPerfLevel.VERBOSE + )(implicit p: Parameters): Unit = { + var previousValid = false.B + perfCntSeq.foreach { + case (name: String, valid: Bool, value: UInt) => + XSPerfAccumulate(s"${perfNamePrefix}_$name", Mux(perfValid && !previousValid && valid, value, 0.U), perfLevel) + previousValid = previousValid || valid + case (name: String, valid: Bool) => + XSPerfAccumulate(s"${perfNamePrefix}_$name", perfValid && !previousValid && valid, perfLevel) + previousValid = previousValid || valid + case _ => + throw new Exception("XSPerfPriorityAccumulate perfCntSeq must be Seq[(String, Bool)] or [(String, Bool, UInt)]") + } + } +} + object XSPerfReference extends HasRegularPerfName with XSLogTap { private val perfInfos = ListBuffer.empty[(Option[BaseModule], String, UInt)] def apply(perfName: String, perfOut: UInt, perfLevel: XSPerfLevel = XSPerfLevel.VERBOSE) From 489a5987abff0dfd6535a47dcbf09b8facef94d9 Mon Sep 17 00:00:00 2001 From: Muzi Date: Wed, 3 Dec 2025 11:27:10 +0800 Subject: [PATCH 2/2] feat(perf): add prefix mode for XSPerfAccumulate --- src/main/scala/utility/PerfCounterUtils.scala | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/scala/utility/PerfCounterUtils.scala b/src/main/scala/utility/PerfCounterUtils.scala index d81b459..b2d5ecb 100644 --- a/src/main/scala/utility/PerfCounterUtils.scala +++ b/src/main/scala/utility/PerfCounterUtils.scala @@ -79,6 +79,21 @@ object XSPerfAccumulate extends HasRegularPerfName with XSLogTap { XSPerfPrint(curMod)(perfDump, p"$perfName, $next_counter\n") } } + + def apply( + perfNamePrefix: String, + perfValid: Bool, + perfCntSeq: Seq[Product], + )(implicit p: Parameters): Unit = { + perfCntSeq.foreach { + case (name: String, valid: Bool, value: UInt) => + XSPerfAccumulate(s"${perfNamePrefix}_$name", Mux(perfValid && valid, value, 0.U), XSPerfLevel.VERBOSE) + case (name: String, valid: Bool) => + XSPerfAccumulate(s"${perfNamePrefix}_$name", perfValid && valid, XSPerfLevel.VERBOSE) + case _ => + throw new Exception("XSPerfAccumulate perfCntSeq must be Seq[(String, Bool)] or [(String, Bool, UInt)]") + } + } } object XSPerfPriorityAccumulate {