mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Fix step timing, rewrite jtag to include explicit reset
This commit is contained in:
parent
7dd0182407
commit
5c593c3321
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user