Support for data TLB counters.

This commit is contained in:
jon
2020-12-17 16:52:45 +00:00
parent 4dd0a73051
commit 4ddcaff497
2 changed files with 38 additions and 11 deletions

View File

@@ -1122,7 +1122,8 @@ module mkCore#(CoreId coreId)(Core);
Vector #(31, Bit #(Report_Width)) other_core_evts_vec = to_large_vector (hpm_core_events[0]);
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 = to_large_vector (iMem.events);
Vector #(16, Bit #(Report_Width)) dmem_evts_vec = to_large_vector (dMem.events);
EventsCache dataMem = unpack(pack(dMem.events) | pack(dTlb.events));
Vector #(16, Bit #(Report_Width)) dmem_evts_vec = to_large_vector (dataMem);
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);
Vector #(16, Bit #(Report_Width)) tgc_evts_vec = to_large_vector (events_tgc_reg);

View File

@@ -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
@@ -52,6 +52,11 @@ import LatencyTimer::*;
import HasSpecBits::*;
import Vector::*;
import Ehr::*;
`ifdef PERFORMANCE_MONITORING
import PerformanceMonitor::*;
import CCTypes::*;
import BlueUtils::*;
`endif
export DTlbReq(..);
export DTlbResp(..);
@@ -86,7 +91,7 @@ typedef struct {
typedef struct {
// may get page fault: i.e. hit invalid page or
// get non-leaf page at last-level page table
Maybe#(TlbEntry) entry;
Maybe#(TlbEntry) entry;
DTlbReqIdx id;
} DTlbTransRsFromP deriving(Bits, Eq, FShow);
@@ -117,6 +122,9 @@ interface DTlb#(type instT);
// performance
interface Perf#(L1TlbPerfType) perf;
`ifdef PERFORMANCE_MONITORING
method EventsCache events;
`endif
endinterface
typedef FullAssocTlb#(DTlbSize) DTlbArray;
@@ -199,6 +207,7 @@ module mkDTlb#(
Fifo#(1, void) flushRsFromPQ <- mkCFFifo;
// perf counters
LatencyTimer#(DTlbReqNum, 12) latTimer <- mkLatencyTimer; // max latency: 4K cycles
Fifo#(1, L1TlbPerfType) perfReqQ <- mkCFFifo;
`ifdef PERF_COUNT
Fifo#(1, PerfResp#(L1TlbPerfType)) perfRespQ <- mkCFFifo;
@@ -211,8 +220,6 @@ module mkDTlb#(
Count#(Data) hitUnderMissCnt <- mkCount(0);
Count#(Data) allMissCycles <- mkCount(0);
LatencyTimer#(DTlbReqNum, 12) latTimer <- mkLatencyTimer; // max latency: 4K cycles
rule doPerf;
let t <- toGet(perfReqQ).get;
Data d = (case(t)
@@ -236,6 +243,9 @@ module mkDTlb#(
when(all(isMiss, readVReg(pendWait)), allMissCycles.incr(1));
endrule
`endif
`ifdef PERFORMANCE_MONITORING
Array #(Reg #(EventsCache)) perf_events <- mkDRegOR (3, unpack (0));
`endif
// do flush: start when all misses resolve
Bool noMiss = all(\== (False) , readVReg(pendValid_noMiss));
@@ -246,6 +256,11 @@ module mkDTlb#(
flushRqToPQ.enq(?);
waitFlushP <= True;
if(verbose) $display("[DTLB] flush begin");
`ifdef PERFORMANCE_MONITORING
EventsCache ev = unpack(0);
ev.evt_TLB_FLUSH = 1;
perf_events[2] <= ev;
`endif
endrule
rule doFinishFlush(needFlush && waitFlushP);
@@ -333,9 +348,9 @@ module mkDTlb#(
ldTransRsFromPQ.deq;
end
`ifdef PERF_COUNT
// perf: miss
let lat <- latTimer.done(idx);
`ifdef PERF_COUNT
if(doStats) begin
if(isValid(respForOtherReq)) begin
missPeerLat.incr(zeroExtend(lat));
@@ -347,7 +362,12 @@ module mkDTlb#(
end
end
`endif
`ifdef PERFORMANCE_MONITORING
EventsCache ev = unpack(0);
ev.evt_TLB_MISS_LAT = saturating_truncate(lat);
ev.evt_TLB_MISS = 1;
perf_events[0] <= ev;
`endif
// conflict with wrong spec
wrongSpec_doPRs_conflict.wset(?);
endrule
@@ -516,10 +536,8 @@ module mkDTlb#(
idx, fshow(r));
end
end
`ifdef PERF_COUNT
// perf: miss
latTimer.start(idx);
`endif
end
end
else begin
@@ -534,6 +552,11 @@ module mkDTlb#(
if(doStats) begin
accessCnt.incr(1);
end
`endif
`ifdef PERFORMANCE_MONITORING
EventsCache ev = unpack(0);
ev.evt_TLB = 1;
perf_events[1] <= ev;
`endif
// conflict with wrong spec
wrongSpec_procReq_conflict.wset(?);
@@ -623,4 +646,7 @@ module mkDTlb#(
`endif
endmethod
endinterface
`ifdef PERFORMANCE_MONITORING
method EventsCache events = perf_events[0];
`endif
endmodule