diff --git a/dv/verilator/pcount/cpp/ibex_pcounts.cc b/dv/verilator/pcount/cpp/ibex_pcounts.cc index e5629dfc..60e9d535 100644 --- a/dv/verilator/pcount/cpp/ibex_pcounts.cc +++ b/dv/verilator/pcount/cpp/ibex_pcounts.cc @@ -7,6 +7,12 @@ #include #include +#include + +extern "C" { +extern long long mhpmcounter_get(int index); +} + #include "ibex_pcounts.h" // see mhpmcounter_incr signals in rtl/ibex_cs_registers.sv for details @@ -26,7 +32,7 @@ const std::vector ibex_counter_names = { "Multiply Wait", "Divide Wait"}; -std::string ibex_pcount_string(uint64_t pcounts[], bool csv) { +std::string ibex_pcount_string(bool csv) { char seperator = csv ? ',' : ':'; std::string::size_type longest_name_length; @@ -52,7 +58,7 @@ std::string ibex_pcount_string(uint64_t pcounts[], bool csv) { pcount_ss << ' '; } - pcount_ss << pcounts[i] << std::endl; + pcount_ss << mhpmcounter_get(i) << std::endl; } return pcount_ss.str(); diff --git a/dv/verilator/pcount/cpp/ibex_pcounts.h b/dv/verilator/pcount/cpp/ibex_pcounts.h index 0d90678e..67061963 100644 --- a/dv/verilator/pcount/cpp/ibex_pcounts.h +++ b/dv/verilator/pcount/cpp/ibex_pcounts.h @@ -34,11 +34,9 @@ extern const std::vector ibex_counter_names; * longercountername1: 43980 * ... * - * @param pcounts Array of performance counter values, must be of length - * ibex_pcount_num * @param csv Choose csv or pretty-print formatting * @return String of formatted performance counter values, newline at end */ -std::string ibex_pcount_string(uint64_t pcounts[], bool csv); +std::string ibex_pcount_string(bool csv); #endif // IBEX_PCOUNTS_H_ diff --git a/examples/simple_system/ibex_simple_system.cc b/examples/simple_system/ibex_simple_system.cc index 819b91f8..7dcc9ad6 100644 --- a/examples/simple_system/ibex_simple_system.cc +++ b/examples/simple_system/ibex_simple_system.cc @@ -28,17 +28,19 @@ int main(int argc, char **argv) { return 1; } + // Set the scope to the root scope, the ibex_pcount_string function otherwise + // doesn't know the scope itself. Could be moved to ibex_pcount_string, but + // would require a way to set the scope name from here, similar to MemUtil. + svSetScope(svGetScopeFromName("TOP.ibex_simple_system")); // TODO: Exec can return with "true" (e.g. with `-h`), but that does not mean // `RunSimulation()` was executed. The folllowing values will not be useful // in this case. std::cout << "\nPerformance Counters" << std::endl << "====================" << std::endl; - std::cout << ibex_pcount_string(top.ibex_simple_system__DOT__mhpmcounter_vals, - false); + std::cout << ibex_pcount_string(false); std::ofstream pcount_csv("ibex_simple_system_pcount.csv"); - pcount_csv << ibex_pcount_string( - top.ibex_simple_system__DOT__mhpmcounter_vals, true); + pcount_csv << ibex_pcount_string(true); return 0; } diff --git a/examples/simple_system/rtl/ibex_simple_system.sv b/examples/simple_system/rtl/ibex_simple_system.sv index f96670c2..a37bd993 100644 --- a/examples/simple_system/rtl/ibex_simple_system.sv +++ b/examples/simple_system/rtl/ibex_simple_system.sv @@ -249,12 +249,10 @@ module ibex_simple_system ( .timer_intr_o (timer_irq) ); - // Expose the performance counter array so it's easy to access in - // a verilator siumulation - logic [63:0] mhpmcounter_vals [32] /*verilator public_flat*/; + export "DPI-C" function mhpmcounter_get; + + function automatic longint mhpmcounter_get(int index); + return u_core.u_ibex_core.cs_registers_i.mhpmcounter[index]; + endfunction - for(genvar i = 0;i < 32; i = i + 1) begin - assign mhpmcounter_vals[i] = u_core.u_ibex_core.cs_registers_i.mhpmcounter[i]; - end endmodule -