Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Altera / ahdl

.pdf
Скачиваний:
69
Добавлен:
10.12.2013
Размер:
592.21 Кб
Скачать

Например: B ”10x00”, H ”5ED0”.

Логические уравнения (Boolean Equation)

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

Уравнения описываются в следующем виде:

__node_name = __node_name __operator __node_name;

где __node_name – обозначение порта или именованного вывода, а operator - логический, арифметический или оператор сравнения. Возможно применение скобок для выполнения нескольких логических преобразований в одном выражении.

В AHDL используются следующие логические операторы (Табл. 1).

Табл. 1. Логические операторы языка AHDL

Оператор

Пример использования

Описание

!

!fo

Инверсия

NOT

NOT fo

 

&

fo & x4

И

AND

fo AND x4

 

!&

a[3..1] !& b[5..3]

И-НЕ

NAND

a[3..1] NAND b[5..3]

 

#

x2 # z1

ИЛИ

OR

x2 OR z1

 

!#

a[3..1] !# b[5..3]

ИЛИ-НЕ

NOR

a[3..1] NOR b[5..3]

 

$

f_mux $ data[5]

Исключающее ИЛИ

XOR

f_mux XOR data[5]

 

!$

f_mux !$ data[5]

Инверсия исключающего ИЛИ

XNOR

f_mux XNOR data[5]

 

Арифметические операторы и операторы сравнения языка AHDL приведены в Табл. 2 и Табл. 3 соответственно.

Табл. 2. Арифметические операторы языка AHDL

Оператор

Пример

Описание

+ (унарный)

+1

Плюс

- (унарный)

-a[4..1]

Минус

+

count[7..0] + delta[7..0]

Сложение

-

count[] - delta[]

Вычитание

!

!a

Отрицание

^

a ^ 2

Степень

MOD

4 MOD 2

Модуль

DIV

4 DIV 2

Деление

LOG2

LOG2(4-3)

Логарифм по основанию 2

*

a * 2

Умножение

11

Табл. 3. Операторы сравнения языка AHDL

Оператор

Пример

Описание

== (логическое)

addr[19..4] == H”B800”

Равно

!= (логическое)

b1 != b3

Не равно

< (арифметическое)

frame[] < power[]

Меньше

<= (арифметическое)

money[] <= power[]

Меньше или равно

> (арифметическое)

liv[] > max[]

Больше

>= (арифметическое)

delta[] >= 0

Больше или равно

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

Группы

Однотипные переменные или выводы могут быть объединены в одномерную, двумерную или временную группу.

Текстовое описание, иллюстрирующее использование одномерных и временных

групп:

SUBDESIGN Group

 

 

(

 

 

A[3..0]:

INPUT;

--одномерная группа с 4 членами

B[4..1] :

INPUT;

-- одномерная группа с 4 членами

c, d, e, f:

INPUT;

--одноразрядные входы

E[2..1]:

INPUT;

-- одномерная группа с 3 членами

OUT[5..2]:

OUTPUT;

-- одномерная группа с 4 членами

R[1..0][2..1]:

OUTPUT;

--двумерная группа

)

BEGIN

OUT[] = (A[] # B[1..4]) & !(c, d, e, f); R[][] = (E[1..2], E[]);

END;

Группы A[] и B[] имеют одинаковое число членов, поэтому возможно поразрядное применение оператора # (из примера).

Если в логическом уравнении используются все члены группы, причем в том же порядке, в котором они были заданы, то для ссылки на такую группу можно воспользоваться сокращенной формой записи: A[] вместо A[3..0]. При ссылке на группу B[4..1] ее индексы перечислены в обратном порядке B[1..4], поэтому указываются явно.

(c, d, e, f) – временная группа с 4 членами. Выражение !(c, d, e, f) задает поразрядное выполнение инвертирования.

Значение одной группы может быть присвоено другой группе (т.е. между ними можно поставить знак равенства) только в том случае, если они имеют одинаковое число разрядов.

Базовые значения логических функций (Defaults Statement)

Необходимость в задании базовых значений логических функций возникает тогда, когда они определены не на всех наборах аргументов. Базовые значения могут быть заданы:

неявно (по умолчанию);

12

явно.

Задаваемое по умолчанию базовое значение — логический нуль.

Для явного задания базовых значений логических функций применяется оператор

DEFAULTS:

DEFAULTS

__node_name = __constant_value; END DEFAULTS;

При описании логической функции с помощью операторов CASE и IF THEN целесообразно явное определение ее на всех наборах аргументов.

Константы (Constant Statement)

Использование в текстовом описании символических имен вместо фиксированных числовых значений (т. е. использование констант) позволяет:

сделать текстовое описание более наглядным;

упростить внесение изменений, связанных с изменением фиксированных числовых значений.

Константы задаются следующим образом:

CONSTANT __constant_name = __constant_value;

Пример использования констант приведен ниже:

CONSTANT у = 9;

CONSTANT IO_ADR = y-4;

CONSTANT ADC = IO_ADR+2;

Таблица истинности (Truth Table Statement)

Таблица истинности логической функции задается следующим образом:

TABLE

 

__node_name,__node_name

=> __node_name,

__input_value, __input_value

=> __output_value,

__input_value, __input_value

=> __output_value,

__input_value, __input_value

=> __output_value,

END TABLE;

 

__node_name;

__output_value; __output_value; __output_value;

Открывает таблицу ключевое слово TABLE, а закрывают ключевые слова END TABLE, за которыми следует точка с запятой (;).

Первая после слова TABLE строка определяет форму таблицы. В ней через запятую перечисляются аргументы (внутренние переменные, входы или выходы модуля) и имена формируемых логических функций (внутренние переменные или выходы модуля). Аргументы и функции разделяет символ стрелка (=>). В конце строки ставится точка с запятой. В следующих строках в соответствии с заданной формой указываются наборы аргументов и значения логических функций.

Ниже приведен пример использования таблицы истинности:

13

TABLE

 

 

 

 

a0,

f[4..1].q

=>

f[4..1].d,

y_out;

0,

B"0000"

=>

H"1",

1;

0,

B"0100"

=>

H"2",

0;

1,

B"0XXX"

=>

H"4",

0;

X,

B"1111"

=>

H"6",

1;

END TABLE;

 

 

 

 

Оператор IF THEN (If Then Statement)

Оператор If then может использоваться в одной из следующих форм:

IF __expression THEN

IF __expression THEN

IF __expression THEN

__statement;

__statement;

__statement;

__statement;

__statement;

__statement;

ELSIF __expression THEN

ELSE

END IF;

__statement;

__statement;

 

__statement;

__statement;

 

ELSE

END IF;

 

__statement;

 

 

__statement;

 

 

END IF;

 

 

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

Оператор может быть и составным:

IF __expression THEN __statement; __statement;

ELSIF __expression THEN __statement; __statement;

ELSIF __expression THEN __statement; __statement;

ELSIF __expression THEN __statement; __statement;

ELSE

__statement; __statement;

END IF;

Отметим, что оператору IF THEN внутренне присущна приоритетность проверки условий.

Оператор CASE (Case Statement)

Этот оператор может использоваться в одной из следующих форм:

14

CASE __expression IS

WHEN __constant_value => __statement; __statement;

WHEN __constant_value => __statement; __statement;

WHEN OTHERS => __statement; __statement;

END CASE;

CASE __expression IS

WHEN __constant_value => __statement; __statement;

WHEN __constant_value => __statement; __statement;

END CASE;

Оператор CASE позволяет оценить значение одноразрядной переменной (одноразрядного вывода), группы переменных (группы выводов) и по результатам оценки выбрать тот или иной оператор для выполнения.

Использование оператора CASE показано в следующем примере:

CASE f[].q IS

WHEN H"00" => addr[] = 0; s = a & b;

WHEN H"01" => count[].d = count[].q + 1;

WHEN H"02", H"03", H"04" => f[3..0].d = addr[4..1]; WHEN OTHERS => f[].d = f[].q;

END CASE;

Оператор цикла (For Generate Statement)

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

FOR __index_variable IN __range GENERATE __statement;

__statement; END GENERATE;

Оператор задается следующим образом:

За ключевым словом FOR указывается символическое имя внутренней переменной оператора. Это имя не может совпадать с именем констант, параметров или переменных, используемых в текстовом описании.

Ключевые слова IN ... TO ... определяют границы изменения значений внутренней переменной оператора.

Границы задаются арифметическими выражениями.

|

За ключевым словом GENERATE следуют логические уравнения и операторы языка AHDL.

Оператор оканчивается ключевыми словами END GENERATE, за которыми следует точка с запятой (;).

Пример использования оператора:

CONSTANT NUM_OF_ADDERS = 8;

15

SUBDESIGN 4gentst

(

a[NUM_OF_ADDERS..1], b[NUM_OF_ADDERS..1], cin : INPUT; c[NUM_OF_ADDERS..1], cout :

OUTPUT;

)

VARIABLE

carry_out[(NUM_OF_ADDERS+1)..1] : NODE;

BEGIN

carry_out[1] = cin;

FOR i IN 1 TO NUM_OF_ADDERS GENERATE c[i] = a[i] $ b[i] $ carry_out[i];

carry_out[i+1] = a[i] & b[i] # carry_out[i] & (a[i] $ b[i]); END GENERATE;

cout = carry_out[NUM_OF_ADDERS+1];

END;

Примитивы (Primitives)

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

В языке AHDL определены два способа обращения к примитиву:

непосредственное обращение (In_Line Reference);

присвоение примитиву символического имени, т. е. объявление его переменной,

иобращение к нему как к переменной.

Непосредственное обращение к примитиву осуществляется следующим образом:

указывается выход (либо внутренняя переменная) модуля, на который передается сигнал с выхода примитива;

далее ставится знак равенства и имя примитива;

за именем примитива в круглых скобках, через запятую перечисляются передаваемые значения: числа, константы, переменные или выводы модуля, сопоставляемые входам примитива;

за круглыми скобками ставится точка с запятой.

Сопоставление входов примитива с передаваемыми значениями может осуществляться:

позиционно;

по именам.

При позиционном сопоставлении порядок перечисления передаваемых значений должен соответствовать порядку перечисления входов, использованному в описании прототипа примитива:

Вход модуля (внутренняя переменная) = Имя примитива (передаваемое значение, передаваемое значение,...)

16

Отметим, что прототипы примитивов встроены в пакет, и для их подключения к текстовому описанию оператор INCLUDE не используется.

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

При сопоставлении передаваемых значений и входов примитива по именам в списке передаваемых значений через запятую перечисляются пары: вход, передаваемое значение. Формат записи:

Вход модуля (внутренняя переменная) = Имя примитива (.имя выхода=передаваемое значение, .имя выхода=передаваемое значение, ...);

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

Другой способ обращения к примитиву — обращение к нему как переменной. При реализации этого способа примитив, прежде всего, следует объявить перемен-

ной. Для этого в разделе переменных (Variable Section) символическому имени или группе символических имен сопоставляется примитив. Объявленная таким образом переменная, а также каждая переменная из объявленной группы переменных, будет иметь тот же набор выводов, что и примитив.

Обращение к конкретному выводу примитива осуществляется путем указания имени переменной, разделяющей точки и имени вывода примитива.

Прототип модуля (Function Prototype Statement)

Язык AHDL позволяет при описании модуля использовать в качестве компонентов созданные ранее модули. Для этого текстовое описание верхнего уровня иерархии должно содержать описания прототипов этих модулей.

Прототип задается с помощью оператора Function Prototype Statement, который может быть расположен либо непосредственно в текстовом описании, либо в файле включения (Include File), содержимое которого подсоединяется к текстовому описанию на этапе компиляции.

Файл включения (Include File) с описанием прототипа модуля создается с помощью команды Create Default Include File (меню File), выполняемой в окне текстового редактора пакета MAX+plusII, содержащем описание модуля.

В языке AHDL определены два способа обращения к прототипу модуля:

Непосредственное обращение (In_Line Reference).

Присвоение прототипу символического имени, т. е. объявление его переменной,

иобращение к нему как к переменной.

Отметим, что указанные способы обращения к прототипу совпадают с описанными ранее способами обращения к примитиву. В языке AHDL определено два типа модулей:

Параметризированные (Parameterized).

Непараметризированные (Unparameterized).

При этом, как те, так и другие могут быть созданы либо самим разработчиком, либо фирмой Altera.

17

Соседние файлы в папке Altera