From 259d34618c61f030d04ae8b4ea89f338f87642ba Mon Sep 17 00:00:00 2001 From: jon Date: Tue, 1 Dec 2020 18:02:11 +0000 Subject: [PATCH] A design that actually passes one performance monitor trace from TestRig. The example counted redirections, which happend to match between Flute and Toooba for this example. --- .../Makefile | 1 + src_Core/CPU/Core.bsv | 80 ++++++++++++++++ src_Core/CPU/CsrFile.bsv | 80 ++++++++++++++-- src_Core/RISCY_OOO/procs/lib/CSRs.bsvi | 95 +++++++++++++++++++ src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv | 6 ++ 5 files changed, 252 insertions(+), 10 deletions(-) diff --git a/builds/RV64ACDFIMSUxCHERI_Toooba_RVFI_DII_bluesim/Makefile b/builds/RV64ACDFIMSUxCHERI_Toooba_RVFI_DII_bluesim/Makefile index 6316758..11baa09 100644 --- a/builds/RV64ACDFIMSUxCHERI_Toooba_RVFI_DII_bluesim/Makefile +++ b/builds/RV64ACDFIMSUxCHERI_Toooba_RVFI_DII_bluesim/Makefile @@ -38,6 +38,7 @@ BSC_COMPILATION_FLAGS += \ -D CheriMasterIDWidth=1 \ -D CheriTransactionIDWidth=5 \ -D CAP128 -D BLUESIM \ + -D PERFORMANCE_MONITORING \ -D MEM64 \ -D RISCV \ -D RVFI_DII \ diff --git a/src_Core/CPU/Core.bsv b/src_Core/CPU/Core.bsv index 1c16a97..238ece2 100644 --- a/src_Core/CPU/Core.bsv +++ b/src_Core/CPU/Core.bsv @@ -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::*; @@ -157,6 +161,48 @@ interface CoreRenameDebug; interface Get#(RenameErrInfo) renameErr; endinterface +// ================================================================ + +`ifdef PERFORMANCE_MONITORING +typedef struct { + Bool evt_REDIRECT; + Bool evt_TLB_EXC; // TODO: Misleading name + Bool evt_BRANCH; + Bool evt_JAL; + Bool evt_JALR; + Bool evt_AUIPC; + Bool evt_LOAD; + Bool evt_STORE; + Bool evt_LR; + Bool evt_SC; + Bool evt_AMO; + Bool evt_SERIAL_SHIFT; + Bool evt_INT_MUL_DIV_REM; + Bool evt_FP; + Bool evt_SC_SUCCESS; + Bool evt_LOAD_WAIT; + Bool evt_STORE_WAIT; + Bool evt_FENCE; + Bool evt_F_BUSY_NO_CONSUME; + Bool evt_D_BUSY_NO_CONSUME; + Bool evt_1_BUSY_NO_CONSUME; + Bool evt_2_BUSY_NO_CONSUME; + Bool evt_3_BUSY_NO_CONSUME; + Bool evt_IMPRECISE_SETBOUND; + Bool evt_UNREPRESENTABLE_CAP; + Bool evt_MEM_CAP_LOAD; + Bool evt_MEM_CAP_STORE; + Bool evt_MEM_CAP_LOAD_TAG_SET; + Bool evt_MEM_CAP_STORE_TAG_SET; +} EventsCore deriving (Bits, FShow); + +instance BitVectorable #(EventsCore, 1, m) provisos (Bits #(EventsCore, m)); + function to_vector = struct_to_vector; +endinstance +`endif + +// ================================================================ + interface Core; // core request & indication interface CoreReq coreReq; @@ -258,6 +304,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 +454,11 @@ module mkCore#(CoreId coreId)(Core); `endif ); globalSpecUpdate.incorrectSpec(False, spec_tag, inst_tag); +`ifdef PERFORMANCE_MONITORING + EventsCore events = unpack (0); + events.evt_REDIRECT = True; + aw_events[1] <= events; +`endif endmethod method correctSpec = globalSpecUpdate.correctSpec[finishAluCorrectSpecPort(i)].put; method doStats = doStatsReg._read; @@ -1075,6 +1134,27 @@ module mkCore#(CoreId coreId)(Core); endrule `endif +`ifdef PERFORMANCE_MONITORING + // ================================================================ + // Performance counters + + Vector #(1, Bit #(Counter_Width)) null_evt = replicate (0); + Vector #(31, Bit #(Counter_Width)) core_evts_vec = to_large_vector (aw_events_reg); + Vector #(16, Bit #(Counter_Width)) imem_evts_vec = replicate (0);//to_large_vector (near_mem.imem.events); + Vector #(16, Bit #(Counter_Width)) dmem_evts_vec = replicate (0);//to_large_vector (near_mem.dmem.events); + Vector #(32, Bit #(Counter_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 diff --git a/src_Core/CPU/CsrFile.bsv b/src_Core/CPU/CsrFile.bsv index 9519ac2..c09ff4d 100644 --- a/src_Core/CPU/CsrFile.bsv +++ b/src_Core/CPU/CsrFile.bsv @@ -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 #(Counter_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#(Counter_Width)) evts); +endinterface +(* synthesize *) +module mkPerfCountersToooba (PerfCountersVec); + PerfCounters_IFC #(No_Of_Ctrs, Counter_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 ((csrAddrMHPMCNT3.addr <= c) && (c <= csrAddrMHPMCNT31.addr)) + ret = perf_counters.counter_vec[c-csrAddrMHPMCNT3.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; @@ -810,20 +868,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 +1398,7 @@ module mkCsrFile #(Data hartid)(CsrFile); `endif +`ifdef PERFORMANCE_MONITORING + method send_performance_events = perf_counters.send_performance_events; +`endif endmodule diff --git a/src_Core/RISCY_OOO/procs/lib/CSRs.bsvi b/src_Core/RISCY_OOO/procs/lib/CSRs.bsvi index a7b029b..85e93bf 100644 --- a/src_Core/RISCY_OOO/procs/lib/CSRs.bsvi +++ b/src_Core/RISCY_OOO/procs/lib/CSRs.bsvi @@ -37,6 +37,101 @@ `CSR(MIP, 12'h344) `CSR(MCYCLE, 12'hb00) `CSR(MINSTRET, 12'hb02) + +`ifdef PERFORMANCE_MONITORING +`CSR(HPMCNT3, 12'hc03) +`CSR(HPMCNT4, 12'hc04) +`CSR(HPMCNT5, 12'hc05) +`CSR(HPMCNT6, 12'hc06) +`CSR(HPMCNT7, 12'hc07) +`CSR(HPMCNT8, 12'hc08) +`CSR(HPMCNT9, 12'hc09) +`CSR(HPMCNT10, 12'hc0a) +`CSR(HPMCNT11, 12'hc0b) +`CSR(HPMCNT12, 12'hc0c) +`CSR(HPMCNT13, 12'hc0d) +`CSR(HPMCNT14, 12'hc0e) +`CSR(HPMCNT15, 12'hc0f) +`CSR(HPMCNT16, 12'hc10) +`CSR(HPMCNT17, 12'hc11) +`CSR(HPMCNT18, 12'hc12) +`CSR(HPMCNT19, 12'hc13) +`CSR(HPMCNT20, 12'hc14) +`CSR(HPMCNT21, 12'hc15) +`CSR(HPMCNT22, 12'hc16) +`CSR(HPMCNT23, 12'hc17) +`CSR(HPMCNT24, 12'hc18) +`CSR(HPMCNT25, 12'hc19) +`CSR(HPMCNT26, 12'hc1a) +`CSR(HPMCNT27, 12'hc1b) +`CSR(HPMCNT28, 12'hc1c) +`CSR(HPMCNT29, 12'hc1d) +`CSR(HPMCNT30, 12'hc1e) +`CSR(HPMCNT31, 12'hc1f) + +`CSR(MHPMCNT3, 12'hb03) +`CSR(MHPMCNT4, 12'hb04) +`CSR(MHPMCNT5, 12'hb05) +`CSR(MHPMCNT6, 12'hb06) +`CSR(MHPMCNT7, 12'hb07) +`CSR(MHPMCNT8, 12'hb08) +`CSR(MHPMCNT9, 12'hb09) +`CSR(MHPMCNT10, 12'hb0a) +`CSR(MHPMCNT11, 12'hb0b) +`CSR(MHPMCNT12, 12'hb0c) +`CSR(MHPMCNT13, 12'hb0d) +`CSR(MHPMCNT14, 12'hb0e) +`CSR(MHPMCNT15, 12'hb0f) +`CSR(MHPMCNT16, 12'hb10) +`CSR(MHPMCNT17, 12'hb11) +`CSR(MHPMCNT18, 12'hb12) +`CSR(MHPMCNT19, 12'hb13) +`CSR(MHPMCNT20, 12'hb14) +`CSR(MHPMCNT21, 12'hb15) +`CSR(MHPMCNT22, 12'hb16) +`CSR(MHPMCNT23, 12'hb17) +`CSR(MHPMCNT24, 12'hb18) +`CSR(MHPMCNT25, 12'hb19) +`CSR(MHPMCNT26, 12'hb1a) +`CSR(MHPMCNT27, 12'hb1b) +`CSR(MHPMCNT28, 12'hb1c) +`CSR(MHPMCNT29, 12'hb1d) +`CSR(MHPMCNT30, 12'hb1e) +`CSR(MHPMCNT31, 12'hb1f) + +`CSR(MCNTIHB, 12'h320) // Machine Counter-Inhibit + +`CSR(MHPMEVENT3, 12'h323) +`CSR(MHPMEVENT4, 12'h324) +`CSR(MHPMEVENT5, 12'h325) +`CSR(MHPMEVENT6, 12'h326) +`CSR(MHPMEVENT7, 12'h327) +`CSR(MHPMEVENT8, 12'h328) +`CSR(MHPMEVENT9, 12'h329) +`CSR(MHPMEVENT10, 12'h32a) +`CSR(MHPMEVENT11, 12'h32b) +`CSR(MHPMEVENT12, 12'h32c) +`CSR(MHPMEVENT13, 12'h32d) +`CSR(MHPMEVENT14, 12'h32e) +`CSR(MHPMEVENT15, 12'h32f) +`CSR(MHPMEVENT16, 12'h330) +`CSR(MHPMEVENT17, 12'h331) +`CSR(MHPMEVENT18, 12'h332) +`CSR(MHPMEVENT19, 12'h333) +`CSR(MHPMEVENT20, 12'h334) +`CSR(MHPMEVENT21, 12'h335) +`CSR(MHPMEVENT22, 12'h336) +`CSR(MHPMEVENT23, 12'h337) +`CSR(MHPMEVENT24, 12'h338) +`CSR(MHPMEVENT25, 12'h339) +`CSR(MHPMEVENT26, 12'h33a) +`CSR(MHPMEVENT27, 12'h33b) +`CSR(MHPMEVENT28, 12'h33c) +`CSR(MHPMEVENT29, 12'h33d) +`CSR(MHPMEVENT30, 12'h33e) +`CSR(MHPMEVENT31, 12'h33f) +`endif // PERFORMANCE_MONITORING + `CSR(MVENDORID, 12'hf11) `CSR(MARCHID, 12'hf12) `CSR(MIMPID, 12'hf13) diff --git a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv index 85c6235..34d5e2a 100755 --- a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv @@ -1040,3 +1040,9 @@ function Fmt showInst(Instruction inst); endfunction function x addPc(x cap, Bit#(12) inc) provisos (Add#(f, 12, c), CHERICap::CHERICap#(x, a, b, c, d, e)) = setAddrUnsafe(cap, getAddr(cap) + signExtend(inc)); + +`ifdef PERFORMANCE_MONITORING +typedef 96 No_Of_Evts; +typedef 64 Counter_Width; +typedef 29 No_Of_Ctrs; +`endif