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.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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!!!
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user