From 73d25bf8f5ed8f6910d3736dd51615f022d4a16b Mon Sep 17 00:00:00 2001 From: jon Date: Mon, 14 Dec 2020 18:10:06 +0000 Subject: [PATCH] Support performance counters (hopefully) in the caches. The DCache should be fully wired up. --- src_Core/CPU/Core.bsv | 6 +- src_Core/RISCY_OOO/coherence/src/CCTypes.bsv | 20 +++ src_Core/RISCY_OOO/coherence/src/L1Bank.bsv | 134 +++++++++++++------ src_Core/RISCY_OOO/procs/lib/L1CoCache.bsv | 6 + 4 files changed, 125 insertions(+), 41 deletions(-) diff --git a/src_Core/CPU/Core.bsv b/src_Core/CPU/Core.bsv index 0d5e0c1..25544b6 100644 --- a/src_Core/CPU/Core.bsv +++ b/src_Core/CPU/Core.bsv @@ -245,6 +245,10 @@ instance BitVectorable #(EventsCoreMem, SizeOf#(HpmRpt), EventsCoreMemElements) function Vector#(EventsCoreMemElements, HpmRpt) to_vector(EventsCoreMem e) = reverse(unpack(pack(e))); endinstance +instance BitVectorable #(EventsCache, SizeOf#(HpmRpt), EventsCacheElements) provisos (Bits #(EventsCache, m)); + function Vector#(EventsCacheElements, HpmRpt) to_vector(EventsCache e) = + reverse(unpack(pack(e))); +endinstance `endif (* synthesize *) @@ -1116,7 +1120,7 @@ module mkCore#(CoreId coreId)(Core); Vector #(31, Bit #(Report_Width)) other_core_evts_vec = to_large_vector (hpm_core_events_reg); Vector #(31, Bit #(Report_Width)) core_evts_vec = unpack(pack(mem_core_evts_vec) | pack(other_core_evts_vec)); 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 #(16, Bit #(Report_Width)) dmem_evts_vec = to_large_vector (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); diff --git a/src_Core/RISCY_OOO/coherence/src/CCTypes.bsv b/src_Core/RISCY_OOO/coherence/src/CCTypes.bsv index b583769..27b21ab 100644 --- a/src_Core/RISCY_OOO/coherence/src/CCTypes.bsv +++ b/src_Core/RISCY_OOO/coherence/src/CCTypes.bsv @@ -45,6 +45,26 @@ import Connectable::*; import GetPut::*; import ClientServer::*; +`ifdef PERFORMANCE_MONITORING +typedef struct { + Bit#(8) evt_LD; + Bit#(8) evt_LD_MISS; + Bit#(8) evt_LD_MISS_LAT; + Bit#(8) evt_ST; + Bit#(8) evt_ST_MISS; // Unimplemented + Bit#(8) evt_ST_MISS_LAT; // Unimplemented + Bit#(8) evt_AMO; + Bit#(8) evt_AMO_MISS; + Bit#(8) evt_AMO_MISS_LAT; + Bit#(8) evt_TLB; + Bit#(8) evt_TLB_MISS; // Only leaf is stored in TLB thus a full + Bit#(8) evt_TLB_MISS_LAT; // walk must happen every miss + Bit#(8) evt_TLB_FLUSH; + Bit#(8) evt_EVICT; +} EventsCache deriving (Bits, FShow); +typedef TDiv#(SizeOf#(EventsCache),8) EventsCacheElements; +`endif + typedef enum { I = 2'd0, S = 2'd1, diff --git a/src_Core/RISCY_OOO/coherence/src/L1Bank.bsv b/src_Core/RISCY_OOO/coherence/src/L1Bank.bsv index 3e4adec..59dd7a9 100644 --- a/src_Core/RISCY_OOO/coherence/src/L1Bank.bsv +++ b/src_Core/RISCY_OOO/coherence/src/L1Bank.bsv @@ -60,6 +60,10 @@ import CrossBar::*; import Performance::*; import LatencyTimer::*; import RandomReplace::*; +`ifdef PERFORMANCE_MONITORING +import PerformanceMonitor::*; +import SpecialWires::*; +`endif export L1CRqStuck(..); export L1PRqStuck(..); @@ -103,6 +107,9 @@ interface L1Bank#( // performance method Action setPerfStatus(Bool stats); method Data getPerfData(L1DPerfType t); +`ifdef PERFORMANCE_MONITORING + method EventsCache events; +`endif endinterface typedef struct { @@ -191,6 +198,7 @@ module mkL1Bank#( `endif // performance + LatencyTimer#(cRqNum, 10) latTimer <- mkLatencyTimer; // max 1K cycle latency `ifdef PERF_COUNT Reg#(Bool) doStats <- mkConfigReg(False); Count#(Data) ldCnt <- mkCount(0); @@ -202,43 +210,81 @@ module mkL1Bank#( Count#(Data) ldMissLat <- mkCount(0); Count#(Data) stMissLat <- mkCount(0); Count#(Data) amoMissLat <- mkCount(0); - - LatencyTimer#(cRqNum, 10) latTimer <- mkLatencyTimer; // max 1K cycle latency - - function Action incrReqCnt(MemOp op); - action - if(doStats) begin - case(op) - Ld: ldCnt.incr(1); - St: stCnt.incr(1); - Lr, Sc, Amo: amoCnt.incr(1); - endcase - end - endaction - endfunction - - function Action incrMissCnt(MemOp op, cRqIdxT idx); - action - let lat <- latTimer.done(idx); - if(doStats) begin - case(op) - Ld: begin - ldMissLat.incr(zeroExtend(lat)); - ldMissCnt.incr(1); - end - St: begin - stMissLat.incr(zeroExtend(lat)); - stMissCnt.incr(1); - end - Lr, Sc, Amo: begin - amoMissLat.incr(zeroExtend(lat)); - amoMissCnt.incr(1); - end - endcase - end - endaction - endfunction `endif +`ifdef PERFORMANCE_MONITORING + Array #(Wire #(EventsCache)) perf_events <- mkDWireOR (2, unpack (0)); + Reg #(EventsCache) perf_events_reg <- mkConfigReg(unpack(0)); + rule update_events_reg; + perf_events_reg <= perf_events[0]; + endrule +`endif +function Action incrReqCnt(MemOp op); +action +`ifdef PERF_COUNT + if(doStats) begin + case(op) + Ld: ldCnt.incr(1); + St: stCnt.incr(1); + Lr, Sc, Amo: amoCnt.incr(1); + endcase + end +`endif +`ifdef PERFORMANCE_MONITORING + EventsCache events = unpack (0); + case(op) + Ld: events.evt_LD = 1; + St: events.evt_ST = 1; + Lr, Sc, Amo: events.evt_AMO = 1; + endcase + perf_events[0] <= events; +`endif + noAction; +endaction +endfunction + +function Action incrMissCnt(MemOp op, cRqIdxT idx); +action + let lat <- latTimer.done(idx); +`ifdef PERF_COUNT + if(doStats) begin + case(op) + Ld: begin + ldMissLat.incr(zeroExtend(lat)); + ldMissCnt.incr(1); + end + St: begin + stMissLat.incr(zeroExtend(lat)); + stMissCnt.incr(1); + end + Lr, Sc, Amo: begin + amoMissLat.incr(zeroExtend(lat)); + amoMissCnt.incr(1); + end + endcase + end +`endif +`ifdef PERFORMANCE_MONITORING + EventsCache events = unpack (0); + case(op) + Ld: begin + events.evt_LD_MISS_LAT = saturating_truncate(lat); + events.evt_LD_MISS = 1; + end + St: begin + events.evt_ST_MISS_LAT = saturating_truncate(lat); + events.evt_ST_MISS = 1; + end + Lr, Sc, Amo: begin + events.evt_AMO_MISS_LAT = saturating_truncate(lat); + events.evt_AMO_MISS = 1; + end + endcase + perf_events[1] <= events; +`endif + noAction; +endaction +endfunction + function tagT getTag(Addr a) = truncateLSB(a); @@ -274,10 +320,8 @@ module mkL1Bank#( addr: r.addr, mshrIdx: n })); -`ifdef PERF_COUNT // performance counter: cRq type incrReqCnt(r.op); -`endif if (verbose) $display("%t L1 %m cRqTransfer_new: ", $time, fshow(n), " ; ", @@ -849,10 +893,8 @@ module mkL1Bank#( ("pRs must be a hit") ); cRqHit(cOwner, procRq); -`ifdef PERF_COUNT // performance counter: miss cRq incrMissCnt(procRq.op, cOwner); -`endif end else begin doAssert(False, ("pRs owner must match some cRq")); @@ -1089,6 +1131,9 @@ module mkL1Bank#( default: 0; endcase); endmethod +`ifdef PERFORMANCE_MONITORING + method EventsCache events = perf_events_reg; +`endif endmodule @@ -1320,4 +1365,13 @@ module mkL1Cache#( end return fold(\+ , d); endmethod +`ifdef PERFORMANCE_MONITORING + method EventsCache events; + EventsCache ret = unpack(0); + for(Integer i = 0; i < valueof(bankNum); i = i+1) begin + ret = unpack(pack(ret) | pack(banks[i].events)); + end + return ret; + endmethod +`endif endmodule diff --git a/src_Core/RISCY_OOO/procs/lib/L1CoCache.bsv b/src_Core/RISCY_OOO/procs/lib/L1CoCache.bsv index 26e652a..9edaaaa 100644 --- a/src_Core/RISCY_OOO/procs/lib/L1CoCache.bsv +++ b/src_Core/RISCY_OOO/procs/lib/L1CoCache.bsv @@ -178,6 +178,9 @@ interface DCoCache; method Bool flush_done; method Action resetLinkAddr; interface Perf#(L1DPerfType) perf; +`ifdef PERFORMANCE_MONITORING + method EventsCache events; +`endif interface ChildCacheToParent#(L1Way, void) to_parent; @@ -267,6 +270,9 @@ module mkDCoCache#(L1ProcResp#(DProcReqId) procResp)(DCoCache); `endif endmethod endinterface +`ifdef PERFORMANCE_MONITORING + method EventsCache events = cache.events; +`endif interface to_parent = cache.to_parent;