Supporting most architectural counters, wiring them out from
CommitStage. Also support multiple events per cycle.
This commit is contained in:
@@ -161,48 +161,6 @@ interface CoreRenameDebug;
|
||||
interface Get#(RenameErrInfo) renameErr;
|
||||
endinterface
|
||||
|
||||
// ================================================================
|
||||
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
typedef struct {
|
||||
Bool evt_REDIRECT;
|
||||
Bool evt_TLB_EXC; // TODO: Misleading name
|
||||
Bool evt_BRANCH;
|
||||
Bool evt_JAL;
|
||||
Bool evt_JALR;
|
||||
Bool evt_AUIPC;
|
||||
Bool evt_LOAD;
|
||||
Bool evt_STORE;
|
||||
Bool evt_LR;
|
||||
Bool evt_SC;
|
||||
Bool evt_AMO;
|
||||
Bool evt_SERIAL_SHIFT;
|
||||
Bool evt_INT_MUL_DIV_REM;
|
||||
Bool evt_FP;
|
||||
Bool evt_SC_SUCCESS;
|
||||
Bool evt_LOAD_WAIT;
|
||||
Bool evt_STORE_WAIT;
|
||||
Bool evt_FENCE;
|
||||
Bool evt_F_BUSY_NO_CONSUME;
|
||||
Bool evt_D_BUSY_NO_CONSUME;
|
||||
Bool evt_1_BUSY_NO_CONSUME;
|
||||
Bool evt_2_BUSY_NO_CONSUME;
|
||||
Bool evt_3_BUSY_NO_CONSUME;
|
||||
Bool evt_IMPRECISE_SETBOUND;
|
||||
Bool evt_UNREPRESENTABLE_CAP;
|
||||
Bool evt_MEM_CAP_LOAD;
|
||||
Bool evt_MEM_CAP_STORE;
|
||||
Bool evt_MEM_CAP_LOAD_TAG_SET;
|
||||
Bool evt_MEM_CAP_STORE_TAG_SET;
|
||||
} EventsCore deriving (Bits, FShow);
|
||||
|
||||
instance BitVectorable #(EventsCore, 1, m) provisos (Bits #(EventsCore, m));
|
||||
function to_vector = struct_to_vector;
|
||||
endinstance
|
||||
`endif
|
||||
|
||||
// ================================================================
|
||||
|
||||
interface Core;
|
||||
// core request & indication
|
||||
interface CoreReq coreReq;
|
||||
@@ -278,6 +236,13 @@ typedef enum {
|
||||
} Core_Run_State
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
instance BitVectorable #(EventsCore, SizeOf#(SupCnt), EventsCoreElements) provisos (Bits #(EventsCore, m));
|
||||
function Vector#(EventsCoreElements, SupCnt) to_vector(EventsCore e) =
|
||||
reverse(unpack(pack(e)));
|
||||
endinstance
|
||||
`endif
|
||||
|
||||
(* synthesize *)
|
||||
module mkCore#(CoreId coreId)(Core);
|
||||
let verbose = False;
|
||||
@@ -456,7 +421,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
globalSpecUpdate.incorrectSpec(False, spec_tag, inst_tag);
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
EventsCore events = unpack (0);
|
||||
events.evt_REDIRECT = True;
|
||||
events.evt_REDIRECT = 1;
|
||||
aw_events[1] <= events;
|
||||
`endif
|
||||
endmethod
|
||||
@@ -1138,11 +1103,15 @@ module mkCore#(CoreId coreId)(Core);
|
||||
// ================================================================
|
||||
// Performance counters
|
||||
|
||||
Vector #(1, Bit #(Counter_Width)) null_evt = replicate (0);
|
||||
Vector #(31, Bit #(Counter_Width)) core_evts_vec = to_large_vector (aw_events_reg);
|
||||
Vector #(16, Bit #(Counter_Width)) imem_evts_vec = replicate (0);//to_large_vector (near_mem.imem.events);
|
||||
Vector #(16, Bit #(Counter_Width)) dmem_evts_vec = replicate (0);//to_large_vector (near_mem.dmem.events);
|
||||
Vector #(32, Bit #(Counter_Width)) external_evts_vec = replicate (0);//to_large_vector (w_external_evts);
|
||||
rule report_commit_events;
|
||||
aw_events[2] <= commitStage.events;
|
||||
endrule
|
||||
|
||||
Vector #(1, Bit #(Report_Width)) null_evt = replicate (0);
|
||||
Vector #(31, Bit #(Report_Width)) core_evts_vec = to_large_vector (aw_events_reg);
|
||||
Vector #(16, Bit #(Report_Width)) imem_evts_vec = replicate (0);//to_large_vector (near_mem.imem.events);
|
||||
Vector #(16, Bit #(Report_Width)) dmem_evts_vec = replicate (0);//to_large_vector (near_mem.dmem.events);
|
||||
Vector #(32, Bit #(Report_Width)) external_evts_vec = replicate (0);//to_large_vector (w_external_evts);
|
||||
|
||||
let events = append (null_evt, core_evts_vec);
|
||||
events = append (events, imem_evts_vec);
|
||||
|
||||
@@ -185,7 +185,7 @@ interface CsrFile;
|
||||
`endif
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
(* always_ready, always_enabled *)
|
||||
method Action send_performance_events (Vector #(No_Of_Evts, Bit #(Counter_Width)) evts);
|
||||
method Action send_performance_events (Vector #(No_Of_Evts, Bit #(Report_Width)) evts);
|
||||
`endif
|
||||
endinterface
|
||||
|
||||
@@ -246,11 +246,11 @@ interface PerfCountersVec;
|
||||
interface Vector#(No_Of_Ctrs, Reg#(Data)) counter_vec;
|
||||
interface Vector#(No_Of_Ctrs, Reg#(Data)) event_vec;
|
||||
interface Reg#(Data) inhibit;
|
||||
method Action send_performance_events (Vector #(No_Of_Evts, Bit#(Counter_Width)) evts);
|
||||
method Action send_performance_events (Vector #(No_Of_Evts, Bit#(Report_Width)) evts);
|
||||
endinterface
|
||||
(* synthesize *)
|
||||
module mkPerfCountersToooba (PerfCountersVec);
|
||||
PerfCounters_IFC #(No_Of_Ctrs, Counter_Width, No_Of_Evts) perf_counters <- mkPerfCounters;
|
||||
PerfCounters_IFC #(No_Of_Ctrs, Counter_Width, Report_Width, No_Of_Evts) perf_counters <- mkPerfCounters;
|
||||
Vector#(No_Of_Ctrs, Reg#(Data)) counters = ?;
|
||||
for (Bit#(TLog#(No_Of_Ctrs)) i = 0; i < 29; i = i + 1) counters[i] =
|
||||
interface Reg;
|
||||
|
||||
@@ -43,6 +43,7 @@ import Vector::*;
|
||||
import GetPut::*;
|
||||
import Cntrs::*;
|
||||
import ConfigReg::*;
|
||||
import DReg::*;
|
||||
import FIFO::*;
|
||||
import FIFOF::*;
|
||||
import Types::*;
|
||||
@@ -161,6 +162,9 @@ interface CommitStage;
|
||||
method Bool is_debug_halted;
|
||||
method Action debug_resume;
|
||||
`endif
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
method EventsCore events;
|
||||
`endif
|
||||
`ifdef DEBUG_WEDGE
|
||||
(* always_enabled *)
|
||||
method Tuple2#(CapMem, Bit#(32)) debugLastInst;
|
||||
@@ -410,6 +414,10 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
Count#(Data) flushCacheCnt <- mkCount(0);
|
||||
`endif
|
||||
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
Reg#(EventsCore) events_reg <- mkDReg(unpack(0));
|
||||
`endif
|
||||
|
||||
`ifdef RVFI
|
||||
// RVFI trace report. Not an input?
|
||||
FIFO#(Rvfi_Traces) rvfiQ <- mkFIFO;
|
||||
@@ -1060,7 +1068,6 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
// incr committed inst cnt at the end of rule
|
||||
SupCnt comInstCnt = 0;
|
||||
SupCnt comUserInstCnt = 0;
|
||||
`ifdef PERF_COUNT
|
||||
// incr some performance counter at the end of rule
|
||||
SupCnt brCnt = 0;
|
||||
SupCnt jmpCnt = 0;
|
||||
@@ -1070,7 +1077,6 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
SupCnt lrCnt = 0;
|
||||
SupCnt scCnt = 0;
|
||||
SupCnt amoCnt = 0;
|
||||
`endif
|
||||
|
||||
`ifdef RVFI
|
||||
Rvfi_Traces rvfis = replicate(tagged Invalid);
|
||||
@@ -1170,7 +1176,6 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
comUserInstCnt = comUserInstCnt + 1; // user space inst
|
||||
end
|
||||
|
||||
`ifdef PERF_COUNT
|
||||
// performance counter
|
||||
case(x.iType)
|
||||
Br: brCnt = brCnt + 1;
|
||||
@@ -1182,7 +1187,6 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
Sc: scCnt = scCnt + 1;
|
||||
Amo: amoCnt = amoCnt + 1;
|
||||
endcase
|
||||
`endif
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1235,6 +1239,19 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
end
|
||||
end
|
||||
`endif
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
EventsCore events = unpack(0);
|
||||
events.evt_BRANCH = brCnt;
|
||||
events.evt_JAL = jmpCnt;
|
||||
events.evt_JALR = jrCnt;
|
||||
events.evt_AUIPC = 0; // XXX
|
||||
events.evt_LOAD = ldCnt;
|
||||
events.evt_STORE = stCnt;
|
||||
events.evt_LR = lrCnt;
|
||||
events.evt_SC = scCnt;
|
||||
events.evt_AMO = amoCnt;
|
||||
events_reg <= events;
|
||||
`endif
|
||||
`ifdef RVFI
|
||||
rvfiQ.enq(rvfis);
|
||||
traceCnt <= traceCnt + zeroExtend(whichTrace);
|
||||
@@ -1309,6 +1326,10 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
endmethod
|
||||
`endif
|
||||
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
method events = events_reg;
|
||||
`endif
|
||||
|
||||
`ifdef DEBUG_WEDGE
|
||||
method Tuple2#(CapMem, Bit#(32)) debugLastInst;
|
||||
return tuple2(rg_last_pcc, rg_last_inst);
|
||||
|
||||
@@ -1043,6 +1043,40 @@ function x addPc(x cap, Bit#(12) inc) provisos (Add#(f, 12, c), CHERICap::CHERIC
|
||||
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
typedef 96 No_Of_Evts;
|
||||
typedef 8 Report_Width;
|
||||
typedef 64 Counter_Width;
|
||||
typedef 29 No_Of_Ctrs;
|
||||
|
||||
typedef struct {
|
||||
SupCnt evt_REDIRECT;
|
||||
SupCnt evt_TLB_EXC; // TODO: Misleading name
|
||||
SupCnt evt_BRANCH;
|
||||
SupCnt evt_JAL;
|
||||
SupCnt evt_JALR;
|
||||
SupCnt evt_AUIPC;
|
||||
SupCnt evt_LOAD;
|
||||
SupCnt evt_STORE;
|
||||
SupCnt evt_LR;
|
||||
SupCnt evt_SC;
|
||||
SupCnt evt_AMO;
|
||||
SupCnt evt_SERIAL_SHIFT;
|
||||
SupCnt evt_INT_MUL_DIV_REM;
|
||||
SupCnt evt_FP;
|
||||
SupCnt evt_SC_SUCCESS;
|
||||
SupCnt evt_LOAD_WAIT;
|
||||
SupCnt evt_STORE_WAIT;
|
||||
SupCnt evt_FENCE;
|
||||
SupCnt evt_F_BUSY_NO_CONSUME;
|
||||
SupCnt evt_D_BUSY_NO_CONSUME;
|
||||
SupCnt evt_1_BUSY_NO_CONSUME;
|
||||
SupCnt evt_2_BUSY_NO_CONSUME;
|
||||
SupCnt evt_3_BUSY_NO_CONSUME;
|
||||
SupCnt evt_IMPRECISE_SETBOUND;
|
||||
SupCnt evt_UNREPRESENTABLE_CAP;
|
||||
SupCnt evt_MEM_CAP_LOAD;
|
||||
SupCnt evt_MEM_CAP_STORE;
|
||||
SupCnt evt_MEM_CAP_LOAD_TAG_SET;
|
||||
SupCnt evt_MEM_CAP_STORE_TAG_SET;
|
||||
} EventsCore deriving (Bits, FShow);
|
||||
typedef TDiv#(SizeOf#(EventsCore),SizeOf#(SupCnt)) EventsCoreElements;
|
||||
`endif
|
||||
|
||||
Reference in New Issue
Block a user