Supporting most architectural counters, wiring them out from

CommitStage.
Also support multiple events per cycle.
This commit is contained in:
jon
2020-12-02 15:28:41 +00:00
parent e99e1e6274
commit 4fcc18635a
4 changed files with 79 additions and 55 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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