ЦУМ / lbm1_19
.pdfОписание процесса, построенное по данной схеме, называют также оператором процесса. Он определяет поведение (процесс функционирования) некоторой части проектируемого устройства, описанное совокупностью включенных в данный оператор последовательных операторов.
Имя процесса (метка процесса) необязательно, но если оно есть в конце (после слов end process), то должно быть и в начале (перед словом process).
При описании оператором процесса нетактируемой (асинхронной) части устройства в список чувствительностей включаются все ее входные сигналы. В случае тактируемой (синхронной) части устройства в указанный список включаются только сигнал тактирования и входные сигналы асинхронного управления, т. е. те, которые способны влиять на состояние описываемой части устройства независимо от действия (или отсутствия) тактирующих импульсов.
В декларативной части процесса могут быть декларации типов, констант, переменных и др. Сигналы не могут быть декларированы внутри оператора процесса.
Примером использования оператора процесса является следующее описание объекта (рис. 12):
entity ANDOR is
port (e0,e1,e2 : in bit; z : out bit);
end ANDOR;
architecture RTL1 of ANDOR is signal f : bit;
begin
a0 : process (e0,e1) begin
f <= not (e0 and e1); end process a0;
a1 : process (f, e2) variable y : bit;
begin
y := f or e2; z <= y;
end process a1; end RTL1;
Внутри оператора процесса с меткой a0 декларативная часть отсутствует. Аналогично мог бы быть составлен оператор процесса a1. Однако, в приведенном VHDL-тексте он составлен в таком варианте, который содержит декларативную часть.
Операторы процесса можно использовать для описания тех частей устройства (каждая из них описывается отдельным оператором процесса), которые должны функционировать одновременно (параллельно), например, для повы-
21
шения быстродействия устройства. Часто оператор процесса используется для описания "единственной части" устройства, так как оно может использоваться в качестве одной из составных частей другого устройства.
6.9.Последовательные операторы
ВVHDL последовательные операторы подобны операторам языков высокого уровня. Они могут использоваться внутри параллельных операторов или самостоятельно (без параллельных операторов) внутри тела архитектуры.
6.9.1.Оператор присваивания значения переменной
Оператор присваивания значения переменной ":=" используется для замены текущего значения переменной новым значением. Такая замена осуществляется по схеме:
имя_переменной := новое_значение_переменной;
Разумеется, такой строке должна предшествовать декларация переменной. В качестве нового значения может выступать число, запись логического преобразования или какое-либо иное выражение. В 6.5. приведены как примеры декларации переменных, так и примеры использования рассматриваемого оператора присваивания. Один из этих примеров показывает, что присваивание значений переменной может осуществляться непосредственно при ее декларации.
Отметим, что переменные в языке VHDL является локальными. Это означает, в частности, что если какая-либо переменная продекларирована, например, внутри описания определенного процесса, то при ее использовании под тем же именем внутри описании другого процесса или в ином месте тела архитектуры она будет восприниматься компилятором как новая переменная и поэтому должна заново декларироваться.
6.9.2. Присваивание значений сигналам (назначение сигналов)
Оператор присваивания значения сигналу “<=” используется (после декларации сигнала) в следующей схеме:
имя_сигнала <= значение_сигнала;
Как и для переменной, значением сигнала может быть число, запись логического преобразования или какое-либо иное выражение. Некоторые примеры использования данного оператора приведены в 6.2 и 6.8. В качестве дополнительных примеров приведем следующие:
...
signal z_bus : bit_vector (3 downto 0); signal c_bus : bit_vector (0 to 4);
...
z_bus (3 downto 2) <= "00";
c_bus (1 to 2) <= z_bus (3 downto 2);
...
22
Сигналы и переменные одного и того же типа могут быть присвоены друг другу (см. пример в 6.8).
6.9.3. Оператор "если" (if)
Оператор if языка VHDL подобен операторам if в других языках программирования. Рассмотрим лишь тот случай, когда данный оператор размещается внутри оператора процесса. В этом случае для оператора if используется
следующая схема:
if (условие) then
...; -- операторы elsif (условие) then
...; -- операторы else
...; -- операторы end if;
Выражение условия имеет тип BOOLEAN. Переход к операторам, записанным после некоторого условия, осуществляется, если это условие выполняется (имеет значение TRUE). В указанном случае реализуется также переход от данных операторов к строке end if (игнорируются иные предшествующие ей операторы). В одном операторе if может быть одна (ни одной) либо более частей elsif. Ключевое слово elsif следует отличать от слов else if. Часть else может быть только одна (или ни одной). Переход к операторам, записанным в этой части, осуществляется, если ни одно из записанных выше (после оператора if) условий не выполняется.
Объект (рис. 12) при использовании оператора if можно описать следую-
щим образом:
entity ANDOR is
port (e0,e1,e2 : in bit; z : out bit);
end ANDOR;
architecture RTL1 of ANDOR is begin
process (e0,e1,e2) begin
if ((e0 and e1) = '0') then z <= '1';
elsif (e2 = '0') then z <= '0';
else
z <= '1'; end if;
end process; end RTL1;
23
6.9.4. Оператор "случай" (case)
Оператор case выбирает одну из альтернатив и используется внутри оператора процесса в соответствии со следующей схемой:
case выражение is
when выбор 1 => операторы;
...
when выбор N => операторы; when others => операторы;
end case;
Тип выражения может быть любым. Выбираемая альтернатива (случай) определяется значением выражения. При этом записывается несколько вариантов значений выражения. В приведенной схеме такие варианты обозначены как "выбор 1", ... , "выбор N ". Если упомянутое выражение принимает значение "выбор n " ( n
... , N ), то осуществляется переход к операторам, записан-
ным в соответствующей строке схемы. Операторы, записанные в строке с ключевыми словами when others, выполняются, если выражение не принимает ни одной из значений: "выбор 1", ... , "выбор N ". Эти значения должны быть того же типа, что и выражение.
Объект (рис. 12) при использовании оператора case можно описать следующим образом:
entity ANDOR is
port (e0,e1,e2 : in bit; z : out bit);
end ANDOR;
architecture RTL1 of ANDOR is begin
process (e0,e1,e2) begin
case e0 and e1 is
when '0' => z <= '1'; when '1' =>
if (e2 = '1') then z <= '1';
else
z <= '0'; end if;
end case; end process;
end RTL1;
24
6.9.5. Оператор "компонент" (component)
Оператор component употребляется, для того чтобы использовать ранее созданные проекты в составе нового проекта. Употребление данного оператора осуществляется в соответствии со схемой:
сomponent имя_компонента1
port (карта-список портов с указанием их типов); end component;
Пример использования данного оператора приведен в 6.2, где, в частности, обращается внимание на требования к записи имени компонента и его портов при декларации, а также на необязательность использования меток.
...; -- аналогичная декларация других компонентов -- и их портов
...; -- декларация сигналов, переменных и констант begin
...; -- операторы
метка_1 : имя_компонента1 port map (новая карта портов);
...; -- операторы
метка_2 : имя_компонента2 port map (новая карта портов);
...; -- операторы
7.Задание на проектирование и порядок его выполнения
7.1.Общая формулировка задания и его варианты
Вкачестве задания к данной лабораторной работе предлагается проектирование генератора сигнала в виде отрезка псевдослучайной последовательности (ПСП). ПСП представляет собой последовательность элементов di ( i – но-
мер элемента, являющийся целым числом), повторяющихся с периодом N , т. е. di
i . Каждый из элементов может принимать одно из двух значений: 
или . При выполнении данной лабораторной работы должны быть созданы два проекта генератора, формирующего отрезок ПСП, длина которого совпадает с периодом N
. Чтобы записать такой отрезок ПСП, необходимо задать первые 3 элемента последовательности ( d1, d2 , d3 ) согласно номеру варианта
задания и табл. 6, а другие 4 элемента определить по следующим рекуррентным соотношениям:
di |
di |
di |
– для вариантов 1-7; |
di |
di |
di |
– для вариантов 8-14. |
Упомянутые два проекта генератора должны быть следующими.
Первый проект выполняется с помощью текстового редактора САПР Quartus II по аналогии с проектированием такого же генератора средствами графического редактора, рассмотренным в [2]. Т. е. генератор составляется из двух частей (компонентов): блока (счетчика) COUNTER2 и комбинационного преобразователя кодов. При этом указанные два компонента необходимо
25
|
|
|
Таблица 6 |
№ варианта |
d1, d 2 , d3 |
№ варианта |
d1, d 2 , d3 |
задания: |
|
задания: |
|
1 |
–1,–1,+1 |
8 |
–1,–1,+1 |
2 |
–1,+1,–1 |
9 |
–1,+1,+1 |
3 |
+1,–1,+1 |
10 |
+1,+1,+1 |
4 |
–1,+1,+1 |
11 |
+1,+1,–1 |
5 |
+1,+1,+1 |
12 |
+1,–1,+1 |
6 |
+1,+1,–1 |
13 |
–1,+1,–1 |
7 |
+1,–1,–1 |
14 |
+1,–1,–1 |
описать на поведенческом уровне (присваивая первому из них новое имя COUNTER2 , а второму – KCC ) и объединить средствами VHDL. Упомянутое объединение компонентов означает использование в проекте структурного описания объекта. Структуру объекта при таком проектировании графически можно представить так, как показано на рис. 14. Здесь два компонента связаны между собой 3-разрядной (образованной тремя линиями-проводами) шиной, а выходные сигналы действуют на 4-разрядной шине OUTG .
|
|
COUNTER2 |
|
KCC |
|
|
START |
|
START |
3 |
|
4 |
|
|
|
|||||
|
|
COUNT |
|
COUNT OUTG |
|
OUTG |
|
|
|
|
|||
CLK |
|
CLK |
|
|
|
|
|
|
|
|
|
Рис. 14
Компонент COUNTER2 должен функционировать как 3-разрядный двоичный счетчик тактовых импульсов, поступающих на счетный вход CLK (коэффициент счета – 8). Срабатывание по фронтам положительных перепадов CLK при условии формирования соответствующего сигнала на входе запуска START . Исходным должно быть нулевое состояние счетчика (параллельный код 000 на выходной 3-разрядной шине). При этом счетчик готов к реакции на сигнал START (в иных состояниях сигнал START не оказывает влияния на работу счетчика). Для начала счета и последовательного изменения выходных сигналов счетчика на вход START подается уровень логической единицы, который должен сохраняться хотя бы до завершения формирования переднего фронта одного положительного импульса CLK . Тогда с этого импульса начинается счет. Результат счета (количество импульсов, поступивших на вход CLK ) отражается параллельным двоичным кодом на выходной 3-разрядной шине COUNT . После 7-го тактового импульса с момента начала счета на ней появится число 7 в двоичном коде 111. Следующим (8-м) тактовым импульсом счетчик сбрасывается в исходное нулевое состояние 000 . Если в это время на входе START действует уровень логической единицы, то счет повторяется. В
26
противном случае счет прекращается, т. е. счетчик остается в нулевом состоянии до следующего импульса START .
В результате формирование сигнала START
необходимой длительности (от 1 до 8 периодов повторения импульсов CLK , например, 2 периода) позволяет реализовать однократную последовательную смену восьми состояний счетчика (двоичных чисел на шине COUNT ) от 000 до 111 с последующим возвратом в состояние 000. Семь из них (от 001 до 111) являются порядковыми номерами элементов отрезка ПСП (элементов сигнала) и должны обеспечить формирование этих элементов. Т. е. в упомянутых семи состояниях должен генерироваться сигнал, принимающий значения
или
(параллельные дополнительные коды 0001 или 1111 соответственно), а вне временного интервала генерации сигнала (в состоянии 000 счетчика) проектируемый генератор должен формировать дополнительный код нуля ( 0000 ). Такое преобразование кодов, появляющихся на шине COUNT , в указанные дополнительные коды должен осуществлять компонент KCC (рис. 14).
Второй проект генератора должен выполняться с использованием только поведенческого описания объекта. При этом генератор необходимо описать на языке VHDL как автомат с памятью, соответствующий диаграмме состояний (рис. 15). На этой диаграмме CLK
соответствует формированию фронта положительного тактового импульса.
|
|
Началь-е |
CLK START |
Дополни- |
CLK |
Дополни- |
|||
|
|
|
сост-е |
|
|
|
тельный |
|
тельный |
|
|
|
(0000) |
|
|
|
код d1 |
|
код d 2 |
|
|
|
|
|
|
|
|
||
CLK START |
CLK |
|
|
|
|
|
CLK |
||
|
|
|
|
|
|
|
|
||
|
|
Дополни- |
|
|
|
|
|
Дополни- |
|
|
|
|
тельный |
|
|
|
|
|
тельный |
|
|
|
код d7 |
|
|
|
|
|
код d3 |
|
|
|
CLK |
|
|
|
|
|
CLK |
|
|
Дополни- |
|
|
Дополни- |
|
Дополни- |
||
|
|
|
CLK |
|
CLK |
||||
|
|
тельный |
|
|
|
тельный |
|
тельный |
|
|
|
|
код d6 |
|
|
|
код d 5 |
|
код d 4 |
Рис. 15
7.2. Методика составления VHDL-описаний проектируемых устройств
Составление VHDL-описаний проектируемых генераторов поясним на примерах. При этом для простоты рассмотрим тот случай, когда требуется
27
спроектировать генератор сигнала, составленного не из семи, а из трех элемен-
тов: d1
, d2
, d3
.
7.2.1.VHDL-описание генератора для первого проекта
Вслучае 3-элементного сигнала можно провести рассуждения о структуре генератора и функционировании двух его компонентов по аналогии с 7.1. При этом убедимся, что компонент COUNTER2 должен будет иметь двухразряд-
ную выходную шину COUNT . Тогда в результате формирования сигнала
START
необходимой длительности (от 1 до 4 периодов повторения импульсов CLK , например, 2 периода) должна происходить однократная последовательная смена четырех кодов на шине COUNT от 00 до 11 с последующим возвратом в состояние 00 . С учетом этого VHDL-описание (при поведенческом подходе к нему) компонента COUNTER2 может быть составлено в следующем виде:
entity counter2 is
--декларация 2-разрядной выходной шины COUNT путем
--указания пределов возможных изменений (от 0 до 3)
--данных типа NATURAL
port (start, clk : in bit;
count : out natural range 0 to 3); end counter2;
architecture example of counter2 is begin
process (clk)
--в связи с тем, что внутри оператора процесса
--не могут декларироваться сигналы (см. 6.8), вводится
--вспомогательная переменная - аналог состояния
--выходной шины COUNT
variable number : natural range 0 to 3;
--переменная, единичное значение которой будет
--использоваться как признак появления сигнала START variable push : bit;
begin
if (clk'event and clk = '1') then -- строка с записью
--условия формирования фронта положительного
--тактового импульса
if (start = '1') then push := '1';
end if;
if (push = '1') then number := number + 1;
else
number := 0; -- сброс (обнуление) счетчика
28
end if;
if (number = 3) then push := '0';
end if; end if;
count <= number; end process;
end example;
Описание компонента KCC составим с учетом того, что в случае 3- элементного сигнала данный компонент должен осуществлять преобразование двоичных кодов 01, 10 , 11 соответственно в четырехразрядные дополнительные коды значений элементов d1
, d2
, d3
, т. е. в параллельные
коды 0001, 0001, 1111. Код 00 должен преобразовываться в дополнительный код 0000 числа 0 . VHDL-текст с таким поведенческим описанием может иметь следующий вид:
entity kcc is
port (count : in natural range 0 to 3; outg : out integer range –8 to +7);
end kcc;
architecture ind of kcc is begin
process (count) begin
case count is
when 0 => outg <= 0; when 1 => outg <= +1; when 2 => outg <= +1; when 3 => outg <= –1;
end case; end process;
end ind;
VHDL-текст со структурным описанием объединения компонентов COUNTER2 и KCC согласно рис. 14 (при 2-разрядной шине COUNT ) можно представить в виде
entity generator2 is
port (start, clk : in bit;
outg : out integer range –8 to +7); end generator2;
architecture exe of generator2 is component counter2
port (start, clk : in bit;
count : out natural range 0 to 3); end component;
component kcc
29
port (count : in natural range 0 to 3; outg : out integer range –8 to +7);
end component;
signal F : natural range 0 to 3; begin
a0 : counter2 port map (start, clk, F);
a1 : kcc port map (F, outg); end exe;
Напомним, что описанием генератора, соответствующего первому проекту, является совокупность трех последних VHDL-текстов.
7.2.2.VHDLописание генератора для второго проекта
Вслучае 3-элементного сигнала в диаграмме, аналогичной рис. 15, будут
отсутствовать состояния, соответствующие дополнительным кодам d 4 , d5, d6 , d7 . При этом VHDL-текст с поведенческим описанием генератора можно
составить в следующем виде: entity generator3 is
port (start, clk : in bit;
outg : out integer range –8 to +7); end generator3;
architecture example of generator3 is begin
process (clk)
--декларация 2-битной переменной, которая вводится в
--связи с совпадением значений (+1 или –1) отдельных
--элементов генерируемого сигнала и моделирует
--некоторый 2-разрядный счетчик номеров четырех
--состояний выходной шины генератора
variable count : natural range 0 to 3 := 0; variable result : integer range –8 to +7 := 0; variable push : bit := '0';
begin
if (clk'event and clk = '1') then if (start = '1') then
push := '1'; end if;
if (push = '1') then count := count + 1;
else
count := 0; end if;
case count is
when 0 => result := 0;
30
