From fa9931b64ccd26004848ae1a48fd54b408e6b38a Mon Sep 17 00:00:00 2001 From: jon Date: Tue, 15 Dec 2020 18:16:21 +0000 Subject: [PATCH] Implement a couple Cache counters in the LLCache. These aren't too useful... We don't seem to have normal counters for loads and stores in the baseline. --- src_Core/CPU/Core.bsv | 10 ++++ src_Core/CPU/Proc.bsv | 8 +++ src_Core/RISCY_OOO/coherence/src/IBank.bsv | 4 -- src_Core/RISCY_OOO/coherence/src/LLBank.bsv | 65 ++++++++++++--------- src_Core/RISCY_OOO/procs/lib/LLCache.bsv | 12 +++- src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv | 8 +-- 6 files changed, 69 insertions(+), 38 deletions(-) diff --git a/src_Core/CPU/Core.bsv b/src_Core/CPU/Core.bsv index 0085c35..8b59ae8 100644 --- a/src_Core/CPU/Core.bsv +++ b/src_Core/CPU/Core.bsv @@ -216,6 +216,9 @@ interface Core; method Bit#(32) debugRename; `endif +`ifdef PERFORMANCE_MONITORING + method Action events_llc(EventsCache events); +`endif endinterface // fixpoint to instantiate modules @@ -1107,6 +1110,7 @@ module mkCore#(CoreId coreId)(Core); // ================================================================ // Performance counters + Reg#(EventsCache) events_llc_reg <- mkRegU; rule report_events; hpm_core_events[2] <= unpack(pack(commitStage.events)); endrule @@ -1118,11 +1122,13 @@ module mkCore#(CoreId coreId)(Core); Vector #(16, Bit #(Report_Width)) imem_evts_vec = to_large_vector (iMem.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); + Vector #(16, Bit #(Report_Width)) llc_evts_vec = to_large_vector (events_llc_reg); let events = append (null_evt, core_evts_vec); events = append (events, imem_evts_vec); events = append (events, dmem_evts_vec); events = append (events, external_evts_vec); + events = append (events, llc_evts_vec); (* fire_when_enabled, no_implicit_conditions *) rule rl_send_perf_evts; @@ -1522,4 +1528,8 @@ module mkCore#(CoreId coreId)(Core); endmethod `endif +`ifdef PERFORMANCE_MONITORING + method events_llc = events_llc_reg._write; +`endif + endmodule diff --git a/src_Core/CPU/Proc.bsv b/src_Core/CPU/Proc.bsv index d3af7d3..d65e6e4 100644 --- a/src_Core/CPU/Proc.bsv +++ b/src_Core/CPU/Proc.bsv @@ -188,6 +188,14 @@ module mkProc (Proc_IFC); statReqs.deq; endrule +`ifdef PERFORMANCE_MONITORING + rule broadcastPerfEvents; + for(Integer j = 0; j < valueof(CoreNum); j = j+1) begin + core[j].events_llc(llc.events); + end + endrule +`endif + // ================================================================ // Stub out deadlock and renameDebug interfaces diff --git a/src_Core/RISCY_OOO/coherence/src/IBank.bsv b/src_Core/RISCY_OOO/coherence/src/IBank.bsv index ef1bf10..a1aed8b 100644 --- a/src_Core/RISCY_OOO/coherence/src/IBank.bsv +++ b/src_Core/RISCY_OOO/coherence/src/IBank.bsv @@ -252,10 +252,8 @@ module mkIBank#( })); // enq to indexQ for in order resp cRqIndexQ.enq(n); -`ifdef PERF_COUNT // performance counter: cRq type incrReqCnt; -`endif if (verbose) $display("%t I %m cRqTransfer: ", $time, fshow(n), " ; ", @@ -640,10 +638,8 @@ module mkIBank#( "pRs must be a hit" ); cRqHit(cOwner, procRq); -`ifdef PERF_COUNT // performance counter: miss cRq incrMissCnt(cOwner); -`endif end else begin doAssert(False, ("pRs owner must match some cRq")); diff --git a/src_Core/RISCY_OOO/coherence/src/LLBank.bsv b/src_Core/RISCY_OOO/coherence/src/LLBank.bsv index 06be57a..28dd961 100644 --- a/src_Core/RISCY_OOO/coherence/src/LLBank.bsv +++ b/src_Core/RISCY_OOO/coherence/src/LLBank.bsv @@ -51,6 +51,10 @@ import LatencyTimer::*; import Cntrs::*; import ConfigReg::*; import RandomReplace::*; +`ifdef PERFORMANCE_MONITORING +import PerformanceMonitor::*; +import BlueUtils::*; +`endif export LLCRqStuck(..); export LLBank(..); @@ -102,6 +106,9 @@ interface LLBank#( // performance method Action setPerfStatus(Bool stats); method Data getPerfData(LLCPerfType t); +`ifdef PERFORMANCE_MONITORING + method EventsCache events; +`endif endinterface typedef struct { @@ -219,6 +226,7 @@ module mkLLBank#( `endif // performance + LatencyTimer#(cRqNum, 10) latTimer <- mkLatencyTimer; // max 1K cycle latency `ifdef PERF_COUNT Reg#(Bool) doStats <- mkConfigReg(False); Count#(Data) dmaMemLdCnt <- mkCount(0); @@ -233,25 +241,34 @@ module mkLLBank#( Count#(Data) upRespDataCnt <- mkCount(0); Count#(Data) dmaLdReqCnt <- mkCount(0); Count#(Data) dmaStReqCnt <- mkCount(0); - - LatencyTimer#(cRqNum, 10) latTimer <- mkLatencyTimer; // max 1K cycle latency - - function Action incrMissCnt(cRqIndexT idx, Bool isDma); - action - let lat <- latTimer.done(idx); - if(doStats) begin - if(isDma) begin - dmaMemLdCnt.incr(1); - dmaMemLdLat.incr(zeroExtend(lat)); - end - else begin - normalMemLdCnt.incr(1); - normalMemLdLat.incr(zeroExtend(lat)); - end - end - endaction - endfunction `endif +`ifdef PERFORMANCE_MONITORING + Array #(Reg #(EventsCache)) perf_events <- mkDRegOR (2, unpack (0)); +`endif +function Action incrMissCnt(cRqIndexT idx, Bool isDma); +action + let lat <- latTimer.done(idx); +`ifdef PERF_COUNT + if(doStats) begin + if(isDma) begin + dmaMemLdCnt.incr(1); + dmaMemLdLat.incr(zeroExtend(lat)); + end + else begin + normalMemLdCnt.incr(1); + normalMemLdLat.incr(zeroExtend(lat)); + end + end +`endif +`ifdef PERFORMANCE_MONITORING + EventsCache events = unpack (0); + events.evt_LD_MISS_LAT = saturating_truncate(lat); // Don't support seperate DMA counts. + events.evt_LD_MISS = 1; + perf_events[1] <= events; +`endif +endaction +endfunction + function tagT getTag(Addr a) = truncateLSB(a); @@ -515,10 +532,8 @@ module mkLLBank#( fshow(cRq), " ; ", fshow(cSlot), " ; " ); -`ifdef PERF_COUNT // performance counter: normal miss lat and cnt incrMissCnt(n, False); -`endif endrule // this mem resp is just for a DMA req, won't go into pipeline to refill cache @@ -530,10 +545,8 @@ module mkLLBank#( // save data into cRq mshr & send to DMA resp IndexQ cRqMshr.mRsDeq.setData(mRs.id.mshrIdx, Valid (mRs.data)); rsLdToDmaIndexQ_mRsDeq.enq(mRs.id.mshrIdx); -`ifdef PERF_COUNT // performance counter: dma miss lat and cnt incrMissCnt(mRs.id.mshrIdx, True); -`endif endrule // send rd/wr to mem @@ -572,10 +585,8 @@ module mkLLBank#( $display("%t LL %m sendToM: load only: ", $time, fshow(msg)); doAssert(!isValid(data), "cannot have data"); doAssert(!doLdAfterReplace, "doLdAfterReplace should be false"); -`ifdef PERF_COUNT // performance counter: start miss timer latTimer.start(n); -`endif `ifdef DEBUG_DMA if(cRq.id matches tagged Dma .dmaId) begin dmaRdMissQ.enq(dmaId); // DMA read takes effect @@ -619,10 +630,8 @@ module mkLLBank#( doLdAfterReplace <= False; if (verbose) $display("%t LL %m sendToM: rep then ld: ld: ", $time, fshow(msg)); -`ifdef PERF_COUNT // performance counter: start miss timer latTimer.start(n); -`endif end else begin // do write back part toMemT msg = Wb (WbMemRs { @@ -1531,6 +1540,9 @@ module mkLLBank#( default: 0; endcase); endmethod + `ifdef PERFORMANCE_MONITORING + method EventsCache events = perf_events[0]; + `endif endmodule // Scheduling notes @@ -1593,4 +1605,3 @@ endmodule // -- this cRq is different from that in mRsDeq // -- this cRq is different from that in sendRsToC/sendRsToDma // -- XXX this cRq may be the same as that in sendRqToC!!! - diff --git a/src_Core/RISCY_OOO/procs/lib/LLCache.bsv b/src_Core/RISCY_OOO/procs/lib/LLCache.bsv index 401aa2c..70a5cf7 100644 --- a/src_Core/RISCY_OOO/procs/lib/LLCache.bsv +++ b/src_Core/RISCY_OOO/procs/lib/LLCache.bsv @@ -13,7 +13,7 @@ // // This work was supported by NCSC programme grant 4212611/RFA 15971 ("SafeBet"). //- -// +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -21,10 +21,10 @@ // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -254,6 +254,9 @@ interface LLCache; interface Get#(LLCStuck) cRqStuck; // performance interface Perf#(LLCPerfType) perf; +`ifdef PERFORMANCE_MONITORING + method EventsCache events; +`endif endinterface `ifdef SECURITY @@ -462,4 +465,7 @@ module mkLLCache(LLCache); `endif endmethod endinterface +`ifdef PERFORMANCE_MONITORING + method EventsCache events = cache.events; +`endif endmodule diff --git a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv index 83d3f00..8b13ae1 100755 --- a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv @@ -1041,10 +1041,10 @@ endfunction function x addPc(x cap, Bit#(12) inc) provisos (Add#(f, 12, c), CHERICap::CHERICap#(x, a, b, c, d, e)) = setAddrUnsafe(cap, getAddr(cap) + signExtend(inc)); `ifdef PERFORMANCE_MONITORING -typedef 96 No_Of_Evts; -typedef 8 Report_Width; -typedef 64 Counter_Width; -typedef 29 No_Of_Ctrs; +typedef 112 No_Of_Evts; +typedef 8 Report_Width; +typedef 64 Counter_Width; +typedef 29 No_Of_Ctrs; typedef struct { SupCnt evt_REDIRECT;