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,105 +42,99 @@ def prog_buff_test(cvw):
|
|||||||
print()
|
print()
|
||||||
|
|
||||||
|
|
||||||
def flow_control_test():
|
def flow_control_test(cvw):
|
||||||
with OpenOCD() as cvw:
|
#time.sleep(70) # wait for OpenSBI
|
||||||
cvw.reset_dm()
|
|
||||||
cvw.reset_hart()
|
|
||||||
|
|
||||||
cvw.halt()
|
cvw.halt()
|
||||||
cvw.read_data("DCSR")
|
cvw.read_data("DCSR")
|
||||||
for _ in range(50):
|
for _ in range(50):
|
||||||
cvw.step()
|
cvw.step()
|
||||||
print(cvw.read_data("PCM"))
|
print(cvw.read_data("PCM"))
|
||||||
cvw.resume()
|
cvw.resume()
|
||||||
|
|
||||||
|
|
||||||
def register_rw_test():
|
def register_rw_test(cvw):
|
||||||
with OpenOCD() as cvw:
|
registers = dict.fromkeys(cvw.register_translations.keys(),[])
|
||||||
registers = dict.fromkeys(cvw.register_translations.keys(),[])
|
reg_addrs = list(registers.keys())
|
||||||
reg_addrs = list(registers.keys())
|
|
||||||
|
|
||||||
global XLEN
|
global XLEN
|
||||||
XLEN = cvw.LLEN
|
XLEN = cvw.LLEN
|
||||||
global nonstandard_register_lengths
|
global nonstandard_register_lengths
|
||||||
nonstandard_register_lengths = cvw.nonstandard_register_lengths
|
nonstandard_register_lengths = cvw.nonstandard_register_lengths
|
||||||
|
|
||||||
cvw.reset_dm()
|
#time.sleep(70) # wait for OpenSBI
|
||||||
cvw.reset_hart()
|
|
||||||
|
|
||||||
#time.sleep(70) # wait for OpenSBI
|
cvw.halt()
|
||||||
|
|
||||||
cvw.halt()
|
# dump data in all registers
|
||||||
|
for r in reg_addrs:
|
||||||
# dump data in all registers
|
try:
|
||||||
for r in reg_addrs:
|
data = cvw.read_data(r)
|
||||||
try:
|
registers[r] = data
|
||||||
data = cvw.read_data(r)
|
print(f"{r}: {data}")
|
||||||
registers[r] = data
|
except Exception as e:
|
||||||
print(f"{r}: {data}")
|
if e.args[0] == "exception": # Invalid register (not implemented)
|
||||||
except Exception as e:
|
del registers[r]
|
||||||
if e.args[0] == "exception": # Invalid register (not implemented)
|
cvw.clear_abstrcmd_err()
|
||||||
del registers[r]
|
|
||||||
cvw.clear_abstrcmd_err()
|
|
||||||
else:
|
|
||||||
raise e
|
|
||||||
input("Compare values to ILA, press any key to continue")
|
|
||||||
|
|
||||||
# Write random data to all registers
|
|
||||||
reg_addrs = list(registers.keys())
|
|
||||||
if random_order:
|
|
||||||
random.shuffle(reg_addrs)
|
|
||||||
test_reg_data = {}
|
|
||||||
for r in reg_addrs:
|
|
||||||
test_data = random_hex(r)
|
|
||||||
try:
|
|
||||||
cvw.write_data(r, test_data)
|
|
||||||
test_reg_data[r] = test_data
|
|
||||||
print(f"Writing {test_data} to {r}")
|
|
||||||
except Exception as e:
|
|
||||||
if e.args[0] == "not supported": # Register is read only
|
|
||||||
del registers[r]
|
|
||||||
cvw.clear_abstrcmd_err()
|
|
||||||
else:
|
|
||||||
raise e
|
|
||||||
|
|
||||||
# GPR X0 is always 0
|
|
||||||
test_reg_data["x0"] = "0x" + "0"*(cvw.LLEN//4)
|
|
||||||
|
|
||||||
# Confirm data was written correctly
|
|
||||||
reg_addrs = list(registers.keys())
|
|
||||||
if random_order:
|
|
||||||
random.shuffle(reg_addrs)
|
|
||||||
for r in reg_addrs:
|
|
||||||
try:
|
|
||||||
rdata = cvw.read_data(r)
|
|
||||||
except Exception as e:
|
|
||||||
raise e
|
|
||||||
if rdata != test_reg_data[r]:
|
|
||||||
print(f"Error: register {r} read did not return correct data: {rdata} != {test_reg_data[r]}")
|
|
||||||
else:
|
else:
|
||||||
print(f"Reading {rdata} from {r}")
|
raise e
|
||||||
|
input("Compare values to ILA, press any key to continue")
|
||||||
|
|
||||||
# Return all registers to original state
|
# Write random data to all registers
|
||||||
reg_addrs = list(registers.keys())
|
reg_addrs = list(registers.keys())
|
||||||
for r in reg_addrs:
|
if random_order:
|
||||||
print(f"Writing {registers[r]} to {r}")
|
random.shuffle(reg_addrs)
|
||||||
try:
|
test_reg_data = {}
|
||||||
cvw.write_data(r, registers[r])
|
for r in reg_addrs:
|
||||||
except Exception as e:
|
test_data = random_hex(r)
|
||||||
|
try:
|
||||||
|
cvw.write_data(r, test_data)
|
||||||
|
test_reg_data[r] = test_data
|
||||||
|
print(f"Writing {test_data} to {r}")
|
||||||
|
except Exception as e:
|
||||||
|
if e.args[0] == "not supported": # Register is read only
|
||||||
|
del registers[r]
|
||||||
|
cvw.clear_abstrcmd_err()
|
||||||
|
else:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
# Confirm data was written correctly
|
# GPR X0 is always 0
|
||||||
for r in reg_addrs:
|
test_reg_data["x0"] = "0x" + "0"*(cvw.LLEN//4)
|
||||||
try:
|
|
||||||
rdata = cvw.read_data(r)
|
|
||||||
except Exception as e:
|
|
||||||
raise e
|
|
||||||
if rdata != registers[r]:
|
|
||||||
raise Exception(f"Register {r} read did not return correct data: {rdata} != {registers[r]}")
|
|
||||||
print("All writes successful")
|
|
||||||
|
|
||||||
cvw.resume()
|
# Confirm data was written correctly
|
||||||
|
reg_addrs = list(registers.keys())
|
||||||
|
if random_order:
|
||||||
|
random.shuffle(reg_addrs)
|
||||||
|
for r in reg_addrs:
|
||||||
|
try:
|
||||||
|
rdata = cvw.read_data(r)
|
||||||
|
except Exception as e:
|
||||||
|
raise e
|
||||||
|
if rdata != test_reg_data[r]:
|
||||||
|
print(f"Error: register {r} read did not return correct data: {rdata} != {test_reg_data[r]}")
|
||||||
|
else:
|
||||||
|
print(f"Reading {rdata} from {r}")
|
||||||
|
|
||||||
|
# Return all registers to original state
|
||||||
|
reg_addrs = list(registers.keys())
|
||||||
|
for r in reg_addrs:
|
||||||
|
print(f"Writing {registers[r]} to {r}")
|
||||||
|
try:
|
||||||
|
cvw.write_data(r, registers[r])
|
||||||
|
except Exception as e:
|
||||||
|
raise e
|
||||||
|
|
||||||
|
# Confirm data was written correctly
|
||||||
|
for r in reg_addrs:
|
||||||
|
try:
|
||||||
|
rdata = cvw.read_data(r)
|
||||||
|
except Exception as e:
|
||||||
|
raise e
|
||||||
|
if rdata != registers[r]:
|
||||||
|
raise Exception(f"Register {r} read did not return correct data: {rdata} != {registers[r]}")
|
||||||
|
print("All writes successful")
|
||||||
|
|
||||||
|
cvw.resume()
|
||||||
|
|
||||||
|
|
||||||
def random_hex(reg_name):
|
def random_hex(reg_name):
|
||||||
@ -160,8 +154,11 @@ def random_hex(reg_name):
|
|||||||
|
|
||||||
|
|
||||||
with OpenOCD() as cvw:
|
with OpenOCD() as cvw:
|
||||||
|
print(cvw.read_dmi("0x16"))
|
||||||
|
cvw.trst()
|
||||||
cvw.reset_dm()
|
cvw.reset_dm()
|
||||||
cvw.reset_hart()
|
cvw.reset_hart()
|
||||||
#register_rw_test()
|
quit()
|
||||||
#flow_control_test()
|
#register_rw_test(cvw)
|
||||||
prog_buff_test(cvw)
|
flow_control_test(cvw)
|
||||||
|
#prog_buff_test(cvw)
|
||||||
|
@ -98,7 +98,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
|
|||||||
// [0] = 1
|
// [0] = 1
|
||||||
localparam JTAG_DEVICE_ID = 32'h1002AC05;
|
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,
|
.ReqReady, .ReqValid, .ReqAddress, .ReqData, .ReqOP, .RspReady,
|
||||||
.RspValid, .RspData, .RspOP);
|
.RspValid, .RspData, .RspOP);
|
||||||
|
|
||||||
@ -253,7 +253,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
|
|||||||
{2'bx,`HARTINFO},
|
{2'bx,`HARTINFO},
|
||||||
{2'bx,`ABSTRACTAUTO},
|
{2'bx,`ABSTRACTAUTO},
|
||||||
{2'bx,`NEXTDM} : State <= READ_ZERO;
|
{2'bx,`NEXTDM} : State <= READ_ZERO;
|
||||||
default : State <= INVALID;
|
default : State <= READ_ZERO;//INVALID;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -388,7 +388,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
|
|||||||
end
|
end
|
||||||
|
|
||||||
INVALID : begin
|
INVALID : begin
|
||||||
RspOP <= `OP_FAILED;
|
RspOP <= `OP_SUCCESS;//`OP_FAILED;
|
||||||
State <= ACK;
|
State <= ACK;
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
|
@ -65,7 +65,7 @@ module dmc (
|
|||||||
assign DebugMode = (State != RUNNING);
|
assign DebugMode = (State != RUNNING);
|
||||||
assign DebugStall = (State == HALTED);
|
assign DebugStall = (State == HALTED);
|
||||||
|
|
||||||
assign EnterDebugMode = (State == FLUSH) & (Counter == 0);
|
assign EnterDebugMode = (State == FLUSH) & ~|Counter;
|
||||||
assign ExitDebugMode = (State == HALTED) & ResumeReq;
|
assign ExitDebugMode = (State == HALTED) & ResumeReq;
|
||||||
assign ForceNOP = (State == FLUSH);
|
assign ForceNOP = (State == FLUSH);
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ module dmc (
|
|||||||
case (State)
|
case (State)
|
||||||
RUNNING : begin
|
RUNNING : begin
|
||||||
if (HaltReq) begin
|
if (HaltReq) begin
|
||||||
Counter <= 0;
|
Counter <= NOP_CYCLE_DURATION;
|
||||||
State <= FLUSH;
|
State <= FLUSH;
|
||||||
DebugCause <= `CAUSE_HALTREQ;
|
DebugCause <= `CAUSE_HALTREQ;
|
||||||
end
|
end
|
||||||
@ -87,25 +87,22 @@ module dmc (
|
|||||||
|
|
||||||
// fill the pipe with NOP before halting
|
// fill the pipe with NOP before halting
|
||||||
FLUSH : begin
|
FLUSH : begin
|
||||||
if (Counter == NOP_CYCLE_DURATION)
|
if (~|Counter)
|
||||||
State <= HALTED;
|
State <= HALTED;
|
||||||
else
|
else
|
||||||
Counter <= Counter + 1;
|
Counter <= Counter - 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
HALTED : begin
|
HALTED : begin
|
||||||
if (ResumeReq)
|
if (ResumeReq) begin
|
||||||
State <= RESUME;
|
if (Step) begin
|
||||||
end
|
Counter <= NOP_CYCLE_DURATION;
|
||||||
|
State <= FLUSH;
|
||||||
RESUME : begin
|
DebugCause <= `CAUSE_STEP;
|
||||||
if (Step) begin
|
end else begin
|
||||||
Counter <= 0;
|
State <= RUNNING;
|
||||||
State <= FLUSH;
|
ResumeAck <= 1;
|
||||||
DebugCause <= `CAUSE_STEP;
|
end
|
||||||
end else begin
|
|
||||||
State <= RUNNING;
|
|
||||||
ResumeAck <= 1;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
module dtm #(parameter ADDR_WIDTH, parameter JTAG_DEVICE_ID) (
|
module dtm #(parameter ADDR_WIDTH, parameter JTAG_DEVICE_ID) (
|
||||||
// System clock
|
// System clock
|
||||||
input logic clk,
|
input logic clk, rst,
|
||||||
// External JTAG signals
|
// External JTAG signals
|
||||||
input logic tck,
|
input logic tck,
|
||||||
input logic tdi,
|
input logic tdi,
|
||||||
@ -90,7 +90,7 @@ module dtm #(parameter ADDR_WIDTH, parameter JTAG_DEVICE_ID) (
|
|||||||
// DTMCS
|
// DTMCS
|
||||||
assign DtmcsOut = {11'b0, ErrInfo, 3'b0, Idle, DmiStat, ABits, Version};
|
assign DtmcsOut = {11'b0, ErrInfo, 3'b0, Idle, DmiStat, ABits, Version};
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
if (~resetn | DtmHardReset) begin
|
if (rst | ~resetn | DtmHardReset) begin
|
||||||
DtmHardReset <= 0;
|
DtmHardReset <= 0;
|
||||||
DmiReset <= 0;
|
DmiReset <= 0;
|
||||||
end else if (UpdateDtmcs) begin
|
end else if (UpdateDtmcs) begin
|
||||||
@ -103,7 +103,7 @@ module dtm #(parameter ADDR_WIDTH, parameter JTAG_DEVICE_ID) (
|
|||||||
|
|
||||||
// DMI
|
// DMI
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
if (~resetn | DtmHardReset) begin
|
if (rst | ~resetn | DtmHardReset) begin
|
||||||
ValRspData <= 0;
|
ValRspData <= 0;
|
||||||
ValRspOP <= `OP_SUCCESS;
|
ValRspOP <= `OP_SUCCESS;
|
||||||
//ErrInfo <= 4;
|
//ErrInfo <= 4;
|
||||||
|
@ -48,15 +48,10 @@ module ir (
|
|||||||
assign tdo = shift_reg[0];
|
assign tdo = shift_reg[0];
|
||||||
|
|
||||||
// Shift register
|
// Shift register
|
||||||
always @(posedge clockIR) begin
|
flop #(1) shift_regmsb (.clk(clockIR), .d(shift_reg[1] | captureIR), .q(shift_reg[0]));
|
||||||
shift_reg[0] <= shift_reg[1] | captureIR;
|
|
||||||
end
|
|
||||||
genvar i;
|
genvar i;
|
||||||
for (i = INST_REG_WIDTH; i > 1; i = i - 1) begin
|
for (i = INST_REG_WIDTH; i > 1; i = i - 1)
|
||||||
always @(posedge clockIR) begin
|
flop #(1) shift_reg (.clk(clockIR), .d(shift_reg[i] & ~captureIR), .q(shift_reg[i-1]));
|
||||||
shift_reg[i-1] <= shift_reg[i] & ~captureIR;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
// Instruction decoder
|
// Instruction decoder
|
||||||
// 6.1.2
|
// 6.1.2
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
module jtag #(parameter ADDR_WIDTH, parameter DEVICE_ID) (
|
module jtag #(parameter ADDR_WIDTH, parameter DEVICE_ID) (
|
||||||
|
input logic rst,
|
||||||
// JTAG signals
|
// JTAG signals
|
||||||
input logic tck,
|
input logic tck,
|
||||||
input logic tdi,
|
input logic tdi,
|
||||||
@ -79,7 +80,7 @@ module jtag #(parameter ADDR_WIDTH, parameter DEVICE_ID) (
|
|||||||
assign CaptureDmi = captureDR & DmiInstr;
|
assign CaptureDmi = captureDR & DmiInstr;
|
||||||
assign UpdateDmi = updateDR & 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);
|
.clockIR, .updateIR, .shiftDR, .captureDR, .clockDR, .updateDR, .select);
|
||||||
|
|
||||||
// IR/DR input demux
|
// IR/DR input demux
|
||||||
@ -103,34 +104,23 @@ module jtag #(parameter ADDR_WIDTH, parameter DEVICE_ID) (
|
|||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
always_ff @(posedge UpdateDtmcs)
|
flopr #(32) dtmcsreg (.clk(UpdateDtmcs), .reset(rst), .d(DtmcsShiftReg[31:0]), .q(DtmcsIn));
|
||||||
DtmcsIn <= DtmcsShiftReg[31:0];
|
flopr #(34+ADDR_WIDTH) dmireg (.clk(UpdateDmi), .reset(rst), .d(DmiShiftReg[34+ADDR_WIDTH-1:0]), .q(DmiIn));
|
||||||
|
|
||||||
always_ff @(posedge UpdateDmi)
|
|
||||||
DmiIn <= DmiShiftReg[34+ADDR_WIDTH-1:0];
|
|
||||||
|
|
||||||
assign DtmcsShiftReg[32] = tdi_dr;
|
assign DtmcsShiftReg[32] = tdi_dr;
|
||||||
assign tdo_dtmcs = DtmcsShiftReg[0];
|
assign tdo_dtmcs = DtmcsShiftReg[0];
|
||||||
for (i = 0; i < 32; i = i + 1) begin
|
for (i = 0; i < 32; i = i + 1)
|
||||||
always_ff @(posedge clockDR) begin
|
flopr #(1) dtmcsshiftreg (.clk(clockDR), .reset(rst), .d(captureDR ? DtmcsOut[i] : DtmcsShiftReg[i+1]), .q(DtmcsShiftReg[i]));
|
||||||
DtmcsShiftReg[i] <= captureDR ? DtmcsOut[i] : DtmcsShiftReg[i+1];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assign DmiShiftReg[34+ADDR_WIDTH] = tdi_dr;
|
assign DmiShiftReg[34+ADDR_WIDTH] = tdi_dr;
|
||||||
assign tdo_dmi = DmiShiftReg[0];
|
assign tdo_dmi = DmiShiftReg[0];
|
||||||
for (i = 0; i < 34+ADDR_WIDTH; i = i + 1) begin
|
for (i = 0; i < 34+ADDR_WIDTH; i = i + 1)
|
||||||
always_ff @(posedge clockDR) begin
|
flopr #(1) dmishiftreg (.clk(clockDR), .reset(rst), .d(captureDR ? DmiOut[i] : DmiShiftReg[i+1]), .q(DmiShiftReg[i]));
|
||||||
DmiShiftReg[i] <= captureDR ? DmiOut[i] : DmiShiftReg[i+1];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
// jtag id register
|
// jtag id register
|
||||||
idreg #(DEVICE_ID) id (.tdi(tdi_dr), .clockDR, .captureDR, .tdo(tdo_idcode));
|
idreg #(DEVICE_ID) id (.tdi(tdi_dr), .clockDR, .captureDR, .tdo(tdo_idcode));
|
||||||
|
|
||||||
// bypass register
|
// bypass register
|
||||||
always_ff @(posedge clockDR) begin
|
flopr #(1) bypassreg (.clk(clockDR), .reset(rst), .d(tdi_dr & shiftDR), .q(tdo_bypass));
|
||||||
tdo_bypass <= tdi_dr & shiftDR;
|
|
||||||
end
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
module tap (
|
module tap (
|
||||||
|
input logic rst,
|
||||||
input logic tck,
|
input logic tck,
|
||||||
input logic tms,
|
input logic tms,
|
||||||
output logic resetn,
|
output logic resetn,
|
||||||
@ -40,6 +41,8 @@ module tap (
|
|||||||
output logic select
|
output logic select
|
||||||
);
|
);
|
||||||
|
|
||||||
|
logic tckn;
|
||||||
|
|
||||||
enum logic [3:0] {
|
enum logic [3:0] {
|
||||||
Exit2DR = 4'h0,
|
Exit2DR = 4'h0,
|
||||||
Exit1DR = 4'h1,
|
Exit1DR = 4'h1,
|
||||||
@ -59,36 +62,39 @@ module tap (
|
|||||||
TLReset = 4'hF
|
TLReset = 4'hF
|
||||||
} State;
|
} State;
|
||||||
|
|
||||||
always @(posedge tck) begin
|
always @(posedge rst, posedge tck) begin
|
||||||
case (State)
|
if (rst)
|
||||||
TLReset : State <= tms ? TLReset : RunTestIdle;
|
State <= TLReset;
|
||||||
RunTestIdle : State <= tms ? SelectDR : RunTestIdle;
|
else
|
||||||
SelectDR : State <= tms ? SelectIR : CaptureDR;
|
case (State)
|
||||||
CaptureDR : State <= tms ? Exit1DR : ShiftDR;
|
TLReset : State <= tms ? TLReset : RunTestIdle;
|
||||||
ShiftDR : State <= tms ? Exit1DR : ShiftDR;
|
RunTestIdle : State <= tms ? SelectDR : RunTestIdle;
|
||||||
Exit1DR : State <= tms ? UpdateDR : PauseDR;
|
SelectDR : State <= tms ? SelectIR : CaptureDR;
|
||||||
PauseDR : State <= tms ? Exit2DR : PauseDR;
|
CaptureDR : State <= tms ? Exit1DR : ShiftDR;
|
||||||
Exit2DR : State <= tms ? UpdateDR : ShiftDR;
|
ShiftDR : State <= tms ? Exit1DR : ShiftDR;
|
||||||
UpdateDR : State <= tms ? SelectDR : RunTestIdle;
|
Exit1DR : State <= tms ? UpdateDR : PauseDR;
|
||||||
SelectIR : State <= tms ? TLReset : CaptureIR;
|
PauseDR : State <= tms ? Exit2DR : PauseDR;
|
||||||
CaptureIR : State <= tms ? Exit1IR : ShiftIR;
|
Exit2DR : State <= tms ? UpdateDR : ShiftDR;
|
||||||
ShiftIR : State <= tms ? Exit1IR : ShiftIR;
|
UpdateDR : State <= tms ? SelectDR : RunTestIdle;
|
||||||
Exit1IR : State <= tms ? UpdateIR : PauseIR;
|
SelectIR : State <= tms ? TLReset : CaptureIR;
|
||||||
PauseIR : State <= tms ? Exit2IR : PauseIR;
|
CaptureIR : State <= tms ? Exit1IR : ShiftIR;
|
||||||
Exit2IR : State <= tms ? UpdateIR : ShiftIR;
|
ShiftIR : State <= tms ? Exit1IR : ShiftIR;
|
||||||
UpdateIR : State <= tms ? SelectDR : RunTestIdle;
|
Exit1IR : State <= tms ? UpdateIR : PauseIR;
|
||||||
endcase
|
PauseIR : State <= tms ? Exit2IR : PauseIR;
|
||||||
|
Exit2IR : State <= tms ? UpdateIR : ShiftIR;
|
||||||
|
UpdateIR : State <= tms ? SelectDR : RunTestIdle;
|
||||||
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
|
assign tckn = ~tck;
|
||||||
|
|
||||||
always @(negedge tck) begin
|
flopr #(1) resetnreg (.clk(tckn), .reset(rst), .d(~(State == TLReset)), .q(resetn));
|
||||||
resetn <= ~(State == TLReset);
|
flopr #(1) tdo_enreg (.clk(tckn), .reset(rst), .d(State == ShiftIR | State == ShiftDR), .q(tdo_en));
|
||||||
tdo_en <= State == ShiftIR | State == ShiftDR;
|
flopr #(1) captureIRreg (.clk(tckn), .reset(rst), .d(State == CaptureIR), .q(captureIR));
|
||||||
captureIR <= State == CaptureIR;
|
flopr #(1) updateIRreg (.clk(tckn), .reset(rst), .d(State == UpdateIR), .q(updateIR));
|
||||||
updateIR <= State == UpdateIR;
|
flopr #(1) shiftDRreg (.clk(tckn), .reset(rst), .d(State == ShiftDR), .q(shiftDR));
|
||||||
shiftDR <= State == ShiftDR;
|
flopr #(1) captureDRreg (.clk(tckn), .reset(rst), .d(State == CaptureDR), .q(captureDR));
|
||||||
captureDR <= State == CaptureDR;
|
flopr #(1) updateDRreg (.clk(tckn), .reset(rst), .d(State == UpdateDR), .q(updateDR));
|
||||||
updateDR <= State == UpdateDR;
|
|
||||||
end
|
|
||||||
|
|
||||||
assign clockIR = tck | State[0] | ~State[1] | ~State[3];
|
assign clockIR = tck | State[0] | ~State[1] | ~State[3];
|
||||||
assign clockDR = tck | State[0] | ~State[1] | State[3];
|
assign clockDR = tck | State[0] | ~State[1] | State[3];
|
||||||
|
Loading…
Reference in New Issue
Block a user