2 * Copyright (C) 2005 by Dominic Rath
5 * Copyright (C) 2007,2008 Øyvind Harboe
6 * oyvind.harboe@zylin.com
8 * Copyright (C) 2008 Peter Hettkamp
9 * peter.hettkamp@htp-tel.de
11 * Copyright (C) 2009 SoftPLC Corporation. http://softplc.com
12 * Dick Hollenbeck <dick@softplc.com>
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 /* The specification for SVF is available here:
31 * http://www.asset-intertech.com/support/svf.pdf
32 * Below, this document is refered to as the "SVF spec".
34 * The specification for XSVF is available here:
35 * http://www.xilinx.com/support/documentation/application_notes/xapp503.pdf
36 * Below, this document is refered to as the "XSVF spec".
44 #include <jtag/jtag.h>
48 /* XSVF commands, from appendix B of xapp503.pdf */
49 #define XCOMPLETE 0x00
57 #define XSETSDRMASKS 0x0A
72 /* XWAITSTATE is not in the xilinx XSVF spec, but the svf2xsvf.py translator
73 * generates this. Arguably it is needed because the XSVF XRUNTEST command
74 * was ill conceived and does not directly flow out of the SVF RUNTEST command.
75 * This XWAITSTATE does map directly from the SVF RUNTEST command.
77 #define XWAITSTATE 0x18
79 /* Lattice has extended the SVF file format, and Dick Hollenbeck's python based
80 * SVF2XSVF converter supports these 3 additional XSVF opcodes, LCOUNT, LDELAY, LSDR.
81 * Here is an example of usage of the 3 lattice opcode extensions:
83 ! Set the maximum loop count to 25.
85 ! Step to DRPAUSE give 5 clocks and wait for 1.00e + 000 SEC.
86 LDELAY DRPAUSE 5 TCK 1.00E-003 SEC;
87 ! Test for the completed status. Match means pass.
88 ! Loop back to LDELAY line if not match and loop count less than 25.
100 /* XSVF valid state values for the XSTATE command, from appendix B of xapp503.pdf */
101 #define XSV_RESET 0x00
102 #define XSV_IDLE 0x01
103 #define XSV_DRSELECT 0x02
104 #define XSV_DRCAPTURE 0x03
105 #define XSV_DRSHIFT 0x04
106 #define XSV_DREXIT1 0x05
107 #define XSV_DRPAUSE 0x06
108 #define XSV_DREXIT2 0x07
109 #define XSV_DRUPDATE 0x08
110 #define XSV_IRSELECT 0x09
111 #define XSV_IRCAPTURE 0x0A
112 #define XSV_IRSHIFT 0x0B
113 #define XSV_IREXIT1 0x0C
114 #define XSV_IRPAUSE 0x0D
115 #define XSV_IREXIT2 0x0E
116 #define XSV_IRUPDATE 0x0F
118 /* arguments to XTRST */
122 #define XTRST_ABSENT 3
124 #define XSTATE_MAX_PATH 12
127 static int xsvf_fd
= 0;
130 /* map xsvf tap state to an openocd "tap_state_t" */
131 static tap_state_t
xsvf_to_tap(int xsvf_state
)
137 case XSV_RESET
: ret
= TAP_RESET
; break;
138 case XSV_IDLE
: ret
= TAP_IDLE
; break;
139 case XSV_DRSELECT
: ret
= TAP_DRSELECT
; break;
140 case XSV_DRCAPTURE
: ret
= TAP_DRCAPTURE
; break;
141 case XSV_DRSHIFT
: ret
= TAP_DRSHIFT
; break;
142 case XSV_DREXIT1
: ret
= TAP_DREXIT1
; break;
143 case XSV_DRPAUSE
: ret
= TAP_DRPAUSE
; break;
144 case XSV_DREXIT2
: ret
= TAP_DREXIT2
; break;
145 case XSV_DRUPDATE
: ret
= TAP_DRUPDATE
; break;
146 case XSV_IRSELECT
: ret
= TAP_IRSELECT
; break;
147 case XSV_IRCAPTURE
: ret
= TAP_IRCAPTURE
; break;
148 case XSV_IRSHIFT
: ret
= TAP_IRSHIFT
; break;
149 case XSV_IREXIT1
: ret
= TAP_IREXIT1
; break;
150 case XSV_IRPAUSE
: ret
= TAP_IRPAUSE
; break;
151 case XSV_IREXIT2
: ret
= TAP_IREXIT2
; break;
152 case XSV_IRUPDATE
: ret
= TAP_IRUPDATE
; break;
154 LOG_ERROR("UNKNOWN XSVF STATE 0x%02X", xsvf_state
);
163 static int xsvf_read_buffer(int num_bits
, int fd
, uint8_t* buf
)
167 for (num_bytes
= (num_bits
+ 7) / 8; num_bytes
> 0; num_bytes
--)
169 /* reverse the order of bytes as they are read sequentially from file */
170 if (read(fd
, buf
+ num_bytes
- 1, 1) < 0)
171 return ERROR_XSVF_EOF
;
178 COMMAND_HANDLER(handle_xsvf_command
)
180 uint8_t *dr_out_buf
= NULL
; /* from host to device (TDI) */
181 uint8_t *dr_in_buf
= NULL
; /* from device to host (TDO) */
182 uint8_t *dr_in_mask
= NULL
;
185 int xruntest
= 0; /* number of TCK cycles OR microseconds */
186 int xrepeat
= 0; /* number of retries */
188 tap_state_t xendir
= TAP_IDLE
; /* see page 8 of the SVF spec, initial xendir to be TAP_IDLE */
189 tap_state_t xenddr
= TAP_IDLE
;
193 long file_offset
= 0;
196 tap_state_t loop_state
= TAP_IDLE
;
202 int tdo_mismatch
= 0;
206 bool collecting_path
= false;
207 tap_state_t path
[XSTATE_MAX_PATH
];
208 unsigned pathlen
= 0;
210 /* a flag telling whether to clock TCK during waits,
211 * or simply sleep, controled by virt2
213 int runtest_requires_tck
= 0;
216 /* use NULL to indicate a "plain" xsvf file which accounts for
217 additional devices in the scan chain, otherwise the device
218 that should be affected
220 struct jtag_tap
*tap
= NULL
;
224 command_print(CMD_CTX
, "usage: xsvf <device#|plain> <file> [<variant>] [quiet]");
228 /* we mess with CMD_ARGV starting point below, snapshot filename here */
229 const char *filename
= CMD_ARGV
[1];
231 if (strcmp(CMD_ARGV
[0], "plain") != 0)
233 tap
= jtag_tap_by_string(CMD_ARGV
[0]);
236 command_print(CMD_CTX
, "Tap: %s unknown", CMD_ARGV
[0]);
241 if ((xsvf_fd
= open(filename
, O_RDONLY
)) < 0)
243 command_print(CMD_CTX
, "file \"%s\" not found", filename
);
247 /* if this argument is present, then interpret xruntest counts as TCK cycles rather than as usecs */
248 if ((CMD_ARGC
> 2) && (strcmp(CMD_ARGV
[2], "virt2") == 0))
250 runtest_requires_tck
= 1;
255 if ((CMD_ARGC
> 2) && (strcmp(CMD_ARGV
[2], "quiet") == 0))
260 LOG_USER("xsvf processing file: \"%s\"", filename
);
262 while (read(xsvf_fd
, &opcode
, 1) > 0)
264 /* record the position of this opcode within the file */
265 file_offset
= lseek(xsvf_fd
, 0, SEEK_CUR
) - 1;
267 /* maybe collect another state for a pathmove();
268 * or terminate a path.
270 if (collecting_path
) {
275 /* ignore/show comments between XSTATE ops */
278 /* try to collect another transition */
279 if (pathlen
== XSTATE_MAX_PATH
) {
280 LOG_ERROR("XSVF: path too long");
285 if (read(xsvf_fd
, &uc
, 1) < 0)
291 mystate
= xsvf_to_tap(uc
);
292 path
[pathlen
++] = mystate
;
294 LOG_DEBUG("XSTATE 0x%02X %s", uc
,
295 tap_state_name(mystate
));
297 /* If path is incomplete, collect more */
298 if (!svf_tap_state_is_stable(mystate
))
301 /* Else execute the path transitions we've
304 * NOTE: Punting on the saved path is not
305 * strictly correct, but we must to do this
306 * unless jtag_add_pathmove() stops rejecting
307 * paths containing RESET. This is probably
308 * harmless, since there aren't many options
309 * for going from a stable state to reset;
310 * at the worst, we may issue extra clocks
311 * once we get to RESET.
313 if (mystate
== TAP_RESET
) {
314 LOG_WARNING("XSVF: dodgey RESET");
320 /* Execute the path we collected
322 * NOTE: OpenOCD requires something that XSVF
323 * doesn't: the last TAP state in the path
324 * must be stable. In practice, tools that
325 * create XSVF seem to follow that rule too.
327 collecting_path
= false;
329 if (path
[0] == TAP_RESET
)
332 jtag_add_pathmove(pathlen
, path
);
334 result
= jtag_execute_queue();
335 if (result
!= ERROR_OK
) {
336 LOG_ERROR("XSVF: pathmove error %d",
348 LOG_DEBUG("XCOMPLETE");
350 result
= jtag_execute_queue();
351 if (result
!= ERROR_OK
)
359 LOG_DEBUG("XTDOMASK");
360 if (dr_in_mask
&& (xsvf_read_buffer(xsdrsize
, xsvf_fd
, dr_in_mask
) != ERROR_OK
))
366 uint8_t xruntest_buf
[4];
368 if (read(xsvf_fd
, xruntest_buf
, 4) < 0)
374 xruntest
= be_to_h_u32(xruntest_buf
);
375 LOG_DEBUG("XRUNTEST %d 0x%08X", xruntest
, xruntest
);
383 if (read(xsvf_fd
, &myrepeat
, 1) < 0)
388 LOG_DEBUG("XREPEAT %d", xrepeat
);
395 uint8_t xsdrsize_buf
[4];
397 if (read(xsvf_fd
, xsdrsize_buf
, 4) < 0)
403 xsdrsize
= be_to_h_u32(xsdrsize_buf
);
404 LOG_DEBUG("XSDRSIZE %d", xsdrsize
);
406 if (dr_out_buf
) free(dr_out_buf
);
407 if (dr_in_buf
) free(dr_in_buf
);
408 if (dr_in_mask
) free(dr_in_mask
);
410 dr_out_buf
= malloc((xsdrsize
+ 7) / 8);
411 dr_in_buf
= malloc((xsdrsize
+ 7) / 8);
412 dr_in_mask
= malloc((xsdrsize
+ 7) / 8);
416 case XSDR
: /* these two are identical except for the dr_in_buf */
423 const char* op_name
= (opcode
== XSDR
? "XSDR" : "XSDRTDO");
425 if (xsvf_read_buffer(xsdrsize
, xsvf_fd
, dr_out_buf
) != ERROR_OK
)
431 if (opcode
== XSDRTDO
)
433 if (xsvf_read_buffer(xsdrsize
, xsvf_fd
, dr_in_buf
) != ERROR_OK
)
443 LOG_DEBUG("%s %d", op_name
, xsdrsize
);
445 for (attempt
= 0; attempt
< limit
; ++attempt
)
447 struct scan_field field
;
451 /* perform the XC9500 exception handling sequence shown in xapp067.pdf and
452 illustrated in psuedo code at end of this file. We start from state
460 This sequence should be harmless for other devices, and it
461 will be skipped entirely if xrepeat is set to zero.
464 static tap_state_t exception_path
[] = {
472 jtag_add_pathmove(ARRAY_SIZE(exception_path
), exception_path
);
475 LOG_USER("%s mismatch, xsdrsize=%d retry=%d", op_name
, xsdrsize
, attempt
);
478 field
.num_bits
= xsdrsize
;
479 field
.out_value
= dr_out_buf
;
480 field
.in_value
= calloc(DIV_ROUND_UP(field
.num_bits
, 8), 1);
483 jtag_add_plain_dr_scan(field
.num_bits
, field
.out_value
, field
.in_value
,
486 jtag_add_dr_scan(tap
, 1, &field
, TAP_DRPAUSE
);
488 jtag_check_value_mask(&field
, dr_in_buf
, dr_in_mask
);
490 free(field
.in_value
);
493 /* LOG_DEBUG("FLUSHING QUEUE"); */
494 result
= jtag_execute_queue();
495 if (result
== ERROR_OK
)
504 LOG_USER("%s mismatch", op_name
);
509 /* See page 19 of XSVF spec regarding opcode "XSDR" */
512 result
= svf_add_statemove(TAP_IDLE
);
513 if (result
!= ERROR_OK
)
516 if (runtest_requires_tck
)
517 jtag_add_clocks(xruntest
);
519 jtag_add_sleep(xruntest
);
520 } else if (xendir
!= TAP_DRPAUSE
) {
521 /* we are already in TAP_DRPAUSE */
522 result
= svf_add_statemove(xenddr
);
523 if (result
!= ERROR_OK
)
530 LOG_ERROR("unsupported XSETSDRMASKS");
535 LOG_ERROR("unsupported XSDRINC");
540 LOG_ERROR("unsupported XSDRB");
545 LOG_ERROR("unsupported XSDRC");
550 LOG_ERROR("unsupported XSDRE");
555 LOG_ERROR("unsupported XSDRTDOB");
560 LOG_ERROR("unsupported XSDRTDOC");
565 LOG_ERROR("unsupported XSDRTDOE");
573 if (read(xsvf_fd
, &uc
, 1) < 0)
579 mystate
= xsvf_to_tap(uc
);
581 LOG_DEBUG("XSTATE 0x%02X %s", uc
, tap_state_name(mystate
));
583 if (mystate
== TAP_INVALID
) {
584 LOG_ERROR("XSVF: bad XSTATE %02x", uc
);
589 /* NOTE: the current state is SVF-stable! */
591 /* no change == NOP */
592 if (mystate
== cmd_queue_cur_state
593 && mystate
!= TAP_RESET
)
596 /* Hand off to SVF? */
597 if (svf_tap_state_is_stable(mystate
))
599 result
= svf_add_statemove(mystate
);
600 if (result
!= ERROR_OK
)
606 * A sequence of XSTATE transitions, each TAP
607 * state adjacent to the previous one. Start
610 collecting_path
= true;
618 if (read(xsvf_fd
, &uc
, 1) < 0)
624 /* see page 22 of XSVF spec */
628 xendir
= TAP_IRPAUSE
;
631 LOG_ERROR("illegial XENDIR argument: 0x%02X", uc
);
636 LOG_DEBUG("XENDIR 0x%02X %s", uc
, tap_state_name(xendir
));
641 if (read(xsvf_fd
, &uc
, 1) < 0)
647 /* see page 22 of XSVF spec */
651 xenddr
= TAP_DRPAUSE
;
654 LOG_ERROR("illegial XENDDR argument: 0x%02X", uc
);
659 LOG_DEBUG("XENDDR %02X %s", uc
, tap_state_name(xenddr
));
665 uint8_t short_buf
[2];
668 tap_state_t my_end_state
= xruntest
? TAP_IDLE
: xendir
;
672 /* one byte bitcount */
673 if (read(xsvf_fd
, short_buf
, 1) < 0)
678 bitcount
= short_buf
[0];
679 LOG_DEBUG("XSIR %d", bitcount
);
683 if (read(xsvf_fd
, short_buf
, 2) < 0)
688 bitcount
= be_to_h_u16(short_buf
);
689 LOG_DEBUG("XSIR2 %d", bitcount
);
692 ir_buf
= malloc((bitcount
+ 7) / 8);
694 if (xsvf_read_buffer(bitcount
, xsvf_fd
, ir_buf
) != ERROR_OK
)
698 struct scan_field field
;
700 field
.num_bits
= bitcount
;
701 field
.out_value
= ir_buf
;
703 field
.in_value
= NULL
;
709 jtag_add_plain_ir_scan(field
.num_bits
,
710 field
.out_value
, field
.in_value
, my_end_state
);
712 jtag_add_ir_scan(tap
, &field
, my_end_state
);
716 if (runtest_requires_tck
)
717 jtag_add_clocks(xruntest
);
719 jtag_add_sleep(xruntest
);
722 /* Note that an -irmask of non-zero in your config file
723 * can cause this to fail. Setting -irmask to zero cand work
724 * around the problem.
727 /* LOG_DEBUG("FLUSHING QUEUE"); */
728 result
= jtag_execute_queue();
729 if (result
!= ERROR_OK
)
740 unsigned int ndx
= 0;
745 if (read(xsvf_fd
, &uc
, 1) < 0)
751 if (ndx
< sizeof(comment
)-1)
756 comment
[sizeof(comment
)-1] = 0; /* regardless, terminate */
758 LOG_USER("# %s", comment
);
764 /* expected in stream:
765 XWAIT <uint8_t wait_state> <uint8_t end_state> <uint32_t usecs>
770 uint8_t delay_buf
[4];
772 tap_state_t wait_state
;
773 tap_state_t end_state
;
776 if (read(xsvf_fd
, &wait_local
, 1) < 0
777 || read(xsvf_fd
, &end
, 1) < 0
778 || read(xsvf_fd
, delay_buf
, 4) < 0)
784 wait_state
= xsvf_to_tap(wait_local
);
785 end_state
= xsvf_to_tap(end
);
786 delay
= be_to_h_u32(delay_buf
);
788 LOG_DEBUG("XWAIT %s %s usecs:%d", tap_state_name(wait_state
), tap_state_name(end_state
), delay
);
790 if (runtest_requires_tck
&& wait_state
== TAP_IDLE
)
792 jtag_add_runtest(delay
, end_state
);
796 /* FIXME handle statemove errors ... */
797 result
= svf_add_statemove(wait_state
);
798 if (result
!= ERROR_OK
)
800 jtag_add_sleep(delay
);
801 result
= svf_add_statemove(end_state
);
802 if (result
!= ERROR_OK
)
810 /* expected in stream:
811 XWAITSTATE <uint8_t wait_state> <uint8_t end_state> <uint32_t clock_count> <uint32_t usecs>
814 uint8_t clock_buf
[4];
815 uint8_t usecs_buf
[4];
818 tap_state_t wait_state
;
819 tap_state_t end_state
;
823 if (read(xsvf_fd
, &wait_local
, 1) < 0
824 || read(xsvf_fd
, &end
, 1) < 0
825 || read(xsvf_fd
, clock_buf
, 4) < 0
826 || read(xsvf_fd
, usecs_buf
, 4) < 0)
832 wait_state
= xsvf_to_tap(wait_local
);
833 end_state
= xsvf_to_tap(end
);
835 clock_count
= be_to_h_u32(clock_buf
);
836 usecs
= be_to_h_u32(usecs_buf
);
838 LOG_DEBUG("XWAITSTATE %s %s clocks:%i usecs:%i",
839 tap_state_name(wait_state
),
840 tap_state_name(end_state
),
843 /* the following states are 'stable', meaning that they have a transition
844 * in the state diagram back to themselves. This is necessary because we will
845 * be issuing a number of clocks in this state. This set of allowed states is also
846 * determined by the SVF RUNTEST command's allowed states.
848 if (!svf_tap_state_is_stable(wait_state
))
850 LOG_ERROR("illegal XWAITSTATE wait_state: \"%s\"",
851 tap_state_name(wait_state
));
853 /* REVISIT "break" so we won't run? */
856 /* FIXME handle statemove errors ... */
857 result
= svf_add_statemove(wait_state
);
858 if (result
!= ERROR_OK
)
861 jtag_add_clocks(clock_count
);
863 jtag_add_sleep(usecs
);
865 result
= svf_add_statemove(end_state
);
866 if (result
!= ERROR_OK
)
873 /* expected in stream:
874 LCOUNT <uint32_t loop_count>
876 uint8_t count_buf
[4];
878 if (read(xsvf_fd
, count_buf
, 4) < 0)
884 loop_count
= be_to_h_u32(count_buf
);
885 LOG_DEBUG("LCOUNT %d", loop_count
);
891 /* expected in stream:
892 LDELAY <uint8_t wait_state> <uint32_t clock_count> <uint32_t usecs_to_sleep>
895 uint8_t clock_buf
[4];
896 uint8_t usecs_buf
[4];
898 if (read(xsvf_fd
, &state
, 1) < 0
899 || read(xsvf_fd
, clock_buf
, 4) < 0
900 || read(xsvf_fd
, usecs_buf
, 4) < 0)
906 /* NOTE: loop_state must be stable! */
907 loop_state
= xsvf_to_tap(state
);
908 loop_clocks
= be_to_h_u32(clock_buf
);
909 loop_usecs
= be_to_h_u32(usecs_buf
);
911 LOG_DEBUG("LDELAY %s clocks:%d usecs:%d", tap_state_name(loop_state
), loop_clocks
, loop_usecs
);
915 /* LSDR is more like XSDRTDO than it is like XSDR. It uses LDELAY which
916 * comes with clocks !AND! sleep requirements.
920 int limit
= loop_count
;
926 if (xsvf_read_buffer(xsdrsize
, xsvf_fd
, dr_out_buf
) != ERROR_OK
927 || xsvf_read_buffer(xsdrsize
, xsvf_fd
, dr_in_buf
) != ERROR_OK
)
936 for (attempt
= 0; attempt
< limit
; ++attempt
)
938 struct scan_field field
;
940 result
= svf_add_statemove(loop_state
);
941 if (result
!= ERROR_OK
)
943 jtag_add_clocks(loop_clocks
);
944 jtag_add_sleep(loop_usecs
);
946 field
.num_bits
= xsdrsize
;
947 field
.out_value
= dr_out_buf
;
948 field
.in_value
= calloc(DIV_ROUND_UP(field
.num_bits
, 8), 1);
950 if (attempt
> 0 && verbose
)
951 LOG_USER("LSDR retry %d", attempt
);
954 jtag_add_plain_dr_scan(field
.num_bits
, field
.out_value
, field
.in_value
,
957 jtag_add_dr_scan(tap
, 1, &field
, TAP_DRPAUSE
);
959 jtag_check_value_mask(&field
, dr_in_buf
, dr_in_mask
);
961 free(field
.in_value
);
964 /* LOG_DEBUG("FLUSHING QUEUE"); */
965 result
= jtag_execute_queue();
966 if (result
== ERROR_OK
)
975 LOG_USER("LSDR mismatch");
986 if (read(xsvf_fd
, &trst_mode
, 1) < 0)
995 jtag_add_reset(1, 0);
999 jtag_add_reset(0, 0);
1004 LOG_ERROR("XTRST mode argument (0x%02X) out of range", trst_mode
);
1011 LOG_ERROR("unknown xsvf command (0x%02X)", uc
);
1015 if (do_abort
|| unsupported
|| tdo_mismatch
)
1017 LOG_DEBUG("xsvf failed, setting taps to reasonable state");
1019 /* upon error, return the TAPs to a reasonable state */
1020 result
= svf_add_statemove(TAP_IDLE
);
1021 if (result
!= ERROR_OK
)
1023 result
= jtag_execute_queue();
1024 if (result
!= ERROR_OK
)
1032 command_print(CMD_CTX
, "TDO mismatch, somewhere near offset %lu in xsvf file, aborting",
1041 off_t offset
= lseek(xsvf_fd
, 0, SEEK_CUR
) - 1;
1042 command_print(CMD_CTX
,
1043 "unsupported xsvf command (0x%02X) at offset %jd, aborting",
1044 uc
, (intmax_t)offset
);
1050 command_print(CMD_CTX
, "premature end of xsvf file detected, aborting");
1065 command_print(CMD_CTX
, "XSVF file programmed successfully");
1070 static const struct command_registration xsvf_command_handlers
[] = {
1073 .handler
= handle_xsvf_command
,
1074 .mode
= COMMAND_EXEC
,
1075 .help
= "Runs a XSVF file. If 'virt2' is given, xruntest "
1076 "counts are interpreted as TCK cycles rather than "
1077 "as microseconds. Without the 'quiet' option, all "
1078 "comments, retries, and mismatches will be reported.",
1079 .usage
= "(tapname|'plain') filename ['virt2'] ['quiet']",
1081 COMMAND_REGISTRATION_DONE
1084 int xsvf_register_commands(struct command_context
*cmd_ctx
)
1086 return register_commands(cmd_ctx
, NULL
, xsvf_command_handlers
);
1089 #if 0 /* this comment style used to try and keep uncrustify from adding * at begin of line */
1091 PSUEDO
-Code from Xilinx Appnote XAPP067
.pdf
:
1093 the following pseudo code clarifies the intent of the xrepeat support
. The
1094 flow given is
for the entire processing of an SVF file
, not an XSVF file
.
1095 No idea
if this is just
for the XC9500
/XL
/XV devices
or all Xilinx parts
.
1097 "Pseudo-Code Algorithm for SVF-Based ISP"
1099 1. Go to Test
-Logic
-Reset state
1100 2. Go to Run
-Test Idle state
1103 4. if SIR record then
1104 go to Shift
-IR state
1107 5. else if SDR record then
1108 set
<repeat count
> to
0
1109 store
<TDI value
> as
<current TDI value
>
1110 store
<TDO value
> as
<current TDO value
>
1111 6. go to Shift
-DR state
1112 scan in
<current TDI value
>
1113 if <current TDO value
> is specified then
1114 if <current TDO value
> does
not equal
<actual TDO value
> then
1115 if <repeat count
> > 32 then
1117 go to Run
-Test Idle state
1126 increment
<repeat count
> by
1
1127 pause
<current pause time
> microseconds
1131 go to Run
-Test Idle state
1134 else if RUNTEST record then
1135 pause tester
for <TCK value
> microseconds
1136 store
<TCK value
> as
<current pause time
>