
- •Типы vhdl-данных и их интерпретация
- •1 Объявление типов
- •2 Классификация скалярных типов данных
- •3 Целочисленные типы
- •4 Вещественные типы
- •5 Физические типы
- •6 Перечислимые типы
- •7 Подтипы
- •8 Атрибуты
- •9 Массивы
- •10 Многомерные массивы
- •11 Неограниченные массивы
- •12 Атрибуты
- •13 Операции
- •14 Преобразование типов
- •15 Агрегаты
- •16 Строковые литералы
- •17 Записи
- •18 Преобразование типов данных в процессе vhdl-синтеза
- •Перечислимый тип представляется набором шин:
10 Многомерные массивы
Согласно показанному синтаксическому правилу, язык VHDL позволяет определять многомерные массивы. В качестве примера их использования рассмотрим описание модуля, который реализует не предоставляемую по умолчанию логическую функцию. Например, это может быть функция импликации (implication), имеющая следующую таблицу истинности (truth table) и соответствующую ей карту Карно (Karnaugh map) (рис. 1):
Рисунок 1 – Таблица истинности и карта Карно функции импликации
Использование многомерных массивов дает возможность описать поведение модуля путем непосредственного задания показанной выше карты Карно:
entity implication is
port (
p : in boolean;
q : in boolean;
z : out boolean
);
end entity implication;
architecture behavioral of implication is
type karnaugh_map is array (boolean, boolean) of boolean;
constant implication_karnaugh_map : karnaugh_map := (
(true , true),
(false, true));
begin
z <= implication_karnaugh_map (p, q);
end architecture behavioral;
11 Неограниченные массивы
Типы массивов, которые определены в соответствии с показанным ранее правилом, называются ограниченными (constrained), так как они требуют задания границ диапазонов при определении типа. Кроме них, язык VHDL позволяет определять также неограниченные (unconstrained) типы массивов, для которых задается тип индекса, но не задаются границы диапазона для него. Правило определения неограниченного типа массива следующее:
<определение типа массива> ::=
array (<метка типа> range <> {, (<метка типа> range <>}*)
of <определение подтипа>
Основные преимущества использования неограниченных массивов состоят в том, что, во-первых, границы диапазона индексов неограниченных типов задаются при объявлении конкретных объектов, что расширяет возможности для повторного использования типов, во-вторых, при описании портов можно использовать неограниченные типы, не задавая границ диапазона индексов, что позволяет создавать обобщенные модули.
С точки зрения языка VHDL при объявлении некоторого объекта можно определить новый подтип, но не новый тип. По этой причине тип любого массива должен определяться до его использования. Однако, при задании границ диапазона индексов для неограниченного типа в объявлении некоторого объекта происходит создание подтипа согласно следующего правила:
<определение подтипа> ::=
<метка типа> [(<дискретный диапазон> {, <дискретный диапазон>})]
По умолчанию предоставляется два неограниченных типа массивов:
тип для представления символьных строк:
type string is array (positive range <>) of character;
тип для представления данных на высоком уровне абстракции:
type bit_vector is array (natural range <>) of bit;
Кроме перечисленных следует обратить внимание на неограниченные типы массивов, которые предоставляются в арифметическом пакете numeric_bit (определенном в стандарте IEEE 1076.3-1997):
type unsigned is array (natural range <>) of bit;
type signed is array (natural range <>) of bit;
В стандарте IEEE 1076.3-1997 также описан арифметический пакет numeric_std, в котором определены типы signed и unsigned, однако элементы этих массивов принадлежат типу std_logic.
В пакете стандартной логики std_logic_1164 предоставляются два неограниченных типа массивов, предназначенных для моделирования низкоуровневой логики:
type std_ulogic_vector is array (natural range <>) of std_ulogic;
type std_logic_vector is array (natural range <>) of std_logic;
Неограниченные типы массивов позволяют эффективно моделировать представление данных на аппаратном уровне. Рассмотрим это на примере устройства, которое осуществляет проверку по четности. Проверяться будет значение, которое состоит из восьми бит данных и бита четности.
entity parity_checker is
port (
checked_word : in bit_vector (8 downto 0);
is_correct : out boolean
);
end entity parity_checker;
architecture behavioral of parity_checker is
begin
check : process (checked_word) is
variable checksum : bit;
begin
checksum := '0';
for i in checked_word'range loop
checksum := checksum xor checked_word (i);
end loop;
if checksum = '0' then
is_correct <= true;
else
is_correct <= false;
end if;
end process check;
end architecture behavioral;
В примере, следует обратить внимание на то, что, так как язык VHDL является строго типизированным, неявное преобразование из битового типа в булев недопустимо. Поэтому это преобразование выполнятся явно с использованием условного оператора. Также следует обратить внимание на использование атрибута объекта массива, который позволяет получить диапазон индексов для него.