Add counter support to ITLB.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user