Действительно ли нам нужен VHDL

       

Конструкции VHDL для Описания Поведения Системы


Действительно ли нам нужен VHDL? Представление Системы в VHDL: Единицы Проекта Объекты VHDL:Сигнал Спецификация Интерфейса Системы Конструкции VHDL для Описания Поведения Системы Описание Поведения при помощи Процессов Многократные Процессы в Архитектуре Определение Структуры Системы Испытание Проекта при помощи Испытательного стенда

Глава 5

Конструкции VHDL для Описания Поведения Системы

Содержание Главы 5

5.1. Краткий обзор Главы

Не-логические Типы данных

5.2.1. Введение к Типам данных



5.2.2. Скалярные Типы

5.2.3. Определяемые пользователем Типы Перечисления

5.2.4. Физические Типы

5.2.5. Предопределенные Массивы

5.2.6. Массивы определяемые пользователем

5.2.7. Записи

Выражения и Операторы

5.3.1. Введение

5.3.2. Логические операторы

5.3.3. Числовые Операторы

5.3.4. Операторы отношений

5.3.5. Операторы сдвига

5.3.6. Оператор Конкатенаци

Простое Назначение Сигнала

5.4.1. Присваивание Выражений Сигналам

5.4.2. Присвоение Может Быть Задержано

5.4.3. Инерционная Задержка

5.4.4. Транспортная Задержка

5.4.5. Инерционная Задержка против Транспортной

Константы

5.5.1. Объявление Констант

5.5.2. Использование Констант

5.5.3. Константы против. Generics

Резюме

5.1. Краткий обзор Главы

После описания таких ключевых понятий в устройствах на VHDL как сущность и архитектура пришло время описать основные VHDL конструкции, который будут использоваться в определении архитектуры.

В Секции 2 рассмотрены основные типы VHDL. Два логических типа (bit и bit_vector) были уже представлены, но некоторые проектировщики помимо этих используют и другие типы. Эти типы могут группироваться как scalar (скалярные) типы, enumeration (перечисляемые) типы, physical (физические) типы (которые являются частными случаями скалярных типов) и complex (комплексные) типы (arrays (массивы) и records (записи)). Кроме них, VHDL допускает использование еще двух типов: files (файлы) и acctss (доступ). Так как эти типы используются менее часто, они будут опущены здесь. См. Руководство по применению для подробной информации относительно них.


Подразделе 3 представлены конструкции для изменения значений входного сигнала: выражения и операторы, которые используются в выражениях. Аналогично, операторы могут группироваться согласно функциям, которые они выполняют, и эта Секция организована вокруг такой классификации.

Когда новое значение вычислено, оно должно быть назначено выходному или промежуточному сигналу. Назначения сигнала может роисходить разными путями. Одни из них, приведенные в секции 4, описывают задержки, которые имеют важное значение при моделировании реальных систем.

В заключение, Секция 5 вводит constant (константы). Эти объекты играют роль подобную generics, но объявляются и используются немного разными способами.

5.2.1. Введение к Типам данных

Ключевые вопросы:

Каждая единица информации внутри компьютера или другой цифровой системы записывается в форме битов (bit) и разрядных векторов (bit_vector). Однако, часто неудобно использовать эту форму. Так как одна буква представлена 8 битами, и каждое обращение к памяти PC требует, по крайней мере, 20 битов для определения адреса, то более проще использовать некоторые цифры или шестнадцатеричные числа вместо битов.

Точно так же много комплексных но регулярных структур данных могут быть представлены массивами и физическими параметрами. Так образом это - типичные приложения. Поэтому VHDL поддерживает все эти структуры и параметры, и объекты VHDL могут быть объявлены так что они будут являться одним из этих типов.

Примеры:



Рисунок:

5.2.2. Скалярные Типы

Ключевые вопросы:

Scalar (скалярный) тип - обобщенное имя, которое присваивается всем типам, чьи объекты имеют единственное значение в любой момент времени. Скалярные типы не имеют никаких элементов или внутренней структуры. Все значения скалярного типа упорядоченные и значения определены или как попадающие внутрь диапазона или явно перечисленные (внесенный в список).

VHDL определяет отдельные скалярные типы. Однако, Вы можете определять ваши специфичные собственные типы, чаще на основании диапазона или как перечисляемые.


Обычно, такой определяемый пользователем скалярный тип объявлен как подтип типа, определенного ранее, или как стандартная модель или другой определяемый пользователем тип.

Рисунок:

constant N : positive := 4;

type Byte is range 255 downto 0;

type Voltage_Level is range 0 to 5;

type Int_64K is range -65536 to 65535;

type Word_Index is range 31 downto 0;

type MUX_ADDRESS is range (2**(N+1))-1 downto 0;

Рисунок:

5.2.3. Определяемые пользователем Типы Перечисления

Ключевые вопросы:

Проектировщики часто должны кодировать некоторую информацию системы очень эффективно или с учетом ее удобочитаемости. Классический пример - конечный автомат (FSM) представляющий последовательное проектирование. Для целей синтеза, каждое состояние FSM кодируется при помощи переменной состояния (триггером), которая хранят информацию относительно фактического состояния. Однако, на уровне спецификаций намного более удобно приписать уникальное имя к каждому состоянию, а затем обращаться к этому состоянию через имя. Для этого в декларации нового типа enumeration все имена состояний переписаны (перечисленны).

Примечание: Значения в декларации типа (имена состояний) определены " поскольку они - ", без любых апострофов или двойных кавычек.

Примеры:

Чтобы лучше пояснить декларацию типа enumeration, рассмотрим их синтаксис на примере:

-- Syntax:

-- type type_name is (type_element, type_element, …);

-- Примеры:

type NotGood is (X,'0','1',X); -- illegal

type MyBit is (L,H);

type Test is (’0’,’1’,L,H);

type FSM_States is (Init,Read,Decode,Execute,Write);

Рисунок:

5.2.4. Физические Типы

Ключевые вопросы:

Physical (физические) типы уникальны в VHDL, потому что они определяют не только значения объекта но также и единицы, в которых значения выражены. Это допускает такие физические величины как время, расстояние, поток, температура, и т.д., определять с нужной точностью. Стандарт VHDL определяет только один физический тип - время, однако другие типы могут быть определены по желанию.


Один из примеров как это сделать показан справа

Имеются два вида единиц в физических декларациях типа: первичные единицы и вторичные единицы, которые определяется в терминах первичных единиц. Заметьте, что диапазон, указанный в заголовке декларации типа ссылается только на первичные единицы.

Несмотря на их наглядность и привлекательность, (physical) физические типы - не синтезируются хорошо (not synthesizeable).

Примеры:

type Capacity is range 0 to 1E9

units

pF; -- picofarad

nF = 1000 pF; -- nanofarad

uF = 1000 nF; -- microfarad

mF = 1000 uF; -- milifarad

F = 1000 mF; -- farad

end units Capacity;

type Distance is range 0 to 1E9

units

um; -- micrometer

mm = 1000 um; -- millimeter

inch = 25400 um; -- inch

end units Distance;

Рисунок:

5.2.5. Предопределенные Массивы

Ключевые вопросы:

Массивы - составной тип с регулярной структурой, состоящий из элементов того же самого типа. Число элементов в массиве определяется диапазоном массива. Диапазон может быть неограничен или ограничен, “поддерживая” левую связанную или правую границу и направление следования индексов между ними (способ, которым это обеспечивается рассмотрен в Главе 3 для разрядных векторов). Неограниченный диапазон определен как:

range <>

Имеется два (2) предопределенных VHDL массива - bit_vector (с элементами типа bit) и string (строка) (имеющий элементы типа character"символ"). Оба они объявлены с неограниченным диапазоном. Конечно, они отличаются способ, которым они определяют нижнюю границу: первый элемент bit_vector индексирован как 0, а string начинается с 1.

Заметьте: простой элемент этих массивов определен в одинарных кавычках , но два или больше элемента, называемых кристаллом (slice), беруться в двойные кавычки.

Примеры:

type bit_vector is array (natural range <>) of bit;

type string is array (positive range <>) of character;

-- Примеры:

signal DataBus : bit_vector(7 downto 0) := "01010101";

signal AddressBus : bit_vector (0 to 15);

signal ChipSelect : bit := '1';



constant Message1 : string(1 to 20) := "hold time violation";

signal Letter1 : character;

signal Message2 : string(1 to 10);

Рисунок:

5.2.6. Массивы определяемые пользователем

Ключевые вопросы:

Так как предопределенные массивы одномерны, они иногда названы векторами. Все элементы этих массивов указаны в одном измерении. Пользователь, однако, может объявлять массив, имеющий произвольное число измерений, хотя больше чем три измерения делают массив не читаемым.

Типичный пример двухмерного массива - запоминающее устройство, которое может рассматриваться как двухмерный массив битов. В настоящей памяти биты обычно группируются в слова. Это практически делает их “вектором векторов” – каждый элемент вектора в свою очередь является вектором. Отдельные примеры типов памяти определены на рисунке справа

Примеры:

type Real_Matrix1 is array (1 to 10) of real;

type X is (LOW, HIGH);

type Byte is range 0 to 7;

type DATA_BUS is array (Byte, X) of bit;

-- unconstrained array of element of real type

type Real_Matrix2 is array (positive range <>) of real;

signal Real_Matrix_Object : Real_Matrix2 (1 to 8);

Рисунок:

5.2.7. Записи

Ключевые вопросы:

Записи, как одноименные массивы, принадлежат к составным типам. Однако они имеют два различия: элементы записи могут иметь различные типы, и они обозначаются именами вместо индексов. Ссылка на элемент записи имеет следующий вид

:

record_name.element_name

Эти имена всегда написаны без круглых скобок.

Первичнаеназначение записей состоит в том, что они должна группировать вместе различные параметры отдельных объектов. Каждый такой объект обозначается отдельным именем, которое делает код более компактным и читаемым.

Не каждая запись может быть синтезирована, но большинство синтезаторов способно справиться с записями состоящими из типов bit, bit_vector, boolean и integer.

Примеры:

Сравните предложенный общий синтаксис и декларацию записи. Пример - немного изменен и взят из обучающей программы.

-- Syntax:

-- type record_type_name is record



-- element_name : element type;

-- element_name : element type;

. . .

-- end record record_type_name;

type RegisterName is (AX, BX, CX, DX);

type Operation is record

Mnemonic : string;

OpCode : bit_vector(3 downto 0);

Op1, Op2, Res : RegisterName;

end record;

signal Instr1, Instr2, Instr3 : Operation;

. . .

Instr1 <= ("ADD AX, BX", "0001", AX, BX, AX);

Instr2 <= ("ADD BX, BX", "0010", others => BX);

Instr3.Mnemonic <= "MUL AX, BX";

Instr3.Op1 <= AX;

Рисунок:

5.3.1. Введение

Ключевые вопросы:

Кроме очень тривиальных систем, входные сигналы должны всегда преобразовываться для того чтобы некоторым способам генерировать желательные выходные сигналы. Этот процесс можно наглядно себе представить как

outputs <- transformations(inputs)

Преобразования осуществляются при помощи выражений на основе формул которые состоят из операторов с соответствующем числом операндов. Фактически, любая спецификация поведения системы может быть определена как упорядоченный набор выражений приписываемый выходным сигналам входные. Эта секция разъясняет, как создаются выражения. Порядок назначений сигналов будет обсужден в последующих двух главах.

Основной элемент каждого выражения - оператор. Каждому оператору назначен некоторый определенный тип (или типы) и для него требуется один или два операнда, которые являются объектами над которыми производятся действия. Запрещено использовать оператор или операнд тип которых не поддерживается, но пользователь может определять новое значение для существующего оператора для других типов. Это выполнено через так называемую перегрузку оператора - см., руководство по применению для детального знакомства с этим.

Примеры:

Выражения определяют способ, которым новое значение вычисляются. Они состоят из операндов и операторов. Например, выражение " 1 + 2 " прибавляет два целых числа. Числа - операнды, и знак "плюс" - предопределенный оператор добавления.


Каждый операнд имеет значение и тип, а тип выражения зависит от типов операндов и действий. Порядок, в котором выполняются действия , зависят от приоритетов, принятых в языке. Ниже приведенная таблица, группирует список операторов согласно уровню приоритетов, самый высокий приоритет вначале списка.

Смешанные операторы ** | abs | not

Мультипликативные операторы * | / | mod | rem

Операторы знака + | -

Операторы сложения + | - | &

Операторы сдвига sll | srl | sla | sra | rol | ror

Реляционные операторы = | \= | < | <= | > | >=

Логические операторы and | or | nand | nor | xor | xnor

Рисунок:

5.3.2. Логические операторы

Ключевые вопросы:

Так как цифровые сигналы системы - обычно логические сигналы,, наиболее часто используемый класс операторов VHDL - логические операторы. Логические операторы делают такие действия с двумя операндами как and, or, nand, nor, xor и xnor. Оператор not - действие с одним операндом. Логические действия определены для типов: bit, boolean, and bit_vector, Это означает, что оба операнда должны состоять из тех типов. Результат имеет всегда тот же самый тип что и операнды.

В случае разрядных векторов логические операторы выполняются на индивидуальных битах, то есть крайний левый бит вектора результата вычислен на крайнем левом бите операндов, второй бит - на втором бите операндов, и т.д. Это правило ведет к очевидному заключению, что операнды и результирующий вектор должны иметь ту же самую длину.

Примеры:

Пусть выражение построено так , что используются and, or, xor или xnor Более того эти логические операторы могут содержать любую последовательность действий. Тогда, если nand или nor действия использующиеся в выражениях, то они могут содержать только одно действие этого типа. Если необходимо большее количество таких действий, то круглые скобки должны использоваться.

signal A, B, C, D : bit;

-- И-НЕТ оператор появляется только если :

C <= A nand B;

--Многоуровневая операция моделированная И-НЕТ, с

круглыми скобками:



A <= ( D nand B) nand C;

-- Операторы И, Или могут использоваться больше чем один раз в одном выражении:

A <= '1' and B and C or D;

A <= '1' and (B and (C or D));

Рисунок:

5.3.3. Числовые Операторы

Ключевые вопросы:

Оператор это общее название объектов, делающим действия над числовыми операндами. Они включают в себя сложение, вычитание, умножение, деление, модуль, взятие остатка, возведение в степень, и абсолютную величину. Эти действия могут быть сделаны, как над целыми числами так и над действительными типами, но требовать, чтобы оба операнда были того же самого типа. Единственное исключение из этого правила - возведение в степень, где второй операнд – всегда целое число.

Типы обоих операндов должны быть согласованы. Это требование настолько строго, что даже в случае так называемых универсальных целых чисел (значение целого числа, указанно явно) эти типы не могут использоваться с действительными числами.

Кроме целого числа и реальных типов время также может использоваться с числовыми операторами. В этом случае, правила не так строги: сложение и вычитание требует, чтобы оба операнда были типа времени, но переменная времени может быть умножена на целые числа или действительные числа либо разделена на целое число. В каждом случае результат имеет тип времени.

Примеры:

Ниже приведенные примеры переводят объект типа bit_vector в целое число и наоборот. Обратите внимание на то, как арифметические операторы используются здесь.

. . .

signal Input : bit_vector (0 to size-1);

signal Output : integer :=0;

signal Power : integer :=1;

. . .

if Input'length = 0 then Output := 0;

end if;

for I in Input'reverse_range loop

if Input(I) = '1' then Output <= Output + Power;

end if;

Power <= Power * 2;

end loop;

. . .

signal vector : bit_vector (0 to size-1);

signal tmp_int : integer := value;

. . .

for I in size-1 downto 0 loop

if tmp_int mod 2 = 1

then vector(I) <= '1';

else vector(I) <= '0';

end if;

tmp_int <= tmp_int / 2;

end loop;

Рисунок:



5.3.4. Операторы отношений

Ключевые вопросы:

Всякий раз, когда два объекта сраваются, используются операторы отношений. Они охватывают все виды сравнений: равный, не равный, меньше чем, меньше чем или равный, больший чем, больший чем или равный. Сравниваемые объекты должны быть того же самого типа и могут быть булевы, битовые, строковые, целые числа, действительные числа, времени, литерные или bit_vector. Однако, результат всегда булев, что означает, что выражение является или истинным или ложным.

Можно отметить, что, когда два разрядных вектора сравниваются, они могут быть разной длины. Вместо того, чтобы прибавлять конечные нули к более короткому операнду, оба операнда должны быть выравнены. В случае VHDL реализации это ведет к тому что 1011 будет меньшим чем 110. Совершенно неожиданный факт, не так ли?

Примеры:

Предложенные примеры показывают то, какие результаты будут получены в VHDL при моделировании устройства для заданных величин и операторов.

signal S1: REAL := 100.0;

signal S2 : bit_vector (0 to 7) := ('0','0','0','0','0','0','0','0');

signal S3, S4 : bit_vector (1 downto 0);

S1 /= 342.54 -- True

S1 = 100.0 -- True

S2 /= ('1','0','0','0','0','0','0','0') – True

S3 = S4 -- True

S1 > 42.54 -- True

S1 >= 100.0 -- True

S2 < ('1','0','0','0','0','0','0','0') -- True

S3 <= S2 -- True

Рисунок:

5.3.5. Операторы сдвига

Ключевые вопросы:

Как видно из имени оператора сам оператор предполагает, сдвиг элементов одномерных массивов. Этот класс операций ограничен массивам, у которых элементы типа бит или булевы.

Операторы сдвига требуют двух операндов. Левый представляет массив, а правый является целым числом, которое определит число место положения в массиве, на которое будет смещен его элемент. При этом стоит отметит, что, если значение второго операнда отрицательная величина, то направление смещения реверсивно, т.е. sll -n эквивалентен к srl n (левый сдвиг -n – такое же как право смещения на n разрядов), аналогично, ror -n делает то же самое действие что и rol n, и т.д.



В случае операций логического сдвига значение элемента вставляется в крайний левый (в случае srl) или младший разряда (для sll) вектора, т.е. положение формально определено как первый разряд типа элемента. По этой причине, первое значение для типа bit будет '0', а для типа boolean - 'ложь'.

Примеры:

Комментарии в каждой строке содержат результаты каждого действия сдвига, сделанного на сигнале S5. Отметим эквивалентность некоторых операторов, если используются реверсивные операнды.

signal S5 : bit_vector (0 to 3) := ('1','0','1','1');

S5 sll 1 -- ('0','1','1','0')

S5 sll 3 -- ('1','0','0','0')

S5 sll -3 -- S5 srl 3

S5 srl 1 -- ('0','1','0','1')

S5 srl 3 -- ('0','0','0','1')

S5 srl -3 -- S5 sll 3

S5 sla 1 -- ('0','1','1','1')

S5 sla 3 -- ('1','1','1','1')

S5 sla -3 -- S5 sra 3

S5 sra 1 -- ('1','1','0','1')

S5 sra 3 -- ('1','1','1','1')

S5 sra -3 -- S5 sla 3

S5 rol 1 -- ('0','1','1','1')

S5 rol 3 -- ('1','1','0','1')

S5 rol -3 -- S5 ror 3

S5 ror 1 -- ('1','1','0','1')

S5 ror 3 -- ('0','1','1','1')

S5 ror -3 -- S5 rol 3

Рисунок:

5.3.6. Оператор Конкатенаци

Ключевые вопросы:

Сцепление - удобный способ создания новых значений массивов любого типа. Это действие предопределено для одномерных массивов.

Действие конкатенаця соединяет два операнда, которые вместе используют оператор конкатенаци. Это приводит к массиву, в котором длина является суммой длин обоих операндов. Последовательность элементов массива сохранена, то есть результирующий массив имеет значения левых элементов операнда с лева и значение правых - с права.

Сцепление не ограничено только операндами массива – вполне законно конкатенировать два массива или отдельные значения (отдельные биты) если тип отдельных значений и типа элементов массива (2-ой операнд) сопоставими.

Примеры:

В действии конкатенация могут быть следующие ситуации:

  • Когда оба операнда - одномерные массивы того же самого типа, конкатенация соединяет два массива в один. Направление расположения элементов нового массива – такое же как направление в массиве левого операнда:
  • constant B1: bit_vector := "0000"; -- four element array



    constant B2: bit_vector := "1111"; -- four element array

    constant B3: bit_vector := B1 & B2;-- eight element array,

    -- ascending direction, value "00001111"

    subtype BIT_VECTOR_TAB is bit_vector (1 downto 0);

    constant B4: BIT_VECTOR_TAB := "01";

    constant B5: bit_vector:= B4 & B2; -- six element array,

    -- descending direction, value "011111"

  • Когда один из операндов - одномерный массив, а второй операнд - скаляр того же самого типа как и элементы исходного массива, то результат конкатенации – такой же как в первом пункте:
  • constant B6 : bit := '0' ;

    constant B7 : bit_vector := B2 & B6;-- five element array,

    -- ascending direction, value "11110"

  • В случае, если оба операнда имеют тот же самый скалярный тип, то результат конкатенации - одномерный массив с элементами того же самого типа как операнд:
  • constant B8: bit := '1';

    constant B9: bit_vector := B6 & B8; -- two element array,

    -- ascending direction value "01"

    Рисунок:

    5.4.1. Присваивание Выражений Сигналам

    Ключевые вопросы:

    Окончательная цель каждой электронной системы состоит в том, чтобы сгенерировать желательную реакцию (выходные сигналы) по входным сигналам. Обычно, это требует некоторых действий с их значениями. Как такие действия могут быть определены в VHDL, показано в предыдущей секции.

    В конечном счете, результаты действий должны быть присвоен выходным сигналам. Механизм присвоения прост: целевой сигнал указывается слева. Это сопровождается символом присвоения сигнала (< = ) и в заключение определяется. выражение присвоения Результат выражения будет передаваться целевому сигналу, внесенному в список слева. Чтобы лучше запоминать символ присвоения, его обозначили похожим на стрелку, которая обозначает поток информации.

    Заметьте: символ присвоения сигнала всегда направлен справа налево (< = ) Противоположный символ (= > ) также используется в VHDL, но он имеет другое значение. Оба символа < = и = > могут использоваться как операторы отношений.


    Их интерпретация зависит от контекста.

    Примеры:

    Даже без того, чтобы много знать относительно VHDL, совершенно просто определить поведение простого комбинаторного счетчика. Заметьте присвоение сделано выходнму сигналу.



    entity MyFirstCircuit is

    port (A, B, C, D : in bit;

    Y : out bit);

    end entity MyFirstCircuit;

    architecture MyFirstCircuit_Arch of MyFirstCircuit is

    begin

    Y <= (A and B) or (C and D); -- Classical assignment

    -- of a logical operation

    end architecture MyFirstCircuit_Arch;

    Рисунок:

    5.4.2. Присвоение Может Быть Задержано

    Ключевые вопросы:

    Ничто не случается немедленно в реальном мире. Результаты в любой системе появляются один за другим в течении определенного времени. Такое поведение в VHDL моделируется присваиванием с after, которое может быть добавлено к любому утверждению, которое присваивает сигнал.

    Присваивание с after определяет количество времени, которое должно пройти прежде, чем присвоение становиться эффективным.

    Примечание: значение ‘0’ после присваивания в примере из предыдущей страницы означает ' никакакой задержки нет'.

    Примеры:

    Применение к примеру из предыдущей страницы after после присваивания, приведет к более реалистичному поведению счетчика.

    entity MyFirstCircuit is

    port (A, B, C, D : in bit;

    Y1 : out bit);

    end entity MyFirstCircuit;

    architecture MyFirstCircuit_Arch2 of MyFirstCircuit is

    begin

    Y1 <= (A and B) or (C and D) after 10 ns;

    end architecture MyFirstCircuit_Arch2;

    Этим способом, все изменения значения Y1 будут происходить на 10 ns позже чем тактовые Y:

    Рисунок:

    5.4.3. Инерционная Задержка

    Ключевые вопросы:

    Когда произошла отсрочка реакции системы , возникает важный вопрос : как быстро входные изменения приведут к изменению выхода? Интуитивно понятно,что ответ, “ это не имеет значение неправильный, потому что как пользователь Windows Вы знаете, что два последовательных щелчка мыши - только два отдельных щелчка, когда пауза между ними - достаточно велика, но они становятся двойным щелчком ( когда Вы щелкнете достаточно быстро.



    Точно так же, если светодиод переключается очень быстро это будет казаться, как непрерывный свет. Такая характеристика светодиода называется инерцией и моделируется в VHDL инерционной задержкой.

    Инерционная задержка типична для большинства систем реальной жизни и из-за этого, она определяется моделью задержки в VHDL. Присвоение с after автоматически определяет инерционную задержку. Характерным элементом этой модели – является то, что два последующих изменения входа, будут игнорироваться, если время между ними более короткое чем указанная задержка.

    Примеры:

    Присвоение с after применилось в предыдущем примере, чтобы определить время распространения сигнала в цепи. Давайте использовать это снова, для моделирования времени реальной схемы AND. Заметьте что может произойти в случается когда вход изменяется быстрее чем задержка распространения сигнала:

    architecture MyFirstGate_Arch1 of MyFirstGate is

    begin

    Output <= InputA nand InputB after 20 ns; -- propagation

    -- time of and gate

    end architecture MyFirstGate_Arch1;

    Рисунок

    Рисунок:

    5.4.4. Транспортная Задержка

    Ключевые вопросы:

    Инерционная задержка типична для большинства электронных объектов, но не для всех. Рассмотрим например линию электропередачи, по которой распространяется импульсы с независимой шириной. Так как никакая инерция не может происходить, то использование инерционной модели задержки был бы шаг к неправильному моделированию линий электропередачи.

    При оценке поведения линии электропередачи требуется новая модель задержки. Так как эта модель применяется к транспортировке сигналов без любых изменений, то она была названа, транспортная задержка модели. Чтобы отличить ее от определенной ранее инерционной модели, ключевое слово transport предшествует спецификации значения и задержки.

    Примеры:

    Транспортный способ задержки, который вводиться с помощью ключевого слова transport, изменяет поведение моделируемой цепи . Ниже приведенные диаграммы времени показывают то, что случается с AND из предыдущего примера, если AND имеет транспортную задержку вместо инерционной.


    Форма сигнала входа - точно таже самая:

    architecture MyFirstGate_Arch2 of MyFirstGate is

    begin

    Output <= transport InputA nand InputB after 20 ns;

    end architecture MyFirstGate_Arch2;

    Рисунок:

    5.4.5. Инерционная Задержка против Транспортной

    Ключевые вопросы:

    Инерционные и транспортные модели задержки достаточны для описания любой физической системы в VHDL. Их главные подобия и различия следующие:

  • Инерционная задержка - задержка по определению в VHDL и не требует никаких дополнительных деклараций. Однако, транспортная задержка требует, чтобы использовалось ключевое слово transport;
  • Инерционная задержка не распространяет импульсы более короткие чем декларированная задержка; транспортная задержка распространяет все изменения входного сигнала, независимо от того, как быстро или как часто они могут появляться;
  • Инерционные и транспортные задержки определяются при использовании after с указанием нормы времени;
  • Обе модели задержки могут применяться к сигналам любого типа.

    Примеры:

    Позвольте нам сравнить две модели задержки. Предложенная диаграмма содержит, и инерционную модель (MyFirstGate_Arch1), и транспортную модель (MyFirstGate_Arch2). Результаты следующие:

    Рисунок:

    5.5.1. Объявление Констант

    Ключевые вопросы:

    Константы играют ту же самую роль что и generics: они поддерживают статическую информацию, которая может использоваться внутри модели. Однако, в отличие от generics, которые объявлены в объектах, константы, объявляются внутри архитектуры.

    Декларация констант состоит из следующих элементов:

  • Ключевое слово constant;
  • Имя константы (идентификатор константы);
  • Двоеточие;
  • Индикация типа для константы;
  • Значение константы указанное после символа ': = ';
  • Точка с запятой, завершающая строку.
  • Если две или больше констант имеют тот же самый тип и имеют то же самое значение, они могут быть определены в одной декларации.

    В некоторых частных случаях назначение постоянного значения может быть отсрочено. Пожалуйста обратитесь К руководству по применению для подробной информации относительно не синтезируемых, конструкций.

    Примеры:



    type WeekDay is (Mon,Tue,Wed,Thu,Fri,Sat,Sun);

    constant StartDay : WeekDay := Sat;

    constant LogicalGND : bit := '0';

    constant BusWidth, QueueLength : integer := 16;

    constant CLKPeriod : Time := 15 ns;

    constant MaxSimTime : Time := 200 * CLKPeriod;

    type NumericCodeType is array ( 7 downto 0) of integer range 0 to 9;

    constant EntryCode : NumericCodeType := (2,6,4,8,0,0,1,3);

    constant DataBusReset: std_logic_vector(7 downto 0) := "00000000";

    Рисунок:

    5.5.2. Использование Констант

    Ключевые вопросы:

    Главная цель использования констант состоит в том, чтобы применить " четкие имена " с явно определенными типами вместо литеральных значений, которые названы "жестко закодированными". При таком способе, код становится более читаемым и проще его хранить, потому что замена константы в одном месте будет влиять на все образцы в полной архитектуре.

    Если жестко закодированные значения использовались, пользователь должен будет тщательно проверить полную спецификацию " строка в строку " чтобы удостовериться, что все значения исправлены.

    Вообще константы используются тем же самым способ как generics. Специально, они используются для:

  • Определения размера комплексных объектов (одномерных массивов или шин);
  • Управления циклом;
  • Определения временных параметров: задержки, времени подготовки к работе, временной задержки, времени переключения, и т.д.
  • Так как константы объявлены в архитектуре, они не могут использоваться, чтобы определить размер векторов, объявленных как порты в объектах (см. примеры на generics на странице 4.4.3). Это - главная причина, почему этот случай не рассматривается в примерах справа Однако это ограничение, , может быть преодолено, если константа объявлена в блоке, используемом сущностью.

    Примеры:

    Ниже приведенный пример показывает, как использовать константы.

    entity Mux2to1 is

    port (I0, I1, SEL : in bit;

    Y : out bit);

    end entity Mux2to1;

    architecture Mux2to1_Arch of Mux2to1 is

    constant tp : time := 10 ns;



    begin

    Y <= (I0 and SEL) or (I1 and not(SEL)) after tp;

    end architecture Mux2to1_Arch;

    entity CPU IS

    port(Input_CPU : in bit_vector (31 downto 0);

    Output_CPU : out bit_vector (31 downto 0));

    end entity CPU;

    architecture CPU_Arch of CPU is

    constant Width : integer := 7;

    constant Depth : integer := 15;

    signal IntAddr : bit_vector (Depth downto 0);

    signal IntData : bit_vector (Width downto 0);

    begin

    . . .

    end architecture CPU_Arch;

    Рисунок:

    5.5.3. Константы против. Generics

    Ключевые вопросы:

    Многие впервые столкнувшись с VHDL задаются вопросом, почему язык содержит два такие конструкции как generics и constants. Нужны ли в действительности обе из них?

    Основное различие между generics и constants состоит в том, что generics может использоваться динамически, в то время как constants совершенно статические. Это означает, что Вы можете изменять значение generics без никаких изменений в коде. Однако, константы не могут быть изменены без того, чтобы изменился код. Это важно особенно в случае, когда спецификация будет использоваться как компонент для спецификации с более высоким уровнем. Каждый раз как такой компонент используется, мы может назначать новые значения, если они определены generics.

    Как обсуждено в Главе 2, та же самая сущность может быть разделена отдельной архитектурой, однако generics обращаются ко всей архитектуре сущности. Так как то же самое обобщенное имя может использоваться в различных архитектурах, то любое изменение значения влияло бы на все компоненты во всех архитектурах. Если вместо этого используются константы, то они локализуют все изменения только к выбранной архитектуре.

    Примеры:

    Видимость констант зависит от места их декларации:

  • Константы, определенные в блоке могут использоваться отдельными устройствами проекта:
  • Package Timing is

    Constant Reset : std_logic;

    end package Timing;

    package body Timing is

    constant Reset: std_logic := '0';

    end package body Timing;

  • Описание константы в сущности проекта доступно всем утверждениям внутри архитектуры этой сущности:
  • entity Mux2to1 is



    port (I0, I1, SEL : in bit;

    Y : out bit);

    constant NumberOfIteration : positive := 5;

    begin

    end entity Mux2to1;

  • Константы, определенные в разделе описаний устройства в проекте доступны во всех блоках, внутри этого проекта, включая процесс:
  • architecture DFF_Arch of DFF is

    constant t_setup : time := 10 ns;

    constant t_hold : time := 1 ns;

    constant t_propagation : time := 15 ns;

    begin

    end architecture DFF_Arch;

    Рисунок:

    Резюме

    1. Каждый объект в VHDL должен иметь некоторый тип. Этот тип определяет возможные операции и значения, которые могут принадлежать этому типу.
    2. Язык VHDL это язык со строгим контролем типов, что означает, что две лексемы с идентичными типами, но с различными именами, будет рассматриваться по разному.
    3. Если требуется переход от одного типа к другому, то преобразование типов необходимо, даже если два типа очень похожи (например, переменная со знаком и целая переменная).
    4. Скалярные значения типа не могут содержать элементы любой сложности. Все значения в скалярном типе счетны. Благодаря этому все операторы отношений для все типов предопределены. Более того , каждое значение дискретного или физического типа имеет номер положения. Все числовые типы (то есть целое число,число с плавающей запятой и физический) могут быть определены в определенном диапазоне, который состоит из набора возможных значений.
    5. Объект сложного типа – состоит из других объектов, которые назваются элементами. Элементы могут иметь любой тип scalar, composite или access. При этом не допускается использование типа file как элемента сложного типа.
    6. Разница между массивами и записями состоит в том, что все элементы массива должны иметь тот же самый тип. С другой стороны, каждый элемент записи может иметь различный тип. Каждый элемент массива задается именем массива и индексом. С другой стороны, элементы записи (называемые полями) задаются через их индивидуальные имена (вместе с полным именем записи), или через агрегатирование.
    7. VHDL имеет широкий набор операторов, которые могут быть разделены на группы того же самого уровня старшинства (приоритета): смешанные операторы, мультипликативные операторы, знаковые операторы,операторы сложения, операторы сдвига, операторы отношений, логические операторы.
    8. Блок STANDARD обеспечивает предопределенные операторы для стандартных типов.
    9. Оператор not классифицирован как смешанный оператор только с целью определения старшинства.


      Иначе, его можно классифицировать как логический оператор.
    10. Если операции nand или nor используются, то выражения могут содержать только одно действие этого типа. Если необходимо многократное их применение, то должны использоваться круглые скобки.
    11. Оператор кокатенации (обозначенный как &) помещает два одномерных массива в больший массив того же самого типа (объявленное число элементов в массиве результата должено быть большой достаточным, чтобы охватить число элементов обоих добавленных операндов).
    12. Имеются два механизма задержки, доступные в VHDL: инерционная задержка и транспортная задержка. Транспортная задержка определена, при помощи использования зарезервированного слова transport, и типична для линий электропередачи. Инерционная задержка определена при помощи зарезервированного слово inertial и используется для моделирования приборов, которые являются по существу инерционными. Практически, это означает, что импульсы короче чем указанное время переключения не будут передавться.
    13. Если механизм задержки не определен, то по умолчанию это инерционная задержка.
    14. Механизмы задержек могут применяться только к сигналам.
    15. Константа это объект у которого значение никогда не может быть изменено в течение моделирования.
    16. Используйте константы настолько часто, насколько возможно, потому что они создают более читаемый и машино совместимый код

    Далее>>

    Содержание раздела