Merge branch 'cheri-perfmon' into CHERI

This commit is contained in:
jon
2020-12-04 16:29:51 +00:00
7 changed files with 322 additions and 16 deletions

View File

@@ -59,6 +59,10 @@ import TlbTypes::*;
import SynthParam::*;
import VerificationPacket::*;
import Performance::*;
`ifdef PERFORMANCE_MONITORING
import PerformanceMonitor::*;
import SpecialWires::*;
`endif
import HasSpecBits::*;
import Exec::*;
import FetchStage::*;
@@ -232,6 +236,13 @@ typedef enum {
} Core_Run_State
deriving (Bits, Eq, FShow);
`ifdef PERFORMANCE_MONITORING
instance BitVectorable #(EventsCore, SizeOf#(SupCnt), EventsCoreElements) provisos (Bits #(EventsCore, m));
function Vector#(EventsCoreElements, SupCnt) to_vector(EventsCore e) =
reverse(unpack(pack(e)));
endinstance
`endif
(* synthesize *)
module mkCore#(CoreId coreId)(Core);
let verbose = False;
@@ -258,6 +269,14 @@ module mkCore#(CoreId coreId)(Core);
Vector #(SupSize, FIFOF #(Trace_Data2)) v_f_to_TV <- replicateM (mkFIFOF);
`endif
`ifdef PERFORMANCE_MONITORING
Array #(Wire #(EventsCore)) aw_events <- mkDWireOR (5, unpack (0));
Reg #(EventsCore) aw_events_reg <- mkConfigReg(unpack(0));
rule update_aw_events_reg;
aw_events_reg <= aw_events[0];
endrule
`endif
// ================================================================
// front end
@@ -400,6 +419,11 @@ module mkCore#(CoreId coreId)(Core);
`endif
);
globalSpecUpdate.incorrectSpec(False, spec_tag, inst_tag);
`ifdef PERFORMANCE_MONITORING
EventsCore events = unpack (0);
events.evt_REDIRECT = 1;
aw_events[1] <= events;
`endif
endmethod
method correctSpec = globalSpecUpdate.correctSpec[finishAluCorrectSpecPort(i)].put;
method doStats = doStatsReg._read;
@@ -1075,6 +1099,31 @@ module mkCore#(CoreId coreId)(Core);
endrule
`endif
`ifdef PERFORMANCE_MONITORING
// ================================================================
// Performance counters
rule report_commit_events;
aw_events[2] <= commitStage.events;
endrule
Vector #(1, Bit #(Report_Width)) null_evt = replicate (0);
Vector #(31, Bit #(Report_Width)) core_evts_vec = to_large_vector (aw_events_reg);
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 #(32, Bit #(Report_Width)) external_evts_vec = replicate (0);//to_large_vector (w_external_evts);
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);
(* fire_when_enabled, no_implicit_conditions *)
rule rl_send_perf_evts;
csrf.send_performance_events (events);
endrule
`endif
`ifdef INCLUDE_GDB_CONTROL
// ================================================================
// DEBUG MODULE INTERFACE

View File

@@ -58,6 +58,10 @@ import ISA_Decls_CHERI::*;
import Cur_Cycle :: *;
`ifdef PERFORMANCE_MONITORING
import PerformanceMonitor :: *;
`endif
// ================================================================
// Project imports from Toooba
@@ -179,6 +183,10 @@ interface CsrFile;
method Action dcsr_cause_write (Bit #(3) dcsr_cause);
`endif
`ifdef PERFORMANCE_MONITORING
(* always_ready, always_enabled *)
method Action send_performance_events (Vector #(No_Of_Evts, Bit #(Report_Width)) evts);
`endif
endinterface
// Fancy Reg functions
@@ -233,6 +241,38 @@ function Reg#(t) addWriteSideEffect(Reg#(t) r, Action a);
endinterface);
endfunction
`ifdef PERFORMANCE_MONITORING
interface PerfCountersVec;
interface Vector#(No_Of_Ctrs, Reg#(Data)) counter_vec;
interface Vector#(No_Of_Ctrs, Reg#(Data)) event_vec;
interface Reg#(Data) inhibit;
method Action send_performance_events (Vector #(No_Of_Evts, Bit#(Report_Width)) evts);
endinterface
(* synthesize *)
module mkPerfCountersToooba (PerfCountersVec);
PerfCounters_IFC #(No_Of_Ctrs, Counter_Width, Report_Width, No_Of_Evts) perf_counters <- mkPerfCounters;
Vector#(No_Of_Ctrs, Reg#(Data)) counters = ?;
for (Bit#(TLog#(No_Of_Ctrs)) i = 0; i < 29; i = i + 1) counters[i] =
interface Reg;
method Action _write(Data x) = perf_counters.write_counter(i,x);
method Data _read = perf_counters.read_counters[i];
endinterface;
Vector#(No_Of_Ctrs, Reg#(Data)) events = ?;
for (Bit#(TLog#(No_Of_Ctrs)) i = 0; i < 29; i = i + 1) events[i] =
interface Reg;
method Action _write(Data x) = perf_counters.write_ctr_sel(i,truncate(x));
method Data _read = zeroExtend(perf_counters.read_ctr_sels[i]);
endinterface;
interface counter_vec = counters;
interface event_vec = events;
interface inhibit = interface Reg;
method Action _write(Data x) = perf_counters.write_ctr_inhibit(truncate(x));
method Data _read = zeroExtend(perf_counters.read_ctr_inhibit);
endinterface;
method send_performance_events = perf_counters.send_performance_events;
endmodule
`endif
function Bool has_csr_permission(CSR csr, Bit#(2) prv, Bool write);
Bit#(12) csr_index = pack(csr);
return ((prv >= csr_index[9:8]) && (!write || (csr_index[11:10] != 2'b11)));
@@ -682,6 +722,16 @@ module mkCsrFile #(Data hartid)(CsrFile);
Reg #(Data) rg_dscratch1 <- mkConfigRegU;
`endif
`ifdef PERFORMANCE_MONITORING
PerfCountersVec perf_counters <- mkPerfCountersToooba;
//Reg #(Bit #(2)) rg_ctr_inhib_lsb <- mkReg (0);
//Wire #(Bit #(2)) w_ctr_inhib_lsb <- mkWire;
//Bit #(3) ctr_inhibit_lsb = { rg_ctr_inhib_lsb [1], 0, rg_ctr_inhib_lsb [0] };
//Word ctr_inhibit = zeroExtend ({ perf_counters.read_ctr_inhibit, ctr_inhibit_lsb });
//CSR_Addr no_of_ctrs = fromInteger (valueOf (No_Of_Ctrs));
`endif
`ifdef SECURITY
// sanctum machine CSRs
@@ -756,6 +806,14 @@ module mkCsrFile #(Data hartid)(CsrFile);
// Function for getting a csr given an index
function Reg#(Data) get_csr(CSR csr);
Reg#(Data) ret = readOnlyReg(64'b0);
`ifdef PERFORMANCE_MONITORING
let c = csr.addr;
if ((csrAddrMHPMCOUNTER3.addr <= c) && (c <= csrAddrMHPMCOUNTER31.addr))
ret = perf_counters.counter_vec[c-csrAddrMHPMCOUNTER3.addr];
if ((csrAddrMHPMEVENT3.addr <= c) && (c <= csrAddrMHPMEVENT31.addr))
ret = perf_counters.event_vec[c - csrAddrMHPMEVENT3.addr];
`endif
return (case (csr)
// User CSRs
csrAddrFFLAGS: fflags_csr;
@@ -797,6 +855,9 @@ module mkCsrFile #(Data hartid)(CsrFile);
csrAddrMIMPID: mimpid_csr;
csrAddrMHARTID: mhartid_csr;
csrAddrMCCSR: csr_capcause(mccsr_reg);
`ifdef PERFORMANCE_MONITORING
csrAddrMCOUNTERINHIBIT: perf_counters.inhibit;
`endif
`ifdef SECURITY
csrAddrMEVBASE: mevbase_csr;
csrAddrMEVMASK: mevmask_csr;
@@ -810,20 +871,19 @@ module mkCsrFile #(Data hartid)(CsrFile);
csrAddrMSPEC: mspec_csr;
csrAddrTRNG: trng_csr;
`endif
csrAddrTSELECT: rg_tselect;
csrAddrTDATA1: rg_tdata1;
csrAddrTDATA2: rg_tdata2;
csrAddrTDATA3: rg_tdata3;
csrAddrTSELECT: rg_tselect;
csrAddrTDATA1: rg_tdata1;
csrAddrTDATA2: rg_tdata2;
csrAddrTDATA3: rg_tdata3;
`ifdef INCLUDE_GDB_CONTROL
csrAddrDCSR: rg_dcsr; // TODO: take NMI into account (cf. Piccolo/Flute)
csrAddrDPC: scrToCsr(rg_dpc);
csrAddrDSCRATCH0: rg_dscratch0;
csrAddrDSCRATCH1: rg_dscratch1;
csrAddrDCSR: rg_dcsr; // TODO: take NMI into account (cf. Piccolo/Flute)
csrAddrDPC: scrToCsr(rg_dpc);
csrAddrDSCRATCH0: rg_dscratch0;
csrAddrDSCRATCH1: rg_dscratch1;
`endif
default: readOnlyReg(64'b0);
default: ret;
endcase);
endfunction
@@ -1341,4 +1401,7 @@ module mkCsrFile #(Data hartid)(CsrFile);
`endif
`ifdef PERFORMANCE_MONITORING
method send_performance_events = perf_counters.send_performance_events;
`endif
endmodule