Текст
                    СЕРИЯ СИСТЕМЫ ПРОЕКТИРОВАНИЯ


ILH. Бибило ОСНОВЫ ЯЗЫКА VHDL Издание второе исправленное и дополненное Москва СОЛОН-Р 2002
УДК 519.711 Рецензенты: доктор технических наук А.А. Петровский, доктор технических наук А.А. Прихожий, кандидат технических наук Д.И. Черемисинов П.11. Бибило Основы языка VHDL — М.: СОЛОН-Р, 2002. — 224 с.: ил. ISBN 5-93455-162-0 Описывается применение языка VHDL на алгоритмическом и логическом уровнях проектирования цифровых систем. Язык VHDL является международным стандар- том в системах автоматизации проектирования и предназначен для спецификации, моделирования и синтеза цифровых систем на основе заказных и программируемых пользователями сверхбольших интегральных схем. Книга предназначена для первоначального ознакомления с языком VHDL и может быть полезна студентам, аспирантам и специалистам, занимающимся разработкой электронной аппаратуры с помощью средств САПР. Эту книгу можно заказать по почте (наложенным платежом — стоимость 118 руб.) двумя способами: 1) выслать почтовую открытку или письмо по адресу: 123242, Москва, а/я 20; 2) передать заказ по электронной почте (e-mail) по адресу: magazin@solon-r.ru. Необходимо написать полный адрес, по которому выслать книги. Обязательно указывать индекс и Ф. И. О. получателя! При наличии — указать телефон, по которому с вами мо< н»» сни- заться, и адрес элекзронной почты (E-mail). Цены действительны к> i с«*н1мПри 'он • » Вы можете нлкйни- нремч нолучны пн <н|| <н* »-«• и ы|нц.ства ‘СОЦОН Г п<> IhnciuH iу, !!••• -ыи ns» и»* nib ।»• • it 4 piithH аннннвет- Ч1П 1И> л |pr« V killuhh < till I lit IlM'iHh '«Il.ril II' рлссылку ||<ИИГ I Hilltll M МММ Illi .(Дресу lirvx '' .ulih| 1 ill « h I । inn . I ’ll • III III । ШМ •»' I" н к письма. । ti > •»» i и. । u mi'll HI Р», 2002
Оглавление Предисловие............................................ 5 Глава!. Основные элементы языка VHDL................... 8 1.1. Структурное и поведенческое описание цифровой системы ....................................... 8 1.2. Лексические элементы и типы данных...........22 1.3. Декларации.................................. 37 1.4. Интерфейс и архитектура объекта .............40 1.5. Атрибуты................................... 43 1.6. Имена ...................................... 49 1.7. Операторы .................................. 50 1.8. Понятие сигнала в языке VHDL................ 57 1.9. Дельта-задержка ............................ 62 Упражнения................................. 66 Глава 2. Последовательные и параллельные операторы ..71 2.1. Последовательные операторы.................. 71 2.2. Параллельные операторы...................... 88 Упражнения................................. НО Глава 3. Организация проекта......................... 119 3.1. Подпрограммы............................... 119 3.2. Функции..................................... И9 3.3. Процедуры.................................. 122 3.4. Разрешающие функции. Пакет std_logic_l 164. 124
Оглавление 4 3.5. Архитектура.............................. 130 3.6. Декларация интерфейса объекта............ 131 3.7. Карта портов и карта настройки........... 134 3.8. Конфигурация............................. 135 3.9. Блоки проекта и VHDL-библиотеки.......... 138 Упражнения.............................. 141 Глава 4. Примеры проектирования па VHDL............ 144 4.1. Стили описания поведения ................ 144 4.2. Формы описания сигналов.................. 147 4.3. Описание автоматов....................... 151 4.4. Отладка VHDL-описаний.................... 169 4.5. Синтезируемое подмножество языка VHDL.... 172 Упражнения.............................. 184 Литература......................................... 186 Приложения ...................................... 187 1. Форма задания синтаксических конструкций языка VHDL.................................... 187 2. Синтаксис языка VHDL’93.................... 188 3. Пакет STANDARD............................. 214 4. Пакет STD_LOGIC_1164....................... 216
Предисловие 5 Предисловие Язык VHDL (Very high speed integrated circuits Hardware De- scription Language) является фактически международным стандар- том в области автоматизации проектирования цифровых систем, это входной язык многих современных систем автоматизированного проектирования (САПР) как заказных, так и программируемых ло- гических интегральных схем (ПЛИС) - Programmable Logic Devices (PLD) - и программируемых пользователями вентильных матриц - Field-Programmable Gate Arrays (FPGA). VHDL предназначен, в пер- вую очередь, для спецификации - точного описания проектируемых систем и их моделирования на начальных этапах проектирования - алгоритмическом и логическом. С помощью VHDL можно модели- ровать электронные схемы с учетом реальных временных задержек. В последнее время весьма успешно разрабатываются и систе- мы синтеза схем по спецификациям на этом языке. Например, ис- пользуя САПР Foundation Scries 3.1i, можно провести модели- рование исходного описания схемы на языке VHDL, а затем синте- зировать схему и получить файл настройки (конфигурации) микро- схемы типа FPGA фирмы Xilinx. Использование САПР MAX+PLUSII позволяет решать аналогичные задачи для програм- мируемых микросхем, выпускаемых фирмой Altera. Для заказных СБИС могут быть использованы САПР фирмы Graphics Mentor: сис- тема моделирования ModclSim позволяет провести моделирование описаний, представленных на языке VHDL, система синтеза Leonar- doSpcctrum позволяет автоматически получать по описаниям на язы- ке VHDL схемы в заданных базисах логических элементов. Такие крупнейшие фирмы - производители программного обеспечения САПР в области микроэлектроники, как Cadence, Synopsys и многие другие используют язык VHDL в качестве языка исходного описа- ния проектов.
6 Предисловие VHDL - это мощный язык, он позволяет описывать поведение, т.е. алгоритмы функционирования цифровых систем, а также прово- дить иерархическое функционально-структурное описание систем, имеет средства для описания параллельных асинхронных процессов, регулярных (систолических) структур и в то же время имеет все признаки языка программирования высокого уровня - позволяет создавать свои типы данных, имеет широкий набор арифметических и логических операций и т.д. Язык VHDL был разработан в США по инициативе министер- ства обороны этой страны. В 1987 г. VIIDL был принят в качестве стандарта ANSI IEEE Std 1076-1987. Данный стандарт часто назы- вают VHDL’87. Затем язык был усовершенствован, новый стандарт ANSI IEEE Std 10 6-1993 (стандарт VHDL’93) появился в 1993 г. Книга [7] целиком посвящена новому стандарту языка и его отличи- ям от стандарта VHDL’87. В 1999 г. утвержден стандарт Std 1076.1-1999 (или более рас- пространенное наименование VHDL-AMS), который включает рас- ширения, дающие возможность описания моделей аналоговых и смешанных (цифро-аналоговых) схем. Язык VHDL развивается, ему посвящаются международные конференции, выходят научные журналы, в которых изучаются про- блемы использования VHDL. Он стал языком разработки междуна- родных проектов, в том числе осуществляемых с помощью всемир- ной компьютерной сети Internet. Знакомство с этим языком необхо- димо для эффективной работы по созданию самой разнообразной электронной аппаратуры на современной элементной базе сверх- больших интегральных схем. Данная книга предназначена для первоначального ознакомле- ния с языком VHDL. Приводимые в ней определения синтаксиче- ских конструкций языка ориентируются па стандарт VHDL’93. В приложении дается синтаксис стандарта VHDL’93. Основной упор в книге делается на применение языка VHDL на этапах алгоритмиче- ского и логического проектирования цифровых систем; она оказа- лась незаменимой при начальном изучении языка VHDL студентами Бслгосуниверситета (специализация «Математическая электрони- ка»), При написании книги за основу был взят материал лекционно- го курса, читаемого автором в этом вузе на протяжении ряда лет. В
Предисловие 7 । онцс каждой главы даются вопросы, задачи и упражнения для са- тигельной работы. Книга будет полезна как для студентов и ас- пирантов соответствующих специальностей, так и для специалистов, ишпмающихся разработкой электронной аппаратуры с помощью р в гн САПР. Автор выражает благодарность О.В.Клачко за помощь в пол- ыновке рукописи к изданию. Предисловие к второму изданию Увеличение числа пользователей языка VHDL потребовало Hioporo издания книги. Книга оказалась весьма полезной как для и жильного лекционного обучения и проведения практических заня- IIIи так и для самостоятельного изучения языка VHDL. В данном втором издании изложение языка полностью ориен- I прус гея на стандарт VHDL’93. Исправлены некоторые неточности, определения грамматических конструкций даются в более доступ- ппи форме. Вместо описаний параллельных автоматов приводятся примеры описаний на языке VHDL микропрограммных автоматов, Лоисе распространенных в практике проектирования.
Глава 1 Основные элементы языка VHDL 1.1. Структурное и поведенческое описание цифровой системы Цифровая система может быть описана на уровне поведения - функций, реализуемых системой, и на структурном уровне. Структурное описание - это описание системы в виде совокупности компонент (подсхем, элементов) и связей между компонентами. Поведенческое описание - это описание системы при помощи некоторых процедур на уровне зависимостей выходов от входов. Иначе говоря, поведенческое описание задаст алгоритм, реализуемый системой. Цифровая система может быть сложной, как, например, СБИС, (микропроцессор) или весьма простой, как логический элемент (вентиль). Естественно, некоторые компоненты системы в структурном описании могут состоять из нескольких частей — компонент более низкого уровня иерархии описания. Представляя отношение вхождения подсхем в схемы в виде графа, можно получить дерево (граф) иерархии описания всей системы. Например, пусть цифровая снсгсма S (pin 1 I) р анизует следующий аиоршм. На нхо пн.те Полины иь ц*мы S иодинися два lity\разрядных чинш ii-(n?,nl)l I» in пЛ Ю старшие ра »ря и.| чи гм и b • ooiiirieim чин» и * у Иран iiitoiiiihi . ш нал [3]. I < ли х -1. i |н нкы S uni । ин н* pi инк « и 11 ин 'i i и b и выдать ЧС11 ip« xpiipiiiihii' Ч1К IO tl (ill.И I III | I. «I . I. I* ’III 4 (I III HH i I II I. |n 14011.1 Лни I i . I|l|( при этом в paipii'H <11 и. ri/in и ii и 1.1H и np.np.ir H перенос c2, в
Основные элементы языка VHDL 9 алгоритм, который языке. Однако проектирования разряде d2 - старшин разряд суммы s2, в разряде dl - младший разряд суммы si. Предполагается, что (а2,а!) + (Ь2,Ы)= (c2,s2,sl). Мы описали S, на русском (компьютерного) спецификация. должна реализовать система для автоматизированного требуется формальная al а2 Ь2 Ы х Рис. 1.1. Система S и ее интерфейс
10 Глава 1 Формальные спецификации должны быть записаны на соответствующем формальном языке. Позже будет показано, что алгоритм, реализуемый системой S, может быть очень коротко описан па языке VHDL. Если же рассматривать структурный уровень описания системы S, то можно легко увидеть, что в систему S входит двухразрядный сумматор и двухразрядный умножитель. Двухразрядный сумматор - это устройство для сложения двухразрядных чисел, а двухразрядный умножитель - устройство для перемножения двух чисел, каждое из которых имеет только два разряда. В систему S должно входить также простейшее устройство управления и схема дизъюнктивного объединения выходных сигналов. Структура системы S изображена на рис. 1.2. Рис. 1.2. С'грукпрл Цифрпн<И| ( lb It il.f s
Основные элементы языка VHDL 11 На рис. 1.2 adder_2 - двухразрядный сумматор, mult_2 - (вухразрядный умножитель, YY — устройство управления, dd — схема дизъюнктивного формирования выходных сигналов. Схему dd образуют три дизъюнктора. Устройство управления YY является весьма простым и функционирует следующим образом: если х=0, то (a2,al)=(f4,f3), (b2,bl)=(f6,f5), (f2,fl)=(0,0), т.е. числа а, b подаются на вход сумматора addcr_2. Если же х=1, то (f4,f3)=(0,0), (f6,f5)=(O,O), (a2,al)=(f2,fl), т.е. числа а, b подаются на вход умножителя inult_2. Пусть описание системы S имеет имя V LSI _1. Тогда иерархия структурного описания системы S будет иметь вид (рис. 1.3) Рис. 1.3. Дерево иерархии структурного описания системы S Рассмотрим двухразрядный умножитель mult_2. На вход данной схемы (рис. 1.4) поступают сигналы rl, rO, si, sO. Сигналы rl, гО интерпретируются как двухразряднос целое число r=(rl,rO), сигналы si, sO - как двухразрядное целое число s=(sl,sO). Выходные сигналы в t3, t2, tl, tO представляют собой разряды числа t=(t3, t2, tl, tO) - произведения чисел s, г: (t3, t2, tl, tO) = (rl,rO)x(sl,sO).
12 Глава 1 Рис. 1.4. Двухразрядный умножитель mult_2 В схему входят элементы двух типов - addl и and2. Элемент and2 представляет собой логический элемент И - двухвходовый конъюнктор. Заметим, что на языке VHDL знак & употребляется нс для обозначения логической операции «И» (конъюнкции), а для операции конкатенации векторов. Оператором логической конъюнкции служит оператор and, поэтому описание функции элемента and2 на языке VHDL выглядит следующим образом: у <= xl and х2;
Основные элементы языка VHDL 13 1 ;е xl, х2 - имена входных сигналов, у - имя выходного сигнала, • =- оператор назначения сигнала (будет рассмотрен позже). Элемент addl представляет собой одноразрядный полусумматор, функционирование которого описывается таблицей истинности (табл. 1.1). Таблица 1.1 ы Ь2 cl sl 0 0 0 0 0 1 0 1 1 0 0 1 1 1 1 0 В данном случае Ы, Ь2 интерпретируются как одноразрядные числа, si - сумма, cl - перенос в следующий разряд. В привычной математической записи булевы функции si, cl могут быть представлены следующим образом: si = Ы Ф Ь2 = ( Ы л Ь2 )v( bl л Ь2 ), cl = ЫаЬ2. В языке VI1DL функционирование элемента addl записывается следующим образом: si <= ((bl and (not b2)) or (not bl) and b2)); cl <= bl and b2; где or - оператор логической дизъюнкции; and - оператор логической конъюнкции; not - оператор отрицания. Итак, в дерево проекта схемы умножителя, которую назовем mult_2, входят элемент and2 и подсхема addl. Если использовать логические элементы ог2 (двухвходовый дизъюнктор) и inv (инвертор) и and2 (двухвходовый конъюнктор) для реализации подсхемы addl, то дерево проекта будет трехуровневым.
14 Глава 1 Элементы and2, or2, inv являются листьями проекта. Листья проекта не имеют составных частей и называются примитивами проекта. Примитив описывается только на поведенческом уровне. Объектами проекта для двухразрядного умножителя являются mult_2, addl, and2. Обозначение корня дерева (mult_2) является именем проекта. Каждый объект проекта имеет два различных типа описаний: - описание объекта «в целом» (entity); - описание архитектуры объекта (architecture). Упрощенно можно сказать, что описание объекта «в целом» состоит из имени объекта и описания портов (входов, выходов) объекта. Описание объекта «в целом» в языке VHDL носит название «интерфейс» объекта. Чтобы отличать один объект проекта от другого, термин entity будет пониматься иногда и как объект проекта. Для сигналов, подаваемых, снимаемых с портов указывается вид (режим, направление) сигнала: входной (in), выходной (out) и его тип. Описание объекта проекта and2 имеет вид. entity and2 is port (xl,x2: in BIT; y: out BIT); end and2; — декларация имени объекта проекта - декларация входных портов - декларация выходного порта architecture functional of and2 is - декларация архитектуры begin у <= xl and x2; - описание функции объекта end functional; В тексте данной программы имеются комментарии. Комментарий начинается двумя смежными дефисами и продолжается до конца строки. В данном примере BIT - это тип сигнала. Архитектурное тело может определять поведение объекта проекта непосредственно (быть примитивом), либо представлять собой структурную
Основные элементы языка VHDL 15 1скомпозицию на более простые компоненты. Описание объекта проекта addl выглядит следующим образом: entity addl is port (bl,b2 : in BIT; cl,si : out BIT); end addl; architecture struct 1 of add 1 is begin sl<= ((bl and (not b2)) or ((not bl) and b2)); cl<= bl and b2; end struct !; Описание объекта проекта mult_2 выглядит следующим образом: entity mult_2 is port (sl,sO,rl,rO : in BIT; t3,t2,tl,tO: out BIT); end mult_2; architecture structure of mult 2 is component addl port (bl,b2: in BIT; cl,si: out BIT); end component; signal pl,p2,p3,p4 : BIT; begin tO <= rO and sO; p2 <= rO and si; pl <= rl and sO; p4 <=rl and si; - элемент el 1 - элемент el_3 - элемент cl_2 - элемент el 4
16 Глава 1 circl:addl port map (pl, р2, p3,tl); circ2: addl port map (p3,p4,t3,t2); end structure; В описании архитектуры объявляются (декларируются) две подсхемы (компоненты). После ключевого слова begin приводятся экземпляры описаний. Каждый экземпляр имеет уникальную метку (circl, circ2 — метки). Каждый экземпляр имеет карту портов (port map). Карта портов отражает связь между входами, выходами описаний компонента и экземплярами компонента. Заметим, что в данном описании мы использовали понятие компонента (подсхемы) для add 1, в то время как логические элементы И схемы мы описали на функциональном уровне, не используя понятие компонента. Возможность проведения таких сметанных описаний является важной полезной особенностью языка VHDL. Данная гибкость весьма удобна при проектировании на начальных этапах, когда важно получить точное алгоритмическое описание, не вдаваясь в детали структурной организации некоторых частей проекта. Аналогично можно рассмотреть двухразрядный сумматор adder_2 (рис. 1.5), состоящий из двух подсхем addl, add2, где addl — это уже известный нам одноразрядный полусумматор, a add2 - одноразрядный сумматор, функционирование которого описывается следующей таблицей истинности (табл. 1.2): Таблица 1.2 О О О О 1 1 1 1 О О 1 1 О О 1 1 а2 О 1 О 1 О 1 О 1 с2 О О О 1 О 1 1 1 s2 О 1 1 О 1 о о 1
Основные элементы языка VHDL 17 а с2 si s2 f f f adder_2 Hff al bl a2 b2 Рис. 1.5. Двухразрядный сумматор (al,bl)+(a2,b2)=(c2,s2,sl): a - условное обозначение; б - схема в виде каскадного соединения одноразрядного полусумматора addl и одноразрядного сумматора add2 В дерево проекта для подсхемы addcr_2 входят подсхемы addl, add2, а VHDL-описание имеет вид entity addcr_2 is port (al, bl, a2,b2 : in BIT; c2,s2,sl : out BIT); end addcr_2; architecture structure of adder 2 is component addl port (bl,b2: in BIT; cl,sl: out BIT); end component;
18 Глава 1 component add2 port(cl, al,a2:in BIT; c2,s2:out BIT); end component; signal cl: BIT; begin circl: addl port map (bl,b2, cl,si); circ2: add2 port map (cl,al,a2,c2,s2); end structure; Можно заметить, что в различные подсхемы входит addl, при этом подсхема addl, входящая в сумматор addcr_2, является листом проекта и поэтому описана на поведенческом уровне. Подсхема addl, входящая в умножитель inult_2, описана на структурном уровне. Предлагаем читателю самостоятельно описать подсхему addl в виде объекта проекта, используя примитивы and2, or2, inv. Итак, VHDL-код для структурного описания системы S (см. рис. 1.2) выглядит следующим образом: entity vlsi_l is port (a2, al, b2,bl,x:in BIT; d4,d3,d2,dl: out BIT); end vlsi l; architecture structure of vlsi 1 is component adder 2 port (al,bl,a2,b2: in BIT; c2,s2,sl: out BIT); end component; component mult_2 port(sl,sO, rl,rO: in BIT; t3,t2,tl,tO: out BIT); end component; component dd port (xl,x2,x3,x4,x5,x6 : in BIT; yl,y2,y3 : out BIT); - декларация компонента -декларация компонента -декларация компонента
Основные элементы языка VHDL 19 end component; component yy — декларация компонента port( a2,al,b2,bl,x : in BIT; f6,f5,f4,I3,I2,fl : out bit); end component; signal fl,f2,f3,f4,f5,f6,t4,t3,t2,tl,c2,s2,sl: BIT; — декларация внутренних сигналов begin circl: yy port map (a2,al, b2,b 1, x, f6,f5,f4,f3,f2,fl); circ2: mult_2 port map (f2,fl, b2,bl, d4,t3,t2,t 1); circ3: adder_2 port map ( f4,f3, f6,f5,c2,s2,sl); circ4: dd port map ( 81,11,52,12,02,13, d 1 ,d2,d3); end structure; Описания подсхем YY, dd па функциональном уровне имеют следующий вид: entity YY is port (a2,al,b2,bl, x : in BIT; f6,f5,f4,f3,f2,fl : out BIT); end YY; architecture struct_l of YY is begin fl<= x and al; f2<= x and a2; f3<= not x and al; f4 <- not x and a2; f5 <= not x and bl; f6 <= not x and b2; end struct 1;
20 Глава 1 entity dd is. port (xl,x2,x3,x4,x5,x6 : in BIT; yl,y2,y3 : out BIT); end dd; architecture struct_l of dd is begin yl<= xl or x2; y2<= x3 or x4; y3<= x5 or x6; end struct_ 1; Дерево проекта для системы S изображено на рис. 1.6. Рис. 1.6. Дерево проекта цифровой системы S Приведем один из вариантов алгоритмического описания системы S в целом. Следует обратить внимание па то, что входные и выходные сигналы интерпретируются как целые числа, что позволяет сделать алгоритмическое описание весьма компактным. entity vlsi l is port (a,b : in integer range 0 to 3; x : in BIT;
Основные элементы языка VHDL 21 D : out integer range 0 to 15); end vlsi 1; architecture functional of vlsi_l is signal e: integer range 0 to 15; begin pO: process(a, b, x) begin if (x-O') then e <= a + b; elsif ( x = ’Г) then e <= a * b ; end if; end process; D <= e; end functional; Как видно, оно значительно компактнее структурного описания. Очевидно, что переход от алгоритмического описания к структурному представляет значительный практический интерес. К сожалению, автоматический переход возможен только для подмножества языка VHDL. Такое подмножество языка называется . ‘интезируемым. Получение функционально-структурной схемы по ее алгоритмическому описанию называется высокоуровневым синтезом в отличие от логического синтеза, когда по функционально-структурному описанию цифровой системы надо получить логическую схему из заданных базисных логических элементов. Программу, осуществляющую по VHDL-описанию синтез схемы, например схемы FPGA, часто называют компилятором. Однако в системах моделирования VHDL-кодов под компиляцией также понимается преобразование VHDL-кода в промежуточный язык, с которым оперируют непосредственно программы моделирования. Как и для языков программирования, сборку откомпилированных модулей осуществляет программа LINK. Программа, осуществляющая проверку синтаксической корректности, называется VHDL-n//a7/«azHopa«.
22 Глава 1 Приведенное VHDL-описание системы S станет понятным позже, когда будут введены типы данных и основные операторы языка VHDL - операторы процессов, назначения сигналов и др 1.2. Лексические элементы и типы данных Лексические элементы, разделители, операторы. Текст на языке VHDL есть последовательность раздельных лексических элементов, таких как: • идентификатор; • разделитель; • ключевое (зарезервированное) слово; • литерал (десятичный, базовый, символьный, строковый, строка бит); • комментарий. Смежные лексические элементы разделяются: • разделителями; • концами строк; • знаками форматирования. Разделитель есть один из следующих специальных символов: &()* + ?- •/ :;< = > I Составной разделитель есть композиция двух смежных спе- циальных символов — > >_ <— <> Пример. VHDL-предложение А <= В and С; имеет шесть лексических элементов "А", ”В”, ’’and ', ’’С", . Два из шести лексических элементов являются разделителями: " <= " (составной разделитель - оператор назначения сигнала); И . t!
Основные элементы языка VHDL 23 В качестве разделителей в данном примере используются нро- ослы, однако пег необходимости иметь разделитель между операто- ром "; " и лексическим элементом "С". Комментарий начинается с двух смежных дефисов и продол- кается до конца строки. Комментарии не учитываются при модели- ровании VHDL-описаний и синтезе схем по VHDL-описаниям. Идентификаторы Определение. basic identificr ::= letter { [ underline ] lcttcr_or_digit} Внимание! Здесь и далее формальная запись синтаксических конструкций языка VHDL основывается на формах Бэкуса-Наура, употребление которых разъясняется в Приложении 1. Далее важная информация, на которую следует обратить особое внимание, будет сопровождаться только восклицательным знаком. Для облегчения понимания конструкций языка VHDL в данной книге будем использовать также упрощенную форму: будем записы- вать общий вид конструкции, в записи конструкции будут ключевые слова и другие символы алфавита языка VHDL, фразы русского язы- ка и символы - фигурные и квадратные скобки, вертикальные чер- точки. Используемые фигурные скобки, также как и при задании форм Бэкуса-Наура, будут служить для обозначения повторения вы- ражения, заключенного в них; вертикальная черта - для обозначения альтернативных случаев; квадратные скобки - для обозначения не- обязательного выражения или необязательного слова (см. приложе- ние 1). ! При изучении языка VHDL и написании программ настоятельно рекомендуем пользоваться точными определениями синтаксиче- ских конструкций, приводимыми в описаниях соответствующих стандартов [10, 11].
24 Глава 1 Идентификаторы употребляются как пользовательские имена и ключевые слова. Идентификатор должен начинаться с буквы (не цифры). Мо- жет употребляться кроме букв и цифр, знак подчеркивания. Два подряд идущих подчеркивания не допускаются. ! В VHDL-коде нет различия между прописными и строчными бук- вами. АЬС7 эквивалентно аВС7, А_3 не эквивалентно АЗ. Идентификатор нс должен оканчиваться подчеркиванием. Пример. Правильные Идентификаторы Саггу_0иТ DimSum Count7SUB_2goX AaBBb Неправильные Идентификаторы 7АВ (начинается с цифры) А@В (специальный символ @) 8иМ_(кончается подчеркиванием) PI__А (два подчеркивания подряд) Зарезервированные (ключевые) слова Как и многие другие языки программирования, VHDL имеет ключевые (специальные) слова. Список ключевых слов (стандарт VHDL ’87) abs access after alias all and architecture array assert attribute begin block body buffer bus case component configuration constant disconnect downto else elsif end entity exit file for function generate generic guarded if in inout
Основные элементы яЗыка VHDL 25 IS - i > 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 report return select seventy signal subtype then to transport type units until use variable wait when while with xor В стандарт VHDL’93 добавлены следующие слова: group impure inertial literal postponed pure reject rol ror shared sla sll sra srl unaffected xnor * Литералы Классификация литералов языка VHDL приведена на рис. 1.7. Десятичный литерал может быть целым, вещественным или вещественным с экспонентой. Примеры. Целые литералы: 21,0, 1Е2, Зе4,123_000. Вещественные литералы: 11.0, 0.0, 0.468, 3.141_592_6. Вещественные литералы с экспонентой: 1.23Е-11, 1.0Е+4, 3.024Е+23. Знак экспоненты Е может быть строчным либо прописным, одчеркивание в десятичном литерале не является значащим. Экс- понента для целого литерала не должна иметь знак минус. Базовый литерал указывает на систему счисления: от двоич- ной до шестнадцатеричной:
26 Глава 1 Рис. 1.7. Классификация литералов Число 16#6#Е1 означает 6* 16**1 - это число 96 в десятичной системе счисления: 96 = 6Х 161. Символ * - знак умножения, ** - возведение в степень. Число 2Е - 3 не является целым, Зе4 - это чис- ло ЗХ1О4. I Символьный литерал формируется одним из символов (букв) между апострофами: 'А',’а',’°о, (литерал - апостроф),'' (пробел); ’А' отличается от ‘а’ в случае символьного литерала. Строковый литерал формируется как последовательность букв (возможно пустая) между двумя кавычками, употребляемыми I как строковые скобки.
Основные элементы языка VHDL 27 Строковый литерал должен располагаться в одной строке. Для (формирования ’’длинных” строковых литералов может быть упот- реблена операция конкатенации & (напомним, что для оператора логического И употребляется оператор AND). Литерал "строка бит" Литерал "строка бит” формируется как последовательность цифр 0,..., 9, А,... ,F (или а,..., f) между двумя кавычками. Подчер- кивание в таком литерале не является значащим. Литерал "строка бит” может быть В — бинарным; О - восьмеричным; X - шестнадцатеричным. Очевидно, вместо прописных букв В, О, X могут употреблять- ся строчные буквы Ь, о, х. Длина строкового битового литерала есть число бит в после- юватсльности, представляющей литерал. Для примера: все литера- лы X"FJFF”, О”7777”, В”1111J 111J 111” имеют длину 12. Примеры. В’ЧОЮИО” О” 126” Х"56" -длина 7 - эквивалентно В"001_010_110", длина 9 -эквивалентно В”0101_0110", длина 8 Пакеты Базовым элементом в языке VHDL служит блок. Блок - это ог- раниченный фрагмент текста, содержащий раздел описания и ис- полняемый раздел. Само архитектурное тело есть блок. Более под- робно оператор "блок" будет рассмотрен далее. Пакет (package) в VHDL - это блок, который может включать множество деклараций: • типов; • подтипов; • констант; • процедур; • функций.
28 Глава 1 Пример функции языка VHDL: функция NOW возвращает те- кущее время системы моделирования. Тело пакета есть одно из мест, где могут быть определены те- ла функций, тела процедур и другие VHDL-описания (рис. 1.8). configuration package body package Рис. 1.8. В пакете могут размещаться различные VHDL-описания Функции и процедуры иногда называют подпрограммами. Приведем только пример декларации процедуры, более подробно подпрограммы будут рассмотрены далее. Пакет multiplexer показывает, что процедура MX декларирует- ся в пакете и тело процедуры определяется в теле пакета. package multiplexer is procedure MX( signal SEL : in bit; signal xO : in bit; signal xl : in bit; signal F : out bit);
Основные элементы языка VHDL 29 end multiplexer; package body multiplexer is procedure MX( signal SEL : in bit; signal xO : in bit; signal xl : in bit; signal F : out bit) is begin case SEL is when ’O' => F <= xO; when others => F <= xl; end case; end MX; end multiplexer; Типы Большинство языков программирования предусматривает раз- личные типы данных, и язык VHDL не является в этом смысле ис- ключением. Однако, поскольку этот язык используется для прсд- < швления аппаратных проектов в самых разных вариантах, средства шпизации данных приобретают здесь особенно важное значение. Например, они дают разработчику возможность представить группу шпий (проводников) шины в виде: • массива битов; • целого числа. В языке VHDL реализована строгая типизация. Это означает, что смешение различных типов в одной операции является ошибкой. (Средства строгого контроля типов играют ответственную роль, по- скольку позволяют уточнять намерения разработчика [1]. Тип - поименованное множество значений с некоторыми об- щими характеристиками. Подтип - подмножество значений данного типа. Например, тип NATURAL есть подтип типа INTEGER. Классификация типов языка VHDL дана на рис. 1.9.
30 Глава 1 Рис. 1.9. Классификация типов Типы определяются обычно в • пакете; • процессе; • архитектурном теле. Тип "целый" Примеры декларации целых типов. type byte _int is range 0 to 255; type signed_word_int is range-32768 to 32767; type bit index is range 31 dovvnto 0; В табл. 1.3 приведены основные типы данных языка VHDL. В пакете STANDARD (см. приложение 3), поставляемом ( системами моделирования и синтеза, декларируются типы ВОО LEAN, BIT, BITJVECTOR, INTEGER, POS1TIV, NATURAL CHARACTER, STRING, а также тип TIME.
Основные элементы языка VHDL 31 Таблица 1.3 Логические Типы Арифметические типы Символьные типы BOOLEAN (булев) INTEGER (целый) CHARACTER (символьный) BIT (битовый) POSITIV (положительный) STRING (строковый) B1T_VECTOR (битовый вектор) NATURAL (натуральный) м REAL (вещественный) Тип BOOLEAN состоит из значений TRUE (истина), FALSE I южь). Все операторы IF (если) в языке должны проверять объекты и in выражения этого типа. Тип BIT состоит из значений 0,1. Значение TRUE типа ВОО- 1 EAN не эквивалентно значению 1 типа BIT, аналогично, значение ! ALSE не эквивалентно значению 0. Тип CHARACTER, по сути дела, представляет набор симво- юв кода ASCII. Числовые типы имеют диапазон (range), или область значений. Примеры. type INDEX is range 0 to 9; — тип целый, type VOLTAGE is range 0.0 to 10.0; — тип вещественный. Физический тип Поскольку VHDL - это язык описания аппаратуры, в нем пре- дусмотрены физические типы. Например, тип TIME (время) может быть описан следующим образом: type TIME is range 0 to 1E20 units fs;
32 Глава 1 ps = lOOOfs; ns = lOOOps; us = 1000ns; ms = lOOOus; s = 1000ms; min = 60s; nr = 60min; end units; В качестве базовой выбрана фемтосекунда (10'5 с). Диапазот (1Е20) обеспечивает максимальный период времени 100 000 < (27,7 ч). Естественно, диапазон ограничивается длиной слова инет рументальной машины. Перечислимые типы Примеры перечислимых типов. type logic_level is (unknown, low, undriven, high); type alu_function is (disable, pass, add, subtract, multiply, di vide); type octal_digit is ('O’, T, '2', ’3’, '4', '5', '6', '7'); Определения некоторых перечислимых типов: type severity level is (note, warning, error, failure); type boolean is (false, true); type bit is ('O', '1'); Составные типы - это тип "массив" (индексируемый тип) i тип "запись" (структурный тип). Массивы Примеры декларации типа "массив".
Основные элементы тыка VHDL 33 type word is array (31 downto 0) of bit; type memory is array (address) of word; type transform is array (1 to 4, 1 to 4) of real; type register bank is array (byte range 0 to 132) of integer; Тип BIT VECTOR определяет массив битов, например B1T_VECTOR (0 to 7). Тип B1T_VECTOR есть тип массива, который неявно описывается следующим образом: type BIT VECTOR is array (NATURAL range o) of BIT; BIT — базовый тип элементов массива, выражение NATURAL i.mge (диапазон натуральный) - это стандартный способ указать, что шина массива будет задаваться диапазоном натуральных чисел. Пользователь должен задавать конкретный диапазон при при- менении такого типа, например, BIT_VECTOR (0 to 3) - возрастающий диапазон, BIT_VECTOR (7 downto 0) - убывающий диапазон. Пример. signal DataBus: bit_vector (7 downto 0); 10 0 10 10 1 7 6 5 4 3 2 1 0 номер разряда DataBus = "10010101" DataBus(7)=’ 1 ’ DataBus(6)=’O’ DataBus(5)=’O’ DataBus(4)=’ 1 ’ DataBus(3)=’O’ DataBus(2)=’ 1 ’ DataBus(l)=’O’ DataBus(0)=’ 1 ’
34 Глава 1 • Примеры массивов, определяемых пользователем (рис. 1.10). signal Memlk4: array(0 to 1023) of bit_vcctor(3 downto 0); Рис. 1.10. Примеры массивов, определяемых пользователем 4kxl6 signal Mcm4kl6: array(0 to 4095) of bit_vcctor( 15 downto 0); Пример двумерного массива. Type TWO_D1MENSION is array (natural range <>, natural range o) of bit; Записи Тип "запись" — это составной тип, состоящий из ряда полей. Примеры декларации типа "запись". type instruction is record op_code: proccssor op; address mode : mode; operand 1, operand?: integer range 0 to 15; end record;
Основные элементы языка VHDL 35 type Instr_T is record Mnemonic: String; Code: Bit_vector (3 downto 0); ExeCycles: Integer; end record; signal Instr 1, Instr2, Instr3: Instr_T; Примеры сигналов типа Instr T Instr 1.Mnemonic:"add regl, rcg2" Instr 1. Code: "0010" Instrl. ExeCycles: 2 Instr2.Mnemonic:"or regl, reg2" Instr2. Code: "0001" Instr2. ExeCycles: 1 Instr3.Mnemonic:"null regl, rcg2" Instr3. Code: "1110" Instr3. ExeCycles: 8 Например, тип DATE (дата) можно описать как, тип "запись", следующим образом: type DATE is record DAY: INTEGER range 1 to 31; MONTH: MONT_NAME; YEAR:1NTEGER range 0 to 3000; end record; Здесь MONTH_NAME (имя месяца) - это перечислимый тип, содержащий имена месяцев. Определение данного перечислимого типа содержится в разд. 2.1 (см. описание оператора case). VHDL предусматривает (см. рис. 1.9) определенные типы файлов (FILE) и типы доступа (ACCSESS). В данной книге они не рассматриваются.
36 Глава 1 Подтипы, конверсия типов Подтип определяется, как тип с ограничением (уточнением) следующим образом subtype имя подтипа is базовый тип [уточнение]; Например, пусть базовый тип определен так Type bigintegcr is range 0 to 2000; Тогда подтип smal!_intcger может быть определен так Subtype small integer is big integcr range 0 to 15; Смешение типов в VHDL - это ошибка. Однако значения под- типа могут быть переданы типу (конверсия типов). Пример, ж Type big_integer is range 0 to 2000; Subtype small_integer is big_integcr range 0 to 15; Signal intermediate : small integer; Signal final: big integcr; • • • Final <= intermediate * 5; — нет ошибки, конверсия типов В данном фрагменте VHDL-кода нет ошибки, так как small integer есть подтип базового типа big_ integer. Если же типы определяются независимо друг от друга, то при- своение значений одного типа другому невозможно, т.с. приводит к ошибке. Пример. Type big integer is range 0 to 2000; Type small integer is range 0 to 15; Signal intermediate : small_integer; Signal final: big_integer; Final <= intermediate * 5; — ошибка, смешение типов
Основные элементы языка VHDL 37 13. Декларации Имеются три класса объектов языка VHDL: • константы; • сигналы; • переменные. С помощью объектов языка VHDL описываются объекты про- екта, т. е. различные подсистемы проектируемой (моделируемой) цифровой системы. Поэтому, естественно, следует отличать объекты проекта от объектов языка VHDL Декларация константы. Общий вид конструкции, употребляемой при декларации кон- стант одного и того же типа constant список констант : тип [ := выражение] ; В VHDL константы подобны константам в других языках 11 рограммирования. Примеры декларации констант. constant PERIOD: constant PI: time:= 100ns; real:= 3.14159; constant WIDTH: integer:=32; constant DEFAULT: bit_yector(0 to 3):= "0101”; constant a, b, c, d : integer := 5; Каждая из декларированных в последней строке констант а, Ь, с, d равна 5. Если символов ":=" нет в декларации константы, то константа называется задержанной. Такие константы могут быть в разделе декларации пакета. Соответствующая полная декларация появляется в теле пакета. Если в VHDL-коде символы следуют после выражения, то выражение принимает значение объекта, находящегося справа от
38 Глава 1 данных символов, при этом, естественно, не должно быть смешения типов. Декларация переменной Общий вид конструкции, употребляемой при декларации пе- ременных variable список переменных : тип [ := выражение]; Переменная в VHDL подобна идентификатору, употребляе- мому в других языках программирования высокого уровня. Значе- ние переменной может быть инициализировано и изменено немед- ленно после выполнения предложения, присваивающего перемен- ной новое значение. Примеры декларации переменных variable ROM, COLUMN: integer range 0 to 31; variable COUNT : positive :=100; variable MEMORY : TWO DIMENSION (0 to 15, 0 to 31); variable a, b, c, d: bit:=T; Каждая из декларированных в последней строке битовых пе- ременных а, Ь, с, d равна 'Г. Декларация сигнала Общий вид конструкции, употребляемой при декларации сиг- налов одного типа signal список сигналов : тип [register | bus] [ := выражение]; В необязательной опции [register | bus] может быть указано только одно из ключевых слов - либо слово register, либо слово bus. Концепция сигнала в VHDL является одной из самых важных. Сигналы подобны (соответствуют) физическим линиям (проводин-
I Основные элементы языка VHDL 39 кам), которые соединяют элементы схемы. Сигналы и переменные будут рассмотрены далее. Примеры декларации сигналов. signal CLK, RESETn: bit; signal COUNTER: integer range 0 to 31; signal RAM : TWO-DIMENSIONAL (0 to 15, 0 to 31); signal INSTRUCTION: bit_vcctor (15 downto 0); signal a, b, c, d: bit :='0’; Как видно из последней строки примера, сигналам при декла- рации может быть присвоено начальное значение. Декларация компонента Общий вид конструкции, употребляемой при декларации ком- понента component имя компонента generic (список параметров); port (список портов); end component; Список портов, начинающийся с ключевого слова port, опре- деляет имя, направление (режим - mode) и тип каждого порта. Тип порта - это тип сигнала, ассоциированного с данным портом. На- правление порта может быть: in - входной порт, out - выходной, inout - двунаправленный, linkage, buffer. Компоненты, имеющие направления портов linkage или buffer, в данной книге не будут рас- сматриваться. Компоненты декларируются в архитектурном теле прежде оператора begin. Ключевое слово generic служит для переда- чи параметров, чаще всего таких, как разрядность, число полюсов и других настраиваемых параметров. Примеры настраиваемых пара- метров будут даны позже. Компонент является частью проекта. Его реализация осуществляется соответствующим entity и одним либо несколькими архитектурными телами.
40 Глава 1 ! В entity и декларируемом компоненте должны совпадать специ- фикации. 1.4. Интерфейс и архитектура объекта Понятие entity определяется как "интерфейс объекта проекта". В entity описывается интерфейс между объектом проекта и окруже- нием, в котором употребляется объект. "Внутренность" объекта в entity не описывается и может быть уподоблена "черному ящику". Термин "архитектура" безотносительно к языку VHDL может быть определен как распределение функций, реализуемых системой, по отдельным ее уровням и точное определение границ между этими уровнями. К термину "архитектура" близок термин "структура", пони- маемый как совокупность элементов системы и связей между ними. Архитектура - это структура системы на функциональном уровне ее описания. Архитектурное тело (architecture) определяет тело объекта, т. е. раскрывает внутренность "черного ящика". В архитектурном теле описываются функции (поведение) либо структура объекта проекта. В приведенном ниже примере архитектурные тела RTL1, RTL2 задают поведение схемы, представленной на рис. 1.11. Архи- тектурные тела, в данном примере это RTL1, RTL2, могут быть раз- личными, задавая одно и то же поведение. Пример. entity ANDOR is port (х 1, х2, хЗ : in bit; f : out bit); end ANDOR; architecture RTL1 of ANDOR is begin f <= (xl and x2) or x3; cndRTLl;
Основные элементы языка VHDL 41 architecture RTL2 of ANDOR is signal \v : bit; begin w <= xl and x2; pl : process (w, x3) begin f <= w or x3; end process pl; end RTL2; Рис. 1.11. Комбинационная логическая схема В entity (в разделе деклараций) наряду с декларацией портов могут быть декларированы параметры. Для декларации таких пара- метров употребляется ключевое слово generic (настраиваемый). С помощью generic могут передаваться такие параметры, как ширина (разрядность) шины, число входных либо выходных полюсов, за- держки элементов и т. д. Пример декларации объекта с настраиваемым (изменяемым) параметром N. entity Cate is generic (N: Natural:=4);
42 Глава 1 port (Inputs: in bit_vector ( 1 to N); Result: out bit); end Cate; Изменяя параметр N, можно получать объект Cate с различ- ным числом входов. При этом вносить другие изменения в VHDL- код нет необходимости. Пример "минимальной" декларации объекта entity TestBench is end TestBench; В гл.4, будет показано, что минимальная декларация объекта проекта используется при отладке VHDL-описания. Пример использования generic для описания объекта Processor с переменной шириной шины (рис. 1.12). DataBus б DataBus Рис. 1.12. Объект Processor с переменной шириной шины: а - ширина шины равна 3; б - ширина шины равна 4 а
Основные элементы языка VHDL 43 entity Processor is generic (BusWidth: Integcr:=3); port (DataBus: inout bit_vector (BusWidth-1 downto 0); . . . end Processor; 1.5. Атрибуты Атрибуты - это значения, связанные с поименованным эле- ментом - объектом языка VHDL. В VHDL имеются предопределенные (predefined) атрибуты и определенные пользователем (user-defined) атрибуты. Для построе- ния моделей и моделирования важную роль играют атрибуты сигна- юв. Например, предопределенный атрибут event ассоциируется с каким-либо сигналом (например, с сигналом CLK). Атрибут записы- вается CLK'event. Этот атрибут имеет тип BOOLEAN с значением TRUE, когда значение CLK. изменилось. Атрибут S'last_value (прошлое значение S) - предыдущее зна- чение, которое сигнал имел непосредственно перед последним из- менением S. Относится к тому же самому типу, что и S. Атрибут S'transaction имеет тип bit, атрибут изменяет свое значение в циклах моделирования, в которых происходит изменение (транзакция) S. Атрибут S'stablc(T) имеет тип BOOLEAN. Атрибут имеет ис- тинное значение, если сигнал S стабилен в течение последних Т единиц времени. Если Т=0, атрибут записывается S’stable. Атрибуты сигналов, в том числе и такие, как S’delayed(t), S'quiet(t), S'transaction, S'active(t), S'last_event, S'driving, S'drivingvaluc используются главным образом при моделировании. Пример. На рис. 1.13 показано, как изменяются значения ат- рибутов cx’transaction, ex'event, ex'Iast_value при изменении сигна- ла ех. Временная диаграмма (рис. 1.13) получена в результате моде- лирования следующего VHDL-кода. entity signalex is end signal ex;
44 Глава 1 architecture beh of signal_ex is signal ex, yl, y3 : bit; signal y2 : boolean; begin ex <= 'O' after 20 ns, T after 50 ns, 'O' after 60 ns, 'Г after 80 ns; yl <= ex'transaction; y2 <= ex'event; y3 <= ex'last_value; end beh; n 0 ns Время > — 10 ns 20 ns 30 ns 40 ns 50 ns 60 ns 70 ns 80 ns 90 ns 100 ns <--------1------ I 1--------1--------i I I । ♦..... >2a У3а Рис. 1.13. Изменение сигнала ex и его атрибутов На временной диаграмме (рис. 1.13) значение true сигнала у2 представляется единичным значением, значение false - нулевым значением. Рассмотрим на временной диаграмме (рис. 1.13) измене- ние значения yl - атрибута ’transaction сигнала ех. В момент времени 20ns произошла транзакция сигнала ех (назначение сигнала *0’ after 20 ns), поэтому атрибут изменил свое значение; следующее измене- ние произошло в момент времени 50 ns, т. е. тогда, когда произошло следующее изменение сигнала ех, и т. д. Атрибут ’event (сигнал у2) один раз изменил свое значение, а именно, после того, как первый раз изменилось значение сигнала ех. Атрибут ’last valuc (сигнал уЗ) показывает предыдущее значение сигнала ех. При моделировании и синтезе схем большее значение имеют следующие предопределенные атрибуты типа (табл. 1.4).
Основные элементы языка VHDL 45 Таблица 1.4 Предопределенные атрибуты \ грибут объекта S Тип атрибута Результат S'left такой, как S крайнее левое значение в S S'right »«_ крайнее правое значение в S Slow п _ нижняя граница S'high tl верхняя граница S’ascending boolean true, если S возрастающего диапа- зона, false - в противном случае S’image(x) string текстовое представление значения х типа S S’value(t) базовый тип S значение в S, представленное стро- кой t S’pos(x) integer номер позиции объекта х в S S’val(x) базовый тип S значение в позиции х в S S’succ(x) базовый тип S значение в позиции на единицу больше, чем х pred базовый тип S значение в позиции на единицу меньше, чем х S’leftof(x) базовый тип S значение левой от х позиции в S S’right(x) базовый тип S значение правой от х позиции в S S’base базовый тип S базовый тип S С использованием атрибута ’high в пакете STANDARD опре- юляются подтипы NATURAL, POSITIVE subtype natural is integer range 0 to integer’high; subtype positive is integer range 1 to integer’high; Полезный набор атрибутов относится к массивам (табл. 1.5). Атрибуты A'lcft(N), A’right(N), A*high(N), A’low(N) ассоции- руются с массивом объектов или конструируемым массивом подти- пов. Атрибуты возвращают значение N-ro объекта в массиве. Пара- метр N является необязательным и по умолчанию равен 1. Атрибут S’base возвращает базовый тип TS.
46 Глава 1 Таблица 1.5 Атрибуты типа “массив” Атрибут Результат S'left левая граница S S’right правая граница S S'low нижняя граница S S'high верхняя граница S S’range(n) диапазон индексов n-й размерности S'reverse_rangc(n) перевернутый по направлению и границам диапазон индексов n-й размерности S’lenght(n) длина диапазона индексов размерности п S’ascending (n) true, если S возрастающего диапазона, false - в противном случае Пример. Пусть тип type A_BYTE есть массив бит убывающего диапа- зона (7 downto 0). Тогда A_BYTE'left = A_BYTE'high= 7; A_BYTE'low = A_BYTE'right= 0; * В случае type table is array (1 to 8) of bit; variable array_l : table := ”00001 111"; значением атрибута array_l'left является 1 - левая граница возрас- тающего диапазона. Примеры. 1. Пусть Type TWO_DIMENSION is array (natural range о, natural range о) of bit;
Основные элементы языка VHDL 47 signal RAM: TWO-DIMENSIONAL (0 to 10, 0 to 15); Тогда RAM'left(2) = RAM'low(2) = RAM'low(l) = RAM'low = KAM'left = RAM'lcft(l) = 0; RAM'high(l)= RAM'right(I)=10; RAM'high(2)= RAM'right(2)=15; 2. Пусть Type new_va!ues is (low, high, middle); Тогда значением атрибута ncwvalues'pred (high) является 'low'. 3. Ниже приведен тест для определения значений атрибутов । ина vector, декларированного I у ре vector is array (7 downto 0) of bit; t» * L । лк массив бит убывающего диапазона. < ntity test_attr_vector is end test attr vector; >i chitecture bch of tcst attr vcctor is type vector is array (7 downto 0) of bit; signal x : vector; signal А, В, C, D : integer; dgnal E: boolean; signal F, G, H : integer; begin A <= vector'left; 1i <= vcctor'right; < <= vector'low; I > <= vector'high; I <= vector'range; ( । <= vector'reverse_range; 11 <= vector'lcngth; end beh;
48 Глава I В результате моделирования А=7, В=0, С=0, D=7, F=7, G=(J Н=9. 1 4. Ниже приведен тест для определения значений атрибутов перечислимого типа, состоящего из элементов al, Ы, а2, Ь2, аЗ, ЬЗ w. entity test_attr_scalar is end test_attr_scalar; architecture beh of test_attr_scalar is type ncw_valucs is (al, bl, a2, Ь2, аЗ, ЬЗ, w); signal А, В, C, D : ncw_ values; signal II: integer; signal K, L, M, N, P : new values; begin A <= new_valucs'lcft; В <= new values'right; C <= ncw valucs'low; D <= new_values'high; H <= new_values'pos(b3); К <= new_values'val(2); - - L <= new_va!ues'succ(w); -- bad L <= new_values'succ(b3); M <= ncw_valucs'prcd(b2); — N <= new_values'leftof(a 1); — bad N <= ncw_valucs'lcftof(bl); - - P <= new_values'rightof(w); — bad P <= new_valucs'rightof(b3); .end beh; В строках, оформленных как комментарии, содержатся приме- ры ошибок: неправомерно пытаться определить значение атрибута] 'leftof для элемента al (назначение сигнала N). Также неправомерно “заходить” за правую границу перечислимого типа, т. е. пытаться узнать значения атрибутов 'rightof, 'succ для элемента w (назначение сигналов L.P). В результате моделирования A=al, B=w, C=al, D=w, 11=5,
Основные элементы языка VHDL 49 В некоторых системах моделирования реализация атрибутов может быть иная — в таких системах можно “захбдить” за границы перечислимых типов. Атрибуты, определенные пользователем Если атрибут определяется пользователем, то сначала декла- рируется его тип, а затем определяется значение. Значение может быть сигналом либо другим объектом языка VHDL. Определенный пользователем атрибут при употреблении предваряется знаком (апостроф). Пример, определенного пользователем, атрибута ’two_length signal vect: bit vector (0 to 5); attribute two lcngth : integer; attribute twojength of vect: signal is (vect’length)*2; • • • C <= vcct’two_length; Сигнал С типа integer получит значение 12, так как длина vect’length массива vect равна 6. Атрибуты, определяемые пользователями, могут быть введены не только для сигналов, по и для меток, компонент и т. д. [7]. 1.6. Имена Имена употребляются для обозначения декларируемых объек- юв. Простые имена являются идентификаторами, такими как COUNTER, CLK. Индексированные имена употребляются для обозначения эле- ментов массива, например, RAM(1,3) — элемент двумерного массива, INSTRUCTION^) - элемент одномерного массива. Интервал имен одномерного массива: INSTRUCTION (7 downto 0). Выборка имен используется для выбора полей записи или считывания, а также для выбора элемента библиотеки.
50 Глава 1 Пример. DATE1.MONTH обозначает имя элемента, содержащегося в поле MONTH записи DATE. WORK.DESIGN может обозначать объект проекта DESIGN в библиотеке WORK. Имена атрибутов могут употребляться для обозначения пре- допределенных атрибутов или определенных пользователем атрибу- тов. 1.7. Операторы Набор операторов (операций) в VHDL обеспечивает возмож- ность работы с предусмотренными типами данных. Список операций приведен в табл. 1.6. Строки табл. 1.7 располагаются в порядке старшинства (от низшего к высшему) операторов. Операторы, находящиеся в одной строке, обладают одинаковым старшинством (приоритетом). Таким образом, операции нижней строки табл. 1.7 обладают наибольшим приоритетом и выполняются первыми, в частности, логический опе- ратор not выполняется прежде других логических операторов. Исходя из контекста VHDL-кода следует отличать оператор <= (назначение сигнала и оператор <= (меньше либо равно). Сле- дует также отличать унарные операции присвоения знака +, - от со- ответствующих бинарных операций сложения и вычитания. Замечание. Для устранения неоднозначностей трактовки старшинства операций используются скобки. Например, выражение "A nand В nand С” неверно (синтаксиче- ская ошибка). Данное выражение нс представляет трсхвходовый элемент И-НЕ (трсхвходовую NAND-ячсйку). Правильная запись ’’not (A and В and С) ”. Запись "A nand (В nand С)” не есть то же са- мое, что "(A nand В) nand С".
Основные элементы языка VHDL 51 Таблица 1.6 Операции языка VHDL Обозначение Название not and or nand nor xor xnor логическое HE логическое И логическое ИЛИ логическое И-НЕ логическое ИЛИ-НЕ исключающее ИЛИ эквивалентность (VHDL'93) /= равно не равно меньше меньше либо равно больше больше либо равно * & сложение, присвоение знака + вычитание, присвоение знака - конкатенация * / mod rem *♦ abs умножение деление модуль остаток возведение в степень абсолютное значение
52 Глава 1 Таблица 1.7 Классификация операций_________________ Класс операций Операции Логические and or nand nor xor xnoi (VHDL’93) Сравнения /= Сложения и конкатенации -р — & Присвоение знака — Умножения * / mod rem Смешанные *♦ abs not Примеры арифметических операторов. Сложение (+) RealX2+2.0 - если RealX2 есть сигнал типа вещественный, то число 2 должно быть записано как вещественное lus+3ns — 1003ns Вычилание (-) 8.33-5 — неправильно, оба числа должны быть одного типа Bus Width-1 - допустимо, если BusWidth типа integer Умножение (*) 4*SomeVal Mult*5ns допустимо, если SomcVal типа Integer или Time результат типа Integer либо Real в зависимости от типа Mult
Основные элементы языка VHDL 53 Деление (/) CLK/2 -- тип CLK - Integer 5.0/2.0 — результат - вещественное число 2.5 10ns/2ns -- результат 5 типа Integer, но не Time Модуль (mod) 6 mod 4 - результат 2 6 mod (-4) -- результат -2 (-6) mod 4 - результат 2 Остаток деления (rem) 6 rem 4 6 rem (-4) (-6) rem 4 результат 2 результат 2 результат -2 Экспонента (**) с**0.5 А**2 В**3 неправильно в VHDL эквивалентно А*А эквивалентно В*В*В Абсолютное значение (abs) absl abs(-1) abs(5*(-2)) результат 1 результат 1 результат 10 Следует быть внимательным при переходе от битовых векзо 1>ов к числам: Bit vector (0 to 7); -- возрастающий _____________________ диапазон [1 | 0 | 1 | I | 1 | 1 | 0 | 0 | Число 61 (десятичное), 0 12 3 4 5 6 7 старший разряд справа
54 Глава 1 Bit vector (7 downto 0); — убывающий — диапазон 0 0 0 Число 188 (десятичное) 7 6 5 4 3 2 0 старший разряд слева Логические операторы выполняются для следующих тнпо! данных: • boolean; • bit, bit_vector; • stdjogic, stdjogic vector; • std ulogic, std_ulogic__vector. Логические операторы and, or, xor имеют одинаковое стар шинство и выполняются слева направо в выражениях. Оператор по имеет более высокое старшинство и выполняется прежде други? операторов. В сложных логических выражениях порядок выполне ния операторов регулируется скобками. Рекомендуем читатели применять скобки в затруднительных случаях. Например, для выра жения Z <= A and not В or С; будет только отрицание В, в выражении Z <= A and not (В or С); будет отрицание подвыражения В or С, находящегося в скобках. Операторы сдвига Данные операторы поясним на примере семиразрядного бито вого вектора Му Bus. signal MyBus: bit_vector(7 downto 0) := "01101001";
Основные элементы языка VHDL 55 1<>гический сдвиг влево (Shift Left Logical) оператор sll начало сдвиг на 1 разряд сдвиг на 2 разряда 1>>гичсский сдвиг вправо (Shift Right Logical) оператор srl \рифметический сдвиг влево (Shift Left Arithmetic) начало сдвиг на 1 разряд сдвиг на 2 разряда
56 Глава 1 Арифметический сдвиг вправо (Shift Right Arithmetic) Вращение логическое влево (Rotate Left Logical) ► 10 1 10 10 0 сдвиг на 1 разряд ► 01011010 сдвиг на 2 разряда Обычно операторы сдвига реализуются в виде функций, пр мер вызова такой функции см. в разд. 3.9.
Основные элементы языка VHDL 57 ! обратите внимание на реализацию операторов сдвига. В некото- рых системах моделирования и синтеза данные операторы могут быть реализованы в виде функций. Оператор конкатенации Оператор конкатенации обозначается через &. Пример. BitOnc: bit Data2: bit vcctor( 0 to 7) 0 0 1 0 1 0 1 0 I_____________I Data2: ( 3 to 5) Datal: bit_vector( 0 to 7) 1 0 1 1 0 0 1 0 Datal: (0 to 3) AggVec:bit_vcctor(0 to 7) T 1 0 1 1 0 1 0 1 AggVcc<=(Datal(0 to 3)&Data(3 to 5)&BitOnc); Рис. 1.14. Конкатенация векторов H. Понятие сигнала в языке VHDL Логические сигналы в логических схемах передаются и обра- нываются параллельно.
58 Глава 1 На схеме показаны три логических блока [1]. Если предположить, что входной набор 1 и входной набор ] активизируются одновременно, то логические блоки 1, 2 будут актн визироваться также одновременно. Логический блок 3 будет активизирован, а через блоки 1, 2 мо| гут проходить измененные значения сигналов входного набора 1 s входного набора 2. Таким образом, поток сигналов может проходип через все блоки одновременно. Рис. 1.15. Логическому блоку схемы соответствует процесс языка VHDL Язык описания аппаратуры должен иметь средства для ото бражения такой одновременности. В языке VHDL это требовани реализуется при помощи механизма процессов. Каждый процесс представляет некоторый логический бло моделируемой схемы, причем все процессы выполняются парад лельно (во времени). Три параллельных процесса могут быть описаны следующие образом.
Основные элементы языка V1IDL 59 BLOCK 1: process(Xl,X2,X3) - Х1,Х2,ХЗ список чувствительности блока 1 begin — операторы процесса BLOCK 1 end process BLOCK!; BLOCK2: process(X2,X4) — операторы процесса BLOCK2 end process BLOCK2; BLOCK3: process(Zl,Z2) — операторы процесса BLOCK3 end process BLOCK3; В языке VHDL процесс активизируется, когда происходит из- менение какого-либо сигнала в списке сигналов запуска этого про- цесса. Список сигналов запуска - то же самое, что и список чувстви- тельности (sensitivity list). В общем случае список сигналов запуска • одержит входной набор сигналов соответствующего логического опока. Рассмотрим схему (рис. 1.16). Рис. 1.16. Сигнал Y, имеющий два источника Сигнал У ведет к двум источникам. Каждый источник сигнала имеет свой драйвер. Драйвер - это понятие языка VHDL, связанное с моделированием. Драйвер можно представлять себе как контейнер 11], т. е. как какое-то хранилище - область памяти для хранения зна-
60 Глава 1 чения сигнала. Значения сигнала в данном хранилище изменяет только система моделирования во время процесса моделирования VHDL-кода. Моделирование является событийным. Событием явля- ется изменение какого-либо сигнала. Моделирование в любой вре-^ менной точке осуществляется в два этапа: сначала изменяются драй-^ веры сигналов, затем значения сигналов выдаются “наружу”, т. е туда, где они могут наблюдаться, например, на временных диаграмм) мах. I ! Можно определять только по одному драйверу на сигнал в npo«J цессе. Так как в каждом процессе сигнал должен иметь только один источник, то, в случае, если имеется несколько источников сигнала^ требуется специальная (разрешающая) функция, которая будет вы< числять значение сигнала по значениям этого сигнала из нескольким драйверов. Например, сигнал Y (рис. 1.16) имеет два источника, и соответственно, два драйвера. Для такого сигнала требуется разре4 шающая функция. Подробнее эта проблема будет рассмотрена далей (разд. 3.4). I Каждый процесс может быть в одном из трех состояний: I • выполняющийся; I • активный; • приостановленный. I Выполняющийся - когда система моделирования выполняем процесс. I Активный - когда процесс является ожидающим, чтобы сис тема моделирования его выполнила. Приостановленный — когда он нс является выполняющимся или активным. ] Большинство ЭВМ, на которых работают системы модслира вания, являются однопроцессорными. Параллелизм программы! имитируется. Поэтому только один процесс из нескольких парал лельпых процессов является "выполняющимся" по существу. Рсали зация параллельных процессов происходит следующим образом. |
Основные элементы языка VHDL 61 Параллельные процессы, которые надо "одновременно” вы- полнять, выстраиваются в очередь. Система моделирования выбира- ет процесс из очереди активных процессов и выполняет процесс, тем самым исполняет предложения языка VHDL, относящиеся к данно- му процессу. Другие активные процессы выбираются поочередно. Заметим, что выполненный процесс является приостановленным. Когда очередь активных процессов пуста, считается, что все парал- ^льные процессы выполнились ’’одновременно", и может начаться следующий цикл моделирования. Приостановленный процесс может стать активным, когда изменился хотя бы один из драйверов сигна- юв из списка чувствительности это! о процесса. Рассмотрим простую двухуровневую логическую схему (ем. рис. 1.11) и се описание в языке VHDL в виде параллельных процессов. entity ANDOR is port( xl,x2, хЗ: f: in bit; out bit); end ANDOR; architecture example of ANDOR is signal w : bit; begin pO : w <= xl and x2 after 10 ns; pl : process (vv, x3) begin f<= w or x3 after 20 ns; end process pl; end example; Во время фазы инициализации каждый сигнал из множества (х 1,х2,хЗ} имеет значение 0. Процесс рО вычислит w и приостано- вится. Затем вычисляется значение f через 30ns, так как 10ns выпол- няется процесс р0 и 20ns — процесс pl. Цикл моделирования начина- йся, когда один из сигналов изменится.
62 Глава I Временная диаграмма изображена на рис. 1.17. Заметим, чтс если сигнал х1 при декларации не имеет начального значения, то п< умолчанию он принимает значение левой границы (xl'left) деклари русмого типа. Например, signal I: integer range 0 to 3; - при инициализации значе ние 0; signal X : std_logic; — при инициализации значение V. 10 ns 30 ns 50 ns 80 ns 100 ns 110 ns Время | |----1...|-----1---♦——t - 4——4--------1---1----1 1 I—I- j --------------------------------------------------------- xl 0 ]-------------------------------------- x2 o -------------------- I x3 о -----------------------------------------------—— ------ 1 ----------------------------------------- w 0 ................................................ - — 0 Рис. 1.17. Моделирование схемы ANDOR 1.9. Дельта-задержка Изменим архитектурное тело example для entity ANDOR, уда лив ключевые слова after и конкретные временные задержки, — тел самым логические операции and, or будут срабатывать ’’мгновенно”. architecture DELTA of ANDOR is signal w:bit; begin pO: w<= xl and x2; — нет слова after pl: process(w, x3) begin
Основные элементы языка VHDL 63 f<=w or хЗ; — нет слова after end process pl; end DELTA; Рассмотрим временную диаграмму (рис. 1.18). Рис. 1.18. Временная диаграмма (architecture DELTA) В 80ns входной сигнал х2 изменился, что послужило причиной изменения сигнала w и причиной изменения сигнала f. Эта ситуация очерчена лупой на временной диаграмме (рис. 1.18). Все это случи- юсь точно в то же время. Рассмотрим более подробно, что же про- изошло в момент времени 80 ns. В 80ns входной сигнал х2 изменяется. Начинается цикл модс- шрования. Активизируется процесс рО, выполняется, приостанавли- вается. Сигнал w изменяется в 0. Резонно сказать, что сигнал w из- менился после сигнала х2. Мы будем ссылаться на это время как на время дельта, или дельта-задержку (рис. 1.19).
64 Глава 1 80 ns 1 — — _ | , , xl 0 1 - х2 0 1 хЗ л и 1 - W 0 1 — 1 L " V ' 1 ' f 0 • ее • । е ► и—— Дельта Рис. 1.19. Временная диаграмма, иллюстрирующая понятие "дельта-задержка " Изменение сигнала w служит причиной для процесса pl, кото- рый активизируется, выполняется, приостанавливается. Сигнал f изменяется после изменения сигнала w. Появляется другая дельта-задержка. Понятие дельта-задержки есть основное понятие модели- рования в языке V1IDL. В одно и то же время (физическое) много сигналов могут из- меняться и много процессов могут быть активными. После того как все процессы пришли в сосюянис "приоста- новленный’', система моделирования увеличивает время моделиро- вания. Итак, ответом на вопрос "Что представляет собой дельта- задержка или просто дельта?" является следующее: ! Дельта есть один цикл прогона VHDL-модели. VHDL-модель, имитирующая поведение цифровой системы состоит из множества процессов. Во время прогона модели в данном цикле запускаются все процессы, входные параметры которых изме-
Основные элементы языка VHDL 65 пились с момента выполнения последнего цикла. После того как все процессы выполнены, данный цикл моделирования считается за- вершенным. Следующий цикл начнется после того, как в очередной раз произойдет изменение какого-то входного сигнала для какого-то процесса. Этот период может составлять наносекунды времени мо- делирования или может просто означать, что мы перешли на сле- дующий цикл моделирования, т. е. сделали временной шаг дельта. Шаг величиной дельта образуется, например, при выполнении операторов назначения сигналов (в рассмотренном примере это сиг- налы w, f), не имеющих фразы after. С точки зрения логической схемы дельта - это задержка на одном уровне (каскаде) логики, когда не задана конкретная задержка логического элемента. Параллельные выполнения операторов (назначение сигналов) называются при помощи символов <=. Символы := означают про- цедурное выполнение и называются операторами присваивания зна- чения переменной. Требует ответа еще один важный вопрос: “Где в описаниях на । <ыке VHDL могут быть использованы операторы присваивания шачсний переменным и операторы назначения сигналов?” Ответ: "Операторы присваивания значений переменным раз- решается использовать внутри процессов и в подпрограммах (функ- циях или процедурах)". Оператор назначения сигналов может встречаться в любом месте выполняемого раздела архитектурного тела. Природа оператора назначения сигнала, оператора присваива- ния переменной и блоков процессов дает разработчику VHDL- моделей ряд возможностей выбора [1]. В начале проектирования разработчик может использовать блок процесса, алгоритм которого реализуется при помощи операто- ров присваивания значений переменным, а последний оператор бло- ка есть оператор назначения сигнала, вычисляющий выходной сиг- нал блока. Такой подход применяется на этапе алгоритмического проектирования, не ориентируясь на какую-то конкретную схему. Другой подход заключается в том, чтобы использовать операторы назначения сигналов. Этот подход называется иногда реализацией
66 Глава 1 ’’потока данных” (data flow), он ориентирован на конкретную схему и более целесообразен на этапе логического проектирования. 1 УПРАЖНЕНИЯ 1. Что такое язык VHDL? 2. Для чего предназначен язык VHDL? Выберите правильный ответ. а) только для проектирования заказных СБИС; Ь) только для проектирования программируемых пользовате- лями вентильных матриц; . с) для спецификации аппаратурной части проектируемой циф- ровой системы; I d)/um спецификации системы перед разбиением ее на аппа- ратную и программную части; е) для всех случаев а - d. 3. Что такое VHDL-описанис, VHDL-код? 4. Что такое проект, лист проекта, примитив проекта? | 5. Что такое иерархия проекта? 6. Что такое высокоуровневый синтез? 7. Что такое логический синтез? 8. Что такое структура схемы, функция схемы, поведение схе- мы? 9. Что такое IEEE? 10. Что такое VHDL-компилятор, VHDL-анализатор, система моделирования VHDL-кода? 11. Опишите технологию проектирования цифровых систем с использованием VHDL. 12. Можно ли на языке VHDL написать программу нахожде- ния факториала натурального числа? 13. Что такое ’’синтезируемое подмножество” языка VHDL?
Основные элементы языка VHDL 67 14. Правильно ли утверждение: "VHDL имеет много возмож- ностей для моделирования аналоговых схем" ? 15. Когда были приняты стандарты языка VHDL? 16. Используя примитивы or2, and2, inv, составьте VHDL-код обьекта addl. 17. Какие из следующих операторов являются неправильными п почему? А_А, А_, 9U, А%В, Р8_3, с4, wait, in, OUT 18. Какие из следующих литералов являются неправильными и почему? 12__ООО, 1Е-0, 2#1101#, 5#44#, #3#, 16#F#E3 19. Какие из следующих литералов с плавающей точкой яв- цяются неправильными и почему? 1_'0.00, 1ОО_.О, 1.1Е-2, 2Н#10.11#, 16#F#E2, 1_0.0. 20. Какие из следующих литералов типа "строка бит" являются неправильными и почему? 2"110", В "1101", О"047", H"ABcd", 10"99", "0101" 21. Укажите правильные и неправильные идентификаторы a) Decoder_ 1 b) -Decoder-1 с) 2FFT d) sig_N е) Not_Ack f) Not-Ask g) Sig-#N h) FFT 22. Найдите ошибки в следующем VHDL-коде: entity EXP is end EXP; architecture RTL of EXP is signal А, В, C, D, E, F : bit; signal X, Y, Z, S, T, R : bit; begin R <= A and В and C;
68 Глава 1 S <= В or C or D; T <= A and В or D; Y <= C nor E nor F; X <= A and not В and not C; Z <= F nand E nand B; end RTL; Исправьте их, проверьте результат с помощью VHDL- анализатора. 23. Правильно ли утверждение: Комментарий в языке VHDL начинается и оканчивается двумя дефисами ”? 24. Для каждого из утверждений ответьте, является оно пра- вильным или ложным: а) все элементы массива должны быть одного и того же типа; Ь) значение true типа boolean эквивалентно значению 0 типа bit; с) константы могут употребляться в выражениях. 25. Как специфицируются скалярные типы? Выберите пра- вильный ответ: а) употребляя только понятие диапазона значений; I Ь) употребляя только понятие перечисления элементов; с) употребляя а) и Ь) одновременно. | 26. Какой тип данных, возвращаемых операторами сравнения? 27. Правильно ли, что в языке VHDL разрешено умножение вещественного числа на целое? А если один из операндов имеет тип time? 28. Какой из трех операторов отличается от двух других? a) Z <= not X and not Y; b) Z <= not (X and Y); c) Z<=notXandY; 29. Правильно ли утверждение: "Константе может быть при- своено новое значение, если оно эквивалентно предыдущему значе- нию"? 30. Правильно ли утверждение: "Когда константа деклариру- ется, то достаточно специфицировать ее значение, потому что тип константы косвенным образом определяется через ее значение"?
Основные элементы языка VHDL 69 31. Правильно ли, что логические операторы могут употреб- иться только для типа bit ? 32. Как определяются арифметические операции для типа bit? Правильно ли, что операторы всегда определяются для отдельных конкретных) типов данных языка VHDL ? 33. Можно ли в языке VHDL узнать (проверить) предыдущее значение сигнала, предыдущее значение переменной ? Если "да", то как это делается ? 34. Задан фрагмент VHDL-кода. Variable TIME1, TIME2 : time; a) TIME1 :=Т1МЕ2*2,5; b) Т1МЕ1:= TIME2/4; с) Т1МЕ1:=3.б ns + TIME2; d) TIME 1 := TIME2 * 6.62 ns; Укажите правильные и неправильные строки. 35. Что такое сигнал в языке VIIDL? Чему соответствует сиг- нал в логической схеме? 36. Чем сигнал отличается от переменной? Как записывается оператор присвоения значения переменной? 37. Что такое параллельный процесс? 38. В каких состояниях бывают параллельные процессы? 39. Что такое дельта-задержка? 40. В каких разделах VHDL-кода может встретиться: - оператор назначения сигнала; - оператор присвоения значения переменной? 41. В какой части VHDL-кода необходимо указывать тип сиг- нала, который декларируется? Выберите правильный ответ: а) когда сигнал декларируется; Ь) когда сигнал употребляется первый раз в коде; с) в пакете; d) нет необходимости декларировать тип сигнала. 42. Когда (с точки зрения взаимодействия процессов) сигнал корректируется, т. е. получает то новое значение, которое приобре- 1ст в результате операции назначения сигнала, находящейся внутри процесса?
70 Глава 1 43. Промоделируйте "вручную" параллельные процессы А<=Х*У; B<=A+Z; используя понятие дельта-задержки. Запишите VHDL-код и промо- делируйте его с помощью системы моделирования. 44. Рассмотрите рис. 1.20. Назовите внешние и внутренние сигналы системы А. Ответьте, где декларируются внешние сигналы системы А, где декларируются внутренние сигналы системы А. Укажите интерфейсы для системы А и для подсистем В, С, D. 45. Рассмотрите систему, состоящую из телевизора и перенос- ного кнопочного пульта, с помощью которого осуществляется управление телевизором. Укажите entity и architecture для данной системы. TL7 TL9 TL8 ’ис. 1.20. Структура цифровой системы А 46. Рассмотрите персональный компьютер, как систему, со- стоящую из системного блока, монитора и клавиатуры. Укажите en- tity и architecture для данной системы.
Глава 2 Последовательные и параллельные операторы 2.1. Последовательные операторы В VHDL последовательные операторы подобны операторам языков высокого уровня. На рис. 2.1 приведена общая структура VHDL-описания, из которой следует, что последовательные опера- торы (sequential statement) могут появляться внутри операторов про- цесса или внутри тел подпрограмм (функций, процедур). На данном рисунке указаны основные параллельные и после- довательные операторы. Перечислим последовательные операторы: 1) оператор присвоения значения переменной; 2) оператор назначения сигнала, т.е. присвоения значения сиг- налу; 3) оператор if (если); 4) оператор case (случай); 5) оператор loop (цикл); 6) оператор next (следующий); 7) оператор exit (выход); 8) оператор null (нуль, пустой); 9) оператор вызова процедуры; 10) оператор return (возврат); 11) оператор assert (сообщение); 12) оператор wait (ожидать).
72 Глава 2 Пакет (необязательно) Интерфейс (entity) объекта проекта Архитектурное зело (architecture) Декларации компонент, внутренних сигналов и т.д. Параллельные операторы Конкретизация компонента Условное назначения сигнала Выборочное назначение сигнала Оператор генерации и др. Оператор процесса Декларации переменных Последовательные операторы Назначение сигнала Присваивание значения переменной Вызов процедуры Оператор ожидания (wait) Оператор if, case, loop, next и т.д. Рис. 2.1. Структура VHDL-описания Оператор присваивания значения переменной Определение. variablcassignment statement: := [label] target := expression ; Данный оператор заменяет текущее значение (target) перемен- ной новым значением, которое определяется выражением (expression). Переменная и выражение должны быть того же базово- го типа
Последовательные и параллельные операторы 73 Еще раз напомним, что присваивание значения переменным не есть то же самое, что сигналам. Присваивание значений сигналам мы обсудим в следующем разделе. В VHDL локальные переменные могут быть только деклари- рованы в области операторов процессов и подпрограмм (функций или процедур). В следующем VHDL-коде приведены примеры присваивания значений переменным. Слева указаны номера строк, нс относящиеся к тексту на языке VHDL. 1 entity VAR is 2 end VAR; 4 architecture functional of VAR is 5 signal A, B, J : bit vector(l downto 0); 6 signal E, F, G : bit; 7 begin 8 pO : process (А, В, E, F, G, J) 9 variable C, D, H, Y : bit_vector(l downto 0); 10 variable W, Q : bit_vector(3 downto 0); 11 variable Z : bit_vector(0 to 7); 12 variable X : bit; 13 variable DATA : bit_vcctor(31 downto 0); 14 begin 15 C :="1T’; 16 X :=EandF; 17 Y := H nand J; 18 Z(0 to 3) := C & D; - конкатенация 19 Z(4 to 7) := (not A) & (A nor В); - конкатенация 20 D :=('0’,'0'); - агрегат 21 W := (2 downto 1 => G, 3 => 'Г, others => '0'); - агрегат 22 DATA := (others =>' Г); -- агрегат 23 end process; 24 end functional;
74 Глава 2 В строке 15 переменная С получает константное значение. Выражения в строке 16, 17 используют логические операторы. В строке 18 в выражении употребляется оператор & конкате- нации, чтобы присвоить значения первым четырем битам перемен- ной Z. В строке 19 употреблена комбинация логических операторов и конкатенация. Строка 20 показывает агрегат, в котором употребляется пози- ционное отображение (соответствие). Запись (’О’, '0') называется аг- регатом. Агрегат заключается в круглые скобки, входящие в агрегат элементы разделяются запятой. В строке 21 употребляется позиционное отображение и клю- чевое слово others. В строке 22 всем компонентам битового вектора - переменной DATA - присваивается значение нуль. Заметим, что локальные переменные ’’видны" только внутри процессов или подпрограмм, которые декларированы. VHDL‘93 оп- ределяет другой класс переменных, называемых shared (совместно используемые, общие), которые могут совместно использоваться (видны) с процессами и подпрограммами. Понятие "видимости" бу- дет рассмотрено далее. Агрегаты и конкатенация могут использоваться нс только при присвоении значений переменным, но и при назначении сигналов для таких типов данных, как массивы. Рассмотрим пример агрегата. Variable z bus : bit_vector (3 downto 0); Variable A,B,C,D : bit; • z bus := (A,B,C,D); - агрегат Запись (A,B,C,D) является агрегатом. Присваивание значений сигналам (назначение сигналов) В языке VHDL в операторах назначения сигналов, т. е. в опе- раторах присваивания значений сигналам используются два вида задержек: • инерционная задержка; • транспортная задержка;
Последовательные и параллельные операторы 75 Ключевое слово inertial определяет инерционную задержку, ключевое слово transport определяет транспортную задержку. Пример. 4 Х<= inertial Y after 3 ns; — инерционная задержка Х<= transport Y after 3ns; -- транспортная задержка. В случае инерционной задержки передача сигнала будет иметь место, если и только если входной сигнал будет сохранять соответ- ствующий уровень в течение заданного отрезка времени. В языке VHDL этот заданный отрезок времени и есть задержка, указываемая во фразе after. Таким образом, в первом примере изменение значения Y по- действует па значение X только в случае, если новый уровень Y бу- дет сохраняться в течение 3ns и более. Во втором примере (транспортная задержка) все изменения Y будут передаваться в X независимо от того, сколько времени будет сохраняться новое значение Y. 4 ! Если не используется ключевое слово transport, то подразумева- ется инерционная задержка. Пример Х<= Y after 3 ns; — инерционная задержка Как отмечено в [1], механизм инерционной задержки позволя- ет отфильтровывать входные сигналы, которые меняются слишком быстро. Данный механизм по существу имитирует работу реальной схемы. Логический сигнал представляется на схемном уровне на- пряжением узла. Ввиду наличия электрических емкостей напряже- ния узлов не могут изменяться мгновенно; необходимо, чтобы опре- деленное количество энергии подавалось в течение определенного отрезка времени, - только в этом случае напряжение узла изменится настолько, чтобы вызвать переключение схемы, управляемой этим
Глава 2 ?6 - Напряжением. Поэтому при моделировании реальных логических гхем используется инерционная задержка. Транспортная задержка чаще используется на этапе алгорит- мического проектирования. Укажем различия между локальными переменными и сигна- лами. 1. Локальные переменные декларируются н видны только внутри процесса или подпрограммы. Сигналы не могут быть декла- рированы внутри процесса или подпрограммы. 2. Новое значение локальной переменно}! немедленно коррек- тируется, когда выполняется оператор присваивания. Понятие вре- мени не ассоциируется с понятием переменной. (Оператор назначе- ния сигнала корректирует сначала драйвер сигнала. Когда процесс Станет приостановленным, сигнал корректируется. По ному исполь- зование сигналов ведет к двухпроходному моделированию. С точки Зрения системы моделирования переменные применя ть " дешевле". 3. Только сигналы могут употребляться для связывания парал- лельных операторов. * Порты, декларируемые в entity, являются сигналами. Аргументы подпрограмм могут быть сигналами или переменными. 4. В VHDL-описаниях логических (цифровых) схем сигнал Употребляется для описания соединений элементов. Локальные пе- ременные обычно употребляются как временные значения в алго- ритме описания функции. Пример. (Различие между локальной переменной и сигна- лом). Данный VHDL-код Y<= A+(B*C+D*E*F+G); Z<= A-(B*C+D*E*F+G); Эквивалентен следующему VHDL-коду V:=(B*C+D*E*F+G); Y<= A+V-
Последовательные и параллельные операторы 77 Y<= Л- V; однако не эквивалентен приведенному ниже VHDL-коду V<=(B*C+D*E*F+G); Y<= A+V; Z<= A - V; Замечание. Запись x <= у <= z понимается нс как "конвейер- ное" назначение сигналов. Правильное понимание: сигналу х при- сваивается значение, равное значению выражения y<=z (у меньше либо равно z). Назначение сигналов в случае массивов, например битовых векторов, является позиционным. Пример. Signal z_bus : bit_vector (3 downto 0); Signal c_bus : bit_vector (1 to 4); z_bus <= c_bus; эквивалентно z_bus(3) <=c_bus(l); z_bus(2) <=c_bus(2); z_bus( 1) <=c_bus(3); z_bus(0) <=c_bus(4); При назначении сигналов должно указываться то направление диапазона (возрастающий диапазон — to, убывающий диапазон - downto), которое было при декларации массива. Для предыдущего примера z_bus (3 downto 2) <= "00"; — правильно e bus (2 to 4) <= z bus (3 downto 1); — правильно z_bus (0 to 1) <= "11"; — неправильно, так как z bus декларирован с убывающим диапазоном Сигналы и переменные одною и того же типа могут быть при- своены один другому. Пример использования агрегатов при назначении сигналов. Signal z_bus : bit_vector (3 downto 0);
78 Глава 2 Signal A,B,C,D : bit; z_ bus <= (3 => T, 1 downto 0 => 'Г, 2 **> B); — агрегат Оператор if (если) Общий вид оператора if: if условие then упорядоченное множество последовательных операторов {elsif условие then упорядоченное множество последовательных операторов} [else упорядоченное множество последовательных операторов] end if; Оператор if языка VHDL подобен операторам if в других язы- ках программирования. Выражение, представляющее собой “условие” должно иметь тип BOOLEAN. В одном if операторе может быть одна (ни одной) либо более частей elsif. Ключевое слово elsif слсдус! отличать от слов else if. Часть else может быть только одна (или пи одной). Дол- жен быть разделитель между ключевыми словами в заключительной фразе end if; Следующая модель 5-битового счетчика употребляет if опера- торы [9]. entity IFSTMT is . port ( RSTn, CLK, EN, PL : in bit; DATA : in integer range 0 to 31; COUNT : out integer range 0 to 31); end IFSTMT; architecture RTL of IFSTMT is signal COUNT_VALUE : integer range 0 to 31; begin pO : process (RSTn, CLK) I
Последовательные и параллельные операторы 79 begin if (RSTn = '0') then COUNTVALUE <= 0; elsif (CLK'event and CLK = ’Г) then if (PL = T') then COUNT VALUE <= DATA; elsif (EN = T) then if (COUNT_VALUE = 31) then COUNT VALUE <=0; else COUNT VALUE <= COUNT_VALUE + 1; end if; end if; end if; end process; COUNT <= COUNT, VALUE; end RTL; Как показано в разделе деклараций, 5-битовый счетчик имеет порты RSTn, CLK, EN, PL, DATA. Выходной порт COUNT получает значение счетчика, RSTn - асинхронная установка (в нуль), CLK - входной сигнал синхронизации, PL - параллельное считывание, DATA - порт данных. Оператор case (случаи) Общий вид оператора case: case выражение is when выбор => упорядоченное множество последовательных операторов [when выбор => упорядоченное множество последовательных операторов ] end case; Оператор case выбирает одну из альтернатив, избранная аль- тернатива (случай) определяется значением выражения. Выражение
80 Глава 2 должно быть дискретного типа или типа одноразмерного массива символов, значения которых могут быть представлены как строки или строка битов. Выбор должен быть такого же типа, как выраже- ние. Все возможные выборы (случаи) должны быть перебраны. Для случая ’’others" (другие) должно быть такое значение, которое нс соответствует предыдущим альтернативам. Оператор case является подходящим для моделирования ко- нечных автоматов и программ микропроцессора. Используя опера- тор case, приведем пример [9] VHDL-кода для вычисления числа дней в каждом месяце. package PACK is type month_type is (JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC); end PACK; use work.PACK.all; entity CASESTMT is port ( MONTH : in month type; LEAP : in boolean; DAYS : out integer); end CASESTMT; architecture RTL of CASESTMT is begin pO : process (LEAP, MONTH) begin case MONTH is when FEB => if LEAP then DAYS <= 29; else DAYS <= 28; end if;
Последовательные и параллельные операторы 81 when APR | JUN | SEP | NOV => DAYS <= 30; when JUL to AUG => DAYS <=31; when others => DAYS <=31; end case; end process; end RTL; Оператор loop (цикл) Общий вид оператора loop: [метка miKna:][while условие | for идентификатор in диапазон дискретного типа] loop упорядоченное множество последовательных операторов end loop [метка цикла]; Когда в записи цикла используется ключевое слово while, то сначала вычисляется условие (condition). Если условие есть TRUE, выполняется последовательность последовательных операторов, иначе оператор цикла завершается. Когда в записи цикла используется ключевое слово for, то идентификатор определяет цикловой параметр с базовым дискрет- ным типом. Параметр цикла употребляется как константа внутри действия оператора цикла и он не может быть целью оператора при- сваивания. ! Общая ошибка: употребление параметра цикла снаружи оператора цикла. Пример. loopl: for i in 0 to 9 loop exit loopl when A(i)>20;
82 Глава 2 next when A(i)>10; sum:=sum +A(i); end loop loopl; if i=20 then — ошибка! Параметр цикла снаружи цикла. Оператор next (следующий) Общий вид оператора next: next [метка цикла ][when условие]; Пример дан выше. Оператор next употребляется для заверше- ния итераций цикла. Оператор exit (выход) Общий вид оператора exit: exit [метка цикла ] [when условие]; Оператор EXIT употребляется, чтобы завершись выполнение и закрыть оператор цикла. Если условие (condition) есть TRUE, то осуществляется выход из цикла. Оператор null (пустой) Общий вид оператора null (нуль, пустой): null; • Оператор null не представляет действий. Он употребляется, чтобы точно специфицировать, что нет действий. Типичное приме- нение - в операторе case, чтобы определить действия во всех случа- ях. Оператор вызова процедуры Оператор вызова процедуры состоит из имени процедуры с аргументами (если они есть) в скобках. Приведем пример определе- ния и вызова функции и процедуры.
Последовательные и параллельные операторы 83 entity CALL_PRO is end CALL_PRO; architecture RTL of CALL PRO is function bit_bool (inp_bit: in bit) return boolean is begin if (inp_bit = T) then return true; else return false; end if; end bit_bool; procedure lefl_one ( signal DATA : in bit vector (1 to 8); signal l_bit: out integer) is variable temp: integer; begin temp := 0; for i in 1 to 8 loop if (DATA(i) = T) then temp := i; end if; if (temp /= 0) then exit; end if; end loop; l_bit <= temp; end left one; signal DIN : bit_vector (1 to 8); signal bit_l : bit; signal bool_l : boolean; signal DOUT: integer; begin pO: process (bit_l,DlN)
84 Глава 2 begin bool_l <= bit_bool(bit_l); - вызов функции LEFT_ONE(DIN, DOUT);. -- вызов процедуры end process; pl: process begin bit_l <= T after 20 ns, 'O' after 40 ns; DIN <= "01010000" after 20 ns, "00000000" after 40 ns, "00001100" after 60 ns, "00000001" after 80 ns; wait for 100 ns; end process; end RTL; Функция bit_bool преобразует тип BIT в тип BOOLEAN. Предлагаем читателю провести моделирование, проанализировать временную диаграмму и определить функциональное назначение процедуры leftonc. Оператор return (возврат) Общий вид оператора return: return [выражение]; "Употребляется, чтобы завершить выполнение самой внут- ренней функции или процедуры. Он используется только внутри тела функции или процедуры. Оператор return не требуется в теле процедуры, поэтому в архитектурном теле RTL (entity RETURNSTMT) соответствующая строка может быть удалена. Оператор return может быть употреблен с другими последова- тельными операторами, такими как if, case для управления возвра- том функции или процедуры.
Последовательные и параллельные опера юры 85 Оператор assert (сообщение) Общий вид оператора assert: assert условие [report выражение ] [severity выражение ]; Операторы сообщений проверяют, является ли условие истин- ным (TRUE), и сообщают об ошибке, если условие является лож- ным По умолчанию сообщенное выражение есть "Assertion viola- tion" (нарушение). Выражение с ключевым словом severity (severity - степень серьезности) имеет перечислимый тип: NOTE, WARNING, ERROR, FAILURE. Примеры. assert (CLK’evcnt and CLK—O') report ‘D hold error" severitv WARNING; assert (CLK'Iast_event > HOLD) report "D hold error" severity ERROR; В данных примерах атрибут CLK’last evcnt имеет тип TIME и возвращает время, пройденное с момента последнего изменения сигнала CLK, HOLD - имеет тип TIME. Условие LK’last_event>IIOLD может быть либо истинным, либо ложным. Следующие два оператора (две строки) эквивалентны: report "NEW YEAR 3003" severity ERROR; assert FALSE report "NEW YEAR 3003" severity ERROR; 1акже, как и следующие: report "NEW YEAR 2002"; assert FALSE report "NEW YEAR 2002" severity NOTE; Так как FALSE всегда является ложным, то данные сообщения всегда выдаются — это примеры безусловно выдаваемых сообщений.
86 Глава 2 Оператор wait (ожидать) Общий вид оператора wait: wait on список чувствительности until условие for тайм-аут ; Оператор wait является причиной временного прекращения оператора процесса или процедуры. Оператор ожидания wait приос- танавливает процесс до момента, пока не изменится некоторый сиг- нал в списке чувствительности процесса, в это время будет произве- дено вычисление условия. Фраза “условие” есть выражение типа BOOLEAN. Если получается истинное значение, выполнение про- цесса возобновляется. Фраза “тайм-аут” устанавливает максималь- ное время ожидания, после которого процесс возобновит свое вы- полнение. Пример. WAIT on А, В until (С=0) for 50 ns; Этот оператор приостановит процесс до момента изменения А или В, после чего будет проверено выражение С=0 и, если результа- том проверки будет истина, процесс возобновится. Но независимо от этих условий возобновление процесса произойдет через 50ns. Допустимо записывать одно или более условий в операторе ожидания, например, Условие 1. • Условие 2. Условие 3. WAIT on А, В; WAIT until (С=0); WAIT for 50 ns; В условии 1 процесс будет возобновляться, когда изменится А или В. В условии 2 нет списка сигналов запуска, поэтому процесс во- зобновится, когда С изменит свое значение из 1 в 0. В условии 3 процесс возобновится через 50ns независимо от любых других условий.
Последовательные и параллельные операторы 87 В цифровых системах логические процессы часто приостанав- ливаются в своем выполнении, ожидая истечения некоторого перио- да времени или наступления некоторого события. После истечения указанного периода времени или наступления ожидаемого события выполнение процесса возобновляется. Эта ситуация иллюстрируется следующим образом process--- — начало выполнения процесса wait — оператор ожидания ---------- возобновление выполнения процесса end process; — конец выполнения процесса ! Для оператора процесса мы можем иметь либо список чувстви- тельности после ключевого слова процесс. либо оператор wait, но не оба вместе. Может быть более одного оператора wait внутри оператора процесса. Примеры оператора wait. 1. Оператор wait типа for wait for 10ns; wait for CLK_Period/2; 2. Оператор wait типа until wait until CLK=T; wait until CE and (not RST); wait until IntData>16;
88 Глава 2 3. Оператор wait типа on wait on CLK; wait on Enable, Data; wait until Enable - Г; эквивалентно loop wait on Enable; exit when Enable = ‘ 1 end loop; 4. Комбинированный оператор wait (комбинация двух или трех предыдущих) wait on Data until CLK-Г; wait until CLK-Г for 10ns; 2.2. Параллельные операторы Параллельные операторы в VHDL определяют параллельное (во времени) поведение схем. ! Порядок выполнения параллельных операторов не связан с поряд- ком их появления внутри архитектурного тела. Параллельные операторы активизируются сигналами, которые употребляются для связи параллельных операторов. Последователь- ные операторы выполняются в порядке их появления в VHDL-коде. Перечислим параллельные операторы: 1) оператор process (процесс); 2) оператор параллельного сообщения; 3) оператор параллельного вызова процедуры; 4) оператор условного назначения сигнала; 5) оператор select выборочного назначения сигнала; 6) оператор конкретизации (создания экземпляра) компонента;
Последовательные и параллельные операторы 89 7) оператор generate (генерации); 8) оператор block (блок). Параллельный оператор process Общий вид оператора process (процесс): [имя процесса :] [postponed] process [(список чувствительности)] раздел деклараций begin упорядоченное множество последовательных операторов end process [имя процесса]; Оператор процесса есть параллельный оператор, который оп- ределяет независимое последовательное поведение некоторой части проекта, описанное упорядоченной совокупностью последователь- ных операторов. Метка процесса необязательна, однако, если она есть в конце (после слов end process), то она должна быть и вначале перед словом process. В декларативной части процесса могут быть: • тела подпрограмм; • декларации подтипов; • декларация констант; • декларация файлов; • декларация альтернативных точек входа в подпрограмму; • декларация атрибутов; • спецификации атрибутов. • . Процесс может иметь список сигналов запуска и один (или более) операторов ожидания, по не оба вместе. ! Сигналы не могут быть декларированы внутри процессов. ! Ожидание (wait) в начале процесса нс эквивалентно ожиданию в списке чувствительности процесса. Ключевое слово postponed характеризует отложенный про- цесс. Если имеется несколько параллельных процессов и среди них
90 Глава 2 отложенный, то отложенный процесс активизируется только последней дельта-задержки временной точки [7]. в течение process(signal_l) statemcnt_l; statement-?; • • • statementn; end process; эквивалентно process statement!; statement_2; • • • statement n; wait on signal_l; end process; process(signal_l) statement!; statement_2; Л • • statement_n; end process; не эквивалентно process wait on signal_l; statement_l; statement?; • • • statement n; end process; Оператор параллельного сообщения Синтаксис оператора параллельного сообщения (assert) такой же, как и у оператора последовательного сообщения. ’’Параллельность" заключается в том, что оператор assert мо- жет присутствовать в параллельных процессах. Оператор параллельного вызова процедуры Общий вид оператора: [метка:] оператор вызова процедуры Оператор параллельного вызова процедуры представляет про цесс, содержащий оператор последовательного вызова процедуры Его выполнение эквивалентно оператору процесса. Иначе говоря, процедуры могут вызываться параллельно. Пример. 1 entity call_parallel is
Последовательные и параллельные операторы 91 2 port ( data inp : in bit vector(5 downto 0); 4 data_out: out bit_vector(l downto 0)); 5 end call_parallel; 6 architecture RTL of call_parallel is procedure N_XOR ( 8 signal xl, x2, x3 : in bit; 9 signal f : out bit) is 10 begin 11 f<=xlxorx2 хогхЗ; 12 end N_XOR; 13 begin 4 N_XOR (xl => data_inp(5), x2 => data_inp(4), x3 => data_inp(3), 15 f => data_out( I)); 16 pO : N XOR (datajnp(2), data_inp( 1), data_inp(0), data_out(0)); 17 end RTL; В строках 14, 16 осуществляется параллельный вызов проце- дур. В строке 16 параметры передаются позиционным сопоставле- нием, в строке 14 передача параметров осуществляется сопоставле- нием имен: вместо параметра xl передастся data_inp(5), вместо х2 передается data_inp(4) и т.д. ! Каждый формальный параметр процедуры должен быть типа кон- станты или сигнала. Декларация процедур и тела процедур будут обсуждены далее. Параллельный оператор условного назначения сигнала Общий вид оператора: [guarded][transport] {назначение сигнала when условие else} сигнал;
92 Глава 2 Оператор параллельного назначения сигнала эквивалентен оператору процесса, назначающему значения сигналам. Могут быть употреблены опции guarded (охраняемый) transport (транспорт- ный). Пример, показывающий эквивалентность параллельного опе- ратора условного назначения сигнала (архитектурное тело first) и оператора процесса (архитектурное тело second). entity example_condition is port ( xl, x2, x3, x4 : in bit; condition : in bit_vector(l downto 0); F : out bit); end cxample_condition; architecture first of cxample condition is begin F <= xl when condition = ”00" else x2 when condition - "01" else x3 when condition = "10" else x4; end first; architecture second of example_condition is begin process (xl, x2, x3, x4, condition ) begin if (condition = "00") then F<=xl; elsif (condition = "01") then F <= x2; elsif (condition - "10") then F <= x3; else F <= x4; end if; end process; end second;
Последовательные и параллельныс операторы 93 В примере все условия (condition) являются различными, по- этому сигнал F получает одно из значений из множества {xl, х2, хЗ, х4}. Какое же значение получит сигнал, если в нескольких местах будет удовлетворяться условие? Ответ следующий: будет выпол- няться назначение для первого выполненного условия. Параллельный оператор select выборочного назначения сиг- нала Общий вид оператора select (выбирать): with выражение select имя сигнала <= [guarded][transport] {имя сигнала when условие выбора, } имя сигнала условие выбора; Данный оператор эквивалентен оператору процесса. Пример, показывающий эквивалентность параллельного опе- ратора выборочного назначения сигнала (архитектурное тело first) и оператора процесса (архитектурное тело second). entity example_selection is port ( xl, x2, x3, x4 : in bit; selection : in bit_vector(l downto 0); F : out bit); end cxamplc_selection; architecture first of example selection is begin with selection select F <= xl when ”00”, x2 when ”01”, x3 when ”10”, x4 when others; end first; architecture second of example_selection is begin о process (xl, x2, x3, x4, selection)
.4 Глава 2 begin case selection is when "00" => F<=xl; when "01" => F<=x2; when "10" => F<=x3; when others => F <= x4; end case; end process; find second; Параллельный оператор конкретизации компонента Общий вид оператора конкретизации компонента (оператора создания экземпляра компонента): метка: имя компонента [generic (список параметров);] [port map (список портов)]; Этот оператор употребляется для структурной организации Проекта. Часть схемы (подсхема) описывается как компонент (com- ponent), имеющий имя (name). Одна и та же подсхема может входить П схему несколько раз, однако, при этом она имеет различные связи. Чтобы описать эти связи, употребляется оператор создания экземп- ляра компонента (оператор конкретизации компонента), т.е. име- ется в виду конкретизация связей данной подсхемы. Соответствие портов при создании экземпляров компонентов может быть осуществлено: • позиционным сопоставлением; • ключевым соответствием, с использованием оператора • Пример ключевого соответствия портов при создании экземп- ляров компонентов. р 1: A port map (х 1 => х 1, у 1 =>w); - ключевое соответствие р2: В port map (х2 -> w, y2=>z); - ключевое соответствие рЗ: С port map (y3=>v, хЗ => z); - ключевое соответствие
Последовательные и параллельные операторы 95 Сделаем пояснения. При создании экземпляра компонента А портам х 1, у 1 компонента А ставятся в соответствие сигналы xl, w. При создании экземпляра компонента В портам х2, у2 компонента В ставятся в соответствие сигналы w, z (рис. 2.2). При ключевом соот- ветствии порядок перечисления портов нс играет роли, поэтому при ключевом соответствии портов можно сначала указать выходной порт, как это сделано при создании экземпляра компонента С. Рис. 2.2. Конкретизация (создание экземпляров) компонентов Пример позиционного сопоставления (соответствия) портов при создании экземпляров компонентов (рис. 2.2). pl: A port map(xl,w); — позиционное соответствие р2: В port map(w,z); — позиционное соответствие рЗ: С port map(z,v); — позиционное соответствие Рассмотрим 8-разрядный сдвиговый регистр (рис. 2.3), в со- став которого входит восемь подсхем - D-триггсров (элементов па- мяти) [9]. D-триггер имеет имя DFF. SI —► Clk Ru Рис. 2.3. Сдвиговым регистр
96 Глава 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 entity DFF is port ( RSTn, CLK, D : in bit; Q : out bit); end DFF; architecture RTL of DFF is begin process (RSTn, CLK) begin if (RSTn = '0') then Q <= ’O'; elsif (CLK'event and CLK ='!') then Q<=D; end if; end process; end RTL; entity SHIFT is port ( RSTn, CLK, SI: in bit; SO : out bit); end SHIFT; architecture RTL1 of SHIFT is 24 component DFF 25 port ( 26 RSTn, CLK, D : in bit; 27 Q : out bit); 28 *end component; 29 signal T : bit_vector(6 downto 0); 30 begin 31 bit7 : DFF 32 port map (RSTn => RSTn, CLK => CLK, D => SI, Q => T(6)); 33 bit6: DFF 34 port map (RSTn, CLK, T(6), T(5)); 35 bit5 : DFF 36 port map (RSTn, CLK, T(5), T(4)); 37 bit4 : DFF
Последовательные н параллельные операторы 97 38 port map (CLK => CLK, RSTn => RSTn, D => T(4), Q => T(3)); 39 bit3 : DFF 40 port map (RSTn, CLK, T(3), T(2)); 41 bit2: DFF 42 port map (RSTn, CLK, T(2), T( 1)); 43 bitl : DFF 44 port map (RSTn, CLK, T(1),T(O)); 45 bitO: DFF 46 port map (RSTn, CLK, T(0), SO); 47 end RTLI; Схема SHIFT задает сдвиговый регистр - каскадное соедине- ние D-триггеров (элементов памяти). D-триггер описан в строках 1-16. Сдвиговый 8-битовый регистр специфицирован в строках 18-22. Строки 24-28 декларируют компонент DFF. Строка 29 декларирует 7-битовый сигнал Т, употребляемый для связи между соседними триггерами. Компонент DFF конкретизирован (упомянут) восемь раз, что- бы получить сдвиговый регистр. ! Каждый оператор создания экземпляра компонента должен иметь метку. Метки играют роль имен элементов схемы. Карта портов дается в скобках после ключевых слов port map. Назначение портов компонентов является как позиционным (см. метки bitO, bitl, bit2, bit3, bit5, bit6), так и ключевым (см. метки bit4, bit7). ! Для выходных неиспользуемых портов компонентов нужно упот- ребить ключевое слово open.
98 Глава 2 Следующий фрагмент VHDL-кода показывает, что при созда- нии экземпляра компонента addl на вход Ы можно подать констан- ту 0 и выход с 1 нс использовать. Pl: addl port map (bl => 'O', b2 =>x, si => si, cl => open); Рассмотрим еще один пример - 7-разрядный сумматор, яв- ляющийся каскадным соединением одного полусумматора addl и шести одноразрядных сумматоров add2. Схема данного сумматора изображена на рис. 2.4,а. entity adder_N_comp is port (a,b : in bit vector (0 to 6); s : out bit vector (0 to 6); c : out bit); end addcr_N_comp; architecture structural of adder_N_comp is component addl port (bl,b2: in BIT; cl,si: out BIT); end component; component add2 port(cl, al,a2:in BIT; c2,s2:out BIT); end component; signal c_in : bit_vector (0 to 5); begin pO:addl port map (bl => a(0), b2 -> b(0), cl => c_in(0), si => s(0)); p1:add2 port map (c 1 =>c_in(0),a 1 =>a( 1 ),a2=>b( 1 ),c2->c_in( 1 ),s2=>s( 1)); p2:add2 port map (с 1 =>c_in( 1 ),a 1 =>a(2),a2=>b(2),c2=>c_in(2),s2=>s(2));
Последовательные и параллельные операторы 99 рЗ:add2 port map (cl=>c_in(2),al=>a(3),a2=>b(3),c2=>cjn(3),s2=>s(3)); p4:add2 port map (с 1 =>c_in(3),al=>a(4),a2=>b(4),c2=>c_in(4),s2=>s(4)); p5:add2 port map (cl->c_in(4),al=>a(5),a2=>b(5),c2=>c_in(5),s2=>s(5)); p6:add2 port map (cl=>c_in(5),al=>a(6),a2=>b(6),c2=>c,s2=?>s(6)); end structural; Примеры, приведенные для пояснения оператора создания эк- земпляров компонентов, понадобятся на.м в дальнейшем. Схемы сдвигового регистра и сумматора являются регулярными и могут быть описаны более компактно с помощью оператора генерации, рассматриваемого далее. Параллельный оператор generate Общий вид оператора generate (генерации): метка : for параметр генерации generate | if условие generate параллельные операторы end generate [метка]; Параметр генерации - константа дискретного типа в опреде- ленном диапазоне. Параметром генерации не может быть деклари- рованная переменная или сигнал. Оператор генерации позволяет сокращенно (по существу ис- пользуя цикл) описывать совокупности повторяющихся операторов, в том числе и операторов конкретизации компонентов, т. е. оператор генерации представляет собой механизм для проектирования (опи- сания) регулярных (систолических) структур.
100 Глава 2 и двухразрядных сумматоров adder_2p
Последовательные и параллельные операторы 101 Структура регистра регулярна. Мы можем создать N экземп- ляров компонента DFF (D-триггера) и сделать N-битный сдвиговый регистр. Когда число N большое, значительно возрастает длина VHDL-кода. Оператор генерации представляет собой механизм для проектирования (описания) регулярных (систолических) структур. Следующий пример [9] показывает применение оператора ге- нерации к описанию 8-битового сдвигового регистра. architecture RTL2 of SHIFT is component DFF port ( RSTn, CLK, D : in bit; Q : out bit); end component; signal T : bit_vcctor(6 downto 0); begin gO : for i in 7 downto 0 generate gl : if (i = 7) generate bit7 : DFF port map (RSTn => RSTn, CLK => CLK, D => SI, Q => T(6)); end generate; g2 : if (i > 0) and (i < 7) generate bitm: DFF port map (RSTn, CLK, T(i), T(i-l)); end generate; g3 : if (i = 0) generate bitO: DFF port map (RSTn, CLK, T(0), SO); end generate; end generate; end RTL2; Проанализировав данное описание, можно заметить, что неко- торое "неудобство", связанное с установлением связей схемы в це- лом с полюсами элементов, возникает при описании входного (метка
102 Глава 2 bit7) и выходного триггера (метка bitO) Избежать этого неудобства можно, если увеличить размерность сигнала Т . architecture RTL3 of SHIFT is component DFF port ( RSTn, CLK, D : in bit; Q : out bit); end component; signal T : bit_vector(8 downto 0); -- декларация сигнала T begin T(8) <= SI; SO <=T(0); gO : for i in 7 downto 0 generate allbit: DFF port map (RSTn => RSTn, CLK => CLK, D => T(i+1), Q => ПО); end generate; end RTL3; Имеются два способа употребления оператора генерации. Способ 1 - (способ for), синтаксис такой же, как у последова- тельного оператора for loop. Способ 2 - (способ if) употребление подобно по синтаксису последовательному оператору if. В архитектуре RTL2 способ if употреблен внутри способа for. Укажем различия параллельного оператора генерации от по- следовательных операторов for, if. 1. Оператор генерации есть параллельный оператор, a if, for loop есть последовательные операторы. 2. Оператор генерации не имеет фраз else, elsif. 3. Необходима метка для оператора генерации. 4. Только параллельные операторы могут появляться внутри оператора генерации. Только последовательные операторы могут
Последовательные и параллельные операторы 103 появляться внутри последовательного for loop оператора и последо- вательного if оператора. Архитектура DFF может быть декларирована в пакете и упот- реблена в архитектурах RTL1, RTL2, RTL3. Затем эта компонента может быть удалена из этих архитектур. В архитектуре RTL3 параметр i не нуждается в декларации. Все три архитектуры RTL1, RTL2, RTL3 описывают то же самое по- ведение. В следующем примере VHDL-кода оператор generate упот- ребляется для спецификации N-разрядного сумматора adder N (рис.2.5). s(0) s(l) s(N-2) s(N-l) a(0) b(0) a(l) b(l) a(N-2) b(N-2) a(N-l) b(N-l) Рис. 2.5. N-разрядпый сумматор • ’I . • t • ' -♦* •<> ' 1 . * * I * /.‘it 9 J Ц Ц . entity adder_N is generic (N : natural := 4); port (a,b : in bit_vcctor (0 to N-l); s : out bit_vector (0 to N-l); c : out bit); end adder_N; architecture functional of addcr_N is component t. addl port (bl,b2: in BIT; cl,si: out BIT); end component;
104 Глава 2 component add2 port(cl, al,a2:in BIT; c2,s2:out BIT); end component; signal c_in : bit vector (0 to N-l); begin adder: for i in 0 to N-l generate first bit: if (i=0) generate first_cell: addl port map (Ы => a(0), b2 => b(0), cl => c_in(0), si => s(0)); end generate first bit; middle_bit: if (i>0) and (i < N-l) generate middlecell: add2 port map (cl => c_in(i-l), al => a(i), a2 => b(i), c2 => c in(i), s2 => s(i) ); end generate middle bit; end bit: if (i=N-l) generate cnd_cell: add2 port map (cl => c_in(i-l), al => a(i), a2 => b(i), c2 => c, s2 => s(i) ); end generate end bit; end generate adder; end functional; Изменяя число N в строке с ключевым словом generic, можно получать описание сумматора требуемой разрядности. В представ- ленном ниже архитектурном теле func_l для N-разрядного суммато- ра используется только подсхема одноразрядного сумматора add2, при этом на вход переноса cl подсхемы add2 (в разряде с номером 0) подается нулевой сигнал, описание становится более компактным.
Последовательные и параллельные операторы 105 architecture funcl of adder N is component add2 port(cl, al,a2:in BIT; c2,s2:out BIT); end component; signal c_in : bit vector (0 to N); begin -- в схеме (рис. 2.5) все одноразрядные сумматоры - add2 с in(0)<='0'; adder: for i in 0 to N-l generate i_bit_slice: add2 port map (cl => c in(i), al => a(i), a2 => b(i), c2 => c in(i+l), s2 => s(i)); end generate adder; c <= c_in(N); end func_l; Параллельный оператор block Общий вид оператора block (блок): имя блока (метка): Ыоск[(охранное выражение)] заголовок блока раздел деклараций begin параллельные операторы end Ыоск[имя блока]; Оператор блока определяет часть проекта (часть VHDL- описания цифровой системы, схемы). Напомним, что блок - это ог- раниченный фрагмент VHDL-кода, содержащий раздел описания и исполняемый раздел. Блоки могут быть иерархически вложены и поддерживать тем самым декомпозицию проекта. ! Метка необходима в операторе блока.
106 Глава 2 4 •; I В разделе деклараций блока размещаются: • декларации подпрограмм; • тела подпрограмм; - ' • типы, подтипы; • константы; • сигналы; • альтернативные точки входа в подпрограмму; • декларации атрибутов; • декларации констант; • спецификации атрибутов; • конфигурации. . 1 •*' \ V’ ;И‘. • /(. <’.*СД’длг 1 Параллельные операторы размещаются в теле блока. Необязательные охранные выражения будут обсуждены позд- нее. Оператора блока обсудим на примере 7-разрядпого сумматора, составленного из одного полусумматора и трех полных двухразряд- ных сумматоров. Полный двухразрядный сумматор adder_2p есть каскадное со- единение двух полных одноразрядных сумматоров add2. Структурное описание схемы addcr_2p приведено ниже, в данном описании al, Ы - младшие разряды двухразрядных склады- ваемых чисел а = (а2, al), b = (Ь2, Ы); а2, Ь2 - старшие разряды; сО - перенос из предыдущего разряда. Таким образом, схема adder_2p реализует операцию сложения (сО) + (а2, al) + (Ь2, bl) = (с2, s2,sl) одноразрядного числа сО с двухразрядными числами а, Ь. t • > , . ? I entity adder_2p is 1' - “ port (al, bl, а2,Ь2,сО : in BIT; :! , c2,s2,sl : out BIT); end adder_2p; architecture structural of adder_2p is component add2
Последовательные и параллельные операторы 107 port(cl, а 1 ,a2:in BIT; c2,s2:out BIT); end component; signal cl:BIT; begin circ 1: add2 port map (cl => cO, al => Ы,а2 =>b2,c2 =>cl,s2=>sl); circ2: add2 port map (cl => cl, al => al,a2 =>a2,c2 =>c2,s2=>s2); end structural; В приводимом ниже описании две схемы addcr_2p, предназна- ченные для сложения разрядов 1-4, описываются в виде блока. Подсхемы, входящие в блок, отмечены па рис. 2.4,6 штриховой ли- нией. entity addcr_N_block is port (a,b : in bit_vector (0 to 6); s : out bit_vector (0 to 6); c : out bit); end adder N block; architecture structural of adder N block is component add 1 port (b 1 ,b2: in BIT; с 1 ,s 1: out BIT); end component; component adder_2p port(al,bl,a2,b2,c0:in BIT; c2,s2,sl:out BIT); end component; signal c in : bit vector (0 to 2); begin pO: addl port map (bl => a(0), b2 => b(0), cl => c_in(0), si => s(0)); block():block begin stage 1: adder_2p port map (cO => c_in(0), al => a(l), bl => b( 1),
108 Глава 2 а2 => а(2), Ь2 => b(2), с2 => c_in(l), s2 => s(2), si => s(l) ); stage2: adder_2p port map (cO => c_in(l), al => a(3), bi => b(3), a2 => a(4), b2 => b(4), c2 => c_ in(2), s2 => s(4), si => s(3)); end block; stage3: adder_2p port map (cO => c_in(2), al => a(5), bl => b(5), a2 => a(6), b2 => b(6), c2 => c, s2 => s(6), si => s(5) ); end structural; В данном примере отсутствуют охранные выражения, заголо- вок блока, раздел деклараций блока. Блоки могут быть вложены. architecture XX of SYSTEM is - — -- раздел описаний внешнего блока begin — выполнимые операторы внешнего блока A: block ---- — раздел описаний внутреннего блока А begin -- выполнимые операторы внутреннего блока А end block А; В: block - — — раздел описаний внутреннего блока В Ж М «М V* begin — выполнимые операторы внутреннего блока В .... end block В; end XX; ’ }J. J '! ;< w 4*"I В данном примере блоки А, В вложены в блок XX.
Последовательные и параллельные операторы 109 Обсудим теперь охранные выражения блоков. Рассмотрим ар- хитектурное тело addl_e одноразрядного сумматора в виде охраняе- мого блока. entity addl_e is port (bl,b2,enable : in BIT; cl,si : out BIT); end addl_e; architecture struct_3 of addl_e is begin pO: block (enable = T) begin sl<= guarded (bl xor b2); cl<= guarded (bl and b2); end block pO; end struct_3; Охранным выражением блока является выражение enable = 1. Если это выражение принимает значение true (истина), то охраняе- мые конструкции (назначения сигналов) выполняются, т. е. однораз- рядный сумматор складывает числа, если же значение выражения является false (ложь), то охраняемые назначения сигналов не выпол- няются, т. е. сумматор не складывает числа bl, Ь2. Охрана назначе- ния сигналов осуществляется указанием ключевого слова guarded. В качестве другого примера охраняемого блока приведем пример описания D-триггера с асинхронным сбросом в виде блока с охранным выражением (elk = 'Г or clr = Т). entity dlatch is port ( D,clk, clr : in bit; Q : out bit); end dlatch; architecture functional of dlatch is begin P: block (elk = T or clr = T) begin
по ['лава 2 Q guarded 'O' when clr = T else D when elk = '1' else unaffected; end block P; end functional; В данном примере elk - вход синхронизации, clr - асинхрон- ный сброс, D - вход данных, Q — выход триггера. Когда охранное выражение (elk = 'Г or clr = 'Г) имеет значение ложь, то сигнал Q в левой части сохраняет свое прежнее значение. Легко видеть, что сигнал асинхронного сброса имеет приоритет по отношению к сиг- налу elk. Ключевое слово unaffected употребляется в операторе ус- ловного назначения сигнала для случая, когда требуется, чтобы на- значаемый сигнал (в примере сигнал Q) не изменял своего значения. УПРАЖНЕНИЯ 1. Перечислите последовательные операторы языка VHDL . 2. Какой порядок выполнения последовательных операторов? 3. Правильно ли утверждение: "Булево условие в цикле типа while проверяется в начале каждой итерации"? 4. Правильно ли утверждение: "Счетчик в цикле типа for есть переменная, которую нужно декларировать в начале процесса, в ко- тором цикл употребляется"? 5. Какой будет дельта-задержка после выполнения операторов в случаях a) X:=A+B+C+D; b) Y:=A+B+C; с) Z:=A+B; d) W:=A; 6. Где в VHDL-коде может быть декларирована локальная пе- ременная? 7. Где в VHDL-коде может быть декларирован сигнал?
11ослсдовательные и параллельные операторы 111 8. Перечислите различия между локальными переменными и сигналами в языке VHDL . 9. Какие из последовательных операторов могут быть помече- ны? Являются ли метки обязательными? 10. Может ли процесс иметь список сигналов запуска и опера- тор wait внутри оператора процесса? 11. Может ли процесс иметь: - несколько списков сигналов запуска; - несколько операторов wait внутри оператора процесса; - несколько списков сигналов запуска и несколько операторов wait внутри оператора процесса. 12. Правильно ли, что знак оператора назначения сигнала мо- жет быть ориентирован как в левую сторону (<=), так и в правую сторону (=>) по желанию проектировщика, пользующегося языком VHDL? 13. Объясните, как Вы понимаете запись на языке VHDL х <= у <= z Является ли она корректной? Почему? 14. Какая часть VHDL-кода содержит последовательные опе- раторы? Выберите правильный ответ: а) процесс (перед ключевым словом begin); b) архитектурное тело; с) процесс (после ключевого слова begin); d) пакет. 15. Пусть имеется фрагмент VHDL-кода. signal a_bus : bit_vcctor( 3 downto 0); signal z_bus : bit_vector( 3 downto 0); signal a_bit, b bit, c__bit, d_bit: bit; 1) BYTE <= (OTHERS => ’Г); 2) z_bus <= a bit & b_bit; 3) a_bus <= (’Г, bbit, ’O’, d_bit); 4) a_bus (0 to 1) <= (OTHERS => ’O’); Какие строки корректны? Выберите правильный ответ. Обос- нуйте ответ. а) только 2 и 4;
Г лава 2 112 Ь) только 3 и 4; с) только 1 и 2; d) только 1 и 3. 16. Пусть имеется фрагмент VHDL-кода. Type mystate is (RESET, IDLE, RW_CYCLE, INT CYCLE); signal STATE : my state; signal TWOBIT : bit vector (0 to 1); 1) STATE <= RESET; 2) STATE <= "00"; 3) STATE <= TWO BIT; Какие строки корректны? 17. В какой части VHDL-кода можно употреблять операторы if, case, for... loop? Выберите правильный ответ: a) architecture; b) entity; с) package; d) process. 18. В данном фрагменте VHDL-кода осуществляется инициа- лизация массива z_bus четырьмя способами: Signal z bus : bit_vector (3 downto 0); a) z_bus <= "0000"; b) z bus <= (1 => 'O', others => 'O'); c) zbus <= (others => 'O'); d) z_bus <= ('O' ,'0','0', 'O'); Укажите способ, который наиболее просто осуществляет ини- циализацию массива независимо от его длины. 19. Что такое транспортная и инерционная задержка сигнала? Какой тип задержки (транспортная, инерционная) принят по умол- чанию в языке VHDL? 20. В каком случае модель инерционной задержки сигнала и модель транспортной задержки сигнала дают тот же результат? 21. Перечислите параллельные операторы языка VHDL.
Последовательные и параллельные операторы ИЗ 22. Какая часть VHDL-кода содержит параллельные операто- ры назначения сигнала. Выберите правильный ответ: a) entity; b) process; с) package; d) architecture. 23. Какой параллельный оператор требуется внутри парал- лельных операторов? 24. В следующем VHDL-коде [9] имеются четыре параллель- ных вызова процедуры. entity PROCALL_EX is end PROCALL_EX; architecture RTL of PROCALL EX is procedure ANDOR ( signal А, В, C, D : in bit_vector(l downto 0); signal Y : out bit_vector( 1 downto 0)) is begin Y <= (A and B) or (C and D); end ANDOR; signal DIN, DOUT : bit_vcctor(7 downto 0); signal X, Y, Z : bit_vcctor(l downto 0); begin callO : ANDOR (A => DIN(7) & DIN(6), В => DIN(5 downto 4), C => DIN(3 downto 2), D => DIN(1 downto 0), Y => DOUT(1 downto 0)); call 1 : ANDOR (A => DIN(7 downto 6), В => DIN(5 downto 4), C => DIN(3 downto 2), D => DIN(1 downto 0), Y => DOUT(3 downto 2)); ca!12 : ANDOR (A => DIN(7 downto 6) and D1N(5 downto 4), В => DIN(5 downto 4), C => DIN(3 downto 2), D => DIN(1 downto 0), Y => DOUT(5 downto 4)); call3 : ANDOR (A => X nand Y, В => Z, C => DIN(3 downto 2), D => DIN(1 downto 0), Y => DOUT(7 dow nto 6)); end RTL;
114 Глава 2 Является ли каждый вызов корректным или нет, почему? 25. Может ли локальная переменная употребляться как факти- ческий параметр оператора параллельного вызова процедуры? Со- ставьте соответствующий VIIDL-код, проверьте его с помощью VHDL-анализатора. 26. Каким параллельным операторам требуются метки? 27. Для каких параллельных операторов метки необязательны? 28. Что такое компонент в языке VHDL? Чему соответствует компонент в логической схеме? Какие средства языка VHDL упот- ребляются для соединения компонент? 29. Могут ли декларироваться компоненты внутри раздела декларации процесса? 30. Требуется ли декларировать сигналы внутри процесса? 31. Допустимо ли декларировать любые объекты внутри про- цесса? 32. Правильно ли, что все операторы внутри процесса выпол- няются один за другим? 33. Правильно ли, что все процессы внутри архитектурного тела выполняются один за другим? 34. Должен ли каждый процесс иметь имя (метку)? Рекомен- дуется ли именовать процессы? Если "да”, то почему? 35. Правильно ли, что имя процесса специфицируется после ключевого слова process? 36. Правильно ли, что как сигналы, так и переменные могут употребляться для храпения временных данных внутри процесса? 37. Перепишите следующий VHDL-код [9], используя опера- тор выборочного назначения сигнала. entity IFCASE is port ( HEX : in bit_vector(3 downto 0); LED : out bit_vector(6 downto 0)); end IFCASE; architecture RTL of IFCASE is begin pO : process (HEX)
Последовательные и параллельные операторы 115 begin case HEX is when "0000" => LED <="1111110"; when "0001" => LED <= "1100000"; when "0010" => LED <="1011011"; when "0011" => LED <="1110011"; when "0100" => LED <= "1100101"; when "0101" => LED <="0110111"; when "0110" => LED <="0111111"; when "0111" => LED <= "1100010"; when " 1000" => LED <="1111111"; when "1001" => LED <="1110111"; when "1010" => LED <= "0111001"; when " 1011" => LED <="0111101"; when " 1100" => LED <= "0011001"; when "1101" => LED <="1111001"; when "111 0" => LED <="1011111"; when others =>LED<= "0001 111"; end case; end process; end RTL; Проведите моделирование, сравните результаты. 38. Правильно ли, что оператор выборочного назначения сиг- нала и оператор условного назначения сигнала представляют то же действие, только записанное по-разному? 39. Правильно ли утверждение "Условное назначение сигнала может употребляться как в архитектурном теле (как параллельный оператор), так и в процессе (как последовательный оператор)"? 40. Для чего служит оператор generate? Структуру каких схем удобно описывать с его помощью? 41. Допустимо ли при конкретизации компонентов использо- вать оба направления (=>, <=) в зависимости от того, является порт входным либо выходным? 42. Разработайте логическую схему, и, употребляя оператор generate, запишите VHDL-код структурного описания мультиплек- сора с двумя, тремя, четырьмя и «-управляющими входами.
116 Глава 2 43. Разработайте функциональное описание схемы для пере- множения двух матриц А, В размерностью 4x4, элементами которых являются целые числа. Используйте двумерные массивы для вход- ных и выходных данных. Примените операторы generic, generate, запишите VHDL-код для общего случая, когда матрицы имеют размерность NxN. Разработайте структурные описания для случаев N=2, N=3, используя умножители и сумматоры, и полагая, что элементами a(J, / by матриц А,В являются целые числа, не большие числа 3. Примени- те битовое представление входных и выходных данных. I Проведите моделирование, убедитесь в корректности VHDL- кода. Введите соответствующие типы данных и разработайте пове- денческое VHDL-описание схемы для умножения матрицы А па вектор с. Разработайте структурное описание, используя битовое пред- ставление входных данных для случая, когда элементы матрицы А и компоненты вектора с являются целыми числами, нс большими 7, а матрица А имеет размерность Nx N, вектор с имеет размерность N, N=2,3,4. Используйте функции преобразования типов integer, bit_vector. 44. На рис. 2.6 изображена схема 4-разрядного умножителя. Введите имена сигналам, соединяющим элементы схемы: однораз- рядные полусумматоры addl, одноразрядные сумматоры add2, двух- входовые конъюнкторы. Опишите схему, используя операторы создания экземпляров компонентов. Составьте более компактное описание, используя дру- гие операторы языка VHDL. Проведите моделирование, сравните результаты. Введите за- держки элементам: addl - 10ns, add2 -15 ns, элементам И - 5 ns. Проведите моделирование. Определите задержку схемы.
Последовательные и параллельные операторы 117 Рис. 2.6. Чстырехразрядный умножитель 45. На рис. 2.7 дана схема D-триггера. Введите задержки эле- ментам и составьте структурное описание. Модифицируйте функ- циональное описание, введя задержку в оператор назначения сигна- ла, проведите моделирование в обоих случаях. Сравните результаты.
118 Глава 2 Рис. 2.7. D-триггер (защелка): а - условное обозначение; б - схема D-триггсра на элементах И-НЕ 46. Опишите функционирование RS-триггера с использовани- ем конструкции "охраняемый блок".
Глава 3 Организация проекта f, -->— ! 3.1. Подпрограммы Декларация подпрограммы Определение. . » •< —V , — ' ' « ’ • . < ' (Г'Л ! | . -JM — •• ♦ subprogram_specification :.*= procedure designator [ ( formal_parameter_list) ] | [ pure | impure ] function designator [ (formal_parametcr_list) ] return typc_mark Подпрограммы имеют две формы — функции и процедуры. Вызов процедуры есть оператор, в то время как вызов функции воз- вращает значение в выражении. Указателем функции (операторным символом) может быть идентификатор или строковый литерал. За- метим, что строковый литерал не может быть именем процедуры. Подпрограммы могут быть декларированы в тексте пакета, интер- фейсе объекта проекта, архитектурном теле, процессе, процедуре или функции. Подпрограммы могут вызывать другие подпрограм- мы. Примеры подпрограмм уже приводились и будут даны далее. 3.2. Функции Общий вид оператора декларации функции: [pure | impure] function имя функции (параметр {, параметр} )
Глава 3 return тип возвращаемого функцией значения is раздел деклараций begin тело функции end [имя функции]; Общий вид оператора вызова функции: яЧя функции ( фактический параметр {, фактический параметр} ); Функция имеет только входные параметры. Следующий ил- Лостративпый пример показывает (декларирует) функцию ^OOLTOSL, преобразующую тип BOOLEAN в тип STDJJLOGIC. Типы данных STD_ULOGIC, STD_LOGIC будут сбъяснеиы в разд.3.4. Пример. function BOOL_TO_SL(X: boolean) return std_ulogic is begin ifX then return 'Г; else return 'O'; end if; end BOOL_TO_SL; Следующий пример показывает функцию преобразования ти па bit в тип boolean. Напомним, что данные типы пе эквивалентны. function bit_bool (inpbit: in bit) return boolean is begin if (inp bit ='!') then return true; else
Организация проекта 121 return false; end if; end bit_bool; Функция может содержать последовательные операторы, ис- ключая операторы ожидания и назначения сигналов. В теле функции могут декларироваться локальные переменные. Например, в теле функции PARITY декларируется локальная переменная ТМР. Пример. function PARITY (X : std_ulogic_vector) return stdulogic is variable TMP : std ulogic := 'O'; begin for J in X'range loop TMP := TMPxor X(J); end loop; return TMP; end PARITY; Пример использования функции PARITY в архитектурном теле. architecture FUNCTIONS of PAR is begin — вызов функции PARITY BYTE <= PARITY(DATA_BYTE); PARITYWORD <= PARITY(DATAWORD); end FUNCTIONS; Необязательные ключевые слова pure, impure при декларации функции имеют следующий смысл: ключевое слово impure говорит о том, что функция может иметь побочные эффекты, т. е. такая функция может иметь доступ к внешним данным, например, читать внешний файл [7]. Функции без побочных эффектов могут деклари- роваться с необязательным словом pure. В данной книге все функ- ции языка VHDL являются функциями без побочных эффектов.
122 L' Глава 3 - - 3.3. Процедуры и Общий вид оператора декларации процедуры: ' . • ' h .. h ЦЭД л/И/НП4 procedure имя процедуры ( параметр {, параметр} ) is - * । h । раздел декларации , . lii /. ♦ begin 1 . , it. .J-’’ тело процедуры end [имя процедуры]; hr♦ Процедура может иметь входные (in), выходные(out) и вход/выходные (inout) параметры. Это могут быть сигналы, пере- менные или константы. По умолчанию входные параметры - кон- станты, выходные и вход/выходные параметры - переменные. Общий вид оператора вызова процедуры: имя процедуры (фактический параметр {, фактический параметр} ); * ’ . / . * • » ' '. * : ' • * ; • . I J 1 • - ' " ' ' • »I ‘ I ’ » ' 1 • • ч' ’ J Таким образом, вызов процедуры состоит из имени процедуры и списка фактических параметров. Процедуры могут вызываться последовательно или параллельно. При параллельном вызова проис- ходит выполнение процедуры; когда1 какой-нибудь1, входной вход/выходной параметр изменился. VHDL-код с текстом подпро- граммы, т. е. функции или процедуры может находится в разделе деклараций архитектурного тела, либо в пакете. Если подпрограмма определена в пакете, то текст подпрограммы должен быть в теле па- кета. ‘ •' '. f 1 Если подпрограмма находится в пакете, то в этом случае перед текстом entity, где процедура используется (процедуры могут ис- пользоваться в архитектурных телах), требуется указание'«имени библиотеки и имени пакета, в котором содержится текст подпро- граммы. Библиотеки и содержащиеся в них пакеты будут рассмот- рены далее. Л 1 ’/Г ' . ' .Г. Г' * I Следующий пример i процедуры PARITY показывает отличия процедуры от функции: функция имеет только входные йарамстры,
Организация проекта 123 режим (mode) которых не специфицируется, в процедуре могут со- держаться операторы назначения сигналов. Пример. procedure PARITY (signal X : in std_ulogic_vector; signal Y : out std_ulogic) is variable TMP : std_ulogic := 'O'; begin for J in X'range loop TMP := TMP xor X(J); end loop; Y <= TMP; — в процедуре могут быть операторы назначения сигналов end PARITY; Следующий пример показывает процедуру DISPLAY_MUX и ее вызов в архитектурном теле SUBPROG. procedure DISPLAY_MUX (ALARM TIME, CURRENT TIME : in digit; SHOWA : in std_ulogic; signal DISPLAY_TIME : out digit) is begin if (SHOW_A = T) then DISPLAY TIME <= ALARM TIME; else DISPLAY TIME <= CURRENT TIME; end if; end DISPLAY_MUX; architecture SUBPROG of DISP_MUX is • • • begin — вызов процедуры DISPLAY_MUX (ALARM_TIME, CURRENT_TIME, SHOW_A, DISPLAY_TIME); end SUBPROG;
124 Глава 3 3.4. Разрешающие функции. Пакет std_logic_1164 Когда сигнал имеет один драйвер (иногда драйвер называют контейнером), то значение сигнала легко определить, потому что, когда процесс приостанавливается, значение сигнала из драйвера передается сигналу. Однако во многих практических ситуациях один и тот же сигнал может назначаться в различных (нескольких) про- цессах. Например, шипа данных в персональном компьютере может получать данные из процессора, памяти (ОЗУ), жесткого диска и других устройств. Сигнал от многих источников называется в языке VHDL разрешаемым (resolved), т. с. требующим решения проблемы разрешения - определения значения результирующего сигнала по значениям сигналов из различных источников. Сигнал, не требую- щий решения проблемы разрешения, называется неразрешаемым (unresolved) - это сигнал из одного источника. । Функция разрешения — это функция определения значения сигнала по его значениям из различных источников. Далее будем рассматривать два источника и для этого случая изучать функции разрешения в электронных схемах. Для моделирования процессов прохождения сигналов в реальных электронных схемах использует- ся многозначная логика. Тип bit обобщается на случай девяти значе- ний сигнала 'U' — инициализировано; 'X' — неизвестное значение (сильный источник сигнала); 41 'О' — логический 0 (сильный источник сигнала); ’Г -- логическая 1 (сильный источник сигнала); 'Z* высокий импеданс (цепь не подключена к источнику); 'W' -- неизвестное значение (слабый источник сигнала); 1 'L' — логический 0 (слабый источник сигнала); 'Н' — логическая 1 (слабый источник сигнала); 1 — неопределенное значение (don't саге). ' На практике чаще всего используется шестизначный алфавит {U,X,O,1,Z,-}. Заметим, что неизвестное значение 'X' не эквивалент- но неопределенному значению Неопределенное значение эффек- тивно используется при логическом синтезе схемы и логической оп- тимизации. Читатель, знакомый, например, с методами мипимиза-
Организация проекта 125 ции не полностью определенных булевых функций, может вспом- нить о том, что некоторые неопределенные значения функции за- меняются при минимизации определенными (0,1) с целью получе- ния лучшего результата. Расширение типа bit на случай девяти значений сигнала при- вело к понятию типа std_logic. Основное назначение типа std_logic - это дать "легальную" возможность разработчику делать многократные присваивания од- ному и тому же сигналу. Пример. Signal FlagC : std_logic := 'Z'; ALU: process begin if Carry then FlagC <=’!’; end if; end process ALU; COMM: process begin FlagC <= 'O’; end process COMM; В данном примере для сигнала FlagC требуется разрешающая функция, так как операторы назначения данного сигнала имеются в двух процессах (рис. 3.1). Тип stdjogic будем называть разрешаемым. Тип std_logic яв- ляется подтипом типа std_ulogic. Тип std_ulogic является не разре- шаемым перечислимым типом с множеством значений {'U', 'X', '0','r,'Z',’W', Ъ','Н','-'}. Для сигналов этого типа запрещено использо- вать много источников сигнала, поэтому нет необходимости указы- вать разрешающую функцию. Буква и в названии типа std_ulogic сигнализирует о термине (unresolved). Итак, типы std_Iogic, std_ulogic - это перечислимые типы. Их определение содержится в пакете std_logic_1164 (см. приложение 4).
126 Глава 3 process ALU Рис. 3.1. Функция разрешения F для сигналов с многими драйверами Сигнал FlagC В пакете std_logic_l 164 содержатся определения типов, под- типов, функций на случай многозначной логики: • тип std_ulogic - неразрешаемый логический тип с девяти- значным алфавитом; • тип std_logic_vector; • подтип std logic типа std_ulogic; • ’’перегружаемые” логические функции and, nand, or, xor, not для операндов std__ulogic и др. Заметим, что для преобразования типа bit в тип std_logic (и на- оборот) требуются соответствующие функции. Т абл. 3.1, по существу, есть табличное задание разрешающей функции F для сигнала из двух источников. Рис. 3.2 иллюстрирует смысл таблицы, т. с. получение значения сигнала с помощью функ- ции разрешения F. Фактически типы std logic, std ulogic стали промышленным стандартом и доступны во всех системах моделирования с языком VHDL, поставляющихся вместе с пакетом std logic 1164. Чтобы ис- пользовать пакет std_logic_l 164, необходимо указать следующее: Library IEEE; use IEEE. std_logic_l 164.all;
Организация проекта 127 Опишем схему (рис.3.3), используя для сигналов тип std_logic. Таблица 3.1 и 0 1 Z W L II - и У и1 У У У •и- У У 'U' -X У *Х/ ’2С 'X' X' X' 'X’ 'X' 0 У ’X’ ’О’ 'X' ’О’ '0' 'О' 0’ ’X* J У X’ ’Г Ч’ ’1’ Ч’ Ч’ ’X’ Z V *Х/ ’О' 'Г 'Z' ’W’ ’L' •И’ •X’ W У 'О' ’Г w •W' •W’ •W' L У *Х* 'О' 'L' •W’ L' 'W' *х^* II У \Xf •о* 'Г ’1Г ’W' 'W* •1Г *х? * У ТХ^ X' 'X' 'X' 'X' ’X' 'X' \Х* Рис. 3.2. Иллюстрация табличного задания функции разрешения F для сигналов типа std_logic с двумя драйверами
128 Глава 3 Чтобы описать монтажное ИЛИ, введем тип rcsolvedbit, яв- ляющийся подтипом типа std_logic, и определим в пакете wire, на- ходящемся в рабочей библиотеке work, разрешающую функцию res_func для сигнала типа resolved_bit. Разрешающая функция опре- деляет значение сигнала по значениям сигналов из нескольких ис- точников. В данном примере разрешающая функция назначит сиг- налу out_wire значение 'Г, если хотя бы один из выходных сигналов логических элементов И первого уровня схемы (рис. 3.3) будет иметь значение 'Г, в противном случае сигнал out_wire примет зна- чение 'О'. В VHDL-коде используются следующие имена: схема, изо- браженная на рис. 3.3, имеет имя circuit_wire, двухвходовый элемент И - имя сс. out_circ Рис.3.3. Схема circuit wire library IEEE; use IEEE.std_logic_l 164.all; library work; use work.wire.all; entity circuit wire is
Организация проекта 129 port (xl,x2,x3,x4,x5,x6 : in stdlogic; out_circ : out std logic); end circuit wire; architecture structure of circuit wire is component cc port (xl,x2 : in std_logic; у : out std_logic); end component; signal out wire : resolved bit; begin pl: cc port map (xl => xl, x2 => x2, у => out_wirc); p2: cc port map (xl => хЗ, x2 => x4, у => out_wire ); p3: cc port map (xl => x5, x2 => хб, у => out_wire ); p4: cc port map (xl => out_wirc, x2 => x2, у => out circ); end structure; library IEEE; use lEEE.std_logic_l 164.all; entity cc is — описание логического элемента И port (xl,x2: in std logic; у: out std_logic); end cc; architecture functional of cc is begin у <= xl and x2; end functional; Ниже приведен пакет wire и тело (body) этого пакета. library IEEE; use lEEE.std_logic_l 164.all; package wire is function RES_FUNC(DATA: in stdlogicvcctor) return std logic;
130 Глава 3 subtype RESOLVED_B1T is RES_FUNC std logic; end; package body wire is — описание разрешающей функции function RES_FUNC(DATA: in std logic vector) return std logic is begin for I in DATA'range loop if DATA(l) = T then return T; end if; end loop; return 'O'; end; end; В тексте функции RES_FUNC используется атрибут DA- TA'rangc - диапазон сигнала DATA. Аналогичным образом можно ввести разрешающую функцию для монтажного И. 3.5. Архитектура Ранее в общем виде была представлена архитектура объекта проекта и интерфейс объекта проекта. Приведем определение архи- тектуры. Определение. architecture_body ::= architecture identifier of enftYy_name is architecturc_declarative_part begin architccture_statement_part end [ architecture ] [ urc/n7ecture_simplc_name ]; В разделе деклараций архитектуры (architecture decla- rativejpart) могут быть: • декларации подпрограмм; • тела подпрограмм;
Организация проекта 131 • спецификации конфигурации; • декларации типов, подтипов, констант, сигналов, файлов, альтернативных точек входа, компонентов и др. ! В разделе деклараций архитектуры не могут быть декларированы локальные переменные. ! Только параллельные операторы размещаются в теле архитектуры между ключевыми словами begin, end. Последовательные опера- торы могут быть внутри оператора процесса или подпрограммы. Допустимо, чтобы параллельных операторов не было внутри архитектурного тела. 3.6. Декларация интерфейса объекта Определение. entity_declaration ::= entity identifier is entity header entity_dcclarative_part [ begin entity_statcmcnt_part ] end [ entity ] [ en/fty_simple_name ]; Необязательный раздел операторов entity, начинающийся с ключевого слова begin, может иметь только параллельные вызовы процедур, параллельные операторы сообщения, операторы процесса. Все они должны быть пассивными, так чтобы не было присваивания значений сигналам. Раздел entity header включает в себя список настройки и спи- сок портов: [generic (gencric list);] [port (port list);]
132 Глава 3 Список портов (port_list) и список настройки (generic list) та- кие же, как и в подпрограммах. Если специфицировать объект другого класса, а не сигнал по- сле ключевого слова port, то это является ошибкой. Ошибкой будет также, если специфицировать не константу после ключевого слова generic. В entity ключевое слово port является необязательным. Список после ключевого слова generic (общий, настраивае- мый) есть хороший способ проведения (передачи) параметров в ин- терфейс объекта проекта, таких как параметры временной задержки, ширина шины (число проводников) и т.д. Употребляя настройку (слово generic), можно специфициро- вать регулярную структуру переменной длины. Приведем пример [9] entity для сдвигового регистра перемен- ной длины N, определив сперва модификацию D-триггера с предус- тановкой (очисткой). library IEEE; use IEEE.std_logic_l 164.all; entity DFF is - D-триггер generic ( PRESETCLRn : in integer); port ( RSTn, CLK, D : in std_logic; Q : out std logic); end DFF; architecture RTL of DFF is begin process (RSTn, CLK) begin if (RSTn = '()’) then if (PRESET CLRn = 0) then Q <= 'O’; else ' Q <=’!’; end if;
Организация проекта 133 elsif (CLK'cvcnt and CLK = 'Г) then Q<=D; end if; end process; end RTL; Тогда архитектурное тело сдвигового регистра переменной длины N будет иметь вид library IEEE; use IEEE.std_logic_l 164.aH; entity SHIFTN is — сдвиговый регистр длины N generic ( PRESET CLRn : in integer; N : in integer); port ( RSTn, CLK, SI: in std_logic; SO : out std_logic); signal T : std_logic_vector(N downto 0); begin assert (N > 3) and (N < 33) report "N outside of range 3 to 32"; end SHIFTN; architecture RTL1 of SHIFTN is component DFF generic ( PRESET_CLRn : in integer); port ( RSTn, CLK, D : in std logic; Q : out std_logic); end component; begin T(N) <= SI; SO <=T(0); gO : for i in N-l downto 0 generate allbit: DFF
134 Глава 3 generic map (PRESETCLRn => PRESET CLRn) port map (RSTn=>RSTn, CLK=>CLK, D=>T(i+l), Q=>T(i)); end generate; end RTL1; Обращаем внимание на то, что спецификация компонента DFF в архитектурном теле RTL1 совпадает с его определением в entity DFF. 3.7. Карта портов и карта нас громки Соединение VHDL-описаний осуществляется с помощью карт (тар). Для иерархического проекта порты низкоуровневых компо- нент (уровня i-1) могут быть отображены в порты высокоуровневого объекта (уровня i) сигналами с учетом следующих ограничений. Сигнал порта, имеющий режим (mode) in, может быть соеди- нен с портом, имеющим режим in, inout, buffer (рис. 3.4). Рис. 3.4. Связи портов компонента с портами объекта
Организация проекта 135 На рис. 3.4 изображены только некоторые возможные соеди- нения портов компонента с портами той подсхемы, в которую ком- понент входит. Сигнал порта режима out может быть соединен с портом, имеющим режим out или inout, buffer. Сигнал порта режима inout, buffer может быть отображен (соединен) с портом, имеющим режим вида inout, buffer соответственно. Сигнал порта режима linkage может быть соединен с сигналом порта любого режима. С точки зрения проектирования аппаратуры вид связи linkage нс является естественным, данный тип связи более подходит для алгоритмических описаний. Режим inout употребляется чаще всего для двунаправленных контактов, которые находятся снаружи кристалла СБИС. Для внут- ренних сигналов режим не указывается. 3.8. Конфигурация Один и тот же объект проекта (entity) может иметь много ар- хитектурных тел. Как при моделировании выбрать то или другое архитектурное тело? Формальное определение (синтаксис) понятия конфигурации довольно сложное. Начнем с простейших случаев Пусть мы определили компоненту goose. entity goose is port (a, b: in bit; c : out bit); end goose; architecture struct_l of goose is begin c <= a xor b; end struct_l; Мы можем употребить данную компоненту стандартным об- разом, употребляя имя goose.
136 Глава 3 entity flock is port (a, b: bit; c: out bit); end flock; architecture threegccsc of flock is signal w, r: bit; component goose — декларация компонента port (a, b: bit; c: out bit); end component; begin one: goose port map (a, b, w); — создание экземпляра компонента two: goose port map (a, w, r); three: goose port map (a, r, c); end three_geese; Архитектурное тело содержит три экземпляра компонента goose. По умолчанию предполагается, что это тот же самый компо- нент goose, который был определен ранее и который содержится в рабочей библиотеке (Work - имя рабочей библиотеки). Пусть у пас имеется другое архитектурное тело для компонен- та goose. architecture struct_2 of goose is begin c <= ((a and (not b)) or ((not a) and b)); end struct_2; Мы можем не действовать "по умолчанию", а "явно" опреде- лить употребление того или другого архитектурного тела для кон- кретного компонента на основе конфигурации. configuration bird of flock is — bird - имя конфигурации for three geese for one: goose use entity work.goosc(struct_2);
Организация проекта 137 end for; for two: goose use entity work.goose(struct_l); end for; for three: goose use entity work.goose(struct_l); end for; end for; end bird; Мы указали, что для компонента goose, имеющего имя (метку) one, необходимо использовать (use) из рабочей библиотеки архитек- турное тело struct_2, аналогично - для компонентов с метками two, three необходимо использовать архитектурное тело structl. Рассмотрим немного более сложный пример конфигурации па примере схемы vlsi l (см. рис. 1.2). Представим, что в схемах сум- матора adder_2 и умножителя mult_2 мы хотим использовать раз- личные архитектурные тела для одноразрядного полусумматора addl. Итак, в умножителе будем использовать для подсхемы addl архитектурное тело struct 2, а в сумматоре - архитектурное тело struct 1. Архитектурное тело struct 2 отличается от архитектурного тела struct _1 только назначением сигнала: вместо sl<=((bl and (not Ь2)) or (not bl) and b2)); можно использовать sl<= (bl xor b2); Конфигурация example выглядит следующим образом: configuration example of vlsi 1 is for structure — имя архитектурного тела схемы vlsi_l for circ2: mult_2 use entity work.mult_2(structure);
138 Глава 3 for structure for all: addl use entity work.addl(struct_2); end for; end for; end for; for circ3: adder_2 use entity work.addcr_2(structure); for structure for all: addl use entity work.addl(struct l); end for; for all: add2 use entity work.add2(struct_I); — вместо struct_l end for; можно указать end for; другую архитектуру end for; end for; end example; В данной конфигурации предполагается, что подсхемы сумма- тора и умножителя находятся в рабочей библиотеке work. Использо- вание библиотек в языке VHDL рассматривается в следующем раз- деле. При записи конфигурации могут быть использованы другие конфигурации для подсхем, входящих в схему, таким образом, опи- сание конфигурации может быть организовано иерархически, напо- добие иерархической организации описания проектируемой цифро- вой системы. Большое число примеров конфигураций для сдвигово- го регистра можно найти в [9]. 3.9. Блоки проекта и VHDL-библиотски Файл проекта может содержать один или более блоков проек- та. Имеются первичные и вторичные блоки проекта. Первичные блоки проекта:
Организация проекта 139 • декларация объекта в целом (интерфейса entity); • декларация конфигурации; • декларация пакета. Первичный блок может быть связан с многими вторичными блоками проекта, которые включают: • архитектурное тело; • тело пакета. ! Каждый первичный блок в дайной библиотеке должен иметь уни- кальное простое имя. Каждое архитектурное тело, связанное с entity, должно быть уникальным. Блоки проекта (первичные и вторичные) размещаются в библио- теках (рис.3.5). Рабочая библиотека может быть только одна. Рис. 3.5. VHDL-библ потеки и VHDL-анализатор В рабочей библиотеке размещаются файлы (блоки), анализи- руемые VHDL-анализатором. В библиотеках ресурсов размещаются блоки, на которые ссы- лаются анализируемые блоки. Ресурсной библиотеки может не быть во время анализа. Ссыл- ка на библиотеку осуществляется указанием ключевого слова li- brary.
14) Глава 3 Например, ссылка па библиотеку STD, содержащую пакет STANDARD, и на библиотеку WORK, содержащую пакет FXP, осуществляется следующим образом: library STD, WORK; use STD.STANDARD.all; use WORK.FXP.all VHDL-анализатор читает файлы исходного VHDL-кода, чита- еюсылки на ресурсные библиотеки и генерирует базу данных моде- лфования в рабочей библиотеке. Область видимости библиотеки - от начальной ссылки до кснца декларативной области, связанной с блоком проекта, где сеялка появилась. Видимость сигналов: сигнал, декларированный в пакете, явля- ется видимым во всех объектах проекта, которые употребляют солку (use) на данный пакет. Сигнал, декларированный в entity как плт, является видимым во всех архитектурных телах, связанных с данным entity. Сигнал, декларированный в разделе деклараций архи- тектурного тела, видим только внутри данного архитектурного тела. Приведем пример VHDL-кода, в котором используется вызов функций, реализующих операторы сдвига. В данном случае функция $1реализует оператор sll (сдвиг влево), функция sr реализует опера- тор srl (сдвиг вправо). Функции si, sr находятся в пакете e»mplar_l 164 библиотеки exemplar. Так как имеется ссылка на па- кет cxemp]ar_l 164, то функции si, sr являются видимыми (доступ- ными), поэтому нет необходимости давать коды этих функций в рвделе деклараций архитектурного тела. Так как используется тип sti_logic__vector, то требуется также ссылка на пакет SIDLOGIC1164. library IEEE; ufc 1EEE.STD LOGICJ 164. all; library exemplar; ufc exemplar.exemplar__1164.all; entity shift__example is
Opi апизация проекта 141 port (a, b : in std_logic_vector (3 downto 0); xl, x2 : out std_logic_vcctor (3 downto 0)); end shift_cxamplc; architecture Synt of shift_example is signal y, z : std logic vector (3 downto 0); begin у <= si (a, 3); — сдвиг влево z <= sr (a, 3); — сдвиг вправо xl <= у and b; x2 <= z xor b; end Synt; В записи si (a, 3) : si - обозначение оператора (функции), a — массив бит, 3 — число разрядов, на которые надо сдвинуть влево массив а. В записи sr (а, 3) : sr - обозначение оператора (функции), а - массив бит, 3 - число разрядов, на которые надо сдвинуть вправо массив а. Данный пример показывает также, что логические опера- ции можно выполнять поразрядно над массивами бит. УПРАЖНЕНИЯ 1. В какой части VHDL-кода должны быть декларированы ло- кальные сигналы архитектурного тела? Выберите правильный ответ: а) в списке портов архитектурного тела; Ь) в конфигурации; с) в архитектурном теле после ключевого слова begin; d) в архитектурном теле перед ключевым словом begin. 2. Как должны быть подобны компонент (component) и соот- ветствующий интерфейс (entity)? Выберите правильный ответ: a) entity и component должны иметь одно и то же имя, но пор- ты могут различаться; Ь) имена entity и component могут различаться, но имена пор- тов должны быть одинаковы; с) entity и component должны иметь одинаковые имена и должны иметь одинаковые имена портов.
142 Глава 3 3. Правильно ли, что компоненты, декларируемые в архитек- турном теле, должны специфицироваться полностью, т. е. вместе с их интерфейсом и выполняемыми функциями? 4. Как много архитектурных тел может быть связано с одним entity? Выберите правильный ответ: а) одно или более; Ь) более одного; с) только одно; d) ни одного. 5. Правильно ли утверждение: "Каждый порт должен быть специфицирован с его режимом (mode)"? 6. Правильно ли утверждение: "Режим порта специфицирует направление потока данных через порт"? 7. Являются ли порты сигналами? 8. Правильно ли утверждение: "Описание каждого порта с комментарием в конце строки является необходимым согласно стан- дарту языка VHDL"? 9. Разрешается ли специфицировать начальное значение пор- та? 10. Может ли настраиваемый параметр (generic) динамически изменяться во время моделирования? 11. Правильно ли утверждение: "Все процессы в архитектур- ном теле являются активными, когда архитектура активна "? 12. Могут ли употребляться переменные для передачи инфор- мации между процессами? 13. Напишите VHDL-код для схемы 4-разрядпого сумматора, представляющей каскадное соединение одноразрядных сумматоров. Напишите VHDL-код для одноразрядного сумматора add2 в виде а) логической схемы элементов И, ИЛИ, НЕ; б) логических функций. Запишите различные конфигурации, используя различные ар- хитектурные тела для одноразрядных сумматоров addl, add2. 14. Рассмотрите предыдущую задачу для случая 4-разрядного умножителя (см. рис. 2.6). Запишите различные конфигурации. 15. Разработайте логическую схему для вычисления функции f = (p + q) + wxd,
Организация проекта 143 где р = (р2»Р|)> q = (q2,q1), w = (w2,wl), d = (d2,d|) -двухраз- рядные числа. Опишите се на языке VHDL. Запишите различные конфигура- ции, употребляя различные архитектурные тела для сумматоров и умножителя. 16. Что из перечисленного ниже не является блоком проекта? Выберите правильный ответ: a) architecture; b) entity; с) process; d) package.
Глава 4 Примеры проектирования па VHDL 4.1. Стили описания поведения Рассмотрим различные стили описания одного и того же пове- дения на примере дешифратора DC(2), который имеет два входных полюса и четыре выходных ( рис. 4.1). х(0) DC х(1) у(0) у(1) У(2) У(3) Рис. 4.1. Дешифратор На рис. 4.1 слева и справа указаны имена входных и выходных полюсов, употребляемых в VHDL-описании. Функции дешифратора имеют следующий вид: у0= хО Л xl; yl= хО Л xl; у2= хО Л xl; уЗ= хО A xl; Интерфейс дешифратора entity Decoder is
Примеры проектирования на VHDL 145 port (X: in Bit_vcctor (0 to 1); Y: out Bit_vector (0 to 3)); end Decoder; Представим различные стили описания функционирования дешифратора: ’’чисто” структурное описание, описание в виде пото- ка данных, процедурное описание. Заметим, что при спецификации цифровых систем допустим смешанный стиль, что весьма удобно при проектировании. Структурное описание архитектурного тела в виде схемы в базисе инверторов (Inverter) и двухвходовых элементов И (AND_Gatc) имеет вид architecture structure of Decoder is signal S: bit_vector (0 to 1); component AND_Gatc port (A, B: in Bit; D: out Bit); end component; component Inverter port (A: in Bit; B: out Bit); end component; begin Inv 1: Inverter port map (A=>x(0), B=>s(0)); lnv2: Inverter port map (A=>x(l), B=>s(l)); Al:AND_Gate port map (A=>s(0), B=>s(l), D=>y(0)); A2:AND_Gatc port map (A=>s(0), B=>x(l), D=>y(l)); A3:AND_Gate port map (A=>x(0), B=>s(l), D=>y(2)); A4:AND_Gate port map (A=>x(0), B=>x(l), D=>y(3)); end structure; Описание поведения дешифратора в виде потока данных (data flow). architecture Data flow of Decoder is begin y(0) <= not x(0) and not x(I); y(l) <= not x(0) and x(l); y(2) <= x(0) and not x( 1);
146 Глава 4 y(3)<=x(0) and х(1); end Data_flow; Процедурное описание дешифратора выглядит следующим образом: architecture Procedural of Decoder is signal s: bit vector (0 to 3); begin process (x) case x is when ”00”=> s<= ”1000”; when "01”=>s<= ”0100”; when ”10”=> s<= ”0010”; when "ll"=>s<= ”0001”; end case; end process; y<=s; end Procedural; Смешанное описание, использующее элементы структурного описания и элементы описания ’’поток данных”, приведено ниже. architecture Mixed of Decoder is component Inverter port (A: in Bit; B: out Bit); end component; signal S: bit vector (0 to 1); begin Invl: Inverter port map (A=>x(0), B=>s(0)); Inv2: Inverter port map (A=>x(l), B=>s(l)); p: process (s, x) begin y(0) <= s(0) and s(l); y(l)<=s(0) and x(l); y(2)<=x(0) and s(l); y(3) <= x(0) and x(l));
Примеры проектирования на VIIDL 147 end process; end Mixed; В данном примере структурное описание и описание типа "по- ток данных" весьма схожи, так как происходит замена логических элементов (компонентов) логическими выражениями. Однако для более сложных схем такая замена может быть совершенно не оче- видной. 4.2. Формы описания сигналов Битовое представление сигналов может быть громоздким. На начальных этапах проектирования могут быть использованы другие типы данных [1]. Component UU Component OU Рис. 4.2. Сигнал С может быть описан как bit_vector и как перечислимый тип Пусть устройство управления (UU) посылает четырехбитовый код в операционное устройство (OU). Четырехбитовый код опреде- ляет операцию, подлежащую выполнению. На рис. 4.2 выходной порт устройства управления имеет имя COUT, входной порт опера- ционного устройства - имя OUIN. Можно описать сигнал С на битовом уровне signal С: BIT_VECTOR(0 to 3); или же как перечислимый тип type CONTROL is (AND, OR, XOR, ADD, SUB,..., TCOMP); signa! C: CONTROL;
148 Глава 4 Таким образом, если использовать перечислимый тип, то управляющую информацию можно представлять в мнемоническом виде, т.е. именовать команды UU. При этом в архитектурном теле устройства управления можно было бы использовать операторы на- значения сигнала, такие как COUT <= ADD; а в архитектурном теле операционного устройства I if (OUIN = ADD) then ... При таком подходе разработчик модели освобождается от не- обходимости беспокоиться о низкоуровневых деталях [1]. Другой вариант описания сигнала С выглядит следующим образом: subtype CONTROL is INTEGER range 0 to 15; signal C: CONTROL; Подтип CONTROL ограничивает диапазон значений, которые могут быть присвоены сигналу С, тем самым обеспечивается неко- торый контроль ошибок. В некоторых случаях может понадобиться как битовый уро- вень, так и более высокий уровень - типа INTEGER. Для преобразо- вания типов нужны функции. Ниже описаны две функции. Функция BIN4 _TO_INT преобразует битовые векторы в це- лые числа путем суммирования соответствующих степеней двойки. Функция INT TO B1N4 выполняет обратную операцию. J Функция INT_TO_BIN4 приведена ниже в пакете w_vls. Пре- доставляем читателю самостоятельно написать VHDL-код функции BIN4 TO INT, для образца можно воспользоваться VHDL-кодом функции BIN2 O_INT, находящемся в теле пакета vv_vls. С использованием функции BIN2 TO_INT, INT TO BIN4 легко описывается (на алгоритмическом уровне) поведение схем mult_2, adder_2, входящих в схему VLSI1 (см. гл. 1). Определим функции BIN2_TO_INT, 1NT_TO_BIN4 в пакете vvjvls. 1 package vvjvls is function bin2_to_int (signal w2,wl: bit)
Примеры проектирования на VHDL 149 return integer; function int to_bin4 (signa! INPUT: integer) return bit_vector; type fsm_in_type is (zl, z2); type fsm_out_type is (wl, w2, w3, w4, w5); end vv_vls; package body vv vls is function bin2_to_int — функция преобразования битового (signal w2,wl: bit) вектора в число, w2 - старший разряд return integer is variable sum : integer :=0; begin ifwl=Tthen sum:=l; else sum :=0; end if; if w2 =T then sum := sum+2; else sum := sum; end if; return sum; end bin2_to_int; function int_to_bin4 -- функция преобразования числа (signal INPUT : integer) в битовый вектор return bit vector is variable fout: bit_vector(0 to 3); variable temp a: integer:=0; variable temp_b: intcger:=0; begin temp_a:=INPUT; for i in 3 downto 0 loop temp_b:=temp_a/(2**i); temp a:=temp_a rem (2**i); if (temp b=l) then
150 Глава 4 fout(i):-Г; else fout(i):-0'; end if; end loop; return fout; end int_to_bin4; end vv_vls; library work; use work.w_vls.all; entity mult_2 is -- функциональное описание умножителя port (sl,sO,rl,rO : in BIT; t3,t2,tl,tO: out BIT); end mult_2; architecture functional of mult_2 is signal ss, rr : integer range 0 to 3; signal tt: integer range 0 to 9; signal tt_sig : bit_vector (0 to 3); begin ss <= bin2_to_int(sl,s0); rr <= bin2_to_ int(r 1 ,r0); tt <= ss*rr; — функция умножителя tt_sig <= int_to_bin4(tt); to <= tt_sig(O); — формирование выходных сигналов tl <=tt_sig(l); t2 <= tt_sig(2); t3 <= tt_sig(3); end functional; library work; use work.vv_vls.all; entity adder_2 is — функциональное описание сумматора port (al,bl,a2,b2 : in BIT; c2,s2,sl : out BIT); end adder_2; architecture functional of adder 2 is signal aa, bb : integer range 0 to 3; signal cc : integer range 0 to 7;
Примеры проектирования на VHDL 151 signal сс_ sig : bit_vector (0 to 3); begin aa <= bin2_to_int (al,bl); bb <= bin2_to_int (a2,b2); cc <= aa+bb; cc_sig <= int_to_bin4(cc); si <=cc_sig(0); — функция сумматора — формирование выходных сигналов s2<=cc sig(l); c2 <= cc_sig(2); end functional; Предлагаем читателю провести моделирование схемы VLSI1 (разд. 1.1), используя архитектурные тела functional (алгоритми- ческие описания) для объектов проекта mult_2, adder_2 вместо архи- тектурных тел structure, представленных ранее в разд. 1.1. Чтобы заменить в VHDL-коде архитектурного тела fiinctional схемы VLSI_1 алгоритмическое описание структурным, необходимо сна- чала перейти к битовому уровню представления входных сигналов а. b (использовать функцию преобразования типа INTEGER в тип BIT_VECTOR), а затем от битового представления выходных сигналов D перейти к типу INTEGER. Предоставляем читателю сде- лать это самостоятельно. 4.3. Описание автоматов * Схема с обратной связью Рассмотрим схему, изображенную на рис. 4.3. В нее входит элемент памяти (D-триггер) и комбинационный элемент И. Данная схема описывается в виде двух процессов, причем для описания функционирования D-триггера вводится функция rising edge. architecture circ_fccdback of some_entity is signal b: bit; function rising_edge (signal s : bit) return boolean is begin return s = ’Г and s'event; end; begin
152 Глава 4 process (elk, reset) begin if reset = ’Г then c <= 'O’; elsif rising_edge(clk) c <= b; end if; end process; process (a, c) begin b <= a and c; end process; end circ feedback; — комбинационный процесс Рис. 4.3. Схема с обратной связью (architecture circ feedback) Конечный автомат Широкое распространение в практике проектирования дне кретпых устройств получила модель конечного (абстрактного) авто мата. Конечный автомат К определяется как набор K = (A,Z,W, 6, Х,а,),
Примеры проектирования на VHDL 153 где А = { а| ,..., 3q } - множество (алфавит) состояний (имеются в виду внутренние состояния автомата); Z = { Z| zN } - множество входных сигналов (входной ал- фавит); W = { w, ,..., wM } - множество выходных сигналов (выходной алфавит); 5 - функция переходов, определяющая состояние автомата в момент времени t+1 в зависимости от состояния автомата и входно- го сигнала в момент времени t, иначе говоря, as 5 (am , z), (4.1) где am - состояние автомата в момент времени t; z - входной сигнал в момент времени t; as - состояние автомата в момент времени t+1; X - функция выходов. Если функция X по состоянию авто- мата ат и входному сигналу zn определяет значение выходного сиг- нала wm wm = X (aq , zn), (4.2) то конечный автомат называется автоматом Мили , если же Wm = Л. (aq), (4.3) то конечный автомат называется автоматом Мура\ aj — начальное состояние автомата в момент времени t =0, ajG А. Функционирование автомата происходит следующим образом: в дискретные моменты времени t = 0, 1,2, 3,... па вход устройства поступает входной сигнал - один из элементов множества Z, а на выходе появляется выходной сигнал - один из элементов множества W, в этот же момент времени t автомат из состояния ат переходит в состояние а,, в котором он будет находиться в момент времени t+1. Разработаны различные формы задания конечных автоматов. Например, в табл. 4.1 задан конечный автомат с четырьмя внутрен- ними состояниями [2].
154 Глава 4 Таблица 4.1 Входные сигналы Состояния а. а2 а? a4 Z| a2/W| a2/w, ai/w2 ayw4 z2 a4/w5 a3/w3 a4/w4 a4/w5 Алфавит состояний А = {аь а2, а3, а4}, q = 1,...,4. Входной ал- фавит Z образуют сигналы zh z2t т. с. Z = {z,, z2}, n = 1,2. Выходной алфавит W образуют сигналы wb w5, т. е. W = {wb w2 ,w3 ,w4,w5}, m = 1,...,5. На пересечении строки zn и столбца aq в таблице находит- ся состояние as, в которое должен перейти автомат из состояния aq под воздействием сигнала zn. После косой черты в этой же графе таблицы указывается выходной сигнал, выдаваемый автоматом в состоянии aq при поступлении на его вход сигнала zn. Иначе говоря, табл. 4.1 является таблицей задания функций 5 Д и называется со- вмещенной таблицей переходов и выходов. Автомат может быть задан ориентированным графом, в кото- ром вершинам соответствуют абстрактные внутренние состояния автомата, а дуги соответствуют переходам между состояниями. Та- кой граф носит название графа автомата. Для автомата, заданного табл. 4.1, граф автомата имеет вид (рис.4.4). Рис. 4.4. Граф конечного автомата
Примеры проектирования на VHDL 155 Легко видеть, что совмещенная таблица переходов и выходов автомата и граф автомата являются эквивалентными формами зада- ния поведения конечного автомата. Следующий VHDL-код реализует поведение конечного авто- мата, заданного в табл. 4.1. Поведение автомата представляется в виде совокупности двух взаимодействующих процессов (рис. 4.5). Процесс NS определяет выходной сигнал w и внутренний сиг- нал NEXT_state, который является входным для процесса REG. За- метим, однако, что в списке чувствительности процесса REG имеет- ся только сигнал clk, который соответствует моментам времени сра- батывания автомата. Для входных сигналов автомата в пакете vv__vls определяется перечислимый тип type fsmjn type is (zl, z2); Рис. 4.5. Описание функционирования конечного автомата в виде совокупности двух процессов (entity FSM_A) для выходных сигналов в том же пакете определяется перечислимый тип type fsm_out_type is (wl , w2 ,w3 ,w4 ,w5); Для задания состояний автомата в архитектурном теле опре- деляется перечислимый тип t state. Предполагается, что начальное состояние автомата равно al. Начальное состояние явно пе указыва-
156 Глава 4 ется, так как при инициализации будет взят элемент нижней грани- цы перечислимого типа - это и будет элемент al. Library work; use work.vv_vls.all; entity FSMA is port (z : in fsm_in_type; elk: in bit; w: out fsm_out_type); end FSM_A; architecture rtl_a of fsm a is type T state is (al,a2,a3,a4); signal NEXT_state: T_state; signal state: T_state; begin NS : process (state, z) begin case state is when al => if (z=zl) then NEXT state <= a2; w <= wl; elsif (z=z2) then NEXT state <= a4; w <= w5; end if; when a2 => if (z=zl) then NEXT state <= a2; w <= wl; elsif (z=z2) then NEXT_state <= a3; w <= w3; end if; when a3 => if (z=zl) then NEXT_state <= al; w <= w2; elsif (z=z2) then NEXT_state <= a4; w <= w4; end if; when a4 => if (z=zl) then NEXT_state <= al; w <= w4; elsif (z=z2) then NEXT_state <= a3; w <= w5; end if; end case; end process;
Примеры проектирования на VHDL 157 REG : process(clk) begin if elk = 'Г then state <= NEXT_statc; end if; end process; end rtl_a; Сделав следующие назначения сигналов z, elk z <= zl, z2 after 50 ns, zl after 100 ns, zl after 200 ns, z2 after 150 ns, z2 after 250 ns; clk<=T, 'O'after 25 ns, Tafter 50 ns, 'O' after 75 ns, * 1' after 100 ns, 'O'after 125 ns, 'Г after 150 ns, 'O' after 175 ns, T after 200 ns, 'O'after 225 ns, 'Г after 250 ns; "снаружи" объекта FSM_A, получим соответствующую временную диаграмму (рис. 4.6) функционирования автомата. Многократное изменение синхросигнала elk можно более компактно описать в виде процесса generator. Переменная number задаст число тактов. В данном случае число тактов равно 5. generator: process variable number : integer := 5; begin for i in 1 to number loop elk <= transport 'Г; wait for 25 ns; elk <= transport 'O'; wait for 25 ns; end loop; end process;
158 Глава 4 Рис. 4.6. Временная диаграмма функционирования конечного автомата
Примеры проектирования на VI1DL 159 При схемной реализации автомата обычно поступают сле- дующим образом. Выделяют комбинационную часть автомата и па- мять. Как же детализировать описание поведения автомата на слу- чай элементов памяти того или иного типа? В случае нашего приме- ра будем реализовывать элементы памяти на D-триггсрах. Заметим, что в архитектурном теле rtl a для entity FSM_A не указывается, как будут функционировать элементы памяти. Так как поведение D- триггера нам известно, можем использовать соответствующий VHDL-код для описания процесса REG. Описание поведения конеч- ного автомата в виде совокупности двух взаимодействующих про- цессов — процесса NS и детализированного процесса REG - показано на рис. 4.7. Library work; use work.vv vis.all; entity FSM is port (z : in fsm_in_typc; elk, rst: in bit; w: out fsm_out_type); end FSM; architecture rtl of fsm is type T state is (al,a2,a3,a4); signal NEXT_statc, state : T state; begin NS : process (state, z) — комбинационный процесс • • • описание процесса NS дано в архитектурном теле rtl а для entity FSM_A end process NS; REG: process (elk, rst) — процесс REG для D-триггсра begin if (rst = ’Г) then state <= al; elsif clk’cvcnt and elk = 'Г then state <= NEXT__statc; end if; end process REG; end rtl;
160 Глава 4 z state rst Рис. 4.7. Детализированное описание функциони- рования конечного автомата (entity FSM) Дальнейшая детализация поведения автомата связана с коди- рованием значений перечислимых типов булевыми векторами, опи- санием функций комбинационной части схемы и формированием регистра триггеров. В качестве упражнения можно составить VHDL- код для структурной схемы автомата, для этого можно использовать приведенную в [2] структуру: булевы функции для комбинационной части и регистр D-триггеров. Микропрограммный автомат Микропрограммный автомат является одной из форм задания конечного автомата для случая, когда абстрактные входные и вы- ходные сигналы автомата закодированы булевыми переменными. Состояния микропрограммного автомата являются абстрактными (не закодированными). Микропрограммный автомат может зада- ваться графически - в виде граф-схемы алгоритма (ГСЛ). Одна и та же ГС А может реализовываться различными структурными схема- ми - автоматом Мили (Mealy) либо автоматом Мура (Мооге). Полу- чение различных структурных схем связано с различными методи- ками разметки ГСА - так называется процесс ввода внутренних со- стояний автомата. Далее будут приведены две реализации одной и той же ГСА (рис. 4.8) в виде автомата Мили и автомата Мура.
Примеры проектирования на VHDL 161 Рис. 4.8. Граф-схема алгоритма (разметка состояний для автомата Мили) Пример ГСА взят из книги [2], в которой подробно рассматри- ваются методики кодирования состояний и перехода от ГСЛ либо к графу автомата (графу переходов между состояниями), либо к таб- личной форме задания размеченной ГСА.
162 Глава 4 Автомат Мили На рис. 4.8 показаны внутренние состояния соот- ветствующие модели автомата Мили. Граф автомата Мили задан на рис. 4.9. Табл. 4.2 представляет собой табличную (эквивалентную гра- фовой) форму задания автомата Мили. Таблица 4.2 Таблица переходов автомата Мили Состояние а т Состояние as Условия перехода Выходные сигналы а, а2 1 У,Уз а2 а2 XtX2X3 аз Х1Х2 у 2У 3 а4 Х,Х2Х} У4 а5 XI 2 аз а4 1 У,У4 а4 at Х2 —- а6 Х2 Уз <*3 а, Х1Х4 Уб а4 Х4 у,у4 • а5 Х/Х4 — а6 а, I Уб В первом столбце табл. 4.2 показано состояние ат микропро- граммного автомата, из которого совершается переход, во втором столбце - состояние as, куда .совершается переход. Переходу соот- ветствует строка табл. 4.2.
Примеры проектирования на VHDL 163 VHDL-модель автомата Мили, построенная по эквивалентным формам задания (ГСА (рис.4.8), граф автомата (рис.4.9), табл. 4.2) приводятся ниже. Рис. 4.9. Граф автомата Мили entity Mealy is port(x:in bit_vector (4 downto 1); elk, rst :in bit; y:out bit vector (6 downto 1)); end Mealy; architecture rtl of Mealy is type T_state is (al, a2, аЗ, a4, a5, a6); signal NEXT_statc, state:T_state; begin NS : process (state,x) begin case state is « when al => NEXT state <= a2; у <="000101"; - код y= (у6, y5, y4, уЗ, у2, у 1) — код х= (х4, хЗ, х2, xl) when а2 => if ((х( 1) and not х(2) and not х(3))= 'Г)
164 Глава 4 then NEXTstate <= a2; у <="000000"; elsif (not x(l) = T) then NEXT_statc <= a5; у <="000010"; elsif ((x(l) and not x(2) and x(3)) = ’Г) then NEXT_statc <= a4; у <="001000"; elsif ((x(l) and x(2)) = T) then NEXT_state <= аЗ; у <="000110"; end if; when a3 => NEXT_state <= a4; у <="001001"; when a4 => if (x(2)= T) then NEXT_state <= аб ; у <="010000"; elsif ( not x(2) ='Г) then NEXT_statc <= al ; у <="000000"; end if; when a5 => if((x(l)and x(4))=T) then NEXTstate <= a5; у <="000000"; elsif (not x(4) = 'Г) then NEXT_state <= a4; у <="001001"; elsif ((not x(l) and x(4)) = T) then NEXT_state <= al; у <="100000"; end if; when a6 => NEXT_state <= al; у <="100000"; end case; end process NS; state <= al when rst = T else NEXT_state when clk'event and elk = T else state; end rtl; В формальной модели микропрограммного автомата (граф- схеме алгоритма) сигналы elk, rst отсутствуют. Введение сигнала elk в текст VHDL-программы необходимо для управления переключе- нием элементами памяти по переднему фронту сигнала elk. Можно обойтись без оператора процесса, воспользовавшись оператором назначения сигнала для переключения состояний. В тексте
Примеры проектирования на VHDL 165 VHDL-кода присутствует также сигнал rst, управляющий установ- кой автомата в начальное состояние al. Автомат Мура, На рис. 4.10 показаны внутренние состояния ah а2,...9 со- ответствующие модели автомата Мура. Рис. 4.10. Граф-схема алгоритма (разметка состояний для автомата Мура) Граф автомата Мура задан па рис. 4.11, табл. 4.3 представляет собой эквивалентную размеченной ГСЛ графовую форму задания автомата Мура. В первом столбце табл. 4.3 показано состояние мик-
166 Глава 4 ропрограммного автомата, из которого совершается переход, во вто- ром столбце - состояние, куда совершается переход. Так как для ав- томата Мура выходные сигналы определяются только состоянием, то для каждого состояния во втором столбце указываются тс выход- ные сигналы, единичные значения которых автомат выдаст, нахо- дясь в данном состоянии. Рис. 4.11. Граф автомата Мура Таблица 4.3 Таблица переходов автомата Мура Состояние ат Состояние ах, выходные сигналы Условие перехода а! а2 1 а2 а2> У,Уз XfX2X3
Примеры проектирования на VHDL 167 Продолжение табл. 4.3 a2 аз> У2У3 a4> У4 a6> У 2 Х{Х2 Х2Х3 Xi аз ?5> У1У4 1 a4 ai У 5 Х2 Х2 a5 °, У 5 Х2 Х2 a6 ОД У/У 4 a6 > У 2 а8> Уб Х4 Х,Х< Х1Х4 a7 а8> Уб 1 a8 а! 1 VHDL-модель автомата Мура, построенная по эквивалентным формам задания (ГСА (рис. 4.10), граф автомата (рис. 4.11), табл. 4.3) приводятся ниже. Сигнал elk управляет переключениями элементов памяти, по единичному значению сигнала rst автомат пе- реходит в начальное состояние al. entity Moore is port(x:in bit_vector (4 downto 1); clk, rst :in bit; y:out bit_vector (6 downto 1)); end Moore; architecture rtl of Moore is type T state is (al, a2, аЗ, a4, a5, a6, a7, a8); signal NEXT_state,state:T_state; begin
168 Глава 4 NS : process (state,x) begin case state is when al => NEXT_statc <= a2; when a2 => , • ; if ((x( 1) and not x(2) and not x(3))= *1 *) then NEXT_state <= a2; elsif ((x(l) and x(2)) = T) then NEXT_state <= a3; elsif ((x(I) and not x(2) and x(3)) = T) then NEXT_state <= a4; elsif (not x(l) = 'Г) then NEXT_state <= a6; end if; when a3 =>NEXT_statc <= a5; when a4 => if (not x(2) = ’Г) then NEXTstate <= al; elsif (x(2) = 'Г) then NEXT_state <= a7; end if; when a5 => if (not x(2) = T) then NEXT_state <= al; elsif (x(2) = T) then NEXT_state <= a7; end if; when a6 => if (not x(4) = T) then NEXT_state <= a5; elsif ((x(l) and x(4)) = T) then NEXT state <= a6; elsif ((not x(l) and x(4)) = T') then NEXT_state <= a8; end if; when a7 => NEXT_state <= a8; when a8 => NEXT state <= a 1; end case; end process NS;
Примеры проектирования на VIIDL 169 у <= "000000" when state = al else "000101" when state = a2 else "000110" when state = a3 else "001000" when state = a4 else "001001" when state = a5 else "000010" when state = a6 else "010000" when state = a7 else "100000"; state <= al when rst = T else NEXT_statc when clk'event and elk = T else state; end rtl; Обращаем внимание на то, что в автомате Мура выходные сигналы полностью определяются внутренними состояниями авто- мата, поэтому их можно “собрать” в один оператор параллельного назначения сигнала. 4.4. Отладка VHDL-описаний Отладка VHDL-кодов происходит путем подачи входных сиг- налов в объект проекта, после чего происходит сравнение получен- ных реакций с ожидаемыми. Этот процесс, по существу, аналогичен отладке программ. С точки зрения "отладки" аппаратуры этот про- цесс напоминает тестирование схемы на предмет установления пра- вильности ее функционирования. Пример тестирования VHDL-кода схемы VLSI1. entity test_vlsi_l is end test_vlsi_l; architecture test of tcst_vlsi_l is component vlsi 1 port (a2,al,b2,bl,x : in BIT; d4,d3,d2,dl : out BIT); end component; signal a2, al, b2, bl, x, d4, d3,d2,dl : BIT; begin
170 Глава 4 pxomponent vlsi_l port map (a2 => a2, al=>al, b2=>b2,bl=>bl,x=>x, d4=>d4, d3=>d3,d2=>d2,dl=>dl); Ь2 <= 'Г; bl <= ’Г; a2 <= T; al <= 'O’, 'Г after 50 ns; x <= 'O', 'Г after 30 ns, 'O' after 70 ns ; end test; . г » ' b { Временная диаграмма показана на рис. 4.12. В табл. 4.4 дано функционирование схемы во времени. О 30ns 50ns 70ns 100ns i—l—l—I—I—I—I—।—I—i—I— Время b2 bl x d4 d3 d2 dl Рис. 4.12. Временная диаграмма
Примеры проектирования на VHDL 171 Таблица 4.4 Сигналы Время [Ons, 30ns] [30ns, 50ns] [50ns, 70ns] 70ns, 100ns] а=(а2, al) b=(b2,bl) х=(х) 2 3 0 (сложение) 2 3 1 (умножение) 3 3 1 (умножение) 3 3 0 (сложение) d=(d4,d3, d2,dl) 5 6 9 6 В данном примере объект проекта test_vlsi__l представляет со- бой "оболочку" (рис. 4.13) объекта проекта vlsil с единственной целью - организовать подачу входных сигналов в объект vlsi_l, так как внутри архитектурного тела объекта vlsi_l нельзя назначить входные сигналы. Входные сигналы для entity должны быть назна- чены ’’снаружи”! entity tcst_VLSI_l Рис. 4.13. При тестировании объекта VLSI_1 entity test_VLSl_l не имеет портов
172 Глава 4 4.5. Синтезируемое подмножество языка VHDL После того как проектировщик убедился в корректности VHDL-модели цифровой системы, возникает проблема программной либо схемной реализации данной модели. Схемные реализации, как правило, являются более быстродействующими, поэтому важной задачей является задача синтеза схемы, функции которой реализуют поведение VHDL-модели. На практике, однако, переход к соответст- вующей логической схеме осуществляется не для всего языка VHDL, а только для некоторого подмножества этого языка, назы- ваемого синтезируемым подмножеством. Для VHDL-модсли цифро- вой системы, описанной на синтезируемом подмножестве языка VHDL, можно получить схему. Обычно это интегральная схема типа ПЛИС либо схема, программируемой пользователем, вентильной матрицы [5]. Общий метод получения такой схемы является компи- лятивным. Операторы языка VHDL заменяются компилятами. Ком- пилят - это подсхема, реализующая вполне определенный оператор (конструкцию) языка, например, оператор сложения. При синтезе схемы типы данных bit отражаются при синтезе в проводники (по- люса) схем, типы данных bit vector - в шины (жгуты проводников). Перечислимые типы данных при синтезе кодируются булевыми век- торами. Кодирование обычно ведется с использованием минималь- ного числа кодирующих переменных. Например, для перечислимого типа type my state is (RESET, IDLE, RW_CYCLE, INT_CYCLE); может быть проведено кодирование RESET = "00", IDLE = "01", RW CYCLE = "10", 1NTCYCLE = "11". Очевидно, в кодах 00, 01, 10, 11 используются только две ко- дирующие булевы переменные. Компилятивный подход - не единственный для реализации ал- горитмических описаний. Например, в работе [4] предлагается спо-
Примеры проектирования на VHDL 173 соб схемной реализации параллельных процессов, описанных в тер- минах только двоичных переменных. Предложенный в [4] язык опи- сания параллельных процессов и способ схемной реализации бази- руются на мощном формализме сетей Петри. Переменные языка VHDL, мгновенно передающие свои значе- ния, исчезают при схемной реализации. В приведенном ниже приме- ре проследите за переменной W в VHDL-коде и в соответствующей схеме (рис. 4.14). Пример схемной "реализации" переменных языка VHDL. Library' IEEE; use lEEE.stdlogicl 164,all; entity xor_var is port (A,B,C : in std_logic; X,Y : out std logic); end xor var; architecture example of xor_var is begin P: process (A,B,C) variable W: std_logic; begin W := A; X <= C xor W; W := B; Y <= C xor W; end process; end example; Рис. 4.14. Исчезновение переменных при схемной реализации
174 Глава 4 Для логических операторов and, or, nand, nor, xor, xnor, not, над типами bit, boolean, arrays, bit_vector, компиляция в схему осу- ществляется прямым преобразованием логических выражений в со- ответствующие логические вентили (элементы). Пример схемной реализации логических выражений. entity logical_pps__l is port (a, b, c, d: in bit; m: out bit); end Iogical_ops_l; architecture example of logical_ops_l is signal e: bit; begin m <= (a and b) or e; — оператор назначения сигнала e <= c xor d; end example; Схема, реализующая поведение объекта logical_ops_l, приве- дена на рис. 4.15. Рис. 4.15, Схемная реализация логического выражения для типа bit Пример схемной реализации логических выражений типа bit vector.
Примеры проектирования на VHDL 175 entity logical_ops_2 is port (a, b: in bit_vector (0 to 3); m: out bit_vector (0 to 3)); end logical_ops_2; architecture example of logical_ops_2 is begin m <= a and b; end example; Соответствующая схема приведена на рис. 4.16. а(0) Ь(0) а(1) Ь(1) а(2) Ь(2) а(3) Ь(3) т(0) т(1) т(2) т(3) Рис. 4.16. Схемная реализация логического выражения для типа bit_vector Схемная реализация операторов отношения Операторами отношения являются следующие операторы: = (равно); /= (неравно); > (больше); < (меньше); >= (больше или равно); <= (меньше или равно).
176 Глава 4 Операторы « , /= определяются в языке VHDL для всех типов. Операторы (>=, <=, >, < ) определяются для числовых типов, пере- числимых типов и некоторых массивов. Результирующий тип для всех операторов boolean. Следующие два примера показывают схемную реализацию для операторов а=Ь, а>=Ь. entity relational_ops_l is port (a, b: in bit_yector (0 to 3); m: out boolean); end relational_ops_l; architecture example of relational_ops_l is begin m <= a = b; end example; Схема, реализующая оператор равенства для типа bit vector, приведена на рис'. 4.17. а(0) Ь(0) а(1) Ь(1) а(2) Ь(2) а(3) Ь(3) m Рис. 4.17. Схемная реализация оператора а=Ь для типа bit_vector (0 to 3)
Примеры проектирования на VHDL 177 entity relational_ops_2 is port (a, b: in integer range 0 to 3; m: out boolean); end relational_ops_2; architecture example of relational_ops_2 is begin m <= a >= b; end example; Схема, реализующая оператор >= для типа integer, показана на рис. 4.18. Схемная реализация арифметических операторов Арифметические операторы + (сложение); - (вычитание); * (умножение); / (деление); mod (модуль); rem (остаток); abs (абсолютное значение); ** (возведение в степень) определяются для числовых типов. Операторы ( +, - ) являются достаточно ’’дорогостоящими" (дающими сложные схемы). Операторы (*, / , mod, rem) являются очень дорогостоящими. Обычно при синтезе делается специальная оптимизация, если справа от оператора находится константа или число, не большее 2. Реализация оператора (abs) не является слож- ной. Оператор (**) поддерживается только для констант. Примеры схем, реализующих операторы сложения и умноже- ния, уже рассматривались в данной книге. Например, сложение двухразрядных чисел осуществляется схемой addcr__2, умножение двухразрядных чисел - схемой mult_2 (см. разд. 1.1), сложение N- разрядных чисел - схемой adder_N (см. разд. 2.2).
178 Глава 4 Рис. 4.18. Схемная реализация оператора отношения а>=Ь для целых чисел a =(a3,a2,al,a0), b =(ЬЗ,Ь2,Ь1,Ь0)
Примеры проектирования на VHDL 179 Схемная реализация операторов управления Схемным ’’аналогом” оператора if является, по существу, мультиплексор (рис. 4.19) с одним управляющим входом, где Ь, с выступают в качестве настроечных входов, вход а - в качестве управляющего. Функционирование мультиплексора описывается следующей формулой: m = а& с v а& b. entity control_if is port (a, b, c: boolean; m: out boolean); end control_if; architecture example of controMf is begin process (a, b, c) variable n: boolean; begin if a then n := b; else n := c; end if; m <= n; end process; end example; Схема, реализующая оператор if, изображена на рис. 4.19: если а=1, то m=b, если а=0, то т=с. Предлагаем читателю сравнить функ- цию, реализуемую процедурой MX, содержащейся в пакете multi- plexer (разд. 1.2), с функцией объекта проекта control_if. Однако не всегда очевидна та логическая схема, которая соот- ветствует оператору языка VHDL. В качестве примера укажем на тот факт, что в компиляторах, осуществляющих схемную реализа- цию VHDL-кода, оператор if, у которого после ключевого слова else не производится никаких действий, интерпретируется как D-триггер (задержка). Поэтому получение нужных логических схем по VHDL- кодам с помощью САПР требует тщательного изучения библиотеки компилятов.
180 Глава 4 Рис. 4.19. Схемная реализация оператора управления if (entity controlif) Схемная реализация оператора case entity control_case is port (sei: in bit_vector (0 to 1); a,b,c,d : in bit; m: out bit); end control_case; architecture example of control case is begin process (sel,a,b,c,d) begin case sei is when "00" => m <= c; when "01" => m <= a; when " 10" => m <= d; when others => m <= b; end case; end process; end example; Схема, реализующая оператор case, изображена на рис. 4.20. Схемная реализация подпрограмм и циклов Операторы generate, loop (for loop, while loop), function, proce- dure также могут быть схсмно реализованы.
Примеры проектирования на VHDL 181 sel(l) Рис.4.20. Схемная реализация оператора case (entity control case) Для каждого вызова подпрограммы и для каждой итерации цикла создастся соответствующая схема. entity control_loop is port (a: bit-Vector (0 to 3); m: out bit-Vector (0 to 3)); end control-loop; architecture example of control-loop is
182 Глава 4 begin process (a) variable b: bit; begin b for i in 0 to 3 loop b:= a(3-i) and b; m( i) <= b; end loop; end process; end example; entity subprograms is port (a: bit vector (0 to 2); m: out bit_vector (0 to 2)); end subprograms; architecture example of subprograms is function simple (w, x, y: bit) return bit is begin return (w and x) or y; end; begin process (a) begin m(0) <= simple(a(0), a(l), a(2)); m(l) <- simple(a(2), a(0), a(l)); m(2) <= simple(a(l), a(2), a(0)); end process; end example; Например, для цикла (entity loop stmt) и для подпрограммы (entity subprograms) соответствующие схемы приведены ниже (рис. 4.21,4.22).
Примеры проектирования на VHDL 183 Рис. 4.21. Схемная реализация оператора loop (entity control_loop) Рис. 4.22. Схемная реализация оператора ’’подпрограмма" (entity subprograms)
1 184 Глава 4 В заключение можно сказать, что мир VHDL большой и дос- таточно сложный, так как сложны те электронные схемы и системы, инструментом описания, моделирования, верификации и синтеза которых он является. За чертой остались еще такие аспекты языка VHDL, как типы файлов и типы доступа, инородные подпрограммы, j группы, разделяемые переменные и другие вопросы. Автор надеет- ся, что провести их изучение можно будет, базируясь на материалах, представленных в данной книге. 4 УПРАЖНЕНИЯ | 1. Правильны ли утверждения: а) структурное VHDL-описание может быть иерархичным; Ь) поведенческое VHDL-описание может быть иерархичным; с) смешанное (структурно-поведенческое) VHDL-описание не может быть иерархичным? / I 2. Правильно ли, что структурное описание состоит из компо- нент и сигналов? 3. Правильно ли, что все компоненты должны быть специфи- цированы на поведенческом уровне? 1 4. Какие компоненты проекта не имеют структурного описа- ния? 5. Какое устройство реализует поведение, представленное VHDL-кодом? j Library IEEE; use lEEE.std logic 1164.all; 1 entity £X is port (A : in std_ulogic_vector(0 to 15); I SEL : in integer range 0 to 15; Z : out std ulogic); 1 end EX; I architecture RTL of EX is I begin WHAT: process (A, SEL) begin ] for I in 0 to 15 loop
Примеры проектирования на VHDL 185 if SEL = I then z <= A(l); end if; end loop; end process WHAT; end RTL; Выберите правильный ответ: а) дешифратор; в) счетчик; с) мультиплексор. Укажите разрядность устройства, 6. Опишите поведение конечного автомата, используя двух- размерные массивы для задания совмещенной таблицы переходов и выходов. 7. Используя информацию о структурной схеме, приведенную в [2, с. 20-21], составьте VHDL-код и проведите моделирование ко- нечного автомата, поведение которого задано в архитектурном теле rtl a (entity FSMA). 8. Составьте VHDL-код для генерации синхроимпульсов (см. рис. 4.5) в виде процесса с использованием оператора wait. 9. Как должен быть написан VHDL-код, чтобы с помощью существующих средств САПР можно было автоматически получить схему? Выберите правильный ответ. а) код должен быть написан на поведенческом уровне; Ь) код должен быть написан на уровне регистровых передач; с) код должен быть написан на уровне логических вентилей; d) средства САПР могут синтезировать схему для любого уровня VHDL-описания. 10. В данной книге даны различные архитектурные тела для D-триггера. Рассмотрите особенности их функционального и струк- турного описания. Проведите моделирование.
Литература 1. Армстронг Дж. Р. Моделирование цифровых систем на языке VHDL/Пер с англ. - М.: Мир, 1992. - 175 с. 2. Баранов С. И., Скляров В. А. Цифровые устройства на программируемых БИС с матричной структурой. - М.: Радио и связь, 1986. - 279 с. 3. Бибило П. Н. Кремниевая компиляция заказных СБИС. — Минск: Ин-т техн, кибернетики АН Беларуси, 1996. - 268 с. 4. Закревский А. Д. Параллельные алгоритмы логического управления. - Минск: Ин-т техн, кибернетики НАН Беларуси, 1999. - 202 с. 5. Соловьев В. В., Васильев А. Г. Программируемые логиче- ские интегральные схемы и их применение. - Минск: Беларуская навука, 1998. — 270 с. 6. VHDL для моделирования, синтеза и формальной верифи- кации аппаратуры / Пер с англ. - М: Радио и связь, 1995. - 360с. 7. VHDL’92. Новые свойства языка описания аппаратуры VHDL / Пер с англ. - М.: Радио и связь, 1995. -256 с. 8. Asheden Р. J. The VHDL Cookbook. University of Adelaide, South Australia. -1990. 9. Chang К. C. Digital design and modeling with VHDL and synthesis. IEEE Computer Society Press. 1997. 10. IEEE Standard VHDL Language Reference Manual, IEEE Std 1076-1987. 11. IEEE Standard VHDL Language Reference Manual, IEEE Std 1076-1993. .
Приложения 1. Форма задания синтаксических конструкций языка VHDL Для задания синтаксических конструкций языка VHDL исполь- зуются так называемые формы Бэкуса-Наура, служащие для описа- ния грамматик формальных языков. Для определения синтаксиче- ской конструкции используется выражение <синтаксическая конструкция^ :-<о пред ел сние> Используемые фигурные скобки служат для обозначения по- вторения выражения, заключенного в них. Выражение может повто- ряться к раз (к=0,1,2,...). При к=0 выражение отсутствует. Вертикальная черта служит для обозначения альтернативных случаев. Например, letter_or_digit ::= letter | digit, т.е. синтаксическая конструкция символ_или_число определяется как символ (letter) или цифра (digit). В случае, например, choices::=choice{ choise}, когда в фигурных скобках стоит то же выражение (с символом «вер- тикальная черта»), это означает повторение того же выражения. В данном примере повторяется выражение «choice». Квадратные скобки служат для обозначения необязательного выражения или необязательного слова. Например, запись retum_statement::=retum[expression]; эквивалентна записи retum_statement::=return; | retum[expression]; Если элемент синтаксической конструкции начинается с курси- ва, то выделяемая курсивом часть конструкции несет смысловую нагрузку (семантическую информацию). Выделяемое курсивом сло- во может не приниматься во внимание. Например, элементы (ype_name и swtyjpejiame могут рассмат- риваться просто как name (имя). В случае (у/>е_пате подчеркивается, что это имя типа, в случае зиЫуре_пате, что это имя подтипа.
188 Приложения 2. Синтаксис языка VHDL’93 Синтаксические конструкции, приводимые в данном прило- жении, можно найти по следующему адресу сети Internet: http://tech-www.informatik.uni-haniburg.de/vhdl/tools/vhdl-93.bnf abstract literal ::= decimal-literal | based_ literal access_type_defmition ::= access subtype indication actual-designator ::= expression | signal name | var/aWe—name |У//е_пате | open actualjparamcter_part ::=/2ara?2ie/er__association list actual_part ::= actual-designator \ function ( actual-designator ) | type mark ( actual designator) adding-Operator ::= +1 - | & aggregate ::= ( element_association {, element-association }) alias_declaration ::= alias alias_designator [: subtype_indication ] is name [signa- ture]; alias designator ::= identifier | character literal | operator-symbol
Приложения 189 allocator ::= new subtypc_indication | new' qualifiedexpression architecture__body ::= architecture identifier of e/iZ/Tyname is architecture declarative_part begin architecture _statement_part end [ architecture ] [ tzrcA/7ecZwre_simple__name ]; architecture_declarative_part ::= { block_declarative item } architecture_statemcnt_part ::= { concurrent_statemcnt} array_type_definition ::= unconstrained_array_defmition | constraincd_array_defmition assertion ::= assert condition [ report expression ] [ severity expression ] assertion_statement ::= [ label: ] assertion ; association_element ::= [ formal_part => ] actual__part association list ::= association element {, association_element} attribute_dcclaration attribute identifier: type_mark ; attribute designator ::= ^zzrz7?i//c_simple_name
190 Приложения attribute name ::= prefix [ signature ]' attribute designator [ ( expression ) ] attribute_specification ::= attribute attribute designator of cntity_specification is expres- sion ; base ::= integer base_specifier В | О | X base_unit declaration : := identifier; based_integer ::= extended_digit {[ underline ] extended_digit} based_literal ::= base # based_integer [. based_integer ] # [ exponent ] basic_character ::= basic_graphic_character | format_effector basic graphic character ::= upper_case_letter | digit | special_character| space character basic_identifier ::= letter {[ underline ] lettcr_or_digit} binding indication ::= [ use entity_aspect ] [ generic_map_aspect ] [ port_map_aspect ] bit_string_literal ::= base_specifier " bit value " bit_value ::= extended_digit {[ underline ] extended_digit}
Приложения 191 block configuration ::= for block specification {use_clause } { configuration item } end for; block_declarative_item ::= subprogram_declaration | subprogram_body type_declaration | subtype_declaration | constant_declaration | signaldeclaration | sAaretZ-Variabledeclaration file_declaration | alias_dcclaration | component declaration | attribute_declaration | attribute_specification | configuration_specification | disconnection specification | use clause | group_template_declaration | groupdeclaration block_dcclarative_part ::= {block declarativc item } block_hcader ::= [ generic_clause [ generic map_aspect; ] ] [ port_clause [ port_map_aspect; ] ]
192 I [риложсния block_specification ::= architecture | block_statement__ label | generate-Statement[ (indexspecification ) ] block_statement ::= Ыоск_\аЪе\: block [ ( guard^expression ) ] [ is ] block_headcr block_ declarative-part begin block_statement_part end block [ block_\abc\ ]; block_statement_part ::= {concurrcnt_statemcnt} case_statemcnt ::= [ cave_label : ] case expression is casestatcmentaltemative { case_stateinent_alternative } end case [ case_label ]; casc_statement_altemative ::= when choices => sequence_of_statements character litcral ::= * graphic_character ’ choice ::= simple_expression | discrete range | e/e/HenZ_simple_name | others choices ::= choice {| choice }
Приложения 193 component_configuration ::= for component_spccification [ bindingindication; ] [ block_configuration ] end for; component declaration ::= component identifier [ is ] [ /oc«/_generic_clause ] [ /oca/_port_clausc ] end component [ co/n/;one/i/_simple_name ]; component instantiation statement ::= instantiationlabel: instantiatedunit [ generic_map_aspect ] [ port_map aspect ]; component specification ::= instantiation_list: component_name composite_typc_definition ::= array_type_dcfinition | record_type_definition concurrent_assertion_statcment ::= [ label: ] [ postponed ] assertion ; concurrent_procedure_call_statement ::= [ label: ] [ postponed ] proccdure call; concurrent_signal_assignment_statement ::= [ label: ] [ postponed ] conditional- signal assignment | [ label: ] [ postponed ] selected_signal_assignmcnt
194 Приложения concurrent_statement ::= block_statement | process_statement | concurrent_procedure_call_statement | concurrent_asscrtion_statement | concuirent_signal_assignmcnt_statcment | component_instantiation_statcment | generate_statement condition ::= boolean-expression condition_clause ::= until condition conditional—signal—assignment: := target <= options conditional_waveforms ; conditional-Waveforms ::= { waveform when condition else } waveform [ when condition ] configuration-declaration configuration identifier of enZ/ry_name is configuration_declarativc-part block_configuration end [ configuration ] [ configuration_smple_narne ]; configuration-declarative_item: := use-dause | attribute_specification I group_declaration configuration_dcclarative_part ::= {configuration_declarative_item } configuration_item ::= block_configuration | component-configuration
Приложения 195 configuration specification ::= for component_specification binding_indication; constant_declaration ::= constant identifier list: subtype_indication [ := expression ]; constrained_array_definition ::= array index constraint of eZemew/_subtype_indication constraint ::= range_constraint | index constraint context_clause ::= { context_item } context_itcm ::= library_clausc | use clause decimal_literalinteger [. integer ] [ exponent ] declaration ::= typc_dcclaration | subtype_declaration | object declaration | interface declaration | alias dcclaration | attributc dcclaration | component_declaration | group_template_declaration | group_declaration | entity declaration | configuration declaration | subprogram declaration | packagc_dcclaration
196 Приложения delay_mechanism ::= transport | [ reject z<we_exprcssion ] inertial design_file ::= design_unit { design_unit} design_unit ::= context_clause library_unit designator ::= identifier | opcrator_symbol direction ::= to | downto disconnection_specification ::= disconnect guarded_signal_spccification after Zzme_expression ; discrete_range t/zscreresubtypeindication | range element_association ::= [ choices => ] expression element_declaration ::= identifier_Iist: element_subtype_definition; element_subtype_definition ::= subtype_indication entity_aspect entity en/z'ryname [ ( architecture_identifier) ] | configuration con/iguration_name | open entity_class ::= entity | architecture | procedure | function | type | subtype | signal | variable | label | literal | group | file | configuration |package | constant | component | units
Приложения 197 cntity_class_entry ::= entity_class [ о ] entity_class_entry_list ::= entity_class_entry {, entity_class_entry } entity_dcclaration ::= entity identifier is entity_header entity_declarative_part [ begin entity_statement_part ] end [ entity ] [ en/z/y_simple_name ]; entity_declarative_item ::= subprogram_declaration | subprogram_body I type_dcclaration | subtype_declaration | constant_declaration | signal_declaration 16Aarec/_variable_declaration | file_declaration | alias declaration | attribute_declaration | attribute_specification | disconnection_specification | use_clausc | group_template_declaration | group_declaration entity_declarative_part ::= { cntity_dcclarative_item } entity_designator ::= entity_tag [ signature ] entity_header ::= [ybrwa/_generic_clause ] [/br/»a/_port_clause ]
200 Приложения function call ::= function name [ ( actual_paramcter_part ) ] gcnerate_statement ::= ge/7erate_labcl : gcneration_schcmc generate [ { block__dcclarative__item } begin { concurrent_statcmcnt} end generate [ ge/iera/ejabel ]; generation_scheme ::= for ge/?e/^Ze_parameter_spccification | if condition gencric_clause generic ( gcneric_list ) ; generic_list ::= ge//c/7c_intcrface_list generic_map_aspect ::= generic map (ge>wr/c_associationjist) graphic charactcr ::= basic graphic_character | lowcr_case_ letter | other_spccial_character group_constitucnt ::= name | character literal group_constituent_Jist ::= group constituent {, group constituent} group_tcmplate_declaration ::= group identifier is ( entity_class_entry_Jist); group-declaration ::= group identifier : group_t&nplatejnavat (group_constitucnt_ list);
Приложения 201 guarded-Signal-Spccification ::= gw<7/Y/ed_signal_Jist: type mark identifier ::= basic_identifier | extcndcd_jdentifier identifier_list ::= identifier { , identifier } i f_statement ::= [ z/Jabcl: ] if condition then scquence_of_statcments { elsif condition then sequence_of_statements} [ else sequcncc_of_statements ] end if [ z/Jabel ]; incomplete_typc_declaration type identifier; index_constraint ::= ( discrete_range {, discrete_range } ) index_spccification ::= discrete_range 15/tf//c_cxpression indcx_subtype_dcfmition ::= type_mark range indexed_name ::= prefix ( expression {, expression }) instantiatcd_unit ::= [ component ] componentname | entity e/n/7v_namc [ ( architecturefidenUfier ) ] | configuration configuration jname
202 Приложения instantiation_list ::= instantiation_label { , instantiation Jiabci } | others | all integer ::= digit { [ underline ] digit } integer_type_definition ::= range_constraint interface_constant_declaration ::= [ constant ] identifier list: [ in ] subtype indication [ := staZ/c exprcssion ] interface__declaration ::= interface_constant_declaration | interface_signal_declaration | interface_variable_dcclaration | interface_file_declaration interface_element ::= interface declaration intcrface_filc_declaration ::= file identifier_list: subtype indication interface list intcrface_element {; intcrface_element} interface signal__declaration [signal] identifier list: [ mode ] subtypc indication [ bus ] [ := staZzc__expres*sion ] interface_variable_declaration ::= [variable] identifier list: [ mode ] subtype_indication [ := staticexpression ] iteration_scheme ::= while condition | for /oop__parameter__specification
Приложения 203 label ::= identifier letter ::= uppcr_case_letter | Iower_case_lcttcr letterordigit letter | digit library_clause ::= library logical_name_list; library_unit ::= primaryunit | secondary unit literal ::= numeric_li teral | enumeration literal | string litcral | bit_string_literal I null logicalnamc ::= identifier logical_name_list ::= logical_name {, logicai_name } logical_operator ::= and | or | nand | nor | xor | xnor loop_statement ::= [ /oqpjabel: ] [ iteration scheme ] loop scquence_of_statements end loop [ /op/?_Iabel ]; miscellaneous operator ::= ** | abs | not mode ::= in | out | inout | buffer | linkage multiplying operator ::= * | / | mod | rem
204 Приложения name ::= simplc_name | operator symbol | selected_namc | indexed_name | slice_name | attribute_name next_statement ::= [ label: ] next [ /ooplabel ] [ when condition ]; null_statement ::= [ label: ] null; numeric_literal ::= abstract_litcral | physical Ji teral object_declaration ::= constant_declaration | signal_declaration | variable_declaration | file_declaration operator_symbol ::= string_literal options ::= [ guarded ] [ delay_mechanism ] package_body ::= package bodypackageis package_body_declarative_part end [ package body ] [ p«ctoge_simple_name ]; package_body_declarative_item: := subprogramdeclaration | subprogram_body I type_declaration | subtype_declaration
Приложения 205 | constant__declaration | s/iared_variable_declaration | file-declaration | alias-declaration | usc_clause I group—template declaration I group-declaration packagebodydeclarativejpart ::= {package_body_declarative_itein} package-declaration ::= package identifier is package_declarative_part end [ package ] [p^cA^ge_simple_name ]; package_declarative_item subprogram declaration I type-declaration | subtype_declaration | constant-declaration | signal-declaration | s/7ared-Variable_declaration | file-declaration | alias-declaration | component-declaration | attributc_dcclaration | attribute specification | disconnection-specification | usC-dause | group-template-declaration I group declaration packagc_dcclarative_part ::= {package-declarative_item}
206 Приложения paramet er_specification identifier in discrete_range physical_litcral ::= [ abstract_litcral ] w/n7_name physical_type_dcfinition ::= range_constraint units base_unit_dcclaration {secondary unit declaration} end units [ physical_type_simp\e_name ] port_clause ::= port ( port_list) ; port_list ::=/?or/_interface_list port_map_aspect ::= port map ( porZ_association_list) prefix ::= name | function_call primary ::= name | literal | aggregate | functibn_call | qualifted_exprcssion I type_conversion | allocator | ( expression )
Приложения 207 primary_unit ::= entity_declaration | configuration_dcclaration | package-declaration proccdurc_call ::= procedure[ ( actual_paramcter_j)art) ] procedure_call_statement ::= [ label : ] procedure_call; proccss_dcclarativc_item ::= subprogram_declaration | subprogram_body I typC-declaration | subtype_declaration | constant-declaration | variable_declaration | file_declaration | alias_dcclaration | attribute_declaration | attribute_specification | use_clause | group_template_declaration I group-declaration process_dcclarativc-part ::= { process—declarative_itcm} process_statcmcnt ::= [process-label: ] [ postponed ] process [ ( sensitivity_list) ] [ is ] procesS-declarative_part begin process_statcmcnt-part end [ postponed ] process [ proce55_label ];
208 Приложения process_statement_part ::= { sequential statement} qualified expression ::= type mark 1 ( expression) I type_mark * aggregate range ::= range, attribute name | simple_expression direction simple expression range_constraint ::= range range rccord_type_definition record elementdeclaration { element declaration } end record [ record_ type simple_namc ] relation ::= sb ift_ex press ion [ rclational_operator shift_exprcssion ] relational__operator ::= = | report statement ::= [ label: ] report expression [ severity expression ]; return_statcmcnt ::= [ label: ] return [ expression ]; scalar_typc definition ::= enumeration_type_definition | integer_typc_dcfinition | floating_typc_dcfinition physical_type_dcfmition
Приложения 209 secondary_unit ::= architecture_body (package body secondary_unit_dcclaration ::= identifier = physical-literal; selected__namc ::= prefix . suffix selected signal-assignment ::= with expression select target <= options sclectedwaveforms ; selccted_wavcforms ::= { waveform when choices , } waveform when choices sensitivity_clause ::= on sensitivity^list sensitivity_list signal_name { ,signal name } sequence_of_statements ::= { sequential_statemcnt} scquential_statement ::= wait_statement | assertion_statement | report statement | signal_assignment_statement | variable_assignmcnt_statement | proccdure_call_statement | if_statement | case-Statcment | loop_statemcnt | next_statement | exit statement | return_statcmcnt | null_statement
210 Приложения shift-expression ::= simplC-Cxpression [ shift_operator simple_expression ] shift_operator ::= sll | srl | sla | sra | rol | ror sign::= + |- signal_assignmcnt_statcmcnt: := [ label: ] target <= [ delay_mechanism ] waveform ; signal declaration ::= signal identifier_list: subtypc_indication [ signal-kind ] [ := ex- pression ]; signal kind ::= register | bus signallist ::= signal_nan\e { , signal_name } | others | all signature ::= [ [ type_mark {, type_mark } ] [ return type_mark ] ] simplc_cxprcssion [ sign ] term { adding_operator term } simple_name ::= identifier slice_name ::= prefix ( discrete range ) string_Jiteral ::= " { graphic_character } " subprogram_body ::= Subprogram-Specification is subprogram_declarativc_part begin subprogram_statement_part end [ subprogram-kind ] [ designator ];
Приложения 211 subprogram_declaration ::= subprogram-specification; subprogram-declarative_item ::= subprogram-declaration | subprogram_body I type_declaration | subtype-declaration | constant-declaration | variable-declaration | file_declaration | alias_declaration | attribute-declaration | attribute_specification | use-dause | group_tcmplate_declaration I group-declaration subprogram_declarative-part { subprogram_declarative-item } subprogram_kind ::= procedure | function subprogram-specification ::= procedure designator [ ( formal_parameter_list) ] | [ pure | impure ] function designator [(formal-parametcr_list)] return type-inark subprogram_statement_part ::= { Sequential-Statement} subtype-declaration ::= subtype identifier is subtype_indication ; subtype_indication ::= [ resolution_function_name ] type_mark [ constraint ]
212 Приложения suffix ::= simple name | character_literal | opcrator_symbol | all target ::= name | aggregate term ::=factor { multiplying_operator factor } timeout clause ::= for rnue expression typc_con version ::= type_mark ( expression ) typedcclaration ::= full_type_declaration | mcomplete_type_declaration type_defmition ::= scalar_type_definition | compositc_type_definition | access_type_definition | file_type’definition type_mark ::= zype_namc | jr«b(ype_name unconstrained_array_dcfinition ::= array (indcx_subtype_dcfinition {, index_subtype_definition} ) of e/e/nen/_subtype_indication use_clause ::= use selcctcd_name {, selcctcd_name } ;
Приложения 213 variable assignment statement ::= [ label: ] target := expression ; variable_declaration ::= [ shared ] variable identifier_list: subtype_indication [ := ex- pression ]; wait_statement ::= [ label: ] wait [ sensitivity_clause ] [ condition clause ] [ time- out- clause ]; waveform ::= waveform_element {, waveform_element} | unaffected waveform_element ::= value expression [ after time expression ] [ null [ after hme_exprcssion ]
214 Приложения 3. Пакет STANDARD package standard is type boolean is (false,true); type bit is ('O', ’Г); type character is ( nul, soh, stx, etx, cot, enq, ack, bel, bs, ht, If, vt, ff, cr, so, si, die, del, dc2, dc3, dc4, nak, syn, etb, can, em, sub, esc, fsp, gsp, rsp, usp, '','!’, '#', '$', k > J > 9 9 9 9 9 • 9 f 9 'O','Г, '2', '3','4', '5', '6', '7', . ’9’ 1,1 1=1 ,^>l *7* '@', 'A', 'B', 'C\ 'D', 'E', T', 'G', H’,'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', T, 'U', 'V, 'W', . X* ’V’ ’7’ T’ ’V 1 ’ 9 * 9 9 L » > 9 9 _ 9 ,м, ’а’, ’b’, ’c’, ’d’, ’e’, ’f, ’g\ ’h’, 7, j’, ’k’, T, ’m’, ’n’, ’o’, ’p', 'q', 'r', ’s’, 'f, ‘u’, ’v’, ’w’, ’x’, ’у’, T,’}’, 4 del); type scvcrityjevel is (note, warning, error, failure); type integer is range -2147483647 to 2147483647; type real is range -1.0E38 to 1.OE38; type time is range -2147483647 to 2147483647 units fs; ps = 1000 fs; ns = 1000 ps; us = 1000 ns; ms = 1000 us; sec = 1000 ins; min = 60 sec; hr = 60 min; end units;
Приложения 215 function now return time; subtype natural is integer range 0 to integer’high subtype positive is integer range 1 to integer’high; type string is array (positive range o) of character; type bit_vector is array (natural range o) of bit; end standard;
216 Приложения 4. Пакет STDJLOGIC 1164 package PACK 1164 is type stdulogic is ( 'U', -- Uninitialized 'X', -- Forcing Unknown 'O', — Forcing 0 T, -- Forcing 1 'Z', — High Impedance 'W', — Weak Unknown 'L', - Weak 0 'H', - Weak 1 — Don't care type std_ulogic_vcctor is array (NATURAL RANGE о ) of stdulogic; function resolved ( s : std_ulogic_vector ) RETURN std ulogic; subtype UX01 is resolved std_ulogic RANGE 'U' TO T; subtype std_logic is resolved std ulogic; type std_logic_vector is array ( NATURAL RANGE o) of std logic; function "and" (1: std ulogic; r: std_ulogic) RETURN UX01; function "and" (I, r : std_logic_vector ) RETURN std_logic_vcctor; function "and" (1, r : std_ulogic_vector ) RETURN std ulogicvcctor; end PACK1164; package body PACK1164 is type stdlogic_ Id is array (std_ulogic) of std_ulogic; type stdlogic tablc is array (std ulogic, std ulogic) of std_ulogic; constant resolution_table : stdlogic_table := ( x о 1 Z W L H ( •U’, ’U', ’v, •U'z •U’z •U’z ’U’z 'U' ) z — — и ( ’U’z •X’, X’, ’X’, •X', ’X', •X', X', 'X' ) z — — X ( ’U’r ’X', 'O', •X’, ’O', ’O', •O', •O', 'X' ) z — — 0 ( ’U’z 'X', •X', ’l’z •l’z 'l’z •l’z •l’z 'X' ) z — — 1 ( ’U’, X’, ’O', ’l’z Z', •w, •L', •H’, 'X' ) z z ( ’U', •x', O', ’l’z ' W' , ' w, 'W , •w, X’ ) z — — w ( ’IT, ’x1, •O', ’I’z •L’, •w, •L', w, 'X' ) z " — L ( U', 'X', •O', •l’z H', •w, •w, •H’z 'X' ) z — — H ( ’U', ’X\ •X', •X', •X', X', •X', •X», 'X' ) — — —
11риложсния 217 function resolved (s : std_ulogic_vcctor) RETURN std ulogic IS variable result: std_ulogic := *Z'; — weakest state default begin if (s'LENGTH = 1) then RETURN s(s'LOW); else for i in s'RANGE loop result := resolution_tablc(result, s(i)); end loop; end if; RETURN result; end resolved; constant and_tablc : stdlogic_table := ( l и X 0 1 z w L H — 1 ( U', U’r O’, 'O’, 'U', 'U', ’O’, •U’ ), — — 1 и ( ’U’, ’X’, •O’, ’X', 'X', 'X', •O’, •X’, •X' ) , — — X ( ’O', 'O', O’, •O’, ’O’, 'O', O’, O’, •O' ), — — 1 0 ( •u', •X' , O’, '1', ’X’, ’X', O’, •1', •X’ ), — 1 ( O’, ’X', •O’, •X', ’X’, 'X', O', X’, •X’ ), — — 1 z ( U’, x*, •O’, X', ’X', 'X', O', •X', 'X' ), 1 w ( ’O’, 'O', •O’, •O', 'O', 'O', O’, •O', 'O' ), i L ( 'O’, 'X', O', •1', 'X', 'X', •O’, 1’, 'X' ), I H ( •x*, •O’, •X', 'X', ’X', •O’, •X’, •X' ) —1 — ); function "and" (1 : std ulogic; r : std_ulogic) RETURN UX01 is begin RETURN (and_tablc(l, r)); end "and"; function "and' (l,r: std_logic_vcctor) RETURN std_logic_vcctor is alias Iv : std logic vector ( 1 TO 1'LENGTH ) is 1; alias rv : std_logic_vector ( 1 TO r'LENGTH ) is r; variable result: std logic vector ( 1 TO 1'LENGTH ); begin if (1'LENGTH /= r'LENGTH ) then assert FALSE report
218 Приложения "arguments of 'and' operator are not of the same length" severity FAILURE; else for i in result'RANGE loop result(i) := and_table (lv(i), rv(i)); end loop; end if; RETURN result; end "and"; function "and" (l,r: std_ulogic_vector ) RETURN std_ulogic_vcctor is alias Iv : std_ulogic_vector ( 1 TO 1'LENGTH) is 1; alias rv : std_ulogic_vector ( 1 TO r'LENGTH) is r; variable result: std_ulogic_vector ( 1 TO 1'LENGTH); begin if (1'LENGTH /= r'LENGTH ) then assert FALSE report "arguments of 'and' operator are not of the same length" severity FAILURE; else for i in result'RANGE loop result(i) := and_table (lv(i), rv(i)); end loop; end if; RETURN result; end "and"; end PACK 1164;
Уважаемый читатель! Перед Вами 14 номер каталога книг издательства “СОЛОН Р". предлагаемых к рассылке по почте. В этом каталоге представлены все книги нашего издательства, на данный момент предлагаемые к рассылке. Срок действия цен, указанных в каталоге — до 1 сентября 2002 г. По окончании этого срока, в случае получения заказа, издательство оставляет за собой право высылать книги по новым ценам. Цены, указанные в каталогах 1-13 более недействительны, заказы по ним выполняться не будут. ВНИМАНИЕ! Вы можете в любое время получить свежий каталог издательства «СОЛОН-Р» по Интернету, послав пустое письмо на робот-автоответчик по адресу KATALOG@SOLON-R.RU, а также подписаться на рассылку новостей о новых книгах издательства, послав письмо по адресу NEWS@SOLON-R.RU с текстом “SUBSCRIBE" (без кавычек) в теле письма. Если у вас нет доступа к Интернету, вы можете получить следующий бесплатный каталог нашего издательства по почте. Для этого необходимо прислать нам пись- мо, вложив в него широкий конверт (формат 22x11 см.) с маркой и вашим адресом. Наш адрес: 123242, Москва, а/я 20 —— - - -- ----------- - - ------------- --- К сожалению, отдельные схемы, альбомы схем и радиоэлементы мы не высылаем! Мы высылаем книги только по территории России наложенным платежом! Для оформления заказа необходимо:______________________________________________ 1) Указать номер данного каталога - 14. номера книг по каталогу и количество экземпля- ров (названия книг указывать не нужно); Если Вы хотите заказать ежемесячные журналы "Ремонт & Сервис", напишите "журнал Ремонт & Сервис" и укажите интересующие вас номера, год и количество экземпляров; 3) Написать полный адрес, по которому выслать книги. Просьба обязательно указывать индекс и фамилию, И. О. получателя! Желательно указать также телефон, по которому с вами можно связаться, и адрес электронной почты (E-mail) (при наличии). Внимание! Убедительная просьба все данные писать разборчиво и аккуратно! Большая просьба при перемене адреса или индекса сообщать об этом при очередном заказе. Пример: Каталог 14. Книги. 2 — 1 экз., 5 — 2 экз., 12 — 4 экз. Журнал " Ремонт & Сер- вис"; 1/02— 1 экз. Адрес: 123456, Тверь, ул. Свободы, д. 4, корп. 2, кв. 5. Иванову Ивану Ивановичу. Тел.: 1-11-11. E-mail, ivanov@ivan.msk.ru. 27.08.02 г. Передать нам Ваш заказ Вы можете следующими способами:____________________________ 1) выслать почтовую открытку или письмо по адресу: 123242, Москва, а/я 20; 2) передать по электронной почте (e-mail) по адресу magazin@solon-r.ru ___________ P.S Возврат книг в случае брака или ошибки производить по обратному адресу, ука- занному на бандероли. Отдел “Книга-почтой" издательства "СОЛОН-Р". Адрес: 123242, Москва, а/я 20. E-mail: magazin@solon-r.ru Тел. для справок (095) 254-44-10