Skip to content

Commit

Permalink
add debug bits to see how far we're getting in the TAP state machine …
Browse files Browse the repository at this point in the history
…in our GL tests
  • Loading branch information
stevej committed Nov 5, 2024
1 parent 5086ef0 commit 9156866
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 36 deletions.
53 changes: 39 additions & 14 deletions src/jtag.v
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,30 @@ module jtag (
wire trst;
assign trst = ~trst_n;

// Debug signals to see how far we've gotten in the TAP state machine.
bit in_run_test_idle;
bit in_select_dr_scan;
bit in_capture_dr;
bit in_shift_dr;
bit in_exit1_dr;

// TAP controller state in one-hot encoding
localparam bit [15:0] TestLogicReset = 16'b0000_0000_0000_0000; // 0
localparam bit [15:0] RunTestOrIdle = 16'b0000_0000_0000_0001; // 1
localparam bit [15:0] SelectDrScan = 16'b0000_0000_0000_0010; // 2
localparam bit [15:0] SelectIrScan = 16'b0000_0000_0000_0100; // 3
localparam bit [15:0] CaptureDr = 16'b0000_0000_0000_1000; // 4
localparam bit [15:0] CaptureIr = 16'b0000_0000_0001_0000; // 5
localparam bit [15:0] ShiftDr = 16'b0000_0000_0010_0000; // 6
localparam bit [15:0] ShiftIr = 16'b0000_0000_0100_0000; // 7
localparam bit [15:0] Exit1Dr = 16'b0000_0000_1000_0000; // 8
localparam bit [15:0] Exit1Ir = 16'b0000_0001_0000_0000; // 9
localparam bit [15:0] PauseDr = 16'b0000_0010_0000_0000; // 10
localparam bit [15:0] PauseIr = 16'b0000_0100_0000_0000; // 11
localparam bit [15:0] Exit2Dr = 16'b0000_1000_0000_0000; // 12
localparam bit [15:0] Exit2Ir = 16'b0001_0000_0000_0000; // 13
localparam bit [15:0] UpdateDr = 16'b0010_0000_0000_0000; // 14
localparam bit [15:0] UpdateIr = 16'b0100_0000_0000_0000; // 15
localparam bit [15:0] SelectIrScan = 16'b0000_0000_0000_0100; // 4
localparam bit [15:0] CaptureDr = 16'b0000_0000_0000_1000; // 8
localparam bit [15:0] CaptureIr = 16'b0000_0000_0001_0000; // 10
localparam bit [15:0] ShiftDr = 16'b0000_0000_0010_0000; // 20
localparam bit [15:0] ShiftIr = 16'b0000_0000_0100_0000; // 40
localparam bit [15:0] Exit1Dr = 16'b0000_0000_1000_0000; // 80
localparam bit [15:0] Exit1Ir = 16'b0000_0001_0000_0000; // 100
localparam bit [15:0] PauseDr = 16'b0000_0010_0000_0000; // 100
localparam bit [15:0] PauseIr = 16'b0000_0100_0000_0000; // 200
localparam bit [15:0] Exit2Dr = 16'b0000_1000_0000_0000; // 400
localparam bit [15:0] Exit2Ir = 16'b0001_0000_0000_0000; // 800
localparam bit [15:0] UpdateDr = 16'b0010_0000_0000_0000; // 1000
localparam bit [15:0] UpdateIr = 16'b0100_0000_0000_0000; // 2000

reg [15:0] current_state;

Expand Down Expand Up @@ -104,6 +111,12 @@ module jtag (

always @(posedge tck) begin
if (~trst_n) begin
in_run_test_idle <= 1'b0;
in_select_dr_scan <= 1'b0;
in_capture_dr <= 1'b0;
in_shift_dr <= 1'b0;
in_exit1_dr <= 1'b0;

current_state <= TestLogicReset; // State 0
tms_reset_check <= 5'h0;
cycles <= 8'h0;
Expand All @@ -113,6 +126,12 @@ module jtag (
reset_byte_transmitter <= 1'b0;
been_reset <= 1'b1;
end else if (enable && been_reset) begin
in_run_test_idle <= 1'b0;
in_select_dr_scan <= 1'b0;
in_capture_dr <= 1'b0;
in_shift_dr <= 1'b0;
in_exit1_dr <= 1'b0;

current_state <= current_state;
tms_reset_check <= tms_reset_check << 1;
tms_reset_check[0] <= tms;
Expand All @@ -131,12 +150,14 @@ module jtag (
endcase
end
RunTestOrIdle: begin // 1
in_run_test_idle <= 1'b1;
case (tms)
1: current_state <= SelectDrScan;
default: current_state <= RunTestOrIdle;
endcase
end
SelectDrScan: begin // 2
in_select_dr_scan <= 1'b1;
case (tms)
1: current_state <= SelectIrScan;
default: current_state <= CaptureDr;
Expand All @@ -149,6 +170,7 @@ module jtag (
endcase
end
CaptureDr: begin // 4
in_capture_dr <= 1'b1;
case (tms)
1: current_state <= Exit1Dr;
default: begin
Expand Down Expand Up @@ -180,18 +202,20 @@ module jtag (
endcase
end
ShiftDr: begin // 6
in_shift_dr <= 1'b1;
// in the Shift-DR state, this data is shifted out, least significant bit first
// Pretty sure this means connect a shift register to TDO and drain it
case (tms)
1: current_state <= Exit1Dr;
default: begin
case (current_ir_instruction)
IdCode: begin
if (!idcode_out_done) begin
if (~idcode_out_done) begin
current_state <= ShiftDr;
end else begin
reset_byte_transmitter <= 1'b1;
byte_transmitter_enable <= 1'b0;
r_output_selector_transmitter <= 1'b1; // give the TAP controller write control.
current_state <= Exit1Dr; // Not sure if this is correct.
end
end
Expand All @@ -210,6 +234,7 @@ module jtag (
endcase
end
Exit1Dr: begin // 8
in_exit1_dr <= 1'b1;
case (tms)
1: current_state <= UpdateDr;
default: current_state <= PauseDr;
Expand Down
14 changes: 7 additions & 7 deletions src/project.v
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
`include "minipit.v"

module tt_um_jtag_example_stevej (
input wire [7:0] ui_in, // Dedicated inputs
output wire [7:0] uo_out, // Dedicated outputs
input wire [7:0] uio_in, // IOs: Input path
input wire [7:0] ui_in, // Dedicated inputs
output wire [7:0] uo_out, // Dedicated outputs
input wire [7:0] uio_in, // IOs: Input path
output wire [7:0] uio_out, // IOs: Output path
output wire [7:0] uio_oe, // IOs: Enable path (active high: 0=input, 1=output)
input wire ena, // always 1 when the design is powered, so you can ignore it
input wire clk, // clock
input wire rst_n // reset_n - low to reset
output wire [7:0] uio_oe, // IOs: Enable path (active high: 0=input, 1=output)
input wire ena, // always 1 when the design is powered, so you can ignore it
input wire clk, // clock
input wire rst_n // reset_n - low to reset
);

// All output pins must be assigned. If not used, assign to 0.
Expand Down
29 changes: 14 additions & 15 deletions test/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,48 +105,47 @@ async def test_tms_five_high_for_reset(dut):
@cocotb.test()
async def test_idcode(dut):
dut._log.info("Start")
clock = Clock(dut.clk, 3, units="us")
clock = Clock(dut.clk, 1, units="us")
cocotb.start_soon(clock.start())
dut._log.info("Reset the interrupt timer")
dut._log.info("Reset the part")
dut.ena.value = 1
dut.ui_in.value = 0
dut.uio_in.value = 0
dut.rst_n.value = 1
dut.ui_in.value = 0b0000_0001
await ClockCycles(dut.clk, 1)
dut.rst_n.value = 0
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")
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)
dut.rst_n.value = 1


# Drive TRST and TCK high then low to reset tap controller
dut._log.info("Reset the jtag tap controller")
dut.ui_in.value = 0b0000_0001
dut.ui_in.value = 0b0000_1001
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.
assert dut.uo_out.value == 0x0

# .tck(ui_in[0]),
# .tdi(ui_in[1]),
# .tms(ui_in[2]),
# .trst(ui_in[3]),
#
# Drive TCK and TMS into ShiftDr state
# TMS: 0 1 0 0 to get into ShiftDr
STATES = [0b0000_1001, 0b0000_1101, 0b0000_1001, 0b0000_1001, 0b0000_1000]
STATES = [0b0000_1001, 0b0000_1101, 0b0000_1001, 0b0000_1001]
for state in STATES:
dut.ui_in.value = state
await ClockCycles(dut.clk, 1)
dut.ui_in.value = 0b0000_1000
await ClockCycles(dut.clk, 1)
#assert dut.uo_out.value == 0x0

expected_idcode = 0xFAF01
given_idcode = 0
Expand Down

0 comments on commit 9156866

Please sign in to comment.