четверг, 24 ноября 2011 г.

JTAG

Поскольку в своё время у меня возникли проблемы с пониманием довольно специфичного протокола JTAG, то я решил сделать небольшое описание механизмов его работы, не затрагивая его прикладную сторону; так сказать, на пальцах, чтобы вы не тупили столько же времени, что и я.

Сначала о проводах. JTAG-интерфейс предполагает 4 обязательных и 1 опциональный сигнал:
  • TDI (test data in) - входные по отношению к JTAG-устройству данные;
  • TDO (test data out) - исходящие данные;
  • TMS (test mode state) - сигнал управление внутренней state-машиной;
  • TCK (test clock) - тактирующий сигнал;
  • TRST (test reset) - сброс JTAG-контроллера. Этот провод опционален.
Пусть вас не смущает повсеместно присутствующее слово "test". JTAG изначально был создан для пограничного сканирования ИС и проводников печатных плат. Про это сейчас можно забыть.

Входящие сигналы (TDI & TMS) записываются в JTAG-устройство по переднему фронту сигнала TCK. Исходящий (TDO) выставляется самим устройством по заднему фронту сигнала TCK.

Рис 1.

На Рис. 1 приведён пример осциллограммы с шины JTAG (сиганалы TMS & TDI намеренно приведены в хаотичном виде - реальные генераторы этих сигналов будут выдерживать некий временной "стиль").
Если зыбать про сигнал TMS, в данной примере можно видеть, что ИС пропускает через себя все входящие сигналы (TDI) наружу (TDO) с задержской в 1 такт TCK. К этому мы ещё вернёмся.


Внутри любого JTAG-устройства имеется TAP (Test Access Port ) - его state-машина.

Рис. 2.

Состояние TAP (одно из допустимых состояний, которые изображены на Рис. 2) определяется сигналом TMS: тактируя высокий или низкий уровень TMS мы указываем TAP-у направится по направлению '1' или '0', соответственно, в его диаграмме состояний.

По подаче питания TAP находится в неопределённом состоянии. В этом случае нам следует дать команду сброс JTAG-контроллеру, а его TAP-контроллер перевезти в исходное состояние (Run-Test/Idle).
Если внимательно посмотреть на диаграмму, то можно видеть, что, если подать 5 единичек на вход TMS (разумеется, тактировав их, иначе, не имеет смысла), то мы обязательно добежим по диаграмме до состояния Test Logic Reset, в каком бы состоянии мы бы не неаходились. А если подать шестой TMS, то TAP "кувырнётся" в это же состояние, сделав внутренний сброс JTAG-контроллера (и, возможно, внутренней логике ИС - это уже дело производителя). Следующий нуль на TMS поставит TAP в Idle.
Работу с устройством всегда следует начинать с данной процедуры. Следующие примеры двух равнозначных осциллограмм (Рис. 3) описывают сценарий последовательности по включению питания (уровень TDI не имеет значения).

Рис. 3.


Теперь разберёмся, зачем вобще нужно столько состояний JTAG-контроллеру и как, собственно, этим JTAG пользоваться. Помимо уже описаных двух состояний Test Logic Reset и Idle нас интересуют ShiftIR и ShiftDR.
У JTAG-контроллера если некоторое количество регистров данных, записывая информацию в которые мы и осуществляем управление ИС. Эти регистры доступны на запись только в состоянии ShiftDR (shift data register). Но как же нам обратиться к интересуещему нас в данный момент регистру данных, если предусмотрено лишь одно состояние для доступа к нему? Для этого служит регистр инструкций (один единственный), который доступен в состоянии ShiftIR (расшифровки не требуется). Этот регистр является "стрелочником", которые отправляет поезда-данные, приходящие по монорельсу TDI в ИС. Гипотетически, если размер регистра инструкции равен четырём и если в состоянии ShiftIR по TDI передать '0000' (четыре нуля), то, перейдя в ShiftDR мы можем записывать данные в регистр данных 'A' (название - с потолка), а записав в инструкцию '0001' (младший бит - вперёд!), будет доступен регистр 'B'.

Рис. 4.

Стандарт JTAG предполагает обязательные и опциональные инструкции. Так любой производитель ИС может установить свои инструкции, необходимые для работы с его жуком.
Рассмотрим несколько общих инструкций.
  • IDCODE - если передать n-ое количество TDI при установленной этой инструкции, то на выходе (TDO) чип "выплюнет" некий идентификатор устройтва;
  • BYPASS - регистр для "обхода" ИС. Этот регистр данных имеет длинну в 1 бит и входные сигналы просто передаются на выход с опознанием в 1 такт (см. Рис. 1);
  • EXTEST - тестирование проводников печатной платы.

Теперь о том, что когда-то ввело меня в полное непонимание происходящего вокруг. ИС в вашем устройстве, поддерживающие JTAG, не обязаны быть подключенными к отдельному JTAG-интерфейсу. Это было бы очень накладно с точки зрения места на печатной плате и портов ввода-вывода управляющего контроллера. Для объединения ИС их можно подключить в последовательную цепочку (JTAG chain):
  • TDO предыдущего - на TDI последующего;
  • TMS & TCK подключены параллельно ко всем устройствам в цепочке.
Принципиально это выглядин так:

Рис. 5.

Для понимания работы этой цепочки надо знать, что регистр инструкций и все регистры данных - сдвиговые. Что такое сдвиговый регистр? Представьте себе трубу (регистр) определённой длинны (собственно, длина регистра в битах), у которой есть вход (TDI), выход (TDO) и какое-то наполнение в данный момент. Если мы будем записывать в TDI этой трубы нолики и единички, то данные, которые в данный момент находятся у другого конца трубы будут выплёвываться наружу через TDO.

JTAG-цепочка имеет общие TCK и TMS, таким образом все устройства в цепи скачут по TAP-контроллеру одинаково, т.е. в определённый момент времени TAP-контроллер всех жуков находится в одном и том же состоянии (если, конечно, правильно произвести сброс).

Задача для цепочки с Рис. 5 (для простоты предположим, что у нас 3 JTAG-устройства в цепи):
    Записать данные в устройства в соответствии со следующими требованиями:
  • В device 0 записать '0100101' в 7-битный регистр 'HEHE', соответствующий инструкции '0110';
  • В device 1 записать '0100' в 4-битный регистр 'BEBE', соответствующий инструкции '0010';
  • В device 2 записать '01000110100' в 11-битный регистр 'MEME', соответствующий инструкции '1011'.
Для этого нужно учитывать факт того, что "посылка", идущая первой, попадёт в последний девайс.
Последовательность действий:
  • Сделать общий сброс ('1111110' на TMS; TDI не имеет значения);
  • Перевести девайсы в состояние ShiftIR;
  • Передать последовательность TDI (младший бит - вперёд): 0110'0010'1011 (здесь апострофы лишь для визуального выделения).
  • Перевезти девайсы в состояние ShiftDR (через Idle);
  • Передать последовательность TDI: 0100101'0100'01000110100.
В конце приведу пример битсрима для данной задачи (года 2 назад отдал бы почку за такую информацию). Советую держать диаграмму состояний TAP-контроллера перед глазами.

Первая колонка - TDI, вторая - TMS.

01
01
01
01
01
01 # Гарантированно прокрутились в Reset
00 # Idle
01
01
00
00
10 ##### TAP "застрял" в ShiftIR
10 # Инструкция
00 # для dev 2
10 #####
00 #####
10 # Для dev 1
00 #
00 #####
00 #####
10 # Для dev 0
10 #
01 ##### Одновременно с последним битом сваливаем из ShiftIR
01
00
00 # Idle
01
00
00
00 # Первый бит для ShiftDR
00 #
10 #
00 #
10 #
10 #
00 #
00 #
00 #
10 #
00 ##### Последний бит данных для регистра 'MEME' dev 2
00 ##### Данные для 'BEBE' dev 1
00 #
10 #
00 #####
10 ##### Для 'HEHE' device 0
00 #
10 #
00 #
00 #
10 #
01 ##### Как всегда, побежали в исходный Idle
01
00
00 # Idle

Btw, насколько я знаю, все (или почти все) JTAG-устройства при передачи данных или инструкций требуют замыкающий бит чётности. Т.е. если фактическая инструкция имеет размер в 4 бита, то в ShiftIR мы должны записать 5 бит. Например, пересывая инструкцию '0111' с выходом из ShiftIR (TMS == 1) мы отправим ещё один положительный TDI, поскольку сумма переданных битов - нечётная. То же верно и для регистров данных. В приведённом битстриме это не учитывается.


Комментариев нет:

Отправить комментарий