Введение в последовательные заявления VHDL
В этой статье мы попытаемся лучше понять важность последовательного заявления в VHDL.
В предыдущей статье мы рассмотрели некоторые параллельные заявления VHDL. В этой статье мы попытаемся лучше понять важность последовательного заявления.
Пожалуйста, ознакомьтесь с моей статьей о начале работы с VHDL для получения дополнительной вводной информации.
Почему нам нужны последовательные заявления "" src = "// www.allaboutcircuits.com/uploads/articles/VHDL_Sequential_Statements_1.jpg" />
Рисунок 1
Ниже приведена архитектура кода VHDL для этой схемы.
1 architecture Behavioral of comb1 is 2 signal sig1: std_logic; 3 begin 4 sig1 <= (a and b); 5 out1 <= (sig1 or c); 6 out2 <= (not d); 7 end Behavioral;
Рассмотрим строки 2, 4, 5 и 6 этого кода. Каждая из этих строк имеет четкое отображение в аппаратной схеме, показанной на рисунке 1. Например, строка 2 становится проводкой в окончательной конструкции, которая на рисунке обозначена sig1. Строка 5 указывает логический элемент ИЛИ с выходом out1 и входами sig1 и c.
Как обсуждалось в предыдущей статье, чтобы правильно описать физические компоненты на рисунке 1, программное обеспечение синтеза одновременно оценивает линии этого кода. Вот почему мы называем их параллельными операторами. Таким образом, одновременные операторы оцениваются одновременно и имеют четкое сопоставление с аппаратными компонентами.
С помощью этих параллельных операторов мы можем реализовать различные логические логики. Следовательно, теоретически совпадающие утверждения достаточны для описания произвольной цифровой схемы.
Однако по ряду причин VHDL предоставляет нам несколько последовательных операторов, в которых важны порядок утверждений:
Последовательные заявления облегчают абстрактное описание схемы
Последовательные утверждения позволяют нам описывать абстрактное поведение схемы, а не использовать компоненты низкого уровня, такие как разные логические ворота, для построения схемы. Это абстрактное описание поведения может иногда упростить схему. Это связано с тем, что человеческие рассуждения и алгоритмы напоминают последовательный процесс.
Примером может быть дальнейшее разъяснение этого. Предположим, что нам нужно спроектировать схему, которая получает в качестве входного сигнала четырехбитовый вектор, in1, и вычисляет количество начальных нулей в этом векторе. Как мы можем спроектировать такую схему с помощью цифровых ворот?
Ну, мы можем найти таблицу истинности вывода, упростить ее, а затем использовать логические ворота для реализации требуемых уравнений; однако это кажется довольно трудоемким.
Как насчет использования некоторых стандартных цифровых строительных блоков, таких как сумматоры и мультиплексоры для проектирования схемы? Одна возможная блок-схема показана на рисунке 2.

фигура 2
Первый элемент входного вектора in1 (0) используется в качестве входного входа мультиплексора mux0. Если этот элемент равен нулю, то выход mux0, m0 будет равен единице, иначе он будет равен нулю.
Для второго мультиплексора нам нужно проверить второй элемент входного вектора, а также первый. Это можно сделать, используя логический элемент ИЛИ. Когда оба из in1 (0) и in1 (1) равны нулю, mux1 выдает m0 + 1; в противном случае он сам пройдет m0. Таким образом, мы можем подсчитать количество ведущих нулей.
Другими словами, до тех пор, пока мы не достигли одного, мы выбираем путь, исходящий от инкремента. Однако после этого мы просто передаем результат предыдущего этапа без изменений. Например, для входного вектора in1 = «0011» мы получим зеленый путь на рисунке 3, который дает out1 = 2.

Рисунок 3
Схема на рисунке 2 намного интуитивна, чем поиск таблицы истинности, а затем, используя основные логические ворота для ее реализации. Давайте сравним его с алгоритмом, показанным на рисунке 4.

Рисунок 4
В этом случае каждый бит проверяется. Если он равен нулю, счет увеличивается на единицу. Если нет, мы заканчиваем процесс.
Этот алгоритм в основном основан на человеческом рассуждении для подсчета числа начальных нулей в последовательности бит. Вот почему метод, показанный на рисунке 4, кажется более понятным по сравнению с рисунком 2. Как показывает этот пример, наши рассуждения обычно имеют последовательный характер, т. Е. Мы анализируем элементы входного вектора один за другим и принимаем соответствующее решение.
Более того, у нас есть абстрактные описания для некоторых операций. Например, когда мы достигаем одного на рисунке 4, мы заканчиваем процесс; однако нет такой операции, как «завершение процесса» в схеме на рисунке 2.
Резюмируя, алгоритм на рисунке 4 является последовательным и использует абстрактные описания. Поскольку это напоминает человеческие рассуждения, это легче понять. Однако, в отличие от блок-схемы на рисунке 2, алгоритм, показанный на рисунке 4, не дает нам никаких указаний относительно базовой структуры оборудования. Поскольку каждый из этих двух методов имеет свои плюсы и минусы, VHDL предоставляет нам инструменты для использования обоих этих двух методов.
Сопутствующие операторы VHDL могут использоваться для описания схемы, которая очень близка к окончательному оборудованию, тогда как последовательные операторы позволяют нам иметь более абстрактное описание схемы.
Некоторые последовательные заявления используют оптимизированные структуры
Иногда использование последовательных утверждений не только более простое, но и более безопасное и более эффективное. Например, при использовании последовательных инструкций для описания конкретных схем, таких как триггеры, программное обеспечение синтеза распознает намеченную схему и использует некоторые оптимизированные структуры для ее реализации. Однако эти оптимизированные схемы не используются, когда мы описываем триггер с логическими затворами. Чтобы прочитать об опасности получения элемента памяти из примитивных ворот, см. Раздел 8.3 этой книги. Описание VHDL триггера D-типа будет рассмотрено далее в этой статье.
Почему нам нужны процессы?
В отличие от параллельных операторов, последовательные операторы выполняются по строкам. Следовательно, нам нужно отделить эти два типа кода друг от друга. Это делается путем включения последовательных операторов внутри конструкции VHDL, известной как «процесс». «Процесс» может появиться где угодно после «начала» утверждения «архитектуры».
Основная структура «процесса» такова:
1 process(sensitivity_list) 2 declarations; 3 begin 4 sequential_statements; 5 end process;
Как предполагает вышеприведенная структура, последовательные утверждения размещаются между ключевыми словами «begin» и «end». В этой части кода порядок инструкций важен так же, как и код в традиционном компьютерном программировании.
Часть деклараций включает любые объекты, которые необходимо объявить и использовать внутри процесса. Эти объекты будут локальными для процесса.
Список чувствительности - это список сигналов, которые непрерывно контролируются конструкцией «процесс». Всякий раз, когда изменяется сигнал из списка чувствительности, «процесс» активируется, и последовательные инструкции «процесса» будут выполняться по строкам. Затем «процесс» будет ждать другого изменения в списке чувствительности. В этом случае говорится, что «процесс» приостановлен. Следовательно, «процесс» имеет два состояния: он либо активируется из-за изменения в списке чувствительности, либо приостановлен, ожидая изменения сигналов в списке чувствительности.
В будущих статьях мы рассмотрим примеры последовательных инструкций VHDL более подробно. Однако, чтобы лучше ознакомиться с концепциями, обсуждаемыми в этой статье, давайте кратко рассмотрим описание VHDL триггера D-типа (DFF):
Код VHDL для позитивного DFF
На рисунке 5 показаны символы DFF с положительным фронтом (рис. 5 (a)) и DFF с отрицательным фронтом (рис. 5 (b)). Эти DFF имеют три входа: ввод данных, ввод часов и сброс, которые, соответственно, показаны на D, clk и rst на рисунке. Выход обозначается через Q.
Флип-флоп - это чувствительный к краю элемент памяти. Это означает, что состояние выхода не изменяется, если ни на переднем фронте, ни на заднем фронте часов. Например, DFF с положительным фронтом чувствителен к нарастающему фронту часов, следовательно, по нарастающему фронту часов, триггер становится прозрачным и передает вход D на выход Q. Выход будет сохранять свое значение до следующего нарастающего фронта часов.

Рисунок 5 (a) DFF с положительным фронтом и (b) DFF с отрицательным фронтом
Теперь давайте посмотрим на описание VHDL положительного DFF. Обратите внимание, что в будущих статьях подробно рассматриваются последовательные утверждения, и цель этого примера - познакомиться с некоторыми из концепций, рассмотренных выше.
Поскольку рекомендуемое описание DFF использует описание поведения, довольно легко понять большую часть следующего кода, даже без предварительного ознакомления с темой.
1 library IEEE; 2 use IEEE. STD_LOGIC_1164. ALL; 3 entity DFF is 4 port(d, rst, clk: in std_logic; 5 q: out std_logic); 6 end DFF; 7 architecture Behavioral of DFF is 8 begin 9 process(clk) 10 begin 11 if (clk'event and clk="1") then 12 if rst="1" then 13 q <= '0'; 14 else 15 q <= d; 16 end if; 17 end if; 18 end process; 19 end Behavioral;
Этот код использует «процесс» для описания DFF.
Строка 9 кода указывает начало «процесса». Сигнал синхронизации, clk, указан в списке чувствительности этого «процесса». Это означает, что всякий раз, когда clk изменяется, либо от низкого до высокого, либо наоборот, будут выполняться последовательные инструкции «процесса».
Внутри «процесса» есть два оператора «if». Операторы if if VHDL аналогичны условным структурам, используемым в компьютерных языках программирования. Когда условие после ключевого слова "if" истинно, будут выполняться инструкции после ключевого слова "then". В противном случае будут выполняться операторы после ключевого слова else. Однако ветка «else» является необязательной. Например, в приведенном выше коде внешний оператор «if» не имеет ветви «else», тогда как внутренний оператор «if» делает это.
Условие для первого оператора «if»: clk'event и clk = «1». Это утверждение является ключевым выражением для вывода триггера. Clk'event возвращает true, когда происходит изменение значения сигнала clk. ANDing это выражение с clk = "1" означает, что значение clk изменилось, и его текущее значение равно '1'. Это булево выражение будет истинным на переднем фронте часов. Таким образом, оператор «if» строки 11 проверяет, произошел ли фронт часов или нет. На восходящем фронте будет выполняться оператор после ключевого слова «then», который является другим оператором if.
Этот второй оператор «if» проверяет ввод сброса rst. Если первое значение велико, выход идет на низкий; в противном случае он принимает значение входных данных D. На самом деле это поведенческое описание DFF с положительным фронтом.
После выполнения операторов внутри тела «процесс» «процесс» приостанавливается, что означает, что он будет ждать следующего края clk.
Чтобы проверить работу вышеуказанного кода, изучите моделирование ISE кода, приведенного ниже.

Рисунок 6
Резюме
- Параллельные операторы оцениваются одновременно и имеют четкое сопоставление с аппаратными компонентами.
- Последовательные утверждения позволяют нам описывать абстрактное поведение схемы, а не использовать компоненты низкого уровня, такие как разные логические ворота, для построения схемы. Это абстрактное описание поведения может иногда упростить схему.
- Иногда использование последовательных утверждений не только более простое, но и более безопасное и более эффективное.
- VHDL использует конструкцию, известную как «процесс» для разделения последовательных операторов от одновременных.
Чтобы просмотреть полный список моих статей, перейдите на эту страницу.