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:
rsnikhil
2020-01-17 20:08:04 -05:00
parent 977e3c92cd
commit fa5e141550
25 changed files with 18592 additions and 18656 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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