/*
* SPDX-FileCopyrightText: Copyright 2025 Arm Limited and/or its
* affiliates
* SPDX-License-Identifier: Apache-2.0
*/
/* PMU integration for Ethos-U in Zephyr TFLM sample */
#include
#include
#include
#include
/* Selected PMU events (configured via CMake definitions ETHOSU_PMU_EVENT_N) */
static const enum ethosu_pmu_event_type pmu_events[ETHOSU_PMU_NCOUNTERS] = {
ETHOSU_PMU_EVENT_0, ETHOSU_PMU_EVENT_1, ETHOSU_PMU_EVENT_2, ETHOSU_PMU_EVENT_3,
#if (ETHOSU_PMU_NCOUNTERS > 4)
ETHOSU_PMU_EVENT_4, ETHOSU_PMU_EVENT_5, ETHOSU_PMU_EVENT_6, ETHOSU_PMU_EVENT_7,
#endif
};
static inline uint32_t pmu_counter_mask(uint32_t idx)
{
switch (idx) {
case 0:
return ETHOSU_PMU_CNT1_Msk;
case 1:
return ETHOSU_PMU_CNT2_Msk;
case 2:
return ETHOSU_PMU_CNT3_Msk;
case 3:
return ETHOSU_PMU_CNT4_Msk;
#if (ETHOSU_PMU_NCOUNTERS > 4)
case 4:
return ETHOSU_PMU_CNT5_Msk;
case 5:
return ETHOSU_PMU_CNT6_Msk;
case 6:
return ETHOSU_PMU_CNT7_Msk;
case 7:
return ETHOSU_PMU_CNT8_Msk;
#endif
default:
return 0;
}
}
extern "C" void ethosu_inference_begin(struct ethosu_driver *drv, void *)
{
ETHOSU_PMU_Enable(drv);
for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; ++i) {
ETHOSU_PMU_Set_EVTYPER(drv, i, pmu_events[i]);
ETHOSU_PMU_CNTR_Enable(drv, pmu_counter_mask(i));
}
ETHOSU_PMU_PMCCNTR_CFG_Set_Stop_Event(drv, ETHOSU_PMU_NPU_IDLE);
ETHOSU_PMU_PMCCNTR_CFG_Set_Start_Event(drv, ETHOSU_PMU_NPU_ACTIVE);
ETHOSU_PMU_CNTR_Enable(drv, ETHOSU_PMU_CCNT_Msk);
ETHOSU_PMU_CYCCNT_Reset(drv);
ETHOSU_PMU_EVCNTR_ALL_Reset(drv);
}
extern "C" void ethosu_inference_end(struct ethosu_driver *drv, void *)
{
const uint64_t cycles = ETHOSU_PMU_Get_CCNTR(drv);
uint32_t pmu_values[ETHOSU_PMU_NCOUNTERS] = {};
for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; ++i) {
pmu_values[i] = ETHOSU_PMU_Get_EVCNTR(drv, i);
}
ETHOSU_PMU_Disable(drv);
printf("\nEthos-U PMU report:\n");
printf("ethosu_pmu_cycle_cntr : %" PRIu64 "\n", cycles);
for (uint32_t i = 0; i < ETHOSU_PMU_NCOUNTERS; ++i) {
printf("ethosu_pmu_cntr%" PRIu32 " : %" PRIu32 "\n", i, pmu_values[i]);
}
}