Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lektsii.doc
Скачиваний:
58
Добавлен:
15.12.2018
Размер:
631.81 Кб
Скачать

Введение

Сегодняшнюю жизнь невозможно представить без вычислитель­ных устройств (ВУ), скрытых в бытовой технике, измерительных и медицинских приборах, управлении агрегатами транспортных средств, телекоммуникациях, чип-картах и т.п. В персональных компьютерах, которых сейчас в мире сотни миллионов штук, функ­ции периферийных устройств исполняют различные специализи­рованные ВУ. Если мысленно охватить всю электронику, используе­мую человеком, то в целом, на один универсальный микропроцессор приходятся многие десятки специализированных ВУ. Число новых применений ВУ стремительно возрастает, а сроки их разработки неуклонно сокращаются.

Основная часть специализированных ВУ реализована на микро­контроллерах. Но остается большое множество задач, требующих экстремальных характеристик быстродействия, пропускной способ­ности, энергопотребления, для реализации которых необходима раз­работка заказных микросхем. В последнее время ядро микрокон­троллера и необходимые сложные периферийные устройства выпол­няют в виде системы на кристалле (СНК). Возрастающий объем разработок специализированных ВУ и СНК требует освоения новых технологий их проектирования.

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

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

Использование при разработке ВУ таких языков проектирования, как VHDL и Venlog, позволяет отказаться от составления схем на

большинстве этапов разработки ВУ. Технология проектирования ВУ с помощью VHDL предполагает описание исходных алгоритмов функционирования аппаратуры и ее интерфейса на языке VHDL и автоматическую трансляцию этого описания до уровня логических схем и далее - до уровня масок микросхем или прошивки програм­мируемых логических интегральных схем (ПЛИС). При этом схемы ВУ в графическом виде практически не используются, а отсутствие ошибок в проекте автоматически контролируется средствами вери­фикации. Как основное средство верификации, используется моде­лирование функционирования ВУ на VHDL-симуляторе на всех эта­пах проектирования. Разработка современных ВУ без использования языков VHDL и Verilog стала практически невозможной.

Язык VHDL - необычный язык, как для программистов, так и для разработчиков аппаратуры. Это связано с тем, что по своей при­роде VHDL - язык параллельного программирования. Начинающие программисты иногда путаются в основах программирования на VHDL, допускают трудно выявляемые ошибки, а их результирую­щие проекты ВУ нередко оказываются далекими от оптимальных. Кроме того, современная технология проектирования средств ВУ основана на ряде особенных требований, предъявляемых к проек­там, описанным на VHDL. А большинство разработчиков аппарату­ры, изучающих VHDL, с этими требованиями мало знакомо. Поэто­му цель данной книги - помочь освоить VHDL, как современное средство проектирования ВУ.

Кратко о VHDL

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

Язык Very high speed integrated circuits Hardware Description Language (VHDL) был разработан в 1983 г. по заказу Министерства обороны США с целью формального описания логических схем для всех этапов разработки электронных систем. Он является стандарт­ным языком с 1987 г. Стандартом 1993 г. закреплены многие его усовершенствования [1]. Наряду с языком Verilog он является базо­вым языком при разработке аппаратуры современных вычислитель­ных систем.

В чем преимущества VHDL над схемным проектированием?

Проектирование больших вычислительных устройств (ВУ). С по­мощью VHDL проще и быстрее ввести и проверить большой проект. Десятью строками VHDL можно описать как 1, так и 100000 триг­геров. Микросхему с интеграцией более 10000 вентилей разработать только с помощью электрических схем практически невозможно по причине громоздкости схем.

Проект на VHDL — объединение структуры ВУ и алгоритма его функционирования. Для ВУ, описанного на VHDL, необязательно выполнять проверку правильности его функционирования, напри­мер, путем его макетирования. Чтобы определить, правильно ли ВУ выполняет заданный алгоритм, достаточно его VHDL-программу за­пустить на исполнение в симуляторе VHDL. Соответствующие САПР

преобразуют VHDL-описание в комплект документации для изготов­ления работоспособного устройства.

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

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

Проект на VHDL — универсальный проект. Разработанный одна­жды вычислительный блок может быть использован во многих дру­гих проектах. При этом многие структурные и функциональные па­раметры блока могут быть настраиваемыми (параметры разрядно­сти, объема памяти, элементная база, состав блока и структура межсоединений).

Проект на VHDL — портативный проект. Разработанный для од­ной элементной базы, проект ВУ без труда переносится на другую элементную базу, напр. СБИС с различной технологией.

Проект на VHDL — долгоживущий проект. Электрическая схема всегда разрабатывается под конкретную элементную базу и интер­фейс. Так как элементная база сменяется через 2-5 лет, за этот же период устаревают и электрические схемы, использующие её. Про­ект ВУ на VHDL может быть повторно использован через несколько лет. Хорошее техническое решение (напр., изобретение), описанное на VHDL, может быть востребованным в течение десятилетий.

VHDL - универсальное средство описания ВУ на уровнях:

  • алгоритмическом,

  • структурном,

□ регистровых передач (RTL) и потоков данных (dataflow), и логическом,

□ аналоговых схем.

Ход проектирования с использованием VHDL

На рис. 1 показана схема разработки проекта ВУ, предназначен­ного для исполнения в программируемой логической интегральной схеме (ПЛИС).

Вначале ВУ описывается в виде своей поведенческой модели, на которой отрабатывается задуманный алгоритм функционирования ВУ. Затем эта модель вручную перерабатывается в синтезируемую модель ВУ, описанную на уровне регистровых передач. Такая мо­дель, будучи странслированной компилятором-синтезатором, дает проектную документацию в виде файла описания схемы ВУ на уровне вентилей (EDIF-файл). При этом автоматически выполняется логическая оптимизация ВУ. Одновременно этот файл автоматиче­ски преобразуется в VHDL-модель ВУ на уровне вентилей.

Проект ВУ в виде Electronic Distribution International Format (ЕБПГ)-файла принимается, как исходные данные, всеми САПР из­готовления ПЛИС и СБИС. Эти САПР выполняют замену вентилей на библиотечные компоненты, их размещение на площади кристал­ла, трассировку межсоединений, проектирование масок, проверку соответствия проектным нормам и т.п. В результате, записываются файлы проектной документации изготовления кристалла и его логи-

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

Стоимость ошибок при проектировании СБИС очень высока, осо­бенно на ранних этапах. Поэтому все этапы проектирования - алго­ритмический, структурный, логический, технологический - сопро­вождаются моделированием ВУ с помощью, так называемого, испы­тательного стенда (testbench). Этот стенд представляет собой VHDL-модель, составными частями которой являются модель тестируемого ВУ и модели генератора тестовых сигналов и логического анализа­тора, проверяющих правильность функционирования ВУ. Причем на всех этапах может использоваться один и тот же испытательный стенд и те же тестовые файлы.

VHDL используется в современных САПР

Исторически сложилось, что в микроэлектронной индустрии наи­большее распространение получил язык Verilog. Полтора десятиле­тия назад этот язык выиграл конкурентную борьбу с другими язы­ками задания ВУ, благодаря небольшим вычислительным ресурсам, требуемым от прежних рабочих станций и достаточно точным ре­зультатам моделирования СБИС. VHDL - более универсальный и гибкий язык, но он проигрывал в быстродействии языку Verilog, особенно при моделировании на уровне вентилей и транзисторов. VHDL получил широкое распространение в университетах и ис­следовательских учреждениях, так как это строгий, стройный, уни­версальный и расширяемый язык. Так, например, появились пакеты VHDL для аналогового моделирования, моделирования многознач­ной логики. Кроме того, симуляторы VHDL были гораздо дешевле симуляторов Verilog.

Все современные САПР микроэлектроники имеют компиляторы как с Verilog, так и с VHDL. Программист, освоивший VHDL, без особого труда может перейти к программированию на языке Verilog. Но программисту, знающему Verilog, перейти к VHDL труднее.

Важнейшими качествами VHDL в САПР выступают следующие:

Гибкость. Проект, описанный на VHDL, может быть легко на­строен под конкретные задачи потребителя.

Универсальный язык. VHDL - общепринятый язык для всех ос­новных фирм - изготовителей микросхем ПЛИС, ПЛМ, заказных

СБИС, как стандартный язык для задания сложных проектов. Про­ектирование с VHDL - устойчивая тенденция в инженерной техно­логии. Существуют компиляторы, транслирующие VHDL-программы в эквивалентные им Verilog-программы.

Моделирование с учетом задержек. Фирмы-изготовители микро­схем в своих САПР обеспечивают генерацию моделей результатов размещения и трассировки, описанных на VHDL.

Стандартное подключение блоков. Конструкции языка, такие как entity, port map, configuration, обеспечивают надежную и бы­струю стыковку блоков, разработанных разными фирмами и разра­ботчиками, в различном сочетании.

Стандартное тестирование. На всех этапах разработки выполня­ется тестирование по одной методике одними и теми же тестами.

VHDL — стандарт будущего. Все новые САПР основаны на техно­логии трансляции описания ВУ на языке описания аппаратуры. Ис­пользование VHDL - гарантия того, что через 5 и 10 лет найдется САПР, поддерживающая старые разработки.

Технология разработки систем на кристалле

Согласно известному закону Мора, количество транзисторов на кристалле СБИС с каждым годом увеличивается приблизительно на 60 %. С определенного момента времени то оборудование, которое размещалось на одной печатной плате, стало возможным поместить на одном кристалле (рис. 2). Причем это становится выгодным, бла­годаря уменьшению общей стоимости, числа необходимых микро­схем, энергопотребления, повышению надежности ВУ.

Таким образом, на одном кристалле размещается не только кон­кретное функциональное устройство, например, центральный про­цессор, но и другие устройства, такие как АЦП, ОЗУ, ПЗУ, блоки цифровой обработки сигналов, интерфейсные узлы и т.п., допол­няющие его до законченной системы блоков. Поэтому такое ВУ при-

нято называть System On the Chip (SOC) - системой на кристалле (CHK) [2].

СНК - это, как правило, заказная СБИС. Чтобы разработка СНК себя окупила, необходимо реализовать десятки и сотни тысяч СБИС. Проект ВУ, реализованный на ПЛИС, может быть выгодным при партиях, как в десятки, так и в десятки тысяч экземпляров, благо­даря дешевизне разработки и производства такой ВУ. Разработка такого ВУ длится, как минимум, в 2 раза быстрее, чем проектиро­вание СБИС. Это обусловило бурное распространение ПЛИС в каче­стве элементной базы СНК.

Наиболее трудоемкими и ответственными этапами разработки СНК выступают этапы структурного проектирования и верификации соответствия ВУ заданным алгоритмам функционирования. Поэтому эффективность САПР микросхем и производительность разработчи­ков, выполняющих проектирование на уровне регистровых передач, постоянно растет приблизительно на 20 % в год. Но, начиная с се­редины 90-х годов, производительность разработчиков стала заметно отставать от роста сложности СНК (рис. 3).

Первым направлением улучшения технологии разработки СНК, ориентированным на уменьшение зазора между ростом производи­тельности проектирования на уровне регистровых передач и ростом сложности СНК, является применение крупных библиотечных вы­числительных модулей (Intellectual Property Cores). Эти модули должны быть надежно повторяемыми и настраиваемыми под решае­мые задачи в ряде проектов СНК. Повторное применение таких мо­дулей (IP Core reuse), которые можно назвать вычислительными заготовками за их функциональную и технологическую адапти­руемость, позволяет уменьшить трудозатраты и сроки проектирова­ния СНК.

Второе направление - это разработка САПР совместного проектиро­вания аппаратно-программного обеспечения (Hardware - Software Codesign). Архитектура СНК, как правило, включает в себя микропро­цессорное ядро с периферийными устройствами в различном сочетании. Обычно процесс разработки ВУ с такой архитектурой состоит из трех последовательных этапов: проектирования электрической схемы аппа­ратуры, разработки матобеспечения микропроцессора и стыковки мато­беспечения с аппаратурой.

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

Наибольшее ускорение разработки СНК может дать внедрение САПР непосредственного отображения алгоритмов в аппаратуру, т.е. САПР системного проектирования. Например, такая САПР может включать в себя трансляцию программы с языка высокого уровня, таком как C++, с автоматическим разделением вычислительных за­дач между микропроцессорным ядром и спецпроцессорами и други­ми периферийными устройствами.

Для более плавного перехода от алгоритма функционирования системы, описанного на языке C++, к аппаратно-программному опи­санию всё чаще применяется язык System-C. Особенность этого под­множества языка C++ в том, что его функции имеют взаимно одно­значное соответствие с конструкциями языков VHDL и Verilog, опи­сывающими аппаратуру.

Вычислительные заготовки

В крупных фирмах, долгие годы занимающихся разработкой СБИС, а теперь и СНК, наработаны большие библиотеки стандарт­ных модулей, таких как: ОЗУ, АЛУ, периферийные устройства. В новых проектах СНК некоторые блоки приходится разрабатывать заново, а остальные - обычно берутся из библиотеки. При этом если модуль неясно описан, не имеет удобного интерфейса, документа­ции, комментариев, испытательного стенда с надежными тестами, то он повторно применяться не будет.

Если такой модуль изначально оформлен в виде вычислительной заготовки, то он будет без лишних проблем вставляться в любой но­вый проект. Более того, лицензию на него можно предлагать другим фирмам-разработчикам СНК. Рисунки 2, 4 иллюстрируют суть вы­числительной заготовки (IP core).

14

1. VHDL и технология систем на кристалле

Гибкие заготовки обычно подстраиваются к условиям нового про­екта в широких пределах и независимы от его технологии (серия ПЛИС, технология СБИС). Обычно в них задаются разрядность дан­ных, объем памяти, таблицы констант, перечень периферийных уст­ройств, иногда - быстродействие, которое пропорционально аппара­турным затратам. Минимизация аппаратурных затрат вычислитель­ных заготовок обеспечивает не только уменьшение стоимости СНК, но и минимизацию его энергопотребления, что является важным фактором для портативных и энергонезависимых ВУ, в которых применяются СНК.

Чтобы проект ВУ был принят как гибкая вычислительная заго­товка, он должен иметь:

а исчерпывающую и ясную документацию;

а текст описания на VHDL или Verilog в хорошем стиле для синтеза, заготовка должна быть настраиваемой под техниче­ские условия потребителя;

а хорошие средства верификации в виде испытательных стен­дов, исчерпывающих тестов, возможно, экспериментальных макетов;

а четкую методику того, как ВУ вставлять в СНК, включающую надежные скрипты (программы на макроязыке САПР, автома­тизирующие тестирование и создание жесткой или твердой за­готовки) [2].

В сегодняшних условиях, чтоб быстрее перейти от идеи к "желе­зу", эффективнее провести проектирование новой СНК, необходимо эту СНК "собрать" из имеющихся вычислительных заготовок (рис. 2), а отсутствующие заготовки - приобрести на рынке IP cores, который бурно развивается в последние годы.

Если приобрести не удастся или если проект - исследователь­ский, то необходимую заготовку можно поискать, например, в банке бесплатных IP cores, что на сайте www.opencores.org. Этот банк соз­дан по инициативе организаций, содействующих развитию техноло­гии СНК, а также инженеров, желающих поделиться своими ре­зультатами. Если оба этих пути не устраивают, то придется ВУ про­ектировать самостоятельно и данная книга может этому помочь.

Программируемые логические интегральные схемы

Что такое FPGA?

Программируемые логические интегральные схемы (ПЛИС) поя­вились полтора десятилетия назад как альтернатива программируе­мым логическим матрицам (ПЛМ). ПЛИС отличаются от последних как по архитектуре, так и по технологии изготовления.

ПЛМ представляет собой матрицу многовходовых (более десятка входов) логических элементов с триггерами, в которых программи­руются конституенты единиц дизъюнктивных нормальных форм функций этих элементов. В первых ПЛМ программирование выпол­нялось пережиганием перемычек между источниками сигналов пе­ременных и входами логических элементов. Затем перемычки заме­нили МОП-транзисторами с плавающим затвором, как в электриче­ски перепрограммируемом ПЗУ. Поэтому сейчас. ПЛМ изготов­ляются по технологии флэш-памяти. Большие ПЛМ (CPLD) отличаются только тем, что несколько ПЛМ собраны на одном кри­сталле и объединены программируемым полем связей.

ПЛИС представляет собой матрицу маловходовых (от двух до пя­ти входов) логических элементов, триггеров, отрезков линий связи, соединяемых перемычками из полевых транзисторов. Судя по анг­лийскому названию ~ Field Programmable Gate Array (FPGA), ПЛИС программируются изменением уровня электрического поля (field) в затворах этих транзисторов. Затворы всех "программирующих" по­левых транзисторов подключены к выходам триггеров одного длин­ного сдвигового регистра, который заполняется при программирова­нии ПЛИС. Некоторые из участков этого регистра могут также ис­полнять роль ячеек ПЗУ.

Прошивка обычно хранится в ПЗУ, стоящем рядом с ПЛИС. По­сле включения питания или по сигналу сброса она автоматически переписывается в программирующий сдвиговый регистр ПЛИС. Этот процесс называется конфигурированием ПЛИС. Так как основу ПЛИС составляют триггеры, хранящие прошивку, называемую кон­фигурацией, то ПЛИС изготавливаются по технологии микросхем статического ОЗУ.

По сравнению с CPLD, ПЛИС выигрывают, во-первых, в неогра­ниченном количестве перепрограммирований, во-вторых, в логиче-

ской емкости, в том числе в удельной емкости вентилей на цент, в-третьих, в малом энергопотреблении. Как правило, ПЛИС имеют на два-три порядка большую емкость в числе эквивалентных логиче­ских вентилей, чем CPLD и также как статическое ОЗУ, почти не потребляют энергии при отсутствии переключений. Поскольку топо­логия ПЛИС регулярна и масштабируема, период разработки и вне­дрения ПЛИС новых серий сравнительно мал, и они изготовляются по самой современной технологии. Наконец, у ПЛИС на порядок выше надежность (ниже интенсивность отказов), чем у CPLD.

Архитектура ПЛИС фирмы Xilinx

Фирма Xilinx принадлежит к числу родоначальников ПЛИС и самых крупных их производителей. Ниже рассматривается краткое описание архитектурных особенностей ПЛИС серии Virtex выпус­каемой этой фирмой [3]. Эти особенности наследуются в новых сери­ях ПЛИС, а также в серии Spartan, микросхемы которой призваны заменить заказные СБИС в мало- и среднесерийном производстве изде­лий электроники. Кроме того, принципы функционирования структур­ных элементов ПЛИС этой серии узнаваемы в архитектурах ПЛИС дру­гих фирм-производителей, таких как, Altera, Actel, Atmel.

Топология ПЛИС

На площади кристалла ПЛИС (рис. 5.) размещены матрица кон­фигурируемых логических блоков (КЛБ или CLB), матрица отрезков линий межсоединений, покрытых матрицами из полевых транзисто-

ров - перемычек (МП). По краям кристалла размеше­ ны блоки настраиваемых ОЗУ - BlockRAMs. По пе­ риметру кристалла разме­ щены блоки ввода-вывода сигналов (IOBs), а также периферийный канал ли­ ний межсоединений, на­ зываемый VersaRing, предназначенный для сое­ динения КЛБ с произ­ вольным ЮВ линией свя­ зи с малой задержкой.

Для обеспечения достаточ-11 ых возможностей маршрута-1ации межсоединений, а также i [ х высокого быстродействия, используется до девяти слоев металлизации в которых реали-юваны матрица отрезков линий межсоединений, система линий < инхронизации и питания.

Логическая таблица

Роль основного логического элемента в ПЛИС играет логи­ческая таблица (ЛТ) или look-

up table (LUT), представляющая собой однобитное ОЗУ на 16 ячеек (рис. 6).

В ЛТ по адресу G3,G2,G1,G0 записана единица, если код адреса представляет собой конституенту единицы заданной четырехвходо-иой логической функцией. Например, если по адресу 1,1,1,1 записа­на единица, а по остальным адресам - ноль, то ЛТ реализует че-1 ырехвходовую функцию И. На рис. 6 показан пример кодирования функции Исключающее ИЛИ на четыре входа. Триггеры ЛТ входят и состав программирующего сдвигового регистра, и их начальное (остояние заполняется в период конфигурирования ПЛИС.

Триггер

В ПЛИС используются программируемые D-триггеры (рис. 7). При конфигурировании можно задать такие режимы работы триг-

iepa, как триггер с начальным сбросом (R) или начальной ус-[ ановкой (S), с записью по фронту или спаду синхро-< ерии, с разрешением или без разрешения записи.

После окончания конфигу­рирования ПЛИС выдает сиг-кал общего сброса GSR, кото­рый устанавливает все тригге­ры в 0 или 1.

Структура КЛБ

В базовой серии ПЛИС ХС4000 фирмы Xilinx основной единицей обору­дования считается КЛБ, состоящий из двух триггеров, двух ЛТ и схем уско­ренного переноса, суммирования и управления CY. В новых сериях ПЛИС количество триггеров и ЛТ в КЛБ уве­личилось вдвое и вчетверо. Чтобы ос­тавить для всех серий одну и ту же единицу оборудования, условились на­зывать КЛБ из двух триггеров и двух ЛТ эквивалентным КЛБ (ЭКЛБ) или CLB slice. Таким образом, КЛБ серии Virtex состоит из двух ЭКЛБ, а серии VirtexII - из четырех ЭКЛБ (рис. 8).

Схемы для ускорения арифметических операций

В ЭКЛБ две ЛТ и два триггера соеди-

нены вместе через схему ускоренного переноса и два однобитных полусумматора (рис. 9). Эти схемы позволяют эффективно реа­лизовать многоразрядные параллельные сумматоры, а на их осно­ве - различные счетчики и АЛУ.

Для минимизации оборудования и ускорения вычисления опера­ции умножения используется дополнительная схема поразрядного произведения. Необходимо добавить, что в новой серии Virtex2 реа­лизованы аппаратные умножители 18 на 18 разрядов.

Мультиплексоры в ПЛИС

Большую долю оборудования в ВС за­нимают мультиплексоры. С помощью одного ЛТ можно реализовать двух-входовой мультиплексор. Для эф­фективной реализации 4-х и более входовых коммутаторов в КЛБ имеются схемы мультиплексоров F5 и F6, которые играют роль верхних уровней древовидного мультиплексора (рис. 10).

Шины с тремя состояниями

Применение шин с тремя состояниями - типичное схемное реше­ние ВУ, реализованных на плате. Благодаря такому решению, легко достигается многомодульность и наращиваемость системы, низкие аппаратурные затраты и малые задержки в системе межсоединений. I in утри заказных СБИС редко применяются шины с тремя сос­тояниями из-за технологических трудностей их безотказной реали­зации, а также увеличенной задержки их переключения.

Несмотря на это, в ПЛИС фирмы ХШпх всё-таки широко приме­няются шины с тремя состояниями, хотя это существенно повышает их себестоимость. Зато, во-первых, проще выполнить переход от проекта схемы на плате к проекту СНК. Во-вторых, ВУ с общими шинами, к которым подключено несколько десятков модулей, имеет аппаратные затраты в несколько раз меньше, чем такое же ВУ, в котором глины заменены на эквивалентную схему из системы муль­типлексоров. В-третьих, с помощью общих шин эффективно реали-иовать встроенное распределенное ОЗУ, о котором пойдет речь ниже.

Для реализации общей шины каждый КЛБ имеет два буфера с •громя состояниями BUFT, которые через транзисторы-перемычки могут подключаться к общим шинам, проходящим вдоль всего кри­сталла (рис. 11).

В обычных шинах третье состояние характеризуется уровнем, находящимся между уровнями логической 1 и логического 0. Одна­ко в случае, когда все тристабильные буферы будут в третьем (за-

крытом) состоянии, выходные каскады приемников, подключенных к общей шине, Пудут полуоткрытыми, через них потечет большой постоянный ток, и они могут вый­ти из строя. Для исключения такого элек­трического режима, в ПЛИС общая шина нагружена на концах специальной тригтерной схемой - Weak Keeper, которая выводит уро­вень шины или к уровню Н, или к уровню L (слабые 1 или 0), если все буферы закрыты.

ОЗУ в ПЛИС

Для реализации в ПЛИС модулей ОЗУ предусмотрено две возможности. Первую воз­можность предоставляет каждая ЛТ, которая

может быть сконфигурирована как 16-битовое синхронное ОЗУ. Две соседних ЛТ могут быть сконфигурированы как 16-битовое двухпортовое ОЗУ с записью и чтением по одному адресу и чте­нием по другому адресу (рис. 12). При этом для реализации син­хронного режима записи входной бит данного, сигнал записи и ад­рес запоминаются в триггерах-защелках, а для чтения по второ­му адресу из блока второй ЛТ ис-

пользуется только мультиплексор чтения.

Для наращивания емкости памяти выхо­ды нескольких КЛБ с модулями ОЗУ через тристабильные буферы подключаются к об­щим шинам. При этом- требуется допол­нительное оборудование только для по­строения схемы дешифрации адреса, кото­рая выдает сигналы выборки той или иной ЛТ для записи или того или другого три-стабильного буфера для чтения. Такое ОЗУ распределено по площади кристалла и по­этому названо Distributed RAM.

Если ЛТ запрограммировать как прими­тив SRL16, то из ее триггеров будет реали­зован 16-разрядный сдвиговый регистр с однобитовым входом и программируемым номером выходного разряда, т.е. память FIFO регулируемой длины. Такие регистро­вые линии задержки удобно использовать при проектировании конвейерных спе­циализированных ВУ, ВУ с поразрядной

обработкой, буферов для приема и передачи данных и т.п.

Вторую возможность предоставляют отдельные блоки памяти BlockRAM. В ПЛИС серии Virtex они могут быть сконфигурирова­ны, как ОЗУ объемом 256 16-разрядных слов, 512 8-разрядных слов, и т.д. Эта память может быть запрограммирована как однопортовая или как полностью двухпортовая память (рис. 13). Начальное со-

сгоиние этой памяти задается при ее конфигурировании, поэтому ими может быть использована также как ПЗУ. В каждой новой се­рии ПЛИС объем блоков BlockRAM и их число - увеличиваются.

Блоки ввода-вывода сигналов

ПЛИС находят широкое применение благодаря тому, что их можно включать в большинство проектов ВУ и ими можно заменять схемы, реализованные на устаревшей элементной базе. Предпосыл­кой этому служит большое число блоков ввода-вывода сигналов ЮВ, настраиваемых под различные стандарты электрического соединения иходов микросхем. На рис. 14 показана структура одного ЮВ.

Сигнальный вывод ПЛИС получил название PAD. С помощью на­стройки к нему можно подключать внутренний нагрузочный рези­стор PULLUP или резистор PULLDOWN, соединенные с шиной пи­тания или шиной земли, соответственно. Эти резисторы обеспечива­ют режим выхода с открытым коллектором (стоком) для систем с рп.шичными уровнями логики. Входной сигнал с PAD поступает на компаратор IBUF, порог срабатывания которого программируется мод уровни ТТЛ, КМОП, шины PCI и многие другие, а также может регулироваться установкой подаваемого снаружи потенциала уровня срабатывания Vref. Для обеспечения временного сдвига сигнала от­носительно фронта синхросерии, обеспечивающего надежный прием сигнала во внутренние триггеры, в цепь входного сигнала может иключаться специальная схема задержки.

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

В ПЛИС новых поколений к сигнальным выводам кристалла подключаются резисторы с программируемым сопротивлением, предназначенные для согласования импеданса источника или прием­ника сигнала с импедансом линии связи. Благодаря этому возможна на­дежная высокочастотная передача данных между микросхемами.

Напряжение питания ПЛИС каждого нового поколения постоян­но уменьшается, благодаря чему минимизируется энергопотребление при высоком быстродействии (см. главу 4). Для того, чтобы обеспе­чить согласование входных и выходных уровней для как можно большего числа стандартов уровней напряжения логических схем, на блоки ЮВ подается отдельное питание.

ЮВ сгруппированы в банки, и на каждый из банков можно пода­вать различный уровень напряжения питания. Но для ПЛИС по­следних поколений это напряжение не должно превосходить 3,3 В. Сигнальные входы-выходы ПЛИС обычно защищены от перенапря­жения цепочками из ограничивающего резистора и диода, подключенных между PAD и линиями питания и земли. Поэтому обычно допускается подавать на входы PAD уровень, больший 3,3 В через дополнительный резистор, ограничивающий входной ток и обеспечивающий входной уровень на PAD, не превосходящий напря­жение питания плюс падение напряжения на открытом диоде.

При диагностике, отладке, в одном из режимов конфигурирова­ния, ПЛИС может быть переключена в режим пограничного скани­рования (Boundary Scan). В этом режиме все ЮВ соединяются в це­почку одного длинного регистра сдвига. Путем стандартного внеш­него управления этим регистром сдвига через интерфейс JTAG можно считывать состояния выводов, подавать тестовые сигналы, конфигурировать ПЛИС.

В период конфигурирования ПЛИС для того, чтобы подключае­мые к ней устройства не функционировали неопределенным обра­зом, выходы ЮВ отключаются и на них обычно выставляется уро­вень Н слабой единицы.

Система синхронизации

Одним из принципов разработки проектов для ПЛИС является принцип однотактной синхронизации, согласно которому все тригге­ры в ВУ или в его блоке срабатывают одновременно по одному сиг­налу синхросерии (см. главу 4). Для его реализации в ПЛИС син­хросигналы распространяются по быстродействующей древообразной

( e i it, которая обеспечивает почти одновременный приход фронта син­хроимпульса на синхровходы всех i ршгеров (рис. 15).

Для надежного функциониро-иимия ПЛИС синхросигнал дол­жен подаваться через вывод GCLKPAD и попадать в сеть синхро­серии через буфер GCLKBUF.

В ПЛИС предусмотрено 4 вы­пи дя GCLKPAD, размещенных на iipoi ивоположных сторонах ее

корпуса. Синхросигнал может вырабатываться и внутри ПЛИС, по в этом случае его следует завести в сеть синхросерии через i лобальный буфер BUFG.

С помощью синхронного автомата, сконфигурированного в ПЛИС, можно изменять частоту и фазу синхросерии. Но в этом <* л учае ее временные параметры будут недостаточно ста-бпмьными, и поэтому такой подход обычно не применяется. Для надежного регулирования частоты синхросерии в ПЛИС вклю-чпюг делители частоты синхросерии с автоподстройкой — блоки (MiKDLL. На рис. 16 показана типичная схема его включения. Инок CLKDLL обеспечивает умножение частоты синхросерии в 2 рм.за, сдвиг ее фазы на 90, 180 и 270 градусов, деление на 1.5, 2, 2.5, 3, 4.5, 8 и 16.

Конфигурирование ПЛИС

Для конфигурирования ПЛИС в ней предусмотрены входы зада­ния режима М2, Ml, МО, вывод синхросерии программирования CCLK, вход последовательности конфигурации PROGRAM, выход флага окончания конфигурирования DONE и выводы порта JTAG. В зависимости от установленного режима можно загружать прошивку ПЛИС через однобитовый вход PROGRAM, порт JTAG или 8-разрядную шину D с использованием для управления выводов WRITE и BUSY.

Конфигурирование через однобитовый вход длится до нескольких десятков секунд. Это стандартный способ конфигурирования и для него не требуется дополнительного оборудования, кроме ПЗУ про­шивки с однобитовым выходом. С помощью одной микросхемы ПЗУ можно запрограммировать несколько ПЛИС, цепи программирова­ния которых для этого соединяются в кольцо.

Для реализации конфигурирования через шину D необходимо до­полнительное внешнее устройство (автомат или микроконтроллер), управляющее записью и выдающее последовательность адресов чте­ния на входы ПЗУ восьмиразрядной шиной данных. Зато оно проис­ходит значительно быстрее - практически с максимальным темпом чтения из ПЗУ.

В последнее время выпускаются ПЗУ, специально предназначен­ные для конфигурирования ПЛИС через шину D, в состав которых входит автомат управления записью.

Основы программирования на VHDL

Модели вычислителей VHDL

Начинающий программист VHDL легко осваивает структурный пчшь программирования, которым формально описывается структу­ра ВУ. Без трудностей он программирует стилем потоков данных, пыражая операторами параллельного присваивания прохождение данных через некоторую комбинационную схему. Но при переходе к поведенческому стилю, основанному на операторах процессов, не­редко возникают сложности с пониманием выполнения этих опера-1оров, программированием желаемого поведения системы и отлад­кой составленной программы.

Он знает, что VHDL — это язык программирования. Но у него воз­никает вопрос, программирования чего? При программировании на Он программист представляет, что он с помощью языка описывает ипдуманный алгоритм для его реализации на модели ЭВМ, содер-жмщей АЛУ, регистровую, оперативную, дисковую память и т.д., что существуют определенные типы данных и механизмы доступа к ним. Другими словами, он программирует некоторую программист­скую модель вычислителя для реализации данного языка.

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

Составление программы VHDL означает программирование этой модели. Поэтому далее рассмотрим программистскую модель вычис­лителя для реализации языка VHDL. Для понимания реализации VHDL в симуляторах будет также рассмотрена модель вычислителя с точки зрения разработчика симуляторов. Наконец, будет приведе­на аппаратная модель реализации VHDL, т.е. модель, реализуемая в СБИС или ПЛИС.

Модель вычислителя для программирования на VHDL

Наиболее полно программистская модель вычислителя VHDL описана в руководстве к стандарту языка [1]. В нем параллельно с описанием синтаксиса и семантики всех языковых конструкций приводятся объяснения их реализации в модели некоторого вирту­ального симулятора. Но, изучая это руководство, с первого раза трудно постичь основы этой модели. Ниже описывается упрощенная модель вычислителя VHDL, которая не противоречит модели, опи­сываемой в [1].

В отличие от большинства современных языков программирова­ния, язык VHDL основан на параллельной многопроцессорной моде­ли. Нижний уровень модели образует архитектура виртуального процессорного элемента (ВПЭ), а верхний уровень - множество ВПЭ, объединенных некоторой запрограммированной системой межпро­цессорных связей.

Структура ВПЭ состоит из арифметико-логического устройства (АЛУ), ОЗУ данных (ОЗУД), ОЗУ программы (ОЗУП) и определенно­го количества источников (ИС) и приемников (ПС) сигналов (рис. 18).

ЛЛУ выполняет такой же набор операций, какой требуется для Iтипизации большинства языков программирования, как, например, сложение, умножение, деление с фиксированной и плавающей запя-и>И. логические операции и т.д. Кроме того, АЛУ выполняет многие друие операции, специфические для VHDL, такие как операции над днимими с заданной разрядностью, функции с многозначным логи­ческим представлением разрядов. При выполнении операций по­стоянно проверяется корректность результата, и фиксируются ошиб­ки, как-то: выход за заданный диапазон представления числа, деле­ние на ноль и т.п.

П ОЗУ данных хранятся переменные, участвующие в вычислени­ях. Переменные имеют статические адреса, но можно реализовать и динамический доступ к переменным. Источники и приемники сиг-мнмов служат, в основном, для связи ВПЭ с внешним миром. При поступлении сигнала приемник фиксирует это событие. В приемни­ке хранится как текущее, так и предыдущее состояние сигнала. При и i.i иол нении операции с идентификатором сигнала, как с операндом, выполняется чтение приемника или источника сигнала. Источник генерирует сигнал не сразу после выполнения оператора присва-шищия, а в момент остановки ВПЭ.

li ОЗУ программы хранится программа в виде цепочки операто­ром. Операторы, включая условные операторы, выполняются после-допптельно друг за другом, как в обычных языках программирова­нии. Но на операторах wait выполнение программы останавливает-с и. Такая программа записывается в VHDL-программе как один пираллельный оператор, называемый процессом, а ВПЭ выполняет его как вычислительный процесс.

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

Отдельным входом-выходом ВПЭ является шина передачи гло-шшьных (shared) переменных. Глобальная переменная может прини-

маться (участвовать как операнд) или передаваться из ПЭ (как результат операции присваивания) в произвольные моменты времени.

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

Верхний уровень программистской модели составляет множество ВПЭ, объединенных линиями связи, по которым передаются сигна­лы (рис. 19). Консоль для связи с программистом (клавиатура и дисплей), дисковая память и ОЗУ глобальных переменных исполь­зуются всеми ВПЭ как обшие.

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

Как и в других языках параллельного программирования, в VHDL сигнал используется одним вычислительным процессом для сообщения другим вычислительным процессам факта исполнения некоторого события. Кроме того, сигнал используется для передачи исходных и промежуточных данных между процессами. Наконец, выбранные сигналы при исполнении VHDL-программы можно запи­сать в своем развитии и затем воспроизвести в виде временных гра­фиков или таблиц.

При запуске скомпилированной программы сперва все перемен­ные принимают заданное начальное значение. Затем во всех ВПЭ начинают выполняться вычислительные процессы со своих первых операторов. При достижении операторов wait ВПЭ генерируют новые значения сигналов и останавливаются. Эти сигналы, пройдя через соответствующие им линии связи до других ВПЭ, запускают в них продолжение вычислительных процессов. Такое функционирование вычислительной системы может продолжаться неопределенно долго, пока оно не будет остановлено с консоли или не выполнится опера­тор assert, требующий останова. В большинстве программ VHDL один из процессов является ведущим и задает поток возбуждающих состояний сигнала для других процессов. Например, этот процесс моделирует источник исходных данных или генератор синхросиг­нала. Тогда ВПЭ — генератор возбуждающего сигнала — запускает смежные с ним ВПЭ. Эти ВПЭ запускают ВПЭ следующие за ними и т.д. Таким образом, по вычислительной системе проходят волны за­пусков. Поэтому модель вычислителя для реализации VHDL можно трактовать как волновой процессор со специализированной тополо­гией.

Если в процессе не использованы операторы wait с установленной задержкой, то цикл запуска-остановки этого процесса выполняется почти мгновенно, а точнее — с дельта-задержкой. Здесь дельта-задержка - исчезающе малый промежуток времени, одинаковый для всех таких процессов.

Основное назначение консоли - это запуск программы на испол­нение и вывод сообщений на экран, которые генерируются специ­альными операторами assert и report.

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

При программировании на VHDL необходимо учитывать следующее.

□ Все процессы исполняются параллельно.

а Одновременно исполняемые процессы образуют фронт волны запусков процессов. Этот фронт может передвигаться с вре­менным шагом, равным дельта-задержке.

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

а Структура вычислительной модели остается неизменной после компиляции программы, т.е. после своего формирования. Эта структура не зависит от сигналов и переменных, изменяемых в процессе выполнения программы, т.е. она не может пере­страиваться динамически.

□ Область действия всех переменных (кроме глобальных) огра­ ничена рамками операторов процесса. Вне процессов перемен­ ные невидимы.

а Порядок доступа к глобальным переменным непредсказуем. Следует с осторожностью программировать с этими перемен­ными.

Вычислительная модель си муля тор a VHDL

Модель вычислителя с точки зрения программиста не может быть реализована в виде реальной многопроцессорной вычислительной системы из-за чрезмерно высоких аппаратурных затрат. С другой стороны, язык VHDL разрабатывался с целью реализации в симуля-торах дискретных систем. Такой симулятор, как правило, исполня­ется на однопроцессорной ЭВМ. Рассмотрим архитектуру вычисли­теля VHDL с точки зрения разработчика симулятора.

На рис. 20 условно показана архитектура симулятора VHDL. В данной модели каждый ВПЭ реализован как отдельный вычисли­тельный процесс (ВП). Все вычислительные процессы разделяют во времени один и тот же аппаратный ресурс - центральный процес­сорный элемент (ЦПЭ) микропроцессора ПЭВМ.

Все ВП разделены на три подмножества - очередь спящих про­цессов, очередь готовых процессов и исполняемый процесс. Боль­шинство ВП относится к числу спящих, т.е. к ВП, для исполнения которых нет готовых входных данных. Например, такой ВП ожида­ет какой-либо входной сигнал из списка чувствительности его one-

ратора wait. При поступлении сигнала этот ВП переносится в оче­редь готовых к исполнению ВП. Один из готовых ВП, выбранный произвольно, пересылается в кэш-ОЗУ микропроцессора для испол­нения. Исполняемый ВП выполняет свои операторы в соответствии с семантикой функционирования ВПЭ на ресурсах ЦПЭ микро­процессора и с использованием соответствующих библиотек проце­дур. При достижении оператора wait ВП останавливается. Вырабо­танные им сигналы запоминаются и пересылаются другим ВП, ко­торые являются приемниками этих сигналов. Затем остановленный ВП пересылается в очередь спящих процессов.

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

Для моделирования программист создает проект — каталог с фай­лами VHDL, имеющий название проекта. После компиляции в про­екте создается библиотека проекта, которая имеет название проекта и содержит все скомпилированные объекты проекта. После запуска программы на моделирование выполняется связывание объектов

проекта и назначение начальных значений переменным и сигналам (elaboration).

Затем запускается собственно моделирование. При этом выбран­ные программистом сигналы записываются в отдельной области па­мяти в своем развитии и могут быть отображены на дисплее в виде таблиц или графиков.

Для того чтобы сохранить семантику исполнения множества па­раллельных процессов, такую же, как у системы из ВПЭ, симулятор в каждом цикле моделирования выполняет следующие шаги:

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

  2. Каждый запущенный ВП исполняется до своей остановки на операторе wait, при этом вычисляются новые значения сигна­лов в операторах присваивания сигналам.

  3. Вычисляется новое значение текущего времени Тв как бли­жайший момент времени, в который будет запущен какой-либо ВП, остановленный на операторе wait ожидания оконча­ния задержки или момент времени следующей активации ис­точников сигнала.

  4. Счетчик времени принимает новое значение Тс = Тв.

  5. Каждому сигналу, для которого было вычислено новое значе­ние, присваивается это значение, т.е. источники сигналов ак­тивизируются; эти изменения сигналов проверяются, являют­ся ли они событиями для каких-либо ВП.

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

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

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

Описанная модель симулятора является приближенной. В реаль­ных симуляторах упомянутые процессы не имеют ничего общего с процессами и потоками, исполняемыми под управлением операци­онной системы. Обычно каждая новая версия симулятора отличается повышенным быстродействием. Например, для увеличения быстро­действия, по результатам компиляции VHDL-программы строится ациклический граф потоков данных, вершинами которого являются процессы программы и который соответствует алгоритму, исполняе­мому за один главный цикл моделирования. Тогда моделирование сводится к обходу вершин этого графа.

Другой метод предполагает предсказание тех процессов, которые будут исполняться в следующем цикле моделирования. Тогда моде­лирование ускоряется за счет того, что проверяется готовность к ис­полнению не всех процессов, а только предсказанных [4].

При составлении VHDL-программ желательно иметь в виду сле­дующее,

□ Даже небольшой процесс занимает в памяти несколько кило­байт. Максимальное количество процессов в скомпилирован­ной программе определяется объемом динамической памяти компьютера.

D Смена одного ВП другим ВП представляет собой смену кон­текста в работе ЦПЭ, которая может длиться несколько тысяч тактов ЦПЭ.

D Наибольшую долю времени занимает исполнение ВП ядра си­мулятора, которая возрастает нелинейно с увеличением числа ВП и числа сигналов в списках чувствительности их операто­ров wait. Поэтому, чем меньше процессов в скомпилированной программе и сигналов в списках чувствительности - тем быст­рее выполняется эта программа в симуляторе.

D Нельзя программировать процесс без оператора wait (или без списка чувствительности), т.к. после того, как этот процесс станет активным, он монопольно захватит ресурсы ЦПЭ.

Аппаратная модель реализации VHDL

Одним из важнейших назначений VHDL является описание про­ектов дискретных устройств при автоматизированном проектирова­нии микросхем. В основе технологии разработки микросхем (заказ­ных СБИС или ПЛИС) лежит автоматическая трансляция VHDL-описания дискретного устройства в схему на логическом уровне, ко­торая выполняется с помощью компилятора-синтезатора. Здесь под синтезом понимается получение аппаратной модели, которая испол­няет исходную VHDL-программу и преобразование её в схему на ло­гическом уровне. Причем подбор структуры модели и её логическая оптимизация по критериям минимума аппаратуры и максимума бы­стродействия с учетом элементного базиса целевой микросхемы вы­полняются автоматически.

Работа компилятора-синтезатора основана на взаимно-однозначном инъективном отображении программистской модели, отвечающей исходной VHDL-программе, в аппаратную модель. Это означает, что каждому из ВПЭ с его программой ставится в соответствие некото­рый специализированный процессорный элемент (СПЭ) (рис.21), причем ПС, ИС и ИС/ПС отвечают входам, выходам и входам-выходам ВПЭ. В свою очередь, граф линий связи между ВПЭ и граф соединений между СПЭ - изоморфны (рис. 22). Так как отображение инъективно, то одна VHDL-программа может дать большое мно­жество функционально эквивалентных схем, отличающихся по сте­пени оптимальности и элементному базису.

Различают два типа СПЭ: СПЭ с памятью и СПЭ без неё. СПЭ без памяти представляют собой комбинационную схему, состояние вы­ходов которой (источников сигнала) представляет собой некоторую логическую функцию от состояния её входов (приемников сигнала).

Если по семантике оператора процесса предполагается, что не все его переменные и сигналы выполняют присваивания при некотором запуске процесса, то это означает, что такие переменные и сигналы должны хранить свое предыдущее состояние при этом запуске. По­этому эти процессы отображаются в СПЭ с памятью.

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

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

При отображении в аппаратуру вместо оператора каждого типа подставляется соответствующая ему логическая схема. Так, опера­ции and ставится в соответствие логическое "И", а операции "*" -комбинационный умножитель.

На аппаратную модель реализации VHDL налагается ряд ограни­чений, связанных с особенностями элементной базы СБИС или ПЛИС. Эти ограничения имеют прообразы в программистской моде­ли. В основном, они образуют множество объектов и операторов языка, которые не могут быть отображены в аппаратуру, так как не имеют в ней соответствующего эквивалента.

Например, на сегодняшний день не могут быть автоматически отображены в аппаратуру сигналы и переменные типа с плавающей запятой, динамического, файлового типа, операция деления, опера­торы wait с параметром задержки, операторы вывода на консоль

assert и report. Также в большинстве случаев глобальные перемен­ные не находят своего отображения.

Некоторые значения перечисляемого типа, например, стандарт­ного типа stcLlogic, такие как "и" - не инициализированное, "X" -неизвестное, "-" - безразличное, также не могут быть отображены в аппаратуру, а другие, как например, "н" - слабая единица или "L" -слабый ноль, отображаются, соответственно, в 1 и 0.

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

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

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

□ Компиляторы-синтезаторы также существенно различаются по возможностям оптимизации отображения, набором атрибутов, управляющих синтезом, библиотеками процедур и функций, возможностями распознавания идиом языка, которые эффек­тивно отображаются в СПЭ и адаптированы к целевой эле­ментной базе. Например, не все компиляторы выполняют эф­фективно минимизацию оборудования путем разделения ре­сурсов. Поэтому для умелого написания программ для синтеза желательно накопить опыт работы с тем или иным компиля­тором.

Объекты и типы языка

37

Объекты и типы языка

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

В приведенных ниже описаниях синтаксиса текст в квадратных скобках означает необязательный элемент, фигурными скобками выделяется текст, который может повторяться 0,1,2,... раз, верти­кальными линиями разделяются альтернативы. Ключевые слова языка выделены полужирным шрифтом.

Комментарии

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

Литералы

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

Числовой литерал представляет собой целое или вещественное число.

Десятичный литерал - это числовой литерал в системе счисления по основанию (базису) 10, например, 120.

Вещественный литерал отличает обязательное наличие точки, отделяющей целую часть от дробной, например, 120.0, 1.20е2.

Базисный литерал - это число в системе счисления с заданным базисом от 0 до 16. Его условный синтаксис:

\базисный литерал\::=\базис\#\число в базисе\#[\экспонента\], например, 10#112# = 1б#70# = 5#422# = 2#1110000# = 2#111#е4.

Символьный литерал используется как значение для операторов или как элемент перечисляемого типа, например, бит. Он записыва­ется как символ в одиночных кавычках, например, 'Г, 'F*, '@'.

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

Идентификатор может состоять из произвольной цепочки симво­лов, в том числе из букв кириллицы. Но эта цепочка должна быть заключена между обратными косыми. Это, так называемый, расши­ренный идентификатор. Например:

С, A_and_B, \наш сигнал\, \а+в\, \process\

являются корректными идентификаторами.

Перечисляемый литерал. К перечисляемым литералам относятся символьный литерал и идентификатор. Из этих литералов формиру­ется множество перечисляемого типа.

Строчный литерал. Строчным литералом является цепочка сим­волов, заключенная в двойные кавычки, например, "абвг". Литерал битовой строки может иметь различный вид в зависимости от базиса системы счисления. Например, литералы "01111010", в"01111010", х"7А" представляют собой одно и то же значение, причем в и х озна­чают двоичный и шестнадцатиричный базисы, соответственно.

В числовых литералах и битовых строках допускается вставлять символы подчеркивания для удобства чтения, которые удаляются при компиляции. Например, x'^BBA^CDCD", "1101_011Г\ 1_024.

Тип

Тип - это множество значений с общим признаком. VHDL - стро­го типизированный язык. Каждый объект объявляется своим типом и может присваивать значение только данного типа. Соблюдение строгого соответствия типов в операторах присваивания, выражени­ях, вызовах подпрограмм требует дополнительных усилий програм­миста. Но благодаря этой особенности, программы VHDL имеют вы­сокую надежность и обеспечивают экономию времени при отладке.

Перечисляемый тип определяется как список (перечисление) всех возможных значений данного типа. Объявления этого типа выгля­дит как:

type \имя типа\ is (\перечисляемый литерал\

{Д перечисляемый литерал\});

Элементы списка литералов нумеруются при компиляции слева -направо, начиная с нуля. Например, объявление

type \цвет\ is (\красный\,\желтый\Дзеленый\);

означает, что состояния идентификатора \цвет\ будут кодироваться так, что \красный\ соответствует 0, \зеленый\ - 2. Целый тип. Объявление этого типа выглядит как:

type \имя типа\ is range \диапазон целых\;

где \диапазон целых\::=\выражение\ to \выражение\

|\выражение\ downto \выражение\ .

Выражение целого типа в диапазоне должно быть вычислимо в

период компиляции. Максимальный диапазон целых задается как:

-2147483647 to 2147483647.

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

Регулярный тип представляет собой множество элементов одина­кового типа. Различают неограниченные и ограниченные регуляр­ные типы. Неограниченный тип объявляется как:

type \имя регулярного типа\ is

array (\имя типа диапазона\гапде<>) of \имя типа элементах;

где \имя типа диапазонах имя типа integer или какого-либо подти­па от integer.

Ограниченный регулярный тип объявляется как:

type \имя регулярного типа\ is

array (Хдиапазон целых\ of \имя типа элементах);

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

VHDL допускает многомерные массивы. В их определениях диа­пазоны индексов перечисляются через запятую, например:

type MATR is array (integer range <>, integer range <>) of integer

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

type \имя комбинированного типа\ is record \имя элементах:\тип элементах; {\имя элементах:\тип элементах;} end гесо^[\имя комбинированного типа\];

Физический тип представляется целым числом, единица которого имеет вес единицы измерения некоторой физической величины. Наиболее распространенным физическим типом в VHDL является время time, которое измеряется в фемтосекундах (fs), пикосекундах (ps), наносекундах (ns) и т.д. Объекты физического типа, как прави­ло, не синтезируются, но они могут участвовать как операнды в вы­числениях констант других типов. Задание физического типа отли­чает VHDL от других языков.

Другие типы объектов

Особенными типами являются тип ссылки (access) и тип файла (file). Тип ссылки позволяет манипулировать с массивами перемен­ных, объем которых заранее неизвестен и которые создаются и лик­видируются динамически во время вычислений, как и в других языках. Тип файла обеспечивает доступ к файлам, записанным в дисковой памяти. Переменные такого типа применяют для ввода-вывода исходных данных и результатов вычислений.

Подтип

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

\подтип\::=subtype \имя подтипах is \базовый тип\ [\ограничение\];

Здесь \ограничение\ - диапазон или подмножество, в зависимости от базового типа. Подтип используют для отождествления группы объектов. Ограничение подтипа позволяет выявить ошибки на этапе моделирования. Объекты разных подтипов, у которых один родона-чальный тип, могут участвовать в вычислениях без конфликтов ти­пов.

Предопределенные типы данных

Основные типы данных VHDL определены в пакете standard, ко­торый подключается к проекту по умолчанию. Вот так в нем опре­делены некоторые стандартные типы объектов:

type boolean is (false, true);

type bit is CO', '!');

type integer is range -2147483647 to 2147483647;

subtype natural is integer range 0 to 2147483647;

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

Также определены типы character как набор букв, цифр и зна­ков, включая буквы альтернативного алфавита, подтип positive, включающий положительные значения типа integer, тип string как одномерный регулярный тип из элементов типа character.

Сигнал

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

signal:\идентификатор\{,\идентификатор\}[:= \начальное значение\];

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

Константа

Константой является объект, не изменяющий свое значение при вычислениях. После объявления константы присваивание ей значе­ния запрещено (кроме случая отложенной константы). Пример объ­явления константы:

constant thousand: integer:=1000;

Переменная

Переменная - это объект, хранящий значение в пределах опера­торов процесса, функции или процедуры. В отличие от сигнала, присваивание переменной выполняется немедленно. Синтаксис объявления переменной:

\объявление переменной\::=

[shared] variable \идентификатор\{Дидентификатор\}:\тип\ [:=\начальное значением;

Пример объявления переменной:

variable byte_int: integer range -128 to 127:=0;

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

Порт

В структуре программы VHDL выделяются объекты проекта, на­зываемые entity. Их не следует путать с объектами языка. Порт представляет собой интерфейсный сигнал объекта проекта. Как и в декларации сигнала, в декларации порта указывается его идентифи­катор, тип, начальное значение. Дополнительно указывается режим работы: in - прием, out - передача, inout - прием и передача, buffer - передача и использование как сигнал-операнд внутри объ­екта проекта и link. Упрощенный синтаксис объявления портов объ­екта проекта следующий:

\объявление портов объекта\::=port (\объявление порта\

{; \объявление порта\}); \объявление порта\::=\идентификатор\: in I out|inout|buffer|1ink

\тип\ [:=\начальное значение\] .

Режим link является анахронизмом. Он был введен для аналого­вого моделирования, но теперь в аналоговом VHDL он не использу­ется.

Настроечная константа generi с

Настроечная константа generic кодирует определенное свойство объекта проекта. Она используется, например, для задания разряд­ности линий связи, кодирования структуры моделируемого устрой­ства. При вставке компонента через интерфейс связывания настро­ечных констант, настройка объекта верхнего уровня передается объ­ектам нижнего уровня. Упрощенный синтаксис объявления настроечных констант следующий:

\объявление настроечных констант\::=

депепс(\о6ъявление настроечной константы\

{; \объявление настроечной константы\}); \объявление настроечной константы\::=

\идентификатор\:\тип\[:=\начальное значение\]

Переменная цикла

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

Начальное значение объекта

Начальное значение объекта в его объявлении - это то значение, которое принимает объект перед первым циклом моделирования. Если начальное значение не присвоено, то симулятор присваивает наименьшее значение данного типа, если тип - числовой или самое левое значение, если тип - перечисляемый.

Это значение может быть выражением. Но значение выражения должно быть вычисленным до момента трансляции данного объяв­ления. Например, первое объявление:

signal bb:bit:=aa; signal aa:bit : = Ч';

неверно, так как при его рассмотрении компилятор еще не имеет сведений об идентификаторе аа.

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

Выражения

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

Операции в выражениях

Операции VHDL перечислены в таблице 3.1 в порядке их при­оритета.

Тип операции

Символ или ключевое слово

Логические

and, or, nand, nor, xor, хпог

Сравнения

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

Сдвига

sll, srl, sla, sra, rol, ror

Сложения

+, -, & (конкатенация)

Унарные (знак)

+ » -

Умножения

*, /, mod, rem

Различные

**, abs, not

Логические операции имеют самый низкий приоритет. Операнды логических операций должны быть одного типа bit или boolean, или одномерного регулярного типа (векторы) из элементов типа bit или boolean. Для однозначной компиляции логических выражений необ­ходимо использовать скобки, например:

(a or b) and с and (d or с).

Операции сравнения выполняются над операндами одинакового типа и возвращают тип boolean. Операции равенства "=" и неравен­ства "/=" выполняются над всеми типами. Остальные операции сравнения выполняются над перечисляемыми типами, целыми ти­пами и одномерными регулярными типами (векторами) из элементов такого типа.

При сравнении перечисляемых типов элемент, стоящий в ряду правее (старший), считается большим. При сравнении векторов сравниваются пары элементов векторов, начиная с самых левых. Если пара элементов неодинакова, то вектор с более старшим эле­ментом считается бо лыиим. Если пара элементов одинакова то рас­сматривается следующая пара элементов. Например, в сравнении векторов битов "0111" >=м01011" результат будет true.

Операции сдвига выполняют сдвиг вектора битов на число разря­дов типа integer. Например, результатом выражения "100110" sra 3 будет вектор "111100", т.е. происходит арифметический сдвиг вправо на 3 разряда.

Операции сложения - вычитания "+", "-" предопределены для целых чисел и чисел с плавающей запятой. Операция конкатенации "&" применяется со всеми одномерными регулярными типами или с их элементами. С помощью этой операции векторы - операнды объ­единяются в более длинные векторы. Например, выражение "101" & 'Г & "10" даст результат "101110".

Унарные операторы применяются к одиночным операндам. Опе­ратор минус инвертирует значение операнда. Операторы умножения "*", деления "/" применяются с целыми операндами и операндами с плавающей запятой. Операторы mod (модуль), rem (остаток) приме­няются с целыми числами. Операции абсолютного значения abs и возведения в степень "**" определены для целых чисел и чисел с плавающей запятой, причем показатель степени должен быть це­лым.

Для многих операций языка существуют функции с таким же обозначением. Эти функции выполняют аналогичные действия, что и операции, но над другими типами операндов. Например, функция "+" из пакета numeric„bit библиотеки IEEE выполняет сложение век­торов битов, которые кодируют целые числа. Такие функции пере­гружают операции в зависимости от типа операндов.

При программировании для синтеза следует учесть, что правый операнд для операций "/". mod, rem может быть равным только сте­пени двойки, а левый операнд операции "**" должен быть равен 2, так что эти операции будут означать сдвиг двоичного кода.

Операнды в выражениях

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

Простое выражение чаще всего представляет собой имя объекта со знаком +,- или без него. Для многих операторов операнды долж­ны быть простыми выражениями. Особенно это касается стиля про­грамм для синтеза.

Имя с индексом дает значение элемента регулярного типа, номер которого задается выражением з скобках. Например, vect(4) озна­чает 4-й бит вектора vect, arr(i,j) означает элемент (i,j) двумер­ного массива агг.

Имя-вырезка задает цепочку элементов объекта регулярного ти­па. Его упрощенный синтаксис:

\имя-вырезка\::=\имя\(\выражение\ to | downto \выражение\)

\выражение\ - должно вычислять значение, не превосходящее диа­пазон индексов объекта регулярного типа с именем \имя\. Направ­ление изменения индекса to или downto должно совпадать с направ­лением, заданным в объявлении типа. Например, если объявлен сигнал:

signal A: bit„vector(15 downto 0);

то А(15 downto 8) - старший байт сигнала А.

Поле комбинированного типа. Чтобы оперировать с полем объек­та комбинированного типа его вставляют в выражение согласно син­таксису:

\поле комбинированного типа\::=\имя комбинированного типа\.\имя поля\

где \имя поля\ - может представлять поле любого типа, а также его имя с индексом, имя-вырезку, агрегат. Например, если объявлены тип и сигнал:

type comp„vect is record

(Re: bit_vector(0 to 15); Im:bit_vector(0 to 15)); end record; signal A: comp_vect;

то A.Re(0 to 7) - старший байт поля Re сигнала А типа comp_vect.

Вызов функции. При вызове функции выполняется функция с заданными значениями параметров. Упрощенный синтаксис вызова функции:

\вызов функции\::=\имя функции\ ([\имя параметра =>\] \выражение\ {,[\имя параметрах => ] \выражение\});

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

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

Например, в пакете iEEE.Math_.Real определена функция синуса:

function Sin (x: in real) return real;

Ее вызов по аргументу вещественного типа выглядит как: SIN(x=>math_2_pI * angle) или sin(math_2„pi * angle),

где math__2_pi - константа, равная 2, определенная в этом пакете.

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

Различают два вида преобразования типа: переход типа и вызов функции преобразования типа. Переход типа применяется для пре­образования тесно связанных типов или подтипов. Такими парами типов являются, например, real и integer, integer и natural, регу­лярные типы с одинаковым числом элементов того же самого типа и с одинаковыми диапазонами индексов. Например, при переходе из значения с плавающей запятой к целому значению:

C:=integer(123.5);

результат с округляется до ближайшего целого, т.е. до 124.

Если типы не тесно связанные, то необходимо выполнить вызов функции преобразования типа. Например, типы boolean и bit - не тесно связанные т.к. принадлежат к перечисляемым типам с раз­личными множествами элементов. Поэтому, например, преобразова­ние переменной х типа boolean в переменную Y типа bit может вы­полняться функцией преобразования типов, которая включает опе­ратор:

if X then Y: = 'l'; else Y: = '0'; end if;

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

Атрибут. У объектов языка имеется некоторое множество свойств и особенных значений. Атрибут объекта - это специальная функция, которая возвращает его особенное значение. Например, атрибут objectl'left возвращает значение самого левого элемента объекта objectl перечисляемого типа. Подробнее об атрибутах будет рас­смотрено в разделе, посвященном атрибутам.

Агрегат. Агрегатом называется операция, которая объединяет одно или несколько значений в значение составного типа, т.е. регу­лярного или комбинированного типа. Его упрощенный синтаксис:

\агрегат\::=(\связывание элементов\ {Довязывание элементов\}) \связывание элементов\::=[\альтернативы\ =>] \выражение\ \альтернативы\::=Лальтернатива\ {Д альтернатива\}

\альтернатива\: :=\простое выражение\|\диапазон\|\имя элемента\| others

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

variable v_5: bit_vector (0 to 4) : = С09, '0', ,01, '1', Ч') ;

битам 0, 1 и 2 присвоено начальное значение 0, а битам 2,3 -значение 1. Если каждый элемент связывается со своим значением по имени, то такое связывание называется поименованным. Напри­мер, для той же переменной v_5:

(3|4 => '1\ others => '0') или (0 to 2 => '0'; 3 to 4 => 'Г).

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

СО9,'О9, 3 to 4 => '1\ others -> 'О').

Но такое связывание допускают далеко не все трансляторы VHDL.

Такая альтернатива, как простое выражение, применяется только для регулярных типов и должна определять номер элемента из диапазона этого типа, например, агрегат (i => '!', others => '0') задает вектор в котором на £-м месте стоит 1, а остальные биты — нулевые.

Альтернатива \имя элементах применяется только для комбиниро­ванных типов, например:

type complex is record (Re: integer; im: integer ); end record; variable x is complex:=(Re => 1000, im => 0);

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

\квалифицированное выражение\::=\имя типа\'(\выражение\)

Например, если объявлено

type vect is bit„vector(0 to 9); var x: vect;

то выражение (3=>'l'.others => '0') может принадлежать к типу векторов любой длины и разных типов. Поэтому для присваивания переменной этого выражения необходимо выполнить его квалифи­цированным:

x^vect'O^'l' .others -> '0');

Статические выражения

Как уже указывалось, структура виртуальной параллельной вы­числительной системы и ее параметры формируются при компиля­ций программы VHDL и остаются неизменными в процессе ее ис­полнения. Точнее, это происходит на последнем этапе - этапе свя­зывания объектов (elaboration). В программах часто встречаются выражения, от результатов которых зависят структура и параметры системы. Это например, настроечные переменные (generic), опреде­ляющие порядок включения блоков, их разрядность. Некоторые операторы, например, case, вставки компонента, требуют, чтобы в них входили статические выражения. Результаты этих выражений должны иметь конкретные значения перед исполнением программы и не должны зависеть от входных сигналов и переменных. Такие выражение получили название статических. Другими словами, не­посредственно перед моделированием статическое выражение долж­но быть вычислено до константы или приведено к сигналу или пере­менной конкретного типа. Выражения от литералов, констант, ста­тических выражений и функций от них являются статическими выражениями.

Например, если объявлены сигналы

signal n: integer;

signal A: bit_vector(16 downto n+1);

то на момент начала моделирования операнд п неизвестен и симуля-тор будет пытаться подставить п = -2147483647, что вызовет ава­рийную остановку симулятора при размещении сигнала А в памяти, т.е. здесь выражение п+1 - не статическое.

Если симулятор дает широкие возможности исполнения про­граммы, обеспечиваемые большими ресурсами памяти компьютера и последовательным многократным исполнением операторов, то при аппаратной реализации программы эти возможности значительно

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

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

Реализация выражения в аппаратной модели VHDL

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

Логические операции реализуются в соответствующих элементах: and — в элементе "И", not - элементе "НЕ" и т.д. При операциях над битовыми или булебскими данными реализуются одиночные логические элементы. При выполнении операции над операндами регулярного типа каждому элементу операнда ставится в соответст­вие один логический элемент.

Операции равенства и неравенства реализуются с помощью соот­ветствующего числа элементов "И" с объединением их выходов в элементе "ИЛИ". Операции "больше" или "больше или равно" вы­полняются с помощью многоразрядной схемы сумматора-вычитателя, выход переполнения которой соответствует булевскому результату этой операции.

Операции, сложения, вычитания, изменения знака выполняются с помощью схемы сумматора, а операция умножения - с помощью комбинационного умножителя. При этом если операнды типа positive или natural, то умножение выполняется на умножителе без учета знака, а если типа integer - на умножителе со знаком.

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

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

Операция "&" конкатенации пары операндов регулярного типа соответ­ствует объединению двух шин, пере­сылающих эти операнды, в одну, со­стоящую из исходных шин.

При выполнении операций сложе­ния и вычитания разрядность резуль­тата должна быть равна максимальной разрядности операндов. Операнды

операции умножения должны иметь суммарную разрядность, рав­ную разрядности произведения.

Если операнды объявлены как тип integer без диапазона, то им соответствуют 32-разрядные типы и соответствующие 32-разрядные схемы реализации операций. Для минимизации оборудования реко­мендуется принять объявление переменной с диапазоном: например, если переменные объявлены как:

variable a, b: integer range (-128 to 127);

то выражение a+b выполняется на 8-разрядном сумматоре.

Сложное выражение от нескольких операндов при отсутствии скобок и с равноприоритетными операциями выполняется последо­вательно слева направо. Ему соответствует схема из цепочки моду­лей, выполняющих эти операции. Вставка скобок в это выражение задает приоритет выполнения операций, который отображается в аппаратную схему. Благодаря этому результирующая схема имеет вид дерева из модулей, задержка логических схем которого может быть намного меньше, чем в исходной схеме. На рис. 24 показаны аппаратные схемы, соответствующие выражениям a+b+c+d и (a+b)+(c+d).

Таким образом, вставка скобок в выражение является одним из способов управления ходом синтеза, выполняемого компилятором-синтезатором.

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

Последовательные операторы в VHDL вставляются в операторы процессов и исполняются последовательно в виртуальных процес­сорных элементах программистской модели. Все операторы в VHDL оканчиваются точкой с запятой. Несколько операторов можно раз­мещать в одной строке и один оператор может занимать несколько строк.

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

Он выполняет присваивание переменной или сигналу результата выражения. Этот оператор выглядит следующим образом:

\результат\:= \выражение\; - для присваивания переменной \результат\ <= \выражение\; - для присваивания сигнала.

Здесь результат \результат\ может быть именем, например, var, именем с индексом, как var(l), вырезкой, как var(0 to 1), полем, как гее.var или агрегатом, как (ReTim).

Присваивание переменной отличается от присваивания сигналу. Присваивание переменной выполняется немедленно.

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

При выполнении присваивания для части элементов сигнала со­ставного типа или перечисляемого типа, например, имени с индек­сом, вырезке считается, что выполняется присваивание всем элемен­там сигнала, причем те элементы, которые не указаны в операции присваивания, принимают старое значение. Например, по фрагменту программы

signal d:bit_vector(0 to 7);

d <= (others => '0'); d(l to 3) <= "Oil"; d(4 to 5) <= "IIй; wait ...

сигналу d будет присвоено значение "00111100".

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

фликт присваивания одному сигналу значений из нескольких источ­ников сигнала.

Если пользоваться пакетом ieee.STD_logic_1164, to сигнал, объ­явленный как stcLlogic, можно присваивать в разных процессах, так как в этом пакете есть функция разрешения для такого типа сигналов.

Присваивание сигналу при моделировании

При моделировании дискретных систем важное место занимает моделирование распространения сигнала с учетом задержки в про­водниках или в вентилях. Для этого используют следующий расши­ренный синтаксис присваивания сигналу:

\присваивание сигналу\::=\результат\ <= [\способ задержки\] \график\; \спосо6 задержки\::= transport |[reject \выражение времени\] inertia! \график\::= \выражение\ [after \выражение времени\]

{, \выражение\ [after \выражение времени\] }

Здесь график (waveform) представляет собой запись, состоящую из одной или нескольких пар: величина сигнала - задержка сигна­ла. В первой паре задержка может не указываться, подразумевается, что она нулевая.

Способ задержки transport означает, что при присваивании сиг­налы, представленные в графике, будут задержаны подобно тому, как сигнал задерживается в линии задержки или в проводниках. Величина задержки отсчитывается относительно момента остановки процесса и задается выражением \выражение времени\, которое име­ет тип time.

Способ задержки inertia! реализует поведение задержки в ис­точнике сигнала, который не реагирует на слишком короткие вход­ные импульсы. Фразой reject задается минимальная ширина им­пульса, которая выдается источником. Если этой фразы нет, то ми­нимальная ширина импульса задается в фразе after. По умолчанию в операторе применяется способ задержки inertia"!. В следующем ряде примеров показано действие оператора.

Y<= х after 10 ns;

- значение сигнала х на момент запуска процесса присвоится сигна­лу Y с задержкой 10 не, при этом импульсы шириной менее 10 не будут подавлены.

Y<= '0\ '1' after 10 ns, '0' after 20 ns, '1' after 30 ns;

- сигналу Y сначала присвоится 0, через 10 не - 1, через 20 не - 0, и через 30 не - 1. Иногда таким способом задаются тестовые последо­ вательности сигналов.

Y<= а, А+в after delay_sum;

- сигналу Y сначала присвоится А, а через задержку, определяемую статическим выражением delay_sum - сумма сигналов А и в.

Y<= transport X after 1000 ns;

- модель линии задержки сигнала х с задержкой 1 мкс.

Y<= reject t_rej inertial A and в after t_d;

- моделируется вентиль "И" с задержкой t_d , который не пропус­ кает импульсы короче t_rej.

Оператор ожидания события wai t

Этот оператор уже упоминался при описании модели для про­граммирования на VHDL и принципов работы симулятора. На этом операторе процесс останавливается, в момент остановки выполняют­ся присваивания сигналам, и процесс продолжает исполнение при появлении события, которое выбирается этим оператором. Синтак­сис оператора wai t:

\оператор waitY- :=wait [on \имя сигнала\ {Димя сигнала\}]

[until \6улевское выражение\] [for \выражение времени\];

где ключевое слово on начинает список чувствительности, until -условие ожидания, a for - означает задержку ожидания. По опера­тору

wait on clk, rst;

продолжение выполнения процесса начнется по событию изменения сигналов clk или RST. По оператору

wait until CLK='l';

продолжение начнется в момент изменения состояния clk из '0' в '1', т.е. по фронту этого сигнала. Оператор

wait for clk_period;

остановит процесс на время, заданное переменной clk_period типа ti me.

Возможно комбинирование списка чувствительности и условия ожидания в одном операторе. Оператор wait без списка чувствитель-

ности, условия ожидания и задержки останавливает процесс до кон­ца моделирования.

Оператор i f

Этот условный оператор в зависимости от заданных условий вы­полняет цепочки последовательных операторов, причем от условия зависит, которая из цепочек операторов выполняется. Упрощенный синтаксис оператора:

\оператор if\::=if \условие 1\ then

{\последовательный оператор 1\}

[ { elsif \условие 2\ then

{\последовательный оператор 2\}]

[else

{"^последовательный оператор 3\}]

end if;

Каждое из условий должно быть выражением, вычисляющим ре­зультат булевского типа. При выполнении этого оператора условия проверяются последовательно друг за другом, пока результат усло­вия не будет true. Тогда выполняется соответствующая этому усло­вию цепочка операторов и выполнение данного оператора if пре­кращается.

Оператор case

Этот оператор разрешает выполнение одной из цепочек последо­вательных операторов в зависимости от значения выражения селек­тора. Его синтаксис:

\оператор case\::=case \простое выражение\ is

when \альтернативы\ => {"^последовательный оператор\} {when \альтернативы\ => {"^последовательный оператор\}} end case; \альтернативы\:= \альтернатива\{ | \альтернатива\}

В выражении селектора \простое выражение\ должен вычисляться целый результат или значение перечисляемого или регулярного ти­па. Каждая из альтернатив \альтернатива\ должна быть такого же типа, что и \выражение\ и представлена статическим выражением или диапазоном, например, 0 to 4. Никакие два значения, получае­мые из выражений альтернатив, не должны быть равны друг другу, т.е. множества альтернатив не перекрываются. Последней альтерна­тивой может быть ключевое слово others, которое указывает на не перечисленные альтернативы. Если others не применяется, то в аль-

тернативах должны быть перечислены все возможные значения, принимаемые в селекторе \выражение\. Пример оператора case:

variable sel, a: integer 0 to 9;

case sel is

when 0 => a <= 0;

when 112 I 3 => a <= 1;

when 4 to 7 -> a <= 2;

when others => a <= 3; end case;

Пустой оператор

Оператор null - не выполняет никаких действий и может быть вставлен в любом месте программы, как последовательный оператор. Например, если в операторе case по каким-то альтернативам не нужно ничего выполнять, то ставится этот оператор:

case sel is

when 0 => a <= 0; when 1 to 9 => a <= b; when others => null; end case;

Оператор цикла

Этот оператор несколько раз выполняет последовательность опе­раторов. Его синтаксис:

\оператор цикла\::=[\метка\:][\схема итерации\]1оор ■^последовательный оператор\}

{next[\MeTKa\][when \условие\];} {ехЩ\метка\] [when \условие\];} end loop [\метка\]; \схема итерации\::=while \условие\

| for \переменная цикла \ in \диапазон\

Метка \метка\ необязательна, она отмечает начало цикла и с по­мощью ее во вложенных циклах указывается, в каком цикле начать новую итерацию по оператору next или из какого цикла выйти по оператору exit.

По первой схеме итераций цикл, ограниченный ключевыми сло­вами loop и end loop будет выполняться, пока условие \условие\ не примет значение false. Причем, это условие проверяется до выпол­нения цикла и если оно сразу равно false, то цикл не выполняется.

В примере:

variable vec: bit_vector(l to n); variable or_vec:bit; variable i:natural;

i:=l;

or_vec:='0'; while i<=n loop

or_vec:= or_vec or vec(i);

i: =i +1; end loop;

вычисляется переменная or_vec, равная функции ИЛИ от всех раз­рядов вектора vec длины п. Если п = 0, то цикл не вычисляется. Этот пример можно записать с помощью второй схемы итерации как:

variable vec: bit_vector(l to n); variable or_vec:bit;

or_vec:='0'; for i in 1 to n loop

or_vec:= or_vec or vec(i); end loop;

Здесь переменная цикла i последовательно принимает значения 1,2,... из диапазона 1 to п. Если необходим обратный порядок изме­нения переменной цикла: п, п-1,... то этот диапазон может быть за­дан как: n downto 1. Переменную цикла не нужно объявлять, как другие переменные и ей нельзя выполнять присваивания.

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

В примере

variable vec: bit_vector(l to n); variable numb:natural;

numb:=0;

for i in 1 to n loop

next when vec(i)='0';

numb:=numb+l; end loop;

вычисляется число единиц в векторе vec.

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

В примере

variable vec: bit_vector(l to n); variable numb:natural;

numb:=0;

for i in 1 to n loop

exit when vec(i)='l';

numb:=numb+l; end loop;

благодаря оператору exit, находится номер самой левой единицы в векторе vec, т.е. реализована функция приоритетного шифратора.

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

signal elk: bit; signal numb:natural;

numb<=0; loop

wait until clk='l';

numb<=numb+l; end loop;

Вызов процедуры

Вызов процедуры также представляет собой последовательный оператор. Его упрощенный синтаксис:

\вызов процедуры\::=\имя процедуры\[([\имя параметра =>\] \выражение\ {,[\имя параметрах => ] \выражение\})];

Здесь \имя процедуры\ - имя ранее определенной процедуры. Связывание формальных и фактических параметров выполняется аналогично, как в вызове функции. Выражение - параметр функции должно давать результат типа, соответствующего имени параметра \имя параметрах. Параметры можно задавать с поименованным или позиционным связыванием. При позиционном связывании парамет­ры-выражения подставляются в порядке, определенном порядком следования имен параметров в определении функции. При поимено­ванном связывании каждое имя параметра связывается с соот­ветствующим параметром с помощью символов "=>", причем поря­док следования параметров может быть произвольным.

В пакете iEEE.Math_Real определена процедура генерации случай­ных чисел:

procedure uniform(variable SEEDl,SEED2:inout positive;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]