diff --git a/dv/verilator/pcount/cpp/ibex_pcounts.cc b/dv/verilator/pcount/cpp/ibex_pcounts.cc index 20cfec9736..6924ee5261 100644 --- a/dv/verilator/pcount/cpp/ibex_pcounts.cc +++ b/dv/verilator/pcount/cpp/ibex_pcounts.cc @@ -10,6 +10,7 @@ #include extern "C" { +extern unsigned int mhpmcounter_num(); extern unsigned long long mhpmcounter_get(int index); } @@ -32,14 +33,35 @@ const std::vector ibex_counter_names = { "Multiply Wait", "Divide Wait"}; +static bool has_hpm_counter(int index) { + // The "cycles" and "instructions retired" counters are special and always + // exist. + if (index == 0 || index == 2) + return true; + + // The "NONE" counter is a placeholder. The space reserves an index that was + // once the "MTIME" CSR, but now is unused. Return false: there's no real HPM + // counter at index 1. + if (index == 1) + return false; + + // Otherwise, a counter exists if the index is strictly less than + // the MHPMCounterNum parameter that got passed to the + // ibex_cs_registers module. + return index < mhpmcounter_num(); +} + std::string ibex_pcount_string(bool csv) { char separator = csv ? ',' : ':'; std::string::size_type longest_name_length; if (!csv) { longest_name_length = 0; - for (const std::string &counter_name : ibex_counter_names) { - longest_name_length = std::max(longest_name_length, counter_name.length()); + for (int i = 0; i < ibex_counter_names.size(); ++i) { + if (has_hpm_counter(i)) { + longest_name_length = + std::max(longest_name_length, ibex_counter_names[i].length()); + } } // Add 1 to always get at least once space after the separator @@ -49,6 +71,9 @@ std::string ibex_pcount_string(bool csv) { std::stringstream pcount_ss; for (int i = 0; i < ibex_counter_names.size(); ++i) { + if (!has_hpm_counter(i)) + continue; + pcount_ss << ibex_counter_names[i] << separator; if (!csv) { diff --git a/examples/simple_system/rtl/ibex_simple_system.sv b/examples/simple_system/rtl/ibex_simple_system.sv index d9647335a1..ac74691d68 100644 --- a/examples/simple_system/rtl/ibex_simple_system.sv +++ b/examples/simple_system/rtl/ibex_simple_system.sv @@ -318,6 +318,12 @@ module ibex_simple_system ( .timer_intr_o (timer_irq) ); + export "DPI-C" function mhpmcounter_num; + + function automatic int unsigned mhpmcounter_num(); + return u_top.u_ibex_top.u_ibex_core.cs_registers_i.MHPMCounterNum; + endfunction + export "DPI-C" function mhpmcounter_get; function automatic longint unsigned mhpmcounter_get(int index);