diff --git a/src_Core/CPU/Core.bsv b/src_Core/CPU/Core.bsv index 1f77235..071c975 100644 --- a/src_Core/CPU/Core.bsv +++ b/src_Core/CPU/Core.bsv @@ -201,6 +201,13 @@ interface Core; interface Vector #(SupSize, Get #(Trace_Data2)) v_to_TV; `endif +`ifdef DEBUG_WEDGE + (* always_enabled *) + method Tuple2#(CapMem, Bit#(32)) debugLastInst; + (* always_enabled *) + method Tuple2#(CapMem, Bit#(32)) debugNextInst; +`endif + endinterface // fixpoint to instantiate modules @@ -1446,4 +1453,9 @@ module mkCore#(CoreId coreId)(Core); interface v_to_TV = map (toGet, v_f_to_TV); `endif +`ifdef DEBUG_WEDGE + method Tuple2#(CapMem, Bit#(32)) debugLastInst = commitStage.debugLastInst; + method Tuple2#(CapMem, Bit#(32)) debugNextInst = rob.debugNextInst; +`endif + endmodule diff --git a/src_Core/CPU/Proc.bsv b/src_Core/CPU/Proc.bsv index 219bad9..740a52c 100644 --- a/src_Core/CPU/Proc.bsv +++ b/src_Core/CPU/Proc.bsv @@ -103,6 +103,11 @@ import ProcTypes :: *; import Trace_Data2 :: *; `endif +`ifdef DEBUG_WEDGE +import CHERICap :: *; +import CHERICC_Fat :: *; +`endif + // ================================================================ (* synthesize *) @@ -328,6 +333,11 @@ module mkProc (Proc_IFC); interface v_to_TV = core [0].v_to_TV; `endif +`ifdef DEBUG_WEDGE + method Tuple2#(CapMem, Bit#(32)) hart0_last_inst = core[0].debugLastInst; + method Tuple2#(CapMem, Bit#(32)) hart0_next_inst = core[0].debugNextInst; +`endif + endmodule: mkProc // ================================================================ diff --git a/src_Core/CPU/Proc_IFC.bsv b/src_Core/CPU/Proc_IFC.bsv index 7c4a263..dca743b 100644 --- a/src_Core/CPU/Proc_IFC.bsv +++ b/src_Core/CPU/Proc_IFC.bsv @@ -46,6 +46,11 @@ import Trace_Data2 :: *; import Types :: *; `endif +`ifdef DEBUG_WEDGE +import CHERICap :: *; +import CHERICC_Fat :: *; +`endif + // ================================================================ // CPU interface @@ -128,6 +133,13 @@ interface Proc_IFC; interface Vector #(SupSize, Get #(Trace_Data2)) v_to_TV; `endif +`ifdef DEBUG_WEDGE + (* always_enabled *) + method Tuple2#(CapMem, Bit#(32)) hart0_last_inst; + (* always_enabled *) + method Tuple2#(CapMem, Bit#(32)) hart0_next_inst; +`endif + endinterface // ================================================================ diff --git a/src_Core/Core/CoreW.bsv b/src_Core/Core/CoreW.bsv index 7bbbff7..d573715 100644 --- a/src_Core/Core/CoreW.bsv +++ b/src_Core/Core/CoreW.bsv @@ -231,6 +231,11 @@ module mkCoreW #(Reset dm_power_on_reset) mkConnection (debug_module.hart0_client_run_halt, proc.hart0_run_halt_server); mkConnection (debug_module.hart0_get_other_req, proc.hart0_put_other_req); + +`ifdef DEBUG_WEDGE + mkConnection (proc.hart0_last_inst, debug_module.hart0_last_inst); + mkConnection (proc.hart0_next_inst, debug_module.hart0_next_inst); +`endif `endif `ifdef INCLUDE_TANDEM_VERIF diff --git a/src_Core/Debug_Module/DM_Common.bsv b/src_Core/Debug_Module/DM_Common.bsv index 45049f2..cbb1a67 100644 --- a/src_Core/Debug_Module/DM_Common.bsv +++ b/src_Core/Debug_Module/DM_Common.bsv @@ -22,7 +22,7 @@ package DM_Common; typedef Bit #(7) DM_Addr; -DM_Addr max_DM_Addr = 'h5F; +DM_Addr max_DM_Addr = 'h7F; typedef Bit #(32) DM_Word; @@ -79,6 +79,26 @@ DM_Addr dm_addr_sbdata1 = 'h3d; DM_Addr dm_addr_sbdata2 = 'h3e; DM_Addr dm_addr_sbdata3 = 'h3f; +// ---------------- +// Custom registers + +DM_Addr dm_addr_custom0 = 'h70; +DM_Addr dm_addr_custom1 = 'h71; +DM_Addr dm_addr_custom2 = 'h72; +DM_Addr dm_addr_custom3 = 'h73; +DM_Addr dm_addr_custom4 = 'h74; +DM_Addr dm_addr_custom5 = 'h75; +DM_Addr dm_addr_custom6 = 'h76; +DM_Addr dm_addr_custom7 = 'h77; +DM_Addr dm_addr_custom8 = 'h78; +DM_Addr dm_addr_custom9 = 'h79; +DM_Addr dm_addr_custom10 = 'h7a; +DM_Addr dm_addr_custom11 = 'h7b; +DM_Addr dm_addr_custom12 = 'h7c; +DM_Addr dm_addr_custom13 = 'h7d; +DM_Addr dm_addr_custom14 = 'h7e; +DM_Addr dm_addr_custom15 = 'h7f; + // ================================================================ function Fmt fshow_dm_addr (DM_Addr dm_addr); diff --git a/src_Core/Debug_Module/Debug_Module.bsv b/src_Core/Debug_Module/Debug_Module.bsv index afe53be..1d3043a 100644 --- a/src_Core/Debug_Module/Debug_Module.bsv +++ b/src_Core/Debug_Module/Debug_Module.bsv @@ -91,6 +91,12 @@ import DM_Run_Control :: *; import DM_Abstract_Commands :: *; import DM_System_Bus :: *; +`ifdef DEBUG_WEDGE +import ConfigReg :: *; +import CHERICap :: *; +import CHERICC_Fat :: *; +`endif + // ================================================================ export DM_Common :: *; @@ -126,6 +132,15 @@ interface Debug_Module_IFC; // CSR access interface Client #(DM_CPU_Req #(12, XLEN), DM_CPU_Rsp #(XLEN)) hart0_csr_mem_client; + // Optional debug from commit stage and ROB +`ifdef DEBUG_WEDGE + (* always_enabled *) + method Action hart0_last_inst (Tuple2 #(CapMem, Bit #(32)) pcc_inst); + + (* always_enabled *) + method Action hart0_next_inst (Tuple2 #(CapMem, Bit #(32)) pcc_inst); +`endif + // ---------------- // Facing Platform @@ -154,6 +169,13 @@ module mkDebug_Module (Debug_Module_IFC); FIFO#(DM_Addr) f_read_addr <- mkFIFO1; +`ifdef DEBUG_WEDGE + Reg #(CapMem) rg_last_pcc <- mkConfigReg (unpack (0)); + Reg #(Bit #(32)) rg_last_inst <- mkConfigReg (0); + Reg #(CapMem) rg_next_pcc <- mkConfigReg (unpack (0)); + Reg #(Bit #(32)) rg_next_inst <- mkConfigReg (0); +`endif + // ================================================================ // Reset all three parts when dm_run_control.dmactive is low @@ -228,6 +250,32 @@ module mkDebug_Module (Debug_Module_IFC); dm_word <- dm_system_bus.av_read (dm_addr); +`ifdef DEBUG_WEDGE + else if (dm_addr == dm_addr_custom0) + + dm_word = getAddr (rg_last_pcc) [31:0]; + + else if (dm_addr == dm_addr_custom1) + + dm_word = getAddr (rg_last_pcc) [63:32]; + + else if (dm_addr == dm_addr_custom2) + + dm_word = rg_last_inst; + + else if (dm_addr == dm_addr_custom3) + + dm_word = getAddr (rg_next_pcc) [31:0]; + + else if (dm_addr == dm_addr_custom4) + + dm_word = getAddr (rg_next_pcc) [63:32]; + + else if (dm_addr == dm_addr_custom5) + + dm_word = rg_next_inst; +`endif + else begin // TODO: set error status? dm_word = 0; @@ -315,6 +363,19 @@ module mkDebug_Module (Debug_Module_IFC); // CSR access interface Client hart0_csr_mem_client = dm_abstract_commands.hart0_csr_mem_client; + // Optional debug from commit stage +`ifdef DEBUG_WEDGE + method Action hart0_last_inst (Tuple2 #(CapMem, Bit #(32)) pcc_inst); + rg_last_pcc <= tpl_1 (pcc_inst); + rg_last_inst <= tpl_2 (pcc_inst); + endmethod + + method Action hart0_next_inst (Tuple2 #(CapMem, Bit #(32)) pcc_inst); + rg_next_pcc <= tpl_1 (pcc_inst); + rg_next_inst <= tpl_2 (pcc_inst); + endmethod +`endif + // ---------------- // Facing Platform diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv index b3cc5b3..6531543 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv @@ -161,6 +161,10 @@ interface CommitStage; method Bool is_debug_halted; method Action debug_resume; `endif +`ifdef DEBUG_WEDGE + (* always_enabled *) + method Tuple2#(CapMem, Bit#(32)) debugLastInst; +`endif endinterface // we apply actions the end of commit rule @@ -620,6 +624,11 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); endfunction `endif +`ifdef DEBUG_WEDGE + Reg#(CapMem) rg_last_pcc <- mkReg(unpack(0)); + Reg#(Bit#(32)) rg_last_inst <- mkReg(0); +`endif + // TODO Currently we don't check spec bits == 0 when we commit an // instruction. This is because killings of wrong path instructions are // done in a single cycle. However, when we make killings distributed or @@ -779,6 +788,13 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); x, no_fflags, no_mstatus, tagged Valid trap_updates, no_ret_updates); `endif rg_serial_num <= rg_serial_num + 1; +`ifdef DEBUG_WEDGE + Bool is_exception = trap.trap matches tagged Interrupt .i ? False : True; + if (is_exception) begin + rg_last_pcc <= trap.pc; + rg_last_inst <= trap.orig_inst; + end +`endif // system consistency // TODO spike flushes TLB here, but perhaps it is because spike's TLB @@ -945,6 +961,10 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); x, no_fflags, new_mstatus, no_trap_updates, m_ret_updates); `endif rg_serial_num <= rg_serial_num + 1; +`ifdef DEBUG_WEDGE + rg_last_pcc <= x.pc; + rg_last_inst <= x.orig_inst; +`endif // rename stage only sends out system inst when ROB is empty, so no // need to flush ROB again @@ -1068,6 +1088,10 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); // (whereas the 'fflags' variable does just one update after superscalar retirement). Bit #(5) po_fflags = ?; Data po_mstatus = ?; +`endif +`ifdef DEBUG_WEDGE + CapMem last_pcc = rg_last_pcc; + Bit#(32) last_inst = rg_last_inst; `endif // compute what actions to take for(Integer i = 0; i < valueof(SupSize); i = i+1) begin @@ -1110,6 +1134,10 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); no_trap_updates, no_ret_updates); `endif instret = instret + 1; +`ifdef DEBUG_WEDGE + last_pcc = x.pc; + last_inst = x.orig_inst; +`endif // inst can be committed, deq it rob.deqPort[i].deq; @@ -1163,6 +1191,10 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); end end rg_serial_num <= rg_serial_num + instret; +`ifdef DEBUG_WEDGE + rg_last_pcc <= last_pcc; + rg_last_inst <= last_inst; +`endif // write FPU csr if(csrf.fpuInstNeedWr(fflags, will_dirty_fpu_state)) begin @@ -1281,4 +1313,10 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); endmethod `endif +`ifdef DEBUG_WEDGE + method Tuple2#(CapMem, Bit#(32)) debugLastInst; + return tuple2(rg_last_pcc, rg_last_inst); + endmethod +`endif + endmodule diff --git a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv index 8425be9..1609f8d 100755 --- a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv @@ -661,6 +661,11 @@ interface SupReorderBuffer#(numeric type aluExeNum, numeric type fpuMulDivExeNum method Bool isFull_ehrPort0; interface ROB_SpeculationUpdate specUpdate; + +`ifdef DEBUG_WEDGE + (* always_enabled *) + method Tuple2#(CapMem, Bit#(32)) debugNextInst; +`endif endinterface typedef struct { @@ -1305,4 +1310,10 @@ module mkSupReorderBuffer#( end endmethod endinterface + +`ifdef DEBUG_WEDGE + method Tuple2#(CapMem, Bit#(32)) debugNextInst; + return tuple2(fifo_first[0].pc, fifo_first[0].orig_inst); + endmethod +`endif endmodule diff --git a/src_SSITH_P3/Makefile b/src_SSITH_P3/Makefile index 19bd37c..740c1f3 100644 --- a/src_SSITH_P3/Makefile +++ b/src_SSITH_P3/Makefile @@ -40,6 +40,9 @@ BSC_COMPILATION_FLAGS += \ -D BRVF_TRACE \ -D XILINX_BSCAN -D JTAG_TAP +# Enable to expose last and next instruction info as DMI registers +#BSC_COMPILATION_FLAGS += -D DEBUG_WEDGE + # Synth only BSC_COMPILATION_FLAGS SYNTH_BSC_OPTIONS = -D XILINX_XCVU9P diff --git a/src_SSITH_P3/src_BSV/JtagTap.bsv b/src_SSITH_P3/src_BSV/JtagTap.bsv index 1efe670..e094651 100644 --- a/src_SSITH_P3/src_BSV/JtagTap.bsv +++ b/src_SSITH_P3/src_BSV/JtagTap.bsv @@ -13,7 +13,7 @@ import PowerOnReset ::*; import ClockHacks ::*; import Giraffe_IFC ::*; -typedef 6 ABITS; +typedef 7 ABITS; `ifdef XILINX_BSCAN `ifdef XILINX_XCVU095 typedef 6 IR_LENGTH;