diff --git a/src_Core/CPU/Core.bsv b/src_Core/CPU/Core.bsv index f1f6106..e9c5fec 100644 --- a/src_Core/CPU/Core.bsv +++ b/src_Core/CPU/Core.bsv @@ -159,20 +159,11 @@ interface Core; method Action setDEIP (Bit #(1) v); `ifdef INCLUDE_GDB_CONTROL - method Action debug_halt; - - (* always_ready *) - method Bool is_debug_halted; - - method Action debug_resume; - - interface Server #(DM_CPU_Req #(5, 64), DM_CPU_Rsp #(64)) hart0_gpr_mem_server; + interface Server #(Bool, Bool) hart0_run_halt_server; + interface Server #(DM_CPU_Req #(5, 64), DM_CPU_Rsp #(64)) hart0_gpr_mem_server; `ifdef ISA_F - // FPR access - interface Server #(DM_CPU_Req #(5, 64), DM_CPU_Rsp #(64)) hart0_fpr_mem_server; + interface Server #(DM_CPU_Req #(5, 64), DM_CPU_Rsp #(64)) hart0_fpr_mem_server; `endif - - // CSR access interface Server #(DM_CPU_Req #(12, 64), DM_CPU_Rsp #(64)) hart0_csr_mem_server; `endif endinterface @@ -188,6 +179,7 @@ endinterface typedef enum { `ifdef INCLUDE_GDB_CONTROL + CORE_HALTING, CORE_HALTED, `endif CORE_RUNNING @@ -744,8 +736,8 @@ module mkCore#(CoreId coreId)(Core); `ifdef INCLUDE_GDB_CONTROL if (commitStage.is_debug_halted) begin started <= False; - rg_core_run_state <= CORE_HALTED; - $display ("%0d: %m.rule readyToFetch: debug halt", cur_cycle); + rg_core_run_state <= CORE_HALTING; + $display ("%0d: %m.rule readyToFetch: halting for debug mode", cur_cycle); end `endif endrule @@ -1031,7 +1023,9 @@ module mkCore#(CoreId coreId)(Core); // ================================================================ // DEBUG MODULE INTERFACE - // ---------------- + Bool show_DM_interactions = True; // for debugging the interactions + + // ---------------------------------------------------------------- // Debug Module GPR read/write FIFOF #(DM_CPU_Req #(5, 64)) f_gpr_reqs <- mkFIFOF1; @@ -1053,7 +1047,8 @@ module mkCore#(CoreId coreId)(Core); let rsp = DM_CPU_Rsp {ok: True, data: data_out}; f_gpr_rsps.enq (rsp); - // if (cur_verbosity > 1) + + if (show_DM_interactions) $display ("%0d: %m.rl_debug_read_gpr: reg %0d => 0x%0h", cur_cycle, regnum, data_out); endrule @@ -1071,26 +1066,26 @@ module mkCore#(CoreId coreId)(Core); 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_in); - $display ("%m.gpr_write (%0d, %0x), phy_rindx %0d", regnum, data_in, phy_rindx); 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", cur_cycle, regnum, data_in); + if (show_DM_interactions) + $display ("%0d: %m.rl_debug_gpr_write: reg %0d <= 0x%0h (phy_rindx = %0d)", + cur_cycle, regnum, data_in, phy_rindx); endrule - rule rl_debug_gpr_access_busy (rg_core_run_state != CORE_HALTED); + rule rl_debug_gpr_access_busy (rg_core_run_state == CORE_RUNNING); let req <- pop (f_gpr_reqs); let rsp = DM_CPU_Rsp {ok: False, data: ?}; f_gpr_rsps.enq (rsp); - // if (cur_verbosity > 1) + if (show_DM_interactions) $display ("%0d: %m.rl_debug_gpr_access_busy", cur_cycle); endrule `ifdef ISA_F - // ---------------- + // ---------------------------------------------------------------- // Debug Module FPR read/write FIFOF #(DM_CPU_Req #(5, 64)) f_fpr_reqs <- mkFIFOF1; @@ -1112,7 +1107,8 @@ module mkCore#(CoreId coreId)(Core); let rsp = DM_CPU_Rsp {ok: True, data: data_out}; f_fpr_rsps.enq (rsp); - // if (cur_verbosity > 1) + + if (show_DM_interactions) $display ("%0d: %m.rl_debug_read_fpr: reg %0d => 0x%0h", cur_cycle, regnum, data_out); endrule @@ -1130,26 +1126,28 @@ module mkCore#(CoreId coreId)(Core); 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_in); - $display ("%m.gpr_write (%0d, %0x), phy_rindx %0d", regnum, data_in, phy_rindx); 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", cur_cycle, regnum, data_in); + if (show_DM_interactions) + $display ("%0d: %m.rl_debug_write_fpr: reg %0d <= 0x%0h (phy_rindx %0d)", + cur_cycle, regnum, data_in, phy_rindx); endrule - rule rl_debug_fpr_access_busy (rg_core_run_state != CORE_HALTED); + rule rl_debug_fpr_access_busy ( (rg_core_run_state == CORE_RUNNING) + && f_fpr_reqs.notEmpty); + let req <- pop (f_fpr_reqs); let rsp = DM_CPU_Rsp {ok: False, data: ?}; f_fpr_rsps.enq (rsp); - // if (cur_verbosity > 1) + if (show_DM_interactions) $display ("%0d: %m.rl_debug_fpr_access_busy", cur_cycle); endrule `endif - // ---------------- + // ---------------------------------------------------------------- // Debug Module CSR read/write // Debugger CSR read/write request/response @@ -1164,7 +1162,8 @@ module mkCore#(CoreId coreId)(Core); let rsp = DM_CPU_Rsp {ok: True, data: data_out}; f_csr_rsps.enq (rsp); - // if (cur_verbosity > 1) + + if (show_DM_interactions) $display ("%0d: %m.rl_debug_read_csr: csr %0d => 0x%0h", cur_cycle, csr_addr, data_out); endrule @@ -1178,19 +1177,107 @@ module mkCore#(CoreId coreId)(Core); let rsp = DM_CPU_Rsp {ok: True, data: ?}; f_csr_rsps.enq (rsp); - // if (cur_verbosity > 1) + if (show_DM_interactions) $display ("%0d: %m.rl_debug_write_csr: csr 0x%0h <= 0x%0h", cur_cycle, csr_addr, data_in); endrule - rule rl_debug_csr_access_busy (rg_core_run_state != CORE_HALTED); + rule rl_debug_csr_access_busy (rg_core_run_state == CORE_RUNNING); let req <- pop (f_csr_reqs); let rsp = DM_CPU_Rsp {ok: False, data: ?}; f_csr_rsps.enq (rsp); - // if (cur_verbosity > 1) + if (show_DM_interactions) $display ("%0d: %m.rl_debug_csr_access_busy", cur_cycle); endrule + // ---------------------------------------------------------------- + // Debug Module run-halt control + + FIFOF #(Bool) f_run_halt_reqs <- mkFIFOF; + FIFOF #(Bool) f_run_halt_rsps <- mkFIFOF; + Reg #(Bool) rg_sent_halt_rsp <- mkReg (False); + + // ---------------- + // Debug Module Halt control + + rule rl_debug_halt_req ( (rg_core_run_state == CORE_RUNNING) + && (f_run_halt_reqs.first == False)); + f_run_halt_reqs.deq; + + // Debugger 'halt' request (e.g., GDB '^C' command) + // This is initiated just like an interrupt. + renameStage.debug_halt_req; + rg_sent_halt_rsp <= False; + + if (show_DM_interactions) + $display ("%0d: %m.rl_debug_halt_req", cur_cycle); + endrule + + rule rl_debug_halt_req_already_halted ( (rg_core_run_state != CORE_RUNNING) + && (f_run_halt_reqs.first == False)); + f_run_halt_reqs.deq; + + // Notify debugger that we've 'halted' + f_run_halt_rsps.enq (False); + + if (show_DM_interactions) + $display ("%0d: %m.rl_debug_halt_req_already_halted", cur_cycle); + endrule + + // Monitors when we've reached halted state while running + // (due to halt, step or EBREAK) and notifies DM + rule rl_debug_halted (rg_core_run_state == CORE_HALTING); + // Notify debugger that we've halted + f_run_halt_rsps.enq (False); + rg_core_run_state <= CORE_HALTED; + + if (show_DM_interactions) + $display ("%0d: %m.rl_debug_halted", cur_cycle); + endrule + + // ---------------- + // Debug Module Resume (run) control + + // Resume command when in debug mode + rule rl_debug_resume ( (rg_core_run_state == CORE_HALTED) + && (f_run_halt_reqs.first == True) + + // prioritise gpr/fpr/csr read/write requests before resuming + && (! f_gpr_reqs.notEmpty) +`ifdef ISA_F + && (! f_fpr_reqs.notEmpty) +`endif + && (! f_csr_reqs.notEmpty)); + + f_run_halt_reqs.deq; + + let startpc = csrf.dpc_read; + fetchStage.redirect (startpc); + renameStage.debug_resume; + commitStage.debug_resume; + + started <= True; + rg_core_run_state <= CORE_RUNNING; + + // Notify debugger that we've started running + f_run_halt_rsps.enq (True); + + if (show_DM_interactions) + $display ("%0d: %m.debug_resume, dpc = 0x%0h", cur_cycle, startpc); + endrule + + // Run command when already running + rule rl_debug_run_redundant ( (rg_core_run_state == CORE_RUNNING) + && (f_run_halt_reqs.first == True)); + f_run_halt_reqs.deq; + + // Notify debugger that we're running + f_run_halt_rsps.enq (True); + + if (show_DM_interactions) + $display ("%0d: %m.rl_debug_run_redundant", cur_cycle); + endrule + // ================================================================ `endif @@ -1276,35 +1363,12 @@ module mkCore#(CoreId coreId)(Core); method Action setDEIP (v) = csrf.setDEIP (v); `ifdef INCLUDE_GDB_CONTROL - method Action debug_halt () if (started && (rg_core_run_state == CORE_RUNNING)); - $display ("%0d: %m.debug_halt", cur_cycle); - renameStage.debug_halt; // start the halt protocol - endmethod - - method Bool is_debug_halted; - return (rg_core_run_state == CORE_HALTED); - endmethod - - method Action debug_resume () if (rg_core_run_state == CORE_HALTED); - let startpc = csrf.dpc_read; - fetchStage.redirect (startpc); - - 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 - - interface Server hart0_gpr_mem_server = toGPServer (f_gpr_reqs, f_gpr_rsps); - + interface Server hart0_run_halt_server = toGPServer (f_run_halt_reqs, f_run_halt_rsps); + interface Server hart0_gpr_mem_server = toGPServer (f_gpr_reqs, f_gpr_rsps); `ifdef ISA_F - interface Server hart0_fpr_mem_server = toGPServer (f_fpr_reqs, f_fpr_rsps); + interface Server hart0_fpr_mem_server = toGPServer (f_fpr_reqs, f_fpr_rsps); `endif - - // CSR access - interface Server hart0_csr_mem_server = toGPServer (f_csr_reqs, f_csr_rsps); + interface Server hart0_csr_mem_server = toGPServer (f_csr_reqs, f_csr_rsps); `endif endmodule diff --git a/src_Core/CPU/Proc.bsv b/src_Core/CPU/Proc.bsv index 24c209b..3d0ee9f 100644 --- a/src_Core/CPU/Proc.bsv +++ b/src_Core/CPU/Proc.bsv @@ -85,23 +85,6 @@ import TV_Info :: *; import DM_CPU_Req_Rsp :: *; `endif -// ================================================================ -// CPU run-states -// TODO: Reset from GDB etc. - -typedef enum {CPU_RUNNING // Normal operation -`ifdef INCLUDE_GDB_CONTROL - , - CPU_ENTERING_DEBUG_MODE, // On GDB breakpoint, while waiting for fence completion - CPU_DEBUG_MODE // Halted for debugger -`endif - } CPU_State -deriving (Eq, Bits, FShow); - -function Bool fn_is_running (CPU_State cpu_state); - return (cpu_state == CPU_RUNNING); -endfunction - // ================================================================ (* synthesize *) @@ -120,27 +103,12 @@ module mkProc (Proc_IFC); // Verbosity: 0=quiet; 1=instruction trace; 2=more detail Reg #(Bit #(4)) cfg_verbosity <- mkConfigReg (0); - // ---------------- - // CPU run/debug states - - Reg #(CPU_State) rg_state <- mkReg (CPU_RUNNING); - // ---------------- // Reset requests and responses (TODO: to be implemented) FIFOF #(Bit #(0)) f_reset_reqs <- mkFIFOF; FIFOF #(Bit #(0)) f_reset_rsps <- mkFIFOF; -`ifdef INCLUDE_GDB_CONTROL - // ---------------- - // Communication to/from External debug module (TODO: to be implemented) - - // Debugger run-control - FIFOF #(Bool) f_run_halt_reqs <- mkFIFOF; - FIFOF #(Bool) f_run_halt_rsps <- mkFIFOF; - -`endif - // ---------------- // Tandem Verification (TODO: to be implemented) @@ -182,7 +150,7 @@ module mkProc (Proc_IFC); end // Note: mkLLCDmaConnect is Toooba version, different from riscy-ooo version - let llc__mem_server <- mkLLCDmaConnect(llc.dma, tlbToMem); + let llc_mem_server <- mkLLCDmaConnect(llc.dma, tlbToMem); // ================================================================ // interface Back-side of LLC to AXI4 @@ -278,85 +246,6 @@ module mkProc (Proc_IFC); end endrule - // ================================================================ - // ================================================================ - // ================================================================ - // DEBUGGER ACCESS - -`ifdef INCLUDE_GDB_CONTROL - - // ---------------- - // Debug Module Run (resume) control - - // Run command when in debug mode - rule rl_debug_run ((f_run_halt_reqs.first == True) - // && (! f_csr_reqs.notEmpty) - && (rg_state == CPU_DEBUG_MODE)); - // if (cfg_verbosity > 1) - $display ("%0d: %m.rl_debug_run", cur_cycle); - - f_run_halt_reqs.deq; - core[0].debug_resume; - rg_state <= CPU_RUNNING; - - // Notify debugger that we've started running - f_run_halt_rsps.enq (True); - endrule - - // Run command when already running - rule rl_debug_run_redundant ((f_run_halt_reqs.first == True) - // && (! f_csr_reqs.notEmpty) - && fn_is_running (rg_state)); - // if (cfg_verbosity > 1) - $display ("%0d: %m.rl_debug_run_redundant", cur_cycle); - - f_run_halt_reqs.deq; - - // Notify debugger that we're running - f_run_halt_rsps.enq (True); - endrule - - // ---------------- - // Debug Module Halt control - - rule rl_debug_halt ((f_run_halt_reqs.first == False) && fn_is_running (rg_state)); - // if (cfg_verbosity > 1) - $display ("%0d: %m.rl_debug_halt", cur_cycle); - - f_run_halt_reqs.deq; - - // Debugger 'halt' request (e.g., GDB '^C' command) - // This is just like an interrupt. - core[0].debug_halt; - endrule - - // 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 - rg_state <= CPU_DEBUG_MODE; - - // if (cfg_verbosity > 1) - $display ("%0d: %m.rl_debug_halted", cur_cycle); - endrule - - rule rl_debug_halt_redundant ((f_run_halt_reqs.first == False) && (! fn_is_running (rg_state))); - // if (cfg_verbosity > 1) - $display ("%0d: %m.rl_debug_halt_redundant", cur_cycle); - - f_run_halt_reqs.deq; - - // 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)); - endrule - -`endif - // ================================================================ // ================================================================ // ================================================================ @@ -430,27 +319,23 @@ module mkProc (Proc_IFC); // Optional interface to Debug Module `ifdef INCLUDE_GDB_CONTROL - // run-control, other - interface Server hart0_server_run_halt = toGPServer (f_run_halt_reqs, f_run_halt_rsps); + // run/halt, gpr, mem and csr control goes to core + interface Server hart0_run_halt_server = core [0].hart0_run_halt_server; + interface Server hart0_gpr_mem_server = core[0].hart0_gpr_mem_server; +`ifdef ISA_F + interface Server hart0_fpr_mem_server = core[0].hart0_fpr_mem_server; +`endif + interface Server hart0_csr_mem_server = core[0].hart0_csr_mem_server; + // mem access goes to LLC (stays coherent with CPU pipeline). + interface debug_module_mem_server = llc_mem_server; + + // We don't implement 'other' functionality interface Put hart0_put_other_req; method Action put (Bit #(4) req); cfg_verbosity <= req; endmethod endinterface - - // GPR access - interface Server hart0_gpr_mem_server = core[0].hart0_gpr_mem_server; - -`ifdef ISA_F - // FPR access - interface Server hart0_fpr_mem_server = core[0].hart0_fpr_mem_server; -`endif - - // CSR access - interface Server hart0_csr_mem_server = core[0].hart0_csr_mem_server; - - interface debug_module_mem_server = llc__mem_server; `endif endmodule: mkProc diff --git a/src_Core/CPU/Proc_IFC.bsv b/src_Core/CPU/Proc_IFC.bsv index 13e93a5..202394e 100644 --- a/src_Core/CPU/Proc_IFC.bsv +++ b/src_Core/CPU/Proc_IFC.bsv @@ -85,22 +85,16 @@ interface Proc_IFC; // Optional interface to Debug Module `ifdef INCLUDE_GDB_CONTROL - // run-control, other - interface Server #(Bool, Bool) hart0_server_run_halt; - interface Put #(Bit #(4)) hart0_put_other_req; - - // GPR access + interface Server #(Bool, Bool) hart0_run_halt_server; interface Server #(DM_CPU_Req #(5, XLEN), DM_CPU_Rsp #(XLEN)) hart0_gpr_mem_server; - `ifdef ISA_F - // FPR access interface Server #(DM_CPU_Req #(5, FLEN), DM_CPU_Rsp #(FLEN)) hart0_fpr_mem_server; `endif - - // CSR access interface Server #(DM_CPU_Req #(12, XLEN), DM_CPU_Rsp #(XLEN)) hart0_csr_mem_server; + interface AXI4_Slave_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) debug_module_mem_server; - interface AXI4_Slave_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) debug_module_mem_server; + // Non-standard + interface Put #(Bit #(4)) hart0_put_other_req; `endif endinterface diff --git a/src_Core/Core/CoreW.bsv b/src_Core/Core/CoreW.bsv index 9cb5a71..4bb29f2 100644 --- a/src_Core/Core/CoreW.bsv +++ b/src_Core/Core/CoreW.bsv @@ -206,7 +206,7 @@ module mkCoreW (CoreW_IFC #(N_External_Interrupt_Sources)); `ifdef INCLUDE_GDB_CONTROL `ifndef EXTERNAL_DEBUG_MODULE // DM to CPU connections for run-control and other misc requests - mkConnection (debug_module.hart0_client_run_halt, proc.hart0_server_run_halt); + mkConnection (debug_module.hart0_client_run_halt, proc.hart0_run_halt_server); mkConnection (debug_module.hart0_get_other_req, proc.hart0_put_other_req); `endif `endif @@ -230,8 +230,8 @@ module mkCoreW (CoreW_IFC #(N_External_Interrupt_Sources)); rg_fromhost_addr); endrule - rule rl_hart0_server_run_halt; - let tmp <- proc.hart0_server_run_halt.response.get; + rule rl_hart0_run_halt_server; + let tmp <- proc.hart0_run_halt_server.response.get; endrule Reg#(Bool) hart0_halt <- mkReg(False); @@ -409,10 +409,6 @@ module mkCoreW (CoreW_IFC #(N_External_Interrupt_Sources)); // Slaves on the local 2x3 fabric // default slave is taken out directly to the Core interface mkConnection (fabric_2x3.v_to_slaves [plic_slave_num], plic.axi4_slave); - - // TODO: This slave can be connected to mkLLCDmaConnect for Debug Module System Bus Access - // AXI4_Slave_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) dummy_slave = dummy_AXI4_Slave_ifc; - // mkConnection (fabric_2x3.v_to_slaves [near_mem_io_slave_num], dummy_slave); mkConnection (fabric_2x3.v_to_slaves [near_mem_io_slave_num], proc.debug_module_mem_server); // ================================================================ diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv index dbf78e73..dbc89ce 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv @@ -90,7 +90,7 @@ interface RenameStage; interface Get#(RenameStuck) renameCorrectPathStuck; `ifdef INCLUDE_GDB_CONTROL - method Action debug_halt; + method Action debug_halt_req; method Action debug_resume; `endif endinterface @@ -1105,9 +1105,9 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); endmethod `ifdef INCLUDE_GDB_CONTROL - method Action debug_halt () if (rg_m_halt_req == tagged Invalid); + method Action debug_halt_req () if (rg_m_halt_req == tagged Invalid); rg_m_halt_req <= tagged Valid DebugHalt; - $display ("%0d: %m.renameStage.renameStage.debug_halt", cur_cycle); + $display ("%0d: %m.renameStage.renameStage.debug_halt_req", cur_cycle); endmethod method Action debug_resume () if (rg_m_halt_req != tagged Invalid);