Fixed resume-after-break problem (details below).
When controlled from a debugger (build with INCLUDE_GDB_CONTROL macro);
when stopped due a EBREAK instruction; on a 'resume' command ('continue' in GDB),
was getting stuck. This is now working.
At this point, all debugger functionality (almost: see below) is working:
halt, step, breakpoints, resume, read/write gpr/fpr/csr, read/write memory.
Still todo: "NDM reset" (non-debug module reset).
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
|
||||
// Copyright (c) 2017 Massachusetts Institute of Technology
|
||||
// Portions Copyright (c) 2019-2020 Bluespec, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
@@ -189,6 +190,8 @@ deriving (Bits, Eq, FShow);
|
||||
(* synthesize *)
|
||||
module mkCore#(CoreId coreId)(Core);
|
||||
let verbose = False;
|
||||
Integer verbosity = 0; // Bluespec
|
||||
|
||||
Reg#(Bool) outOfReset <- mkReg(False);
|
||||
rule rl_outOfReset if (!outOfReset);
|
||||
$fwrite(stderr, "mkProc came out of reset\n");
|
||||
@@ -267,18 +270,6 @@ module mkCore#(CoreId coreId)(Core);
|
||||
// whether perf data is collected
|
||||
Reg#(Bool) doStatsReg <- mkConfigReg(False);
|
||||
|
||||
// redirect func
|
||||
//function Action redirectFunc(Addr trap_pc, Maybe#(SpecTag) spec_tag, InstTag inst_tag );
|
||||
//action
|
||||
// if (verbose) $fdisplay(stdout, "[redirect_action] new pc = 0x%8x, spec_tag = ", trap_pc, fshow(spec_tag));
|
||||
// epochManager.redirect;
|
||||
// fetchStage.redirect(trap_pc);
|
||||
// if (spec_tag matches tagged Valid .valid_spec_tag) begin
|
||||
// globalSpecUpdate.incorrectSpec(valid_spec_tag, inst_tag);
|
||||
// end
|
||||
//endaction
|
||||
//endfunction
|
||||
|
||||
// write aggressive elements + wakupe reservation stations
|
||||
function Action writeAggr(Integer wrAggrPort, PhyRIndx dst);
|
||||
action
|
||||
@@ -650,7 +641,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
|
||||
rule setDoFlushCaches(flush_caches && fetchStage.emptyForFlush && lsq.noWrongPathLoads);
|
||||
doFlushCaches.send;
|
||||
$display ("%0d: %m.rl_setDoFlushCaches", cur_cycle);
|
||||
// $display ("%0d: %m.rl_setDoFlushCaches", cur_cycle);
|
||||
endrule
|
||||
|
||||
rule setDoFlushBrPred(flush_brpred && fetchStage.emptyForFlush);
|
||||
@@ -663,7 +654,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
flush_caches <= False;
|
||||
iMem.flush;
|
||||
dMem.flush;
|
||||
$display ("%0d: %m.rule flushCaches (imem and dmem)", cur_cycle);
|
||||
// $display ("%0d: %m.rule flushCaches (imem and dmem)", cur_cycle);
|
||||
endrule
|
||||
|
||||
// security flush branch predictors: wait for wrong path inst fetches to
|
||||
@@ -671,7 +662,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
rule flushBrPred(doFlushBrPred);
|
||||
flush_brpred <= False;
|
||||
fetchStage.flush_predictors;
|
||||
$display ("%0d: %m.rule flushBrPred", cur_cycle);
|
||||
// $display ("%0d: %m.rule flushBrPred", cur_cycle);
|
||||
endrule
|
||||
`endif
|
||||
|
||||
@@ -739,31 +730,12 @@ module mkCore#(CoreId coreId)(Core);
|
||||
if (commitStage.is_debug_halted) begin
|
||||
started <= False;
|
||||
rg_core_run_state <= CORE_HALTING;
|
||||
$display ("%0d: %m.rule readyToFetch: halting for debug mode", cur_cycle);
|
||||
if (verbosity >= 1)
|
||||
$display ("%0d: %m.rule readyToFetch: halting for debug mode", cur_cycle);
|
||||
end
|
||||
`endif
|
||||
endrule
|
||||
|
||||
/*
|
||||
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
|
||||
$display (" reconcile_d = %0d", reconcile_d);
|
||||
`endif
|
||||
`endif
|
||||
endrule
|
||||
*/
|
||||
|
||||
`ifdef PERF_COUNT
|
||||
// incr cycle count
|
||||
(* fire_when_enabled, no_implicit_conditions *)
|
||||
@@ -1025,7 +997,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
// ================================================================
|
||||
// DEBUG MODULE INTERFACE
|
||||
|
||||
Bool show_DM_interactions = True; // for debugging the interactions
|
||||
Bool show_DM_interactions = False; // for debugging the interactions
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Debug Module GPR read/write
|
||||
@@ -1166,7 +1138,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
f_csr_rsps.enq (rsp);
|
||||
|
||||
if (show_DM_interactions)
|
||||
$display ("%0d: %m.rl_debug_read_csr: csr %0d => 0x%0h", cur_cycle, csr_addr, data_out);
|
||||
$display ("%0d: %m.rl_debug_read_csr: csr [%0h] => 0x%0h", cur_cycle, csr_addr, data_out);
|
||||
endrule
|
||||
|
||||
rule rl_debug_csr_write ( (rg_core_run_state == CORE_HALTED)
|
||||
@@ -1180,7 +1152,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
f_csr_rsps.enq (rsp);
|
||||
|
||||
if (show_DM_interactions)
|
||||
$display ("%0d: %m.rl_debug_write_csr: csr 0x%0h <= 0x%0h", cur_cycle, csr_addr, data_in);
|
||||
$display ("%0d: %m.rl_debug_write_csr: csr [%0h] <= 0x%0h", cur_cycle, csr_addr, data_in);
|
||||
endrule
|
||||
|
||||
rule rl_debug_csr_access_busy (rg_core_run_state == CORE_RUNNING);
|
||||
@@ -1197,7 +1169,6 @@ module mkCore#(CoreId coreId)(Core);
|
||||
|
||||
FIFOF #(Bool) f_run_halt_reqs <- mkFIFOF;
|
||||
FIFOF #(Bool) f_run_halt_rsps <- mkFIFOF;
|
||||
Reg #(Bool) rg_sent_halt_rsp <- mkReg (False);
|
||||
|
||||
// ----------------
|
||||
// Debug Module Halt control
|
||||
@@ -1209,7 +1180,6 @@ module mkCore#(CoreId coreId)(Core);
|
||||
// Debugger 'halt' request (e.g., GDB '^C' command)
|
||||
// This is initiated just like an interrupt.
|
||||
renameStage.debug_halt_req;
|
||||
rg_sent_halt_rsp <= False;
|
||||
|
||||
if (show_DM_interactions)
|
||||
$display ("%0d: %m.rl_debug_halt_req", cur_cycle);
|
||||
@@ -1219,8 +1189,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
&& (f_run_halt_reqs.first == False));
|
||||
f_run_halt_reqs.deq;
|
||||
|
||||
// Notify debugger that we've 'halted'
|
||||
f_run_halt_rsps.enq (False);
|
||||
// Ignore this.
|
||||
|
||||
if (show_DM_interactions)
|
||||
$display ("%0d: %m.rl_debug_halt_req_already_halted", cur_cycle);
|
||||
@@ -1265,7 +1234,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
f_run_halt_rsps.enq (True);
|
||||
|
||||
if (show_DM_interactions)
|
||||
$display ("%0d: %m.debug_resume, dpc = 0x%0h", cur_cycle, startpc);
|
||||
$display ("%0d: %m.rl_debug_resume, dpc = 0x%0h", cur_cycle, startpc);
|
||||
endrule
|
||||
|
||||
// Run command when already running
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package Proc;
|
||||
|
||||
// Copyright (c) 2018 Massachusetts Institute of Technology
|
||||
// Portions Copyright (c) 2019-2020 Bluespec, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
// Copyright (c) 2017 Massachusetts Institute of Technology
|
||||
// Portions Copyright (c) 2019-2020 Bluespec, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
@@ -146,8 +147,7 @@ deriving (Eq, FShow, Bits);
|
||||
module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
Bool verbose = False;
|
||||
|
||||
// Bluespec: for lightweight verbosity trace
|
||||
Integer verbosity = 1;
|
||||
Integer verbosity = 1; // Bluespec: for lightweight verbosity trace
|
||||
Reg #(Bit #(64)) rg_instret <- mkReg (0);
|
||||
|
||||
|
||||
@@ -437,7 +437,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
});
|
||||
commitTrap <= commitTrap_val;
|
||||
|
||||
if (verbosity > 0) begin
|
||||
if (verbosity >= 1) begin
|
||||
$display ("instret:%0d PC:0x%0h instr:0x%08h", rg_instret, x.pc, x.orig_inst,
|
||||
" iType:", fshow (x.iType), " [doCommitTrap]");
|
||||
end
|
||||
@@ -487,6 +487,11 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
if(trap.trap matches tagged Interrupt .inter) begin
|
||||
inIfc.commitCsrInstOrInterrupt;
|
||||
end
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
else if (trap.trap == tagged Exception Breakpoint) begin
|
||||
inIfc.commitCsrInstOrInterrupt;
|
||||
end
|
||||
`endif
|
||||
|
||||
Bool debugger_halt = False;
|
||||
|
||||
@@ -518,7 +523,8 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
// Go to quiescent state until debugger resumes execution
|
||||
rg_run_state <= RUN_STATE_DEBUGGER_HALTED;
|
||||
|
||||
$display ("%0d: %m.commitStage.doCommitTrap_handle; debugger halt:", cur_cycle);
|
||||
if (verbosity >= 2)
|
||||
$display ("%0d: %m.commitStage.doCommitTrap_handle; debugger halt:", cur_cycle);
|
||||
end
|
||||
`endif
|
||||
|
||||
@@ -587,7 +593,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
rob.deqPort[0].deq;
|
||||
let x = rob.deqPort[0].deq_data;
|
||||
if(verbose) $display("[doCommitSystemInst] ", fshow(x));
|
||||
if (verbosity > 0) begin
|
||||
if (verbosity >= 1) begin
|
||||
$display("instret:%0d PC:0x%0h instr:0x%08h", rg_instret, x.pc, x.orig_inst,
|
||||
" iType:", fshow (x.iType), " [doCommitSystemInst]");
|
||||
rg_instret <= rg_instret + 1;
|
||||
@@ -752,7 +758,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
else begin
|
||||
if (verbose) $display("[doCommitNormalInst - %d] ", i, fshow(inst_tag), " ; ", fshow(x));
|
||||
|
||||
if (verbosity > 0) begin
|
||||
if (verbosity >= 1) begin
|
||||
$display("instret:%0d PC:0x%0h instr:0x%08h", rg_instret + instret, x.pc, x.orig_inst,
|
||||
" iType:", fshow (x.iType), " [doCommitNormalInst [%0d]]", i);
|
||||
instret = instret + 1;
|
||||
@@ -912,7 +918,8 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
|
||||
method Action debug_resume () if (rg_run_state == RUN_STATE_DEBUGGER_HALTED);
|
||||
rg_run_state <= RUN_STATE_RUNNING;
|
||||
$display ("%0d: %m.commitStage.debug_resume", cur_cycle);
|
||||
if (verbosity >= 2)
|
||||
$display ("%0d: %m.commitStage.debug_resume", cur_cycle);
|
||||
endmethod
|
||||
`endif
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
// Copyright (c) 2017 Massachusetts Institute of Technology
|
||||
// Portions Copyright (c) 2019-2020 Bluespec, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
@@ -572,7 +573,7 @@ module mkFetchStage(FetchStage);
|
||||
main_epoch: in.main_epoch };
|
||||
f22f3.enq(tuple2(nbSupX2,out));
|
||||
|
||||
if (verbosity > 0) begin
|
||||
if (verbosity >= 2) begin
|
||||
$display ("----------------");
|
||||
$display ("Fetch2: TLB response pyhs_pc 0x%0h cause ", phys_pc, fshow (cause));
|
||||
$display ("Fetch2: f2_tof3.enq: nbSupX2 %0d out ", nbSupX2, fshow (out));
|
||||
@@ -582,7 +583,7 @@ module mkFetchStage(FetchStage);
|
||||
// Break out of i$
|
||||
rule doFetch3;
|
||||
let {nbSupX2In, fetch3In} = f22f3.first;
|
||||
if (verbosity > 0) begin
|
||||
if (verbosity >= 2) begin
|
||||
if (f22f3.notEmpty)
|
||||
$display("Fetch3: nbSupX2In: %0d fetch3In: ", nbSupX2In, fshow (fetch3In));
|
||||
else
|
||||
@@ -599,7 +600,7 @@ module mkFetchStage(FetchStage);
|
||||
// associated with the same epoch.
|
||||
pending_n_items = 0;
|
||||
pending_straddle = tagged Invalid;
|
||||
if (verbosity > 0) begin
|
||||
if (verbosity >= 2) begin
|
||||
$display ("----------------");
|
||||
$display ("Fetch3: Drop pending: main_epoch: %d decode epoch: %d", f_main_epoch, decode_epoch[1]);
|
||||
$display ("Fetch3: rg_pending_n_items: ", fshow (rg_pending_n_items));
|
||||
@@ -656,7 +657,7 @@ module mkFetchStage(FetchStage);
|
||||
if (fetch3In.main_epoch != f_main_epoch || fetch3In.decode_epoch != decode_epoch[1]) begin
|
||||
pending_straddle = tagged Invalid;
|
||||
end
|
||||
if (verbosity > 0) begin
|
||||
if (verbosity >= 2) begin
|
||||
$display ("----------------");
|
||||
$display ("Fetch3: Drop: main_epoch: %d decode epoch: %d fetch3 epoch %d", f_main_epoch, decode_epoch[1], fetch3_epoch);
|
||||
$display ("Fetch3: f22f3.first: ", fshow (f22f3.first));
|
||||
@@ -749,7 +750,7 @@ module mkFetchStage(FetchStage);
|
||||
if (n_items > 0) begin
|
||||
instdata.enq(take(v_items));
|
||||
f32d.enq(tuple2(nbSupOut, out));
|
||||
if (verbosity > 0) begin
|
||||
if (verbosity >= 2) begin
|
||||
$display ("----------------");
|
||||
$display ("Fetch3: epoch inst: %d, epoch main : %d", out.main_epoch, f_main_epoch);
|
||||
$display ("Fetch3: inst_d: ", fshow (inst_d));
|
||||
@@ -915,8 +916,13 @@ module mkFetchStage(FetchStage);
|
||||
cause: cause,
|
||||
tval: tval};
|
||||
out_fifo.enqS[i].enq(out);
|
||||
if (verbosity > 0)
|
||||
$display("Decode: ", fshow(out));
|
||||
if (verbosity >= 1) begin
|
||||
$write ("%0d: %m.rule doDecode: out_fifo.enqS[%0d].enq", cur_cycle, i);
|
||||
$display (" pc %0h inst %08h", out.pc, out.orig_inst);
|
||||
end
|
||||
if (verbosity >= 2) begin
|
||||
$display (" ", fshow(out));
|
||||
end
|
||||
end // if (in.decode_epoch == decode_epoch_local)
|
||||
else begin
|
||||
if (verbose) $display("Drop decoded within a superscalar");
|
||||
@@ -1018,7 +1024,7 @@ module mkFetchStage(FetchStage);
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
method Action setWaitFlush;
|
||||
waitForFlush <= True;
|
||||
$display ("%0d.%m.FetchStage.setWaitFlush", cur_cycle);
|
||||
// $display ("%0d.%m.setWaitFlush", cur_cycle);
|
||||
endmethod
|
||||
`endif
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
// Copyright (c) 2017 Massachusetts Institute of Technology
|
||||
// Portions Copyright (c) 2019-2020 Bluespec, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
@@ -97,6 +98,7 @@ endinterface
|
||||
|
||||
module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
Bool verbose = False;
|
||||
Integer verbosity = 0;
|
||||
|
||||
// func units
|
||||
FetchStage fetchStage = inIfc.fetchIfc;
|
||||
@@ -174,7 +176,8 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
action
|
||||
if (csrf.dcsr_step_bit == 1'b1) begin
|
||||
rg_m_halt_req <= tagged Valid DebugStep;
|
||||
$display ("%0d: %m.renameStage.fa_step_check: rg_m_halt_req <= tagged Valid DebugStep", cur_cycle);
|
||||
if (verbosity >= 2)
|
||||
$display ("%0d: %m.renameStage.fa_step_check: rg_m_halt_req <= tagged Valid DebugStep", cur_cycle);
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
@@ -313,10 +316,14 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
fa_step_check;
|
||||
|
||||
if (firstTrap == tagged Valid (tagged Interrupt DebugHalt))
|
||||
$display ("%0d: %m.renameStage.doRenaming_Trap: DebugHalt", cur_cycle);
|
||||
else if (firstTrap == tagged Valid (tagged Interrupt DebugStep))
|
||||
$display ("%0d: %m.renameStage.doRenaming_Trap: DebugStep", cur_cycle);
|
||||
if (verbosity >= 1) begin
|
||||
if (firstTrap == tagged Valid (tagged Interrupt DebugHalt))
|
||||
$display ("%0d: %m.renameStage.doRenaming_Trap: DebugHalt", cur_cycle);
|
||||
else if (firstTrap == tagged Valid (tagged Interrupt DebugStep))
|
||||
$display ("%0d: %m.renameStage.doRenaming_Trap: DebugStep", cur_cycle);
|
||||
else if (firstTrap == tagged Valid (tagged Exception Breakpoint))
|
||||
$display ("%0d: %m.renameStage.doRenaming_Trap: Breakpoint", cur_cycle);
|
||||
end
|
||||
`endif
|
||||
let x = fetchStage.pipelines[0].first;
|
||||
let pc = x.pc;
|
||||
@@ -364,6 +371,12 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
if(firstTrap matches tagged Valid (tagged Interrupt .i)) begin
|
||||
inIfc.issueCsrInstOrInterrupt;
|
||||
end
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
else if (firstTrap == tagged Valid (tagged Exception Breakpoint)) begin
|
||||
inIfc.issueCsrInstOrInterrupt;
|
||||
end
|
||||
`endif
|
||||
|
||||
`ifdef CHECK_DEADLOCK
|
||||
renameCorrectPath.send;
|
||||
`endif
|
||||
@@ -1107,12 +1120,14 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
method Action debug_halt_req () if (rg_m_halt_req == tagged Invalid);
|
||||
rg_m_halt_req <= tagged Valid DebugHalt;
|
||||
$display ("%0d: %m.renameStage.renameStage.debug_halt_req", cur_cycle);
|
||||
if (verbosity >= 1)
|
||||
$display ("%0d: %m.renameStage.renameStage.debug_halt_req", cur_cycle);
|
||||
endmethod
|
||||
|
||||
method Action debug_resume () if (rg_m_halt_req != tagged Invalid);
|
||||
method Action debug_resume;
|
||||
rg_m_halt_req <= tagged Invalid;
|
||||
$display ("%0d: %m.renameStage.renameStage.debug_resume", cur_cycle);
|
||||
if (verbosity >= 1)
|
||||
$display ("%0d: %m.renameStage.renameStage.debug_resume", cur_cycle);
|
||||
endmethod
|
||||
`endif
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
// Copyright (c) 2017 Massachusetts Institute of Technology
|
||||
// Portions Copyright (c) 2019-2020 Bluespec, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
||||
@@ -8,10 +8,8 @@
|
||||
// connected to the AXI4_Master of the Debug Module.
|
||||
// This axi4_slave accepts and responds to both read and write transactions.
|
||||
|
||||
// Modifications Copyright (c) 2020 Bluespec, Inc.
|
||||
|
||||
// Original copyright:
|
||||
// Copyright (c) 2017 Massachusetts Institute of Technology
|
||||
// Portions Copyright (c) 2019-2020 Bluespec, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
|
||||
Reference in New Issue
Block a user