
- •Введение
- •Классы и объекты
- •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); -- Разрешаем индикацию
- •Заключение
- •Приложение а
Подробно о std_logic
... а вот кому набор стандартных ложек.
Давайте посмотрим, хватает ли нам типов для описания логических схем или их моделирования. Ну возьмем хотябы состояние высокого импеданса. Ни один из вышеперечисленных типов такой возможности не дает. Поэтому были введены типы std_ulogic и std_ulogic_vector: type std_ulogic is ( 'U', -- Неинициализированный. Этот сигнал не был задан еще. 'X', -- Сильный неизвестный сигнал. '0', -- Сильный 0 '1', -- Сильная 1 'Z', -- Высокий импеданс 'W', -- Слабый неизвестный сигнал 'L', -- Слабый 0 'H', -- Слабая 1 '-' -- Не имеет значения какой сигнал ); type std_ulogic_vector is array ( natural range <> ) of std_ulogic;
Такие объявления типов находятся в библиотеке std_logic_1164. В большинстве книгах по VHDL на этом все и заканчивается, мы же рассмотрим эти типы поподробнее.
Итак, начнем с конца. Тип std_ulogic_vector есть просто вектор ранее объявленного типа std_ulogic. Это аналогично типу bit_vector. И мы можем спокойно написать следующие выражения:
signal a : std_ulogic_vector(0 to 7);
signal b : std_ulogic_vector(7 downto 0);
А теперь перейдем к типу std_ulogic. Как видим это перечислимый тип, состоящий из 9 символов. Первый символ 'U' обозначает неинициализированные данные. Ну представьте себе ОЗУ, после включения питания. Реально конечно там будут либо нолики, либо единички, поэтому данный символ не годится для проектирования синтезируемой логики, но активно используется для моделирования.
Символы 'X', '1' и '0' обозначают сильные сигналы. Что означает сильные сигналы? Давайте посмотрим на рисунки 2 и 3. Рисунок 2 не требует комментариев, а вот рисунок 3 поясним. Конечно, реально в схеме будет или '1' или '0', просто мы точно не знаем значение. И конечно для синтеза логических схем символ 'X' не подходит, но, как и 'U' часто используется при моделировании.
На рисунке 4 показаны пояснения к символу 'Z'. В принципе это простой высокий импеданс. Этот символ подходит как для моделирования, так и для синтеза, но следует отметить, что в ПЛИС такой сигнал можно реализовать только на выходных каскадах микросхемы.
Теперь давайте посмотрим на слабые сигналы (рисунки 5, 6, 7). Думаю понятно, почему они слабые, просто их можно "поддавить". При моделировании используются в основном как нагрузка на открытом коллекторе (или его имитации).
Вот пример на VHDL открытого коллектора с нагрузкой (на рисунке 8 приведена схемная реализация данного кода):
out <= '0' when in = '1' else 'H';
Причем некоторые ПЛИС содержат такие резисторы в своих выходных каскадах, а некоторые синтезаторы даже подключат их, встретив такой VHDL-код. В крайнем случае, это можно сделать вручную через настройки выходов, правда, сопротивление таких резисторов порядка 50 кОм.
И наконец, загадочный символ '-', который используется только при моделировании и означает, что Вам плевать какое значение имеет сигнал. Автор никогда его не использовал, но может, есть такие ситуации, когда его использование целесообразно. Пример такого использования показан на рисунке 9.
А теперь давайте разберемся, причем здесь std_ulogic, когда мы хотели подробно говорить об std_logic. А все очень просто - буква 'u' в std_ulogic означает unresolved, что означает неразрешенный. Следовательно, std_logic является разрешенным подтипом, что, кстати, следует из его объявления в библиотеке std_logic_1164:
subtype std_logic is resolved std_ulogic;
И далее объявляется вектор:
type std_logic_vector is array ( natural range <> ) of std_logic;
Как видите, подтип std_logic образуется из типа std_ulogic c помощью разрешающей функции resolved, которая также объявлена и определена в библиотеке std_logic_1164. Для разрешения данных типа std_logic, функция resolved использует разрешающую таблицу, VHDL-код которой приведен ниже:
type stdlogic_table is array(std_ulogic, std_ulogic) of std_ulogic;
constant resolution_table : stdlogic_table := (
-- ---------------------------------------------------------
-- | U X 0 1 Z W L H - | |
-- ---------------------------------------------------------
( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U |
( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
( 'U', 'X', '0', 'X', '0', '0', '0', '0', 'X' ), -- | 0 |
( 'U', 'X', 'X', '1', '1', '1', '1', '1', 'X' ), -- | 1 |
( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'X' ), -- | Z |
( 'U', 'X', '0', '1', 'W', 'W', 'W', 'W', 'X' ), -- | W |
( 'U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'X' ), -- | L |
( 'U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'X' ), -- | H |
( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) -- | - |
);
Данная таблица определяет, какой сигнал получится в итоге "столкновения" двух сигналов типа std_logic. Например, приходят сигналы '0' и 'H', смотрим, что в месте пересечения соответствующих строки и столбца получается '0'. И это не удивительно, если вспомнить, что сигнал '0' - сильный (рисунок 2), а 'H' - слабый (рисунок 5). Аналогично можно разрешить ситуацию и с другими сигналами.
Кроме того, в библиотеке std_logic_1164 переопределены операторы and, or, nand, nor, xor, xnor и not для типов std_ulogic и std_logic. И в той же библиотеке определены несколько полезных функций.
А теперь о главном. В отличие от библиотеки STD, библиотеку std_logic_1164 нужно подключать с помощью следующих VHDL инструкций:
library ieee;
use ieee.std_logic_1164.all;
.......
-- Дальше можно делать объявления std_logic
signal a, b : std_logic;
signal c : std_logic_vector(7 downto 0);
shared variable d : std_logic_vector(7 downto 0):="01010101";