mirror of
https://github.com/lowRISC/ibex.git
synced 2025-06-28 09:17:17 -04:00
Although the current code isn't wrong as far as I can tell, it would be better to initialize the lognest_name_length variable when it is declared to avoid a build warning with older Verilator versions.
89 lines
2.2 KiB
C++
89 lines
2.2 KiB
C++
// Copyright lowRISC contributors.
|
|
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
#include <numeric>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <svdpi.h>
|
|
|
|
extern "C" {
|
|
extern unsigned int mhpmcounter_num();
|
|
extern unsigned long long mhpmcounter_get(int index);
|
|
}
|
|
|
|
#include "ibex_pcounts.h"
|
|
|
|
// see mhpmcounter_incr signals in rtl/ibex_cs_registers.sv for details
|
|
|
|
const std::vector<std::string> ibex_counter_names = {
|
|
"Cycles",
|
|
"NONE",
|
|
"Instructions Retired",
|
|
"LSU Busy",
|
|
"Fetch Wait",
|
|
"Loads",
|
|
"Stores",
|
|
"Jumps",
|
|
"Conditional Branches",
|
|
"Taken Conditional Branches",
|
|
"Compressed Instructions",
|
|
"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 = 0;
|
|
|
|
if (!csv) {
|
|
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
|
|
longest_name_length++;
|
|
}
|
|
|
|
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) {
|
|
int padding = longest_name_length - ibex_counter_names[i].length();
|
|
|
|
for (int j = 0; j < padding; ++j)
|
|
pcount_ss << ' ';
|
|
}
|
|
|
|
pcount_ss << mhpmcounter_get(i) << std::endl;
|
|
}
|
|
|
|
return pcount_ss.str();
|
|
}
|