
- •Введение
- •Классы и объекты
- •Constant - константа.
- •Variable - переменная;
- •Signal - сигнал;
- •Комментарии
- •Типы данных
- •Подробно о std_logic
- •О массивах в языке vhdl
- •Операции в языке vhdl
- •Операторы vhdl
- •Интерфейс
- •Inout - двунаправленный порт (чтение и запись);
- •Архитектура
- •Часть, содержащую описания (декларации);
- •Часть, содержащую исполняемые операторы.
- •Процессы
- •Атрибуты
- •Подпрограммы vhdl
- •Библиотеки vhdl
- •Тестирование
- •Im_cpu(res, '0', ale, wr, oe, cs, X"0000", addr, X"00", data); -- Вызываем имитатор
- •Im_cpu(res, '0', ale, wr, oe, cs, X"0021", addr, X"3", data); -- Разрешаем индикацию
- •Заключение
- •Приложение а
Процессы
... процесс пошел.
Давайте продолжим развивать наш VHDL-проект. Пусть наше устройство будет программируемым, и сигналами разрешения/запрещения индикации ошибки будет управлять внешний процессор через управляющий регистр RegUpr. Итак, нам нужен регистр. Давайте напишем VHDL-интерфейс нашего регистра.
---------------------------------
-- VHDL-интерфейс регистра
---------------------------------
library ieee;
use ieee.std_logic_1164.all;
---------------------------------
entity RegUpr is
port (
wr, cs : in std_logic;
addr : in std_logic_vector(1 downto 0);
datain : in std_logic_vector(7 downto 0);
en1, en2 : out std_logic
);
end RegUpr;
---------------------------------
Теперь нам нужно сделать так, чтобы регистр реагировал на определенную комбинацию сигналов rw, cs и addr. В языке VHDL добиться этого можно несколькими способами. Один из способов это организовать процесс. В общем виде VHDL-процесс записывается так:
LABEL: process (лист чувствительности)
-- область деклараций
begin
--VHDL операторы
end process;
Язык VHDL допускает процессы без меток, а также отсутствие листа чувствительности при наличии в теле процесса хотябы одного оператора wait. C учетом вышесказанного, напишем архитектуру регистра на VHDL:
-----------------------------------
-- VHDL-архитектура регистра
-----------------------------------
architecture arch of RegUpr is
signal regupr : std_logic_vector(7 downto 0);
begin
-------------------------------
-- VHDL-процесс регистра
-------------------------------
process (wr, cs, addr)
begin
if (cs = '1' and wr = '0') then
case addr is
when "01" => regupr <= datain;
when others => null;
end case;
end if;
end process;
en1 <= regupr(0);
en2 <= regupr(1);
end arch;
Теперь осталось соединить наш VHDL-регистр со схемой формирования ошибки и у нас получится работоспособное программируемое устройство.
--------------------------------------------------
-- VHDL код управления индикацией
--------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
---------------------------------
entity ERR_LED is
port (
ERR1, ERR2, wr, cs : in std_logic;
addr : in std_logic_vector(1 downto 0);
data : in std_logic_vector(7 downto 0);
LED : out std_logic
);
constant GND : std_logic:='0';
constant TRI : std_logic:='Z';
end ERR_LED;
---------------------------------
architecture led_arch of ERR_LED is
signal serror, en1, en2 : std_logic;
begin
C0: entity WORK.RegUpr(arch) port map(wr => wr, cs => cs, en1 => en1, en2 => en2, datain => data, addr => addr);
C1: entity WORK.NAND2X3(bbb) port map(a => ERR1, b => en1, c => ERR2, d => en2, q => serror);
LED <= GND when serror = '1' else TRI;
end led_arch;
Синтезатор Leonardo Spectrum для микросхемы MAX3128ATC144 из данного VHDL-кода сгенерирует схему, показанную на рисунке 14.
Все хорошо, но смущает сигнал выбора устройства. Конечно без него никак, потому как адресная шина процессора наверняка больше, чем наши два разряда. Но есть вопрос, кто его формирует. Конечно, многие современные процессоры могут сами формировать несколько CS для разных областей адресного пространства, но мы в учебных целях будем считать, что дешифрация адреса возложена на периферию. Итак, нам нужен дешифратор адреса. Пусть адрес стробируется сигналом ALE. Тогда нам надо как-то ловить этот строб. Вот таким вот путем мы и подошли к атрибутам VHDL, которые и рассмотрим в следующем разделе.