Comments 33
Спасибо, ждём продолжения (уровнем не ниже цикла про ВЧ магию :)).
Любопытно было посмотреть на вашу реализацию. А диаграммы в чём вы рисовали?
Пользуясь отладчиком, всегда была интересно: "что происходит внутри микросхемы?". БОльшая часть статей, как вы и упомянули, написана так, что терпения и желания дочитать даже до середины не хватало:)
Отличная статья, все красиво нарисовано, описано буквально по шагам - очень жду продолжения цикла;)
Автор, ввиду примеров на SystemVerilog хотелось бы узнать. Может ли цикл статей завести нас в особенности использования JTAG именно в ПЛИС? Там ведь он используется не только для классических задач: граничное сканирование (Boundary Scan) и дебага кода как, например, в MCU. Но также и для "прошивки" ПЛИС, управления внутренней логикой (с использованием специальных ip-корок, конечно), дебагом внутренностей проекта (различные SignalTap, ChipScope и т.д.).
Во-первых, хотел бы поблагодарить вас за прочтение статьи и ваши комментарии. Это всегда приятно.
Во-вторых, я бы не хотел загадывать наперёд, на каком месте закончится данный цикл. А то пообещаю, не сделаю, а потом меня будет мучать совесть :) Но. Не хотелось бы говорить фразу, которую уже давно отсеивает баннерная слепота глухота про "лайк-репост-подписку", однако, если я всё же напишу про управление внутренней логикой, то (на сколько я понимаю), в случае вашей подписки, вы не пропустите данную статью :)
В любом случае, спасибо, что обозначили потребность в данной тематике. Это мотивирует.
Прекрасная статья, грамотно написана и отлично читается. Подписался, ждём новых статей по BSDL и SystemVerilog.
Вскользь упоминаемая SPEA отрабатывает значительно более широкий круг задач, большинство которых JTAG никогда не решит. Я осваивал в 2009 году первую и единственную на тот момент времени SPEA в России. Написание кода для неё - та ещё задача. Но гораздо сложнее заставить конструкторов делать посадочные места компонентов в соответствии с требованиями инженеров SPEA.
Интересный цикл статей, самому разбираться с 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. Они как раза рассказывают про то, что "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.
Готовой инструкции я не нашёл, но завтра постараюсь поиграть с STM32 при помощи TopJTAG Probe. Если всё будет успешно, напишу вам что где качать и что где нажимать.
Наличие модуля JTAG в микросхеме позволяет при помощи интерфейса JTAG ввести микросхему в тестовый режим и установить любое логическое состояние на любом выходном пине
Ну закоротили вы при пайке два соседних пина.
По Jtag на оном поставили 1 на другом 0.
В результате сожгли пины...
Успех!
Надо не "логическое состояние на любом выходном пине" устанавливать, а подтяжку на пине. Причем ещё не только устанавливать, но и одновременно читать.
https://habr.com/ru/articles/762142/
В самом названии JTAG скрывается Joint Test Action Group. В добавление к посту выше скажу, что можно управлять и одной микросхемой с JTAG тестируюя реакцию остальной схемы, которая без JTAG.
Разглядывая JTAG: идентификация