
- •Типы vhdl-данных и их интерпретация
- •1 Объявление типов
- •2 Классификация скалярных типов данных
- •3 Целочисленные типы
- •4 Вещественные типы
- •5 Физические типы
- •6 Перечислимые типы
- •7 Подтипы
- •8 Атрибуты
- •9 Массивы
- •10 Многомерные массивы
- •11 Неограниченные массивы
- •12 Атрибуты
- •13 Операции
- •14 Преобразование типов
- •15 Агрегаты
- •16 Строковые литералы
- •17 Записи
- •18 Преобразование типов данных в процессе vhdl-синтеза
- •Перечислимый тип представляется набором шин:
14 Преобразование типов
К объектам массивов разрешено применять операции преобразования типов, с учетом следующих ограничений накладываемых на исходный тип и целевой тип массивов:
типы элементов должны совпадать;
количество измерений должно совпадать;
тип индекса исходного типа массива должен быть преобразуем в тип индекса целевого типа массива.
Возможность преобразования типов массивов особенно важна для таких родственных типов как, например, битовый вектор (bit_vector) и числа со знаком (signed) и без знака (unsigned). Рассмотрим пример реализации бинарного счетчика, который выполняет отсчет на каждом восходящем фронте синхросигнала, если сигнал разрешения находится в высоком уровне.
library ieee;
use ieee.numeric_bit.all;
entity binary_counter is
port (
reset : in bit;
clock : in bit;
enable : in bit;
data_out : buffer bit_vector (7 downto 0)
);
end entity binary_counter;
architecture behavioral of binary_counter is
begin
counting : process (reset, clock) is
begin
if reset = '1' then
data_out <= (others => '0');
elsif clock'event and clock = '1' then
if enable = '1' then
data_out <= bit_vector (unsigned (data_out) + 1);
end if;
end if;
end process counting;
end architecture behavioral;
Использование преобразование типов позволяет избавить клиентов от подробностей работы модуля. В частности, в данном случае, интерфейс модуля построен на обобщенном типе bit_vector, а не на специфичном – unsigned. В то же самое время, реализация модуля основана на применении средств стандартного арифметического пакета.
Следует обратить внимание на то, что вторым аргументов оператора + является целое число (принадлежащее подтипу natural так как используется арифметика без знака), а не битовый массив. Арифметический пакет позволяет использовать в качестве аргумента любой арифметической операции, логической операции, операции сдвига или операции сравнения целое число. При этом другой аргумент должен принадлежать типу signed или unsigned.
15 Агрегаты
При работе с массивами, как и при работе с другими объектами, зачастую необходимо выполнять операции инициализации и назначения. При этом, в качестве правого операнда не всегда может выступать другой массив, например, речь идет об инициализации константного массива или об инициализации при поступлении сигнала сброса.
Для решения этой проблемы язык VHDL позволяет создавать совокупности значений или агрегаты (aggregates):
<агрегат> ::=
(<элемент агрегата> {, <элемент агрегата>}*)
<элемент агрегата> ::=
[<варианты> =>] <выражение>
Синтаксис для задания вариантов в описании агрегата соответствует тому, который был показан при рассмотрении оператора выбора:
Наиболее простая форма агрегата представляет собой перечисление всех входящих в него значений:
type integer_array is array (0 to 15) of integer;
constant fibonacci : integer_array :=
(1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987);
При этом, в случае использования неограниченного типа массива, диапазон индексов может выводиться на основе информации агрегата. Например, показанный пример с числами Фибоначчи можно переписать следующим образом:
type integer_array is array (natural range <>) of integer;
constant fibonacci : integer_array := (
0 | 1 => 1,
2 => 2,
3 => 3,
4 => 5,
5 => 8,
6 => 13,
7 => 21,
8 => 34,
9 => 55,
10 => 89);
В этом случае диапазон для объекта fibonacci индексов будет от нуля до десяти (то есть, например, верно следующее: fibonacci'left = 0 and fibonacci'right = 10).
Если агрегат для объекта массива
неограниченного типа сформирован
позиционно, то диапазон индексов будет
следующим:
.
Также широко распространены варианты агрегатов, которые состоят из одинаковых значений. Такие агрегаты часто используются для инициализации при поступлении сигнала сброса. Следующая модель восьмиразрядного синхронного регистра, который поддерживает возможность асинхронного сброса, показывает использование такого агрегата.
entity reg is
port (
reset : in bit;
clock : in bit;
data_in : in bit_vector (7 downto 0);
data_out : out bit_vector (7 downto 0)
);
end entity reg;
architecture behavioral of reg is
begin
process (reset, clock) is
begin
if reset = '1' then
data_out <= (others => '0');
elsif clock'event and clock = '1' then
data_out <= data_in;
end if;
end process;
end architecture behavioral;
В некоторых случаях могут потребоваться и более сложные агрегаты. Например, для выполнения сортировки может понадобиться представление наибольшего положительного целого число в битовой форме. Причем, если речь идет об обобщенном описании, то такое представление не должно зависеть от разрядности данных. Для решения этой задачи можно использовать следующий агрегат, построение которого выполняется на основе информации об объекте массиве, получаемой через его атрибуты (предполагается, что знаковым является старший бит):
max_value <= (max_value'high => '0', others => '1');
Агрегат может использоваться и слева от оператора назначения. В таком случае тип определяется на основании выражения в правой части оператора назначения.