mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-23 05:37:16 -04:00
Support for halting and couple of debug regs
This commit is contained in:
parent
cfc1ec086f
commit
1024523a72
2 changed files with 144 additions and 8 deletions
|
@ -154,5 +154,9 @@ module commit_stage (
|
|||
exception_o = csr_exception_i;
|
||||
exception_o.tval = commit_instr_i.ex.tval;
|
||||
end
|
||||
// If we halted the processor don't take any exceptions
|
||||
if (halt_i) begin
|
||||
exception_o.valid = 1'b0;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
|
@ -20,12 +20,13 @@
|
|||
import ariane_pkg::*;
|
||||
|
||||
module debug_unit (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
|
||||
input logic [63:0] commit_pc_i,
|
||||
input scoreboard_entry commit_instr_i,
|
||||
input logic commit_ack_i,
|
||||
|
||||
input exception ex_i, // instruction caused an exception
|
||||
output logic halt_o, // halt the hart
|
||||
// External Debug Interface
|
||||
input logic debug_req_i,
|
||||
output logic debug_gnt_o,
|
||||
|
@ -39,6 +40,31 @@ module debug_unit (
|
|||
input logic debug_resume_i
|
||||
|
||||
);
|
||||
// select debug register source/destination
|
||||
enum logic [2:0] {RD_NONE, RD_CSR, RD_GPR, RD_DBGA, RD_DBGS} rdata_sel_q, rdata_sel_n;
|
||||
|
||||
enum logic [1:0] {RUNNING, HALT_REQ, SINGLE_STEP, HALTED} CS, NS;
|
||||
|
||||
// debug interface registers, we need to give the read data back one cycle later along with the rvalid flag
|
||||
logic rvalid_n, rvalid_q;
|
||||
logic rdata_n, rdata_q;
|
||||
// save previous PC
|
||||
logic ppc_n, ppc_q;
|
||||
// ---------------
|
||||
// Debug Register
|
||||
// ---------------
|
||||
// enable exceptions which will cause a transfer to the debug mode
|
||||
logic [63:0] dbg_ie_n, dbg_ie_q;
|
||||
// cause register which caused transfer to debug mode
|
||||
logic [63:0] dbg_cause_n, dbg_cause_q;
|
||||
|
||||
// change debug mode
|
||||
logic halt_req, resume_req;
|
||||
logic ss_req, ss_resume_req; // request single step and resume execution from single step
|
||||
|
||||
assign debug_rvalid_o = rvalid_q;
|
||||
assign debug_rdata_o = rdata_q;
|
||||
|
||||
|
||||
// | Address | Name | Description |
|
||||
// |---------------|-----------------|---------------------------------------------------------------------|
|
||||
|
@ -49,20 +75,64 @@ module debug_unit (
|
|||
// | 0x4000-0x7FFF | CSR | Control and Status Registers. Only accessible if the core is halted |
|
||||
|
||||
always_comb begin : debug_ctrl
|
||||
rdata_sel_n = RD_NONE;
|
||||
|
||||
debug_gnt_o = 1'b0;
|
||||
rdata_n = 'b0;
|
||||
rvalid_n = 1'b0;
|
||||
|
||||
halt_req = 1'b0;
|
||||
ss_req = 1'b0;
|
||||
ss_resume_req = 1'b0;
|
||||
// update the previous PC if got a valid commit
|
||||
ppc_n = (commit_ack_i) ? commit_instr_i.pc : ppc_q;
|
||||
// debug registers
|
||||
dbg_ie_n = dbg_ie_q;
|
||||
dbg_cause_n = dbg_cause_q;
|
||||
|
||||
// ----------
|
||||
// Read
|
||||
// ----------
|
||||
// we've got a new read request
|
||||
if (debug_req_i && !debug_we_i) begin
|
||||
|
||||
|
||||
// we can immediately grant the request
|
||||
debug_gnt_o = 1'b1;
|
||||
// decode debug address
|
||||
case (debug_addr_i)
|
||||
DBG_CTRL: rdata_n = {32'b0, 15'b0, (CS == HALTED), 15'b0, (CS == SINGLE_STEP)};
|
||||
DBG_HIT: rdata_n = {63'b0, sshit};
|
||||
DBG_IE: rdata_n = dbg_ie_q;
|
||||
DBG_CAUSE: rdata_n = dbg_cause_q;
|
||||
DBG_NPC: rdata_n = commit_instr_i.pc;
|
||||
DBG_PPC: rdata_n = ppc_q;
|
||||
endcase
|
||||
// ----------
|
||||
// Write
|
||||
// ----------
|
||||
end else if (debug_req_i) begin
|
||||
// we can also immediately grant
|
||||
debug_gnt_o = 1'b1;
|
||||
// decode debug address
|
||||
case (debug_addr_i)
|
||||
DBG_CTRL: begin
|
||||
// check if requested a halt
|
||||
halt_req = debug_wdata_i[16];
|
||||
resume_req = ~debug_wdata_i[16];
|
||||
// enable/disable single step
|
||||
ss_req = debug_wdata_i[0];
|
||||
ss_resume_req = ~debug_wdata_i[0];
|
||||
DBG_HIT:
|
||||
DBG_IE: dbg_ie_n = debug_wdata_i;
|
||||
DBG_CAUSE: dbg_cause_n = debug_wdata_i;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// if an exception occurred and it is enabled to trigger debug mode, halt the processor
|
||||
if (ex_i.valid && (|(ex_i.cause & dbg_ie_q)) == 1'b1) begin
|
||||
halt_req = 1'b1;
|
||||
// save the cause why we entered the exception
|
||||
dbg_cause_n = ex_i.cause;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -70,4 +140,66 @@ module debug_unit (
|
|||
// HW Breakpoints
|
||||
// --------------------
|
||||
|
||||
endmodule
|
||||
// --------------------
|
||||
// Stall Control
|
||||
// --------------------
|
||||
always_comb begin
|
||||
NS = CS;
|
||||
// do not halt by default
|
||||
halt_o = 1'b0;
|
||||
case (CS)
|
||||
// CPU is running normally
|
||||
RUNNING: begin
|
||||
// external debugger requested to halt the CPU
|
||||
if (halt_req) begin
|
||||
NS = HALT_REQ;
|
||||
end
|
||||
|
||||
end
|
||||
// a halt was requested, we wait here until we get the next valid instruction
|
||||
// in order to properly populate the npc and ppc counters
|
||||
HALT_REQ: begin
|
||||
// we've got a valid instruction in the commit stage so we can proceed to the halted state
|
||||
if (commit_instr_i.valid) begin
|
||||
NS = HALTED;
|
||||
end
|
||||
end
|
||||
// we are in single step mode
|
||||
SINGLE_STEP: begin
|
||||
// resume from single steps
|
||||
if (ss_resume_req) begin
|
||||
NS = RUNNING;
|
||||
end
|
||||
end
|
||||
|
||||
// CPU is halted, we are in debug mode
|
||||
HALTED: begin
|
||||
halt_o = 1'b1;
|
||||
if (resume_req)
|
||||
NS = RUNNING;
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
// --------------------
|
||||
// Registers
|
||||
// --------------------
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (~rst_ni) begin
|
||||
CS <= RUNNING;
|
||||
rdata_q <= '0;
|
||||
rvalid_q <= 1'b0;
|
||||
ppc_q <= 64'b0;
|
||||
dbg_ie_q <= 64'b0;
|
||||
dbg_cause_q <= 64'b0;
|
||||
end else begin
|
||||
CS <= NS;
|
||||
rdata_q <= rdata_n;
|
||||
rvalid_q <= rvalid_n;
|
||||
ppc_q <= ppc_n;
|
||||
dbg_ie_q <= dbg_ie_n;
|
||||
dbg_cause_q <= dbg_cause_n;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue