Как стать автором
Обновить

Разглядывая JTAG: идентификация

Время на прочтение19 мин
Количество просмотров16K
Всего голосов 52: ↑52 и ↓0+52
Комментарии31

Комментарии 31

Спасибо, ждём продолжения (уровнем не ниже цикла про ВЧ магию :)).

Любопытно было посмотреть на вашу реализацию. А диаграммы в чём вы рисовали?

Спасибо.
Я их рисовал в InkScape. Включив сетку, подобные вещи там рисовать весьма удобно - как на клетчатой бумаге. А потом можно поиграть с толщиной и цветом.

Пользуясь отладчиком, всегда была интересно: "что происходит внутри микросхемы?". БОльшая часть статей, как вы и упомянули, написана так, что терпения и желания дочитать даже до середины не хватало:)
Отличная статья, все красиво нарисовано, описано буквально по шагам - очень жду продолжения цикла;)

Автор, ввиду примеров на SystemVerilog хотелось бы узнать. Может ли цикл статей завести нас в особенности использования JTAG именно в ПЛИС? Там ведь он используется не только для классических задач: граничное сканирование (Boundary Scan) и дебага кода как, например, в MCU. Но также и для "прошивки" ПЛИС, управления внутренней логикой (с использованием специальных ip-корок, конечно), дебагом внутренностей проекта (различные SignalTap, ChipScope и т.д.).

Во-первых, хотел бы поблагодарить вас за прочтение статьи и ваши комментарии. Это всегда приятно.

Во-вторых, я бы не хотел загадывать наперёд, на каком месте закончится данный цикл. А то пообещаю, не сделаю, а потом меня будет мучать совесть :) Но. Не хотелось бы говорить фразу, которую уже давно отсеивает баннерная слепота глухота про "лайк-репост-подписку", однако, если я всё же напишу про управление внутренней логикой, то (на сколько я понимаю), в случае вашей подписки, вы не пропустите данную статью :)
В любом случае, спасибо, что обозначили потребность в данной тематике. Это мотивирует.

Прекрасная статья, грамотно написана и отлично читается. Подписался, ждём новых статей по BSDL и SystemVerilog.

Вскользь упоминаемая SPEA отрабатывает значительно более широкий круг задач, большинство которых JTAG никогда не решит. Я осваивал в 2009 году первую и единственную на тот момент времени SPEA в России. Написание кода для неё - та ещё задача. Но гораздо сложнее заставить конструкторов делать посадочные места компонентов в соответствии с требованиями инженеров SPEA.

SPEA отрабатывает значительно более широкий круг задач, большинство которых JTAG никогда не решит

Точно также, как и рентгеновская установка никогда не будет заменена отладчиком JTAG. Однако, в рамках маркетинговых статей подобные обороты периодически встречаются.

Интересный цикл статей, самому разбираться с JTAG не было времени и сил.

В логике конечного автомата лишние begin-end. Используя тернарный оператор "?:" можно переделать "if"-ы и привести к более табличному виду:

always @(posedge tck)
	case(jtag_fsm)
		TEST_LOGIC_RESET: jtag_fsm <=	tms ? TEST_LOGIC_RESET : RUN_TEST_IDLE;
		RUN_TEST_IDLE:    jtag_fsm <=	tms ? SELECT_DR_SCAN   : RUN_TEST_IDLE;
		
		SELECT_DR_SCAN:   jtag_fsm <=	tms ? SELECT_IR_SCAN   : CAPTURE_DR;
		CAPTURE_DR:       jtag_fsm <=	tms ? EXIT1_DR         : SHIFT_DR;
		SHIFT_DR:         jtag_fsm <=	tms ? EXIT1_DR         : SHIFT_DR;
		EXIT1_DR:         jtag_fsm <=	tms ? UPDATE_DR        : PAUSE_DR;
		PAUSE_DR:         jtag_fsm <=	tms ? EXIT2_DR         : PAUSE_DR;
		EXIT2_DR:         jtag_fsm <=	tms ? UPDATE_DR        : SHIFT_DR;
		UPDATE_DR:        jtag_fsm <=	tms ? SELECT_DR_SCAN   : RUN_TEST_IDLE;
		
		SELECT_IR_SCAN:   jtag_fsm <=	tms ? TEST_LOGIC_RESET : CAPTURE_IR;
		CAPTURE_IR:       jtag_fsm <=	tms ? EXIT1_IR         : SHIFT_IR;
		SHIFT_IR:         jtag_fsm <=	tms ? EXIT1_IR         : SHIFT_IR;
		EXIT1_IR:         jtag_fsm <=	tms ? UPDATE_IR        : PAUSE_IR;
		PAUSE_IR:         jtag_fsm <=	tms ? EXIT2_IR         : PAUSE_IR;
		EXIT2_IR:         jtag_fsm <=	tms ? UPDATE_IR        : SHIFT_IR;
		UPDATE_IR:        jtag_fsm <=	tms ? SELECT_DR_SCAN   : RUN_TEST_IDLE;
	endcase

Теперь код FSM влезает на одну страничку.

BTW, хабровский редактор знает подсветку синтаксиса VHDL, но нет подсветки для Verilog. Грустно.

Теперь код FSM влезает на одну страничку.

Симпатично выглядит. Можно и так. Правда строчки становятся слишком длинными и не очень человекочитаемый язык - без "если-то-иначе". Ну тут как с "camelCase" и "snake_case" - дело вкуса.

хабровский редактор знает подсветку синтаксиса VHDL, но нет подсветки для Verilog.

Я за неимением подсветки Verilog-а включаю подсветку C++.

Исследовал как использовать JTAG UART или сырой JTAG.

Наткнулся на блог Тома. У Тома целый цикл статей с попыткой уйти от проприетарного альтеровского JTAG-UART и nios-terminal.

Собственно, Том пишет конечный автомат в таком же стиле...

https://tomverbeure.github.io/2021/10/30/Intel-JTAG-Primitive.html

Также, в вашей последней статье я заметил, что пины назначены:

tms -> E10
tck -> B11
tdi -> D11
tdo -> B12

Что эквивалентно GPIO[27,29,31,33].

Настоящие же TCK,TMS,TDI,TDO подключены к H3,J5,H4,J4.

Думаю, многим разработчикам интересно именно переиспользование порта JTAG в качестве последовательного/отладочного порта для отладки или пост-настройки окружения.

Тратить же пины, чтобы сделать кастомный JTAG - с таким же успехом можно на 4 пина повесить SPI, 2xUART, 2xI2C.

В контексте статей, кастомный JTAG сделан для иллюстрации работы протокола. Если после текста и схем у читателя остались неразрешённые вопросы, он может изучить код кастомного JTAG и возможно этот взгляд с третей стороны дорисует в сознании полную картину. Практическая ценность с точки зрения промышленного кода (в особенности - реализация протокола на Си) здесь минимальна.

Ваша иллюстрация работы протокола это хорошо, как минимум ваш цикл статей пробудил в аудитории интерес к JTAG.

Хотелось бы еще увидеть моделирование в modelsim. Т.к. неясно какие сигналы подает USB-бластер. Можно, конечно, зафорвадить сигналы на другие пины и снять осциллограмму logic-аналайзером (возможно и через signaltap).

Ну и второй вопрос: есть ли у вас в планах статья об использовании родного интерфейса JTAG на DE0-Nano в промышленных целях? Тот же проприетарный JTAG UART, Virtual JTAG или свой собственный протокол через команды USER0, USER1?

Хотелось бы еще увидеть моделирование в modelsim. Т.к. неясно какие сигналы подает USB-бластер.

Следует разделить ModelSim и USB-бластер.

То, что выдаёт USB-бластер, а также прочие отладчики либо максимально приближено к приводимым в цикле статей иллюстрациям, либо отличается от них самым причудливым образом. Так, связка "TopJTAG Probe+FT2232" при проверке идентификационного номера зачем-то проверяет также и регистр инструкций, пытаясь поместить в него очень странную длинную последовательность. Можно, конечно, написать разработчику и уточнить, но это (в отличие от причуд самого стандарта JTAG) столь частный случай, объяснимый к тому же чем-нибудь вроде "Ааа. Ну это мы когда тестировали ПО забыли закомментировать отладочный код, но он же не должен вроде мешать, да?", что разбирать его нет особого смысла.

Результаты моделирования в ModelSim также дадут лишь повторение тех изображений, что уже приводились. Кроме того, всё, что заработало в ПЛИС - заработает и в ModelSim, обратное - не всегда верно. Не вижу, что особо ценного ModelSim мог бы привнести сверх того, что было написано в цикле.

есть ли у вас в планах статья об использовании родного интерфейса JTAG на DE0-Nano в промышленных целях? Тот же проприетарный JTAG UART, Virtual JTAG или свой собственный протокол через команды USER0, USER1?

Были очень отдалённые планы написать про SVF. Проприетарный JTAG-UART, как мне кажется, специфичен столь сильно, что это будет мало кому интересно. Количества читателей, в моём представлении, распределены следующим образом:
Программисты > Электронщики > ПЛИСоводы > специалисты по Альтере > те, кому интересен JTAG-UART.

Как выглядит общая бинарная структура пакета на шине JTAG?

В общем виде в JTAG отсутствует понятие пакета. Данный термин можно ввести в рамках некоторой надстройки над JTAG-ом. Но тогда нужно определиться, какого рода действия вы планируете выполнять при помощи типового пакета.

Как при помощи jtag делать тест на пропай?

Наличие модуля JTAG в микросхеме позволяет при помощи интерфейса JTAG ввести микросхему в тестовый режим и установить любое логическое состояние на любом выходном пине. Либо прочитать логическое состояние на любом входном пине.

Соответственно, если две микросхемы с JTAG-ом соединены друг с другом какой-нибудь, скажем, параллельной шиной, то при помощи JTAG возможно приказать одной микросхеме установить на шине характерный паттерн, а с другой микросхемы считать его. Затем поменять его и снова считать. Если считывается то, что было установлено, значит непропаев нет.

Вот здесь парни сделали крупный наглядный выставочный стенд, иллюстрирующий работу JTAG. Они как раза рассказывают про то, что "You can find the solder failure..."

Вот здесь небольшое руководство по работе с ПО, осуществляющим в том числе прозвонку межсоединений при помощи JTAG.

Наличие модуля JTAG в микросхеме позволяет при помощи интерфейса JTAG ввести микросхему в тестовый режим и установить любое логическое состояние на любом выходном пине. Либо прочитать логическое состояние на любом входном пине.

Есть ли инструкция того как это делать на микроконтроллере STM32?

Я писал свой JTAG на STM32, где прогружал битстрим в Cyclone IV а потом через Boundary Scan контроллировал бит CONFIG_DONE, чтобы убедиться что битстрим прогружен. Сам Cyclone IV был подключём к другим ногам к этой же STM32 и будучи прогруженным взаимодействовал с ним посредством аппаратных SPI, CAN, USART и т.д.

Ммм. Не очень понимаю, зачем же вы писали именно JTAG, когда для заливки в четвёртый Циклон достаточно было бы сымитировать EPCS16, которая работает банальнейшим образом.

Потому, что STM на ходу мог менять прошивки FPGA, меняя таким образом и текущее назначение прибора. Конфигурационное устройство там не нужно.

Любопытно, конечно, было бы узнать назначение устройства - так ли уж нужна была в нём динамическая реконфигурация.

Автономное универсальное устройство. Экранчик, STM32F437 как "мозг" и Cyclone IV 22k LE как логика связи с внешним миром. FPGA прогружается в зависимости от задачи, модули кода так же загружаются в ОЗУ и работают оттуда у STM32F437, получая сервис основной OS через SVC. Как-то так. Большего сказать, увы, не могу, связан NDA.

Код прогрузки битстрима написан на ассемблере, чтобы получить максимальную скорость от ногодрыга:

// Прогружаем буфер в JTAG через TDI в узком цикле
__attribute__ ((naked)) void WriteJTAGBuf( uint32_t Buf, uint32_t Size )
{	// Все в наших руках
	__asm volatile
	(	// Вводная часть
		"PUSH	{R0-R8}\n"
		// План распределения регистров
		// R0 - указатель на массив данных
		// R1 - счетчик байт
		"ORRS	R1, R1, #0\n"
		"BEQ	WriteJTAGExit\n"
		// R2 - указатель на GPIOD->BSRR
		"MOVW	R2, #0x0C18\n"
		"MOVT	R2, #0x4002\n"
		// R3 - Установить TDI в 1
		"MOVW	R3, #0x8000\n"
		"MOVT	R3, #0x0000\n"
		// R4 - Сбросить TDI в 0
		"MOVW	R4, #0x0000\n"
		"MOVT	R4, #0x8000\n"
		// R5 - Установить TCK в 1
		"MOVW	R5, #0x1000\n"
		"MOVT	R5, #0x0000\n"
		// R6 - Сбросить TCK в 0
		"MOVW	R6, #0x0000\n"
		"MOVT	R6, #0x1000\n"
		// R7 - Счетчик бит (8 за раз)
		// R8 - Временный регистр с данными
		"WriteJTAGLoop:\n"
		// Цикл BYTEов
		"LDRB	R8, [R0, #0]\n"
		"ADD	R0, R0, #1\n"
		"MOVW	R7, #0x0008\n"
		"MOVT	R7, #0x0000\n"
		"WriteJTAGBits:\n"
		// Цикл бит BYTEа
		"LSRS	R8, #1\n"
		"BCS	WriteJTAGOne\n"
		"STR	R4, [R2, #0]\n"
		"B		WriteJTAGCont\n"
		"WriteJTAGOne:\n"
		"STR	R3, [R2, #0]\n"
		"B		WriteJTAGCont\n"
		"WriteJTAGCont:\n"
		"STR	R5, [R2, #0]\n"
		"SUBS	R7, #1\n"
		"NOP\n"
		"NOP\n"
		"NOP\n"
		"STR	R6, [R2, #0]\n"
		"BNE	WriteJTAGBits\n"
		"SUBS	R1, #1\n"
		"BNE	WriteJTAGLoop\n"
		// Конец
		"WriteJTAGExit:\n"
		"POP	{R0-R8}\n"
		"BX		LR\n"
	);
}

780 килобайт RBF прогружается примерно 0.1-0.2с. Точно не измерял, но конкретно для того проекта всё, что менее 1с считалось нормой. С-шный вариант грузил около 1,5с даже с тугой оптимизацией. Его ASM код был напичкан всяким мусором, увы.

В таком случае не вполне понятно, чего не сделать полное реконфигурирование ПЛИС, которое было бы проще запрограммировать? Да, оно будет длится чуть дольше и на время конфигурирования ПЛИС не сможет взаимодействовать с внешним миром. Ну так и что же?

Мне кажется, что JTAG здесь избыточен.

Мне кажется, что JTAG здесь избыточен.

Забыл уточнить, JTAG там не только для реконфигурирования FPGA. Там на самом деле планировался daisy chain с FPGA у корня и JTAG выведен на краевой системный разъём. Что именно туда потом подключил заказчик меня не информировали (возможно специально), а делать отдельно JTAG и отдельно эмулятор реконфигуратора вот как раз избыточная задача. К тому же остальные интерфейсы должны были быть свободными, а ногодрыг на 10МГц, которые выдаёт FPGA при реконфигурировании, это уж слишком, хотя и возможно.

PS Проще не всегда выгоднее. Кстати, реконфигурирование FPGA доступно загружаемому модулю, в том числе он может указать какой битстрим следует грузить с локальной SD карты.

Субъективно я не проникся вышеперечисленными доводами. Мне всё ещё кажется, что имитатор EPCS16 был бы здесь несколько уместнее. Не исключаю, однако, что я не прав. Вам на месте было конечно было виднее, возможно были и ещё какие-то доводы в пользу JTAG.

возможно были и ещё какие-то доводы в пользу JTAG

В том числе и сабж данной ветки обсуждения: Boundary Scan. И не только для контроля за CONFIG_DONE, но и тестовый модуль, который делал тест аппаратуры использует написанный JTAG для контроля интерфейсной части, подключенной к FPGA.

Готовой инструкции я не нашёл, но завтра постараюсь поиграть с STM32 при помощи TopJTAG Probe. Если всё будет успешно, напишу вам что где качать и что где нажимать.

В самом названии JTAG скрывается Joint Test Action Group. В добавление к посту выше скажу, что можно управлять и одной микросхемой с JTAG тестируюя реакцию остальной схемы, которая без JTAG.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории