Операции суммирования, вычитания, конкатенации



Курсовая работа

На тему: Основы языка VHDL

 

Москва, 2009


Содержание

 

1.1 Введение

1.2 Идентификаторы в языке VHDL

1.3 Объекты языка VHDL

1.4 Типы данных

1.5 Операции языка VHDL

1.6 Последовательные операторы

1.7 Параллельные операторы

1.8 Описание интерфейса устройства

1.9 Архитектура

1.10 Особенности синтеза схем по описаниям на языке VHDL

Литература


Введение

 

Язык VHDL служит для описания модели цифрового устройства (прибора, системы). Описание на языке VHDL определяет внешние связи устройства (“вид снаружи” или интерфейс) и один или несколько “видов изнутри” (см. рис. 1.1). Вид снаружи задает интерфейс устройства, набор сигналов, которыми устройство обменивается с внешним миром. Этот вид описывает абстрактное представление устройства “в целом” и обозначается английским термином entity, что в дословном переводе означает «сущность» и наиболее точно отражает смысл представления. Однако в литературе термин «сущность» не нашел широкого распространения, для обозначения внешнего описания объекта используются термины «интерфейс объекта», «декларативная часть» и другие. В настоящем пособии будет использоваться термин «интерфейс объекта» или просто «интерфейс».

 

Рис. 1.1. Цифровое устройство и его модель

 

Вид изнутри определяет функциональные возможности устройства или его структуру. Внутреннее строение объекта определяет архитектура (architecture body).

Как и в языках программирования, язык VHDL имеет свои правила, в том числе правила описания имен переменных, объектов, типов данных и других параметров. Основные правила языка VHDL описаны в последующих разделах.

Идентификаторы в языке VHDL

 

Идентификаторы - это последовательность букв и цифр произвольной длины. Легальными символами являются прописные (A…Z), строчные (a…z), цифры (0…9), знак подчеркивания. Первый символ должен быть буквой, а последний символ не может быть знаком подчеркивания. Строчные и прописные буквы считаются идентичными, например, Count, COUNT и CouNT рассматриваются как один идентификатор. Знаки подчеркивания не должны следовать друг за другом. Комментарии начинаются с двойного дефиса и следуют до конца строки, например,

- это комментарий, он продолжается до конца строки

- это продолжение комментария

entity UART is end  -- это комментарий, который следует за декларацией интерфейса устройства.

Следующие идентификаторы зарезервированы для использования в качестве ключевых слов и не могут быть использованы иначе:

 

Abs Access after alias All
And architecture array begin Block
Body Buffer case component Configu-ration
Constant disconnect downto else Elsif
End Entity file for function
generate Generic guarded if In
inout Is label library linkage
loop Map mod nand New
next Nor not null Of
on Open or others Out
package Port procedure process Range
record Register rem select severity
signal Subtyupe then to Transport
type Units until use vriable
wait When while with Xor

 

Объекты языка VHDL

 

Объекты это область хранения данных определенного типа. Создаются объекты посредством декларации объекта, например:

variable COUNT: INTEGER;

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

Объекты – данные могут быть трех классов:

- сonstant (константа) - может хранить отдельное значение определенного типа. Это значение присваивается объекту в начале моделирования и не может изменяться в процессе моделирования.

- variable (переменная) - объект этого класса может хранить отдельное значение определенного типа, однако, в процессе моделирования ему могут присваиваться различные значения. Для этого используются выражения присваивания (variable assignment statement).

- signal (сигнал) – объект данного класса имеет предыдущее значение, имеет текущее значение и набор последующих значений.

Объекты класса signal моделируют проводные соединения в схемах, в то время как переменные (variable) и константы (constant) используются для моделирования поведения схемы, они аналогичны объектам, используемым в языках программирования C и Pascal.

Декларация констант

Декларации объектов (object declaration) имеют целью дать имя объекту, объявить его тип, класс и даже присвоить значение. Примеры деклараций констант описаны ниже:

constant RISE_TIME: TIME := 10ns;

constant BUS_WIDTH: INTEGER := 8:

В первом случае объявляется объект RISE_TIME, который хранит значение типа TIME, объекту в начале моделирования присваивается величина 10 наносекунд. Во втором случае объявляется, что BUS_WIDTH (ширина шины) типа INTEGER (целое) и ей присвоено значение 8.

Декларация переменных

Примеры деклараций объектов класса variable приведены ниже:

variable CTRL_STATUS: BIT_VECTOR(10 downto 0);

variable SUM: INTEGER range 0 to 100 := 10;

variable FOUND, DONE: BOOLEAN;

В первом случае декларируется переменная CTRL_STATUS как массив из 11 элементов, причем, каждый элемент типа BIT. Во втором случае переменная SUM декларируется как целое, лежащее в диапазоне от 0 до 100, в начале моделирования переменной присваивается значение 10. Если переменной в начале моделирования не задано значение, то используется значение по умолчанию. Им служит самое “левое” значение в наборе значений данного типа. Например, переменная типа BOOLEAN имеет набор значений (FALSE, TRUE) и в третьем примере начальное значение переменных FOUND и DONE будет взято по умолчанию, т.е. FALSE.

Декларация сигналов

Декларации объектов класса signal схожи с декларациями переменных:

signal CLOCK: BIT;

signal DATA_BUS: BIT_VECTOR(0 to 7);

signal GATE_DELAY: TIME := 10 ns;

В первом примере декларируется объект CLOCK типа BIT, начальное значение при моделировании будет взято по умолчанию, т.е. 0 (набор значений типа BIT: 0,1 и крайнее левое значение 0).

Не все объекты в языке VHDL создаются путем декларирования, например, входные/выходные порты всегда считаются объектами класса signal.

 

Типы данных

 

Каждый объект в языке VHDL может хранить значения, относящиеся к определенному набору. Это множество значений декларируется с помощью объявления типа (type declaration). Тип – это имя, которое связывается с определенным набором значений и набором операций. Некоторые типы предопределены языком VHDL. Например, BOOLEAN имеет набор значений FALSE, TRUE и набор операторов: and, or, nor, nand, not. В языке имеется возможность создавать новые типы с использованием деклараций и задания набора операций.

Все возможные типы в VHDL распадаются на четыре больших категории:

- scalar (скалярные),

- composite (композитные) – они состоят из элементов одного типа (массивы) или различного типа (записи),

- access type (типы доступа) – обеспечивают доступ к данному типу через указатели,

- file types (тип – файл) – обеспечивает доступ к объектам, содержащим последовательности значений данного типа.

В свою очередь скалярные типы подразделяются на четыре вида:

-enumeration (перечислимый тип),

-integer (целый тип),

-physical(физический тип),

-floating point (тип “с плавающей запятой”).

Перечислимый тип

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

type MVL is ('U','0','1','Z);

type MICRO_OP is (LOAD, STORE, ADD, SUB, MUL, DIV);

MVL – перечислимый тип с упорядоченным набором значений: 'U', '0', '1', и 'Z'. MICRO_OP имеет набор значений: LOAD, STORE, ADD, SUB, MUL, DIV. Порядок записи значений в декларации определяет лексику, т.е. значение справа всегда больше значения слева: STORE<DIV is true, SUB > MUL is false. Значения в перечислимых типах имеют позиционный номер. Позиционный номер самого левого элемента 0. Значения в перечислимых типах еще называют enumeration literals (литералы перечислимого типа). Например, в декларации:

type CAR_STATE is (STOP, SLOW, MEDIUM, FAST);

литералами являются STOP, SLOW, MEDIUM, FAST и только они могут присваиваться переменной CAR_STATE.

Целый тип

Integer – целое, задает тип, набор значений которого находится в заданном целочисленном диапазоне, например:

type INDEX is range 0 to 15;

type WORD_LENGTH is range 31 downto 0;

subtype DATA_WORD is WORD_LENGTH range 15 downto 0;

type MY_WORD is range 4 to 6;

INDEX – это переменная целочисленного типа, набор значений которой размещен в диапазоне целых от 0 до 15. DATA_WORD – подтип WORLD_LENGTH в диапазоне от 15 до 0. В отличие от перечислимых в целочисленных типах позиционный номер равен величине значения, например, для значения 31 переменной WORD_LENGTH позиция равна 31.

Тип “с плавающей запятой”

Тип floating point обладает набором значений в заданном диапазоне вещественных чисел, например:

type TTL_VOLTAGE is range 1.4 to 5.5

type REAL_DATA is range 0.0 to 31.9;

Литералы типа floating point отличаются от целочисленных присутствием точки ( . ). В результате 0 – это целочисленный литерал, а 0.0 – это литерал типа с плавающей запятой.

Физический тип

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

type CURRENT is range 0 to 1 E9

units

nA; -- (base unit) nano-ampere

uA = 1000 nA; -- micro-ampere

mA = 1000 mA; --milli-ampere

Amp = 1000 mA; -- ampere

end units;

subtype FILTER_CURRENT is CURRENT range 10 mA to 5 mA;

Здесь CURRENT определен как физический тип, имеющий значения в диапазоне от 0 nA до 10^9 nA. Базовой единицей является наноАмпер, а все остальные являются производными. Позиционный номер значения равен числу базовых единиц, представленных данным значением, например, 2 mA имеют позиционный номер 2000, в то время как 100 nA занимают позицию 100. Физический литерал записывается как целое, за которым следует название единицы измерения (пробел обязателен).

Тип “массив”

Объект типа array состоит из элементов одного типа. Ниже даны примеры массивов:

type ADDRESS_WORD is array (0 to 63) of BIT;

type DATA_WORD is array (7 downto 0) of MVL;

type ROM is array (0 to 125) of DATA_WORD;

ADDRESS_WORD – одноразмерный массив из 64 элементов типа BIT. DATA_WORD – одноразмерный массив из 8 элементов типа MVL. ROM – массив из 126 элементов типа DATA_WORD, т.е. в данном случае имеем дело с массивом массивов.

Доступ к элементам массива осуществляется с помощью индексов, например, ADDRESS_WORD(26) ссылается на 27-ой элемент массива ADDRESS_WORD.

Операции языка VHDL

 

В языке VHDL имеются операции следующих категорий:

1. Логические операции

2. Операции отношений

3. Операции сложения/вычитания

4. Операции умножения/деления

5. Прочие

Приоритет операций возрастает от категории 1 к категории 5. Операции одной категории имеют одинаковый приоритет и выполняются в последовательности: слева направо. Скобки используются для изменения последовательности исполнения.

Операции логические

Существует шесть логических операций: and, or, nand, nor, xor, not.

Операции применимы к типам BIT, BOOLEAN, к одноразмерным массивам BIT и BOOLEAN. При выполнении битовые значения ‘0’ и ‘1’ интерпретируются как булевские FALSE и TRUE. Результат имеет тот же тип, что и операнды. Операция not – унарная операция, она имеет приоритет категории 5.

Операции отношений

В языке VHDL имеются следующие операции отношений:

=, /=, <, <=, >, >=

Результатом выполнения любой операции отношений является булевское выражение BOOLEAN. Операции равенства ( = ) и неравенства ( /= ) допустимы со всеми типами, за исключением типа “файл”. Остальные четыре операции допустимы над скалярными типами (целочисленными, перечислимыми) или над массивами дискретного типа. Когда операндами являются массивы, то сравнение выполняется слева направо по одному элементу, например при следующем сравнении:

BIT_VECTOR'('0', '1', '1') < BIT_VECTOR'('1', '0', '1')

получен результат TRUE, т.к. первый элемент вектора слева меньше первого элемента вектора справа. Другой пример, если декларирован тип:

type MVL is ('U', '0', '1', 'Z' );

то результат сравнения:

MVL'( 'U' ) < MVL'( 'Z' )

будет TRUE, т.к. ‘U’ находится левее ‘Z’.

Операции суммирования, вычитания, конкатенации

Операции имеют обозначения:

+, -, &.

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

‘0’ & ‘1’

образуется массив символов “01”, или еще пример:

‘C’ & ‘A’ & ‘T’

дает “CAT”.

Операции умножения, деления

К этой группе оператций относятся: *, /, mod, rem.

Операнды умножения ( * ) и деления ( / ) должны быть одновременно либо целочисленного типа (integer) либо типа с плавающей запятой (floating point). Результат всегда того типа, что и операнды. Операция умножения может иметь один операнд физического типа, а другой – либо целочисленного, либо натурального типа. Результат выдается в виде физического типа.

В операции деления допустимо делить объект физического типа на целочисленный или натуральный. Результат - всегда физического типа. Деление физического типа на физический дает целочисленный результат.

Операции остатка ( rem ) и “деления по модулю” ( mod ) в качестве операндов могут иметь целочисленные типы и результат - целочисленного типа. Результат rem имеет знак первого операнда и определяется следующим образом:

A rem B = A - ( A / B ) * B

Результат mod имеет знак второго операнда и определяется следующим образом:

A mod B = A – B * N,

где N – некоторое целое.

Прочие операции

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

Последовательные операторы

 

К последовательным операторам (Sequential Statements) относятся операторы присваивания (Assignment Statements), условные операторы if (if Statements) и case (case Statements), операторы цикла (loop - next Statements) и другие. Рассмотрим некоторые из операторов этого типа

Оператор присваивания

Эти операторы делятся на операторы присваивания переменной (обозначается знаком :=) и операторы назначения сигнала (<=). В обоих случаях снаала вычисляется значение выражения, стоящее справа от знака равенства, а затем полученное значение присваивается переменной или сигналу, стоящим слева от знака. Например, оператор

abar := not a;

задает новое значение переменной abar, а именно – инверсное значение a.

Оператор

z <= not (a and b);

задает новое значение сигнала z, которое получается справа от знака <=.

Оператор if

В общем случае if представляет собой последовательность выражений, оговаривающих условия. В качестве условий применимы любые выражения, при вычисление которых получается булевская величина (FALSE и TRUE).

if булевское_выражение then

 последовательностные_выражения

[elsif булевское_выражение then

 последовательностные_выражения ]

[else

 последовательностные_выражения]

end if;

Выражение if вычисляется путем просмотра условий одного за другим, пока не будет найдено истинное. Затем вычисляется набор последовательностных выражений, связанных с этим условием. Предложений вида elsif в выражении if может быть от 0 и более. Может использоваться и предложение else. Выражения if могут вкладываться одно в другое без ограничений.

Рассмотрим простой пример.

if CTRL = '1' then

 MUX_OUT<= "10";

else

 MUX_OUT<= "01";

end if;

Если управляющий сигнал CTRL1 равен ‘1’, то выходной сигнал MUX_OUT принимает значение "10", иначе MUX_OUT примет значение "01". На этом оператор if завершается.

Рассмотрим более сложный пример.

if CTRLI = '1' then

 if CTRL2 = '0' then

 MUX_OUT<= "0010";

 else

 MUX_OUT<= "0001";

 end if;

else

 if CTRL2 = '0' then

 MUX_OUT <= "1000";

 else

 MUX_OUT <= "0100";

 end if;

end if;

Если управляющий сигнал CTRL1 равен ‘1’, тогда при условии (открывается вложенное if) CTRL2=’0’ выходной сигнал MUX_OUT<= "0010", иначе (т.е. при любых других значениях сигнала CTRL2) MUX_OUT<= "0001". Здесь завершается внутренний (вложенный) оператор if. Иначе (т.е. при любых других значениях сигнала CTRL1), если (открывается новый вложенный оператор if) CTRL2=’0’, тогда MUX_OUT<= "1000", иначе (т.е. при любых других значениях сигнала CTRL2) MUX_OUT<= "1000". Здесь завершается внутренний (вложенный) оператор if, а также завершается и наружный.

Оператор case

Оператор case имеет следующий формат:

case выражение is

 when вариант выбора => последовательностные_выражения

 when вариант выбора => последовательностные_выражения

-- произвольное число вариантов выбора.

 when others => последовательностные_выражения]

end case;

При вычислении выражения case выбирается одна из ветвей в соответствии со значением выражения. Выражение может иметь значения типа перечислимого или типа одномерного массива. Рассмотрим пример:

type WEEK_DAY is (MON, TUE, WED, THU, FRI, SAT, SUN);

type DOLLARS is range 0 to 10;

variable DAY: WEEK_DAY;

variable POCKET_MONEY: DOLLARS;

case DAY is

 when TUE => POCKET_MONEY := 6; -- ветвь 1

 when MON I WED => POCKET_MONEY := 2; -- ветвь 2

 when FRI to SUN => POCKET_MONEY := 7; -- ветвь 3

 when others => POCKET_MONEY := 0; -- ветвь 4

end case;

Переменная WEEK_DAY имеет значения перечислимого типа (дни недели). Переменная DOLLARS имеет целочисленные значения в диапазоне от 0 до 10. Ветвь 1 выбирается, когда день недели TUE. Ветвь 2 выбирается в случае когда дни недели MON или WED (вертикальная черта означает ИЛИ). Ветвь 3 покрывает значения от FRI до SUN, т.е. FRI, SAT и SUN. Ветвь 4 покрывает все оставшиеся значения, т.е. THU.

Оператор loop

Оператор loop используется для задания итерации набора последовательных выражений.

[ярлык для loop: ] итерационная схема loop

 последовательностные_выражения

end loop [ярлык для loop ] ;

Существует три итерационных схемы. Первая имеет форму:

for идентификатор in диапазон

Пример использования схемы:

FACTORIAL := 1;

for NUMBER in 2 to N loop

 FACTORIAL := FACTORIAL * NUMBER;

end loop;

Тело loop исполняется N-1 раз, при этом идентификатор NUMBER в конце каждой итерации увеличивается на 1. Подразумевается, что идентификатор целочисленного типа и значения его лежат в диапазоне от 2 до N.

Второй итерационной схемой является следующая:

while булевскоe_выражение

Пример использования схемы:

J:=0;SUM:=10;

WH-LOOP: while J<20 loop -- loop имеет ярлык WH_LOOP

 SUM := SUM * 2;

 J:=J+3;

end loop;

Выражения в теле loop выполняются одно за другим и эта последовательность повторяется, пока условие J<20 истинно.

Третьей cхемой является конструкция, в которой итерационная схема не задается и выход из loop осуществляется с использованием выражений: exit, next или return, например:

SUM:=1;J:=0;

 L2: loop --loop имеет ярлык

 J:=J+21;

 SUM := SUM* 10;

 exit when SUM > 100;

end loop L2;

В этом примере выражение exit заставляет выходить из петли L2 когда SUM становится больше 100. При отсутствии выражения exit loop будет исполняться бесконечно.

Параллельные операторы

 

К параллельным операторам (Concurrent Statements) оператор process, оператор параллельного вызова процедуры, оператор конкретизаци компонента, оператор генерации (generate) и другие. Параллельные операторы определяют параллельное поведение схем, порядок их выполнения не зависит от их появления внутри блока.

Рассмотрим кратко оператор process. В общем виде он может быть записан следующим образом.

[имя процесса:][postponed] process [(список)]

 раздел деклараций

 begin

 операторы

 end process [имя процесса];

Имя процесса и ключевое слово [postponed] являются необязательными и часто отсутствуют. Список, находящийся после ключевого слова process, хотя и является необязательным, на практике используется достаточно часто для указания сигналов запуска. Перед ключевым словом могут находиться различного рода декларации типов, констант атрибутов и т. д.

Хотя процесс является параллельным оператором, он может содержать последовательные операторы. Внутри процессов не мегут быть декларированы сигналы.

 


Дата добавления: 2019-07-15; просмотров: 80; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!