Для облегчения визуального восприятия оператора table следует располагать значения переменных в строках вариантов под соответствующими именами переменных в заголовке таблицы.
2.11.4. Значения по умолчанию для переменных
(оператор defaults)
Значения по умолчанию для узлов и групп используются компилятором в двух случаях:
· если переменной в логическом разделе файла не присвоено явным образом значение, то используется значение по умолчанию;
· если переменной неоднократно присваиваются значения, то для узлов типа node со значением по умолчанию gnd реализуется операция or над присваиваемыми величинами, а для узлов со значением по умолчанию vcc над присваиваемыми сигналами выполняется операция and.
Значения по умолчанию для переменных могут быть явно определены с помощью оператора defaults. Это требуется только в случае, когда таким значением должно быть vcc, например для узлов с активным низким уровнем. При отсутствии явного определения узлам автоматически присваивается значение по умолчанию gnd.
Определение значений по умолчанию начинается с ключевого слова оператора defaults и содержит для каждой переменной отдельное логическое уравнение. Уравнения в правой части должны иметь логические выражения, результатом выполнения которых являются константы. Каждое уравнение заканчивается точкой с запятой. Весь оператор заканчивается ключевыми словами end defaults и точкой с запятой.
Для переменных, используемых в операторах if then, case и table, также можно определить значения по умолчанию с помощью оператора defaults. В этом случае конструкция логического оператора может быть упрощена.
Пример:
subdesign exampl10
(
i[3..0] :input;
code[7..0] :output;
)
begin
defaults
code[]=b"";
end defaults;
table
i[3..0] => code[7..0];
b"1000" => b"";
b"0100" => b"";
b"0010" => b"";
b"0001" => b"";
end table;
end;
В приведенном примере оператор table описывает четыре варианта выходного восьмиразрядного кода, который должен вырабатываться устройством при наличии на входах соответствующих четырехразрядных комбинаций. Все другие комбинации входных сигналов должны генерировать выходной код b"". Поскольку в операторе table отсутствует возможность, подобная варианту when others в операторе case, то в данном случае для выходной шины code[]с помощью оператора defaults явно указано значение по умолчанию. Это значение и будет использовано компилятором в случае любой комбинации входных сигналов, не описанной в операторе table.
При употреблении оператора defaults следует соблюдать следующие правила.
1. В конструкторском файле может быть только один оператор defaults, располагаемый в логическом разделе сразу за ключевым словом begin.
2. Если в операторе defaults переменной присваивается значение по умолчанию больше одного раза, то игнорируются все определения, кроме последнего.
3. Присваиваемые значения по умолчанию не должны содержать двоичных значений "x".
Не следует смешивать значения по умолчанию для переменных со значениями по умолчанию для внешних входных портов, присваиваемых в интерфейсном разделе (subdesign section).
2.11.5. Оператор for generate
Оператор for generate предназначен для многократного повторения набора логических уравнений или операторов, что позволяет тиражировать одинаковые блоки внутри устройства, например отдельные одноразрядные сумматоры внутри многоразрядного сумматора.
Оператор начинается ключевым словом for, за которым следует имя переменной-счетчика, используемой внутри этого оператора. Она не объявляется где-либо специально и исчезает после выполнения оператора компилятором. Имя этой переменной не должно совпадать с именами каких-либо переменных, портов, параметров или констант в проекте.
За именем переменной следуют ключевое слово in и далее начальное и конечное значения переменной-счетчика, разделяемые ключевым словом to. Эти значения могут быть арифметическими выражениями, состоящими только из констант и параметров. За конечным значением счетчика следует ключевое слово generate, после которого располагаются логические уравнения, повторяемые много раз.
Если в уравнении содержится элемент группы и уравнение необходимо выполнить для всех ее элементов, то следует использовать в качестве номера элемента переменную-счетчик. В этом случае одна и та же логическая схема будет реализована для всех элементов группы начиная с элемента с номером, равным начальному значению счетчика, до элемента с номером, равным конечному значению счетчика.
Каждое уравнение заканчивается точкой с запятой. Оператор завершается ключевыми словами end generate и точкой с запятой.
Пример:
constant w=8;
subdesign example11
(
a[w-1..0], b[w-1..0],cin :input;
sum[w-1..0],cout :output;
)
variable
carry[w..0] :node;
begin
carry[0]=cin;
for i in 0 to w-1 generate
sum[i]=a[i] $ b[i] $ carry[i];
carry[i+1]=a[i]&b[i]#carry[i]&(a[i]$b[i]);
end generate;
cout=carry[w];
end;
В приведенном примере реализован 8-разрядный сумматор, в котором a[] и b[]являются слагаемыми, cin – входным переносом младшего (нулевого) разряда. Сумма такой же размерности, как и слагаемые, формируется на выходах sum[], а выходной перенос в девятый разряд поступает на выход cout.
Первое логическое уравнение в операторе for generate формирует одноразрядную сумму из входных слагаемых a[i], b[i] и переноса из предыдущего разряда carry[i]. Поскольку оператор выполняется начиная со значения счетчика i=0 до значения w-1, т. е. 8 раз, то на выходе будут получены биты суммы для 8 разрядов. При вычислении суммы каждого следующего разряда требуется значение переноса из предыдущего. Это значение также вычисляется 8 раз. Последний сигнал переноса carry[8] не используется для вычисления очередной суммы, а за пределами оператора for generate поступает на выход устройства cout.
2.11.6. Оператор if generate
Оператор if generate предназначен для выбора на этапе компиляции одного из двух наборов логических уравнений и операторов. Выбор определяется истинностью или ложностью арифметического выражения. Оператор начинается ключевым словом if, за ним следуют анализируемое арифметическое выражение и далее ключевое слово generate. После слова generate располагаются уравнения и операторы, выполняемые в случае истинности арифметического выражения. Они отделяются друг от друга точкой с запятой.
После первого набора уравнений и операторов следуют ключевые слова else generate, за которыми располагается второй набор уравнений и операторов, также разделяемых точкой с запятой. Завершают оператор в целом ключевые слова end generate и точка с запятой.
Пример:
if DEVICE_FAMILY=="FLEX8K" generate
c[]=8kadder(a[], b[], cin);
else generate
c[]=adder(a[], b[], cin);
end generate;
В приведенном примере используется предопределенный параметр САПР Quartus II DEVICE_FAMILY, который принимает значение семейства микросхем, выбранного в пункте "Assignments\Device…" основного меню пакета. В случае если выбрано семейство FLEX8K, выполняется первое логическое уравнение примера, в котором применен сумматор 8kadder, специально разработанный для этого семейства. В противном случае выполняется второе уравнение с обычным сумматором.
Оператор if generate может быть использован в логическом разделе, а также в разделе переменных (variable section).
2.12. Служебные операторы
Кроме логических операторов в языке AHDL существует ряд операторов, выполняющих служебные функции. Эти операторы, за исключением оператора assert, должны располагаться в предварительном разделе.
1. Оператор title позволяет ввести в конструкторский файл имя проекта, которое затем будет помещено в начало текстового или HTML файла отчета, формируемого компилятором.
Пример:
title "Display Controller";.
2. Оператор parameters рассмотрен в разделе 2.6.3.
3. Оператор include предназначен для размещения в конструкторском файле текста внешнего include файла (с расширением. inc). В include файле обычно размещается прототип модуля (функции), который описан в другом конструкторском файле (нижнего уровня иерархии) и будет использован в данном проекте. Include файл для модуля нижнего уровня иерархии может быть создан автоматически с помощью команды основного меню "File\Create/Update\Create AHDL Include Files for Current File", когда конструкторский файл модуля загружен в пакете САПР. Include файл должен иметь расширение ".inc". Кроме прототипа модуля (функции) в нем могут быть помещены операторы define, parameters и constant. Файл не должен содержать интерфейсного раздела. Include файлы не могут быть вложенными.
При использовании оператора include следует выполнять следующие правила:
· имя include файла не должно содержать пути;
· все мегафункции, поставляемые фирмой Altera, имеют имена, состоящие только из строчных (малых) букв, поэтому при работе с операционными системами рабочих станций, различающими прописные и строчные буквы, имена include файлов этих функций (модулей) также должны вводиться только строчными буквами;
· один оператор include подключает один include файл; количество операторов include в конструкторском файле не ограничивается.
Пример применения операторов include приведен в разделе 2.7.2.
4. Оператор constant рассмотрен в разделе 2.6.2.
5. Оператор define рассмотрен в разделе 2.10.
6. Оператор function prototype предназначен для предварительного объявления модуля (функции), описанного в конструкторском файле более низкого уровня и используемого в данном проекте как компонент. Оператор начинается ключевым словом function, за которым следует имя модуля (функции). За именем в круглых скобках следует список имен входных портов. Если модуль параметризированный, то за списком входных портов следуют ключевое слово with и список параметров в круглых скобках. Имена параметров отделяются друг от друга запятыми. Далее следует ключевое слово returns, сопровождаемое списком выходных и двунаправленных портов модуля в круглых скобках. Завершается оператор точкой с запятой. Имена входных и выходных портов в списках отделяются запятыми.
Примеры прототипов модулей (функций) приведены в разделе 2.7.2 (Модули).
Применяя внешние модули (функции), необходимо принимать во внимание следующее:
· формально в прототипе выходные и двунаправленные порты не отличаются друг от друга и все рассматриваются как выходные, в результате, если внутренний порт модуля, определенный в нем как двунаправленный, в проекте верхнего уровня оказался неподключенным, компилятор генерирует сообщение об ошибке;
· предпочтительным вариантом размещения прототипа в файле проекта является подключение с помощью оператора include файла *.inc, содержащего прототип.
7. Оператор options позволяет управлять двумя свойствами компилятора.
С помощью переменной окружения компилятора bit0 можно применять в проекте желаемую нумерацию элементов в группе без возникновения предупреждений. В AHDL при указании границ диапазона элементов группы первое число, т. е. левая граница диапазона, всегда определяет элемент, являющийся старшим значащим битом (MSB), а второе число, т. е. правая граница, – элемент, являющийся младшим значащим битом (LSB). По умолчанию значение переменной bit0 равно LSB, т. е. младший номер бита соответствует младшему значащему разряду. Если при этом границы диапазона будут указаны в возрастающем порядке, т. е. меньшим числом слева, а большим – справа, компилятор сформирует предупреждение. Если значение переменной bit0 будет установлено равным MSB, то предупреждение появится при указании границ группы в убывающем порядке. Если же установить значение bit0 равным ANY, предупреждения не генерируются в любом случае.
С помощью переменной name_substitution можно включать или выключать режим подстановки, который обеспечивает замену объявленного параметра присвоенным ему строковым значением. Такой параметр, предваряемый символом "@", может быть применен в качестве имени модуля (функции) в операторе function prototype, в объявлении экземпляра модуля и при использовании модуля (функции) "вызовом по ссылке". Это обеспечивает возможность замены одного модуля (функции) на другой во всем проекте путем присвоения нового имени параметру. Заменяемые модули должны иметь прототипы, отличающиеся только именем.
Примеры:
а) options
bit0=MSB;
subdesign. . . ;
б) options
bit0=MSB,
name_substitution=ON;
subdesign. . . ;
в) options
name_substitution=ON;
parameters
(
name="add"
);
function @name(a, b,cin)
returns(s, cout);
subdesign example12
(
x, y,c :input;
sum[1..0] :output;
)
variable
f:@name;
begin
f. a=x;
f. b=y;
f. cin=c;
sum[0]=f. s;
sum[1]=f. cout;
end;
В последнем примере на этапе компиляции вместо строки @name будет подставлено имя add.
8. Оператор assert позволяет в ходе компиляции вывести сообщение в окно сообщений (оператор активизируется) в случае, если анализируемое арифметическое выражение дает результат "false". Выражение может быть составлено из параметров, чисел и вычисляемых функций. Если анализируемое выражение отсутствует, сообщение будет выводиться всегда.
Оператор начинается ключевым словом assert, за которым следует анализируемое выражение. Выражение может быть дополнительно заключено в круглые скобки.
Далее после ключевого слова report располагается строка сообщения, заключенная в двойные кавычки. Строка может содержать символы "%", вместо которых при выводе сообщения будут подставлены значения переменных сообщения, которые должны следовать за строкой и разделяться запятыми. Они будут подставляться в том порядке, в котором следуют символы "%". Значениями этих переменных могут быть положительные числа или строки.
Следующее затем ключевое слово severity определяет один из трех уровней предупреждения: error (ошибка), warning (предупреждение) или info (информация). Если переменная severity явно не определена, то применяется уровень error. Необходимо отметить, что при этом уровне предупреждения в случае активизации оператора компиляция останавливается. Заканчивается оператор точкой с запятой.
Оператор assert может быть применен в предварительном и логическом разделах.
Пример:
assert (width>0)
report "Размер регистра width=% ошибочен!" width
severity error;
В приведенном примере реализован оператор, который в случае, если параметр width будет установлен равным 0, выведет в окно сообщений следующий текст: "Размер регистра width=0 ошибочен!" и остановит компиляцию.
3. Описание некоторых параметризированных модулей библиотеки фирмы Altera
В настоящем разделе приводятся описания некоторых простых модулей (Megafunctions), входящих в библиотеку пакета САПР Quartus II. Эта библиотека носит название Library Parameterized Modules (LPM).
3.1. Универсальный регистр (lpm_ff)
Регистр из D - или T-триггеров с задаваемой разработчиком разрядностью. Позволяет осуществлять синхронную и асинхронную установку и сброс всех разрядов, а также их загрузку данными.
Прототип модуля lpm_ff:
function lpm_ff(data[lpm_width-1..0], clock, enable, sclr, sset, sload, aclr, aset, aload)
with (lpm_width, lpm_avalue, lpm_svalue, lpm_fftype)
returns (q[lpm_width-1..0]);
Входные порты модуля lpm_ff:
Имя порта | Необходимость | Описание | Примечание |
data[] | Нет | Т-триггеры: разрешение переключения D-триггеры: входы данных | Разрядность определяется параметром lpm_width. Если не подключен, то, по крайней мере, один из следующих портов должен быть подключен: aset, aclr, sset, sclr |
clock | Да | Вход тактового сигнала с положительным синхронизирующим фронтом | |
enable | Нет | Вход разрешения синхронизации | Значение по умолчанию 1 |
sclr | Нет | Вход синхронного сброса | Если подключены порты sset и sclr и оба активизированы, то превалирует sclr |
sset | Нет | Вход синхронной установки | Устанавливает на выходах q значения, определенные параметром lpm_svalue, если он инициализирован, и значения 1 в противном случае. При одновременном подключении и активизации порта sclr превалирует sclr |
sload | Нет | Вход синхронной загрузки. Загружает в регистр значения из порта data при очередном возрастающем фронте тактового сигнала | Значение по умолчанию 0. Если порт sload подключен, то порт data также должен быть подключен. Загрузка выполняется если уровень sload высокий (1), при этом на входе enable также должна быть 1, или он должен быть не подключен. Порт sload игнорируется, если для параметра lpm_fftype установлено значение "DFF" |
aclr | Нет | Вход асинхронного сброса | Если подключены порты aset и aclr и оба активизированы, то превалирует aclr |
aset | Нет | Вход асинхронной установки | Устанавливает на выходах q значения, определенные параметром lpm_avalue, если он инициализирован, и значения 1 в противном случае |
aload | Нет | Вход асинхронной загрузки. Загружает в регистр значения из порта data | Значение по умолчанию 0. Если порт aload подключен, то порт data также должен быть подключен |
Выходные порты модуля lpm_ff:
Имя порта | Необходимость | Описание | Примечание |
q[] | Да | Выходы D - или Т-триггеров | Разрядность определяется параметром lpm_width |
Параметры модуля lpm_ff:
Параметр | Тип | Необходимость | Описание |
lpm_width | Число | Да | Разрядность портов data[] и q[] |
lpm_avalue | Число | Нет | Числовая константа, которая загружается в регистр, когда на вход aset подан высокий уровень. Если параметр опущен, то загружаются единицы. Разрядность параметра ограничена 32 битами. Altera рекомендует в AHDL проектах определять эту величину в виде десятичного числа |
lpm_svalue | Число | Нет | Числовая константа, которая загружается в регистр по возрастающему фронту тактового сигнала, если уровень sset – высокий. Если параметр опущен, то загружаются единицы. Altera рекомендует в AHDL проектах определять эту величину в виде десятичного числа |
lpm_fftype | Строка | Нет | Определяет тип триггеров. Возможные значения: "DFF", "TFF" и "UNUSED". Если параметр опущен, то значением по умолчанию является "DFF". При значении параметра "DFF" порт sload игнорируется |
lpm_hint | Строка | Нет | Для применения в проектах на языке VHDL |
lpm_type | Строка | Нет | Для применения в проектах на языке VHDL |
Таблица истинности модуля lpm_ff (T-триггеры):
Входы | Выходы | ||||||
aclr | aset | enable | clock | sclr | sset | sload | q[lpm_width-1..0] |
1 | x | x | x | x | x | x | |
0 | 1 | x | x | x | x | x | или lpm_avalue |
0 | 0 | 0 | x | x | x | x | q[lpm_width-1..0] |
0 | 0 | 1 | ∫ | 1 | x | x | |
0 | 0 | 1 | ∫ | 0 | 1 | x | или lpm_svalue |
0 | 0 | 1 | ∫ | 0 | 0 | 1 | data[lpm_width-1..0] |
0 | 0 | 1 | ∫ | 0 | 0 | 0 | q[lpm_width-1..0] |
Потребляемые модулем lpm_ff ресурсы: одна логическая ячейка на разряд.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 |


