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