diff --git a/src_Core/CPU/Core.bsv b/src_Core/CPU/Core.bsv index 190cce4..83bc436 100644 --- a/src_Core/CPU/Core.bsv +++ b/src_Core/CPU/Core.bsv @@ -188,12 +188,12 @@ interface Core; interface Toooba_RVFI_DII_Server rvfi_dii_server; `endif `ifdef INCLUDE_GDB_CONTROL - interface Server #(Bool, Bool) hart0_run_halt_server; - interface Server #(DM_CPU_Req #(5, 64), DM_CPU_Rsp #(64)) hart0_gpr_mem_server; + interface Server #(Bool, Bool) hart_run_halt_server; + interface Server #(DM_CPU_Req #(5, 64), DM_CPU_Rsp #(64)) hart_gpr_mem_server; `ifdef ISA_F - 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)) hart_fpr_mem_server; `endif - interface Server #(DM_CPU_Req #(12, 64), DM_CPU_Rsp #(64)) hart0_csr_mem_server; + interface Server #(DM_CPU_Req #(12, 64), DM_CPU_Rsp #(64)) hart_csr_mem_server; `endif `ifdef INCLUDE_TANDEM_VERIF @@ -1498,12 +1498,12 @@ module mkCore#(CoreId coreId)(Core); method Action setSEIP (v) = csrf.setSEIP (v); `ifdef INCLUDE_GDB_CONTROL - 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); + interface Server hart_run_halt_server = toGPServer (f_run_halt_reqs, f_run_halt_rsps); + interface Server hart_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 hart_fpr_mem_server = toGPServer (f_fpr_reqs, f_fpr_rsps); `endif - interface Server hart0_csr_mem_server = toGPServer (f_csr_reqs, f_csr_rsps); + interface Server hart_csr_mem_server = toGPServer (f_csr_reqs, f_csr_rsps); `endif `ifdef INCLUDE_TANDEM_VERIF diff --git a/src_Core/CPU/Proc.bsv b/src_Core/CPU/Proc.bsv index 76789f7..b391a79 100644 --- a/src_Core/CPU/Proc.bsv +++ b/src_Core/CPU/Proc.bsv @@ -116,12 +116,6 @@ module mkProc (Proc_IFC); core[i] <- mkCore(fromInteger(i)); end - // ---------------- - // Verbosity control for debugging - - // Verbosity: 0=quiet; 1=instruction trace; 2=more detail - Reg #(Bit #(4)) cfg_verbosity <- mkConfigReg (0); - // ---------------- // MMIO @@ -259,6 +253,16 @@ module mkProc (Proc_IFC); end endrule + let emptyPut = interface Put + method put (x) = noAction; + endinterface; + function proj_run_halt_server (x) = x.hart_run_halt_server; + function proj_gpr_mem_server (x) = x.hart_gpr_mem_server; +`ifdef ISA_F + function proj_fpr_mem_server (x) = x.hart_fpr_mem_server; +`endif + function proj_csr_mem_server (x) = x.hart_csr_mem_server; + // ================================================================ // ================================================================ // ================================================================ @@ -309,7 +313,7 @@ module mkProc (Proc_IFC); // For tracing method Action set_verbosity (Bit #(4) verbosity); - cfg_verbosity <= verbosity; + noAction; endmethod // ---------------- @@ -325,20 +329,19 @@ module mkProc (Proc_IFC); // Optional interface to Debug Module `ifdef INCLUDE_GDB_CONTROL - // run/halt, gpr, mem and csr control goes to core - interface Server hart0_run_halt_server = core [0].hart0_run_halt_server; - interface Put hart0_put_other_req; - method Action put (Bit #(4) req); - cfg_verbosity <= req; - endmethod - endinterface + // run/halt, gpr, mem and csr control goes to cores + interface harts_run_halt_server = map (proj_run_halt_server, core); - interface Server hart0_gpr_mem_server = core[0].hart0_gpr_mem_server; + // currently "other req" not core specific - only affected cfg_verbosity which + // is not read anywhere! + interface harts_put_other_req = replicate(emptyPut); + + interface harts_gpr_mem_server = map(proj_gpr_mem_server, core); `ifdef ISA_F - interface Server hart0_fpr_mem_server = core[0].hart0_fpr_mem_server; + interface harts_fpr_mem_server = map(proj_fpr_mem_server, core); `endif - interface Server hart0_csr_mem_server = core[0].hart0_csr_mem_server; + interface harts_csr_mem_server = map(proj_csr_mem_server, core); `endif diff --git a/src_Core/CPU/Proc_IFC.bsv b/src_Core/CPU/Proc_IFC.bsv index a8468bb..1af5afb 100644 --- a/src_Core/CPU/Proc_IFC.bsv +++ b/src_Core/CPU/Proc_IFC.bsv @@ -33,19 +33,16 @@ import AXI4 :: *; import Fabric_Defs :: *; import SoC_Map :: *; import CCTypes :: *; +import ProcTypes :: *; `ifdef INCLUDE_GDB_CONTROL import DM_CPU_Req_Rsp :: *; `endif `ifdef INCLUDE_TANDEM_VERIF -import ProcTypes :: *; import Trace_Data2 :: *; `endif -`ifdef RVFI_DII -import ProcTypes :: *; -`endif // ================================================================ // CPU interface @@ -109,15 +106,15 @@ interface Proc_IFC; // Optional interface to Debug Module `ifdef INCLUDE_GDB_CONTROL - interface Server #(Bool, Bool) hart0_run_halt_server; - interface Server #(DM_CPU_Req #(5, XLEN), DM_CPU_Rsp #(XLEN)) hart0_gpr_mem_server; + interface Vector #(CoreNum, Server #(Bool, Bool)) harts_run_halt_server; + interface Vector #(CoreNum, Server #(DM_CPU_Req #(5, XLEN), DM_CPU_Rsp #(XLEN))) harts_gpr_mem_server; `ifdef ISA_F - interface Server #(DM_CPU_Req #(5, FLEN), DM_CPU_Rsp #(FLEN)) hart0_fpr_mem_server; + interface Vector #(CoreNum, Server #(DM_CPU_Req #(5, FLEN), DM_CPU_Rsp #(FLEN))) harts_fpr_mem_server; `endif - interface Server #(DM_CPU_Req #(12, XLEN), DM_CPU_Rsp #(XLEN)) hart0_csr_mem_server; + interface Vector #(CoreNum, Server #(DM_CPU_Req #(12, XLEN), DM_CPU_Rsp #(XLEN))) harts_csr_mem_server; // Non-standard - interface Put #(Bit #(4)) hart0_put_other_req; + interface Vector #(CoreNum, Put #(Bit #(4))) harts_put_other_req; `endif `ifdef INCLUDE_TANDEM_VERIF diff --git a/src_Core/Core/CoreW.bsv b/src_Core/Core/CoreW.bsv index 5586dd6..bd622dd 100644 --- a/src_Core/Core/CoreW.bsv +++ b/src_Core/Core/CoreW.bsv @@ -147,11 +147,13 @@ module mkCoreW #(Reset dm_power_on_reset) let clk <- exposeCurrentClock; Bool initial_reset_val = False; Integer hart_reset_duration = 10; // NOTE: assuming 10 cycle reset enough for hart - let dm_hart0_reset_controller <- mkReset(hart_reset_duration, initial_reset_val, clk); + Vector #(CoreNum, MakeResetIfc) dm_harts_reset_controller <- replicateM(mkReset(hart_reset_duration, initial_reset_val, clk)); - let hart0_reset <- mkResetEither (ndm_reset, dm_hart0_reset_controller.new_rst); + function Reset proj_new_rst (MakeResetIfc x) = x.new_rst; + + let all_harts_reset <- foldlM (mkResetEither, ndm_reset, map (proj_new_rst, dm_harts_reset_controller)); `else - let hart0_reset = ndm_reset; + let all_harts_reset = ndm_reset; `endif // ================================================================ @@ -162,17 +164,17 @@ module mkCoreW #(Reset dm_power_on_reset) // RISCY-OOO processor // TODO (when we do multicore): need resets for each core. - Proc_IFC proc <- mkProc (reset_by hart0_reset); + Proc_IFC proc <- mkProc (reset_by all_harts_reset); // handle uncached interface let proc_uncached = extendIDFields (zeroMasterUserFields (proc.master1), 0); // Bridge for uncached expernal bus transactions. - let uncached_mem_shim <- mkAXI4ShimFF(reset_by hart0_reset); + let uncached_mem_shim <- mkAXI4ShimFF(reset_by all_harts_reset); // handle cached interface // AXI4 tagController - TagControllerAXI#(Wd_MId, Wd_Addr, Wd_Data) tagController <- mkTagControllerAXI(reset_by hart0_reset); // TODO double check if reseting like this is good enough - mkConnection(proc.master0, tagController.slave, reset_by hart0_reset); + TagControllerAXI#(Wd_MId, Wd_Addr, Wd_Data) tagController <- mkTagControllerAXI(reset_by all_harts_reset); // TODO double check if reseting like this is good enough + mkConnection(proc.master0, tagController.slave, reset_by all_harts_reset); `ifdef PERFORMANCE_MONITORING rule report_tagController_events; Vector#(7, Bit#(1)) evts = tagController.events; @@ -209,29 +211,32 @@ module mkCoreW #(Reset dm_power_on_reset) // Hart-reset from DM `ifdef INCLUDE_GDB_CONTROL - Reg #(Bit #(8)) rg_hart0_reset_delay <- mkReg (0); + Reg #(Bit #(8)) rg_harts_reset_delay <- mkReg (0); Reg #(Bit #(64)) rg_tohost_addr <- mkReg (0); Reg #(Bit #(64)) rg_fromhost_addr <- mkReg (0); - rule rl_dm_hart0_reset (rg_hart0_reset_delay == 0); - let x <- debug_module.hart0_reset_client.request.get; - dm_hart0_reset_controller.assertReset; - rg_hart0_reset_delay <= fromInteger (hart_reset_duration + 200); // NOTE: heuristic + for (Integer core = 0; core < valueOf(CoreNum); core = core + 1) + rule rl_dm_harts_reset (rg_harts_reset_delay == 0); + let x <- debug_module.harts_reset_client[core].request.get; + dm_harts_reset_controller[core].assertReset; + rg_harts_reset_delay <= fromInteger (hart_reset_duration + 200); // NOTE: heuristic - $display ("%0d: %m.rl_dm_hart0_reset: asserting hart0 reset for %0d cycles", + $display ("%0d: %m.rl_dm_harts_reset: asserting harts reset for %0d cycles", cur_cycle, hart_reset_duration); endrule - rule rl_dm_hart0_reset_wait (rg_hart0_reset_delay != 0); - if (rg_hart0_reset_delay == 1) begin + rule rl_dm_harts_reset_wait (rg_harts_reset_delay != 0); + if (rg_harts_reset_delay == 1) begin let pc = soc_map_struct.pc_reset_value; Bool is_running = True; proc.start (is_running, pc, rg_tohost_addr, rg_fromhost_addr); - debug_module.hart0_reset_client.response.put (is_running); - $display ("%0d: %m.rl_dm_hart0_reset_wait: proc.start (pc %0h, tohostAddr %0h, fromhostAddr %0h", + // We reset all the harts, so we indicate this to the DM, even though it's possible only one hart was requested to reset + for (Integer core = 0; core < valueOf(CoreNum); core = core + 1) + debug_module.harts_reset_client[core].response.put (is_running); + $display ("%0d: %m.rl_dm_harts_reset_wait: proc.start (pc %0h, tohostAddr %0h, fromhostAddr %0h", cur_cycle, pc, rg_tohost_addr, rg_fromhost_addr); end - rg_hart0_reset_delay <= rg_hart0_reset_delay - 1; + rg_harts_reset_delay <= rg_harts_reset_delay - 1; endrule `endif @@ -240,8 +245,8 @@ module mkCoreW #(Reset dm_power_on_reset) // ================================================================ // Direct DM-to-CPU connections for run-control and other misc requests - mkConnection (debug_module.hart0_client_run_halt, proc.hart0_run_halt_server); - mkConnection (debug_module.hart0_get_other_req, proc.hart0_put_other_req); + mkConnection (debug_module.harts_client_run_halt, proc.harts_run_halt_server); + mkConnection (debug_module.harts_get_other_req, proc.harts_put_other_req); `endif `ifdef INCLUDE_TANDEM_VERIF @@ -322,15 +327,15 @@ module mkCoreW #(Reset dm_power_on_reset) // BEGIN SECTION: DM, no TV // Connect DM's GPR interface directly to CPU - mkConnection (debug_module.hart0_gpr_mem_client, proc.hart0_gpr_mem_server); + mkConnection (debug_module.harts_gpr_mem_client, proc.harts_gpr_mem_server); `ifdef ISA_F_OR_D // Connect DM's FPR interface directly to CPU - mkConnection (debug_module.hart0_fpr_mem_client, proc.hart0_fpr_mem_server); + mkConnection (debug_module.harts_fpr_mem_client, proc.harts_fpr_mem_server); `endif // Connect DM's CSR interface directly to CPU - mkConnection (debug_module.hart0_csr_mem_client, proc.hart0_csr_mem_server); + mkConnection (debug_module.harts_csr_mem_client, proc.harts_csr_mem_server); // DM's bus master is directly the bus master let dm_master_local = debug_module.master; @@ -428,7 +433,7 @@ module mkCoreW #(Reset dm_power_on_reset) proc.start (is_running, pc, tohost_addr, fromhost_addr); `ifdef INCLUDE_GDB_CONTROL - // Save for potential future use by rl_dm_hart0_reset + // Save for potential future use by rl_dm_harts_reset rg_tohost_addr <= tohost_addr; rg_fromhost_addr <= fromhost_addr; `endif diff --git a/src_Core/Debug_Module/DM_Abstract_Commands.bsv b/src_Core/Debug_Module/DM_Abstract_Commands.bsv index 370ee52..b4d9b89 100644 --- a/src_Core/Debug_Module/DM_Abstract_Commands.bsv +++ b/src_Core/Debug_Module/DM_Abstract_Commands.bsv @@ -28,6 +28,7 @@ import FIFOF :: *; import GetPut :: *; import ClientServer :: *; import ConfigReg :: *; +import Vector :: *; // ---------------- // Other library imports @@ -41,6 +42,7 @@ import Cur_Cycle :: *; import ISA_Decls :: *; import DM_Common :: *; import DM_CPU_Req_Rsp :: *; +import ProcTypes :: *; // ================================================================ // Interface @@ -55,11 +57,11 @@ interface DM_Abstract_Commands_IFC; // ---------------- // Facing CPU/hart - interface Client #(DM_CPU_Req #(5, XLEN), DM_CPU_Rsp #(XLEN)) hart0_gpr_mem_client; + interface Vector #(CoreNum, Client #(DM_CPU_Req #(5, XLEN), DM_CPU_Rsp #(XLEN))) harts_gpr_mem_client; `ifdef ISA_F - interface Client #(DM_CPU_Req #(5, FLEN), DM_CPU_Rsp #(FLEN)) hart0_fpr_mem_client; + interface Vector #(CoreNum, Client #(DM_CPU_Req #(5, FLEN), DM_CPU_Rsp #(FLEN))) harts_fpr_mem_client; `endif - interface Client #(DM_CPU_Req #(12, XLEN), DM_CPU_Rsp #(XLEN)) hart0_csr_mem_client; + interface Vector #(CoreNum, Client #(DM_CPU_Req #(12, XLEN), DM_CPU_Rsp #(XLEN))) harts_csr_mem_client; endinterface // ================================================================ @@ -73,19 +75,21 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC); Reg #(Bool) rg_start_reg_access <- mkConfigReg (False); + Reg #(Bit#(20)) rg_dmcontrol_hartsel <- mkConfigReg(0); + // FIFOs for request/response to access GPRs - FIFOF #(DM_CPU_Req #(5, XLEN)) f_hart0_gpr_reqs <- mkFIFOF; - FIFOF #(DM_CPU_Rsp #(XLEN)) f_hart0_gpr_rsps <- mkFIFOF; + Vector #(CoreNum, FIFOF #(DM_CPU_Req #(5, XLEN))) f_harts_gpr_reqs <- replicateM(mkFIFOF); + Vector #(CoreNum, FIFOF #(DM_CPU_Rsp #(XLEN))) f_harts_gpr_rsps <- replicateM(mkFIFOF); // FIFOs for request/response to access FPRs `ifdef ISA_F - FIFOF #(DM_CPU_Req #(5, FLEN)) f_hart0_fpr_reqs <- mkFIFOF; - FIFOF #(DM_CPU_Rsp #(FLEN)) f_hart0_fpr_rsps <- mkFIFOF; + Vector #(CoreNum, FIFOF #(DM_CPU_Req #(5, FLEN))) f_harts_fpr_reqs <- replicateM(mkFIFOF); + Vector #(CoreNum, FIFOF #(DM_CPU_Rsp #(FLEN))) f_harts_fpr_rsps <- replicateM(mkFIFOF); `endif // FIFOs for request/response to access CSRs - FIFOF #(DM_CPU_Req #(12, XLEN)) f_hart0_csr_reqs <- mkFIFOF; - FIFOF #(DM_CPU_Rsp #(XLEN)) f_hart0_csr_rsps <- mkFIFOF; + Vector #(CoreNum, FIFOF #(DM_CPU_Req #(12, XLEN))) f_harts_csr_reqs <- replicateM(mkFIFOF); + Vector #(CoreNum, FIFOF #(DM_CPU_Rsp #(XLEN))) f_harts_csr_rsps <- replicateM(mkFIFOF); // ---------------------------------------------------------------- // rg_data0 @@ -227,8 +231,8 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC); rg_abstractcs_busy <= True; rg_start_reg_access <= True; cmderr = DM_ABSTRACTCS_CMDERR_NONE; - if (verbosity != 0) - $display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: OKAY", cur_cycle, dm_word); + if (verbosity != 0) + $display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: OKAY", cur_cycle, dm_word); end rg_abstractcs_cmderr <= cmderr; end @@ -258,217 +262,253 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC); // ---------------------------------------------------------------- // Write CSR - rule rl_csr_write_start ( rg_abstractcs_busy - && rg_start_reg_access - && rg_command_access_reg_write - && is_csr); - let req = DM_CPU_Req {write: True, - address: csr_addr, + + Rules finishRules = emptyRules; + + for (Integer core = 0; core < valueOf(CoreNum); core = core + 1) begin + rule rl_csr_write_start ( rg_abstractcs_busy + && rg_start_reg_access + && rg_command_access_reg_write + && is_csr + && (fromInteger(core) == rg_dmcontrol_hartsel)); + let req = DM_CPU_Req {write: True, + address: csr_addr, `ifdef RV32 - data: rg_data0 + data: rg_data0 `endif `ifdef RV64 - data: {rg_data1, rg_data0} + data: {rg_data1, rg_data0} `endif - }; - f_hart0_csr_reqs.enq (req); - rg_start_reg_access <= False; + }; + f_harts_csr_reqs[core].enq (req); + rg_start_reg_access <= False; - if (verbosity != 0) - $display ("%0d: DM_Abstract_Commands.rl_csr_write_start: ", cur_cycle, fshow (req)); - endrule + if (verbosity != 0) + $display ("%0d: DM_Abstract_Commands.rl_csr_write_start hart %i: ", cur_cycle, core, fshow (req)); + endrule - // ---------------- + // ---------------- - rule rl_csr_write_finish (rg_abstractcs_busy - && rg_command_access_reg_write - && is_csr); - let rsp <- pop (f_hart0_csr_rsps); - if (verbosity != 0) - $display ("%0d: DM_Abstract_Commands.rl_csr_write_finish: ", cur_cycle, fshow (rsp)); + finishRules = rJoinMutuallyExclusive(finishRules, + rules + rule rl_csr_write_finish (rg_abstractcs_busy + && rg_command_access_reg_write + && is_csr); + let rsp <- pop (f_harts_csr_rsps[core]); + if (verbosity != 0) + $display ("%0d: DM_Abstract_Commands.rl_csr_write_finish hart %i: ", cur_cycle, core, fshow (rsp)); - rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME); - rg_abstractcs_busy <= False; - endrule + rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME); + rg_abstractcs_busy <= False; + endrule + endrules + ); - // ---------------------------------------------------------------- - // Read CSR + // ---------------------------------------------------------------- + // Read CSR - rule rl_csr_read_start ( rg_abstractcs_busy - && rg_start_reg_access - && (! rg_command_access_reg_write) - && is_csr); - Bit #(XLEN) data = ?; - let req = DM_CPU_Req {write: False, address: csr_addr, data: data}; - f_hart0_csr_reqs.enq (req); - rg_start_reg_access <= False; + rule rl_csr_read_start ( rg_abstractcs_busy + && rg_start_reg_access + && (! rg_command_access_reg_write) + && is_csr + && (fromInteger(core) == rg_dmcontrol_hartsel)); + Bit #(XLEN) data = ?; + let req = DM_CPU_Req {write: False, address: csr_addr, data: data}; + f_harts_csr_reqs[core].enq (req); + rg_start_reg_access <= False; - if (verbosity != 0) - $display ("%0d: DM_Abstract_Commands.rl_csr_read_start: ", cur_cycle, fshow (req)); - endrule + if (verbosity != 0) + $display ("%0d: DM_Abstract_Commands.rl_csr_read_start hart %i: ", cur_cycle, core, fshow (req)); + endrule - // ---------------- + // ---------------- - rule rl_csr_read_finish ( rg_abstractcs_busy - && (! rg_command_access_reg_write) - && is_csr); - let rsp <- pop (f_hart0_csr_rsps); - if (verbosity != 0) - $display ("%0d: DM_Abstract_Commands.rl_csr_read_finish: ", cur_cycle, fshow (rsp)); + finishRules = rJoinMutuallyExclusive(finishRules, + rules + rule rl_csr_read_finish ( rg_abstractcs_busy + && (! rg_command_access_reg_write) + && is_csr); + let rsp <- pop (f_harts_csr_rsps[core]); + if (verbosity != 0) + $display ("%0d: DM_Abstract_Commands.rl_csr_read_finish hart %i: ", cur_cycle, core, fshow (rsp)); - rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME); + rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME); `ifdef RV32 - rg_data0 <= rsp.data; + rg_data0 <= rsp.data; `endif `ifdef RV64 - rg_data0 <= truncate (rsp.data); - rg_data1 <= rsp.data[63:32]; + rg_data0 <= truncate (rsp.data); + rg_data1 <= rsp.data[63:32]; `endif - rg_abstractcs_busy <= False; - endrule + rg_abstractcs_busy <= False; + endrule + endrules + ); - // ---------------------------------------------------------------- - // Write GPR + // ---------------------------------------------------------------- + // Write GPR - rule rl_gpr_write_start ( rg_abstractcs_busy - && rg_start_reg_access - && rg_command_access_reg_write - && is_gpr); - let req = DM_CPU_Req {write: True, - address: gpr_addr, + rule rl_gpr_write_start ( rg_abstractcs_busy + && rg_start_reg_access + && rg_command_access_reg_write + && is_gpr + && (fromInteger(core) == rg_dmcontrol_hartsel)); + let req = DM_CPU_Req {write: True, + address: gpr_addr, `ifdef RV32 - data: rg_data0 + data: rg_data0 `endif `ifdef RV64 - data: {rg_data1, rg_data0} + data: {rg_data1, rg_data0} `endif - }; - f_hart0_gpr_reqs.enq (req); - rg_start_reg_access <= False; - if (verbosity != 0) - $display ("%0d: DM_Abstract_Commands.rl_gpr_write_start: ", cur_cycle, fshow (req)); - endrule + }; + f_harts_gpr_reqs[core].enq (req); + rg_start_reg_access <= False; + if (verbosity != 0) + $display ("%0d: DM_Abstract_Commands.rl_gpr_write_start hart %i: ", cur_cycle, core, fshow (req)); + endrule - // ---------------- + // ---------------- - rule rl_gpr_write_finish ( rg_abstractcs_busy - && rg_command_access_reg_write - && is_gpr); - let rsp <- pop (f_hart0_gpr_rsps); - if (verbosity != 0) - $display ("%0d: DM_Abstract_Commands.rl_gpr_write_finish: ", cur_cycle, fshow (rsp)); + finishRules = rJoinMutuallyExclusive(finishRules, + rules + rule rl_gpr_write_finish ( rg_abstractcs_busy + && rg_command_access_reg_write + && is_gpr); + let rsp <- pop (f_harts_gpr_rsps[core]); + if (verbosity != 0) + $display ("%0d: DM_Abstract_Commands.rl_gpr_write_finish hart %i: ", cur_cycle, core, fshow (rsp)); - rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME); - rg_abstractcs_busy <= False; - endrule + rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME); + rg_abstractcs_busy <= False; + endrule + endrules + ); - // ---------------------------------------------------------------- - // Read GPR + // ---------------------------------------------------------------- + // Read GPR - rule rl_gpr_read_start ( rg_abstractcs_busy - && rg_start_reg_access - && (! rg_command_access_reg_write) - && is_gpr); - Bit #(XLEN) data = ?; - let req = DM_CPU_Req {write: False, address: gpr_addr, data: data }; - f_hart0_gpr_reqs.enq (req); - rg_start_reg_access <= False; + rule rl_gpr_read_start ( rg_abstractcs_busy + && rg_start_reg_access + && (! rg_command_access_reg_write) + && is_gpr + && (fromInteger(core) == rg_dmcontrol_hartsel)); + Bit #(XLEN) data = ?; + let req = DM_CPU_Req {write: False, address: gpr_addr, data: data }; + f_harts_gpr_reqs[core].enq (req); + rg_start_reg_access <= False; - if (verbosity != 0) - $display ("%0d: DM_Abstract_Commands.rl_gpr_read_start: ", cur_cycle, fshow (req)); - endrule + if (verbosity != 0) + $display ("%0d: DM_Abstract_Commands.rl_gpr_read_start hart %i: ", cur_cycle, core, fshow (req)); + endrule - // ---------------- + // ---------------- - rule rl_gpr_read_finish ( rg_abstractcs_busy - && (! rg_command_access_reg_write) - && is_gpr); - let rsp <- pop (f_hart0_gpr_rsps); - if (verbosity != 0) - $display ("%0d: DM_Abstract_Commands.rl_gpr_read_finish: ", cur_cycle, fshow (rsp)); + finishRules = rJoinMutuallyExclusive(finishRules, + rules + rule rl_gpr_read_finish ( rg_abstractcs_busy + && (! rg_command_access_reg_write) + && is_gpr); + let rsp <- pop (f_harts_gpr_rsps[core]); + if (verbosity != 0) + $display ("%0d: DM_Abstract_Commands.rl_gpr_read_finish hart %i: ", cur_cycle, core, fshow (rsp)); `ifdef RV32 - rg_data0 <= rsp.data; + rg_data0 <= rsp.data; `endif `ifdef RV64 - rg_data0 <= truncate (rsp.data); - rg_data1 <= rsp.data[63:32]; + rg_data0 <= truncate (rsp.data); + rg_data1 <= rsp.data[63:32]; `endif - rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME); - rg_abstractcs_busy <= False; - endrule + rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME); + rg_abstractcs_busy <= False; + endrule + endrules + ); - // ---------------------------------------------------------------- - // Write FPR + // ---------------------------------------------------------------- + // Write FPR `ifdef ISA_F - rule rl_fpr_write_start ( rg_abstractcs_busy - && rg_start_reg_access - && rg_command_access_reg_write - && is_fpr); - DM_CPU_Req#(5, ISA_Decls::FLEN) req = DM_CPU_Req {write: True, - address: fpr_addr, + rule rl_fpr_write_start ( rg_abstractcs_busy + && rg_start_reg_access + && rg_command_access_reg_write + && is_fpr + && (fromInteger(core) == rg_dmcontrol_hartsel)); + DM_CPU_Req#(5, ISA_Decls::FLEN) req = DM_CPU_Req {write: True, + address: fpr_addr, `ifdef RV32 - data: unpack(zeroExtend(rg_data0)) + data: unpack(zeroExtend(rg_data0)) `endif `ifdef RV64 - data: unpack({rg_data1, rg_data0}) + data: unpack({rg_data1, rg_data0}) `endif - }; - f_hart0_fpr_reqs.enq (req); - rg_start_reg_access <= False; - if (verbosity != 0) - $display ("%0d: DM_Abstract_Commands.rl_fpr_write_start: ", cur_cycle, fshow (req)); - endrule + }; + f_harts_fpr_reqs[core].enq (req); + rg_start_reg_access <= False; + if (verbosity != 0) + $display ("%0d: DM_Abstract_Commands.rl_fpr_write_start hart %i: ", cur_cycle, core, fshow (req)); + endrule - // ---------------- + // ---------------- - rule rl_fpr_write_finish ( rg_abstractcs_busy - && rg_command_access_reg_write - && is_fpr); - let rsp <- pop (f_hart0_fpr_rsps); - if (verbosity != 0) - $display ("%0d: DM_Abstract_Commands.rl_fpr_write_finish: ", cur_cycle, fshow (rsp)); + finishRules = rJoinMutuallyExclusive(finishRules, + rules + rule rl_fpr_write_finish ( rg_abstractcs_busy + && rg_command_access_reg_write + && is_fpr); + let rsp <- pop (f_harts_fpr_rsps[core]); + if (verbosity != 0) + $display ("%0d: DM_Abstract_Commands.rl_fpr_write_finish hart %i: ", cur_cycle, core, fshow (rsp)); - rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME); - rg_abstractcs_busy <= False; - endrule + rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME); + rg_abstractcs_busy <= False; + endrule + endrules + ); - // ---------------------------------------------------------------- - // Read FPR + // ---------------------------------------------------------------- + // Read FPR - rule rl_fpr_read_start ( rg_abstractcs_busy - && rg_start_reg_access - && (! rg_command_access_reg_write) - && is_fpr); - Bit #(FLEN) data = ?; - let req = DM_CPU_Req {write: False, address: fpr_addr, data: data }; - f_hart0_fpr_reqs.enq (req); - rg_start_reg_access <= False; + rule rl_fpr_read_start ( rg_abstractcs_busy + && rg_start_reg_access + && (! rg_command_access_reg_write) + && is_fpr + && (fromInteger(core) == rg_dmcontrol_hartsel)); + Bit #(FLEN) data = ?; + let req = DM_CPU_Req {write: False, address: fpr_addr, data: data }; + f_harts_fpr_reqs[core].enq (req); + rg_start_reg_access <= False; - if (verbosity != 0) - $display ("%0d: DM_Abstract_Commands.rl_fpr_read_start: ", cur_cycle, fshow (req)); - endrule + if (verbosity != 0) + $display ("%0d: DM_Abstract_Commands.rl_fpr_read_start hart %i: ", cur_cycle, core, fshow (req)); + endrule - // ---------------- + // ---------------- - rule rl_fpr_read_finish ( rg_abstractcs_busy - && (! rg_command_access_reg_write) - && is_fpr); - let rsp <- pop (f_hart0_fpr_rsps); - if (verbosity != 0) - $display ("%0d: DM_Abstract_Commands.rl_fpr_read_finish: ", cur_cycle, fshow (rsp)); + finishRules = rJoinMutuallyExclusive(finishRules, + rules + rule rl_fpr_read_finish ( rg_abstractcs_busy + && (! rg_command_access_reg_write) + && is_fpr); + let rsp <- pop (f_harts_fpr_rsps[core]); + if (verbosity != 0) + $display ("%0d: DM_Abstract_Commands.rl_fpr_read_finish hart: ", cur_cycle, core, fshow (rsp)); - rg_data0 <= truncate (rsp.data); + rg_data0 <= truncate (rsp.data); `ifdef RV64 - rg_data1 <= rsp.data[63:32]; + rg_data1 <= rsp.data[63:32]; `endif - rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME); - rg_abstractcs_busy <= False; - endrule + rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME); + rg_abstractcs_busy <= False; + endrule + endrules + ); +`endif + end -`endif + addRules(finishRules); // ---------------------------------------------------------------- // Read/Write unknown address @@ -505,10 +545,12 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC); method Action reset; rg_start_reg_access <= False; - f_hart0_gpr_reqs.clear; - f_hart0_gpr_rsps.clear; - f_hart0_csr_reqs.clear; - f_hart0_csr_rsps.clear; + function proj_clear (x) = x.clear(); + + mapM_(proj_clear, f_harts_gpr_reqs); + mapM_(proj_clear, f_harts_gpr_rsps); + mapM_(proj_clear, f_harts_csr_reqs); + mapM_(proj_clear, f_harts_csr_rsps); rg_abstractcs_busy <= False; rg_abstractcs_cmderr <= DM_ABSTRACTCS_CMDERR_NONE; @@ -552,7 +594,15 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC); action let dm_addr_name = fshow_dm_addr (dm_addr); - if (dm_addr == dm_addr_abstractcs) + if (dm_addr == dm_addr_dmcontrol) begin + rg_dmcontrol_hartsel <= fn_dmcontrol_hartsel(dm_word); + // It is specified that the debugger must not change hartsel while this module is busy. + // If this is done, the debug unit will wedge, so print a warning. + $display ("%0d: DM_Abstract_Commands.write: [", cur_cycle, dm_addr_name, + "] <= 0x%08h: ERROR: must not change hartsel while busy", dm_word); + end + + else if (dm_addr == dm_addr_abstractcs) fa_rg_abstractcs_write (dm_word); else if (rg_abstractcs_cmderr != DM_ABSTRACTCS_CMDERR_NONE) begin @@ -593,11 +643,11 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC); // ---------------- // Facing CPU/hart - interface Client hart0_gpr_mem_client = toGPClient (f_hart0_gpr_reqs, f_hart0_gpr_rsps); + interface harts_gpr_mem_client = zipWith (toGPClient, f_harts_gpr_reqs, f_harts_gpr_rsps); `ifdef ISA_F - interface Client hart0_fpr_mem_client = toGPClient (f_hart0_fpr_reqs, f_hart0_fpr_rsps); + interface harts_fpr_mem_client = zipWith (toGPClient, f_harts_fpr_reqs, f_harts_fpr_rsps); `endif - interface Client hart0_csr_mem_client = toGPClient (f_hart0_csr_reqs, f_hart0_csr_rsps); + interface harts_csr_mem_client = zipWith (toGPClient, f_harts_csr_reqs, f_harts_csr_rsps); endmodule // ================================================================ diff --git a/src_Core/Debug_Module/DM_Common.bsv b/src_Core/Debug_Module/DM_Common.bsv index 45049f2..a111ff1 100644 --- a/src_Core/Debug_Module/DM_Common.bsv +++ b/src_Core/Debug_Module/DM_Common.bsv @@ -35,13 +35,14 @@ typedef Bit #(32) DM_Word; DM_Addr dm_addr_dmcontrol = 'h10; DM_Addr dm_addr_dmstatus = 'h11; DM_Addr dm_addr_hartinfo = 'h12; -DM_Addr dm_addr_haltsum = 'h13; +DM_Addr dm_addr_haltsum1 = 'h13; DM_Addr dm_addr_hawindowsel = 'h14; DM_Addr dm_addr_hawindow = 'h15; DM_Addr dm_addr_devtreeaddr0 = 'h19; DM_Addr dm_addr_authdata = 'h30; -DM_Addr dm_addr_haltregion0 = 'h40; -DM_Addr dm_addr_haltregion31 = 'h5F; +DM_Addr dm_addr_haltsum2 = 'h34; +DM_Addr dm_addr_haltsum3 = 'h35; +DM_Addr dm_addr_haltsum0 = 'h40; DM_Addr dm_addr_verbosity = 'h60; // Non-standard (not in spec) @@ -87,14 +88,15 @@ function Fmt fshow_dm_addr (DM_Addr dm_addr); dm_addr_dmcontrol: $format ("dm_addr_dmcontrol"); dm_addr_dmstatus: $format ("dm_addr_dmstatus"); dm_addr_hartinfo: $format ("dm_addr_hartinfo"); - dm_addr_haltsum: $format ("dm_addr_haltsum"); + dm_addr_haltsum1: $format ("dm_addr_haltsum1"); dm_addr_hawindowsel: $format ("dm_addr_hawindowsel"); dm_addr_hawindow: $format ("dm_addr_hawindow"); dm_addr_devtreeaddr0: $format ("dm_addr_devtreeaddr0"); dm_addr_authdata: $format ("dm_addr_authdata"); - dm_addr_haltregion0: $format ("dm_addr_haltregion0"); - dm_addr_haltregion31: $format ("dm_addr_haltregion31"); - dm_addr_verbosity: $format ("dm_addr_verbosity"); + dm_addr_haltsum2: $format ("dm_addr_haltsum2"); + dm_addr_haltsum3: $format ("dm_addr_haltsum3"); + dm_addr_haltsum0: $format ("dm_addr_haltsum0"); + dm_addr_verbosity: $format ("dm_addr_verbosity"); // Abstract Commands dm_addr_abstractcs: $format ("dm_addr_abstractcs"); @@ -168,8 +170,8 @@ function Bool fn_dmcontrol_hasel (DM_Word dm_word); return unpack (dm_word [26]); endfunction -function Bit #(10) fn_dmcontrol_hartsel (DM_Word dm_word); - return dm_word [25:16]; +function Bit #(20) fn_dmcontrol_hartsel (DM_Word dm_word); + return {dm_word [15:6], dm_word[25:16]}; endfunction function Bool fn_dmcontrol_ndmreset (DM_Word dm_word); diff --git a/src_Core/Debug_Module/DM_Run_Control.bsv b/src_Core/Debug_Module/DM_Run_Control.bsv index 4887ade..a912d5b 100644 --- a/src_Core/Debug_Module/DM_Run_Control.bsv +++ b/src_Core/Debug_Module/DM_Run_Control.bsv @@ -28,6 +28,7 @@ import FIFOF :: *; import GetPut :: *; import ClientServer :: *; import ConfigReg :: *; +import Vector :: *; // ---------------- // Other library imports @@ -40,6 +41,7 @@ import GetPut_Aux :: *; import ISA_Decls :: *; import DM_Common :: *; +import ProcTypes :: *; // ================================================================ // Interface @@ -54,10 +56,10 @@ interface DM_Run_Control_IFC; method Action write (DM_Addr dm_addr, DM_Word dm_word); // ---------------- - // Facing a hart: reset and run-control - interface Client #(Bool, Bool) hart0_reset_client; - interface Client #(Bool, Bool) hart0_client_run_halt; - interface Get #(Bit #(4)) hart0_get_other_req; + // Facing harts: reset and run-control + interface Vector #(CoreNum, Client #(Bool, Bool)) harts_reset_client; + interface Vector #(CoreNum, Client #(Bool, Bool)) harts_client_run_halt; + interface Vector #(CoreNum, Get #(Bit #(4))) harts_get_other_req; // ---------------- // Facing Platform: Non-Debug-Module Reset (reset all except DM) @@ -78,56 +80,69 @@ module mkDM_Run_Control (DM_Run_Control_IFC); FIFOF #(Bool) f_ndm_reset_reqs <- mkFIFOF; FIFOF #(Bool) f_ndm_reset_rsps <- mkFIFOF; - // ---------------------------------------------------------------- - // Hart0 run control + Reg #(Bool) rg_ndm_reset_pending <- mkConfigReg(False); - Reg #(Bool) rg_hart0_running <- mkRegU; + // ---------------------------------------------------------------- + // Hart run control + + Vector #(CoreNum, Reg #(Bool)) rg_harts_hasreset <- replicateM(mkRegU); + Vector #(CoreNum, Reg #(Bool)) rg_harts_resumeack <- replicateM(mkRegU); + Vector #(CoreNum, Reg #(Bool)) rg_harts_running <- replicateM(mkRegU); // Reset requests to hart - FIFOF #(Bool) f_hart0_reset_reqs <- mkFIFOF; - FIFOF #(Bool) f_hart0_reset_rsps <- mkFIFOF; + Vector #(CoreNum, FIFOF #(Bool)) f_harts_reset_reqs <- replicateM(mkFIFOF); + Vector #(CoreNum, FIFOF #(Bool)) f_harts_reset_rsps <- replicateM(mkFIFOF); // Run/halt requests to hart and responses - FIFOF #(Bool) f_hart0_run_halt_reqs <- mkFIFOF; - FIFOF #(Bool) f_hart0_run_halt_rsps <- mkFIFOF; + Vector #(CoreNum, FIFOF #(Bool)) f_harts_run_halt_reqs <- replicateM(mkFIFOF); + Vector #(CoreNum, FIFOF #(Bool)) f_harts_run_halt_rsps <- replicateM(mkFIFOF); // Non-standard requests to hart and responses // Currently only verbosity - FIFOF #(Bit #(4)) f_hart0_other_reqs <- mkFIFOF; + Vector #(CoreNum, FIFOF #(Bit #(4))) f_harts_other_reqs <- replicateM(mkFIFOF); + + // ---------------------------------------------------------------- + // rg_dmcontrol + + Reg #(Bool) rg_dmcontrol_haltreq <- mkRegU; + // resumereq is a W1 field, no need for a register + Reg #(Bool) rg_dmcontrol_hartreset <- mkRegU; + Reg #(Bool) rg_dmcontrol_ndmreset <- mkRegU; + Reg #(Bool) rg_dmcontrol_dmactive <- mkReg (False); + Reg #(Bit#(20)) rg_dmcontrol_hartsel <- mkReg (0); + + Bit#(20) core_num_sel = fromInteger(valueOf(CoreNum)); // ---------------------------------------------------------------- - Bit #(32) haltregion0 = { 31'h0, pack (! rg_hart0_running) }; - Bit #(32) haltsum = { 31'h0, pack (! rg_hart0_running) }; + // We only support haltsum0, so can only support < 33 harts. This will give + // a type error if an unsupported number of cores are requested. + Bit #(32) haltsum0 = zeroExtend(~pack(readVReg(rg_harts_running))); // ---------------------------------------------------------------- // rg_dmstatus - // Since we currently support only 1 hart, + // Since we currently support only 1 hart at a time, // 'anyXX' = 'allXX' // 'allrunning' = NOT 'allhalted' Bool dmstatus_impebreak = False; - Reg #(Bool) rg_hart0_hasreset <- mkRegU; - Bool dmstatus_allhavereset = rg_hart0_hasreset; - Bool dmstatus_anyhavereset = rg_hart0_hasreset; + Bool dmstatus_allhavereset = rg_dmcontrol_hartsel < core_num_sel && rg_harts_hasreset[rg_dmcontrol_hartsel]; + Bool dmstatus_anyhavereset = dmstatus_allhavereset; - Reg #(Bool) rg_dmstatus_allresumeack <- mkRegU; + Bool dmstatus_allresumeack = rg_dmcontrol_hartsel < core_num_sel && rg_harts_resumeack[rg_dmcontrol_hartsel]; + Bool dmstatus_anyresumeack = dmstatus_allresumeack; - Bool dmstatus_allresumeack = rg_dmstatus_allresumeack; - Bool dmstatus_anyresumeack = rg_dmstatus_allresumeack; - - Bool dmstatus_allnonexistent = False; + Bool dmstatus_allnonexistent = rg_dmcontrol_hartsel >= core_num_sel; Bool dmstatus_anynonexistent = dmstatus_allnonexistent; - Reg #(Bool) rg_dmstatus_allunavail <- mkReg (False); - Bool dmstatus_allunavail = rg_dmstatus_allunavail; - Bool dmstatus_anyunavail = rg_dmstatus_allunavail; + Bool dmstatus_allunavail = rg_dmcontrol_hartsel < core_num_sel && rg_ndm_reset_pending; + Bool dmstatus_anyunavail = dmstatus_allunavail; - Bool dmstatus_allrunning = rg_hart0_running; + Bool dmstatus_allrunning = rg_dmcontrol_hartsel < core_num_sel && rg_harts_running[rg_dmcontrol_hartsel]; Bool dmstatus_anyrunning = dmstatus_allrunning; - Bool dmstatus_allhalted = (! rg_hart0_running); + Bool dmstatus_allhalted = rg_dmcontrol_hartsel < core_num_sel && (! rg_harts_running[rg_dmcontrol_hartsel]); Bool dmstatus_anyhalted = dmstatus_allhalted; DM_Word virt_rg_dmstatus = {9'b0, @@ -151,21 +166,16 @@ module mkDM_Run_Control (DM_Run_Control_IFC); pack (False), // devtreevalid 4'h2}; // version - // ---------------------------------------------------------------- - // rg_dmcontrol - - Reg #(Bool) rg_dmcontrol_haltreq <- mkRegU; - // resumereq is a W1 field, no need for a register - Reg #(Bool) rg_dmcontrol_hartreset <- mkRegU; - Reg #(Bool) rg_dmcontrol_ndmreset <- mkRegU; - Reg #(Bool) rg_dmcontrol_dmactive <- mkConfigReg (False); - DM_Word virt_rg_dmcontrol = {2'b0, // haltreq, resumereq (w-o) pack (rg_dmcontrol_hartreset), 2'b0, pack (False), // hasel - 10'b0, // hartsel - 14'b0, + rg_dmcontrol_hartsel[9:0], + rg_dmcontrol_hartsel[19:10], + 1'b0, // setkeepalive + 1'b0, // clrkeepalive + 1'b0, // setresethaltreq + 1'b0, // clrkeepalive pack (rg_dmcontrol_ndmreset), pack (rg_dmcontrol_dmactive)}; @@ -183,6 +193,7 @@ module mkDM_Run_Control (DM_Run_Control_IFC); rg_dmcontrol_hartreset <= hartreset; rg_dmcontrol_ndmreset <= ndmreset; rg_dmcontrol_dmactive <= dmactive; + rg_dmcontrol_hartsel <= hartsel; // Debug Module reset if (! dmactive) begin @@ -207,7 +218,7 @@ module mkDM_Run_Control (DM_Run_Control_IFC); end // Ignore if NDM reset is in progress - else if (rg_dmstatus_allunavail) begin + else if (rg_ndm_reset_pending) begin $display ("%0d: %m.dmcontrol_write 0x%0h: ndm reset in progress; ignoring this write", cur_cycle, dm_word); end @@ -229,7 +240,7 @@ module mkDM_Run_Control (DM_Run_Control_IFC); end f_ndm_reset_reqs.enq (running); - rg_dmstatus_allunavail <= True; + rg_ndm_reset_pending <= True; // Error-checking if (hartreset) begin @@ -243,8 +254,8 @@ module mkDM_Run_Control (DM_Run_Control_IFC); // Hart reset else if (hartreset) begin Bool running = (! haltreq); - f_hart0_reset_reqs.enq (running); - rg_hart0_hasreset <= True; + f_harts_reset_reqs[hartsel].enq (running); + rg_harts_hasreset[hartsel] <= True; // Deassert platform reset if (verbosity != 0) begin @@ -265,8 +276,8 @@ module mkDM_Run_Control (DM_Run_Control_IFC); $display ("%0d:ERROR: %m.dmcontrol_write 0x%08h: hasel is not supported", cur_cycle, dm_word); - if (hartsel != 0) - $display ("%0d:ERROR: %m.dmcontrol_write 0x%08h: hartsel 0x%0h not supported", + if (hartsel >= core_num_sel) + $display ("%0d:WARNING: %m.dmcontrol_write 0x%08h: hartsel 0x%0h refers to non-existent hart", cur_cycle, dm_word, hartsel); if (haltreq && resumereq) begin @@ -275,15 +286,15 @@ module mkDM_Run_Control (DM_Run_Control_IFC); $display (" This behavior is 'undefined' in the spec; ignoring"); end // Resume hart(s) if not running - else if (resumereq && (! rg_hart0_running)) begin - f_hart0_run_halt_reqs.enq (True); - rg_dmstatus_allresumeack <= False; - $display ("%0d: %m.dmcontrol_write: hart0 resume request", cur_cycle); + else if (resumereq && (! rg_harts_running[hartsel])) begin + f_harts_run_halt_reqs[hartsel].enq (True); + rg_harts_resumeack[hartsel] <= False; + $display ("%0d: %m.dmcontrol_write: hart %i resume request", cur_cycle, hartsel); end // Halt hart(s) - else if (haltreq && rg_hart0_running) begin - f_hart0_run_halt_reqs.enq (False); - $display ("%0d: %m.dmcontrol_write: hart0 halt request", cur_cycle); + else if (haltreq && rg_harts_running[hartsel]) begin + f_harts_run_halt_reqs[hartsel].enq (False); + $display ("%0d: %m.dmcontrol_write: hart %i halt request", cur_cycle, hartsel); end end endaction @@ -307,35 +318,37 @@ module mkDM_Run_Control (DM_Run_Control_IFC); // ---------------------------------------------------------------- // System responses - // Response from system for hart0 reset - rule rl_hart0_reset_rsp; - Bool running <- pop (f_hart0_reset_rsps); - rg_hart0_hasreset <= False; - rg_hart0_running <= running; + // Response from system for hart reset + for (Integer core = 0; core < valueOf(CoreNum); core = core + 1) + rule rl_harts_reset_rsp; + Bool running <- pop (f_harts_reset_rsps[core]); + rg_harts_hasreset[core] <= False; + rg_harts_running[core] <= running; - if (verbosity != 0) - $display ("%0d: %m.rl_hart0_reset_rdp: hart running = ", cur_cycle, fshow (running)); + if (verbosity != 0) + $display ("%0d: %m.rl_harts_reset_rsp: hart %i running = ", cur_cycle, core, fshow (running)); endrule // Response from system for NDM reset rule rl_ndm_reset_rsp; Bool running <- pop (f_ndm_reset_rsps); - rg_hart0_running <= running; - rg_dmstatus_allunavail <= False; + writeVReg(rg_harts_running, replicate(running)); + rg_ndm_reset_pending <= False; if (verbosity != 0) - $display ("%0d: %m.rl_ndm_reset_rsp: hart running = ", cur_cycle, fshow (running)); + $display ("%0d: %m.rl_ndm_reset_rsp: harts running = ", cur_cycle, fshow (running)); endrule + for (Integer core = 0; core < valueOf(CoreNum); core = core + 1) // Response from system for run/halt request - rule rl_hart0_run_rsp (! f_ndm_reset_rsps.notEmpty); - let running <- pop (f_hart0_run_halt_rsps); - rg_hart0_running <= running; + rule rl_harts_run_rsp (! f_ndm_reset_rsps.notEmpty); + let running <- pop (f_harts_run_halt_rsps[core]); + rg_harts_running[core] <= running; if (running) - rg_dmstatus_allresumeack <= True; + rg_harts_resumeack[core] <= True; if (verbosity != 0) - $display ("%0d: %m.rl_hart0_run_rsp: 'running' = ", cur_cycle, fshow (running)); + $display ("%0d: %m.rl_harts_run_rsp hart: hart %i 'running' = ", cur_cycle, core, fshow (running)); endrule // ---------------------------------------------------------------- @@ -349,21 +362,24 @@ module mkDM_Run_Control (DM_Run_Control_IFC); f_ndm_reset_reqs.clear; f_ndm_reset_rsps.clear; - f_hart0_reset_reqs.clear; - f_hart0_reset_rsps.clear; + function proj_clear (x) = x.clear(); - rg_hart0_running <= True; // Safe approximation of whether the CPU is running or not - f_hart0_run_halt_reqs.clear; - f_hart0_run_halt_rsps.clear; + mapM_(proj_clear, f_harts_reset_reqs); + mapM_(proj_clear, f_harts_reset_rsps); + + writeVReg(rg_harts_running, replicate(True)); // Safe approximation of whether the CPU is running or not + mapM_(proj_clear, f_harts_run_halt_reqs); + mapM_(proj_clear, f_harts_run_halt_rsps); rg_dmcontrol_haltreq <= False; rg_dmcontrol_hartreset <= False; rg_dmcontrol_ndmreset <= False; rg_dmcontrol_dmactive <= True; // DM module is now active - rg_hart0_hasreset <= False; - rg_dmstatus_allresumeack <= False; - rg_dmstatus_allunavail <= False; // NDM not in progress + writeVReg(rg_harts_hasreset, replicate(False)); + writeVReg(rg_harts_resumeack, replicate(False)); + + rg_ndm_reset_pending <= False; rg_verbosity <= 0; @@ -379,8 +395,7 @@ module mkDM_Run_Control (DM_Run_Control_IFC); DM_Word dm_word = case (dm_addr) dm_addr_dmcontrol: virt_rg_dmcontrol; dm_addr_dmstatus: virt_rg_dmstatus; - dm_addr_haltsum: haltsum; - dm_addr_haltregion0: haltregion0; + dm_addr_haltsum0: haltsum0; dm_addr_verbosity: extend (rg_verbosity); endcase; @@ -400,7 +415,7 @@ module mkDM_Run_Control (DM_Run_Control_IFC); dm_addr_dmcontrol: fa_rg_dmcontrol_write (dm_word); dm_addr_verbosity: begin rg_verbosity <= truncate (dm_word); - f_hart0_other_reqs.enq (truncate (dm_word)); + f_harts_other_reqs[rg_dmcontrol_hartsel].enq (truncate (dm_word)); end default: noAction; endcase @@ -409,13 +424,13 @@ module mkDM_Run_Control (DM_Run_Control_IFC); // ---------------- // Facing Hart: Reset, Run-control, etc. - interface Client hart0_reset_client = toGPClient (f_hart0_reset_reqs, f_hart0_reset_rsps); - interface Client hart0_client_run_halt = toGPClient (f_hart0_run_halt_reqs, f_hart0_run_halt_rsps); - interface Get hart0_get_other_req = toGet (f_hart0_other_reqs); + interface harts_reset_client = zipWith(toGPClient, f_harts_reset_reqs, f_harts_reset_rsps); + interface harts_client_run_halt = zipWith(toGPClient, f_harts_run_halt_reqs, f_harts_run_halt_rsps); + interface harts_get_other_req = map (toGet, f_harts_other_reqs); // ---------------- // Facing Platform: Non-Debug-Module Reset (reset all except DM) - interface Client ndm_reset_client = toGPClient (f_ndm_reset_reqs, f_ndm_reset_rsps); + interface ndm_reset_client = toGPClient (f_ndm_reset_reqs, f_ndm_reset_rsps); endmodule // ================================================================ diff --git a/src_Core/Debug_Module/Debug_Module.bsv b/src_Core/Debug_Module/Debug_Module.bsv index d08c56e..9c17d71 100644 --- a/src_Core/Debug_Module/Debug_Module.bsv +++ b/src_Core/Debug_Module/Debug_Module.bsv @@ -71,6 +71,7 @@ import FIFO :: *; import GetPut :: *; import ClientServer :: *; import SpecialFIFOs :: *; +import Vector :: *; // ---------------- // Other library imports @@ -84,6 +85,7 @@ import AXI4 :: *; import ISA_Decls :: *; import Fabric_Defs :: *; +import ProcTypes :: *; import DM_Common :: *; import DM_CPU_Req_Rsp :: *; @@ -111,20 +113,20 @@ interface Debug_Module_IFC; // This section replicated for additional harts. // Reset and run-control - interface Client #(Bool, Bool) hart0_reset_client; - interface Client #(Bool, Bool) hart0_client_run_halt; - interface Get #(Bit #(4)) hart0_get_other_req; + interface Vector #(CoreNum, Client #(Bool, Bool)) harts_reset_client; + interface Vector #(CoreNum, Client #(Bool, Bool)) harts_client_run_halt; + interface Vector #(CoreNum, Get #(Bit #(4))) harts_get_other_req; // GPR access - interface Client #(DM_CPU_Req #(5, XLEN), DM_CPU_Rsp #(XLEN)) hart0_gpr_mem_client; + interface Vector #(CoreNum, Client #(DM_CPU_Req #(5, XLEN), DM_CPU_Rsp #(XLEN))) harts_gpr_mem_client; // FPR access `ifdef ISA_F - interface Client #(DM_CPU_Req #(5, FLEN), DM_CPU_Rsp #(FLEN)) hart0_fpr_mem_client; + interface Vector #(CoreNum, Client #(DM_CPU_Req #(5, FLEN), DM_CPU_Rsp #(FLEN))) harts_fpr_mem_client; `endif // CSR access - interface Client #(DM_CPU_Req #(12, XLEN), DM_CPU_Rsp #(XLEN)) hart0_csr_mem_client; + interface Vector #(CoreNum, Client #(DM_CPU_Req #(12, XLEN), DM_CPU_Rsp #(XLEN))) harts_csr_mem_client; // ---------------- // Facing Platform @@ -187,13 +189,11 @@ module mkDebug_Module (Debug_Module_IFC); if ( (dm_addr == dm_addr_dmcontrol) || (dm_addr == dm_addr_dmstatus) || (dm_addr == dm_addr_hartinfo) - || (dm_addr == dm_addr_haltsum) + || (dm_addr == dm_addr_haltsum0) || (dm_addr == dm_addr_hawindowsel) || (dm_addr == dm_addr_hawindow) || (dm_addr == dm_addr_devtreeaddr0) || (dm_addr == dm_addr_authdata) - || (dm_addr == dm_addr_haltregion0) - || (dm_addr == dm_addr_haltregion31) || (dm_addr == dm_addr_verbosity)) dm_word <- dm_run_control.av_read (dm_addr); @@ -241,21 +241,25 @@ module mkDebug_Module (Debug_Module_IFC); endmethod method Action write (DM_Addr dm_addr, DM_Word dm_word) if (dm_run_control.dmactive); + + Bool handled = False; + if ( (dm_addr == dm_addr_dmcontrol) || (dm_addr == dm_addr_dmstatus) || (dm_addr == dm_addr_hartinfo) - || (dm_addr == dm_addr_haltsum) + || (dm_addr == dm_addr_haltsum0) || (dm_addr == dm_addr_hawindowsel) || (dm_addr == dm_addr_hawindow) || (dm_addr == dm_addr_devtreeaddr0) || (dm_addr == dm_addr_authdata) - || (dm_addr == dm_addr_haltregion0) - || (dm_addr == dm_addr_haltregion31) - || (dm_addr == dm_addr_verbosity)) + || (dm_addr == dm_addr_verbosity)) begin dm_run_control.write (dm_addr, dm_word); + handled = True; + end - else if ( (dm_addr == dm_addr_abstractcs) + if ( (dm_addr == dm_addr_dmcontrol) + || (dm_addr == dm_addr_abstractcs) || (dm_addr == dm_addr_command) || (dm_addr == dm_addr_data0) || (dm_addr == dm_addr_data1) @@ -270,22 +274,26 @@ module mkDebug_Module (Debug_Module_IFC); || (dm_addr == dm_addr_data10) || (dm_addr == dm_addr_data11) || (dm_addr == dm_addr_abstractauto) - || (dm_addr == dm_addr_progbuf0)) + || (dm_addr == dm_addr_progbuf0)) begin dm_abstract_commands.write (dm_addr, dm_word); + handled = True; + end - else if ( (dm_addr == dm_addr_sbcs) + if ( (dm_addr == dm_addr_sbcs) || (dm_addr == dm_addr_sbaddress0) || (dm_addr == dm_addr_sbaddress1) || (dm_addr == dm_addr_sbaddress2) || (dm_addr == dm_addr_sbdata0) || (dm_addr == dm_addr_sbdata1) || (dm_addr == dm_addr_sbdata2) - || (dm_addr == dm_addr_sbdata3)) + || (dm_addr == dm_addr_sbdata3)) begin dm_system_bus.write (dm_addr, dm_word); + handled = True; + end - else begin + if (! handled) begin // TODO: set error status? noAction; end @@ -297,23 +305,23 @@ module mkDebug_Module (Debug_Module_IFC); endinterface // ---------------- - // Facing CPU/hart0 + // Facing CPU/harts // Reset and run-control - interface Client hart0_reset_client = dm_run_control.hart0_reset_client; - interface Client hart0_client_run_halt = dm_run_control.hart0_client_run_halt; - interface Get hart0_get_other_req = dm_run_control.hart0_get_other_req; + interface harts_reset_client = dm_run_control.harts_reset_client; + interface harts_client_run_halt = dm_run_control.harts_client_run_halt; + interface harts_get_other_req = dm_run_control.harts_get_other_req; // GPR access - interface Client hart0_gpr_mem_client = dm_abstract_commands.hart0_gpr_mem_client; + interface harts_gpr_mem_client = dm_abstract_commands.harts_gpr_mem_client; // FPR access `ifdef ISA_F - interface Client hart0_fpr_mem_client = dm_abstract_commands.hart0_fpr_mem_client; + interface harts_fpr_mem_client = dm_abstract_commands.harts_fpr_mem_client; `endif // CSR access - interface Client hart0_csr_mem_client = dm_abstract_commands.hart0_csr_mem_client; + interface harts_csr_mem_client = dm_abstract_commands.harts_csr_mem_client; // ---------------- // Facing Platform