diff --git a/doc/performance_counters.rst b/doc/performance_counters.rst index fb4c1fb3..d0ace8ca 100644 --- a/doc/performance_counters.rst +++ b/doc/performance_counters.rst @@ -41,6 +41,10 @@ The following events can be monitored using the performance counters of Ibex. +--------------+------------------+---------------------------------------------------------+ | 10 | NumInstrRetC | Number of compressed instructions retired | +--------------+------------------+---------------------------------------------------------+ +| 11 | NumCyclesMulWait | Cycles waiting for multiply to complete | ++--------------+------------------+---------------------------------------------------------+ +| 12 | NumCyclesDivWait | Cycles waiting for divide to complete | ++--------------+------------------+---------------------------------------------------------+ The event selector CSRs ``mhpmevent3`` - ``mhpmevent31`` define which of these events are counted by the event counters ``mhpmcounter3(h)`` - ``mhpmcounter31(h)``. If a specific bit in an event selector CSR is set to 1, this means that events with this ID are being counted by the counter associated with that selector CSR. @@ -99,6 +103,10 @@ The association of events with the ``mphmcounter`` registers is hardwired as lis +----------------------+----------------+--------------+------------------+ | ``mhpmcounter10(h)`` | 0xB0A (0xB8A) | 10 | NumInstrRetC | +----------------------+----------------+--------------+------------------+ +| ``mhpmcounter11(h)`` | 0xB0B (0xB8B) | 11 | NumCyclesMulWait | ++----------------------+----------------+--------------+------------------+ +| ``mhpmcounter12(h)`` | 0xB0C (0xB8C) | 12 | NumCyclesDivWait | ++----------------------+----------------+--------------+------------------+ Similarly, the event selector CSRs are hardwired as follows. The remaining event selector CSRs are tied to 0, i.e., no events are counted by the corresponding counters. diff --git a/dv/cs_registers/tb/tb_cs_registers.sv b/dv/cs_registers/tb/tb_cs_registers.sv index 61f0ddaf..c0ab3fac 100644 --- a/dv/cs_registers/tb/tb_cs_registers.sv +++ b/dv/cs_registers/tb/tb_cs_registers.sv @@ -94,6 +94,8 @@ module tb_cs_registers #( logic mem_load_i; // load from memory in this cycle logic mem_store_i; // store to memory in this cycle logic dside_wait_i; // core waiting for the dside + logic mul_wait_i; + logic div_wait_i; //----------------- // Reset generation diff --git a/dv/verilator/pcount/cpp/ibex_pcounts.cc b/dv/verilator/pcount/cpp/ibex_pcounts.cc index 8f2cf699..e5629dfc 100644 --- a/dv/verilator/pcount/cpp/ibex_pcounts.cc +++ b/dv/verilator/pcount/cpp/ibex_pcounts.cc @@ -22,7 +22,9 @@ const std::vector ibex_counter_names = { "Jumps", "Conditional Branches", "Taken Conditional Branches", - "Compressed Instructions"}; + "Compressed Instructions", + "Multiply Wait", + "Divide Wait"}; std::string ibex_pcount_string(uint64_t pcounts[], bool csv) { char seperator = csv ? ',' : ':'; diff --git a/examples/sw/benchmarks/coremark/ibex/core_portme.c b/examples/sw/benchmarks/coremark/ibex/core_portme.c index 7b66e04c..353c31bd 100644 --- a/examples/sw/benchmarks/coremark/ibex/core_portme.c +++ b/examples/sw/benchmarks/coremark/ibex/core_portme.c @@ -66,6 +66,8 @@ void pcount_read(uint32_t pcount_out[]) { PCOUNT_READ(mhpmcounter8, pcount_out[6]); PCOUNT_READ(mhpmcounter9, pcount_out[7]); PCOUNT_READ(mhpmcounter10, pcount_out[8]); + PCOUNT_READ(mhpmcounter11, pcount_out[9]); + PCOUNT_READ(mhpmcounter12, pcount_out[10]); } const char *pcount_names[] = {"Instructions Retired", @@ -76,7 +78,9 @@ const char *pcount_names[] = {"Instructions Retired", "Jumps", "Branches", "Taken Branches", - "Compressed Instructions"}; + "Compressed Instructions", + "Multiply Wait", + "Divide Wait"}; const uint32_t pcount_num = sizeof(pcount_names) / sizeof(char *); diff --git a/rtl/ibex_core.sv b/rtl/ibex_core.sv index 96e0fbdc..2357bd50 100644 --- a/rtl/ibex_core.sv +++ b/rtl/ibex_core.sv @@ -257,6 +257,8 @@ module ibex_core #( logic perf_iside_wait; logic perf_dside_wait; + logic perf_mul_wait; + logic perf_div_wait; logic perf_jump; logic perf_branch; logic perf_tbranch; @@ -533,6 +535,8 @@ module ibex_core #( .perf_branch_o ( perf_branch ), .perf_tbranch_o ( perf_tbranch ), .perf_dside_wait_o ( perf_dside_wait ), + .perf_mul_wait_o ( perf_mul_wait ), + .perf_div_wait_o ( perf_div_wait ), .instr_id_done_o ( instr_id_done ), .instr_id_done_compressed_o ( instr_id_done_compressed ) ); @@ -828,7 +832,9 @@ module ibex_core #( .branch_taken_i ( perf_tbranch ), .mem_load_i ( perf_load ), .mem_store_i ( perf_store ), - .dside_wait_i ( perf_dside_wait ) + .dside_wait_i ( perf_dside_wait ), + .mul_wait_i ( perf_mul_wait ), + .div_wait_i ( perf_div_wait ) ); if (PMPEnable) begin : g_pmp diff --git a/rtl/ibex_cs_registers.sv b/rtl/ibex_cs_registers.sv index ea4295c5..5f60957c 100644 --- a/rtl/ibex_cs_registers.sv +++ b/rtl/ibex_cs_registers.sv @@ -14,7 +14,7 @@ module ibex_cs_registers #( parameter bit DbgTriggerEn = 0, - parameter int unsigned MHPMCounterNum = 8, + parameter int unsigned MHPMCounterNum = 10, parameter int unsigned MHPMCounterWidth = 40, parameter bit PMPEnable = 0, parameter int unsigned PMPGranularity = 0, @@ -97,7 +97,9 @@ module ibex_cs_registers #( input logic branch_taken_i, // branch was taken input logic mem_load_i, // load from memory in this cycle input logic mem_store_i, // store to memory in this cycle - input logic dside_wait_i // core waiting for the dside + input logic dside_wait_i, // core waiting for the dside + input logic mul_wait_i, // core waiting for multiply + input logic div_wait_i // core waiting for divide ); import ibex_pkg::*; @@ -855,6 +857,8 @@ module ibex_cs_registers #( mhpmcounter_incr[8] = branch_i; // num of branches (conditional) mhpmcounter_incr[9] = branch_taken_i; // num of taken branches (conditional) mhpmcounter_incr[10] = instr_ret_compressed_i; // num of compressed instr + mhpmcounter_incr[11] = mul_wait_i; // cycles waiting for multiply + mhpmcounter_incr[12] = div_wait_i; // cycles waiting for divide // inactive counters for (int unsigned i=3+MHPMCounterNum; i<32; i++) begin : gen_mhpmcounter_incr_inactive diff --git a/rtl/ibex_id_stage.sv b/rtl/ibex_id_stage.sv index ee7d3834..1d242708 100644 --- a/rtl/ibex_id_stage.sv +++ b/rtl/ibex_id_stage.sv @@ -160,6 +160,8 @@ module ibex_id_stage #( output logic perf_tbranch_o, // executing a taken branch instr output logic perf_dside_wait_o, // instruction in ID/EX is awaiting memory // access to finish before proceeding + output logic perf_mul_wait_o, + output logic perf_div_wait_o, output logic instr_id_done_o, output logic instr_id_done_compressed_o ); @@ -836,6 +838,9 @@ module ibex_id_stage #( assign instr_id_done_o = instr_done; end + assign perf_mul_wait_o = stall_multdiv & mult_en_dec; + assign perf_div_wait_o = stall_multdiv & div_en_dec; + assign instr_id_done_compressed_o = instr_id_done_o & instr_is_compressed_i; ////////////////