Add counter support to ITLB.

This commit is contained in:
jon
2020-12-17 17:57:43 +00:00
parent 4ddcaff497
commit f86d4d9dc0
2 changed files with 40 additions and 10 deletions

View File

@@ -1121,7 +1121,8 @@ module mkCore#(CoreId coreId)(Core);
Vector #(31, Bit #(Report_Width)) mem_core_evts_vec = to_large_vector (coreFix.memExeIfc.events);
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);
EventsCache instMem = unpack(pack(iMem.events) | pack(iTlb.events));
Vector #(16, Bit #(Report_Width)) imem_evts_vec = to_large_vector (instMem);
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);

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
@@ -49,6 +49,11 @@ import Cntrs::*;
import SafeCounter::*;
import CacheUtils::*;
import LatencyTimer::*;
`ifdef PERFORMANCE_MONITORING
import PerformanceMonitor::*;
import CCTypes::*;
import BlueUtils::*;
`endif
// currently blocking
typedef `L1_TLB_SIZE ITlbSize;
@@ -60,7 +65,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;
} ITlbRsFromP deriving(Bits, Eq, FShow);
interface ITlbToParent;
@@ -85,6 +90,9 @@ interface ITlb;
// performance
interface Perf#(L1TlbPerfType) perf;
`ifdef PERFORMANCE_MONITORING
method EventsCache events;
`endif
endinterface
typedef FullAssocTlb#(ITlbSize) ITlbArray;
@@ -122,6 +130,7 @@ module mkITlb(ITlb::ITlb);
Fifo#(1, void) flushRsFromPQ <- mkCFFifo;
// perf counters
LatencyTimer#(2, 12) latTimer <- mkLatencyTimer; // max latency: 4K cycles
Fifo#(1, L1TlbPerfType) perfReqQ <- mkCFFifo;
`ifdef PERF_COUNT
Fifo#(1, PerfResp#(L1TlbPerfType)) perfRespQ <- mkCFFifo;
@@ -130,8 +139,6 @@ module mkITlb(ITlb::ITlb);
Count#(Data) missCnt <- mkCount(0);
Count#(Data) missLat <- mkCount(0);
LatencyTimer#(2, 12) latTimer <- mkLatencyTimer; // max latency: 4K cycles
rule doPerf;
let t <- toGet(perfReqQ).get;
Data d = (case(t)
@@ -146,6 +153,9 @@ module mkITlb(ITlb::ITlb);
});
endrule
`endif
`ifdef PERFORMANCE_MONITORING
Array #(Reg #(EventsCache)) perf_events <- mkDRegOR (3, unpack (0));
`endif
// do flush: only start when all misses resolve
rule doStartFlush(needFlush && !waitFlushP && !isValid(miss));
@@ -154,6 +164,11 @@ module mkITlb(ITlb::ITlb);
flushRqToPQ.enq(?);
waitFlushP <= True;
if(verbose) $display("ITLB %m: flush begin");
`ifdef PERFORMANCE_MONITORING
EventsCache ev = unpack(0);
ev.evt_TLB_FLUSH = 1;
perf_events[2] <= ev;
`endif
endrule
rule doFinishFlush(needFlush && waitFlushP && !isValid(miss));
@@ -172,7 +187,7 @@ module mkITlb(ITlb::ITlb);
// search TLB to check whether the PTE is already in TLB; this may
// happen for mega/giga pages. We don't want same PTE to occupy >1
// TLB entires.
// check permission
if(hasVMPermission(vm_info,
en.pteType,
@@ -206,11 +221,17 @@ module mkITlb(ITlb::ITlb);
// miss resolved
miss <= Invalid;
`ifdef PERF_COUNT
let lat <- latTimer.done(0);
`ifdef PERF_COUNT
if(doStats) begin
missLat.incr(zeroExtend(lat));
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
endrule
@@ -320,8 +341,8 @@ module mkITlb(ITlb::ITlb);
if(verbose) begin
$display("ITLB %m req (miss): ", fshow(vaddr));
end
`ifdef PERF_COUNT
latTimer.start(0);
`ifdef PERF_COUNT
if(doStats) begin
missCnt.incr(1);
end
@@ -338,6 +359,11 @@ module mkITlb(ITlb::ITlb);
if(doStats) begin
accessCnt.incr(1);
end
`endif
`ifdef PERFORMANCE_MONITORING
EventsCache ev = unpack(0);
ev.evt_TLB = 1;
perf_events[1] <= ev;
`endif
endmethod
endinterface
@@ -387,4 +413,7 @@ module mkITlb(ITlb::ITlb);
`endif
endmethod
endinterface
`ifdef PERFORMANCE_MONITORING
method EventsCache events = perf_events[0];
`endif
endmodule