mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
improve hart status signalling
This commit is contained in:
parent
7f63daa49c
commit
95df21ff1e
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user