Распродажа

Электронные компоненты со склада по низким ценам, подробнее >>>

Содержание ChipNews

2003: 
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
2002: 
1, 5, 6, 7, 8, 9
2001: 
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
2000: 
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
1999: 
1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Новости электроники

Мне нравится

Комментарии

дима пишет в теме Параметры биполярных транзисторов серии КТ827:

люди куплю транзистар кт 827А 0688759652

тамара плохова пишет в теме Журнал Радио 9 номер 1971 год. :

как молоды мы были и как быстро пробежали годы кулотино самое счастливое мое время

Ивашка пишет в теме Параметры отечественных излучающих диодов ИК диапазона:

Светодиод - это диод который излучает свет. А если диод имеет ИК излучение, то это ИК диод, а не "ИК светодиод" и "Светодиод инфракрасный", как указано на сайте.

Владимир пишет в теме 2Т963А-2 (RUS) со склада в Москве. Транзистор биполярный отечественный:

Подскажите 2т963а-2 гарантийный срок

Владимир II пишет... пишет в теме Параметры биполярных транзисторов серии КТ372:

Спасибо!

В. Стешенко, А. Самохин

Школа разработки аппаратуры цифровой обработки сигналов на ПЛИС Занятие 5. Язык описания аппаратуры AHDL

Общие сведения о языке описания аппаратуры AHDL

    Язык описания аппаратуры AHDL разработан фирмой Altera и предназначен для описания комбинационных и последовательностных логических устройств, групповых операций, цифровых автоматов (state machine) и таблиц истинности с учетом архитектурных особенностей ПЛИС фирмы Altera. Он полностью интегрируется с системой автоматизированного проектирования ПЛИС MAX+PlusII. Файлы описания аппаратуры, написанные на языке AHDL, имеют расширение "*.TDF" (Text design file). Для создания TDF-файла можно использовать как текстовый редактор системы MAX+PlusII, так и любой другой. Проект, выполненный в виде TDF-файла, компилируется, отлаживается и используется для формирования файла программирования или загрузки ПЛИС фирмы Altera.

    Операторы и элементы языка AHDL являются достаточно мощным и универсальным средством описания алгоритмов функционирования цифровых устройств, удобным в использовании. Язык описания аппаратуры AHDL дает возможность создавать иерархические проекты в рамках одного этого языка или использовать TDF-файлы, разработанные на языке AHDL, наряду с другими типами файлов. Для создания проектов на AHDL можно, конечно, пользоваться любым текстовым редактором, но текстовый редактор системы MAX+PlusII предоставляет ряд дополнительных возможностей для ввода, компиляции и отладки проектов.

    Проекты, созданные на языке AHDL, легко внедряются в иерархиче-скую структуру. Система MAX+PlusII позволяет автоматически создать символ компонента, алгоритм функционирования которого описывается TDF-файлом, и затем вставить его в файл схемного описания (GDF-файл). Подобным же образом можно вводить в любой TDF-файл собственные функции разработчика и около 300 макрофункций, разработанных фирмой Altera. Для всех функций, включенных в макробиблиотеку системы MAX+PlusII, фирма Altera поставляет файлы с расширением "*.inc", которые используются в операторе включения INCLUDE.

    При распределении ресурсов устройств разработчик может пользоваться командами текстового редактора или операторами языка AHDL для того, чтобы сделать назначения ресурсов и устройств. Кроме того, разработчик может только проверить синтаксис или выполнить полную компиляцию для отладки и запуска проекта. Любые ошибки автоматически обнаруживаются обработчиком сообщений и высвечиваются в окне текстового редактора. При работе с AHDL следует соблюдать так называемые "Золотые правила" (Golden Rules). Выполнение их позволит эффективно применять язык AHDL и избежать многих ошибок.

"Золотые правила AHDL"

Использование чисел и констант в языке AHDL

    Числа используются для представления констант в булевых выражениях и уравнениях. Язык AHDL поддерживает все комбинации десятичных, двоичных, восьмеричных и шестнадцатеричных чисел.

    На врезке 2 приведен файл decode1.tdf, который представляет собой дешифратор адреса, генерирующий высокий активный уровень сигнала разрешения доступа к шине, если адрес равен шестнадцатеричному числу 370h.

Врезка 2

SUDESIGN decode1
      (
      address[15..0] : INPUT;
      chip_enable : OUTPUT;
      )
BEGIN
      chip_enable = (adress[15..0] == H"0370");
END;

    В этом примере десятичные числа использованы для указания размерности массива бит, которым записывается адрес шины. Шестнадцатеричным числом H"0370" записано значение адреса, при котором обеспечивается высокий уровень сигнала.

    В файле AHDL можно использовать константы для описательных имен разных чисел. Такое имя, используемое на протяжении всего файла, может быть более информативным, чем число; например, имя UPPER_LI несет больше информации, чем число 103. В языке AHDL константы вводятся объявлением CONSTANT.

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

Комбинационная логика

    Как известно, логическая схема называется комбинационной, если состояния выходов являются только функциями входов независимо от момента времени. Комбинационная логика в языке AHDL реализована булевыми выражениями и уравнениями, таблицами истинности и большим количеством макрофункций. В число примеров комбинаторных логических функций входят дешифраторы, мультиплексоры и сумматоры.

    Булевы выражения это множества узлов, чисел, констант и других булевых выражений, выделяемых операторами, компараторами и, возможно, сгруппированных в заключающих круглых скобках. Булево уравнение устанавливает равенство между узлом или группой и булевым выражением. В качестве примера на врезке 3 приведен файл boole1.tdf, в котором даны два простых булевых выражения, представляющих два логических элемента.

Врезка 3

SUBDESIGN boole1
       (
       a0, a1, b : INPUT;
       out1, out2 : OUTPUT;
       )
BEGIN
       out1 = a1 & !a0;
       out2 = out1 # b;
END;

    Здесь выход out1 получается в результате логической операции И, примененной ко входу a1 и инвертированному входу a0, а выход out2 получается в результате применения логической операции ИЛИ к выходу out1 и входу b. Поскольку эти уравнения обрабатываются одновременно, последовательность их следования в файле не важна.

    Узел, который объявляется в секции переменных VARIABLE в объявлении NODE, можно использовать для хранения промежуточных выражений.

    Это полезно делать, если булево выражение повторяется несколько раз и его целесообразно заменить именем узла. Файл boole1.tdf можно переписать по-другому (врезка 4).

Врезка 4

SUBDESIGN boole2
       (
       a0, a1, b : INPUT;
       out : OUTPUT;
       )
VARIABLE
       a_equals_2 : NODE;
BEGIN
       a_equals_2 = a1 & !a0;
       out = a_equals_2 # b;
END;

    Здесь объявляется узел a_equals_2, и ему присваивается значение выражения "a1 & !a0". Если узел используется в нескольких выражениях, то его объявление помогает экономить ресурсы устройств.

    Важным понятием AHDL является группа. Она может включать в себя до 256 элементов (бит), рассматривается как совокупность узлов и участвует в различных действиях как единое целое. В булевых уравнениях группа может быть приравнена булевому выражению, другой группе, одному узлу, VCC, GND, 1 или 0. В каждом случае значения группы разные.

    Если группа определена, для краткого указания всего диапазона ставят две квадратные скобки [ ]. Например, группу a[4..1] можно кратко записать как a[ ].

    Условная логика делает выбор между режимами в зависимости от логических входов. Для реализации условной логики используются операторы IF или CASE:

Логика оператора IF

    В качестве примера рассмотрим файл priority.tdf (врезка 5), в котором описан кодировщик приоритета, который преобразует уровень самого приоритетного активного входа в значение. Он генерирует двухразрядный код, показывающий вход с наивысшим приоритетом, запускаемый VCC.

Врезка 5

SUBDESIGN priority
       (
       low, middle, high : INPUT;
       highest_level[1..0] : OUTPUT;
       )
BEGIN
       IF high THEN
          highest_level[] = 3;
       ELSIF middle THEN
          highest_level[] = 2;
       ELSIF low THEN
          highest_level[] = 1;
       ELSE
          highest_level[] = 0;
       END IF;
END;

    Здесь оцениваются входы low, middle и high, чтобы определить, запущены ли они VCC. На выходе получится код, соответствующий приоритету того входа, который был запущен VCC. Если ни один вход не запущен, значение кода будет равно 0.

Логика оператора CASE

    В качестве примера рассмотрим файл decoder.tdf (врезка 6), реализующий функции дешифратора, преобразующего код из двухразрядного в четырехразрядный. В результате его работы два двухразрядных двоичных входа преобразуются в один "горячий код", называемый так потому, что четыре его допустимых значения содержат по одной единице: 0001, 0010, 0100, 1000.

Врезка 6

SUBDESIGN decoder
             (
                    code[1..0] : INPUT;
                    out[3..0] : OUTPUT;
             )
      BEGIN
             CASE  code[] IS
WHEN 0 => out[] = B"0001";
WHEN 1 => out[] = B"0010";
WHEN 2 => out[] = B"0100";
WHEN 3 => out[] = B"1000";
               END CASE;
       END;

    Здесь группа входа code [1..2] может принимать значения 0, 1, 2, 3. В зависимости от реального кода активизируется соответствующая ветвь оператора, и только она одна, в данный момент времени. Например, если вход code [] равен 1, на выходе out устанавливается значение В"0010".

    Операторы IF и CASE похожи. Иногда использование любого из них приводит к одним и тем же результатам. Однако между этими двумя операторами существуют несколько важных различий:

    Рассмотрим описание типовых комбинационных схем на AHDL. Дешифратор содержит комбинаторную логику, которая преобразует входные схемы в выходные значения или задает выходные значения для входных схем. Для создания дешифратора в языке AHDL используется объявление таблицы истинности TABLE.

    На врезке 7 приведен файл 7segment.tdf, представляющий собой дешифратор, который задает логику схемы управления светодиодами. Светодиоды отображают на семисегментном дисплее шестнадцатеричные цифры (от 0 до 9 и буквы от A до F).

Врезка 7

SUBDESIGN 7segment
(
 i[3..0] : INPUT;
 a, b, c, d, e, f, g : OUTPUT;
)
BEGIN
 TABLE
 i[3..0] => a, b, c, d, e, f, g;
 
 H"0" => 1, 1, 1, 1, 1, 1, 0;
 H"1" => 0, 1, 0, 0, 0, 0, 0;
 H"2" => 1, 1, 0, 1, 1, 0, 0;
 H"3" => 1, 1, 1, 1, 0, 0, 1;
 H"4" => 0, 1, 1, 0, 0, 1, 1;
 H"5" => 1, 0, 1, 1, 0, 1, 1;
 H"6" => 1, 0, 1, 1, 1, 1, 1;
 H"7" => 1, 1, 1, 0, 0, 0, 0;
 H"8" => 1, 1, 1, 1, 1, 1, 1;
 H"9" => 1, 1, 1, 1, 0, 1, 1;
 H"A" => 1, 1, 1, 0, 1, 1, 1;
 H"B" => 0, 0, 1, 1, 1, 1, 1;
 H"C" => 1, 0, 0, 1, 1, 1, 0;
 H"D" => 0, 1, 1, 1, 1, 0, 1;
 H"E" => 1, 0, 0, 1, 1, 1, 1;
 H"F" => 1, 0, 0, 0, 1, 1, 1;
 END TABLE;
END;

    В этом примере показаны все возможные шестнадцатиричные цифры (i[3..0]) и соответствующие состояния светодиодов (a, b, c, d, e, f, g), которые обеспечивают "начертание" цифры на дисплее. Изображение светодиодов на дисплее дано в виде комментария перед файлом.

    На врезке 8 приведен файл дешифратора адреса decode3.tdf для шестнадцатиразрядной микропроцессорной системы.

Врезка 8

SUBDESIGN decode3
(
 addr[15..0], m/io : INPUT;
 rom, ram, print, sp[2..1] : OUTPUT;
)
BEGIN
 TABLE
 m/io, addr[15..0] => rom, ram, print, sp[];
 1, B"00XXXXXXXXXXXXXX" => 1, 0, 0, B"00";
 1, B"100XXXXXXXXXXXXX" => 0, 1, 0, B"00";
 0, B"0000001010101110" => 0, 0, 1, B"00";
 0, B"0000001011011110" => 0, 0, 0, B"01";
 0, B"0000001101110000" => 0, 0, 0, B"10";
 END TABLE;
END;

    В данном примере существуют тысячи возможных вариантов входа (адреса), поэтому было бы непрактично сводить их все в таблицу. Вместо этого, можно пометить символом "Х" несущественные, не влияющие на выход, разряды. Например, выходной сигнал rom (ПЗУ) будет высоким для всех 16384 вариантов адреса addr[15..0], которые начинаются с 00. Поэтому вам нужно только указать общую для всех вариантов часть кода, то есть 00, а в остальных разрядах кода поставить "Х". Такой прием позволит использовать в данном проекте меньше устройств и ресурсов.

    Приведенный на врезке 9 пример decode4.tdf показывает использование стандартной параметризируемой функции lpm_decode в задаче разработки дешифратора, аналогичной примеру decode1.tdf.

Врезка 9

INCLUDE "lpm_decode.inc";

SUBDESIGN decode4
(
 address[15..0] : INPUT;
 chip_enable : OUTPUT;
)
BEGIN
 chip_eneble = lpm_decode(.data[]=address[])
 WITH (LPM_WIDTH=16, LPM_DECODES=2^10)
 RETURNS (.eq[H"0370"]);
END;

    Иногда для переменных удобно использовать значения по умолчанию. Можно определить значения по умолчанию для узла или группы, которые будут автоматически использоваться, если в файле их значения не будут заданы. Язык AHDL позволяет присваивать значение узлу или группе в файле неодно-кратно. Если при этом произойдет конфликт, система автоматически будет использовать значения по умолчанию. Если они не были заданы, используется значение GND.

    Объявление значений по умолчанию DEFAULTS можно использовать для задания переменных в таблице истинности, операторах IF и CASE.

    На врезке 10 приводится файл default1.tdf, в котором происходит оценка входов и выбор соответствующего ASCII-кода.

Врезка 10

SUBDESIGN default1
             (
                    i[3..0] : INPUT;
                    ascii_code[7..0] : OUTPUT;
             )
      BEGIN
                    DEFAULTS
      ascii_code[] = B"00111111";% ASCII question mark"?" % END DEFAULTS;
                   TABLE
                          i[3..0] => ascii_code[];
                          B"1000" => B"01100001"; % "a" %
B"0100" => B"01100010"; % "b" %
B"0010" => B"01100011"; & "c" %
B"0001" => B"01100100"; % "d" %
                      END TABLE;
	  END;	

    Если значение входа совпадает с одним из значений в левой части таблицы, код на выходе приобретает соответствующее значение ASCII-кода в правой части таблицы. Если входное значение не совпадает ни с одним из (левых) табличных, выходу будет присвоено значение по умолчанию B"00111111" (вопросительный знак).

    В приведенном на врезке 11 файле default2.tdf показано, как при многократном присваивании узлу разных значений возникает конфликт и как он разрешается средствами AHDL.

Врезка 11

SUBDESIGN default2
             (
a, b, c : INPUT;
select_a, select_b, select_c : INPUT;
wire_or, wire_and : OUTPUT;
             )
      BEGIN
                  DEFAULTS
                        wire_or = GND;
                        wire_and = VCC;
                  END DEFAULTS;
                  IF select_a THEN
                              wire_or = a;
                              wire_and = a;
                  END IF;
       IF select_b THEN
                              wire_or = b;
                              wire_and = b;
                  END IF;
                  IF select_c THEN
                              wire_or = c;
                              wire_and = c;
                  END IF;
      END;

    В данном примере выход wire_or устанавливается равным a, b или c, в зависимости от входных сигналов select_a, select_b и select_c. Если ни один из них не равен VCC, то выход wire_or принимает значение по умолчанию, равное GND.

    Если более одного сигнала (select_a, select_b или select_c) равны VCC, то wire_or равно результату логической операции ИЛИ над соответствующими входными сигналами. Например, если select_a и select_b равны VCC, то wire_or равно a ИЛИ b.

    С сигналом wire_and производятся аналогичные действия, но он становится равным VCC, когда входные сигналы select равны VCC, и равен логическому И от соответствующих входных сигналов, если более, чем один из них равен VCC.

    Рассмотрим реализацию логики с активным низким уровнем. Значение сигнала с низким активным уровнем равно GND. Такие сигналы могут быть использованы для управления памятью, периферийными устройствами и микропроцессорными чипами.

    На врезке 12 приводится файл daisy.tdf, который представляет модуль арбитражной схемы для соединения гирляндой (daisy chain). Данный модуль делает запрос на доступ к шине для предыдущего (в гирлянде) модуля. Он получает запрос на доступ к шине от самого себя и от следующего (в цепочке) модуля. Доступ к шине предоставляется модулю с более высоким приоритетом.

Врезка 12

  SUBDESIGN daisy
              (
                    /local_request : INPUT;
                    /local_grant : OUTPUT;
                    /request_in : INPUT; % from lower priority % /request_out : OUTPUT; % to higher
priority % /grant_in : INPUT; % from higher priority % /grant_out : OUTPUT; % to lower priority %
              )
      BEGIN
                   DEFAULTS
      /local_grant = VCC; % active-low output % /request_out = VCC; % signals should default % /
grant_out = VCC; % to VCC %
                   END DEFAULTS;
      IF /request_in == GND # /local_request == GND THEN
       /request_out = GND;
      END IF;
      IF /grant_in == GND THEN
  IF /local_request == GND THEN
    /local_grant = GND;
  ELSIF /request_in -- GND THEN
   /grant_out = GND;
                    END IF;
       END IF;
  END;

    Все сигналы в данном файле имеют активный низкий уровень. Фирма Altera рекомендует помечать как-нибудь имена сигналов с низким активным уровнем, например, первым символом в имени ставить "/", не являющийся оператором, и использовать его постоянно.

    В операторе IF проверяется, является ли модуль активным, то есть равен ли он GND. Если это так, то реализуются действия, записанные в операторе IF.

    В объявлении по умолчанию DEFAULTS считается, что сигналу присваивается значение VCC, если он не активен.

    Система MAX+PlusII позволяет конфигурировать порты ввода/вывода (I/O) в устройствах Altera как двунаправленные порты. Двунаправленный вывод задается как порт BIDIR, который подсоединяется к выходу примитива TRI. Сигнал между этим выводом и буфером с тремя состояниями является двунаправленным, и его можно использовать в проекте для запуска других логических схем.

    Приводимый на врезке 13 файл bus_reg2.tdf реализует регистр, который делает выборку значения, найденного на шине с тремя состояниями, а также может передать обратно на шину хранимое значение.

Врезка 13

SUBDESIGN bus_reg2
             (
                    clk : INPUT;
                    oe : INPUT;
                    io : BIDIR;
             )
     BEGIN
             io = TRI(DFF(io, clk,, ), oe);
     END;

    Двунаправленный сигнал io, запускаемый примитивом TRI, используется в качестве входа d для D-триггера (DFF). Запятые в конце списка параметров отделяют места для сигналов триггера clrn и prn. Эти сигналы по умолчанию установлены в неактивное состояние.

    Двунаправленный вывод можно также использовать для подсоединения TDF-файла более низкого уровня к выводу с высоким уровнем. Прототип функции для TDF-файла более низкого уровня должен содержать двунаправленный вывод в предложении RETURNS. В приведенном на врезке 14 файле bidir1.tdf даны четыре примера использования макрофункции bus_reg2.

Врезка 14

FUNCTION bus_reg2 (clk, oe) RETURNS (io);
      SUBDESIGN bidir1
             (
                  clk, oe : INPUT;
                  io[3..0] : BIDIR;
             )
     BEGIN
             io0 = bus_reg2 )clk, oe);
             io1 = bus_reg2 )clk, oe);
             io2 = bus_reg2 )clk, oe);
             io3 = bus_reg2 )clk, oe);
     END;

    В следующем номере мы продолжим знакомство с языком описания аппаратуры AHDL на примере построения последовательностных схем и цифровых автоматов.

Тел.: 263 6736
E-mail: stesheenk@sm.bmstu.ru






Ваш комментарий к статье
Школа разработки аппаратуры цифровой обработки сигналов на ПЛИС Занятие 5. Язык описания аппаратуры AHDL :
Ваше имя:
Отзыв: Разрешено использование тэгов:
<b>жирный текст</b>
<i>курсив</i>
<a href="http://site.ru"> ссылка</a>