Fix step timing, rewrite jtag to include explicit reset

This commit is contained in:
Matthew 2024-06-17 10:51:22 -05:00
parent 7dd0182407
commit 5c593c3321
7 changed files with 152 additions and 167 deletions

View File

@ -42,10 +42,8 @@ def prog_buff_test(cvw):
print()
def flow_control_test():
with OpenOCD() as cvw:
cvw.reset_dm()
cvw.reset_hart()
def flow_control_test(cvw):
#time.sleep(70) # wait for OpenSBI
cvw.halt()
cvw.read_data("DCSR")
@ -55,8 +53,7 @@ def flow_control_test():
cvw.resume()
def register_rw_test():
with OpenOCD() as cvw:
def register_rw_test(cvw):
registers = dict.fromkeys(cvw.register_translations.keys(),[])
reg_addrs = list(registers.keys())
@ -65,9 +62,6 @@ def register_rw_test():
global nonstandard_register_lengths
nonstandard_register_lengths = cvw.nonstandard_register_lengths
cvw.reset_dm()
cvw.reset_hart()
#time.sleep(70) # wait for OpenSBI
cvw.halt()
@ -160,8 +154,11 @@ def random_hex(reg_name):
with OpenOCD() as cvw:
print(cvw.read_dmi("0x16"))
cvw.trst()
cvw.reset_dm()
cvw.reset_hart()
#register_rw_test()
#flow_control_test()
prog_buff_test(cvw)
quit()
#register_rw_test(cvw)
flow_control_test(cvw)
#prog_buff_test(cvw)

View File

@ -98,7 +98,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
// [0] = 1
localparam JTAG_DEVICE_ID = 32'h1002AC05;
dtm #(`ADDR_WIDTH, JTAG_DEVICE_ID) dtm (.clk, .tck, .tdi, .tms, .tdo,
dtm #(`ADDR_WIDTH, JTAG_DEVICE_ID) dtm (.clk, .rst, .tck, .tdi, .tms, .tdo,
.ReqReady, .ReqValid, .ReqAddress, .ReqData, .ReqOP, .RspReady,
.RspValid, .RspData, .RspOP);
@ -253,7 +253,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
{2'bx,`HARTINFO},
{2'bx,`ABSTRACTAUTO},
{2'bx,`NEXTDM} : State <= READ_ZERO;
default : State <= INVALID;
default : State <= READ_ZERO;//INVALID;
endcase
end
@ -388,7 +388,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
end
INVALID : begin
RspOP <= `OP_FAILED;
RspOP <= `OP_SUCCESS;//`OP_FAILED;
State <= ACK;
end
endcase

View File

@ -65,7 +65,7 @@ module dmc (
assign DebugMode = (State != RUNNING);
assign DebugStall = (State == HALTED);
assign EnterDebugMode = (State == FLUSH) & (Counter == 0);
assign EnterDebugMode = (State == FLUSH) & ~|Counter;
assign ExitDebugMode = (State == HALTED) & ResumeReq;
assign ForceNOP = (State == FLUSH);
@ -77,7 +77,7 @@ module dmc (
case (State)
RUNNING : begin
if (HaltReq) begin
Counter <= 0;
Counter <= NOP_CYCLE_DURATION;
State <= FLUSH;
DebugCause <= `CAUSE_HALTREQ;
end
@ -87,20 +87,16 @@ module dmc (
// fill the pipe with NOP before halting
FLUSH : begin
if (Counter == NOP_CYCLE_DURATION)
if (~|Counter)
State <= HALTED;
else
Counter <= Counter + 1;
Counter <= Counter - 1;
end
HALTED : begin
if (ResumeReq)
State <= RESUME;
end
RESUME : begin
if (ResumeReq) begin
if (Step) begin
Counter <= 0;
Counter <= NOP_CYCLE_DURATION;
State <= FLUSH;
DebugCause <= `CAUSE_STEP;
end else begin
@ -108,6 +104,7 @@ module dmc (
ResumeAck <= 1;
end
end
end
endcase
end
end

View File

@ -31,7 +31,7 @@
module dtm #(parameter ADDR_WIDTH, parameter JTAG_DEVICE_ID) (
// System clock
input logic clk,
input logic clk, rst,
// External JTAG signals
input logic tck,
input logic tdi,
@ -90,7 +90,7 @@ module dtm #(parameter ADDR_WIDTH, parameter JTAG_DEVICE_ID) (
// DTMCS
assign DtmcsOut = {11'b0, ErrInfo, 3'b0, Idle, DmiStat, ABits, Version};
always_ff @(posedge clk) begin
if (~resetn | DtmHardReset) begin
if (rst | ~resetn | DtmHardReset) begin
DtmHardReset <= 0;
DmiReset <= 0;
end else if (UpdateDtmcs) begin
@ -103,7 +103,7 @@ module dtm #(parameter ADDR_WIDTH, parameter JTAG_DEVICE_ID) (
// DMI
always_ff @(posedge clk) begin
if (~resetn | DtmHardReset) begin
if (rst | ~resetn | DtmHardReset) begin
ValRspData <= 0;
ValRspOP <= `OP_SUCCESS;
//ErrInfo <= 4;

View File

@ -48,15 +48,10 @@ module ir (
assign tdo = shift_reg[0];
// Shift register
always @(posedge clockIR) begin
shift_reg[0] <= shift_reg[1] | captureIR;
end
flop #(1) shift_regmsb (.clk(clockIR), .d(shift_reg[1] | captureIR), .q(shift_reg[0]));
genvar i;
for (i = INST_REG_WIDTH; i > 1; i = i - 1) begin
always @(posedge clockIR) begin
shift_reg[i-1] <= shift_reg[i] & ~captureIR;
end
end
for (i = INST_REG_WIDTH; i > 1; i = i - 1)
flop #(1) shift_reg (.clk(clockIR), .d(shift_reg[i] & ~captureIR), .q(shift_reg[i-1]));
// Instruction decoder
// 6.1.2

View File

@ -26,6 +26,7 @@
////////////////////////////////////////////////////////////////////////////////////////////////
module jtag #(parameter ADDR_WIDTH, parameter DEVICE_ID) (
input logic rst,
// JTAG signals
input logic tck,
input logic tdi,
@ -79,7 +80,7 @@ module jtag #(parameter ADDR_WIDTH, parameter DEVICE_ID) (
assign CaptureDmi = captureDR & DmiInstr;
assign UpdateDmi = updateDR & DmiInstr;
tap tap (.tck, .tms, .resetn, .tdo_en, .captureIR,
tap tap (.rst, .tck, .tms, .resetn, .tdo_en, .captureIR,
.clockIR, .updateIR, .shiftDR, .captureDR, .clockDR, .updateDR, .select);
// IR/DR input demux
@ -103,34 +104,23 @@ module jtag #(parameter ADDR_WIDTH, parameter DEVICE_ID) (
endcase
end
always_ff @(posedge UpdateDtmcs)
DtmcsIn <= DtmcsShiftReg[31:0];
always_ff @(posedge UpdateDmi)
DmiIn <= DmiShiftReg[34+ADDR_WIDTH-1:0];
flopr #(32) dtmcsreg (.clk(UpdateDtmcs), .reset(rst), .d(DtmcsShiftReg[31:0]), .q(DtmcsIn));
flopr #(34+ADDR_WIDTH) dmireg (.clk(UpdateDmi), .reset(rst), .d(DmiShiftReg[34+ADDR_WIDTH-1:0]), .q(DmiIn));
assign DtmcsShiftReg[32] = tdi_dr;
assign tdo_dtmcs = DtmcsShiftReg[0];
for (i = 0; i < 32; i = i + 1) begin
always_ff @(posedge clockDR) begin
DtmcsShiftReg[i] <= captureDR ? DtmcsOut[i] : DtmcsShiftReg[i+1];
end
end
for (i = 0; i < 32; i = i + 1)
flopr #(1) dtmcsshiftreg (.clk(clockDR), .reset(rst), .d(captureDR ? DtmcsOut[i] : DtmcsShiftReg[i+1]), .q(DtmcsShiftReg[i]));
assign DmiShiftReg[34+ADDR_WIDTH] = tdi_dr;
assign tdo_dmi = DmiShiftReg[0];
for (i = 0; i < 34+ADDR_WIDTH; i = i + 1) begin
always_ff @(posedge clockDR) begin
DmiShiftReg[i] <= captureDR ? DmiOut[i] : DmiShiftReg[i+1];
end
end
for (i = 0; i < 34+ADDR_WIDTH; i = i + 1)
flopr #(1) dmishiftreg (.clk(clockDR), .reset(rst), .d(captureDR ? DmiOut[i] : DmiShiftReg[i+1]), .q(DmiShiftReg[i]));
// jtag id register
idreg #(DEVICE_ID) id (.tdi(tdi_dr), .clockDR, .captureDR, .tdo(tdo_idcode));
// bypass register
always_ff @(posedge clockDR) begin
tdo_bypass <= tdi_dr & shiftDR;
end
flopr #(1) bypassreg (.clk(clockDR), .reset(rst), .d(tdi_dr & shiftDR), .q(tdo_bypass));
endmodule

View File

@ -26,6 +26,7 @@
////////////////////////////////////////////////////////////////////////////////////////////////
module tap (
input logic rst,
input logic tck,
input logic tms,
output logic resetn,
@ -40,6 +41,8 @@ module tap (
output logic select
);
logic tckn;
enum logic [3:0] {
Exit2DR = 4'h0,
Exit1DR = 4'h1,
@ -59,7 +62,10 @@ module tap (
TLReset = 4'hF
} State;
always @(posedge tck) begin
always @(posedge rst, posedge tck) begin
if (rst)
State <= TLReset;
else
case (State)
TLReset : State <= tms ? TLReset : RunTestIdle;
RunTestIdle : State <= tms ? SelectDR : RunTestIdle;
@ -80,15 +86,15 @@ module tap (
endcase
end
always @(negedge tck) begin
resetn <= ~(State == TLReset);
tdo_en <= State == ShiftIR | State == ShiftDR;
captureIR <= State == CaptureIR;
updateIR <= State == UpdateIR;
shiftDR <= State == ShiftDR;
captureDR <= State == CaptureDR;
updateDR <= State == UpdateDR;
end
assign tckn = ~tck;
flopr #(1) resetnreg (.clk(tckn), .reset(rst), .d(~(State == TLReset)), .q(resetn));
flopr #(1) tdo_enreg (.clk(tckn), .reset(rst), .d(State == ShiftIR | State == ShiftDR), .q(tdo_en));
flopr #(1) captureIRreg (.clk(tckn), .reset(rst), .d(State == CaptureIR), .q(captureIR));
flopr #(1) updateIRreg (.clk(tckn), .reset(rst), .d(State == UpdateIR), .q(updateIR));
flopr #(1) shiftDRreg (.clk(tckn), .reset(rst), .d(State == ShiftDR), .q(shiftDR));
flopr #(1) captureDRreg (.clk(tckn), .reset(rst), .d(State == CaptureDR), .q(captureDR));
flopr #(1) updateDRreg (.clk(tckn), .reset(rst), .d(State == UpdateDR), .q(updateDR));
assign clockIR = tck | State[0] | ~State[1] | ~State[3];
assign clockDR = tck | State[0] | ~State[1] | State[3];