1 /*
2 * SPDX-FileCopyrightText: <text>Copyright 2025 Arm Limited and/or its
3 * affiliates <open-source-office@arm.com></text>
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /* PMU integration for Ethos-U in Zephyr TFLM sample */
8
9 #include <ethosu_driver.h>
10 #include <pmu_ethosu.h>
11
12 #include <cinttypes>
13 #include <cstdio>
14
15 /* Selected PMU events (configured via CMake definitions ETHOSU_PMU_EVENT_N) */
16 static const enum ethosu_pmu_event_type pmu_events[ETHOSU_PMU_NCOUNTERS] = {
17 ETHOSU_PMU_EVENT_0, ETHOSU_PMU_EVENT_1, ETHOSU_PMU_EVENT_2, ETHOSU_PMU_EVENT_3,
18 #if (ETHOSU_PMU_NCOUNTERS > 4)
19 ETHOSU_PMU_EVENT_4, ETHOSU_PMU_EVENT_5, ETHOSU_PMU_EVENT_6, ETHOSU_PMU_EVENT_7,
20 #endif
21 };
22
pmu_counter_mask(uint32_t idx)23 static inline uint32_t pmu_counter_mask(uint32_t idx)
24 {
25 switch (idx) {
26 case 0:
27 return ETHOSU_PMU_CNT1_Msk;
28 case 1:
29 return ETHOSU_PMU_CNT2_Msk;
30 case 2:
31 return ETHOSU_PMU_CNT3_Msk;
32 case 3:
33 return ETHOSU_PMU_CNT4_Msk;
34 #if (ETHOSU_PMU_NCOUNTERS > 4)
35 case 4:
36 return ETHOSU_PMU_CNT5_Msk;
37 case 5:
38 return ETHOSU_PMU_CNT6_Msk;
39 case 6:
40 return ETHOSU_PMU_CNT7_Msk;
41 case 7:
42 return ETHOSU_PMU_CNT8_Msk;
43 #endif
44 default:
45 return 0;
46 }
47 }
48
ethosu_inference_begin(struct ethosu_driver * drv,void *)49 extern "C" void ethosu_inference_begin(struct ethosu_driver *drv, void *)
50 {
51 ETHOSU_PMU_Enable(drv);
52
53 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; ++i) {
54 ETHOSU_PMU_Set_EVTYPER(drv, i, pmu_events[i]);
55 ETHOSU_PMU_CNTR_Enable(drv, pmu_counter_mask(i));
56 }
57
58 ETHOSU_PMU_PMCCNTR_CFG_Set_Stop_Event(drv, ETHOSU_PMU_NPU_IDLE);
59 ETHOSU_PMU_PMCCNTR_CFG_Set_Start_Event(drv, ETHOSU_PMU_NPU_ACTIVE);
60 ETHOSU_PMU_CNTR_Enable(drv, ETHOSU_PMU_CCNT_Msk);
61 ETHOSU_PMU_CYCCNT_Reset(drv);
62 ETHOSU_PMU_EVCNTR_ALL_Reset(drv);
63 }
64
ethosu_inference_end(struct ethosu_driver * drv,void *)65 extern "C" void ethosu_inference_end(struct ethosu_driver *drv, void *)
66 {
67 const uint64_t cycles = ETHOSU_PMU_Get_CCNTR(drv);
68
69 uint32_t pmu_values[ETHOSU_PMU_NCOUNTERS] = {};
70 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; ++i) {
71 pmu_values[i] = ETHOSU_PMU_Get_EVCNTR(drv, i);
72 }
73 ETHOSU_PMU_Disable(drv);
74
75 printf("\nEthos-U PMU report:\n");
76 printf("ethosu_pmu_cycle_cntr : %" PRIu64 "\n", cycles);
77 for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; ++i) {
78 printf("ethosu_pmu_cntr%" PRIu32 " : %" PRIu32 "\n", i, pmu_values[i]);
79 }
80 }
81