Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Введение в инструментальн.pdf
Скачиваний:
63
Добавлен:
05.06.2015
Размер:
1.94 Mб
Скачать

лаемая функция отображена в нем таким образом, что поведение устройства оказывается совершенно очевидным.

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

entity KC is port (

N: in INTEGER range 0 to 7; F: out BIT

); end KC;

architecture KC_arch of KC is begin

with N select

F <= '1' when 1 | 2 | 3 | 5 | 7, '0' when others;

end KC_arch;

Еще раз обратим внимание на разницу в записи значений сигналов различных типов (табл. 2).

Таблица 2

Разница в записи значений сигналов различных типов

Тип

Примеры

 

 

BIT

'0', '1'

BIT_VECTOR

"10", "110"

INTEGER

0, 1, 2, 6

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

Как видно из последнего примера, иногда параллельным оператором можно непосредственно описать требуемое поведение логической схемы. И это очень хорошо, потому что возможность пове-

денческого описания (behavioral description) и выполнение поведен-

119

ческого проекта (behavioral design) является главным достоинством языка VHDL. Однако для большинства поведенческих описаний нужны некоторые дополнительные элементы языка, рассматриваемые в этом разделе.

Ключевым поведенческим элементом языка VHDL является «процесс». Процесс (process) — совокупность «последовательных» операторов (они будут описаны чуть ниже), которые выполняются одновременно с другими параллельными операторами и с другими процессами. С помощью процесса можно задать сложное взаимодействие сигналов и событий таким способом, что при моделировании это взаимодействие реализуется практически за нулевое время в модели, а результатом синтеза становится комбинационная или последовательностная схема, которая выполняет моделируемую операцию непосредственно.

Оператор процесса (process statement) в языке VHDL можно использовать повсюду, где возможно употребление параллельного оператора. Оператор процесса вводится ключевым словом process; синтаксис этого оператора приведен в листинге 15. Оператор process пишут внутри некоторой объемлющей архитектуры, поэтому ему доступны все типы, сигналы, константы, функции и процедуры, объявленные в этой архитектуре, а также так или иначе видимые из этой архитектуры. Но можно также определять и локальные типы, переменные, константы, функции и процедуры внутри данного процесса.

Листинг 15. Синтаксис оператора process

process (signal-name, signal-name,

..., signal-name)

type declarations

 

variable declarations

 

constant declarations

 

function definitions

 

procedure definitions

 

begin

 

sequential-statement

 

. . .

 

sequential-statement

 

end process;

 

120

Обратите внимание на то, что внутри процесса можно объявлять только «переменные», но не сигналы. Переменная (variable) в языке VHDL отслеживает состояние процесса только внутри него и вне процесса ее не видно. В зависимости от того, как используется переменная, ей в конце концов будет или не будет соответствовать определенный сигнал при физической реализации создаваемой схемы. Синтаксис определения переменной внутри процесса подобен синтаксису объявления сигнала в архитектуре, за исключением того, что используется ключевое слово variable:

variable variable-names : variable-type;

VHDL-процесс всегда либо выполняется (running process), либо приостановлен (suspended process). Перечнем сигналов в определении процесса, который называется списком чувствительности (sensitivity list), задаются условия, когда процесс выполняется. Первоначально процесс остановлен; когда изменяется значение любого из сигналов в его списке чувствительности, исполнение процесса возобновляется, начиная с его первого последовательного оператора, и оно продолжается, пока не будет достигнут конец. Если ка- кой-либо сигнал из списка чувствительности изменяет свое значение в результате исполнения процесса, то процесс выполняется снова. Это продолжается до тех пор, пока запуск процесса не перестанет приводить к изменению значения любого из этих сигналов. При моделировании все это происходит за нулевое время в модели.

Последовательный сигнальный оператор присваивания

иоператор присваивания значения переменной

Вязыке VHDL имеются последовательные операторы несколь-

ких видов. Первый из них — это последовательный сигнальный оператор присваивания (sequential signal-assignment statement); у

него тот же самый синтаксис, что и у параллельного аналога

(signal-name <= expression;),

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

оператор присваивания значения переменной (variable-assignment statement), синтаксис которого имеет вид

121

"variable-name: = expression;"

Заметьте, что в случае переменных используется другой оператор присваивания – := .

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

Листинг 16. Потоковая VHDL-архитектура для дешифратора, основанная на использовании процесса

entity DECODER is

port (A: in BIT_VECTOR (1 downto 0); E: in BIT;

D: out BIT_VECTOR (0 to 3)); end DECODER;

architecture DECODER_arch of

DECODER is

begin

 

 

 

 

 

process (A,E)

 

 

 

 

variable V: BIT_VECTOR (0 to 3);

begin

:= not A(0) and not

A(1)

and E;

V(0)

V(1)

:=

A(0)

and not

A(1)

and E;

V(2)

:= not A(0)

and

A(1)

and E;

V(3)

:=

A(0)

and

A(1)

and E;

D <= V; end process;

end DECODER_arch;

Последовательный оператор if

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

122

ратор if (if statement), синтаксис которого приведен в листинге 17. В первой и простейшей форме этого оператора проверяется булево выражение boolean-expression и, если оно имеет значение true, то исполняется последовательный оператор sequentialstatement. Во второй форме добавляется предложение "else" с другим последовательным оператором sequential-statement, который исполняется, если булево выражение имеет значение false.

Для образования вложенных операторов if-then-else в языке VHDL используют специальное ключевое слово elsif, которое вводит «средние» предложения. Последовательный оператор sequential-statement предложения elsif исполняется в том случае, когда булево выражение boolean-expression в этом предложении истинно, а все предшествующие булевы выражения booleanexpressions оказываются ложными.

Последовательный оператор sequential-statement заключительного необязательного предложения else исполняется только тогда, когда все предыдущие выражения boolean-expressions имеют значения false.

В листинге 18 представлен вариант архитектуры дешифратора, в котором используется оператор if.

Листинг 17. Синтаксис оператора if

if boolean-expression then sequential-statement end if;

if boolean-expression then sequential-statement else sequential-statement

end if

if boolean-expression then sequential-statement elsif boolean-expression then sequential-statement

. . .

elsif boolean-expression then sequential-statement end if;

if boolean-expression then sequential-statement elsif boolean-expression then sequential-statement

. . .

eisif boolean-expression then sequential-statement else sequential-statement

end if;

123

Листинг 18. Архитектура дешифратора в поведенческом стиле с использованием оператора if

entity decoder is port (

A: in BIT_VECTOR (1 downto 0); E: in BIT;

D: out BIT_VECTOR (3 downto 0)

);

end decoder;

architecture decoder_arch of decoder is begin

process (A,E) begin

if E='0' then D <= "0000"; elsif A="00" then D <= "0001"; elsif A="01" then D <= "0010"; elsif A="10" then D <= "0100"; elsif A="11" then D <= "1000";

end if; end process;

end decoder_arch;

Последовательный оператор case

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

оператор case (case statement).

Синтаксис оператора case представлен в листинге 19. В этом операторе вычисляется заданное выражение expression, по его значению выбирается одна из альтернатив choices и исполняются соответствующие последовательные операторы sequential-statements. Заметьте, что в каждом из наборов альтернатив choices можно записать один или большее число последовательных операторов. Сами альтернативы choices могут иметь форму одного значения или

124

нескольких значений, разделенных вертикальной чертой (|). Альтернативы choices должны быть взаимно исключающими и содержать все возможные значения типа выражения expression; в последней альтернативе choices можно воспользоваться ключевым словом others для указания всех значений, которые еще не были упомянуты ранее.

Листинг 19. Синтаксис оператора case

case expression is

when choices => sequential-statements

. . .

when choices => sequential-statements end case;

В листинге 20 приведена еще одна архитектура устройства для обнаружения простых чисел, на этот раз записанная с использованием оператора case. Подобно тому, как это было в варианте с параллельным оператором select (см. листинг 14), оператор case позволяет в очень наглядной форме задать желаемое функциональное поведение.

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

entity KC is port (

N: in INTEGER range 0 to 7; F: out BIT);

end KC;

architecture KC_arch of KC is begin

process(N) begin

case N is

when 1 |2 |3 | 5 | 7 => F <= '1'; when others => F <= '0';

end case; end process;

end KC_arch;

125

В листинге 21 приведен вариант архитектуры дешифратора в поведенческом стиле, в котором используется оператор case.

Листинг 21. Архитектура дешифратора в поведенческом стиле с использованием оператора case

entity DECODER is port (

A: in BIT_VECTOR (1 downto 0); E: in BIT;

D: out BIT_VECTOR (3 downto 0)); end DECODER;

architecture DECODER_arch of DECODER is begin

process (A,E)

variable V: BIT_VECTOR (0 to 3); begin

case A is

when "00" => V := "0001"; when "01" => V := "0010"; when "10" => V := "0100"; when "11" => V := "1000";

end case;

if E='1' then D <= V; else D <= "0000";

end if; end process;

end DECODER_arch;

Особенности проектирования последовательностных схем

Процессы можно использовать для описания поведения как комбинационных, так и последовательностных схем. Для описания последовательностных схем рассмотрим некоторые дополнительные свойства языка VHDL.

На практике большинство устройств, проектируемых и моделируемых в среде VHDL, представляют собой тактируемые синхронные системы, в которых используются переключающиеся по фронту триггеры. Следовательно, необходимы средства анализа поведе-

126

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

signal_name'attribute_name

Например, предопределенный атрибут event ассоциируется с каким-либо сигналом, допустим, с сигналом CLOCK. Тогда атрибут запишется CLOCK'event. Этот атрибут имеет тип boolean со значением true, когда значение CLOCK изменилось, и значение false — в противном случае.

Используя атрибут event, можно задать поведение переключающегося по положительному фронту D-триггера с асинхронным входом сброса так, как это сделано в листинге 22. Здесь асинхронный сигнал reset на входе сброса преобладает над тактовым входным сигналом clock и поэтому проверяется первым в предложении if. Только тогда, когда сигнал на входе reset имеет неактивный уровень, вступает в действие то, что предусмотрено предложением elsif, и имеющиеся в нем операторы исполняются по положительному фронту сигнала clock. Заметьте, что величина clock'event истинна при любом изменении сигнала clock, поэтому для анализа фронта 0/1 сигнала clock предусмотрена проверка clock = ‘1’.

Листинг 22. Поведенческое описание D-триггера с прямым С входом

entity D_ff is port (

clock, reset, D: in BIT; Q, QN: out BIT );

end D_ff;

architecture D_ff_arch of D_ff is begin

process (reset, clock) begin

if reset='1' then Q <= '0' ; QN <= '1';

elsif clock'event and clock='1' then Q <= D; QN <= not D; end if;

end process; end D_ff_arch;

127

В листинге 23 приведено поведенческое описание закольцованного регистра сдвига. По приоритетному входу r регистр устанавливается в состояние 0001. По входу clk выполняется сдвиг на один разряд от Q0 к Q3:

Q3Q2Q1Q0 = 0001 0010 0100 1000 0001.

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

Листинг 23. VHDL-программа для закольцованного регистра сдвига

entity RG is port (

clk, R: in BIT;

Q: out BIT_VECTOR (3 downto 0)

); end RG;

architecture RG_arch of RG is signal iQ: BIT_VECTOR (3 downto 0); begin

process (R,clk,IQ) begin

if R='1' then IQ <= "0001"; elsif CLK'event and CLK='1' then

IQ <= IQ(2 downto 0) & IQ(3); end if;

Q <= IQ; end process;

end RG_arch;

Заслуживают внимание следующие особенности этой программы.

Поскольку выходной сигнал Q нельзя «прочитать» внутри структуры объекта, то введен внутренний сигнал IQ, который могут читать и писать операторы процесса. Сигнал IQ, в конце концов, становится выходным сигналом Q. Можно было бы и не вво-

128