Типы данных
VHDL имеет 4 класса объектов данных, которые хранят значения определенного типа:
- • Константы. Имеют одно значение данного типа и не могут быть изменены, constant Data_Bus_Width: integer:=16;
- • Переменные. Имеют одно значение и обновляются с помощью присвоения переменной, variable count_temp: unsigned (2 downto 0);
- • Сигналы. Соединяют различные части проекта вместе, signal A: stdjogic;
- • Файлы. Обеспечивают последовательный доступ к файлам. file dataout: text open read_mode is "stordat.txt";
В VHDL объекты данных используются для передачи значений из одной точки в другую. Каждый объект имеет набор возможных значений заданного типа. Константа может хранить одни конкретные данные определенного типа и её значение не может быть изменено после объявления. Переменная может содержать любое значение определенного типа данных и обычно используется для временных значений внутри процесса. Сигнал содержит список текущих и будущих значений, которые будут назначены, когда появятся на сигнале. Файл относится к файловой системе и содержит значений указанного типа, которые считываются или записываются последовательно.
Широкий спектр доступных типов данных обеспечивает гибкость в аппаратном моделировании и встроенной проверке ошибок для обеспечения совместимости сигналов в больших, сложных схемах. Правила типизации должны соблюдаться. Типы данных очень важны в VHDL. Заданные типы данных обеспечивают применение значений только в пределах своих диапазонов. Каждый объект (сигнал, переменная, константа или порт) должен иметь определенный тип, заданный при объявлении. VHDL имеет ограниченное число встроенных типов данных, их количество расширяется библиотеками.
VHDL является строго типизированным языком. Соединительные сигналы должны быть одного типа. Строгая типизация позволяет использовать операторы и функции "перегрузки". Перегрузка будет обсуждаться в разделе функций и процедур. Проще говоря, типы аргументов функций и операторов помогают VHDL выбрать, какую функцию выполнять. Например, оператор "+" определен для целых и вещественных данных. Во время анализа VHDL определяет тип операторов и находит "правильную" функцию для перегруженного оператора, которая имеет целочисленный или вещественный тип данных.
Выражения состоят из операторов и операндов. Объекты данных образуют операнды выражения и их значения используются операторами в VHDL. У<=А+(В-С); - простое выражение с операндами А, В и С и операторами "+" и M<=Y; - может быть также один идентификатор. sig_hold<= func_or(a,b); - или функция.
Литерал - это постоянное значение операнда. А<='1'; - один бит двоичного литерала (bit или std logic). Y<=" 10000100"; - битовый строчный литерал, где Y вектор [7;0]. Используйте двойные кавычка " " для строк. Ch<=’a’; - один символьный литерал. Str<="VHDL class"; - символьный строковый литерал. Int<=35; -целочисленный литерал. State<=IDLE; - перечисляемый литерал. Приведенные выше примеры иллюстрируют безусловное назначение сигнала, где значение правой части с помощью символа присваивания (<=) применяется к объекту левой части. Операторы VHDL могут включать литералы, идентификаторы, выражения, вызовы функций. Значения приведенных выше литералов приведены в простой, безусловной форме присваивания сигнала. Предполагается, что А типа bit или std logic; Y типа bit_vector или std_logic_vector; Ch символьного типа; Str строкового типа; Int целочисленного типа; State определяемого пользователем, перечисляемого типа. Тип данных и ширина должны соответствовать сигналу и назначению портов. Например:
signal A: stdjogic;
signal В: bit;
signal С: stdjogic;
signal D: integer;
signal E: std_Logic_vector(3 downto 0);
signal cntrl: stdjogic_vector (1 downto 0);
signal Q.: stdjogic_vector (3 downto 0);
A <= С; - верно, так как и А и С типа stdjogic.
А <= cntrl(l); - Это выражение берет один бит cntrl (второй справа) и присваивает его А. Так как cntrl является массивом символов типа stdjogic, один элемент из этого массива будет типа stdjogic и следовательно это верное присваивание.
Е <= С+1; строго говоря, ошибка, т.к. С типа stdjogic, а 1 целое число. Существует, тем не менее, часто используемая библиотека (IEEE.STD_LOGIC_UNSIGNED), которая содержит перегрузку функции, которая преобразует std_logic_vector в целое число, выполняет операцию и возвращает stdJogic_vector.
А <= В; А может представлять всю информацию, указанную в В, но т.к. они не совсем равны, это недопустимое присвоение. Простая функция, выполняющая это преобразование, уже существует в библиотеке stdjogic_l 164.
D <= Е; Хотя Е может представлять собой целое число, это просто вектор без смысла. Е должно быть преобразовано в целое число, для того, чтобы присвоить его целому числу.
В <= D; Чтобы выполнить это присваивание, нужна функция преобразования, потому что целое число (с множеством возможных значений) преобразуется в бит. Как должно быть выполнено это преобразование? Только если младший разряд преобразуется в ‘Г или ‘О’, или любое ненулевое значение преобразуется в ‘Г -неоднозначность является явной; следовательно, присвоение является недействительным.
О. <= cntrl; Несмотря на то, что Q и CNTRL оба типа stdjogic_vector, Q 4-битный, a cntrl только 2-битный; поэтому ошибка не в типе, а в размерности.
Стоит также отметить, что D является неограниченным целым числом. Это означает, что инструменты синтеза и моделирования, как правило, устанавливают диапазон целых чисел ±232 бит (технически от -232 до 232 -1). Это минимальная реализация, требуемая языком, однако диапазон может быть больше. В общем, это плохая практика.
Рассмотрим скалярные и составные типы данных. Скалярные типы имеют единственное значение. К ним относятся bit, boolean, stdjogic, integer, real, character, физические данные, перечисляемый тип.
bit - {0,1} - встроенный тип данных, который позднее был вытеснен типом stdjogic. Тип данных bit, как правило, больше не используется для синтеза. Он был заменен, главным образом, типом std_logic. Тип данных bit выполняется быстрее при моделировании, т.к. имеет только два состояния, а не 9. Если вы решите использовать этот тип, убедитесь, что никакое другое состояние, кроме ‘Г и ‘0’ не возникнет при моделировании.
boolean - {false, true} - Логические выражения часто используются при поведенческом моделировании. Тип данных boolean является синтезируемым, однако чаще он используется в испытательных стендах.
std_logic и std_ulogic - {‘О’, ‘Г, ‘L’, ‘Н’, ‘U’, ‘X’, ‘Z’, ‘-‘, ‘W’} -std_logic (и std_logic_vector) являются наиболее употребимыми типами данных для синтеза и моделирования, хотя не все значения std_logic синтезируемы (такие, как ‘L’, ‘Н’ и ‘W’). Std_ulogic был разработан для систем с многозначной логикой (MVL) и обеспечивает более подробное аппаратное моделирование, чем bit. Он поддерживает различные уровни сигнала, условие безразличного состояния (don't-care) и управление 3-мя состояниями. Определен в пакете std_logic_1164. Std_logic является «разрешенной» формой std_ulogic и используется чаще. Тип std_ulogic имеет следующие значения: ‘U’ - uninitialized, без инициализации; ‘X’ - strong drive, unknown logic value, сильный сигнал, неизвестное логическое значение; ‘О’- strong drive, logic zero, сильный сигнал, логический ноль; ‘Г- strong drive, logic one, сильный сигнал, логическая единица; ‘Z’ -high impedance, высокоимпедансное состояние; ‘W’ - weak drive, unknown logic value, слабый сигнал, неизвестное логическое значение; ‘L’ - weak drive, logic zero, слабый сигнал, логический ноль; ‘Н’ -weak drive, logic one, слабый сигнал, логическая единица, ‘-‘ - don't саге, безразличное состояние. Литерал Z используется при моделировании тристабильных логических схем; литералы Н и L позволяют строить логические схемы проводное-И (wire-and) и проводное-ИЛИ (wire-or). Состояние U используется по умолчанию для всех неинициализированных объектов, так что их можно легко обнаруживать при моделировании и при необходимости корректировать.
VHDL не чувствителен к регистру. Хотя это верно, например, для идентификаторов и ключевых слов, типы std_logic и std_ulogic фактически являются перечисляемыми типами, которые должны в точности совпадать. Таким образом, когда используется std_logic/std_ulogic значения (‘Z’, ‘U’, ‘W’,...) всегдадолжны быть заглавными, потому что они определены как перечисляемые типы. Оба типа std_logic и std_ulogic содержат одинаковый набор возможных значений. Разница в реализации. U в Ulogic означает нерешенный. Если необходимо подключить два или более сигнала к общему типу std_logic, можно использовать некоторые формы разрешения функции. Std_ulogic не предполагает такую возможность, но имеет встроенные средства проверки ошибок для случая использования проводного-ИЛИ (wire-or).
signal A,B,C,RES_OUT: stdjogic; signal OUT 1: std.ulogic;
OUT.1 <=A;
A
В
c
OUT 1 <= в. A OUT.1 <= C; A
UT.1 p
RES OUT<=A;
RES OUT<=B;
RES OUT<=C.
RES OUT
Хотя выражение справа разрешается при моделировании с компилятором, использующим разрешающую таблицу в пакете std_logic_l 164, компилятор синтеза для устройств Xilinx не позволяет моделировать проводное-И (wire-and) и проводное-ИЛИ (wire-or), потому что это не поддерживается технологией на уровне чипа.
Данный выход не может иметь несколько драйверов проводного-ИЛИ. Существует несколько методов моделирования буферов с 3 состояниями; один из них с помощью условного присвоения сигнала и типа данных std_logic.
signal А,В,С, RES OUT: stdjogic ;
RES-OUT <= A when ENO = Telse 'Z’< RES.OUT <= В when EN1 = *1’ else Z’; RES_OUT <= C when EN2 = ‘1 ’ else Z’;
Это правило зависит от технологии. В FPGA Xilinx и большинстве устройств, проводное-ИЛИ и проводное-И не разрешается.
Std_logic и, соответственно, std_logic_vector могут быть использованы в логических операциях. Not - инверсия: SI_A<= not sl_B;. Двухвходовая логика (AND, NAND, OR, NOR, XOR, XNOR): SI_C<=sl_A XNOR sl_B;. Сравнение равенства и неравенства: if(sl_A=sl_B) then... if(sl_A/=sl_B) then... Напомним, что stdjogic имеет 9 различных значений потенциала. Сравнение std_logic будет сравнивать положение перечисляемого типа с положением другого элемента перечисляемого типа. Скорее всего, ожидаемый результат не будет реализован, поэтому имеет смысл только для проверки на равенство или неравенство. Битовые сдвиги. SHIFT_LEFT, SHIFTJRIGHT, ROTATE_LEFT, ROTATEJRIGHT (для std_logic_vector). sll, sla, rol, ror (для signed/unsigned).
Математика не может быть выполнена с std_logic/std_logic_ vector. Некоторые библиотеки перегружают основные математические операторы для выполнения математики на std_logic_vector. Как правило, это не рекомендуется. Лучшая практика требует преобразования std_logic_vector в integer или signed/unsigned и выполнение операций в этой области. Std_logic_vector является массивом типа stdjogic. Он будет рассмотрен далее. Сокращения “slv” для std_logic_vector, “si” для stdjogic, и “i” для integer известны как Венская нотация.
Библиотека NUMERICJSTD содержит перегрузки соответствующих функций для поддержки различных сравнений и функций сдвига. Она сама по себе не является частью VHDL. Однако, обычная практика - использовать эту библиотеке, поэтому она и включена в шаблон, генерируемый средой проектирования ISE.
Signed и unsigned являются специальными случаями stdjogic_vector. Они также будут рассмотрены далее.
integer — {natural} - Целые числа наиболее часто связаны с математическими вычислениями (целые числа могут быть использованы для представления вещественных чисел с фиксированной точкой), индексами в массивах и матрицах, значениях цикла. Целые числа могут быть синтезированы и смоделированы, они обеспечивают гибкие и интуитивно понятные величины и значения. Указание диапазона любого целого числа имеет значительное влияние в процессе синтеза. Если диапазон не указан, компилятор по умолчанию берет максимальный диапазон, signal A: integer range 0 to 7; signal В: integer range 15 downto 0;
real - {natural} - Вещественные значения, как правило, используются при моделировании вычислений. Хотя вещественные значения, как правило, не синтезируемы, недавно утвержденная IEEE библиотека поддерживает числа с плавающей точкой одинарной точности. Обратите внимание, что вещественный тип данных используется не так, как целочисленный. Используйте вещественный тип данных для создания собственного типа данных, как показано в примере: type CAPACITY is range -25.0 to 25.0; signal SIG_1: CAPACITY := 3.0.
Для эффективного моделирования, вещественные числа могут быть использованы для масштабирования и смещения физических типов данных, или использованы для чисто математических процессов. Вещественные числа могут быть использованы с физическими константами (такими, как время или напряжение) в средах моделирования, которые поддерживают моделирование смешанного сигнала.
Для целых и вещественных чисел разрешены все формы сравнения: >, <, >=, <=, =, /=, а также основные математические функции (NUMERIC_STD обеспечивает соответствующую поддержку для signed и unsigned): +, -, *, /, mod, rem. Следует помнить, что некоторые из этих операций могут вызвать проблемы во время синтеза, но не во время моделирования.
Signed и unsigned являются специальным случаем bit и std_logic. Типы std_logic_vector и bit_vector только содержат образцы без позиционного смысла. Signed и unsigned добавляют позиционный смысл. Определены данные типы в стандарте целых числовых пакетов: nu-meric_bit, numeric_std. Используйте эти библиотеки вместо устаревших STD_LOGIC_ARITH и STD_LOGIC_UNSIGNED.
Причины использования numeric_std вместо STD_LOGIC_ARITH:
- • Более читаемый код. Использование типа signed/unsigned позволяет использовать cnt<=cnt+l вместо cnt<=cnt+"00001" (в зависимости от размерности ent).
- • Более надежный. Numeric_std не перегружает std_logic_vector. Это позволяет избежать некоторых видов путаницы сравнений (если сравнивать целое число или std logic vector)
- • Функции преобразования улучшенного типа. Функции ясны и однозначны. Используйте приведение типов в случае необходимости.
• Наличие функции для манипуляции, таких как SHIFT_LEFT, SHIFT_RIGHT и RESIZE. Аналогичных функций нет в старых библиотеках Synopsis.
character - {control, numbers, symbols, alpha...} - Синтезируемы и могут быть использованы для обработки символьных данных (таких, как строки) для устройств взаимодействия с человеком. Символьный тип синтезируем. Строки являются массивом символов. Обратите внимание, что большинство символов записывается в одинарных кавычках, type character is (nul, sol, stx, etx, eot, enq, ack, bel,..., 'А', 'В', ‘C, 'D', 'E', 'F', 'G',...);
Физические данные - {time,...} - Физический тип используется для количественной оценки реальных физических понятий и величин, таких как масса, длина и время. Физический тип должен быть определен в терминах своих основных единиц. Любые вторичные единицы должны быть кратны основным. Только тип time естественно поддерживаемый физический тип. type time is range 1 to 1000000 units fs; ps = 1000 fs; ns = 1000 ps; us = 1000 ns; ms= 1000 us; end units. Расширения для других единиц поддерживаются через сторонние или IEEE библиотеки. Не являются синтезируемыми.
Перечисляемые типы - {определяются пользователем} -Предлагает наибольшую гибкость в абстрактном аппаратном моделировании. Определяемые пользователем перечисляемые типы используют значения, которые сразу узнаются и интуитивно относятся к работе модели. Перечисляемые типы синтезируемы и наиболее часто используются в конечных автоматах. Перечисляемый тип подключает инструменты синтеза, которые выбирают наиболее подходящий метод для представления этих значений на аппаратном уровне.
Синтаксис: type
По умолчанию, перечисляемые значения последовательно кодируются слева направо в скобках. В данном примере получим тип MY-STATE со значениями "ООО", "001", "010", "ОН", "100" для RST, LOAD, FETCH, STOR, SHIFT соответственно.
Обратите внимание, что различные инструменты синтеза могут применять различные схемы кодирования на основе конкретной технологии алгоритмов оптимизации или других существенных факторов.
VHDL чувствителен к регистру только при использовании перечисляемого типа, который заключен в одинарные кавычки. Наиболее распространенные примере: std_logic/std_logic_vector.
Рассмотрим пример.
type rx_states is (IDLE, START, DATA, PARITY, STOP);
type tx_states is (IDLE, START, DATA, PARITY, STOP);
signal rx_state: rx_states:= IDLE;
signal tx_state: tx_states:= IDLE;
Несмотря на то, что имена состояний идентичны, присвоение rx_state <= tx_state; является неверным. Даже если имена состояний идентичны, "IDLE" определенный в rx_states не то же самое, что "IDLE" определенный в tx_states. Эти состояния могут быть закодированы по-разному в процессе синтеза, но что более важно, они считаются совершенно разных типов.
Для простоты понимания следует рассматривать список состояний в rx_states как rx_states.lDLE, rx_states.START, и т.д. Кроме того, рассматривать состояния в tx_states как tx_states.lDLE, tx_states.START, и т.д. Теперь становится ясно, что rx_state имеет совершенно отличный набор значений, чем tx_state.
Подтипы улучшают использование определенного ранее типа или подтипа путем ограничения его объема. Основной синтаксис: subtype
С точки зрения хорошего кодирования, это помогает определить конкретные размеры, избегая определенных видов ошибок в расчетах, и таким образом, делая код более надежным.
Далее рассмотрим такой важный вопрос, как преобразование типов. VHDL является строго типизированным языком. По своей природе присвоение одного типа другому является запрещенным. Для выполнения изменения типа требуется механизм преобразования. Наиболее часто используется конвертация между std_logic_vector и integer. Часто используется для индексов массивов и математики с реальными данными.
Преобразование std_logic_vector—>integer. Для начала std_logic_vector сводится к типу signed/unsigned. Этот процесс описывает, как биты будут использованы. Дальше signed или unsigned преобразуется к integer. Integer_value<=to_integer (unsigned (slv_value));
Преобразование Integer—>stdjogicvec tor. Для начала integer сводится к типу signed/unsigned. Длина конечного signed/unsigned должна быть также указана (показана как ‘п’ ниже). Дальше signed или unsigned преобразуется к std_logic_vector. Slv_value<=std_logic_ vector (to_unsigned (integer_value,n));
Рассмотрим следующий пример: std_logic_vector является множеством элементов std_logic. Технически type UNSIGNED is array (NATURAL range <>) of STD_LOGIC, type SIGNED is array (NATURAL range <>) of STD_LOGIC.
Это означает, что signed и unsigned также множество элементов std_logic. Поэтому std_logic_vector и signed/unsigned имеют довольно много общего (кроме того, что signed/unsigned не могут иметь отрицательные индексы). Это позволяет им быть изменяемыми до тех пор, пока std_logic_vector не имеет отрицательных индексов.
Целые числа являются чем-то совершенно иным. Некоторые могут подумать, что целые числа также являются просто набором бит (которым они являются в компьютере), но в VHDL это не так. Целые числа определяются почти как литералы, type INTEGER is range -2147483647 to 2147483647; Это делает невозможным изменение типа, но возможным конвертацию.
Составные типы данных представляют собой группы элементов в виде массива или записи. Bit_vector, std_logic_vector и string являются предопределенными составными типами.
signal A WORD : std_logic_vector (3 downto 0):="0011"; Данная запись создает 4 элемента типа std_logic, сгруппированных вместе в массив. Здесь нет предопределенной интерпретации младшего (LBS) и старшего (MBS) бита, следовательно, это значение не читается компилятором автоматически как 3.
Обратите внимание на использование двойных кавычек ("ООН") для любых bit_vector, std_logic_vector или string объектов и использование одинарных кавычек (Т) для bit, std_logic и character.
VHDL не подразумевает, что самый большой индекс является старшим битом (3 в данном примере). VHDL просто индексирует вектор слева направо. Выбор и использование последовательно одного метода индексации является хорошей практикой, например ‘(3 downto 0)’ или ‘(0 to 3)’. Наиболее популярным является метод ‘(3 downto 0)’, т.к. этот метод похож на схематическое представление шины My_BusA[3:0].
Тем не менее, VHDL делает вывод о старшем и младшем бите для подтипов signed и unsigned. Хотя они и являются специальными версиями std_logic_vector, арифметические подпрограммы, написанные для этих типов, рассматривают и трактуют старший бит как знаковый.
Массив - это группа элементов одного типа. Синтаксис type
^xa mР*е 1: | type WORD is array (0 to 3) ofstdjogic; |
I s/gna/B_BUS : WORD ; I D Q1
I---1 d DUO
0 12 3
index position
Example 2: [ type DATA is array (0 to 3) of integer range 0 to 9; |
| signal B BUS : DATA ; ~
Если B_BUS типа WORD, возможные значения для каждого элемента - ‘U’, ‘X’, ‘О’, ‘Г, Z’, ‘W’, ‘L’, Н’,Таким образом, есть 94 (6561) возможных комбинаций, против 16 в случае типа bit. При объявлении массива целых чисел не забудьте указать диапазон целых чисел, чтобы избежать стандартной (минимум) 32-битной реализации.
При присвоении одного массива другому:
- 1. Массивы должны быть одного типа.
- 2. Массивы должны быть одной длины.
- 3. Присвоение является позиционным, слева направо.
signal BUS.A, BUS_B: stdjogk_vactor (3 downto О) ; signal BUS C : stdjogkyctor (0 to 3) ;
Позиционное присвоение означает, что массивы выстроены так, как они были задекларированы ((3 downto 0) или (0 to 3)). Как показано во втором примере, это вызывает перестановку бит, хотя данные всё еще выровнены слева направо. В этом нет ничего плохого, что биты поменяли свой порядок, это было сделано намеренно, а не как результат случайного изменения порядка индекса. Лучший способ избежать этой проблемы является использование последовательного правила при объявлении массивов.
Обратите внимание, что, как правило, для объявления вектора использует downto, чтобы во время преобразования самый левый бит оказался знаковым. Когда вы определяете массив, наоборот, обычно используется to. Для упрощения задания массива - и для повышения читаемости - вы можете присваивать, используя шестнадцатеричную или восьмеричную системы счисления. Подчеркивания также могут быть использованы для дальнейшего повышения читаемости.
Example 1. Sjgnai DATA WORD : std loglc yector (11 downto 0) ; fl
DATA_WORD <= X"A6F" ;
DATA_WORD <= “101001101111” ;
DATA_WORD <= СГ5157";
DATA_WORD <= B“1010_0110_1111” ;
signal DATA WORD : std logic vector (10 downto 0) ;
Example 2:
----[_
DATA_WORD <= B"100_0110_111Г DATA_WORD <= X"46F”;
ERROR!
Большинство компиляторов разрешает использование подчеркивания для повышения читабельности. XST в программном обеспечении ISE® позволяет использовать подчеркивания при условии, что основание явно определено через шестнадцатеричную, восьмеричную или двоичную записи, как показано здесь.
Обратите внимание, что десятичной системы среди них нет, т.к. она не является степенью двойки, как это необходимо. Если длина вектора не кратна степени двойки, 3 для восьмеричной и 4 для шестнадцатеричной, эти системы не могут быть использованы.
Например, если вектор был 6 downto 0, то единственный способ представить это двоичный или конкатенация одного восьмеричного и одного шестнадцатеричного символа вместе.
Пример 2 показывает, что размер вектора должен быть целым числом, кратным основанию. Для того чтобы использовать шестнадцатеричное основание, длина вектора должна быть кратна 4. Для восьмеричной - кратно 3.
Любую группу смежных элементов в массиве можно присвоить вектору. Остальные элементы не влияют на присвоение. При этом направление (по возрастанию или по убыванию) подмножества должно совпадать с направлением массива. Также полезным является использование ключевого слова "others" в качестве присвоения по умолчанию, независимо от размера вектора.
Signal AVEC, BVEC: std_logic_vector (7 downto 0);
Signal Z_VEC: std_logic_vector (15 downto 0);
signal A_BUT, BBUT, C_BIT, D_BIT: stdjogic;
B_VEC<=Z_VEC(12 downto 5);
A_VEC<=(others=>'0');
A_VEC(1 downto 0)<=C_BIT & D_BIT;
Запись - это группа элементов, которые могут быть разного типа.
type PACKET is record
PARITY: bit;
ADDRESS : std_logic_vector (0 to 3);
DATA_BYTE : std_logic_vector ( 7 downto 0);
NUM VALUE : integer range 0 to 6;
STOP_BITS : bit_vector (1 downto 0);
end record;
signal TX_PACKET, RX_PACKET : PACKET;
|
• • • |
|||||||||||||||
|
PARITY |
•-----ADDRESS--• |
«----- DATA.BYTE ---* |
?— NUM. VALUE |
STOP-BITS |
|||||||||||
TX PACKET
Для доступа к отдельным частям записи используется синтаксис
Кроме того, хотя этот пример показывает использование типов bit и std_logic в одном проекте, это сделано только чтобы продемонстрировать, что различные типа могут быть объединены в одной записи. Использование обоих типов не является хорошей практикой кодирования.
Строка это определяемый пользователем массив символьного типа. Строковые константы должны точно совпадать с размером. Строки и символы могут быть объединены с помощью оператора .
Строки являются очень полезными в процессе моделирования и отладки для отображения определённого пользователем текста, сообщений, предупреждений, ошибок и часто используются с оператором assert, который будет рассмотрен в курсе позднее.
Обратите внимание, что инструмент Xilinx ISim генерирует ошибки, если размер строки и заявленный размер не совпадают.
Удобный способ моделирования структур памяти - создание структуры псевдодвумерного массива. Эффективный массив массивов (или записей). Инструменты синтеза понимают эту конструкцию как способ представления памяти.
type MEM_ARRAY is array (0 to 3) of std logic vector (7 downto 0);
signal MY.MEM : MEM_ARRAY ; 7 6 5 4 3 2 1 0
Для большинства приложений памяти, чтение и запись вектора адреса преобразуется в целое число, ссылаясь на ряд в массиве. Отдельные биты могут быть выбраны из этого ряда.
type MEM.ARRAYis array(0to3) of std logic victor(7downto0);
signal MY.MEM: MEM.ARRAY;
signal R ADDR,W ADDR: std logk vector (1 downto 0);
MY MEM(to_intag»rtunsignad(W ADDR)))<= DATA-IN;
D-OUT <» MY.MEM tto_intagarfunsignod(R_ADDR)));
Настоящие многомерные массивы могут быть построены путем создания определенного пользователем типа требуемого размера.
type MATRIX_A is а г ray( 1 to 3,1 to 16) of stdjogic;
type MATRIX B is array(l to 3,1 to 3,1 to 3) of integer range -1024 to 1023;
Инициализация выполняется таким же образом, как и для записи.
signal MATRIX_3xl6: MATRIX_A:=(others=> (other =>'0'));
signal MATRIX_3x3x3: MATRIX_B:= (oth-ers=>(others=>(others=>0)));
Доступ в любую заданную точку осуществляется с помощью записи:
MATRIX_3xl6 (3,15) <='1';
value <= MATRIX_3x3x3(2,l,3);
Обратите внимание на запись (others=>(others=>'0')). Это «рекурсивная» форма совокупного присвоения. Конечно, проектировщик может выбрать для инициализации отдельные строки и даже отдельные элементы.
Итоги
Теперь вы знаете наиболее используемые типы данных и как создать пользовательский тип, а также как конвертировать между различными типами данных.