Pull to refresh

Разглядывая JTAG: *.bsdl своими руками

Reading time15 min
Views7.4K
  1. Разглядывая JTAG: идентификация

  2. Разглядывая JTAG: *.bsdl своими руками

  3. Разглядывая JTAG: что внутри?

  4. Разглядывая JTAG: самый быстрый программный JTAG на Arduino

В предыдущей статье мы немного поработали с конечным автоматом модуля JTAG в контексте чтения идентификационного номера. Совершённые нами манипуляции были бы одинаковы практически для любой микросхемы с JTAG-ом. Однако при попытке установить/считать через JTAG уровень напряжения на произвольном выводе микросхемы мы столкнёмся с объективной проблемой: количество выводов, их назначение и расположение у разных микросхем принципиально отличаются. Для того, чтобы у ПО, управляющего JTAG-ом была информация об этих отличиях, ему необходим файл описания модуля JTAG для конкретной микросхемы. Об этих файлах и пойдёт речь в данной статье.

Файл *.bsdl содержит ряд параметров модуля JTAG. Сейчас, в 2022 году может показаться, что разумнее всего было бы использовать для подобной цели нечто вроде XML. Проблема в том, что первый стандарт JTAG — IEEE1149.1 — был выпущен в 1990 году, тогда как XML 1.0 появился лишь в 1998. При современном взгляде на текст файла *.bsdl можно уловить, во-первых, схожесть его синтаксиса с VHDL, во-вторых, избыточность и многословность даже для тех времён. К примеру, при указании длины регистра инструкций можно было бы ожидать чего-то вроде...

entity SIMPLE_IC is
	<...>
	INSTRUCTION_LENGTH	4
	<...>
end SIMPLE_IC;

...или хотя бы...

entity SIMPLE_IC is
	<...>
	attribute INSTRUCTION_LENGTH = 4;
	<...>
end SIMPLE_IC;

Но по стандарту длина регистра инструкций задаётся так:

entity SIMPLE_IC is
	<...>
	attribute INSTRUCTION_LENGTH of SIMPLE_IC : entity is 4;
	<...>
end SIMPLE_IC;

Дело в том, что BSDL появился в стандарте JTAG не сразу в 1990 году, а начиная с версии IEEE1149.1B-1994. До его появления управляющее ПО получало информацию о структуре модуля JTAG напрямую из файлов описания микросхемы, написанных на VHDL. То есть BSDL скорее формализовал действующую на тот момент практику, чем был специально, с нуля, разработан для использования в качестве языка описания модуля JTAG.

За дополнительными разъяснениями я обратился к Кэролу Пайрону (Carol Pyron), представителю от NXP в группе JTAG и, по совместительству, вице-председателю данной группы:

- Добрый день, мистер Пайрон! Почему в качестве основы языка BSDL был взят VHDL?

- Добрый день. Я не принимал непосредственного участия в разработке первой выпущенной версии BSDL, поэтому я не могу вам дать определённый ответ, но я помню, мне говорили, что многие европейские и американские аэрокосмические компании в конце 80-х — начале 90-х использовали VHDL гораздо чаще, чем Verilog. Поскольку большинство людей, участвовавших в разработку BSDL, имели именно такой бэкграунд, был выбран именно этот язык. Конечно, с тех пор Verilog стал намного более распространённым и доминирующем.

Оригинал моей переписки на английском

- Hello, mr. Piron. May I ask you why VHDL was chosen as the base syntax for BSDL?

- Hello. I was not directly involved in the original version of BSDL, so I cannot give you a definitive answer, but I remember being told that VHDL was always more used by many European companies and by American aerospace companies back in the late 80's/ early 90's than Verilog. Since most of the people involved in BSDL had that background, VHDL was selected. Of course since then, Verilog has become much more common and dominate.

На текущий момент в ряде синтаксических конструкций BSDL уже нет прежнего сакрального смысла и обратная совместимость 30-летней давности, возможно, будет несколько резать глаза. Но с этим придётся смириться.

Итак. Всё описание модуля JTAG находится между декларацией имени микросхемы и окончанием описания:

entity SIMPLE_IC is
	--Описание модуля JTAG
end SIMPLE_IC;

Сразу после декларации имени нужно вписать параметр для указания конкретного корпуса:

generic (PHYSICAL_PIN_MAP : string);

Его можно оставить незаполненным, а можно вписать туда какой-нибудь из корпусов, которые будут описаны далее в файле BSDL:

generic (PHYSICAL_PIN_MAP : string := "PLCC20");

Выбор, сделанный в данной декларации, не повлияет на работу с файлом в «TopJTAG Probe» и в данном ПО можно будет выбрать конкретный корпус независимо от указанного в «generic». Однако, по стандарту данная декларация должна присутствовать.

Затем необходимо указать общую структуру входов-выходов, их названия и тип. То, что описывается в разделе «port» — это не совсем выводы микросхемы. Скорее, это контактные площадки кристалла, хотя и это, строго говоря, не совсем верно. Это, скажем так, все возможные контакты микросхемы, описанные с некоторым запасом (чуть дальше будет яснее). В блоке «port» необходимо указать как «полезные» контакты микросхемы, так и контакты самого JTAG, а также контакты питания, земли и отсутствующие контакты — контакты, которые не предполагается соединять с кристаллом:

port  (
	LED: out bit_vector(0 to 7);
	BTN: in  bit_vector(0 to 7);

	TMS: in  bit;
	TDI: in  bit;
	TCK: in  bit;
	TDO: out bit;

	VDD: linkage bit;
	VSS: linkage bit;
	NC:  linkage bit_vector(0 to 9)
);

Здесь всё более-менее интуитивно понятно. Если вывод одиночный — он помечается как «bit». Если это шина, она помечается как «bit_vector(X to Y)». Входы — «in», выходы — «out», двунаправленные линии — «inout».

Линии питания/земли, а также аналоговые входы-выходы и выводы, не соединённые с кристаллом, стандарт настоятельно рекомендует помечать как «linkage». В стандарте IEEE1149.1-2013 вместо «linkage» вводится 10 новых типов вроде «POWER_POS» или «LINKAGE_MECHANICAL». Однако «TopJTAG Probe» их не распознаёт. Кроме того, файлы BSDL, написанные по стандарту 2013 года на текущий момент гораздо менее распространены, чем файлы предыдущих версий стандарта, поэтому мы будем рассматривать, по большей части, версию стандарта 2001 года.

После блока «port» стандарт требует подключить библиотеку стандарта JTAG:

use STD_1149_1_2001.all;

Этой библиотеки у нас нет, но это и не важно — данная строка просто один из рудиментов VHDL.

Итого, подготовительные процедуры приведут нас к следующему коду:

entity SIMPLE_IC is
	generic (PHYSICAL_PIN_MAP : string);
	port  (
		LED:	out bit_vector(0 to 7);
		BTN:	in  bit_vector(0 to 7);
		TMS:	in  bit;
		TDI:	in  bit;
		TCK:	in  bit;
		TDO:	out bit;
		VDD:	linkage bit;
		VSS:	linkage bit;
		NC:	linkage bit_vector(0 to 9)
		);
	use STD_1149_1_2001.all;
	--Атрибуты модуля JTAG
end SIMPLE_IC;

Теперь нам необходимо заполнить некоторое количество атрибутов модуля JTAG. В общем случае, для отдельного атрибута это заполнение будет выглядеть так:

attribute XXX of SIMPLE_IC : entity is YYY;

Последовательность заполнения атрибутов крайне нежелательно изменять. Но некоторые из атрибутов являются необязательными. Их можно пропустить. К примеру, атрибут «RUNBIST_EXECUTION» мы заполнять не будем.

Первым атрибутом будет версия стандарта JTAG. Да-да, мы, уже подключили библиотеку с этим самым названием стандарта, но так надо:

attribute COMPONENT_CONFORMANCE of SIMPLE_IC : entity is "STD_1149_1_2001";

Затем нам необходимо заполнить атрибут «PIN_MAP» не особо осмысленной строкой:

attribute PIN_MAP of SIMPLE_IC : entity is PHYSICAL_PIN_MAP;

А дальше уже интереснее:

constant  PLCC20:PIN_MAP_STRING:=
	"LED:	(1,2,3,4), " &
	"BTN:	(8,7,6,5), " &
	"TMS:	9, " &
	"TDI:	10, " &
	"TCK:	11, " &
	"TDO:	12, " &
	"VDD:	13, " &
	"VSS:	14, " &
	"NC:	(15,16,17,18,19,20) ";

В этой конструкции описывается конкретный корпус микросхемы. После слова «constant» указывается его название, а затем контакты из раздела «port» распределяются по выводам корпуса. Программа «TopJTAG Probe» способна распознать некоторые названия корпусов и подобрать соответствующее схематическое изображение.

Распределение одиночных контактов достаточно прозрачно: один контакт — один вывод. Распределение шин (векторов) происходит в порядке очерёдности контактов в шине. Причём допускается распределить не все контакты из раздела «port».

Стандарт допускает указание нескольких подобных блоков в рамках одного файла BSDL:

constant  PLCC20:PIN_MAP_STRING:=
	"LED:	(1,2,3,4), " &
	<...>
	"NC:	(15,16,17,18,19,20) ";
constant  TQFP32:PIN_MAP_STRING:=
	"LED:	(1,2,3,4,5,6,7,8), " &
	<...>
	"NC:	(29,30,31,32) ";

В таком случае «TopJTAG Probe» не сможет определить нужный корпус автоматически (даже если он был задан в «generic»), но его можно будет выбрать из меню.

Для того, чтобы выбрать в «TopJTAG Probe» определённый тип корпуса надо:

  1. Выбрать пункт меню «Scan→ Dev1 Package...»

  2. В открывшемся окне выбрать тип из списка.

  3. Нажать «Select» для автоопределения типа, количества выводов и их расположения. Затем нажать «OK».

Также, в «TopJTAG Probe» возможно указать параметры корпуса вручную, не прибегая к автоопределению по названию корпуса.

Далее нам нужно задать атрибуты, привязывающие контакты, указанные в разделе «port» к выводам JTAG, а также указать максимальную частоту тактового сигнала TCK. В нашем примере — это 10кГц.

attribute TAP_SCAN_MODE  of TMS : signal is true;
attribute TAP_SCAN_IN    of TDI : signal is true;
attribute TAP_SCAN_CLOCK of TCK : signal is (10.0e3, BOTH);
attribute TAP_SCAN_OUT   of TDO : signal is true;

Следующие атрибуты — особенно важны. В предыдущей статье помимо регистра данных, мы создавали 8-битный регистр инструкций, инициализируемый нулём. Для каждой конкретной модели микросхем длина этого регистра фиксирована. Однако у разных моделей эта длина будет разная. Длина регистра инструкций задаётся при помощи следующего атрибута:

attribute INSTRUCTION_LENGTH of SIMPLE_IC : entity is 8;

Также нам нужно описать сами инструкции и их коды. Существуют обязательные стандартные инструкции, необязательные стандартные инструкции и уникальные инструкции конкретного производителя микросхем. Поводу инструкций стандарт говорит следующее:

The following public instructions shall be provided in all components claiming conformance to this standard: BYPASS, SAMPLE, PRELOAD, and EXTEST. If the optional device identification register is included in a component, the IDCODE instruction shall be provided.

Несмотря на использование слова «shall», а не «must», это именно обязательные инструкции. Как верно отметил уважаемый @ak-fau, в разделе 1.3.1 стандарт сообщает, что:

Material titled “Specifications” contain the rules, recommendations, and permissions that define this standard:
a) Rules specify the
mandatory aspects of this standard. Rules contain the word shall.
b) Recommendations indicate preferred practice for designs that seek to conform to this standard. Recommendations contain the word should.

Однако «TopJTAG Probe» без проблем воспринимает файл BSDL, в котором атрибут, описывающий идентификационный код отсутствует, а из всех инструкций имеется лишь «MY_INSTRUCTION». Также имеется одна небольшая деталь, привнесённая стандартом 2001 года. Если раньше инструкции «SAMPLE» и «PRELOAD» совмещались в единую инструкцию «SAMPLE/PRELOAD» (в тексте файла BSDL она записывалась как просто «SAMPLE»), то стандарт 2001 года требует отдельного упоминания каждой из обоих инструкций, но им можно указать один и тот же код.

Не углубляясь сейчас в предназначение инструкций «EXTEST» и «SAMPLE/PRELOAD», поговорим про «IDCODE» и «BYPASS».

Представим, что у нас имеется цепь из 3-х микросхем. Каким образом мы сможем за наиболее короткое время определить идентификационный номер первой микросхемы в цепи?

Мы можем действовать также, как в предыдущей статье:

  1. Подадим 5 единиц по TMS и введём все микросхемы цепи в состояние «TEST LOGIC RESET». Это займёт 5 тактов.

  2. Переведём все микросхемы цепи в состояние «SHIFT DR». Это займёт ещё 4 такта.

  3. Протактируем полный сдвиг 32-битных регистров идентификационного кода трёх микросхем — два регистра микросхем, находящихся за интересующей нас микросхемой, плюс, собственно, интересующий нас регистр. То есть 32х3=96 тактов.

Итого: 105 тактов.

Однако, мы можем поступить и иначе:

  1. Подадим 5 единиц по TMS и введём все микросхемы цепи в состояние «TEST LOGIC RESET» — 5 тактов.

  2. Переведём все микросхемы цепи в состояние «SHIFT IR» — 5 тактов.

  3. Размер регистра инструкций произволен, но часто составляет 3-4 бита. Пускай, для 3-х микросхем нашей воображаемой цепи длина регистров инструкций будет 8 бит, 5 бит и 3 бита. Итого — 16 бит. Составим такой 16-битный пакет, в котором в начале будет 3‑битный код инструкции «BYPASS» третей микросхемы, затем 5‑битный код инструкции «BYPASS» второй микросхемы и, наконец, 8‑битный код инструкции «IDCODE» первой микросхемы. Отметим, что для различных микросхем коды инструкции «BYPASS» могут различаться.

  4. Введём эту последовательность через TDI. Это займёт у нас «16-1» тактов (почему «-1» разберёмся позже). Длина регистра инструкций для каждой конкретной микросхемы является строго фиксированной величиной. А вот длина регистра данных — нет. И, вводя определённые коды в регистр инструкций, совершенно различные регистры разной длины могут подключаться в качестве регистра данных. В частности, код инструкции «IDCODE» подключает в качестве регистра данных 32-битный регистр, заполненный идентификационным кодом, а код инструкции «BYPASS» подключает в качестве регистра данных регистр длиной 1 бит, заполненный нулём.

  5. Теперь переведём все микросхемы цепи из состояния «SHIFT IR» в состояние «SHIFT DR». На это уйдёт 5 тактов.

  6. И, наконец, протактируем два бита регистров «BYPASS» двух микросхем, стоящих перед целевой, а также 32 бита идентификационного кода. На это уйдёт ещё 34 такта.

Итого: 64 такта.

Быстрее на 40%. Очевидно, чем больше микросхем в цепи, тем выгоднее использовать инструкцию «BYPASS».

Вернёмся к заполнению файла BSDL. Чтобы присвоить коды инструкциям, заполним следующий атрибут:

attribute INSTRUCTION_OPCODE of SIMPLE_IC : entity is
	"IDCODE (00000001)," &
	"EXTEST (00000010)," &
	"BYPASS (11111111)," &
	"SAMPLE (00000100) ";

Одной команде можно присвоить сразу несколько разных кодов. Например, так:

"BYPASS (11111111,00000101,0001XXXX)," &

Здесь «X» будет пометкой для управляющего ПО, что значения бит на этих позициях могут быть любые.

Пара важных замечаний относительно инструкции BYPASS.
Во-первых: пункт «b» раздела 8.4.1 стандарта IEEE1149.1 сообщает:
«A binary code for BYPASS instruction shall be {111...1} (i.e., a logic 1 entered into every instruction register cell)».
То есть код инструкции BYPASS должен в обязательном порядке состоять из одних единиц (правда пункт «f» того же раздела разрешает иметь несколько кодов помимо обязательного).
Во-вторых: пункт «d» раздела 8.1.1 стандарта IEEE1149.1 сообщает:
«Instruction binary codes that are not otherwise required to provide control of test logic shall be equivalent to the BYPASS instruction».
То есть если устройству был передан код, который не совпадает ни с одной инструкцией, реакция устройства должна быть такой же, как если бы ему передали код BYPASS.

В прошлой статье мы инициализировали регистр инструкций нулём. Причём делали это в состоянии «TEST LOGIC RESET». В реальности, регистр инструкций инициализируется в состоянии «CAPTURE IR». В файле BSDL указывается, чем именно инициализируется регистр инструкций:

attribute INSTRUCTION_CAPTURE of SIMPLE_IC : entity is "0000001";

Однако есть ограничение стандарта: младший бит обязательно должен быть единицей, а следующий бит — нулём, то есть в начале инициализирующего значения должно стоять «01».

Заполним атрибут файла BSDL, отвечающий за идентификационный номер тем же числом h0AA55003, что использовали в предыдущей статье:

attribute IDCODE_REGISTER of SIMPLE_IC : entity is
	"0000" &             -- код ревизии или чего-нибудь типа того
	"1010101001010101" & -- код модели микросхемы hAA55
	"00000000001" &      -- код производителя (соответствует AMD)
	"1";                 -- единица по стандарту IEEE1149.1

Как указывалось выше, различные коды, помещаемые в регистр инструкций, способны подключить в качестве регистра данных различные внутренние регистры. Помимо подключаемых регистров, с которыми мы работали чуть выше — «BYPASS» и «DEVICE_ID» — в модуле JTAG имеется, если так можно выразиться, самый главный подключаемый регистр — «BOUNDARY». Какая именно инструкция подключит в качестве регистра данных какой именно регистр — определяет атрибут «REGISTER_ACCESS»:

attribute REGISTER_ACCESS of SIMPLE_IC : entity is
	"DEVICE_ID (IDCODE)," &
	"BYPASS   (BYPASS)," &
	"BOUNDARY (EXTEST, SAMPLE)";

По аналогии с инструкциями, которые могут быть стандартными, а могут быть уникальными для конкретного производителя микросхем (или конкретной модели), также и подключаемые регистры модуля JTAG могут не ограничиваться списком из «DEVICE_ID», «BYPASS» и «BOUNDARY». И, введя в атрибуте «INSTRUCTION_OPCODE» инструкцию «MY_INSTRUCTION», можно в атрибуте «REGISTER_ACCESS» сообщить управляющему ПО о желании подключать нестандартный регистр, если соответствующая инструкция была загружена в регистр инструкций:

attribute REGISTER_ACCESS of SIMPLE_IC : entity is
	<...>
	"MY_REG[8] (MY_INSTRUCTION)," & -- здесь «8» это длина регистра
	<...>

Кроме того, в данном атрибуте можно указать, каким значением должен быть проинициализирован подключаемый регистр при попадании модуля JTAG в состояние «CAPTURE DR»:

"MY_REG[8] (MY_INSTRUCTION CAPTURES 01010101)," &

Однако, по поводу данного атрибута стандарт говорит следующее:

The association of registers with the BYPASS, CLAMP, EXTEST, HIGHZ, IDCODE, INTEST, PRELOAD, SAMPLE, and USERCODE instructions is mandated by this standard. Descriptions of these assignments are redundant and not needed in BSDL. But if they are given, they shall be checked against the mandatory assignment specified in this standard and an error issued if they are not correct; and they shall not have a “CAPTURES” element in their description.

Иными словами, для стандартных инструкций используются стандартные подключаемые регистры и их явное соотнесение в файле BSDL будет носить скорее справочно‑декоративный характер. Поэтому у ряда микросхем атрибут «REGISTER_ACCESS» будет заполнен не для всех инструкций и подключаемых регистров, а программа «TopJTAG Probe» принимает на вход файлы BSDL даже с отсутствующим атрибутом «REGISTER_ACCESS». Но если мы всё-таки решим расписать данный атрибут полностью, то метка «CAPTURE» с указанием значения по умолчанию в стандартных подключаемых регистрах будет являться синтаксической ошибкой.

Наконец мы подходим к атрибутам самого главного подключаемого регистра. JTAG наиболее известен возможностью при помощи четырёх проводов «пошевелить» практически любым выводом микросхемы. Соответственно, где-то внутри модуля JTAG должна иметься структура, отвечающая за каждый доступный вывод микросхемы. Такой структурой является подключаемый регистр «BOUNDARY».

Для начала нам потребуется задать длину данного регистра:

attribute BOUNDARY_LENGTH of SIMPLE_IC : entity is 8;

А затем — связать доступные для манипуляций выводы микросхемы с битами данного регистра:

attribute BOUNDARY_REGISTER	of SIMPLE_IC : entity is
	"0 (BC_1, LED(0), output2, X)," &
	"1 (BC_1, LED(1), output2, X)," &
	"2 (BC_1, LED(2), output2, X)," &
	"3 (BC_1, LED(3), output2, X)," &
	"4 (BC_1, BTN(0), input,   X)," &
	"5 (BC_1, BTN(1), input,   X)," &
	"6 (BC_1, BTN(2), input,   X)," &
	"7 (BC_1, BTN(3), input,   X)" ;

В простейшем случае строка связи вывода и регистра состоит из следующих пунктов:

  • Номер бита в регистре «BOUNDARY»

  • Типовая группа контактов. В стандарте данный параметр называется странным термином <cell name>. На самом деле, крайне непрозрачный параметр, о котором надо знать, пожалуй, две вещи: если у вас двунаправленный вывод, то этот параметр следует записать, как «BC_7», в иных случаях — как «BC_1»

  • Наименование контакта микросхемы из раздела «port». В случае шины следует также указать номер линии в шине.

  • Тип контакта. В простейшем случае — это «input» или «output2» («...2» символизирует два возможных состояния линии).

  • Безопасное значение. В простейшем случае данный параметр указывается как «X», что означает, что любое значение на выходе данного контакта — безопасное.

Более сложное описание связи для типов контактов «bidir» и «output3» выглядит так:

"42 (BC_7, MY_BUS(0), bidir, X, 44, 1, Z)," &
"43 (BC_7, MY_BUS(1), bidir, X, 44, 1, Z)," &
"44 (BC_1, *, control, 1)," &

Как видно, 42-й бит регистра «BOUNDARY» связан с нулевой линией двунаправленной шины «MY_BUS». У этого описания связи, помимо 5-и уже упомянутых параметров появляется три дополнительных:

  • Номер бита в регистре «BOUNDARY», который способен повлиять на выход линии «MY_BUS(0)». К примеру, перевести её в высокоимпедансное состояние. В данном случае — это 44-й бит.

  • Конкретное значение 44-ого бита при котором это влияние будет осуществлено.

  • Тип влияния. Буква «Z» означает перевод в высокоимпедансное состояние. Но также в стандарте предусмотрен ряд иных типов влияния. К примеру, «KEEPER». В случае применения данного типа влияния, контакт «MY_BUS(0)» сохранит предыдущее значение, даже если содержимое 42-ого бита, привязанного к контакту изменится.

Логично предположить, что в вышеописанном случае 44-й бит может быть не привязан к какому-либо контакту. Поэтому, тип подобных битов устанавливается в «control», а вместо наименования контакта ставится символ «*». В подавляющем большинстве случаев, битам, переводящим контакты в высокоимпедансное состояние явно задаётся такое безопасное значение, при котором эти контакты гарантированно окажутся в состоянии «HiZ». Так же из вышеприведённого примера видно, что один управляющий бит способен оказывать влияние сразу на несколько контактов.

Собрав все элементы вместе, мы получим следующий файл BSDL:
entity SIMPLE_IC is
	generic (PHYSICAL_PIN_MAP : string);
	port  (
		LED: out bit_vector(0 to 7);
		BTN: in  bit_vector(0 to 7);
		TMS: in  bit;
		TDI: in  bit;
		TCK: in  bit;
		TDO: out bit;
		VDD: linkage bit;
		VSS: linkage bit;
		NC:  linkage bit_vector(0 to 9)
		);

	use STD_1149_1_2001.all;

	attribute COMPONENT_CONFORMANCE of SIMPLE_IC : entity is "STD_1149_1_2001";
	attribute PIN_MAP of SIMPLE_IC : entity is PHYSICAL_PIN_MAP;

	constant  PLCC20:PIN_MAP_STRING:=
		"LED:	(1,2,3,4), " &
		"BTN:	(8,7,6,5), " &
		"TMS:	9, " &
		"TDI:	10, " &
		"TCK:	11, " &
		"TDO:	12, " &
		"VDD:	13, " &
		"VSS:	14, " &
		"NC:	(15,16,17,18,19,20) ";

	attribute TAP_SCAN_MODE	of TMS : signal is true;
	attribute TAP_SCAN_IN		of TDI : signal is true;
	attribute TAP_SCAN_CLOCK	of TCK : signal is (10.0e3, BOTH);
	attribute TAP_SCAN_OUT		of TDO : signal is true;

	attribute INSTRUCTION_LENGTH of SIMPLE_IC : entity is 8;
	attribute INSTRUCTION_OPCODE of SIMPLE_IC : entity is
		"IDCODE (00000001)," &
		"EXTEST (00000010)," &
		"BYPASS (11111111)," &
		"SAMPLE (00000100) ";
	attribute INSTRUCTION_CAPTURE of SIMPLE_IC : entity is "00000001";

	attribute IDCODE_REGISTER of SIMPLE_IC : entity is
		"0000" &             -- код ревизии или чего-нибудь типа того
		"1010101001010101" & -- код модели микросхемы hAA55
		"00000000001" &      -- код производителя (соответствует AMD)
		"1";                 -- единица по стандарту IEEE1149.1

	attribute REGISTER_ACCESS of SIMPLE_IC : entity is
		"DEVICE_ID	(IDCODE)," &
		"BYPASS	(BYPASS)," &	
		"BOUNDARY	(EXTEST, SAMPLE)";

	attribute BOUNDARY_LENGTH of SIMPLE_IC : entity is 8;
	attribute BOUNDARY_REGISTER of SIMPLE_IC : entity is
		"0 (BC_1, LED(0), output2, X)," &
		"1 (BC_1, LED(1), output2, X)," &
		"2 (BC_1, LED(2), output2, X)," &
		"3 (BC_1, LED(3), output2, X)," &
		"4 (BC_1, BTN(0), input,   X)," &
		"5 (BC_1, BTN(1), input,   X)," &
		"6 (BC_1, BTN(2), input,   X)," &
		"7 (BC_1, BTN(3), input,   X)" ;
end SIMPLE_IC;

На этом месте может возникнуть вопрос о правильности написания файла BSDL, проверке его синтаксиса, а также проверке соответствия файла самой микросхеме. То есть его верификации. В поисках аналогии взглянем, скажем, на IBIS — стандарт написания моделей выходных буферов цифровых микросхем. Группа, развивающая данный стандарт предлагает для свободного скачивания «Золотой парсер IBIS» — консольную утилиту, проверяющую синтаксис файла модели. В случае с JTAG такой утилиты нет. Зато имеется возможность онлайн-проверки на сайте компании «Intellitech», генеральным директором которой является Кристофер Кларк (C.J. Clark) — председатель группы JTAG. Ну как — «имеется»? Лично у меня по состоянию на 09.04.2022 при попытке загрузить туда файл BSDL происходит перенаправление на страницу ошибки. Онлайн-проверка файлов BSDL представлена также у компании «Asset Intertech». Проверив наш файл в этой системе мы получим следующий отчёт:

Job Status: Fail

Entity name: SIMPLE_IC
IEEE Std 1149.1-2001 (Version 2.0)
Error, Line 21, The number of LED pins does not match the port definition.
Error, Line 22, The number of BTN pins does not match the port definition.
Packaging option selected is PLCC20.
Error, Line 31, Port 'LED' has 4 missing pin mapping assignments.
Error, Line 31, Port 'BTN' has 4 missing pin mapping assignments.
Error, Line 42, Mandatory PRELOAD opcode was not specified.
Compilation failed due to errors.

Как видно, система хочет, чтобы мы навели порядок с количеством линий «LED» и «BTN», а также создали отдельную команду «PRELOAD», как того требует обновлённый стандарт 2001 года. После соответствующих исправлений результат будет такой:

Job Status: Pass

Entity name: SIMPLE_IC
IEEE Std 1149.1-2001 (Version 2.0)

Packaging option selected is PLCC20.
Inputs = 4
Outputs = 4
Bidirectionals = 0
Instruction Reg Length = 8
Boundary Reg Length = 8

BSDL compilation of 65 lines completed without errors.

В следующей статье мы напишем код на «Си» и «Verilog», который бы имитировал работу модуля JTAG микросхемы «SIMPLE_IC», описанием которого мы сейчас занимались. И параллельно, в деталях рассмотрим работу JTAG при выполнении различных инструкций.

Tags:
Hubs:
Total votes 36: ↑36 and ↓0+36
Comments5

Articles