diff --git a/doc/performance_counters.rst b/doc/performance_counters.rst index c48ef0cc..9c844366 100644 --- a/doc/performance_counters.rst +++ b/doc/performance_counters.rst @@ -45,6 +45,10 @@ The following events can be monitored using the performance counters of Ibex. +--------------+------------------+---------------------------------------------------------+ | 12 | NumCyclesDivWait | Cycles waiting for divide to complete | +--------------+------------------+---------------------------------------------------------+ +| 13 | NumPacInstrRet | Number of pac instructions retired | ++--------------+------------------+---------------------------------------------------------+ +| 14 | NumAutInstrRet | Number of aut instructions retired | ++--------------+------------------+---------------------------------------------------------+ 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. @@ -107,6 +111,10 @@ The association of events with the ``mphmcounter`` registers is hardwired as lis +----------------------+----------------+--------------+------------------+ | ``mhpmcounter12(h)`` | 0xB0C (0xB8C) | 12 | NumCyclesDivWait | +----------------------+----------------+--------------+------------------+ +| ``mhpmcounter13(h)`` | 0xB0D (0xB8D) | 13 | NumPacInstrRet | ++----------------------+----------------+--------------+------------------+ +| ``mhpmcounter14(h)`` | 0xB0E (0xB8E) | 14 | NumAutInstrRet | ++----------------------+----------------+--------------+------------------+ 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/verilator/pcount/cpp/ibex_pcounts.cc b/dv/verilator/pcount/cpp/ibex_pcounts.cc index 60e9d535..9b57cf97 100644 --- a/dv/verilator/pcount/cpp/ibex_pcounts.cc +++ b/dv/verilator/pcount/cpp/ibex_pcounts.cc @@ -30,7 +30,9 @@ const std::vector ibex_counter_names = { "Taken Conditional Branches", "Compressed Instructions", "Multiply Wait", - "Divide Wait"}; + "Divide Wait", + "PAC Instructions", + "AUT Instructions"}; std::string ibex_pcount_string(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 e32431d5..51333e73 100644 --- a/examples/sw/benchmarks/coremark/ibex/core_portme.c +++ b/examples/sw/benchmarks/coremark/ibex/core_portme.c @@ -68,6 +68,8 @@ void pcount_read(uint32_t pcount_out[]) { PCOUNT_READ(mhpmcounter10, pcount_out[8]); PCOUNT_READ(mhpmcounter11, pcount_out[9]); PCOUNT_READ(mhpmcounter12, pcount_out[10]); + PCOUNT_READ(mhpmcounter13, pcount_out[11]); + PCOUNT_READ(mhpmcounter14, pcount_out[12]); } const char *pcount_names[] = {"Instructions Retired", @@ -80,7 +82,9 @@ const char *pcount_names[] = {"Instructions Retired", "Taken Branches", "Compressed Instructions", "Multiply Wait", - "Divide Wait"}; + "Divide Wait", + "PAC Instructions", + "AUT Instructions"}; const uint32_t pcount_num = sizeof(pcount_names) / sizeof(char *); diff --git a/rtl/ibex_core.sv b/rtl/ibex_core.sv index f88e954c..d99a394c 100644 --- a/rtl/ibex_core.sv +++ b/rtl/ibex_core.sv @@ -307,6 +307,8 @@ module ibex_core #( logic perf_tbranch; logic perf_load; logic perf_store; + logic perf_pac; + logic perf_aut; // for RVFI logic illegal_insn_id, unused_illegal_insn_id; // ID stage sees an illegal instruction @@ -628,6 +630,8 @@ module ibex_core #( .perf_mul_wait_o ( perf_mul_wait ), .perf_div_wait_o ( perf_div_wait ), .instr_id_done_o ( instr_id_done ), + .perf_pac_o ( perf_pac ), + .perf_aut_o ( perf_aut ), .instr_id_done_compressed_o ( instr_id_done_compressed ), // Pointer Authentication @@ -1023,7 +1027,9 @@ module ibex_core #( .mem_store_i ( perf_store ), .dside_wait_i ( perf_dside_wait ), .mul_wait_i ( perf_mul_wait ), - .div_wait_i ( perf_div_wait ) + .div_wait_i ( perf_div_wait ), + .pac_i ( perf_pac ), + .aut_i ( perf_aut ) ); // These assertions are in top-level as instr_valid_id required as the enable term diff --git a/rtl/ibex_cs_registers.sv b/rtl/ibex_cs_registers.sv index 9a94dfd0..39090d36 100644 --- a/rtl/ibex_cs_registers.sv +++ b/rtl/ibex_cs_registers.sv @@ -17,7 +17,7 @@ module ibex_cs_registers #( parameter bit DataIndTiming = 1'b0, parameter bit DummyInstructions = 1'b0, parameter bit ICache = 1'b0, - parameter int unsigned MHPMCounterNum = 10, + parameter int unsigned MHPMCounterNum = 12, parameter int unsigned MHPMCounterWidth = 40, parameter bit PMPEnable = 0, parameter int unsigned PMPGranularity = 0, @@ -115,7 +115,9 @@ module ibex_cs_registers #( input logic mem_store_i, // store to memory in this cycle 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 + input logic div_wait_i, // core waiting for divide + input logic pac_i, // pac instr retired + input logic aut_i // aut instr retired ); import ibex_pkg::*; @@ -937,6 +939,8 @@ module ibex_cs_registers #( 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 + mhpmcounter_incr[13] = pac_i; // num of pac instr + mhpmcounter_incr[14] = aut_i; // num of aut instr end // event selector (hardwired, 0 means no event) diff --git a/rtl/ibex_id_stage.sv b/rtl/ibex_id_stage.sv index a03fdf2e..c415b64e 100644 --- a/rtl/ibex_id_stage.sv +++ b/rtl/ibex_id_stage.sv @@ -177,6 +177,8 @@ module ibex_id_stage #( // access to finish before proceeding output logic perf_mul_wait_o, output logic perf_div_wait_o, + output logic perf_pac_o, + output logic perf_aut_o, output logic instr_id_done_o, output logic instr_id_done_compressed_o, @@ -1036,6 +1038,9 @@ module ibex_id_stage #( assign perf_mul_wait_o = stall_multdiv & mult_en_dec; assign perf_div_wait_o = stall_multdiv & div_en_dec; + assign perf_pac_o = instr_id_done_o & pac_en_id; + assign perf_aut_o = instr_id_done_o & aut_en_id; + assign instr_id_done_compressed_o = instr_id_done_o & instr_is_compressed_i; assign pa_data0_o = rf_rdata_a_fwd;