Multicore debug-module
This commit is contained in:
@@ -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