Support performance counters (hopefully) in the caches. The DCache
should be fully wired up.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user