From dcfb285c29e8d973f3a90636246c951ba13da03f Mon Sep 17 00:00:00 2001 From: rsnikhil Date: Mon, 13 Jan 2020 15:34:27 -0500 Subject: [PATCH] Work-in-progress. Now able to single-step from debugger. --- src_Core/CPU/Core.bsv | 100 ++++++++++++------ src_Core/CPU/Proc.bsv | 88 ++++++++++++++- .../RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv | 14 +-- .../RISCY_OOO/procs/RV64G_OOO/SynthParam.bsv | 5 +- 4 files changed, 161 insertions(+), 46 deletions(-) diff --git a/src_Core/CPU/Core.bsv b/src_Core/CPU/Core.bsv index 122c6e9..18352ff 100644 --- a/src_Core/CPU/Core.bsv +++ b/src_Core/CPU/Core.bsv @@ -155,8 +155,14 @@ interface Core; method Action debug_resume; - method Data csr_read (Bit #(12) csr_addr); + method Data csr_read (Bit #(12) csr_addr); method Action csr_write (Bit #(12) csr_addr, Data data); + method Data gpr_read (Bit #(5) gpr_addr); + method Action gpr_write (Bit #(5) gpr_addr, Data data); +`ifdef ISA_F + method Data fpr_read (Bit #(5) fpr_addr); + method Action fpr_write (Bit #(5) fpr_addr, Data data); +`endif `endif endinterface @@ -171,7 +177,6 @@ endinterface typedef enum { `ifdef INCLUDE_GDB_CONTROL - CORE_HALTING, CORE_HALTED, `endif CORE_RUNNING @@ -720,42 +725,27 @@ module mkCore#(CoreId coreId)(Core); `endif ); fetchStage.done_flushing(); - endrule `ifdef INCLUDE_GDB_CONTROL - rule rl_debug_halting((rg_core_run_state == CORE_HALTING) && - !flush_reservation && !flush_tlbs && !update_vm_info - && iTlb.flush_done && dTlb.flush_done - && !flush_caches && !flush_brpred - && iMem.flush_done && dMem.flush_done - && fetchStage.flush_predictors_done -`ifdef SELF_INV_CACHE - && !reconcile_i && iMem.reconcile_done -`ifdef SYSTEM_SELF_INV_L1D - && !reconcile_d + if (commitStage.is_debug_halted) begin + started <= False; + rg_core_run_state <= CORE_HALTED; + $display ("%0d: %m.rule readyToFetch: debug halt", cur_cycle); + end `endif -`endif - && commitStage.is_debug_halted - ); - - fetchStage.done_flushing(); - rg_core_run_state <= CORE_HALTED; - - $display ("%0d: %m.rl_debug_halting", cur_cycle); endrule -`endif /* -`ifdef INCLUDE_GDB_CONTROL - // TODO: DELETE AFTER DEBUGGING - rule rl_flushing_conditions (rg_core_run_state == CORE_HALTING); - $display ("%0d: %m.rl_done_flushing_for_debug_halt", cur_cycle); + rule rl_readyToFetch_conds_debug + $display ("%0d: %m.rl_readyToFetch_conds_debug:", cur_cycle); $display (" !flush_reservation = %0d, !flush_tlbs = %0d, !update_vm_info = %0d", !flush_reservation, !flush_tlbs, !update_vm_info); $display (" iTlb.flush_done = %0d, dTlb.flush_done = %0d", iTlb.flush_done, dTlb.flush_done); +`ifdef SECURITY_OR_INCLUDE_GDB_CONTROL $display (" !flush_caches = %0d !flush_brpred = %0d", !flush_caches, !flush_brpred); $display (" iMem.flush_done = %0d dMem.flush_done = %0d", iMem.flush_done, dMem.flush_done); $display (" fetchStage.flush_predictors_done = %0d", fetchStage.flush_predictors_done); +`endif `ifdef SELF_INV_CACHE $display (" !reconcile_i = %0d, iMem.reconcide_done = %0d", !reconcile_i, iMem.reconcile_done); `ifdef SYSTEM_SELF_INV_L1D @@ -763,7 +753,6 @@ module mkCore#(CoreId coreId)(Core); `endif `endif endrule -`endif */ `ifdef PERF_COUNT @@ -1107,9 +1096,7 @@ module mkCore#(CoreId coreId)(Core); `ifdef INCLUDE_GDB_CONTROL method Action debug_halt () if (started && (rg_core_run_state == CORE_RUNNING)); $display ("%0d: %m.debug_halt", cur_cycle); - started <= False; renameStage.debug_halt; // start the halt protocol - rg_core_run_state <= CORE_HALTING; endmethod method Bool is_debug_halted; @@ -1117,13 +1104,13 @@ module mkCore#(CoreId coreId)(Core); endmethod method Action debug_resume () if (rg_core_run_state == CORE_HALTED); - renameStage.debug_resume; - commitStage.debug_resume; - let startpc = csrf.dpc_read; fetchStage.redirect (startpc); - started <= True; + renameStage.debug_resume; + commitStage.debug_resume; + + started <= True; rg_core_run_state <= CORE_RUNNING; $display ("%0d: %m.debug_resume, dpc = 0x%0h", cur_cycle, startpc); endmethod @@ -1135,6 +1122,53 @@ module mkCore#(CoreId coreId)(Core); method Action csr_write (Bit #(12) csr_addr, Data data) if (rg_core_run_state == CORE_HALTED); csrf.csrInstWr (unpack (csr_addr), data); endmethod + + method Data gpr_read (Bit #(5) gpr_addr) if (rg_core_run_state == CORE_HALTED); + let arch_regs = ArchRegs {src1: tagged Valid (tagged Gpr gpr_addr), + src2: ?, + src3: ?, + dst: ?}; + let rename_result = regRenamingTable.rename[0].getRename (arch_regs); + let phy_rindx = fromMaybe (?, rename_result.phy_regs.src1); + let data = rf.read [debuggerPort].rd1 (phy_rindx); + return data; + endmethod + + method Action gpr_write (Bit #(5) gpr_addr, Data data) if (rg_core_run_state == CORE_HALTED); + let arch_regs = ArchRegs {src1: tagged Valid (tagged Gpr gpr_addr), + src2: ?, + src3: ?, + dst: ?}; + let rename_result = regRenamingTable.rename[0].getRename (arch_regs); + let phy_rindx = fromMaybe (?, rename_result.phy_regs.src1); + rf.write [debuggerPort].wr (phy_rindx, data); + $display ("%m.gpr_write (%0d, %0x), phy_rindx %0d", gpr_addr, data, phy_rindx); + endmethod + +`ifdef ISA_F + method Data fpr_read (Bit #(5) fpr_addr) if (rg_core_run_state == CORE_HALTED); + let arch_regs = ArchRegs {src1: tagged Valid (tagged Fpu fpr_addr), + src2: ?, + src3: ?, + dst: ?}; + let rename_result = regRenamingTable.rename[0].getRename (arch_regs); + let phy_rindx = fromMaybe (?, rename_result.phy_regs.src1); + let data = 0; // TODO: rf.read [debuggerPort].rd1 (phy_rindx); + return data; + endmethod + + method Action fpr_write (Bit #(5) fpr_addr, Data data) if (rg_core_run_state == CORE_HALTED); + let arch_regs = ArchRegs {src1: tagged Valid (tagged Fpu fpr_addr), + src2: ?, + src3: ?, + dst: ?}; + let rename_result = regRenamingTable.rename[0].getRename (arch_regs); + let phy_rindx = fromMaybe (?, rename_result.phy_regs.src1); + // TODO: rf.write [debuggerPort].wr (phy_rindx, data); + $display ("%m.fpr_write (%0d, %0x), phy_rindx %0d", fpr_addr, data, phy_rindx); + endmethod +`endif + `endif endmodule diff --git a/src_Core/CPU/Proc.bsv b/src_Core/CPU/Proc.bsv index 436733a..d28004e 100644 --- a/src_Core/CPU/Proc.bsv +++ b/src_Core/CPU/Proc.bsv @@ -349,12 +349,13 @@ module mkProc (Proc_IFC); f_run_halt_reqs.deq; // Debugger 'halt' request (e.g., GDB '^C' command) + // This is just like an interrupt. core[0].debug_halt; - - rg_state <= CPU_ENTERING_DEBUG_MODE; endrule - rule rl_debug_halted ((rg_state == CPU_ENTERING_DEBUG_MODE) && core [0].is_debug_halted); + // Monitors when we've reached halted state while running (halt, + // step or EBREAK) and notifies DM + rule rl_debug_halted (fn_is_running (rg_state) && core [0].is_debug_halted); // Notify debugger that we've halted f_run_halt_rsps.enq (False); // Stop executing rules until ready to restart from debugger @@ -373,7 +374,8 @@ module mkProc (Proc_IFC); // Notify debugger that we've 'halted' f_run_halt_rsps.enq (False); - $display ("%0d: %m.rl_debug_halt_redundant: CPU already halted; state = ", cur_cycle, fshow (rg_state)); + $display ("%0d: %m.rl_debug_halt_redundant: CPU already halted; state = ", + cur_cycle, fshow (rg_state)); endrule // ---------------- @@ -410,6 +412,84 @@ module mkProc (Proc_IFC); // if (cur_verbosity > 1) $display ("%m.rl_debug_csr_access_busy"); endrule + + // ---------------- + // Debug Module GPR read/write + + rule rl_debug_read_gpr ((rg_state == CPU_DEBUG_MODE) && (! f_gpr_reqs.first.write)); + let req <- pop (f_gpr_reqs); + Bit #(5) regname = req.address; + + let data = core [0].gpr_read (regname); + + let rsp = DM_CPU_Rsp {ok: True, data: data}; + f_gpr_rsps.enq (rsp); + if (cur_verbosity > 1) + $display ("%0d: %m.rl_debug_read_gpr: reg %0d => 0x%0h", + mcycle, regname, data); + endrule + + rule rl_debug_write_gpr ((rg_state == CPU_DEBUG_MODE) && f_gpr_reqs.first.write); + let req <- pop (f_gpr_reqs); + Bit #(5) regname = req.address; + let data = req.data; + core [0].gpr_write (regname, data); + + let rsp = DM_CPU_Rsp {ok: True, data: ?}; + f_gpr_rsps.enq (rsp); + + if (cur_verbosity > 1) + $display ("%0d: %m.rl_debug_write_gpr: reg %0d <= 0x%0h", + mcycle, regname, data); + endrule + + rule rl_debug_gpr_access_busy (rg_state != CPU_DEBUG_MODE); + let req <- pop (f_gpr_reqs); + let rsp = DM_CPU_Rsp {ok: False, data: ?}; + f_gpr_rsps.enq (rsp); + + if (cur_verbosity > 1) $display ("%0d: %m.rl_debug_gpr_access_busy", mcycle); + endrule + + // ---------------- + // Debug Module FPR read/write + +`ifdef ISA_F + rule rl_debug_read_fpr ((rg_state == CPU_DEBUG_MODE) && (! f_fpr_reqs.first.write)); + let req <- pop (f_fpr_reqs); + Bit #(5) regname = req.address; + let data = core [0].fpr_read (regname); + let rsp = DM_CPU_Rsp {ok: True, data: data}; + f_fpr_rsps.enq (rsp); + if (cur_verbosity > 1) + $display ("%0d: %m.rl_debug_read_fpr: reg %0d => 0x%0h", + mcycle, regname, data); + endrule + + rule rl_debug_write_fpr ((rg_state == CPU_DEBUG_MODE) && f_fpr_reqs.first.write); + let req <- pop (f_fpr_reqs); + Bit #(5) regname = req.address; + let data = req.data; + core [0].fpr_write (regname, data); + + let rsp = DM_CPU_Rsp {ok: True, data: ?}; + f_fpr_rsps.enq (rsp); + + if (cur_verbosity > 1) + $display ("%0d: %m.rl_debug_write_fpr: reg %0d <= 0x%0h", + mcycle, regname, data); + endrule + + rule rl_debug_fpr_access_busy (rg_state != CPU_DEBUG_MODE); + let req <- pop (f_fpr_reqs); + let rsp = DM_CPU_Rsp {ok: False, data: ?}; + f_fpr_rsps.enq (rsp); + + if (cur_verbosity > 1) + $display ("%0d: %m.rl_debug_fpr_access_busy", mcycle); + endrule +`endif + `endif // ================================================================ diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv index 052cf65..c8e91f5 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv @@ -171,7 +171,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); action if (csrf.dcsr_step_bit == 1'b1) begin rg_m_halt_req <= tagged Valid DebugStep; - $display ("%0d: %m.fa_step_check: rg_m_halt_req <= tagged Valid DebugStep", cur_cycle); + $display ("%0d: %m.renameStage.fa_step_check: rg_m_halt_req <= tagged Valid DebugStep", cur_cycle); end endaction endfunction @@ -260,8 +260,8 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); `ifdef INCLUDE_GDB_CONTROL if (rg_m_halt_req matches tagged Valid .cause) begin - // Stop due to debugger halt or step - trap = tagged Valid (tagged Interrupt cause); + // Stop due to debugger halt or step + trap = tagged Valid (tagged Interrupt cause); end else `endif @@ -308,9 +308,9 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); fa_step_check; if (firstTrap == tagged Valid (tagged Interrupt DebugHalt)) - $display ("%0d: %m.doRenaming_Trap: DebugHalt", cur_cycle); + $display ("%0d: %m.renameStage.doRenaming_Trap: DebugHalt", cur_cycle); else if (firstTrap == tagged Valid (tagged Interrupt DebugStep)) - $display ("%0d: %m.doRenaming_Trap: DebugStep", cur_cycle); + $display ("%0d: %m.renameStage.doRenaming_Trap: DebugStep", cur_cycle); `endif let x = fetchStage.pipelines[0].first; let pc = x.pc; @@ -1092,12 +1092,12 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); `ifdef INCLUDE_GDB_CONTROL method Action debug_halt () if (rg_m_halt_req == tagged Invalid); rg_m_halt_req <= tagged Valid DebugHalt; - $display ("%0d: %m.renameStage.debug_halt", cur_cycle); + $display ("%0d: %m.renameStage.renameStage.debug_halt", cur_cycle); endmethod method Action debug_resume () if (rg_m_halt_req != tagged Invalid); rg_m_halt_req <= tagged Invalid; - $display ("%0d: %m.renameStage.debug_resume", cur_cycle); + $display ("%0d: %m.renameStage.renameStage.debug_resume", cur_cycle); endmethod `endif diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/SynthParam.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/SynthParam.bsv index aaeb447..3c6b3cb 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/SynthParam.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/SynthParam.bsv @@ -35,8 +35,8 @@ typedef TDiv#(SupSize, 2) FpuMulDivExeNum; // Phy RFile // write: Alu < FpuMulDiv < Mem // read: Alu, FpuMulDiv, Mem -typedef TAdd#(1, TAdd#(FpuMulDivExeNum, AluExeNum)) RFileWrPortNum; -typedef TAdd#(1, TAdd#(FpuMulDivExeNum, AluExeNum)) RFileRdPortNum; +typedef TAdd#(2, TAdd#(FpuMulDivExeNum, AluExeNum)) RFileWrPortNum; +typedef TAdd#(2, TAdd#(FpuMulDivExeNum, AluExeNum)) RFileRdPortNum; // sb lazy lookup num: same as RFile read, becaues all pipelines recv bypass typedef RFileRdPortNum SbLazyLookupPortNum; @@ -65,6 +65,7 @@ Integer memWrAggrPort = 1 + valueof(FpuMulDivExeNum) + valueof(AluExeNum); function Integer aluRdPort(Integer i) = i; function Integer fpuMulDivRdPort(Integer i) = valueof(AluExeNum) + i; Integer memRdPort = valueof(FpuMulDivExeNum) + valueof(AluExeNum); +Integer debuggerPort = memRdPort + 1; // ports for correct spec, ordering doesn't matter typedef TAdd#(2, AluExeNum) CorrectSpecPortNum;