add start of JTAG TAP

This commit is contained in:
Brendan Haines 2021-09-09 00:06:57 -06:00
parent 625001152d
commit 7ab99bb5ff

179
other_projects/jtag.v Normal file
View File

@ -0,0 +1,179 @@
// IEEE 1149.1 - digital
// IEEE 1149.4 - analog / mixed-signal
// IEEE 1149.5 - system level
// IEEE 1149.6 - ac-coupled, differential nets
// IEEE 1532 - boundary scan (superset of IEEE 1149.1)
// References:
// http://www.interfacebus.com/Design_Connector_JTAG_Bus.html
// Designing to IEEE 1149.1-2013
module jtag_tap(
input wire jtag_tck,
input wire jtag_tms, // tie high to disable module
input wire jtag_tdi,
output reg jtag_tdo,
input wire jtag_trst, // [optional] async active low reset
);
// NOTE: do not connect jtag_trst to any system logic (only tie to test logic)
// For instance a reset input to the IC must not change the JTAG TAP state
// TODO: TMP controller (IEEE 1149.1-2013 6.2.1)
// State values according to IEEE 1149.1-2013
localparam STATE_EXIT_2_DR = 4'h0,
STATE_EXIT_1_DR = 4'h1,
STATE_SHIFT_DR = 4'h2,
STATE_PAUSE_DR = 4'h3,
STATE_SELECT_IR_SCAN = 4'h4,
STATE_UPDATE_DR = 4'h5,
STATE_CAPTURE_DR = 4'h6,
STATE_SELECT_DR_SCAN = 4'h7,
STATE_EXIT_2_IR = 4'h8,
STATE_EXIT_1_IR = 4'h9,
STATE_SHIFT_IR = 4'hA,
STATE_PAUSE_IR = 4'hB,
STATE_RUN_TEST_IDLE = 4'hC,
STATE_UPDATE_IR = 4'hD,
STATE_CAPTURE_IR = 4'hD,
STATE_TEST_LOGIC_RESET = 4'hF;
localparam INSTR_BYPASS = 8'hFF, // required always // may also be other codes: recommend 0
INSTR_SAMPLE = 8'h, // required always
INSTR_PRELOAD = 8'h, // required always
INSTR_EXTEST = 8'h, // required always
INSTR_IDCODE = 8'h, // required if IDCODE register is included
INSTR_USERCODE = 8'h, // required if IDCODE register is included in a user-programmable component that does not allow programming via this test logic
// INSTR_CLAMP = 8'hxx,
// INSTR_HIGHZ = 8'hxx,
INSTR_IC_RESET = 8'h, // required if reset selection register is included
// INSTR_CLAMP_HOLD = 8'hxx, // required if TMP controller & TMP status register are included
// INSTR_CLAMP_RELEASE = 8'hxx, // required if TMP controller & TMP status register are included
// INSTR_TMP_STATUS = 8'hxx, // required if TMP controller & TMP status register are included
// recommended if there is programmable I/O
// INSTR_INIT_SETUP = 8'h, // required if initialization data register is included
// INSTR_INIT_SETUP_CLAMP = 8'h, // required if initialization data register is included
// INSTR_INIT_RUN = 8'h, // required if initialization status register is included
// required registers
reg [3:0] state = STATE_TEST_LOGIC_RESET;
reg [7:0] reg_instruction_shift, reg_instruction;
reg [7:0] reg_data;
always @(posedge jtag_tck or posedge jtag_trst) begin : state_transitions
if (jtag_trst == 1'b0) begin
state <= STATE_TEST_LOGIC_RESET;
end else begin
case (state) begin
STATE_TEST_LOGIC_RESET: state <= jtag_tms ? STATE_TEST_LOGIC_RESET : STATE_RUN_TEST_IDLE;
STATE_RUN_TEST_IDLE: state <= jtag_tms ? STATE_SELECT_DR_SCAN : STATE_RUN_TEST_IDLE;
STATE_SELECT_DR_SCAN: state <= jtag_tms ? STATE_SELECT_IR_SCAN : STATE_CAPTURE_DR;
STATE_CAPTURE_DR: state <= jtag_tms ? STATE_EXIT_1_DR : STATE_SHIFT_DR;
STATE_SHIFT_DR: state <= jtag_tms ? STATE_EXIT_1_DR : STATE_SHIFT_DR;
STATE_EXIT_1_DR: state <= jtag_tms ? STATE_UPDATE_DR : STATE_PAUSE_DR;
STATE_PAUSE_DR: state <= jtag_tms ? STATE_EXIT_2_DR : STATE_PAUSE_DR;
STATE_EXIT_2_DR: state <= jtag_tms ? STATE_UPDATE_DR : STATE_SHIFT_DR;
STATE_UPDATE_DR: state <= jtag_tms ? STATE_SELECT_DR_SCAN : STATE_RUN_TEST_IDLE;
STATE_SELECT_IR_SCAN: state <= jtag_tms ? STATE_TEST_LOGIC_RESET : STATE_CAPTURE_IR;
STATE_CAPTURE_IR: state <= jtag_tms ? STATE_EXIT_1_IR : STATE_SHIFT_IR;
STATE_SHIFT_IR: state <= jtag_tms ? STATE_EXIT_1_IR : STATE_SHIFT_IR;
STATE_EXIT_1_IR: state <= jtag_tms ? STATE_UPDATE_IR : STATE_PAUSE_IR;
STATE_PAUSE_IR: state <= jtag_tms ? STATE_EXIT_2_IR : STATE_PAUSE_IR;
STATE_EXIT_2_IR: state <= jtag_tms ? STATE_UPDATE_IR : STATE_SHIFT_IR;
STATE_UPDATE_IR: state <= jtag_tms ? STATE_SELECT_DR_SCAN : STATE_RUN_TEST_IDLE;
end
end
end
always @(posedge jtag_tck or posedge jtag_trst) begin : actions_posedge
if (jtag_trst == 1'b0 || state == STATE_TEST_LOGIC_RESET) begin
reg_instruction_shift <= 8'hxx;
reg_instruction <= INSTR_IDCODE;
end else begin
case (state)
STATE_TEST_LOGIC_RESET: begin
reg_instruction_shift <= 8'hxx;
reg_instruction <= INSTR_IDCODE;
end
STATE_CAPTURE_IR: begin
// TODO: check MSB/LSB first
reg_instruction_shift[1:0] <= 2'b01;
reg_instruction_shift[7:2] <= 6'h00; // these bits may be chosen to be any fixed value
// reg_instruction <= reg_instruction;
end
STATE_SHIFT_IR: begin
// TODO: check MSB/LSB first
reg_instruction_shift[7] <= jtag_tdi;
reg_instruction_shift[6:0] <= reg_instruction_shift[7:1];
// reg_instruction <= reg_instruction;
end
STATE_EXIT_1_IR,
STATE_EXIT_2_IR,
STATE_PAUSE_IR: begin
// reg_instruction_shift <= reg_instruction_shift;
// reg_instruction <= reg_instruction;
end
STATE_UPDATE_IR: begin
// reg_instruction_shift <= reg_instruction_shift;
reg_instruction <= reg_instruction_shift;
// TODO: do this on negedge? see pg 70
end
default: begin
reg_instruction_shift <= 8'hxx;
// reg_instruction <= reg_instruction;
end
endcase
// case (state) begin
// STATE_TEST_LOGIC_RESET: state <= jtag_tms ? STATE_TEST_LOGIC_RESET : STATE_RUN_TEST_IDLE;
// STATE_RUN_TEST_IDLE: state <= jtag_tms ? STATE_SELECT_DR_SCAN : STATE_RUN_TEST_IDLE;
// STATE_SELECT_DR_SCAN: state <= jtag_tms ? STATE_SELECT_IR_SCAN : STATE_CAPTURE_DR;
// STATE_CAPTURE_DR: state <= jtag_tms ? STATE_EXIT_1_DR : STATE_SHIFT_DR;
// STATE_SHIFT_DR: state <= jtag_tms ? STATE_EXIT_1_DR : STATE_SHIFT_DR;
// STATE_EXIT_1_DR: state <= jtag_tms ? STATE_UPDATE_DR : STATE_PAUSE_DR;
// STATE_PAUSE_DR: state <= jtag_tms ? STATE_EXIT_2_DR : STATE_PAUSE_DR;
// STATE_EXIT_2_DR: state <= jtag_tms ? STATE_UPDATE_DR : STATE_SHIFT_DR;
// STATE_UPDATE_DR: state <= jtag_tms ? STATE_SELECT_DR_SCAN : STATE_RUN_TEST_IDLE;
// STATE_SELECT_IR_SCAN: state <= jtag_tms ? STATE_TEST_LOGIC_RESET : STATE_CAPTURE_IR;
// STATE_CAPTURE_IR: state <= jtag_tms ? STATE_EXIT_1_IR : STATE_SHIFT_IR;
// STATE_SHIFT_IR: state <= jtag_tms ? STATE_EXIT_1_IR : STATE_SHIFT_IR;
// STATE_EXIT_1_IR: state <= jtag_tms ? STATE_UPDATE_IR : STATE_PAUSE_IR;
// STATE_PAUSE_IR: state <= jtag_tms ? STATE_EXIT_2_IR : STATE_PAUSE_IR;
// STATE_EXIT_2_IR: state <= jtag_tms ? STATE_UPDATE_IR : STATE_SHIFT_IR;
// STATE_UPDATE_IR: state <= jtag_tms ? STATE_SELECT_DR_SCAN : STATE_RUN_TEST_IDLE;
// end
end
end
always @(negedge jtag_tck or posedge jtag_trst) begin : actions_negedge
if (jtag_trst == 1'b0 || state == STATE_TEST_LOGIC_RESET) begin
end else begin
// case (state) begin
// STATE_TEST_LOGIC_RESET: state <= jtag_tms ? STATE_TEST_LOGIC_RESET : STATE_RUN_TEST_IDLE;
// STATE_RUN_TEST_IDLE: state <= jtag_tms ? STATE_SELECT_DR_SCAN : STATE_RUN_TEST_IDLE;
// STATE_SELECT_DR_SCAN: state <= jtag_tms ? STATE_SELECT_IR_SCAN : STATE_CAPTURE_DR;
// STATE_CAPTURE_DR: state <= jtag_tms ? STATE_EXIT_1_DR : STATE_SHIFT_DR;
// STATE_SHIFT_DR: state <= jtag_tms ? STATE_EXIT_1_DR : STATE_SHIFT_DR;
// STATE_EXIT_1_DR: state <= jtag_tms ? STATE_UPDATE_DR : STATE_PAUSE_DR;
// STATE_PAUSE_DR: state <= jtag_tms ? STATE_EXIT_2_DR : STATE_PAUSE_DR;
// STATE_EXIT_2_DR: state <= jtag_tms ? STATE_UPDATE_DR : STATE_SHIFT_DR;
// STATE_UPDATE_DR: state <= jtag_tms ? STATE_SELECT_DR_SCAN : STATE_RUN_TEST_IDLE;
// STATE_SELECT_IR_SCAN: state <= jtag_tms ? STATE_TEST_LOGIC_RESET : STATE_CAPTURE_IR;
// STATE_CAPTURE_IR: state <= jtag_tms ? STATE_EXIT_1_IR : STATE_SHIFT_IR;
// STATE_SHIFT_IR: state <= jtag_tms ? STATE_EXIT_1_IR : STATE_SHIFT_IR;
// STATE_EXIT_1_IR: state <= jtag_tms ? STATE_UPDATE_IR : STATE_PAUSE_IR;
// STATE_PAUSE_IR: state <= jtag_tms ? STATE_EXIT_2_IR : STATE_PAUSE_IR;
// STATE_EXIT_2_IR: state <= jtag_tms ? STATE_UPDATE_IR : STATE_SHIFT_IR;
// STATE_UPDATE_IR: state <= jtag_tms ? STATE_SELECT_DR_SCAN : STATE_RUN_TEST_IDLE;
// end
end
end
endmodule