Языки AHDL, VHDL и Verilog – язык описания аппаратуры от англ. «HDL – Hardware Description Language» . VHDL – язык описания высокоскоростных интегральных схем от англ. «Very high speed integrated circuit HDL» . Элементы языка VHDL 1) Комментарии Часть строки после двух знаков "--" рассматривается как комментарий. Пример: -- Начало программы
2) Идентификаторы Символы алфавита от А до Z и от а до z, цифры, символ подчеркивания _. Идентификатор должен начинаться с символа алфавита, не должен заканчиваться символом подчеркивания и не должен содержать несколько символов подчеркивания подряд. Идентификатором не может быть ключевое зарезервированное VHDL (выделяется синим цветом). Язык VHDL не чувствителен к регистру. Data data DATA Data 1 Data_1 1_Data_ слово,
3) Числа Целые числа могут записываться по основанию, отличному от 10. Для оснований от 10 до 15 при записи цифр, больших 9, используются символы а-f: 184 10#184# 2#11111010# 16#FD# Для удобочитаемости больших чисел между отдельными знаками могут включаться символы подчеркивания: 27_000.
4) Строки Содержимое строки заключается в двойные кавычки. VHDL поддерживает битовые строки, строки восьмеричных и шестнадцатеричных символов. Перед такими строками соответственно ставятся символы: b, о, х: b"1101"
Типы данных в VHDL Тип – множество значений с общим признаком. VHDL является строго типизированным языком, т. е. каждый объект языка объявляется со своим типом может принимать значения только данного типа. Для представления целых чисел используется тип integer. Этот тип позволяет представить числа в диапазоне от -2 147 483 647 до 2 147 483 64. Для представления чисел без знака от 0 до 2147483647 используется тип natural. Оба этих типа являются встроенными для языка VHDL.
Тип std_logic Предназначен для описания логических сигналов. Не является встроенным для языка VHDL.
Для подключения типа std_logic к проекту нужно подключить пакет std_logic_1164 из библиотеки ieee: library ieee; use ieee. std_logic_1164. all; Эти две строчки присутствуют в начале каждой программы.
Для использования операций в проекте нужно подключить к нему пакет арифметических операций: use ieee. std_logic_arith. all;
Сущность и архитектура объекта Синтезируемое цифровое устройство в VHDL можно представить как некий «черный» ящик с заданными входами и выходами. Для определения объекта используется ключевое слово entity ( «сущность» ); для определения его входов и выходов (портов объекта) – ключевое слово port. В декларации порта обязательно указываются его идентификатор (имя), режим работы и тип. В VHDL определены следующие режимы работы: in – прием; out – передача; inout – прием и передача (двунаправленная линия).
Архитектура Алгоритм работы «черного ящика» описывает архитектура (ключевое слово architecture). Архитектура имеет свое имя, в качестве которого принято использовать имя Behavior. Для определения объекта используется ключевое слово entity ( «сущность» ); для определения его входов и выходов (портов объекта) – ключевое слово port. Архитектура содержит две основные части: 1. часть, содержащую описания (декларации), и 2. часть, содержащую исполняемые параллельные операторы; данная часть заключена между операторами begin … end <имя архитектуры>;
Декларации В декларативной части архитектуры объявляются: - константы, - сигналы, - типы и подтипы, - функции и процедуры пользователя, - компоненты (другие объекты, используемые в проекте). Объявленные в теле архитектуры элементы видимы только в пределах этой архитектуры.
Сигналы в VHDL Сигналом является объект языка, который переносит значение от одного процесса к другому и вместе с ним – синхронизирующее воздействие. Для присвоения сигналам значений используется параллельный оператор присваивания «<=» . signal x, y: std_logic; … x <= ‘ 0’; y <= ‘ 1’; … Присваивание происходит параллельно (одновременно).
Оператор процесса Оператор процесса – это параллельный оператор, представляющий основу языка VHDL. По сути процесс – это микропрограмма, выполняемая на виртуальном процессорном элементе. Его упрощенный синтаксис: process (<сигнал 1> , <сигнал 2>, <сигнал N>) is <декларации>; begin <последовательные операторы>; end process; В декларативной части процесса объявляются: - типа и подтип, - процедуры и функции, - константы, - переменные.
Оператор процесса - все процессы в программе выполняются параллельно; - процессы обмениваются сигналами, которые выполняют синхронизацию процессов и переносят значения между; - для каждого сигнала существует только один источник (драйвер), поэтому нельзя присваивать значение одному сигналу в разных процессах; - сигналы нельзя объявлять в процессах; - процесс невозможно поместить в процесс, так как там есть место только для последовательных операторов; - в круглых скобках заголовка процесса указывается множество сигналов, при изменении которых процесс запускается – список чувствительности.
Переменные Переменной является элемент языка VHDL, хранящий некоторое значение в пределах оператора процесса, т. е. область видимости переменной ограничена процессом. Для объявления переменной используется ключевое слово Variable. При объявлении нужно указать ее значение по умолчанию. Присваивание переменной отличается от присваивания сигнал: оно выполняется мгновенно присваивания « : = » . Variable cnt: natural : = 0; … cnt : = cnt + 1; и реализуется оператором
Пример: 2 -хвходовый 4 -хразрядный мультиплексор Мультиплексором называется цифровое устройство, которое в зависимости от значения сигнала на адресном входе коммутирует один из N входов данных на единственный выход.
library ieee; use ieee. std_logic_1164. all; -- описание сущности объекта entity Mux is port ( Data 1, Data 2: in std_logic_vector(3 downto 0); -- входы данных -- поскольку число входов данных равно двум, -- то для адресного входа требуется всего один разряд: -- если на входе адреса ‘ 0’ – выдаем на выход Data 1, если ‘ 1’ – Data 2 Adr: in std_logic; -- адресный вход Data_out: out std_logic_vector(3 downto 0); -- выход ); end Mux;
-- описание архитектуры architecture Behavior of Mux is -- пустой для данной программы раздел деклараций begin -- начало архитектуры -- поскольку логика работы мультиплексора изменяется -- в зависимости от значения адресного входа, -- введем процесс с сигналом Adr в списке чувствительности process (Adr) begin -- воспользуемся последовательным оператором выбора Case case Adr is when ‘ 0’ =>Data_out <= Data 1; when ‘ 1’ =>Data_out <= Data 2; -- определим алгоритм работы объекта Mux в остальных -- случаях, для чего используем пустой оператор Null when others => null;
end case; -- завершаем оператор Case end process; -- завершаем процесс end Behavior; -- завершаем архитектуру
Компоненты. Подключение проекта к проекту верхнего уровня При использовании структурного стиля программирования необходимо в декларативной части архитектуры объявить образы используемых сущностей – компоненты.
component Mux is port ( Data 1, Data 2: in std_logic_vector(3 downto 0); -- входы данных Adr: in std_logic; Data_out: out std_logic_vector(3 downto 0); ); end component;
Vyhod_MUX component Comparator is port ( Data, Reference: in natural; -- входы данных Compare: out std_logic ); end component; Также в декларативной части архитектуры необходимо объявить сигнал для переноса информации от мультиплексора к компаратору. signal Vyhod_MUX: std_logic_vector(3 downto 0);
Для подключения к входам компонентов нужных сигналов в исполнительной части архитектуры используются два типа присвоения. 1. При позиционном присвоении важен порядок объявления входных и выходных сигналов – в строгом соответствии с порядком их объявления в компоненте: <метка>: <имя компонента> port map (<список сигналов>); Comp_MUX: MUX port map (Vhod 1, Vhod 2, Upr, Vyhod_Mux);
2. При поименованном присвоении сигнал для каждого порта указывается в явном виде с использованием оператора назначения « => » . Порядок следования портов компонента при этом не важен. Comp_MUX: MUX port map ( Data 1 => Vhod 1, Data 2 => Vhod 2, Data_Out => Vyhod_Mux, Adr => Upr );
Функции преобразования типов В языке VHDL определены две функции преобразования типов. 1. Функция conv_integer(arg:
Функции преобразования типов Функции conv_integer и conv_std_logic_vector определены сразу в двух пакетах ieee: ieee. std_logic_unsigned и ieee. std_logic_signed (соответственно преобразование чисел без знака и со знаком). Данные пакеты являются взаимоисключающими. Чаще используется беззнаковый пакет: use ieee. std_logic_unsigned. all; Пример: conv_integer("0110" ) = 6 conv_std_logic_vector (6, 8) = "00000110"
Vyhod_MUX 2. При подключении входа Data компаратора используем функцию преобразования типов: Comp_Comparator: Comparator port map ( Data => conv_integer(Vyhod_MUX), … );
Тактируемые цифровые устройства. Счетчик – тактируемое цифровое устройство, циклически меняющее свои состояния под действием импульсов, подаваемых на тактовый вход. Количество тактов, через которое повторяется исходное состояние счетчика, называют модулем счета Ксч. По фронту увеличивается тактовой частоты (суммирующий clk счетчик) значение или счетчика уменьшается (вычитающий счетчик) на 1. Временные диаграммы для суммирующего счетчика с Ксч = 4.
library ieee; use ieee. std_logic_1164. all; use ieee. std_logic_arith. all; entity counter is -- задаем настроечную константу generic ( N: natural : = 4 -- коэффициент счета со значением по умолчанию ); port ( clk: in std_logic; rst: in std_logic; -- сигнал сброса счетчика секунд cntr: out natural ); end counter;
architecture Behavior of counter is begin -- алгоритм работы счетчика зависит от двух сигналов: -- тактовых импульсов clk и сигнала сброса rst, поэтому -- указываем их в списке чувствительности процесса process(clk, rst) -- вводим переменную для хранения текущего состояния счетчика variable cnt: natural range 0 to N-1; begin -- реализуем асинхронный сброс, т. е. при активном уровне -- сигнала сброса rst сразу же, не дожидаясь переднего фронта -- тактовых импульсов clk, будем обнулять значение счетчика: if rst = '1' then cnt : = 0; cntr <= 0; -- иначе по переднему фронту -- будем увеличивать значение счетчика
-- условие переднего фронта: -- 1) сигнал изменился -> clk'event и (and) -- 2) стал равным '1' -> clk = '1' elsif clk'event and clk = '1' then -- проверяем условие достижения максимального значения, -- равного (Модуль счета - 1) if cnt = N - 1 then cnt : = 0; else cnt : = cnt + 1; end if; -- закрываем оператор if cnt = N - 1 cntr <= cnt; end if; -- закрываем оператор if c условием переднего фронта end process; end Behavior;
Подключение пакета с настроечной константой к проекту верхнего уровня Comp_counter: counter generic map (N => 100) port map (<подключение портов>); Точка с запятой между port map и generic map не ставится.
Пакеты в VHDL. Глобальные константы задаются в пакетах. Пакет – первичный блок проекта, синтаксис которого имеет вид: package <имя_пакета> is <декларации>; end <имя_пакета>; Декларациями могут быть объявления типа и подтипа, константы (ключевое слово constant), компонента, функции и процедуры.
package my_params is constant N: natural : = 16; constant M: integer : = 200; end my_params; Для подключения всего пакета к проекту в разделе подключения библиотек и пакетов нужно записать: use work. <имя_пакета>. all; use work. my_params. all;
Дополнительные материалы Книги ftp: //stk-kholopov@stk-kholopov. space. rsreu. ru/public/Books_VHDL. rar Презентация ftp: //stk-kholopov@stk-kholopov. space. rsreu. ru/public/VHDL_АСУ. ppt Задание на курсовой проект и примеры выполнения пояснительной записки к курсовому проекту ftp: //stk-kholopov@stk-kholopov. space. rsreu. ru/public/КП. rar Методические указания к лабораторным работам ftp: //stk-kholopov@stk-kholopov. space. rsreu. ru/public/Lab_PLIS_1_2_ASU. pdf Готовый VHDL-проект с результатами моделирования и затем пояснительную записку отправлять на E-mail kholopov. i. s@rsreu. ru