Multicore debug-module
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
// ================================================================
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
// ================================================================
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user