From 95df21ff1e99fa72dde703d7c5ed1ba62a2d475b Mon Sep 17 00:00:00 2001 From: Matthew <106996253+Matthew-Otto@users.noreply.github.com> Date: Sun, 9 Jun 2024 11:26:58 -0500 Subject: [PATCH] improve hart status signalling --- src/debug/dm.sv | 38 +++++++++++++++++++++++--------------- src/debug/dtm.sv | 16 ++++++++-------- src/debug/hartcontrol.sv | 39 ++++++++++++++++++++++++++++++++------- 3 files changed, 63 insertions(+), 30 deletions(-) diff --git a/src/debug/dm.sv b/src/debug/dm.sv index 9b8560217..60a83f496 100644 --- a/src/debug/dm.sv +++ b/src/debug/dm.sv @@ -81,14 +81,15 @@ module dm import cvw::*; #(parameter cvw_t P) ( .RspValid, .RspData, .RspOP); // Core control signals - logic HaltReq; - logic ResumeReq; - logic HaltOnReset; - logic Halted; + logic HaltReq; + logic ResumeReq; + logic HaltOnReset; + logic Halted; + logic AckHaveReset; - hartcontrol hartcontrol(.clk, .rst(rst | ~DmActive), .NdmReset, .HaltReq, - .ResumeReq, .HaltOnReset, .DebugStall, .Halted, .AllRunning, - .AnyRunning, .AllHalted, .AnyHalted, .AllResumeAck, .AnyResumeAck); + hartcontrol hartcontrol(.clk, .rst(rst | ~DmActive), .NdmReset, .AckHaveReset, .HaltReq, + .ResumeReq, .HaltOnReset, .DebugStall, .Halted, .AllRunning, .AnyRunning, + .AllHalted, .AnyHalted, .AllResumeAck, .AnyResumeAck, .AllHaveReset, .AnyHaveReset); enum logic [3:0] {INACTIVE, IDLE, ACK, R_DATA, W_DATA, DMSTATUS, W_DMCONTROL, R_DMCONTROL, @@ -137,9 +138,11 @@ module dm import cvw::*; #(parameter cvw_t P) ( // DMStatus logic StickyUnavail; logic ImpEBreak; + logic AllHaveReset; + logic AnyHaveReset; logic AllResumeAck; logic AnyResumeAck; - logic AllNonExistent; + logic AllNonExistent; // TODO logic AnyNonExistent; logic AllUnavail; // TODO logic AnyUnavail; @@ -164,7 +167,7 @@ module dm import cvw::*; #(parameter cvw_t P) ( 10'b0, 4'b0, NdmReset, DmActive}; assign DMStatus = {7'b0, 1'b0, StickyUnavail, ImpEBreak, 2'b0, - 2'b0, AllResumeAck, AnyResumeAck, AllNonExistent, + AllHaveReset, AnyHaveReset, AllResumeAck, AnyResumeAck, AllNonExistent, AnyNonExistent, AllUnavail, AnyUnavail, AllRunning, AnyRunning, AllHalted, AnyHalted, Authenticated, AuthBusy, HasResetHaltReq, ConfStrPtrValid, Version}; @@ -183,8 +186,11 @@ module dm import cvw::*; #(parameter cvw_t P) ( case (State) INACTIVE : begin // Reset Values + // TODO: one-line these RspData <= 0; HaltReq <= 0; + ResumeReq <= 0; + AckHaveReset <= 0; HaltOnReset <= 0; NdmReset <= 0; StickyUnavail <= 0; @@ -204,6 +210,7 @@ module dm import cvw::*; #(parameter cvw_t P) ( ACK : begin NewAcState <= AC_IDLE; ResumeReq <= 0; + AckHaveReset <= 0; if (~ReqValid) State <= ~DmActive ? INACTIVE : IDLE; end @@ -256,7 +263,7 @@ module dm import cvw::*; #(parameter cvw_t P) ( W_DMCONTROL : begin // While an abstract command is executing (busy in abstractcs is high), a debugger must not change // hartsel, and must not write 1 to haltreq, resumereq, ackhavereset, setresethaltreq, or clrresethaltreq - if (Busy & (ReqData[`HALTREQ] | ReqData[`RESUMEREQ] | ReqData[`SETRESETHALTREQ] | ReqData[`CLRRESETHALTREQ])) + if (Busy & (ReqData[`HALTREQ] | ReqData[`RESUMEREQ] | ReqData[`ACKHAVERESET] | ReqData[`SETRESETHALTREQ] | ReqData[`CLRRESETHALTREQ])) CmdErr <= ~|CmdErr ? `CMDERR_BUSY : CmdErr; else begin HaltReq <= ReqData[`HALTREQ]; @@ -266,11 +273,12 @@ module dm import cvw::*; #(parameter cvw_t P) ( // On any given write, a debugger may only write 1 to at most one of the following bits: resumereq, // hartreset, ackhavereset, setresethaltreq, and clrresethaltreq. The others must be written 0 - case ({ReqData[`RESUMEREQ],ReqData[`SETRESETHALTREQ],ReqData[`CLRRESETHALTREQ]}) - 3'b000 :; // None - 3'b100 : ResumeReq <= 1; - 3'b010 : HaltOnReset <= 1; - 3'b001 : HaltOnReset <= 0; + case ({ReqData[`RESUMEREQ],ReqData[`ACKHAVERESET],ReqData[`SETRESETHALTREQ],ReqData[`CLRRESETHALTREQ]}) + 4'b0000 :; // None + 4'b1000 : ResumeReq <= 1; + 4'b0100 : AckHaveReset <= 1; + 4'b0010 : HaltOnReset <= 1; + 4'b0001 : HaltOnReset <= 0; default : begin // Invalid (not onehot), dont write any changes HaltReq <= HaltReq; AckUnavail <= AckUnavail; diff --git a/src/debug/dtm.sv b/src/debug/dtm.sv index b3a7a36e8..16e8fd96b 100644 --- a/src/debug/dtm.sv +++ b/src/debug/dtm.sv @@ -55,7 +55,7 @@ module dtm #(parameter ADDR_WIDTH, parameter JTAG_DEVICE_ID) ( // Clock Domain Crossing logic tcks; // Synchronized JTAG clock - logic resetn; + logic resetn; // TODO: reset DM (but not hart) logic UpdateDtmcs; logic [31:0] DtmcsIn; logic [31:0] DtmcsOut; @@ -65,13 +65,13 @@ module dtm #(parameter ADDR_WIDTH, parameter JTAG_DEVICE_ID) ( logic [34+ADDR_WIDTH-1:0] DmiOut; // DTMCS Register - const logic [2:0] ErrInfo = 0; - logic DtmHardReset; - logic DmiReset; - const logic [2:0] Idle = 0; - logic [1:0] DmiStat; - const logic [5:0] ABits = ADDR_WIDTH; - const logic [3:0] Version = 1; // DTM spec version 1 + const logic [2:0] ErrInfo = 0; + logic DtmHardReset; + logic DmiReset; + const logic [2:0] Idle = 0; + logic [1:0] DmiStat; + const logic [5:0] ABits = ADDR_WIDTH; + const logic [3:0] Version = 1; // DTM spec version 1 logic [31:0] ValRspData; logic [1:0] ValRspOP; diff --git a/src/debug/hartcontrol.sv b/src/debug/hartcontrol.sv index 5080eb2be..9a00fd9cc 100644 --- a/src/debug/hartcontrol.sv +++ b/src/debug/hartcontrol.sv @@ -30,6 +30,7 @@ module hartcontrol( input logic clk, rst, input logic NdmReset, // Triggers HaltOnReset behavior + input logic AckHaveReset, // Clears *HaveReset status input logic HaltReq, // Initiate core halt input logic ResumeReq, // Initiates core resume @@ -44,18 +45,31 @@ module hartcontrol( output logic AllHalted, output logic AnyHalted, output logic AllResumeAck, - output logic AnyResumeAck + output logic AnyResumeAck, + output logic AllHaveReset, + output logic AnyHaveReset ); + enum logic {RUNNING, HALTED} State; + + assign AnyHaveReset = AllHaveReset; + + always_ff @(posedge clk) begin + if (NdmReset) + AllHaveReset <= 1; + else if (AckHaveReset) + AllHaveReset <= 0; + end + assign Halted = DebugStall; assign AllRunning = ~DebugStall; assign AnyRunning = ~DebugStall; assign AllHalted = DebugStall; assign AnyHalted = DebugStall; - assign AllResumeAck = ~DebugStall; - assign AnyResumeAck = ~DebugStall; - - enum logic {RUNNING, HALTED} State; + // BOZO: when sdext is implemented (proper step support is added) + // change ResumeReq to be ignored when HaltReq + // but ResumeReq should still always clear *ResumeAck + assign AnyResumeAck = AllResumeAck; assign DebugStall = (State == HALTED); @@ -66,9 +80,20 @@ module hartcontrol( State <= HaltOnReset ? HALTED : RUNNING; else begin case (State) - RUNNING : State <= HaltReq ? HALTED : RUNNING; + RUNNING : begin + if (HaltReq) begin + State <= HALTED; + end else if (ResumeReq) begin + AllResumeAck <= 0; + end + end - HALTED : State <= ResumeReq ? RUNNING : HALTED; + HALTED : begin + if (ResumeReq) begin + State <= RUNNING; + AllResumeAck <= 1; + end + end endcase end end