Документ взят из кэша поисковой машины. Адрес
оригинального документа
: http://www.sm.bmstu.ru/sm5/n4/oba/gl3.html
Дата изменения: Thu Feb 15 17:43:24 2007 Дата индексирования: Mon Oct 1 18:46:11 2012 Кодировка: Windows-1251 Поисковые слова: п п п п п п п п р п п р п п р п п р п п р п п р п п р п п р п п р п п р п п р п |
Глава 3. Язык описания аппаратуры AHDL |
3.1. Общие сведения Язык описания аппаратуры AHDL разработан фирмой Altera и предназначен для описания комбинационных и последовательностных логических устройств, групповых операций, цифровых автоматов (state machine) и таблиц истинности с учетом архитектурных особенностей ПЛИС фирмы Altera. Он полностью интегрируется с системой автоматизированного проектирования ПЛИС MAX+PLUS II. Файлы описания аппаратуры, написанные на языке AHDL, имеют расширение *.TDF (Text design file). Для создания TDF-файла можно использовать как текстовый редактор системы MAX+PLUS II, так и любой другой. Проект, выполненный в виде TDF-файла, компилируется, отлаживается и используется для формирования файла программирования или загрузки ПЛИС фирмы Altera.Операторы и элементы языка AHDL являются достаточно мощным и универсальным средством описания алгоритмов функционирования цифровых устройств, удобным в использовании. Язык описания аппаратуры AHDL дает возможность создавать иерархические проекты в рамках одного этого языка или же в иерархическом проекте использовать как TDF-файлы, разработанные на языке AHDL, так и другие типы файлов. Для создания проектов на AHDL можно, конечно, пользоваться любым текстовым редактором, но текстовый редактор системы MAX+PLUS II предоставляет ряд дополнительных возможностей для ввода, компиляции и отладки проектов (см. Главу 2).Проекты, созданные на языке AHDL, легко внедряются в иерархическую структуру. Система MAX+PLUS II позволяет автоматически создать символ компонента, алгоритм функционирования которого описывается TDF-файлом, и затем вставить его в файл схемного описания (GDF-файл). Подобным же образом можно вводить собственные функции разработчика помимо порядка 300 макрофункций, разработанных фирмой Al tera, в любой TDF-файл. Для всех функций, включенных в макробиблиотеку системы MAX+PLUS II, фирма Altera поставляет файлы с расширением *.inc, которые используются в операторе включения INCLUDE.При распределении ресурсов устройств разработчик может пользоваться командами текстового редактора или операторами языка AHDL для того, чтобы сделать назначения ресурсов и устройств. Кроме того, разработчик может только проверить синтаксис или выполнить полную компиляцию для отладки и запуска проекта. Любые ошибки автоматически обнаруживаются обработчиком сообщений и высвечиваются в окне текстового редактора. При работе с AHDL следует соблюдать так называемые 'Золотые правила' (Golden Rules). Выполнение этих правил позволит эффективно применять язык AHDL и избежать многих ошибок:
Общие 'золотые правила' ввода проекта :Общие 'золотые правила' системы MAX+PLUS II :
3.2. Использование чисел и констант в языке AHDL 3.2.1 Использование чисел Числа используются для представления констант в булевских выражениях и уравнениях. Язык AHDL поддерживает все комбинации десятичных, двоичных, восьмеричных и шестнадцатеричных чисел. Ниже приведен файл decode1.tdf, который представляет собой дешифратор адреса, генерирующий высокий активный уровень сигнала разрешения доступа к шине, если адрес равен шестнадцатеричному числу 370h.SUBDESIGN decode1 ( address[15..0] : INPUT; chip_enable : OUTPUT; ) BEGIN chip_enable = (address[15..0] == H"0370"); END; В этом примере десятичные числа использованы для указания размерности массива бит, которым записывается адрес шины. Шестнадцатеричным числом H'0370' записано значение адреса, при котором обеспечивается высокий уровень сигнала. 3.2.2. Использование констант В файле AHDL можно использовать константы для описательных имен разных чисел. Такое имя, используемое на протяжении всего файла, может быть более информативным, чем число; например, имя UPPER_LI несет больше информации, чем число 103. В языке AHDL константы вводятся объявлением CONSTANT. Приведенный выше файл можно записать по-другому, используя вместо числа H'0370' константу IO_ADDRESS. CONSTANT IO_ADDRESS = H'0370'; SUBDESIGN decode2 ( a[15..0] : INPUT; ce : OUTPUT; ) BEGIN ce = (a[15..0] == IO_ADDRESS); END; Преимущество использования констант особенно заметно, если одно и то же число используется в файле несколько раз. Тогда, если его нужно изменить, меняют его только один раз в объявлении константы. 3.3. Комбинационная логика Как известно, логическая схема называется комбинационной, если в заданный момент времени выходы являются только функциями входов в этот момент времени. Комбинационная логика в языке AHDL реализована булевыми выражениями и уравнениями, таблицами истинности и большим количеством макрофункций. В число примеров комбинаторных логических функций входят Дешифраторы, мультиплексоры и сумматоры. 3.3.1. Реализация булевых выражений и уравнений Булевы выражения - это множества узлов, чисел, констант и других булевых выражений, выделяемых операторами, компараторами и, возможно, сгруппированные в заключающих круглых скобках. Булево уравнение устанавливает равенство между узлом или группой и булевым выражением. В качестве примера приведен файл boole1.tdf, в котором даны два простых булевых выражения, представляющих два логических элемента. SUBDESIGN boole1 ( a0, a1, b : INPUT; out1, out2 : OUTPUT; ) BEGIN out1 = a1 & !a0; out2 = out1 # b; END; Здесь выход out1 получается в результате логической операции И, примененной ко входу а1 и инвертированному входу а0, а выход out2 получается в результате применения логической операции ИЛИ к выходу out1 и входу b. Поскольку эти уравнения обрабатываются одновременно, последовательность их следования в файле не важна.3.3.2. Объявление NODE (узел) Узел, который объявляется в секции переменных VARIABLE в объявлении NODE, можно использовать для хранения промежуточных выражений. Это полезно делать, если булево выражение повторяется несколько раз и его целесообразно заменить именем узла. Приведенный выше файл boole1.tdf можно переписать по-другому: 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. Использование узлов помогает экономить ресурсы устройств, если узел используется в нескольких выражениях.3.3.3. Определение групп Группа может включать в себя до 256 элементов (бит), рассматривается как совокупность узлов и участвует в различных действиях как единое целое. В булевых уравнениях группа может быть приравнена булевому выражению, другой группе, одному узлу, VCC, GND,1 или 0. В каждом случае значения группы разные. Если группа определена, для краткого указания всего диапазона ставят две квадратные скобки [ ]. Например, группу а[4..1] можно кратко записать как а[ ]. Примеры определения групп: 3.3.4. Реализация условной логики Условная логика делает выбор между режимами в зависимости от логических входов. Для реализации условной логики используются операторы IF или CASE: В операторе IF оценивается одно или несколько булевых выражений и затем описываются режимы для разных значений этих выражений. В операторе CASE дается список альтернатив, которые имеются для каждого возможного значения некоторого выражения. Оператор оценивает значение выражения и по нему выбирает режим в соответствии со списком. 3.3.4.1. Логика оператора IF В качестве примера рассмотрим файл priority.tdf, в котором описан кодировщик приоритета, который преобразует уровень самого приоритетного активного входа в значение. Он генерирует двухразрядный код, показывающий вход с наивысшим приоритетом, запускаемый VCC.
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.3.3.4.2. Логика оператора CASE В качестве примера рассмотрим файл decoder.tdf, реализующий функции Дешифратора, преобразующего код из двухразрядного в четырехразрядный. В результате его работы два двухразрядных двоичных входа преобразуются в один 'горячий код', который так называется потому, что четыре его допустимых значения содержат по одной единице: 0001, 0010, 0100, 1000.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'.3.3.4.3. Сравнение операторов IF и CASE Операторы IF и CASE похожи. Иногда использование любого из них приводит к одним и тем же результатам: |
If Then |
Case |
IF a[] == 0 THEN y = c & d; ELSIF a[] == 1 THEN y = e & f; ELSIF a[] == 2 THEN y = g & h; ELSIF a[] == 3 THEN y = i; ELSE y = GND; END IF; |
CASE a[] IS WHEN 0 => y = c & d; WHEN 1 => y = e & f; WHEN 2 => y = g & h; WHEN 3 => y = i; WHEN OTHERS => y = GND; END CASE; |
Однако между этими двумя операторами существуют несколько важных различий: IF a THEN IF a THEN c = d; c = d; END IF; ELSIF b THEN IF !a & b THEN c = e; c = e; END IF; ELSE IF !a & !b THEN c = f; c = f; END IF; END IF; 3.3.5. Описание дешифраторов Дешифратор содержит комбинаторную логику, которая преобразует входные схемы в выходные значения или задает выходные значения для входных схем. Для создания дешифратора в языке AHDL используется объявление таблицы истинности TABLE. Ниже приведен файл 7segment.tdf, представляющий собой Дешифратор, который задает логику схемы светодиодов. Светодиоды светятся на семисегментном дисплее для индикации шестнадцатеричной цифры (от 0 до 9 и буквы от A до F).
% -a- % % f| |b % % -g- % % e| |c % % -d- % % % % 0 1 2 3 4 5 6 7 8 9 A b C d E F % % % 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, 1, 0, 0, 0, 0; H"2" => 1, 1, 0, 1, 1, 0, 1; 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), которые обеспечивают 'начертание' цифры на дисплее. Изображение светодиодов на дисплее дано в виде комментария перед файлом.Ниже приведен файл дешифратора адреса decode3.tdf для шестнадцатиразрядной микропроцессорной системы.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, а в остальных разрядах кода поставить 'Х'. Такой прием позволит сделать проект, требующий меньше устройств и ресурсов.Приведенный ниже пример decode4.tdf показывает использование стандартной параметризируемой функции lpm_decode в задаче разработки дешифратора, аналогичной примеру decode1.tdfINCLUDE "lpm_decode.inc"; SUBDESIGN decode4 ( address[15..0] : INPUT; chip_enable : OUTPUT; ) BEGIN chip_enable = lpm_decode(.data[]=address[]) WITH (LPM_WIDTH=16, LPM_DECODES=2^10) RETURNS (.eq[H"0370"]); END; 3.3.6. Использование для переменных значений по умолчанию Можно определить значения по умолчанию для узла или группы, которые будут автоматически использоваться для них, если в файле их значения не будут заданы. Язык AHDL позволяет присваивать значение узлу или группе в файле неоднократно. Если при этом произойдет конфликт, система автоматически будет использовать значения по умолчанию. Если значения по умолчанию не были заданы, используется значение GND. Объявление значений по умолчанию DEFAULTS можно использовать для задания переменных в таблице истинности, операторах IF и CASE. Примечание. Не следует путать значения по умолчанию для переменных со значениями по умолчанию для портов, которые задаются в секции SUBDESIGN.
Ниже приводится файл default1.tdf, в котором происходит оценка входов и выбор соответствующего ASCII кода.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' (вопросительный знак).В приведенном ниже файле default2.tdf показано, как при многократном присваивании узлу разных значений возникает конфликт и как он разрешается средствами AHDL.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, или с в зависимости от входных сигналов 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.3.3.7. Реализация логики с активным низким уровнем Значение сигнала с низким активным уровнем равно GND. Сигналы с низким активным уровнем могут быть использованы для управления памятью, периферийными устройствами и микропроцессорными чипами. Ниже приводится файл daisy.tdf, который представляет модуль арбитражной схемы для соединения гирляндой (daisy chain). Данный модуль делает запрос на доступ к шине для предыдущего (в гирлянде) модуля. Он получает запрос на доступ к шине от самого себя и от следующего (в цепочке) модуля. Доступ к шине предоставляется тому модулю, у которого приоритет выше.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, если он не активен. 3.3.8. Реализация двунаправленных выводов Система MAX+PLUS II позволяет конфигурировать порты ввода/вывода (I/O) в устройствах Altera как двунаправленные порты. Двунаправленный вывод задается как порт BIDIR, который подсоединяется к выходу примитива TRI. Сигнал между этим выводом и буфером с тремя состояниями является двунаправленным, и его можно использовать в проекте для запуска других логических схем. Приводимый ниже файл bus_reg2.tdf реализует регистр, который делает выборку значения, найденного на шине с тремя состояниями, а также может передать обратно на шину хранимое значение.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. В приведенном ниже файле bidir1.tdf даны четыре примера использования макрофункции bus_reg2.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; 3.4. Последовательностная логика Логическая схема называется последовательностной, если выходы в заданный момент времени являются функцией входов не только в тот же момент, но и во все предыдущие моменты времени. Таким образом, в последовательностную схему должны входить некоторые элементы памяти (триггеры). В языке AHDL последовательностная логика реализована цифровыми автоматами с памятью (state machines), регистрами и триггерами. При этом средства описания цифровых автоматов занимают особое место. Кроме того, к последовательностным логическим схемам относятся различные счетчики и контроллеры. 3.4.1. Объявление регистров Регистры используются для хранения значений данных и промежуточных результатов счетчика, тактирование осуществляется синхросигналом. Регистр создается его объявлением в секции VARIABLE. Для подсоедиинения примера примитива, макрофункции или цифрового автомата к другой логике в TDF-ФАЙЛ можно использовать порты. Порт примера описывается в следующем формате: <имя примера>.<имя порта>. Имя порта - это вход или выход примитива, макрофункции или цифрового автомата, что является синонимом имени вывода в файлах проектов (GDF-файл), *.WDF и других. Ниже приводится файл bur_reg.tdf, содержащий байтовый регистр, который фиксирует значения на входах d по выходам q на фронте синхроимпульса, когда уровень загрузки высокий.SUBDESIGN bur_reg ( clk, load, d[7..0] : INPUT; q[7..0] : OUTPUT; ) VARIABLE ff[7..0] : DFFE; BEGIN ff[].clk = clk; ff[].ena = load; ff[].d = d[]; q[] = ff[].q; END; Как видно из файла, регистр объявлен в секции VARIABLE как D-триггер с разрешением (DFFE). В первом булевом уравнении в логической секции происходит соединение входа тактового сигнала подпроекта к портам тактового сигнала триггеров ff[7..0]. Во втором уравнении отпирающий тактовый сигнал соединяется с загрузкой. В третьем уравнении входы данных подпроекта соединяются с портами данных триггеров ff[7..0]. В четвертом уравнении выходы подпроекта соединяются с выходами триггеров. Все четыре уравнения оцениваются одновременно. Можно также в секции VARIABLE объявить T-, JK- и SR-триггеры и затем использовать их в логической секции. При использовании T-триггеров придется в третьем уравнении изменить порт d на t. При использовании JK- и SR-триггеров вместо третьего уравнения придется записать два уравнения, в которых происходит соединение портов j и k или s и r с сигналами.Примечание. При загрузке регистра по заданному фронту глобального тактового сигнала фирма Altera рекомендует использовать вход разрешения одного из регистров: DFFE, TFFE, JKFFE или SRFFE, чтобы контролировать загрузку регистра. 3.4.2. Объявление регистровых выходов Можно объявить регистровые выходы, если объявить выходы подпроекта как D-триггеры в секции VARIABLE. Приведенный ниже файл reg_out.tdf обеспечивает те же функции, что и предыдущий файл bur_reg.tdf, но имеет регистровые выходы.SUBDESIGN reg_out ( clk, load, d[7..0] : INPUT; q[7..0] : OUTPUT; ) VARIABLE q[7..0] : DFFE; BEGIN q[].clk = clk; q[].ena = load; q[] = d[]; END; При присвоении значения регистровому выходу в логической секции это значение формирует входные d сигналы регистров. Выход регистра не изменяется до тех пор, пока не придет фронт синхросигнала. Для определения тактирующего сигнала регистра нужно использовать описание в следующем формате: <имя выходного вывода>.clk для входа тактирующего сигнала регистра в логической секции. Глобальный синхросигнал можно реализовать примитивом GLOBAL или выбором в диалоговом окне компилятора Logic Synthesis (логический синтез) опции Automatic Global Clock.Каждый отпирающий D-тригер, объявленный в секции VARIABLE, возбуждает выход с таким же именем, поэтому можно обращаться к q выходам объявленных триггеров без использования q порта этих триггеров.3.4.3. Создание счетчиков Счетчиками называются последовательностные логические схемы для счета тактовых импульсов. В некоторых счетчиках реализован счет вперед и назад (реверсивные счетчики), в некоторые счетчики можно загружать данные, а также обнулять их. Счетчики обычно определяют как D-триггеры (DFF и DFFE) и используют операторы IF. Ниже приведен файл ahdlcnt.tdf, который реализует 16-битовый загружаемый счетчик со сбросом.SUBDESIGN ahdlcnt ( clk, load, ena, clr, d[15..0] : INPUT; q[15..0] : OUTPUT; ) VARIABLE count[15..0] : DFF; BEGIN count[].clk = clk; count[].clrn = !clr; IF load THEN count[].d = d[]; ELSIF ena THEN count[].d = count[].q + 1; ELSE count[].d = count[].q; END IF; q[] = count[]; END; В данном файле в секции VARIABLE объявлены 16 D-триггеров и им присвоены имена от count0 до count15. В операторе IF определяется значение, загружаемое в триггеры по фронту синхросигнала (например, если загрузка запускается VCC, то триггерам присваивается значение d[ ]).3.5. Цифровые автоматы с памятью (state mashine)Цифровые автоматы так же, как таблицы истинности и булевы уравнения, легко реализуются в языке AHDL. Язык структурирован, поэтому пользователь может либо сам назначить биты и значения состояний, либо предоставить эту работу компилятору системы MAX+PLUS. Компилятор, по уверениям производителя 'использует патентованные перспективные эвристические алгоритмы', позволяющие сделать такие автоматические назначения состояний, которые минимизируют логические ресурсы, нужные для реализации цифрового автомата. Пользователю просто нужно нарисовать диаграмму состояний и построить таблицу состояний. Затем компилятор выполняет автоматически следующие функции:
По желанию пользователя можно задать в TDF-файле переходы в машине состояний с помощью объявления таблицы истинности .В языке AHDL для задания цифрового автомата нужно включить в TDF-файл следующие элементы:
Цифровые автоматы в языке AHDL можно также экспортировать и импортировать, совершая обмен между файлами типа TDF и (GDF-файл) или *.WDF; при этом входной или выходной сигнал задается как порт цифрового автомата в секции SUBDESIGN. 3.5.1. Реализация цифровых автоматов (state machine)Цифровой автомат задают в секции VARIABLE путем объявления имени цифрового автомата, его состояний и, возможно, выходных битов. Ниже приведен файл simple.tdf, который реализует функцию D-триггера.SUBDESIGN simple ( clk : INPUT; reset : INPUT; d : INPUT; q : OUTPUT; ) VARIABLE ss : MACHINE WITH STATES (s0, s1); BEGIN ss.clk = clk; ss.reset = reset; CASE ss IS WHEN s0 => q = GND; IF d THEN ss = s1; END IF; WHEN s1 => q = VCC; IF !d THEN ss = s0; END IF; END CASE; END; В данном файле в секции VARIABLE объявлен цифровой автомат (state machine) ss. Состояния автомата определяются как s0 и s1. Биты состояний не определены.3.5.2. Установка сигналов Clock, Reset и Enable Сигналы Clock, Reset и Enable управляют триггерами регистра состояний в цифровом автомате. Эти сигналы задаются булевыми уравнениями управления в логической секции. В предыдущем примере (файл simple.tdf) синхросигнал цифрового автомата (Clock) формируется входом clk. Асинхронный сигнал сброса цифрового автомата (Reset) формируется входом reset, имеющим высокий активный уровень. Для подключения сигнала отпирания (Enable) нужно добавить в данный файл проекта строку 'ena : INPUT;' в секцию SUBDESIGN, а также добавить в логическую секцию булево уравнение 'ss.ena = ena;'.3.5.3. Задание выходных значений для состояний Для задания выходных значений можно использовать операторы IF и CASE. В приведенном выше примере (файл simple.tdf) значение выхода q устанавливается равным GND, если цифровой автомат ss находится в состоянии s0, и равным VCC, когда она находится в состоянии s1. Эти присваивания делаются в предложениях WHEN оператора CASE.Выходные значения можно также задавать в таблицах истинности, как будет описано в разделе 'Присвоение битов и значений в машине состояний'. 3.5.4. Задание переходов между состояниями Переходы между состояниями определяют условия, при которых машина переходит в новое состояние. Переходы в машине состояний задаются путем условного присвоения состояния в рамках одной конструкции, описывающей режим. Для этой цели рекомендуется использовать оператор CASE или таблицу истинности. В приведенном выше примере (файл simple.tdf) переходы для каждого состояния определены в предложениях WHEN оператора CASE.3.5.5. Присвоение битов и значений в цифровом автомате Бит состояния - это выход триггера, используемый для хранения одного бита значений цифрового автомата. В большинстве случаев для минимизации логических ресурсов следует предоставить компилятору системы MAX+PLUS II присвоение битов и значений состояния. Однако пользователь может сделать это самостоятельно в объявлении цифрового автомата, если, например, он хочет, чтобы определенные биты были выходами цифрового автомата. Ниже приведен файл stepper.tdf, реализующий функцию контроллера шагового двигателя.SUBDESIGN stepper ( clk, reset : INPUT; ccw, cw : INPUT; phase[3..0] : OUTPUT; ) VARIABLE ss : MACHINE OF BITS (phase[3..0]) WITH STATES ( s0 = B"0001", s1 = B"0010", s2 = B"0100", s3 = B"1000"); BEGIN ss.clk = clk; ss.reset = reset; TABLE ss, ccw, cw => ss; s0, 1, x => s3; s0, x, 1 => s1; s1, 1, x => s0; s1, x, 1 => s2; s2, 1, x => s1; s2, x, 1 => s3; s3, 1, x => s2; s3, x, 1 => s0; END TABLE; END; В данном примере выходы phase[3..0], объявленные в секции SUBDESIGN, объявляются также, как биты цифрового автомата ss в объявлении цифрового автомата.3.5.6. Цифровоые автоматы с синхронными выходами Если выходы цифрового автомата зависят только от его состояния, их можно задать в предложении WITH STATES объявления цифрового автомата. Это сделает их менее подверженными ошибкам. Кроме того, в некоторых случаях для логических операций потребуется меньше логических ячеек. Ниже приведен пример (файл moorel.tdf), в котором реализован автомат Мура с четырьмя состояниями. SUBDESIGN moore1 ( clk : INPUT; reset : INPUT; y : INPUT; z : OUTPUT; ) VARIABLE % current current % % state output % ss :MACHINE OF BITS (z) WITH STATES (s0 = 0, s1 = 1, s2 = 1, s3 = 0); BEGIN ss.clk = clk; ss.reset = reset; TABLE % current current next % % state input state % ss, y => ss; s0, 0 => s0; s0, 1 => s2; s1, 0 => s0; s1, 1 => s2; s2, 0 => s2; s2, 1 => s3; s3, 0 => s3; s3, 1 => s1; END TABLE; END; В даном примере состояния определены в объявлении цифрового автомата. Переходы между состояниями определены в таблице next_state, которая задана в объявлении таблицы истинности. В данном примере машина имеет четыре состояния и только один бит состояния z. Компилятор системы MAX+PLUS II автоматически добавляет еще один бит и делает соответствующие присвоения этой синтезированной переменной для того, чтобы получилась машина с четырьмя состояниями. Такой цифровой автомат (state machine) требует, по крайней мере, двух битов.Если значения состояний используются как выходы ( как в файле moorel.tdf), для проекта потребуется меньше логических ячеек, но, возможно, логические ячейки потребуют больше логики, чтобы возбудить входы триггера. В этом случае модуль логического синтезатора компилятора, возможно, не сможет полностью минимизировать автомат.Другой способ построения цифрового автомата заколючается в том чтобы не делать присвоения состояний и явно объявить выходные триггеры. Этот альтернативный метод использован в приведенном ниже файле moore2.tdf.SUBDESIGN moore2 ( clk : INPUT; reset : INPUT; y : INPUT; z : OUTPUT; ) VARIABLE ss : MACHINE WITH STATES (s0, s1, s2, s3); zd : NODE; BEGIN ss.clk = clk; ss.reset = reset; z = DFF(zd, clk, VCC, VCC); TABLE % current current next next % % state input state output % ss, y => ss, zd; s0, 0 => s0, 0; s0, 1 => s2, 1; s1, 0 => s0, 0; s1, 1 => s2, 1; s2, 0 => s2, 1; s2, 1 => s3, 0; s3, 0 => s3, 0; s3, 1 => s1, 1; END TABLE; END; В данном примере вместо того, чтобы задать выходы присвоением значений состояниям в объявлении цифрового автомата, в объявление таблицы истинности добавлен один столбец под названием ' next output (следующий выход)'. В этом методе для синхронизации выходов синхросигналом используется D-триггер, вызов которого записан с помощью непосредственной ссылки.3.5.7. Цифровые автоматы с асинхронными выходами В языке AHDL возможна реализация цифрового автомата с асинхронными выходами. Выходы такого типа автоматов всегда изменяются, когда изменяются входы, независимо от состояния синхросигнала. В приведенном ниже фале mealy.tdf реализован автомат Мили с четырьмя состояниями и асинхронными выходами.SUBDESIGN mealy ( clk : INPUT; reset : INPUT; y : INPUT; z : OUTPUT; ) VARIABLE ss : MACHINE WITH STATES (s0, s1, s2, s3); BEGIN ss.clk = clk; ss.reset = reset; TABLE % current current current next % % state input output state % ss, y => z, ss; s0, 0 => 0, s0; s0, 1 => 1, s1; s1, 0 => 1, s1; s1, 1 => 0, s2; s2, 0 => 0, s2; s2, 1 => 1, s3; s3, 0 => 0, s3; s3, 1 => 1, s0; END TABLE; END; 3.5.8. Восстановление после неправильных состоянийЛогика, сгенерированная для цифрового автомата компилятором системы MAX+PLUS II, будет работать так, как определено в TDF-файле. Однако проекты с использованием цифровых автоматов часто допускают значения битов состояний, которые не присваиваются правильным состояниям. Эти значения с не присвоенными битами состояний называются неправильными состояниями. Проект, который переходит в неправильное состояние, например, в результате нарушений временных требований к установке или задержке, может реализовать ошибочные выходы. Несмотря на рекомендации фирмы Altera по соблюдению временных требований к установке и задержке, пользователь может сделать восстановление цифрового автомата после неправильного состояния путем принудительного преобразования неправильного состояния к известному правильному в рамках оператора CASE. Для восстановления после неправильных состояний следует поименовать их все для данного автомата. Предложение WHEN OTHERS в операторе CASE, которое принудительно преобразует состояния, применяется только к состояниям, которые были объявлены, а не упомянуты в предложении WHEN. Данный метод работает, только если все неправильные состояния определены в объявлении цифрового автомата. Для n-битового цифрового автомата существует 2 n возможных состояний. Поэтому нужно добавить воображаемые имена состояний, чтобы получилось такое их число.Ниже приведен файл recover.tdf, в котором реализован цифровой автомат, который может восстанавливаться из неправильных состояний.SUBDESIGN recover ( clk : INPUT; go : INPUT; ok : OUTPUT; ) VARIABLE sequence : MACHINE OF BITS (q[2..0]) WITH STATES ( idle, one, two, three, four, illegal1, illegal2, illegal3); BEGIN sequence.clk = clk; CASE sequence IS WHEN idle => IF go THEN sequence = one; END IF; WHEN one => sequence = two; WHEN two => sequence = three; WHEN three => sequence = four; WHEN OTHERS => sequence = idle; END CASE; ok = (sequence == four); END; В данном примере цифровой автомат имеет три бита, поэтому она должна иметь 2 3, или 8 состояний. В объявлении заданы только 5 состояний. Следовательно, нужно туда добавить еще три воображаемых состояния illegal1, illegal2, illegal3.
3.6. Реализация иерархического проекта В иерархической структуре проекта TDF-файлы, написанные на языке AHDL, можно использовать вместе с другими файлами проектов. На нижнем уровне проекта могут быть макрофункции, поставляемые фирмой Altera или разработанные пользователями. 3.6.1. Использование макрофункций системы Altera MAX+PLUS II В системе MAX+PLUS II есть большая библиотека, в которую входят 74 стандартных макрофункций, реализующих шины с последовательным опросом, оптимизацию архитектуры и конкретные приложения. Библиотека представляет собой собрание блоков высокого уровня, используемых для создания проекта с иерархической логикой. Во время инсталляции системы эти макрофункции автоматически записываются в каталог \maxplus2\max2lib и его подкаталоги, создаваемые в процессе инсталляции. В языке AHDL существуют два способа вызова (то есть вставки в качестве примера) макрофункции: объявить переменную типа <macrofunction> в объявлении примеров INSTANCE в секции VARIABLE и использовать порты примера макрофункции в логической секции. В этом способе важное значение имеют имена портов; использовать для макрофункции непосредственную ссылку в логической секции файла TDF. В этом способе важен порядок портов. Входы и выходы макрофункций перечисляются в описании прототипов функций (FUNCTION PROTOTYPE). Прототипы функций можно записать в отдельный файл и указать его в своем файле с помощью директивы INCLUDE. Такие Include-файлы создаются автоматически для данного проекта с помощью команды Create Default Include File. Include-файл вставляется вместо вызывающей его директивы INCLUDE. Для всех макрофункций системы MAX+PLUS II Include-файлы должны находиться в каталоге \maxplus2\max2inc.Ниже приведен файл macro1.tdf, который реализует четырех битовый счетчик, подсоединенный к дешифратору 4бит -> 16 бит. Соответствующие макрофункции вызываются объявлениями примеров в секции VARIABLE INCLUDE "4count"; INCLUDE "16dmux"; SUBDESIGN macro1 ( clk : INPUT; out[15..0] : OUTPUT; ) VARIABLE counter : 4count; decoder : 16dmux; BEGIN counter.clk = clk; counter.dnup = GND; decoder.(d,c,b,a) = counter.(qd,qc,qb,qa); out[15..0] = decoder.q[15..0]; END;
В данном файле используются директивы INCLUDE для импортирования прототипов функций для двух макроофункций фирмы Altera: 4count и 16dmux. В секции VARIABLE объявляются две переменные: counter и decoder как примеры этих макрофункций. В логической секции определяются входные порты для обеих макрофункций в формате <имя переменной-примера>.<имя порта>. (Они ставятся в левой части булевых уравнений, а выходные порты - справа.) Порядок портов в прототипе функции не важен, так как имена портов в логической секции перечисляются явно.Ниже приведен файл macro2.tdf, выполняющий те же функции, что и предыдущий, но макрофункции в нем вызываются непосредственной ссылкой.
INCLUDE "4count"; INCLUDE "16dmux"; SUBDESIGN macro2 ( clk : INPUT; out[15..0] : OUTPUT; ) VARIABLE q[3..0] : NODE; BEGIN (q[3..0], ) = 4count (clk, , , , , GND, , , , ); % out[15..0] = 16dmux (.(d, c, b, a)=q[3..0]); % equivalent in-line ref. with positional port association % % out[15..0] = 16dmux (q[3..0]); % END; Вызов макрофункций 4count и 16dmux осуществляется в логической секции непосредственной ссылкой (в правой части булевых уравнений).Ниже приведены прототипы этих макрофункций, записанные в файлах 4count.inc 16dmux.inc:FUNCTION 4count (clk, clrn, setn, ldn, cin, dnup, d, c, b, a) RETURNS (qd, qc, qb, qa, cout); FUNCTION 16dmux (d, c, b, a) RETURNS (q[15..0]); Соединение портов показано в логической секции файла macro2.tdf. Порядок портов важен, так как должно быть однозначное соответствие между портами, описанными в прототипе функции и при ее реализации в логической секции. В данном примере запятыми отделяются (но не перечисляются) порты, для которых не делается явного подключения.3.6.2. Создание и применение пользовательских макрофункций В файлах, написанных на AHDL можно легко создавать и использовать пользовательские макрофункции, выполняя следующие действия:
Прототип функции дает краткое описание функции: ее имя, а также входные, выходные и двунаправленные порты. Можно также использовать машинные порты для макрофункций, которые импортируют или экспортируют цифрового автомата. Объявление прототипов функций может быть размещено в Include-файле, который вызывается в пользовательском файле. Используя команду Create Default Include File, можно автоматически создавать Include-файл с прототипом функции для любого файла проекта.
3.6.3. Определение пользовательской макрофункции Для использования макрофункции ее нужно либо включить в описание прототипа функции в TDF-файле, либо указать в директиве INCLUDE файла TDF имя Include-файла, содержащего прототип этой макрофункции. Как уже упоминалось выше, Include-файлы можно создавать автоматически. Ниже приводится файл keyboard.tdf, в котором реализован кодировщик для 16-клавишной клавиатуры. TITLE "Keyboard Encoder"; INCLUDE "74151"; INCLUDE "74154"; INCLUDE "4count"; FUNCTION debounce (clk, key_pressed) RETURNS (pulse); SUBDESIGN keyboard ( clk : INPUT; % 50-KHz clock % col[3..0] : INPUT; % keyboard columns % row[3..0], d[3..0] : OUTPUT; % keyboard rows, key code % strobe : OUTPUT; % key code is valid % ) VARIABLE key_pressed : NODE; % VCC when key d[3..0] is pressed % mux : 74151; decoder : 74154; counter : 4count; opencol[3..0] : TRI; BEGIN % Drive keyboard rows with a decoder and % % open-collector outputs. % row[] = opencol[].out; opencol[].in = GND; opencol[].oe = decoder.(o0n,o1n,o2n,o3n); decoder.(b,a) = counter.(qd,qc); % Sense keyboard columns with a multiplexer % mux.d[3..0] = col[3..0]; mux.(b,a) = counter.(qb,qa); key_pressed = !mux.y; % Scan keyboard until a key is pressed. % % Drive key's code onto d[] outputs % counter.clk = clk; counter.cin = !key_pressed; d[] = counter.(qd,qc,qb,qa); % Generate strobe when key has settled % strobe = debounce(clk, key_pressed); END; В данном примере в директивах INCLUDE указываются файлы прототипов функции для стандартных макрофункций фиромы Altera: 4count, 74151 и 74154.Отдельно в файле дан прототип функции для макрофункции debounce, в котором описаны входы clk и key_pressed и выход pulse.Примеры макрофункций 4count, 74151 и 74154 вызываются объявлением примеров в секции VARIABLE. Пример макрофункции debounce вызывается непосредственной ссылкой в тексте логической секции3.6.4. Импорт и экспорт цифровых автоматов (state machine) Операции импорта и экспорта цифровых автоматов осуществляются между файлами TDF и другими файлами проекта путем задания входного или выходного порта как входа автомата (MACHINЕ INPUT) и его выхода (MACHINЕ OUTPUT) в секции SUBDESIGN. Прототип функции, который представляет собой файл, содержащий машину состояние, должен указывать, какие входы и выходы принадлежат машине состояний. Это осуществляется снабжением имен сигналов префиксом - ключевым словом Machine. Замечание. Порты типа MACHINЕ INPUT и MACHINЕ OUTPUT нельзя использовать в файл проекта верхнего уровня. Можно переименовать автомат, дав ей временное имя Ниже приводится файл ss_def.tdf, который определяет и экспортирует цифровой автомат ss с портом ss_out типа MACHINЕ OUTPUT.SUBDESIGN ss_def ( clk, reset, count : INPUT; ss_out : MACHINE OUTPUT; ) VARIABLE ss : MACHINE WITH STATES (s1, s2, s3, s4, s5); BEGIN ss_out = ss; CASE ss IS WHEN s1=> IF count THEN ss = s2; ELSE ss = s1; END IF; WHEN s2=> IF count THEN ss = s3; ELSE ss = s2; END IF; WHEN s3=> IF count THEN ss = s4; ELSE ss = s3; END IF; WHEN s4=> IF count THEN ss = s5; ELSE ss = s4; END IF; WHEN s5=> IF count THEN ss = s1; ELSE ss = s5; END IF; END CASE; ss.(clk, reset) = (clk, reset); END; Ниже приводится файл ss_use.tdf, который импортирует цифровой автомат с портом ss_in типа MACHINE INPUT.SUBDESIGN ss_use ( ss_in : MACHINE INPUT; out : OUTPUT; ) BEGIN out = (ss_in == s2) OR (ss_in == s4); END; Ниже приведен файл top1.tdf, в котором используются непосредственные ссылки в тексте для вставки примеров функций ss_def и ss_use. В прототипах этих функций содержится ключевое слово MACHINE для указания, какие входы и выходы являются цифровыми автоматами с памятью (state machine).FUNCTION ss_def (clk, reset, count) RETURNS (MACHINE ss_out); FUNCTION ss_use (MACHINE ss_in) RETURNS (out); DESIGN IS "top1" DEVICE IS "AUTO"; SUBDESIGN top1 ( sys_clk, /reset, hold : INPUT; sync_out : OUTPUT; ) VARIABLE ss_ref: MACHINE; % Machine Alias Declaration % BEGIN ss_ref = ss_def(sys_clk, !/reset, !hold); sync_out = ss_use(ss_ref); END; Внешний цифровой автомат можно также реализовать в TDF-файле верхнего уровня с объявлением примера в секции VARIABLE. Ниже приведен файл top2.tdf, который имеет ту же функцию, что и файл top1.tdf, но для вызова макрофункций использует объявление примеров.FUNCTION ss_def (clk, reset, count) RETURNS (MACHINE ss_out); FUNCTION ss_use (MACHINE ss_in) RETURNS (out); DESIGN IS "top2" DEVICE IS "AUTO"; SUBDESIGN top2 ( sys_clk, /reset, hold : INPUT; sync_out : OUTPUT; ) VARIABLE sm_macro : ss_def; sync : ss_use; BEGIN sm_macro.(clk, reset, count) = (sys_clk, !/reset,!hold); sync.ss_in = sm_macro.ss_out; sync_out = sync.out; END; 3.7. Управление синтезом 3.7.1. Реализация примитивов LCELL и SOFT Можно ограничить логический синтез с помощью замены переменных типа узел (NODE) примитивами SOFT и LCELL. Переменные NODE и примитивы LCELL обеспечивают наилучшее управление логическим синтезом. Примитивы SOFT обеспечивают более слабый управление логическим синтезом.Переменные NODE, которые объявляются в секции VARIABLE, накладывают слабые ограничения на логический синтез. Во время синтеза модуль логического синтеза компилятора системы MAX+PLUS II заменяет каждый пример использования переменной NODE логикой, которую она представляет. Затем происходит минимизация логики до одной логической ячейки. Этот метод обычно приводит к ускорению работы схемы, но в результате может получиться слишком сложная логика или же ее трудно свести к одной ячейке. Буферы SOFT обеспечивают лучшее управление использованием ресурсов, чем переменные NODE. Модуль логического синтезатора выбирает, когда заменить примеры использования примитивов SOFT примитивами LCELL Буферы SOFT могут помочь уничтожить логику, которая оказалась слишком сложной, и сделать проект проще; однако при этом может быть увеличено число логических операций и скорость выполнения программы соответственно уменьшится. Наиболее сильное управление процессом логического синтеза обеспечивается примитивами LCELL. Модуль логического синтезатора минимизирует всю логику, которая запускает примитив LCELL, таким образом, чтобы можно было свести ее к одной логической ячейке. Примитивы LCELL реализуются в виде одной логической ячейки (их нельзя убрать из проекта, даже если они имеют единственный вход). Если проект минимизирован до такой степени, что один примитив LCELL имеет единственный вход, в этом случае вместо примитивов LCELL можно использовать примитивы SOFT, которые убираются в процессе логического синтеза.Примечание . При многоуровневом синтезе компилятор системы MAX+PLUS II автоматически помещает буферы SOFT в более выгодное место проекта, если включить опцию SOFT Buffer Insertion logic.Ниже приводятся две версии файла TDF - с переменными NODE и с примитивами SOFT. В версии nodevar переменная odd_parity объявлена как NODE; затем ей присваивается булево выражение d0 $ d1 $... $ d8. В версии softbuf компилятор заменит некоторые примитивы SOFT примитивами LCELL во время обработки данных для лучшего использования ресурсов устройства. |
TDF with NODE Variables: |
TDF with SOFT Primitives: |
SUBDESIGN nodevar |
SUBDESIGN softbuf |
( |
( |
: |
: |
) |
) |
VARIABLE |
VARIABLE |
odd_parity : NODE; |
odd_parity : NODE; |
BEGIN |
BEGIN |
odd_parity = d0 $ d1 $ d2 |
odd_parity = SOFT(d0 $ d1 $ d2) |
$ d3 $ d4 $ d5 |
$ SOFT(d3 $ d4 $ d5) |
$ d6 $ d7 $ d8; |
$ SOFT(d6 $ d7 $ d8); |
END; |
END; |
3.7.2. Значения констант по умолчанию Логический синтезатор автоматически выполняет подключение к GND всех выходов таблицы истинности, если не удовлетворяется ни одно из условий входа таблицы. Для присвоения выходам таблицы истинности значения VCC можно использовать одно или несколько объявлений языка AHDL по умолчанию. С помощью этих объявлений можно задать значения по умолчанию для соответствующих выходов. Например, если большинство выходов таблицы истинности равны 1, можно задать значение по умолчанию VCC. Примечание. Не следует путать значения по умолчанию для переменных и портов, которые присваиваются в секции SUBDESIGN.Присвоение битов и значений в цифровом автомате Логический синтезатор автоматически минимизирует число битов состояния, требуемое для цифрового автомата. При этом оптимизируется как использование устройства, так и характеристики его работы. Однако некоторые цифрового автомата могут работать быстрее, при значениях состояния, использующих число битов, большее минимального. Для контроля этих случаев пользователь сам объявляет биты и значения для цифрового автомата. 3.8. Элементы языка AHDL 3.8.1.Зарезервированные ключевые слова
Зарезервированные ключевые слова используются для следующих целей:
Ключевые слова можно использовать как символические имена только если они заключены в символы одинарных кавычках ('). Их можно также использовать в комментариях. Для того чтобы получить контекстовую помощь по ключевлому слову, убедитесь, что ваш файл сохранен с расширением. tdf, затем нажмите одновременно две кнопки Shift+F1 в окне текстового редактора Text Editor и щелкните кнопкой мыши Button 1 на ключевом слове.Altera рекомендует все ключевые слова набирать прописными буквами. Список всех зарезервированных ключевых слов языка A HDL: |
FUNCTION |
OTHERS |
|
CASE |
TABLE |
JKFFE |
BITS |
SRFFE |
NCLUDE |
DFF |
VCC |
NODE |
DFFE |
WHEN |
NOR |
ELSE |
WITH |
NOT |
END |
XNOR |
OPTIONS |
EXP |
XOR |
OR |
AND |
GLOBAL |
OUTPUT |
BEGIN |
GND |
RETURNS |
BURIED |
INPUT |
SOFT |
BIDIR |
IF |
SRFF |
CARRY |
IS |
STATES |
CASCADE |
JKFF |
SUBDESIGN |
CLIQUE |
LATCH |
TFF |
CONNECTED_PINS |
LCELL |
TFFE |
CONSTANT |
MACHINE |
THEN |
DEFAULTS |
MACRO |
TITLE |
DESIGN |
MCELL |
TRI |
DEVICE |
NAND |
VARIABLE |
ELSIF |
OF |
X |
3.8.2. Символы Ниже приведены символы, имеющие определенное значение в языке AHDL. В этот перечень не включены символы, используемые в булевых выражениях как операторы и для операций сравнения. |
Символ |
Функция |
_ (подчеркивание) |
Используемые пользователем идентификаторы |
- (тире) |
символы в символических именах |
-- (два тире) |
Начинает комментарий в стиле VHDL, который продолжается до конца строки |
% (процент) |
Заключает с двух сторон комментарий стиля AHDL |
( ) (круглые скобки) |
Заключают и определяют последовательные имена групп. Заключают имена выводов в секции подпроекта (Subdesign Section) и в прототипах функций. Заключают (необязательно) входы и выходы таблиц в объявлении Truth Table. Заключают состояния в объявлении цифрового автомата State Machine. Заключают более приоритетные операции в булевых выражениях. Заключают необязательные варианты в секции проекта Design Section (внутри объявления назначения ресурсов Assignment). |
[ ] (квадратные скобки) |
Заключают диапазон значений в десятичном имени группы |
'...' (одинарные кавычки) |
Заключают символические имена. |
"..." (двойные кавычки) |
Заключают строку в объявлении названия Title Заключают цифры в не десятичных номерах Заключают путь в объявлении Include. Могут (необязательно) заключать имя проекта и устройства в секции проекта Design Section. Могут (необязательно) заключать имя в объявлении назначения клики графа Clique Assignment. |
. (точка) |
Отделяет символические имена переменных в макрофункции или примитиве от имен портов. Отделяет имя файла от расширения |
... (многоточие) |
Разделяет наименьшее и наибольшее значение в диапазонах |
; (точка с запятой) |
Заканчивает объявления и секции в языке AHDL |
, (запятая) |
Разделяет элменты последовательных групп и списков |
: (двоеточие) |
Отделяет символические имена от типов в объявлениях и назначениях ресурсов. |
@ 'собака' |
Присваивает символические узлы выводам устройства и логическим ячейкам в объявлениях назначения ресурсов Resource Assignment |
= (равенство) |
Присваивает значения по умолчанию GND и VCC входам в секции подпроекта Subdesign Присваивает установочные значения в вариантах Присваивает значения состояниям в машине состояний Присваивает значения в булевых уранениях |
=> (стрелка) |
Отделяет входы от выходов в объявлениях таблицы истинности Truth Table Отделяет предложения с WHEN от булевых выражений в операторе Case |
3.8.3. Имена в кавычках и без кавычек В языке AHDL есть три типа имен: * Символические имена - это определяемые пользователем идентификаторы. Они используются для обозначения следующих частей TDF:внутренних и внешних узлов (вершин); констант; переменных цифрового автомата, битов состояний, имен состояний; примеров (Instance). * Имена подпроекта - это определяемые пользователем имена для файлов проекта более низкого уровня. Имя подпроекта должно быть таким же, как имя файла TDF.
В файле Fit вашего проекта могут появиться генерируемые компилятором имена выводов, с символом 'тильда' (~). Этот символ зарезервирован для имен, генерируемых компилятором, пользователю запрещается его использовать для обозначения имен выводов, узлов (вершин), групп (шин). Существуют две формы записи для всех трех типов имен (символических, подпроекта и портов): в кавычках (') и без кавычек. Если разработчик создает символ по умолчанию для файла TDF, который включает в себя имена портов в кавычках, собственно кавычки не входят в имена выводов. Ниже в таблице указаны все возможные варианты записи имен в языке AHDL: |
Разрешенные символы |
Имя подпроекта |
Символическое имя |
Имя порта |
|||||
Без кавычек |
В кавычках |
Без кавычек |
В кавычках |
Без кавычек |
В кавычках |
|||
A-Z |
+ |
+ |
+ |
+ |
+ |
+ |
||
a-z |
+ |
+ |
+ |
+ |
+ |
+ |
||
0-9 |
+ |
+ |
+ |
+ |
+ |
+ |
||
Подчеркивание (_) |
+ |
+ |
+ |
+ |
+ |
+ |
||
Косая черта (/) |
- |
- |
+ |
+ |
+ |
+ |
||
Тире (-) |
- |
+ |
- |
+ |
- |
+ |
||
Только цифры (0-9) |
+ |
+ |
- |
+ |
+ |
+ |
||
Ключевое слово |
- |
+ |
- |
+ |
- |
+ |
||
Максималь-ное число символов |
8 |
8 |
32 |
32 |
32 |
32 |
Примеры: Символические имена без кавычек a, /a : разрешенные -foo, node, 55 : неразрешенные Символические имена в кавычках '-bar', ' table', '1221' :разрешенные'bowling4$', 'has a space ', 'a_name_with_more_than_32_characters' : неразрешенные 3.8.4. Группы Символические имена и порты одного и того же типа можно объявить и использовать как группы в булевых выражениях и уравнениях. Группа, в которую может входить до 256 элементов (или 'битов'), обрабатывается как коллекция узлов (вершин) и считается единым целым. Группа в логической секции файла TDF может состоять из узлов или чисел. Одиночные узлы и константы GND и VCC могут дублироваться для образования групп в булевых выражениях и уравнениях. В файле Fit могут появиться генерируемые компилятором имена выводов, с символом 'тильда' (~). Этот символ зарезервирован для имен, генерируемых компилятором, пользователю запрещается его использовать для обозначения имен выводов, узлов (вершин), групп (шин).3.8.5.1. Форма записи групп Существует две формы записи при объявлении групп: 1. Десятичное имя группы состоит из символического имени (или имени порта), за которым следует диапазон десятичных чисел, заключенный в квадратные скобки, например, a[4..1]. После этого имени группы указывается только один лиапазон. Всего символическое имя (или имя порта) вместе с самым длинным (по написанию) номером в диапазоне может содержать до 32 символов.Если группа определена, квадратные скобки обеспечивают самый кратикий путь задания всего диапазона. Вместо диапазона можно также указывать только одно десятичное число, например, a[5]. Однако такая форма записи означает единственное символическое имя, а не имя грцппы и эквивалентно имени a5. 2. Последовательное имя группы состоит из заключенного в скобки перечня символических имен, имен портов или чисел, разделенных запятыми, например, (a, b, c). В этом перечне могут быть также десятичные имена групп, например, (a, b, c[5..1]). Такая запись используется для задания имен портов.Например: reg. (d, clk, clrn, prn). В следующем примере показаны варианты записи одной и той же группы: b[5..0] (b5, b4, b3, b2, b1, b0) b[]
3.8.5.2. Диапазон и поддиапазон групп Диапазоны в десятичных именах групп обозначаются десятичными номерами, обычно перечисляемыми в порядке убывания. Для того чтобы указать диапазон в порядке возрастания или в обоих порядках, разработчик должны установить опцию BIT0 в объявлении опций Options; тогда компилятор не будет выдавать предупреждающие сообщенияПоддиапазоны включают подмножество узлов, заданных в объявлении группы; их можно указывать различными способами. Например, если разработчик объявили группу c[5..1], разработчик можете использовать следующие поддиапазоны этой группы: c[3..1], c4, c[5], (c2,, c4). В левой части булевых уравнений или в ссылках (reference) по тексту программы (in-line) на макрофункции или примитивы в написании имени группы можно использовать запятые вместо перечисления имен. При указании диапазона вместо чисел можно использовать константы. Например, q[MAX..0] является разрешенной формой записи, если константа MAX определена в объявлении Constant.3.8.6. Числа в языке AHDL В языке AHDL можно использовать десятичные, двоичные, восьмиричные и шестнадцатиричные числа в любой комбинации. В таблице приведен синтаксис записи чисел в языке AHDL для каждой системы счисления. |
Система счисления |
Значения |
Десятичная |
<последовательность цифр 0-9> |
Двоичная |
B"<последовательность из 0, 1, X>", где символ Х обозначает безразличное значение |
Восьмиричная |
O"< последовательность цифр 0-7>" или Q"< последовательность цифр 0-7>" |
Шестнадцатиричная |
X"< последовательность цифр 0-9, букв A-F>" или H"< последовательность цифр 0-9, букв A-F>" |
Примеры разрешенной записи чисел в языке AHDL: B"0110X1X10" Q"4671223" H"123AECF" К числам в языке AHDL применяются следующие правила: 3.8.7. Булевы выражения Булевы выражения состоят из операндов, разделенных логическими и арифметическими операторами и компараторами и (необязательно) сгруппированных с помощью круглых скобок. Выражения используются в булевых уравнениях, а также в других конструкциях языка, таких как операторы Case и If.Существуют следующие применения булевых выражений: * Операнд. Пример: a, b[5..1], 7, VCC * Встроенная в текст (in-line) ссылка (reference) на примитив или макрофункцию. * Префиксный оператор (! или -), примененный к булеву выражению. Пример: !c * Два булевых выражения, разделенные двоичным (не префиксным) оператором. Пример: d1 $ d3 * Заключенное в круглые скобки булево выражение. Пример: (!foo & bar) Результат каждого булева выражения должен иметь ту же ширину, что и узел или группа (в левой стороне уравнения), которому он, в конечном счете, присваивается. 3.8.8. Логические операторы В таблице приведены логические операторы для булевых выражений. |
Оператор: |
Пример: |
Описание: |
! |
!tob |
Дополнение (префиксное обращение) |
NOT |
NOT tob |
|
& |
bread & butter |
Логическое И |
AND |
bread AND butter |
|
!& |
a[3..1] !& b[5..3] |
Обращение логического И |
NAND |
a[3..1] NAND b[5..3] |
|
# |
trick # treat |
Логическое ИЛИ |
OR |
trick OR treat |
|
!# |
c[8..5] !# d[7..4] |
Обращение логического ИЛИ |
NOR |
c[8..5] NOR d[7..4] |
|
$ |
foo $ bar |
Исключающее ИЛИ |
XOR |
foo XOR bar |
|
!$ |
x2 !$ x4 |
Обращение исключающего |
XNOR |
x2 XNOR x4 |
логического ИЛИ |
Каждый оператор представляет собой логический вентиль с двумя входами; исключение составляет оператор NOT, являющийся префиксным инвертором. Для записи логического оператора можно использовать его имя или символ. Выражения, в которых используются эти операторы, интерпретируются по-разному в зависимости от того, что представляют собой операнды: одиночные узлы (вершины), группы или числа. Кроме того, выражения с оператором NOT интерпретируются не так как другие логические операторы. 3.8.8. Выражения с оператором NOT С оператором NOT можно использовать три типа операндов:
Выражения с операторами AND, NAND, OR, NOR, XOR, & XNORСуществует четыре комбинации операндов с двоичными (не префиксными) операторами, и каждая из них интерпретируется по-особому.
Выражение с константой VCC интерпретируется не так как выражение с операндом 1. В первом выражении приведенного ниже примера число 1 расширяется по числу битов двоичного представления, чтобы соответствовать размеру группы. Во втором уравнении узел VCC дублируется для образования группы того же размера. Затем каждое уравнение интерпретируется как групповая операция .! operation. (a, b, c) & 1 = (0, 0, c) (a, b, c) & VCC = (a, b, c). 3.8.9. Арифметические операторы
Арифметические операторы используются для выполнения арифметических операций сложения и вычитания над группами и числами. В языке AHDL применяются следующие арифметические операторы: |
Оператор : |
Пример : |
Описание : |
+ (унарный) |
+1 |
Положительное значение |
- (унарный) |
-a[4..1] |
Отрицательное значение |
+ |
count[7..0] + delta[7..0] |
Сложение |
- |
rightmost_x[] - leftmost_x[] |
Вычитание |
Унарные плюс (+) и минус (-) являются префиксными операторами. Оператор + не влияет на свой операнд, и разработчик можете использовать его для иллюстративных целей (т.е. для указания положительного числа). Оператор - интерпретирует свой операнд в двоичном представлении (если он таковым не является с самого начала). Затем он выполняет операцию унарного минуса, т.е. получает дополнение операнда как двоичного числа. К другим арифметическим операторам применяются следующие правила:
3.8.10. Компараторы (Операторы сравнения) Компараторы используются для сравнения одиночных узлов или групп. Существует два типа компараторов: логические и арифметические. В языке AHDL реализованы следующие компараторы: |
Компаратор : |
Пример : |
Описани е: |
== (логический) |
addr[19..4] == B"B800" |
Равны ? |
!= (логический) |
b1 != b3 |
Не равны ? |
< (арифметический) |
fame[] < power[] |
Меньше чем ? |
<= (арифметический) |
money[] <= power[] |
Меньше либо равно ? |
> (арифметический c) |
love[] > money[] |
Больше чем ? |
>= (арифметический) |
delta[] >= 0 |
Больше либо равно ? |
Оператор (==) используется исключительно в булевых выражениях. Логические компараторы могут сравнивать одиночные узлы, группы узлов и числа. При сравнении групп узлов или чисел размер групп должен быть одинаковым. Компилятор системы MAX+PLUS II выполняет побитовое сравнение групп и возвращает значение VCC, если результат истина, и GND, если результат -ложь. Арифметические компараторы могут сравнивать только группы узлов и числа, и группы должны иметь одинаковый размер. Компилятор выполняет над группами операции беззнакового сравнения значений, т.е. каждая группа интерпретируется как положительное двоичное число и сравнивается с другой группой. 3.8.11. Приоритеты в булевых уравнениях Операнды, разделенные логическими и арифметическими операторами и компараторами, оцениваются по правилам приоритетов, перечисленным ниже (приоритет 1 является наивысшим). Равноприоритетные операции выполняются по очереди, слева направо. Порядок выполнения может быть изменен с помощью заключения в круглые скобки. |
Приоритет : |
Оператор |
Компаратор |
1 |
- |
(отрицание) |
1 |
! |
(логическое НЕ) |
2 |
+ |
(сложение) |
2 |
- |
(вычитание) |
3 |
== |
(равно?) |
3 |
!= |
(не равно?) |
3 |
< |
(меньше чем) |
3 |
<= |
(меньше либо равно) |
3 |
> |
(больше чем) |
3 |
>= |
(больше либо равно) |
4 |
& |
(AND) |
4 |
!& |
(NAND) |
5 |
$ |
(XOR) |
5 |
!$ |
(XNOR) |
6 |
# |
(OR) |
6 |
!# |
(NOR) |
3.8.12. Примитивы В системе MAX+PLUS II есть разнообразные примитивные функции для проектирования электрических схем. Поскольку логические операторы, порты и некоторые объявления языка AHDL заменяют примитивы в файлах TDF, написанных на языке AHDL, примитивы языка AHDL являются подмножеством примитивов, которые имеются для файлов графического проекта (GDF-файл), как будет показано ниже. В файлах TDF нет необходимости использования прототипов функций языка AHDL для примитивов. Однако путем включения в ваш TDF-файл прототипа функции разработчик можете переопределить порядок вызова входов примитива. 3.8.12.1. Примитивы буферов CARRY LCELL (MCELL) CASCADE SOFT EXP TRI GLOBAL (SCLK)
Примитив CARRY (перенос)Прототип функции: FUNCTION CARRY (in) RETURNS (out); Примитив CARRY определяет логику 'переноса на выход' (carry-out) для одной функции и действует как 'перенос на вход' (carry-in) для другой функции. Функция переноса (carry) осуществляет логику быстрого переноса по цепочке для таких функций как сумматоры и счетчики. Примитив CARRY поддерживается только для устройств семейства FLEX 8000. Для других устройств он игнорируется. Если разработчик используете примитив CARRY некорректно, он игнорируется и компилятор выдает соответствующее предупреждающее сообщение. Вы можете позволить компилятору автоматически вставлять и убирать CARRY во время синтеза логики; для этого нужно выбрать опцию логики с переносом по цепочке Carry Chain или стиль синтеза логики, который включает эту опцию.Примитив CASCADE (каскад)Прототип функции: FUNCTION CASCADE (in) RETURNS (out); Буфер CASCADE определяет функцию каскадного выхода из логической схемы И (AND) или ИЛИ (OR) и действует как входной каскад для другой логической схемы И или ИЛИ. Функция входного каскада позволяет организовать каскадный процесс, который представляет собой быстрый выход, расположенный на каждой Комбинационной логической ячейке и участвующий в операции ИЛИ или И с выходом соседней Комбинационной логической ячейки в устройстве. С помощью примитива CASCADE логическая ячейка И или ИЛИ, которая питает примитив CASCADE и логическая ячейка И или ИЛИ, которая запитывается примитивом CASCADE, помещаются в одном устройстве, причем первый символ после проведения над ним логической операции И или ИЛИ переходит во второй символ. Примитив CASCADE поддерживается только для устройств семейства FLEX 8000. Для других устройств он игнорируется. При использовании примитива CASCADE, нужно соблюдать следующие правила:
Если разработчик использует примитив CASCADE некорректно, он игнорируется и компилятор выдает соответствующее предупреждающее сообщение. Вы можете позволить компилятору автоматически вставлять и убирать примитивы CASCADE во время синтеза логики; для этого нужно выбрать опцию логики с переносом по цепочке Cascade Chain или стиль синтеза логики, который включает эту опцию.Примитив EXP (расширитель)Прототип функции: FUNCTION EXP (in) RETURNS (out); Расширительный буфер EXP определяет необходимость дополнительного места при вычислении произведения в проекте. Произведение из расширителя в устройстве инвертируется. Примитив EXP поддерживается только семейством устройств MAX5000/EPS464 и MAX 7000. В других устройствах он рассматривается как логическая схема НЕ (NOT). Для каждого отдельного устройства нужно ознакомиться с его техническим паспортом, чтобы узнать, как конкретное устройство использует логические ячейки и расширительные буферы для вычисления произведений. Будет или нет использоваться расширитель для произведения, зависит от полярности логики, требуемой вычисляемыми функциями. Например, если буфер EXP питает две логические схемы И (AND) (т.е. логическое умножение), а вторая схема И имеет инвертированный вход, то примитив EXP, питающий инвертированный вход, во время логического синтеза убирается, создавая, таким образом, положительную логику. Примитив EXP, питающий неинвертированный вход, не убирается, и для реализации логики используется расширитель для произведения. Обычно логический синтезатор определяет, куда вставлять и откуда убирать буферы. Фирма Altera рекомендует, чтобы только опытные разработчики использовали примитив EXP в своих проектах. В устройствах, содержащих много логических блоков (LAB) , выход буфера EXP может формировать сигнал только в пределах одного LAB. Примитив EXP дублируется для каждого LAB, где он требуется. Если проект содержит много расширительных буферов, логический синтезатор может преобразовать их в буферы LCELL, чтобы сбалансировать использование расширителя для произведения и логической ячейки. Не используйте примитивы EXP для создания намеренной задержки или асинхронного импульса. Задержка этих элементов изменяется с температурой, напряжением питания и при процессах изготовления устройства, поэтому может возникнуть режим состязания и получится ненадежная схема. Примитив GLOBAL (глобальный)Прототип функции: FUNCTION GLOBAL (in) RETURNS (out); Буфер GLOBAL указывает, что сигнал (signal) должен использовать глобальный синхронный сигнал Clock, Clear, Preset или Output Enable вместо сигналов, сгенерированных внутренней логикой или поступающих через обычные выводы вход/выход (I/O ). Глобальные сигналы используются в различных семействах устройств в соответствии с их синхронизацией. Если входной вывод формирует сигнал непосредственно на вход примитива GLOBAL, то выход примитива GLOBAL может быть использован, чтобы формировать сигнал на входы Clock, Clear, Preset или Output Enable к примитиву. Должно существовать непосредственное соединение от выхода GLOBAL ко входу регистра или буфера TRI. Если буфер GLOBAL формирует сигнал вход сигнала Output Enable буфера TRI, может потребоваться логическая схема НЕ (NOT). Один единственный вход может проходить через GLOBAL перед тем как формировать сигнал для входа регистра для сигналов Clock, Clear или Preset или вход буфера TRI для сигнала Output Enable. Глобальные синхросигналы распространяются быстрее, чем асинхронные (array) сигналы, и могут освобождать ресурсы устройства для реализации другой логики. Для осуществления синхронизации части или всего проекта следует использовать примитив GLOBAL. Для того чтобы проверить, имеют ли регистры глобальную синхронизацию, нужно просмотреть файл отчета Report File обрабатываемого проекта. Если ваш проект устройства MAX 5000 сочетает асинхронный режим работы и режим с глобальной синхронизацией, а модуль компилятора Fitter не может выбрать подходящий, проблема может быть решена удалением буфера GLOBAL. Если аналогичная проблема встретится вам в проекте MAX 7000, замените асинхронный режим режимом с глобальной синхронизацией. В качестве альтернативы использованию примитива GLOBAL разработчик можете продоставить компилятору автоматически выбирать, каким будет существующий сигнал проекта, глобальным Clock, Clear, Preset или Output Enable, посредством команды Logic Synthesis.Примитив LCELLПрототип функции: FUNCTION LCELL (in) RETURNS (out); Буфер LCELL выделяется для логической ячейки проекта. Буфер LCELL вырабатывает истинное значение и дополнение логической функции и делает их доступными для всей логики устройства. Для обратной совместимости с более ранними версиями системы MAX+PLUS II имеется буфер MCELL, функционально такой же, как и буфер LCELL. В новых проектах следует использовать только буфер LCELL. Буфер LCELL всегда занимает одну логическую ячейку. Он не удаляется из проекта во время логического синтеза. Не используйте примитивы LCELL для создания задержки или асинхронного импульса. Задержка этих элементов изменяется с температурой, напряжением питания и в процессе изготовления изделия, поэтому могут возникнуть режимы состязаний. С помощью команды компилятора Automatic LCELL Insertion разработчик может дать указание компилятору автоматически вставлять буферы LCELL в проект, если это необходимо для трассировки проекта в том случае, когда назначения определенных пользователем ресурсов и имеющиеся у устройства, не обеспечивают подгонки монтажа в проекте. Примитив SOFT
Прототип функции: FUNCTION SOFT (in) RETURNS (out); Буфер SOFT устанавливает, что логическая ячейка может понадобиться в проекте. При обработке проекта процессором логический синтезатор исследует логику, питающую прмитив, и определяет, нужна ли логическая ячейка. Если нужна, буфер SOFT преобразуется в LCELL; в противном случае, SOFT удаляется. Если компилятор показывает, что проект слишком сложный, разработчик можете редактировать проект, вставляя буферы SOFT для предотвращения расширения логики. Например, разработчик можете добавить буфер SOFT в комбинаторный выход макрофункции для развязки двух комбинаторных цепей. разработчик можете также включить логическую опцию SOFT Buffer Insertion в стили логического синтеза по умолчанию в проект, чтобы компилятор вставлял буферы SOFT автоматически.Примитив TRI
Прототип функции: FUNCTION TRI (in, oe) RETURNS (out); Примитив TRI представляет собой трехстабильный буфер с сигналами входным, выходным и Output Enable (Отпирание выхода). Если уровень сигнала Output Enable высокий, выход будет управляться входом. При низком уровне сигнала Output Enable выход переходит в состояние высокого импеданса, что позволяет использовать I/O как входной вывод. По умолчанию сигнал Output Enable устанавливается в значение VCC. Если сигнал Output Enable буфера TRI подсоединяется к VCC или логической функции, которая будет минимизировать до истины, буфер TRI может быть преобразован в буфер SOFT во время логического синтеза. При использовании буфера TRI нужно соблюдать следующие правила:
Примитивы FLIPFLOP (ждущий мультивибратор) & LATCH (триггер-защелка)
DFF SRFF DFFE SRFFE JKFF TFF JKFFE TFFE LATCH Примитивы Latch описывают D-триггер, управляемый уровнями тактовых сигналов, триггер-защелка.Когда входной сигнал разрешения D-триггера ENA (Latch Enable) имеет высокий уровень, D-триггер пропускает сигнал от D к Q. Если вход ENA имеет низкий уровень, сохраняется состояние Q, несмотря на входной сигнал D. Для устройств, не поддерживающих сигнал Latch Enable, логический синтез генерирует логические уравнения, содержащие D-триггеры с сигналами Latch Enable. эти логические уравнения корректно эмулируют логику, заданную в вашем проекте. Все ждущие мультивибраторы (Flipflop) переходят в рабочее состояние по положительному перепаду сигнала. Примитив LATCH
Прототип функции: FUNCTION LATCH (D, ENA) RETURNS (Q);
|
Inputs |
Output |
|
ENA |
D |
Q |
L |
X |
Qo* |
H |
L |
L |
H |
H |
H |
* Qo = уровень Q перед тактовым импульсом. Примитив DFF (D-триггер типа, Flipflop)Прототип функции: FUNCTION DFF (D, CLK, CLRN, PRN) RETURNS (Q);
|
Inputs |
Output |
|||
PRN |
CLRN |
CLK |
D |
Q |
L |
H |
X |
X |
H |
H |
L |
X |
X |
L |
L |
L |
X |
X |
Запрещенное состояние |
H |
H |
L |
L |
|
H |
H |
H |
H |
|
H |
H |
L |
X |
Qo * |
H |
H |
H |
X |
Qo |
* Qo = уровень Q перед тактовым импульсом. Примитив DFFE
Прототип функции: FUNCTION DFFE (D, CLK, CLRN, PRN, ENA) RETURNS (Q); |
Inputs |
Output |
||||
CLRN |
PRN |
ENA |
D |
CLK |
Q |
L |
H |
X |
X |
X |
L |
H |
L |
X |
X |
X |
H |
L |
L |
X |
X |
X |
Illegal |
H |
H |
L |
X |
X |
Qo* |
H |
H |
H |
L |
L |
|
H |
H |
H |
H |
H |
|
H |
H |
X |
X |
L |
Qo* |
* Qo = уровень Q перед тактовым импульсом. Примитив TFF (Триггер Т-типа, Flipflop)Прототип функции: FUNCTION TFF (T, CLK, CLRN, PRN) RETURNS (Q); |
Inputs |
Output |
|||
PRN |
CLRN |
CLK |
T |
Q |
L |
H |
X |
X |
H |
H |
L |
X |
X |
L |
L |
L |
X |
X |
Illegal |
H |
H |
L |
Qo* |
|
H |
H |
H |
Toggle |
|
H |
H |
L |
X |
Qo* |
* Qo = уровень Q перед тактовым импульсом. Примитив TFFE
Прототип функции: FUNCTION TFFE (T, CLK, CLRN, PRN, ENA) RETURNS (Q); |
Inputs |
Output |
||||
CLRN |
PRN |
ENA |
T |
CLK |
Q |
L |
H |
X |
X |
X |
L |
H |
L |
X |
X |
X |
H |
L |
L |
X |
X |
X |
Illegal |
H |
H |
L |
X |
X |
Qo* |
H |
H |
H |
L |
Qo* |
|
H |
H |
H |
H |
Toggle |
|
H |
H |
X |
X |
L |
Qo* |
Примитив JKFF (Триггер JK-типа, Flipflop)Прототип функции: FUNCTION JKFF (J, K, CLK, CLRN, PRN) RETURNS (Q); |
Inputs |
Output |
||||
PRN |
CLRN |
CLK |
J |
K |
Q |
L |
H |
X |
X |
X |
H |
H |
L |
X |
X |
X |
L |
L |
L |
X |
X |
X |
Illegal |
H |
H |
L |
X |
X |
Qo* |
H |
H |
L |
L |
Qo* |
|
H |
H |
H |
L |
H |
|
H |
H |
L |
H |
L |
|
H |
H |
H |
H |
Toggle |
* Qo = уровень Q перед тактовым импульсом. Примитив JKFFEПрототип функции: FUNCTION JKFFE (J, K, CL K, CLRN, PRN, ENA)RETURNS (Q); |
Inputs |
Output |
|||||
ENA |
PRN |
CLRN |
CLK |
J |
K |
Q |
X |
L |
H |
X |
X |
X |
H |
X |
H |
L |
X |
X |
X |
L |
X |
L |
L |
X |
X |
X |
Illegal |
X |
H |
H |
L |
X |
X |
Qo* |
H |
H |
H |
L |
L |
Qo* |
|
H |
H |
H |
H |
L |
H |
|
H |
H |
H |
L |
H |
L |
|
H |
H |
H |
H |
H |
Toggle |
|
L |
H |
H |
X |
X |
X |
Qo* |
* Qo = level of Q before Clock pulse Примитив SRFF (Триггер SR-типа, Flipflop)Прототип функции: FUNCTION SRFF (S, R, CLK, CLRN, PRN) RETURNS (Q);
|
Inputs |
Output |
||||
PRN |
CLRN |
CLK |
S |
R |
Q |
L |
H |
X |
X |
X |
H |
H |
L |
X |
X |
X |
L |
L |
L |
X |
X |
X |
Illegal |
H |
H |
L |
X |
X |
Qo* |
H |
H |
L |
L |
Qo* |
|
H |
H |
H |
L |
H |
|
H |
H |
L |
H |
L |
|
H |
H |
H |
H |
Toggle |
* Qo = уровень Q перед тактовым импульсом. Примитив SRFFE
Прототип функции: FUNCTION SRFFE (S, R, CLK, CLRN, PRN, ENA) RETURNS (Q); |
Inputs |
Output |
|||||
ENA |
PRN |
CLRN |
CLK |
S |
R |
Q |
X |
L |
H |
X |
X |
X |
H |
X |
H |
L |
X |
X |
X |
L |
X |
L |
L |
X |
X |
X |
Illegal |
X |
H |
H |
L |
X |
X |
Qo* |
H |
H |
H |
L |
L |
Qo* |
|
H |
H |
H |
H |
L |
H |
|
H |
H |
H |
L |
H |
L |
|
H |
H |
H |
H |
H |
Toggle |
|
L |
H |
H |
X |
X |
X |
Qo* |
3.813. Порты Порт представляет собой вход или выход примитива, макрофункции или цифрового автомата. Порт может появляться в трех местах файла:
3.8.13.1. Порты текущего файла Порт, являющийся входом или выходом текущего файла, объявляется в секции подпроекта Subdesign следующим образом: <имя порта> : <тип порта> [ = <значение порта по умолчанию> ] Есть следующие типы портов: INPUT MACHINE INPUT OUTPUT MACHINE OUTPUT BIDIR Если TDF-файл является файлом верхнего уровня иерархии, имя порта является синонимом имени вывода. Для портов типа INPUT и BIDIR может быть определено по умолчанию значение VCC или GND. Это значение используется только если порт остается неподключенным в случае использования примера данного TDFа в файле более высокого уровня. Входные и выходные порты, объявленные в секции подпроекта Subdesign, могут быть назначены выводам, логическим элементам, чипам, кликам и логическим опциям при назначении ресурсов Resource Assignment в секции проекта Design. Назначения выводов могут быть сделаны только на верхнем уровне иерархии. Любые назначения выводов на более низких иерархических уровнях игнорируются. В приводимом ниже примере в секции подпроекта Subdesign объявлены входные, выходные и двунаправленные порты, а в секции проекта Design два входных порта назначаются (присваиваются) выводам. DESIGN IS top BEGIN DEVICE IS AUTO BEGIN foo @ 1, bar @ 2 : INPUT; END; END; SUBDESIGN top ( foo, bar, clk1, clk2 : INPUT = VCC; % VCC - это значение порта по умолчанию % a0, a1, a2, a3, a4 : OUTPUT; b[7..0] : BIDIR; ) Между файлами TDF, (GDF-файл) или *.WDF можно осуществлять импортирование и экспортирование цифровых автоматов (state machine), если разработчик определит входной или выходной порт как MACHINE INPUT или MACHINE OUTPUT в секции подпроекта Subdesign. В прототипе функции (Function Prototype), описывающем этот файл, должно быть указано, какие порты являются цифровыми автоматами с памятью (state machine). Порты MACHINE INPUT и MACHINE OUTPUT можно использовать только в файлах более низких уровней в иерархии проекта. 3.8.13.2. Порты примеров (INSTANCE) Соединение порта, являющегося входом или выходом примера (instance) в файл проекта более низкого уровня или примитивы, осуществляется в логической секции Logic. Для соединения примитива, макрофункции или цифрового автомата с другими частями файла TDF нужно вставить пример (instance) примитива или макрофункции как ссылку с ключевым словом in-line или дать в конструкции объявления примера Instance или объявить цифровой автоматв конструкции State Machine, а затем использовать порты функции в логической секции.Если разработчик для вставки примера примитива или макрофункции использует ссылку с ключевым словом in-line, важен порядок перечисления портов, но не их имена. Этот порядок определяется в прототипе функции для примитива или макрофункции.Если для вставки примера разработчик используете конструкцию объявления примера Instance, важны имена портов, а не порядок их перечисления. Имена портов даются в следующем формате:<имя примера>.<имя порта> Здесь <имя примера> представляет собой определенное пользователем имя функции, а <имя порта> совпадает с именем порта, объявленного в логической секции файла TDF более низкого уровня или совпадает с именем вывода в файле проекта другого типа. Это <имя порта> является синонимом имени штыревого вывода для символа, который представляет пример данного файл проектаа в файле (GDF-файл). В приводимом ниже примере триггер (flipflop) типа D объявлен как переменная reg в секции объявления переменных VARIABLE и затем используется в логической секции.VARIABLE reg : DFF; BEGIN reg.clk = clk reg.d = d out = reg.q END; Все поставляемые фирмой Altera примитивы и макрофункции имеют предопределенные имена портов (штыревые выводы), которые описываются в прототипе функции. Наиболее широко используемые имена портов приведены в таблице: |
Имя порта |
Описание |
.q |
Выход двухстабильного мультивибратора (flipflop) или тригера-защелки (latch) |
.d |
Информационный вход в триггер D-типа (flipflop) или триггер-защелку (lat ch) |
.t |
Вход переключения (Toggle) триггера T-типа (flipflop) |
.j |
Вход J триггера J-K-типа (flipflop) |
.k |
Вход K триггера J-K-типа (flipflop) |
.s |
Вход S триггера S-R-типа (flipflop) |
.r |
Вход R триггера S-R-типа (flipflop) |
.clk |
Вход тактового сигнала (Clock) триггера (flipflop) |
.ena |
Вход отпирания тактового сигнала (Clock Enable) для триггера, отпирания защелки (Latch Enable) и отпирания цифрового автомата (Enable) |
.prn |
Вход установки триггера (flipflop) Preset с низким активным уровнем |
.clrn |
Вход сброса триггера (flipflop) Clear с низким активным уровнем |
.reset |
Вход цифрового автомата Reset с высоким активным уровнем |
.oe |
Вход Output Enable (отпирание выхода) примитива TRI |
.in |
Основной вход примитивов TRI, SOFT, GLOBAL и LCELL |
.out |
Выход примитивов TRI, SOFT, GLOBAL и LCELL |
3.9. Синтаксис языка ahdl3.9.1. Лексические элементы Синтаксис лексических элементов языка AHDL описан ниже с использованием формул Бэкуса-Наура. <основание системы счисления> ::= B | Q | H | O | X | b | q | h | o | x <число с основанием> ::= < основание системы счисления > " <цифра> { <цифра> }" <цифра> ::= <буква> | <десятичная цифра> <столбец> ::= <десятичная цифра >:1:2 <символ комментария> ::= <любой символ, кроме %> | %% <комментарий> ::= % { < символ комментария > } %| -- { < символ комментария > } <конец строки> <десятичное число> ::= <десятичная цифра>:1:10 <имя проекта> ::= <имя файла> <вывод устройства> ::= <символ имени>:1:3 <десятичная цифра> ::= 0 | 1 |... | 9 <имя файла> ::= (<символ имени>):1:8 | ' (<символ имени в кавычках>):1:8 ' <лабиринт> ::= <строка матрицы> <столбец> <буква> ::= A |... | Z | a |... | z <логический элемент> ::= LC <десятичная цифра>:1:3 | LC <десятичная цифра>:1:2 <лабиринт> | MC <десятичная цифра>:1:3 | MC <десятичная цифра>:1:2 <лабиринт> <символ имени> ::= <буква> | <десятичная цифра> | _ <число> ::= <десятичное число> | <число с основанием> <имя порта> ::= (<символ имени> | /):1:32 | ' (<символ имени в кавычках> | /):1:32 ' < символ имени в кавычках >::= <символ имени> | - <строка матрицы> ::= <буква> <символ строки> ::= <любой символ, кроме " и символа перехода на новую строку> | "" <строка> ::= " { <символ строки> }" <символическое имя> ::= (<имя символа> | /):1:32 | ' (<символ имени в кавычках> | /):1:32 ' Символическое имя без кавычек не может состоять из одних цифр. 3.9.2. Основные конструкции языка AHDL С помощью формул Бэкуса-Наура синтаксис файла TDF можно описать следующим образом: <файл AHDL > ::= <оператор AHDL > { < оператор AHDL > } < оператор AHDL > ::=<название> | <задание константы> | <прототип> | <оператор включения > | < варианты> | < секция проекта > | <секция подпроекта> <операторы> ::= <оператор> { <оператор> } <оператор> ::= <булево уравнение> | <оператор выбора> | <условный оператор> | <оператор таблицы> | <присвоение по умолчанию> <название> ::= TITLE <строка>; <задание константы> ::= CONSTANT <символическое имя> = <число>; <прототип> ::= FUNCTION <макрофункция> ( <список входов> ) RETURNS ( <список выходов> ); | FUNCTION <примитив> ( <список входов> ) RETURNS ( <список выходов> ); <макрофункция> ::= <имя проекта> <примитив> ::= <символическое имя> <список входов> ::= <группа прототипа> {, <группа прототипа> } <список выходов> ::= <группа прототипа> {, <группа прототипа> } <оператор включения> ::= INCLUDE <строка> ; <вариант> ::= <вариант устройства> | <вариант 0-го бита AHDL > | <логическая опция> <вариант устройства> ::= | SECURITY = (ON | OFF) | TURBO = (ON | OFF | DEFAULT) <вариант 0-го бита AHDL > ::= BIT0 = (ANY-произвольный | LSB-младший | MSB-старший) <логическая опция> ::= CARRY_CHAIN = (AUTO | IGNORE | MANUAL | DEFAULT) | CASCADE_CHAIN = (AUTO | IGNORE | MANUAL | DEFAULT) | DECOMPOSE_GATES = (ON | OFF | DEFAULT) | DUPLICATE_LOGIC_EXTRACTION = (ON | OFF | DEFAULT) | EXPANDER_FACTORING = (ON | OFF | DEFAULT) | MINIMIZATION = (FULL | PARTIAL | NONE | DEFAULT) | MULTI-LEVEL_FACTORING = (ON | OFF | DEFAULT) | NOT_GATE_PUSH-BACK = (ON | OFF | DEFAULT) | OPTIMIZE = (AREA | DELAY | ROUTING | DEFAULT) | PARALLEL_EXPANDERS = (ON | OFF | DEFAULT) | PERIPHERAL_REGISTER = (ON | OFF | DEFAULT) | REDUCE_LOGIC = (ON | OFF | DEFAULT) | REFACTORIZATION = (ON | OFF | DEFAULT) | REGISTER_OPTIMIZATION = (ON | OFF | DEFAULT) | RESYNTHESIZE_NETWORK = (ON | OFF | DEFAULT) | SLOW_SLEW_RATE = (ON | OFF | DEFAULT) | SOFT_BUFFER_INSERTION = (ON | OFF | DEFAULT) | STYLE = <имя стиля> | SUBFACTOR_EXTRACTION = (ON | OFF | DEFAULT) | TURBO = (ON | OFF | DEFAULT) | XOR_SYNTHESIS = (ON | OFF | DEFAULT) <имя стиля> ::= FAST | WYSIWYG | NORMAL | <стиль пользователя> <стиль пользователя> ::= <символическое имя> Каждый <вариант> за исключением BIT0 и имени стиля может быть сокращен до 3 первых символов по обе стороны от знака равенства (=). Однако фирма Altera рекомендует писать полные имена для удобства документирования. 3.9.3. Синтаксис объявления названия <название> ::= TITLE <строка>; 3.9.4. Синтаксис оператора включения <оператор включения> ::= INCLUDE <имя файла> ; Описываемый в операторе включения файл должен иметь расширение. inc, а <имя файла> не должно содержать путь.3.9.5. Синтаксис задания константы <задание константы> ::= CONSTANT <символьное имя> = <число>; 3.9.6. Синтаксис прототипа функции <прототип> ::= FUNCTION <макрофункция> ( <список входов> ) RETURNS ( <список выходов> ); | FUNCTION <примитив> ( <список входов> ) RETURNS ( <список выходов> ); <макрофункция> ::= <имя проекта> <примитив> ::= <символьное имя> <список входов> ::= <группа прототипа> {, <группа прототипа> } <список выходов> ::= <группа прототипа> {, <группа прототипа> } 3.9.7. Синтаксис оператора вариантов <варианты> ::= OPTIONS <вариант> {, <вариант> }; <вариант> ::= <вариант устройства> | <вариант 0-го бита AHDL> | < логическая опция><вариант устройства> ::= | SECURITY = (ON-вкл | OFF-откл) | TURBO = (ON-вкл | OFF-откл | DEFAULT-по умолчанию) <вариант 0-го бита AHDL> ::= BIT0 = (ANY-произвольный | LSB-младший | MSB-старший) <логическая опция> ::= CARRY_CHAIN = (AUTO-авто | IGNORE-игнорировать | MANUAL-ручной | DEFAULT-по умолчанию)| CASCADE_CHAIN = (AUTO | IGNORE | MANUAL | DEFAULT) | DECOMPOSE_GATES = (ON-вкл | OFF-откл | DEFAULT-по умолчанию) | DUPLICATE_LOGIC_EXTRACTION = (ON | OFF | DEFAULT) | EXPANDER_FACTORING = (ON | OFF | DEFAULT) | MINIMIZATION = (FULL-полная | PARTIAL-частичная | NONE-нет | DEFAULT-по умолчанию) | MULTI-LEVEL_FACTORING = (ON | OFF | DEFAULT) | NOT_GATE_PUSH-BACK = (ON | OFF | DEFAULT) | OPTIMIZE = (AREA-площадь | DELAY-задержка | ROUTING-маршрутизация | DEFAULT-по умолчанию) | PARALLEL_EXPANDERS = (ON | OFF | DEFAULT) | PERIPHERAL_REGISTER = (ON | OFF | DEFAULT) | REDUCE_LOGIC = (ON | OFF | DEFAULT) | REFACTORIZATION = (ON | OFF | DEFAULT) | REGISTER_OPTIMIZATION = (ON | OFF | DEFAULT) | RESYNTHESIZE_NETWORK = (ON | OFF | DEFAULT) | SLOW_SLEW_RATE = (ON | OFF | DEFAULT) | SOFT_BUFFER_INSERTION = (ON | OFF | DEFAULT) | STYLE = <имя стиля> | SUBFACTOR_EXTRACTION = (ON | OFF | DEFAULT) | TURBO = (ON | OFF | DEFAULT) | XOR_SYNTHESIS = (ON | OFF | DEFAULT) <имя стиля> ::= FAST | WYSIWYG | NORMAL | <стиль пользователя> <стиль пользователя> ::= <символьное имя> 1. Каждый <вариант> кроме BIT0 и имени стиля может быть сокращен до трех символов по обеим сторонам знака равенства (=). Однако фирма Altera рекомендует использовать полное имя для удобства документации. 2. Типы вариантов, которые могут быть включены в оператор OPTIONS, определяются местоположением этого оператора и правилами построения содержимого файла. 3.9.8. Синтаксис секции подпроекта Subdesign <секция подпроекта> ::= SUBDESIGN <имя проекта> ( { <список сигналов> ; } <список сигналов> [ ; ] ) [ <переменные> ] BEGIN <операторы> END; <список сигналов> ::= <список портов> : <тип порта> <тип порта> ::= INPUT [ = VCC | = GND ] | OUTPUT | BIDIR [ = VCC | = GND ] | MACHINE INPUT | MACHINE OUTPUT Ключевые слова BEGIN и END обрамляют логическую секцию, которая является телом секции подпроекта.3.9.9. Синтаксис секции переменных <переменные> ::= VARIABLE <список портов> : <тип переменной> ; { <список портов> : <тип переменной> ; } <тип переменной> ::= NODE | <макрофункция> | <примитив> | <цифровой автомат (state machine)> | <псевдоним цифрового автомата> <макрофункция> ::= < имя проекта><примитив> ::= <символьное имя> 3.9.10. Синтаксис объявления цифрового автомата <символьное имя> : <цифровой автомат (state machine)>; <цифровой автомат (state machine)> ::= MACHINE [ <биты> ] <состояния> <биты> ::= OF BITS ( <список портов> ) <состояния> ::= WITH STATES ( <состояние> {, <состояние> } ) <состояние> ::= <символьное имя> [ = <значение состояния> ] <значение состояния> ::= <число> | <символьное имя> 3.9.11. Синтаксис объявления псевдонима цифрового автомата <символьное имя> : MACHINE; Объявление псевдонима цифрового автомата не задает биты или имена состояний. Эта информация импортируется из секции подпроекта через порт MACHINE INPUT файла более высокого уровня в иерархии проекта или же через прототип функции из файла более низкого уровня в иерархии проекта.
3.9.12. Синтаксис логической секции Логическая секция, заключенная между ключевыми словами BEGIN и END, представляет собой тело секции подпроекта. Информация о синтаксисе приводится отдельно для каждого варианта логической секции.3.9.13. Синтаксис булевых уравнений <булево уравнение> ::= <левая часть> = <правая часть>; 3.9.14. Синтаксис булевых уравнений управления <символьное имя>.clk = <правая часть>; [<символьное имя>.reset = <правая часть>;] [<символьное имя>.ena = <правая часть>;] Элемент <символьное имя> в булевом уравнении управления должен быть объявлен также, как в объявлении цифрового автомата в секции переменных. 3.9.15. Синтаксис оператора Case <оператор выбора> ::= CASE <правая часть> IS WHEN <выбор> => <операторы> { WHEN <выбор> => <операторы> } [ WHEN OTHERS => <операторы> ] END CASE; <выбор> ::= <группа констант> {, <группа констант> } 3.9.16. Объявление по умолчанию <объявление по умолчанию> ::= DEFAULTS <задание значения> ; { <задание значения> ; } END DEFAULTS; <задание значения> ::= <левая часть> = <группа констант> 3.9.17. Синтаксис условного оператора IF <условный оператор> ::= IF <правая часть> THEN <операторы> { ELSIF <правая часть> THEN <операторы> } [ ELSE <правая часть> THEN <операторы> ] END IF; 3.9.18. Синтаксис встроенных (in-line) ссылок на макрофункцию или примитив <макрофункция> ( <список правых частей> )
<примитив> ( <список правых частей> ) 3.9.19. Синтаксис объявления таблицы истинности <оператор таблицы> ::= TABLE <входы> => <выходы> ; <входные значения> => <выходные значения> ; { <входные значения> => <выходные значения> ; } END TABLE; <входы> ::= <правая часть> {, <правая часть> } <выходы> ::= <левая часть> {, <левая часть> } <входные значения> ::= <группа констант> {, <группа констант> } <выходные значения> ::= <группа констант> {, <группа констант> }
3.9.20. Синтаксис порта Порт, являющийся в текущем файле входом или выходом, объявляется в секции подпроекта в следующем формате: <имя порта> : <тип порта> [ = <значение порта по умолчанию> ] Имеются следующие типы портов: |
INPUT |
MACHINE INPUT |
OUTPUT |
MACHINE OUTPUT |
BIDIR |
Порты, являющиеся входами и выходами примера ( instance) примитива или макрофункции, используются в следующем формате: <имя примера>.<имя порта> <имя примера> ::= <символьное имя> 3.9.21. Синтаксис группы Группы могут быть записаны в следующих двух нотациях: 1. Нотация <десятичное имя группы> состоит из символьного имени, за которым следует диапазон десятичных чисел, заключенный в квадратные скобки, например, a[4..1]. Допускается указание только одного диапазона после символьного имени.<десятичное имя группы> ::= <символьное имя> [ <диапазон> ] <диапазон> ::= <десятичное число> | <десятичное число>..<десятичное число> Если группа уже определена, можно для краткости вместо диапазона указывать только пустые скобки [ ]. Вместо диапазона можно также использовать одно только число, например, a[5]. Однако в такой нотации обозначается только одно символьное имя, а не имя группы, и это эквивалентно записи a5. 2. Нотация <последовательное имя группы> состоит из списка символьных имен, портов или чисел, разделенных запятой и заключенных в круглые скобки, например, (a, b, c). Десятичные имена группы также можно перечислять в круглых скобках.<последовательное имя группы> ::= ( <список правых частей> ) <список правых частей> ::= [ <правая часть> ] {, [ <правая часть> ] } Данная нотация полезна для задания портов примера ( instance) функции, который объявляется в объявлении примера. 3.9.22. Синтаксические группы и списки <группа констант> ::= <символьное имя> | <число> | VCC | GND | ( <список группы констант> ) <список группы констант> ::= [ <группа констант> ] {, [ <группа констант> ] } <группа точек> ::= <имя порта> | <символьное имя> [ ] | <символьное имя> [ <диапазон> ] | ( <список группы точек> ) <список группы точек> ::= [ <группа точек> ] {, [ <группа точек> ] } <левая часть> ::= < левая часть >. <группа точек>| <символьное имя> | <символьное имя> [ ] | <символьное имя> [ <диапазон> ] | ! < левая часть > | ( <список левых частей> ) <список левых частей> ::= [ < левая часть > ] {, [ < левая часть > ] } <группа портов> ::= <имя порта> | <символьное имя> [ <диапазон> ] | ( <список портов> ) <список портов> ::= <группа портов> {, <группа портов> } <группа прототипа> ::= <группа портов> | MACHINE <символьное имя> <диапазон> ::= <десятичное число> [.. <десятичное число> ] <правая часть> ::= <правая часть>. <группа точек> | ! <правая часть> | <число> | <символьное имя> | <символьное имя> [ ] | <символьное имя> [ <диапазон> ] | VCC | GND | <правая часть> == <правая часть> | <правая часть> >= <правая часть> | <правая часть> > <правая часть> | <правая часть> <= <правая часть> | <правая часть> < <правая часть> | <правая часть> != <правая часть> | <правая часть> # <правая часть> | <правая часть> !# <правая часть> | <правая часть> & <правая часть> | <правая часть> !& <правая часть> | <правая часть> $ <правая часть> | <правая часть> !$ <правая часть> | <правая часть> + <правая часть> | <правая часть> - <правая часть> | - <правая часть> | + <правая часть> | <макрофункция> ( <список правых частей> ) | <примитив> ( <список правых частей> )| ( <список правых частей> ) <список правых частей> ::= [ <правая часть> ] {, [ <правая часть> ] } |
|
||