diff --git a/other_projects/jtag.v b/other_projects/jtag.v new file mode 100644 index 0000000..9516906 --- /dev/null +++ b/other_projects/jtag.v @@ -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