mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 04:47:25 -04:00
[rtl/sw] Add multiply and divide wait counters
This commit is contained in:
parent
efbfecbb38
commit
3927fd8d2a
7 changed files with 36 additions and 5 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -22,7 +22,9 @@ const std::vector<std::string> 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 ? ',' : ':';
|
||||
|
|
|
@ -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 *);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
////////////////
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue