From 4e0398f052ecee49615b6caa26bed25e5faf114c Mon Sep 17 00:00:00 2001 From: Steve Jenson Date: Mon, 4 Nov 2024 07:14:36 -0800 Subject: [PATCH] write to TDO on the negative edge. This adds a half-cycle delay to avoid hold time violations. This changes how long it takes to get IDCODE out. --- src/byte_transmitter.v | 4 +++- src/jtag.v | 12 +++++++++++- test/test.py | 19 +++++++++++-------- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/byte_transmitter.v b/src/byte_transmitter.v index 54b50e6..6d50fc1 100644 --- a/src/byte_transmitter.v +++ b/src/byte_transmitter.v @@ -24,7 +24,9 @@ module byte_transmitter ( reg r_done; assign done = r_done; - always @(posedge clk) begin + // TDO must be written on the falling edge + // to avoid hold violations. + always @(negedge clk) begin if (reset) begin byte_count <= 6'h20; r_done <= 1'b0; diff --git a/src/jtag.v b/src/jtag.v index 5e59c02..2710c59 100644 --- a/src/jtag.v +++ b/src/jtag.v @@ -98,6 +98,10 @@ module jtag ( bit been_reset; + always @(negedge tck) begin + if (r_output_selector_transmitter) tap_channel <= 1'b0; + end + always @(posedge tck) begin if (~trst_n) begin current_state <= TestLogicReset; // State 0 @@ -116,7 +120,6 @@ module jtag ( cycles <= cycles + 1'd1; current_ir_instruction <= current_ir_instruction; r_output_selector_transmitter <= r_output_selector_transmitter; - tap_channel <= 1'b0; byte_transmitter_enable <= byte_transmitter_enable; reset_byte_transmitter <= reset_byte_transmitter; // TAP state machine @@ -157,6 +160,13 @@ module jtag ( r_output_selector_transmitter <= 1'b0; byte_transmitter_enable <= 1'b1; end + Abort: begin + current_state <= ShiftDr; + end + Bypass: begin + // TODO: disable pins connected to the scan chain + current_state <= ShiftDr; + end default: begin current_state <= ShiftDr; end diff --git a/test/test.py b/test/test.py index 18bff07..5a6dcb9 100644 --- a/test/test.py +++ b/test/test.py @@ -112,14 +112,17 @@ async def test_idcode(dut): dut.ui_in.value = 0 dut.uio_in.value = 0 dut.rst_n.value = 1 - # We start with TRST being high per the spec. - dut.ui_in.value = 0b0000_1001 + dut.ui_in.value = 0b0000_0001 await ClockCycles(dut.clk, 1) dut.rst_n.value = 0 - await ClockCycles(dut.clk, 1) dut.ui_in.value = 0b0000_0000 + await ClockCycles(dut.clk, 1) + dut.ui_in.value = 0b0000_0001 dut.rst_n.value = 1 await ClockCycles(dut.clk, 1) + dut.ui_in.value = 0b0000_0000 + await ClockCycles(dut.clk, 1) + # Drive TRST and TCK high then low to reset tap controller dut._log.info("Reset the jtag tap controller") @@ -127,10 +130,10 @@ async def test_idcode(dut): await ClockCycles(dut.clk, 1) dut.ui_in.value = 0b0000_1000 await ClockCycles(dut.clk, 1) - dut.ui_in.value = 0b0000_1101 - await ClockCycles(dut.clk, 1) - dut.ui_in.value = 0b0000_1000 - await ClockCycles(dut.clk, 1) + #dut.ui_in.value = 0b0000_1001 + #await ClockCycles(dut.clk, 1) + #dut.ui_in.value = 0b0000_1000 + #await ClockCycles(dut.clk, 1) # Should be nothing on the output lines as there hasn't been enough # for an interrupt and we haven't changed out of the initial JTAG state. @@ -148,7 +151,7 @@ async def test_idcode(dut): expected_idcode = 0xFAF01 given_idcode = 0 # Drive TCK high/low enough times to see 0xFAF01, our IDCODE - for i in range(32): + for i in range(31): dut.ui_in.value = 0b0000_1001 await ClockCycles(dut.clk, 1) dut.ui_in.value = 0b0000_1000