Text
                    И. Е. Тарасов
ПЛИС
С XILINX.
Языки описания аппаратуры
VHDLnVerilog САПР,
приемы проектирования
Москва
Горячая линия - Телеком
2022


УДК 681.3 ББК 32.852.3 Т19 Рецензент: доктор техн. наук, главный научный сотрудник ФГУП «НИИ «Квант» В. В. Корнеев; доктор техн. наук, профессор РТУ МИРЭА Д. С. Потехин. Тарасов И. Е. Т19 ПЛИС ХШпх. Языки описайия аппаратуры VHDL и Verilog, САПР, приемы проектирования. - М.: Горячая линия - Телеком, 2022.-538 с: ил. ISBN 978-5-9912-0802-4. Рассмотрен широкий спектр вопросов, связанных с разработкой цифровых устройств с применением ПЛИС ХШпх. Изложение материала основано на ПЛИС серии 7, концентрируясь на проектировании систем начального и среднего уровня. Сведения могут быть использованы и для проектирования на базе семейств UltraScale и UltraScale-K Рассмотрены также семейство Spartan-б и САПР ISE. Кроме основных сведений о цифровых устройствах и ПЛИС, изложены сведения об основных языках описания аппаратуры - VHDL и Verilog. Приведены необходимые сведения для быстрого освоения САПР ПЛИС, включая настройку процессорных систем и подробнее сведения о настройке САПР для оптимизации проектов. В отдельной главе рассмотрены примеры разработки цифровых модулей. Материал сопровождается аналитическими обзорами и рекомендациями, включающими выбор инструментов проектирования, семейства ПЛИС, отладочных плат и Организации повышения квалификации. Для специалистов в области проектирования цифровых систем, студентов, аспирантов и преподавателей учебных заведений, а также энтузиастов. ББК 32.852.3 Адрес издательства в Интернет WWW.TECHBOOK.RU Справочное издание Тарасов Илья Евгеньевич ПЛИС ХШпх. Языки описания аппаратуры VHDL и Verilog, САПР, приемы проектирования Редактор Ю. Н. Чернышев Компьютерная верстка Ю. Н. Чернышева Обложка художника О. Г. Карповой Подписано в печать 21.05.2019. Печать офсетная. Формат 60x88/16. Уч. изд. л. 33,63. Тираж 500 экз. D-й завод - 50 экз ) Изд. JV» 190802 ООО «Научно-техническое издательство «Горячая линия - Телеком» ISBN 978-5-9912-0802-4 © И. Е. Тарасов, 2G19, 2022 © Издательство «Горячая линия - Телеком», 2022
От автора Выход в 2005 году моей книги «Разработка цифровых устройств на основе ПЛИС Xilinx™ с применением языка VHDL» [8] показал, что изложенный в ней материал в целом востребован российскими читателями. Полученный за более чем 20 лет опыт разработки цифровых устройств различного назначения и преподавания в учебном центре компании Xilinx в России позволил существенно переработать материал книги, которая задумывалась как практическое пособие для инженеров, не претендующее на справочную полноту изложения материала, однако поясняющее наиболее актуальные вопросы проектирования. Общение со специалистами и консультации по выполнению проектов показывают, что в области работы с ПЛИС существует целый ряд вопросов, нуждающихся в иллюстрациях, схемах и подробном разъяснении источников наблюдаемых эффектов и способов решения проблем. Издания справочного характера или техническая документация обычно не способствуют формированию системного взгляда на вопросы проектирования, который для практикующего разработчика должен включать всесторонний анализ решаемых им задач. Вместо этого книга задумывалась и писалась как сборник ответов на вопросы «что конкретно делать с проектом сейчас?». В процессе подготовки материала и создания примеров активно использовались результаты обсуждений на лекциях учебного центра Xilinx. Российские инженеры — слушатели курсов — наглядно демонстрировали высокий уровень технической подготовки и ставили интересные и актуальные вопросы. Многие из них получили свое отражение в материале книги. Также важным источником материалов и местом проверки идей является инженерная группа, возглавляемая профессором Дмитрием Станиславовичем Потехиным. Деятельность этого коллектива стала источником интересных задач, позволивших на практике исследовать многие вопросы, отраженные в материалах книги. Отдельное спасибо человеку, имеющему уникально тесную связь с моей деятельностью по созданию книг. Выход в свет моей первой книги и его рождение отделяют всего несколько дней. В итоге мой сын Антон стал первым читателем материала, опробовав на себе освоение некоторых проблемных вопросов проектирования. Хочется надеяться, что и технические специалисты найдут изложение достаточно простым и понятным.
Введение Данная книга предлагает читателю сведения о проектировании цифровых систем на базе ПЛИС Xilinx. В главе 1 приведены начальные сведения о цифровой электронике и описание ПЛИС семейств Spartan-6, Spartan-7, Artix-7, Kintex-7 и Zynq-7000, которые могут быть использованы в широком спектре устройств, в том числе и для расширения возможностей микроконтроллера. Материалы книги могут быть использованы для изучения порядка проектирования с использованием семейств верхнего уровня, таких как Virtex и Zynq MPSOC. Глава 2 содержит описание «быстрого старта» в САПР ПЛИС Vivado и ISB. Главы 3 и 4 описывают возможности языков описания аппаратуры VHDL и Verilog. Главы имеют приблизительно одинаковую организацию, поскольку рассмотренные языки обладают сопоставимыми возможностями. С учетом того, что разработчики могут выбирать один из языков в качестве приоритетного, главы могут быть изучены выборочно или совместно. Рекомендуется начинать изучение с языка VHDL. Глава 5 посвящена применению дополнительных инструментов проектирования Xilinx. В ней приводятся примеры реализации процессорных систем на базе так называемых софт-процессоров (т.е. процессоров, которые образуются путем программирования ячеек ПЛИС) MicroBlaze и PicoBlaze. Также приводятся краткие сведения о применении языков высокого уровня (HLS, High Level Synthesis). Глава 6 приводит примеры реализации отдельных модулей на HDL. Знакомство с данной главой может быть полезно для эффективного использования возможностей ПЛИС Spartan-б и создания устойчиво работающих схем, учитывающих технологические особенности производства современных цифровых микросхем. В главе 7 приведены сведения, касающиеся подходов оптимизации проектов на ПЛИС и используемых для этого инструментов САПР. В первую очередь это касается эффективного использования проектных ограничений и анализа отчетов о результатах работы САПР. Глава 8 рассматривает вопросы проектирования устройств на базе ПЛИС, включая вопросы организации питания, программирования, разработки печатной платы. В приложении приведены сведения о языке System Verilog, который обладает широкими возможностями при моделировании цифро-
Введение 5 вых схем. Этот язык на момент издания книги ограниченно поддерживается в САПР Vivado, поэтому его практическое использование следует рассматривать при использовании других инструментов моделирования схем. В целом владение языком пока нельзя считать критически важным навыком при разработке систем на базе ПЛИС, поэтому информация о нем приведена в приложении. Практическое использование ПЛИС Xilinx можно начать с установки бесплатно распространяемой версии САПР Vivado Webpack (или ISE Webpack для Spartan-6), загружаемой официального сайта компании-производителя http://www.xilinx.com/ В России также функционирует учебный центр Xilinx на базе официального дистрибьютора Xilinx КТЦ «Инлайн Груп», http://www.plis.ru, реализующий программы повышения квалификации по учебным материалам, разработанным Xilinx.
Начальные сведения о цифровой электронике и архитектуре ПЛИС Xilinx Возможность провести оперативное и недорогое натурное моделирование крайне полезно во многих областях человеческой деятельности. Разработка программ является наглядным примером процесса создания нового продукта, который не требует затрат компонентов или сырья для каждой итерации. Имея компьютер, программист может реализовать широчайший спектр идей, при этом он не ограничен требованием каждый раз безвозвратно расходовать материальные носители информации. В области механики подобные возможности предоставляют конструкторы Lego. В области дискретной электроники такую роль играет возможность монтажа компонентов пайкой на макетную плату или накруткой проводов. Во всех случаях комбинирование компонентов базового набора (команды компьютерного процессора, кубики Lego) открывает достаточно широкие возможности для построения устройств. Микроэлектроника предполагает исполнение всех компонентов и связей между ними на полупроводниковой пластине. После изготовления интегральной микросхемы промышленным способом изменение ее схемы уже невозможно, а стоимость подготовки производства существенно возрастает с каждым поколением технологических процессов. Поэтому производители микросхем должны выбирать такие схемы, которые могли бы быть востребованы тиражами десятки и сотни тысяч штук. Это практически исключает возможность экспериментов с микросхемами, требующих их постоянного исправления. Обеспечить относительную гибкость интегральной микросхемы можно, если управлять соединениями не механически, путем добавления или разрыва проводников, а электрически, программируя заранее предусмотренные на кристалле соединители. Микросхемы с набором таких соединителей (ключей) на кристалле относятся к классу программируемых устройств. В зависимости от того, переключаются цифровые или аналоговые сигналы, микросхемы относят к программируемым логическим интегральным гаемам (ПЛИС) или к программируемым аналоговым интегральным схемам (ПАИС).
Начальные сведения об архитектуре ПЛИС ХШпх 7 Микросхемы ПЛИС на протяжении своего существования претерпели достаточно заметную эволюцию. От простых программируемых устройств (SPLD, Simple Programmable Logic Device), которые имели ограниченные возможности модификации, они прошли путь до комплексных устройств с гибкими возможностями построения схемы — CPLD (complex Programmable Logic Devices) и PPGA (Field Programmable Gate Array). Эти микросхемы в настоящее время производятся с применением наиболее современных технологических процессов, что обеспечивает высокие технические характеристики и большой объем в логических элементах. В данном издании будут рассмотрены ПЛИС небольшого логического объема (преимущественно Spartan-б, серия 7 компании ХШпх), с помощью которых тем не менее можно разработать достаточно широкий спектр устройств. 1.1. Основы схемотехники цифровых устройств В основе цифровой электроники лежит использование ключевых режимов работы полупроводниковых приборов. В таком режиме полупроводниковый транзистор может рассматриваться как устройство, сопротивление между двумя электродами которого может управляться при помощи третьего. В биполярном транзисторе ток базы управляет сопротивлением между эмиттером и коллектором, а в полевом напряжение затвор-исток управляет сопротивлением между истоком и стоком. В одном из состояний сопротивление близко к нулю (ключ замкнут), а в другом — бесконечно велико (ключ разомкнут). Механическая модель транзистора и варианты его включения показаны на рис. 1.1. Из подобных элементов может быть построена схема, состояние которой может быть описано двумя уровнями напряжения —• низким и высоким. С целью увеличения помехоустойчивости для каждого уровня выбирается некоторый диапазон значений напряжения, обеспечивающий устойчивое считывание состояния цифрового выхода входами других цифровых узлов (рис. 1.2). Напряжения, меньшие некоторого минимального значения ) трактуются как логическая величина «ноль», а большие не- Механический Биполярный транзистор Полевой транзистор аналог При наличии тока базы уменьшается сопротивление между эмитером При наличии напряжения затвор- базы уменьшается сопротивление между и колектором истоком и стоком Рис. 1.1. Механическая модель транзистора и транзисторы в роли ключей.
Глава 1 и„ Неопределенное значение Рис. 1.2. Логические уровни в цифровых устройствах Рис. 1.3. Простейший инвертор на биполярном транзисторе которого U\ min — как «логическая единица». Напряжение питания естественным образом ограничивает диапазон возможных значений напряжения — нижним пределом логического нуля является нулевое напряжение, а верхним пределом логической единицы — напряжение питания. Таким образом, с помощью значений напряжения можно представить простейшие сигналы, принимающие только два значения. Однако кроме представления требуется и преобразование сигналов, что также обеспечивается полупроводниковыми устройствами. На рис. 1.3 изображена упрощенная схема инвертора на биполярном транзисторе. Принцип работы данной схемы можно понять, если учесть, что при наличии тока базы транзистор уменьшает сопротивление между выводами эмиттера и коллектора («открывается»), а при отсутствии — увеличивает («закрывается»). Резисторы R\ и i?2 служат для ограничения тока базы, a R$ ограничивает максимальный ток коллектора. Теперь, если на вход данной схемы будет подано напряжение, соответствующее логической единице, управляющий ток базы откроет транзистор и сопротивление между эмиттером и коллектором резко уменьшится. Следовательно, напряжение на коллекторе будет близко к нулю. Если же напряжение на входе будет близко к нулю, ток базы будет слишком мал для открывания транзистора и напряжение на коллекторе будет определяться током, протекающим от источника питания через резистор Дз. Таким образом, логический уровень на выходе данной схемы всегда противоположен логическому уровню на ее входе. Такое устройство называется инвертором (рис. 1.4). Показанная на рис. 1.3 схема является сильно упрощенной и не соответствует схемотехнике промышленных цифровых микросхем. Тем не менее она позволяет ознакомиться с принципом использования биполярных транзисторов для создания цифровых схем. В реальных устройствах используется первичное преобразование элек-
Начальные сведения об архитектуре ПЛИС Xilinx 1*з Из Выход = О ~Т^» 7 Рис. 1.4. Работа инвертора трических сигналов, которое обычно также выполняется с помощью транзисторов. Вследствие этого одна из наиболее распространенных архитектур цифровых систем носит название «транзисторно- транзисторная логика», или ТТЛ. Такое название отражает тот факт, что транзисторы используются как для первичного преобразования сигналов, так и для формирования выходного напряжения. Предшественниками такой архитектуры являются резисторно- транзисторная (показанная на рис. 1.3) и диодно-транзисторная логика. Существенным недостатком микросхем ТТЛ является наличие статического потребления — для удержания биполярного транзистора в открытом состоянии требуется протекание постоянного тока базы, поэтому использование биполярных транзисторов в цифровых устройствах ограничено максимальной рассеиваемой мощностью. Альтернативным вариантом является построение цифровых устройств на полевых транзисторах, которые управляются потенциалом затвора и не требуют постоянного протекания управляющего тока. Удобнее использовать полевые транзисторы, выполненные по технологии «металл-окисел-полупроводник» (МОП). В зависимости от типа проводимости канала такие транзисторы могут открываться либо низким логическим уровнем, либо высоким. Использование транзисторов, аналогичных по характеристикам, но имеющих разный тип проводимости канала (комплементарных, т.е. «дополняющих») позволяет реализовать эффективный инвертор (рис. 1.5). Архитектура микросхем, основанных на комплементарных полевых транзисторах, обозначается КМОП (также CMOS — Complementary Metal- Oxide-Semiconductor) . На схеме рис. 1.5 верхний транзистор открывается при низком логическом уровне, подключая к выходу напряжение питания (т. е. обеспечи- -г- Vdd Рис. 1.5. Принципиальная электрическая схема инвертора КМОП
10 Глава 1 вая высокий уровень выходного напряжения). При высоком входном уровне верхний транзистор закрывается, а нижний — открывается и подключает к выходу уровень нуля. Статическое потребление такой схемы определяется утечками тока через слой диэлектрика между затвором и каналом, т. е. весьма мало. Большую роль играет так называемое динамическое потребление: в процессе переключения входного напряжения существует период времени, в течение которого оба транзистора обладают конечным сопротивлением и наблюдается протекание тока через оба канала (в статическом состоянии один из транзисторов почти полностью открыт, а другой — почти полностью закрыт). При этом мощность, потребляемая схемами КМОП, оказывается приблизительно пропорциональной частоте переключения внутренних сигналов. На практике различие между ТТЛ и КМОП проявляется в уровне напряжений логической единицы. Сравнение схем инверторов позволяет увидеть, что в коллекторной цепи выходного транзистора ТТЛ имеется резистор. Поэтому если транзистор открыт, то выход подключается не к напряжению питания, а к этому резистору. Чем больше выходной ток, требуемый от элемента, тем большим будет падение напряжения на резисторе и, соответственно, меньше выходное напряжение. Поэтому для микросхем ТТЛ уровень, воспринимаемый как логическая единица, устанавливается достаточно низким, чтобы учесть возможное падение напряжения. Для схем с питанием 5 В или 3,3 В этот уровень составляет 2,4 В. В ряде случаев применяется порог 2,0 В. В отличие от ТТЛ, микросхемы КМОП имеют на выходе симметричный каскад из комплементарных полевых транзисторов (ком- плементарность и отражена в аббревиатуре — символом «К»). Поэтому уровни выходных напряжений оказываются близки к нулю и напряжению питания соответственно. Порог срабатывания для логической единицы устанавливается в 80 % от напряжения питания. Таким образом, при питании в 5 В микросхема КМОП требует подачи на вход напряжения 4,0 В для надежного распознавания логической единицы. Уровень логического нуля для обоих вариантов одинаков и составляет 0,8 В. Однако несоответствие выходного напряжения ТТЛ и входного уровня логической единицы КМОП может вызвать проблему при их соединении. Это касается только случая, когда выход ТТЛ подается на вход КМОП, поскольку ТТЛ может выдавать 2,4 В, рассчитывая, что это напряжение будет достаточным для распознавания логической единицы, но вход микросхемы КМОП потребует
Начальные сведения об архитектуре ПЛИС ХШих 11 4,0 В. В подобных случаях необходимо использовать специальные микросхемы согласования уровней. Можно отметить, что в ряде случаев микросхемы КМОП выполняются с учетом особенностей работы ТТЛ и их входной уровень логической единицы равен 2,4 или даже 2,0 В. ТТЛ и КМОП являются наиболее распространенными, но не единственными подходами к реализации цифровых устройств. Ранее использовались также интегральная инжекционная (И2Л) и эмиттерно-связанная логика (ЭСЛ, также Emitter Coupled Logic, ECL). Последняя позволяет обеспечить достаточно высокое быстродействие, однако имеет повышенное энергопотребление по сравнению со схемами ТТЛ и КМОП. Кроме того, элемент ЭСЛ использует отрицательное напряжение питания. Это усложняет его соединение с компонентами ТТЛ/КМОП, однако с развитием полупроводниковой технологии преимущества отрицательного питания стали не такими существенными. Поэтому существует и современная разновидность PECL (Positive Emitter-Coupled Logic). Для повышения помехоустойчивости цифровых линий на высоких рабочих частотах используются также дифференциальные электрические интерфейсы. Одним из наиболее распространенных является LVDS (Low-Voltage Differential Signaling). Логический уровень при этом передается не абсолютным уровнем напряжения, а их разностью на положительном (positive, P) и отрицательном (negative, N) проводниках (рис. 1.6). Повышение помехоустойчивости при этом достигается за счет того, что оба проводника обычно прокладываются на печатной плате параллельно, поэтому помехи, наведенные на один из них, будут практически в том же виде наведены и на другой. В конечном счете разность потенциалов между ними останется примерно одинаковой, т. е. определяемой микросхемой- источником. Применение интерфейса LVDS требует специальных микросхем: драйвера (источника) и приемника. Также можно обратить внимание, что для микросхемы-приемника используется резистор, вклю- Микросхема-источник Микросхема-приемник р N 100 n| JRxJ>- Рис. 1.6. Соединение микросхем с помощью интерфейса LVDS
12 Глава 1 ченный между линиями. В соответствии со стандартом его номинал составляет 100 Ом, поэтому LVDS при работе потребляет относительно большую мощность по сравнению с К МОП. Микросхемы ПЛИС имеют возможность конфигурировать выводы как однопро- водные (КМОП, ТТЛ) или дифференциальные (LVDS и др.). Тем не менее произвольное образование дифференциальных пар в ПЛИС не допускается, каждому выводу Р соответствует определенный вывод N (обычно расположенный рядом). Приведенные выше сведения о схемотехнике цифровых устройств являются сильно упрощенными и не отражают целый ряд вопросов. Например, уменьшение норм технологического процесса и размеров транзисторов приводит к тому, что сопротивление диэлектрика между затвором и каналом также уменьшается, что приводит к резкому росту утечек тока. Не рассмотрено также поведение транзисторных ключей в динамическом режиме, подключение нагрузки к выходам, особенности технологических процессов изготовления цифровых устройств и многое другое. Для подробного изучения схемотехники цифровых элементов следует обратиться к специальной литературе. Инвертор не является единственным устройством для преобразования логических сигналов. Более того, интерес представляют как раз не одновходо- вые, а многовходовые устройства, позволяющие сформировать сигнал, представляющий собой сложную функцию от состояния * — J s 1 л -Г* _ ji _ Рис. 1.7. Вазовые логические элементы: логическое НЕ (инвертор), логическое И, логическое ИЛИ. Верхний ряд — изображение по IEEE, нижний ряд — по ЕСКД входов. Набор базовых логических элементов приведен на рис. 1.7. Логические элементы называются также вентилями (в англоязычной литературе gate). Необходимо обратить внимание, что таким же термином обозначается и затвор полевого транзистора, хотя смысловая нагрузка в этих случаях различна. Удобным способом описания работы логических вентилей является составление таблиц истинности. В такую таблицу записывается состояние выхода в зависимости от комбинации входных сигналов. Для элементов, показанных на рис. 1.7, таблицы истинности будут выглядеть так, как показано в табл. 1.1. Число входов для логических элементов И и ИЛИ моз^ет быть больше двух. При этом сохраняется принцип работы, показанный в табл. 1.1: на выходе элемента И логическая 1 появляется только в
Начальные сведения об архитектуре ПЛИС ХШпх 13 Таблица 1.1 Таблицы истинности для базовых логических элементов Элемент И Элемент ИЛИ Элемент НЕ А 0 1 Q 1 0 А 0 0 1 1 В 0 1 0 1 Q 0 о 0 1 А 0 0 1 1 в 0 1 0 1 Q 0 1 1 1 том случае, если все входы находятся в состоянии логической 1 («И на первом, И на втором, И на третьем...»), а для появления логической 1 на выходе элемента ИЛИ достаточно наличия логической 1 хотя бы на одном из его входов. Имея двухвходовые логические элементы, можно создать такой же элемент с числом входов больше двух, соединяя одинаковые элементы последовательно. С помощью базовых логических элементов можно формировать и более сложные схемы, которые будут описываться сложными таблицами истинности. Для упрощения построения = 1 Рис. 1.8. Вспомогательные логические элементы: ИСКЛЮ- ЧАЩВБ ИЛИ, И-НЕ, ИЛИ-НЕ. Верхний ряд — изображение по IEEE, нижний ряд — по ЕСКД таких схем вводятся вспомогательные логические элементы. Основными их разновидностями являются: вентиль ИСКЛЮЧАЮЩЕЕ ИЛИ, схемы И-НЕ, ИЛИ- НЕ. Графические обозначения этих вентилей показаны на рис. 1.8, а таблицы истинности приведены в табл. 1.2. Из табл. 1.2 видно, что элемент ИСКЛЮЧАЩЕЕ ИЛИ формирует на выходе логическую 1, когда логические уровни на его входах различны. Его можно также рассматривать как элемент ИЛИ, за исключением состояния «оба входа равны 1». Элементы И-НЕ и ИЛИ-НЕ могут быть получены путем последовательного соединения элементов И, НЕ и ИЛИ, НЕ соответст- Таблица 1.2 Таблицы истинности для вспомогательных логических элементов Элемент ИСКЛЮЧАЮЩЕЕ ИЛИ Элемент И-НЕ Элемент ИЛИ-НЕ А 0 0 1 1 В 0 1 0 1 Q 0 1 1 0 А 0 0 1 1 В 0 1 0 1 Q 1 1 1 0 А 0 0 1 1 В 0 1 0 1 Q 1 0 0 0
14 Глава 1 Таблица 1.3 Таблица истинности для элемента 2И-НБ с объединенными входами Таблица 1.4 Таблица истинности для элемента 2И-НБ с инвертированными входами А 0 1 В 0 1 Q 1 0 А 0A) 0A) 1@) 1@) В 0A) 1@) 0A) 1@) Q 0 1 1 1 венно. Для упрощения графического изображения символ инверсии (небольшой кружок) размещают непосредственно на выходе такого элемента. Часто в обозначении элемента указывается и число его входов. Например, ЗИЛИ соответствует трехвходовому элементу ИЛИ. Символы инверсии могут быть размещены и на входах логических элементов. В этом случае их работу необходимо анализировать так, как если бы сигнал на этот вход подавался через элемент НЕ. Рассмотрим двухвходовой элемент И-НВ BИ-НЕ). Если объединить его входы, то таблицу истинности можно представить так, как показано в табл. 1.3. Из этой таблицы следует, что элемент 2И-НЕ в данном случае выполняет функцию инвертора. Соединив элементы 2И-НЕ и инвертор, созданный из такого же элемента с объединенными входами, получаем элемент 2И. Наконец, вводя инверторы для входных сигналов, получаем следующую таблицу истинности (в скобках показаны значения инвертированных сигналов, которые в действительно воспринимаются элементом 2И-НЕ). Итак, для элемента 2И логическая единица на выходе должна появиться только в том случае, если оба сигнала, стоящие в скобках, равны 1. В остальных случаях на выходе присутствует логический ноль. С учетом инвертора, стоящего на выходе, получаем результаты, показанные в табл. 1.4. Нетрудно убедиться, что они соответствуют логике работы элемента 2ИЛИ. Таким образом, имея достаточное число элементов 2И-НЕ, можно реализовать любой из элементов И, ИЛИ, НЕ. Поэтому элемент 2И-НЕ может выступать в роли некоторого эквивалента сложности комбинационной схемы. Аналогичные рассуждения можно провести и для элемента 2ИЛИ-НЕ, с помощью которого также реализуются любые схемы комбинационной логики. Элементы 2И-НЕ (называемый также базисом Шеффера) и 2ИЛИ-НЕ (базис Пирса) являются эквивалентными логическими вентилями (equivalent logic gates), с
Начальные сведения об архитектуре ПЛИС ХШпх 15 помощью которых можно оценить сложность того или иного цифрового устройства. Особенностью работы представленных логических элементов является то, что соответствующий таблице истинности сигнал на их выходе появляется с незначительной задержкой относительно смены состояний на входе. Эта задержка обусловлена только процессами переключения элементов схемы и при рассмотрении идеальных элементов считается, что она равна нулю. Таким образом, изменение уровня выходного сигнала может произойти в любой момент времени, поэтому такие схемы относят к классу асинхронных. Однако более точным названием, отражающим использование логических вентилей, состояние которых определяется только уровнем входного сигнала, является термин «комбинационная логика». Действительно, для точного определения состояния выхода такой схемы достаточно знать комбинацию состояний ее входов. При этом предыстория их изменений не играет роли. Существуют также устройства, состояние которых может также измениться в любой момент времени, но определяется не только текущим состоянием входов, но и историей изменения этих состояний. На базе устройств комбинационной логики возможно решение многих задач вычислительной техники. В частности, с их помощью производится выполнение базовых арифметических операций. Рассмотрим операцию сложения, выполняемую над числами, представленными в двоичной системе счисления. В этой системе возможны всего четыре варианта: 0 + 0 = 0, 0 + 1 = 1, 1 + 0=1, 1+1=10 Bю). Для представления числа 2, которое в двоичном виде запишется как 10, требуется уже два разряда. Запишем таблицу истинности для элемента, устанавливающего выход в соответствии с младшим разрядом результата сложения двух чисел, представленных в двоичной системе (табл. 1.5). В последнем случае в таблице записан ноль, поскольку произошел перенос в следующий разряд. Из таблицы видно, что операция сложения реализуется элементом ИСКЛЮЧАЮЩЕЕ ИЛИ. Для представления числа, переносимого в следующий разряд, потребуется еще один выход. Нетрудно убедиться, что значение этого выхода равно 1 только в том случае, когда оба входа равны 1 — сигнал переноса, таким образом он формируется элементом И. Таблица 1.5 Таблица истинности одноразрядного сумматора: результат сложения чисел А и В А 0 0 1 1 В 0 1 0 1 Q 0 1 1 0
16 Глава 1 АО — ВО — О 1 Cin A Q В Coi Q0 А1 — В1 — Cin A Q В Cout Таблица 1.6 Таблица истинности одного разряда многоразрядного сумматора — Q1 А2 — В2 — Cin A Q В Cout — Q2 А 0 0 1 1 0 0 1 1 в 0 1 0 1 0 1 0 1 Cin 0 0 0 0 1 1 1 1 Q 0 1 1 0 1 0 0 1 Cout 0 0 0 1 0 1 1 1 Рис. 1.9. Многоразрядный сумматор При сложении многоразрядных двоичных чисел (рис. 1.9) необходимо учитывать сигналы переноса, приходящие из предыдущих разрядов, и формировать такие сигналы для последующих разрядов. С учетом сигнала переноса каждый элемент сумматора, начиная со второго, должен иметь три входа вместо двух. Обозначим вход переноса как Cin, а выход как Cout и составим таблицу истинности для такого блока (табл* 1.6). При составлении таблицы истинности использовалось свойство коммутативности сложения: поскольку порядок слагаемых не влияет на результат, можно ориентироваться на то, что нечетное число единиц в трех входных сигналах обуславливает появление единицы на выходе Q, а выход Cout принимает значение 1 в тех случаях, когда два или три входа находятся в состоянии единицы. Можно подобрать несколько вариантов реализации устройства комбинационной логики, реализующего сложение. Элементы комбинационной логики реализуются цифровыми микросхемами малой степени интеграции. Это серии 155, 555, 1533 и другие российского производства и их аналоги 74хх, выполненные по технологии ТТЛ, а также КМОП-устройства серий 176, 561 и 54хх соответственно. В составе этих серий присутствует большое число элементов рассмотренных выше типов с различным числом входов. Схема, показанная на рис. 1.9, называется сумматором с последовательным переносом {ripple-carry adder) и не является единственным вариантом реализации сумматора. Однако она представляет интерес как своей простотой, так и тем, что в рассматриваемых в данной книге микросхемах PPGA имеются аппаратные реализации именно такой схемы.
Начальные сведения об архитектуре ПЛИС ХШпх 17 Щ В проектах для FPGA не следует реализоеывать сумматоры путем описания их схемы в соответствии с рис. 1.9. В этих микросхемах существуют специальные цепи для реализации переноса, которые эффективно используются САПР. Самостоятельное повторение схемы сумматора приведет к менее эффективной реализации. В противоположность асинхронным, синхронные цифровые устройства изменяют состояние выходных сигналов в строго определенные моменты времени. Эти моменты, как правило, соответствуют положительному перепаду специального синхронизирующего сигнала, называемого проще тактовым сигналом. Для описания работы синхронных устройств может использоваться такое представление, как временные диаграммы работы. Они представляют собой графики зависимости логических уровней от времени, на которых показывают типичные комбинации и события (перепады уровня) на входных линиях, а также соответствующие изменения выходных сигналов. Вазовым синхронным элементом является D-триггер. Его графическое изображение и временные диаграммы работы показаны на рис. 1.10. На рис. 1.10 видно, что выход триггера Q принимает то же со- стояние, что было на входе дан- ных D в момент положительного перепада (фронта) тактового сиг- tj Рис. 1.10. Графическое изо- нала. В остальные моменты вре- бражение и ^ диа. бражение и мени изменения ЛОГИЧеСКОГО урОВ- граммы работы D-триггера ня на входе D никак не влияют на состояние выхода. Такое поведение позволяет, в частности, использовать D-триггер в качестве устройства хранения данных. После подачи на вход D требуемого уровня сигнала и запоминания его в триггере по фронту тактового сигнала значение с входа данных D может быть убрано. При этом возникает проблема: как добиться того, чтобы последующие фронты тактового сигнала не переписывали запомненное в триггере значение? Одним из способов является формирование вспомогательного тактового сигнала с помощью элемента 2И. На первый из входов этого вентиля подается собственно тактовый сигнал, а на второй •— сигнал разрешения. Обращаясь к таблице истинности 2И, нетрудно убедиться, что если на втором входе будет присутствовать сигнал логического нуля, то выход этого элемента будет оставаться в нуле при любом уровне тактового сигнала. Если же на вход разрешения подан сигнал логической единицы, то состояние выхода пол-
18 Глава 1 ностью определяется состоянием входа, на который подан тактовый сигнал. Таким образом, элемент 2И может запрещать прохождение тактового сигнала на вход С триггера в те периоды времени, когда обновление его состояния не требуется. В ряде случаев введение в проект вспомогательных вентилей, запрещающих прохождение тактового сигнала, ведет к труднообна- ружимым ошибкам. Их источником является тот факт, что тактовый сигнал, прошедший через логический вентиль, оказывается задержанным относительно исходного сигнала на время, требуемое для переключения внутренних схем элемента 2И. Это приводит к тому, что фронт тактового сигнала приходит на разные триггеры в разные моменты времени и часть триггеров проекта, срабатывая раньше, может исказить логические сигналы, требующие записи в остальные триггеры. Этот неприятный эффект носит название «гонки фронтов», и его следует всячески избегать. Для исключения записи в неподходящие моменты времени в состав триггеров (и других синхронных узлов) вводят специальный вход разрешения записи СВ (от Clock Enable — «разрешение тактового сигнала»). Перезапись состояния триггера происходит только в том случае, если в момент прихода фронта тактового сигнала на входе СЕ присутствовал высокий логический уровень. Правильное формирование тактового сигнала внутри ПЛИС должно быть обеспечено с помощью специальных компонентов — аппаратных формирователей и тактовых сетей. Необходимо иметь в виду, что действительный уровень сигнала, разрешающего работу синхронных устройств, может быть как логическим нулем, так и логической единицей. В схемотехнике ТТЛ существует целый ряд соображений, по которым некоторые сигналы считаются активными, если их уровень соответствует логическому нулю. Такие сигналы обозначают символом инверсии (небольшой кружок на входе, аналогично выходу инвертора), чертой над именем сигнала на его графическом изображении, а в текстовых описаниях — символами ~, #, п перед именем сигнала (например, ~СЕ, #СЕ, пСЕ). Уровень сигнала, при котором соответствующий вход считается влияющим на работу устройства, называют активным уровнем сигнала. Пример изображения D-триггера с входом разрешения тактового сигнала, имеющим активный низкий уровень, приведен на рис. 1.11. Аналогично активный низкий уровень можно назначишь и другим входам и выходам цифровых устройств. Например, если инвертировать тактовый вход D-триггера, то перезапись выхода Q будет
Начальные сведения об архитектуре ПЛИС ХШпх 19 D0- Рис. 1.11. Графическое изображение D- триггера с входом разрешения тактового сигнала, имеющим активный низкий уровень происходить при переходе тактового сигнала от уровня единицы к уровню нуля («по спаду тактового сигнала»). С помощью триггеров можно создавать ряд широко используемых цифровых узлов, например регистры и счетчики. Под регистром в процессорной технике понимают узел для хранения значения переменной состояния. Это может быть как регистр в понимании программиста, так и внутренние сигналы, кодирующие состояние процессора, недоступные программисту, своей основе имеют триггер. D1- D2- D3- CLK- D D — Q0 -Q1 D D — Q2 — Q3 Рис. 1.12. Соединение D- триггеров для получения 4-разрядного регистра Все эти устройства в Если объединить тактовые входы у нескольких триггеров, то запись в них будет происходить одновременно. В схеме, показанной на рис. 1.12, четыре триггера формируют устройство для хранения 4-разрядного двоичного числа. Новое значение в регистр записывается по фронту тактового сигнала. Каждый триггер может иметь также вход разрешения записи, и при объединении этих входов образуется вход разрешения записи в регистр, что позволяет перезаписывать значение регистра только в моменты, предусмотренные разработчиком схемы. Физические принципы построения устройств памяти делят их на два больших класса: постоянные запоминающие устройства (ПЗУ, Read-Only Memory, ROM) и оперативные запоминающие устройства (ОЗУ, Random Access memory, RAM). Как следует из расшифровки первого типа памяти, она предназначена только для чтения записанных в нее чисел и не допускает произвольную неограниченную по числу циклов перезапись. Память второго типа, ОЗУ, допускает как запись, так и чтение. Все устройства памяти представляют собой массив двоичных чисел, нумеруемых последовательно. Номер ячейки называется ее адресом, а хранящееся число — данными. И адреса, и данные представляются набором двоичных линий, поэтому обычно говорят о шине адреса и шине данных.
20 Глава 1 Рассмотрим основные сигналы и временные диаграммы работы устройств памяти того и другого типа. На рис. 1.13 показано изображение постоянного запоминающего устройства. Оно со- Рис. 1.13. Посто- держит линии адреса А0-А15, формирующие янное запомина- 16-разрядное двоичное число, и линии данных ющее устройство D0-D7, формирующие 8-разрядные данные. Сигнал CS расшифровывается как Chip Select («выбор кристалла») и служит сигналом разрешения работы устройства. Неактивный логический уровень на данном входе блокирует работу ПЗУ и переводит его выходы в состояние высокого импеданса. Аналогичную роль играет сигнал OB (Output Enable, «разрешение выхода»). Неактивный уровень на нем также переводит выходы ПЗУ в состояние высокого импеданса, однако одинаковое, на первый взгляд, назначение данных сигналов объясняется необходимостью выполнять программирование ПЗУ. В действительности при неактивном сигнале ОЕ выходы данных становятся входами и позволяют провести программирование устройства, т. е. запись значений в отдельные ячейки. Такое программирование может выполняться однократно или с помощью специального оборудования и требует достаточно большого времени, поэтому ПЗУ, как правило, считаются устройствами «только для чтения». Существуют разновидности ПЗУ с электрическим стиранием и флеш-ПЗУ, которые допускают перепрограммирование, будучи установленными на печатную плату. Сигнал R/W (чтение/запись) служит для выбора направления передачи данных. В примере показано, что высокий логический уровень соответствует режиму чтения, а низкий — режиму записи. Таким образом, для чтения данных из ПЗУ требуется активировать сигналы CS и ОЕ, установить сигнал R/W в состояние «чтение» и подать на входы адреса нужную комбинацию логических уровней, соответствующую номеру ячейки. Через некоторое время ?, называемое временем доступа, на выходах данных появятся соответствующие значения. Временные диаграммы работы ПЗУ показаны на рис. 1.14. На временных диаграммах показан порядок появления сигнала на выходах данных. Основной характеристикой ПЗУ в этом смысле является время доступа, т. е. интервал времени, обозначенный на рис. 1.14 как t, который и определяет, через какое время после смены адреса на выходах появятся соответствующие данные.
Начальные сведения об архитектуре ПЛИС ХШпх 21 А0-А15 CS ОЕ R/W D0-D15 i — / п / 1 \ 1 Рис. 1.14. Временные диаграммы постоянного запоминающего устройства Рис. 1.15. Временные диаграммы оперативного запоминающего устройства при записи данных Из описания работы ПЗУ следует, что в принципе данные устройства допускают запись данных. Однако либо эта операция требует специального оборудования, либо ее проведение способно исчерпать физический ресурс микросхемы по перезаписи значений (некоторые разновидности ПЗУ допускают только однократное необратимое программирование). Поэтому для многократной перезаписи используют ОЗУ, в основе которых может лежать, например, таблица регистров. ОЗУ такого типа, называемые статическими, после записи значения в ячейку способны сколь угодно долго хранить это значение. Единственным требованием является наличие напряжения питания. Графическое изображение статического ОЗУ аналогично показанному на рис. 1.16 изображению ПЗУ, поскольку для записи нового значения требуется тот же набор сигналов: CS, ОЕ, W/R. Соответственно, аналогичны и временные диаграммы чтения. Временные диаграммы записи данных в статическое ОЗУ показаны на рис. 1.15. На временной диаграмме показаны несколько новых интервалов. Непосредственно запись происходит по фронту сигнала R/W. При этом необходимо, чтобы интервалы времени, показанные на диаграмме, были не меньше некоторых значений, задаваемых в технической документации на устройство. Например, twr задает минимальную длительность сигнала записи («строба записи»), ?addr ~~ время от установления адреса до момента прихода фронта R/W. Данные для записи также должны быть выставлены на вход за время не менее чем tsetup («время установления»), и удерживаться после фронта R/W в течение «времени удержания» ?hoid- Часто время удержания данных допускается делать равным нулю, т. е. снимать данные для записи одновременно с подачей фронта сигнала R/W, что облегчает построение систем обработки информации.
22 Глава 1 Приведенные временные диаграммы не являются единственным вариантом. Например, в ряде ОЗУ допускается запись по фронту сигнала ОЕ (OE-controlled запись). Также список требуемых временных интервалов не ограничивается показанными на рис. 1.15. Тем не менее приведенные сведения достаточны для получения первого представления об общих принципах использования ОЗУ. Оба представленных типа памяти не содержали в числе сигналов тактового входа, т. е. обеспечивали асинхронный интерфейс. В ряде случаев эффективнее оказываются устройства с синхронным интерфейсом, т. е. имеющие тактовый вход CLK. Такое решение Рис. 1.16. Графичес- обеспечивает более высокую скорость обмена кое изображение блока и часто используется для статического ОЗУ. синхронной памяти Представленная на рис. 1.16 память имеет следующие сигналы: • CLK — тактовый сигнал, по фронту которого происходят все изменения состояния памяти; • DI (Data Input) — вход данных для записи; • ADDR — вход адреса; • WB (Write Enable) — сигнал разрешения записи. Вели в момент фронта сигнала CLK на WE присутствует активный уровень (в данном случае — логическая «1»), происходит запись д&нных, присутствующих в этот момент на входе DI, в ячейку памяти с адресом, присутствующим на ADDR; • EN — вход разрешения работы. Неактивный уровень сигнала на этом входе запрещает изменение выходов блока памяти или запись новых данных; • DO (Data Output) — выход данных. Как видно из временной диаграммы, показанной на рис. 1.17, данные на выходе (линии DO) появляются с некоторой задержкой относительно фронта тактового сигнала. При чтении (WE неактивный) на выходах появляется содержимое ячейки, адрес которой присутствовал на адресных линиях непосредственно перед приходом фронта тактового сигнала. При записи на выходы передается предыдущее значение ячейки, в которую происходила запись. Особенностью блочной памяти ПЛИС является возможность настройки того, какое именно значение будет появляться на выходах при записи. На приведенной выше диаграмме показана работа в режиме «чтение перед записью» (Read before Write). Альтернативными режимами являются «чтение после записи» (Read after Write), при
Начальные сведения об архитектуре ПЛИС ХШпх 23 CLK WE DI ADDR DO EN A 0000 / DISABLE xxxx xvi S \ X I x : VlEM(aa) READ i —\ 1111 bb. Л— / X X iMEI WRITE \ 2222 X cc. X ] AftbPboM MEN WRITE /—v_ xxxx dd 1 t(cc)>>MEMrdd READ MEM(bb)=llll MEM(cc)=2222 Рис. 1.17. Временные диаграммы работы синхронной памяти котором на выходах будет скопировано входное значение, и «нет чтения при записи» (no Read on Write), при котором состояние выходов не изменится. 1.2. Архитектуры ПЛИС SPLD и CPLD На протяжении развития цифровой электроники разработчики испытывали все больший интерес к инструментам быстрого создания схем. Когда схемы состояли из небольшого числа логических элементов, их можно было собрать на макетной плате с небольшими усилиями. Однако по мере увеличения сложности устройств размеры таких макетных плат пришлось бы постоянно увеличивать, а постоянное изготовление новых вариантов печатной платы с десятками и даже сотнями микросхем занимает много времени и заставляет тратить ресурсы. Тем не менее разработчикам необходимо экспериментировать с разными вариантами схем. Ответом на возрастающую сложность цифровых устройств стало появление языков описания аппаратуры (HDL, Hardware Description Language), таких, как VHDL и Verilog HDL (чаще он упоминается как Verilog). Однако основной причиной создания таких языков была необходимость моделирования цифровых схем, т. е. проверки поведения при подаче входных сигналов. Для быстрого создания и изменения простых схем в 1970-х годах были разработаны несколько вариантов «простых программируемых логических устройств» — SPLD (Simple Programmable Logic Devices). В таких микросхемах общая структура логических элементов была фиксирована, а часть соединений могли программироваться. В зависимости от внутренней структуры микросхемы SPLD подразделялись на несколько классов.
24 Глава 1 Входы Например, архитектура PLA (Programmable Logic Array), показанная на рис. 1.18, подразумевала программируемую матрицу соединений, подключаемую к вентилям И, выходы которых через другую программируемую матрицу подключались к вентилям ИЛИ, которые, в свою очередь, подключа- Выходы лись непосредственно к выходам Рис. 1.18. Общий вид ПЛИС с ар- микросхемы. Среди производите- хитектурой PLA ле# PLA можно указать компании Texas Instruments и Signetics. Интерес к микросхемам, представляющим собой наборы вентилей И и ИЛИ, объясняется тем, что в логике существуют понятия конъюнктивной нормальной формы (КНФ) и дизъюнктивной нормальной формы (ДНФ) для логических выражений. Понятие «конъюнкция» соответствует логической операции И (также обозначается символом Л), а «дизъюнкция» — операции ИЛИ (символ V). Так, дизъюнктивной нормальной формой называют логическую формулу, которая представляет собой дизъюнкцию элементарных конъюнкций, т. е. выражение вида Y = (A$zBk,C) Л (~ А& ~ ВкС). В виде ДНФ можно достаточно просто представить любое выражение, описанное таблицей истинности. Рассмотрим, каким образом можно составить ДНФ для приведенного примера (табл. 1.7). В приведенной таблице представляют интерес строки, для которых выходной сигнал равен 1. Можно сказать, что выход равен единице в случае, когда комбинация входных сигналов равна 011 или равна 101. Союз «или» в данном случае напрямую указывает на то, что выявление любой из упомянутых комбинаций должно приводить к появлению логической 1 на выходе такой схемы. Поэтому реализовать схему, состоящую из нескольких вентилей И, объединенных вентилем ИЛИ, оказывается достаточно просто. Промежуточным выражением для первой из строк, содержащих единицу на выходе, является А — 0, В — 1, С = 1. Его можно Таблица 1.7 Пример таблицы истинности для демонстрации построения ДНФ А 0 0 0 0 1 1 1 1 В 0 0 1 1 0 0 1 1 с 0 1 0 1 0 1 0 1 Q (выход) 0 0 0 1 0 1 0 0
Начальные сведения об архитектуре ПЛИС ХШпх 25 AND2 Входы INV Рис. 1.19. Пример реализации схемы, описанной в дизъюнктивной нормальной форме также представить как ~А = 1,В = 1,С = 1 (здесь символ ~ является признаком инверсии). Для второй строки аналогичным выражением будет А = 1, В — О, С = 1, или А — 1, ~Б = 1, С = 1. Оба этих выражения могут быть представлены как трехвходовый элемент И, причем один из входов (А для первого и В для второго случая) должны быть проинвентированы. Появление логической 1 на выходе любого из элементов ЗИ должно приводить к появлению 1 на выходе всей схемы. Эта функция с очевидностью реализуется элементом 2ИЛИ. Итоговая схема представлена на рис. 1.19. Общий вид ПЛИС с архитектурой PLA показан на рис. 1.18. Можно \ видеть, что входы такой микросхемы . через коммутационную матрицу подключаются к входным вентилям И, " а их выходы через еще одну матри- - цу соединений — к входам вентилей ИЛИ. Рис- 1-20. Архитектура PAL Другой разновидностью SPLD являются PAL (Programmable Array of Logic), архитектура которых показана на рис. 1.20. Рассматривая принцип построения схем согласно ДНФ, можно видеть, что выходы вентилей И практически безальтернативно подключаются к входам вентилей ИЛИ. Это означает, что вторая коммутационная матрица, показанная в PLA, в целом может быть заменена на фиксированную схему, реализующую некоторый общеупотребительный набор соединений. Архитектура GAL (Generic Array Logic) дополняет показанные выше варианты схем синхронными компонентами. Если на выходе PAL поставить триггер, можно получить тактируемую схему, позволяющую строить как асинхронные, так и синхронные узлы. Как правило, коммутация в микросхемах SPLD выполнялась с помощью пережигаемых перемычек (т. е. такие микросхемы были однократно Выходы
26 Глава 1 программируемыми), позже использовались многократно программируемые коммутационные узлы. От «простых программируемых микросхем» полупроводниковая индустрия перешла к «комплексным» (или «сложным») программируемым логическим устройствам — CPLD (Complex Programmable Logic Devices). Идеей CPLD является реализация нескольких узлов, подобных GAL, на одном кристалле, добавляя к ним возможности передачи сигналов между узлами. Современные микросхемы CPLD имеют программируемые узлы на основе флеш-памяти, т. е. являются многократно программируемыми, и содержат блоки из 18 или 16 триггеров вместе с соответствующей матрицей вентилей И-ИЛИ. Такие ПЛИС обладают предсказуемыми задержками распространения сигнала (входные сигналы проходят через несложную схему вентилей и коммутационных узлов), практически не требуют внешних компонентов и удобны для работы в качестве «glue logic», т. е. микросхем, выполняющих в устройстве сопряжение более сложных устройств и заменяющих на печатной плате множество более простых микросхем, состоящих из нескольких вентилей. Недостатком архитектуры CPLD является сложность построения более емких микросхем. Существующие в настоящее время CPLD состоят из десятков-сотен триггеров и практически не получают преимуществ от перехода к новым технологическим процессам. Микросхемы с архитектурой CPLD в настоящее время все еще выпускаются компанией Xilinx. Это серия CoolRunner-II, которая будет рассмотрена далее. 1.3. Архитектура ПЛИС FPGA Программируемые микросхемы с архитектурой FPGA (Field Programmable Gate Array — программируемые пользователем вентильные матрицы) имеют в основе набор конфигурируемых блоков (логических ячеек), содержащих базовые компоненты цифровой логики — логические элементы и триггеры. Отдельные ячейки соединяются друг с другом с помощью программируемых трассировочных линий, как показано на рис. 1.21. Идеей, реализованной в FPGA, является прямое задание логических функций в виде таблицы истинности (LUT, Look-Up Table). Вместо коммутации вентилей ИЛИ и И таблица истинности представляет собой просто блок памяти, на адресные входы которого подаются входные логические сигналы. Их комбинация естественным образом выбирает одну из ячеек таблицы, в которой хранится требуемое состояние ячейки — О или 1. Таким образом, LUT в FPGA может реализовать «любую логическую функцию, если число ее входов не превышает число входов
Начальные сведения об архитектуре ПЛИС ХШпх 27 БВВ БВВ JdJdJd БВВ БВВ БВВ БВВ с с с КЛБ КЛБ КЛБ КЛБ с с t Q Я КЛБ КЛБ КЛБ КЛБ БВВ 1бвв КЛБ КЛБ КЛБ КЛБ БВВ |БВВ БВВ КЛБ КЛБ КЛБ КЛБ БВВ БВВ БВВ БВВ БВВ Рис. 1.21. Программируемые ресурсы ПЛИС FPGA LUT. Долго время LUT в FPGA имели 4 входа, т. е. содержали 16 однобитовых ячеек памяти. Комбинация «4-входовый логический генератор и триггер» получила название «эквивалентная логическая ячейка» (equivalent logic cell) и часто используется для определения сложности схемы, хотя современные FPGA используют уже б-входовые LUT. Несколько логических ячеек объединяются в конфигурируемые логические блоки (КЛБ, Configurable Logic Block, CLB). Между блоками КЛБ, размещенными на кристалле в виде прямоугольной матрицы, проложены программируемые трассировочные линии, а по периметру микросхемы располагаются программируемые блоки ввода- вывода (БВВ). Упрощенная структура FPGA показана на рис. 1.21. Соединение КЛБ трассировочными линиями также может регулироваться. На пересечении вертикальных и горизонтальных линий расположены программируемые трассировочные матрицы (Programmable Routing Matrix), которые так же, как LUT, управляются конфигурационной памятью FPGA. В современных FPGA присутствует достаточное число трассировочных линий разных типов (от локальных, соединяющих соседние КЛБ, до глобальных, пересекающих весь кристалл или его крупный регион). Как правило, числа трассировочных линий достаточно для выполнения всех соединений проекта, однако при высокой степени использования КЛБ и слишком сложных соединениях число трассировочных линий мо-
28 Глава 1 -D -п Рис. 1.22. Фрагмент ПЛИС с архитектурой FPGA жет оказаться и недостаточным. Поэтому от PPGA не стоит ожидать 100 %-го использования программируемых ячеек. Таким образом, реализацию цифровой схемы в PPGA можно проиллюстрировать рис. 1.22. В логические ячейки в КЛБ заносятся требуемые таблицы истинности, при необходимости подключаются триггеры логических ячеек. Соединения с другими ячейками выполняются с помощью замыкания соответствующих коммутационных транзисторов в трассировочных линиях. На рис. 1.22 видно, что две ячейки из всего массива оказались запрограммированы на реализацию определенной логической функции. Поскольку для реализации схемы одной ячейки оказалось недостаточно, ее выход был подключен к входу другой ячейки, для чего задействованы трассировочные линии PPGA. Чтобы реализовать такую схему, необходимо задать режимы работы отдельных компонентов внутри ячеек, а также активировать цифровые ключи, соединяющие отдельные сегменты трассировочных линий. Настройки компонентов и информация о включенных/выключенных коммутаторах хранится в специальной памяти внутри FPGA. Поскольку эта память выполнена по технологии SRAM, она имеет неограниченное число циклов перезаписи, однако теряет информацию при пропадании питания. Поэтому интерфейс программирования и внешняя энергонезависимая микросхема являются обязательными для работы с FPGA. На практике программирование ячеек и формирование трассировочных линий выполняется автоматически с помощью системы автоматизированного проектирования. Структура файла конфигурации является строго конфиденциальной информацией, и формирование такого файла может быть выполнены только с помощью САПР XiUnx. Можно видеть основные особенности подхода, реализованного в FPGA. Во-первых, эти ПЛИС подразумевают гранулярность схемы. Это означает, что сложные схемы с неравномерным использованием компонентов все равно необходимо будет приводить к базовым возможностям логических ячеек, причем весьма вероятно, что какие-то возможности ячеек окажутся незадействованными.
Начальные сведения об архитектуре ПЛИС ХШпх 29 Во-вторых, программируемые трассировочные линии имеют большую задержку распространения сигнала по сравнению с металлическими соединениями интегральных микросхем. Поэтому рабочие частоты ПЛИС оказываются меньше, чем частоты микросхем, выполняемых обычным способом. Таким образом, проекты на базе ПЛИС оказываются дороже и медленнее решений на базе стандартных (Standard Product) или специализированных микросхем (ASIC, ASSP — Application-Specific Integrated Circuit, Application-Specific Standard Product). Тем не менее на протяжении развития цифровой микроэлектроники производство ПЛИС демонстрировало устойчивый рост. Это связано с тем, что стоимость подготовки производства интегральных схем постоянно растет и, например, для технологического процесса с нормой 32 нм достигала 200 млн долл. США (по данным 2012 г.). Поэтому разработка специализированной микросхемы оказывается экономически целесообразной только для массового производства. Поэтому ПЛИС являются подходящей элементной базой для разработки цифровых устройств с уникальной архитектурой, выпускаемых небольшими тиражами. Другими преимуществами ПЛИС являются возможность реализации параллельных вычислительных структур и достижение высокой степени интеграции компонентов системы. Эти свойства проистекают из возможности реализовать в ПЛИС множество небольших блоков, реализующих простые операции. ПЛИС с архитектурой FPGA традиционно используются в задачах цифровой обработки сигналов, поскольку обеспечивают очень высокие показатели производительности (до 5,8 триллионов операций «умножение с накоплением» в секунду). Другим крупным сегментом применения FPGA являются коммуникационные устройства, прежде всего магистральное оборудование проводной связи. Компания ХШпх с 1985 г. выпускает ПЛИС, представляющих основные архитектуры, имеющиеся в микроэлектронике — CPLD и FPGA. На протяжении развития микроэлектронной технологии микросхемы с архитектурой FPGA развивались все более активно, так как возможности их масштабирования позволяют создавать кристаллы с сотнями тысяч и миллионами логических ячеек. В настоящее время именно FPGA являются наиболее универсальными и мощными программируемыми микросхемами, позволяющими реализовать широкий спектр цифровых устройств. Микросхемы CPLD в основном используются в качестве замены дискретных цифровых компонентов.
30 Глава 1 Xilinx, как и большинство производителей ПЛИС, является fab- less-компанией, т. е. не имеет собственного производства, а заказывает изготовление микросхем по разработанным проектам сторонним компаниям (в настоящее время это один из лидеров полупроводниковой отрасли компания TSMC). Соответственно, по мере освоения новых технологических процессов мировыми производителями Xilinx имеет возможность выпустить новое поколение ПЛИС с использованием освоенного технологического процесса. Это и наблюдалось на протяжении существования компании. В конце 90-х годов основной линейкой PPGA среди продукции Xilinx была серия ХС4000 (семейства ХС4000Е, XC4000XL и XC4000XLA). Архитектура ХС4000 оказалась довольно удачной, но оказалось, что в целом ряде проектов возможности стандартной логической ячейки ПЛИС используются далеко не полностью. Возникла естественная альтернатива — использовать дорогие устройства с максимальной производительностью и полным набором функциональных возможностей или, напротив, дешевые ПЛИС, обеспечивающие базовые функции, требующиеся для большинства типовых проектов. В результате в номенклатуре изделий Xilinx появились различные серии FPGA, отвечающие упомянутым альтернативам. Стандартное недорогое решение представляла серия Spartan, на смену которой пришли серии Artix (минимальная стоимость) и Kintex (умеренная стоимость при высокой производительности в задачах цифровой обработки сигналов), тогда как наилучшие технические характеристики достигаются в серии Virtex. На данный момент активными являются семейства серии 7 —¦ Artix-7, Spartan-7, Kintex-7, Virtex-7. Микросхемы UltraScale и UltraScale-f относятся к верхнему ценовому диапазону и предназначены для построения сложных систем с максимальной степенью интеграции компонентов на кристалле. Можно также отметить, что логические ячейки серии Kintex ничем не отличаются от ячеек более дорогой серии Virtex. Архитектура ранних семейств (например, ХС4000) представляла собой прямоугольную матрицу однотипных логических ячеек, окруженных блоками ввода-вывода. Такая архитектура выглядит однородно и в целом удобна для реализации самых разных цифровых схем. Однако с учетом сниженной тактовой частоты программируемой схемы и необходимостью тратить существенную часть площади кристалла на коммутационные линии и неиспользуемые ресурсы ячеек, выяснилось, что целый ряд широко используемых компонентов реализуется в FPGA крайне неэффективно.
Начальные сведения об архитектуре ПЛИС Xilinx 31 ! ARM f If риф. N4 I Ячейки BRAM, DSP MGT XC4000 Virtex, Spartan Zynq Рис. 1.23. Эволюция системной архитектуры ПЛИС FPGA Поэтому в начале 2000-х годов FPGA Xilinx кроме собственно логических ячеек содержали уже аппаратные блоки. В первую очередь были добавлены: • блоки синхронной статической двухпортовой памяти (Block RAM, BRAM). В более современных семействах были добавлены также и более крупные блоки памяти UltraRAM; • умножители независимых целочисленных операндов, позже превратившиеся в «блоки цифровой обработки сигналов», реализующие операцию «умножение с накоплением», обозначаемые как XtremeDSP или DSP48; • высокоскоростные последовательные приемопередатчики (Mul- tiGigabit T^sceivers, MGT). В целом эволюцию системной архитектуры FPGA можно проследить на рис. 1.23. Можно видеть, что по мере развития архитектуры в ПЛИС FPGA последовательно добавлялись аппаратные компоненты, реализующие часто используемые фзгнкциональные возможности цифровых устройств. Блоки «умножение с накоплением»' обеспечивают высокую производительность вычислений в приложениях цифровой обработки сигналов, а приемопередатчики MGT — в коммуникационных применениях. Отдельным направлением ПЛИС, анонс которого состоялся в 2011 г., являются микросхемы класса All Programmable SoC (ППСНК, полностью программируемые системы на кристалле). Первыми из микросхем такого типа являются АР SoC семейства Zynq-7000. Они включают в себя процессорное ядро ARM и матрицу программируемых логических ячеек, аналогичных применяемым в Artix или Kintex. Zynq-7000 имеют также разновидность Zynq-7000S, отличающуюся одноядерной, а не дву- хядерной подсистемой ARM. Семейство UltraScale-h также включает микросхемы Zynq. Они обозначаются как Zynq UltraScale-h и также имеют несколько разновидностей.
32 Глава 1 Новым направлением архитектуры ПЛИС является анонсированная в 2018 г. Adaptive Compute Acceleration Platform (ACAP), или адаптивная платформа ускорения вычислений. В настоящее время она представлена серией Versal, первые образцы которой выпускаются по технологическому процессу с нормами 7 нм на производственных линиях компании TSMC. ПЛИС Versal объединяют матрицу программируемых ячеек, аппаратные процессоры ARM и сеть аппаратно реализованных 32-разрядных RISC-процессоров. Это позволяет использовать на одном кристалле три основные архитектуры вычислительных узлов — CPU, сеть аппаратных процессоров и матрицу программируемых ресурсов. В настоящее время сохраняют некоторую актуальность недорогие ПЛИС Spartan-б, однако основной интерес представляет серия 7, представленная наибольшим числом разновидностей семейств. С учетом взаимодействия Xilinx с контрактными производителями микросхем (в первую очередь TSMC), по мере освоения промышленностью новых технологических процессов регулярно появлялись соответствующие ПЛИС. Диаграмма соответствия поколений ПЛЛИС Xilinx технологическим процессам представлена на рис. 1.24. &О> 28 нм ^Y> 20 нм ^У> 16 нм \ 40/45] // FPGA Versal 28 нм >> 20 нм >> 16 нм » 7нм ППСНК и АСАР Рис. 1.24. Диаграмма соответствия поколений ПЛИС Xilinx технологическим процессам
Начальные сведения об архитектуре ПЛИС ХШпх 33 1.4. Аппаратный состав и области применения ПЛИС FPGA Итак, кроме собственно логических ячеек и блоков ввода-вывода современные FPGA содержат большое число аппаратных блоков, реализующих часто используемые в цифровой схемотехнике функции. Смысл размещения на кристалле таких блоков состоит в том, что те же узлы, выполняемые с помощью логических ячеек, будут иметь существенно больший размер и пониженное быстродействие. В то же время аппаратная реализация часто используемых блоков несущественно увеличивает площадь кристалла и стоимость, зато весьма благоприятно влияет на характеристики проекта в целом. К аппаратным блокам, размещаемым в FPGA, относятся: • блоки синхронной статической двухпортовой памяти В RAM; • блоки цифровой обработки сигналов «умножение с накоплением» XtremeDSP; • формирователи тактовых сигналов ММСМ (Multi-Mode Clock Managers) и PLL (Phase-Locked Loop); • скоростные последовательные приемопередатчики (MGT, Multi-Gigabit Transceivers); • контроллеры PCI Express endpoint и root (т. е. ведомые устройства и корневые концентраторы); • процессорные ядра ARM (Zynq-7000, Zynq-7000S, Zynq-US+). На рис. 1.25 показано изоб- „ ^_ т-,,-^ * ~ — Логические ячейки ражение PPGA семейства Spar- - Блоки памяти tan-б. Видно, что кроме логи- Блоки DSP ческих ячеек современные FPGA — Формирователи содержат большое число специа- тактового сигнала лизированных модулей, облегча- л „ „ „лл д „ _ * ™ Рис. 1.25. FPGA семейства Spartan-6 ющих реализацию широко распространенных задач цифровой схемотехники. Семейство Spartan-б выполнено с соблюдением норм 45-нм технологического процесса. В состав семейства входят несколько микросхем в диапазоне логической емкости от 4 до 150 тысяч эквивалентных логических ячеек. Семейство выпускается компанией Xi- linx с 2008 г. и было заменено семейством Artix-7 с переходом на технологический процесс с нормами 28 нм. Однако с учетом комплекса технических характеристик Spartan-б до сих пор представляет интерес, в первую очередь в связи с наличием корпусов TQFP144 с шагом выводов 0,5 мм, которые допускают монтаж без специального оборудования, в том числе в условиях исследовательской, вузовской
34 Глава 1 Таблица 1.8 Характеристики микросхем семейства Spartan-6, доступных в корпусах типа TQFP144 Элемент Секции Эквивалентные логические ячейки Триггеры Блоки памяти A8 кбит) Блоки DSP48A1 Пользовательские выводы в корпусе TQ144 LX4 600 3840 4800 12 8 LX9 1430 9152 11440 32 16 102 Рис. 1.26. FPGA в корпусе TQFP144 или даже домашней лаборатории (рис. 1.26). В настоящее время Xi- linx предполагает продление сроков выпуска семейства Spartan-б по крайней мере до 2020 г. В табл. 1.8 приведены характеристики микросхем Spartan-б LX4 и LX9. Это наименьшие по логическому объему ПЛИС PPGA и единственные, выпускаемые в корпусе типа QPP — пластиковом корпусе с планарным расположением выводов. В среде разработчиков, недостаточно глубоко знакомых с ПЛИС, существует ряд поверхностных мнений о возможностях и перспективах использования ПЛИС в реальных проектах. Конечно, существование таких мнений отражает тот факт, что обладать исчерпывающими знаниями по всем без исключения направлениям элементной базы попросту невозможно. Кроме того, в развитии различных направлений микроэлектроники имеется своя динамика и те решения, которые по каким-либо причинам были объективно неоптимальны, при появлении новых поколений микросхем могут стать приемлемыми вследствие снижения цены, увеличения производительности, появления новых функциональных возможностей и т. п. Ввиду этого оценки применимости и эффективности ПЛИС, как и другой элементной базы, необходимо периодически пересматривать. Мнение 1. «ПЛИС — чрезмерно дорогие устройства для несложные изделий». В этой связи могут упоминаться совершенно не соответствующие действительности минимальные цены. Как правило, речь идет о сотнях и тысячах долл. США, что справедливо для PPGA верхнего ценового диапазона. Однако в данной главе речь идет о микросхемах, розничные цены на которые находятся в пределах 9-12 долл. Даже эта цена превышает цены на микроконтроллеры начального и среднего уровня. Однако необходимо сразу сделать поправку на то, что стоимость компонентов (не говоря уже о стоимости разработки в целом) определяется стоимостью «главной» микросхемы не
Начальные сведения об архитектуре ПЛИС ХШпх 35 в полной мере. Если сравнивать аналогичные платы, основанные на МК с ценой в 1 долл. и ПЛИС с ценой в 10 долл., совокупная стоимость компонентов не будет различаться в 10 раз. Интерфейсные микросхемы, разъемы, подсистемы питания также внесут свой вклад в общую стоимость элементной базы, и их цена практически не изменится при переходе с МК к ПЛИС. Кроме того, в ряде случаев малая стоимость МК, особенно сформированная по принципу «стоимость МК этой серии — от N$», при развитии проекта является некоей ловушкой. Например, микросхема минимальной стоимости может быть непригодна для проекта, поскольку требуемый набор периферийных устройств не может быть одновременно задействован в корпусе минимального размера. Переход же к корпусу с большим числом выводов повлечет за собой и «продвижение» по линейке МК. С организационной точки зрения снижение цены при серийном выпуске изделий может быть получено при ранней регистрации проекта у официального дистрибьютора. Практика регистрации проектов поддерживается многими производителям элементной базы, поскольку это существенно облегчает для них планирование производства на будущие периоды. ХШпх, работающая по принципу fabless, т. е. не имеющая собственных фабрик, в довольно большой степени зависит от точности своих прогнозов по востребованности элементной базы тех или иных разновидностей, поэтому раннее уведомление о намерении рассмотреть ПЛИС ХШпх в проекте вознаграждается специальными скидками. Можно подчеркнуть, что такое уведомление не означает обязательство покупки определенного числа микросхем и даже не означает, что разработчик уже уверен в использовании ПЛИС ХШпх, а не ПЛИС других производителей или даже микроконтроллера. Однако впоследствии при ссылке на данную регистрацию покупателю предоставляется ранее оговоренная фиксированная цена. В данном случае речь идет только о покупке у официального дистрибьютора, работающего в рамках ценовой политики ХШпх, например www.plis.ru. Мнение 2. «ПЛИС — чрезмерно медленные устройства с большим энергопотреблением». Конечно, программируемые соединения внутри FPGA обусловливают более высокие значения задержек распространения сигналов по сравнению с металлическими соединениями, а универсальные ячейки потребляют больше мощности по сравнению со специализированными ресурсами. Однако на практике единственной нишей,
36 Г лав а 1 где FPGA не подходят в качестве аппаратной платформы, являются микропотребляющие устройства с аккумуляторным питанием. Говоря о скорости и потреблении, можно сразу указать на то, что характеристики и сферы применения FPGA все больше ориентируются на аппаратные ядра в этих микросхемах. Для Spartan-6/7 это блочная память и секции DSP. Они способны работать на высокой тактовой частоте B75...325 МГц в зависимости от класса скорости ПЛИС) и потребляют не больше энергии, чем аналогичные устройства в МК (что естественно, поскольку память и DSP представляют собой непрограммируемые модули). Поэтому говорить о снижении скорости и повышении потребляемой мощности можно в основном для той части проекта, которая выполнена на базе логических ячеек. Важным преимуществом ПЛИС, нивелирующим недостатки программируемых ресурсов, является возможность организовать специализированные вычислительные блоки, построенные на базе секций DSP. Такие блоки могут работать полностью параллельно и обеспечивать суммарную производительность, превосходящую производительность не только МК, но и сигнальных процессоров. Например, 16 секций DSP, работающие на частоте 200 МГц (это вполне достижимо для многих модулей ЦОС), дают суммарную производительность, эквивалентную гипотетическому процессору с тактовой частотой 3,2 ГГц. Потребление типичных проектов на базе ПЛИС Spartan-6 LX4/ LX9 обычно составляет несколько сотен мА. Это действительно больше, чем у многих МК, но не требует специального внимания к подсистеме питания, и даже применения пассивного (радиаторного) охлаждения. Исключением могут стать проекты с большим числом интенсивно переключающихся триггеров, однако во избежание появления таких эффектов на поздних стадиях проекта можно воспользоваться утилитой Xpower, входящей в состав САПР. Она достаточно точно оценивает потребляемую мощность, основываясь на числе используемых в проекте ресурсов и заданной тактовой частоте. Мнение 3. «Разработка устройств на базе ПЛИС очень сложна и требует дорогостоящих средств разработки». Xilinx бесплатно предоставляет лицензию на САПР с ограничением по объему ПЛИС. Однако планка ограничения установлена на емкости, в десятки раз превышающем емкость ПЛИС, практически применимых в проектах начального уровня. Объем самрго проекта (число строк, IP-ядер, файлов и т. п.) не ограничен ничем. Бесплат-
Начальные сведения об архитектуре ПЛИС ХШпх 37 Таблица 1.9 Сравнительные характеристики семейств ПЛИС, предназначенных для разработки систем начального уровня Характеристика Логические ячейки, тыс. Блочная память, Мбит Секции DSP Приемопередатчики Максимальная скорость приемопередатчиков, Гбит/с Число программируемых внешних выводов, максимум Spartan-6 4-150 0,2-4,8 8-180 0-8 3,2 576 Spartan-7 6-100 0,18-4,3 10-160 — — 400 Artix-7 12-215 0,72-13,1 40-740 2-16 6,6 500 Zynq-7000 23-85 1,8-4,9 60-220 СЫ6 6,6 328 ная версия САПР в действительности не существует как отдельный продукт — это та же версия САПР ISE, для которой генерируется лицензионный файл специального типа, устанавливающий ограничения по типам доступных для проекта микросхем. САПР можно загрузить с официального сайта ХШпх www.xilinx.com. Относительно справедливо мнение о том, что ПЛИС обладает существенно меньшим разнообразием накристалльных периферийных устройств. Такие компоненты, как флеш-память или BBPROM, АЦП, ЦАП, USB, должны быть реализованы во внешних микросхемах. В табл. 1.9 показаны сравнительные характеристики семейств ПЛИС, предназначенных для разработки систем начального уровйя. В табл. 1.10 показаны сравнительные характеристики семейств ПЛИС Kintex. Это ПЛИС среднего-высокого уровня, оптимизированные по показателю производительность/цена для приложений цифровой обработки сигналов. В этом семействе размещается большое число аппаратных блоков DSP48, а тактовые частоты логических ячеек такие же, как в более дорогом семействе Virtex. В табл. 1.11 показаны сравнительные характеристики семейств ПЛИС Virtex. Это семейство предоставляет в пределах одного кристалла наибольшую для соответствующего поколения ПЛИС логическую емкость и большое число аппаратных приемопередатчиков. Это делает Virtex аппаратной платформой для предельных по характеристикам систем проводной передачи данных, а благодаря большой логической емкости ПЛИС Virtex удобны для прототипи- рования СБИС. Особенностью семейства Zynq является наличие в этих микросхемах аппаратной подсистемы на базе процессора ARM Cortex-A. Все ПЛИС имеют одну и ту же процессорную подсистему на основе двухядерного процессора ARM. Характеристики ядра ARM в соста-
38 Глава J Таблица 1.10 Сравнительные характеристики семейств высокопроизводительных ПЛИС Kintex Характеристика Логические ячейки, тыс. Блочная память, Мбит Память Ultra RAM, Мбит Секции DSP Приемопередатчики Максимальная скорость приемопередатчиков, Гбит/с Число программируемых внешних выводов, максимум Kintex-7 65-477 4,9-34,4 — 240-1920 8-32 12,5 500 Kintex UltraScale 318-1451 12,7-75,9 — 1152-5520 12-64 16,3 668 Kintex UltraScale Plus 356 —1143 12,7-34,6 0-36 1368-3528 0-76 32,75 668 Таблица 1.11 Сравнительные характеристики семейств высокопроизводительных ПЛИС Virtex Характеристика Логические ячейки, тыс. Блочная память, Мбит Память Ultra RAM, Мбит Секции DSP Приемопередатчики Максимальная скорость приемопередатчиков, Гбит/с Число программируемых внешних выводов, максимум Virtex-7 305-1954 27-67,7 — 1120-3600 28-96 13,1 1200 Virtex UltraScale 783-5541 44,3-132,9 — 600-2880 40-120 30,5 1456 Virtex Ultra- Scale Plus 862-3780 23,6-94,5 90-360 2280-12288 32-128 58 832 ве Zynq-7000 представлены ниже: • Ядро: сдвоенное Cortex-A9, тактовая частота 667/773/800/1000 МГц (в зависимости от градации скорости). • Расширения ядра: NEON™, плавающая точка одинарной и двойной точности. • Кэш первого уровня: 32 кб инструкций, 32 кб данных на каждое ядро. • Кэш второго уровня: 512 кб. • Поддержка внешней памяти: DDR2, DDR3, LPDDR2. • Каналы ПДП: 8. • Периферия: о USB 2.0 (OTG) с ПДП'2; о Трехрежимный A0/100/1000) Etnernet с ПДП — 2; о SD/SDIO с ПДП — 2; о UART — 2; о CAN 2.0B - 2; о 12С - 2; о SPI — 2; о GPIO — 32 бита. • Шифрование — AES и SHA 256 битов. • Мультиплексируемых линий памяти и ввода-вывода — 54.
Начальные сведения об архитектуре ПЛИС ХШпх 39 • Интерфейсы к программируемым ресурсам: о AXI 32 бита Master — 2; о AXI 32 бита Slave — 2; о AXI 64/32 бита, интерфейс с памятью — 4; о AXI 64 бита АСР; о Прерываний — 16. В семействе Zynq UltraScale-f, выполненном по нормам 16 нм, процессорная система существенно изменена. Многопроцессорная система в ZynqUS-f состоит из следующих компонентов: • 4-ядерный 64-битовый процессор общего назначения ARM Cortex А53; • 2-ядерный 32-битовый процессор для задач реального времени ARM Cortex R5; • графический процессор ARM Mali-400MP; • видеокодек Н.265, способный обрабатывать потоки PullHD F0 кадров в секунду) или 4К2К A5 кадров в секунду). Кроме того, семейство разделено на три платформы, ориентированные на задачи управления (Control), обработки видео (Vision) и работы с сетью (Network). Платформы различаются соотношением и самим набором основных ресурсов — так, например, у микросхем, ориентированных на работу с сетью, отсутствует видеокодек, однако имеются аппаратные ядра Interlaken и 100G Ethernet. Сравнительные характеристики ППСНК ХШпх, включая Zynq UltraSca- 1е+ и Zynq-7000, приведены в табл. 1.12. Семейство ПЛИС ХШпх Versal, упоминаемое в предварительных анонсах начала 2018 г. как Everest, представляет собой новый подкласс программируемых микросхем, обозначаемый как Adaptive Compute Acceleration Platform (ACAP), или адаптивная платформа ускорения вычислений. В новых ПЛИС совмещаются три основных класса высокопроизводительных вычислительных архитектур: • процессоры общего назначения в виде многоядерного ARM Cor- tex-A72 и двухядерного процессора реального времени ARM Cortex-R5; • матрица программируемых ресурсов: логических ячеек, блоков памяти и цифровой обработки сигналов (Adaptable Hardware); • матрица процессоров с векторными расширениями системы команд (AI engines). Важнейшим отличием микросхем Versal от предыдущих поколений ПЛИС ХШпх является наличие ядер, обозначенных как AI core. Каждое из ядер, организованных в матрицу, представляет собой полноценное, автономно работающее процессорное ядро, имеющее следующие свойства:
40 Глава 1 Таблица 1Л2 Сравнительные характеристики ППСНК Характеристика Логические ячейки, тыс. Секции DSP Блочная память Блоки UltraRAM Интерфейсы PCI Express Видеокодеки 150G Interlaken 100G Ethernet MAC Приемопередатчики MGT Блоки AMS (Analog Mixed Signal) Zynq UltraScale+ МПСнК Управление (Smarter Control) 155 728 7,7 Мбит 13,5 Мбит Gen4x8 Gen3xl6 1 — — 20 ® 16 Гб/с Видео (Smarter Vision) 405 1728 11,2 Мбит 27 Мбит Gen4x8 Gen3xl6 1 — — 28 ® 16 Гб/с Системный монитор - 1 МГц АЦП, Сеть (Smarter Network) 920 3528 35,4 Мбит 128 Мбит Gen4x8 Gen3xl6 — 4 4 76® 33 Гб/с - 10 битов, 17 дифференциальных входов Xilinx Zynq- 7000 На базе Artix (до 7020) 85 220 560 Кб — Gen2x4 — — — 4® 6,6 Гб/с XADC битов, 1 На базе Kintex G030 и выше) 444 2020 3020 Кб — Gen2x8 — — — 16® 12,5 Гб/с — 2x12 МГц АЦП, 17 дифференциальных ] входов • выделенные 16KB памяти программ и 32KB памяти данных; • 32-разрядное RISC-ядро скалярного процессора; • векторные расширения — 512-разрядная арифметика с фиксированной точкой и 512-разрядная арифметика с плавающей точкой с соответствующими наборами векторных регистров; • обработка синхронизации; • схема трассировки и отладки. В анонсе Xilinx указаны предварительные характеристики двух разновидностей АСАР Versal — AI core и Prime. Их сводные характеристики приведены в табл. 1.13. Семейства Kintex, Virtex и Versal представляют собой достаточно дорогие, хотя и высокопроизводительные микросхемы. Высокая цена является главным препятствием к их применению в широком спектре электронной аппаратуры, и возможности использования таких семейств обычно являются предметом отдельного обсуждения. Напротив, для ПЛИС начального уровня их применение в цифровых устройствах часто может быть оправдано как с технической, так и с экономической точек зрения. Кроме семейств Spartan, Artix и Zynq, в ряде случаев можно рассматривать и применение младших ПЛИС семейств Kintex и Zynq MPSOC. Можно указать некоторые области применения ПЛИС начального уровня.
Начальные сведения об архитектуре ПЛИС ХШпх 41 Сводные характеристики АСАР Versal Таблица 1.13 Характеристика Сводная производительность при операциях над 8- разрядными целыми числами, Топ/с Логические ячейки, тыс. Память, Мбит Ядра DSP Ядра AI Последовательные приемопередатчики (NRZ, PAM4) Максимальная пропускная способность последовательных приемопередатчиков, Тбит/с Программируемые выводы Контроллеры памяти AI core 49... 147 540-1968 68-191 928-1968 128-400 8-44 2,9 346-692 2-4 Prime 3...27 352-2154 40-324 472-3984 - 12-66 4,2 238-778 1-6 Примечание: оба семейства имеют процессорную подсистему и накристалль- ную сеть (Network On Chip) Преобразование интерфейсов выступает в качестве универсальной области применения, которая не требует высокой производительности ПЛИС. Основной характеристикой в данном случае выступает число внешних выводов и возможность ПЛИС реализовать требуемые периферийные контроллеры в большом числе. Нет технических ограничений на размещение в ПЛИС, например 20 контроллеров UART или 40 контроллеров ШИМ. Конечно, для такого примера было бы трудно подобрать практическую задачу, однако в целом можно говорить, что при больщом числе интерфейсных портов проще всего преобразовать их с помощью ПЛИС. Обработка датчиков является похожей задачей. При большом числе датчиков разных типов, подключаемых с помощью АЦП (с параллельным или последовательным интерфейсом), цифровых интерфейсов различных типов, а также, возможно, требующих настройки, общая структура системы может выглядеть достаточно сложной. В целом создание на базе ПЛИС «расширителей интерфейсов» выгладит достаточно просто, к тому же дает разработчику определенный «запас прочности» для его проекта, поскольку внезапные изменения требований к интенсивности обмена, порядку опроса датчиков и алгоритмам преобразования могут быть адекватно отражены в изменении схемы внутри ПЛИС. Системы управления представляют собой комбинацию подсистем обработки датчиков и управления исполнительными элементами. Например, в системе управления вращением электродвигателя могут присутствовать датчики скорости вращения, тока, температуры, возможно и другие датчики, обеспечивающие защиту и мониторинг параметров (например, релейные датчики механических огра-
42 Глава 1 ничителей). Для собственно управления требуется как минимум контроллер ШИМ для одноканального или мостового регулятора. Для реализации системы управления требуется не только организация основного цикла регулирования (измерение скорости вращения и управление ШИМ), но и обработка датчиков аварийных состояний в режиме реального времени. Если добавить и реализацию интерфейса пользователя (в виде GUI, проводного или беспроводного интерфейса), задача принимает довольно масштабные черты. Можно отметить, что с точки зрения безопасной работы системы управления, ПЛИС обладает важным преимуществом. Программист, работающий с микроконтроллером, вынужден постоянно следить за тем, чтобы во всех режимах работы его программы обеспечивалась своевременная реакция на срабатывание аварийных датчиков. В то же время длительный цикл обработки или ожидание внешнего устройства заставит МК приостановить программный опрос внешних датчиков, а если по каким-то причинам окажутся запрещены прерывания, то аварийное состояние будет полностью проигнорировано программой управления. В такой ситуации на базе ПЛИС можно реализовать простейшую аппаратную защиту, блокирующую силовые компоненты при наличии сигналов аварийного состояния. Такая защита (реализованная прбсто на уровне логических вентилей) полностью независима от процессора и способна обеспечить аппаратную реакцию на аварийные состояния. Системы безопасности и обработка изображений добавляют новый технический аспект, связанный с подключением и обработкой сигналов от видеокамер. В настоящее время увеличивающаяся производительность цифровых систем позволяет реализовать обработку видео в реальном времени. Соответственно, возникают и решаются задачи распознавания лиц (например, для системы контроля доступа в помещения), идентификации компонентов и контроля их качества при сборке в промышленности, определения препятствий при движении автомобиля и т. п. Анализ и работа в облачных системах соответствуют применению платформы Zynq. Ввиду того, что облачные вычисления и системы хранения данных представляют собой большие комплексы устройств, решаемые в них задачи достаточно разнообразны. Сочетание процессорной системы ARM и большого числа программируемых логических ячеек позволяет использовать ППСНК Zynq и для обмена высокоскоростными данными (с применением мультигигаби- товых приемопередатчиков), и для параллельной обработки пакетов
Начальные сведения об архитектуре ПЛИС Xilinx 43 данных, и для решения задач мониторинга аппаратных компонентов облачных систем. В основе совместного использования МК и ПЛИС лежит уже описанная выше ориентация этих устройств на решение различных задач. Основное преимущество ПЛИС заключается в возможности реализации параллельно работающих потоков обработки данных, необязательно программируемых. Однако если основной упор сделать на реконфигурируемость ПЛИС, полагая эту микросхему разновидностью ускорителя для МК, то окажется, что МК должен сформировать аргументы для ускорителя в ПЛИС и прочитать результаты. Основной поток данных все равно проходит через МК, и программист не может высвободить существенные ресурсы процессора. Более эффективный вариант совместной работы основан на реализации в ПЛИС основного объема операций по обработке данных. В этом случае ПЛИС выполняет все операции по обработке потока данных, а МК решает задачи управления, переключения режимов, мониторинга состояния, а также использует свои периферийный устройства для организации интерфейсов. В таком случае выполнение в МК длительной операции обмена данными или обработки пользовательского интерфейса не приведут к остановке основного потока вычислений. Наглядным примером такой системы является цифровой фильтр. С одной стороны, коэффициенты фильтра являются предметом исследования и меняются в процессе разработки. Поэтому фиксировать их в IP-ядре фильтра, реализованном в ПЛИС, не вполне удобно и разработчик может склоняться к программной реализации фильтра, которая дает большую свободу в настройке его параметров. Однако такой же эффект может быть получен, если процессор будет иметь доступ к настройкам фильтра в ПЛИС. Поэтому следует сохранять подход, при котором компоненты внутри ПЛИС работают непрерывно и независимо, реализуя основную функциональность разрабатываемого изделия, а микроконтроллер используется для управления, настройки и реализации пользовательского интерфейса. 1.5. Логические ячейки ПЛИС FPGA Логические ячейки являются основным программируемым ресурсом FPGA, определяющим ее архитектуру как таковую и наиболее универсальным с точки зрения функциональных возможностей. Схема логической ячейки FPGA показана на рис. 1.27. В современных семействах, включая Spartan-б, серию 7 и последующие,
44 Глава 1 Рис. 1.27. Упрощенная схема логической ячейки FPGA ячейка состоит из б-входовой таблицы истинности (LUT) и двух триггеров. Комбинационная логика реализуется в таких ячейках путем заполнения таблиц истинности, представляющих собой модули памяти. Комбинация состояний на входах для такого модуля является адресом ячейки, хранящей требуемое значение выхода. Такой подход позволяет реализовать произвольную логическую функцию, поскольку независимо от сложности схемы все возможные состояния выхода записываются в память. Эта память представляет собой ОЗУ, и ее содержимое записывается в процессе загрузки конфигурации FPGA. На протяжении развития PPGA архитектура логической ячейки претерпевала изменения, которые схематично можно проиллюстрировать рис. 1.29 для FPGA верхнего ценового диапазона (Virtex) и на рис. 1.30 для недорогих FPGA (Spartan). Можно виднть, что от 4-входовой LUT ячейки перешли к б-входовой и от одного триггера в ячейке к двум. Логический генератор (LUT, Look-Up Table — таблица истинности) представляет собой статическую память, инициализируемую Рис. 1.28. Принцип реализации комбинационной логики в ПЛИС FPGA А 0 0 0 0 0 0 1 1 1 1 В 0 0 0 0 1 1 1 1 1 1 с 0 0 1 1 0 0 0 0 1 1 D 0 1 0 1 0 1 0 1 0 1 Z 0 0 0 1 1 1 0 0 0 1 LUT4 М- LUT6 LUT6 IV Рис. 1.29. Изменения в архитектуре логической ячейки в различных поколениях FPGA Xilinx (Virtex-4, Virtex-5, Virtex-6/7)
Начальные сведения об архитектуре ПЛИС ХШпх 45 LUT4 ГИ |~ LUT6 [У| о О о о о °— LUT6 15 14 13 О 12 И 10 Рис. 1.30. Изменения в архитектуре логической ячейки в различных поколениях FPGA ХШпх (Spartan-3, Spartan-6) Рис. 1.31. Графическое изображение логического генератора в процессе загрузки конфигурации FPGA. Графическое изображение логического генератора представлено на рис. 1.31. Логический генератор (LUT) реализует любую функцию с не более чем б операндами. Кроме того, возможно использование LUT в режиме с частично совмещенными входами, когда память разбивается на два фрагмента по 32 бита, давая возможность сформировать две логические функции с не более чем 5 операндами каждая. При этом, поскольку в самой LUT всего б входов, часть входов должна быть обобщена (рис. 1.32). Такой режим автоматически используется САПР по мере возможности. Логические генераторы могут также использоваться в режимах распределенной памяти (distributed memory) и сдвиговых регистров. Поскольку логический генератор представляет собой элемент статической памяти, который хранит таблицу истинности в явном виде, его можно использовать по прямому назначению — в качестве обычного компонента памяти. 6-LUT А5 D А4 A3 5-LUT А2 А1 А5 D А4 A3 5-LUT А2 А1 Л \ Об —г> О5 о— О О О о о о о о °— RAM16X1D ™ SPO WCLK АО DPO А1 А2 A3 DPRA0 DPRA1 DPRA2 DPRA3 Рис. 1.32. LUT в режиме совместного использования входов Рис. 1.33. Графическое изображение элемента двухпортовой распределенной памяти
46 Глава 1 Распределенная память может работать в однопортовом или простом двухпортовом (simple dual-port) режимах. Простой двухпортовый режим имеет то ограничение, что только один порт может использоваться для чтения и записи, а второй предназначен только для чтения. Показанный на рис. 1.33 элемент распределенной памяти имеет следующие сигналы: • we — сигнал разрешения записи; • d — данные для записи; • wclk — вход тактового сигнала; • а — адрес для записи; • dpra — адрес для чтения, второй порт (dual port read address); • spo — выход первого порта (single port output); • dpo — выход второго порта (dual port output). Временные диаграммы работы распределенной памяти показа- цы на рис. 1.34. Из рисунка видно, что запись в память происходит синхронно (в момент времени 15 не, когда данные d = 1 записываются по адресу addr = ООИ2 = Зю), а чтение — асинхронно. В момент времени 23 не изменение адреса на входе dpra приводит к соответствующему изменению выхода dpo. Этот момент (без фронта тактового сигнала) был выбран специально, чтобы продемонстрировать, что память реагирует на изменение адреса асинхронно. Аналогично, изменение состояния входа а немедленно приводит к появлению на выходе spo значения из ячейки с адресом а. Распределенная память удобна для организации небольших блоков данных — буферов, линий задержки, небольших таблиц. Реализация больших блоков на распределенной памяти в общем случае нецелесообразна из-за сильной фрагментации такого блока. Для объемов в 512 слов и больше удобнее использовать блочную память. Тем не менее распределенная память обладает важным свойством, отсутствующим у блочной памяти, — она допускает асинхронное чтение. а dpra we d elk spo dpo 0 не : oooo ; —r~~ 10 не 1 1 1 1 1 1 1 1 1 ( 0011 0000 ,--¦;¦¦* • ¦ ¦ - i ~ " л—~ li 20 не X ООП f -1 _J s^T 30 не Рис. 1.34. Временные диаграммы работы распределенной памяти
Начальные сведения об архитектуре ПЛИС ХШпх 47 SPL16 D >CLK АО А1 А2 A3 Q elk din dout Рис. 1.35. Графическое изображение сдвигового регистра, реализованного на базе логического генератора О не 50 не 100 не ЛЛЛЛГ ЛПЛЯГ ЛЛЛ FDCPE Рис. 1.36. Временные диаграммы работы сдвигового регистра Другой вариант использования логического генератора — реализация на его базе сдвигового регистра. Графическое изображение такого компонента показано на рис. 1.35. Сдвиговый регистр имеет следующие сигналы: • d — данные для записи в сдвиговый регистр; • elk — тактовый сигнал; • а — адресный вход; • q — выход данных. В простейшем варианте сдвиговый регистр может представлять собой модуль, задерживающий входной сигнал din на N тактов. Временные диаграммы работы 8-разрядного сдвигового регистра показаны на рис. 1.36. LUT в режиме сдвигового регистра может использоваться совместно с триггером той же логической ячейки, увеличивая глубину сдвигового регистра на 1. Графическое изображение триггера (в одном из возможных вариантов) показано на рис. 1.37. Триггер имеет следующие сигналы: • С — вход тактового сигнала; • D — вход данных; • СЕ — вход разрешения записи (clock enable); • CLR — вход асинхронного сброса (clear); • PRE — вход асинхронной установки в логическую единицу (preset); • R — вход синхронного сброса (reset); • S — вход синхронной установки в логическую единицу (set); • Q — выход данных. Физически существует только один сигнал сброса/установки SR. Сброс, установка (синхронные или асинхронные) реализуются путем комбинирования триггера с другими ресурсами ячейки. Рис. 1.37. Графическое изображение триггера
48 Глава 1 Логические ячейки входят в состав секции (slice), которая объединяет 4 логические ячейки. Понятие секции введено потому, что кроме LUT и триггеров она имеет дополнительные компоненты. Дополнительные компоненты секции — это цепи ускоренного переноса и мультиплексоры. Цепи ускоренного переноса служат для построения сумматоров и вычитателей. Поскольку операции сложения и вычитания широко используются в цифровой схемотехнике, для них в ячейку были добавлены специальные компоненты, которые вычисляют сумму и передают бит переноса на следующий аналогичный компонент соседней секции. Синтезаторы автоматически поддерживают такие конструкции, поэтому выражения вида а + b будут реализованы с использованием цепей ускоренного переноса. Не следует пытаться описывать сумматоры с помощью эквивалентных логических выражений, поскольку в этом случае они будут реализованы в виде таблиц истинности в LUT, а не на базе специализированных цепей. Дополнительные мультиплексоры F7MUX объединяют выходы двух LUT. Эти блоки могут быть полезны в ряде случаев, уменьшая число LUT, требуемых для построения логического узла. Например, схема с 7 входами может быть реализована не на двух LUT, а на связке LUT -f P7MUX. Такие преобразования автоматически выполняются синтезатором и обычно не требуют специального внимания разработчика. Две секции образуют конфигурируемый логический блок (КЛБ, также CLB, Configurable Logic Block). Таким образом, КЛБ — это своеобразная «молекула» в FPGA, состоящая из «атомов»-ячеек (logic cells). Рассмотрение можно начать с семейства Spartan-б, поскольку именно в нем появилось заметное нововведение в виде трех разновидностей логической ячейки. Полезной особенностью FPGA Xilinx традиционно являлась возможность использования логического генератора в режимах распределенной памяти 16x1 или сдвигового регистра. Впоследствии число таких универсальных ячеек было сокращено, и появились секции SliceM и SliceL (символы М и L означают Memory и Logic соответственно, т. е. ряд ячеек мог реали- зовывать функцию памяти, а остальные — только логику). Вместе с тем оба типа секций располагались в рамках каждого КЛВ, т. е. секции, способные реализовать память и сдвиговые регистры, равномерно распределялись по всей матрице КЛВ. В Spartan-б появился третий тип — SliceX. Это менее мощная разновидность секции, поскольку в ней отсутствует цепь ускоренного переноса, т. е. такая секция не может служить для организации сложения или вычитания.
Начальные сведения об архитектуре ПЛИС ХШпх 49 В итоге в КЛБ Spartan-б оказываются следующие секции: • SliceM — универсальная секция с LUT, конфигурируемыми во всех режимах, а также линиями ускоренного переноса; • SliceL — LUT конфигурируется только как логический генератор, есть цепи ускоренного переноса; • SliceX — LUT конфигурируется только как логический генератор, нет цепей ускоренного переноса. Из двух: КЛБ один содержит пару секций SliceL-bSliceX, а другой — SliceM-b SliceX. Блоки соответственно называются CLB.LX и CLB_MX (рис. 1.38). Такое нововведение следует трактовать как формальное ухудшение функциональности. С другой стороны, можно указать и на позитивные факторы — упро- SliceL SliceM CLB LX CLB MX Рис. 1.38. Состав CLB семейства Spartan-6 щение ячеек, а следовательно, повышение производительности и уменьшение стоимости. В практических проектах можно рассчитывать на то, что цепи ускоренного переноса будут требоваться не в 100 % цифровых узлов, так что САПР будет иметь возможность поместить имеющиеся в проекте арифметические блоки в те секции, в которых имеются цепи ускоренного переноса. В серии 7 используется комбинация из одной секции SliceM и трех секций SliceL. Секции SliceX не используются, таким образом, все секции имеют цепи ускоренного переноса. Кроме мультиплексоров F7MUX, объединяющих выходы двух LUT, в секциях серии 7 есть мультиплексоры F8MUX, объединяющие выходы двух F7MUX. Некоторые варианты схем могут быть реализованы, таким образом, с использованием меньшего числа секций в ПЛИС серии 7 по сравнению с Spartan-6. В семействе UltraScale, следующем за серией 7, выходы мультиплексоров F8MUX объединяются мультиплексором F9MUX. Все мультиплексоры применяются синтезаторами автоматически, без явного участия разработчика. Структурная схема секции FPGA (показана серия 7) приведена на рис. 1.39. Можно выделить основные компоненты секции: • таблицы истинности D шт.); • триггеры (8 шт.); • мультиплексоры F7MUX и F8MUX; • цепь ускоренного переноса. Для эффективного использования ресурсов логических ячеек следует обращать внимание на возможность реализации сложения/
50 Глава 1 LUT LUT LUT LUT F8MUX Цепь ускоренного переноса Рис. 1.39. Структурная схема секции FPGA серии 7 вычитания с помощью цепей ускоренного переноса, а мультиплексоров — с применением дополнительных мультиплексоров секций. Эти функции не следует специально переносить в LUT, описывая в виде таблиц истинности. Вместо этого операции сложения/вычитания и мультиплексирование (например, с помощью конструкции switch яли case в VHDL) рекомендуется использовать в проектах, если это возможно. 1.6. Блоки ввода-вывода Блоки ввода-вйвода связывают PPGA с внешними устройствами. Они представляют собой двунаправленные цифровые выводы, которые могут программироваться как по направлению (вход, выход, выход с третьим состоянием, двунаправленный вывод), так и по типу электрического интерфейса (ТТЛ, КМОП, LVDS и т.д., всего более 40 типов интерфейсов, включая дифференциальные). Структурная схема блока ввода-вывода показана на рис. 1.40. Блоки могут попарно обтэединяться для реализации дифференциальных интерфейсов (например, LVDS). Необходимо учитывать, что выводы не могут образовывать пары в произвольном порядке — каждая пара строго фиксирована в корпусе ПЛИС. На рис. 1.40 символы Р и N обозначают непосредственно контактные площадки, подключенные к выводам корпуса ПЛИС. Р соответствует положительному (positive), aN- отрицательному (negative) выводу в том случае, если речь идет о дифференциальном интерфейсе. Также между выводами расположен компонент аппаратного терминирования для стандарта LVDS. Дифференциальный
Начальные сведения об архитектуре ПЛИС Xilinx 51 К ячейкам FPGA Выходная логика Сериализатор Входная логика Десериализатор Выходная задержка Входная задержка Master —< Управление Z-состоянием Выходная логика Сериализатор Входная логика Десериализатор Выходная задержка Входная задержка Slave —< Рис. 1.40. Структурная схема блока ввода-вывода интерфейс может и не использоваться, в этом случае выводы Р и N используются как один из вариантов однопроводного (single-ended) электрического интерфейса. IDDR2 В блоках ввода-вывода расположены также триггеры с возможностью работы в режиме DDR (Double Data Rate). Они предназначены для организации соответствующих интерфейсов'с памятью DDR и некоторыми другими типами микросхем (например, высокоскорост- ODDR2 — о 0— о 0 D СО С1 СЕ R S Q0 Q1 Рис. 1.41. Графическое изображение триггеров с функцией DDR ными АЦП). Графическое изображение компонентов IDDR (входной DDR-триггер) и ODDR (выходной DDR-триггер) показано на рис. 1.41. Входы триггера IDDR2 имеют следующее назначение: • D — вход данных (подключается к внешнему сигналу); • СО — тактовый вход, по фронту которого сигнал входа D появ^ ляется на выходе Q0; • С1 — тактовый вход, по фронту которого сигнал входа D появляется на выходе Q1; • СЕ (clock enable) — вход разрешения работы (высокий активный уровень); • R — асинхронный вход сброса;
52 Глава 1 • S —- асинхронный вход установки. Входы триггера ODDR2 имеют похожее назначение: • DO —- вход данных (подключается к одному из внутренних сигналов ПЛИС); • D1 — вход данных (подключается к одному из внутренних сигналов ПЛИС); • СО — тактовый вход, по фронту которого сигнал входа DO появляется на выходе Q; • С1 — тактовый вход, по фронту которого сигнал входа D1 появляется на выходе Q; • СЕ (clock enable) — вход разрешения работы (высокий активный уровень); • R — асинхронный вход сброса; • S — асинхронный вход установки. Выход Q компонента ODDR2 подключается к внешнему выводу ПЛИС. Наименования IDDR2 и ODDR2 соответствуют семейству Spar- tan-6. В серии 7 аналогичные компоненты называются IDDR3 и ODDR3. Также в блоках расположены аппаратные сериализаторы/десе- риализаторы. Они позволяют преобразовать параллельно загружаемые данные в последовательный поток, передаваемый на увеличенной частоте (вплоть до 1:7 в одном блоке, а для дифференциальной пары до 1:14). Например, на тактовой частоте 100 МГц скорость передачи составит до 700 Мбит/с, что недостижимо при выводе данных из матрицы логических ячеек. Максимальная скорость передачи для дифференциальной пары в Spartan-б составляет 1050 Мбит/с. Этого достаточно, например, для построения интерфейсов DVI или HDMI. Базовые варианты блоков ввода-вывода реализуются в проекте автоматически, без дополнительного участия разработчика. Достаточно указать на верхнем уровне проекта направление выводов, чтобы САПР установила соответствующий буфер. Тип электрического интерфейса определяется проектными ограничениями в отдельном файле (User Constraints File в ISE, Xilinx Design Constraints в Vivado). Для сложных вариантов интерфейсов, например с использованием сериализаторов, удобнее пользоваться генератором интерфейсов SelectIO Interface Wizard, входящим в состав библиотеки IP- ядер (рис. 1.42). * В каждом блоке ввода-вывода можно установить индивидуальную задержку распространения сигнала для входного и выходного
Начальные сведения об архитектуре ПЛИС ХШпх 53 SelectIO Interface Wizard . ... , ; . , ,..,:, Data Bus Рйс. 1.42. Диалоговое окно мастера настройки блоков ввода-вывода буфера по отдельности. Для ПЛИС Spartan-б выходная задержка не может регулироваться динамически, в процессе работы микросхемы. Для ПЛИС серии 7 и последующих такой режим возможен. Управление задержкой в блоках ввода-вывода требуется для высокоскоростных интерфейсов. Для многих интерфейсов с частотой передачи данных в сотни МГц практически невозможно получить фиксированную задержку распространения сигнала, согласованную для нескольких параллельных линий. Поэтому современной тенденцией является или переход к последовательным высокоскоростным интерфейсам, или применение динамической подстройки задержек. Например, для подключения внешней памяти стандарта DDR3 требуется подстройка задержки из-за влияния температуры, напряжения питания и других факторов. Для этих целей в интерфейсе DDR3 присутствуют калибровочные сигналы DQS, сопровождающие данные на линиях DQ. Контроллер памяти, отслеживая положение сигнала DQS, должен подстраивать задержки на линиях данных. Таким образом, ПЛИС серии 7 способны реализовать скоростные параллельные интерфейсы, а для подключения памяти DDR2 или DDR3 к Spartan-б в этих ПЛИС отдельно реализованы аппаратные контроллеры для такой памяти. Подключение памяти DDR2/3 к обычным выводам Spartan-б невозможно.
54 Г лава 1 \ BANK3 / BANKO BANK2 / BANK \ BANK4 BANK3 \ — / BANKO / — BANK2 \ BANK5 BANK1 50 выводов Spartan-б Серия 7 Рис. 1.43. Банки ввода-вывода в ПЛИС Подробная информация о работе блоков ввода-вывода, включая управление задержкой, триггерами DDR, сериализаторами/десери- ализаторами, представлена в документе UG381 Spartan-6 FPGA Se- lectlO Resources User Guide. Программируемые выводы сгруппированы в банки. Для Spartan-6 каждая сторона корпуса содержит выводы одного банка (для ПЛИС большого объема левая и правая стороны разделены на два банка каждая). В ПЛИС серии 7 и последующих каждый банк ввода-вывода имеет фиксированный размер (для серии 7 это 50 выводов). Число банков зависит от общего числа программируемых выводов корпуса. Схема расположения банков показана на рис. 1.43. В каждом банке возможно только одно напряжение питания. Соответственно, для каждого банка в документации указываются входы питания, которое будет подано на этот банк. Кроме того, некоторые электрические интерфейсы предусматривают подачу опорного напряжения Vref, которое также имеет входы в каждом банке (они совмещены с программируемыми выводами). Опорное напряжение является общим для всех выводов банка. Максимальное напряжение питания для ПЛИС Spartan-б составляет 3,3 В. Для ПЛИС серии 7 используются банки двух типов: High Range (HR) и High Performance (HP). Максимальное напряжение для банков составляет: для HR — 3,3 В, для HP — 1,8 В. Максимальная производительность, как видно из названия, при этом у блоков типа HP. Пиковые характеристики скорости обмена приводятся именно для блоков такого типа. Соотношение блоков ввода-вывода, применяемое в ПЛИС, приведено в табл. 1.14. Видно, что ПЛИС начального уровня используют в основном блоки HR. Корпуса типа TQFP144 не позволяют использовать^ некоторые аппаратные возможности Spartan-б. К основным ограничениям относятся:
Начальные сведения об архитектуре ПЛИС ХШпх 55 ! Pioe !fhO7 iPioe И05 • P1O4 IP1O3 P102 > P1O1 P1OO PW P96 P93 P92 P&1 P90 P89 P88 P86 P86 P84 P83 ' P82 P81 P80 I P77 1Р76 JP75 IP74 I ШвгЮРЫ о юиосу # Ф € в ffl 8J КММчю* VR?F P^OOK 00-015 FCS/RWE/fHD /WJC/LOC юпйга S3 a IS в ffl e e a сок CSJ cso от OOUT^BUSY Ml, MO AWAKE C EJ Ш a в и B3 SO PftOGRAMBJ* TCK TW TOO TMS OONEjg SUSPENO CMPCSJB_2 OtwPim © от 0 VCXMUX BS vcomt IS vcco Q3 NC Рис. 1.44. Изображение корпуса TQFP144 для ПЛИС семейства Spartan-б (фрагмент документа «Spartan-б FPGA Packaging and Pinouts Product Specification») • отсутствие аппаратных контроллеров памяти DDR2/3 (такие контроллеры имеются в FPGA Spartan-6 в корпусах BGA); • объединенное питание для всех банков ввода-вывода. В документе «Spartan-б FPGA Packaging and Pinouts Product
56 Глава 1 Таблица 1.14 Виды блоков ввода-вывода, применяемые в ПЛИС HR HP Artix-7 Spartan-7 Все Kintex-7 Много Неск. банков Virtex-7 Неск. банков Много Virtex-7 HT Virtex-7 XT Все Specification» (UG385) приводятся условные графические изображения корпусов FPGA с отмеченными типами выводов. На этих изображениях отмечены выводы различных типов, что облегчает подключение питания, специальных выводов и т. д. На рис. 1.44 показано изображение корпуса TQPP144. Этот рисунок может облегчить проектирование печатной платы, если вывести его на дополнительный монитор (или распечатать). Для других семейств ПЛИС имеются аналогичные документы. Кроме того, на сайте Xilinx размещены текстовые документы — Package Pinout Files https://www.xilinx.com/support/package-pinout- files.html. Это документы в ASCII формате, не использующие дополнительное форматирование текста, в которых содержится перечень выводов ПЛИС в каждом из доступных корпусов. 1.7. Блочная память Блочная память является показательным примером встроенного аппаратного ресурса, повышающего эффективность ПЛИС при решении типовых задач схемотехники. Блок памяти занимает гораздо меньше места, чем аналогичный по емкости блок, выполненный на распределенной памяти логических ячеек, и к тому же обладает предсказуемо высокими характеристиками производительности. Память является «истинно двухпортовой» (true dual-port). Это означает, что она имеет два независимых набора сигналов, допускающих проведение операций чтения или записи одновременно. Альтернативой является разновидность simple dual-port, когда только один порт допускает и чтение, и запись, а второй работает в режиме «только чтение». Память в Spartan-б размещается блоками по 18 кбит. Графическое представление компонента блочной памяти показано на рис. 1.45. Показанные сигналы имеют следующее назначение (обозначения А и В на конце имени сигналов соответствуют портам А и В): • ADDRA, ADDRB — входы адреса; • DIA, DIB — входы данных для записи; • DIPA, DIPB — дополнительные разряды входов данных; • WEA, WEB — входы разрешения записи;
Начальные сведения об архитектуре ПЛИС ХШпх 57 • CLKA, CLKB — тактовые сигналы; • ENA, ENB — сигналы разрешения работы; • REGCA, REGCB — разрешение записи во внутренний конвейеризующий регистр данных; • RSTA, RSTB — входы сброса внутренних регистров данных (сброс массива ячеек памяти с помощью этих сигналов невозможен); • DOA, DOB — выходы данных; • DOPA, DOPB — дополнительные разряды выходов данных. Память, несмотря на физическую организацию в виде массива 1024x18 битов, может выступать в различных конфигурациях: 16kxl, 8кх2, 4кх4, 2кх9, 1кх18, 512x36. Разработчик может самостоятельно контролировать используемый режим или использовать результаты синтеза. Память в серии 7 укрупнена и имеет базовый размер 36 кбит. Возможными режимами являются 32kxl, 1бкх2, 8кх4, 4кх9, 2кх18, 1кхЗб. Кроме того, в серии 7 каждому блоку памяти добавлен аппаратный контроллер FIFO. Его $= $= <Е= о О О о О О о—— RAMB16WER ADDRAA3:0) ADDRBA3:0) DIAC1:0) DIBC1:0) DIPAC:0) DIPBC:0) WEAC:0) WEBC:0) CLKA CLKB ENA ENB REGCEA REGCEB RSTA RSTB DOAC1:0) DOBC1:0) DOPAC:0) DOPBC:0) Рис. 1.45. Графическое представление компонента блочной памяти функции в целом могут быть реализованы на базе логических ячеек, однако размещение такого контроллера непосредственно в модуле памяти в качестве главного эффекта дает не столько экономию логических ячеек, сколько сохранение высокой тактовой частоты работы памяти при использовании режима FIFO. Контроллер FIFO аппаратно формирует флаги: • empty — очередь пуста; • full — очередь заполнена; • almost_empty — очередь «почти пуста» (используется настраиваемый порог срабатывания); • almost jull — очередь «почти заполнена» (используется настраиваемый порог срабатывания); • rderr — ошибка чтения (чтение из пустой очереди); • wrerr — ошибка записи (запись в полную очередь). Память BRAM может быть автоматически сгенерирована синтезатором на основе анализа исходных текстов проекта. Разработчик
58 Г лава 1 может принудительно задать использование такой памяти в проекте, установив подключение сигналов (component instantiation). Подробнее о способах использования памяти можно узнать в последующих главах. Контроллер FIFO не может быть сгенерирован автоматически и должен устанавливаться разработчиком в проект принудительно. Режим FIFO, как и другие режимы работы с раздельными тактовыми сигналами, крайне важны при построении цифровых систем, использующих более одного тактового сигнала. Как будет рассмотрено ниже, прямая передача данных, тактируемых одним тактовым сигналом, в части схемы, тактируемые другим тактовым сигналом, является источником ошибок, при которых логический уровень может читаться ненадежно. Использование двухпортовой памяти, где каждый порт тактируется собственным источником тактового сигнала, является архитектурно безопасным способом передачи данных между разными тактовыми сетями. При одновременном доступе к ячейке памяти по двум портам, когда один из портов производит запись, а другой — чтение, возможны следующие режимы работы: • чтение перед записью (read before write) — порт, выполняющий чтение, выдает старое значение ячейки памяти, в которую производится запись по другому порту; • чтение после записи (read after write) —- порт, выполняющий чтение, выдает значение, которое записывается по другому порту; • нет чтения при записи (по read on write), состояние порта не изменяется. В последнем случае речь идет не об отсутствии записи в ячейку, а о сохранении состояния выходного регистра модуля памяти. Временные диаграммы работы блочной памяти показаны на рис. 1.46. CLK WE DI ADDR DO 0000 EN _/ Запрещено Рис. 1.46 xxxx » nil X 2222 X ' xxxx Л УЧ ¦ PP-y J >MEMOa) X»oid X MEM(cc); Чтение ! Запись ! Запись \ Чтение Временные диаграммы работы блочной памяти
Начальные сведения об архитектуре ПЛИС ХШпх 59 В семействах UltraScale Plus дополнительно установлены более крупные блоки памяти UltraRAM объемом 288 кбитов. Эта память имеет организацию до 4096x72 бита. Блоки UltraRAM являются двухпортовыми, как и BRAM, однако в отличие от BRAM оба порта должны тактироваться одним и тем же тактовым сигналом. Таким образом, с помощью UltraRAM невозможно построить узел передачи данных между тактовыми сетями проекта. 1.8. Секции DSP48 Операция умножения является примером того, как с помощью аппаратного компонента можно существенно улучшить эффективность ПЛИС в целом. Несмотря на то что умножение можно реализовать и на программируемых ячейках, ресурсы ПЛИС при таком подходе будут использованы расточительно, а тактовая частота окажется невысокой. Поэтому аппаратный блок, который выполняет только умножение, займет существенно меньше места на кристалле ПЛИС и будет работать с высокой тактовой частотой, независимо от того, как реализована трассировка проекта в целом. Операция умножения требуется для широкого спектра алгоритмов цифровой обработки сигналов — с ее помощью реализуются цифровые фильтры, компоненты спектрального и вейвлет-анализа, элементы ней- росетей. Аппаратный умножитель 18-разрядных операндов был впервые добавлен в ПЛИС ХШпх в семействе Virtex-II. Очень скоро стало понятно, что «слабым звеном» теперь стал аккумулятор — для реализации цифровых фильтров требуется вычисление выражений вида s — $ + kx, и если операция умножения стала выполняться быстро, то сложение его результата с переменной s (аккумулятором) в Virtex-II приходилось выполнять на базе программируемых ячеек, что могло уменьшить тактовую частоту блока по сравнению с тем, что мог обеспечить умножитель. Поэтому в последующих поколениях ПЛИС ХШпх использовались более сложные блоки, включающие в себя и аппаратный аккумулятор, способный работать на такой же высокой тактовой частоте, что и умножитель. Таким образом, все выражение s — s + kx стало возможным выполнять целиком на аппаратных компонентах, без привлечения логических ячеек. Блок, содержащий умножитель и аккумулятор, первоначально получил название «секция XtremeDSP», которое потом было изменено на «секция DSP», или «секция DSP48», где 48 обозначает разрядность аккумулятора. Нетрудно убедиться, что перемножение 18-разрядных чисел дает 36-разрядное произведение, и для реали-
60 Г лава 1 Рис. 1.47. Структурная схема блока DSP48A1 зации цифрового фильтра необходимо иметь возможность накапливать сумму таких чисел без переполнения аккумулятора. Именно поэтому разрядность аккумулятора превышает разрядность операндов. ПЛИС Spartan-б, несмотря на то что относится к FPGA начального уровня, содержат аппаратные блоки DSP. Они называются DSP48A1. Секция DSP48A1 содержит аппаратный умножитель независимых 18-разрядных операндов, 48-й разрядный аккумулятор и вспомогательные компоненты. Иногда для обозначения разрядности операндов и результата используется формула 18 * 18 = 48, показывающая, что компонент перемножает два 18-разрядных операнда и помещает результат в 48-разрядный аккумулятор. Структурная схема блока DSP48A1 показана на рис. 1.47. На структурной схеме можно видеть основные компоненты блока DSP48. Кроме непосредственно умножителя и аккумулятора в блоке размещены цепочки конвейеризующих регистров, использование которых необходимо для получения наивысшей достижимой тактовой частоты. Технически секция DSP может выполнять умножение операндов и в режиме комбинационной логики, т.е. без использования выходного регистра, однако в этом случае тактовая частота будет меньше. На рис. 1.47 после входов В и D размещен дополнительный компонент, называемый «предварительным сумматором» (pre-adder). По сравнению с умножителем такой сумматор имеет существенно меньший размер, поэтому не ухудшает характеристики блока в целом. Однако этот узел позволяет уменьшить число блоков DSP48 в два к13 Рис. 1.48. Пример импульсной характеристики фильтра с симметричными коэффициентами раза для целого подкласса алгоритмов цифровой обработки сигналов. Речь идет о цифровых фильтрах с симметричными коэффициентами. Пример импульсной характеристики такого фильтра показан на рис. 1.48.
Начальные сведения об архитектуре ПЛИС Xilinx 61 При реализации схемы такого фильтра выражение для выхода будет выглядеть как Y = kl * xl + ... + ИЗ * х13 + ... + к17 * х17 + ... Однако kl3 = kl7, поэтому этот фрагмент можно переписать следующим образом: Y = kl3*(xl3 + xl7). После такого преобразования получилось, что вместо двух операций «умножение с накоплением» использовано одно умножение, с учетом того, что отсчеты х13 и х17 были предварительно суммированы. Именно для этой операции и предназначен узел pre-adder. Из этого следует, что при выборе цифрового фильтра следует рассматривать возможность применения фильтра с симметричными коэффициентами. В этом случае для реализации фильтра с учетом использования pre-adder потребуется в два раза меньше блоков DSP48. Блоки цифровой обработки в семействах ПЛИС серии 7 имеют существенное отличие — все блоки представляют собой вариант DSP48E1, впервые введенный в Virtex-б. Он способен умножать 25- и 18-битовые числа (более ранние блоки DSP48A1 в Spartan- 6 ограничиваются двумя 18-разрядными операндами). Увеличение разрядности одного и? операндов до 25 битов не только способствует увеличению динамического диапазона представляемых значений, но и помогает с помощью всего двух умножителей 25 х 18 выполнять перемножение чисел с плавающей точкой с одинарной точностью (в формате short float). Для предыдущих поколений FPGA для этого потребовалось бы 4 умножителя, так что новая архитектура блока XtremeDSP способствует эффективной реализации цифровых фильтров, использующих более точное представление чисел. Структурная схема DSP48B2 показана на рис. 1.49. В блоке DSP48E2 сохраняется в целом та же структура — умножитель, аккумулятор, конвейеризующие регистры и предварительный сумматор. Однако есть и ряд дополнительных функций. Вместо аккумулятора в DSP48E2 используется более мощный блок, обозначаемый как арифметико-логическое устройство. Его обозначение показано на рис. 1.50. На рис. 1.50 в обозначении АЛУ видны три обозначения операций в «главном блоке» — сложение, вычитание и изображение логического вентиля. Аккумулятор может как записать результат умножения, так и прибавить или вычесть его из текущего содержи-
62 Г лав а 1 А- D- С- 48-бит.АЛУ Предсумматор Модуль сравнения (Pattern Detector) XOR Pattern Detect Рис. 1.49. Структурная схема блока DSP48E2 ALUMODE[3:0] OPMODE[3:0] Рис. 1.50. Компонент АЛУ в составе блока DSP48B2 мого. Дополнительно над операндами, поступающими в АЛУ, возможно выполнение побитовых логических операций. Их примеры приведены в табл. 1.13. Как правило, непосредственная работа с установкой этих режимов не требуется. Регулирование режимов работы АЛУ и коммутаторов операндов производится или автоматически в процессе синтеза схемы, или специализированными IP- ядрами, разработанными Xilinx, или другими компаниями. Наличие блока АЛУ предоставляет неочевидный вариант использования компонента DSP48 — в качестве 48-разрядного сумматора/вычитателя или устройства, выполняющего поразрядные операции надо 48-разрядными операндами. При этом сохраняется высокая частота работы и экономятся ресурсы логических ячеек, однако вопрос применения таких режимов является предметом отдельного рассмотрения. Еще одной разновидностью дополнительного компонента в составе DSP48E2 является Pattern Detector. Это блок, выполняющий быстрое сравнение 48-разрядного аккумулятора с 48-разрядной константой. Сравнение может производиться с использованием битовой маски. С помощью этого блока можно, например, быстро выполнить сравнение аккумулятора с нулем или отследить превышение некоторого порога. Аккумулятор может использоваться в режиме SIMD (Single Instruction, Multiple Data). Это реализуется путем его разделения
Начальные сведения об архитектуре ПЛИС ХШпх 63 Таблица 1.13 Примеры режимов работы компонента АЛУ в блоке DSP48E2 Операция XXORZ Z XNOR Z X XNOR Z XXORZ X ANDZ X AND (NOT Z) X NAND Z (NOT X) OR Z X XNOR Z XXORZ XXORZ X XNOR Z XORZ X OR (NOT Z) XNORZ (NOT X) AND Z OPMODE[3:2] 00 00 00 00 00 00 00 00 10 10 10 10 10 10 10 10 ALUMODE[3:0] 0100 0101 0110 0111 1100 1101 1110 1111 0100 0101 0110 0111 1100 1101 1110 1111 на два аккумулятора по 24 разряда или 4 аккумулятора по 12 разрядов. Такие режимы также не реализуются автоматически и требуют настройки компонента DSP48E2, которую можно выполнить с помощью IP-ядер, входящих в состав САПР ПЛИС. Синтезаторы автоматически используют блоки DSP48, включая и вспомогательные компоненты. Например, выражение sum <= sum -f a * b; будет реализовано именно в виде «умножитель + аппаратный аккумулятор». Предсказуемость характеристик аппаратных умножителей делает их удобными для реализации систем цифровой обработки сигналов. Например, цифровые фильтры, которые можно сконструировать в специальном приложении FIR Compiler, входящем в состав САПР Vivado или ISB (рис. 1.51), используют только компоненты DSP48. Результатом работы этого инструмента является готовый компонент цифрового фильтра с конечной импульсной характеристикой, который не требует дополнительного вмешательства разработчика. FIR Compiler использует дополнительные возможности блоков DSP48, такие как конвейеризующие регистры и предварительный сумматор. Блоки DSP48 в последующих семействах имеют следующие основные модификации: • UltraScale (DSP48E2) — максимальная разрядность перемножаемых операндов составляет 27 и 18, предварительный сумматор может складывать 27-разрядные числа;
64 Глава 1 frlR Compiler Рис. 1.51. Диалоговое окно инструмента FIR Compiler • UltraScale Plus (DSP48E2) — аналогично блоку DSP48E2 в серии UltraScale; • Versal — максимальная разрядность перемножаемых операндов составляет 27 и 24, аккумулятор имеет разрядность 58 битов. Подробное описание архитектуры секций DSP достаточно объемно и приводится в соответствующих руководствах пользователя отдельно для каждого семейства FPGA. 1.9. Тактовые ресурсы Уменьшение технологических норм и повышение тактовых частот делают цифровые схемы крайне чувствительными к особенностям трассировки, технологическому разбросу параметров, температуре и колебаниям напряжения питания. Поэтому большинство приемов, основанных на асинхронной схемотехнике, для FPGA технически реализуемы, но приводят к нестабильной работе. Для повышения надежности работы проектов на базе FPGA применяемые схемы должны быть синхронными. Основные параметры тактового сигнала показаны на рис. 1.52. На этом рисунке можно видеть, что кроме номинального значения периода для тактового сигнала можно указать время нараста-
Начальные сведения об архитектуре ПЛИС ХШпх 65 Skew Период Рис. 1.52. Основные параметры тактового сигнала ния фронта (skew) и уровень па- Jitter раметра jitter («дрожание», часто используется в русскоязычной литературе в транслитерированной форме «джиттер»). Время нарастания фронта обычно измеряется от уровня 10 % максимального напряжения до 90 % (в некоторых случаях — 20...80 %). Это связано с тем, что непосредственно вблизи нуля и максимального напряжения форма сигнала обычно искажена и на практике точного нуля и максимума фронт может и не достигать. В то же время время фронта важно тем, что в цифровой технике срабатывание триггера может произойти при различных уровня напряжения по мере прихода фронта. Поэтому возможна ситуация, когда один триггер воспримет фронт в положении ближе к максимуму, а следующий за ним — на начальном участке. В этом случае вместо номинального значения периода интервал между срабатываниями последовательно включенных триггеров будет меньше на величину времени нарастания сигнала (skew). Понятие jitter соответствует эффекту «дрожания» фронта относительно его номинального положения на временной оси. Это связано с нестабильностью частоты тактового генератора. Так же, как и для параметра skew, возможна ситуация, когда первый триггер сработает по положению фронта, пришедшему с максимальной задержкой, а следующий фронт придет с минимальной задержкой. В этом случае интервал времени для распространения сигнала по линии данных должен быть уменьшен еще и на величину jitter. Из-за наличия упомянутых эффектов тактовый сигнал желательно иметь с минимально возможными значениями параметров skew и jitter. Именно поэтому необходимо применять специальные формирователи (буферные элементы), обеспечивающие минимальное значение skew, и генераторы, минимизирующие jitter. Такие компоненты имеются на кристаллах современных ПЛИС. Все синхронные компоненты (триггеры, блочная память, блоки DSP) получают тактовый сигнал по выделенным линиям, которые проложены по кристаллу так, чтобы минимизировать неравномерность распространения сигнала. Бели использовать именно эти ресурсы, то можно считать, что все синхронные компоненты работают одновременно. В противном случае возможно возникновение так называемых «гонок фронтов», когда фронт тактового сигнала
66 Г лава 1 приходит на отдельные компоненты в разные моменты времени и в кристалле будут одновременно существовать данные, относящиеся к разным отсчетам тактового сигнала. Комбинация сигналов, относящихся к разным тактам, скорее всего приведет к неправильному поведению схемы. Нельзя утверждать, что следование правилам проектирования синхронных схем создает постоянные проблемы на всем протяжении проекта, однако этому вопросу следует уделить внимание. В ПЛИС Spartan-б предусмотрены специальные буферы для распространения тактового сигнала, однако они расположены только в определенных блоках ввода-вывода, которые помечены в документации. Тактовые сигналы следует подать на эти входы, однако этого еще недостаточно для равномерного распространения фронта по всему кристаллу. Для этой задачи необходимо использовать модули, подстраивающие задержку выходного сигнала, — DCM (Digital Clock Manager) или PLL (Phase-Locked Loop). Оба вида этих компонентов имеются на кристалле FPGA и объединены в Clock Management Tile. Правильное построение системы синхронизации в современных FPGA не является сложным процессом, однако данный этап не следует оставлять без внимания. Методика выбора системы синхронизации базируется на двух последовательно пришедших в микроэлектронную область подходах: 1) полностью синхронный стиль проектирования; 2) глобально асинхронные, локально синхронные схемы. При этом второй подход не отменяет, а расширяет первый, поскольку «глобальная асинхронность» в данном случае не означает, что в каких-то случаях правилами построения синхронных схем можно пренебречь. Речь здесь идет только о том, что для ПЛИС большого объема (сотни тысяч логических ячеек) необходимо изначально создавать проект в виде нескольких синхронных частей, данные между которыми передаются через специальные схемы ресинхронизации (Clock Domain Crossing, CDC). Итак, синхронная схема обладает следующими признаками: • один тактовый сигнал, один перепад (все триггеры используют только фронт или только спад тактового сигнала); • используются D-триггеры (не защелки); • регистры на выходах блоков; • используются сигналы «разрешение счета» вместо управления тактовым сигналом; • используются схемы синхронизации для асинхронных сигналов.
Начальные сведения об архитектуре ПЛИС ХШпх 67 Не используются: • тактовые сигналы, полученные с помощью логических вентилей, комбинирования разрядов счетчиков или делением частоты с помощью триггеров логических ячеек; • локальные асинхронные сигналы сброса/установки; Тактовые ресурсы ПЛИС Тактовые буферы - 4 дифференциальные можно проиллюстрировать на /\пары на каждой стороне рис. 1.53, 1.54. На рис. 1.53 можно видеть основные тактовые ресурсы семейства Spartan-б. В центре кристалла расположены формирователи тактовых сигналов, объединенные в блоки СМТ (Clock Management Tile). Для Spartan-б в таком блоке находятся два компонента DCM (Digital Clock Manager) и один компонент PLL (Phase- Locked Loop). Тактовые сигналы вводятся в ПЛИС через специальные тактовые буферы, которые у Spartan-б расположены на каждой из четырех сторон кристалла. Доступ к буферам возможен только через специальные выводы ПЛИС, помеченные как GCLK. Имеется до 8 тактовых входов, которые могут объединяться в дифференциальные пары (т. е. на них можно подать дифференциальные тактовые сигналы). В серии 7 реализована более развитая схема тактирования. Прежде всего, кристалл ПЛИС разбит по вертикали на тактовые регионы равной высоты. Для серии 7 высота региона равна 50 блоков ввода-вывода, 8 из которых могут вводить тактовые сигналы (они тоже могут объединяться в 4 дифференциальные пары). Регион имеет в высоту 50 CLB, так что блоки логических ресурсов и блоки ввода-вывода совпадают по высоте и находятся в одних и тех же регионах (у Spartan-б группы блоков ввода-вывода имеют разную высоту в зависимости от размеров кристалла). Тактовые сигналы в серии 7 распределяются из центра кристалла. Центральная магистраль имеет 32 тактовые линии, каждая из которых формируется собственным глобальным тактовым буфером BUFG. Каждый тактовый регион может использовать любые 12 из этих линий, которые подаются через вспомогательные буфе- Рис. 1.53. Тактовые ресурсы ПЛИС Spartan-6
68 Глава 1 < л <]bufio ?>BUFR \ bufh12iiit.b г\ каждом 1^ регионе BUFG 32 шт." д 50 10 ^ 50 КЛБ, 4 дифференциальные пары для тактовых сигналов в каждом регионе ры BUPH. Прямое управление буферами BUFH, как правило, не требуется, поскольку они используются автоматически. В серии 7 также выделяют региональные тактовые буферы BUFR и буферы, тактирующие триггеры блоков ввода-вывода BUFIO. Эти буферы можно видеть на рис. 1.54. Буферы BUFR тактируют только компоненты того региона, в котором находятся (CLB, память, блоки DSP), а буферы BUFIO предназначены для триггеров, находящихся в блоках Рис. 1.54. Тактовые ресурсы ПЛИС серии 7 ввода-вывода. Такое решение связано с тем, что размер кристалла ПЛИС для серии 7 может быть довольно большим, и обеспечить распространение множества независимых тактовых сетей по всей площади кристалла оказывается затруднительным. Поэтому применяется комбинация тактовых сетей, из которых глобальные являются наиболее универсальными, а региональные ограничены по распространению, но их тактовые частоты выше. Региональные тактовые буферы помогают в реализации высокочастотных цифровых интерфейсов, синхронизируемых с источником (source-synchronous BUFGCTRL IGN0RE1 CE1 SI И ю—I interface). Имеется также мультирегиональный тактовый буфер BUFMR, который может подать тактовый сигнал на тот регион, в котором он расположен, и на два соседних по высоте региона. Глобальный тактовый буфер в действительности является одним из вариантов конфигурирования достаточно сложного компонента, который обладает широкими возможностями формирования и управления тактовым сигналом. Полный вид графического обозначения этого компонента показан на рис. 1.55. С помощью этих сигналов можно задать режим работы компонента BUFGCTRL, обеспечивая выполнение некоторых употребительных операций с тактовым сигналом. Например, мультиплексирование (переключение) тактовых сигналов выполняется компонентом BUFGMUX. Можно еще раз обратить внимание, что BUFGMUX >—о SO CEO IGNORE0 Рис. 1.55. Полный вид компонента глобального тактового буфера
Начальные сведения об архитектуре ПЛИС ХШпх 69 Tl T2 Рис. 1.56. Работа глобального тактового буфера в режиме мультиплексирования тактовых сигналов как таковой не существует и появляется вследствие задания режима работы компонента BUFGCTRL. Изображение и временные диаграммы работы BUFGMUX показаны на рис. 1.56. На этом рисунке можно видеть основную особенность мультиплексора тактовых сигналов. При переключении входа-селектора S текущий полупериод тактового сигнала завершается и новый полупериод обязательно начинается с нового фронта. При таком подходе на выходе гарантированно отсутствуют слишком короткие полупериоды («пики»), которые могут привести к неопределенному поведению синхронных компонентов ПЛИС. Поскольку триггеры, блоки памяти и блоки DSP48 подразумевают некоторую минимальную длительность периода тактового сигнала, чрезмерно короткий импульс не будет ими воспринят, зато импульс с «пограничной» длительностью может быть частью триггеров воспринят нормально, а частью — проигнорирован. Это приведет к совершенно непредсказуемым последствиям, поэтому переключение тактовых сигналов не может выполняться обычными цифровыми мультиплексорами. Аналогичную функцию — устранение чрезмерно коротких полупериодов — выполняет компонент BUFGCE, который показан на рис. 1.57. Вход СЕ, как и для других компонентов, управляет разрешением счета, в данном случае разрешая прохождение тактового сигнала на выход буфера. Так же, как и в случае BUFGMUX, при включении/выключении тактового сигнала существует опасность получения на выходе короткого полупериода, который будет воспринят только частью триггеров ПЛИС. Поэтому после выключения сигнала СЕ компонент BUGCE корректно завершает текущий BUFGCE После снятия СЕ текущий тактовый импульс будет завершен После включения СЕ новый тактовый импульс начнется с нового фронта Рис. 1.57. Работа глобального тактового буфера в режиме разрешения счета
70 Глава 1 полупериод входного сигнала CLK, а после включения этого сигнала новый полупериод начинается обязательно с нового фронта CLK, приходящего после включения СЕ. Аналогичная возможность существует и у буферов BUFH, подающих тактовые сигналы в отдельные тактовые регионы ПЛИС. Для этого буфера также существует режим BUFHCE, обладающий теми же возможностями, что и BUFGCE. Преимуществом буферов с физическим отключением тактового сигнала на выходе является то, что при необходимости периодически приостанавливать работу большого фрагмента схемы можно разместить ее в одном тактовом регионе, убрав оттуда все остальные компоненты проекта, и подать тактовый сигнал через BUFHCE. Средства проектирования ХШпх могут автоматически применять компоненты BUFGCE и BUFHCE для снятия тактового сигнала с целых регионов. Это позволяет снизить потребляемую мощность и избавиться от необходимости трассировки множества индивидуальных сигналов СЕ для всех синхронных компонентов, расположенных в этом регионе. Региональные тактовые буферы серии 7 могут работать в режиме деления входной тактовой частоты. Коэффициент деления составляет от 2 до 8 в режиме Single Data Rate и от 2 до 14 в режиме Double Data Rate. Подразумевается, что региональный тактовый буфер в сочетании с компонентом BUFIO будет использован для реализации схемы тактирования компонента ISERDES, как показано на рис. 1.58. На рис. 1.58 видно, что приходящие данные через обычный вход A0) подаются на компонент ISERDES. Тактовый сигнал LK, синхронизированный с этими данными, через буфер, способный вводить тактовые сигналы (ССЮ — Clock-Capable 10), подается на BUFIO без изменения частоты и на BUFR с делением частоты на N. Далее выход BUFIO тактирует последовательную часть компонента ISERDES, а выход BUFR, частота на котором в N раз ниже, тактирует регистр с параллельными N-разрядными данными. ISERDES N CLKDIV Ячейки FPGA BUFR Рис. 1.58. Совместное использование региональных тактовых буферов
Начальные сведения об архитектуре ПЛИС ХШпх 71 JBUFG CLKIN CLKOUT DCM (Startan-6) ММСМ или PLL (серия 7) CLKFBIN BUFG Рис. 1.59. Схема включения компонента формирования тактового сигнала Важным вопросом является способ формирования глобальных тактовых сигналов на кристалле ПЛИС. Для того чтобы тактовый сигнал был доставлен на все синхронные компоненты ПЛИС в одно и то же время, недостаточно просто завести его на один из тактовых буферов. Требуемая схема включения блока формирования тактовых сигналов в его простейшем варианте показана на рис. 1.59. Генерация и настройка такого блока достаточно легко осуществляется с помощью инструмента Core Generator, входящего в состав средств разработки ХШпх. На рис. 1.59 показаны следующие компоненты: • IBUFG — тактовый буфер, размещенный в одном из входов, для которых указана возможность ввода тактовых сигналов (Clock- Capable Ю); • DCM/MMCM/PLL — один из вариантов формирователя тактовых сигналов; • BUFG — глобальный тактовый буфер, выход которого подключен к глобальной тактовой сети, а также подается на вход обратной связи CLKFBIN формирователя тактового сигнала. Формирование тактового сигнала осуществляется с использованием сигнала обратной связи. Смысл применения такой схемы заключается в том, что при подаче тактового сигнала на удаленные компоненты схемы из-за влияния температуры, напряжения питания и технологического разброса параметров компонентов задержка распространения тактового сигнала будет изменяться. Однако определить, в какой момент фронт тактового сигнала поступает на удаленный от генератора компонент, физически невозможно — момент поступления фронта сам по себе будет измерен с задержкой. Поэтому сигнал обратной связи поступает на формирователь из определенной точки ПЛИС, а задержка распространения из этой точки до генератора и до остальных компонентов приблизительно одинаковы. Чтобы проиллюстрировать актуальность использования такой схемы, можно рассмотреть взаимное расположение компонентов, показанных на рис. 1.59, на реальном кристалле FPGA. Бели на прин-
72 Глава 1 ципиальной электрической схеме короткий сигнал обратной связи CLKFBIN создает впечатление компактности всего узла, то на рис. 1.60 видно, что два соединенных им компонента находят- тэттт-ч~ ся в различных частях кристал- *BUFG ^ - ; ла. Это сделано для того, чтобы • сигнал обратной связи мог прой- ! ти по кристаллу приблизительно \ такое же расстояние, что и такто- \ вые сигналы, подаваемые на син- \ хронные компоненты FPGA. По- 1 ^ ММСМ лучив фронт сигнала обратной \ связи, компонент ММСМ будет Рис. 1.60. Взаимное расположе- подстраивать его таким образом, ние компонентов ММСМ и BUPG чтобы СИНХрОНИЗИрОВать С ОПОр- на кристалле FPGA серии 7 ным сигналом CLKIN. Получить сведения о моменте прихода фронта тактового сигнала на компоненты, расположенные на противоположном углу кристалла, невозможно, однако можно получить фронт сигнала, проходящего примерно такое же расстояние от BUPG до ММСМ, что и другие тактовые сигналы проходят от BUFG до тактируемых ими компонентов. Поэтому при наличии в системе синхронизации компонентов ММСМ или PLL можно говорить, что все синхронные компоненты проекта получают фронт тактового сигнала в одно и то же время. Генератор обеспечивает такую задержку, чтобы приходящий опорный тактовый сигнал совпадал по фазе с сигналом обратной связи. Это может быть сделано несколькими способами, которые и обусловливают наличие в ПЛИС нескольких разновидностей формирователей. Основными способами подстройки фазы двух тактовых сигналов являются DLL (Delay-Locked Loop) и PLL (Phase-Locked Loop). В первом случае используется линия задержки, состоящая из нескольких буферов, каждый из которых вносит небольшую задержку (десятки пикосекунд). Схема управления, сравнивая фазы входного тактового сигнала и сигнала обратной связи, увеличивает или уменьшает число буферов в линии задержки (рис. 1.61). Это похоже на работу механического переключателя с фиксированным числом положений. Компонент DLL входит в состав модуля Digital Clock Manager
Начальные сведения об архитектуре ПЛИС Xilinx 73 CLKOUT CLKIN CLKFBIN Рис. 1.61. Принцип работы формирователя тактового сигнала Delay-Locked Loop (DCM) в ПЛИС Spartan-6. Обозначение DCM используется, чтобы отразить наличие дополнительных функций — синтез тактового сигнала других частот и управление сдвигом фазы. Синтез частоты основан на том, что схема управления не обязательно должна строго выравнивать фазы входного сигнала и сигнала обратной связи. Вполне возможно использовать алгоритм управления, обеспечивающий формирование N выходных периодов тактового сигнала на каждые М периодов входного сигнала. В компоненте DCM настраивается набор выходных тактовых частот, причем каждый из выходов блока DCM, показанных на рис. 1.62, может иметь частоту, определяемую по формуле F — F[nM/D} где М и D принимают значения в диапазоне от 1 до 32. В примере диалогового окна настройки компонента DCM видно, что при входной частоте 100 МГц САПР автоматически рассчитал параметры для формирования выходных сигналов 50 и 125 МГц, однако попытка установить для выхода CLK_OUT3 значение 126 МГц привело к тому, что в действительности было выбрано близкое значение 125 МГц. Можно убедиться, что, оперируя коэффициентами М и D из диапазона 1...32, не удается получить такую их комбинацию, чтобы выходная частота составила 126 МГц. Вместо этого действительное значение частоты (Actual Output Preq) указано как 125 МГц. Входная частота для DCM в Spartan-б должна находиться в интервале 5...250 МГц. Обычно это не представляет проблем, однако необходимо иметь в виду, что не любой тактовый генератор может быть использован в качестве источника тактового сигнала. Также необходимо проверять, что желаемые выходные частоты могут быть получены с учетом характеристик DCM. Для каждого выхода может быть также настроен сдвиг фазы выходного тактового сигнала относительно опорного. Эти параметры также указываются при настройке. Это может быть полезно при создании высокоскоростных внешних интерфейсов, чтобы скомпенсировать влияние задержки распространения тактового сигнала на внешних печатных проводниках.
74 Глава 1 Clocking Wiz Quit put Clock Output freq (MH?) Ph#se {fit Recjae&teel Actual Requested Рис. 1.62. Настройка компонента DCM в диалоговом окне Clocking Wizard в САПР Xilinx ISB В компоненте DCM можно видеть сигналы RESET и LOCKED. Первый, как очевидно из названия, предназначен для сброса тактового генератора, который при нормальной работе схемы обычно не требуется, поскольку производится при загрузке конфигурации ПЛИС. Сигнал LOCKED имеет активный высокий уровень и сигнализирует о нормальной работе тактового генератора. Обычно для выравнивания фазы выходного сигнала требуется несколько тактов (в материалах Xilinx приводится значение до 1000 тактов входного тактового сигнала при его нестабильной частоте), однако на практике сигнал LOCKED появляется значительно раньше и тактовый сигнал успевает принять стабильные характеристики задолго до завершения загрузки конфигурации. Теоретически сигнал LOCKED может использоваться в качестве сигнала СЕ для тактовых буферов или для формирования аварийного сигнала «потеря тактовой частоты», однако на практике при использовании внешнего кварцевого генератора не удалось обнаружить ситуацию, когда DCM не успевал бы выполнить выход на рабочий режим до окончания загрузки конфигурации ПЛИС.
Начальные сведения об архитектуре ПЛИС ХШпх 75 Параметры DCM могут изменяться динамически непосредственно в процессе работы ПЛИС. Для этого имеется цифровой интерфейс, доступный со стороны программируемых ячеек, аналогичный по составу сигналов интерфейсу SPI. Управление этим интерфейсом удобнее выполнять с помощью процессорной схемы, поскольку он обеспечивает доступ практически ко всем внутренним регистрам DCM, число которых составляет несколько десятков. Детали работы с данным интерфейсом изложены в документе, описывающем работу с Dynamic Reconfiguration Port (XAPP879). В данном случае сигнал LOCKED имеет практическое значение, поскольку в процессе переключения режима выходной тактовый сигнал не будет стабильным. Вторым принципиальным подходом к регулированию тактового сигнала является использование аналоговой схемы — фазовая автоподстройка частоты (ФАПЧ), также PLL, Phase-Locked Loop. В отличие от DLL, где фаза выходного сигнала зависит от задержки, вносимой цепочкой буферов, в PLL используется специальная схема «генератор, управляемый напряжением» (ГУН), также Voltage- Controlled Oscillator (VCO). ГУН является аналоговой схемой, изменяющей фазу выходного сигнала в зависимости от уровня входного напряжения. Если сигналы на входах PLL совпадают по фазе, их разность равна нулю и ГУН не изменяет фазу. В отличие от схемы DLL, которую можно сравнить с механическим переключателем с фиксированными положениями, PLL использует плавное регулирование. Упрощенная схема компонента PLL в ПЛИС серии 7 показана на рис. 1.63. Входной тактовый сигнал и сигнал обратной связи поступают на Phase Frequency Detector (PFD), который формирует сигнал, пропорциональный разности фаз. Этот сигнал поступает на VCO, управляя изменением его выходной частоты. В PLL имеются также делитель частоты D и умножитель М, назначение которых — CLKIN CLKFBIN Рис. 1.63. Упрощенная схема блока PLL в ПЛИС серии 7
76 Глава 1 изменение выходной частоты, как и в DCM. В серии 7 М может принимать значения 1-64, a D — 1-56. Дополнительно 6 выходов PLL используют индивидуальные делители О0-О5, принимающие значения деления 1-128. Особенностью аналоговой реализации PLL является необходимость использования достаточно высокой промежуточной частоты (ее допустимые диапазоны указаны в документации на компонент PLL). Поэтому при необходимости использовать входной тактовый сигнал 100 МГц и выходной 100 МГц для PLL нельзя установить D=l и М=1, поскольку промежуточная частота Pin * М окажется равно 100 МГц, что не позволит попасть в допустимый диапазон промежуточных частот. Для получения работоспособного генератора PLL необходимо установить, например, М = 10 и D = 10, обеспечив промежуточную частоту 1 ГГц. В серии 7 на основе PLL строится также генератор Mixed-Mode Clock Manager, который использует комбинированные аналоговые и цифровые режимы управления и так же, как DCM, обладает возможностью регулирования фазы выходных тактовых сигналов и режимом динамической реконфигурации. Компоненты DCM/PLL в Spartan-б и MMCM/PLL в серии 7 и последующих, как было указано выше, объединяются в блоки СМТ (Clock Management Tile). Такое решение принято потому, что однозначно выбрать между DCM/MMCM и PLL довольно затруднительно. С одной стороны, повышение тактовых частот делает аналоговые схемы PLL более привлекательными, с другой — цифровые и цифро-аналоговые схемы обладают более широкими возможностями синтеза частот и управления фазой. Однако у цифровых схем выше показатель джиттера («дрожания») выходного тактового сигнала. Этот эффект легко объяснить, если представить процесс регулирования выходной фазы переключателем с фиксированными положениями. Если блоку DLL потребуется установить задержку, равную, например, 4,5 единицам внутренних буферов, то в процессе работы схема управления будет устанавливать поочередно 4 или 5 буферов в линии задержки и период выходного сигнала будет постоянно изменяться на небольшую величину. При этом VCO способен изменять фазу выходного сигнала плавно. При необходимости существенно изменять частоту и фазу тактового сигнала предпочтительно использовать ММСМ, a PLL может быть включен последовательно, уменьшая джиттер тактового сигнала, формируемого ММСМ.
Начальные сведения об архитектуре ПЛИС ХШпх 77 При последовательном включении ММСМ и PLL обратная связь CLKFB должна быть реализована для каждого компонента по отдельности, а не целиком для узла из двух тактовых генераторов. При разработке проекта САПР автоматически вставляет тактовые буферы BUFG и BUFH. Тактовые генераторы DCM, ММСМ и PLL не могут быть автоматически синтезированы, если в проекте используется тактовый сигнал. Необходимо использовать подход component instantiation, возможно, используя мастер настройки Clocking Wizard. При проектировании кристалла ПЛИС и прокладке тактовых сетей невозможно добиться абсолютной идентичности в распространении тактового сигнала. Можно только говорить о том, что неравномерность его распространения с учетом применения блоков MMCM/PLL сведена к разумному минимуму, который позволяет говорить о схеме как о полностью синхронной. Рассинхронизация будет увеличиваться по мере возрастания размеров кристалла, и для больших FPGA становится актуален подход GALS (Globally Asynchronous, Locally Synchronous). Он подразумевает, что проект состоит из нескольких синхронных подсистем, которые работают каждая на своей тактовой частоте. Номинально эти частоты могут быть и одинаковы, но если каждый тактовый сигнал формируется своим блоком ММСМ, то на практике фазы этих сигналов все равно будут отличаться в разных областях кристалла. Поэтому необходимо заранее предусматривать способы передачи данных из одного тактового домена в другой. Последующие поколения FPGA, начиная с UltraScale, ориентированы только на архитектуру GALS. В этих ПЛИС используется ступенчатая схема синхронизации, при которой каждый регион имеет собственный тактовый генератор и синхронным может быть только схема, расположенная в границах тактового региона. Использование приемов передачи данных между различными тактовыми сетями (ресинхронизация, также CDC — Clock Domain Crossing) рассмотрено в следующих главах. II Ошибкой является предположение, что использование только буфера BUFG достаточно, чтобы тактовый сигнал был подан на все тактовые входы, внутренних компонентов ПЛИС одновременно. Использование формирователей тактового сигнала (DCM, ММСМ, PLL) является обязательным. Игнорирование этого правила моснсет служить источником труднообнаружимых ошибок и нестабильной работы проекта.
78 Глава! 1.10. Высокоскоростные последовательные приемопередатчики Приемопередатчики (MGT, MultiGigabit Transceivers) являются важным аппаратным компонентом ПЛИС, устанавливаемым в основном в FPGA большого логического объема. Переход к высокоскоростным последовательным внешним интерфейсам — заметная современная тенденция в проводных коммуникациях. Достаточно упомянуть такие интерфейсы как PCI Express, SATA, USB — все они характеризуются передачей данных по дифференциальной паре со скоростью несколько Гбит/с. Параллельные цифровые интерфейсы имеют ряд ограничений, которые не дают увеличивать скорость передачи данных выше пределов 1,5...2 Гбит/с. При попытке проложить проводники между двумя микросхемами на печатной плате между отдельными разрядами параллельной шины данных возникнет разница в задержке распространения сигнала, которая к тому же будет зависеть от температуры, напряжения питания и технологического разброса параметров микросхем и проводников. Рано или поздно неравномерность станет сравнима с длительностью передачи одного параллельного слова, и окажется, что если отдельные разряды данных было выровнены на стороне микросхемы-источника, то на стороне микросхемы-приемника из-за неравномерности задержки в проводниках одновременно присутствуют разряды, принадлежащие разным параллельным словам. Последовательные интерфейсы освобождены от такого недостатка. Последовательность битов, переданных источником, будет в том же порядке поступать на приемник (очевидно, отдельные биты, переданные последовательно, не могут обогнать друг друга при любой длине соединительных проводников). Применение дифференциальной пары для передачи одного потока данных существенно повышает помехоустойчивость — помехи, наведенные на один из проводников, скорее всего будут на том же уровне присутствовать и на втором проводнике (подразумевая, что проводники имеют одну и ту же форму и проложены максимально близко друг к другу). Поэтому разность потенциалов на стороне приемника будет определяться в основном разностью потенциалов, сформированной источником, при минимальном воздействии помех. Передача и прием сигналов со скоростью единицы-десятки Гбит/с не могут осуществляться с помощью цифровых буферов ввода-вывода. Необходимо использовать специальные формирователи выходного дифференциального сигнала (transmitter) и приемники
Начальные сведения об архитектуре ПЛИС ХШпх 79 Rx Ячейки FPGA Рис. 1.64. Структура приемопередатчика [receiver). Комбинация передатчика и приемника носит название transceiver (приемопередатчик). Широко известна сетевая модель OSI (open systems interconnection basic reference model — базовая эталонная модель взаимодействия открытых систем), которая предусматривает использование 7 уровней представления — от высокоуровневого прикладного (application) до низкоуровневого физического (physical). Приемопередатчики, используемые в ПЛИС ХШпх, реализуют второй и третий уровень — Physical Media Attachment (PMA) и Physical Coding Sub-Layer (PCS). Структура приемопередатчика показана на рис. 1.64. Схематично показанная внутренняя структура приемопередатчика в данном случае призвана продемонстрировать, что этот компонент представляет собой сложный модуль, принципиально отличающийся от обычного цифрового вывода ПЛИС. На уровне РМА выполняется преобразование между параллельным и последовательным представлением данных, размещаются физические драйверы электрического стандарта CML, а также реализуется предыскажение выходного сигнала для компенсации снижения амплитуды высокочастотных составляющих на внешних проводниках. На уровне PCS приемопередатчик реализует кодирование 8b/10b, а также имеет встроенный генератор псевдослучайных последовательностей (PRBS — Pseudo Random Binary Sequence) для тестирования передачи данных. Подключение к матрице программируемых ячеек ПЛИС выполняется с помощью параллельного интерфейса. Таким образом, четвертый уровень модели OSI, MAC (Media Access Control) должен быть реализован в виде конфигурируемого ядра. Исключением является контроллер PCI Express, который присутствует во многих семействах ПЛИС и реализует и МАС-уровень. Приемопередатчики не следует рассматривать как разновидность программируемых выводов, с помощью которых можно пере-
80 Глава 1 Таблица 1.14 Характеристики приемопередатчиков ПЛИС ХШпх Семейство ПЛИС Spartan-6 LXT Artix-7 Kintex-7 Kintex-7 Virtex-7 Virtex-7 XT Virtex-7 HT UltraScale UltraScale UltraScale Plus UltraScale Plus Versal Versal Обозначение приемопередатчика GTP GTP GTP GTX GTX GTH GTZ GTH GTY GTH GTY GTY GTM Максимальная скорость передачи данных, Гбит/с 3.125 6,6 6,6 12,5 12,5 13,1 28,05 16,3 30,5 16,3 32,75 32,75 58 давать сигналы между микросхемами с высокой скоростью так же, как это происходит для электрических стандартов TTL или LVDS. Важной особенностью приемопередатчиков является их пакетный режим работы. Поэтому средняя скорость передачи данных пользователя оказывается ниже скорости передачи одного бита по физическому каналу связи. Приемопередатчики в разных семействах ПЛИС имеют вариации, отличающиеся максимально поддерживаемыми скоростями передачи данных. Характеристики приемопередатчиков приведены в табл. 1.14. Применение приемопередатчиков в проектах на базе ПЛИС является сложной и ответственной деятельностью. Крайне важно здесь то, что высокий риск при разработке таких проектов состоит как раз не в настройке приемопередатчика в ПЛИС, а в реализации печатной платы, способной обеспечить передачу сигналов в гигагерцовом диапазоне. Кроме собственно проектирования печатной платы, важен также выбор материалов и контроль качества в процессе изготовления. Можно также указать, что для тривиальной визуализации сигнала на печатных проводниках необходимо использовать специальное дорогостоящее измерительное оборудование, поэтому изучение информации о работе приемопередатчиков еще не гарантирует успешного изготовления собственного устройства с высокоскоростными линиями передачи данных. Конфигурирование приемопередатчиков выполняется сравнительно несложно, с помощью имеющихся в САПР ХШпх мастеров настройки. Можно повторить, что существенно более сложным процессом здесь является проектирование печатной платы.
Начальные сведения об архитектуре ПЛИС ХШпх 81 1.11. Аппаратные контроллеры PCI Express С использованием модулей приемопередатчиков можно построить контроллер широко распространенной шины PCI Express. Однако такая шина требует наличия в ПЛИС контроллера, способного обеспечить взаимодействие с материнской платой, выступая в качестве конечного устройства (Endpoint) или корневого концентратора (Root). Несмотря на то что контроллер PCI Express может быть построен и на базе ячеек ПЛИС (исключая физические линии передачи данных, для которых требуются приемопередатчики), для экономии ресурсов ПЛИС, а главное, для получения предсказуемых результатов, не требующих повторения процесса трассировки ядра контроллера для каждого проекта, в современных семействах ПЛИС ХШпх обычно размещают аппаратные компоненты контроллера PCI Express. Применяется несколько поколений (generation) PCI Express, отличающихся скоростью передачи данных в физическом канале. Эти скорости составляют: • 2,5 Гбит/с для Gen 1; • 5 Гбит/с для Gen 2; • 8 Гбит/с для Gen 3; • 16 Гбит/с для Gen 4. Как и другие высокоскоростные последовательные интерфейсы, PCI Express предполагает пакетную передачу данных. Это означает, что для передачи некоторого массива данных по PCI Express в действительности необходимо передать больше данных с точки зрения физического канала — разбить данные на пакеты, добавить к пакету служебные поля, обеспечить задержку между пакетами. Поэтому крайне важно при планировании применения PCI Express ориентироваться не на пиковую скорость, указанную в спецификации, а на реальную скорость передачи пользовательских данных, учитывающую алгоритмы формирования пакетов и процент их заполнения полезными пользовательскими данными. Также важно, что PCI Express при наличии нескольких линий передачи (lane) не обеспечивает автоматического ускорения передачи одного пользовательского пакета. Так, шина PCI Express х1б не является 16-разрядной, а содержит 16 отдельных каналов, с помощью которых можно передавать 16 пакетов данных. Выигрыш от применения такой шины можно получить, если архитектура устройства действительно требует передачи независимых пакетов данных. Например, современные графические карты используют шину PCI
82 Глава 1 Таблица 1.15 Характеристики контроллеров PCI Express, используемых в ПЛИС Xilinx Семейство ПЛИС Spartan-6 LXT Artix-7 Kintex-7 Virtex-7 T Virtex-7 XT UltraScale UltraScale Plus Versal Программируемая реализация Genl xl — Gen3 x8 Gen3 x8 Gen3 x8 Gen3 x8 Gen3 xl6 Gen4 x8 Аппаратная реализация _ Genl x4 Gen2 x8 Gen2 x8 Gen3 x8 Gen3 x8 Gen3 xl6 Gen4 x8 Express х1б, поскольку можно организовать, например, независимую передачу нескольких текстур высокого разрешения. Характеристики контроллеров PCI Express, используемых в ПЛИС Xilinx, приведены в табл. 1.15. Настройка контроллера PCI Express выполняется с помощью входящих в состав САПР инструментов и с точки зрения проектирования не представляет особенной сложности. Подробно процесс настройки изложен в технической документации, входящей в состав как САПР, так и отладочных плат на базе ПЛИС Xilinx. Как и для любого высокоскоростного интерфейса, основная сложность проектирования заключается в обеспечении требуемых характеристик печатной платы. 1.12. Модуль DeviceDNA Специальный модуль DNA (в переводе — ДНК, по аналогии с ДНК-кодом живых организмов) предназначен для организации защиты интеллектуальной собственности. Этот модуль содержит 57-битовый код, уникальный для каждого экземпляра ПЛИС. Код может быть произвольно использован разработчиком для проверки уникальности устройства. Если проект содержит проверку DNA- кода устройства, несанкционированное копирование конфигурации станет бессмысленным, поскольку несанкционированно скопированный конфигурационный файл будет пригоден для работы в един- DNA PORT Рис. 1.65. Схематическое представление компонента DeviceDNA ственном экземпляре ПЛИС. Разработчик может самостоятельно выбрать реакцию своего проекта на несовпадение кода. На рис. 1.65 показан компонент DeviceDNA. Назначение выводов компонента Device DNA достаточно несложное. Все операции производятся по фронту тактового сигнала CLK. Высокий уровень на входе READ ини-
Начальные сведения об архитектуре ПЛИС ХШпх 83 циализирует чтение внутреннего параллельного 57-разрядного регистра. Бели на входе READ присутствует логический 0, а на входе SHIFT логическая 1, то по фронту сигнала CLK на выходе DOUT появится очередной бит 57-разрядного кода. При этом в сдвиговый регистр модуля вдвигается бит, присутствующий на входе DIN. Таким образом последовательность, читаемая из модуля, может быть расширена до любой длины (но по сигналу READ сдвиговый регистр будет проинициализирован уникальным для каждого кристалла 57- разрядным значением). Код Device DNA может быть прочитан по интерфейсу JTAG с помощью программатора, без загрузки проекта в ПЛИС. Этот код не содержит какой-то специфической информации о семействе ПЛИС и, по опыту практического использования, не может быть заранее предсказан. Выпуск крупной серии изделий с защитой по коду Device DNA необходимо планировать с учетом того, что компания ХШпх пока не предоставляет готового пути поставки ПЛИС с заранее заказанными кодами или с серией последовательно идущих кодов. Способ защиты проекта по Device DNA находится полностью в компетенции разработчика. Каких-либо заранее предусмотренных на аппаратном уровне действий при несовпадении Device DNA с заранее заданными константами в ПЛИС не имеется, Разработчик может предусмотреть остановку работу проекта, вывод информационных сообщений через подключенные к ПЛИС интерфейсы, переход к работе в режиме ограниченной функциональности и т. п. Использование компонента в проектах требует использования подхода component instantiation, т. е. ссылки на аппаратный примитив из библиотеки ХШпх. 1.13. Модуль AMS (Agile Mixed Signal, только для серии 7) ПЛИС серии 7 и последующие имеют аппаратный компонент аналого-цифрового преобразователя, расположенный на кристалле и доступный как со стороны программируемых ресурсов, так и по интерфейсу JTAG. Этот компонент носит название AMS (Agile Mixed Signal), его общую схему иллюстрирует рис. 1.66. В основе модуля AMS два независимых аналого-цифровых преобразователя с разрядностью 12 битов и скоростью преобразования 1 MSPS A млн преобразований в секунду). Входной аналоговый диапазон составляет 0...1 В. АЦП имеют дополнительные скрытые разряды для компенсации нелинейностей, так что разрядность 12
84 Глава 1 Аналоговая часть Цифровая часть 17 внешних входов U, Т АЦП1 АЦП2 Датчики напряжения 12 битов, и температуры 1 MSPS Регистры состояния и управления Порт реконфигурации JTAG Рис. 1.66. Схема модуля AMS битов соответствует максимальной ошибке 1 разряд (при условии стабильного опорного напряжения). Обеспечивается работа в диапазоне температур -40. ..+125 °С. Для работы АЦП рекомендуется использовать внешний источник опорного напряжения 1,25 В. Оно подается на выделенные входы ПЛИС. Ряд внутренних напряжений и датчик температуры являются выделенными линиями и доступны как для измерений проектом пользователя, так и без загрузки конфигурации через интерфейс JTAG. Внешние аналоговые входы модуля AMS совмещены с выводами общего назначения. В небольших корпусах ПЛИС не все внешние выводы АЦП могут быть подключены к выводам корпуса. 1.14. Таблицы характеристик ПЛИС Xilinx В данном разделе приведены таблицы с основными характеристиками актуальных для применения ПЛИС Xilinx. Характеристики ПЛИС UltraScale, UltraScale Plus и Versal, как и подробные характеристики ПЛИС, приведенных в табл. 1.16-1.21, Таблица 1.16 Основные характеристики ПЛИС Zynq-7000 с матрицей ячеек Artix Характеристика Секции Блоки памяти DSP 10, макс XC7Z007S 3600 50 66 100 XC7Z012S 8600 72 120 150 XC7Z014S 10150 107 170 200 XC7Z010 4400 60 80 100 XC7Z015 11550 95 160 150 XC7Z020 13300 140 220 200 Таблица 1.17 Основные характеристики ПЛИС Zynq-7000 с матрицей ячеек Kintex Характеристика Секции Блоки памяти DSP Ю, макс XC7Z030 19650 265 400 250 XC7Z035 42975 500 900 362 XC7Z045 54650 545 900 362 XC7Z100 69350 755 2020 400
Таблица 1.18 Основные характеристики ПЛИС Spartan-6 Характеристика Секции Блоки памяти DSP IO, макс СМТ XC6SLX4 600 12 8 132 2 XC6SLX9 1430 32 16 200 2 XC6SLX16 2278 32 32 232 2 XC6SLX25 3758 52 38 266 2 XC6SLX45 6822 116 58 358 4 XC6SLX75 11662 172 132 408 6 XC6SLX100 15822 268 180 480 6 XC6SLX150 23038 268 180 576 6 Таблица 1.19 Основные характеристики ПЛИС Artix-7 Характеристика Секции Блоки памяти DSP Ю СМТ GTP ХС7А12Т 2000- 20 40 150 3 2 ХС7А15Т 2600 25 45 250 5 4 ХС7А25Т 3650 45 80 150 3 4 ХС7А35Т 5200 50 90 250 5 4 ХС7А50Т 8150 75 120 250 5 4 ХС7А75Т 11800 105 180 300 6 8 ХС7А100Т 15850 135 240 300 6 8 ХС7А200Т 33650 365 740 500 10 16 Основные характеристики ПЛИС Kintex-7 Таблица 1.20 Характеристика Секции Блоки памяти DSP Ю, макс СМТ GTX ХС7К70Т 10250 135 240 300 6 8 ХС7К160Т 25350 325 600 400 8 8 ХС7К325Т 50950 445 840 500 10 16 ХС7К355Т 55650 715 1440 300 6 24 ХС7К410Т 63550 795 1540 500 10 16 ХС7К420Т 65150 835 1680 400 8 32 ХС7К480Т 74650 955 1920 400 8 32
86 Глава 1 Основные Характеристика Секции Блоки памяти DSP Ю, макс СМТ XC7S6 938 5 10 100 2 Таблица 1.21 характеристики ПЛИС Spartan-7 XC7S15 2000 10 20 100 2 XC7S25 3650 45 80 150 3 XC7S50 8150 75 120 250 5 XC7S75 12000 90 140 400 8 XC7S100 16000 120 160 400 8 указаны в документации на официальном сайте производителя. Характеристики дорогостоящих ПЛИС большого логического объема здесь не приводятся из-за чрезмерного объема этой информации и нацеленности данного издания на применение ПЛИС начального и среднего уровня, к которому относятся семейства Spartan, Artix, Zynq и частично Kintex. Важным и неоднозначным вопросом является понятие «тактовая частота ПЛИС». Неверное понимание этого термина может приводить к существенным ошибкам в оценке достижимых технических параметров проекта. В документации производителя приводится параметр «системная тактовая частота». Он составляет, например, 325 МГц для Spartan-6, 450 МГц для Artix-7 и основанных на этом семействе ПЛИС Zynq-7000 (до ZC7020 включительно) и 740 МГц для Kintex-7 и Virtex-7. Системная тактовая частота может быть ошибочно принята за частоту, безусловно поддерживаемую ПЛИС для проекта любой сложности. В действительности это условный параметр, оцениваемый для схемы, обладающей следующими свойствами: • между триггерами расположено не более одной LUT; • триггеры расположены в непосредственной близости и не используют длинные трассировочные линии; • цепи ускоренного переноса объединяют счетчики не более 14 разрядов. На практике достижение системной тактовой частоты практически нереально. Вероятнее достижение частоты работы схемы в 2...3 раза ниже, чем заявленная для данного семейства системная тактовая частота. Это связано как с тем, что между какими-то парами триггерами будет расположено более одной LUT, так и с более сложной трассировкой, вносящей дополнительную задержку. В процессе изготовления интегральных схем параметры отдельных кристаллов оказываются различными. Нецелесообразно чрезмерно занижать достижимые характеристики, чтобы быть уверенными, что любая микросхема способна их обеспечить. Вместо этого
Начальные сведения об архитектуре ПЛИС ХШих 87 при контроле качества производится разделение микросхем на подгруппы в соответствии с их реальными техническими характеристиками. Для обозначения производительности используется несколько «классов скорости» (speed grade). Классы скорости обозначаются цифрой и соответствуют принципу «больше индекс — выше тактовая частота». Отличие в производительности составляет 10... 15 % между каждыми соседними классами скорости. 1.15. ПЛИС с архитектурой CPLD Архитектура CPLD (Complex Programmable Logic Device) принципиально отличается от FPGA и предоставляет существенно меньше программируемых ресурсов. Выпускаемые семейства CPLD компании Xilinx представлены семейством CoolRunner-II. Это семейство выпускается с соблюдением норм 180-нм технологического процесса и использует для хранения конфигурации внутреннюю флеш- память. Таким образом, основное преимущество CPLD заключается в их энергонезависимости. С учетом простой внутренней архитектуры и минимальных требованиях к внешним компонентам микросхемы CPLD удобно использовать в цифровых системах в качестве замены дискретной логики (logic consolidator) или для других вспомогательных функций. Семейство CoolRunner-II отличается также малым статическим потреблением (от 28,8 мкВт), поэтому его можно рассматривать и для систем с автономным питанием. Архитектура микросхем CPLD семейства CoolRunner-II показана на рис. 1.67. Можно видеть, что CPLD имеют существенно более простую структуру по сравнению с PPGA. В целом эти ПЛИС также имеют программируемые ячейки и блоки ввода-вывода, однако ячейки (а точнее, макроячейки — macrocell) не образуют прямоугольную матрицу, а группируются в функциональные блоки по 16 макроячеек. В каждом блоке матрица PAL вычисляет до 56 термов от 40 входных сигналов, которые управляются коммутационной матрицей. В каждой макроячейке имеется D-триггер. Блоки ввода-вывода в CoolRunner-II подключаются к соответствующим выходам функциональных блоков. Таким образом, возможности гибкой коммутации внутри кристалла у CPLD существенно ограничены по сравнению с FPGA. Тем не менее для простых Блоки ввода-вывода Функциональный блок 1 16 / PLA 16 ячеек * / Коммута- ционная матрица Функциональный блокИ 40 / fc / * PLA 16 ячеек 16 / / Блоки ввода-вывода Рис. 1.67. Архитектура микросхем CPLD семейства CoolRunner-II
88 Глава 1 Основные характеристики CPLD Характеристика Макроячейки Программируемые выводы, макс. Время распространения сигнала, не Системная тактовая частота, МГц Типичное потребление в статическом при 25° С, мкА Типичное потребление на частоте 50 режиме @ МГц) МГц при 70°С, мА ХС2С32А 32 33 3,8 323 16 2,5 схем назначение сигнала на определенный вывод обычно решается автоматически, так как САПР вычисляет этот сигнал в соответствующем функциональном блоке. Напряжение питания ядра CoolRunner-II составляет 1,8 В. Блоки ввода-вывода имеют отдельную линию питания и могут использовать напряжения 1,5...3,3 В. Имеются выделенные входы для подачи тактового сигнала (которые могут также использоваться и в качестве обычного входа или выхода). Программирование CoolRunner-II осуществляется с помощью интерфейса JTAG, сигналы которого имеют фиксированное расположение для каждого корпуса этих ПЛИС. Программирование выполняется теми же аппаратными и программными средствами, что и для FPGA Xilinx. После программирования ПЛИС может быть защищена от обратного считывания конфигурационного файла. Тем самым обеспечивается защита от несанкционированного копирования проектов. Основные характеристики CPLD семейства CoolRunner-II приведены в табл. 1.22. В табл. 1.22 можно видеть нехарактерные для FPGA параметры производительности — время распространения сигнала и системную тактовую частоту. Из-за существенно более простой архитектуры время распространения сигнала в CPLD можно предсказать заранее, поскольку оно не зависит от взаимного расположения компонентов и использованных трассировочных ресурсов. Существенно более простая коммутация сигналов дает возможность довольно точно прогнозировать время распространения сигнала и достижимую тактовую частоту. Необходимо учитывать, что при построении сложных схем, таких как многоразрядные счетчики, задержка сигнала между отдельными разрядами будет суммироваться и тактовая частота упадет относительно указанного значения «системной тактовой частоты».
Начальные сведения об архитектуре ПЛИС Xilinx 89 Таблица 1.22 семейства CoolRunner-II ХС2С64А 64 64 4,6 263 17 5 ХС2С128 128 100 5,7 244 19 10 ХС2С256 256 184 5,7 256 21 27 ХС2С384 384 240 7,1 217 23 45 ХС2С512 512 270 7,1 179 25 55 В отличие от FPGA, CPLD выпускаются в основном в дешевых пластиковых корпусах: QPG32, VQG44, QFG48, CPG56, VQG100, CPG132, TQG144, PQG208, TFG256, FGG324. Полный перечень корпусов, имеющихся в наличии для каждого из вариантов ПЛИС CoolRunner-II, следует уточнять в документации производителя (CoolRunner-II CPLD Family Product Specification). В целом из-за энергонезависимости, невысокой стоимости и исполнения в простых для монтажа пластиковых корпусах микросхемы CPLD могут использоваться в простых проектах с невысокими требованиями к логическому объему. Тем не менее при необходимости использовать сотни и тысячи триггеров целесообразнее (и экономически выгоднее) использовать недорогие FPGA. 1.16. Условное обозначение микросхем ПЛИС Xilinx Расшифровка условного обозначения ПЛИС Xilinx показана на рис. 1.68. Условное обозначение (part number) имеет основные компоненты, показанные на рис. 1.68. Например, код 7S относится к семейству Spartan-7, a 50 означает логический объем в тысячах эквивалентных ячеек. Для каждого корпуса обычно существует набор сочетаний класса скорости (speed grade) и температурного диапазона. Поскольку обеспечить работу микросхем при большой температуре сложнее, часто бывает, что цена на микросхему в коммерческом ХС 7 S 50 -2 FG G A484 С Тип ПЛИС Класс скорости Тип корпуса Признак Pb-free Температурный диапазон: С- Commertial @..+85 вС) I - Industrial (-40..+100 °С) Q - Expanded (-40..+125 °С) Число выводов Рис. 1.68. Условное обозначение ПЛИС Xilinx
90 Г л а в а 1 диапазоне класса скорости —2 равна цене той же микросхемы в индустриальном температурном диапазоне, но с классом скорости —1. В целом вопросы ценообразования для ПЛИС ХШпх достаточно сложны. С учетом большой номенклатуры микросхем и необходимости их заказа на полупроводниковой фабрике (в настоящее время основным производителем для Xilinx является компания TSMC), Xilinx придерживается политики ранней регистрации проектов с предоставлением заказчикам специальных цен. Недорогие ПЛИС могут не предполагать специальных цен, однако в настоящее время ценовая политика является достаточно гибкой. Основной рекомендацией Xilinx является возможно более раннее обращение к региональному дистрибьютору с предоставлением перечня интересующих заказчика микросхем. Основным назначением такой рекомендации является сбор статистических данных о потребностях в ПЛИС различного типа, и заявка на регистрацию проекта не означает, что разработчик обязуется впоследствии приобрести эти микросхемы. Для России регистрация проектов может быть выполнена у дистрибьютора www.plis.ru.
2 САПР ISE и Vivado — быстрый старт Компания Xilinx выпускает системы автоматизированного проектирования (САПР), позволяющие вести сквозную разработку — от ввода схемы до загрузки конфигурации ПЛИС с помощью внешнего программатора. Основные этапы проектирования показаны на рис. 2.1. Процесс проектирования для ПЛИС состоит из следующих этапов. Этап 1. Ввод схемы производится в основном с помощью языков описания аппаратуры (HDL, Hardware Description Language). Основными в настоящее время считаются VHDL и Verilog HDL (чаще упоминаемый как просто Verilog). Эти языки в основном предоставляют ёозможность описания проекта на туровне регистровых передач (RTL, Register Transfer Level). Кроме того, тексты на языках описания аппаратуры могут быть автоматически сгенерированы с помощью более высокоуровневых средств — например, встроенного в САПР Xilinx набора утилит Core Generator, использующего диалоговые окна для автоматической настройки параметров и генерации схемы. Также существуют языки, основанные на Си, поддерживаемые отдельной САПР Vivado HLS (High-Level Synthesis). Эти языки преобразуют Си-подобное описание в RTL-представление проекта на VHDL или Verilog. Ввод схемы • Языки описания аппаратуры • Генерация IP-ядер • Схемотехнический/блочный ввод Синтез • Встроенный в САПР Xilinx синтезатор • Синтезаторы сторонних фирм Размещение • Только САПР Xilinx (закрытый формат и трассировка конфигурационного файла) Загоузка * Программаторы Xilinx конфигурации -Программаторы сторонних фирм ^ jk«m I 9 протокол загрузки открыт и документирован Рис. 2.1. Основные этапы проектирования для ПЛИС
92 Глава 2 Этап 2. Синтез проекта подразумевает создание списка связей (netlist) на основе введенного описания. Процесс обработки исходных текстов и создания на их основе схемы может производиться различными, более или менее эффективными способами, а форматы списков связей являются промышленными стандартами, например EDIP (Electronic Design Interchange Format). Поэтому программы- синтезаторы выпускаются многими компаниями, и САПР Xilinx может использовать как встроенный синтезатор, так и синтезаторы сторонних фирм. Вопрос использования встроенного или стороннего синтезатора является открытым, однако можно утверждать, что наличие только встроенного синтезатора не является основанием для отказа от разработки проекта. Этап 3, Размещение и трассировка проекта. Эта группа проектных действий входит в состав стадии САПР implementation, название которой дословно можно перевести как «реализация» или «осуществление», однако в русском языке этот термин является несколько неопределенным и его трудно однозначно связать с проектным шагом, а не просто с общим процессом работы над проектом. На данной стадии производится преобразование списка связей в информацию о размещении отдельных элементов ПЛИС на кристалле и настройке программируемых соединений между ними. Сведения о структуре ПЛИС и формате конфигурационной последовательности являются закрытыми, и этот шаг может быть реализован только с помощью САПР Xilinx. Этап 4. Загрузка конфигурации (файла .bit) выполняется множеством способов с применением программаторов производства Xilinx, сторонних фирм или собственных разработок. Протокол загрузки файла .bit в ПЛИС Xilinx является открытым и хорошо документирован. В состав САПР Xilinx входят встроенные в основной маршрут проектирования утилиты программирования. Таким образом, при наличии САПР Xilinx становится возможным проведение полного цикла проектирования — от ввода схемы до физической загрузки конфигурационного файла в ПЛИС, подключенную к программатору. Для семейств ПЛИС, описанных в данном издании, актуальны две разновидности САПР. Семейство Spartan-б и часть микросхем серии 7 поддерживаются предыдущим поколением САПР — ISE Design Suite (Integrated System Environment). Эта САПР существует уже достаточно длительное время и с появлением серии 7 обновление данного продукта было прекращено. Для серии 7 и последующих необходима САПР Vivado. Схематично поддержка
САПР ISE и Vivado — быстрый старт 93 \ ISE DESIGN 54ЙТ? VIRTEX* KNTEX* VIVADO: VIRTgf KNTEX* Рис. 2.2. САПР Xilinx и поддерживаемые семейства ПЛИС ПЛИС Xilinx инструментами проектирования показана на рис. 2.2. Ряд ПЛИС серии 7 поддерживаются и в САПР ISB, но ввиду существенного изменения алгоритмов размещения и трассировки САПР Vivado показывает для этих семейств существенно лучшие результаты. Кроме того, семейство недорогих ПЛИС Spartan-7 поддерживается только в САПР Vivado. 2.1. Быстрый старт в САПР Vivado САПР Vivado в настоящее время является основным инструментом сквозного проектирования для ПЛИС Xilinx. Понятие «сквозной» подразумевает, что с помощью этой САПР можно провести полный цикл проектирования, от ввода проекта до программирования ПЛИС, подключенной к компьютеру. САПР Vivado появилась в 2012 году в качестве замены предыдущему поколению — САПР ISE Design Suite. Важной причиной такой замены стала невозможность качественной трассировки проектов для появившихся FPGA большого логического объема. По заявлениям Xilinx, пределом, предусмотренным алгоритмами трассировки в ISE, является примерно 2 млн логических ячеек. Это было достигнуто для семейства Virtex- 7. Смена алгоритмов трассировки, произведенная в САПР Vivado, позволила увеличить этот предел и, по сравнению с ISE, получать существенно лучшие результаты для ПЛИС с сотнями тысяч и более логических ячеек. САПР Vivado предназначена для ПЛИС серии 7 и последующих. Семейство Spartan-б, рассматриваемое в данной книге, не поддерживается в Vivado. Для работы с Vivado можно использовать следующие операционные системы: • Windows 7 SP1 F4-bit); • Windows 10 Pro F4-bit);
94 Г лав а 2 • Red Hat Enterprise Workstation/Server 7.2, 7.3, 7.4 F4-bit); • Red Hat Enterprise Workstation 6.6, 6.7, 6.8, 6.9 F4-bit); • SUSE Linux Enterprise 11.4, 12.3 F4-bit); • CentOS 7.2, 7.3, 7.4 F4-bit); • CentOS 6.7, 6.8, 6.9 F4-bit); • Ubuntu Linux 16.04.3 LTS F4-bit). Для работы с ПЛИС рекомендуется обратить внимание на объем оперативной памяти компьютера. Этот параметр на практике оказывает большее влияние на скорость работы САПР, чем тактовая частота процессора. Рекомендуемый объем памяти напрямую зависит от логического объема ПЛИС, для которой создается проект, и если для небольших FPGA рекомендацией является 1...2 Гбайт свободной памяти, то для ПЛИС большого объема может потребоваться 8, 16 или 32 Гбайт для комфортной работы. Типичное и пиковое потребление памяти указано на странице https://www.xilinx.com/pro- ducts/design-tools/vivado/memory.html, где максимальным значением является 48 Гбайт для FPGA XCVU440. Необходимо отметить, что эта микросхема существенно дороже рабочей станции, способной обеспечить эффективную трассировку проекта. В целом для работы с Vivado следует ориентироваться на ощущение комфортной работы с используемыми семействами ПЛИС, Монитор с высоким разрешением и 16...32 Гбайт памяти — рекомендуемые характеристики рабочей станции. Текущая версия дистрибутива Vivado может быть свободно загружена с сайта компании Xilinx. Существует бесплатная лицензия Vivado Webpack, имеющая ограничения по логическому объему поддерживаемых ПЛИС. Ограничения нельзя признать существенными, поскольку неподдерживаемые микросхемы относятся к высокопроизводительным и дорогостоящим, и возможность их приобретения делает стоимость лицензии Vivado сравнительно приемлемой. В бесплатной версии поддерживаются семейства Spartan-7, Ar- tix-7, семейство Zynq-7000 вплоть до ZC7030, Zynq UltraScale-f вплоть до XCZU7, Kintex-7 до ХС7К160Т, Kintex UltraScale XCKU025, XCKU035, Kintex UltraScale+ XCKU3P. XCKU5P. Серия Virtex не поддерживается в бесплатной версии САПР. Для подключения программатора достаточно свободного порта USB. После запуска установленной САПР на экране появится стартовая страница, показанная на рис. 2.3. В группе Quick Start («быстрый старт») имеются очевидные пункты Create Project («создать проект») и Open Project («открыть
САПР ISE и Vivado — быстрый старт 95 Рис. 2.3. Стартовая страница САПР Xilinx Vivado проект»). При создании нового проекта запускается мастер, представляющий собой последовательность диалоговых окон. После приглашающего окна с общей информацией появляется окно, в котором необходимо выбрать имя и размещение нового проекта, как показано на рис. 2.4. В поле Project name вводится желаемое имя проекта. Папка с проектом будет размещена в Project location. Рекомендуется выбирать имя проекта по тем же правилам, что и имена переменных (использовать символы латинского алфавита, цифры и символ подчеркивания, начинать имя с алфавитного символа). Также не рекомендуется размещать проекты в папке «Мои документы» и вообще использовать символы кириллицы, поскольку не все утилиты, входящие в набор средств проектирования, корректно обрабатывают символы кириллицы и пробелы. В ряде случаев встречается ситуация, когда САПР сообщает об ошибке доступа к файлу «С:\Мои», поскольку следующий за этим фрагментом пробел был ошибочно
96 Г л а в а 2 Рис. 2.4. Выбор имени и расположения нового проекта в САПР Vivado использован для выделения аргумента командной строки. Компания ХШпх совершенствует свои программные продукты, однако во избежание подобных рисков следует исключать саму возможность некорректной обработки имен файлов. Создание отдельной папки для проектов ХШпх упрощает работу. В показанном примере используется папка C:/XProject для хранения всех проектов для САПР ISE и Vivado. Следующее диалоговое окно выбирает тип проекта, как показано на рис. 2.5. По умолчанию установлен RTL Project. Это основной вариант работы с Vivado, который подразумевает добавление описаний в стиле RTL (т. е. на языках описания аппаратуры) и создание файла конфигурации ПЛИС на основе этих описаний. Если установить флажок «Do not specify sources at this time», мастер создания проекта пропустит этап добавления файлов к проекту. Если же оставить этот пункт без изменений, будет предложено добавить к проекту существующие файлы или создать новый, как показано на рис. 2.6. После нажатия кнопки Create File появится дополнительное диалоговое окно Create Source File. В этом окне необходимо установить тип файла (в данном случае выбирается файл на языке описания аппаратуры VHDL). Также необходимо ввести имя файла. Имя рекомендуется вводить с учетом правил выбора идентификаторов в VHDL, поскольку оно будет использовано для создания идентификатора в шаблоне описания, а к идентификаторам применимы в целом те же правила, что и для имен переменных в программировании. Дополнительными, более строгими ограничениями в VHDL
САПР ISE и Vivado — быстрый старт 97 Рис. 2.5. Выбор типа проекта в САПР Vivado являются запрет на несколько символов подчеркивания подряд и запрет на завершение имени символом подчеркивания. Следующим необязательным шагом является добавление файла проектных ограничений, как показано на рис. 2.7. Файл проектных ограничений требуется для задания тех правил проектирования, которые не могут быть описаны на языках описания аппаратуры. В простейшем варианте необходимо привязать сигналы к выводам ПЛИС, а это, очевидно, выходит за рамки языков описания аппаратуры. Поэтому подобные сведения о проекте приводятся в файле специального формата xdc (Xilinx Design Constraints). В примере для файла проектных ограничений выбрано имя pins («выводы»), поскольку в этом файле будут содержаться только ограничения, касающиеся привязки сигналов проекта к выводам ПЛИС. Следующий этап — выбор ПЛИС, для которой будет создаваться файл конфигурации. В процессе проектирования можно поме-
98 Г лав а 2 Рис. 2.6. Создание нового модуля для проекта Айй Ccnstraints (optional? Рис. 2.7. Добавление к проекту файла проектных ограничений нять ПЛИС, однако на старте проекта можно указать именно ту микросхему, которая будет использована в действительности. Для примера проекта использована отладочная плата Arty компании Digilent. На плате установлена ПЛИС XC7A35TIC§G324-1L, которая и выбрана на рис. 2.8.
САПР ISE и Vivado — быстрый старт 99 Рис. 2.8. Выбор ПЛИС для проекта После выбора ПЛИС появляется завершающее окно мастера, в котором достаточно нажать кнопку Finish. После этого будут созданы необходимые файлы нового проекта и для добавленного файла top.vhd будет предложено выполнить его описание, как показано на рис. 2.9. На этом рисунке заполнены поля для трех сигналов. Простейший пример будет включать в себя единственное логическое выражение, поэтому входные сигналы выбраны как а и Ь, а выходной — с. Колонка Direction управляет направлением сигналов. Для входов это in, а для выходов out. Бели сигнал описывается как многоразрядный (т.е. шина — bus), необходимо установить переключатель Bus напротив этого сигнала и задать старший (MSB) и младший (LSB) разряды этой шины. Для данного примера это не требуется. На данном этапе необязательно думать об окончательном виде интерфейса. Приведенное окно облегчает построение шаблона
100 Глава 2 Рис. 2.9. Описание интерфейса нового модуля с помощью графического интерфейса VHDL-описания, но этот шаблон может быть впоследствии отредактирован вручную. После завершения работы мастера откроется окно графической среды разработки Vivado, показанное на рис. 2.10. Левая часть окна содержит список процессов, доступных для проекта. Иерархия проекта показана в окне Project Manager. Видно, что созданный файл top.vhd находится на вершине иерархии в группе Design Sources, т.е. его входы и выходы станут выводами ПЛИС. В примере проекта только один файл, поэтому он принят САПР в качестве файла верхнего уровня (давать такому файлу имя top необязательно). Небольшой значок из трех прямоугольников, верхний из которых выделен цветом, дополнительно указывает на то, что САПР считает именно этот файл вершиной иерархии. После создания проекта необходимо описать поведение созданного модуля верхнего уровня. Для этого двойным щелчком на файле top можно открыть его для редактирования в основном рабочем поле САПР. Внешний вид редактора показан на рис. 2.11.
Рис. 2.10. Внешний вид графического интерфейса САПР Vivado после завершения создания нового проекта
102 Глава 2 tf X //' Рис. 2.11. Редактирование файла RTL-описания В этом файле уже сформирован шаблон RTL-описания. Для освоения маршрута проектирования можно добавить в этот файл простейшее поведение, описав вентиль 2И. Для этого в конце файла top.vhd, между строками begin и end Behavioral следует добавить строку с <= a and b; Не вдаваясь в подробности синтаксиса VHDL, можно указать, что в данном случае выход с проекта будет всегда принимать значение выражения «a and Ы. Подробное изучение языков описания аппаратуры приводится в главах 3 и 4. После сохранения отредактированного файла можно провести синтез проекта или сразу его трассировку. Как было указано выше, в процессе синтеза создается абстрактный список связей, а процесс Implementation производит размещение элементов схемы в логические ресурсы ПЛИС и трассировку программируемых соединений. Запуск этих процессов может быть проведен из панели управления САПР, расположенной в левой части окна. Выбор пунктов Run Synthesis или Run Implementation вызовет появление диалогового
САПР ISE и Vivado — быстрый старт 103 окна, как показано на рис. 2.12. На этом рисунке видно, что при запуске могут быть изменены следующие пункты: • стратегия САПР при реализации запускаемого процесса (детали будут рассмотрены в последующих главах); • число ядер процессора, которые могут быть задействованы в САПР Vivado (актуально для больших проектов, состоящих из множества модулей); • возможность генерации скриптов для последующего запуска на более мощной рабочей станции. В простом проекте, имеющем целью освоение маршрута проектирования, настройки могут быть оставлены по умолчанию. После создания списка связей или выполнения трассировки необходимо выполнить еще один обязательный шаг — задание проектных ограничений, чтобы сигналы проекта были назначены на определенные выводы ПЛИС. В САПР Vivado проектные ограничения задаются в специальном файле xdc (Xilins Design Constraints). Языки описания аппаратуры (VHDL или Verilog) не имеют средств назначения сигналов выводам ПЛИС, поэтому хотя бы один файл формата xdc должен присутствовать в проекте. Добавление файла к проекту может быть проведено в явном виде — через пункт Add Sources в панели управления (в группе Project Manager) и выбор типа файла Design Constraints. Также можно открыть синтезированный или трассированный проект (Open Synthesized Design, Open Implemented Design, однако по умолчанию после завершения процесса будет предложено открыть его) и в меню Layout выбрать пункт I/O Planning. После этого откроется представление корпуса выбранной для проекта ПЛИС, как показано на рис. 2.13. В этом представлении консоль САПР, расположенная в нижней части окна, содержит вкладку I/O ports. В ней следует последовательно раскрыть списки All ports, Scalar ports, где сгруппированы скалярные сигналы (в данном случае это означает «не являющиеся шинами»). В проекте, как было задано в VHDL-описании, присутствуют входы a, b и выход с. Разработчик имеет возможность привязать сигналы проекта к любым выводам ПЛИС, которые подключены к блокам ввода-вывода. На рис. 2.13 видно, что выводы корпуса ПЛИС помечены в САПР в зависимости от выполняемой ими функции. Например, в центре корпуса группируются выводы для подачи питания. Программируемые выводы обозначены круглыми символами, а выводы,
104 Глава 2 ¦>¦:-=
Рис. 2.13. Внешний вид окна САПР в процессе назначения выводов корпуса сигналам проекта
106 Глава 2 подключенные к тактовым буферам, — шестиугольниками. Подробные варианты использования можно изучить, увеличив масштаб изображения. Здесь же виден принцип обозначения выводов ПЛИС в корпусах типа BGA — используется комбинация из символа латинского алфавита и цифры (например, в левом верхнем углу корпуса находится вывод А1). Для того чтобы определить, к каким выводам ПЛИС следует подключать сигналы, недостаточно информации, имеющейся в САПР или в документации на саму ПЛИС. После установки ПЛИС на плату внешние компоненты могут быть подключены производителем платы самыми разными способами, поэтому требуется обратиться к технической документации на печатную плату. Для проекта была выбрана плата Arty производства компании Digilent, на одном из вариантов которой и установлена ПЛИС Artix-7 35T, заданная в настройках проекта. Внешний вид платы показан на рис. 2.14. Обратившись к технической документации, можно найти следующую информацию: • А8, СИ — входы ПЛИС, подключенные к переключателям платы; • Сб — выход ПЛИС, подключенный к одному из светодиодов. Щ Эти сведения относятся только к конкретной плате. Для каждого проекта необходимо изучить техническую документацию на используемую печатную плату и определить, к каким выводам ПЛИС подключены требуемые для проекта внешние компоненты. Рис. 2.14. Внешний вид отладочной платы Arty компании Digilent
САПР ISE и Vivado — быстрый старт 107 Определенные в документации на плату Arty обозначения выводов ПЛИС необходимо ввести в колонке Package Pin напротив каждого из сигналов проекта. Также для формата xdc обязательным требованием является явное указание электрического стандарта, используемого для вывода. Он задается в колонке I/O Std и по умолчанию указан как LVCMOS18 (т. е. низковольтный вариант КМОП с напряжением питания 1,8 В). Требуется в явном виде указать для всех сигналов стандарт LVCMOS33. По этому поводу необходимо сделать важное пояснение. ПЛИС не имеют возможности подключать заданные разработчиком напряжения к буферам ввода-вывода, ориентируясь на заданные в файле xdc сведения. Для питания будут использованы напряжения, фактически поданные на банки ввода-вывода (границы банков можно видеть на рисунке корпуса ПЛИС). Неверное указание напряжения в файле xdc не приведет к выходу ПЛИС из строя, однако рассчитанные задержки распространения сигналов окажутся неверными (они зависят от используемого напряжения питания). Однако для всех выводов, находящихся в одном банке ввода-вывода, требуется, чтобы напряжение электрических интерфейсов было одним и тем же. Поэтому разработчик должен явно указать в файле проектных ограничений электрический интерфейс, который он рассчитывает использовать. При появлении в одном банке интерфейсов с разным напряжением САПР сгенерирует ошибку и создание конфигурационного файла будет запрещено. После задания выводов для сигналов проекта в пункте Program and Debug можно запустить процесс Generate Bitstream. Он завершится выводом диалогового окна, показанного на рис. 2.15. В этом окне можно запустить утилиту программирования ПЛИС (пункт Open Hardware Manager). В данный момент САПР готова к загрузке конфигурации в ПЛИС. Можно подключить программатор и включить питание платы. Для платы Arty достаточно подключить кабель от разъема Micro USB к свободному порту USB компьютера (для небольших проектов этой плате достаточно питания от USB). В окне Hardware Manager следует выбрать пункт Open target (представленный в виде гиперссылки), как показано на рис. 2.16. В появившемся меню можно выбрать пункт Auto Connect, После установления соединения с ПЛИС она будет показана в списке подключенного оборудования. С помощью контекстного меню (правой кнопкой мыши) можно выбрать пункт Program Device,
108 Глава 2 Рис. 2.15. Запуск утилиты программатора после завершения создания конфигурационного файла Рис. 2.16. Запуск соединения с программатором Рис. 2.17. Запуск программирования ПЛИС при необходимости указав расположение созданного в САПР конфигурационного файла (с расширением .bit).
САПР ISE и Vivado — быстрый старт 109 После загрузки конфигурации можно экспериментально проверить работу проекта с помощью переключателей SWO, SW1 и све- тодиода LED0. 2.2. Быстрый старт в САПР ISE САПР ISE Design Suite (Integrated System Environment) представляет предыдущее поколение средств разработки для ПЛИС Xi- linx, являвшееся основным в 2000-х годах. Основным приложением, реализующим собственно среду разработки, является Project Navigator. Дальнейшее развитие данного продукта не предполагается, и последними из поддерживаемых семейств являются FPGA серии 7. САПР какое-то время будет сохранять свою актуальность, поскольку в ней поддерживаются и более старые семейства FPGA — Virtex-6, Spartan-6 и более ранние, которые не поддерживаются в САПР Vivado. В настоящее время основной причиной использования ISE является сохраняющаяся актуальность ПЛИС семейства Spartan-6. Не следует использовать ISE для семейств серии 7, поддерживающихся также в Vivado. Из-за существенного пересмотра алгоритмов трассировки Vivado показывает заметно лучшие результаты по сравнению с ISE. САПР ISE имеет бесплатную версию ISE Webpack, которая может быть свободно загружена с сайта Xilinx. Официальный перечень операционных систем не включает Microsoft Windows 10, для которого существует специальная версия ISE, основанная на виртуальной машине Oracle VM, в которой установлена ОС Linux. Требования к компьютеру для работы с САПР ISE невысоки и определяются тем, что ISE исходно является достаточно старым продуктом и рассматривается в основном из-за продолжающегося выпуска недорогого семейства Spartan-б, для которого она является единственным инструментом проектирования: • процессор с тактовой частотой 2,2 ГГц и выше; • 2 Гб памяти; • монитор с разрешением не хуже 1024x768. Поддерживаемые операционные системы: • Windows 7 SP1 F4-bit); • Windows 8.1 F4-bit); • Windows 10 Pro F4-bit); • Red Hat Enterprise Linux: о 6.6-6.9 F4-bit) о 7.0-7.1 F4-bit)
110 Глава 2 ШШЯ §Я11 Рис. 2.18. САПР ISE в ОС Linux, запущенной в виртуальной машине Oracle VM в Windows 10 • CentOS: о 6.7-6.8 F4-bit) о 7.2-7.3 F4-bit) • SUSE Linux Enterprise: о 11.4 F4-bit) о 12.2 F4-bit) • Ubuntu Linux 16.04.2 LTS F4-bit). Внешний вид окна Oracle VM с установленной САПР ISE показан на рис. 2.18. После запуска САПР следует создать новый проект, запустив мастер создания новых проектов (New Project Wizard). Открывшееся диалоговое окно показано на рис. 2.19. В данном окне необходимо указать имя проекта, которое будет совпадать с именем каталога, создаваемого для хранения всех требуемых для работы файлов. Особенности САПР требуют, чтобы в пути к рабочим файлам не было пробелов и символов кириллицы. На рисунке показано, что для проектов САПР ISE выделен каталог /home/ise/XProject, который совмещен с каталогом С : \ХProject в хост-системе. Параметр Top-level source type (тип файла верхнего уровня) задает формат представления главного модуля проекта, который,
САПР ISE и Vivado — быстрый старт 111 Рис. 2.19. Диалоговое окно создания нового проекта собственно, и будет представлять собой проект для выбранной ПЛИС. Выводы этого модуля будут подключены к выводам ПЛИС. В списке показаны четыре типа такого файла: • HDL (Hardware Description Language) означает, что файлом верхнего уровня является текстовый файл на языке описания аппаратуры; • Schematic — файл верхнего уровня — представляет собой графическое изображение принципиальной электрической схемы, составленной из стандартных библиотечных модулей, и модулей, добавляемых разработчиком в виде других графических схем или файлов на HDL; • EDIF, NGC/NGO — устройство представляется в виде готовых списков связей, разработанных ранее в САПР ISB или с помощью иных программных инструментов. Маршруты, основанные на EDIF и NGC/NGO, представляют интерес в том случае, если в ПЛИС выполняется устройство, приобретенное в виде IP-ядра. В такой проект невозможно внести несанкционированные изменения или восстановить его схему, имея NGC- представление. Ш Важное замечание: несмотря на то что среди маршрутов присутствует схемотехническое представление и оно является
112 Глава 2 достаточно наглядным, этот вид проекта верхнего уровня нельзя отнести к эффективным. Логическая емкость современных ПЛИС не позволяет заполнить их в приемлемые сроки, рисуя схемы в графическом редакторе. Более производительным является маршрут проектирования с HDL-описанием верхнего уровня, при котором используются языки VHDL или Verilog. Далее необходимо указать наименование ПЛИС, которая будет использована для выполнения проекта. Бе тип впоследствии можно будет изменить. Порядок заполнения полей диалогового окна настройки параметров ПЛИС показан на рис. 2.20. Для создания нового модуля проекта необходимо нажать кнопку New Source, после чего откроется диалоговое окно соответствующего мастера. Этот мастер будет регулярно использоваться в процессе работы для создания новых модулей всех типов. На рис. 2.21 показан внешний вид стартового окна, а стрелка в левой части рисунка указывает на расположение кнопки New Source на инструментальной панели САПР ISE. Project Setting^ Рис. 2.20. Настройка параметров ПЛИС в мастере создания нового проекта САПР ISE
САПР ISE и Vivado — быстрый старт 113 Рис. 2.21. Диалоговое окно мастера создания нового компонента Проект для ПЛИС должен иметь как минимум два файла: модуль проекта (VHDL, Verilog или Schematic) и файл проектных ограничений, который будет сформирован чуть позже. Для модуля проекта в примере выбрано имя top. Оно демонстрирует, что создается именно модуль верхнего уровня, т.е. выводы этого модуля будут подключаться к выводам ПЛИС. Внешний вид диалогового окна для редактирования выводов модуля показан на рис. 2.22. Проект разрабатывается для демонстрации маршрута проектирования, поэтому будет состоять из единственного компонента 2И. Соответственно, на рис. 2.22 показаны входы а и b и выход с. После завершения работы мастера модуль top.vhd будет добавлен в проект и появится на панели Hierarchy. В конце этого файла между строками begin и end Behavioral следует добавить строку с <= a and b; Для создания схемы проекта можно запустить процесс синтеза, который показан в списке процессов в левой части окна САПР. Для того чтобы запуск синтеза был активен, в списке модулей проекта должен быть выбран HDL-файл верхнего уровня. В данном случае альтернативных вариантов нет, но для сложных проектов случайный выбор другого файла не позволит провести синтез проекта. После ввода описания проекта требуется указать САПР, к каким именно выводам микросхемы необходимо подключить имеющи-
114 Глава 2 Рис. 2.22. Редактирование выводов модуля еся в проекте цепи. Это не может быть проведено в рамках языков описания аппаратуры. Вместо этого используется файл проектных ограничений (Implementation Constraint File), который добавляется в проект с помощью мастера создания новых компонентов, или путем выбора пункта User Constraints -> I/O Pin Planning в списке процессов для модуля верхнего уровня. Другими словами, необходимо выделить мышью файл верхнего уровня в списке модулей проекта, затем «раскрыть» узел дерева User Constraints в списке процессов, который будет показан ниже для этого модуля, и запустить процесс I/O Pin Planning. В ISE, начиная с версии 11.x, для редактирования выводов используется вспомогательное приложение PlanAhead, открывающееся в отдельном окне. Его внешний вид показан на рис. 2.23. Информация о требуемом выводе ПЛИС вводится в поле Site окна I/O Port Properties (нижняя часть окна PlanAhead на рис. 2.23). Альтернативным термином для обозначения позиции вывода является Location (Loc). Название вывода задается в соответствии с технической документацией на используемую ПЛИС и плату, на которой она установлена. В примере проекта была использована плата Atlys производства компании Digilent, показанная на рис. 2.24. На плате установлена ПЛИС Spartan-6 LX45 в корпусе CSG324. Программатор встроен в плату и распознается как в САПР ISE,
Рис, 2.23. Редактирование расположения внепгаих выводов в приложении PlanAhead
116 Г л ав а 2 Рис. 2.24. Внешний вид платы Digilent Atlys так и утилитой загрузки конфигурации, разработанной компанией Digilent. Внешний вид окна утилиты Digilent Adept показан на рис. 2.25. Работа с утилитой достаточно проста. Кнопка Initialize Chain служит для проверки соединения и получения информации об уста- Corifscf Flash 1 е1»! Power Register I/O File I/O I/O H'3GA ; Рис. 2.25. Интерфейс приложения Digilent Adept
САПР ISE и Vivado — быстрый старт 117 новленной ПЛИС (получение идентификатора микросхемы поддерживается в протоколе JTAG и обеспечивается в FPGA Xilinx). После этого с помощью кнопки Browse необходимо выбрать полученный в САПР конфигурационный файл, после чего станет активной кнопка Program. Этот способ загрузки конфигурации рассмотрен потому, что САПР ISB в настоящее время сохраняет актуальность только для ПЛИС Spartan-б. Работа ISE в Windows 10 не обеспечивается, и несмотря на предоставление компанией Xilinx виртуальной машины Linux, успешно работающей в Windows 10, подключение программатора может оказаться невозможным. Однако множество утилит сторонних производителей, такие как Digilent Adept, не имеют таких ограничений и могут работать как в Windows 7, так и в Windows 10. Процесс загрузки конфигурационного файла в ПЛИС хорошо документирован. Есть возможность как повторения схемы программатора (в настоящее время Xilinx, Digilent и некоторые другие производители используют микросхему FTDI2232H, представляющую собой двухканальный контроллер USB с поддержкой JTAG), так и реализации загрузки конфигурации с помощью микроконтроллера. В целом семейство Spartan-б интересно в первую очередь низкой ценой и наличием микросхем в корпусе TQFP-144, которые могут оказаться единственным доступным вариантом для радиолюбителей или небольших организаций, не имеющих возможность монтировать микросхемы в корпусах BGA. Тем не менее, следует планировать освоение более современных семейств ПЛИС начального уровня — Artix-7, Spartan-7, Zynq-7000. Также работа в САПР ISE актуальна только для поддержки существующих проектов, основанных на ПЛИС, не поддерживаемых в САПР Vivado.
3 Язык описания аппаратуры VHDL С ростом сложности интегральных схем появилась необходимость во все более полном моделировании разрабатываемых микросхем перед их передачей в производство. Для решения этой задачи были разработаны языки описания аппаратуры (Hardware Description Languages, HDL). Их основным назначением было моделирование процессов, происходящих в цифровых микросхемах, на различных уровнях. При этом большое число ошибок, проистекающих из- за некорректного планирования или допущенных конструктивных промахов, оказалось возможным идентифицировать уже на этапе моделирования, что существенно дешевле, чем исправлять ошибки путем повторного изготовления полупроводниковой пластины. Поскольку с уменьшением технологических норм стоимость технологической подготовки производства ползгпроводниковых микросхем существенно растет, их предварительное моделирование становится все более и более актуальным. Также эффективным является про- тотипирование цифровых устройств с помощью программируемых логических интегральных схем (ПЛИС). Несмотря на то что главным назначением HDL является моделирование цифровых устройств, в них было выделено синтезируемое подмножество — набор конструкций, которые могут быть преобразованы в список связей цифровых компонентов и далее в топологическое представление интегральной микросхемы или в конфигурационный поток для программирования ПЛИС. Кроме того, различные реализации HDL добавляют к стандартам специфические расширения, зависящие от конкретного производителя. Эти расширения в общем случае не являются переносимыми, поэтому на них следует обращать внимание при создании HDL- Несовместтаюсть описаний, которые предполагается перено- „ „ „ л сить в другие системы проектирования. Со- Рис. 3.1. Соотношение ^ г г- между подмножествами отношение между подмножествами языков конструкций в языках описания аппаратуры можно представить описания аппаратуры Так, как на рис. 3.1.
Язык описания аппаратуры VHDL 119 В настоящее время наиболее распространенными являются языки описания аппаратуры VHDL и Verilog HDL (Verilog). Они имеют одинаковые области применения, схожи по основным характеристикам и отличаются в основном грамматикой. В целом можно сказать, что модули на Verilog являются более компактными, чем аналогичные модули на VHDL, однако это является следствием большей структурированности VHDL и более строгих требований к контролю типов и форматам описания основных синтезируемых конструкций. При этом алгоритмы синтеза схемотехнического представления цифровых систем являются настолько схожими по характеристикам, что не имеет практического смысла переходить с одного языка описания аппаратуры на другой, рассчитывая на улучшение параметров синтезированной схемы только вследствие более эффективной программы синтеза. В то же время синтезаторы различных производителей могут давать различные результаты для относительно сложных цифровых узлов. Стандарт на язык описания аппаратуры VHDL содержится в документе IEEE 1076. В настоящий момент основной для проектирования является версия стандарта от 2000 г. Аббревиатура HDL означает Hardware Description Language, т. е. язык описания аппаратуры, а буква V, в свою очередь, указывает на еще одну аббревиатуру — VHSIC (Very High-Speed Integrated Circuits, сверхвысокочастотные интегральные схемы). Речь идет не о микросхемах СВЧ диапазона, а просто о том, что VHDL создавался в условиях высокой потребности в выразительном средстве описания цифровых микросхем большой степени интеграции. При разработке цифровых систем используется понятие уровней абстрагирования. Их смысл состоит в том, что при смене технологических процессов, полупроводниковых материалов, схемотехнических решений для элементарных цифровых узлов и прочих низкоуровневых деталей реализации было бы нежелательным терять ранее полученные результаты, касающиеся общей архитектуры системы и порядка соединения компонентов. Поэтому изменения в Цифровые системы вносятся на различных уровнях, так что детали реализации конкретных цифровых узлов (например, триггера или сумматора) скрыты от разработчика общей структуры цифрового устройства. Впоследствии, если будет сконструирован более эффективный вариант триггера, все схемы, созданные с использованием такого компонента, могут быть использованы без необходимости их коренного пересмотра. Обычно говорят о следующих уровнях абстрагирования:
120 Г лав а 3 • поведенческий (behavioral level); • уровень регистровых передач (RTL, register transfer level); • вентильный уровень (gate level); • топологический уровень (cells level); • физический уровень (switch/mask level). Описание на поведенческом уровне является наиболее отдаленным от конкретной технической реализации и представляет цифровые модули в виде «черных ящиков» с заданной функциональностью. Языки описания аппаратуры предоставляют достаточно средств для работы на этом уровне, что обеспечивает высокую производительность труда разработчика цифровых устройств. Уровень регистровые передач подразумевает представление цифрового устройства в виде схемы соединения регистров и комбинационной логики. На вентильном уровне производится детализация схемы до базовых логических элементов (вентилей). Таким образом, комбинационные выражения, представляемые на предыдущем уровне в общем виде, получают развернутую форму, что позволяет определить требуемую сложность схемы, уточнить занимаемую ей площадь и задержки распространения сигналов. На топологическом уровне цифровое устройство представляется в виде координат расположения отдельных фрагментов (ячеек), соответствующих имеющимся в технологической библиотеке компонентам. Физический уровень содержит сведения о размещении и параметрах физических устройств (транзисторов), непосредственно реализующих необходимые функции. Проектирование с использованием языков описания аппаратуры обычно производится с перекрытием поведенческого уровня и уровня регистровых передач. Это связано с тем, что конструкции, описываемые на поведенческом уровне, могут оказаться слишком неэффективными для используемой аппаратной базы именно в силу максимального абстрагирования (дистанцирования) от деталей реализации. Использование RTL-представления позволяет конкретизировать пожелания разработчика к способу реализации наиболее ответственных узлов и снизить степень влияния алгоритмов синтеза на получаемый результат. Близко к RTL-представлению находится также структурный подход к описанию схем, при котором схема описывается с помощью указания цифровых элементов из конкретной библиотеки компонен-
Язык описания аппаратуры VHDL 121 тов и схемы их соединения. Сравним следующие способы представления элемента 2И на VHDL. Например, тест out_c <= in_a and in_b; транслируется программой синтеза с получением требуемого цифрового узла. Способ реализации и используемые для этого компоненты автоматически определяются средствами синтеза, используя в качестве входной информации выражение на языке описания аппаратуры. Такой подход к получению компонентов в англоязычной литературе обозначается как inference. Другой подход основан на использовании ссылки на библиотечный компонент. Например, описание and2_instO : and2 port map (a => in_a, b => in_b, с => out.c); служит указанием на то, что требуется использовать некоторый модуль and2, имеющий входы а и Ь, а также выход с. Детали реализации такого модуля должны быть представлены в библиотеке, поставляемой фирмой-производителем САПР, а выводы конкретного экземпляра, названного and2_instO, должны быть подключены к цепям in_a, in_b, out.c соответственно. Поскольку создается экземпляр («пример», instance) библиотечного компонента, подход обозначается как instantiation. Сравнение представленных подходов делает очевидным тот факт, что использование instantmted-KOMnoHeHTOB сопряжено с более сложным форматом их описания и потенциальными проблемами отладки схемы, поскольку никакого анализа поведения и логической корректности подключения выводов не производится. Разработчик, используя instantiation, должен представлять себе дальнейшее поведение создаваемой им схемы и ответственен за правильное подключение внешних сигналов. Напротив, средства синтеза в процессе создания гп/егтей-компонентов способны выбрать корректное с точки зрения схемотехники решение, основываясь на достаточно абстрактном описании желаемого результата. Развитие средств автоматического проектирования делает доступным автоматический синтез эффективных схем для все большего числа цифровых узлов. В настоящее время исключениями для ПЛИС, требующими использования instantiation, являются в основном специфичные компоненты, такие как буферы специального назначения, схемы формирования тактового сигнала, скоростные приемопередатчики и прочие компоненты, которые не могут быть представлены в виде HDL-описания. Кроме того, в ситуациях, когда различные настройки программ синтеза дают отличающие-
122 Глава 3 ся результаты, не устраивающие опытного разработчика, он имеет возможность ликвидировать эту неопределенность, непосредственно указав на библиотечные компоненты, с помощью которых он хотел бы реализовать требуемый фрагмент цифровой системы. Наконец, сборка цифровой системы на верхнем уровне иерархии также может быть произведена путем перечисления экземпляров компонентов и порядка их соединения. Такое описание является альтернативой графическому представлению схемы на верхнем уровне и в ряде случаев может оказаться более удобным, поскольку не зависит от конкретной версии редактора графического представления схем. 3-1. Основы языка VHDL В проекте на VHDL могут быть следующие типы файлов: • синтезируемые модули (VHDL module); • библиотеки (VHDL library); • пакеты (VHDL package); • описания тестов (VHDL testbench). Существующие САПР, как правило, генерируют шаблон модуля VHDL, как показано в приведенном ниже листинге. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STDiOGIC-ARITH.ALL; use IEEE.STD.LOGIC-UNSIGNED.ALL; - library UNISIM; - use UNISIM.VComponents.all; entity newjmodule is Port (a : in STDJLOGIC; b : in STDXOGIC; с : out STDJ.OGIC); end newjmodule; architecture Behavioral of new_module is begin end Behavioral; Анализируя листинг, можно выделить структуру модуля на VHDL. В первых строках модуля подключаются общеупотребительные библиотеки. Их состав и назначение будут рассмотрены позднее. Далее САПР ISE помещает в модуль две закомментированные строки, подключающие библиотеку UNISIM. Эта библиотека содержит компоненты, специфичные для ПЛИС Xilinx, и ее подключение сделает разрабатываемый модуль несовместимым с другими аппаратными платформами — ПЛИС других производителей и полупроводниковыми микросхемами. С другой стороны, использование
Язык описания аппаратуры VHDL 123 аппаратных ядер и instantiated-компонентов невозможно без подключения данной библиотеки. Ш Комментарии в VHDL задаются двумя минусами и действуют до конца строки. Язык VHDL не содержит многострочных комментариев во избежание неоднозначностей в 'I их интерпретации как средствами синтеза, так и разработчиками при чтении исходных текстов 1 модулей. Такое решение является элементом до- ,-; стижения повышенной надежности разработки j г -- - ;™^Т] на VHDL. При необходимости быстрого коммен- i^^^^^^r^ тирования группы строк можно воспользовать- 11 ся кнопками на инструментальной панели ре- л л А Рис. 3.2. Фрагмент дактора, которые показаны на рис. 3.2. Альтер- ИНСтрументальной нативным вариантом для Vivado является ком- панели с кнопками бинация Ctrl + / (символ деления на дополни- а** внесения и телЬНОЙ клавиатуре). удаления символов ' комментария для Далее в описании модуля находятся разде- выделенного кода лы entity и architecture. Пока можно вкратце упомянуть, что в разделе entity описываются «внешние» характеристики модуля, а в architecture — его реализация. В разделе architecture после ключевого слова begin размещается описание работы модуля, что будет подробнее обсуждено позже. 3.2. Структура модуля на VHDL Выше уже было показано, что модуль на VHDL, описывающий синтезируемое устройство, состоит из разделов entity и architecture. Рассмотрим их более подробно. В разделе entity («сущность») описывается интерфейс модуля и сопутствующие ему характеристики. Собственно интерфейс описывается в подразделе Port: entity new_module is Port (a : in STD.LOGIC; b : in STD.LOGIC; с : out STD_LOGIC); end new_module; В разделе Port в показанном примере перечислены входные сигналы а и Ь, а также выходной сигнал с. Формат объявления интерфейсного сигнала следующий: <имя> : Спецификатор направления> <тип> ;
124 Глава 3 Здесь <имя> — один из разрешенных идентификаторов в VHDL, ограничения на которые подобны ограничениям на имена переменных в языках программирования. Идентификатор может содержать буквы латинского алфавита, цифры и символ подчеркивания, не должен начинаться с цифры, не должен заканчиваться символом подчеркивания или содержать внутри два символа подчеркивания подряд. <Спецификатор направления> может быть следующим: • in — входной сигнал, только для чтения; • out — выходной сигнал, только для записи; • inout — двунаправленный сигнал; • buffer — выходной (буферный сигнал), значение которого может быть считано модулем. Типы сигналов будут рассмотрены в следующих разделах. В разделе architecture описывается внутренняя реализация модуля: architecture Behavioral of newjoiodule is begin с <= a and b; end Behavioral; В показанном примере описывается реализация модуля 2И. Идентификатор Behavioral представляет собой имя архитектуры и не является зарезервированным словом. Присвоение архитектуре идентификатора необходимо потому, что каждому объявлению entity может соответствовать несколько архитектур, различающиеся способом реализации. Например, в показанном выше примере был использован подход, основанный на inference — синтезатор выбрал способ реализации логического выражения, основываясь на его поведенческом описании. Если это по каким-то причинам не устраивает разработчика, он может использовать instantiate-no&x.OA, выбрав вентиль 2И из библиотеки стандартных компонентов. Чтобы не править уже готовый вариант архитектуры (тем более что впоследствии может возникнуть желание вернуться к нему), в модуле оформляется еще один раздел architecture^ для которого выбирается другой идентификатор. Выбор идентификаторов для архитектур не имеет официальных ограничений, однако можно порекомендовать общеупотребительные варианты, которые имеют ту же силу, что и названия переменных х, у для координат или ъ для счетчика цикла: - ВЕН, Behavioral — для описаний, выполненных в пореденчес- ком стиле;
Язык описания аппаратуры VHDL 125 RTL —- для описаний на уровне регистровых передач; STRUCT, Structural -— для структурных описаний; TEST — для тестов. В дальнейшем для проекта можно глобально установить использование той или иной архитектуры: for all : HALF.ADD use entity work.new_module(RTL); Эта строка устанавливает использование архитектуры RTL для всех компонентов new_module, используемых в проекте. Несколько вариантов архитектур и регулярное употребление конфигураций обычно сопутствуют сложным, комплексным проектам, разрабатываемым с учетом необходимости проверки альтернативных конструкторских решений и возможного переноса на другую аппаратную базу. Как правило, такой подход не требуется для большинства проектов, ориентированных на ПЛИС. 3.3. Соединение модулей Для создания проектов из нескольких модулей требуется их объединение. Причины разбиения проекта на модули могут быть различны, начиная от простого ограничения сложности каждого отдельного модуля и заканчивая необ- AND2 ходимостью использовать аппарат- Е) "V—i OR2 ные узлы, имеющиеся в составе ПЛИС, которые включаются в проект с помощью библиотечного представления. Предположим, что необ- п п о „ , с г Рис. 3.3. Графическое изображе- ХОДИМО СОЗДатЬ Схему, аналогичную ние схемы из нескольких модулей показанной на рис. 3.3. Требуется, чтобы в библиотеке компонентов имелись модули, соответствующие компонентам and2 и or2. Их описания могут быть следующими: Для модуля and2: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STDiOGIC-ARITH.ALL; use IEEE.STD-LOGICJJNSIGNED.ALL; entity my_and2 is Port (a : in STD.LOGIC; b : in STD.LOGIC; с : out STDJLOGIC); end my_and2; architecture Behavioral of my_and2 is begin
126 Глава 3 с <= a and b; end Behavioral; Для модуля ог2: library IEEE; use IEEE.STDJLOGIC.1164.ALL; use IEEE.STDJiOGIC-ARITH.ALL; use IEEE.STD JiOGIC-UNSIGNED.ALL; entity my«or2 is Port (a : in STDJ.OGIC; b : in STDJLOGIC; с : out STDJLOGIC); end my_or2; architecture Behavioral of ту_ог2 is begin с <= a or b; end Behavioral; Модуль верхнего уровня на языке VHDL будет иметь следующий интерфейс: library IEEE; use IEEE.STDXOGICU164.ALL; use IEEE.STDijOGIC.ARITH.ALL; use IEEE.STDJLOGIC.UNSIGNED.ALL; entity topJevel is Port (a : in STD XOGIC; b : in STDXOGIC; с : in STD J.0GIC; d : in STD_LOGIC; q : out STDJLOGIC); end topJevel; Внутри модуля верхнего уровня должны присутствовать два компонента and2 и один компонент ог2. Они описываются с применением подхода component instantiation: ранее созданные компоненты указываются в тексте модуля верхнего уровня с перечислением сигналов, которые необходимо подключить к их портам. Однако при взгляде на схему можно заметить, что для соединения выходов компонентов and2 с входами ог2 требуются два проводника, которые являются внутренними цепями и не имеют отдельного имени. Стандарт VHDL не допускает прямое соединения выхода одного компонента с входом другого (т. е., например, нельзя указать для порта а компонента ог2, что он подключен непосредственно к порту q компонента and2). Для этого требуется объявление отдельных внутренних цепей после ключевого слова architecture:
Язык описания аппаратуры VHDL 127 architecture Structured of my_or2 is signal netl, net2 : stdJogic; begin — Создадим далее схему соединений: component 1 : my_and2 port map ( a => a, b => b, q => netl); component2 : my_and2 port map ( a => c, b => d, q => net2); components : my_or2 port map ( a => netl, b => net2, q => q); end Structural; Порты верхнего уровня выделены в данном примере жирным шрифтом, чтобы отличать их от совпадающих имен портов компонентов (такое совпадение не является ошибкой). Рассмотрим элементы записи component2 : my_and2 port map ( a => с, b => d, q => net2); Здесь and2 — имя компонента, как оно приведено в его описании после ключевого слова module; component2 — уникальный идентификатор, присвоенный разработчиком данному экземпляру компонента (в схеме присутствует также component 1 такого же типа); а — ссылка на порт а компонента; с — указание цепи, к которой должен быть подключен этот порт. Имена портов компонента можно не указывать, описывая только список сигналов, к которым необходимо подключать порты: component 1 : my_and2 port map (a, b,netl); component2 : my_and2 port map (c, d, net2); components : my_or2 port map (netl, net2, q); В этом примере подключение к портам компонента осуществляется в порядке их описания в самом компоненте. Это так называемое позиционное назначение сигналов (ordered mapping), когда позиция сигнала в списке подключений совпадает с позицией порта в описании компонента. Предыдущий вариант, с явным упоминанием
128 Глава 3 имен портов компонента, называется именованным назначением (named mapping). Нетрудно видеть, что позиционное назначение несколько компактнее, поскольку не включает в себя имена портов компонента. Тем не менее именованное назначение позволяет избежать неявных ошибок, когда разработчик перепутал порядок следования имен. В качестве примера рассмотрим абстрактный компонент, который имеет сигналы сброса и разрешения работы: entity example is Port (elk : in STD-LOGIC; data : in STDXOGIC; reset : in STDXOGIC; en : in STDXOGIC; <прочие сигналю He вдаваясь в подробности реализации такого модуля, рассмотрим варианты его подключения с использованием позиционного назначения сигналов. instO : example port map (netl, net2, net3, net4); instl : example port map (clk_net, datajiet, en_net, reset_net); inst2 : example port map (clk_net, data_net, reset.net, en_net); Первый вариант объявления не дает возможности быстро убедиться, что подключение выполнено правильно, поскольку имена цепей отличаются только номером. Второй вариант (instl) использует «содержательные» имена, которые включают в себя фрагменты имен портов — например, elkjiet дает понятие о том, что этот сигнал следует подключить к порту elk. Однако требуется отдельно сопоставить порядок объявления портов в описании модуля с порядком упоминания сигналов, чтобы убедиться, что для instl перепутан порядок следования сигналов enjiet и resetjiet. Позиционное назначение не позволит САПР выявить или исправить эту логическую ошибку, поскольку никаких формальных запретов на подключение сигнала enjiet к входу reset не существует. Сравним это с именованным назначением: inst3 : example port map (elk => elk-net, data => data_net, en => enjiet, reset => reset_net); В этом примере порядок упоминания сигналов en и reset также не совпадает с порядком объявления сигналов в описании модуля. Однако явное упоминание имен сигналов заставит САПР,подключить цепь enjiet именно к входу en, несмотря на то что на третьем месте в объявлении компонента находится reset. Таким образом,
Язык описания аппаратуры VHDL 129 именованное назначение представляется более безопасным с точки зрения устранения логических ошибок при соединении компонентов. Объявленные внутри архитектуры внутренние цепи называются сигналами (signal). Сигналами являются любые проводники, соединяющие узлы внутри цифровой схемы. Для удобства можно условно считать сигналы аналогами локальных переменных в программировании — точно так же, как программисты создают локальные переменные для хранения данных, не выходящих за пределы программного модуля, разработчик цифровой схемы определяет сигналы для передачи состояний, которые не должны выходить за пределы цифрового модуля. VHDL имеет в своем составе также переменные (variable), константы (constant) и параметры, называемые generic. Переменные отличаются от сигналов тем, что сигналы представляют узлы разрабатываемой схемы, а переменные — данные в САПР, которые требуются в процессе ее разработки. Введение переменной может привести к формированию соответствующего ей сигнала, а может и не привести, что зависит от контекста ее использования. Примеры объявления переменных и констант: variable a : integer := 0; constant init.data : stdJogic_vectorC downto 0) := 100"; Начальное значение для переменных и констант задается после оператора :=. Этот оператор не является обязательным, т. е. можно просто объявить переменную, описав ее имя и тип. Начальное значение для констант, сигналов и переменных действительно не только для моделирования, но и для синтезируемого кода. В процессе загрузки конфигурации FPGA устанавливает также начальные состояния триггеров и блоков памяти, которые и являются устройствами хранения значений сигналов, переменных и констант. 3.4. Типы данных VHDL является строго типизированным языком. Это означает, что он требует согласования типов объектов, используемых в выражениях — например, не допускается присваивать переменной или сигналу одного типа значение, относящееся к другому типу, даже если есть возможность привести один тип к другому. В случае необходимости разработчик должен явно указать функцию преобразования типа, показывая тем самым, что он понимает суть выполняемых действий и согласен, что тип выражения должен измениться.
130 Глава 3 Строгая типизация является одним из элементов повышения общей надежности разрабатываемых проектов. Типы данных в VHDL делятся на следующие категории: • скалярные; • композитные; • указатели; • файлы. 3.4.1. Скалярные типы Тип bit служит для представления величин, принимающих значения 0 и 1. Его использование в целом не рекомендуется, поскольку данного набора недостаточно для описания цифровых линий, которые могут находиться, например, в состоянии высокого импеданса. Тип boolean служит для представления логических величин, принимающих значения ИСТИНА и ЛОЖЬ (true/false). Такой тип данных является результатом операций сравнения, например выражение А > В представляет собой величину типа boolean. Основным типом, наиболее адекватно представляющим цифровые сигналы, является stdJogic. Он может принимать следующие значения: 'U1 — не инициализировано; 'X' — неизвестное значение, формируемое активным выходом (forcing unknown); '0* — логический ноль; 'Г — логическая единица; 'Z* — «третье состояние», состояние высокого импеданса выхода; W — «слабое неизвестное» значение; Ъ* — «слабый ноль», состояние логического нуля, формируемое источником сигнала с более высоким сопротивлением, чем обычный логический выход; 'Н* — «слабая единица», состояние логической единицы, формируемое источником сигнала с более высоким сопротивлением, чем обычный логический выход; '-' — произвольное значение (don't care). Такой список возможных значений учитывает не только особенности аппаратной реализации цифровых устройств, но и особенности их моделирования. Например, состояния «неизвестное значение», «слабое неизвестное значение» в означают, что программа моделирования не в состоянии определить логический уровень, который должен присутствовать в данном узле схемы (однако в реальном устройстве он, конечно же, будет равен какому-то значению). Аналогично, состояние «не инициализировано» говорит только о том,
Язык описания аппаратуры VHDL 131 что начальное состояние не было сообщено программе моделирования, тогда как в цифровой системе в аналогичной ситуации каждый элемент будет иметь вполне определенное состояние. Понятия «слабых» (weak) сигналов соответствуют источникам логических уровней с повышенным сопротивлением по сравнению с обычными логическими элементами. Объединение обычного и слабого источников не является схемной ошибкой, и в этом случае состояние определяется более сильным источником. Например, соединение входа с одним из источников питания через резистор (pull-up или pull-down) обеспечивает на этом входе логический уровень A или 0 соответственно) даже в отсутствие подключения к другим выходам. На практике такие соединения используются при необходимости считывания по единственной линии состояния множества выходов. В этом случае выходы находятся в состоянии высокого импеданса («Z-состояние») и не оказывают влияния на общую линию связи. Чтобы избежать появления неопределенного состояния, электрических помех и наводок (поскольку проводник оказывается неподключенным ни к одному источнику), используется «подтягивающий» (pull-up) резистор, обеспечивающий «слабую единицу». Если любой из выходов будет переведен в активное состояние, ему при необходимости не составит труда «перекрыть» этот уровень, обеспечив состояние логического нуля. Такая схема может быть описана и для ПЛИС: q <= inO when selO = T else 'Z'; q <= inl when sell = T else »Zf; q <= in2 when sel2 = 'I1 else 'Z'; Несмотря на то что в современных FPGA нет внутренних буферов с тремя состояниями, схема с таким поведением может быть реализована на базе мультиплексоров. Для сигналов, описанных как stcLlogic, допустимо большинство операций — побитовые логические, операции сравнения и сдвига. Формально сигналы типа stcLlogic не могут участвовать в арифметических выражениях, однако на практике синтезаторы допускают это путем перегрузки (overloading) арифметических операторов. IS Тип stdJogic является основным типом для представления сигналов в VHDL Тип integer также довольно часто используется в VHDL. Как следует из названия, он описывает целые числа: signal a : integer range 0 to 7; Необязательный спецификатор range задает диапазон значений,
Глава 3 орые может принимать описываемый сигнал. При синтезе для ого сигнала будет автоматически выделено число разрядов, тре- fs мое для представления всех значений из заданного диапазона. П умолчанию разрядность сигнала типа integer равна 32. Станов устанавливает разрядность целых чисел минимум 32, но не аяичивает максимальную разрядность, которую может реализо- производитель того или иного САПР. Для экономии ресурсов " одимые диапазоны зна- Устаяовка диапазона значений integer играет определенную ¦h в устранении логических ошибок проектирования, поскольку ятезатор имеет возможность отслеживать попытки присваивания налам значений, выходящих за пределы установленных диапа- Это не означает, что схемы, реализованные с применением vtfDL автоматически получают способность контролировать запиваемые в них в процессе работы значения, речь идет о проверках в синтеза схемы в САПР. Например, если объявлена переменная, оанящая один разряд десятичного числа, то для нее будет отведе- 4 двоичных разряда, что, в принципе, позволит записывать туда числа от 0 до 15. signal decimal-digit : integer range 0 to 9; При попытке выполнить присваивание decimaLdigit <= 10 синтезатор сообщит об ошибке. Тип real относится к несинтезируемым и представляет числа в формате с плавающей точкой: signal х : real :- 123.45; Применение чисел такого типа ограничивается в основном вы- слением задержек распространения сигналов, а также выполне- математических вычислений, на основании которых можно при- Ть решение о генерации того или иного вида синтезируемого ко- Например, в качестве параметра в модуль на VHDL может быть редана емкость нагрузки или температура окружающей среды, рые удОбно представить в формате с плавающей точкой. На вании анализа этих величин могут быть автоматически сгене- ованы различные варианты синтезируемых узлов. Тип character служит для представления отдельных символов. Он определен следующим образом: type character is (nul, sol, stx, etx, eot, enq, ack, bel, ... '@\ 'A', 'B', 'C\ 'D\ >E', 'F', 'C, ...);
Язык описания аппаратуры VHDL 133 Данный тип является синтезируемым в том смысле, что задаваемые с помощью character значения могут быть представлены в двоичном виде и помещены в соответствующие регистры. Физические типы используются для описания значений, имеющих единицы измерения. В VHDL предварительно задан только один тип — время. Тип time предназначен для задания временных задержек. constant Tpd : time := 1 ns; Допустимы следующие единицы измерения: • fs — фемтосекунда; • ps — пикосекунда; • ns — наносекунда; • us — микросекунда; • ms — миллисекунда; • s — секунда. Объект типа time не является синтезируемым, т. е. невозможно создать синтезируемую конструкцию с требуемой задержкой, просто указав ее величину в операторе присваивания. Подобные типы переменных присутствуют в VHDL для облегчения создания возможно более адекватных моделей проектируемых устройств. Таким образом, разработчик, применяя тип time, самостоятельно отвечает за корректность приводимых им величин задержек. Перечислимые (enumerated) типы определяются путем перечисления значений, которые может принимать переменная или сигнал такого типа. type MY.TYPB is (RUN, STOP, PAUSE); signal STATE : MY_STATE; STATE <= RUN; Использование перечислимых типов позволяет сделать исходный текст на VHDL более читаемым и близким к терминам решаемой задачи. Также рекомендуется описывать состояния конечных автоматов с использованием перечислимых типов, что позволяет программам синтеза выбирать оптимальный способ кодирования таких состояний. Более подробно это обсуждается в разделе, посвященному проектированию и использованию конечных автоматов. Можно обратить внимание, что одинаковые значения, принадлежащие различным типам, не являются эквивалентными. Например, следующий код является некорректным: type TYPE.A is (RUN, STOP, PAUSE);
134 Глава 3 type TYPB3 is (RUN, STOP, PAUSE); signal sig_A : TYPE-A; signal sigJB : TYPEJ3; sig-B <= sig_A; ~ ошибка: сигналы разного типа Несмотря на то что оба типа имеют одинаковый набор идентификаторов, с точки зрения VHDL они являются разными (и к тому же могут иметь разный способ кодирования значений, выбранный синтезатором). Поэтому показанное присваивание не может быть выполнено. Производные типы (subtype) служат для создания пользовательских типов на основе стандартных. subtype type_angle is integer range 0 to 359; signal my .angle : type_angle; Два производных типа не являются совместимыми, даже если они основаны на одном базовом типе. 3.4.2. Композитные типы Композитные типы — это типы, представляющие собой группы элементов более простых типов. Наиболее распространенным является тип stdJogicvector: signal a : stdiogic-vector C downto 0); В данном объявлении определяется сигнал а, представляющий собой группу элементов типа stdJogic. Элементы имеют индексы 3 — 0. Можно использовать и порядок следования индексов по возрастанию: signal b : std Jogicvector @ to 3); Удобнее использовать убывающий порядок следования индексов, что иллюстрируется следующим примером: а <= 001"; Ъ <= 001"; Присваивание значений отдельным разрядам производится в том же порядке, в котором они объявлены. Поэтому для сигнала а в единицу будет установлен разряд с индексом 0, а для сигнала b — с индексом 3. Таким образом, число, записываемое в Ь, соответствует десятичному значению 8 (ОЫООО), что выглядит несколько непривычно для восприятия. В этой связи и оказывается удобнее определять сигналы типа stcUogicvector с убыванием индексов. Ill Сигналам stddogicjuector значения задаются в двойные кавычках ("ООН"), тогда как для stdJogic — в одинарных
Язык описания аппаратуры VHDL 135 ('О'). Это связано с принадлежностью этих сигналов к различным группам — stdJogic является скалярным, a $td- logicjuector — композитным типом. В то (нее время значения для сигналов типа integer (перечислимого типа) записываются без кавычек. Следующим композитным типом являются массивы (arrays). Это группы элементов одинакового типа, например: type Tmem is array @ to 255) of std_logic_vectorG downto 0); signal Mem : Tmem; В примере определяется тип Tmem, который представляется как массив элементов stdJogic_vectorG downto 0). В массиве 256 элементов с индексами 0-255. Далее определяется сигнал Mem типа Tmem. Можно обращаться к отдельным элементам такого массива: signal a : stdJogic_vectorG downto 0); а <= Mem@); Из этого примера видно, что каждый элемент массива Mem является 8-разрядным вектором. Можно рассматривать сигналы типа stdJogicvector как одномерный массив элементов stdJogic. Соответственно, возможен и доступ к отдельным разрядам или группам разрядов таких сигналов. Ниже показаны примеры оперирования с сигналами различной разрядности, выделения и объединения элементов. signal a : stdJogic_vectorG downto 0); signal b, с : std_logic_vectorC downto 0); signal d : stdJogic; aC downto 0) <= b; a <= b & c; d <= aE); a <= G | б => '1', 3 downto 1 => '0'); a <= (others ==> '0'); Ранее не описанным примером использования является оператор конкатенации &. Он «склеивает» сигналы, находящиеся по левую и правую сторону от него, образуя новый сигнал композитного типа. Нельзя выполнять присваивание сигналов типа stdJogicvector с отличающимся порядком изменения индексов. signal а : stdJogicvectorC downto 0); signal b : stdJogic.vector@ to 3); a <= b; — порядок изменения индексов различен
136 Г л а в а 3 Записи (record) представляют собой группы сигналов различного типа. type TCoord is record X, Y : integer range 0 to 1023; Visible : stdJogic; end record ; signal Pointl, Point2 : TCoord; Pointl.X <= 123; Point2.Visible <= 'I1; Point2 <= Pointl; Общим правилом записи выражений на VHDL является строгое соответствие типов и разрядностей присваиваемых значений. Далее будут рассмотрены функции преобразования типов, которые включают в себя и удобные формы записи функций преобразования разрядности. Строки (string) — это массивы символов (character). Они используются в основном при создании тестов: constant message 1 : string A to 5) := "Error"; Задав набор текстовых сообщений, можно в дальнейшем использовать ссылки на них. 3.4.3. Преобразования типов Данные, представленные типом std_logic_vector, не могут быть автоматически интерпретированы как десятичное число. Отдельные элементы такого вектора не рассматриваются средствами синтеза как разряды двоичного числа, таким образом, "ООН" не вполне эквивалентно числу 3 с точки зрения VHDL. Например, нельзя выполнить сравнение "ООН" < 000м, поскольку группы разрядов не трактуются синтезатором как 4-разрядные двоичные числа, а только как отдельные двоичные сигналы, сгруппированные в один композитный объект. Для выполнения операций сравнения следует преобразовать один тип в другой. Для этого можно использовать следующие функции. Сначала будут рассмотрены функции, входящие в состав библиотек более раннего поколения. Их подключение показано в примере. иве IEEE.STDiOGICJVRITH.ALL; use IEEB.STDiOGICJJNSIGNED.ALL; Вместо библиотеки STD_LOGIC_UNSIGNBD можно подключить библиотеку STD_LOGICJ3IGNED. В этом случае все целые числа будут трактоваться как числа со знаком.
Язык описания аппаратуры VHDL 137 Функция convinteger преобразует сигнал или значение типа stcL logic .vector в целочисленный тип. signal x-slv : std_logic_vector G downto 0); signal xJnt : integer range 0 to 255; xint <= convinteger(x_slv); Обратное преобразование выполняет функция convjstdJogic vector: x-slv <= conv_stdJogic_vector(x_int, 8); Второй параметр, равный в примере 8, задает число разрядов, в которые следует поместить результат преобразования. Это связано с тем, что stdJogicvector не рассматривается синтезатором как единый объект, отдельные разряды которого представляют соответствующие разряды двоичного числа со своими весами. Если преобразование stdJogicvector в integer позволяло говорить о том, что группа двоичных разрядов должна быть скомпонована так, чтобы получить значение скалярного сигнала, то обратное утверждение, строго говоря, неверно. Кроме того, преобразование констант в stdJogicvector содержит в себе некоторую неопределенность, поскольку для хранения числа 1 достаточно, вообще говоря, одного разряда. Именно поэтому число двоичных разрядов, которое должен занять результат преобразования, указывается явно. Чтобы иметь возможность использовать в одном модуле и беззнаковое, и знаковое представления, можно использовать библиотеку NUMERICJ3TD: use IEEE.NUMERICJ3TD.ALL; Для этой библиотеки функции преобразования будут выглядеть следующим образом: Signaldnteger <= to_integer(unsigned(signaLslv)); Signal .integer <= to_integer(signed(signaLslv)); Signal_slv <= stdJogic_vector(to_unsigned(signal_integer, SignaLslv'length)); Signal_slv <= stdJogic_vector(to_signed(signal_integer, SignaLslv'length)); Можно видеть, что преобразование стало чуть более сложным, поскольку для сигнала типа std Jogicvector необходимо сначала указать, представляет он беззнаковое или знаковое число, и только потом преобразовать его в тип integer. Для обратного преобразования также используется явное указание представления и затем число преобразуется в тип stdJogicvector. Так же, как и для convjstdJogicvector, используется второй параметр, определяющий разрядность. В примере показано использование атрибута сигнала. Указание после сигнала 'length автоматически определяет раз-
138 2\^в_а_3^ рядность сигнала. Подробнее об атрибутах можно прочитать в разделе 3.11. Чтобы присваивание было корректным, должны совпадать не только типы, но и разрядности выражений в левой и правой частях присваивания. Поскольку сигналы типа stdJogic.vector в проектах могут иметь различную разрядность, возникает проблема ее согласования. Проще всего присвоить фрагмент сигнала большей разрядности сигналу меньшей разрядности. signal al6 : stdJogic.vectorA5 downto 0); signal a8 : stdJogic_vectorG downto 0); a8 <= al6G downto 0); Чтобы выполнить обратное преобразование, необходимо задать значения для старших 8 разрядов сигнала а16 (впрочем, можно записывать а8 и в старшие разряды, и вообще в любые фрагменты а16 размером 8 разрядов). а16G downto 0) <= а8; или а16A5 downto 8) <= а8; Можно расширить имеющиеся 8 разрядов в правой части присваивания с помощью оператора конкатенации &: а16 <= «00000000» & а8; Наконец, можно воспользоваться функциями ext («расширить») и sxt (sign extension, «расширить со знаком»): а16 <= ext(a8, 16); а16 <= sxt(a8, 16); Как и для функции convjstd Jogic.vector, второй параметр представляет собой разрядность получаемого результата. Различие между функциями заключается в том, что ext дополняет старшие разряды нулями, a sxt — значением старшего разряда первого операнда, обеспечивая тем самым его знаковое 'расширение. Можно напомнить смысл знакового расширения. В дополнительной двоичной арифметике используется тот факт, что выражение @-1) дает в результате двоичное представление, в котором все разряды установлены в 1. Прибавление к нему 1 вызовет переполнение и появление бита переноса (Obllllllll + 1 = Obi 0000 0000), но если проигнорировать появляющийся старший разряд, то оставшееся 8-разрядное число будет равно 0. Таким образом, можно считать, что полученное двоичное представление с единицами во всех разрядах соответствует десятичному значению —1 («минус один»).
Язык описания аппаратуры VHDL 139 Аналогично, OblllllllO можно трактовать как —2, поскольку прибавление к этому числу 2 вызовет обнуление имеющихся разрядов с появлением бита переноса в старшем разряде, который будет проигнорирован. При таком подходе можно и число ObOOOOOOOl трактовать как —255, так как прибавление 255 даст в результате нули в имеющихся двоичных разрядах. Однако на практике принимают, что число с единицей в старшем двоичном разряде является отрицательным, а с нулем — положительным. Тогда 8-разрядное двоичное число может принимать значения —128...+127 в дополнительной двоичной арифметике. При таком подходе знаковое расширение требуется для того, чтобы —1 (Obi 1111 111) после его расширения не превращалось в 255 из-за появления новых разрядов, которые будут равны нулю при использовании ext. Если скопировать старший разряд во вновь добавляемые, как это делает sxt, то любое число, которое трактовалось как отрицательное, останется отрицательным и после преобразования. 3.4.4. Указатели Указатели, называемые в VHDL access types, играют ту же роль, что и в языках программирования высокого уровня. Пример использования указателя показан ниже: type Pinteger is access integer; variable ptr : Pinteger; ptr := new integer; ptr.all := 5; Указатели практически не используются при создании синтезируемых конструкций. Как правило, объекты, созданные с помощью указателей, используются при создании тестов. 3.4.5. Файлы (указатели на файлы) Файловые переменные, как и указатели, часто используются при создании тестов и генерации отчетов. Такие переменные в сочетании с рядом библиотечных функций обеспечивают доступ к файлам, позволяя выполнять стандартные для языков программирования операции чтения и записи. Данные в файлах при этом используются как тестовые последовательности, а сохраняются в файлы результаты выполнения и диагностические сообщения. 3.5. Операторы языка VHDL Операторы VHDL можно разбить на несколько групп, рассмотренных ниже.
140 Глава 3 Таблица 3.1 Логические операторы языка VHDL Оператор and nand or nor xor xnor not Название И И-НБ ИЛИ ИЛИ-НБ ИСКЛЮЧАЮЩЕЕ ИЛИ ИСКЛЮЧАЩЕЕ ИЛИ-НЕ НЕ Пример с <= a and b; с <= a nand b; с <= a or b; с <= a nor b; с <= а хог Ь; с <= a xnor b; с <= not a; Таблица 3.2 Таблицы истинности для побитовых операций А 0 0 1 1 В 0 1 0 1 и 0 0 0 1 или 0 1 1 1 ИСКЛЮЧАЮЩЕЕ ИЛИ 0 1 1 0 3.5.1. Логические операторы Логические операторы VHDL приведены в табл. 3.1. Применение этих операторов определено для операндов типа bit, boolean, bit-vector, stdJogic.vector. Для справки можно привести таблицы истинности для логических операторов (табл. 3.2). В таблице не приведены варианты для инверсных операторов — И-НЕ, ИЛИ-НЕ, ИСКЛЮЧАЮЩЕЕ ИЛИ-НЕ. Их значения противоположны (инверсны) результатам выполнения «прямых» операций, т. е. получаются заменой значений 0 на 1 и наоборот. Логические операторы, применяемые к массивам (std Jogicvec- tor — это массив сигналов типа stdJogic), выполняются побитово над каждым из разрядов, при этом тип и размер операндов должны совпадать. Результатом является массив того же типа и размера. 3.5.2. Операторы отношения Операторы отношения в VHDL приведены в табл. 3.3. Операндами могут служить большинство типов VHDL. Результатом является значение типа boolean. 3.5.3. Арифметические операторы Арифметические операторы приведены в табл. 3.4. Операторы определены для основных типов операндов. Допускается смешивать типы, например, для сигнала х, определенного как stdJogic.vector, допустимо писать х <= х + 1;
Язык описания аппаратуры VHDL 141 Операторы отношения в VHDL Таблица 3.3 Оператор < > <= >= = /= Название Меньше Больше Меньше или равно Больше или равно Равно Не равно Пример а < b a>b а <= b а >= b а = b а/= b Таблица 3.4 Арифметические операторы языка VHDL Оператор + - / % ** - Название Сложение Бычитание Умножение Деление Остаток Возведение в степень Унарный минус (смена знака) Пример 2 + 2 = 4 3-1 = 2 2*3 = 6 5/2 = 2 5 % 2 = 1 2**3 = 8 -A) = -1 3.5.4. Операторы сдвига Операторы сдвига являются аналогами подобных операторов, используемых в языках программирования. Они позволяют записывать манипуляции с шинами, заключающиеся в сдвиге их значений на один или несколько разрядов. Существуют следующие операторы сдвига: srl — логический сдвиг вправо; sll — логический сдвиг влево; sra — арифметический сдвиг вправо; sla — арифметический сдвиг влево; гог — логическое вращение вправо; rol — логическое вращение влево. Все операторы имеют два операнда — сдвигаемая шина и число разрядов, на которые производится сдвиг. Например: q = a shr 2; это сдвиг шины а на 2 разряда вправо. При операциях вращения «теряемый» бит помещается с противоположного конца разрядной сетки числа. Отличием логического и арифметического сдвигов является поведение старшего разряда. Дело в том, что операции сдвига являются удобным способом умножения и деления на целые степени двойки — 2, 4, 8, 16 и т.д. Действительно, рассматривая двоичное число
142 Глава 3 0001, нетрудно убедиться, что его сдвиг влево на 1 разряд даст число 0010 (т.е. 2ю), далее 0100 Dю), 1000 (8ю). Рассмотрим теперь представление чисел в дополнительной двоичной арифметике: 0ю - 1ю = -1ю ~> 000000002 - 000000012 = 111111112 - 255ю -1 - 1 = —2 -> 111111112 - 0000000b = 111111102 = 254ю Можно предположить, что операция деления -2/2 с помощью сдвига на один разряд вправо должна давать правильный результат. Если воспользоваться логическим сдвигом, при котором в освобождающиеся разряды помещается 0, то 11111110 srl 1 даст в результате ОИИШг, что соответствует десятичному числу 127. С точки зрения беззнаковой арифметики этот результат является правильным, так как 254/2 = 127. Однако при трактовке числа IIIIIHO2 как числа —2 в дополнительной двоичной арифметике результат некорректен. Для решения этой проблемы используется операция арифметического сдвига вправо, который отличается тем, что старший разряд сдвигаемого числа сохраняется. В этом случае оказывается, что 11111110 sra 1 = 11111111, т.е. -2/2 = -1. 3.5.5. Операторы сцепления Оператор сцепления (конкатенации) & служит для получения числа большей разрядности, составленного из операндов. Например: a, b : stdJogic_vectorC downto 0); q : stdJogicvectorG downto 0); a <= 011"; b <= 100" q <= a & b; - результатом q будет 011.1100" 3.6. Конкурирующие (concurrent) операции Конкурирующие (concurrent) операции названы так потому, что все действия в цифровой схеме выполняются одновременно. Текст на языках описания аппаратуры не описывает последовательность работы создаваемой схемы, а задает порядок ее синтеза. Поэтому добавление дополнительных строк в описание не увеличивает время выполнения операций, как в программах, исполняемых процессорами, а увеличивает размер схемы. Простейшим видом конкурирующей операции является оператор безусловного присваивания. Его также называют continuous присваиванием, поскольку описываемая операция действует постоянно, а не выполняется один раз.
Язык описания аппаратуры VHDL 143 Пример: а <= 'I1; d <= b and с; Показанные строки создают схемы, которые постоянно поддерживают для сигнала а уровень логической единицы, а для сигнала d — результат логического выражения b and с. При изменении любого из сигналов Ь, с сигнал d изменится автоматически постольку, поскольку созданная схема не требует дополнительного управления ее работой. В рамках конкурирующего присваивания можно воспользоваться условным оператором when, имеющим следующий вид: <сигнал_назначения> <= <выражение1> when <условие> else <выражение2>; Например, q <= '1' when a = b else '0'; Сигнал q будет равен '1* все время, пока выполняется условие а = Ь. Поскольку схемы, построенные по такому описанию, формируются с помощью комбинационной логики, ветка else обязательна, так как даже при невыполнении условия значение сигнала все равно должно быть определено. 3.7. Процедурные блоки Процедурные блоки предназначены в основном для моделирования цифровых устройств на VHDL. Однако блоки process могут быть также и синтезируемыми, и предназначены для описания синхронных (тактируемых) схем. Блок process имеет следующий синтаксис: process (<список чувствительности^) begin <операторы> end process; Список чувствительности («sensitivity list») представляет собой список сигналов, изменение которых должно приводить к выполнению операторов, перечисленных внутри «операторных скобок» begin/end process. Можно, например, реализовать с помощью блока process обычное комбинационное выражение. Process(a, b) begin q <= a and b; end process;
144 Глава 3 Такая запись эквивалентна выражению непрерывного присваивания q <= a and b; С точки зрения моделирования различие состоит в том, что для оператора присваивания повторный расчет выражения производится при изменениях любого из сигналов, участвующих в выражении, а для блока process — только для сигналов, перечисленных в списке чувствительности. Для приведенных выше примеров результат будет одинаковым, однако возможны ситуации, когда сокращение списка чувствительности до необходимого минимума способен ускорить процесс моделирования за счет отказа от повторного перерасчета выражений, которые в конечном итоге не влияют на работу схемы. С другой стороны, рассмотрим запись process(a) begin q <= a and b; end process; Несмотря на то что будет синтезирован вентиль 2И, при его моделировании значение выхода не будет рассчитываться при изменениях сигнала Ь, поскольку его нет в списке чувствительности. Следовательно, результаты моделирования окажутся несоответствующими реальному поведению такого устройства. Основное использование блока process в синтезируемых схемах — реализация синхронных схем, простейшим примером которых является D-триггер (D-flip-flop). Это устройство, имеющее вход данных d и выход данных q, а также тактовый вход elk. По фронту тактового сигнала выход принимает значение, равное действующему в этот момент на входе. D-триггер, таким образом, является простейшим элементом памяти. Описание D-триггера на VHDL с помощью процедурного блока process приведено ниже. entity dff is Port (elk : in STD_LOGIC; d : in STDXOGIC; q : out STD-LOGIC); end dff; architecture Behavioral of dff is begin process(clk) begin if elk'event and elk = 'I1 then q <= d;
Язык описания аппаратуры VHDL 145 end if; end process; end Behavioral; Ключевое слово 'event, появившееся внутри процедурного блока, является атрибутом сигнала и в данном случае представляет собой условие «произошло событие», т. е. изменение состояния сигнала. Таким образом, условие в целом можно трактовать как «произошло изменение сигнала elk (elk'event), и его значение стало равно 'Г (and elk = 'I')». Следовательно, строки внутри оператора if/end if будут выполняться каждый раз в момент положительного перепада (фронта) сигнала elk. Внутри процедурного блока находится единственный оператор q <= d; При его выполнении выход q будет принимать значение, равное d. Поскольку выполнение этого оператора будет привязано к моментам положительных перепадов тактового сигнала, итогом синтеза для такого выражения будет D-триггер. 3.8. Управляющие структуры Управляющие структуры в VHDL схожи с управляющими структурами в языках программирования. К ним относятся: if/then case with ... select for... loop while... loop 3.8.1. Оператор if Условный оператор имеет в VHDL одну из следующих форм: process begin if <условие> then <операторы> end if; end process; «Условие» в данной форме записи представляет собой любое выражение, возвращающее логическое значение. Например, D-триггер может быть описан с помощью оператора if, проверяющего условие прихода фронта тактового сигнала: process begin if elk'event and elk = '1' then q <= d;
146 Глава 3 end if; end process; Аналогично условному оператору во многих языках программирования, оператор if в VHDL имеет форму с веткой «иначе». process begin if < условие> then <операторы при выполнении условия> else <операторы при невыполнении условия> end if; end process; В ряде случаев при описании конструкций управления требуется проверка вложенных условий. При этом образуется цепочка условных операторов, наподобие показанной ниже: process begin if a = 1 then count <= count + 1; else if a = 2 then count <= count - 1; if a = 3 then count <= 0; end if; end if; end if; end process; Каждый из использованных операторов требует индивидуальной завершающей строки end if. Для сокращения числа строк можно использовать альтернативную форму: process begin if <условие> then <операторы> elsif <условие> then <операторы> elsif <условие> then <операторы> else <операторы> end if; end process;
Язык описания аппаратуры VHDL 147 Можно еще раз обратить внимание, что оператор if может использоваться только внутри процедурных блоков process. 3.8.2. Оператор case Оператор case имеет вид: process begin case <выражение-селектор> is when <вариант1> => <операторы1> when <вариант2> => <операторы2> when others => <операторы-иначе> end case; end process; В качестве примера рассмотрим арифметико-логическое устройство, выполняющее одну из операций над сигналами a, b в зависимости от значения сигнала and. Если and принимает значение, которому не сопоставлена операция, никаких действий не производится. process begin case cmd is when 0 => res <= a + b; when 1 => res <= a - b; when 2 => res <= a and b; when 3 => res <= a or b; when 4 => res <= a xor b; when others => null; end case; end process; В приведенном примере используется ключевое слово null, которое обозначает отсутствие каких-либо действий. Для синтезатора XST, встроенного в САПР ISE, упоминание строки when others требуется. Более того, при перечислении вариантов переменной- селектора эта строка должна быть последней. Рассмотрим мультиплексор 4-В-1, реализованный с помощью оператора case, в котором в качестве селектора выступает сигнал вида std_logic_vector(l downto 0). signal sel : std_logic_vector(l downto 0); begin Process(a, b, c, d, sel) begin case sel is when 0" => q <= a;
148 Глава 3 when 1" => q <= b; when 0" => q <= c; when 1" => q <= d; end case; end process; Несмотря на то что, на первый взгляд, перечислены все возможные варианты значений селектора, при синтезе такого кода будет обнаружена ошибка. Она связана с тем, что с точки зрения VHDL каждый разряд сигнала stdiogicvector может принимать значения не только 'О' и Т, но и 'X', 'U\ 'Z\ Ъ\ >Н> и т.д. в соответствии со спецификацией языка. Поэтому синтезатор полагает данное описание неполным. Разумеется, в синтезированной конструкции не будет возникать ситуаций, когда значение разряда будет непосредственно равно 'X* или 'U', так как значения «неизвестно» и «не определено» актуальны только для моделирования. Тем не менее данную проблему неполноты описания необходимо разрешить. Например, разработчик может использовать то наблюдение, что кроме комбинаций 0", 1", 0" в работающей конструкции может появиться только 1", которую и можно отнести к «остальным» (others). В этом случае приведенное выше описание можно переписать следующим образом: process(a, b, с, d, sel) begin case sel is when 0" => q <= a; when 1" => q <= b; when 0" => q <= c; when others => q <= d; end case; end process; Подобное описание является корректным с точки зрения получения работоспособной конструкции, однако может служить источником несоответствия результатов моделирования реальному поведению такой системы. Дело в том, что при неопределенном в модели значении селектора (т.е. "XX") в операторе case будет выполняться ветка when others (так как "XX" так же, как и 1", подпадает в этом описании под определение «остальные значения»). Поэтому, несмотря на то, что в реальной конструкции значение селектора при старте может быть равно, например, 0" (что соответствует операции q < = а), программа моделирования посчитает, что следует выполнить q < = d. Проблема усугубляется тем, что если and имеют
Язык описания аппаратуры VHDL 149 при этом одинаковые значения, то разработчик не увидит разницы в поведении реального устройства и его модели и посчитает, что модель составлена корректно. Однако при различных значениях на входах будет наблюдаться несоответствие результатов моделирования реально наблюдаемому поведению. Ошибки подобного рода трудны для диагностирования и требуют дополнительных усилий и времени для исправления. Для повышения удобства моделирования кода можно использовать следующий прием: process(a, b, с, d, sel) begin case sel is when 0" => q <= a; when 1" => q <= b; when 0" => q <= c; when 1" => q <= d; when others => q <= 'X'; end case; end process; В этом примере перечислены все возможные корректные значения сигнала-селектора, а в ветке when others записано, что выходной сигнал должен принять значение «неизвестно». Результаты синтеза такого описания будут эквивалентны предыдущему варианту, но при неинициализированных сигналах в модели на выходе такого устройства будет показано значение «неизвестно», что сразу обратит на себя внимание. Таким образом, идентификация ошибки может быть существенно облегчена. 3.8.3. Оператор with..select Оператор with..select является еще одной разновидностью оператора выбора по селектору, как и case. Он используется вне процедурного блока, однако имеет ограничения по сравнению с case. Формат оператора with..select имеет следующий вид: with < селектор> select <приемник> <= <источник 1> when Оначение 1>, <источник 2> when Оначение 2>, <источник 3> when <значение 3>, <источник 4> when others; Обратите внимание, что отдельные варианты завершаются запятой, а точка с запятой ставится по завершении всей конструкции. Пример реализации мультиплексора с помощью данной конструкции:
150 Глава 3 with sel select q <= a when 0", b when 1", с when 0", d when others; По сравнению с оператором case с помощью данной конструкции невозможно описание «несимметричных» действий. Тогда как with..select может только выбрать одно из значений, записываемых в приемник, с помощью case можно описать цифровой узел, выполняющий действия с различными приемниками при разных значениях селектора. В показанном ниже примере при различных значениях селектора производится запись значений в различные приемники — ql и q2, что потребует двух конструкций with..select. process(a, b, c, d, sel) begin case sel is when 0" => ql <= a; when 1" => q2 <= b; when 0" => ql <= c; q2 <= a; when «11» => ql <= d; when others => ql <= 'X'; q2 <= 'X'; end case; end process; К описанию отдельных значений селектора применимы те же соображения, что и для оператора case. С целью достижения большей адекватности моделирования следует учитывать возможность получения значений селектора 'X', 'U\ Следовательно, все возможные значения, предусматриваемые при нормальной работе, должны быть явно определены, а строка when others должна соответствовать ситуации, когда значение селектора оказалось неопределенным. 3.8.4. Оператор for..loop Оператор for..loop предназначен для организации циклов со счетчиком, управляющих процессом синтеза. Он не предназначен для описания цифровых счетчиков, а позволяет повторить синтез или моделирование некоей конструкции заданное число раз. Ниже приведен пример использования оператора for..loop. Можно обратить внимание, что переменная i не нуждается в отдельном объявлении. process(A, B.BUS) begin for i in 7 downto 0 loop c(i) <= a and b(i);
описания аппаратуры VHDL 151 end loop; end process; Полученная в результате синтеза схема представлена на рис. 3.4 (показаны только старшие разряды). Важно понять, что термин «цикл» относится не к цикличной работе описываемой конструкции, а к организации цикличной установки на кристалл определенного фрагмента схемы. В общем случае, язык описания аппаратуры можно соотнести с программой управления неким автоматическим устройством, AND2 )—ш> Рис. 3.4. Результаты синтеза схемы с использованием оператора for..loop устанавливающим на кристалл компоненты. При этом сложность описания схемы не обязательно означает, что эта схема имеет сложную комплексную структуру и работает медленно. 3.8.5. Оператор while..loop Оператор while..loop служит для организации цикла с условием продолжения исполнения. Он имеет следующий вид: [<метка цикла> :] while <условие> loop <операторы> end loop [<метка цикла>]; Цикл такого вида используется для организации моделирования. Условием выхода из цикла может служить появление запрещающего сигнала или сигнала сброса, достижение некоторого момента времени или конца файла с тестовыми данными. В приведенном ниже примере тактовый сигнал для модели генерируется до тех пор, пока сигнал reset не примет значение 'I1 (тогда выражение not reset примет значение ЛОЖЬ, что соответствует прекращению выполнения цикла). process begin while not reset loop elk <= '0'; wait for 5 ns; elk <= T; wait for 5 ns; end loop; end process; В Показанный пример не приводит к синтезу генератора тактового сигнала. Данный фрагмент используется только для моделирования, т. е. разработчик схемы указывает.
152 Глава 3 что он мооюет обеспечить появление сигнала с описываемым поведением на выводе elk. 3.9. Процедуры и функции Крупные проекты получают существенные выгоды от повторного использования кода и параметризации. Субпрограммы являются эффективным средством организации обоих приемов разработки — они позволяют как организовать программный код для его использования в нескольких модулях, так и сделать этот код достаточно абстрактным для его использования с различными параметрами. Язык VHDL предлагает различные виды субпрограмм — процедуры и функции. Рекомендуется использование процедур и функций для выполнения стандартных, повторяющихся действий или реализация с их помощью сложных операций, требующих повышенного внимания разработчика. Помещение ответственных операций в субпрограммы, а в дальнейшем — в package позволяет разграничить области работы с различными по сложности модулями. Отлаженная и протестированная субпрограмма может в дальнейшем использоваться как блок с известными характеристиками, вокруг которого может выстраиваться проект. Оформление исходных текстов субпрограмм в отдельных файлах снижает опасность их некорректного изменения при разработке. 3.9.1. Процедуры Процедуры в VHDL имеют следующий вид: procedure PROC1 is — объявление процедуры variable VAR1; — объявление локальных переменных begin <операторы> end procedure PROC1; Описанная таким образом процедура может быть вызвана просто по имени. Процедура может быть объявлена и с использованием параметров: procedure PROC2 (INI: in <type> ; OUT1: out <type> ; BIJDIR1: inout <type>) is Параметры с модификатором in могут только читаться. Параметры out могут только изменяться (перезаписываться), и возвращаются вызывающему модулю. Параметры inout могут и читаться процедурой, и изменяться, и также возвращаются вызывающему модулю.
описания аппаратуры VHDL 153 Параметры в VHDL могут принадлежать к следующим классам: • signal; • variable; • constant; • file. По умолчанию параметры типа in (входные) предполагаются имеющими класс constant, a out и inout — variable. При необходимости изменить эти классы следует явно указать их в объявлении процедуры, т.е. procedure PROC2 (signal INI: in stdJogic; signal OUT1: out stdJogic; BLDIR1: inout <type>) is Смысл передачи сигнала в процедуру заключается в том, что в случае передачи константы передается «мгновенное значение», а передача сигнала позволяет процедуре воспользоваться «историей сигнала». Например, если тактовый сигнал будет передан как константа, процедура сможет узнать его текущее значение, но выражение clk'event внутри процедуры использоваться не может, так как понятие event («событие») требует передачи в процедуру не просто мгновенного значения, а всей истории изменения этого сигнала. Для процедуры с параметрами возможен вызов с позиционным или именованным назначением фактических параметров. PROC2(a, Ъ, с); PROC2(IN1 => a, OUT1 => b, BIJDIR1 => с); Как и для подключения сигналов к портам модулей, именованное назначение фактических параметров снижает риск появления ошибки из-за неаккуратности разработчика. - Если процедура объявляется внутри модуля VHDL - package, ее заголовок должен быть объявлен - отдельно, а тело описано в разделе package body, package my .pack is procedure PROCl(in stdJogic a; out stdJogic b); end package my_pack; package body my_pack is procedure PROCl(in stdJogic a; out stdJogic b) is begin end procedure; end package body my.pack;
154 Глава 3 3.9.2. Функции Функции в VHDL имеют вид: function FUNC1 (parameters) return <type> is variable ... begin <операторы> end function FUNC1; Функция отличается от процедуры тем, что возвращает единственный объект, тип которого указан после ключевого слова return: function PAR_GEN (BV : in bit_vector) return bit is variable PAR : bit := '0'; begin — function for i in BV'range loop PAR := PAR xor BV(i) ; end loop ; return PAR ; end function PAR.GEN ; begin — architecture DATA-FRAME <= D.WORD & PAR.GEN (DJWORD); В примере показана функция, которая формирует бит четности для некоторого многоразрядного сигнала с именем BV (от Bit Vector). Ее использование показано в разделе architecture. Результатом синтеза для представленной строки будет комбинационная схема, состоящая из цепочки элементов хог. Ш Показанный пример не создает схему, которая работает циклически, в течение нескольких тактов вычисляя бит четности. Цикличной является только операция синтеза схемы, соединяющая вентили хог. Аналогом являет- ся описание процесса изготовления стула с 4 ножками. Несмотря на то что в инструкции присоединение нооюек к стулу описано последовательно, после изготовления стул не будет перебирать ножками в очередности, показанной при его сборке. Функции могут быть перегружены (overloading). Под перегрузкой понимается возможность использования одной и той же функции с различными сочетаниями типов параметров. Например, среди стандартных функций пакета stdJogic.unsigned имеются варианты оператора -Ь, работающие с двумя значениями std_logic_vector, двумя значениями integer, парой значений std Jogicvector и integer и т. д. (VHDL не имеет предопределенных операторов такого вида). Это
Язык описания аппаратуры VHDL 155 позволяет пользоваться в VHDL выражениями вида а <= а + 1;, где а может иметь тип stdJogicvector, но перегрузка оператора + позволяет свободно использовать его с целочисленным значением X. Это освобождает разработчика от необходимости постоянно производить преобразования типов, что существенно загромождает исходный текст. 3.10. Условная и множественная генерация Для того чтобы обеспечить генерацию только при выполнении определенного условия, можно использовать оператор generate, который имеет следующий вид: [<generate label> :] if <condition> generate <concurrent statements> end generate [<generate label>]; Рассмотрим пример проекта, в котором может либо присутствовать аппаратный умножитель, либо производиться последовательное умножение путем сложения со сдвигом. В зависимости от установленного пользователем параметра HARDWARE_MULTIPLIER производится или не производится синтез выражения mult <= а * b; gen_mult: if HARDWAREJMULTIPLIER = "YES" generate mult <= a * b; end generate gen_mult; Условная генерация удобна для описания зависимых от семейства ПЛИС компонентов. Вели использовать параметры, описывающие наличие или отсутствие каких-либо блоков, в сочетании с операторами условной генерации, то такой модуль на VHDL не потребует редактирования при смене целевого семейства ПЛИС. Например: clk_gen_sp6: if TARGETJPAMILY = "Spartan-6" generate ~ устанавливаем модуль тактового генератора ~ из библиотеки Spartan-6 end generate clk^gen_sp6; if TARGETJFAMILY = "Virtex-7" generate ~ устанавливаем модуль тактового генератора — из библиотеки Virtex-7 end generate clk^gen_v7; При необходимости создания нескольких экземпляров какого- либо устройства или компонента можно использовать оператор множественной генерации: [<generate label> :] for <identifier> in <range> generate
156 Глава 3 <concurrent statements> end generate [<generate label>J; С использованием такого оператора можно создать компактное описание схемы, состоящей из похожих фрагментов. Например, следующий фрагмент создаст 8 умножителей, каждый из которых умножает один и тот же сигнал data на собственный коэффициент k(i). channel8: for i in 0 to 7 generate mult(i) <= k(i) * data; end generate channel8; 3.11. Организация проекта и параметризованные модули Параметры (generic) являются эффективным средством разработки масштабируемых модулей, т. е. модулей, для которых возможна быстрая смена разрядности, числа каналов, пределов счета и тому подобных численных характеристик, при сохранении алгоритмов работы. Параметр определяется с помощью ключевого слова generic в разделе entity. Например: generic (DATA-WIDTH : integer := 8); Впоследствии при упоминании в тексте DATA.WIDTH вместо него будет подставлено значение 8. Параметризованные модули являются достаточно привлекательными для разработки по многим причинам. Рассмотрим, например, реализацию регистров различной разрядности. 8-разрядный регистр. library IEEE; use IEEE.STD-LOGIC-1164.ALL; use IEEE.STDJjOGIC.ARITH.ALL; use IEEE.STD J-OGICJJNSIGNED.ALL; entity reg8 is Port (elk : in STDXOGIC; d : in STD_LOGIC_VECTORG downto 0); q : out STD_LOGIC_VECTORG downto 0)); end reg8; architecture Behavioral of reg8 is begin process(clk) begin if elk'event and elk = '1* then q <= d; end if;
Язык описания аппаратуры VHDL 157 end process; end Behavioral; 16-разрядный регистр. library IEEE; use IEEE.STD.LOGIC-1164.ALL; use IEEE.STD-LOGICJIRITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity regl6 is Port (elk : in STDJLOGIC; d : in STD_L0GIC.VECT0RA5 downto 0); q : out STD_LOGIC_VECTORA5 downto 0)); end regl6; architecture Behavioral of regl6 is begin process(clk) begin if elk'event and elk = '1' then q <= d; end if; end process; end Behavioral; Из описания модулей можно видеть, что кроме имени, они различаются только разрядностью сигналов d и q. Нетрудно понять, что регистр любой разрядности будет описываться процедурным блоком, в котором будет находиться оператор q <= d;. Таким образом, для перехода к другой разрядности необходимо отредактировать только разрядность портов d и q. Используем для управления разрядностью объявление параметра через generic. library IEEE; use IEEE.STDJiOGIC.1164.ALL; use IEEE.STDiOGICJ^RITH.ALL; use IEEE.STDJiOGIC.UNSIGNED.ALL; entity reg_any is generic (DATA_WIDTH : integer := 8); Port (elk : in STD.LOGIC; d : in STD_LOGIC_VECTOR(DATA.WIDTH - 1 downto 0); q : out STD_LOGIC_VECTOR(DATA_WIDTH - 1 downto 0) ); end reg_any; architecture Behavioral of reg_any is begin Process(clk) begin
158 Глава 3 if clk'event and elk = '1' then q <= <*; end if; end process; end Behavioral; При объявлении портов теперь используется не прямое указание числа, а ссылка на определенный через generic параметр, названный DATA-WIDTH (буквально ширина данных или разрядность данных). Поскольку параметр в примере задан равным 8, выражение (DATA-WIDTH - 1 downto 0) эквивалентно G downto 0), что и требуется для 8-разрядного порта. Можно заметить, что редактирование единственной строки, где определен параметр, автоматически изменяет разрядности обоих сигналов — d и q, тогда как при ручном редактировании за приведением разрядности этих сигналов в соответствие друг другу необходимо следить отдельно. Представление требуемых величин в виде параметров особенно эффективно, если они используются в различных модулях, например при разработке системы цифровой обработки сигналов, в которой каждый модуль производит очередное преобразование сигнала. При необходимости изменить разрядность обрабатываемых данных пришлось бы производить коррекции во всех модулях. Для повышения читаемости исходного текста можно использоваться алиасы (alias). Алиас в буквальном переводе означает «прозвище» и служит в программировании для задания альтернативных имен уже существующим объектам. Алиас работает как глобальная подстановка, заменяющая один фрагмент текста другим, поэтому может применяться как для имен объектов, так и для зарезервированных слов VHDL. Например, после нижеследующего объявления: alias SLV is stdiogicvector; можно будет объявлять сигналы в следующем стиле: signal a : SLVG downto 0); Употребление алиасов не следует делать чрезмерным, поскольку на определенном этапе читаемость текста ухудшится из-за обилия непривычных сокращений и замен. Для повышения переносимости и масштабируемости модулей также могут быть полезны атрибуты. Они позволяют обращаться к отдельным характеристикам сигналов композитного типа. Например, если определить сигнал а : std_logic_vectorG downto 0), то следующие атрибуты дадут такие результаты: a'left - 7
Язык описания аппаратуры VHDL 159 a'rigbt - О a'low — О a'high - 7 a'range — 7 downto 0 a'length — 8 a'ascending — FALSE a'reverse_range — 0 to 7. Атрибуты left/right и high/low дают в приведенном примере одинаковые результаты. Разница состоит в том, что left и right возвращают значения, указанные в левой и правой частях объявления размера G downto 0), a high и low вернут наибольший и наименьший индекс. Атрибуты range и reverse_range возвращают интервал изменения индексов в порядке объявления (range) или в обратном порядке (reversejrange). Атрибут ascending возвращает логическое выражение, равное ИСТИНЕ, если интервал композитного типа объявлен в порядке возрастания индексов (т. е. 0 to 7). В приведенном примере этот атрибут вернет ЛОЖЬ, поскольку использовано объявление с ключевым словом downto. Можно еще раз вернуться к примеру функции, рассмотренной в разделе 3.9.3: function PAR_GEN (BV : in bit.vector) return bit is variable PAR : bit := '0'; begin — function for i in BV'range loop PAR := PAR xor BV(i) ; end loop ; return PAR ; end function PAR_GEN ; В объявлении функции не указана разрядность входного сигнала. Вместо этого в теле функции используется атрибут 'range. Это дает возможность вызывать такую функцию для сигналов различной разрядности, при этом вместо атрибута будет подставлена соответствующая строка (например, 7 downto 0). Такой подход делает функции более универсальными и позволяет обойтись меньшим объемом вспомогательных библиотек. Приведенные выше атрибуты являются предопределенными. В синтезаторе XST можно также использовать атрибуты, определенные пользователем, или добавленные Xilinx при адаптации языка VHDL для проектирования ПЛИС. Например, следующая строка
160 Глава 3 укажет синтезатору, что для блока RAM1 следует использовать реализацию в виде блочной памяти. attribute RAMJSTYLE of RAMl: entity is "BLOCK"; Подробный список атрибутов и правила их использования приведены в справочной системе САПР ISE или Vivado. 3.12. Пакеты и библиотеки Пакеты (VHDL package) являются отдельной разновидностью элементов проектов на VHDL. Они используются для хранения общих элементов проекта (а также рабочей группы или организации) — констант, функций, процедур и т. п. Структура пакета показана ниже. package MY-PACK is constant ... function ... component ... alias... type ... end package MYJPACK; Пакет подключается к модулям с помощью строки вида use work.MY_PACK.aU; При необходимости подключить конкретные элементы, описанные в пакете, вместо идентификатора all используется имя этого элемента. Например, если в пакете определена константа DATAWIDTH, подключить только ее можно следующим образом: use work.MYJPACK.DATAWIDTH; Эта возможность представляется достаточно удобной, если в пакете есть множество объявлений, которые по каким-либо соображениям нежелательно помещать в область видимости VHDL-модуля. Все программные модули VHDL и пакеты помещаются в библиотеки. Если не указано иное, компоненты, описанные в модулях, помещаются в библиотеку с именем work (отсюда имя подключаемых компонентов в приводимых выше примерах, начинающееся с «гуог/c.»). Библиотеки не имеют строгих ограничений по типу размещаемых в них компонентов. К модулям, разрабатываемым в стиле RTL, следует подключать стандартную библиотеку IEEE: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD-LOGIG-ARITH.ALL; use IEEE.STDJiOGICLUNSIGNED.ALL;
Язык описания аппаратуры VHDL 161 Такое объявление автоматически генерируется для всех модулей на VHDL в случае использования мастера создания новых компонентов в САПР. 3.13. Моделирование на VHDL 3.13.1. Основы моделирования Моделирование цифровых систем является важным шагом в маршруте их разработки. Возрастание сложности проектируемых устройств заставляет разработчиков тратить все больше времени на их моделирование. Целями моделирования могут быть как исследование алгоритмов работы проектируемого устройства, так и верификация характеристик, получаемых при его аппаратной реализации. В первом случае производится моделирование на верхних уровнях абстрагирования (т. е. преимущественно на поведенческом и, возможно, RTL), а моделирование на физическом уровне призвано проверить возможность работы созданного устройства в заданных условиях эксплуатации (т. е. проверяется возможность работы на заданной тактовой частоте, с требуемыми длительностями сигналов, в заданном температурном диапазоне и т. д.). При моделировании используется подход, основанный на «испытательном стенде» (testbench). Моделируемое устройство (в англоязычной литературе UUT, Unit Under Test) представляется своим синтезируемым кодом, а для проверки его поведения в различных условиях создаются описания тестовых воздействий («моделируемый код»). Задание тестовых входных воздействий может быть выполнено на VHDL с помощью модуля типа VHDL Test Bench. В качестве примера рассмотрим процесс моделирования модуля my .and, синтезируемое описание которого представлено ниже: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STDJLOGICJUUTH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity my_and is Port (a : in STD.LOGIC; b : in STD_LOGIC; с : out STDXOGIC); end my_and; architecture Behavioral of my_and is begin c <= a and b after 3 ns; end Behavioral;
162 Глава 3 Xil.iNX Рис. 3.5. Создание модуля, описывающего тестовые воздействия Данное описание является поведенческим, так как в нем присутствует конструкция after 3 ns, которая моделирует задержку срабатывания вентиля 2И, После добавления к проекту такого компонента можно вновь воспользоваться мастером создания новых модулей. Для унификации обозначений обычно применяется сочетание символов tb (от testbench, «испытательный стенд»). Так, если модуль имеет название my_and, то с ним удобно сопоставить тестовый файл my.and-.tb или top.tb. В САПР Vivado не генерируется шаблон теста с автоматической привязкой к интерфейсу, как это было сделано в САПР ISE. Вместо этого шаблон необходимо ввести самостоятельно, как показано в листинге, приведенном ниже. LIBRARY ieee; USE ieee.stdJogic.1164.ALL; USB ieee.numericjstd.ALL; LIBRARY UNISIM; USB UNISIM.VcomponentsALL; ENTITY top_topj3ch_tb IS END top.top-sclutb; ARCHITECTURE behavioral OF topJtopjsdutb IS COMPONENT top PORT(a b с : END CO] SIGNAL a SIGNAL b SIGNAL с BEGIN IN STDJLOGIC; IN STD-LOGIC; OUT STDJLOGIC); MPONENT; STDXOGIC; : STD.LOGIC; STDXOGIC; UUT: top PORT MAP( a => a.
Язык описания аппаратуры VHDL 163 Рис. 3.6. Ввод имени тестового модуля Ъ => Ъ, с => с ); - *** Test Bench - User Defined Section *** tb . PROCESS BEGIN WAIT, ~ will wait forever END PROCESS; - *** End Tbst Bench - User Defined Section *** END; Это описание необходимо модифицировать для получения требуемого эффекта от моделирования. Предположим, что требуется проверить поведение модуля при последовательной установке в логическую единицу сначала входа а, а затем входа Ь. Тогда раздел «секция пользователя» (User Defined Section) будет выглядеть так: - *** Tbst Bench - User Denned Section *** tb : PROCESS BEGIN a <= '0', T after 20 ns; b <= '0', '1' after 30 ns;
164 Глава 3 Р R О J F С Г M А N А<Г) € Я - J ' ' ¦ ¦ ¦, j top 'I" top Шр SCb tb Рис. 3.7. Запуск моделирования в САПР Vivado WAIT; - will wait forever END PROCESS; - *** End lest Bench - User Denned Section *** Запуск моделирования в Vivado производится в панели управления, как показано на рис. 3.7. Запуск поведенческого моделирования (Behavioral Simulation) приведет к построению временных диаграмм работы модуля. На рис. 3.8 показано, что для заданных входных воздействий симулятор автоматически определил правильное состояние выхода с. В САПР ПЛИС возможно проведение моделирования на физическом уровне, когда задержки распространения сигналов не принимаются равными тем, которые указаны в поведенческом описании, а рассчитываются исходя из физических моделей компонентов ПЛИС и трассировки конкретного проекта. Для моделирования в таком режиме необходимо выбрать пзгнкт Run Post-Implementation Timing Simulation. Результаты моделирования показаны на рис. 3.9. С учетом задержки распространения сигнала логическая единица на выходе с появляется не в момент времени 30 не, а в момент 33,706 не.
описания аппаратуры VHDL 165 Рис. 3.8. Временные диаграммы при моделировании в поведенческом режиме Рис. 3.9. Результаты моделирования модуля my_and в режиме Post-Route Ш Дополнительная величина 3,706 не не является задержкой распространения через единственный логический вентиль, что было бы чрезмерно завышенным, результатом для 28-нм элементной базы. Данная задержка определена с учетом влияния входных буферов для сигналов аиЬ и выходного буфера выхода с, подключенных к выводам ПЛИС. Для получения результатов Post-Route моделирования необходимо, как следует из названия, выполнить трассировку (Routing) проекта. Таким образом, результат оказывается привязан к конкретной элементной базе. Кроме того, его получение связано с необходимостью анализа физических моделей компонентов, что требует существенно большего времени по сравнению с выполнением поведенческого моделирования. Однако такой результат существенно точнее, поскольку времена распространения сигналов рассчитывается по реальной трассировке, а не вводятся в модель из субъективных соображений. При проектировании цифровых систем моделирование на физическом уровне обычно используется на завершающих этапах ве- Рификации проекта, когда требуется подтвердить не просто пра-
166 Глава 3 вильность выполнения преобразований, а соблюдение временных характеристик установления и распространения сигналов. В процессе отладки удобнее использовать моделирование на поведенческом уровне, поскольку оно производится существенно быстрее. В этом случае даже ориентировочные величины задержек позволяют иллюстрировать временной сдвиг сигналов друг относительно друга, что позволяет отлаживать архитектуру устройства. Основные тестовые воздействия задаются внутри процедурных блоков process. В примере, показанном выше, было использовано последовательное назначение состояний отдельным сигналам с помощью ключевого слова after. При этом указывались абсолютные времена, т. е. моменты времени относительно начала моделирования. Другим вариантом является использование конструкции wait for: tbl : process begin reset <= '1'; wait for 100 ns; reset <= '0'; wait ; end process tbl; В данном примере сигналу reset присваивается значение Т, а затем, по истечении интервала времени 100 не, присваивается значение Ч)\ Интервал времени отсчитывается от того момента, который был действителен при выполнении wait for. В качестве еще одного примера можно рассмотреть формирование бесконечного тактового сигнала (free running clock). — создается тактовый сигнал с инициализацией signal elk : stdJogic.vector := Т; architecture ... begin elk <= not elk after 5 ns; В данном примере инициализация обязательна, поскольку в противном случае взять инверсное значение от неопределенного изначально сигнала окажется невозможно. Таким способом моделируется сигнал с периодом в 10 не, так как для получения одного периода необходимо два раза инвертировать значение сигнала, а интервал между этими операциями задан равным 5 не. architecture test of myjnodule is signal elk : stdJogic; constant PERIOD : time := 10 ns; begin
Язык описания аппаратуры VHDL 167 clk-tb: process begin if elk = fU» then elk <= T; wait for PERIOD /2 end if; elk <= not elk; wait for PERIOD /2; end process clk.tb; В этом примере используется отдельный процесс, в котором проверяется состояние тактового сигнала. Если он был неопределенным, что наблюдается только при старте моделирования, ему присваивается значение Т, и моделируется пауза, равная половине периода тактового сигнала. В противном случае значение инвертируется, и также моделируется пауза. В модели на VHDL можно встроить проверку выполнения определенных условий. Это производится с помощью оператора assert. Пример его использования показан ниже: assert SUM_EXPECTED = SUM.OUT report "ERROR: output SUM is incorrect" severity warning; После ключевого слова assert указывается условие, которое предполагается истинным (т. е. при нормальной работе модуля оно должно выполняться). Бели условие не выполняется, в консоль выводится сообщение, указанное после ключевого слова report. После severity указывается уровень важности проверяемого условия. Он может быть следующим: • note — «примечание», это сообщение не является ошибкой и носит информационный характер; • warning — «предупреждение», такие сообщения подсчитывают- ся, но их наличие не является основанием для признания результатов некорректными; • error — «ошибка», результат моделирования признается некорректным, моделирование продолжается; • failure — «сбой», аналогично ошибке, но выполнение немедленно прерывается. По умолчанию сообщения имеют уровень error. Назначение уровня важности производится самим разработчиком теста. Предполагается, что сообщения уровня «сбой» будут присваиваться ошибкам, которые не могут быть достаточно легко
168 Глава 3 исправлены или относятся к «ситуациям, которые никогда не могут возникнуть». Возникновение сообщения такого уровня должно означать, что в процессе моделирования возникли существенные проблемы и производить дальнейший анализ не имеет смысла. Последовательная и максимально полная проверка выполнения наиболее важных условий с помощью набора операторов assert может существенно повысить надежность создаваемых модулей. Тестирование особенно важно для проектов, состоящих из большого числа повторно используемых модулей и IP-ядер. В процессе отладки сложного проекта, когда некорректная работа может объясняться большим числом причин, последовательное покомпонентное моделирование может ускорить процесс идентификации проблемы. 3.13.2. Использование файловых операций Доступ к файлам из модулей на VHDL может быть полезен в целом ряде случаев. Для синтезируемых модулей в файлах удобно хранить данные для инициализации памяти (впрочем, из файлов можно загрузить любые данные). Для моделей в файлах могут храниться тестовые воздействия и образцовые отклики моделируемых систем. Удобство использования текстовых файлов обусловлено также тем, что какие-то данные или параметры для проектирования на VHDL могут быть получены с помощью других программных инструментов — например, пакета Matlab или программы на языке высокого уровня, которая сохраняет результаты работы в текстовом формате. Для доступа к файлам потребуются объекты следующих типов: • TEXT — ссылка на текстовый файл; • LINE — строка, читаемая из файла, с которой будут производиться последующие действия. Для работы с текстовыми файлами используются следующие основные функции: • READLINE — читает очередную строку из файла; • READ — выделяет фрагмент данных из ранее прочитанной строки; • WRITE — помещает фрагмент данных в строку для последующей записи в текстовый файл; • WRITELINE — записывает строку в конец файла; • ENDFILE -— проверка достижения конца файла. Рассмотрим пример: variable LineOfText : line; file source : TEXT open READ .MODE is "source.txt";
Язык описания аппаратуры VHDL 169 В данном случае объявляется переменная LineOfText типа line, которая впоследствии будет использоваться для чтения строк из текстового файла. Также объявляется переменная файлового типа (указатель на файл). Формат объявления такой переменной имеет следующий вид: file <имя переменной> : TEXT open <режим> is <путь к файлу> ; Режим может иметь значения READ_MODE, WRITE_MODE в зависимости от желаемого вида работы с файлом. Input и Output являются предопределенными указателями для работы с консолью. После объявления переменных для работы с файлом следует прочитать строку с помощью функции readline: readline(source, LineOfText); Теперь, когда строка из файла прочитана, можно получить записанные в ней значения. Это выполняется с помощью функций read и hread: read (LineOfText, var, status); hread(LineOfText, hex.var, status); Первая из функций выделяет из строки значение переменной и записывает его в приведенном примере в переменную var. Переменная status хранит результат выполнения преобразования и равна ИСТИНЕ при успешном получении десятичного числа из строки. Для выделения шестнадцатеричного числа служит функция hread, имеющая аналогичный набор параметров. Аналогично производится запись в файл. Создадим переменную, указывающую на файл, предназначенный для записи текста: file dest : TEXT open WRITE .MODE is "report.txt"; Теперь можно подготовить строку для записи в этот файл: write(LineOfText, a); writeline(dest, LineOfText); Подобным образом можно сформировать отчет, подходящий Для изучения разработчиком либо для автоматического анализа с помощью других программных продуктов.
4 Язык описания аппаратуры Verilog Глава 4 в целом повторяет структуру и принципы построения предыдущей главы. При необходимости изучения только одного из языков достаточно ознакомиться только с соответствующей главой без потери значимого материала. Тем не менее рекомендуется следовать порядку изложения материала, принятому в книге*. 4.1. Основы языка Verilog Основой описания на Verilog является модуль, представляемый в виде отдельного файла, обычно с расширением .v. Структура модуля на языке Verilog представлена ниже. module <имя> ([параметры] <объявления портов>) [объявления локальных сигналов и переменных] < синтезируемые конструкции> endmodule Пример шаблона с именем my_and.v выглядит следующим образом: 4timescale Ins / lps module my.and( input a, input b, output с ); endmodule Директива 4timescale предназначена для задания временных интервалов моделирования. Первый из них, равный в приведенном примере 1 не, задает длительность «единицы времени по умолчанию» для моделирования. В поведенческих описаниях, учитывающих время распространения сигналов, все временные интервалы с неуказанными единицами измерения будут рассматриваться как представленные в наносекундах. Второй параметр директивы 4time- scale задает величину дискретного шага, используемого средствами моделирования. В приведенном примере он равен 1 пс. * Если вы пропустили изучение главы 3, рекомендуется ознакомиться с материалом на стр. 118-122.
Язык описания аппаратуры Verilog 171 (Э Первым символом xtimescale является не апостроф, а знак, размещенный на клавише ~. Это снсе символ используется и для других директив — например, ^define. ^timescale Ins / lps module my_and( input a, input b, output с ); assign #3 с =а & b; endmodule Представленный модуль содержит строку, реализующую его описание: assign #3 с = а & Ь; Оператор непрерывного присваивания assign предназначен для описания сигналов, формируемых с помощью комбинационной логики. В данном случае выражение с = а & b синтезирует схему 2И с входами а и b и выходом с. Фрагмент описания #3 говорит о том, что установление нового значения происходит через 3 не («3 единицы времени») после изменения сигналов на входах. Полученное описание добавляется в проект немедленно и его поведение может быть промоделировано как на поведенческом (путем анализа текста на Verilog), так и на физическом (путем анализа физических моделей отдельных компонентов для конкретной аппаратной реализации) уровнях. 4.2. Типы данных В Verilog существуют два основных типа данных: цепи (net) и переменные (variable). Ключевое различие между ними состоит в поведении при моделировании: цепи постоянно отслеживаются, и их состояние обновляется немедленно после изменения состояния сигналов, от которых зависит состояние цепи. Состояние переменных обновляется только внутри специальных процедурных блоков, специально вносимых разработчиком в текст модуля на Verilog. Существуют следующие разновидности цепей: • wire — обычное соединение между двумя узлами электрической схемы; • tri — трехстабильное соединение; • wand, triand — монтажное И; • wor, trior — монтажное ИЛИ; • triO — притягивающий резистор к уровню земли;
172 Глава 4 • tril — притягивающий резистор к уровню питания; • trireg — цепь, имеющая емкость; • supplyO — уровень земли; • supplyl — уровень питания. Поскольку Verilog предназначен в первую очередь для моделирования, в том числе и цифровых систем, состоящих из нескольких микросхем, соединяемых печатными проводниками, большинство цепей из представленного списка не имеют синтезируемого представления, а предназначены для моделирования соединений. Например, «монтажное И», «монтажное ИЛИ» применимы при объединении сигналов резисторно-транзисторной (РТА) или транзисторно- транзисторной логики (ТТЛ) на уровне печатной платы. Основным типом цепей при проектировании цифровых систем на базе ПЛИС является wire. Может также применяться tri, для случаев, относящихся к аппаратно реализованным буферам с третьим состоянием. Начиная с технологических норм 90 нм, основные производители ПЛИС с архитектурой FPGA отказались от реализации аппаратных буферов с третьим состоянием для внутренних цепей. Использование буферов с тремя состояниями ограничивается выходными линиями PPGA. 11 Сигналы с третьим состоянием могут бььть объявлены для внутренних цепей ПЛИС и объединены с использованием схем разрешения одного из выходов, однако средства синтеза заменяют такие описания на эквивалентные узлы мультиплексируемой комбинационной логики. Основным типом переменных в Verilog является reg. Это объект, который сохраняет записанное в него значение, и изменяет его только в явно определенные моменты. Переменная типа reg не означает автоматического применения триггера для ее реализации. Соответствующая синтезируемая схема может быть выполнена с использованием синхронной либо комбинационной логики в зависимости от того, как именно описано присваивание новых значений такой переменной. Сигналы внутри процедурных блоков initial и always могут присваиваться только объектам, имеющим тип reg. Например, мультиплексор на Verilog может быть описан одним из следующих способов. С помощью комбинационной логики и оператора непрерывного присваивания assign: module MUX2 (input А, В, SEL, output wire OUT1); assign OUT1 = (A & SEL) | (B & ~ SEL); endmodule
описания аппаратуры Verilog 173 С помощью процедурного блока always: module MUX2 (input А, В, SEL, output reg OUT1); always О (А, В, SEL) if (SEL) OUT1 = A; else OUT1 = B; endmodule В приведенных выше описаниях разные стили обуславливают разный тип выхода OUT1. Во втором случае, поскольку внутри модуля присваивание нового значения осуществляется внутри процедурного блока always, выход OUT1 объявлен как reg. В первом же варианте мультиплексора он имеет тип wire (это ключевое слово может быть опущено, поскольку wire является типом по умолчанию). Синхронная (тактируемая) логика может быть описана только процедурным блоком: module DFF (input CLK, D, output reg Q) ; always О (posedge CLK) Q = D; endmodule Назначение новой величины выходу Q производится только внутри процедурного блока и только в моменты, когда выполняется условие posedge CLK (т.е. переход уровня сигнала CLK от логического нуля к логической единице). Поэтому для такого описания синтезируется D-триггер (D flip-flop). 4.3. Формат представления значений Основными значениями, которые могут быть присвоены цепям и переменным, являются: 0 — логический ноль; 1 — логическая единица; z — «третье состояние», высокий импеданс; х — неизвестное состояние (unknown). Неизвестное состояние не имеет синтезируемого аналога, а используется при моделировании. Оно может возникнуть, когда в процессе моделирования выявился электрический конфликт (например, два источника сигнала попытались задать различные логические уровни для одной и той же цепи), или быть искусственно сформировано разработчиком, если он планирует таким образом выявить возникновение ситуации, которая допустима с точки зрения электроники, но неприемлема по соображениям нормгильной работы Устройства. В этом случае по наличию состояний «х» можно будет быстро идентифицировать блоки, работающие некорректно.
174 Глава 4 Для задания чисел используется следующий формат: [разрядность]' [s] [основание] <значение> где «разрядность» — разрядность числа в битах, представленная в десятичной системе счисления; 1 — символ «апостроф»; s — необязательный модификатор, указывающий на то, что число представлено в формате со знаком; «основание» — модификатор основания системы счисления; b — двоичная система счисления; о — восьмеричная система счисления; d — десятичная система счисления (по умолчанию); h — шестнадцатиричная система счисления; <значение> — значение числа, записанное в системе счисления, установленной модификатором. Примеры: 8'ЫПЮООО — двоичное 8-разрядное число 11110000 B40ю); 16'hfiff — шестнадцатиричное 16-разрядное число flff F553Бю); 8М123 — десятичное 8-разрядное число 123. Явное указание разрядности позволяет правильно выбрать число незначащих разрядов, заполняемых нулями (для беззнакового представления чисел), или позицию знакового разряда (для представления чисел со знаком). Например, десятичное число 123 формально может быть записано с использованием только 7 разрядов, поэтому модификатор 8* показывает, что в действительности следует использовать дополнительный, 8-й, разряд, поместив в него 0. Если указанная в модификаторе разрядность числа больше, чем число записанных разрядов, число автоматически расширяется до заданной разрядности: 6'bllll -» 001111 Если указанная в модификаторе разрядность числа меньше, чем число записанных разрядов, число автоматически усекается: 4Ь'11ОООО11 -* ООН Если разрядность числа не згказана, она принимается равной 32. Однако при синтезе разрядность определяется исходя из разрядности переменной или цепи, которой оно присваивается. В записи числа можно использовать символы подчеркивания, которые игнорируются при анализе числа и служат для повышения читаемости текста.
Язык описания аппаратуры Verilog 175 Поскольку объявление reg а соответствует одноразрядному значению, для хранения многоразрядных чисел переменные и цепи объединяются в шины (bus). Формат объявления многоразрядной переменной следующий: reg [7:0] data = 255; В этом примере объявляется 8-разрядная переменная data, разряды которой нумеруются от 7 до 0. При создании переменной присваивается значение 255. Числа в скобках соответствуют индексу крайнего левого и крайнего правого разрядов в представлении числа. В представленном виде они совпадают со старшим значащим разрядом (MSB, Most Significant Bit) и младшим значащим разрядом (LSB, Least Significant Bit), однако допустима и форма записи, при котором первым указывается наименьший индекс: reg [0:7] data = 8Ъ10000000; Исходя из формата объявления присваивание константы 100000002 будет производиться так, что единица в старшем (крайнем левом) разряде записи константы будет присвоена 0-му разряду (крайнему левому в объявлении индексов) переменной data и т. д. Таким образом, хотя двоичная константа может быть прочитана как 128ю, при ее записи в переменную действительным значением окажется 1. Поскольку для человека привычнее форма записи, при которой старший разряд находится слева, удобнее использовать и формат объявления шин, в котором индексы указаны по убыванию — [7:0] вместо [0:7]. Тип данных integer также является распространенной формой объявления переменных integer <name> [= <value>]; Пример: integer data = 255; Целочисленные переменные по умолчанию имеют разрядность 32. В версии стандарта Verilog-95 переменные типа integer не могут инициализироваться в объявлении, для этого требуется отдельный оператор в процедурном блоке: integer data; initial data = 255;
176 Глава 4 Следующие типы данных не являются синтезируемыми и служат для повышения информативности моделирования. Тип real представляет числа с плавающей точкой. real х = 1.23; real у = 3.00е8; Применение чисел такого типа ограничивается в основном вычислением задержек распространения сигналов, а также выполнения математических вычислений, на основании которых можно принять решение о генерации того или иного вида синтезируемого кода. Например, в качестве параметра в модуль на Verilog может быть передана емкость нагрузки или температура окружающей среды, которые удобно представить в формате с плавающей точкой. На основании анализа этих величин могут быть автоматически сгенерированы различные варианты синтезируемых узлов. Тип time предназначен для задания временных задержек. time Tpd = 1 ns; Допустимы следующие единицы измерения: • fs — фемтосекунда; • ps — пикосекунда; • ns — наносекунда; • us — микросекунда; • ms — миллисекунда; • s — секунда. Объект типа time не является синтезируемым, т. е. невозможно создать синтезируемую конструкцию с требуемой задержкой, просто указав ее величину в операторе присваивания. Подобные типы переменных присутствуют в Verilog для облегчения создания возможно более адекватных моделей проектируемых устройств. Таким образом, разработчик, применяя тип time, самостоятельно отвечает за корректность приводимых им величин задержек. Тип string используется для хранения строк, используемых при выводе текстовых сообщений в процессе моделирования или работы алгоритмов синтеза. Однако это несинтезируемый тип в том смысле, что коды символов не формируют регистров или иных запоминающих устройств, а используются только для удобного задания текстовой информации, которую разработчик желал бы показать в консоли САПР или в генерируемом отчете. Infojstring = "This is a message from Verilog module"
Язык описания аппаратуры Verilog 177 4.4. Массивы Такие устройства, как память, удобно рассматривать в виде массивов. Verilog предоставляет возможность описывать массивы с помощью конструкции вида reg [7:0] memory [0:1] В данном случае memory представляет собой не зарезервированное слово, а имя идентификатора, назначенного разработчиком. В данном случае объявляется массив 8-разрядных ячеек, к которым можно обращаться как memory[0], memory[1]. Допустимо объявление многомерных массивов. Например: reg [7:0] memory [0:7] [0:7] Обращение к отдельным ячейкам будет производиться, например, как memory [1] [5]. Технически многомерные массивы представляют собой линейную последовательность ячеек, а несколько индексов, задающих «координаты» ячейки, используются лишь для удобства иллюстрирования обращения к многомерным структурам данных. Аналогично, можно считать, что 8-разрядная ячейка данных является в действительности одномерным массивом отдельных разрядов. Для разрядов действительно допустимы индивидуальные операции: а[7] = Ь[4] В этом примере 7-му разряду переменной а присваивается значение 4-го разряда переменной Ь. Возможны операции с группами разрядов, однако число разрядов в группах с левой и правой стороны от знака присваивания должно совпадать: а[7:5] = Ь[3:1] В этом примере указаны по 3 разряда обеих переменных. Стандарт Verilog-2001 допускает еще одну форму задания разрядов, выбираемых из многоразрядной шины. Например, если объявлена шина а [31:0], то для выбора ее части можно написать: а [31-: 8] - аналогично записи а [31:24] а [1б+:8] — аналогично записи а [23:16] Можно увидеть, что первое число задает стартовый разряд, за которым идет символ -f или -, означающие соответственно увеличение или уменьшение индекса. После двоеточия указывается не
178 Глава 4 конечный разряд, а приращение/уменьшение индекса. Такая форма позволяет более наглядно показать в исходном тексте на Verilog ширину того фрагмента шины, который выбирается. 4.5. Порты Модули, описанные на языке Verilog, обязательно имеют объявление портов — внешних выводов «черного ящика», поведение которого описано в теле этого модуля. Можно еще раз привести структуру модуля на языке Verilog. module <имя> ([параметры] <объявления портов>) [объявления локальных сигналов и переменных] <синтезируемые конструкции> endmodule Существуют три типа портов: • вход (input); • выход (output); • двунаправленный вывод (inout). Сигналы типа reg могут быть только выходами. Входы и двунаправленные выводы должны иметь тип net/wire. Это связано с тем, что значение для входов должно быть известно в любой момент времени, что обеспечивается именно типом wire. Для выходов же возможна ситуация, когда их значение не будет изменяться при данном наборе входных сигналов. В этом случае выход будет удерживать состояние, присвоенное ему ранее, что возможно при использовании сигнала типа reg. Все сигналы по умолчанию имеют тип wire. При необходимости изменить тип на reg каждый сигнал должен быть упомянут отдельно: module regjsum (input [7:0] a, b, input elk, en, output reg [7:0] sum ); always @ (posedge elk) if (en == 1) sum = a + b; endmodule В приведенном примере явно указано, что выход имеет тип reg. Это позволяет присваивать выходу новое значение суммы не по каждому фронту сигнала elk, а только в те моменты, когда присутствует сигнал en («разрешение работы»). В противном случае значение выхода не изменяется. Попытка использовать в этом случае сигнал типа wire приведет к тому, что возникнет неопределенная- ситуация •— в моменты времени, когда сигнал разрешения работы отсутствует,
Язык описания аппаратуры Verilog 179 значение выхода не сможет быть назначено равным сумме входных сигналов. В то же время wire не дает возможности использовать элемент памяти для хранения предыдущего состояния, поэтому для того чтобы в схеме появился регистр, для выхода sum использован тип reg. Стандарт Verilog-95, который, возможно, мог бы потребоваться в рамках совместимости с программным обеспечением ранних версий, требует двукратного объявления сигналов типа reg. module regjsum (input [7:0] a, b, input elk, en, output [7:0] sum reg [7:0] sum ); В первой из выделенных строк объявляется сигнал sum. Во второй указывается, что он имеет тип reg, при этом должна быть повторена спецификация размера. Такой способ, очевидно, менее удобен и содержит избыточную информацию, и стандарт 2001 года допускает более компактное объявление сигналов. 4.6. Соединение модулей Для создания проектов из нескольких модулей требуется их объединение. Причины разбиения проекта на модули могут быть различны, начиная от простого ограничения сложности каждого отдельного модуля и заканчивая необходимостью использовать аппаратные узлы, имеющиеся в составе ПЛИС, которые включаются в проект с помощью библиотечного представления. Предположим, что необходимо создать схему, аналогичную показанной на рис. 4.1. Требуется, чтобы в библиотеке компонентов имелись модули, соответствующие компонентам and2 и or2. Их описания могут быть следующими: Для модуля and2: module and2(input a, input b, output q); assign с = a & b; endmodule Для модуля or 2: module or2(input a, input b, output q); AND2 OR2 Рис. 4.1. Графическое изображение схемы из нескольких модулей
180 Глава 4 assign с = а | b; endmodule Модуль верхнего уровня на языке Verilog будет иметь следующий интерфейс: module top(input a, input b, input с, input d, output q); Внутри модуля верхнего уровня должны присутствовать два компонента and2 и один компонент ог2. Они описываются с применением подхода component instantiation: ранее созданные компоненты указываются в тексте модуля верхнего уровня с перечислением сигналов, которые необходимо подключить к их портам. Однако при взгляде на схему можно заметить, что для соединения выходов компонентов and2 с входами ог2 требуются два проводника, которые являются внутренними цепями и не имеют отдельного имени. Стандарт Verilog не допускает прямое соединения выхода одного компонента с входом другого (т. е., например, нельзя указать для порта а компонента or2, что он подключен непосредственно к порту q компонента and2). Для этого требуется объявление отдельных внутренних цепей: wire netl, net2; Создадим далее схему соединений: and2 componentl(.a(a), .b(b), .q(netl)); and2 component2(.a(c), .b(d), .q(net2)); or2 components(.a(netl), .b(net2), .q(q)); endmodule; Порты верхнего уровня выделены в данном примере жирным шрифтом, чтобы отличать их от совпадающих имен портов компонентов (такое совпадение не является ошибкой). Рассмотрим элементы записи and2 component2 (.a(c), Здесь and2 — имя компонента, как оно приведено в его описании после ключевого слова module; component2 — уникальный идентификатор, присвоенный разработчиком данному экземпляру компонента (в схеме присутствует также component 1 такого же типа); .а — ссылка на порт а компонента; с — указание цепи, к которой должен быть подключен этот порт.
Язык описания аппаратуры Verilog 181 Имена портов компонента можно не указывать, описывая только список сигналов, к которым необходимо подключать порты: and2 component I (a, b, netl); and2 component2(c, d, net2); or2 component3(netl, net2, q); В этом примере подключение к портам компонента осуществляется в порядке их описания в самом компоненте. Это так называемое позиционное назначение сигналов (ordered mapping) когда позиция сигнала в списке подключений совпадает с позицией порта в описании компонента. Предыдущий вариант, с явным упоминанием имен портов компонента, называется именованным назначением (named mapping). Нетрудно видеть, что позиционное назначение несколько компактнее, поскольку не включает в себя имена портов компонента. Тем не менее, именованное назначение позволяет избежать неявных ошибок, когда разработчик перепутал порядок следования имен. В качестве примера рассмотрим абстрактный компонент, который имеет сигналы сброса и разрешения работы: module example(input elk, // тактовый сигнал input data, // сигнал данных input reset, // сигнал сброса input en, // сигнал разрешения работы <прочие сигналы> Не вдаваясь в подробности реализации такого модуля, рассмотрим варианты его подключения с использованием позиционного назначения сигналов. example instO(netl, net2, net3, net4); example instl(clk_net, data_net, en_net, reset_net); example inst2(clk_net, datajiet, reset_net, en_net); Первый вариант объявления не дает возможности быстро убедиться, что подключение выполнено правильно, поскольку имена цепей отличаются только номером. Второй вариант (instl) использует «содержательные» имена, которые включают в себя фрагменты имен портов — например, clk_net дает понятие о том, что этот сигнал следует подключить к порту elk. Однако требуется отдельно сопоставить порядок объявления портов в описании модуля с порядком Упоминания сигналов, чтобы убедиться, что для instl перепутан порядок следования сигналов enjiet и reset л et. Позиционное назначение не позволит САПР выявить или исправить эту логическую ошибку, поскольку никаких формальных запретов на подключение
182 Глава 4 сигнала enjiet к входу reset не существует. Сравним это с именованным назначением: example inst3(xlk(clkjiet), .data(data_net), .en(enjiet), .reset(reset_net)); В этом примере порядок упоминания сигналов en и reset также не совпадает с порядком объявления сигналов в описании модуля. Однако явное упоминание имен сигналов заставит САПР подключить цепь enjiet именно к входу en, несмотря на то что на третьем месте в объявлении компонента находится reset. Таким образом, именованное назначение представляется более безопасным с точки зрения устранения логических ошибок при соединении компонентов. 4.7. Операторы языка Verilog Язык Verilog предлагает разнообразные операторы, которые можно разбить на группы. 4.7.1. Побитовые операторы (bitwise) Данные операторы предназначены для описания логических операций над сигналами и шинами, которые выполняются над соответствующими парами разрядов (битов). Побитовые операторы представлены в табл. 4.1. Для справки можно привести таблицы истинности для побитовых операторов (табл. 4.2). В таблице не приведены варианты для инверсных операторов — И-НЕ, ИЛИ-НЕ, ИСКЛЮЧАЮЩЕЕ ИЛИ-НЕ. Их значения проти- Таблица 4.1 Побитовые операторы языка Verilog Оператор & 1 л Название И (AND) И-НЕ (NAND) ИЛИ (OR) ИЛИ-НЕ (NOR) ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR) ИСКЛЮЧАЩЕЕ ИЛИ-НЕ (NXOR) НЕ (NOT) Пример с = а & Ь; с = а ~& Ь; с = а | Ь; с = а ~| Ь; с = а л Ь; с = а ~л Ь; с = ~ а; Таблица 4.2 Таблицы истинности для побитовых операций А 0 0 1 1 В 0 1 0 1 и 0 0 0 1 или 0 1 1 1 ИСКЛЮЧАЮЩЕЕ ИЛИ 0 1 1 0
Язык описания аппаратуры Verilog 183 воположны (инверсны) результатам выполнения «прямых» операций, т. е. получаются заменой значений 0 на 1 и наоборот. 4.7.2. Арифметические операторы (arithmetic) Арифметические операторы реализуют основные арифметические действия над сигналами и шинами. Основные арифметические операторы приведены в табл. 4.3. Арифметические операторы языка Verilog Таблица 4.3 Оператор + _ * / % ** - Название Сложение Вычитание Умножение Деление Остаток Возведение в степень Унарный минус (смена знака) Пример 2 + 2 = 4 3-1 = 2 2*3 = 6 5/2 = 2 5 % 2 = 1 2**3 = 8 4.7.3. Логические операторы (logical) Логические операторы служат для получения логических значений (ИСТИНА/ЛОЖЬ). Результат выполнения этих операций всегда является однобитовым. К логическим операторам относятся: && — логическое И; || — логическое ИЛИ; ! — логическое отрицание (НЕ). Отличие побитовых и логических операций можно наглядно проиллюстрировать следующим примером: 1111 & 1111 = 1111 — результат содержит столько же разрядов, сколько операнды; 1111 && 1111 = 1 — результат представляет собой однобитовое логическое значение. Необходимо обратить внимание, что объект, принимающий результат, должен быть одноразрядным, чтобы избежать расширения результата нулями до разрядности приемника. Игнорирование этого требования может привести к труднообнаружимым логическим ошибкам, если разработчик ошибочно посчитает, что все разряды приемника принимают одинаковое значение. Например, если сначала выполнить feg [7:0] flag; assign flag = a || b;
184 Глава 4 то при попытке выполнить проверку вида 11110000 & flag результат будет равен 00000000, несмотря на то что формально оба операнда должны трактоваться как логическая ИСТИНА (поскольку в обоих хотя бы один разряд равен 1). В общем случае следует осторожно относиться к представлению логических значений многоразрядными числами, поскольку при несовпадении положений единичных разрядов логическое И над такими числами может дать в результате 0, т. е. ЛОЖЬ. Например, ООН & 1100 = 0000, хотя оба операнда трактуются как ИСТИНА. 4.7.4. Операторы отношения (relational) Операторы отношения служат для выполнения операций сравнения между операндами. > — больше; < — меньше; >= — больше или равно; <= — меньше или равно. Результатом сравнения является логическое (однобитовое) выражение ИСТИНА или ЛОЖЬ. 4.7.5. Операторы равенства/тождества (equality) К операторам проверки равенства и тождества относятся: == — равно; !== — не равно; ===== — тождественно равно; !== — тождественно не равно. Несколько необычные варианты операций «тождественно равно» и «тождественно не равно» проистекают из возможности появления значений z и х (unknown) при моделировании. Если хотя бы один из битов сравниваемых операндов равен этим значениям, обычное сравнение выполнить не удается и результатом операции == будеФ х (неизвестно). Однако можно произвести «буквальное сравнение» с помощью операции ===, которая дает истинный результат, если в каждом бите обоих операндов находятся строго одинаковые символы, включая z и х. Это можно проиллюстрировать примером: if (а ===== ОООх)... операторы, показывающие, что младший разряд равен неизвестному значению. Можно добавить, что операторы проверки тождественности имеет смысл использовать только при моделировании, где они полезны для подробной диагностики состояния моделируемой системы и появляющихся в ней ошибок. Приведенный пример позволя-
описания аппаратуры Verilog 185 ет представить возможности глубокой диагностики появляющихся логических ошибок, когда в модели будет проверяться не только появление значений «неизвестно», но еще и выявляться разряд, в котором они появляются. 4.7.6. Операторы свертки (reduction) Операторы свертки являются компактной формой записи операторов, которые выполняются попарно над разрядами одного операнда. Иными словами, операция применяется к двум младшим разрядам многоразрядного операнда, над ее результатом и следующим разрядом опять проводится такая же операция и так далее вплоть до самого старшего разряда. Verilog допускает следующие операции свертки: & - И; ~& ~ И-НВ; | - ИЛИ; -| - ИЛИ-НЕ; л - ИСКЛЮЧАЮЩЕЕ ИЛИ; ~л - ИСКЛЮЧАЮЩЕЕ ИЛИ-НЕ. Практическое применение операторов свертки заключается, например, в проверке многоразрядного числа на ноль: wire [7:0] а; reg non_zero; assign nonjzero = | a; При выполнении свертки операция ИЛИ будет сначала применена к разрядам 0 и 1 сигнала а. Полученный однобитовый результат будет «свернут» с разрядом 2 и так далее. В соответствии со смыслом операции ИЛИ наличие единицы в любом из разрядов а даст единицу в качестве результата свертки. Аналогично, &а даст в результате 1 только в том случае, если все разряды а равны 1. Операция ла при этом вычислит четность а, т. е. ответит на вопрос, является ли число разрядов, установленных в единицу, четным. 4.7.7. Условный оператор (conditional) Единственный условный оператор Verilog является более короткой формой традиционного условного оператора if/then. Пример такого оператора приведен ниже: assign q = sel ? a : b; В этом примере выходу Q будет присвоено значение А, если сигнал SEL представляет собой логическую ИСТИНУ, и сигнал В в противном случае.
186 Глава 4 Удобно использовать такую форму условного оператора для компактного описания буфера с тремя состояниями: assign q = en ? data : l'bz ; 4.7.8. Операторы сцепления/повторения (concatenation/replication) Операторы конкатенации служат для группировки сигналов в шины. Операторы повторения (replication) являются удобной формой объединения повторяющихся сигналов. Например, если а, Ь, с, d представляют собой одноразрядные сигналы, то выражение {а, Ь, с, d} создаст четырехбитовый сигнал, составленный из «сцепленных» разрядов а, Ь, с, d соответственно. Здесь символы {} служат для оформления оператора конкатенации. Оператор повторения (репликации) является разновидностью оператора конкатенации. Например, выражение {4{а}} полностью аналогично записи {а, а, а, а}, т. е. число 4 обозначает число повторений сигнала, указанного во внутренних фигурных скобках. 4.7.9. Операторы сдвига (shift) Операторы сдвига являются аналогами подобных операторов, используемых в языках программирования. Они позволяют записывать манипуляции с шинами, заключающиеся в сдвиге их значений на один или несколько разрядов. Существуют следующие операторы сдвига: >> — логический сдвиг вправо; << — логический сдвиг влево; >>> — арифметический сдвиг вправо; <<< — арифметический сдвиг влево. Все операторы имеют два операнда — сдвигаемая шина и число разрядов, на которые производится сдвиг. Например: assign q = a » 2; это сдвиг шины а на 2 разряда вправо. Отличием логического и арифметического сдвигов является поведение старшего разряда. Дело в том, что операции сдвига являются удобным способом умножения и деления на целые степени двойки — 2, 4, 8, 16 и т.д. Действительно, рассматривая двоичное число 0001, нетрудно убедиться, что его сдвиг влево на 1 разряд даст число 0010 (т.е. 2ю), далее 0100 Dю), 1000 (8ю). Рассмотрим теперь представление чисел в дополнительной двоичной арифметике: От - 1ю = -1ю -> 000000002 - 000000012 = 111111112 = 255ю -1 - 1 = -2 -> 111111112 - OOOOOOOI2 = IHIHIO2 = 254ю
#зык описания аппаратуры Verilog 187 Можно предположить, что операция деления —2/2 с помощью сдвига на один разряд вправо должна давать правильный результат. Бели воспользоваться логическим сдвигом, при котором в освобождающиеся разряды помещается 0, то 11111110 >> 1 даст в результате 011111112, что соответствует десятичному числу 127. С точки зрения беззнаковой арифметики этот результат является правильным, так как 254/2 = 127. Однако при трактовке числа IIIIIHO2 как числа —2 в дополнительной двоичной арифметике результат некорректен. Для решения этой проблемы используется операция арифметического сдвига вправо, который отличается тем, что старший разряд сдвигаемого числа сохраняется. В этом случае оказывается, что 11111110 >» 1 = 11111111, т.е. -2/2 = -1. 4.8. Приоритет операторов При наличии нескольких операторов в выражении они выполняются с учетом приоритета. Наивысшим приоритетом обладают унарные операторы, низшим — операторы конкатенации сигналов. Список операторов Verilog в порядке убывания приоритета приведен ниже: унарные и операторы редукции + - ! ~ &~ & | ~| л ^л л ~ возведение в степень ** умножение, деление, остаток * / % сложение, вычитание -f - сдвиг « » <« »> операторы отношения <<= >>= сравнение == != ===== !=== логическое И & побитовое ИСКЛЮЧАЮЩЕЕ ИЛИ, ИСКЛЮЧАЮЩЕЕ ИЛИ- НЕ л ~л побитовое ИЛИ | логическое И && логическое ИЛИ || условный оператор ? : операторы конкатенации и репликации {} {{}} При необходимости изменения порядка вычисления следует использовать скобки. Кроме того, расстановка скобок в ряде случаев помогает получить более эффективную схемотехническую реализацию при синтезе.
188 Глава 4 4.9. Процедурные блоки Процедурные блоки предназначены в основном для моделирования цифровых устройств на Verilog. Однако блоки always могут быть также и синтезируемыми, и предназначены для описания синхронных (тактируемых) схем. Блок always имеет следующий синтаксис: always @(<список чувствительности>) begin <операторы> end Список чувствительности (sensitivity list) представляет собой список сигналов, изменение которых должно приводить к выполнению операторов, перечисленных внутри операторных скобок begin/end. При этом символ @ (читается как at) вместе с ключевым словом always образует фразу вида «всегда при () выполнять». Можно, например, реализовать с помощью блока always обычное комбинационное выражение: always @(а, b) begin q = а & b; end Такая запись эквивалентна выражению непрерывного присваивания assign q = а & b; С точки зрения моделирования различие состоит в том, что для оператора assign повторный расчет выражения производится при изменениях любого из сигналов, участвующих в выражении, а для блока always — только для сигналов, перечисленных в списке чувствительности. Для приведенных выше примеров результат будет одинаковым, однако возможны ситуации, когда сокращение списка чувствительности до необходимого минимума способен ускорить процесс моделирования за счет отказа от повторного перерасчета выражений, которые в конечном итоге не влияют на работу схемы. С другой стороны, рассмотрим запись always @(а) begin q = а & b; end Несмотря на то что будет синтезирован вентиль 2И, при его моделировании значение выхода не будет рассчитываться при изменениях сигнала Ь, поскольку его нет в списке чувствительности.
Язык описания аппаратуры Verilog 189 Следовательно, результаты моделирования окажутся несоответствующими реальному поведению такого устройства. Основное использование блока always в синтезируемых схемах — реализация синхронных схем, простейшим примером которых является D-триггер (D-flip-flop). Это устройство, имеющее вход данных d и выход данных q, а также тактовый вход elk. По фронту тактового сигнала выход принимает значение, равное действующему в этот момент на входе. D-триггер, таким образом, является простейшим элементом памяти. Описание D-триггера на Verilog с помошью процедурного блока always приведено ниже. module dff(input elk, input d, output reg q); always @ (posedge elk) q <= d; endmodule В списке чувствительности данного примера появилось ключевое слово posedge. Оно означает «положительный перепад» (edge — край, порог), т.е. переход от состояния 0 к состоянию 1. Этот момент времени соответствует, таким образом, фронту сигнала elk. Ш При моделировании условие posedge elk выполняется также при переходах от х к 1 или от z к 1. Это может привести к лишнему срабатыванию условия posedge, если тактовый сигнал, находящийся изначально в неопределенном состоянии, будет инициализирован в 1. Следует обеспечивать инициализацию сигналов для корректного моделирования. По аналогии условие наступления спада тактового сигнала (переход от 1 к 0) задается выражением negedge elk. Внутри процедурного блока находится единственный оператор q <= d; При его выполнении выход q будет принимать значение, равное d. Поскольку выполнение этого оператора будет привязано к моментам положительных перепадов тактового сигнала, итогом синтеза для такого выражения будет D-триггер. Обратите внимание, что для сигнала q использован тип reg. Комбинируя различные условия внутри процедурного блока, можно получить варианты триггера с различными особенностями поведения. К дополнительным сигналам, управляющим поведением триггера, обычно относятся:
190 Глава 4 • се (Clock Enable, разрешение счета), также обозначаемый как en (Enable, разрешение) — сигнал, разрешающий изменение состояния триггера. Высокий уровень на этом входе разрешает выполнение оператора q <= d; • reset (сброс) — сигнал сброса, устанавливающий триггер в состояние нуля. Различают синхронный сброс, выполняющийся по фронту тактового сигнала (обычно его и обозначают как reset), и асихронный, выполняющийся немедленно при появлении высокого уровня, который обычно обозначают как clr (clear, очистка); • set (установка) — сигнал установка, устанавливающий триггер в состояние единицы. Как и для сброса, различают синхронную установку (set), выполняющуюся по фронту тактового сигнала, и асинхронную (preset), выполняющуюся немедленно. Кроме того, все управляющие сигналы могут иметь как высокий, так и низкий логический уровень, при котором условие их появления считается истинным. Такой уровень для сигналов также называют активным. Иными словами, если при появлении единицы на входе reset происходит сброс триггера, то говорят, что активным уровнем для входа reset является высокий, т. е. сигнал логической единицы. Активный низкий уровень часто используется в схемах, выполненных по технологии РТЛ или ТТЛ, где возможно использование схемы «монтажное ИЛИ». При такой схеме входной сигнал с помощью резистора подключался к положительной цепи питания, что обеспечивало «слабый» уровень логической единицы. При этом любой активный выход, который устанавливал уровень логического нуля, перекрывал единицу, установленную резистором. Поведение триггера при одновременном действии нескольких сигналов с противоположным смыслом определяется описанием на Verilog. Например, если сначала проверить сброс, а потом установку, то сброс будет обладать приоритетом, поскольку при успешной проверке условия его наступления будет выполнено присвоение выходу нуля, и дальнейшие проверки выполняться не будут. Некоторые примеры описания триггеров показаны ниже. Триггер с синхронным сбросом. always @(posedge elk) if (reset) begin q <= 0; end else begin q <= d; end
Язык описания аппаратуры Verilog 191 Триггер с асинхронным сбросом и разрешением счета. always @(posedge elk or posedge reset) if (reset) begin q <= 0; end else if (ce) begin q <= d; end 4.10. Блокирующее и неблокирующее присваивание в процедурных блоках В приведенных выше примерах были использованы как оператор =, так и оператор <=. Они соответствуют так называемым блокирующему (=) и неблокирующему (<=) присваиваниям. Блокирующее присваивание инициирует выполнение следующего оператора внутри процедурного блока, а неблокирующее — только планирует его выполнение, но не производит мгновенных действий. Рассмотрим, как эти свойства отражаются на поведении конструкций на языке Verilog. Создадим тестовый пример, включающий в себя блокирующее присваивание значений входным сигналам: initial begin а = 0; Ъ = 0; с = 0; d = 0; #5 а = 1; // * #10 Ь = 1; // ** #15 с = 1; // *** #20 d = 1; // **** end; Блокирующий характер присваиваний проявился в том, что временные интервалы, указанные в строках, помеченных знаками «*», отсчитываются от предыдущей строки, в которой было использовано блокирующее присваивание. Заменим теперь блокирующие присваивания на неблокирующие: initial begin а = 0; b = 0; с = 0; d = 0; а <= #5 1;
192 Глава 4 b <= #10 1; с <= #15 1; d <= #20 1; end; Для этого примера каждое неблокирующее присваивание от- считывается от начала моделирования. Рассмотрим схему, представляющую собой последовательное со- FD FD единение двух триггеров (рис. 4.2). Опишем каждый триггер этой схемы в отдельном процедурном блоке. always @ (posedge elk) b = a; Рис. 4.2. Схема из последова- always @ (posedge elk) тельно соединенных триггеров с = Ь; С точки зрения синтеза схема описана правильно, однако применение блокирующего присваивания приводит к тому, что корректность моделирования будет зависеть от того, какой из процедурных блоков будет вычислен первым в процессе моделирования. Особенности реализации триггеров предполагают, что при одновременном приходе фронта тактового сигнала в первый триггер запишется сигнал а, а во второй — старое значение сигнала Ь. В то же время, если блокирующее присваивание b = а выполнится раньше, то модель покажет, что во второй триггер также запишется сигнал, подаваемый по цепи а. Одновременность процессов, происходящих в синхронных цифровых схемах, является очень важным принципом их работы, который требует отдельного внимания. Программистам известно, что для обмена значений, содержащихся в двух переменных, нельзя использовать конструкцию вида: // некорректно с точки зрения программиста а = Ь; b = а; поскольку первый оператор заменит значение в переменной а на значение переменной Ь, и старое значение а станет недоступным. Для корректного обмена значений двух переменных требуется ввести временную переменную: // корректно с точки зрения программиста, // однако неправильно с точки зрения схемы temp = a; а = Ь;
описания аппаратуры Verilog 193 b = temp; Такой прием хорошо известен программистам и может являться источником логических ошибок при проектировании цифровых схем. Рассмотрим схему, показанную на рис. 4.3. Принципиальный вопрос, на который требуется дать ответ, заключается в следующем: будут ли показанные на рис. 4.3 триггеры на каждом такте обмениваться записанными в них значениями или придут в какое-то фиксированное состояние, приняв одинаковое значение? Для ответа на него обратимся к временным диаграммам работы триггера (рис. 4.4). Как следует из порядка работы триггера, по фронту тактового сигнала его выход q принимает значение, равное значению на входе данных d. Однако, если обратиться к аппаратной реализации триггера, можно увидеть, что записывается то значение, которое присутствовало на входе d в течение некоторого времени до фронта тактового сигнала. Это время зависит от параметров конкретных полупроводниковых компонентов, и его минималь- FD г— — D Q >С :i:==iFD===: D Q >С CLKo-J Рис. 4.3. Синхронная схема, состоящая из двух триггеров Рис. 4.4. Временные диаграммы работы триггера но требуемое значение указывается в спецификации на цифровую микросхему. Оно называется временем установки сигнала (tsetup)- Существует также параметр, называемый временем удержания сигнала (?hoid)> который задает время, в течение которого входной сигнал должен удерживаться на входе после фронта тактового сигнала. Для практических целей можно принять, что этот интервал времени равен нулю, т. е. изменения уровня сигнала, присутствующие на входе триггера после прихода фронта тактового сигнала, уже не оказывают влияния на записанное значение. Кроме того, от момента прихода фронта тактового сигнала до появления записанного значения на выходе триггера проходит некоторое время, называемое задержкой распространения (?р(ь от propagation delay). Сравнив временные диаграммы работы триггера со схемой, показанной на рис. 4.3, нетрудно убедиться, что каждым тактом триггеры будут записывать старое значение своего соседа, т.е. обмениваться состояниями. Очевидно, для этого требуется, чтобы оба триггера использовали один и тот же тактовый сигнал.
194 Глава 4 Подобный принцип работы цифровых устройств существенно отличается от принципов работы алгоритмических языков программирования, которые выполняют операции последовательно, и старое значение переменной оказывается недоступным после записи в нее нового значения (конечно, если язык программирования не обеспечивает специальные меры для сохранения предыдущего значения). Поэтому в языке Verilog корректнее пользоваться неблокирующими присваиваниями, в которых автоматически запоминается предыдущее состояние переменной: always @ (posedge elk) b <= а; always @ (posedge elk) с <= b; В приведенном примере порядок выполнения процедурных блоков не оказывает влияния на возможность считывания предыдущих значений. При этом результаты моделирования окажутся корректными при любом порядке выполнения присваиваний. Можно запомнить несложные практические правила: • блокирующие присваивания используются для чисто комбинационной логики; • неблокирующие присваивания используются для синхронной (тактируемой) и смешанной логики. 4.11. Управляющие структуры Рассмотрим управляющие структуры, используемые в языке Verilog. Они используются как для моделирования, так и для синтеза, но часть из них требуют их упоминания только внутри процедурных блоков. 4.11.1. Условный оператор if/then Условный оператор имеет в Verilog одну из следующих форм: if (<условие>) <оператор> ; Вели требуемое действие не может быть выражено одним оператором, используются «операторные скобки» begin/end. if (<условие>) begin <оператор1> ; <оператор2> ; <оператор_а> ; end Вторая форма условного оператора подразумевает использование ключевого слова else («иначе»).
описания аппаратуры Verilog 195 if (<условие>) <оператор> ; else <оператор-иначе> ; Такая форма используется при необходимости проверки множественных условий. При этом образуются вложенные операторы if/else. if (<условие1>) <оператор1> ; else if (<условие2>) <оператор2> ; else if (<условиеЗ>) <операторЗ> ; else if (<условие4>) <оператор4> ; else <оператор5> ; // ни одно из условий не выполняется Рассмотрим пример реализации мультиплексора 4-в-1. Такой мультиплексор имеет мультиплексируемые входы а, Ь, с, d, вход селектора sel и выход данных q. Процедурный блок с использованием вложенных операторов if/else приведен ниже: always @ * if (sel == 2Ъ00) q = a; else if (sel == 2'bOl) q = b; else if (sel == 2'blO) q = c; else if (sel == 2Ъ11) q = d; else q = l'bx; В приведенном листинге интерес представляет оператор по умолчанию, который присваивает выходу значение х («неизвестно»). С точки зрения цифровой схемотехники использование этой строки излишне, поскольку на двухразрядном входе sel всегда будет присутствовать одна из комбинаций уровней, перечисленных в четырех вариантах условий. Однако с точки зрения САПР возможны также комбинации вида Oz, lz, zz и так далее, несмотря на то что в реальной схеме они появляться не будут. Тем не менее перечисленные варианты не будут считаться исчерпывающим перечислением состояний такой схемы, и она не сможет быть реализована с помощью только комбинационной логики (для чисто комбинационной схемы требуется, чтобы ее выходное состояние было однозначно определено в каждый момент времени и для любой комбинации входных сигналов). Для устранения этого недостатка САПР введет в такую схему защелку (latch) — схему удержания последнего состояния. Таким образом, в схему вводится элемент, который не предусматривается разработчиком, вносит дополнительную задержку и требует аппаратные ресурсы для своей реализации. Ш Для ПЛИС с архитектурой FPGA использование защелок не рекомендуется производителями, поскольку они строятся на базе триггера и мультиплексора. При выборе
196 Г л ав а 4 между триггером и защелкой следует выбирать триггер, а появление защелки в комбинационной схеме, вызванное неполным описанием условий, является стилистической ошибкой. Таким образом, лишняя на первый взгляд строка, явно задающая действия по умолчанию, позволяет избежать появления защелок, которые не требуются по смыслу работы схемы. Кроме того, при моделировании появление значения «неизвестно» позволяет быстро диагностировать проблемы при формировании тестовых воздействий, поскольку выполнение ветки else возможно только в том случае, если в модели не удалось обеспечить правильные логические уровни для сигнала sel. Для сравнения можно привести следующий текст на Verilog: always @ * if (sel == 2Ъ00) q = а; else if (sel == 2Ъ01) q = b; else if (sel == 2'blO) q = c; else q = d; В данном примере в последней строке выходу присваивается значение входа d, поскольку предполагается, что если ни одно из предыдущих условий не выполняется, то значение селектора равно И. С точки зрения синтеза это решение корректно, однако при моделировании оператор q = d будет выполняться и в случае, когда значение селектора не определено (т.е. равно «хх»). Таким образом, проблема в модели, заключающаяся в отсутствии корректного значения для сигнала-селектора, оказывается замаскированной, поскольку на выходе мультиплексора при моделировании все равно будет присутствовать какой-то сигнал, равный d. При этом будет неочевидно, появился этот уровень из-за действительного выбора входа d или это явилось результатом неверно описанной модели. В то же время значение «неизвестно» окажет соответствующее влияние на входы, к которым подключен выход мультиплексора, сделав «неизвестным» результат работы соответствующих блоков, что даст возможность идентифицировать проблему и проследить ее до того блока, в котором и произошло некорректное задание тестовых воздействий. Можно также добавить, что состояния «неизвестно», «не инициализировано» обычно выделяются цветом при графическом построении временных диаграмм сигналов средствами моделирования, что позволяет быстро идентифицировать ошибки.
Язык описания аппаратуры Verilog 197 4.11.2. Оператор case Оператор case соответствует оператору «выбор по переменной- селектору» в языках программирования и в Verilog имеет вид: always О (<входы>) begin case (<выражение>) <вариант 1> : <оператор1> ; <вариант 2> : <оператор2> ; <вариант 3> : <операторЗ> ; default : <оператор по умолчанию> ; endcase end Здесь «выражение» — это выражение или переменная — селектор, на основании значения которого выполняется один из вариантов действий, перечисленных ниже в строках вида <вариант п> : <оператор п> ; Аналогично оператору if, если после символа «двоеточие» требуется указать более одного оператора, они должны быть указаны в «операторных скобках» begin/end. Пример мультиплексора 4-в-1 с использованием оператора case показан ниже: always @ * begin case (sel) 2Ъ00 : q = 2Ъ01 : q = 2Ъ10 : q = 2'bll : q = default : q = endcase end a; b; c; d; = l'bx; Как и в примере с if, оператор default служит для предотвращения введения в схему защелки. Допустимы множественные варианты выбора в одной строке, например 2'ЬОО, 2Ъ11 : Сравнивая реализацию мультиплексора с помощью оператора if/else и case, можно сделать вывод об их логической эквивалентности. Действительно, описанные аналогичным образом, такие схемы будут давать одинаковые результаты при работе. Более того, простых примеров схемная реализация, скорее всего, окажется
198 Глава 4 идентичной (это зависит от особенностей конкретных САПР). Однако для микросхем программируемой логики рекомендуется при наличии возможности использовать именно оператор case, поскольку вложенные операторы if/else формируют «лестничную» комбинацц. онную структуру, при которой следующее условие может быть проверено только после того, как подтверждено невыполнение предыдущего. Такая структура обуславливает дополнительную задержку при распространении сигналов, проверяемых в самом первом условном выражении. В то же время для оператора case существуют шаблоны проектирования, известные САПР ПЛИС, которые позволяют, в частности, реализовать мультиплексоры с применением дополнительных ресурсов программируемых ячеек. Такая схема может оказаться быстрее и компактнее, чем схема, синтезированная из формально аналогичного оператора if/else. Разумеется, оператор if/else не может быть заменен при проверке сложных условий, которые не могут быть сведены к проверке единственной переменной-селектора. Таким образом, идеальный оператор case должен перечислять полный список возможных значений переменной селектора. Возможными негативными последствиями могут быть добавление защелки и реализация приоритетного дешифратора (если одно и то же условие задано в разных вариантах выбора, требуется проверка приоритета). Для устранения этих эффектов могут быть использованы директивы fulLcase и paralleLcase, вводимые уровне RTL, которые устраняют защелки (fulLcase) и схемы проверки приоритета (paralleLcase). Необходимо отметить, что нужный эффект от применения этих директив наблюдается только в том случае, если реализуемая схема в действительности обеспечивает полную и неперекрывающуюся дешифрацию всех возможных условий. 4.11.3. Оператор for Оператор for в синтезируемых конструкциях используется в основном для создания множественных экземпляров схем. Необходимо сразу же подчеркнуть, что данный оператор не предназначен для создания счетчиков или других схем, которые после их синтеза работали бы заданное число тактов. Подобные задачи решаются в языках описания аппаратуры в совершенно ином стиле, и здесь не следует искать прямых соответствий с языками программирования. Рассмотрим пример: module for>ex( input [3:0] а,
описания аппаратуры Verilog 199 input b, output reg [3:0] с ); integer i; always @ (a, b) begin for (i = 0; i < 4; i = i + 1) c[i] = b & a[i]; end endmodule Результат синтеза такой схемы показан на рис. 4.5. Из рис. 4.6 видно, что оператор цикла оказал характерное воздействие прежде все- AND2 Рис. 4.5. Схема, синтезированная для примера с циклом for го на САПР, заставив циклически синтезировать четыре одинаковых фрагмента цифровой схемы, различающихся индексами обрабатываемых сигналов. Такой вид использования, генерация множества экземпляров компонента, различающихся индексами сигналов, является наиболее естественной формой применения оператора for. 4.12. Задачи и функции С целью упрощения разработки крупных проектов многие языки программирования предполагают различные варианты субпрограмм. Их применение позволяет повысить скорость и качество разработки за счет повторного использования кода и вынесения части функциональности в отдельные завершенные модули, что облегчает их отладку и модификации. Verilog предлагает две разновидности субпрограмм — задачи (task) и функции (function). Обе разновидности могут быть использованы как для моделирования, так и для синтеза. Задачи отличаются от функций тем, что могут иметь произвольное число входов, выходов и двунаправленных сигналов. Функция имеет входы, являющиеся ее аргументами, и возвращает единственный результат. Задача имеет следующий формат: task <имя задачи> [формальные параметры] [локальные переменные] begin <операторы> end; endtask
200 Глава 4 Задача идентифицируется именем, которое задается после ключевого слова task. Впоследствии вызвать задачу можно, просто указав ее имя. После объявления имени задачи можно указать формальные параметры, которые имеют тот же формат описания, что и порты модуля: in — входные параметры, передаются в задачу; out — выходы задачи, значения в них могут быть только записаны и возвращаются в вызывающий модуль; inout — двунаправленные сигналы, передаются в задачу вызывающим модулем, могут быть прочитаны задачей и записаны, возвращаются в вызывающий модуль. Если задача имеет формальные параметры, то при ее вызове следует передать ей фактические параметры в том же порядке, в каком формальные были объявлены в описании задачи: task sum.task; input [7:0] а; input [7:0] b; output [7:0] sum; begin sum = a + b; end; endtask Вызов: sum_task(opl, op2, result); При этом фактический параметр opl будет передан в задачу как вход а, ор2 — как вход Ь, а величина sum будет возвращена в вызывающий модуль в переменную result. В стандарте Verilog-2001 возможно объявление формальных параметров в стиле языка Си: task sum_task(input [7:0] a, input [7:0] b, output [7:0] sum) Функции в Verilog, аналогично другим языкам, принимают произвольное число параметров, которые могут быть только входами. Функция возвращает единственный результат, имя которого совпадает с именем функции. Функция объявляется следующим образом: function <имя функции> ; [входные параметры] [локальные объявления] begin <операторы> end;
описания аппаратуры Verilog 201 endfunction Входные параметры функции объявляются также, как и для задачи. Возможен Си-подобный вариант объявления: function func_examplel (input a, input b); 4.13. Организация проекта и параметризованные модули При создании сложных проектов можно использовать ряд организационных и технических приемов, которые облегчают процесс разработки. Директива Include предназначена для подключения текстов на Verilog, размещенных в сторонних файлах. Она оформляется следующим образом: Include <"имя файла "> Использование этой директивы равносильно вставке текста из упоминаемого файла непосредственно в месте упоминания директивы. Имя файла при этом задается в двойных кавычках, файл должен быть доступен из рабочего каталога в соответствии с общими правилами для данной ОС (т. е. файл, в котором упоминается директива, должен находиться в том же каталоге, или путь к подключаемому файлу должен быть указан явно). Использование 'include схоже с применением аналогичной директивы в языке Си, а подключаемые таким образом файлы Verilog можно сопоставить с заголовочными файлами Си (header files), в которых обычно размещаются константы, задачи и функции общего пользования. На имя подключаемого таким образом файла не накладывается специальных ограничений. Предполагается, что в подключаемых файлах находятся объекты, облегчающие разработку. Такими объектами могут быть общие константы, используемые в различных модулях проекта (например, разрядность обрабатываемых данных или тактовая частота), функции общего назначения (например, алгоритмы кодирования и декодирования, функции и задачи, описывающие стандартные интерфейсы и узлы). При разработке подключаемых файлов рекомендуется тщательно планировать интерфейс размещаемых в них субпрограмм, поскольку частая смена интерфейсов заставит постоянно вносить соответствующие изменения в модули, которые использует эти субпрограммы. Также следует подробно документировать подключаемые файлы, сопровождать их примерами использования и тестами.
202 Глава 4 Параметры являются эффективным средством разработка масштабируемых модулей, т. е. модулей, для которых возможна быстрая смена разрядности, числа каналов, пределов счета и тому подобных численных характеристик, при сохранении алгоритмов работы. Параметр определяется с помощью директивы "define: "define <имя_параметра> <значение> Например: "define DATA_WIDTH 8 Впоследствии при упоминании в тексте DATA.WIDTH вместо него будет подставлено значение 8. Параметризованные модули являются достаточно привлекательными для разработки по многим причинам. Рассмотрим, например, реализацию регистров различной разрядности: 8-разрядный регистр: module reg8(input elk, input [7:0] d, output reg [7:0] q); always @ (posedge elk) q <= d; endmodule 16-разрядный регистр: module regl6(input elk, input [15:0] d, output reg [15:0] q); always @ (posedge elk) q <= d; endmodule Из описания модулей можно видеть, что кроме имени, они различаются только разрядностью сигналов d и q. Нетрудно понять, что регистр любой разрядности будет описываться процедурным блоком, в котором будет находиться оператор q <= d;. Таким образом, для перехода к другой разрядности необходимо отредактировать только разрядность портов d и q. Используем для управления разрядностью директиву 4defme: 4define DATA.WIDTH 8 module reg8(input elk, input ['DATA.WIDTH - 1:0] d, output reg ['DATA.WIDTH - 1:0] q); always @ (posedge elk) q <= d; endmodule
описания аппаратуры Verilog 203 При объявлении портов теперь используется не прямое указание числа, а ссылка на определенный через 4define параметр, названный DATA.WIDTH (буквально «ширина данных», или разрядность данных). Поскольку параметр в примере задан равным 8, выражение ['DATAJWIDTH - 1:0] эквивалентно [7:0], что и требуется для 8-разрядного порта. Можно заметить, что редактирование единственной строки, где определен параметр, автоматически изменяет разрядности обоих сигналов — d и q, тогда как при ручном редактировании за приведением разрядности этих сигналов в соответствие друг другу необходимо следить отдельно. Представление требуемых величин в виде параметров особенно эффективно, если они используются в различных модулях — например, при разработке системы цифровой обработки сигналов, в которой каждый модуль производит очередное преобразование сигнала. При необходимости изменить разрядность обрабатываемых данных пришлось бы производить коррекции во всех модулях. Verilog поддерживает также локальные параметры. Они имеют ограниченную область видимости (только в том блоке, в котором объявлены) и предназначены для того, чтобы не перекрывать имена ранее заданных параметров. Например, идентификатор width («ширина») является достаточно популярным при определении разрядности обрабатываемых данных. При его частом использовании в различных модулях может оказаться, что при их совместной трансляции в большом проекте значение параметра width окажется переопределенным одним из загруженных файлов. Для ограничения области видимости и используются локальные параметры, определяемые с помощью ключевого слова localparam. Пример: localparam x = 1; Широкое использование параметров не является самоцелью, однако следует обратить внимание на те возможности по организации разработки, которые предоставляет параметризация. При создании модулей, которые используются во многих проектах или для которых часто применяется частичная коррекция (например, изменение разрядности, пределов счета, начальных значений, порогов срабатывания и т. п.), настоятельно рекомендуется оформить часто изменяемые значения как параметры, вынеся их в отдельный текстовый блок (в пределах модуля или, при необходимости, во внешний загружаемый файл). В этом случае уменьшатся шансы случайно испортить исходные тексты модуля при внесении коррекции в величины, Упоминающиеся по всему исходному тексту, поскольку исправления будет ограничить компактным текстовым фрагментом.
204 Глава 4 4.14. Условная генерация Создание параметризованных модулей может также потребовать включения или выключения процесса синтеза для определенных фрагментов, или настройки числа создаваемых модулей. Это можно выполнить с помощью блока условной генерации, который оформляется с помощью ключевых слов generate и endgenerate. Для создания множественных экземпляров какого-либо компонента в блоке generate необходимо также объявить специальную «генерирующую переменную» с помощью ключевого слова genvar. Переменная, созданная внутри блока generate, доступна только в этом блоке, тогда как переменная, объявленная вне его, доступна и другим подобным генерирующим циклам, размещенным в этом модуле. Пример создания блока из 8 триггеров с помощью generate приведен ниже: generate genvar I; for (I = 0; I < 8; I = I +1) begin: U // метка обязательна // и задает именование // создаваемых блоков DFF DFFJNST (elk, end endgenerate Созданные триггеры имеют общий сигнал elk, а сигналы d и q подключаются к цепям d[0]..d[7] и q[0]..q[7] соответственно. С помощью generate можно создавать компоненты, внутренние сигналы, задачи и функции, параметры, блоки непрерывного присваивания, процедурные блоки initial и always. Однако таким образом невозможно создавать порты или изменять параметры существующих портов. Конструкцию generate можно совмещать с условным оператором if для создания разных вариантов модуля, integer platformJndex; generate if (platformJndex ==0) begin: U module_rtl ... end else begin: V modulejstructural ...
описания аппаратуры Verilog 205 end endgenerate В показанном примере в модуле объявляется переменная platform-index, которая принимает значение, соответствующее номеру аппаратной платформы. Здесь предполагается, что для платформы, обозначенной индексом 0, не имеется готовых реализаций, описанных в виде низкоуровневого структурного представления, и для нее необходимо использовать высокоуровневое описание на Verilog. В зависимости от того, какое значение задано для platform index, будет использовано то или иное описание для компонента. Можно использовать также оператор case: generate case (plat formJndex) 0 : begin: U 1 • begin: V 2 : begin: W default: endcase endgenerate При разработке систем на базе ПЛИС с помощью условной генерации удобно описывать ресурсы, которые имеют разные детали реализации в разных семействах ПЛИС. Например, Spartan-б и серия 7 имеют разные аппаратные примитивы для модулей формирования тактового сигнала. Такие модули настоятельно рекомендуются к использованию во всех проектах, но при смене семейства ПЛИС потребуется отредактировать проект, поскольку такие модули не имеют поведенческого описания, а добавляются с помощью component instantiation (в виде ссылки на библиотеку аппаратных примитивов). Можно также указать на вычислительные устройства, выполняющие операции «умножение с накоплением». В ранних вариантах Spartan-З имеются только умножители формата 18x18 и аккумулятор требует реализации на базе логических ячеек. Семейство Spartan-б имеет также аппаратный 48-битовый аккумулятор, а ПЛИС серии 7 — умножители формата 25x18 и 48-битовый аккумулятор. Таким образом, если разработчик планирует использовать instantiation, он может создать модуль, использующий условную генерацию той или иной разновидности аппаратного примитива в зависимости от используемого семейства ПЛИС. Можно заметить, что параметр «семейство ПЛИС» оказывает глобальное влияние на весь проект, поэтому является подходящим примером для добавления в подключаемый файл, общий для всех
206 Глава 4 модулей проекта. Детали реализации такого параметра (целочис- ленный индекс, текстовая строка) являются предметом отдельного обсуждения, 4.15. Моделирование на Verilog Моделирование цифровых систем является важным шагом в маршруте их разработки. Возрастание сложности проектируемых устройств заставляет разработчиков тратить все больше времени на их моделирование. Целями моделирования могут быть как исследование алгоритмов работы проектируемого устройства, так и верификация характеристик, получаемых при его аппаратной реализации. В первом случае производится моделирование на верхних уровнях абстрагирования (т. е. преимущественно на поведенческом и, возможно, RTL), а моделирование на физическом уровне призвано проверить возможность работы созданного устройства в заданных условиях эксплуатации (т. е. проверяется возможность работы на заданной тактовой частоте, с требуемыми длительностями сигналов, в заданном температурном диапазоне и т.д.). При моделировании используется подход, основанный на «испытательном стенде» (testbench). Моделируемое устройство (в англоязычной литературе UUT, Unit Under Test) представляется своим синтезируемым кодом, а для проверки его поведения в различных условиях создаются описания тестовых воздействий («моделируемый код»). Задание тестовых входных воздействий может быть выполнено на Verilog с помощью модуля типа Verilog Test Fixture. Для этого в диалоговом окне добавления компонента к проекту (Add Sources) выбирается пункт Add or Create Simulation Source. Необходимо выбрать тип файла Verilog и задать его имя, как показано на рис. 4.6. Для унификации обозначений обычно применяется сочетание символов tb (от testbench, «испытательный стенд»). Так, если модуль имеет название my_and, то с ним удобно сопоставить тестовый файл my-andJb. Пример шаблона файла с описанием тестовых воздействий показан ниже. 4timescale Ins / lps module my.AndJbb; // Inputs reg a; reg b; // Outputs wire c;
описания аппаратуры Verilog 207 Рис. 4.6. Создание модуля, описывающего тестовые воздействия // Instantiate the Unit Under Test (UUT) my_and uut ( •a(a), ¦b(b), .c(c) ); initial begin // Initialize Inputs a = 0; b = 0; // Wait 100 ns for global reset #100; // Add stimulus here end endmodule Это описание необходимо модифицировать для получения требуемого эффекта от моделирования. Предположим, что требуется проверить поведение модуля при последовательной установке в логическую единицу сначала входа а, а затем входа Ь. Тогда раздел «инициализация входов» (Initialize Inputs) будет выглядеть так:
208 Глава 4 top top nth fb Рис. 4.7. Запуск моделирования в САПР Vivado initial begin // Initialize Inputs a = 0; # 10; a = 1; b = 0; # 20; b = 1; // Wait 100 ns for global reset to finish #100; // Add stimulus here end Запуск моделирования в Vivado производится в панели управления, как показано на рис. 4.7. Запуск поведенческого моделирования (Behavioral Simulation) приведет к построению временных диаграмм работы модуля. На рис. 4.8 показано, что для заданных входных воздействий симулятор автоматически определил правильное состояние выхода с. В САПР ПЛИС возможно проведение моделирования на физическом уровне, когда задержки распространения сигналов не принимаются равными тем, которые указаны в поведенческом описании, а рассчитываются исходя из физических моделей компонентов ПЛИС и трассировки конкретного проекта. Для моделирования в таком режиме необходимо выбрать пункт Run Post-Implementation Timing Simulation. Результаты моделирования показаны на рис. 4.9.
описания аппаратуры Verilog 209 Рис. 4.8. Временные диаграммы при моделировании в поведенческом режиме Рис. 4.9. Результаты моделирования модуля my_and в режиме Post-Route С учетом задержки распространения сигнала логическая единица на выходе с появляется не в момент времени 30 не, а в момент 33,706 не. Ш Дополнительная величина 3,706 не не является задержкой распространения через единственный логический вентиль, что было бы чрезмерно завышенным результатом для 28-нм элементной базы. Данная задеренска определена с учетом влиянья входных буферов для сигналов аиЪ и выходного буфера выхода с, подключенных к выводам ПЛИС Для получения результатов Post-Route моделирования необходимо, как следует из названия, выполнить трассировку (Routing) проекта. Таким образом, результат оказывается привязан к конкретной элементной базе. Кроме того, его получение связано с необходимостью анализа физических моделей компонентов, что требует существенно большего времени по сравнению с выполнением поведенческого моделирования. Однако такой результат существенно точнее, поскольку времена распространения сигналов рассчитыва-
210 Гла в а 4 ются по реальной трассировке, а не вводятся в модель из субъективных соображений. При проектировании цифровых систем моделирование на физическом уровне обычно используется на завершающих этапах верификации проекта, когда требуется подтвердить не просто правильность выполнения преобразований, а соблюдение временных характеристик установления и распространения сигналов. В процессе отладки удобнее использовать моделирование на поведенческом уровне, поскольку оно производится существенно быстрее. В этом случае даже ориентировочные величины задержек позволяют иллюстрировать временной сдвиг сигналов друг относительно друга, что позволяет отлаживать архитектуру устройства. Более сложные моделирующие конструкции можно создавать с помощью процедурных блоков initial и always. Процедурный блок initial выполняется однократно в процессе моделирования, в момент времени 0, а блок always — каждый раз, когда изменяется любой из сигналов, перечисленных в списке чувствительности. Пример 1: initial begin elk = lb'O; forever #10 elk = ~ elk; end В этом примере с помощью ключевого слова forever организуется бесконечный цикл — через каждые 10 не значение сигнала elk меняется на противоположное (подразумевается, что единицы времени для моделирования установлены равными 1 не, как это обычно бывает). Пример 2: initial begin q = lb'O; end always © (a,b) begin q = a & b; end В примере выходному сигналу q присваивается значение, равное нулю. Далее следует процедурный блок always, который описывает логический вентиль И.
Я описания аппаратуры Verilog 211 Основным преимуществом моделируемого подмножества Verilog является возможность создания моделей, описывающих задержки распространения сигналов. Это позволяет применять такие задержки к элементам, основываясь только на информации, указанной разработчиком модели, что существенно быстрее, чем получение этой информации путем анализа физической модели этого компонента. Таким образом, разработчик модели обязан обеспечить правильные величины задержек, но это компенсируется увеличением скорости моделирования. Задержка указывается с помощью символа #. Например, для непрерывного присваивания assign #3 q = а & b; #3 показывает, что задержка распространения сигнала составляет 3 не (точнее, 3 «единицы времени», величина которых определяется директивой Ntimescale, и обычно равна 1 не). Для логических вентилей могут указываться три величины задержек, соответствующие следующим величинам: • время перехода в высокий уровень (rise time); • время перехода в низкий уровень (fall time); • время отключения (turn off time). Эти времена указываются после символа # в скобках, в порядке, приведенном в списке: assign #B,3,4) q = а & b; Необходимо еще раз подчеркнуть, что приводимые таким образом задержки используются только при моделировании. Они игнорируются средствами синтеза, которые вместо этого могут рассчитать реальные задержки распространения, учитывающие используемые компоненты, соединяющие их проводники, условия работы и т.д. Следующие конструкции не являются синтезируемыми и предназначены только для повышения удобства описания моделей. Конструкция wait предназначена для синхронизации работы процедурных блоков. Например, в одном процедурном блоке может моделироваться установка сигнала, который используется в другом блоке: ^ait (changed_signal) а = b; Указанный блок (в примере состоящий из оператора а = Ь) будет выполняться каждый раз, когда изменится значение сигнала changed_signal.
212 Глава 4 Конструкция while представляет собой цикл с проверкой условия. Она имеет следующий синтаксис: while( <условие>) <оператор> ; При необходимости исполнять в цикле несколько операторов, как обычно в подобных случаях, используются «операторные скобки» begin/end. Команда forever представляет собой бесконечный цикл: initial begin elk = 1'bO ; forever #10 elk = ~ elk ; end Команда repeat повторяет цикл заданное число раз. initial begin counter = 0 ; repeat B56) begin Sdisplay ("Counter = %d", counter); #10 counter = counter + 1; end end 4.16. Создание отчетов и сообщений Для формирования отчетов, требуемых разработчику, используется ряд моделирующих конструкций. Команда Sdisplay имеет вид в соответствии с примером: Sdisplay («Во время %d сигнал а равен %b», $time, a) При этом в отчет выводится указанное в кавычках текстовое сообщение в соответствии с заданными форматными модификаторами. В примере это %d и %Ь, которые задают соответственно вывод числа в десятичном и в двоичном виде. Приведенное далее выражение $time соответствует времени модели, а переменная а указана в качестве примера. Кроме $time, можно использовать команду Srealtime. В процессе исполнения в отчете (консоли вывода средств моделирования) будет сформирована строка вида «Во время 5 сигнал а равен 1». Команда Swrite аналогична Sdisplay, однако не выполняет перевод строки после завершения.
описания аппаратуры Verilog 213 Таблица 4.4 Форматные модификаторы Название %h, %H %Ь, %В %d, %D %s, %S %c, %C %t, %T %o, %O %v, %V %e, %E %f, %F %m, %M Действие Шестнадцатеричный формат Двоичный формат Десятичный формат Текстовая строка Символ ASCII Время Восьмеричный формат Сила сигнала (power/strong/weak и т. п.) Вещественное число в инженерном формате Вещественное число в обычном формате Иерархическое имя Команда $strobe также аналогична Sdisplay, но выводит сообщения по завершению текущего цикла моделирования. Наконец, $monitor является еще одним аналогом Sdisplay, но с этой командой связаны также Smonitoroff и Smonitoron, которые соответственно выключают и включают вывод отчетов с помощью $monitor. Таким образом, с помощью этой команды можно задавать более подробные сообщения о состоянии модели, которые могут включаться по мере необходимости и выключаться, когда их постоянный вывод перегружает отчет о моделировании. Возможен вывод сообщений в текстовый файл, задаваемый пользователем. Для этого предназначены команды Sfdisplay, Sfmoni- tor, Sfstrobe, Sfwrite. Форматные модификаторы для приведенных выше команд показаны в табл. 4.4. Форматный модификатор %t отличается от %d тем, что выводит время в единицах, основанных на директиве 4timescale. Формат вывода может также быть задан командой вида Stimeformat (-9, 3, "ns", 8). Здесь -9 означает десятичный порядок единицы измерения времени (в данном 10~9 означает наносекунду), 3 определяет число знаков, выводимых после десятичной точки, далее следует строка, которую необходимо вывести после значения времени, наконец, 8 задает минимальное число символов для вывода. Команда Sstop приостанавливает моделирование и возвращает Управление оператору. В это время можно, например, изменить значения входных сигналов и возобновить процесс моделирования. Команда Sfinish завершает моделирование, закрывая все открытые файлы. При создании моделей на Verilog можно использовать файловые операции — заполнение массивов из текстовых файлов, открытие, с°здание, чтение и запись.
214 Глава 4 Команды $readmemh и $readmemb заполняют массив памяти из текстового файла, данные в котором представлены в шестнадцате- ричном ($readmemh) или двоичном (Sreadmemb) форматах. Например, если объявлен массив reg [7:0] array 1 [0:1023], и имеется файл arrayljdata.txt, в котором размещены строки вида 0000 1234 РА45 то можно заполнить массив значениями из файла с помощью вызова: $readmemh("arrayljdata.txt", arrayl); Каждая строка соответствует одной ячейке массива памяти. При использовании команды $readmemb в файле должны быть размещены двоичные значения. Команда $fopen возвращает целочисленный индекс открытого файла. Этот индекс можно будет впоследствии указать в качестве аргумента одной из команд $fdisplay, Sfmonitor, Sfwrite, $fstrobe. Например: integer hLog; initial begin hLog = $fopen("filel.log", Mw"); $fdisplay (hLog, "Текстовое сообщение, выводимое в файл"); $fclose(hLog); Команда Sfclose закрывает ранее открытый файл. Стандарты Verilog-95 и Verilog-2001 имеют различающиеся форматы вызова $fopen и связанные с ними ограничения. Для Verilog- 95 вызов $fopen требует только одного параметра — имени файла. В Verilog-2001 вторым параметром является режим доступа к файлу, которые перечислены в табл. 4.5. Другим различием является максимальное число одновременно открытых файлов. Для Verilog-95 это число равно 32, в Verilog-2001 число составляет 230. Старшие биты идентификатора файла зарезервированы для представления предопределенных идентификаторов файлов: stdin, stdout и stderr. Кроме того, Verilog-2001 предлагает дополнительные функций для работы с файлами по сравнению с $readmemh и $readmemb, которые доступны в Verilog-95. Это следующие функции: $fgetc(file) — читает из файла один символ; $fimgetc(char, file) — «возвращает в файл» символ, прочитанный ранее, делая его доступным для следующего вызова $fgetc;
03ык описания аппаратуры Verilog 215 Модификаторы режима доступа к файлу Таблица 4.5 режим доступа Описание 7"rb" "w+b "a+b 7"wb+" a+" "/"ab+" Открывает текстовый или двоичный файл для чтения Создает текстовый или двоичный файл для записи Открывает текстовый или двоичный файл для добавления Открывает существующий двоичный файл для чтения и записи Создает новый текстовый файл для чтения и записи Создает новый файл для чтения и записи Открывает существующий текстовый файл для добавления Открывает существующий двоичный файл для добавления Форматные модификаторы для функции fscanf Таблица 4.6 Модификатор %Ъ %d %о %h, %х %е, %f, %g %t %с %s %% %u %z Описание Двоичное значение (допускаются состояния z, x, ?) Десятичное значение Восьмеричное значение Шестнадцатиричное значение Значение в формате с плавающей точкой Формат представления времени Символ Строка Символ «%», преобразований не производится Битовое значение 0 или 1 4-значное логическое значение: 0, 1, z, x $fscanf(file, переменные) — читает из файла переменные с возможным использованием форматных модификаторов; $fgets(line, file) — читает строку из файла; $fread — читает из файла объекты в соответствии с заданным форматом. Для функции $fscanf используется порядок вызова, аналогичный такой же функции в языке Си. Например: $fscanf(hFile, "%b %d" bin_var, decimaLvar); прочитает из файла с индексом hFile две переменные, bin.var и decimaLvar, причем значение для первой из них будет преобразовано из двоичного формата, а для второй — из десятичного. Данные в файле могут разделяться пробелами или запятыми. Форматные модификаторы для функции $fscanf приведены в табл. 4.6. При чтении из файлов можно пользоваться символом EOF для проверки достижения конца файла: while (CHAR != 'EOF) begin В целом файловые операции являются полезным инструментом при создании тестов сложных устройств. Методология тестирования таких устройств будет рассмотрена ниже.
О Дополнительные инструменты проектирования на базе ПЛИС При проектировании отдельных компонентов системы даже для относительно простых ПЛИС может оказаться полезным комбинирование инструментов разработки. Речь идет не только о совмещении языков описания аппаратуры и, возможно, графического ввода, но и о сочетании HDL, IP-ядер, процессорных компонентов и модулей, разработанных на языках высокого уровня (HLS). 5.1. IP Integrator Понятие IP-ядро (IP-core, Intellectual Property Core) означает больше организационное, чем техническое понятие. С точки зрения Xilinx, некоторые модули или целые проекты могут распространяться бесплатно, в качестве демонстрационных примеров — Reference Design, или «примеры проектов». Эти проекты обычно доступны для загрузки с сайта Xilinx или других компаний-разработчиков, однако техническая поддержка по этим проектам не предоставляется. В отличие от этого, для компонентов, представляемых как IP-ядра, предоставляется поддержка, сопровождение, исправление ошибок, тесты, примеры использования и подробная техническая документация. С технической же точки зрения IP-ядро выглядит как компонент, который может быть использован разработчиков в составе своего проекта. Многие IP-ядра дополняются проектными ограничениями, обеспечивающими достижение высокой тактовой частоты или плотной упаковки в проекте. Поэтому часто проект, состоящий из объединенных IP-ядер, может претендовать на хорошие технические характеристики при небольших усилиях разработчика. Для упрощения использования IP-ядер в САПР Vivado они организованы в специальную библиотеку — IP Integrator. В проекте все файлы каждого ядра объединены в специальный файл с расширением .xci (Xilinx Core Instance). С инструментом IP Integrator связано понятие блочного проекта (block design), который может выступать в качестве элемента иерархии, наряду с модулями на языках VHDL и Verilog. Блочный проект напоминает схемотехнический ввод схемы, который устарел
Дополнительные инструменты проектирования на базе ПЛИС 217 PROJECT MANAGER SYNTH' So иг с? з Vivado. Вместо оперирования отдельными компонентами, такими как триггеры и вентили, блочный проект оперирует IP-ядрами, позволяя соединять их, управлять настраиваемыми параметрами и генерировать RTL-представление для созданного графического представления проекта. Порядок работы с IP Integrator удобнее рассмотреть на примере. Создав новый проект на базе платы Zedboard, можно выбрать для этой платы новый блочный проект, как показано на рис. 5.1. На рисунке можно видеть, что на панели Flow Navigator появилась новая группа, имеющая название IP Integrator. При выборе в этой группе пункт Create Block Design начинается работа «мастера» создания новой подсистемы на основе IP-ядра. Добавить IP-ядро к блочному проекту можно с помощью элемента управления, оформленного в виде гиперссылки, как показано на рис. 5.2. Нажатие на элемент Add IP открывает список доступных ДЛЯ ВЫбраННОЙ Hierv. ПЛИС IP-ядер. Номенклатура IP-ядер Весьма широка И составляет Рис. 5.1. Группа IP Integrator и созда- Несколько СОТен компонентов, ние блочного проекта в САПР Vivado разбитых на группы. Компания Xilinx придерживается политики предоставления разработчикам широкой номенклатуры IP-ядер, поскольку это позволяет быстрее завершать качественные проекты и Увеличивает продажи микросхем. В то же время некоторые IP-ядра могут предусматривать приобретение лицензии. Аппаратные компоненты ПЛИС Xilinx поддержаны бесплатными IP-ядрами. Это означает, что дополнительные лицензионные отчисления, например, для использования приемопередатчиков или процессоров ARM, не требуются.
218 Глава 5 Рис. 5.2. Добавление IP-ядра к блочному проекту 5.2. Работа с процессорной системой ARM Изучение процессорной подсистемы ARM, входящей в состав ПЛИС Zynq-7000, удобно произвести именно с использованием блочного проекта и IP-ядра. Это практически единственный приемлемый путь использования ARM, так как он представляет собой аппаратное решение и его невозможно описать на HDL. После выбора компонента Zynq7 Processing System и завершения работы генератора будет сформировано графическое представление процессорной подсистемы на основе ARM, входящей в состав ПЛИС Zynq. На рис. 5.3 показан интерфейс САПР Vivado после установки такой подсистемы. Для установленного ядра доступна автоматическая настройка его параметров, что видно по сообщению «Designer Assistance available» и гиперссылке, включающей такую автонастройку. В результате работы блока автонастройки к процессорной подсистеме ARM будет подключена внешняя память DDR3 и перифе-
дополнительные инструменты проектирования на базе ПЛИС 219 Рис. 5.3. Представление процессорной подсистемы на базе ARM в виде блочного проекта в САПР Vivado рийные устройства, контроллеры которых имеются на плате Zed- board. Несомненным удобством является наличие функции Validate Design (назначенной также на клавишу F6), однако запуск проверки для автоматически настроенной процессорной подсистемы показывает ошибку: тактовый сигнал при автонастройке на систему не подается. На рис. 5.4 проиллюстрирована эта ситуация вместе со способом ее исправления. Щелчок правой кнопкой мыши по выводу M_AXLGPO_ACLK открывает контекстное меню, в котором, в том числе, есть пункт Make External Рис. 5.4. Добавление внешнего тактового сигнала в проект
220 Глава 5 Вместо внешнего тактового сигнала для процессорной подсистемы можно использовать и внутренний тактовый сигнал, генерируемый самим блоком. Для этого необходимо соединить вход М_АХ1_ GP0JVCLK с выходом FCLK.CLK0. Далее для созданного проекта необходимо запустить процесс Generate Block Design (он также находится в группе IP Integrator). При этом создаются необходимые файлы для синтеза и моделирования созданной подсистемы. Разработчики, знакомые с САПР EDK, могли заметить, что пункт Make External встречается именно в этой САПР. Однако это далеко не единственная функциональность, перенесенная из EDK (а точнее, из программы Xilinx Platforn Studio, с помощью которой выполняется конфигурирование процессорных подсистем). Двойной щелчок на графическом изображении Zynq открьюает диалоговое окно конфигурирования непосредственно в САПР Vivado (рис. 5.5). На этом рисунке показана также часть интерфейса Vivado, чтобы подчеркнуть, что настройка процессорной подсистемы, для которой ранее требовался запуск Xilinx Platform Studio, теперь может быть выполнена непосредственно в интерфейсе Vivado. Подробное изучение деталей настройки представляется нецелесообразным в рамках данной главы. Однако хотелось бы обратить внимание на удобную функцию, упрощающую распределение внешних выводов подсистемы ARM. Дело в том, что при интеграции процессорного ядра ARM в ПЛИС семейства Zynq были приняты определенные компромиссные решения, касающиеся организации внешних выводов. Аппаратные контроллеры периферии, входящие в состав подсистемы ARM, в принципе позволяют подключить множество внешних устройств, задействовав при этом большое число выводов микросхемы. Однако это потребовало бы использования для ПЛИС корпусов с большим числом выводов, заметная часть которых относилась бы к встроенной аппаратной периферии ARM, пусть даже и редко используемой. Поэтому при создании ПЛИС Zynq было использовано мультиплексирование сигналов аппаратных контроллеров — Multiplexed IO (МЮ). В ПЛИС Zynq имеются 54 внешних вывода, принадлежащих подсистеме ARM. Эти выводы недоступны FPGA- части кристалла и могут быть использованы только встроенной периферией ARM. Такого числа сигналов недостаточно для подключения всех устройств, поэтому разработчику необходимо определить, какие именно контроллеры будут использоваться в проекте. Ситуация несколько осложняется тем, что внешние выводы не могут быть назначены произвольно. Каждый контроллер имеет несколько ва-
дополнительные инструменты проектирования на базе ПЛИС 221
I to to tD Рис. 5.6. Графическое представление распределения внешних выводов периферийных устройств процессорной подсистемы ARM От
дополнительные инструменты проектирования на базе ПЛИС 223 Рис. 5.7. Создание «обертки» для блочного проекта риантов размещения, что может привести к конфликтам, когда даже при формальном наличии свободных выводов используемые периферийные контроллеры не могут быть задействованы одновременно. Это касается, в частности, аппаратных контроллеров Ethernet MAC и USB. В ПЛИС Zynq имеются по 2 таких контроллера, однако одновременно на МЮ могут быть выведены только два из четырех устройств (т.е. 2 USB, или 2 ЕМАС, или 1 USB + 1 ЕМАС). Такую особенность организации периферийных контроллеров необходимо заранее учитывать при планировании проекта на базе ПЛИС Zynq, и распределение выводов может быть неочевидным. Однако на рис. 5.6 ситуация представлена вполне наглядно — нетрудно убедиться, что все активированные периферийные устройства не перекрываются между собой. Блочный проект не может выступать в качестве модуля верхнего уровня. Поэтому для него необходимо создать «обертку» (wrapper), что также автоматизировано в Vivado. Создание обертки выполняется из вкладки Sources (рис. 5.7). После выполнения описанных действий можно приступать к запуску процессорной системы ARM на плате Zedboard. В контекстном меню на рис. 5,7 виден также пункт Export Hardware for SDK} который выгружает параметры аппаратной платформы в среду разработки программного обеспечения SDK, выполненную на базе IDE Eclipse. Это позволяет сразу после загрузки конфигурации в ПЛИС приступить к программированию. 5.3. Порядок разработки программного проекта в SDK В качестве SDK используется среда разработки на базе Eclipse. Внешний вид главного окна после экспорта проекта показан на
224 Глава 5 I Рис. 5.8. Внешний вид окна SDK после экспорта аппаратной платформы рис. 5.8. Эта среда имеет привычный для многих программистов вид, включающий список компонентов проекта, рабочую область, в которой можно выполнять редактирование исходных модулей проекта, консоль, вспомогательные панели и окна. Среда Eclipse хорошо известна среди разработчиков и допускает конфигурирование параметров в широком диапазоне, в том числе с использованием plug-in-ов, адаптирующих ее к определенной аппаратной платформе. В качестве компиляторе в SDK используется gcc, что открывает возможность использования языков программирования, поддерживаемых этой цепочкой инструментов. Для проекта на базе ППСНК существует несколько уровней настройки. В отличие от микроконтроллеров, у которых аппаратная часть является в целом фиксированной (хотя часто и настраивается в широких пределах), для проекта на базе Zynq возможна ситуация, когда в составе системы присутствуют самые разные периферийные модули, создаваемые на базе программируемых ресурсов. Поэтому для проектов, разрабатываемых в SDK, рассматриваются три уровня платформы: 1. Hardware Platform — аппаратная конфигурация ПЛИС, определяемая конфигурационным файлом. 2. Board Support Package (BSP) — уровень программных драйверов, генерируемых для поддержки присутствующих в проекте аппаратных средств.
дополнительные инструменты проектирования на базе ПЛИС 225 1 BSP Application project 1 i t Hardware Platform 1 Application project 1 I BSP1 1 Application project 1 Рис. 5.9. Соотношение между Hardware, BSP и проектами 3. Application — программное приложение пользователя. На базе одной аппаратной платформы можно создать несколько BSP (например, на базе разных операционных систем), а для каждой связки Hardware Platform + BSP — несколько программных проектов. Соотношение между Hardware, BSP и проектами иллюстрирует рис. 5.9. При работе в SDK требуется отслеживать, в каком соотношении находятся эти понятия, поскольку наличие промежуточного уровня BSP может несколько дезориентировать разработчика при освоении этой технологии. Аппаратная платформа экспортируется из САПР Vivado. После запуска SDK требуется создать соответствующий пакет поддержки платы (Board Support Package). После выбора в меню проекта пункта New —> Board Support Package открывается диалоговое окно, показанное на рис. 5.10. В диалоговом окне на рис. 5.10 уже установлены параметры «Hardware Platform» и «CPU», поскольку они были определены при запуске SDK. Для проекта можно выбрать базовую программную платформу, как показано на рис. 5.11. По умолчанию выбирается standalone, т.е. минимальный набор программных средств, включающих в себя драйверы устройств, имеющихся на плате. Тем не менее минимальной такую конфигурацию можно назвать достаточно условно, поскольку она может включать в себя программные пакеты с хорошей по отношению к микроконтроллерам функциональностью. Например, доступен стек протоколов TCP/IP на базе библиотеки lwlp, поддержка файловой системы FAT32 на внешних носителях, а также в памяти (memory file system). В ряде случаев такой, на первый взгляд ограниченной, поддержки аппаратуры может оказаться достаточно для решения многих задач. Вопросы использования операционных систем для проектов на базе Zynq являются весьма интересными. Известно, что ориентация на широко распространенную ОС существенно расширяет возмож-
226 Глава 5 -зцо Pfof<x:t %|li ¦'•¦ Рис. 5.10. Диалоговое окно создания пакета поддержки платы Рис. 5.11. Диалоговое окно настроек параметров базового программного обеспечения для создаваемого проекта
дополнительные инструменты проектирования на базе ПЛИС 227 Рис. 5.12. Диалоговое окно создания нового программного проекта ности создаваемого устройства и его привлекательность для потребителей. В то же время доступ к базовым функциям файловой системы, сети, коммуникационных устройств возможен и без установки ОС. Для ряда задач ориентация на вариант standalone может сэкономить разработчикам время, которое в противном случае будет потрачено на установку и адаптацию сложной операционной системы. Далее остается создать программный проект, выполнить его компиляцию и загрузку. В SDK имеются шаблоны проектов на С и C++, среди которых есть простейший и стандартный для программирования шаблон Hello, world. В меню File -> New есть возможность выбора шаблона нового проекта на С, среди которых в Диалоговом окне следует указать Hello, world. Диалоговое окно создания нового проекта показано на рис. 5.12. При этом будет сгенерирован набор файлов, включая заголовочные файлы и исходные тексты. На рис. 5.13 показано окно SDK в режиме редактирования
228 Глава 5 Рис. 5.13. Внешний вид SDK в режиме редактирования исходных текстов проекта файла верхнего уровня helloworld.c. В зависимости от настроек среды разработки сборка проекта может выполняться и автоматически, после каждого сохранения изменений. Если этот режим не выбран, ручной запуск сборки проекта создаст необходимый для загрузки в ПЛИС elf-файл. Результаты сборки видны в консоли на рис. 5.13, где показаны размеры программных секций файла hello.elf. Для корректного размещения программных модулей в памяти системы необходимо создать linker script (файл сценария редактора связей). Это файл с описанием доступных системе областей памяти и инструкциями по их использованию. В отличие от PC, где операционная система автоматически выделяет области памяти для размещения кода, данных, стека и кучи, в создаваемой на базе АР SoC системе может присутствовать несколько областей памяти, соответствующих внешним микросхемам и накристалльным компонентам различных типов. Эта память может быть как энергозависимой, так и энергонезависимой, быть доступной или недоступной для записи, так что размещение каких-то модулей программы в ней может оказаться невозможным. Для разрешения этих проблем разработчик должен самостоятельно указать, какие компоненты памяти необходимо использовать для размещения кода, данных, стека и кучи. На рис. 5.14 показаны настройки сценария редактора связей, которые вызываются после выбора пункта меню Generate Linker Script-
дополнительные инструменты проектирования на базе ПЛИС 229 Рис. 5.14. Настройки сценария для редактора связей (linker script) По умолчанию программные модули размещаются в памяти DDR, однако эта память не инициализируется автоматически, так что запустить программный код из нее непосредственно после старта не удастся. Кроме того, эта память медленнее встроенной накристалль- ной памяти, включая и блочную память программируемой подсистемы, и статическую память ARM. В качестве областей для размещения программных секций следует выбрать память процессорных ядер ARM, как показано на рис. 5.14 в выпадающем списке. После нажатия на кнопку Generate запрос на подтверждение замены существующего файла необходимо подтвердить. Теперь можно выполнить загрузку конфигурации, содержащей описание аппаратной части проекта. Для этого на плате ZedBoard необходимо установить перемычки Mode, как показано на рис. 5.15. Это сочетание разрешает использование интерфейса JTAG не только для конфигурирования программной части, но и для доступа к ядрам ARM. Рис. 5.15. Установка перемычек для платы ZedBoard, позволяющая использовать интерфейс JTAG для связи с процессорной подсистемой
230 Глава 5 WW Рис. 5.16. Загрузка конфигурации FPGA из SDK Щ Примечание: в ряде случаев плата Zedboard поставлялась с положением этих перемычек, рассчитанным, на загрузку с SD-карты, что приводило к частым обращениям разработчиков с поиском решения для «неработающего» интерфейса JTAG. Для загрузки конфигурации можно использовать кнопку быстрого доступа, расположенную на инструментальной панели SDK. В открывшемся диалоговом окне (рис. 5.16) будет автоматически подставлен путь к файлу, содержащему «пустую» конфигурацию, т. е. конфигурацию аппаратной части проекта без загруженной программы. Запуск программы можно будет выполнить в дальнейшем средствами SDK. Компилятор gcc, используемый в SDK, необходимо настроить для создания программного кода с соответствующими свойствами. В SDK используются несколько конфигураций программы, используемые для обычного запуска (Run), отладки (Debug), при которой в код включается информация о программных объектах, и профилирования (Profile), при котором имеется возможность оценки ресурсов, потраченных процессором на выполнение тех или иных функций. Создание конфигурации запуска выполняется, например, в контекстном меню, вызываемом правой кнопкой мыши для программного проекта (рис. 5.17). На рис. 5.18 показано диалоговое окно, в котором установлены параметры конфигурации Xilinx C/C++ ELF- Нажатие на кнопку Run в показанном окне запустит программу на
Дополнительные инструменты проектирования на базе ПЛИС 231 Рис. 5.17. Выбор пункта настройки параметров запуска программного проекта плате ZedBoard, загрузив проект в память процессора ARM, однако перед этим необходимо установить связь с платой. Для установки связи с ZedBoard необходимо использовать од- НУ из коммуникационных программ, способных работать с UART. В качестве такой программы можно использовать, например, Тега Term, которая свободна для использования и позволяет работать как с СОМ-портами, так и TCP/IP. Внешний вид окна Тега Term пРи настройке параметров соединения показан на рис. 5.19. Параметры последовательного порта необходимо согласовать с установ-
232 Глава 5 Рис. 5.18. Диалоговое окно настройки параметров запуска программного проекта Рис. 5.19. Настройка параметров коммуникационной программы (Тега Term) Рис. 5.20. Настройка последовательного порта в программе Тега Term ками, сделанными в SDK. В данном случае это скорость передачи 115200 бит/с, 8 битов данных, один стоп-бит (рис. 5.20). Запуск программы из SDK (кнопка Run на инструментальной панели) позволит наблюдать в окне Тега Term (рис. 5.21) текст, выводимый платой ZedBoard в консоль (последовательный порт связывается с файлами stdin и stdout в настройках компилятора). Рис. 5.21. Внешний вид окна программы Тега Term после установления соединения с платой ZedBoard и запуска демонстрационного программного проекта
дополнительные инструменты проектирования на базе ПЛИС 233 5.4. Софт-процессоры В отличие от hard-processor, т. е. процессора, реализуемого на полупроводниковой пластине в виде отдельных компонентов, софт- процессор появляется в результате конфигурирования части ПЛИС. Для такой операции не существует принципиальных препятствий, поскольку конфигурируемые ресурсы ПЛИС содержат все необходимые для построения процессора компоненты. MicroBlaze, как и любое конфигурируемое ядро, имеет худшие характеристики по сравнению с аппаратным процессором, что связано с необходимостью его реализации на базе программируемых ячеек. Тем не менее, наличие в цифровой системе процессора дает разработчику множество возможностей. Если в проекте имеются сложные последовательности сигналов, используются сложные протоколы обмена данными или имеется множество режимов работы устройств, попытка описать всю функциональность на уровне RTL приведет к чрезмерно сложной реализации, а объем HDL-описаний будет лавинообразно расти при попытке введения новых режимов с сохранением работоспособности предыдущих. В то же время для программистов не представляет принципиальной сложности работа с проектами, имеющими множество режимов и использующих длинные последовательности операций. Все эти последовательности задаются операторами языков программирования (сравним это с одновременной работой всех схем, реализованных на HDL). Поэтому при проектировании можно сочетать достоинства аппаратных и программных решений. Критичные к производительности и времени реакции, но относительно простые операции являются очевидными кандидатами на аппаратную реализацию, а для управления этими устройствами удобно использовать процессор. Можно отметить, что MicroBlaze не следует рассматривать как компонент, обеспечивающий основной вклад в производительность вычислений. Напротив, по сравнению с аналогичными по архитектуре аппаратными решениями использование ПЛИС даже начального уровня будет экономически невыгодным. Основная функция софт-процессора — обеспечение управления аппаратными компонентами ПЛИС. Также важным является то, что с наличием процессора множество операций отладки могут быть проведены на программном Уровне, без необходимости создания нового варианта конфигураци- °нного файла. Для ПЛИС этот процесс занимает от нескольких
234 минут до нескольких часов, что существенно превышает время на компиляцию программного проекта. Поэтому процессорная система позволяет повысить продуктивность разработки и увеличить число итераций отладки в течение рабочего дня. Компания Xilinx предлагает несколько готовых софт-процессоров, работа с которыми поддержана компиляторами и средствами отладки, поставляемыми в составе САПР Vivado. Это IP-ядро Micro- Blaze, приближенное к процессорам ARM, и простое 8-разрядное ядро PicoBlaze, использующее минимальный объем ресурсов. Эти процессоры рассмотрены ниже. 5.4.1. Процессор MicroBlaze MicroBlaze — это RISC-процессор с разрядностью данных 32 или 64 (в версии 11, поставляемой в составе Vivado 2018.3, доступны обе версии ядра). Поскольку это софт-ядро, его параметры могут изменяться в достаточно широком диапазоне. Используется 3-, 5- или 8- ступенчатый конвейер, что дает возможность оптимизировать ядро как по занимаемым ресурсам ПЛИС, так и по производительности. В общем случае с учетом конфигурируемости MicroBlaze подразумевает набор настроек для оптимизации по различным параметрам, из которых минимальный размер и максимальная производительность не являются единственными. RISC-процессор имеет гарвардскую архитектуру. Это означает, что память команд и память данных подключаются с помощью независимых интерфейсов, что позволяет повысить эффективность использования памяти. Процессор имеет 32 регистра общего назначения и использует 32-разрядную 3-операндную команду. Для программирования MicroBlaze адаптирован компилятор gcc, поэтому разработка программных приложений может вестись с помощью SDK на основе Eclipse, как и для подсистемы ARM в ПЛИС Zynq. Упрощенная структура ядра процессора MicroBlaze показана на рис. 5.22. Серым цветом выделены необязательные компоненты. Среди этих компонентов наиболее важными являются: • устройство управления памятью (Memory Management Unit, MMU), которое решает задачу разделения адресных пространств в многозадачных операционных системах. Благодаря такому устройству оказывается возможным обеспечить безопасную работу приложений в операционных системах Windows или Linux. Варианты ОС Linux могут быть запущены и на MicroBlaze при наличии MMU; • компоненты АЛУ: устройство барабанного сдвига (barrel shifter), умножитель, блок целочисленного деления, блок операций над
дополнительные инструменты проектирования на базе ПЛИС 235 ЩинаАХ1 инструкций Устройство управления памятью (MMU) Счетчик команд Буфер команд Декодер команд АЛУ Сдвиг Бараб. сдвиг Умножение Деление FPU Per. файл ШинаАХ1 данных Рис. 5.22. Упрощенная структура ядра MicroBlaze microblaze_mcs_0 dockjtl resetjH ctk Reset MicroBlaze^ MicroBlaze MCS uart_rtLO gpio_rtl_0 gpiojtlj Рис. 5.23. Вид компонента MicroBlaze MCS с настроенным компонентом UART и портами ввода-вывода числами с плавающей точкой (FPU). Все эти компоненты являются относительно ресурсоемкими и их исключение из состава процессора может сократить его размер. Для подключения внешних устройств используется шина AXI. Строго говоря, понятие AXI включает в себя не спецификацию сигналов шины, а описание интерфейса, который физически может быть реализован с помощью различных наборов сигналов. Для MicroBlaze так же, как и для ARM в Zynq-7000, используется автоматическая генерация шаблонов интерфейсов AXI. Для еще большего упрощения работы с MicroBlaze используется его микроконтроллерный вариант MicroBlaze MCS. Внешний вид этого компонента представлен на рис. 5.23. Видно, что компонент содержит минимальный набор внешних сигналов, причем многие периферийные компоненты, характерные для микроконтроллера, уже включены в его состав и могут регулироваться параметризацией IP- ядра. Внешний вид диалогового окна для настройки параметров микроконтроллерного компонента показан на рис. 5.24. На отдельных вкладках можно настроить следующие параметры: • MCS — общие параметры процессора, такие как входная тактовая частота, размер памяти и тип оптимизации (по размеру
236 Глава 5 MicroBIaze MCS C.3) :h- '.'¦{' ¦?..;. »• ,\'.'. .',¦¦".' "•¦;..',: ;.¦•> v":-', t.\; .'¦•. • • .\. г < Associate Etf files ;;...,".' : ¦ v •' Tools •••; ': ..• Рис. 5.24. Внешний вид диалогового окна настройки параметров MicroBIaze MCS или производительности), здесь же можно отметить необходимость вывода шины на внешний интерфейс модуля и наличие встроенного отладчика; • UART — настройка контроллера UART, который является крайне удобным интерфейсом для подключения процессора (и всего проекта на ПЛИС) к внешнему компьютеру. Речь идет не о физическом интерфейса типа RS-232, а о разновидности преобразователя USB-COM, который часто используется на отладочных платах с ПЛИС. При его наличии консоль микроконтроллера
дополнительные инструменты проектирования на базе ПЛИС 237 (т. е. файлы stdin, stdout) можно подключить непосредственно к терминалу на ПК. Настройка контроллера UART производится по всем типичным параметрам — скорости передачи, числу битов, контролю четности и необходимости генерирования прерываний по приему, передаче или ошибке; • FIT (Fixed Interval Timer) — таймер с фиксированным интервалом (в периодах тактового сигнала), который доступен для чтения процессором и запускается при старте FPGA; доступно до 4 таймеров; • PIT (Programmable Interval Timer) —- таймер с программируемым интервалом (также в периодах тактового сигнала); этот таймер также доступен для процессора, но его интервал может изменяться в процессе работы; доступно до 4 таймеров, все таймеры могут генерировать прерывания; • GPO (General-Purpose Output) и GPI (General-Purpose Input) — выходы и входы общего назначения, для которых могут быть заданы до 4 независимых регистров разрядности от 1 до 32; входы могут также генерировать прерывания по любому из перепадов сигнала (фронт, спад, или оба); • Interrupts — настройка внешних входов для прерываний. Можно указать, что 4 канала GPIO конечно же не являются принципиальным ограничением MicroBlaze. Это число определяется интерфейсом настройки MicroBlaze MCS и для более полного варианта IP-ядра диапазон настройки параметров гораздо шире. На рис. 5.25 показан фрагмент диалогового окна с настройкой более полного варианта MicroBlaze, представляющего собой только ядро процессора с выведенными интерфейсами памяти данных (DLMB) и инструкций (ILMB). Рис. 5.25. Фрагмент диалогового окна настройки IP-ядра MicroBlaze
238 ___ г_^а в а 5 Практически все ядра, находящиеся в составе IP-Integrator, име~ ют возможность подключения к шине процессора MicroBlaze, соот- ветствующего протоколу AXI. Подключение в блочном проекте осу. ществляется не отдельными проводниками, а целой шиной. После сборки процессора MicroBlaze и набора периферийных компонентов дальнейшая работа производится так же, как и для системы на базе ARM, которая была рассмотрена выше. Тот факт, что MicroBlaze является софт-процессором, позволяет использовать его и в FPG А, т. е. в ПЛИС без аппаратных процессорных ядер. Можно напомнить, что для семейства Zynq используется термин ППСНК — полностью программируемая система на кристалле (APSOC — All-Programmable System-on-Chip), поэтому формально они не вполне тождественны понятию FPGA, хотя и содержат матрицу PPGA на кристалле. Характеристики MicroBlaze могут варьироваться в зависимости от используемого семейства ПЛИС и настроек. Указываемая в документации номинальная тактовая частота изменяется от 225 МГц (Artix-7) до 397 МГц (Kintex UltraScale), а размер в LUT составляет от 600 до 1100. Кроме того, добавление к проекту периферийных компонентов неминуемо усложнит трассировку, что приведет к снижению реально достижимой тактовой частоты. Поэтому на практике следует предусматривать запас для проведения надежной трассировки проекта в целом, не ориентируясь только на формально указываемые параметры MicroBlaze. Можно еще раз отметить, что MicroBlaze не предназначен для того, чтобы быть основным компонентом проекта, определяющим его производительность. Роль этого процессора состоит в том, чтобы предоставить разработчику удобное управление другими компонентами проекта и перенести часть процесса отладки на программные инструменты, обеспечивающие большую гибкость и более короткий цикл отладки по сравнению с HDL-проектированием. 5.4.2. Процессор PicoBlaze Процессорное ядро PicoBlaze — это 8-разрядный софт-процессор, который был разработан в качестве простейшего ядра микроконтроллерного типа, чтобы обеспечивать альтернативу более сложному и ресурсоемкому MicroBlaze для проектов в ПЛИС минимальной логической емкости. Одна из версий этого ядра занимала всего 96 секций (slice) в FPGA серии Spartan-З. Современные FPGA имеют существенно больший размер, однако вполне возможно применение многоядерной системы, состоящей как из нескольких PicoBlaze, так и из связки ARM -f MicroBlaze + PicoBlaze.
л0цолнительные инструменты проектирования на базе ПЛИС 239 Стек 64-байтовое ОЗУ (Scratchpad RAM) PORT ID |out_port: Флаги СП Zero fUl Carry Рис. 5.26. Структурная схема процессора PicoBlaze Ядро PicoBlaze в текущей версии обозначается также как KPCMS. Аббревиатура расшифровывается как K-coded (Constant- coded) Programmable State Machine, т. е. конечный автомат, программируемый постоянным запоминающим устройством. Под постоянным запоминающим устройством имеется в виду то, что сам процессор не имеет доступа к памяти команд и не может самостоятельно скомпилировать свою программу для ее последующего выполнения. Однако ограниченность ресурсов и не предусматривает запуск компилятора на самом PicoBlaze. Структурная схема этого ядра показана на рис. 5.26. На этом рисунке виден минималистичный подход к архитектуре. Процессор имеет 16 регистров общего назначения, сверхоперативную память (Scratchpad RAM) размером 64 байта, а его программа записывается в один блок BRAM. Ограничение в 1024 шага программы является принципиальным, поскольку не только счетчик команд имеет разрядность 10 битов, но и многие команды перехода задают адрес в фиксированном 10-разрядном поле. Поэтому нарастить размер памяти команд с точки зрения программируемости ПЛИС очень легко, однако это затронет архитектурные ограничения самого процессора. Текущая версия, KPCMS6, оптимизирована для ПЛИС Spartan- 6 и серии 7, где занимает всего 26 секций. Схемотехническое представление этого компонента в варианте микроконтроллера представлено на рис. 5.27. В этом случае внешние интерфейсы представляет собой простые порты для чтения и записи сигналов, а также тактовый сигнал, сигналы сброса и прерывания. Подобная версия дозволяет реализовать вариант несложного 8-разрядного микроконтроллера внутри более сложного проекта, передав его поддержку некоторых протоколов, первичную обработку данных внешних датчиков и т.п.
PicoBlaze IN PORT[7:0] INTERRUPT RESET >CLK Microcontroller OUT PORT[7:0] PORT[7:0] READ STROBE WRITE STROBE INTERRUPT ASK 240 Глава 5 Из-за ограниченного раз. мера памяти команд для Pico- Blaze сомнительно эффективное применение языков программирования " высокого уровня. Средства программи- Рис. 5.27. Схемотехническое представле- ние ядра PicoBlaze в варианте микрокон- Р<»ания ограничиваются ас- троллера семблером. 5.4.3. Перспективы применения многоядерных процессорных систем в проектах на ПЛИС Широкое распространение микроконтроллеров сформировало соответствующие практические подходы к их применению в цифровых системах. Для разработчика микроконтроллерной системы естественно отношение к процессору как к центральному элементу системы, который является единственным инструментом решения всех задач. Снять часть нагрузки с процессора могут периферийные устройства, которые часто обеспечивают генерацию прерываний и прямой доступ к памяти, что в некоторой степени разгружает процессорное ядро. С одной стороны, процессоры в ПЛИС однозначно проигрывают по соотношению цены и производительности аппаратным решениям. Частота софт-ядра MicroBlaze относительно невысока, а стоимость ПЛИС с аппаратным ядром ARM Cortex-A существенно выше многих аналогов, не содержащих FPGA на кристалле. В то же время даже ПЛИС минимальной стоимости (в которые вполне помещается PicoBlaze) все еще в несколько раз дороже 8-разрядных микроконтроллеров, которые к тому же могут иметь интегрированные на кристалле периферийные компоненты, нехарактерные для FPGA, например USB, АЦП, ЦАП, аппаратные контроллеры ШИМ и т.п. Важно, что при проектировании на базе ПЛИС процессоры следует рассматривать не как основной компонент, а как вспомогательный, позволяющий привнести в проект инструменты из «мира программирования». Кроме того, в отличие от аппаратных решений, в ПЛИС возможна реализация многоядерной процессорной системы, которые к тому же могут иметь совершенно оригинальную архитектуру внутренних связей, не копирующую известные решения для многоядерных систем. Например, для разгрузки подсистемы ARM, которая занимается реализацией высокоскоростного обмена по Ethernet, в проект могут быть добавлены несколько ядер MicroBlaze, к каждому из которых подключается собственный набор периферийных устройств.
дополнительные инструменты проектирования на базе ПЛИС 241 В ряде случаев, например для обмена с внешними устройствами по I2C, SPU, UART, оперативной реакции на внешние события, вполне достаточно возможностей даже PicoBlaze. Планирование архитектуры на ранней стадии проектирования может существенно облегчить разработку программного обеспечения, особенно в части обработки независимых событий, которые в реальности могут перекрываться. Для конфигурируемой системы, разрабатываемой для конкретного набора периферийных устройств, протоколов и интенсивности внешних воздействий, вполне может использоваться набор из ARM, нескольких MicroBlaze и нескольких десятков (или даже сотен) PicoBlaze. Такой подход может выглядеть необычным (и разумеется, не должен представляться разработчику самостоятельной целью), однако сам подход, основанный на размещении на кристалле множества независимо работающих процессорных ядер, вполне может рассматриваться на практике. 5.5. Vivado HLS (High-Level Synthesis) Vivado HLS (High Level Synthesis) — новая САПР Xilinx, предназначенная для создания цифровых устройств с применением языков высокого уровня. Попытки использования таких языков (понимая под ними языки с Си-подобным синтаксисом) неоднократно предпринимались различными компаниями на протяжении последнего десятилетия. Основной целью таких продуктов было упрощение процесса проектирования для разработчика, знакомого с программированием. Практическое использование ПЛИС часто вызывает трудности для «чистых» программистов, которые сталкиваются с целым рядом непривычных задач: необходимостью помнить о правильном формировании тактовых сигналов, учитывать латентность, а также вообще понимать, что операторы языков описания аппаратуры не вполне эквивалентны операторам языков программирования. Например, оператор сложения, естественный для программиста, в распространенных языках описания аппаратуры (HDL) требует соответствующего обрамления. Разные схемотехнические решения будут получены для случая, когда сложение выполняется в виде оператора непрерывного присваивания (continuous assignment) и внут- рисинхронного процесса. В то же время цифровая схемотехника по мере уменьшения норм технологического процесса все больше тяготеет к синхронным схемам. В итоге оказывается, что много усилий при проектировании на базе ПЛИС тратится на разработку управляющего автомата, активирующего устройства в нужные моменты времени.
242 Глав. Зная необходимую последовательность операций, можно, меняя регулярные правила, построить соответствующий конечный автомат. В свою очередь, его построение можно автоматизировать разработав соответствующую программу анализа исходного текста на языке высокого уровня. В начале 2000-х годов можно было наблюдать серию программных продуктов, представлявших собой компиляторы, генерирующие VHDL или Verilog на уровне регистровых передач (RTL-уровень) из Си-подобного языка программирования. Получавшиеся файлы обычно могли быть интегрированы в проект наравне с файлами, полученными другим способом. Характеристики проектов, созданных с помощью инструментов C-to-RTL, по проводившимся обзорам, обычно отличали чуть больший объем ресурсов и чуть большая тактовая частота. Это явилось следствием того, что компиляторы разбивали сложные вычисления на элементарные операции, каждая из которых имела небольшую задержку. Соединение таких элементарных схем, управляемых конечным автоматом, давало в результате регулярную структуру из регистров, передававших друг другу данные через вычислительные узлы. Подобные структуры достаточно эффективно реализуются в FPGA. Схожесть языков C-to-RTL с языком программирования Си не означает при этом, что такой инструмент способен создать проект в FPGA, реализующий вычисления, эквивалентные программе на Си для компьютера или микроконтроллера. Выбор Си в качестве основы объяснялся широкой распространенностью этого языка и снижением входного порога освоения для разработчиков, знакомых с программированием. Однако, за исключением простейших примеров, программы на Си должны подвергаться глубочайшей переработке для получения аппаратного решения, способного выступать в качестве ускорителя интересующих нас вычислений. В 2011 г. компания Xilinx объявила о выпуске продукта, относящегося к упомянутому классу инструментов — преобразование Си- подобного исходного текста в эквивалентный код на одном из языков описания аппаратуры. Создаваемое RTL-представление представляет собой конечный автомат (т. е. схему, выполненную в синхронном стиле, что предпочтительно для современных FPGA), управляющий потоками вычислений. Результаты зависят от проектных ограничений (constraints), а также, причем в большой степени, от директив компилятора. Директивы также могут облегчить формирование интерфейсов создаваемого модуля — он может быть экспортирован в виде IP-ядра с интерфейсом, определенным пользователем, но так-
яоПолнительные инструменты проектирования на базе ПЛИС 243 ясе можно указать на необходимость его экспорта в виде периферийного модуля ддя шины AXI4 (для установки в процессорную систему) или в виде модуля для инструмента System Generator for DSP. упрощенный маршрут проектирования в Vivado HLS показан на рис. 5.28. Директивы HLS существенно сильнее влияют на RTL-представление по сравнению с тем, как директивы компилятора языка программирования влияют на скомпилированный код для процессора. Из одного исходного текста с помощью HLS можно получить несколько существенно различающихся схем. Для анализа этой схемы необходимо определить два важных понятия: С, C++, SystemC Constraints/ Directives А Vivado HLS /VHCL Verlog SystemC Экспорт в RTL P-XACT SysGen PCore Рис. 5.28. Упрощенный маршрут проектирования в Vivado HLS • пропускная способность (throughput) — задержка в тактах между поступлением новых входных данных; • латентность (latency) — задержка между поступлением входных данных и появлением соответствующих им выходных. На рис. 5.29 эти понятия проиллюстрированы на примере простейшей конвейерной схемы. На показанной временной диаграмме видно, что каждым тактом входные данные сдвигаются на один регистр, освобождая при этом вход для приема новых данных. Таким образом, пропускная способность такой схемы составляет 1 такт, поскольку новые данные можно подавать каждым новым тактом. Латентность равна числу триггеров в цепочке (в показанном случае это 2 такта). Данные понятия играют важную роль при разработке высокопроизводительных цифровых схем. При построении сложных комбинационных схем период тактового сигнала определяется самой In Out Латентность = 2 такта П_Л_ Пропускная способность = 1 такт Рис. 5.29. Иллюстрация к понятиям «латентность» и «пропускная способность»
244 ___ Глава 5 длинной цепью, соединяющей синхронные компоненты. Поэтому очевидным способом повышения тактовой частоты (т. е. уменьшения периода тактового сигнала) является разделение длинных цепей триггерами. При этом, очевидно, увеличивается латентность схемы однако это является вынужденным побочным эффектом на пути к достижению более приоритетной цели — увеличению тактовой частоты при сохранении пропускной способности, равной одному такту между новыми входными отсчетами. В качестве примера можно рассмотреть исходный текст, который содержит цикл с четырьмя итерациями. loop: for (i = 3; i >= 0; i~) { if (i==) { ace += x*c[0]; shiftjreg[O] = x; }else{ shiftjreg[i] = shift -reg[i-l]; ace += shiftj:eg[i]*c[i]; По умолчанию создается схема, воспроизводящая поведение процессора общего назначения — все итерации цикла выполняются последовательно. Такая реализация занимает наименьшую площадь на кристалле PPGA (т. е. использует наименьшее число ресурсов), однако требует большого числа тактов от начала работы до получения результатов (т.е. имеет большую латентность). Кроме того, поскольку все итерации выполняются одним и тем же вычислительном блоке, невозможно начать новый цикл расчета до полного завершения текущего цикла. Таким образом, данный вариант имеет малую пропускную способность. По аналогии с разворачиванием цикла в компиляторах языков программирования, такой цикл также можно развернуть (этот прием называется loop unrolling). При этом каждая итерация цикла рассчитывается индивидуальным элементом. За счет одновременного выполнения всех итераций латентность становится существенно меньше, однако число ресурсов, требуемое для реализации такой схемы, возрастает практически пропорционально. Дальнейшим улучшением такой схемы является конвейеризация вычислений. Если промежуточные результаты будут записываться в регистры, то это освободит соответствующую часть ресурсов для выполнения вычислений над следующей порцией данных. Латентность при этом не изменяется, но повышается пропускная
дополнительные инструменты проектирования на базе ПЛИС 245 способность. Логические ячейки FPGA так же, как и блочные ресурсы (память и блоки XtremeDSP), имеют регистры на выходе, поэтому глубокая конвейеризация вполне допустима для FPGA. Исходя из представленного примера можно определить приоритеты при разработке высокопроизводительных схем. В первую очередь следует улучшать пропускную способность, вплоть до одного такта на входной отсчет. При этом номинальное значение тактовой частоты повышается путем более глубокой конвейеризации, что автоматически дает побочный эффект в виде увеличения латент- ности. Второстепенной целью является сохранение латентности на разумно малом уровне, не допуская появления избыточных стадий конвейера, которые в действительности не способствуют повышению тактовой частоты. В качестве примера такой избыточной конвейеризации легко представить вычислительное устройство, на выходе которого установлено несколько последовательно включенных регистров. Верхняя граница тактовой частоты такого устройства определится теми компонентами, которые осуществляют преобразование данных, и добавление регистров на выходе не уменьшает задержку распространения сигналов внутри вычислителя. Для выполнения вычислений требуется обеспечить передачу сигналов данных от одного вычислительного узла к другому в определенные моменты времени. Vivado HLS автоматически выделяет из исходного текста и пути данных, и последовательность управления работой. По мере необходимости операции с данными могут быть распараллелены. Вопрос параллельного выполнения операций является довольно важным для FPGA как таковых. Именно возможность организации большого числа параллельно работающих модулей является принципиальным конкурентным преимуществом FPGA как аппаратной платформы. Известным фактом является то, что именно FPGA способны обеспечить реализацию устройства с уникальной аппаратной архитектурой. Однако это преимущество иногда полагается единственным. В действительности при корректном использовании FPGA способны обеспечить за счет параллельной работы не только высокую абсолютную производительность, но и соотношение произво- Дительность/цена, превышающее это соотношение для сигнальных процессоров и процессоров общего назначения. Например, FPGA семейства Kintex-7 начального уровня имеет 240 независимых блоков, внполняющих операцию «умножение с накоплением». Учитывая, что системная тактовая частота для Kintex-7 достигает 700 МГц, получить 168 GMAC/s. Это значение для практики можно
246 Гл^_ва 5 существенно скорректировать с учетом снижения частоты из-за особенностей трассировки и неполного использования ресурсов, однако вполне можно ожидать значения в 100 GMAC/s для устройства, выполняющего многоканальную цифровую фильтрацию или спектральный анализ. Можно представить, что суммарная стоимость процессоров, способных в сумме обеспечить подобную производительность A00 ГГц при условии, что на каждом такте будут выполняться только операции цифровой обработки сигналов), окажется существенно выше, чем стоимость одной ПЛИС Kintex-7 70. Исходя из этого становится очень важным не только выбрать алгоритм, который мог бы эффективно использовать особенности FPGA, но и реализовать его так, чтобы в проекте не появлялись линии с чрезмерно большой задержкой, по которым и будет вырав- нена тактовая частота. Важно, что эту работу Vivado HLS выполняет автоматически. Поскольку одним из параметров проекта в HLS является требуемая тактовая частота, САПР может оценить, укладывается ли синтезированная схема в эти параметры. Для какого-то варианта схемы для достижения высокой тактовой частоты требуется глубокая конвейеризация, поэтому 4 строки исходного текста преобразуются в 4 операции. Соответственно, латентность такой схемы равна 4. Однако при переходе к аппаратной платформе с более высокой производительностью (например, с Artix на Kintex) задержки при выполнении отдельных операций оказываются меньше, поэтому за один такт удается выполнить две операции. Тактовая частота схемы сохраняется на требуемом уровне, однако латентность уменьшается до 2. Таким образом, при генерации схемы Vivado HLS действует следующим образом: • основным приоритетом является повышение пропускной способности схемы при соблюдении проектных ограничений по тактовой частоте, задаваемой пользователем; • следующим по важности приоритетом является снижение ла- тентности; • по возможности минимизируются занимаемые проектом ресурсы. Другой задачей, которую автоматизирует Vivado HLS, является генерация интерфейсов с учетом управляющих сигналов. На рис. 5.30 показан исходный текст функции и схема сгенерированного модуля для реализации этой функции. Кроме сигналов, объявленных в качестве параметров функции, в модуле имеются также сигналы с суффиксами vld, от слова valid («готовность»). Отдельные
Дополнительные инструменты проектирования на базе ПЛИС Void top(int *inl,int *in2, int *outl) ¦outl = *inl+*in2; Обработка данных inl valid 247 outl KA — t~z— \ ------ »/ лл л Out valid Генерация интерфейса > in2_valid *(упрянлвнияУ—=—> Рис. 5.30. Формирование аппаратных интерфейсов для блоков блоки создаются из функций, описанных в С-коде. Функции могут быть «развернуты» для упрощения иерархии (inlining). Для небольших функций это преобразование выполняется автоматически. 5.5.1. Циклы в Vivado HLS Циклы по умолчанию реализуются итеративно: каждая итерация выполняется последовательно на базе одних и тех же ресурсов. Это обеспечивает поведение ПЛИС, схожее с поведением программ для ЭВМ — увеличение числа итераций означает увеличение времени работы, а объем ресурсов, необходимых для этой операции, остается постоянным. Реализацией циклов можно управлять с помощью директив. Для идентификации цикла в директиве каждый цикл должен начинаться с метки, как показано на рис. 5.31. На том же рисунке показана схема преобразования текста на Си в эквивалентную схему. Видно, что все итерации суммирования выполняются одним и тем же сумматором. При необходимости цикл может быть развернут (unroll), однако для этого требуется, чтобы число итераций цикла было известно на этапе синтеза (переменное число итераций не может быть развернуто). Пример «идеального цикла», приведенный в САПР Vivado HLS, показан в листинге 1. В нем видно, что оба уровня вложенного цикла имеют метки (что позволяет устанавливать индивидуальные Директивы для каждого уровня), а число итераций является константой. Для циклов требуются метки, чтобы директивы Tel могли ссылаться на них Void top (...) - add: for {i=3; i>=0; i--} b = a[i] + b; Рис. 5.31. Реализация циклов в HLS
248 ____ _____ Глава s void loop.perfect(din.t A[N], dout_t B[N)) { int ij; dint_t ace; LOOPJ: for(i=0; i < 20; i+H-){ LOOPJ: for(j=0; j < 20; jH if(j==O) ace = 0; ace -f = A[i] * j; if(j==19) B[i] = ace / 20; Листинг 1. Пример «идеального цикла» (perfect loop) в Vivado HLS. Данный пример хорошо подходит для иллюстрирования влияния директив компилятора на результаты синтеза RTL-представле- ния. Уже было упомянуто, что директива UNROLL приводит к разворачиванию цикла — его итерации начинают выполняться параллельно на собственном наборе оборудования. Число тактов на выполнение всего цикла уменьшается за счет роста размера схемы. В принципе такой эффект и лежит в основе одного из главных преимуществ FPGA, имеющих большое число ресурсов. В табл. 5.1 приведены основные результаты синтеза примера из листинга при разном наборе директив компиляции. Результаты синтеза без дополнительных директив достаточно предсказуемы. Цикл имеет в общей сложности 400 итераций B0 на внешнем и 20 на вложенном уровне). Добавляя латентность на вспомогательные пересылки, можно объяснить появление значения 403 в таблице. Это решение имеет минимальный размер. Установив директиву HLSJQNROLL для внутреннего цикла (LOOPJ), можно наблюдать ожидаемое уменьшение латентности. В цикле используется умножение на значение счетчика (асе += A[i] * j), которое не потребовало привлечения дополнительных блоков DSP. Таблица 5.1 Результаты синтеза проекта Набор директив Без дополнительных директив HLSJJNROLL: для внутреннего цикла для внешнего цикла для внутреннего и внешнего циклов Период, не (требуемый период 25 не) 19,94 19,98 19,94 19,98 из листинга Латентность, тактов 403 61 460 (?) 11 (!) Логические генераторы (LUT) 129 326 1920 6360 Блоки DSP48 2 4 40 80
дополнительные инструменты проектирования на базе ПЛИС 249 Следующий шаг эксперимента — установка директивы UNROLL только для внешнего цикла. Однако результаты оказываются, на первый взгляд, неожиданными — при резком увеличении ресурсов латентность не только не уменьшилась, но и несколько увеличилась. Внешний цикл действительно оказался развернут, и каждая йтерация получила собственный экземпляр устройства умножения. Однако в этом случае каждая итерация внешнего цикла ожидает завершения работы вложенного цикла, поэтому для работы требуется целых 460 тактов. Ожидаемого эффекта удается добиться при установке директивы UNROLL для обоих уровней цикла. Объем ресурсов существенно возрастает — вместо 2 блоков DSP для проекта требуется 80, также резко увеличилось число LUT. Однако латентность составила всего И тактов! Если поставленная цель состояла в том, чтобы максимально задействовать ресурсы FPGA для сокращения времени работы, то она оказалась практически достигнута. Использованная в примере FPGA Kintex-7 XC7K160 имеет 600 блоков DSP и 101 тыс. LUT. При полном разворачивании циклов в проекте оказалось задействовано 13 % и б % этих ресурсов соответственно. Таким образом, с помощью директив компилятора можно весьма широко изменять параметры проекта, регулируя число выделенных на него ресурсов и латентность. Большая гибкость в установлении директив делает процесс их внедрения в проект не таким однозначным, поскольку далеко не все сочетания директив приводят к приемлемым результатам. Это требует от разработчиков обращать дополнительное внимание на характеристики, достигаемые при текущем сочетании настроек и рассматривать различные варианты построения проекта, выбора стиля кодирования и установки директив компиляции. 5.5.2. Массивы и работа с памятью Массивы в HLS реализуются на базе памяти. Вели массив выступает в качестве аргумента функции верхнего уровня, память считается размещенной вне ПЛИС. При необходимости память может быть разбита на более мелкие блоки для реализации на базе триггеров и распределенной памяти (distributed RAM). HLS может использовать двухпортовый режим блочной памяти. Использованию памяти в HLS следует уделять особое внимание. Обычно программист для PC не рассматривает память в качестве отдельного ресурса, поскольку все используемые данные автоматически помещаются в основную память компьютера. При оптимизации программ речь может идти о временном размещении каких-то
250 Г л а в а 5 значений в регистрах, учете особенностей кэширования и т. п. Однако для ПЛИС возможности размещения данных существенно шире. Во-первых, память может быть физически реализована в виде следующих аппаратных ресурсов: • триггеры логических ячеек; • LUT секций типа SliceM (распределенная память); • в блоках памяти BRAM. Отдельно можно рассматривать внешнюю память. Она не является частью кристалла FPGA, однако участвует в работе проекта, в то время как на FPGA размещен контроллер для доступа к ней. Во-вторых, важным преимуществом PPGA является крайне высокая теоретическая пропускная способность подсистемы памяти в целом. Память BRAM представляет собой обычную статическую память (т. е. это не программируемый блок, а фрагмент кремниевой пластины с жесткими металлизированными соединениями). Блоки имеют полностью независимые интерфейсы и могут работать на системной тактовой частоте. Таким образом, теоретически FPGA большого объема способны обеспечить пропускную способность порядка сотен гигабайт в секунду, что оставляет далеко позади интерфейсы внешней памяти, в том числе DDR3. Однако важнейшим вопросом при этом является то, способен ли проект получить преимущество от множества параллельно работающих BRAM, и может ли вообще быть обеспечен такой поток данных внутри кристалла. Из-за этих факторов необходимо тщательно продумывать распределение данных, чтобы обеспечить их размещение в ресурсе такого типа, который позволит максимально эффективно использовать особенности ПЛИС. При программировании также необходимо следить, чтобы выбранные синтаксические конструкции не сделали невозможной размещение данных в памяти, которую имеет в виду разработчик. Можно констатировать, что в настоящее время результаты работы компилятора HLS сильно зависят как от особенностей исходного текста, так и от использованных директив. У программиста, знакомого с С, может сложиться впечатление, что результаты работы HLS в ряде случаев весьма далеки от совершенства. Разработчик, работающий с памятью в языках программирования высокого уровня, не нуждается в решении такой задачи, поскольку независимо от вида массивов и порядка обращения к ним пропускная способность памяти компьютера или микроконтроллера ограничена, причем чаще всего единственным интерфейсом. Вопросы распределения данных по областям памяти могут оказаться актуальными для редких случаев многоядерных систем, имеющих
дополнительные инструменты проектирования на базе ПЛИС 251 Рис. 5.32. Установка типа ресурса для массива сложную структуру доступа к памяти по физически раздельным шинам. В отличие от таких систем, для эффективной работы с памятью в FPGA необходимо выбрать оптимальный способ использования большой суммарной пропускной способности интерфейсов независимых блоков памяти. Например, если все данные будут в целях экономии ресурсов размещены в одном блоке памяти, производительность такого блока будет ограничена двумя операциями за такт (в силу того, что блочная память в FPGA является двухпортовой). Если же распределить программные объекты по разным блокам памяти, то за один такт каждый из этих блоков будет способен выполнить две операции. Как и для блоков DSP, вопрос заключается в увеличении числа операций за такт путем вовлечения в проект все большего объема ресурсов FPGA. Конкретный тип ресурса для программного объекта HLS можно установить директивой RESOURCE, как показано на рис. 5.32. Для гибкого управления памятью используется ряд директив. Директива ARRAY_PARTITION используется для разделения одного массива на несколько меньшего размера. Пример настройки этой директивы показан на рис. 5.33. Параметр dimension («размерность») позволяет указать, какая размерность должна быть подверг-
252 Глава Рис. 5.33. Настройка параметров директивы ARRAY PARTITION нута разделению. Например, для массива my_array[10][6][4] установка этого параметра в 1 заставит компилятор разделить массив на 10 независимых массивов (по максимальному значению первого индекса), каждый из которых будет иметь размерность [6] [4]. Установка параметра в 0 приведет к синтезу 10x6x4 = 240 независимых регистров. Директива RESHAPE выполняет обратное действие — объединяет несколько независимых областей данных в один массив. В сочетании с предыдущей директивой она позволяет управлять размещением данных в физических блоках, увеличивая или уменьшая число независимых шин, с помощью которых выполняется доступ к данным. Директива PACK группирует данные, например составляющие элемент структуры, формируя таким образом более широкую шину для одновременного доступа ко всем ее элементам. Использование этих директив для различных объектов не является однозначным. Крайними ситуациями являются чрезмерно низкая производительность шин для пересылки данных, с одной стороны, и перегруженность FPGA независимыми блоками, приводящая к чрезмерному расходованию ресурсов, с другой. Выбор оптимальной организации размещения данных является индивидуальным вопросом для каждого проекта. Гибкость архитектуры FPGA и огромное число возможных вариантов (далеко не все из которых
дополнительные инструменты проектирования на базе ПЛИС 253 сопоставимы в смысле эффективности) не позволяет слишком надеяться на то, что компилятор самостоятельно выберет оптимальный способ размещения данных при любых операциях над ними, которые захочет выполнить разработчик. 5.5.3. Поддержка языков высокого уровня В Vivado HLS можно использовать следующие языки высокого уровня: С, C++, SystemC. Они имеют схожий синтаксис, поэтому освоение данной группы Си-подобных языков обычно не составляет большого труда. Однако с формальной точки зрения С и C++ представляют собой разные языки, на что обращают внимание многие авторы литературы по программированию. То же относится и к SystemC. Важным отличием от языков программирования является поддержка arbitrary-precision типов, т. е. типов данных с явно указываемой разрядностью. Это отличие является таким важным потому, что при программировании разработчик имеет дело с процессором, обрабатывающим данные фиксированной разрядности, определяемой конструкцией этого процессора. Изменение разрядности с точки зрения программы возможно, однако редко целесообразно. В противоположность этому при проектировании цифровых систем разработчик имеет возможность явно указать разрядность обрабатываемых данных, которая наилучшим образом соответствует решаемой задаче. Для разных языков типы отличаются: • С: (u)int (с разрядностью 1-1024); • C++: ap_(u)int (с разрядностью 1-1024), apJixed; • SystemC: sc(u)int, scJixed. Типы с точным указанием разрядности позволяют устранять избыточность ресурсов, например, по сравнению с типом int, разрядность которого равна 32. Эта избыточность может оказаться довольно существенной. Если рассмотреть архитектуру блока DSP, то видно, что такой блок способен умножить 18-разрядное число на 25-разрядное. Если же разрядность множителей будет не зафиксирована явно на достаточном для задачи уровне, а выбрана равной 32 (автоматически, в результате использования типа int), для построения схемы будут привлечены дополнительные аппаратные ресурсы. Vivado HLS позволяет синтезировать многие конструкции С/ C++/SystemC, при условии, что их параметры известны во время компиляции (compile time). По понятным причинам не поддерживался синтез для описаний, элементы которых становятся известны Только во время исполнения (run time). Кроме этого, не синтезируются:
254 Глава 5 • функции динамического управления памятью (malloc/free); • операции ввода-вывода (printf/scanf); • системные вызовы (опрос таймера). В синтезируемом коде поддерживаются указатели (pointers). Как правило, они приводят к синтезу схемы, в которой указатель выступает как адрес устройства памяти (само устройство физически может представлять собой компонент любого доступного типа — регистр, распределенная или блочная память). Указатели полезны в случаях, когда необходимо передать ссылку на объект большого размера (pass-by-reference). В этом случае передается адрес объекта, а не весь объект целиком. Гибкость архитектуры FPGA в принципе позволяет передать 1024 бита в качестве 128 8-разрядных элементов (что произойдет в случае передачи объекта «по значению» — pass- by-value), но такая схема скорее всего будет избыточной для многих практических применений (хотя и позволит обрабатывать все 128 значений параллельно). При использовании указателей необходимо обращать дополнительное внимание на получаемые результаты. В общем случае, при работе с HLS необходимо помнить, что PPGA имеют гибкую архитектуру, позволяющую реализовать требуемое поведение множеством способов, в отличие от выполнения программы на процессоре или микроконтроллере. Стиль программного кода, используемые синтаксические конструкции и директивы компилятора способны оказать существенное влияние на получаемые результаты. 5.5.4. Быстрый старт в Vivado HLS Vivado HLS представляет собой отдельный программный продукт, который может быть установлен в рамках инсталляции общего пакета САПР Xilinx, но имеет собственную среду разработки. При запуске Vivado HLS появляется стартовый экран, как показано на рис. 5.34. На этом экране можно как создать новый проект или открыть существующий, так и ознакомиться с готовыми примерами проектов и документацией по САПР. Основные шаги по созданию проекта удобно рассмотреть на практическом примере, содержащем простейшую схему. На рис. 5.35 показано стартовое диалоговое окно мастера создания нового проекта. На рис. 5.36 показана настройка синтезируемой части проекта. Для синтеза функция верхнего уровня не может называться main(), как это принято в С, такое имя предназначено для верхнего уровня модели.
дополнительные инструменты проектирования на базе ПЛИС 255 Рис. 5.34. Стартовый экран Vivado HLS Рис. 5.35. Стартовое диалоговое окно мастера создания нового проекта Далее можно пропустить шаг добавления тестовых модулей, работа с которыми будет рассмотрена позднее. В окне настройки решения (solution), показанном на рис. 5.37, следует указать желаемый период тактового сигнала для проекта и выбрать конкретное наименование FPGA. Как уже было упомянуто выше, эта информация не является абстрактной, а служит для выбора конкретных схемотехнических решений. Если выбранная FPGA имеет недостаточное быстродействие, для схемы будет синтезирован конвейер с большим тшслом стадий. Соответственно, каждая стадия будет выполнять более простую операцию и общая задержка окажется меньше. В данном примере для определенности можно выбрать плату КС-705 на базе PPGA Kintex-7. После завершения работы мастера окно САПР будет выглядеть, как показано на рис. 5.37. Для текущего проекта необходимо добавить синтезируемый файл верхнего уровня. Это можно сделать с помощью главного
256 Глава 5 A dJ/fie move- Fiies Рис. 5.36. Диалоговое окно настройки синтезируемой части проекта Solution Configuration [Pfeese sekct pan] Рис. 5.37. Настройка решения (solution) меню или же из контекстного меню, вызываемого правой кнопкой мыши в области структуры проекта (панель Explorer). Файл верхнего уровня demo.c может содержать текст, показанный в листинге 2. int top_synth(int a, int b) { return a + b; > Листинг 2. Основной синтезируемый файл проекта demo.c На инструментальной панели имеются кнопки, запускающие моделирование и синтез соответственно. После завершения синтеза будет показан отчет с возможностью детализации по отдельным по-
дополнительные инструменты проектирования на базе ПЛИС 257 Рис. 5.38. Окно САПР Vivado HLS после завершения работы мастера создания проекта казателям (например, распределения ресурсов ПЛИС по отдельным элементам программы на HLS), что можно видеть на рис. 5.39. После завершения синтеза в панели Explorer можно изучить синтезированный код. В группе solution -> syn —> vhdl находится сгенерированный модуль на языке VHDL, который может быть передан в другие инструменты проектирования Xilinx. Содержимое этого модуля показано ниже. - RTL generated by Vivado(TM) HLS "- High-Level Synthesis from C, C++ and SystemC - Version: 2013.3 - Copyright (C) 2013 Xilinx Inc. All rights reserved. library IEEE; use IEEE.std_logic_1164.all; use IEEE.mimericj3td.all; entity topjsynth is Port ( apjstart : IN STDXOGIC;
258 _____ Гла в а 5 Рис. 5.39. Окно САПР после завершения синтеза схемы и формирования отчета apjdone : OUT STDXOGIC; apidle : OUT STD.LOGIC; ap_ready : OUT STDXOGIC; a : IN STD-LOGIC_VECTOR C1 downto 0); b : IN STD-LOGIC.VECTOR C1 downto 0); apjreturn : OUT STD-LOGIC-VECTOR C1 downto 0)); end; architecture behav of top-synth is attribute COREJ3ENERATIONJNFO : STRING; attribute CORE_GENERATION JNFO of behav : architecture is IItop^ynth,hlsipJ2013.3,{HLSJNPUT_TYPE=c,HLSJNPUTJ?LOAT=0, HLSJNPUTJ?IXED=0,HLSJNPUTJ>ART=xc7k325tffg900-2, HLSJNPUT.CLOCK=10.000000, HLSJNPUTJVRCH=others,HLS-SYN.CLOCK=1.600000, HLS^YN_LAT=0,HLS_SYN.TPT=none, HLS.SYN _MEM=0,HLS J3YN J)SP=0,HLS JSYN J?F=0,HLS^YN J,UT=0}"; constant ap.constJogic.1 : STDXOGIC := '1'; constant ap_constJogic-0 : STD_LOGIC := '0'; begin ap.done <= ap.start; apJdle <= ap«const Jogic_l; apjready <= apjstart;
дополнительные инструменты проектирования на базе ПЛИС 259 apjreturn <= stdJogic_vector(unsigned(b) + unsigned(a)); end behav; дястинг З. Результаты генерации RTL-представления проекта на языке VHDL Несмотря на простоту, этот пример позволяет продемонстрировать некоторые особенности Vivado HLS. Собственно вычисление выполняется в строке ap_return <= std_logic_vector(unsigned(b) -f unsigned(a));, однако результаты сопровождаются сигналами готовности (apjready) и завершения работы (ap.done). Разрядность обрабатываемых сигналов автоматически установлена равной 32, поскольку для них указан тип int. Далее в проект можно добавить тестовый модуль, с помощью которого можно будет проверить работу синтезированного проекта. Тестовый модуль является элементом более высокого уровня по отношению к синтезируемому, но он также может обращаться и к другим файлам, содержащим несинтезируемый код. Пример простейшего теста показан в листинге 4. #include "stdio.h" int main() { int result; result = top_synthB, 2); printf("Testing 2 + 2 = %d\n\r", result); return 0; } Листинг 4. Тестовый файл для моделирования поведения синтезированного модуля Запуск модели (кнопка «Run С Simulation» на инструментальной панели) приведет к появлению в консоли (рис. 5.40) сообщений от компилятора, а также сообщений, выводимых тестовой программой. Показанный в листинге пример очевиден, хотя и не может рассматриваться как серьезный тест. Моделирование, претендующее на адекватный анализ характеристик синтезируемого описания, должно включать в себя анализ результатов. Рекомендуется разрабатывать так называемые самопроверяющиеся (self-checking) модели, которые проверяют синтезируемые функции не с помощью вручную написанных последовательностей вызовов, а подавая на вход заранее сгенерированные последовательности данных и сравнивая их с также заранее определенными эталонными откликами. С помощью такого подхода можно проверять большое число вариантов (ограниченное в основном допустимым временем тестирования), а изменения тестов сводятся к изменению файлов с данными, а не Кода на С. Создание файлов с входными данными и эталонными
260 Глава 5 откликами может быть автоматизировано, что еще больше повышает эффективность работы и обеспечивает лучшее покрытие проекта тестовыми примерами. Простейший пример, призванный продемонстрировать Рис. 5.40. Консоль Vivado HLS порядок действий с САПР, не после завершения работы теста дает сколько-нибудь ПОЛНОГО представления о практических возможностях этого инструмента и его назначении. Применимость языков высокого уровня и качество автоматически генерируемых схем необходимо анализировать на более сложных проектах. В листинге 5 приведен исходный текст модуля верхнего уровня для модуля быстрого преобразования Фурье (БПФ, в англоязычном варианте FFT). Этот проект входит в состав примеров, включенных в Vivado HLS. #include "fft.top.h" void dummy_procJe( bool direction, configj* config, cmpxDataln in[FFT_LENGTH], cmpxDataln out[FFT_LENGTH]) { int i; config-> setDir(direction); config-> setSch@x2AB); for (i=0; i< FFT_LBNGTH; i++) out[i] = in[i]; } void dummy_proc_be( status-t* statusJn, bool* ovflo, cmpxDataOut in[FFTJLENGTH], cmpxDataOut out[FFT_LENGTH]) { int i; for (i=0; i< FFTJLENGTH; i++) out[i] = in[i]; *ovflo = status_in-> getOvflo() & 0x1; } void fft_top( bool direction, complex<datain_t> in[FFTJLENGTH],
дополнительные инструменты проектирования на базе ПЛИС 261 complex<data.out_t> out[FFT_LENGTH], bool* ovflo) { ^pragma HLS interface apJhs port=direction ^pragma HLS interface apJifo depth=l port=ovflo ^pragma HLS interface apJifo depth=FFT_LENGTH port=in,out ^pragma HLS data.pack variable=in ^pragma HLS data_pack variable=out # pragma HLS dataflow complex<data_in_t> xn[FFT_LENGTH]; complex<data.out_t> xk[FFT_LENGTH]; config.t fft_config; status.t fftjstatus; dummy_proc_fe(direction, &fft_config, in, xn); // FFT IP hls::fft<configl> (xn, xk, &fft.status, &fft_conng); dummy _proc_be(&fft_status, ovflo, xk, out); } Листинг 5. Исходный текст модуля верхнего уровня быстрого преобразования Фурье Сгенерированный проект обладает следующими характеристиками: • FPGA - XC7K160TFBG484-1; • заданный период тактового сигнала 3,30 не; • оценка периода тактового сигнала средствами Vivado HLS 2,89 не C46 МГц); • латентность 3196 — 5247 тактов; • число триггеров — 9934; • число LUT — 8051. Сгенерированный проект имеет достаточно высокую оценку тактовой частоты. В частности, это является следствием того, что в исходном тексте фактически вызвана функция, ссылающаяся на готовое IP-ядро, выполняющее быстрое преобразование Фурье (строка hls::fft<configl> (xn, xk, fefft-status, &fft_config);). Также можно обратить внимание на то, что латентность указана в виде интервала значений. Такое поведение HLS весьма важно для последующего анализа его применения. Интервальный характер латентности связан с тем, что для компонентов проекта, генерируемых HLS, используется механизм «рукопожатия» (handshaking). Выше можно было видеть, что каждое ядро имеет сигналы готовности к приему новых данных, а выходные Данные сопровождает сигналом их достоверности. Таким образом,
262 Гл^ава 5 каждый последующий компонент в цепочке обработки начинает работать, когда все входные данные сопровождены соответствующими сигналами готовности, а сам компонент свободен для обработки следующей порции входных данных. Существует достаточно много алгоритмов, подразумевающих переменное число тактов для завершения работы, поэтому итоговая латентность и оказывается переменной. 5.5.5. Vivado HLS в сравнении с другими средствами проектирования Xilinx С учетом изложенного выше материала для практикующих разработчиков достаточно остро встает целый ряд вопросов — какое же место занимает новая САПР в ряду инструментов проектирования для FPGA? Представляет ли она собой безусловно прорывное решение, которое призвано вытеснить ставший привычным маршрут проектирования на основе RTL-описаний? Является ли такое вытеснение, если оно состоится, вопросом ближайшего времени или же отдаленной перспективой? Существуют ли задачи, которые уже сейчас эффективно могут быть решены с использованием HLS, и на какие особенности проекта должен обратить внимание разработчик, чтобы усилия по освоению HLS оказались оправданными? При сравнении необходимо сразу обратить внимание, что Xilinx позиционирует Vivado HLS в качестве инструмента разработки устройств цифровой обработки сигналов. Действительно, в HLS появилась возможность использования математических выражений и управляющих конструкций С-подобных языков программирования. При разработке в RTL-стиле первым же психологическим барьером являлась необходимость понять, что операторы HDL выполняются не последовательно, по мере их появления в исходном тексте, а одновременно. В HLS же именно эта особенность разработки на ПЛИС была устранена, и появилась возможность привлечения к проектам программистов. Почему при этом делается упор на разработку систем цифровой обработки сигналов? Прежде всего потому, что применение HLS само по себе не гарантирует качественного роста производительности. Далеко не каждая программа, написанная на С, может быть эффективно реализована в ПЛИС. Функциональности компилятора HLS недостаточно, чтобы для произвольного программного продукта определить именно те участки кода, аппаратное ускорение которых даст существенное увеличение эффективности программно- аппаратного комплекса в целом. Из известных сфер применений
дополнительные инструменты проектирования на базе ПЛИС 263 именно цифровая обработка сигналов с ее потенциальной возможностью задействовать параллельные вычислительные структуры может получить существенный выигрыш при реализации в FPGA по сравнению с другими аппаратными платформами. Это не исключает применения HLS и в других задачах, но для алгоритмов ЦОС, по крайней мере, хорошо известны типичные решения на основе параллельных вычислительных структур. Таким образом, для систем цифровой обработки сигналов в настоящее время существует три подхода: • разработка «вручную» в RTL-стиле, возможно, с использованием стандартных IP-ядер; • разработка с использованием System Generation for DSP; • разработка в HLS. Эти пункты не являются взаимоисключающими, поскольку САПР Vivado, предназначенная для сквозного проектирования, технически позволяет иметь в проекте несколько модулей, разработанных с использованием перечисленных подходов, комбинируя их сильные стороны. Как следует из рассмотренного материала, HLS позволяет описывать проект на языках высокого уровня. Разработчик освобождается от необходимости управлять последовательностью операций, автоматически поддерживаются многие типы данных (в том числе с плавающей точкой). Алгоритмы, разработанные на С/С+-Ь, в принципе могут быть перенесены в FPGA, получая существенное ускорение при наличии в исходной задаче операций, выполняющихся параллельно. Разработанный на HLS модуль может быть легко подключен к проекту в System Generator или к процессорной системе в качестве периферийного модуля с интерфейсом AXI4. В то же время результаты работы HLS имеют две особенности, которые могут затруднить применение разработанных модулей: • сильная зависимость результатов от директив компилятора и стиля кодирования; • интервальный характер латентности, плохо прогнозируемое по- тактовое поведение синтезированной схемы. В целом HLS не очень хорошо подходит для компактных проектов с малой латентностью, основанных на хорошо известных разработчику схемотехнических решениях. Например, простой КИХ- Фильтр имеет несложное RTL-представление и может быть реализован на VHDL или Verilog или в виде IP-ядра, a HLS представляется ^сколько избыточным. Кроме того, при реализации КИХ-фильтра
264 Глава 5 необходимо строго следить за постоянством временного интервала между обработкой отдельных отсчетов и переменный характер латентности здесь недопустим. Напротив, если речь идет о проекте, ориентированном на длительное моделирование, проведение различных экспериментов, то высокая скорость разработки на HLS является значимым преимуществом. 5.6. Отладка в реальном времени с помощью приложения ChipScope Часто при анализе работы системы с реальными сигналами важно знать, в каких конкретно состояниях находятся сигналы внутри ПЛИС. Это невозможно сделать с помощью внешних приборов, а постоянный вывод интересующих разработчика сигналов на внешние выводы ПЛИС займет неоправданно длительное время. В то же время предварительное функциональное моделирование тоже далеко не всегда является достаточным, так как реальные сигналы будут явно отличаться от модельных. Рассуждая об организации отладки, можно, например, вывести на какой-то вывод ПЛИС не просто интересный для отладки сигнал, а несколько сигналов через мультиплексор. Тогда, управляя этим мультиплексором, можно выводить для наблюдения любой из заранее поданных на вход мультиплексора сигналов. Далее, если для отладки интересны не просто сигналы, а быст- ропротекающие процессы, можно «записать» состояние сигналов в память. Для этого можно организовать схему, наподобие показанной на рис. 5.41. В этой схеме интересующие разработчика сигналы подаются на входы данных блока памяти. Если адрес для записи постоянно увеличивается счетчиком с некоторой тактовой частотой, то в память окажутся записаны последовательно зафиксированные состояния используемых для отладки сигналов. Впоследствии содержимое памяти может быть прочитано и выведено на внешние интерфейсы для наблюдения. Для внутрисхемной отладки компания Xilinx предлагает инструмент ChipScope, реализующий такой принцип запоминания сигналов для их последующего просмотра. ПЛИС не имеют специальных Сигнал 1 - Сигнал 2 " Тактовый сигнал Входы данных Счетчик Адрес Память Чтение содержимого памяти Рис. 5.41. Принцип внутрисхемной отладки с помошью блока памяти
дополнительные инструменты проектирования на базе ПЛИС 265 ресурсов для запоминания фрагментов сигнала, для этой цели необходимо выделить блоки памяти. Также некоторое число логических ячеек потребуется для управления этой памятью. В качестве интерфейса отправки данных используется JTAG, с помощью которого обычно производится программирование. Таким образом, ПЛИС с подключенным программатором уже в принципе готовы к организации внутрисхемной отладки, причем схемы отладки организуются на базе конфигурируемых ресурсов ПЛИС. Ядра устанавливаются в проекте автоматически, как будет рассмотрено ниже. Для организации обмена служит компонент ICON (Integrated Controller), который является единственным в проекте и непосредственно подключается к JTAG. К этому контроллеру может быть подключено несколько ядер следующих типов: ILA (Integrated Logic Analyzer) — ядро для наблюдения за произвольными цифровыми сигналами внутри проекта; IBA (Integrated Bus Analyzer) — ядро, предназначенное для отслеживания сигналов на шине процессоров ARM или MicroBlaze; VIO (Virtual Input-Output) — набор виртуальных входов и выходов, с помощью которых можно имитировать переключение внешних сигналов и наблюдать за реакцией модулей проекта. На рис. 5.42 показано расположение пункта Set Up Debug среди процессов синтеза в САПР Vivado. Поскольку пос- > ле синтеза уже известен список сигналов проекта, они могут быть показаны разработчику для подключения к одному из ядер ILA. Ядро ICON будет размещено в проекте автоматически. После запуска мастера настройки отладки будет предложено добавить сигна- *н проекта для наблюдения. Сигналы стройки отладочного быть добавлены И непосредственно ядра в САПР Vivado
266 Глава 5 Рис. 5.43. Настройка сигналов для отслеживания отладочным ядром ILA из списка сигналов проекте, которые показаны на вкладке Netlist. Можно отметить, что внешние сигналы ПЛИС не могут быть добавлены для наблюдения, вместо этого следует использовать выходы блоков IBUP, которые вводят внешние сигналы в матрицу программируемых цепей ПЛИС. На рис. 5.43 показан пример настройки сигналов для последующего наблюдения в приложении ChipScope, которое интегрировано в маршрут проектирования Vivado. После выбора списка сигналов будет предложено выбрать глубину буфера для запоминания сигналов. От числа сигналов и размера буфера очевидно зависит число блоков BRAM, которое потребуется для реализации компонентов ILA. Разработчику необходимо резервировать эти блоки, если планируется внутрисхемная отладка, или предусматривать временное исключение из проекта каких-то компонентов, чтобы освободить BRAM. После загрузки конфигурации в ПЛИС утилита программирования автоматически определит наличие блоков ICON в запущенном проекте и выведет окно просмотра сигналов, как показано на рис. 5.44. На инструментальной панели доступны основные инструменты запуска, остановки, масштабирования и поиска перепадов сигналов. Для запуска процесса захвата сигналов доступны триггеры (т. е. условия запуска счетчика), которые реализуются внутри ILA. Условием начала захвата могут быть фронт, спад сигнала или ?&е его определенное значение (в том числе и для шины). Для формирования условия запуска доступны логические комбинации условий-
дополнительные инструменты проектирования на базе ПЛИС 267 Рис. 5.44. Внешний вид окна ChipScope в режиме просмотра сигналов 5.7. Заключение В данной книге не рассмотрен ряд инструментов проектирования, которые требуют отдельных изданий для подробного изложения материала. Это, в первую очередь, специализированный инструмент для проектирования систем цифровой обработки сигналов System Generator for DSP. Его отсутствие здесь связано как со сложностью и емкостью самого направления, так и с тем, что для работы требуется программный пакет Matlab с соответствующим набором модулей. Продукт System Generator for DSP существенно отличается от схожего по назначению HDL Coder. Основное различие состоит в том, что HDL Coder формирует HDL-описание исходя из описания проекта на встроенном языке Matlab (и оно может оказаться неоптимальным для выбранного семейства ПЛИС), a System Generator представляет собой набор IP-ядер, оптимизированных для ПЛИС Xilinx. Эти ядра имеют свои представления для Matlab и могут быть использованы для моделирования. Впоследствии достаточно задать параметры этих ядер (а не генерировать их текст), а реализация для соответствующего семейства ПЛИС будет произведена с сохранением высоких технических характеристик. Недостатком такого подхода является ограниченный набор функций, определяемый теми компонентами, которые есть в составе библиотеки System Generator. Также не рассмотрены средства высокоуровневого проектирования нового поколения, семейства SDx. Отдельным пунктом можно упомянуть разработку систем под Управлением ОС Linux. Все эти вопросы требуют большого объема изложения и является предметом отдельных публикаций.
6 Примеры реализации схем на базе ПЛИС В данном разделе приведены примеры модулей с описанием на языках VHDL и Verilog. 6.1. Комбинационная логика Блоки комбинационной логики добавляются с помощью оператора непрерывного присваивания. VHDL: q <= a and b; q <= (a or b) xor (c and d); Verilog: assign q = a & b; assign q = (a | b) л (с к d); При необходимости приоритет операций регулируется скобками. Использование скобок также может быть полезно для управления процессом синтеза, поскольку в ряде случаев программы синтеза могут давать неоптимальные результаты. Например, результаты синтеза для выражения q = a + b + c + dHq = (a + b) + (с -I- d) могут оказаться различны — в первом случае будет синтезирована «лестничная» структура, где сигналы а и b пройдут последовательно через три сумматора, а во втором результаты окажутся чуть лучше, поскольку расстановка скобок заставит синтезатор создать два отдельных сумматора для выражений а + Ьис -f d, а затем сложить получившиеся выражения (рис. 6.1). Приведенные рассуждения справедливы только для достаточно сложных выражений, поскольку сложение (и любые другие операции) над 4 входными линиями в любом случае могут быть реализованы в одной LUT. с \jy i—/^\ д^ прояснения вопроса рекомендуется использовать инструмент Technology Рис. 6.1. Возможные результаты синтеза для эквивалентных арифметических выражений, различающихся расстановкой скобок. Детали реализации зависят от настроек синтезатора, и эффект может не проявляться на практике
Лрямеры реализации схем на базе ПЛИС 269 Viewer в ISE или Schematic Viewer в Vivado, чтобы убедиться, что требуемая схема реализована рационально. На уровне базовых примитивов комбинационная логика может быть реализована путем прямого программирования LUT. Для этого необходимо подключить библиотеку UNISIM.VComponents (закомментированный шаблон для ее подключения уже присутствует в модулях, генерируемых САПР). В качестве примера приведен вентиль 2И, созданный путем прямого программирования LUT. VHDL: library IEEE; use IEEE.STD-LOGIC1164.ALL; — необходимо добавить объявление — аппаратных примитивов library UNISIM; use UNISIM.VComponents.all; entity lut_struct is Port (a : in STD_LOGIC; b : in STD.LOGIC; с : out STD-LOGIC); end lutjstruct; architecture Behavioral of lutjstruct is begin LUT2Jnst : LUT2 generic map ( INIT => X"8") - содержимое LUT port map ( О => с, - выход LUT Ю => a, — первый вход LUT II => b ~ второй вход LUT ); end Behavioral; Verilog: module lut( input a, input b, output с ); LUT2 #( ЛШТDЪ8) ) LUT2Jnst ( O(c), eudmodule
>70 Таблица истинности для функции 2И а @-й разряд входа) b A-й о 1 1 0 ! 1 разряд входа) , с 0 0 1 1 0 1 0 0 1 1 Номер Глава б Таблица бд позиции в LUT 0 1 2 3 В примере LUT подключена на структурном уровне — путем прямого указания компонента LUT2 (LUT с двумя входами) и цепей, которые подключаются к его выводам. Содержимое памяти LUT задано с помощью параметра INIT для модуля. В примере значение 8 соответствует таблице истинности для функции 2И. Заполнение таблицы, на первый взгляд, выглядит сложным, однако подчиняется довольно простым правилам. Рассмотрим таблицу истинности для функции 2И. Из табл. 6.1 видно, что значения, заносимые в память LUT для соответствия заданной функции, равны 1000 (заполнение начинается с младших разрядов). Таким образом, это число соответствует Х"8". Проектирование комбинационной логики на структурном уровне обеспечивает полный контроль над реализацией отдельных фрагментов, однако является наименее производительным способом разработки. Рекомендуется использовать такой подход только для наиболее критичных цепей проекта, для которых автоматический синтез дает очевидно неэффективную реализацию. Шаблоны компонентов LUT находятся в справочной системе САПР. На VHDL необходимо подключать библиотеку аппаратных примитивов. 6.2. Мультиплексоры Мультиплексоры представляют собой компоненты, пропускающие на выход один из нескольких входов в соответствии с сигналом выбора (selector). Простейший вариант мультиплексора можно реализовать с помощью условного оператора. VHDL: mux <= inO when sel = '0' else inl; Verilog: assign mux = sel ? inl : inO ; В приведенном примере описан мультиплексор «2-в-1», который имеет, как следует из названия, два входа. Для того чтобы выбрать
примеры реализации схем на базе ПЛИС 271 требуемый вход, достаточно однобитового сигнала-селектора, поэтому порт sel является однобитовым. В общем случае п-разрядный селектор достаточен для мультиплексора с 2П входами. Мультиплексируемые входы не обязаны быть одноразрядными. В показанном примере нет никаких сведений о разрядности сигналов inO, inO и mux, которая в действительности может быть любой. Мультиплексоры с большим числом входов можно реализовать яа базе процедурного блока. VHDL: Вариант 1: process(sel) begin case sel is when 0" => q <= a; when 0" => q <= b; when 0" => q <= c; when 0" => q <= d; when others => q <= 'x'; end case; end Вариант 2: with sel select q <= a when 0", b when 1", с when 0", d when 1", 'x' when others; Verilog: always @ * begin case (sel) 2'bOO : q = 2'bOl : q = 2'blO : q = 2'bll : q = default : q endcase end a; b; c; d; = ГЬх; Обратите внимание, что в приведенных фрагментах описан и нереализуемый в аппаратуре вариант, когда значение селектора не Равно ни одной из допустимых двоичных комбинаций. В этом случае на выход отправляется значение X («неизвестно»). Это делайся для того, чтобы при неполно заданной модели входных сиг-
272 Глав а б налов (т.е. когда sel = "UU", Undefined) выход мультиплексора не принимал одного из значений по умолчанию. Например, можно было включить последний вариант при sel = "И" в ветку обработка по умолчанию, но тогда при моделировании мультиплексор давал бы на выходе сигнал d при отсутствии правильно заданной модели сигнала-селектора. Вариант с использованием case (with..select) предпочтительнее использования вложенных операторов if/else, поскольку, как и в случае с арифметическими операциями, САПР ПЛИС имеет возможность использовать шаблоны проектирования, дающие оптимальные решения для мультиплексоров. Дополнительными ресурсами логических ячеек в этом случае являются их мультиплексоры — F5 и F6 для ПЛИС на базе 4-входовых логических генераторов (Spartan- 3, Virtex-4) и F7, F8 для ПЛИС на базе б-входовых логических генераторов (Spartan-6, Virtex-5, Virtex-6, серия 7). б.З. Арифметические операции Арифметические операции являются разновидностью операций, выполняемых с помощью комбинационной логики, поскольку результаты вычисления арифметических выражений могут быть представлены в виде таблиц истинности, а следовательно, реализованы с помощью базовых логических операций. Например, суммирование двух однобитовых чисел даст в результате следующие варианты: О + 0 = 00 0 + 1 = 01 1 + 0 = 01 14-1 = 10A переносится в следующий разряд) Таким образом, результат сложения двух однобитовых чисел может быть получен с помощью вентиля ИСКЛЮЧАЮЩЕЕ ИЛИ, а бит переноса, если он необходим, — с помощью вентиля И. Однако при проектировании для ПЛИС не следует заменять арифметические выражения на эквивалентные логические аналоги, поскольку в этом случае САПР не сможет воспользоваться оптимальными шаблонами проектирования, которые, в частности, для операций сложения и вычитания, позволяют задействовать выделенные ресурсы логических ячеек — линии ускоренного переноса. Кроме того, построение многоразрядных сумматоров/вычитателей производится с применением шаблонов размещения — так называемых Relationally Placed Macro (RPM). Такие шаблоны обеспечивают оптимальное относительное размещение разрядов сумматора/вычитателя, которое,
изации схем на базе ПЛИС 273 вероятнее всего, не будет достигнуто при синтезе описания сумматора, основанного на логических соотношениях между отдельными разрядами. Поэтому арифметические действия следует описывать с использованием символов соответствующих арифметических операций: assign sum = а + b; assign sub = a - b; assign mul = a * b; assign mac = mac + a*b; Для операции умножения будет автоматически использован выделенный аппаратный умножитель. Последний пример представляет собой операцию «умножение с накоплением» (MAC, Multiply And Accumulate), которая широко используется в устройствах цифровой обработки сигналов. САПР ПЛИС распознают выражения представленного вида, реализуя их на базе блоков «умножение с накоплением», которые присутствуют во многих семействах ПЛИС. 6.4. Триггеры и регистры Триггер представляет собой синхронный элемент и описывается процессом на VHDL или процедурным блоком always на Verilog. В списке чувствительности достаточно привести тактовый сигнал и, если есть, вход синхронного сброса или установки, поскольку изменение других сигналов не оказывает немедленного влияния на выход триггера. Описание D-триггера приведено ниже. VHDL: library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity dff is Port (elk : in STD.LOGIC; d : in STD_LOGIC; q : out STD.LOGIC); end dff; architecture Behavioral of dff is begin process(clk) begin if rising_edge(clk) then q <= d; end if; end process; end Behavioral; Verilog:
274 ___ Г^л а в а б module dff(input elk, input d, output reg q); always @ (posedge elk) q <= d; endmodule Комбинируя различные условия внутри процедурного блока можно получить варианты триггера с различными особенностями поведения. К дополнительным сигналам, управляющим поведением триггера, обычно относятся: • се (Clock Enable, разрешение счета), также обозначаемый как en (Enable, разрешение) — сигнал, разрешающий изменение состояния триггера. Высокий уровень на этом входе разрешает выполнение оператора q <= d. • reset (сброс) — сигнал сброса, устанавливающий триггер в состояние нуля. Различают синхронный сброс, выполняющийся по фронту тактового сигнала (обычно его и обозначают как reset), и асинхронный, выполняющийся немедленно при появлении высокого уровня, который обычно обозначают как clr (clear, очистка). • set (установка) — сигнал установка, устанавливающий триггер в состояние единицы. Как и для сброса, различают синхронную установку (set), выполняющуюся по фронту тактового сигнала, и асинхронную (preset), выполняющуюся немедленно. Кроме того, все управляющие сигналы могут иметь как высокий, так и низкий логический уровень, при котором условие их появления считается истинным. Такой уровень для сигналов также называют активным. Иными словами, если при появлении единицы на входе reset происходит сброс триггера, то говорят, что активным уровнем для входа reset является высокий, т. е. сигнал логической единицы. Активный низкий уровень часто используется в схемах, выполненных по технологии РТЛ или ТТЛ, где возможно использование схемы «монтажное ИЛИ». При такой схеме входной сигнал с помощью резистора подключался к положительной цепи питания, что обеспечивало «слабый» уровень логической единицы. При этом любой активный выход, который устанавливал уровень логического нуля, перекрывал единицу, установленную резистором. Поведение триггера при одновременном действии нескольких сигналов с противоположным смыслом определяется описанием на VHDL/Verilog. Например, если сначала проверить сброс, а потом установку, то сброс будет обладать приоритетом, поскольку
{[рямеры реализации схем на базе ПЛИС 275 успешной проверке условия его наступления будет выполнено присвоение выходу нуля, и дальнейшие проверки выполняться не будут. Некоторые примеры описания триггеров показаны ниже. Триггер с синхронным сбросом. VHDL: process(clk) begin if rising_edge(clk) then if reset = T then q <= '0'; else q <= d; end if; end if, end process; Verilog: always ©(posedge elk) if (reset) begin q <= 0; end else begin q <= d; end Триггер с асинхронным сбросом и разрешением счета. VHDL: process(clk, reset) begin if reset = '1' then q <= '0'; elsif rising_edge(clk) then if ce = T then q <= d; end if; end if; end process; Verilog: always @(posedge elk or posedge reset) if (reset) begin q <= 0; end else if (ce) begin q <= d; end
276 __ Глава б Триггер определенного типа может быть добавлен и на струк, турном уровне, в виде аппаратного примитива. Ниже показана установка в проект триггера с входами разрешения счета и синхронного сброса. VHDL: FDREinst : PDRB generic map ( INIT => 'О' ) — Начальное состояние ('0' or '1') port map ( Q => Q, - Выход С => С, — Тактовый вход СЕ => СЕ, — Вход разрешения счета R => R, ~ Вход синхронного сброса D => D — Вход данных ); Verilog: FDRE #( ЛШТAЪ0 ) // Начальное состояние (ГЬО или 1Ъ1) ) FDREJnst ( .Q(Q), // Выход .С(С), // Тактовый вход .СЕ(СЕ), // Вход разрешения счета .R(R), // Вход синхронного сброса .D(D) // Вход данных ); Различные варианты построения триггера находятся в справочной системе САПР. Общей рекомендацией для элементной базы, выполненной с соблюдением технологических норм 90 нм и менее (Spartan-3, Virtex-4 и более новые семейства FPGA Xilinx), является использование только синхронных сигналов сброса и установки. Кроме того, желательно ограничиться только одним входом управления (сброс или установка). Не следует использовать сигнал сброса, если он предназначен только для инициализации триггера в начальный момент работы, сразу после программирования ПЛИС, поскольку начальные значения триггеров логических ячеек не являются случайными, а принудительно устанавливаются в процессе загрузки конфигурации. Таким образом, отказ от лишнего входа сброса облегчает трассировку проекта, не занимая дополнительные программируемые ресурсы. Это же положительно сказывается на
Примеры реализации схем на базе ПЛИС 277 максимальной тактовой частоте, поскольку проект, перенасыщенный управляющими сигналами, требует большого числа трассиро- зочных линий, которые в противном случае могли бы быть заняты другими цепями, для которых важно добиться малых задержек распространения. Категорически не рекомендуется каким-либо образом разрывать сигнал тактовой цепи, например, с помощью логического вентиля И, управляя таким образом работой триггера. Для разрешения или запрещения срабатывания по фронту тактового сигнала следует использовать вход разрешения счета се, который реализован в триггерах ПЛИС аппаратно. Подача на тактовый вход сигнала, прошедшего через логический генератор, ведет за собой более пологий фронт нарастания тактового сигнала, а также его отставание по времени от основного тактового сигнала, который подается на остальные элементы проекта. Это ведет к весьма негативному эффекту «гонки фронтов», когда триггер уже нельзя считать работающим синхронно с остальными компонентами проекта и он может захватывать значение на входе данных, относящееся как к состоянию на предыдущем такте, так и уже обновленное состояние (что является неправильным с точки зрения построения синхронных схем). Этот эффект особо опасен тем, что его появление является непредсказуемым, а поведение неустойчиво — некорректное поведение может проявляться при повторной трассировке того же проекта с другими настройками САПР, для отдельных микросхем в большой партии, или как перемежающаяся неисправность в одной и той же микросхеме при изменении температуры и/или напряжения питания. Идентификация подобных эффектов и методы устранения являются в очень большой степени эмпирическими, и в то же время использование только глобальных тактовых сигналов кардинально решает данную проблему. При проектировании, таким образом, следует обращать внимание на то, чтобы все события для триггеров и элементов на их базе происходили строго по фронту тактового сигнала, который формируется соответствующим аппаратным блоком (DLL, DCM, PLL, ММСМ для разных семейств FPGA) и подается в логические ячейки по глобальным тактовым линиям, имеющимся во всех семействах FPGA. Использование примеров, приведенных выше, соответствует данному требованию. Регистр представляет собой многоразрядный триггер, и описывается тем же способом. Фактически, основной процедурный блок остается для регистра таким же, как и для триггера, а изменяется объявление портов.
278 Г\ла в а б VHDL: entity reg8 is Port (elk : in STD-LOGIC; d : in STD^OGIC-VECTOR^ downto 0; q : out STD_LOGIC_VBCTORG downto 0); end reg8; Verilog: module reg8(input elk, input [7:0] d, output reg [7:0] q); Для регистра сохраняются те же правила проектирования, что и для триггера, 6.5. Сдвиговые регистры Сдвиговый регистр представляет собой разновидность регистра, для которого по фронту тактового сигнала происходит сдвиг содержимого на один или несколько разрядов в какую-либо сторону. Сдвиговый регистр можно представить следующим текстом. VHDL: library IBEB; use IEEE.STDJ,OGIC-1164.ALL; entity shift-reg is Port (elk : in STDXOGIC; din : in STDJL.OGIC; dout : out STD_LOGIC); end shiftjreg; architecture Behavioral of shiftjreg is signal sr : stdJogic.vectorG downto 0) := x'W; begin process(clk) begin if rising-edge(clk) then sr <= srF downto 0) & din; dout <= srG); end if; end process; end Behavioral; В примере на VHDL представлен 8-разрядный сдвиговый регистр, работающий синхронно. Verilog: module shift _reg( input elk, input din,
примеры реализации схем на базе ПЛИС 279 input се, output [15:0] q reg [15:0] data; always ©(posedge elk) begin if (ce) data <= {data[15:l], d_in} ; end assign q = data; endmodule В примере производится сдвиг содержимого внутреннего регистра data на один разряд влево. В младший разряд при этом помещается значение, подающееся на вход dJn, а старший разряд теряется. Работа сдвигового регистра управляется входом се, низкий уровень на котором запрещает сдвиг. Выход сдвигового регистра q является копией внутреннего сигнала data (в отличие от примера на VHDL значение выходного сигнала устанавливается асинхронно, т. е. появляется на такт раньше). Такое решение выбрано потому, что в строке data <= {data[15:l], din} производится как запись, так и чтение переменной data. Таким образом, эта переменная не может быть портом типа output, так как для такого порта допустима только операция записи. Регистр, сдвигающий свое содержимое на регулируемое число разрядов, называется регистром (устройством) барабанного сдвига (barrel shifter). Это более сложное для реализации устройство, чем обычный сдвиговый регистр, поскольку требует дополнительного мультиплексора, из-за чего занимаемый в ПЛИС объем существенно возрастает. Регистр барабанного сдвига применяется, например, для сложения и вычитания чисел с плавающей точкой, где он производит нормализацию мантисс — сдвиг одной из мантисс на число разрядов, равное разнице двоичных порядков складываемых чисел. Поскольку для операций с плавающей точкой желательна высокая производительность, а обычный сдвиговый регистр может потребовать от 1 до N тактов для нормализации (где N — число двоичных разрядов мантиссы, которое для чисел двойной точности равно 53), применение устройства барабанного сдвига для этой цели является оправданным. Пример описания устройства барабанного сдвига показан ниже: VHDL: sel select q <= d when 0", d shl 1 when 1",
280 Глав а б d shl 2 when 0", d shl 3 when others; Verilog: always @* case (sel) 2Ъ00 : q = d; 2'bOl : q = d « 1; 2Ъ10 : q = d « 2; default: q = d « 3; endcase Приведенный пример может быть дополнен регистром, поскольку в описании показан только асинхронный мультиплексор, сдвигающий входной сигнал d на 0, 1, 2 или 3 разряда. 6.6. Счетчики Счетчик выполняет последовательное увеличение или уменьшение своего выходного значения по каждому тактовому импульсу. Простейший вариант счетчика показан ниже: VHDL: architecture Behavioral of counter is — локальное объявление сигнала для счетчика signal cnt : stdJogic.vector G downto 0); begin process(clk) begin if rising-edge(clk) then cnt <= cnt •+¦ 1; end if; end process; end Behavioral ; Verilog: reg [7:0] cnt; always @ (posedge elk) cnt <= cnt + 1; Поскольку для хранения значения счетчика выбрано 8 разрядов, счетчик будет осуществлять циклическое приращение своего значения от 0 до 255, после чего операция 255+1 опять сделает значение cnt равным 0. В показанном примере счетчик работает строго в диапазоне от 0 до 255. Переключение к новой последовательности происходит естественным образом, в результате переполнения регистра-счетчика. Для того чтобы сброс счетчика произошел раньше, следует отдельно
^1рямеры реализации схем на базе ПЛИС 281 проверить условие достижения максимального значения, как показано ниже. architecture Behavioral of counter is ., локальное объявление сигнала для счетчика signal cnt : std_logic_vector G downto 0); begin process(clk) begin if rising_edge(clk) then if (cnt = 99) then cnt <= (others => '0'); else cnt <= cnt + 1; end if; end if; end process; end Behavioral ; В примере используется условие, которое явно выбирает одно из действий — сброс счетчика или прибавление к нему 1. Показанный ниже вариант приведет к ошибке в ISE, но будет корректно обработан в синтезаторе Vivado. - синтезируемый в Vivado вариант счетчика architecture Behavioral of counter is - локальное объявление сигнала для счетчика signal cnt : stdJogic.vector G downto 0); begin process(clk) begin if rising_edge(clk) then cnt <= cnt + 1; if (cnt = 99) then cnt <= (others => '0'); end if; end if; end process; end Behavioral ; Потенциальная проблема этого примера заключается в том, что прибавление 1 к счетчику происходит на каждом такте, а обнуление — при его равенстве 99. Поэтому при условии cnt = 99 будет сформировано два возможных значения — 100 (из-за строки cnt <= cnt -f 1) и 0 из-за выполнения условия сброса. Можно еще раз обратить внимание что операция cnt <= cnt -f 1 выполняется на каждом такте независимо от условий. Синтезатор ISE рассматривал такую ситуацию как ошибку — фактически из-за «короткого замыкания» Дьух выходов, которое, очевидно, блокируется синтезатором на этапе создания схемы. В то же время синтезатор Vivado синтезирует
282 Глав а б для представленного примера цепь синхронного сброса по условию cnt = 99 и использует для увеличения счетчика обычные входы данных. Вместе с тем необходимо отслеживать стиль описания сложных условий, поскольку в каких-то случаях синтезатор не сможет построить эквивалентную схему с разрешением всех схемотехнических конфликтов. Ш Синтезаторы последовательно совершенствуются и кор. ректно преобразуют некоторые схемы, формирующие потенциально проблемные ситуации в ПЛИС, Например конструкция if rising^edge(clk) and се = ili настоятельно не рекомендуется к применению, поскольку формировала gated clock — вентиль 2И, с помощью которого регулируется прохождение тактового сигнала, В результате такого приема сигнал начинает распространяться по обычным, а не выделенным линиям, что серьезно ухудшает характеристики проекта и даже стабильность само схемы. В то оюе время современные синтезаторы ХШпх преобразуют такие конструкции в сигналы се триггеров проекта или в сигналы се тактовых буферов. Это не означает, что общими рекомендациями мооюно пренебрегать, поскольку их исполнение практически гарантирует получение корректной схемы, не передавая решение этого вопроса на синтезатор. Для счетчиков используются следующие возможности: • разрешение счета; • регулируемое направление счета (up/down); • возможность сброса; • возможность загрузки. Счетчик с регулируемым направлением счета приведен в следующем примере: VHDL: architecture Behavioral of counter is — локальное объявление сигнала — для счетчика signal cnt : stdJogic.vector G downto 0); begin process(clk) begin if rising.edge(clk) then if up .down = T then cnt <= cnt 4- 1; else
>ации схем на базе ПЛИС 283 cnt <= cnt - 1; end if; end if; end process; end Behavioral ; Verilog: reg [7.0] cnt; always ©(posedge elk) if (up-down) cnt <= cnt + 1; else cnt <= cnt - 1; Счетчик имеет дополнительный управляющий вход up_down. Высокий логический уровень на этом входе означает счет на увеличение значения счетчика, а низкий — на уменьшение. Счетчик с загрузкой имеет дополнительные входы — разрешение загрузки и загружаемые данные. Бели на входе разрешения загрузки присутствует активный уровень, то счетчик принимает значение, заданное внешней шиной. Таким образом, с помощью этого интерфейса можно принудительно задать требуемое значение счетчика. Пример счетчика с синхронным сбросом и загрузкой: VHDL: architecture Behavioral of counter is - локальное объявление сигнала - для счетчика signal cnt : stdJogicvector G downto 0); begin process(clk) begin if rising-edge(clk) then if reset = 'Г then cnt <= (others => '0'); elsif load = '1' then cnt <= dan; else cnt <= cnt + 1; end if; end if; end process; e&d Behavioral ; Verilog: reg [7:0] cnt;
284 Глава б always ©(posedge elk) if (reset) cnt <= 0; else if (ce) if (load) cnt <= dJn; else cnt <= cnt + 1; Как и для остальных цифровых модулей на базе ПЛИС, рекомендуется использовать синхронный сброс вместо асинхронного. Двоичное кодирование является не единственно возможным алгоритмом работы счетчика. Вместо последовательного перебора двоичных значений в процессе работы возможно использование и других кодировок. Например, код Грея (Gray code) имеет то свойство, что для перехода к следующему значению достаточно изменить значение единственного разряда. Это полезно при обработке сигналов, в которых существует вероятность сдвига по времени между отдельными разрядами. Например, при переходе от двоичного состояния 0111 Gю) к 1000 (8ю) из-за неодновременной смены разрядов может появиться состояние 0000, 1111 (или любое другое в зависимости от порядка смены разрядов). В то же время подобный эффект при использовании кода Грея приведет к максимальной ошибке, равной 1. Пример реализации счетчика, основанного на коде Грея: parameter gray .width = 8; reg [gray _width-1:0] binary .value; reg [gray .width-1:0] gray .value; always @(posedge elk) if (reset) begin binary.value <= {{gray.width{l'bO}}, ГЬ1} ; gray .value <= {gray.width{l'bO}} ; end else if (ce) begin binary.value <= binary .value + 1; gray .value <= (binary.value >> 1) V binary.value; end Другой разновидностью кодирования является LFSR (Linear Feedback Shift Register) — сдвиговый регистр с линейной обратной связью. Пример 4-разрядного LFSR: reg [3:0] lfer; always ©(posedge elk) if (reset)
примеры реализации схем на базе ПЛИС 285 lfsr <= 4Ъ0; else if (ce) begin lfsr[3:l] <= lfsr[2:0]; lfsr[O] <= ~ V lfsr[4:3]; end Особенностью кодирования по LFSR является более быстрая смена состояний по сравнению с двоичным счетчиком, поскольку при двоичном кодировании возможна ситуация, когда прибавление единицы сменит все разряды, включая самый старший. На распространение бита переноса по всем разрядам двоичного счетчика тратится дополнительное время по сравнению со сдвиговыми регистрами, в которых каждый разряд получает свое значение от соседнего разряда. Вдвигаемое в LFSR значение определяется в строке lfsr[O] <= ~ V lfsr [4:3] и зависит от разрядности счетчика. Недостатком счетчика LFSR является меньшее число уникальных состояний по сравнению с двоичным счетчиком той же разрядности. 6.7. Делители частоты Делитель частоты представляет собой вариант счетчика, который выдает на выходе сигнал, частота которого в заданное число раз меньше, чем входная тактовая частота. VHDL: library IEEE; use IEEE.STD_LOGIC.1164.ALL; entity div_clk is Port (elk : in STD.LOGIC; clk_out : out STD.LOGIC); end div_clk; architecture Behavioral of div_clk is signal cnt : integer range 0 to 200 := 0; begin process(clk) begin if rising.edge(clk) then if cnt = 199 then cnt <= 0; else cnt <= cnt + 1; end if; end if; end process; c&-out <= >r when cnt = 0 else '0'; ebd Behavioral; Verilog:
286 Г л а в а б module div_clk( input elk, output clk_out ); reg [7:0] cnt; always @ (posedge elk) if (cnt == 199) cnt <= 0; else cnt <= cnt -f 1; assign elkjout = (cnt == 0) ? 1:0; endmodule В показанном делителе частоты используется внутренний счетчик с пределом счета 200 (счетчик может принимать значения от 0 до 199). Если достигнутое счетчиком значение уже равно 199, то следующий фронт тактового сигнала загружает значение 0, иначе значение увеличивается на 1. Выходной сигнал формируется асинхронно, путем проверки значения внутреннего счетчика на 0. Поскольку такое состояние наблюдается в течение только 1 периода тактового сигнала из каждых 200, выходная частота оказывается в 200 раз меньше входной. В представленном примере выход делителя будет формировать короткие импульсы длительностью 1/200 от общего периода выходной частоты. При необходимости получения импульсов с коэффициентом заполнения 50 % можно заменить выражение для clk.out на: VHDL: clk_out <= Т when cnt < 100 else '0'; Verilog: assign elkjout = (cnt < 100) ? 1 : 0; Сигнал, полученный с выхода такого делителя, не должен использоваться для тактирования других устройств ПЛИС. Его правильным использованием будет подключение к входу се других синхронных модулей, для которых он будет разрешать счет на один такт из N, тем самым и обеспечивая деление частоты на N. 6.8. Таймеры Таймер отличается от обычного счетчика наличием дополнительных возможностей по запуску, перезагрузке и останову. В примере показан простейший таймер, который обеспечивает задержку появления выходного сигнала на 200 тактов относительно появления входного сигнала reload. После достижения максимального значения таймер не повторяет цикл счета с нуля, а останавливается до появления сигнала reload. В таком режиме данное устройство может
ации схем на базе ПЛИС 287 ^пользоваться как сторожевой таймер {watchdog timer). Эта разновидность таймера предназначена для формирования предупреждений о том, что какое-то событие, вызывающее появление сиг- зала перезагрузки таймера, не происходило уже длительное время. Сторожевой таймер часто используется в микроконтроллерных системах управления, где его перезагрузка происходит в процессе выполнения программы. Отсутствие перезагрузки в течение времени, соответствующего полному циклу счета, свидетельствует о том, что микроконтроллер перестал периодически выполнять команды, приводящие к сбросу счетчика. Это, вероятнее всего, является следствием аппаратного или программного сбоя системы, и выход сторожевого таймера может использоваться как сигнал аппаратного сброса микроконтроллера или индикатор аварийного состояния системы. Пример таймера, сбрасываемого по сигналу reload и прекращающего счет при достижении заданного состояния, приведен ниже: VHDL: library IEEE; use IEEE.STDJjOGIC-1164.ALL; entity timer is Port (elk : in STDXOGIC; reload : in STD-LOGIC; timer_out : out STD-LOGIC); end timer; architecture Behavioral of timer is signal cnt : integer range 0 to 200 := 0; begin process(clk) begin if rismg-edge(clk) then if reload = T then cnt <= 0; elsif cnt < 199 then cnt <= cnt + 1; end if; end if; end process; timer.out <= '1' when cnt = 199 else '0'; end Behavioral; Verilog: module timer( input elk, input reload, output timer_out ); reg [7:0] cat;
288 ______ Глава б always @ (posedge elk) if (reload) cnt <= 0; else if (cnt < 199) cnt <= cnt + 1; assign timer_out = (cnt == 199) ? 1:0; endmodule У сторожевого таймера есть полезное применение, эффективно решающее достаточно важную проблему подавления «дребезга» механических кнопок. Это известная проблема в цифровой технике, заключающаяся в том, что механические кнопки, которые субъективно воспринимаются человеком как источники коротких (в масштабах человеческого восприятия) импульсов, на практике при нажатии и отпускании формируют пачку импульсов. Причиной такого поведения является неизбежное окисление контактов, приводящее к нестабильному соединению в первый момент касания. С точки зрения человека, процесс нажатия может занимать доли секунды, однако в масштабах цифровой системы может пройти от сотен до тысяч тактов системного генератора, прежде чем последовательность 0 и 1 перейдет в стабильное состояние. Поэтому использовать кнопку в качестве источника единичного импульса на практике невозможно. Некоторые схемы подавления дребезга обладают принципиальным недостатком — они ориентируются на вполне конкретные характеристики процесса переключения. Установка внешних RC- фильтров решает проблему только в частных случаях, поскольку даже при подборе номиналов для компонентов фильтра дальнейшие процессы окисления или просто особенности динамики нажатия кнопки приведут к тому, что процесс «дребезга» затянется и примененный фильтр перестанет надежно подавлять импульсы. То же относится и к цифровым схемам подавления «дребезга», построенным по принципу выявления коротких импульсов. Проблема заключается в том, что через некоторое время эксплуатации длительность таких импульсов вполне может измениться. Генератор импульсов, основанный на сторожевом таймере, является хорошим вариантом, способным формировать при нажатии кнопки один длинный импульс. При этом вход reload устанавливает выход в 1 и загружает счетчик начальным значением. Когда на входе reload присутствует логический 0, счетчик сторожевого таймера уменьшается вплоть до 0. При таком подходе короткие импульсы нуля на входе не будут успевать обнулять счетчик во время процессов «дребезга», а удержание кнопки будет приводить к перезагрузи максимального значения счетчика на каждом такте. Длительность счета должна быть выбрана заведомо большей длительности любого
примеры реализации схем на базе ПЛИС 289 процесса «дребезга» с запасом на ухудшение состояния контактов. На практике человек воспринимает в качестве однократных нажатия длительностью в десятые доли секунды. 6.9. Широтно-импульсная модуляция Широтно-импульсная модуляция (ШИМ, PWM — Pulse-Width Modulation) является эффективным способом цифрового управления силовыми системами. При этом регулирование мощности осуществляется путем управления отношением времени, в течение которого сигнал включен, ко времени, в течение которого он выключен. Такой способ управления обладает как минимум двумя достоинствами — он удобен для реализации в цифровой системе и является энергоэффективным, поскольку в ключевом режиме работы управляющий элемент потребляет минимальную мощность (в закрытом состоянии ток через него стремится к нулю, а в открытом стремится к нулю падение напряжения, поскольку сопротивление переключающих элементов стремятся уменьшить). - Модуль ШИМ разрабатывается следующим образом. Входной сигнал d задает число тактов, в течение которых следует удерживать высокий логический уровень на выходе модуля. Внутренний сигнал cnt циклически перебирает состояния от 0 до максимального значения, которое может быть подано в качестве входного. Допустим, что внутренний счетчик является 8-разрядным (т. е. полный цикл счета содержит 256 тактов). Тогда при подаче на вход числа 10 на выходе такого модуля будет логическая единица в течение 10 тактов, а в течение остальных 246 — логический ноль. Увеличивая значение числа, поданного на вход d, можно увеличивать отношение времени включения выходного сигнала к общему времени цикла счета. VHDL: library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity pwm is port(clk : in STD_LOGIC; d : in STD-LOGIC.VBCTORG downto 0); pwm_out : out STD.LOGIC); eild pwm; architecture Behavioral of timer is signal cnt : std_logic_vectorG downto 0) := x0"; begin process(clk) begin if rising_edge(clk) then
290 Глав, cnt <= cnt 4- 1; end if; end process; pwm_out <= 'Г when d > cnt else '0'; end Behavioral; Verilog: module pwm( input elk, input [7:0] d, output pwm reg [7:0] cnt = 0; always @ (posedge elk) cnt <= cnt + 1; assign pwm = (d > cnt) ? 1:0; endmodule Для демонстрации работы созданного модуля используется следующая тестовая последовательность: формируется тактовый сигнал с периодом 20 не и на вход данных подается фиксированное значение 100до. Тестовый модуль pwmjfcb показан ниже: Verilog: module pwm.tb; // Inputs reg elk; reg [7:0] d; // Outputs wire pwm; // Instantiate the Unit Under Test (UUT) pwm uut ( xlk(clk), .pwm(pwm) ); initial begin // Initialize Inputs elk = 0; d = 100; forever elk = #10 ~ elk; end endmodule Временные диаграммы работы модуля в соответствии с поданными тестовыми последовательностями показаны на рис. 6.2. Для получения периода сигнала ШИМ, не равного целой степени двойки, следует обеспечить изменение счетчика в диапазоне
ярймеры реализации схем на базе ПЛИС 291 Рис. 6.2. Временные диаграммы работы модуля ШИМ оТ о до необходимого максимального значения. Можно использовать сигнал типа integer для обеспечения большей наглядности кода. В показанном примере счетчик принимает значения от 0 до 99. process(clk) begin if rising.edge(clk) then if cnt = 99 then cnt <= 0; else cnt <= cnt + 1; end if; end process; 6.10. Модули памяти Память является важным и часто используемым элементом современных цифровых устройств. Она представляет собой массив однотипных ячеек, хранящих число фиксированной разрядности. По характеру выполняемых с ней операций память подразделяется на: • постоянные запоминающие устройства (ПЗУ, ROM — Read-Only Memory), которые хранят фиксированные данные без возможности их изменения; • оперативные запоминающие устройства (ОЗУ, RAM — Random Access Memory), допускающие изменение записанных данных. С точки зрения технической реализации память также имеет смысл подразделять на энергозависимую (сохраняющую данные только при поданном питании) и энергонезависимую. Для ранних вариантов исполнения энергонезависимая память являлась практически синонимом ПЗУ, поскольку техническая реализация таких микросхем подразумевала хранение данных в ячейках с пережигаемыми перемычками, ультрафиолетовым стиранием и т. п. Все эти принципы исполнения обеспечивали сохранность данных при отключении питания, но и не позволяли изменять содержимое памяти без специального оборудования — например, память с ультрафиолетовым стиранием требовала, как следует из ее названия, источника УФ излучения для стирания данных и специального программатора. В настоящее время существуют устройства энергонезависимой памяти, которые допускают изменение содержимого без специального программатора. Например, flash-память, память с электрическим стиранием, память FRAM, другие перспективные типы памяти. Часть из них требует отдельного цикла стирания, а часть позволяет произвольно перезаписывать данные, как для микросхем ОЗУ.
292 Глав а б аC:0) dG:0) По способу организации интерфейса Ь модули памяти подразделяются на моду. ли с асинхронным или синхронным Итт Рис. 6.3. Графическое изо- , .*. ^ йй* бражение модуля памяти с терфейсом, а также с параллельным ила асинхронным интерфейсом последовательным доступом. Наиболее простой вариант — память с параллельным асинхронным доступом. Графическое изображение такого модуля показано на рис. 6.3. Постоянное запоминающее устройство с асинхронным интерфейсом может быть описано с помощью оператора case. VHDL: library IEEE; use IEEE.STD_LOGICL1164.ALL; entity rom is Port (a : in STDXOGIC_VECTOR C downto 0); d : out STDXOGIC.VECTOR G downto 0)); end rom; architecture Behavioral of rom is begin process(a) begin case a is when 000" => d <= 0000001"; when 001" => d <= 0000011"; when 010" => d <= 0000100"; when others => d <= (others => '0'); end case; end process; end Behavioral; Verilog: module rom( input [3:0] a, output [7:0] d ); reg [7:0] data; always @(a) case (a) 0 : data <= 1; 1 : data <= 3; 2 : data <= 4; default : data <= 0; endcase assign d = data; endmodule
ализации схем на базе ПЛИС 293 При описании асинхронного ПЗУ с помощью оператора case используются строки вида <addr> : <data> — для каждого варианта адреса записывается то значение, которое хранится по этому адресу. 1^ожно заметить, что при таком подходе сложно описать массивы памяти большого объема без применения средств автоматизации. В ПЛИС модули ПЗУ небольшого объема обычно реализуются на базе логических генераторов программируемых ячеек. Ячейка с 6 входами (Virtex-5/6/7, Kintex-7, Spartan-6, Artix-7) может хранить 64 бита, а с 4 — 16 битов. Необходимо иметь в виду, что из-за реализации в виде мелких блоков память на базе программируемых ячеек не может обеспечить высокие характеристики производительности. Синхронный интерфейс памяти обеспечивает более высокую производительность, поэтому память такого вида используется чаще. Блочная память, размещаемая в FPGA, является памятью с синхронным интерфейсом. Отличием такого типа интерфейса является выполнение всех действий по фронту тактового сигнала. Для памяти с возможностью чтения и записи (ОЗУ) используются следующие дополнительные сигналы: • din — данные для записи; • we — разрешение записи (Write Enable). Память такого типа работает следующим образом: если по фронту тактового сигнала активен сигнал we, то производится запись данных din в ячейку памяти с адресом addr. Иначе производится чтение из памяти, и на выходе dout появляется содержимое ячейки памяти с адресом addr. Пример описания памяти с произвольным доступом с синхронным интерфейсом. VHDL: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC.STD.ALL; entity ram is Port (elk : in STD.LOGIC; addr : in STD_LOGIC_VECTOR G downto 0); din : in STD_LOGIC_VECTOR A5 downto 0); we : in STDJLOGIC; dout : out STD_LOGIC_VECTOR A5 downto 0)); end ram; architecture Behavioral of ram is type TRamArray is array@ to 255) of std_logic_vectorA5 downto 0); signal ram_array : TRamArray := (others => (others => '0')); begin process(clk) begin
294 Глава if risingjedge(clk) then if we = T then ram^array(to_integer(unsigned(acidr))) <= din; end if; dout <= ram_array(toJnteger(unsigned(addr))); end if; end process; end Behavioral; Verilog: module ram( input elk, input [7:0] addr, input [15:0] din, input we, output reg [15:0] dout ); reg [15:0] гапьаггау [7:0]; // Необязательная инициализация // initial // $readmemh("filejiamen, гапьаггау, // <begin^addr>, <end>addr>); always @(posedge elk) begin if (we) begin ram^array[addr] <= din; end dout = ram^array[addr]; end endmodule в в «^ ram elk doutA5:0) we adrG:0) dinA5:0) Рис. 6.4. Графическое Графическое изображение модуля показано на рис. 6.4. Из описания порядка работы модуля ОЗУ виден его недостаток, проявляющийся в том, что при записи в память невозможно одновременно читать ее содержи- изображение модуля ОЗУ с мое. Например, при использовании бло- синхронным интерфейсом ка памяти ддя хранения таблицы значе- ний, непрерывно выдаваемых на цифро-аналоговый преобразователь, устройство отображения информации или на иное устройство, требующее непрерывного потока данных, возникнет проблема, связанная с тем, что для обновления содержимого памяти придется прервать процесс чтения записанных в нее данных. От этого недостатка свободны многопортовые модули памяти, которые позволяют
ализации схем на базе ПЛИС 295 06ращаться к одному и тому же массиву ячеек с помощью нескольких наборов линий addr, din, we и имеют соответствующее число р^нсодных шин dout. Простейшим вариантом многопортовой памя- тц является двухпортовая (dual-port memory), которая имеет достаточно много разновидностей. По функциональным возможностям второго порта двухпортовая память подразделяется на simple dual- port или pseudo dual-port (простая двухпортовая или псевдодвухпортовая память) и true dual-port (истинно двухпортовая память). Их отличием является то, что память true dual-port имеет два независимых и равноправных порта, по каждому из которых возможно проведение операций чтения и записи. У памяти simple dual-port один порт является универсальным (чтение и запись), а второй — только для чтения. Память такого типа вполне может быть использована в проектах, где требуется обеспечение непрерывного потока читаемых данных. В этом случае при необходимости перезаписи используется универсальный порт, а второй и используется для постоянного считывания. Графическое изображение simple dual-port памяти показано на рис. 6.5. Логические генераторы программируемых ячеек FPGA представляют собой массивы статической памяти, хранящие таблицы истинности. Поэтому они могут быть использованы и в качестве модулей памяти, являясь при этом simple dual-port памятью. Такая память в терминологии FPGA называется также распределенной (distributed), поскольку распределена по программируемым ячейкам. Блочная память, размещаемая в FPGA, является true dual-port («истинно двухпортовая память»). Графическое изображение аппаратного примитива, представляющего собой наиболее полный вариант интерфейса, показано на рис. 6.6. Блок памяти имеет следующие порты: • addra, addrb — адреса портов А и В соответственно; • dia, dib — данные для записи для портов А и В C2 бита); • dipa, dipb — дополнительные данные для записи D бита); • wea, web — входы разрешения записи (побайтно); • clka, clkb — тактовые сигналы для портов; • ena, enb — входы разрешения работы блока памяти (при чтении состояние выходов не обновляется, если нет разрешающего сигнала); • regcea, regceb — разрешение работы выходных регистров; • rsta, rstb — сброс выходных регистров (не влияет на содержимое массивов памяти);
296 Гла; rambl6bwer RAM16X1D WE D t>WCLK АО Al A2 A3 DPRAO DPRA1 DPRA2 DPRA3 SPO DPO Рис. 6.5. Двупортовая память в конфигурации simple dual-port, построенная на базе логической ячейки FPGA ADDRAA3:0) DOAC1:0) ADDRBA3:0) DIAC1:0) DIBC1:0) DIPAC:0) DIPBC:0) DOBC1:0) WEAC:0) WEBC:0) CLKA CLKB ENA DOPAC:0) ENB REGCEA REGCEB RSTA RSTB DOPBC:0) Рис. 6.6. Графическое изображение аппаратного блока памяти • doa, dob — выходы данных для портов А и В C2 бита); • dopa, dopb — дополнительные выходы данных для портов А и В D бита). Физически размещенные в PPGA блоки памяти являются 18- битовыми. Такая разрядность позволяет реализовывать схемы контроля четности, когда каждые 8 бит имеют дополнительный 9-й бит для хранения бита четности. Соответственно, каждые 16 битов имеют 2 дополнительных бита четности, а 32 — 4 бита. Для удобства работы с дополнительными битами в графическом представлении модуля они выделены в отдельные шины dipa, dipb, dopa, dopb. Дополнительные биты не являются автоматически заполняемыми и представляют собой разряды, доступные для записи в них произвольных значений. Разработчик может выбирать требуемую ему разрядность, включая 9, 18 или 36 битов. Блочная память является эффективным аппаратным ресурсом, который допускает работу на системной тактовой частоте. Это максимальная тактовая частота, на которой теоретически мог бы работать проект, если бы он не содержал цепей комбинационной логики, проходящих более чем через один логический генератор, # слишком длинных трассировочных цепей. На практике работа на системной тактовой частоте оказывается доступной только для относительно компактных фрагментов проекта, и важно, что блочная
ации схем на базе ПЛИС 297 не ухудшает эти параметры. Следует также иметь в виду, удельная стоимость блочной памяти ниже, чем памяти того же 06ъема, реализованной на логических ячейках. Сложно указать точную границу объема, превышение которой делает блочную память однозначно более эффективным решением, однако можно ориентироваться на технические характеристики разных устройств A6x1 или 64x1 бит в логическом генераторе, 1024x18 битов в блоке памяти), а конкретный способ реализации памяти выбирать, исходя из доступных ресурсов проекта и требуемых технических характеристик. Для принудительного использования заданного ресурса может потребоваться component instantiating, поскольку синтезаторы для ПЛИС при использовании автоматических настроек выбирают способ реализации памяти (блочная или распределенная) исходя из ее размера и режима работы (для true dual-port возможна реализация только в блочной памяти). Приложение Core Generator входит в состав САПР ПЛИС ISE фирмы Xilinx и предлагает разработчику графический интерфейс быстрого конфигурирования стандартных цифровых блоков для реализации их в ПЛИС (IP-ядер). С помощью Core Generator имеется возможность создания шаблонов на языке Verilog, которые потом будут использованы как instance (см. component instantiation) в проектах пользователя. Генерация компонентов с помощью Core Generator обладает рядом преимуществ: • IP-ядра, как правило, представляют собой верифицированные компоненты, имеющие качественное размещение на кристалле, и вследствие этого способные работать на высокой тактовой частоте; • ряд специфичных ресурсов ПЛИС, например модули формирования тактовой частоты, достаточно сложны для освоения, однако вносят в проект полезные функциональные возможности, поэтому рекомендуются к использованию; соответственно, Core Generator предоставляет возможности для их быстрого конфигурирования с последующим добавлением к проекту. Динамическая память типа DDR (DDR2, DDR3, DDR4) может использована совместно с ПЛИС. Для автоматической генерации контроллера такой памяти используется IP-ядро Memory Inter- fece Generator (MIG). Динамическая память существенно отличается От статической и в общем случае не позволяет работать по принципу <<3адание адреса — получение данных». Использование динамически памяти в проектах требует отдельного рассмотрения и глубокого
298 Гла. изучения принципов ее работы. Удобно использовать динамическую память совместно с софт-процессором MicroBlaze или аппаратные ядром ARM. 6.11. Конечный автомат Конечный автомат (КА, он же FSM, Finite State Machine) — это довольно эффективный по многим показателям подход к описанию работы схемы с несколькими состояниями. Под конечным автоматом понимается схема, число внутренних состояний которой конечно. Такая схема может формировать одинаковые выходные сигналы при нахождении в нескольких состояниях однако обратное не гарантируется. С помощью конечных автоматов можно описывать работу устройств самого разного типа. Например, на рис. 6.7 показан граф, описывающий работу конечного автомата для управления продажей кофе. Представим, что у кофейного аппарата есть датчики опускания монет Rubl и Rub2, реагирующие на попадание соответствующих монет в монетоприемник. Также есть кнопка Ret, управляющая возвратом сдачи. У автомата есть возможность сварить кофе и выдать сдачу монетой в 1 рубль. Примем, что для этого достаточно установить в 1 соответствующие сигналы управления. На схеме работа начинается с состояния Start. В этом состоянии возможно срабатывание датчиков Rubl и Rub2. Нажатие на кнопку «сдача» игнорируется. Видно, что из состояния Start выходят две дуги графа, над которыми указаны соответствующие условия. Фрагмент КА можно описать кодом: process(clk) begin if risingjedge(clk) then cause st is when start => if Rub2 = '1' then state <= Coffee; end if; if Rubl = 'I1 then state <= Half; Рис. 6.7. Представление работы конечного автомата в виде графа
изации схем на базе ПЛИС 299 end if; when ... when Coffee_with_ret => state <= Start; end if; end process; Из примера видно, что по представлению в виде графа можно сопоставить каждому узлу графа состояние КА. Дуги, выходящие яз узлов, описываются условиями перехода. Если переход происходит безусловно, на следующем такте автомат принимает следующее состояние, как показано для примера перехода из состояния «кофе и возврат сдачи» в состояние «старт». На уровне графового представления можно отслеживать важные ошибки проектирования КА — наличие тупиковых и недостижимых состояний. Как можно понять из названия, после попадания в тупиковое состояние КА больше не выходит из него, а для недостижимого состояния нет ни одного условия, приводящего в него. При анализе графового представления можно легко выявить такие состояния, поскольку для них нет либо выходящих дуг (тупиковые), либо входящих (недостижимые). Часто представление работы конечного автомата в виде графа можно получить в качестве описания работы устройства или технического задания на разработку, поскольку оно доступно для разработки широкому кругу специалистов в смежных областях. Структурная схема, реализующая конечный автомат показана на рис. 6.8. На этом рисунке все переменные состояния сгруппированы в регистре REG. Узлы, показанные в виде овалов, содержат некоторую комбинационную логику, конкретная схема которой в данном случае неважна. Важнее то, что рисунок демонстрирует порядок работы КА — на каждом новом такте группы регистров REG принимает какое-то другое состояние, которое зависит от предыдущего состояния и набора входных сигналов. В качестве простого практического примера можно рассмотреть конечный автомат, управляющий светофором. Порядок работы светофора хорошо известен, а смена цветов выполняется строго в одном и том же порядке. Поэтому для него можно использовать простейший КА с линейным порядком смены состояний. Ниже показан Входы Выходы Логика формирования выходов Рис. 6.8. Конечный автомат
300 Глава q листинг на языке описания аппаратуры VHDL, который описывает схему управления цветами светофора. Автомат работает следующим образом. Переменная состояния st (от state — «состояние») изменяется линейно от 0 до 23, формируя таким образом 24 состояния светофора. В состояниях 0-9 горит красный сигнал, далее добавляется желтый на состояния 10-11. Состояния 12-17 соответствуют горящему зеленому, далее в течение 4 состояний формируется его мигание. Завершающие состояния 22-23 соответствуют включенному желтому сигналу. library IEEE; use IEEE.STD_LOGICL1164.ALL; entity fsm is Port (elk : in STDXOGIC; reset : in STD.LOGIC; red : out STD-LOGIC; yellow : out STDJ.OGIC; green : out STDJL.OGIC); end fsm; architecture Behavioral of fsm is signal st : integer range 0 to 23 := 0; begin process(clk) begin if rising_edge(clk) then if reset = T then st <= 0; else case st is when 0 to 9 => red <= 'I1; yellow <= '0'; green <= '0'; st <= st + 1; when 10 to 11 => yellow <= T; st <= st + 1; when 12 to 17 => red <= '0'; yellow <= '0'; green <= T; st <= st + 1; when 18 => green <= '0'; st <= st + 1; when 19 => green <= '1'; st <= st + 1; when 20 => green <= '0J; st <= st + 1; when 21 => green <= '1'; st <= st + 1; when 22 => yellow <= '1'; green <= J0';
ации схем на базе ПЛИС 301 st <= st + 1; when 23 => st <= 0; when others => null; end case; end if; end if; end process; end Behavioral; Листинг. Конечный автомат, реализующий управление сигналами светофора Временные диаграммы работы такого КА показаны на рис. 6.9. Можно пронаблюдать поведение выходных сигналов red, yellow, green и убедиться, что они соответствуют хорошо известному порядку переключения цветов светофора. Простота данного примера служит единственной цели — дать возможность сопоставить поведение выходных сигналов и их описание в КА. Можно убедиться, что описание целиком укладывается в единственный оператор case. При необходимости можно изменить порядок работы, добавить или убрать состояния, ввести дополнительные сигналы (например, запрос на включение пешеходного светофора). Регулярность описания К А и простота его изменения и сопровождения весьма полезны на практике и позволяют не только быстро реализовать схему с требуемым поведением, но и оперативно отслеживать ее корректность, вносить изменения и проводить моделирование и отладку. Рассмотрение работы конечного автомата выявляет важную особенность — для изменения формы выходных сигналов требуется изменение его схемы. С учетом высокой стоимости изготовления заказных микросхем практически нереально создавать конечные автоматы с жестко заданным порядком работы для решения каждой частной задачи. В то же время видно, что формирование выходных сигналов осуществляется довольно регулярным способом — на основе анализа состояния автомата. elk red yellow green 0 не 1Ш1Ш1ЛШШ 100 не ..,, I,.., ШШШ1Ш1ЛШ j П _i и 200 не 11111,11 ¦ шшшшшш 1 п in 300 нс ШШШШШШ 1 п 1— 400 нс 1 1 1 1 1 1 1 1 1 шшшшллм [ п ~1ЛЛ_ Рис. 6.9. Временные диаграммы работы конечного автомата
302 Гла в а 6.11.1. Конечные автоматы Мили и Мура Существуют две основные разновидности конечных автоматов называемые автоматами Мили (Mealy) и Мура (Moore). Их основ-! ное отличие заключается в том, что значения выходных сигналов для автомата Мили зависят и от состояния автомата, и от значений входных сигналов, а для автомата Мура — только от состояния автомата. Эту разницу иллюстрирует рис. 6.10. На первый взгляд, разница между этими автоматами несущественна и заключается в одной дополнительной связи — между входными и выходными сигналами (на рис. 6.10 она показана жирной линией). Автомат Мили превращается в автомат Мура при отсутствии прямой связи между входами и выходами. Однако недостаток автомата Мили с точки зрения цифровой схемотехники заключается именно в этой прямой связи. Сквозное прохождение сигналов через ПЛИС имеет большую задержку распространения сигнала, а в автомате Мура входные сигналы приходят в конечном итоге в группу регистров, хранящую состояние автомата. Поэтому в целом автомат Мура может рассчитывать на более высокую производительность. Положительно влияет на производительность конечного автомата и конвейеризация входных и выходных сигналов (в любых сочетаниях). Вели в исходной схеме выход регистров состояния через логику формирования выходов должен быть подан на выходы ПЛИС, то при синтезе возможная задержка будет оценена без учета реального размещения этих выходов относительно регистров состояния. Алгоритмы размещения могут оказаться в достаточно сложном положении, поскольку регистры состояния должны быть достаточно близко и к входным сигналам (входы автомата подключаются к регистрам через комбинационную логику изменения состояния), Входы Выходы Логика изменения состояния Логика формирования выходов Reg (состояние) Логика изменения состояния Логика формирования выходов Reg (состояние) Рис. 6.10. Конечные автоматы Мура (а) и Мили (б)
реализации схем на базе ПЛИС 303 й я выходным сигналам. Размещение дополнительных регистров облегчает достижение высоких тактовых частот, однако вносит дополнительную латентность. Латентность (latency), т. е. дополнительная задержка в тактах на прохождение сигнала по цепи обработки данных, может оказаться неприемлемой для многих устройств. Однако можно указать и множество вариантов, когда дополнительные регистры на пути входных или выходных данных не влияют на принципиальную работоспособность схемы. Например, если речь идет о механических переключателях или кнопках, то момент распознавания автоматом их срабатывания совершенно неважен. Поскольку реакция человека оценивается в доли секунды, лишние десятки наносекунд, обусловленные прохождением сигнала от кнопки через один или несколько регистров, очевидно не будут замечены при наблюдении за работой устройства. Аналогично сигнальные светодиоды могут срабатывать на несколько тактов позже. Электрические моторы также обладают инерцией, на порядки больше периода тактовой частоты проекта на ПЛИС, поэтому управляющие сигналы для них также могут быть конвейеризованы. 6.11.2. Особенности описания конечных автоматов для проектов в ПЛИС Конечные автоматы хорошо подходят для их реализации в ПЛИС. Их общая структура вполне соответствует логическим ячейкам — состояние КА хранится в триггерах, а логика изменения состояния и формирования выходов реализуется в LUT. Кроме того, описание К А вполне регулярно, удобно для сопровождения и отладки часто может быть получено из описания задачи. Синтезаторы ПЛИС (и в ISE, и в Vivado) обладают развитыми возможностями выявления шаблонов конечных автоматов и способны создавать оптимальные схемы для их реализации с учетом- архитектуры ПЛИС. Существует целый ряд рекомендаций по RTL- описанию конечных автоматов, нацеленных на эффективное использование возможностей синтезаторов. Конечные автоматы могут использовать несколько схем кодирования состояний. Очевидной является двоичное кодирование, при котором каждому состоянию приписывается номер, представляемый в Двоичном коде. Для N-разрядного регистра возможно представление 2N состояний автомата, поэтому такой способ не только очевиден, но и наиболее эффективно использует триггеры ПЛИС. С другой стороны, для проверки того, что К А находится в определенном состоянии, потребуется проверить N-разрядное число. Та-
304 Глава б кая проверка заложена в операторе case, для каждой ветки необхода, мо проверить регистр состояния на равенство некоторой константе Одним из альтернативных вариантов является так называемое one-hot кодирование. Из названия one-hot видно, что при таком кодировании только один разряд регистра состояния равен 1. Такщ* образом, в N разрядах можно закодировать только N состояний. По сравнению с двоичным кодированием это приведет к расточительному использованию триггеров ПЛИС, поскольку при двоичном кодировании для 256 состояний потребуется 8 триггеров, а для one-hot — 256 триггеров. Однако для проверки каждой из веток оператора case достаточно проверить только один триггер. Преимущество one-hot кодирования проявляются при небольшом числе состояний КА. В этом случае рост числа триггеров еще не так существенен, но уже имеется эффект от простой проверки состояния. Другими вариантами кодирования являются LFSR, счетчик Джонсона или сдвиговый регистр с определенным кодом, не повторяющимся при сдвиге. Такие способы кодирования могут быть эффективны, например, при наличии в КА большого числа последовательных переключений. Синтезаторы компании ХШпх имеют режима автоматического выбора кодирования конечных автоматов. Достаточно установить соответствующую настройку в Auto, чтобы был подобран оптимальный способ кодирования состояний К А (или задать этот способ принудительно). Для облегчения идентификации описания КА рекомендуется использовать для его состояний не явно задаваемые константы, а перечислимые (enumerated) типы, как показано в примере. type TMyState is (INIT, WORK, STOP, PAUSE); signal state, nextjstate : TMYState; nextjstate <= INIT; Применение перечислимых типов позволяет синтезатору подобрать оптимальный способ кодирования состояний. Кроме того, перечислимые типы и символические обозначения состояний облегчают отладку и сопровождение КА. Можно воспользоваться полезным приемом под названием «мультипроцессное описание КА». В примере, показанном выше, все описание по сути было сведено к одному оператору case, в отдельных ветках которого описывались все действия, выполняемые
ации схем на базе ПЛИС 305 з конкретном состоянии. При возрастании сложности автомата его работу можно разделить на три процесса: • процесс назначения состояния; • процесс декодирования входных сигналов и определения нового состояния; • процесс назначения выходных сигналов. Процесс назначения состояния является наиболее простым. Его буквальный вид показан в следующем листинге, process(clk) begin if rising_edge(clk) then if reset = T then state <= INIT; else state <= nextjstate; end if; end if; end process; Листинг. Описание процесса назначения состояния КА Можно еще раз указать, что данный листинг является не общим примером, а действительным кодом, применимым для большинства трехпроцессных описаний. В процессе описан сигнал сброса, по которому автомат переходит в начальное состояние (INIT), иначе переменная состояния state принимает значение next_state. Если синтезировать это описание без дополнительных схем, можно убедиться в получении компактной схемы (состоящей практически только из триггеров логических ячеек), способной работать на высокой тактовой частоте. Главная проблема, которую видно из приведенного описания — отсутствие управления сигналом next_state. Очевидно, что этот сигнал должен принимать разные значения в зависимости от текущего состояния и входных сигналов. Логику управления этим сигналом можно сгруппировать во втором процессе: - это НЕ синхронный процесс! process(state, inl, in2, <другие входы>) case state is when INIT => if inl = ... nextjstate <= ... when STATE1 => nextjstate <= ... end case; Листинг. Процесс определения нового состояния Можно заметить, что здесь описывается комбинационная логика, т.е. не используется выражение if rising_edge(clk). Несмотря на то что процессы часто ассоциируются именно с синхронными операциями, это не является обязательным. В данном случае ключевое
306 Г л а in2 ^ftocess(clk) "^\ v^statc <= next_jtate^/ >^next__state Reg state (state,inl , слово process позволяет зовать такие удобные операторы как case и if. В каждой Beis ке необходимо определить, какое значение примет сигнал nextjstate. В сочетании с предыдущим процессом образуется устройство, которое способно переключаться между состоя- ниями в соответствии с подан- ными ВХОДНЫМИ сигналами. На РИС. 6.11 МОЖНО увидеть взаи- Рис. 6.11. Взаимодействие про- цессов назначения состояния и определения нового состояния модействие уже описанных процессов. Процесс назначения состояния, описанный первым, совершенно не изменился и по-прежнему на каждом такте выполняет присваивание state <= next_state. Определение нового значения next jstate полностью сконцентрировано во втором процессе. После завершения описания сигнала next jstate остается еще одна задача — описать состояния выходов КА в зависимости от его состояния и значения входов. Для машины Мура имеет значение только состояние автомата. Пример такого процесса приведен ниже: — это НЕ синхронный процесс! process(state, inl, in2, <другие входы>) - для автомата Мура: process(state) case state is when INIT => outl <= ... out2 <= ... when STATE1 => outl <= ... out2 <= ... end case; Листинг. Процесс назначения выходных сигналов Это также процесс, описывающий комбинационную логику. Для каждого из состояний необходимо определить каждый из выходных сигналов, используемых в К А, во избежание синтеза защелки (latch). Режим latch является возможным режимов работы триггера (flip-flop) и в принципе может использоваться в схемах. Однако незавершенное описание сигналов приведет к тому, что при переключении в состояние, для которого нет явного назначения выхода, этот выход останется в предыдущем состоянии. Однако для этого следует иметь возможность запомнить предыдущее состояние, для чего и будет синтезирован специальный режим «защелка». Сама по себе защелка не является катастрофически неверным решением, оД" нако ее появление свидетельствует о том, что КА синтезирован не в полном соответствии с замыслом разработчика.
примеры реализации схем на базе ПЛИС 307 case state is when STATE1 => outl <= '1'; out2 <= '0'; when STATE2 => out2 <= T; — нет сигнала outl end case; дистинг. Незавершенное описание процесса, приводящее к синтезу защелки ддя сигнала outl Использование многопроцессного описания конечного автомата может способствовать регулярному представлению текста и своевременному выявлению неточностей в описании. Кроме того, при оптимизации проекта для конкретного семейства ПЛИС может потребоваться выделение критических путей со слишком сложной комбинационной логикой и их структурная оптимизация. Это проще сделать, имея локализованное описание комбинационной логики, сконцентрированной в отдельном процессе. В целом конечные автоматы являются полезным инструментом проектирования многих узлов цифровой электроники. Они сочетают известные методики проектирования и хорошее соответствие структуре программируемых компонентов FPGA. 6.12. Контроллер UART Аббревиатура UART обозначает Universal Asynchronous Receiver-Transmitter — универсальный асинхронный приемопередатчик. Этот термин относится к аппаратному устройству, реализующему обмен данными. Физическая передача данных может производиться с помощью различных электрических стандартов, например, RS- 232, RS-485 и др. RS-232 долгое время был стандартным последовательным интерфейсом для PC. Сопряжение устройства на базе ПЛИС с ЭВМ, выполненное без дополнительных внешних устройств (за исключением преобразователя уровней, таких как МАХ232 или ADM232) позволяет подключить созданное устройство к настольному компьютеру. Даже с учетом того, что физические порты RS-232 в настоящее время сложно найти на материнских платах (и практически невозможно в ноутбуках), существует множество преобразователей типа USB-UART, BlueTooth-UART, Ethernet-UART и др. Кроме того, разработка контроллера RS-232 позволяет продемонстрировать Довольно эффективный прием проектирования на VHDL — реализацию конечных автоматов для описания несложных протоколов обмена данными. Для асинхронной передачи по интерфейсу RS-232 достаточно всего двух сигнальных линий — TxD (Transmit Data) и RxD (Receive
308 -Глава б Стартовый бит Dl D2 D3 D4 D5 D6 D7 I—i гН—1 гЧ Ь- ¦+¦ ¦+¦ Столовый бит Бит четности Рис. 6.12. Передача данных по протоколу RS-232 Data). Для электрического сопряжения сигналов потребуются стандартные устройства преобразования уровней RS-232 (лежащих в диапазоне —12. ..-fl2 В) в логические уровни ТТЛ/КМОП. После преобразования к выводам ПЛИС окажутся подключены два сигнала, которые можно обозначить как гх и tx. Протокол передачи UART представлен на рис. 6.12. Передача начинается установкой низкого логического уровня на входе приемника. Низкий уровень сохраняется на время длительности одного бита, который называется стартовым. Далее передаются биты данных (число которых зависит от настроек протокола). В последовательных портах PC передача начинается с младшего бита. После передачи последнего бита данных вводится бит четности, формируемый по позитивной или негативной четности в зависимости от настроек протокола. Теми же настройками передача бита четности может быть отключена. В завершение передается стоповый бит, после которого линия остается в состоянии логической единицы вплоть до следующей посылки данных. Асинхронный протокол передачи накладывает достаточно жесткие требования на стабильность интервалов времени, в течение которых передаются отдельные биты. Для повышения надежности передачи желателен прием отдельных битов возможно ближе к середине этих интервалов. С той же целью можно использовать довольно эффективный прием многократного считывания состояния линии с последующим подсчетом числа принятых нулей и единиц. При реализации приемника в ПЛИС необходимо в первую очередь решить проблему задания временных интервалов. Действительно, если длительность отдельных битов и может быть определена исходя из известных настроек протокола передачи, то ПЛИС, вообще говоря, не имеет собственного устройства отсчета временя. Следовательно, для синхронизации необходимо использовать внешний тактовый сигнал, причем его частота должна быть достаточно большой для обеспечения хорошего разрешения по времени. Наличие внешнего тактового сигнала и асинхронных сигналов, управляющих состоянием приемника, позволяют использовать технологию проектирования конечных автоматов. Под конечным ав-
Лрямеры реализации схем на базе ПЛИС 309 громатом понимается некое устройство, которое может находиться в фиксированном числе состояний, переходы между которыми совершаются при выполнении определенных условий. В ПЛИС внешний тактовый сигнал может быть эффективно использован для тактирования работы конечного автомата. Рассмотрим временную диаграмму приема данных по последовательному интерфейсу. Передача данных начинается со стартового бита, причем время ожидания в общем случае не определено. Разумным решением будет ввод в состав конечного автомата (далее К А) состояния «ожидание начала». Из этого состояния его может вывести появление логического нуля на входе данных гх, что мы и отметим. После выхода из этого состояния необходимо подождать начала передачи младшего бита данных. В терминах К А это означает последовательный переход между вспомогательными состояниями. Эти переходы будут происходить с частотой следования внешних тактовых импульсов, и их число (до середины младшего бита данных) определится длительностью стартового бита и половины длительности младшего бита данных. Длительности одного бита (стартового, стопового или данных) соответствует N тактов внешнего генератора. Следовательно, через N+N/2 тактов после начала стартового бита можно считывать младший бит данных, еще через N тактов — следующий бит и т. д. Всего до приема 8-го бита данных пройдет N + 7N + N/2 тактов внешнего генератора. Поставим в соответствие каждому такту некоторое состояние конечного автомата и запишем последовательность переходов между состояниями. Ожидание начала => Ожидание начала ИЛИ Стартовый бит Стартовый бит => перейти к считыванию бита данных О Вит данных 0 => перейти к считыванию бита данных 1 Вит данных 7 => формированию сигнала «принято» Принято => отключить сигнал «принято» и перейти к ожиданию начала Остальные случаи => переход к следующему состоянию При высокой частоте тактирования КА состояний оказывается довольно много. Однако ввиду простоты переходов между ними ^ожно ввести переменную st (от state — состояние), которая будет хранить номер состояния КА. Пересчитав число тактов (состояний) аа один бит, можно получить номера состояний, в которых необходимо запоминать 0-й, 1-й, 2-й и т. д. биты данных. Чтобы не рассчитывать эти номера вручную, удобно использовать параметризо- в&нное описание. Например, если определить в разделе entity два
310 Глав а б параметра, их можно использовать для расчета номеров состояний в процессе синтеза. generic (PCORE : integer := 50_000_000; UART.BAUDRATE : integer := 115200; signal rxstate : integer range 0 to A9 * FCORE / 2 / UART-BAUDRATE) := 0; process(clk) begin if rising.edge(clk) then case rxstate is when 0 to FCORE / 2 / UART.BAUDRATE => if rx = '0' then rxstate <= rxstate -f 1; end if; when 3 * FCORE / 2 / UART.BAUDRATE => received(O) <= rx; rxstate <= rxstate + 1; when 5 * FCORE / 2 / UART.BAUDRATE => received(l) <= rx; rxstate <= rxstate + 1; when 7 * FCORE / 2 / UARTJBAUDRATE => receivedB) <= rx; rxstate <= rxstate + 1; when 9 * FCORE / 2 / UART-BAUDRATE => receivedC) <= rx; rxstate <= rxstate + 1; when 11 * FCORE / 2 / UART_BAUDRATE => receivedD) <= rx; rxstate <= rxstate + 1; when 13 * FCORE / 2 / UARTJBAUDRATE => receivedE) <= rx; rxstate <= rxstate + 1; when 15 * FCORE / 2 / UART.BAUDRATE => receivedF) <= rx; rxstate <= rxstate + 1; when 17 * FCORE / 2 / UARTJBAUDRATE => receivedG) <= rx; rxstate <= rxstate + 1; when 19 * FCORE / 2 / UART-BAUDRATE => rxstate <= 0; rxcounter <= rxcounter + 1; when others => rxstate <= rxstate + 1; end case; end if; end process; Листинг. Описание конечного автомата, реализующего приемник UART
реализации схем на базе ПЛИС 311 Можно отметить, что выражения вида FCORE/2/UARTJ3AUD- RATE рассчитываются синтезатором и заменяются на соответствующие константы. Схема целочисленного деления при этом не синтезируется (и не занимает место в проекте), поскольку оба параметра известны в момент синтеза модуля. Автомат организован в виде линейной последовательности переходов, за исключением стартового и завершающего состояний. Из стартового состояния автомат приемника выводит условие гх = 'О', а после завершающего состояния автомат безусловно переходит в состояние 0, при этом увеличивается счетчик принятых символов rxcounter. Принятый символ записывается в регистр received. Аналогично можно описать передатчик UART. В качестве счетчика состояний используется сигнал txstate. Передаваемый символ содержится в transmit, а сигналом начала передачи является start_tx. signal txstate : integer range 0 to A1 * PCORB / UARTJBAUDRATB) := 0; process(clk) begin if rising_edge(clk) then case txstate is when 0 => tx <= T; if start.tx = T then txstate <= 1; end if, when 1 => tx <= '0'; txstate <= txstate + 1; when PCORB / UART.BAUDRATE => tx <= transmit@); txstate <= txstate + 1; when 2 * FCORE / UART_BAUDRATE => tx <= transmit A); txstate <= txstate + 1; when 3 * FCORE / UART.BAUDRATB => tx <= transmitB); txstate <= txstate + 1; when 4 * FCORB / UART_BAUDRATE => tx <= transmitC); txstate <= txstate + 1; when 5 * FCORE / UART.BAUDRATE => tx <= transmitD); txstate <= txstate + 1; when 6 * FCORE / UART.BAUDRATB => tx <= transmitE); txstate <= txstate + 1; when 7 * FCORE / UARTJ3AUDRATE => tx <= transmit F); txstate <= txstate + 1; when 8 * FCORE / UART.BAUDRATE => tx <= transmit G); txstate <= txstate + 1; when 9 * FCORE / UART.BAUDRATB =>
312 Глав а б tx <= T; txstate <= txstate -f 1; when 11 * FCORE / UART_BAUDRATE => txstate <= 0; when others => txstate <= txstate + 1; end case; end if; end process; Листинг. Описание конечного автомата, реализующего передатчик UART Интерфейс UART существует уже несколько десятилетий, од- нако его нельзя считать полностью устаревшим. Ввиду своей простоты его удобно использовать для преобразования более сложных интерфейсов, которые невозможно или просто нецелесообразно реализовать в ПЛИС. Например, существуют уже упомянутые выше преобразователи USB-UART, Ethernet-UART, BlueTooth-UART или WiFi-UART. Это дает возможность подключить разработанную плату к USB (Ethernet, ВТ...), но с точки зрения ПЛИС обмен данными будет производиться по линиям rx, tx. В качестве более простого примера рассмотрим USB. Как правило, такой обмен требует установки соответствующего драйвера на компьютер, в результате чего среди его устройств появляется виртуальный СОМ-порт. Физически он представляет собой устройство с интерфейсом USB, однако с появившимся портом можно выполнять те же операции, что и с физическом СОМ-портом. Формирование пакетов USB, их отсылка и обработка скрыты от программиста и не требуют внимания с его стороны. В качестве примеров таких микросхем можно привести продукцию компаний FTDI, Cypress и других (рис. 6.13, 6.14). Использование преобразователя xxx-UART является одним из простейших способов организовать связь между ПК и платой на базе Рис. 6.13. Плата преобразователя USB-UART на основе микросхемы FT232RL произ- Рис. 6.14. Плата преобразова- водства компании PTDI Chip теля BlueTooth-UART НС-Об
ализации схем на базе ПЛИС 313 ПЛИС Простота описания контроллера UART для ПЛИС позволяет быстро начать практическую работу с проектом и использовать зозможности ПК для реализации программ управления и ввода дан- йЬ1Х с датчиков, подключаемых к ПЛИС. 6.13. Тактовый генератор 6.13.1. Настройка тактового генератора Для получения качественного тактового сигнала с последующим его распространением по кристаллу ПЛИС настоятельно рекомендуется использовать модули формирования тактового сигнала. Они могут быть созданы с помощью IP-ядра. На рис. 6.15 показан процесс вызова генератора тактовых сигналов в САПР Vivado. IP- ядро генератора находится в разделе «FPGA Features and Design» в подгруппе «Clocking». После старта мастера создания IP-ядра необходимо указать параметры тактового генератора. Диалоговое окно содержит несколько вкладок, показанные на рис. 6.16 и 6.17. На рис. 6.16 видно, Рис. 6.15. Вызов мастера создания IP-ядра тактового генератора
314 Глав, Рис. 6.16. Настройка основных параметров тактового генератора что для серии 7 можно установить тип аппаратного примитива — ММСМ или PLL. Необходимо убедиться, что частота входного сигнала (Input Clock) соответствует реально поданной на генератор из внешнего источника. На вкладке Output Clocks настраиваются параметры выходных тактовых сигналов. В блоках ММСМ и PLL имеется несколько независимых выходов, которые включаются соответствующими элементами управления. Для каждого выхода устанавливается желаемая (Requested) частота. Модуль генератора проверит возможность получения именно этого значения и установит ближайшее возможное в поле Actual. Возможное отличие частот объясняется ограничениями блоков ММСМ и PLL на генерацию близких по значению частот. Не составляет труда получить 200 или 50 МГц при входной частоте 100 МГц, однако получить частоту 100,1 МГц не удастся.
ггрямерьг реализации схем на базе ПЛИС 315 Рис. 6.17. Настройка выходных частот Тактовый генератор может быть использован в проекте и без необходимости добавления IP-ядра с помощью подхода component instantiation. На рис. 6.18 показан способ добавить в описание на языке VHDL ссылки на компонент ММСМ. В окне редактировании файла значок с изображением лампочки накаливания служит для вызова справочной системы Language Templates. Шаблоны добавления аппаратных компонентов находятся в разделе Device Primitive Instantiation. На рис. 6.18 показан шаблон описания, которое необходимо скопировать в модуль на языке VHDL (или Verilog при вызове соответствующего раздела справочной системы) и заполнить шаблон параметрами и ссылками на подключаемые сигналы. Этот способ является более трудоемким, однако в ряде случае IP-ядро может оказаться неудобным для применения в несложном проекте.
316 Рис. 6.18. Добавление шаблона ссылки на компонент ММСМ 6.13.2. Формирование выходного тактового сигнала Семейство Spartan-б имеет некоторые ограничения по трассировке внутренних цепей. Они не являются критичными, однако не позволяют напрямую вывести тактовый сигнал на внешний вывод микросхемы. Вместо этого необходимо использовать прием, носящий название clock forwarding. Тактовый сигнал действительно нельзя подать непосредственно на выход ПЛИС, однако его можно подать на тактовый вход триггера ODDR, находящегося непосредственно в требуемом блоке ввода-вывода. Этот триггер не может быть автоматически применен синтезатором и требует установки в струк- турном стиле, как показано в примере ниже. В этом примере жирным шрифтом выделены строки, сигналы в которых требуют заполнения разработчиком. На рис. 6.19 показано технологическое представление синтезированной схемы. ODDR2_clkainst : ODDR2 generic map( DDRJVLIGNMENT => "NONE", - Sets output alignment to "NONE", "CO", *&' INIT => '0\ — Sets initial state of the Q output to '0' or T SRTYPE => "SYNC") - Specifies "SYNC" or "ASYNC" set/reset
реализации схем на базе ПЛИС 317 Рис. 6.19. Технологическое представление схемы формирования выходного тактового сигнала port map ( Q => gen.clk, — 1-bit output data CO => elk, — 1-bit clock input Cl => not(clk), -- 1-bit clock input CE => clk_en, ~ 1-bit clock enable input DO => T, - 1-bit data input (associated with CO) Dl => '0', - 1-bit data input (associated with Cl) R => '0', — 1-bit reset input S => '0' -- 1-bit set input ), Листинг. Фрагмент описания со ссылкой на аппаратный компонент ODDR2 Схема работает следующим образом. Триггер ODDR имеет два входа данных — DO и D1, которые связаны с тактовыми входами СО и С1 соответственно. В примере видно, что на DO подана логическая единица, а на D1 — логический ноль. Поэтому по фронту тактового сигнала elk, который также подан на СО, триггер запишет логическую единицу (с DO), а по спаду elk, который после инвертирования окажется фронтом для С1, будет записан логический ноль с D1. Временные диаграммы работы такой схемы показаны на Рис. 6.20. Таким образом, на выходе окажется не сам тактовый сиг- Рис. 6.20. Временные диаграммы работы триггера ODDR
Глава нал, но данные, которые будут меняться точно так же. Этот ^ может быть применен и для других семейств ПЛИС Xilinx, однако для Spartan-б он является обязательным. 6.14. Синхронизация асинхронных сигналов Внешние сигналы, приходящие в ПЛИС, могут иметь другой источник тактирования, не совпадающий с основным тактовым сигналом проекта (если он есть). В общем случае по подходу к синхронизации сигналы подразделяются на: • system-synchronous — сигнал имеет общий источник синхронизации с другими сигналами проекта (это касается и других микросхем на плате, если они есть); • source-synchronous — сигнал или шина имеет собственный источник тактового сигнала, по перепаду которого и изменяется состояние сигнала; • self-synchronous — сигнал не связан с тактовым сигналом, однако информация о моментах изменения его состояния присутствует в самом сигнале (например, частотно-модулированный или фазо-модулированный сигнал). По мере повышения тактовых частот интерфейсы изменяются с system-synchronous к source-synchronous и далее к self-synchronous. Это связано с тем, что теоретически можно подать общий тактовый сигнал на все компоненты проекта, даже если в проекте используются несколько микросхем. Однако будет ли фронт тактового сигнала приходить на все микросхемы строго одновременно? Очевидно, что из-за неодинаковой длины проводников и технологического разброса параметров строгой синхронности добиться не удастся. Для каких же частот можно рассчитывать на пренебрежимо малую величину рассинхронизации? Точного значения указать невозможно, однако на практике уже для частот порядка 100 МГц и выше используются интерфейсы класса source-synchronous. Примером может служить протокол Ethernet MAC, который для режимов 10 и 100 Мбит/с (частоты передачи данных даже в 4-разрядном режиме RMII равны 2,5 и 25 МГц соответственно) использует system-synchronous интерфейс (тактовый сигнал подается на микросхему Ethernet MAC, а выходные данные появляются с некоторой задержкой, которая не является существенной). Однако при переходе на скорость обмена 1000 Мбит/с, что соответствует частоте 125 МГц при 8-разрядных данных, микросхема Ethernet MAC является source-synchronous и сопровождает данные собственным тактовым сигналом. При периоде тактового сигнала 8 не возможные дополнительные задержки и ва" риации параметров печатной платы уже являются существенными.
примеры реализации схем на базе ПЛИС 319 signal_meta_reg signal_meta D Q signal_in ! / j signal_meta j \/-ffi | 4 1 h рис. 6.21. Поведение триггера при попадании в метастабильное состояние Кроме source-synchronous, существуют и более простые случаи, когда сигнал является асинхронным по отношению к тактовым сигналам проекта. Например, обычная кнопка, подключенная к входу ПЛИС, нажимается человеком в произвольные моменты времени, не связанные с тактовым генератором. Прием данных с внешней шины, тактируемой отдельным сигналом, может вызвать определенные сложности. Очевидным, однако некорректным решением является подача внешнего тактового сигнала на выделенный тактовый вход GCLK и захват данных по фронту этого сигнала. Такая схема формально является корректно для идеальных временных характеристик, однако вызывает появление метастабилъных состояний. Под метастабильным состоянием понимается такой режим работы триггера, в котором его выход имеет промежуточный уровень напряжения, воспринимаемое разными компонентами как логический ноль или логическая единица (рис. 6.21). Это нежелательный режим, в котором триггеры оказываются вынужденно, если на входе данных напряжение изменяется непосредственно перед приходом фронта тактового сигнала. По спецификации, каждый триггер имеет время установки (setup time) и время удержания (hold time) — интервалы времени до и после фронта тактового сигнала, в течение которых уровень сигнала на его входе D изменяться не должен. Ме- тастабильность носит вероятностный характер и объясняется особенностями переключения транзисторов, из которых состоит триггер, а не какими-либо специальными приемами проектирования для Цифровой электроники. Метастабильным может стать сигнал, вводимый в ПЛИС, например, от механического переключателя или любой внешней микросхемы, которая тактируется не от внутреннего источника ПЛИС. Любая конструкция, в которой используется два тактовых сигнала, потенциально подвержена метастабильности, которую следует Устранить, или хотя бы снизить вероятность ее появления. Даже в случае, когда номинальные значения тактовых частот одинаковы или кратны, нормальная работа возможна только в недостижимом н* практике идеальном случае — когда фронты обоих тактовых сиг-
320 Гла. налов появляются в строго определенные моменты времени. Именно эту ситуацию и увидит разработчик, попытавшийся промоделиро. вать поведение подобной схемы. Это связано с тем, что идеальная модель (с фиксированным периодом тактового сигнала), очевидно покажет и идеальное поведение схемы. Однако каждый генератор имеет не только свое номинальное значение частоты, но и собственный температурный и долговременный дрейф, собственное распределение помех, что вызовет как случайные колебания периода вокруг некоторого среднего значения, так и систематический дрейф этой средней величины. Например, два кварцевых генератора с номинальным значением частоты 100 МГц, различающиеся на 30 ррщ (типичное значение нестабильности для генераторов), будут иметь разницу в частотах, равную 3000 Гц! Таким образом, каждую секунду один из генераторов будет формировать на 3000 периодов больше другого, и интервал времени между приходом фронтов тактового сигнала с двух генераторов за это время будет принимать значения от 0 до полного периода тактового сигнала. Вероятность попадания в метастабильное состояние при этом, очевидно, ненулевая. Простейшей схемой, снижающей вероятность попадания в метастабильное состояние, является узел, показанный на рис. 6.22. В схеме на рис. 6.22 решение о том, в каком именно состоянии оказался триггер signaljuetajreg, всецело отдано второму триггеру, signaLoutjreg. В данном случае худшее, что может произойти, — переход в нужное состояние на такт позже. С точки зрения схемотехники это приемлемая цена решения вопроса. Альтернативой могла бы стать ситуация, когда signaljneta читался бы двумя триггерами, которые восприняли бы его противоположным образом. В итоге возникла бы ситуация, когда один и тот же сигнал в разных частях схемы иногда представлялся бы и логическим нулем, и ло- sign^l_meta_reg signal_out_reg signal_in dst elk D Q signaljmeta D Q signal_put signal_in ! f signaljneta j \/-tyfi signal_out (H); | \Г signal_out (L) j | | I Рис. 6.22. Схема защиты от метастабильности
примеры реализации схем на базе ПЛИС 321 wr data Ц Full Flag Generator wr elk > Dial] Port RAM id data .Synchitonizer Synchrpnizer II pop Empty Flag Generator empty rd elk Рис. 6.23. Ввод сигнала с помощью FIFO гической единицей. Целью защиты от метастабильности является именно устранение такой ситуации, а не чтение какого-то «истинного» состояния линии. Иными словами, разработчику следует быть готовым к поведению схемы, показанной на рис. 6.22, и не ожидать немедленной реакции на изменение входного сигнала. Чуть большую сложность имеет схема на базе FIFO. В этой схеме приемник ориентируется на флаг «FIFO пуст», при пропадании которого можно читать данные. Для большей безопасности можно контролировать глубину FIFO и читать данные только в том случае, если в FIFO уже записаны как минимум 2 числа (факт начала записи второго числа гарантирует, что предыдущая запись уже завершилась). FIFO может быть собрано на базе распределенной памяти, а для ответственных случаев — и на базе блочной. Однако блочная память является дефицитным ресурсом для Spartan-6/7, особенно У младших микросхем, поэтому возможность использования такого блока должна быть спланирована заранее. На рис. 6.23 показана схема ввода сигнала с помощью FIFO. Правильное понимание сути метастабильного состояния и способов защиты от него является крайне важным при построении проектов с несколькими тактовыми сигналами. Часто нестабильная работа проекта обусловлена именно игнорированием правил передачи Данных между двумя тактовыми сетями. Распространенной ошибкой является попытка моделирования проекта с целью доказать отсутствие проблем с метастабильностью. Ни функциональное, ни post-route моделирование неспособно выбить проблему появления метастабильности, поскольку этот провес носит вероятностный характер и к тому же не является чисто
322 цифровым. Даже выявление того факта, что для какого-то триггера нарушены условия по времени установки или удержания сигнала, не поможет ответить на вопрос «какое состояние примет этот триггер с учетом температуры, напряжения питания и технологического разброса параметров». Использование проектных ограничений также является одним из ошибочных способов устранить эффект метастабильности. Установка параметров max_delay и min_delay для цепей вызывает не подстройку задержки распространения, а проверку того, что какая-то цепь удовлетворяет этим параметрам. Кроме того, установленное значение задержки проверяется относительно параметров тактового сигнала, задаваемых разработчиком. В итоге может возникнуть ситуация, когда разработчик задает в модели частоты 100 МГц и 200 МГц, симулятор строит временные диаграммы этих сигналов в полном соответствии с заданными моделями, и оказывается, что фазы сигналов полностью совпадают. В итоге разработчик убеждается, что на каждый период сигнала 100 МГц приходится два периода сигнала 200 МГц, фронты сигналов полностью совпадают и проблемы с метастабильностью исключены. Однако эта проверка основывалась на условиях строгого соответствия тактовых сигналов номинальным значениям, о чем заявил разработчик, задавая описание сигналов. На практике же частоты будут отличаться от номинальных значений. Практическим путем решения проблемы метастабильности является корректная ресинхронизация сигналов, передаваемых из одного тактового домена в другой. Следует использовать двухпортовую память с портами, подключаемыми к соответствующим тактовым сигналам, где это возможно. Надежным способом передачи одноразрядного сигнала является использование цепочки из 2 или 3 триггеров, причем следует избегать оптимизации этой цепи синтезатором. Рекомендуется описывать узлы ресинхронизации отдельными модулями и проверять детали их реализации после синтеза. 6.15. Подключение SPI Последовательный интерфейс (SPI, Serial Peripheral Interface) широко распространен в цифровых устройствах. Его достоинством является небольшое число линий D или в ряде случаев 3) в сочетании с относительно высокой скоростью передачи данных. Часто эта скорость ограничена требованиями подключаемой внешней микр°" схемы, а встречающимися в документации максимальными значениями являются 5, 20, 80 и 105 Мбит/с. Шина является синхронной
Примеры реализации схем на базе ПЛИС 323 /т.е. имеет явный сигнал синхронизации), что и обеспечивает более вьдсокУ10 по сравнению с UART скорость передачи. Шина SPI подразумевает наличие ведущего устройства (master) й нескольких ведомых (Slave). Ведущее устройство формирует тактовый сигнал, подаваемый на все ведомые устройства. Шина имеет следующие сигналы: • SCLK — тактовый сигнал, выход ведущего и вход ведомых устройств; • MOSI (Master Out, Slave In) — выход данных для ведущего и вход для ведомых устройств; • MISO (Master In, Slave Out) — вход данных для ведущего и выход для ведомых устройств; • CS (Chip Select) — выбор ведомого устройства. Сигналы CS являются индивидуальными для каждого из ведомых устройств, в то время как остальные объединяются. Может показаться, что это образует проблему для сигнала MISO, который объединяет выходы нескольких ведомых устройств. Однако только одно ведомое устройство может быть активным, а неактивные обязаны перевести свой сигнал MISO в состояние высокого импеданса. За активизацию ведомых устройств отвечают сигналы CS, имеющие активный низкий уровень. Ведущее устройство обязано следить, чтобы было активизировано не более одного ведомого устройства. Схема подключения нескольких устройств SPI показана на рис. 6.24. Временные диаграммы работы SPI показаны на рис. 6.25. Начало передачи идентифицируется низким уровнем сигнала CS. Далее в Master SCLK MOSI MISO CSl CS2 CS3 SCLK MOSI MISO CS SCLK MOSI MISO CS SCLK MOSI MISO CS Рис. 6.24. Схема соединения устройств по интерфейсу SPI
324 -Г л а в а if^^ MISO Рис. 6.25. Временные диаграммы работы интерфейса SPI течение нескольких тактов сигнала SCLK передаются данные, причем в зависимости от подключаемой микросхемы ведомое устройство может как передавать свой выходной буфер, так и не передавать. Например, при подключении флеш-памяти с интерфейсом SPI после передачи мастером адреса ведомое устройство памяти начинает передавать содержимое ячейки с запрошенным адресом. Интерфейс SPI не имеет стандартизованного протокола, и каждое устройство может предлагать собственную интерпретацию данных внутри передаваемого пакета. Данные могут передаваться пакетами в 8, 16, 24, 32 или более битов, при этом стандартом не определены какие-либо заголовки или контрольные суммы. Особенностью реализации контроллера SPI в ПЛИС является организация тактового сигнала. Она имеет особенности в обоих случаях — master и slave. В режиме master существует возможность подключения к выходу SCLK одного из внутренних тактовых сигналов ПЛИС. Это не является обязательным для низких скоростей передачи, поскольку тактовый сигнал вполне можно формировать с помощью конечного автомата управления или софт-процессора. Однако если было все же принято решение использовать тактовый сигнал, распространяющийся по глобальным тактовым линиям, потребуется применение приема под названием clock forwarding, рассмотренный выше. Для ПЛИС семейства Spartan-б это единственный способ вывести внутренний тактовый сигнал на внешний вывод, а для ПЛИС серии 7 и последующих строгого запрета нет, но тем не менее прием настоятельно рекомендуется. В режиме slave может показаться, что единственно правильным для ПЛИС решением будет подача тактового сигнала SPI на один из так называемых clock-capable входов — т. е. входов, имеющих специальные буферы для тактовых сигналов. Однако такой прием повлечет за собой необходимость передачи данных, захваченных по одному тактовому сигналу, в регистр, тактируемый (системным) тактовым сигналом. Это потребует реализации
Примеры реализации схем на базе ПЛИС 325 защиты от метастабильности, что само по се6е не является непреодолимой проблемой, однако для подобных ситуаций существует и другой эффективный прием. Ввиду того, что тактовый сигнал SPI предполагается меньшей частоты, чем системный тактовый сигнал внутри ПЛИС, можно произвести выделение по- ложения фронта тактового сигнала с помощью последовательного высокочастотного опроса линии SCLK, что проиллюст- SCLK CLK DO = 1 and Dl = 0 => фронт сигнала SCLK Рис. 6.26. Выделение фронта тактового сигна- рировано на рис. 6.26. Если тактировать ла SPI с помощью последо цеПОЧКу триггеров DO, Dl ВЫСОКОЧаСТОТ- вательного опроса линии ным тактовым сигналом CLK, то эта цепочка будет захватывать последовательные состояния линии SCLK, причем триггер D1 будет содержать предыдущее состояние линии SCLK, a DO — текущее состояние. Появление фронта сигнала на линии SCLK приведет к тому, что старое состояние линии, хранящееся в D1, будет равно О, а новое, прочитанное в DO, станет равно 1. Если условие DO = 'О' and Dl = '1* использовать в качестве разрешения работы, сигналы данных интерфейса SPI смогут быть приведены к тактовой сети CLK. Такой подход требует конвейеризации и для сигнала данных, поскольку фронт сигнала SCLK выявляется с задержкой. В листинге приведен пример slave-контроллера SPI, построенного в соответствии с приведенными требованиями. Контроллер предполагает обмен 32-разрядными словами и реализован на базе конечного автомата. Внешний интерфейс с МК представляет собой простую синхронную шину и использует сигнал адреса addr, сигнал разрешения записи wrio и две шины данных с разными направлением передачи: data и dq. Это пример интерфейса, достаточно универсального для реализации, в том числе эмуляции при наличии Достаточного числа выводов, library IEEE; use IEBE.STDJiOGICJ164.ALL; use ieee.stdJogicarith.all; use ieee.stdJogic.unsigned.all; entity spi_slave is generic (BASEADDR : integer := 10000); Port (elk : in STDJLOGIC; sclk • in STD.LOGIC; mosi : in STD.LOGIC; miso : out STDJX>GIC;
326 Г^л а в а б spi.cs : in STD_LOGIC; — внешний интерфейс для подключения МК addr : in stdJogic_vectorA5 downto 0); data : in stdJogic_vectorC1 downto 0); dq : out stdJogic_vectorC1 downto 0); wrio : stdJogic; en : out stdJogic ); end spi_slave; architecture Behavioral of spijslave is signal sclki)-.pipe, sclkj..pipe : stdJogic := '0'; signal mosLO.pipe, mosLl-pipe : stdJogic := '0'; signal spLcsJLpipe, spi.cs_l.pipe : stdJogic := '0'; signal spij3tate : integer range 0 to 31 := 0; signal spLtxjstate : integer range 0 to 33 := 0; signal spijreg, spi_tx_reg, spijcount: stdJogic .vector C1 downto 0) := (others => '0'); begin sclk-CLpipe <= sclk when risingjedge(clk); sclk.l-pipe <= sclk.0.pipe when rising.edge(clk); mosLCLpipe <= mosi when risingjedge(clk); mosLl.pipe <= mosLO.pipe when rising.edge(clk); spLcsJD.pipe <= spLcs when rising.edge(clk); spixs.l.pipe <= spi.cs_O.pipe when rising..edge(clk); process(clk) begin if rising_edge(clk) then if spLcs = yV then spijstate <= 0; elsif sclk_0-pipe = '0' and sclk_l.pipe = '1' and spi.cs.l.pipe = '0J then spi-reg(spi-state) <= mosi_l.pipe; miso <= spLtxjreg(spijstate); spij3tate <= spijstate -f 1; end if; end if; end process; process(clk) begin if rising_edge(clk) then if spLcs = '1* and spLcs_0_pipe = '0' then spLcount <= spi.count + 1; en <= T; end if; if spLcsJLpipe = '1' and spi_cs_l_pipe = '0* then en <= '0'; end if;
примеры реализации схем на базе ПЛИС 327 end if; end process; process(clk) begin if rising_edge(clk) then if wrio = '1' and convjnteger(addr) = BASEADDR then spi.tx_reg <= data; end if; end if; end process; with conv_integer(addr) select dq <= spijreg when BASEADDR, spLcount when BASEADDR + 1, (others => '0') when others; end Behavioral; Листинг. Реализация контроллера SPI slave Размещение множества независимых контроллеров SPI является сильной стороной ПЛИС. В сочетании с буферизацией или подключением SPI к независимым процессорным ядрам ПЛИС может обеспечить одновременную работу нескольких устройств с интерфейсом SPI. Даже если каждая внешняя микросхема будет подключаться собственным набором сигналов, с учетом нескольких сотен программируемых выводов к ПЛИС можно подключить десятки (и даже сотни) внешних микросхем с интерфейсом SPI. Практическая необходимость именно такого проекта может быть сомнительной, однако интересна сама возможность ввода в одну микросхему Сигналов из многих источников. б. 16. Параллельные интерфейсы, синхронизированные с источником — АЦП и CPI При подключении внешних устройств с синхронным интерфейсом в зависимости от направления тактового сигнала необходимо решить одну из задач: • формирование выходного тактового сигнала, синхронного с основным тактовым сигналом ПЛИС (если устройство принимает тактовый сигнал); • синхронизация тактового сигнала, приходящего с устройства, если оно самостоятельно формирует тактовый сигнал. Выходной тактовый сигнал следует формировать по схеме clock forwarding, чтобы минимизировать отставание фазы от основного тактового сигнала проекта, которое образуется, если просто передать тактовый сигнал на выход с помощью буфера OBUF. При вводе данных может показаться, что достаточно реализовать схему защиты от метастабильности, аналогично тому, как это
328 Глав Ожидание: защита от метастабильности для шины clkA На практике: независимые цепи ^ clkA 1—> I > clkB DO -*• 16 независимых цепей Рис. 6.27. Попытка некорректной защиты от метастабильности для многоразрядной шины было сделано в примере с SPI. Однако пример с ресинхронизацией одноразрядного сигнала на самом деле не может быть автоматически распространен на многоразрядные шины. Проблема заключается в том, что разряды шины не строго идентичны, поэтому эффект метастабильности каждый раз будет проявляться для них независимо (или не проявляться совсем). На рис. 6.27 иллюстрируется эта проблема. Разработчик может ожидать, что установка двух многоразрядных регистров решает проблему защиты от метастабильности, однако каждый из разрядов будет реагировать на метастабильные состояния индивидуально. В итоге в проекте образуется N независимых цепей защиты от метастабильности (в примере показана 16-разрядная шина данных). Например, при переключении данных с 0x0000 к OxPFFP выходной регистр может захватить произвольное промежуточное состояние, составленное из разрядов, которые уже переключились в логическую 1 и были соответствующим образом захвачены из промежуточного метастабильного сигнала, и разрядов, которые не успели это сделать. В итоге 16-разрядное число может оказаться любым в диапазоне от 0 до OxPFFF. Бели в проекте имеются какие-то запрещенные состояния или коды, идентифицирующие наступление определенной ситуации, такое поведение может привести к негативным последствиям. Для передачи многоразрядных сигналов не существует гарантированного пути подстройки отдельных разрядов с целью добиться их строго синхронной и идентичной передачи в тактовый домен назначения. Группировка компонентов на кристалле ПЛИС с помощь10 топологических проектных ограничений может снизить разброс за-
примеры реализации схем на базе ПЛИС 329 держек распространения сигналов, однако не является гарантией строго идентичного поведения отдельных разрядов на протяжении работы проекта. Рассмотрим возможные способы передачи многоразрядных сигналов. 1. Выделение фронта тактового сигнала, как было показано в примере с интерфейсом SPI. Технология захвата фронта тактового сигнала обеспечивает выбор такого положения на временной оси, при котором фронт тактового сигнала надежно идентифицирован, и есть уверенность, что на многоразрядной шине в этот момент нет метастабильных состояний. Недостатком этого способа является необходимость наличия системного тактового сигнала с частотой в несколько раз выше, чем частота изменения входных данных. 2. Применение блоков двухпортовой памяти. Пример использования двухпортовой памяти в режиме FIFO показан на рис. 6.23. Порты блоков статической памяти являются физически независимыми, и одновременный доступ из двух тактовых доменов не является проблемой. Следует, однако, следить за тем, чтобы чтение данных не производилось из ячейки, в которую еще идет запись, поскольку в таком случае поведение памяти не определено. Использование FIFO помогает решить эту проблему, поскольку если счетчик FIFO показывает, что очередь пуста, чтение данных невозможно, а если в FIFO занята всего одна ячейка, то может возникать ситуация, когда флаг, сигнализирующий о появлении данных, будет установлен раньше, чем запись физически завершится и пройдет время удержания после фронта тактового сигнала, по которому производилась запись. Надежнее использовать флаг «almost empty», сигнализирующий о том, что FIFO «почти пусто». Пропадание этого флага будет означать, что в FIFO заняты более одной ячейки и по крайней мере одну можно безопасно читать. Общим принципом реализации схем передачи данных между тактовыми доменами является применение подходов, не зависящих °т конкретного момента приема данных или номера такта в домене — источнике данных. При анализе проекта, содержащего более одной тактовой сети, временной анализ может давать неверные данные, пытаясь анализировать цепи, соединяющие компоненты, тактируемые разными сигналами. На рис. 6.28 показана иллюстрация к такой ситуации. Например, если периоды тактовых сигналов составляют 10 и 12 Нс> то при анализе возникнет ситуация, когда данные будут записа-
330 Г л а; а б REGA REGBO REGB1 D СЕ Q у- D СЕ Q г D СЕ Q Рис. 6.28. Иллюстрация к проблеме временного анализа цепи, соединяющей триггеры REGA и REGB0 ны в один регистр в момент времени 10 не по сигналу elk А, который соединен с триггером, тактируемым сигналом clkB. Однако следующий фронт для этого триггера придет в момент времени 12 не, и на передачу сигнала имеется всего 2 не — от момента записи в 10 не до момента предполагаемого чтения 12 не. Однако в действительности для такой передачи данных предполагается, что для цепи, тактируемой clkB, реализована схема защиты от метастабильности. Поэтому точный момент прихода данных неважен, тем более что на практике периоды 10 и 12 не не будут соблюдаться с абсолютной точностью. Чтобы избежать анализа цепей, для которых неважно точное значение задержки распространения сигнала, необходимо использовать проектные исключения (timing exceptions). Понятие проектных исключений означает перекрытие проверок, которые производит САПР при анализе трассировки проекте. Правила для проверки отдельных цепей могут быть явно указаны разработчиком, если у него есть понимание того, как в действительности работает этот фрагмент схемы. Для приведенного примера задержка распространения сигнала по цепи, соединяющей триггер, тактируемый clkA, и триггер, тактируемый clkB, неважна. По сути она может быть любой, поскольку в домене clkB нет никакой информации о точном числе тактов, прошедшем в домене elk А. Поэтому получившееся время распространения сигнала по линии, соединяющей REGA и REGB0, можно игнорировать. Правило для игнорирования получившейся задержки распространения сигнала для какой-то цепи называется false path (т. е. «ложная цепь»). Цепь, для которой указано это правило, будет исключена из временного анализа, и любое значение задержки сигнала будет приемлемым. На рис. 6.29 показано диалоговое окно мастера создания проектных исключений false path. Ниже приведены возможные варианты установки проектных исключений при передаче сигналов между тактовыми доменами. Кр°" ме false path, можно установить «физически эксклюзивные» такто-
дрямеры реализации схем на базе ПЛИС 331 Рис. 6.29. Установка проектных исключений false path для линий данных, передаваемых между тактовыми доменами вые группы, явно указать, что тактовые группы являются асинхронными (в этом случае анализ задержек между ними не будет производиться), или же явным образом установить максимальную задержку распространения сигнала с ключом -datapath_only. В таком случае будет анализироваться только время распространения сигнала по цепи данных без учета соотношения моментов, в которые появляются фронты тактовых сигналов. set Jalse.path -from [get.clocks CLKA] \ -to [get_clocks CLKB] set_clock_groups -physically.exclusive \ -group CLKA -group CLKB set.clock^groups -asynchronous \ -group CLKA -group CLKB set_max_delay -from [get.cells REGA] -to \ [get.cells REGBO] 5 -datapath-only Листинг. Возможные варианты установки проектных исключений при передаче данных между тактовыми доменами В общем случае говоря, понятие «физически эксклюзивных» тактовых сигналов используется в основном для ситуаций, когда часть схемы может тактироваться либо одним, либо другим тактовым сигналом (например, в разных режимах работы). Процесс переключения тактовых сигналов должен сопровождаться гарантированным интервалом времени, в течение которого оба сигнала отключены. Однако формальный анализ временных параметров проекта может обнаружить момент времени, в который фронты тактовых сигналов находится близко друг к другу. Для ввода большого числа независимых потоков данных можно Использовать региональные тактовые сети. В этом случае подача
332 Гл ав а тактовых сигналов на входы регионов с возможностью тактирования (clock-capable inputs) позволит использовать региональные бу. феры BUFR, записав потоки данных в блоки BRAM, находящиеся в этом регионе. Второй порт BRAM может тактироваться системным тактовым сигналом, например, от микропроцессорной системы на кристалле. Примерами интерфейсов требующих применение подобного подхода, являются высокоскоростные параллельные интерфейсы аналого-цифровых преобразователей (АЦП), а также Camera Parallel Interface (CPI), используемый во многих модулях цифровых видеокамер. Упро CLKin a/d; Генератор ;D0-Dn 'CLKout Рис. 6.30. Структурная схема АЦП с source-synchronous интерфейсом Камера SCL, SDA HREF, VSYN(* Dataf9:01 PCLK FPGA щенная структурная схема АЦП с source-synchronous интерфейсом показана на рис. 6.30. Эта схема характерна для АЦП со скоростями передачи порядка 100 MSPS (мегавыборок в секунду). Особенностью таких микросхем является внутренний генератор, формирующий выходной тактовый сигнал на основе опорного входного тактового сигнала. Соотношение фазы между входным и выходным сигналом нельзя считать определенным, поскольку часто в качестве генератора используется ФАПЧ. Поэтому при приеме данных нельзя ориентироваться на внутренний тактовый сигнал ПЛИС, даже если его копия подана на вход опорного тактового сигнала внешнего АЦП. Похожий принцип используется в параллельном интерфейсе камеры (Camera Parallel Interface, CPI). Структурная схема подключения модуля видеокамеры к ПЛИС показана на рис. 6.31. Сигналы интерфейса CPI имеют следующее назначение: • SCL, SDA — сигналы интерфейса Serial Camera Control Bus (SCCB), организованного наподобие интерфейса 12С, этот интерфейс используется для настройки режимов видеокамеры путем программирования внутренних регистров; • HREF — сигнал горизонтальной синхронизации, находится в высоком уровне, если передаются данные из активной зоны строки; PFDN XCLK Рис. 6.31. Структурная схема подключения модуля видеокамеры к ПЛИС
ализации схем на базе ПЛИС 333 • VSYNC — сигнал вертикальной синхронизации, находится в высоком уровне, если передаются данные с активной зоны кадра, в сочетании с сигналом HREG сигнализирует о передаче актуальных данных; • Data[9:0] — шина данных, может быть 10- или 8-разрядной; • PCLK (Pixel Clock) — тактовый сигнал, сопровождающий данные на шине Data; • PWDN — сигнал перехода в энергосберегающий режим; • XCLK — входной тактовый сигнал, используемый в качестве опорного для формирования сигнала PCLK. Как и в случае параллельного интерфейса АЦП, при подключении камеры не следует использовать копию сигнала XCLK для захвата данных. Вместо этого запись данных во входные регистры ПЛИС должна производиться по сигналу PCLK с последующей ресинхронизацией для передачи в другие тактовые домены. 6.17. Интерфейс VGA Интерфейс VGA (Video Gate Array) является широко распространенным ин- терфейсом для подключения дисплеев. Даже для более современного интерфейса HDMI существуют микросхемы, преобразующие цифровые сигналы, предназначенные для VGA, в сигналы HDMI, поэтому актуальность этого интерфейса jz g сохраняется. jg gg Сигналы VGA показаны на рис. 6.32. Рис. 6.32. Сигналы разъема Сигналы имеют следующее назначе- ние: • Red, Green, Blue — аналоговые сигналы яркостной составляющей красного, зеленого и синего цветов; • HSYNC — сигнал горизонтальной (строчной) синхронизации; • VSYNC — сигнал вертикальной (кадровой) синхронизации. Сигналы горизонтальной и вертикальной синхронизации применялись еще в аналоговом телевидении и полностью сохранены в VGA по принципу действия даже с учетом перехода на цифровые контроллеры дисплеев. Эти сигналы формируют короткий импульс логического 0 при переходе к новому кадру (для вертикальной синхронизации) и к новой строке (для горизонтальной синхронизации). Временная диаграмма сигнала синхронизации показана на рис. 6.33.
334 Гл ава б Front porch Active Back porch ^ Sync pulse Рис. 6.33. Временная диаграмма сигнала синхронизации Сигналы вертикальной и горизонтальной синхронизации имеют одинаковую форму, хотя и разную частоту следования. Перед подачей импульса синхронизации проходит время, обозначенное как front porch. За ним следует импульс синхронизации, после которого проходит время back porch. Далее следует активная зона, во время которой передаются видеоданные. Для передачи данных требуется, чтобы и вертикальная и горизонтальная синхронизация находились в активной зоне. Частота следования импульсов вертикальной синхронизации определяет частоту смены кадров. Соответственно, частота импульсов горизонтальной синхронизации больше, с учетом числа строк в кадре. Необходимость добавления времени для неактивной зоны приводит к тому, что длительность импульса возрастает. Интервалы времени, показанные на рис. 6.33, имеют определяемые стандартом значения для каждого из видеорежимов. Некоторые значения приведены в табл. 6.2, 6.3. По данным табл. 6.2, 6.3 можно сделать наблюдение, что число тактов в строке больше, чем видимых пикселов изображения, а число строк в течение одного периода сигнала вертикальной синхронизации больше, чем видимых строк. Например, для режима 640x480 Таблица 6.2 Характеристики сигнала Режим 640x480, 60 Hz 640x480, 72 Hz 640x480, 75 Hz 640x480, 85 Hz 800x600, 60 Hz 800x600, 72 Hz 800x600, 75 Hz 800x600, 85 Hz 1024x768, 60 Hz 1024x768, 72 Hz 1024x768, 75 Hz 1024x768, 85 Hz горизонтальной синхронизации для некоторых видеорежимов Частота следования данных, МГц 25,175 31,5 31,5 36 40 50 49,5 56,25 65 75 78,75 94,5 Активная зона, тактов 640 640 640 640 800 800 800 800 1024 1024 1024 1024 Front porch, тактов 16 24 16 32 40 56 16 32 24 24 16 48 Hsync, тактов 96 40 96 48 128 120 80 64 136 136 96 96 Back porch, тактов . — 48 128 48 112 88 64 160 152 160 144 176 208
примеры реализации схем на базе ПЛИС 335 Таблица 6 3 Характеристики сигнала вертикальной синхронизации для некоторых видеорежимов -—¦ Режим "^640x480, 60 Hz 640X480, 72 Hz 640x480, 75 Hz 640x480, 85 Hz 800x600, 60 Hz 800x600, 72 Hz 800x600, 75 Hz 800x600, 85 Hz 1024x768, 60 Hz 1024x768, 72 Hz 1024x768, 75 Hz 1024x768, 85 Hz Частота следования данных, МГц 25,175 31,5 31,5 36 40 50 49,5 56,25 65 75 78,75 94,5 Активная зона, тактов 480 480 480 480 600 600 600 600 768 768 768 768 Front porch, тактов 11 9 11 1 1 37 1 1 3 3 1 1 Vsync, тактов 2 3 2 3 4 6 2 3 6 6 3 3 Back porch, тактов 31 28 32 25 23 23 21 27 29 29 28 36 число тактов на строку составляет 800, с учетом неактивной зоны, а число строк — 524. Поэтому число тактов на кадр изображения составляет 800x524 = 419200, а тактовую частоту контроллера можно узнать, умножив это значение на частоту кадров. С возрастанием разрешения экрана и кадровой частоты растет тактовая частота, необходимая видеоконтроллеру для формирования изображения и сигналов синхронизации. Показанное в таблице максимальное разрешение 1024x768 требует тактовой частота 94,5 МГц, что в целом не составляет проблемы для ПЛИС. Характеристики некоторых режимов высокого разрешения приведены в табл. 6.4. В приведенных ниже видеорежимах сигнал вертикальной синхронизации имеет активный высокий уровень. Из табл. 6.4 можно видеть, что тактовая частота, требуемая видеоконтроллеру, заметно растет при повышении разрешения изобра- Таблица 6.4 Характеристики некоторых видеорежимов высокого разрешения Характеристика Частота следования данных, МГц Активная зона, тактов front porch, тактов Hsync, тактов Sack porch, тактов Активная зона, строк front porch, строк Vsync, строк Sack porch, строк 1368x768 Q 60 Hz 85,86 1368 72 144 216 768 1 3 23 1280x720 О 60 Hz 74,25 1280 72 80 216 720 3 5 22 1920x1080 © 60 Hz 148,5 1920 88 44 148 1080 4 5 36 1920x1140 75 Hz 297 1920 144 224 352 1440 1 3 56
336 Гл ав а б Red Green Blue Horizontal Sync 270ft ¦AVv о R (R12) G (T12) B (Rll) о HS(R9) Vertical Sync о VS (T10) Сигналы ПЛИС Рис. 6.34. Фрагмент документации (UG130 Spartan-3 FPGA Starter Kit Board User Guide) с изображением схемы подключения порта VGA к ПЛИС жения. Изображение формата 4К2К имеет в 2 раза больше пикселов по каждой из осей, т. е. как минимум в 4 раза больше пикселов в кадре, чем PullHD A920x1080). Следующее поколение дисплеев, 8К4К, дополнительно удваивает разрешение, размещая в кадре уже не 2 млн пикселов, как в PullHD, a 32 млн. Такой объем данных требует и очень высоких тактовых частот для работы видеоконтроллера. Тем не менее, с учетом частично параллельной обработки и с помощью внешних микросхем формирования сигналов синхронизации работа с этими форматами изображения возможна с применением ПЛИС. Для формирования аналоговых напряжений обычно используются специальные видеоЦАП (videoDAC). Для простейших проектов с однобитовым цветом по каждому каналу в ряде плат используются токоограничивающие резисторы. Например, на рис. 6.34 показан фрагмент схемы отладочной платы Spartan-3 Starter Board, где в каждом канале используется резистор номиналом 270 Ом для преобразования цифрового сигнала с выхода ПЛИС в соответствующее стандарту VGA аналоговое напряжение. Таким способом возможна реализация 8-цветного режима. Чуть более сложна реализация 2- или 4-разрядного цвета. Это может быть реализовано с помощью матрицы резисторов (токового сумматора). Если выбирать резисторы с соотношением номиналов 1:2:4:8..., то вклад каждого последующего резистора будет в 2 раза меньше, чем у предыдущего. Подобным образом можно воссоздать принцип работы цифро-аналогового преобразователя. Следует иметь в виду, что многоразрядные ЦАП используют матрицу резисторов R-2R, поскольку разброс параметров резисторов приведет к тому, что 8- или 12-разрядный токовый сумматор окажется весьма неточным. На рис. 6.35 показана схема организации порта VGA на отладок*
ализации схем на базе ПЛИС 337 VGA-RI RilO VGA-R2 VGA-R3 4К Rill RII2 2К VGA-R4 IK R113 VGA-G1 R114 510 VGA-G2 4К RU5 -ЛЛг- VGA-G3 Rt!9 2K VGA-G4 IK R120 J10 VGA-B1 VGA-B2 R121 510 -ЛЛ- 4К RI22 VGA-B3 RI23 VGA-B4 IK RI24 VGA-HS R126 510 VGA-VS 100 RI27 100 GND 1-1734530-3 Рис. 6.35. Фрагмент схемы отладочной платы Zedboard с 4-разрядным цветом в каждом канале VGA. Используется резистивный токовый сумматор для имитации ЦАП Red л _Green IК разъему Blue Дополнительные входы для синхросигналов и управления Рис. 6.36. ВидеоЦАП ной плате Zedboard, использующей ПЛИС ZC7020. Это достаточно современная плата, имеющая кроме разъема VGA также интерфейс HDMI. Тем не менее 4-битовый цвет в каждом канале обеспечивает 4096 цветов на экране. Видеосигнал, готовый для отправки в видеоЦАП, может быть также использован совместно с преобразователями VGA-HDMI. На-
338 Г л а: пример, микросхема ADV7511 используется в отладочных платах таких как КС705 и Zedboard, принимая на входе поток данных' представляющие цвета пикселов и сигналы синхронизации. Выходы микросхемы подключаются к разъему HDMI. Таким образом подготовка данных в формате VGA позволяет подключаться как к разъему VGA DB15, так и к конвертеру VGA-HDMI при наличии соответствующей микросхемы. Особенностью видеоконтроллера является необходимость постоянного хранения данных и отсылки их в порт. Для этого удобно использовать блоки накристалльной памяти ПЛИС, с учетом их двухпортового интерфейса. Тогда видеоконтроллер мог бы быть организован, как показано на рис. 6.37. Видеоконтроллер, формирующий сигналы синхронизации, вычисляет также адрес пиксела, хранящийся в Запись видеоданных. Pixel clock BRAM Видеоданные "Адрес пиксела Контроллер vsync; Рис. 6.37. Принцип организации видеоконтроллера на базе внутренней памяти ПЛИС BRAM. Прочитанные данные могут быть поданы непосредственно на выход, если их разрядность выбрана совпадающей с разрядностью подключенного к выходу преобразователя. Второй порт памяти удобно использовать в этом случае для обращения к массиву ячеек для записи данных (при необходимости — и чтения). Независимые тактовые входы портов памяти делают возможным установку частоты внешнего интерфейса отличной от частоты Pixel Clock. Однако в этом случае возникает важный вопрос. Блоки накристалльной памяти ПЛИС являются достаточно дефицитным ресурсом, поэтому их использование для хранения пикселов одного кадра может оказаться расточительным. В табл. 6.5 приведены размеры памяти, необходимые для хранения пикселов одного кадра в некоторых видеорежимах. Для удобства эти размеры пересчитаны также в число требуемых блоков памяти 36 кбит с округлением вверх. Таблица 6.5 Размер памяти, необходимый для хранения кадра в некоторых видеорежимах Видеорежим 320x200 | 640x480 800x600 1280x720 1920x1080 Память, бит (блоков 36 кбит) : 1- i .——— для 1-битового цвета для 3-битового цвета для 24-битового цвета 64 000 B) 307 200 (9) 480 000 A4) 921 600 B5) 2073 600 E7) 192 000 F) 921 600 B5) 1440 000 D0) 2764 800 G5) 6220 800 A69) 1536 000 D2) 7372 800 B00) 11 520 000 C13) 22 118 400 F00) 49 766 400 A350)
Примеры реализации схем на базе ПЛИС 339 Из табл. 6.5 видно, что блочную память ПЛИС в принципе мож- но использовать для хранения данных видеорежимов низкого разрешения или монохромного видеорежима. В этом случае на базе ПЛИС можно создать информационную панель или инструмент для отладки, выводящий сигналы непосредственно на дисплей, подключаемый к ПЛИС. Для использования видеорежимов высокого разрешения требуется внешняя видеопамять. Существенной проблемой здесь является подключение этой памяти, особенно если речь идет о памяти DDR2/3/4. Пример реализации контроллера VGA показан ниже. Для платы Digilent Arty можно использовать накристалльную блочную память для хранения экрана размером 320x240 пикселов при 12-разрядном цвете. Установленный режим — 640x480, поэтому каждый пиксел, хранящийся в памяти, выводится на экран размером 2x2. Для контроллера реализован простой внешний интерфейс, состоящий из тактового сигнала, шин адреса и данных, а также сигнала wrio — разрешения записи. Для модуля требуется отдельный тактовый сигнал clk.vga. library IEEE; use IEEE.STD_LOGIC.1164.ALL; use IEEE.NUMERICJ5TD.ALL; entity vga is generic(BASEADDR : integer := 75000; BASEADDRMEM : integer := 100000; MAXVIDEO : integer := 76800 ); Port ( — интерфейс внешнего контроллера elk : in STD_LOGIC; addr : in STD_LOGIC_VECTOR A9 downto 0); data : in STD.LOGIC.VECTOR C1 downto 0); wrio : in STD.LOGIC; - VGA clk_vga : in STDJLOGIC; r : out STD_LOGIC_VECTOR C downto 0); g : out STD-LOGICVECTOR C downto 0); b : out STD.LOGIC.VECTOR C downto 0); vs : out STDJLOGIC; hs : out STDJLOGIC ); end vga; architecture Behavioral of vga is type TVideo is array @ to MAXVIDEO - 1) of stdJogic_vector(ll downto 0); "" видеопамять описана как shared variable
340 — это требуется для обращения к ней сю стороны — двух интерфейсов — память инициализирована, чтобы при включении ~ можно было визуально контролировать — работоспособность shared variable Video : ТVideo := ( 0 to 6399 => x"F00'\ 6400 to 12799 => xF0", others => x00" ); signal vent : integer range 0 to 525 := 0; signal hent : integer range 0 to 800 := 0; signal we_ram : stdJogic; signal vdatajiet : std_logicvector(ll downto 0); signal vaddr, wraddrcpu : integer range 0 to (MAXVIDEO - 1) * 2; begin — счетчик для горизонтальной синхронизации process(clk_vga) begin if rising_edge(clk>vga) then if hent = 799 then hent <= 0; else hent <= hent + 1; end if; end if; end process; — счетчик для вертикальной синхронизации process(clk-vga) begin if rising_edge(clk_vga) then if hent = 799 then if vent = 524 then vent <= 0; else vent <= vent -f 1; end if; end if; end if; end process; vs <= '0' when vent > = 10 and vent < 12 else 'I1; hs <= '0' when hent > = 16 and hent < 112 else '1'; wraddrcpu <= toJnteger(unsigned(addr)) - BASEADDRMEM; we_ram <= T when (wrio = T) and (toJnteger(unsigned(addr)) > BASEADDRMEM) else '0'; vaddr <= (((vent - 45) / 2) * 320 + (hent - 160) / 2) when vent >= 45 and hent >= 160 else 0; process(clk) begin if rising-edge(clk) then
ации схем на базе ПЛИС 341 if we_ram = '1' then Video(wraddrcpu) := data(ll downto 0); end if; end if; end process; process(clk_vga) begin if rising_edge(clk_vga) then vdatajiet <= Video(vaddr); end if; end process; r <= vdata_net(ll downto 8) when vent > = 45 and hent > = 160 else (others => '0'); g <= vdata_netG downto 4) when vent > = 45 and hent > = 160 else (others => '0'); b <= vdata_netC downto 0) when vent > = 45 and hent > = 160 else (others => '0'); end Behavioral; Листинг. Пример видеоконтроллера VGA Компания Xilinx предлагает готовые IP-ядра для использования внешней памяти для хранения данных кадра. Например, IP-ядро AXI Video DMA. Самостоятельная реализация подобного контроллера представляет повышенную сложность и не является предметом рассмотрения данного издания. 6.18. Планирование сигналов сброса Сброс регистров в заранее определенное состояние является нормальной практикой проектирования цифровых систем. Это устраняет неопределенность, которая могла бы возникнуть при разнообразных процессах в момент включения питания, и широко практикуется при построении самых разных узлов. При разработке заказных микросхем сброс синхронных компонентов является обязательным. Те же соображения применимы и для FPGA, однако здесь имеется важное дополнение. Сами микросхемы FPGA уже имеют схемы сброса, и установка всех синхронных компонентов в начальное состояние является частью процесса загрузки конфигурации. Поэтому попытка установить все регистры в начальное состояние при старте проекта будет просто дублированием тех действий, которые только что были проведены. Может показаться, что это несущественная Деталь, которая просто увеличивает надежность проекта, однако на рис. 6.38 можно ознакомиться с примером трассировки избыточного сигнала сброса. Разумеется, такой сигнал вряд ли сделает трассировку проекта невозможной, однако эти линии могут занять места,
342 Глав а б Рис. 6.38. Трассировочные ресурсы, затраченные на избыточный сигнал сброса (пример из материалов ХШпх) которые в ином случае были бы использованы для трассировки более критичных к задержкам сигналов. При выборе типа сброса необходимо иметь в виду, что не все аппаратные ресурсы ПЛИС могут реализовать сброс по тому описанию, которое введет разработчик. В табл. 6.6 перечислены потенциальные проблемы описания сброса при синтезе. В целом можно придерживаться следующих соображений: 1. Лучйим приемом является отказ от глобального сброса, поскольку он уже реализован в ПЛИС. 2. Локальные сигналы сброса, если они необходимы для проекта, должйы быть синхронными и использовать высокий логический уровень. Исключением из общего ряда является аппаратный контроллер FIFO, входящий в состав блоков BRAM36. Он имеет асинхронный сброс, который требуется удерживать в течение пяти тактов. Таблица 6.6 Потенциальные проблемы использования сброса при синтезе Нет сброса Оптимальный вариант, нет ограничений Синхронный сброс Невозможен для массивов памяти: препятствует синтезу BRAM, распределенной памяти и сдвиговых регистров на базе LUT Асинхронный сброс Невозможен для массивов памяти: препятствует синтезу BRAM, распределенной памяти и сдвиговых регистров на базе LUT Невозможен для регистров блоков DSP48 и выходных регистров BRAM
Лрямеры реализации схем на базе ПЛИС 343 При поведенческом описании сигналов можно использовать инициализацию, например: signal х : std_logic_vectorG downto 0) := 0000001"; Это описание гарантирует, что установленное пользователем значение будет загружено в регистр х при инициализации ПЛИС. 6.19. Учет наборов управляющих сигналов для серии 7 В логических ячейках ПЛИС серии 7 имеется особенность, влияющая на результаты синтеза. В каждой секции этих ПЛИС имеется 8 триггеров. Тактовые сигналы, сигналы разрешения записи и сброса всех этих триггеров объединены. Совокупность сигналов elk, се и sr (set/reset) называется управляющим набором (control set). Можно уточнить, что речь идет не просто о том, что все триггеры должны использовать одинаковый логический уровень, а о физическом соединении таких сигналов. Это не является проблемой при построении многоразрядных регистров, у которых перечисленные сигналы действительно одни и те же, однако воспрепятствует размещению в одной секции триггеров, реализующих различные варианты поведения или хотя бы использующих сигналы с разными именами. Синтезаторы автоматически разрешают эти конфликты без необходимости специального вмешательства, однако для критических узлов может возникнуть ситуация, когда разработчик будет рассчитывать на плотную упаковку триггеров, однако на кристалле триггеры будут разнесены по разным секциям. Нельзя с уверенностью утверждать, что именно неаккуратное обращение с управляющими наборами может стать причиной провала проекта. Однако при необходимости низкоуровневой оптимизации знание о данной особенности серии 7 обязательно. Чтобы обеспечить возможность размещения триггеров в одной секции, можно унифицировать их схему включения. На рис. 6.39 показаны некоторые преобразования, которые позволяют превратить обычный триггер в триггер, использующий управляющие сигналы. Если провести такие преобразования, то три варианта триггера могут быть реализованы в одной секции, но при условии добавления к ним логических ресурсов, которые могут быть взяты в LUT, связанных с этими триггерами. Синтезаторы автоматически используют управляющие входы триггеров по мере возможности, однако для этого следует соблюдать соответствующие шаблоны описания. В табл. 6.7 показаны варианты описания триггера с сигналом разрешения записи. В пер-
344 Глава б Проект FPGA D , Ssef D •¦ - Sresei Рис. 6.39. Некоторые виды преобразований для сокращения числа управляющих наборов в триггерах Таблица б 7 Шаблоны описания триггеров с использованием сигнала разрешения записи Синтезируется аппаратный вход се process(clk) begin if rising_edge(clk) then if се = '1' then q <= a; end if; end if; end process; Поведение ее эмулируется в LUT process(clk) begin if rising.edge(clk) then q <= ((ce and a) or (not ce and q); end if; end process; bom случае будет использован аппаратный вход се, а во втором — его поведение эмулируется с привлечением комбинационной логики в LUT. В целом учет наборов управляющих сигналов не представляет собой критическую проблему, требующую постоянного внимания. Однако если разработчик информирован о такой особенности ячеек ПЛИС, это поможет идентифицировать проблемы с плотной упаковкой триггеров в КЛБ, если этому препятствуют разные наборы управляющих сигналов. 6.20. Умножение Умножение может быть реализовано в FPGA несколькими способами в зависимости от требуемых характеристик разрядности перемножаемых операндов и производительности. FPGA Xilinx (начиная с Virtex-II и Spartan-З) имеют на кристалле аппаратные блоки, вьшолняющие умножение независимых операндов на системной тактовой частоте. Часто использование этих блоков является оптимальным решением с точки зрения производительности, используемых ресурсов и потребляемой мощности. В то же время существую* и альтернативные подходы к реализации умножения: • умножение с помощью таблиц;
Примеры реализации схем на базе ПЛИС 345 • последовательные или параллельные умножители на базе логических ячеек FPGA. 6.20.1. Умножение с помощью компонентов DSP48 Для того чтобы САПР могла включить аппаратные ресурсы в проект, следует соблюдать определенные шаблоны описания на уровне RTL. Наиболее простым является использование умножителей и аккумуляторов в блоках DSP48. Описание математической операции умножения ведет к построению схемы на базе этого блока: process(clk) begin if rising_edge(clk) then sum <= sum + a * b; end if; end process; Данное описание не потребует логических ячеек для реализации, поскольку вся описанная функциональность может быть реализована блоком DSP48. В зависимости от разрядности операндов и результата может потребоваться больше одного блока. Можно напомнить, что DSP48 имеет архитектуру 18x25 = 48, т.е. умножает операнды разрядностью не более 18 и 25 битов (для первого и второго операндов соответственно) и помещает результат в 48-битовый аккумулятор. Альтернативным вариантом является подход component instantiation, где разработчик может принудительно установить в проект компонент DSP48 и подключить к нему сигналы. Однако сложная внутренняя структура такого компонента и наличие большого числа параметров делает этот процесс достаточно трудоемким. При необходимости рекомендуется изучить соответствующее руководство разработчика (например, UG479 — «7 Series DSP48E1 Slice User Guide»). 0 Рекомендуется описывать умножение оператором *, давая возможность синтезатору использовать компоненты DSP48. 6.20.2. Умножение с помощью таблиц Умножение с помощью таблиц является полезным приемом, который может сэкономить дефицитные аппаратные умножители, если разрядность перемножаемых чисел невелика. Например, при умножении двух 4-разрядных чисел суммарная разрядность операндов составляет 8 и для хранения таблицы умножения достаточно 256 памяти. По сути два операнда, составленные вместе, могут
346Гла ва рассматриваться как адрес ячейки памяти, где хранится результат их умножения. Если объем такой памяти невелик, можно использовать компоненты BRAM вместо DSP48. Однако при росте суммарной разрядности объем памяти может оказаться непомерно боль- шим. Например, умножение двух 8-разрядных операндов потребует уже 216 — 65536 ячеек, которые к тому же должны хранить 16- разрядные результаты. Для этого потребуется уже 32 компонента BRAM. Умножение 16-разрядных операндов потребует уже хранения 4 Гслов данных, каждое из которых имеет размер 32 бита. Умножение с помощью таблиц применимо, если размеры операндов невелики и использование DSP48 выглядит расточительным. Следует позаботиться о генерации содержимого памяти, которая будет хранить таблицу умножения с учетом разрядностей операндов. Разработчик имеет возможность самостоятельно оценивать целесообразность замены DSP48 на BRAM, ориентируясь на доступные ресурсы ПЛИС. 6.20.3. Умножение на константу Умножение на константу может предоставить разработчику дополнительное пространство для маневра при дефиците ресурсов ПЛИС. Если только один из операндов операции умножения является независимым, а другой известен и является константой, то можно рассматривать некоторые полезные приемы, экономящие блоки DSP48. Самый простой вариант умножения — умножение на степени двойки. Действительно, сдвиг двоичного числа на один разряд влево соответствует его умножению на 2, сдвиг на два разряда — умножению на 4 и т. д. Кроме того, рассмотрим такое выражение: Result <= а * 4 + а * 2; Очевидно, что результат эквивалентен выражению а*б, где константа разложена на два слагаемых, каждое из которых является степенью двойки. Выражение можно переписать с применением операторов сдвига: Result <= (a shl 2) + (a shl 1); Кроме сложения, можно рассматривать и вычитание. Например, 7 можно представить как 8—1. В общем случае многие числа представляются суммой или разностью операндов, являющихся степенью двойки.
Примеры реализации схем на базе ПЛИС 347 Таблица 6.8 Представление некоторых констант в или 3 = 5 = б = 7 = 9 = разности слагаемых 0 1 2 1 Н 4 4 Н 4 Н 8- 8 8 Н Ь 2 к 1 г 2 - 1 к 1 10 = 8 4 12 = 8 Ч 14 = 16 - 15 = 16 - 16 17 = 16 - 18 = 16 - - 2 - 4 -2 - 1 f 1 f 2 , являющихся 20 = 16 + 4 24 = 16 + 8 28 = 32 — 4 виде суммы [ степенями 2 30 = 32 ¦ 31 = 32 - 32 33 = 32 Н 34 = 32 И 36 = 32 Н - 2 - 1 h 1 h 2 Ь4 Таблица 6.9 Пример таблицы для умножения независимого операнда на 3 X 0 1 2 3 х*3 0 3 6 9 Можно рассматривать и три компонента, комбинируя сложение и вычитание. Это несколько усложняет схему, поэтому целесообразность применения такого приема оказывается зависящей от множества факторов, включая наличие свободных компонентов DSP48, глобальных целей оптимизации проекта и возможностью потратить дополнительное время на проверку характеристик получаемых умножителей на константу. При умножении на константу можно обратиться к уже рассмотренному умножению с помощью таблиц. Если один из операндов представляет собой константу, то разрядность адреса таблицы определяется разрядностью только одного независимого операнда, а не суммой разрядностей. Например, при умножении на 3 достаточно иметь таблицу (табл. 6.9). Аналогично предыдущим подходам, целесообразность применения табличного умножения на константу зависит от соотношения используемых ресурсов ПЛИС и того, какие из компонентов, память или DSP48, имеются в большем числе. 6.20.4. Последовательное умножение Последовательное умножение (serial multiplication) реализуется на базе логических ячеек ПЛИС. Для иллюстрации такого подхода можно рассмотреть умножение двоичных чисел в столбик (рис. 6.40). Из этого рисунка видно, что при умножении числа на 1 результатом является само число, а при умножении на 0 результатом является 0. Для получения таких произведений достаточно выполнить операцию логическое И над первым операндом и одним из разрядов второго операнда. Сдвинув полученные результаты, как показано на рис. 6.40, их необходимо сложить. Операция 110010 1101 , 110010 ,000000 ,110010 * 110010 1010001010 Рис. 6.40. Умножение двоичных чисел в столбик сложения с
348 одновременным сдвигом операндов может быть повторена послед вательно в течение N тактов, где N соответствует разрядности вто- рого из операндов. Пример модуля, выполняющего последователь- ное умножение по алгоритму «сдвиг-сложение», показан в листинге Сигнал start используется для загрузки операндов во внутренние ре^ гистры и обнуления регистра, хранящего результат. Регистр, хра- нящий первый операнд, имеет увеличенную разрядность, так как его значение будет сдвигаться влево, для чего требуются дополна- тельные разряды. library IEEE; use IEEE.STDJiOGIC.1164.ALL; use IEEE.NUMERICJ3TD.ALL; entity serial_mult is Port (elk : in STD.LOGIC; a : in STD .LOGIC-VECTOR G downto 0); b : in STDXOGIC.VECTOR G downto 0); start : in STD-LOGIC; q : out STDJjOGICLVECTOR A5 downto 0)); end serialjnult; architecture Behavioral of serial_mult is signal ajreg : std_logicvectorA5 downto 0) := (others => '0'); signal b_reg : stdiogic_vectorG downto 0) := (others => '0'); signal ace : stdJogicvectorA5 downto 0) := (others => '0'); begin process(clk) begin if rismg-edge(clk) then if start = '1' then ace <= (others => '0'); ajreg <= xH00" & a; b_reg <= b; else if bjreg(O) = T then ace <= stdJogic>vector(to.unsigned(toJnteger(unsigned(acc)) + to_integer(unsigned(ajreg)), ace'length)); end if; ajreg <= a_regA4 downto 0) 8c '0'; bjreg <= '0* & bj:egG downto 1); end if; end if; end process; q <= ace; end Behavioral;
реализации схем на базе ПЛИС 349 Рис. 6.41. Временные диаграммы сигналов последовательного умножителя Временные диаграммы сигналов при умножении показаны на рис. 6.41. Видно поведение регистра b_reg, который каждым тактом сдвигается на один разряд вправо. Также видно, что значение сигнала аккумулятора увеличивается на тех тактах, когда младший разряд регистра bjreg равен *1\ Последовательное умножение реализуется с помощью логических ячеек ПЛИС и не требует аппаратных блоков умножения. Если операнды имеют различающуюся разрядность, существует возможность выбора, какой из операндов будет использоваться в качестве слагаемого, а какой — управлять необходимостью сложения. Из примера видно, что число тактов для умножения равно разрядности второго операнда. Необходимо иметь в виду, что алгоритм применим для умножения беззнаковых чисел. Числа, представленные в формате дополнительного двоичного кода, будут перемножены в соответствии с их беззнаковым представлением, т. е. 8-разрядное число «-1» будет воспринято как 255. 6.20.5. Реализация параллельного умножения на базе логических ячеек ПЛИС Умножение чисел в столбик можно выполнять и параллельно, имитируя работу умножителя в блоке DSP48. Если выполнять все операции сложения, показанные на рис. 6.40, параллельно, результат можно получить без необходимости ожидания задержки в N тактов. Сложение N чисел можно произвести разными способами, од-
350 Г ла: А[7:0] | Установка регистров повышает • J частОту, но увеличивает число тактов до получения результатов Рис. 6.42. Умножение с помощью дерева сумматоров (adder tree) нако наименьшая длина последовательной цепочки сумматоров получается при реализации так называемого дерева сумматоров, показанного на рис. 6.42. На входе схемы находится цепочка однобитовых умножителей, реализованных на базе вентилей 2И. Чтобы умножить операнд А на В[0], для каждого из разрядов А нужно выполнить операцию «логическое И» с сигналом В[0]. Проводя такую же операцию с разрядами В[1]... В[7], можно получить промежуточные результаты умножения, показанные на рис. 6.40. Складывая их попарно, можно получить итоговый результат, имея log2N слоев сумматоров, где N — разрядность операнда В. Для больших разрядностей В потребуется 4 или 5 слоев сумматоров. Это приведет к увеличению суммарной задержки через такую цепочку, и тактовая частота умножителя, реализованного на логических ячейках ПЛИС, окажется ниже, чем у блока DSP48. Установка регистров (показаны на рис. 6.42 пунктиром) между слоями сумматоров повысит тактовую частоту умножителя, однако увеличит число тактов до получения результата. При этом новые операнды могут подаваться на вход такой схемы каждый такт, поэтому такое решение вполне пригодно для систем цифровой обработки сигналов, которые обрабатывают потоки данных и не слишком критичны к числу тактов, проходящих от подачи входных сигналов до появления на выходе соответствующего результата. Щ Прототипирование блоков умножения в ПЛИС не гарантирует получения качественных результатов в СВИС Синтез дерева сумматоров не является гарантией качественного размещения такой сложной схемы на полупроводниковом кристалле с сохранением коротких связей между блоками. Даже при реализации показанной схемы» умножителя в ПЛИС следует проверять взаимное Vй3'
Ярямеры реализации схем на базе ПЛИС 351 мещение сумматоров, образующих дерево. Рекомендуется использовать IP-ядра, сопровождаемые топологическими ограничениями (area constraints), регулирующими взаимное расположение компонентов умножителя для достижения качественных результатов трассировки. Альтернативные варианты реализации умножения могут помочь выбирать эффективные способы использования ресурсов ПЛИС, комбинируя блоки DSP48, память и логические ячейки. @ Не следует использовать встроенные сумматоры блоков DSP48 для построения дерева сумматоров. На кристалле ПЛИС существуют выделенные трассировочные ресурсы, ускоряющие сложение с помощью цепочки (chain). Принудительное соединение DSP48 в виде дерева даст худшие результаты. 6.21. Деление В цифровой схемотехнике в общем случае не применяется одно- тактное деление независимых операндов. Как и для умножения, при делении можно использовать таблицы результатов (при небольших разрядностях операндов) или последовательное деление, реализуемое с помощью логических ячеек. Рассмотрим алгоритм деления. Так же, как и 110010 I 101 при умножении, можно воспользоваться делением в 101000 t»lQИ) столбик (рис. 6.43). 1010—^/ I При делении целых чисел образуется частное и 010 I остаток. Для реализации деления регистры иници- 0 — ализируются так, чтобы расширить их до двойной Рис. 6.43. разрядности. При этом для делимого старшие раз- Деление ряды дополняются нулями, а делитель изначально двоичных ^ w чисел в сдвигается влево, чтобы старший разряд соответст- столбик вовал старшему разряду расширенного делителя. Пример модуля, реализующего последовательное деление, приведен ниже. library IBBE; use IEEE.STDJLOGICU164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STDJLOGIC.UNSIGNED.ALL; entity div32 is Port (elk : in STD.LOGIC; a : in STD_LOGIC_VECTOR C1 downto 0); b : in STDXOGIC.VECTOR C1 downto 0); start : in STDJLOGIC; q : out STD_LOGIC_VECTOR C1 downto 0);
352 Глав а б qr : out STD_LOGICLVECTOR C1 downto 0)); end div32; architecture Behavioral of div32 is signal divst : integer range 0 to 34 := 0; signal diva, divb : stdJogicvectorF3 downto 0); signal wdiv, rdiv, rrem : stdJogic_vectorC1 downto 0); begin process(clk) begin if rising^edge(clk) then case divst is when 0 => if start = 'Г then diva <= ext(a, 64); divb <= b & x0000000"; wdiv <= (others => '0'); divst <= 1; end if; when 1 to 33 => if diva > = divb then wdiv <= wdivC0 downto 0) & '1'; diva <= diva - divb; else wdiv <= wdivC0 downto 0) & '0'; end if; divb <= '0' & divbF3 downto 1); divst <= divst + 1; when 34 => rdiv <= wdivC1 downto 0); rrem <= divaC1 downto 0); divst <= 0; when others => divst <= 0; end case; end if; end process; q <= rdiv; qr <= rrem; end Behavioral; Листинг. Модуль последовательного деления с остатком Приведенный способ реализации деления является простейшим, копирующим известный алгоритм деления в столбик. В зависимости от требований проекта, ресурсов и приоритетов возможно применение других алгоритмов деления, в том числе используют^ специфику операндов. В составе библиотеки Vivado имеется IP-ядро модуля деления целых чисел. Внешний вид диалогового окна настройки показан на рис. 6.44.
Лримеры реализации схем на базе ПЛИС 353 :»3tOr E.1) L Рис. 6.44. Диалоговое окно настройки IP-ядра модуля деления Операция деления является ресурсоемкой по сравнению с операцией умножения, и тем более по сравнению со сложением и вычитанием. Кроме того, она требует больше тактов для реализации (обычно не менее N тактов для N-разрядного результата), поэтому применение деления в проектах следует ограничивать, несмотря на то, что оно прочно ассоциируется с «простейшим арифметическим Действием», находясь в одном ряду с известными еще с начальной Я1колы операциями сложения, вычитания и умножения. 6.22. Операции с плавающей точкой Формат представления чисел с плавающей точкой (floating Point) широко распространен в вычислительной технике. Его основным преимуществом является большой дигшазон представления , подходящий для различных областей науки и техники.
354 Гла: Рассмотрим сначала формат с фиксированной точкой. Он на зван так потому, что для двоичного числа можно представить, ч^ часть его младших разрядов отделена двоичной точкой и число имеет разряды не только с положительной степенью двойки, но и с отрицательной. Такие степени обрабатываются так же, как и положительные. Ниже приведены веса отдельных разрядов двоичного числа, у которого три младшие разряда отделены точкой: Номер разряда 4 Вес разряда | 16 3 8 2 4 1 2 0 1 -1 1/2 -2 1/4 -3 1/8 При показанной нумерации разрядов двоичное число 10001.010 будет переведено в десятичный вид как 1*16 + 1*1 -hi* 1/4 = 17,25. Двоичная точка отделяет три младших разряда, поэтому число, показанное в примере, может обозначаться как 5.3, где 5 — число разрядов до двоичной точки, а 3 — число разрядов после нее. Сложение и вычитание чисел с фиксированной точкой выполняется по тем же правилам, что и для целых чисел, однако число разрядов, отделяемых двоичной точкой, должно быть одинаково. Если это не так, одно из чисел следует сдвинуть влево до совпадения положения двоичной точки. При умножении числа могут быть перемножены без сдвига двоичного представления. Однако двоичная точка должна отделять столько разрядов в результате, сколько было отделено точкой у операндов в сумме. Т.е. при умножении чисел формата 8.8 и 8.4 результат будет иметь 28 разрядов, из которых 12 (84-4) должны быть отделены точкой, т.е. итоговый формат представляется как 16.12. Двоичная точка сама по себе никак не представляется в аппаратуре. Разработчик самостоятельно приписывает разрядам двоичные веса, и именно разработчик ответственен за интерпретацию результата. Формат с фиксированной точкой дает возможность представлять дробные числа, однако у него имеется недостаток, схожий с недостатком целых чисел. Рассмотрим сложение чисел 27 и 2" • Первое число выглядит в двоичном представлении как 10000000, а второе, с учетом разрядов после двоичной точки, как 0.00000001- Чтобы иметь возможность сложить эти числа, их необходимо записать в одинаковом формате, т. е. оба числа должны иметь 8 разрядов до точки и 8 после нее. Поэтому для фиксированной точки возникает проблема увеличения разрядности, если необходимо представ-
{[рямеры реализации схем на базе ПЛИС 355 д^ть числа, существенно отличающимися по величине. С учетом того, что в технике числа могут иметь диапазон от величин микромира «о величин, описывающих характеристики Вселенной, разрядность числа с фиксированной точкой, способного представить любую величину, которая могла бы иметь практический смысл, очень велика. Принимая приближенно, что 3 десятичных разряда A03 = 1000) соответствуют 10 двоичным B10 — 1024), и рассматривая числа от постоянной Планка до числа атомов во Вселенной, можно получить разницу десятичных порядков на уровне 110-120, что эквивалентно примерно 400 разрядам двоичного числа. Вместо резервирования избыточного числа разрядов можно записать только старшие значащие разряды двоичного представления и отдельно указать, какому положению соответствует старший разряд полученной записи. Например, в записи 0.00000101 старшие нули могут быть отброшены, так как не являются значащими. Однако чтобы понять, сколько разрядов было отброшено, необходимо отдельно записать это число. Соответственно, формат представления чисел с плавающей точкой состоит из мантиссы (М) и порядка (Б). Зная эти компоненты, можно получить число как X = М * 2Е. Для мантиссы отдельно представляется знак (S). В общем виде число с плавающей точкой записывается в двоичном виде в нескольких распространенных форматах, показанных на рис. 6.45. Например, для формата single порядок записывается в 8 разрядах, а мантисса — в 23. Однако с учетом того, что мантисса записывается в нормализованном виде, т.е. S Е , 5 « 8 » М Ю (+1) „ „ 23 (+1) ,, Half A6) Single C2) Double F4) Рис. 6.45. Распространенные форматы записи числа с плавающей точкой ее старший значащий разряд всегда равен 1, этот разряд можно не хранить. Поэтому к 23 разрядам, отведенным для хранения мантиссы, следует добавить еще один. Такой подход соблюдается для всех показанных форматов представления чисел. Считается, что мантисса лежит в диапазоне от 1/2 до 1. Если смещение двоичной точки не требуется, то порядок принимается равным половине возможного Диапазона, т. е. для числа одинарной точности с 8-разрядным порядком отсутствие смещения представляется числом 127. При сложении и вычитании чисел с плавающей точкой необходимо сначала совместить положение точки. Для этого мантисса числа, порядок которого меньше, сдвигается вправо на величину
356 Г л а ва Л01Ш1 ^ ;Jl01E2 ^ СП«>+.0101)Е2 - 1.0001Е2 - 1.0001Е2 = ЛОООЕЗ Выровнять Сложить Нормализовать порядки мантиссы Рис. 6.46. Сложение чисел с плавающей точкой разницы порядков (В2 — В1). После этого можно складывать или вычитать мантиссы. Однако после сложения мантисс может оказаться, что результат не помещается в разряды, отведенные для хранения мантиссы, В этом случае необходимо выполнить нормализацию, т. е. привести мантиссу к диапазону 1/2.. 1. Порядок сложения чисел с плавающей точкой проиллюстрирован на рис. 6.46. На рис. 6.45 можно увидеть, что при выравнивании порядков младший разряд второго слагаемого оказался потерян, так как вышел за границы разрядной сетки, отведенной для хранения мантиссы. Такое поведение является некоторой проблемой для чисел с плавающей точкой и известно программистам как потеря точности и связанное с этим понятие машинного нуля. Под машинным нулем понимается такая величина х, прибавление которой к 1 не изменяет двоичное представление результата в формате с плавающей точкой. Это легко понять, если представить сложение чисел, порядки которых отличаются больше, чем на размер мантиссы. Тогда при попытке совместить двоичные точки все значащие разряды мантиссы меньшего по модулю числа окажутся за пределами разрядной сетки и при сложении мантисс первое число сложится с нулем. Проблема потери точности при операциях с плавающей точкой является объективным следствием выбранного формата представления этих чисел. При вычислениях следует иметь в виду данный эффект, который не имеет гарантированного способа устранения. Возможную потерю точности следует учитывать при анализе результата. При умножении чисел с плавающей точкой их мантиссы перемножаются, а порядки складываются (аналогично тому, как это происходит при умножении чисел, представленных в десятичной записи). При делении, соответственно, мантиссы делятся, а порядок делителя вычитается из порядка делимого. Результат в том и другом случае может оказаться необходимо привести к нормализованному виду. Числа с плавающей точкой и операции с ними описаны в широко используемом формате IEEE754. Этот формат поддерживается большинством процессоров и содержит также информацию о
примеры реализации схем на базе ПЛИС 357 Рис. 6.47. Диалоговое окно настройки IP-ядра для работы с числами с плавающей точкой правилах округления результата и хранения некоторых специальных величин, например «бесконечность» и «не-число» (NaN, Not a Number). В силу широкой распространенности этих операций существует множество реализаций модулей для работы с числами с плавающей точкой. Их самостоятельная реализация чаще всего нецелесообразна из-за наличия оптимизированных IP-ядер, имеющих хорошие характеристики производительности и учитывающие особенности архитектуры ПЛИС. На рис. 6.47 показано диалоговое окно настройки IP-ядра для работы с числами с плавающей точкой. Это ядро поставляется с составе САПР Vivado и имеет широкий диапазон настроек, включая базовые арифметические операции, преобразования форматов и др. Поддерживаются как показанные на рис. 6.45 основные форматы представления чисел, так и формат, настраиваемый пользователем, в котором можно указать собственные значения разрядности мантиссы и порядка.
358 Глава б Необходимо учитывать, что операции с плавающей точкой обычно не выполняются за один такт. IP-ядро в САПР Vivado предлагает различные варианты латентности для выполнения конкретной операции, в зависимости от которых могут быть получены разные результаты по тактовой частоте и числу используемых ресурсов. Можно указать важную причину для использования чисел с плавающей точкой — большой диапазон возможных значений для обрабатываемых чисел, который сложно записать в целочисленном формате или формате с фиксированной точкой. Например, такие формулы, как вычисление энергии электрона Е — eU или энергии кванта Е = fw оперируют со значениями, существенно различающимся по значению десятичного порядка. Заряд электрона равен 1,6 • 10~19 Кл, а постоянная Планка Н = 6,626 • 10~34 Дж-с, тогда как разность потенциалов и особенно частота электромагнитной волны существенно больше. Подобные формулы очевидно требуют чисел с плавающей точкой для представления отдельных составляющих. Можно отметить, что при умножении не происходит потеря точности, так как мантиссы можно перемножать без необходимости их взаимного сдвига. 6.23. Трансцендентные функции В математике используется большой набор трансцендентных функций. Согласно определению, трансцендентной называется функция, которую невозможно представить в виде алгебраических выражений (т. е. с помощью полиномов, которые выражаются через умножения и сложения). Поэтому реализация четырех базовых арифметических операций (сложения, вычитания, умножения и деления) не позволяет выразить с их помощью точные значения логарифма, показательной функции ах или тригонометрических функций. Компромиссным вариантом является использование разложения в ряд для представления трансцендентных функций. Например, известны ряды Тейлора, раскладывающие функцию в бесконечных ряд степенных функций. Однако достижение высокой точности требует вычисления большого числа членов ряда, к тому же при удалении от базовой точки, для которой было построено разложение, возрастает ошибка представления искомой функции. 6.23.1. Табличное представление трансцендентных функций Табличное представление является одним из простейших и применимо для любых функций. Если функция является алгебрай-
цримеры реализации схем на базе ПЛИС 359 ческой, ее табличное представление окажется существенно расточительнее по ресурсам по сравнению с вычислением на базе логических ячеек и, возможно, блоков DSP48. Однако для трансцендентных функций алгебраическое представление неприменимо. Целесообразность использования табличного представления функции напрямую зависит от разрядности ее аргумента. Для небольшой разрядности (8-12) вполне допустимо выделить таблицу в 256-4096 значений функции, напрямую записанных в память ПЛИС. Ресурсов блочной памяти вполне достаточно для представления таблиц таких размеров. Однако уже для 16-разрядного аргумента размером необходимого блока памяти нельзя пренебрегать, а для 32- разрядного аргумента потребуется хранение 4 Гслов, что является чрезмерным. Для тригонометрических функций sin, cos можно воспользоваться следующим их свойством: sin(a + j3) — sin a cos /3 -f cos a sin /3; cos(a + /?) = cos a cos /3 — sin a sin /3. Если представлять угол как сумму «грубого» утла а (например, от 0 до 90 с шагом в 1°) и «точного» угла /3 (например, от 0 до 1°с шагом в 0,01°), то для «грубого» угла потребуется таблица на 90 значений, а для «точного» — на 100. Вместе с тем приведенные формулы обеспечивают вычисление синуса или косинуса для 9000 возможных значений аргумента от 0 до 90 с шагом 0,01°. Для вычисления синуса или косинуса суммы потребуются также блоки умножения, однако такой подход позволит сократить размер памяти за счет привлечения блоков DSP48. Такие функции, как факториал или числа Фибоначчи, являются интересным примером применения таблиц для их представления. Несмотря на то что факториал часто приводится в качестве примера, демонстрирующего применение рекурсивного алгоритма, на практике диапазон возможных аргументов для факториала довольно мал. Например, уже 100! = 9,3326Е+157, поэтому для хранения практически используемых значений факториала достаточно небольшой таблицы. 6.23.2. Алгоритм CORDIC Алгоритм CORDIC (Coordinate Rotating Digital Computer, т. е. «цифровой вычислитель для вращения координат») представляет Удобный способ для точного вычисления тригонометрических функций без потери точности.
360 Глава Рис. 6.48. Иллюстрация к принципу работы алгоритма CORDIC Алгоритм основан на том, что црй вращении координат некоторого век* тора отслеживаются как угол поворота вектора, так и связанные с ним ко- ординаты конца этого вектора х, у} которые при единичной длине вектора представляют собой косинус и синус от угла поворота. Иллюстрация к алгоритму показана на рис. 6.48. При повороте вектора (х; у) с углом к оси абсцисс а на угол ср его новые координаты (xf\yf) станут равны: xf = cos(a + <р) = cos a cos ^ — sin a sin (р\ у' — sin(a Н- ф) = sin a cos ip -f cos a sin (p. Вынесем за скобку cos cp: x1 = yr = cosip(y- l + xtg(p). Выражение tg ip в скобках появилось из-за того, что при вынесении cos ip понадобилось сначала умножить sin ip на дробь cos ip/ cos p. Выражение cos (p в числителе оказалось возможным вынести за скобку, при этом оставшиеся sin <p/ cos (p образовали функцию tg <р. На первый взгляд, полученные выражения ничего принципиально не изменили. Однако условимся, что поворот будет производиться только на такие утлы, для которых tg<p равен целой степени двойки (т.е. 1, 1/2, 1/4, 1/8 и т.д.). В этом случае умножение xtg^ равносильно сдвигу х на 0, 1, 2, 3... позиции вправо. Аналогично выполняется вычисление у tg (p. Таким образом, умножение на синус и косинус в алгоритме оказалось заменено на умножение на 1 (благодаря вынесению за скобки cos x) и умножение на степени двойки, которое может быть выполнено сдвигом. Имея набор углов поворота <р, тангенсы которых равны целой степени двойки, можно последовательными поворотами на положительные и отрицательные утлы добиться того, чтобы суммарный угол поворота стал равен некоторому значению. Для этого необходимо учесть, что: х1 — cos(a — <р) = cos a cos (p -f sin a sin <p; у' — sin(a — <р) — sin a cos <? — cos a sin (p.
Примеры реализации схем на базе ПЛИС 361 Имея таблицу углов и проинициализировав х = 1, у = О, можно повернуть угол <р максимально близко к искомому углу <ро, заданному в качестве аргумента. Если после очередного поворота (р > <р0> то на следующей итерации алгоритма поворот происходит на отрицательный угол. Таким образом, методом последовательного приближения (р устремляется с^о» а его координаты х,у естественным образом представляют косинус и синус угла ip. Можно заметить, что на каждой итерации за скобки выносится cos </?, на которую производится умножение. Однако поскольку значения углов на каждой итерации известны, итоговое произведение можно вычислить заранее и учесть его при коррекции результата. Также можно инициализировать х значением, обратным произведению всех величин cosy?. Алгоритм является хорошо известным и его самостоятельная реализация хотя и возможна, но при первом приближении даст худшие результаты по сравнению с оптимизированным IP-ядром, входящим в поставку САПР Vivado. Внешний вид диалогового окна настройки этого ядра показан на рис. 6.49. Можно видеть, что ядро выполняет вычисление как синуса и косинуса (эти операции выполняется одновременно, поскольку данные функции являются проекциями одного и того же вектора), так и гиперболических синуса и Рис. 6.49. Диалоговое окно настройки IP-ядра для реализации алгоритма CORDIC
362 Глав, Характеристики некоторых Разрядность и функция 32, sin+cos 32, sin+cos 32, arctan 32, arctan вариантов IP-ядра CORDIC при в ПЛИС Kintex-7 Режим 1 ; Parallel Serial Parallel Serial Частота, МГц 418 260 330 260 Таблица б.ю реализации LUT —.. 3600 731 3487 665 косинуса sinh ж, cosh ж, а также арктангенса, гиперболического арктангенса и квадратного корня. Ядро обладает широкими возможностями параметризации, позволяя регулировать разрядность аргумента, управлять числом шагов, а также реализовывать этот компонент в последовательном или параллельном режиме. В параллельном режиме новый аргумент может быть подан на вход до завершения вычислений предыдущего аргумента, однако в этом случае размер существенно возрастает. Характеристики некоторых вариантов IP-ядра при реализации в ПЛИС Kintex-7 приведены в табл. 6.10. Сведения являются оценочными, поскольку отражают характеристики версии ядра в варианте, поставляемом в САПР Vivado 2018.3. Алгоритм CORDIC, в отличие от разложения в ряд, дает точные (в пределах разрядности) значения тригонометрических функций и может быть практически неограниченно расширен до требуемой точности. Он настоятельно рекомендуется как основной при необходимости вычисления тригонометрических функций в проекте. 6.24. Вычисление экспоненты Вычисление экспоненты базируется на формулах гиперболических функций: sinh я - (е* - е~*ж)/2; coshx = (е* + е~х)/2. Сложив левые и правые части этих уравнений, получаем: sinh х + cosh х — ех; cosh х — sinh х — е~х. Вычисление гиперболических функций может быть произведено с помощью алгоритма CORDIC с соответствующим оптимизированным IP-ядром. Однако особенностью этого алгоритма при вычислении гиперболических функций является ограниченный диапазон возможных аргументов. Дело в том, что вычисление этих функций происходит путем замены знаков в формулах поворота угла, в результате чего конец вектора движется по гиперболической
ации схем на базе ПЛИС 363 кривой с уравнением х2 — у2 — 1. При слишком больших значениях аргумента вектор, проведенный под таким углом, не пересечет гиперболическую кривую и результат последовательных поворотов вектора окажется некорректным. Для решения этой проблемы следует воспользоваться свойством степенных функций: Бели разложить аргумент экспоненты на два слагаемых, результирующую экспоненту можно будет вычислить как произведение двух составляющих. При этом одна часть аргумента может быть представлена в таблице, а вторая — получена с помощью алгоритма CORDIC через гиперболические функции. Первую часть аргумента следует выбирать, например, с шагом 0,5, т. е. задавать в таблице значения экспонент для аргументов 0,5, 1, 1,5, 2 и т.д. Поскольку экспонента быстро возрастает при росте аргумента (и быстро убывает для отрицательных аргументов), размер таблицы будет невелик и составит несколько десятков значений для 32-разрядного представления. 6.25. Простое процессорное ядро 6.25.1. Представление процессора в виде конечного автомата Конечный автомат (КА), рассмотренный в разд. 6.11, является полезным практическим приемом построения схем, реализующих последовательность каких-либо действий. В этом смысле КА является определенной альтернативой микропроцессору. Однако рассмотрение работы конечного автомата выявляет важную особенность — для изменения формы выходных сигналов требуется изменение его схемы. С учетом высокой стоимости изготовления заказных микросхем практически нереально создавать конечные автоматы с жестко заданным порядком работы для решения каждой частной задачи. В то же время видно, что формирование выходных сигналов осуществляется довольно регулярным способом — на основе анализа состояния автомата. Сделать КА более гибкой можно, если добавить таблицу с правилами перехода между состояниями, как показано на рис. 6.50. Рассмотренный в разд. 6.11 пример работы светофора можно легко модифицировать, если привязывать состояния сигналов светофора не к номеру состояния, а к коду, записанному в таблице.
364 Глав Логика изменения состояния > Таблица переходов Состояние > Рис. 6.50. Конечный автомат с таблицей переходов между состояниями Последовательный перебор адресов таблицы, начиная с 0, будет читать содержимое памяти, которое можно произвольно менять в процессе работы схемы. Тогда длительность удержания цветов, число миганий зеленого цвета и прочие параметры светофора могут быть исправлены простым изменением содержимого таблицы. Показанная на рис. 6.50 схема очень близка к процессору. Действительно, представим, что таблица переходов представляет собой память программы. Входной сигнал является адресом этой памяти, а содержимое (данные) — номером состояния, в который должен перейти КА. Остальная часть конечного автомата должна быть разработана таким образом, чтобы по коду команды вносить изменения в регистры конечного автомата. Такой подход позволяет изменять логику работы КА в определенных пределах. Следующим шагом является разработка простого процессорного ядра. Оно будет включать в себя основные компоненты, которые привычно видеть в процессоре: память программ, управляющее устройство, регистры и арифметико-логическое устройство. 6.25.2. Проектирование простого процессорного ядра Рассмотрим порядок проектирования простого процессорного ядра, при котором можно было бы наглядно проследить порядок проектирования и основания для принятия тех или иных решений. Проект процессора определяется следующими важнейшими составляющими: 1. Архитектура системы команд (АСК, также Instruction Set Architecture, ISA). На этом уровне описываются допустимые для процессора команды так, как они видны для программиста. Для описания АСК также используются программные модели процессора, описывающие набор регистров процессора, их разрядность, операции с ними, особенности и т. д. 2. Микроархитектура (аппаратная архитектура), описывающая порядок работы отдельных узлов процессора и их взаимодействие. Для простейшего варианта, демонстрирующего порядок проектирования, достаточно использовать такую же простую программную архитектуру, которая не будет содержать всего многообразия
ации схем на базе ПЛИС 365 RegA RegB PC RetA Регистры общего назначения Системные регистры Рис. 6.51. Регистровая модель примера процессора К узлам процессора Рис. 6.52. Структурная схема примера процессора регистров, привычных для программистов, однако продемонстрирует минимальный набор ресурсов, достаточный для запуска основных операций. Регистровая модель примера показана на рис. 6.51. Данная модель содержит всего два регистра общего назначения, определенных как RegA и RegB. Эти регистры будут использованы для выполнения основных арифметических и логических действий. Также в составе модели показаны системные регистры. Это PC (Program Counter), который хранит адрес команды процессора, и регистр RetA для хранения адреса возврата из подпрограммы. Хорошо известно, что хранение адресов возврата должно производиться в специальной структуре данных — стеке возвратов, что обеспечивает возможность вложенных вызовов (кроме того, стек используется и для размещения параметров подпрограмм). Тем не менее для простого примера будет достаточно и одного регистра, поскольку реализация доступа к стеку в памяти усложнит схему. Для узлов, использованных на рис. 6.52, можно выявить важную особенность. Среди действий процессора имеется команда перехода, которая, вообще говоря, может быть запрограммирована в произвольный момент времени. Однако без чтения команды непонятно, является ли она командой перехода, поэтому определить следующий адрес для выполнения невозможно. Далее будут рассмотрены варианты конвейеризованной микроархитектуры, однако для простоты можно принять, что каждая команда процессора будет выполняться за два такта (рис. 6.53). На первом такте процессор читает команду из ячейки памяти программ по адресу PC. На втором такте, имея в своем распоряжении код команды, на его основе можно определить, какой результат (и в какой регистр) записывать, а также адрес следующей команды.
366 Глава /Выборка4^ (Fetch; Периоды тактового сигнала Рис. 6.53. Временная диаграмма операций, выполняемых процессором для различных тактов Так же, как и для программной модели, в примере использован мак- симально простой подход, призванный продемонстрировать основные задачи решаемые при реализации процессора а также служить отправной точкой для последующих модификаций, превращающих данную схему в более распространенные на сегодняшний день микроархитектуры. Рассмотрим далее основные приемы кодирования процессного модуля на языке описания аппаратуры VHDL. Предполагается использование САПР Xilinx, например ISE или Vivado. В первом случае разработчики могут использовать дешевые ПЛИС семейства Spartan-б, которые не поддерживаются в более современной САПР Vivado. В обоих случаях используются САПР, имеющие вариант бесплатной лицензии и при этом обеспечивающие полный маршрут проектирования от ввода исходного текста до программирования ПЛИС. Первые этапы проектирования целесообразнее фокусировать на поведенческом моделировании, которое использует описание на уровне регистровых передач для построения диаграмм изменения сигналов цифрового устройства. В листинге приведено описание интерфейса примера процессора и объявление его основных ресурсов, доступных в регистровой модели для программиста. Раздел generic в объявлении задает два параметра, которые удобно иметь в подобном настраиваемом виде для проекта. Это размер памяти программ и размер памяти данных. Вынесение этих параметров в раздел generic позволяет изменить их впоследствии. Следует учесть, что в простом примере размеры памяти не являются произвольно изменяемыми, поскольку ряд особенностей архитектуры пока не позволяет превысить размер в 256 ячеек. Поэтому такие параметры носят в основном демонстрационный характер и обращают внимание на то, что глобальные параметры процессорного ядра могут регулироваться в помощью объявлений в разделе generic. В разделе port кроме очевидных сигналов elk и reset объявлена дополнительная группа сигналов, обеспечивающая интерфейс программирования памяти команд. Это простейший интерфейс, состоящий из шины адреса, шины данных и сигнала разрешения записи we.cmd. Объявление такого интерфейса кроме практической целя программирования процессора носит также определенный утиля-
Примеры реализации схем на базе ПЛИС 367 тарный характер. Дело в том, что если содержимое памяти программ будет являться фиксированным, при определенных условиях синтезатор в САПР может попытаться оптимизировать схему с учетом того, что процессор должен выполнять одну-единственную неизменяемую программу. Лавинообразная оптимизация может привести к тому, что какие-то важные узлы будут просто исключены из проекта, поскольку записанная в память программа их не использует. Очевидно, что этот эффект существенно уменьшит размер процессора по сравнению с действительным и внесет явные искажения в оценку характеристик полнофункционального ядра. Добавление интерфейса программирования не позволит синтезатору заменить память программ на ПЗУ (или даже на единственный регистр, хранящий 0), поэтому подобная неоправданная оптимизация не произойдет. В листинге, показанном ниже, модули памяти описаны похожим образом, с применением отдельных типов TProgram и TDataMem. Для реализации собственно модулей памяти создаются по одному экземпляру данных типов, которые объявляются не как signal, а как shared variable. Это рекомендуемый стиль описания, который разрешает использование полезной особенности — модифицирования ячеек памяти в нескольких блоках process. Это недопустимо для объектов типа signal, однако поскольку память является двухпортовой, для нее возможна ситуация, когда в проекте используются оба порта, работа с которыми описывается в отдельных блоках process. С точки зрения требований VHDL, для этого требуется объект типа shared variable. В следующем листинге описывается поведение процессора. В обоих листингах полные списки констант с командами и вспомогательные сигналы не приведены для сокращения объема материала. Назначение и формат их описания очевидны и могут быть свободно воспроизведены разработчиками. entity simple.core is generic (PROGRAMSIZE : integer := 256; DATASIZE : integer := 256); Port (elk : in STDJLOGIC; reset : in STD.LOGIC; — интерфейс программирования памяти команд addrin : in STD_LOGIC_VECTOR G downto 0); cmdin : in STDXOGIC.VECTOR G downto 0); we.cmd : in STD_LOGIC; ~ интерфейс процессора addr : out STD_LOGIC_VECTOR G downto 0);
368 Глава б data : out STD-LOGIC..VECTOR G downto 0); din : in STDXOGIC.VECTOR G downto 0); wrio : out STD_LOGIC); end simple_core; architecture Behavioral of simple_core is type TProgram is array@ to PROGRAMSIZE - 1) of integer range 0 to 255; shared variable Program : TProgram := (others => 0); type TDataMem is array@ to DATASIZE - 1) of std_logic_vectorG downto 0); shared variable DataMem : TDatamem := (others => (others => '0')); signal st : integer range 0 to 1; — фаза команды процессора signal cmd : integer range 0 to 255; — сигнал команды ~ регистры signal RegA, RegB : stdJogic_vectorG downto 0) := (others => '0'); signal pc : integer range 0 to PROGRAMSIZE - 1; signal RetA : integer range 0 to DATASIZE - 1 := DATASIZE - 1; — коды команд оформляются в виде констант constant cmdNOP : integer := 0; Листинг. Объявление интерфейса модуля процессора и сигналов для основных узлов — этот процесс описывает работу памяти программ. — Кроме интерфейса программирования, — основная работа памяти описана строкой — cmd <= Program(pc); — Таким образом, модуль памяти программ — работает по фронту тактового сигнала — и помещает на выход содержимое ячейки, — адресуемое регистром PC — Program Counter process(clk) begin if rising..edge(clk) then if we_cmd = '1' then Program(to_integer(unsigned(addrin))) := tointeger(unsigned(cmdin)); end if; cmd <= Program(pc); end if; end process; ~ память данных также работает по фронту тактового сигнала ~ регистр RegA всегда содержит данные для записи ~ регистр RegB всегда содержит адрес памяти process(clk) begin if risingjedge(clk) then if wejnem = '1' then DataMem(toJnteger(unsigned(RegB))) := RegA; end if;
реализации схем на базе ПЛИС 369 щетг <= DataMem(toJnteger(unsigned(RegB))); end if; end process; .- сигнал wejnem должен быть объявлен как stdJogic .. этот сигнал формируется комбинационной логикой, если процессор находится „- в стадии исполнения команды (st = 1) и код команды соответствует ЗАПИСИ we_mem <= Jl} when and = cmdSTORE and st = 1 else '0'; - специальное правило — иногда разряды - E downto 0) команды содержат литерал cmdJit <= stdJogic_vector(to_unsigned(cmd, 6)); - основной цикл работы процессора process (elk) begin if rising_edge(clk) then case st is -- стадия «выборка». На этой стадии работает — только память программ when 0 => st <= 1; — на стадии «исполнение» код команды уже актуален. ~ можно вернуться на стадию «выборка» - и одновременно выполнить действия, ~ соответствующие прочитанной команде when I => st <= 0; case cmd is when cmdNOP => pc <= pc + 1; when cmdAB => pc <= pc + 1; RegA <= RegB; when cmdBA => pc <= pc + 1; RegB <= RegA; when cmdSWAP => pc <= pc + 1; RegA <= RegB; RegB <= RegA; - несколько сложно выглядит сложение и вычитание ~ с применением библиотеки numeric.std. - Необходимо явно указать преобразование регистров - к беззнаковому целочисленному формату - to_integer(to_unsigned(..)) - затем сложить/вычесть получившиеся числа, - а к результату применить преобразование - std_logic_vector(<value>, <разрядность>) when cmdPLUS => pc <= pc + 1; RegA <= stdJogic_vector(to_unsigned(to_integer(unsigned(RegA)) + toJnteger(unsigned(RegB)), RegA'length)); when cmdMINUS => pc <= pc + 1; RegA <= stdJogic_vector(to_unsigned(to_integer(unsigned(RegA)) - to_integer(unsigned(RegB)), RegA'length)); - логические выражения выглядят проще when cmdAND => pc <= pc + 1; RegA <= RegA and RegB;
370 when cmdOR => pc <= pc + 1; RegA <= RegA or RegB; when cmdXOR => pc <= pc + 1; RegA <= RegA xor RegB; when cmdSHR => pc <== pc + 1; RegA <= '0' & RegA G downto 1); when cmdSHL => pc <= pc -f 1; RegA <= RegAF downto 0) & '0'; ~ чтение памяти разбито на две фазы. — Перед этим, на стадии «выборка», регистр ~ RegB был безусловно использован в качестве адреса для чтения — таким образом, память данных была прочитана «на всякий случай» — Это упрощенный подход работы с памятью, и он будет изменен — в более практичных микроархитектурах when cmdREAD => pc <= pc + 1; RegA <= memr; ~ изменение порядка выполнения команд — JMPZ — условный переход по адресу, — загруженному в регистр RegB, — если в регистре RegA содержится 0 — JMP — безусловный переход по адресу, — загруженному в регистр RegB — CALL - вызов подпрограммы по адресу, — загруженному в регистр RegB — RET — возврат из подпрограммы when cmdJMPZ => if toJnteger(unsigned(RegA)) = 0 then pc <= toJnteger(unsigned(RegB)); else pc <= pc + 1; end if; when cmdJMP => pc <= toJnteger(unsigned(RegB)); when cmdCALL => pc <= toJnteger(unsigned(RegB)); RetA <= pc + 1; when cmdRET => pc <= RetA; — работа с внешними устройствами when cmdINPORT => pc <= pc + 1; RegA <= din; — загрузка непосредственных значений (литералов) в регистры — поскольку разрядность регистров равна разрядности команды, — загрузить число полностью невозможно, — поэтому число загружается сдвигом — — справа «вдвигаются» 6 младших разрядов команды, т. е. ~ Юххххххх - вдвигание хххххх в RegA — llxxxxxxx ~ вдвигание хххххх в RegB when 128 to 191 => pc <== pc + 1; RegA <= RegA(l downto 0) & cmdJit; (а б
примеры реализации схем на базе ПЛИС 371 when 192 to 255 => рс <= рс + 1; RegB <= RegB(l downto 0) & cmdJit; when others => pc <= pc + 1; end case; — завершение оператора case „- для обработки команд when others => null; end case; — завершение оператора case - для обработки состояний процессора end if; end process; - сигнал «разрешение записи» для внешних - устройств формируется комбинационной логикой. - Для этого требуется, чтобы процессор был - в стадии «выполнение» и код команды - соответствовал записи в порт В В wrio <= '1' when cmd = cmdOUTPORT and st = 1 else '0'; Листинг. Описание работы основных узлов процессора Работу процессора можно проверить в комплексном виде с помощью так называемого системного теста. Если узлы процессора, такие, как память и АЛУ, проверять по отдельности (так называемые юнит-тесты), то вопрос работоспособности ядра в целом остается открытым. Показательнее способ, когда создается комплексная модель, проверяющая весь процесс выполнения тестовой программы. Разработка такой модели оказывается проще, чем отдельные тесты для узлов процессора. Для нее достаточно заполнить память программ процессора и подать тактовый сигнал. Бели используется САПР ISE, генерация текста, описывающего внешний тактовый генератор для сигнала elk, будет произведена автоматически при выполнении мастера создания нового теста на VHDL. В описание процессора необходимо внести изменения по примеру, показанному в листинге. Здесь память программ инициализируется тестовым примером. В простом случае проверяется сложение регистров RegA и RegB и вызов подпрограммы по адресу 10, которая сразу же возвращает управление. Результаты моделирования этого теста приведены на рис. 6.54. shared variable Program : TProgram := ( 0 => 130, - RegA = 2 1 => 194, -- RegB = 2 2 => cmdPLUS, 3 => 192, - RegB = 0, обнуление старших разрядов 4 => 202, - RegB = 10
372 Глава ns <•¦ х < о (XX 2 X X 50 ns X ~X з X 123 X X X ilOO ns ШХ , x 10 10 4 X JL il50ns X 128 ~X 7 1200 ns X d IXZIZXZ] Рис. 6.54. Результаты моделирования простого теста 5 => cmdCALL, 6 => 192, — RegB = 0, обнуление старших разрядов 7 => 192, - RegB = 0 8 => cmdJMP, — переход к адресу 0 10 => cmdRET, others => 0); Листинг. Простая модель для проверки работы процессора Подобный процессор крайне прост, и его характеристики в плане тактовой частоты и объема используемых ресурсов выглядят привлекательно. Однако он вряд ли может быть применен в серьезных практических целях. Не рассматривая вопросы его программной поддержки, можно указать направления, по которым можно усовершенствовать представленную микроархитектуру. 1. Регистровая модель выбрана минималистичной. Кроме того, что используются только 2 регистра общего назначения, они имеют также жестко привязанные к ним вспомогательные функции, например хранение адреса для работы с памятью и переходов в RegB, хранение данных в RegA. Кроме того, все команды имеют формат RegA = Operation (RegA, RegB). Это требует изменения. 2. Двухтактный конвейер имеет очевидное улучшение — во время выполнения команды вполне можно читать следующую команду, предполагая, что процессор не изменит линейный порядок выполнения. Большинство используемых процессорных архитектур работают по подобной схеме, когда команды продвигаются по конвейеру из синхронных узлов. Длина конвейера может быть больше 2, и в современных процессорах используются от 3-5 до 10 и более стадий. 3. Управление выполнением программы ограничено одним вариантом безусловного перехода и одноуровневым вызовом подпрограмм. 4. Выбрана простая архитектура системы команд. Реализация более развитой регистровой модели и поддержки различных режимов адресации памяти потребует планирования формата команды и подходов к ее декодированию.
примеры реализации схем на базе ПЛИС 373 Проектирование процессоров является перспективным как для цифровой электроники в целом, так и для ПЛИС, поскольку параллельная работа узлов ПЛИС открывает широкие возможности для размещения в проекте вспомогательных процессоров, облегчающих управление сложными устройствами, а реконфигурируемость ПЛИС не заставляет разработчика тщательно оптимизировать процессор и делать его конкурентоспособным, как это происходит при выпуске интегральных микросхем, предназначенных для широкого рынка. Облегчение работы с конкретным проектом путем размещения в нем вспомогательного специализированного процессора может само по себе являться положительным результатом. 6.25.3. Примеры задач для простых процессорных ядер Для сложных проектов, включающих контроллеры периферийных устройств, часто бывает полезно выделить несложный программируемый узел для управления медленными процессами, которыми неудобно управлять с помощью конечного автомата, а процессор в качестве управляющего узла удобен тем, что позволяет проводить отладку сложных протоколов и оперативное внесение изменение без перестройки конфигурации всего проекта. Примерами таких задач являются контроллер I2C и интерфейс знакосинтезирующих индикаторов LCD. Шина I2C (ПС — Inter-Integrated Circuit) — одна из распространенных в настоящее время шин для связи устройств на печатной плате. Шина использует два сигнала, один из которых является тактовым (SCL), а другой — двунаправленным сигналом данных (SDA). Первые спецификации предусматривали частоту тактирования 100 кГц или 400 кГц. Несмотря на наличие более современных режимов с частотой передачи до 5 МГц, ряд устройств до сих пор используют максимальную частоту передачи 100 или 400 кГц. Шина I2C удобна прежде всего наличием всего двух линий, которые могут быть использованы для подключения до 112 устройств. Такое ограничение связано с 7-битовым адресом, предусмотренным протоколом обмена, и наличием 16 зарезервированных адресов. Физическое подключение устройств по I2C крайне просто. Необходимость всего двух линий для связи в сочетании с возможностью подключения множества устройств делает шину удобной при наличии в системе множества устройств с невысокими требованиями к скорости обмена данными. Несмотря на то что на шине сигнал SCL Управляется только ведущим устройством, его имеет смысл делать
374 Гл, —*t CPU - - —*t i ' SCL Устройство 1 1 ^ ' SDA Устройство 2 1 Рис. 6.55. Подключение устройств к ПЛИС по шине I2C двунаправленным, как показано на рис. 6.55 (на рисунке не показаны требуемые pull-up резисторы). Это связано с тем, что медленное ведомое устройство может удерживать линию SCL в состоянии логического нуля, если оно не готово к приему следующего бита. В связи с необходимостью реализации протокола обмена согласно стандарту удобно использовать для управления шиной I2C простой процессор. При использовании аппаратного решения разработчик будет вынужден повторять процесс создания конфигурационного файла при необходимости не только отладки, но и изменения адреса устройства, а программная реализация протокола позволит ограничиваться компиляцией программы встроенного процессора. Такое же физическое подключение используется в шине SCCB (Serial Camera Control Bus — последовательная шина управления камерой), применяемая для управления видеодатчиками. Протокол SCCB имеет некоторые отличия, в основном касающиеся временных задержек после переключения уровня SCL, поэтому его запуск и отладку также удобнее проводить путем изменения программы, а не коррекции схемы. Интерфейс LCD (жидкокристаллического индикатора) показан на рис. 6.56. Несмотря на множество доступных вариантов подключения непосредственно индикаторов, стандартом де-факто стал вариант интерфейса, реализованный, например, в микросхемах ksO66 или hd44780. Большинство символьных индикаторов использует именно эту схему подключения. Интерфейс состоит из 8-разрядной шины данных, в которой можно оставить подключенными только 4 старших разряда. Линяя RS управляет передачей инструкции контроллеру @) или данных для вывода A). Линия R/W управляет записью данных @) или чтением A). Контроллер можно использовать и в режиме «только запись», подключив R/W к низкому логическому уровню, поскольку читаемая информация о состоянии контроллера и содержимом его памяти не является критически важной для сохранения рабо-
лрцмеры реализации схем на базе ПЛИС 375 LCD ПЛИС D01 Ш - D2 D3J D4 D5 D6 D7 Е ER/W RS Отсутствуют для 4-разрядного варианта) ^^ интерфейса Valid data D[7:0]_ RS: 0 — инструкции; 1 — данные R/W: 0 — запись; 1 - чтение рис. 6.56. Интерфейс распространенных контроллеров LCD и временные диаграммы обмена тоспособности. Сигнал Е используется в качестве стробирующе- го. В отличие от тактового сигнала, высокий уровень на линии Е означает, что в любой момент, пока Е = '1', данные на шине D достоверны (valid). Для работы LCD обычно должен получить последовательность команд (команды показаны с битовыми полями, включающими конкретные режимы работы): 1. 0x28 (команда Function Set). 2. 0x06 (команда Entry Mode Set). 3. ОхОС (команда Display On/Off). 4. 0x01 (команда Clear Display). После этого можно выводить данные, установив линию RS в 1. Выводимые символы будут сопровождаться соответствующими изменениями позиции курсора, если это было установлено в полях команды Entry Mode Set. Особенностью контроллеров LCD являются достаточно длительные задержки, предусмотренные для сигнала Е и между посылкой отдельных команд контроллеру. Ввиду наличия множества совместимых с данным интерфейсом контроллеров точные характеристики следует уточнять в технической документации на конкретную модель. Однако, например, длительность строба сигнала Е может составлять порядка 250 не, а после команды инициализации контроллер может требовать паузы около 15 мс (миллисекунд!). Паузы требуются практически после всех инструкций. Аппаратное решение для подобного протокола не слишком удобно для реализации. Конечный автомат для инициализации LCD будет довольно сложен, к тому же должен поддерживать формирование длительных пауз. С другой стороны, попытка программного Управления линиями со стороны процессора ARM или Microblaze
376 Г л а: ARM или MicroBlaze Dual-port RAM Процессор управления Л N. N v LCD Центральный процессор Вспомогательный процессор помещает данные, которые читает данные из буфера и требуется вывести, и формирует требуемые продолжает работу временные диаграммы для LCD Рис. 6.57. Подключение LCD с помощью вспомогательного процессора привлекательна своей простотой, но разработчик быстро обнаружит, что программное формирование длительных задержек является расточительным расходованием времени быстрого процессорного ядра. Применение вспомогательного процессора для управления LCD представляется эффективным решением, разгружающим центральный процессор системы. Вариант такой системы показан на рис. 6.57. При использовании двухпортовой памяти центральный процессор системы может просто поместить данные, которые требуется вывести на LCD, и продолжать выполнение работы. Вспомогательный процессор периодически проверяет состояние этого буфера, используя второй порт памяти, и формирует требуемые задержки для сравнительно медленного интерфейса LCD. Освобождение мощного центрального процессора от необходимости заниматься слишком простой для него задачей в целом положительно влияет на характеристики системы. Показанными примерами не исчерпываются варианты эффективного использования несложных процессорных ядер. В данном случае от дополнительных процессоров не требуется демонстрировать максимальную производительность или поддержку сложных команд. Их основным назначением является «точечная» разгрузка более производительных узлов системы. Такой стиль организации многоядерной процессорной системы на кристалле хорошо подходит для ПЛИС как таковых, позволяя при необходимости сконфигурировать часть кристалла в качестве софт-процессора, гибко управляя его архитектурой и выделенными для него ресурсами. Это направление представляется весьма перспективным и дает множество направлений для исследования процессорных архитектур и способов их взаимодействия на кристалле. б.26. Фильтр с конечной импульсной характеристикой Цифровая фильтрация является обширной областью, в которой рассматриваются самые разные аспекты проектирования и яс-
примеры реализации схем на базе ПЛИС 377 пользования цифровых фильтров. Важнейшим свойством цифровых систем, отличающим их от аналоговых схем, является более высокая стабильность параметров, которая позволяет производить самые разные преобразования для сигналов, после того как с ними было произведено аналого-цифровое преобразование. Простейшим видом фильтра является фильтр с конечной импульсной характеристикой (КИХ-фильтр, FIR — Finite Impulse Response). Его работа заключается в вычислении выходного сигнала по набору входных отсчетов: у = kixi + к2х2 + ..., где xi, х2 — отсчеты входного сигнала в последовательные моменты времени; fci, к2 — коэффициенты. Для работы фильтра последние N отсчетов входного сигнала должны быть доступны ему. Поскольку невозможно хранить бесконечное число отсчетов, длина буфера будет равна N (что характеризует порядок фильтра). Если подать на такую схему последовательность отсчетов, представляющую собой один импульс (х ф 0), за которым следует нулевые отсчеты, то после того как импульс при последовательной работе фильтра пройдет по всем положениям (#i, x2i хз,.. .)> во всех позициях х останутся нули и выход фильтра также примет нулевое значение. Такое поведение и определяет класс фильтра — «с конечной импульсной характеристикой». Также существуют фильтры с бесконечной импульсной характеристикой (БИХ), структура которых допускает возможность бесконечной генерации сигнала при подаче на вход импульса. Для получения БИХ-фильтра достаточно продолжить ряд суммирования кх, добавив к нему сумму произведений ту} где т — коэффициенты, а у — значения выхода фильтра на предыдущих тактах работы. Разновидности фильтров и способы их проектирования являются предметом отдельного рассмотрения. Важен тот факт, что вычисление выходного значения фильтра является очень эффективным способом применения ресурсов ПЛИС. Блоки DSP48 полностью соответствуют схеме вычисления отдельных произведений, и содержат необходимые сопутствующие компоненты — аккумулятор, конвейеризующие регистры, схемы ускоренного переноса меж- АУ блоками и дополнительные трассировочные ресурсы. Основная операция фильтра — умножение с накоплением (MAC, Multiply and Accumulate) — непосредственно реализуется в этих блоках. КИХ-фильтр может быть легко реализован непосредственно на HDL. Синтезаторы корректно определяют возможность применения
378 Гл а; Reg/+ MAC engine.N тактов до получения результата ш Reg/+ Reg MACfam N блоков DSP48 Рис. 6.58. Основные разновидности схемы КИХ-фильтра ресурсов DSP48, как для умножения, так и для накопления выходного значения. В целом КИХ-фильтр может быть синтезирован с применением только блоков DSP48. Как правило, это означает достаточно высокую тактовую частоту, поскольку логические ячейки не вмешиваются в построение схемы, а фиксированное положение DSP48 на кристалле позволяет использовать выделенные трассировочные ресурсы с предсказуемо хорошими характеристиками. В то же время может возникнуть вопрос — следует ли использовать блоки DSP48 на заведомо более низкой частоте? Предположив, что тактовая частота в ПЛИС составляет 200 МГц, а входные данные поступают с тактовой частотой 10 МГц, каждый блок DSP48 будет работать только на одном такте из 20. На рис. 6.58 показаны основные разновидности схемы КИХ- фильтра. Они не образуют полного перечня возможных реализаций, а демонстрируют диаметрально противоположные подходы к вычислению выхода фильтра. Первая схема (MAC engine) дает возможность вычислять выход фильтра в течение N тактов после прихода входного сигнала. Для этого необходимо хранить N последних отсчетов входного сигнала и таблицу из N коэффициентов. Для такой схемы требуется только один блок DSP48. Второй вариант (MAC farm) является противоположностью в смысле режима использования DSP48. Каждый блок имеет собственный коэффициент, и вычисляет произведение только для него. Входные отсчеты передаются на последующие блоки умножения через цепочку конвейеризующих регистров. Возможны и промежуточные варианты. Легко представить, что при тактовой частоте 200 МГц и частоте следования входных отсчетов 100 МГц можно использовать каждый блок DSP48 для вычисления двух произведений, добавив столько блоков, сколько необходимо для работы со всеми коэффициентами. В составе САПР Vivado имеется генератор КИХ-фильтров -~ IP-ядро FIR Compiler. Его внешний вид показан на рис. 6.59.
примеры реализации схем на базе ПЛИС 379 Рис. 6.59. Внешний вид диалогового окна настройки параметров КИХ- фильтра фильтра задаются основные параметры — набор коэффициентов, тактовая частота для работы фильтра и частота следования входных отсчетов. На рис. 6.60 показана АЧХ фильтра, которая наглядно демонстрирует, какие параметры достигнуты при заданном наборе коэффициентов. По соотношению частоты следования отсчетов и тактовой частоты IP-ядро может выбрать структуру фильтра, оптимально задействовав ресурсы блоков DSP48. Важным является вопрос применения фильтров в цифровых системах. Распространение процессорной техники и появление специальных сигнальных процессоров (процессоры цифровой обработки сигналов, DSP-процессоры) способствует формированию стереотипа о необходимости проведения всех вычислений на базе процессорного ядра. Наличие в сигнальных процессорах команд «умножение с накоплением» вызывает естественное желание применить Для обработки именно этот процессор. Если же использовать процессор для постобработки потока данных фильтра, реализованного в ПЛИС, выяснится, что суммарная производительность блоков DSP48 существенно превосходит возможности процессора по вводу этих данных через системную шину, не говоря уже о возможности их обработки. Поэтому система, в которой процессор находится в цепочке цифровой обработки сигнала, вероятнее всего является Неэффективной.
380 Г л а ва Рис. 6.60. Внешний вид диалогового окна настройки параметров КИХ- фильтра в режиме просмотра АЧХ Кроме того, для цифровых фильтров крайне важно выдерживать постоянную величину интервала дискретизации по времени. Если данные поступают для обработки в процессорное ядро, то существует множество возможностей нарушить это условие. Например, промах кэш-памяти (cache miss), который «прозрачен» для программиста, захват системной шины другим устройством или переключение на обработку прерывания вызовут приостановку обработки входного потока, и часть отсчетов будет потеряна. Применение аппаратно реализованного фильтра полностью исключает подобные проблемы. При этом процессор может участвовать в управлении работой фильтра — загружая коэффициенты, наблюдая за входным и выходным сигналом, приостанавливая работу и т. п. Однако при этом сохраняется высокая частота работы компонентов DSP48, а самое главное — сохранение непрерывности вычислений выходного значения фильтра. Можно рекомендовать размещение цифрового фильтра и процессорной системы в разных тактовых доменах, с реализацией корректной схемы передачи данных (CDC, Clock Domain Crossing). Это позволит сохранять высокую тактовую частоту для цифрового фильтра без необходимости обеспечивать ее достижение заведомо более сложными компонентами проекта (рис. 6.61). В целом направление цифровой обработки сигналов является
Цримеры реализации схем на базе ПЛИС 381 Фильтр а) Процессор Фильтр & Процессор рис. 6.61. Совместная работа фильтра й процессорного ядра: a — неудачная архитектура — процессор замедляет работу фильтра; прерывания процессора вызовут приостановку фильтрации сигнала; б — фильтр работает автономно; процессор загружает коэффициенты и получает состояние фильтра Ф весьма перспективным для ПЛИС. Большое число блоков DSP48 делают ПЛИС не только гибкой, но и конкурентоспособной вычислительной платформой по сравнению с сигнальными процессорами и GPU. 6.27. Сложные для самостоятельной разработки интерфейсы Ряд широко распространенных компонентов имеют повышенную сложность разработки, поэтому не рекомендуются для самостоятельного повторения без соответствующего опыта проектирования. Сложность может заключаться как в необходимости поддержки разнообразных протоколов, так и в дополнительных требованиях, таких как высокие требования к качеству трассировки печатной платы, что выходит за рамки инструментов проектирования для ПЛИС. Некоторые из этих интерфейсов можно рассмотреть, чтобы предостеречь разработчиков от добавления их в проект без соответствующей инструментальной поддержки и опыта использования. Проблемы могут касаться как достижения принципиальной работоспособности, так и эффективной реализации соответствующего интерфейса в сравнении с альтернативными решениями или внешними микросхемами. 6.27.1. Контроллер памяти DDR3/4 Динамическая память (в настоящее время это DDR3 и DDR4). Возможные проблемы: 1. Неустранимая неработоспособность интерфейса из-за несоответствия параметров печатной платы требованиям. Микросхемы динамической памяти имеют нижний предел тактовой частоты, обусловливающий сохранение процесса регенерации данных. Кроме того, внутри байтовой группы данных требуется достаточно точная согласованность задержек распространения сигналов, а линии Данные должны быть согласованы с сигналом строба DQS. Если требования по согласованности задержек не выполняются, запуск Интерфейса памяти может оказаться невозможным.
382 Глав а б 2. Сложность реализации протоколов обмена с памятью, с том того, что обмен данными производится с существенными отличиями от интерфейса статической памяти. Решения: 1. Использование профессиональной САПР печатных плат имеющей функции контроля импеданса проводников и выравнивания задержек распространения сигналов по печатным проводникам. Контроль импеданса дорожек при изготовлении печатной платы. 2. Использование IP-ядра Memory Interface Generator. 3. Использование аппаратного контроллера памяти в семействах Spartan-6, Zynq-7000 (для подключения к процессору ARM). 6.27.2. USB Интерфейс USB в настоящее время является широко распространенным и может формировать впечатление несложного для реализации. Использование в нем дифференциальной пары сигналов D+, D- наталкивает на вопрос: можно ли принимать данные с помощью выводов ПЛИС, сконфигурированных в режиме дифференциальной пары? В общем случае такой путь не рекомендуется. Возможные проблемы: 1. Необходимость электрического согласования выводов ПЛИС с линией передачи USB. 2. Необходимость поддержки сложных протоколов обмена. Решения: 1. Использование внешней микросхемы контроллера USB в виде преобразователя USB-UART, USB-Parallel или внешнего МК с интефейсом USB. 2. Использование встроенного контроллера USB в ПЛИС Zynq- 7000. 6.27.3. Ethernet MAC В целом прием и отправка IP-пакетов не представляет особенной сложности. Даже в режиме 1000 Мбит/с частота передачи данных по 8-разрядной шине составляет 125 МГц (в таком режиме это source-synchronous интерфейс). Однако кроме приема и отправки одиночных пакетов разработчик обычно ожидает полноценной поддержки стека протоколов TCP/IP и возможности доступа к проекту в ПЛИС с помощью веб-интерфейса. Возможные проблемы: 1. Отказ в обмене данными со стороны ПК из-за отсутствия поддержки ARP (Address Resolution Protocol). В ряде случаев
Цраиеры реализации схем на базе ПЛИС 383 потребоваться поддержка DHCP и ICMP, без которых сетевое оборудование может посчитать проект в ПЛИС отсутствующим в сети. 2. Отсутствие поддержки протокола TCP из-за отсутствия буферов для поддержки сессий обмена данными. 3. Низкая скорость обмена при использовании высокоуровневых протоколов. Решения: 1. Использование готового IP-ядра Ethernet MAC. 2. Использование аппаратного ядра контроллера Ethernet в ПЛИС Zynq. В качестве программных стеков протоколов могут быть использованы библиотека lwIP, которая имеет возможность работы в режиме Standalone (т.е. без операционной системы), или встроенные сетевые решения ОС Linux. Приведенные сведения не следует рассматривать как рекомендации отказаться от перечисленных компонентов. Можно заметить, что во всех случаях приведены рекомендации по возможным путям решения проблемы. С другой стороны, попытки улучшить работу подобных сложных устройств, надеясь на выявление каких-то неучтенных особенностей их работы, вряд ли даст эффект в короткой перспективе. 6.28, Выводы по главе Перечисленными примерами невозможно охватить все аспекты проектирования для ПЛИС. В то же время глава содержит основные примеры кода и приемы проектирования, включая как базовые схемы, так и полезные (например, конечный автомат или процессор), и основные схемы, имеющие риск появления ошибки (прежде всего, схемы с несколькими тактовыми сигналами). Обратная связь от читателей могла бы быть хорошим источником для рассмотрения новых примеров.
Т Оптимизация проекта В процессе получения конфигзграции ПЛИС программное обеспечение формирует список связей между отдельными компонентами, а затем пытается разместить эти компоненты на кристалле и сформировать программируемые связи между ними. Это типичная задача вида «разместить М элементов в N возможных позициях», которая весьма трудна для автоматического решения. Трудность заключается в том, что прямой перебор вариантов для достаточно больших М и N невозможен (а для FPGA серии Virtex-7 N исчисляется уже миллионами), поэтому приходится ограничиваться оптимизацией частных случаев в сочетании с эвристическими алгоритмами. При оптимизации размещения используется алгоритм градиентного спуска, известным свойством которого является высокая чувствительность к начальным условиям. Для проектов на ПЛИС это означает, что эффективность размещения существенно зависит от того, насколько грамотно разработчик задал проектные ограничения, управляющие топологией проекта «в целом». На рис. 7.1 схематично показан маршрут проектирования в САПР Vivado, ориентированный на интенсивное использование IP- ядер (как предоставляемых Xilinx и другими производителями, так Тексты на С High-Level Synthesis Исходные тексты: PTL, списки связей, ограничения System Generator (проекты ЦОС) Интеграция IP (логика, ЦОС, встр. системы) Системная интеграция PTL Упаковка IP Синтез Реализация Программирование и отладка Анализ проекта Ограничения Моделирование Отладка Точки наблюдения Каталог IP Пользовательские IP Рис. 7Л. Маршрут проектирования в САПР Vivado, ориентированный на использование IP-ядер
Оптимизация проекта 385 0 создаваемых самим разработчиком проекта). В Vivado также входит САПР Vivado HLS (High Level Synthesis), которое представляет Зовое поколение языков описания аппаратуры. В версии 2018.3 это языки С, C++ и SystemC, которые могут использоваться как для моделирования, так и для создания синтезируемых описаний. На ранних этапах проектирования важно выбрать подходящий инструмент проектирования, комбинируя HDL-описания для задач общего вида, HLS и System Generator for DSP для некоторых задач цифровой обработки сигналов, готовые IP-ядра и микропроцессорные системы. Применение подходящего сочетания инструментов является хорошей основой для достижения высоких технико- экономических показателей проекта. 7.1. Методология оптимизации проекта Компания Xilinx предлагает методические рекомендации по проектированию на базе выпускаемых ей ПЛИС. Конечно, невозможно охватить все аспекты проектирования, однако ряд особенностей ПЛИС как таковых и современных ПЛИС Xilinx, в частности, позволяют создать список наиболее значимых проектных мероприятий. Оценка достижимой тактовой частоты проекта является сложным и неоднозначным процессом. На рис. 7.2 показана иллюстрация, поясняющая факторы снижения тактовой частоты проекта относительно прогнозируемых характеристик. Важным параметром является показатель logic levels, который в целом может быть определен как число LUT в самой длинной комбинационной цепочке. Кроме LUT могут быть важны и другие компоненты комбинационной логики, но в целом можно указать, что Частота'1 Fsy8tem/4 Снижение частоты вследствие задержек трассировки Семейство 1 Семейство 2 Семейство ПЛИС Рис. 7.2. Факторы снижения тактовой частоты проекта
386 Г1 л а в а у если между триггерами находятся две LUT, то достижимая тактовая частота может быть оценена как Esys/2. Поэтому сложность комбинационной схемы, определяемая по самой медленной цепи, является главным ограничивающим фактором для тактовой частоты. Однако сложность схемы не является единственным фактором. Кроме задержек на цифровых компонентах ПЛИС, существуют задержки на трассировочных линиях, которые могут быть тем существеннее, чем сложнее проект, и чем дальше отстоят друг от друга компоненты. Поэтому в зависимости от сложности трассировки может возникнуть дополнительный важный фактор снижения тактовой частоты проекта относительно прогнозируемых величин. Описанные факторы имеют, в целом, собственные методы для работы с ними. Длина самой медленной комбинационной цепочки зависит от сложности выражений, описанных разработчиком, поэтому эта проблема решается на этапе проектирования. Длина трассировочных линий уменьшается комбинацией приемов. Разработчик может повлиять на результаты трассировки управлением взаимного расположения компонентов проекта на кристалле ПЛИС (с помощью топологических проектных ограничений). Кроме того, эксперименты со стратегиями размещения и трассировки способны помочь САПР найти оптимальные варианты в автоматическом режиме. Управление с помощью топологических ограничений рекомендуется использовать на верхних уровнях проекта, поскольку грамотный разработчик обладает интуитивным пониманием ситуации и может прогнозировать долгосрочные эффекты от расстановки компонентов, а САПР способна эффективно оптимизировать проект на локальном уровне. «Три шага к повышению тактовой частоты» в изложении Xilinx выглядят следующим образом: 1. Используйте аппаратные компоненты. 2. Используйте синхронные схемы. 3. Настройте САПР. 7.2. Использование аппаратных компонентов К основным аппаратным ресурсам FPGA относятся: • секции DSP48; • высокоскоростные последовательные приемопередатчик^ (МОТ); • блочная память (BRAM); Дополнительно можно учитывать следующие типы ресурсов:
Оптимизация проекта 387 • режимы распределенной памяти и сдвиговых регистров для логических генераторов; • регистры, сериализаторы/десериализаторы и линии задержки в блоках ввода-вывода; • контроллеры PCI Express. Тактовые ресурсы FPGA (блоки СМТ, тактовые буферы) обычно также указываются производителем в списке ресурсов. Однако с точки зрения разработчика, это не дополнительные компоненты, которые могут быть использованы по собственному усмотрению, а обязательные узлы ПЛИС, которые должны быть корректно настроены для получения стабильно работающей тактовой сети. В целом можно придерживаться правила — если ПЛИС содержит аппаратный компонент для реализации некоторой функции, его желательно использовать в проекте. Аппаратные компоненты обладают не только высокой тактовой частотой, но, что важно, предсказуемыми характеристиками, что обеспечивает для проекта своеобразные «опорные точки», вокруг которых может быть сгруппированы программируемые логические ячейки. 7.3. Правила описания синхронных схем Правильное построение системы синхронизации в современных FPGA не является сложным процессом, однако данный этап не следует оставлять без внимание. Методика выбора системы синхронизации базируется на двух последовательно пришедших в микроэлектронную область подходах: 1. Полностью синхронный стиль проектирования. 2. Глобально асинхронные, локально синхронные схемы. При этом второй подход не отменяет, а расширяет первый, поскольку «глобальная асинхронность» в данном случае не означает, что в каких-то случаях правилами построения синхронных схем можно пренебречь. Итак, синхронная схема обладает следующими признаками: • один тактовый сигнал, один перепад (все триггеры используют только фронт или только спад тактового сигнала); • используются D-триггеры (не защелки); • регистры на выходах блоков; • используются сигналы «разрешение счета» вместо управления тактовым сигналом; • используются схемы синхронизации для асинхронных сигналов. Не используются:
388 Г л а ва г Рис. 7.3. Результаты синтеза логического выражения • тактовые сигналы, полученные с помощью логических вентилей, комбинирования разрядов счетчиков или делением частоты с помощью триггеров логических ячеек; • локальные асинхронные сигналы сброса/установки. При описании логических выражений в критических цепях, которые должны быть реализованы в LUT, следует учитывать архитектуру не только самих LUT, но и логических ячеек в целом. Сами LUT имеют б входов и могут, таким образом, реализовать любую функцию от 6 независимых сигналов. В примере, приведенном ниже, выходной сигнал q формируется, на первый взгляд, достаточно сложным образом, однако поскольку в выражении участвует б одноразрядных сигналов, итоговая логическая функция все равно будет реализована в одной LUT. На рис. 7.3 показана синтезированная схема, где видно, что между входными и выходным регистрами присутствует только один компонент LUT6. Следовательно, тактовая частота такой схемы будет достаточно высокой. library IEEE; use IEEE.STD_LOGIC.1164.ALL;
Оптимизация проекта 389 entity testl is Port (elk : in STD.LOGIC; din : in STD_LOGIC_VECTOR E downto 0); qjreg : out STDXOGIC); end testl; architecture Behavioral of testl is signal a, b, c, d, e, f, q : stdJogic; begin a <= din@) when rising_edge(clk), b <= din(l) when rising_edge(clk); с <= dinB) when rising_edge(clk); d <= dinC) when rising_edge(clk); e <= dinD) when rising_edge(clk); f <= dinE) when rising_edge(clk); q <= (a and b) or ((c xor d) and (e or f)); qjreg <= q when rising_edge(clk); end Behavioral; Листинг. Пример компонента, ориентированного на возможности LUT6 С другой стороны, можно рассмотреть выражение, которое с точки зрения математики выглядит достаточно простым. Например, проверка равенства может быть произведена одной операцией (а = Ь), но означает ли это, что и схема, синтезированная по этому выражению, будет работать на максимальной частоте? На рис. 7.4 показана схема, синтезированная для описания, приведенного ниже. library IEEE; use IEEE.STD_LOGICLU64.ALL; entity testl is Port (elk : in STD_LOGIC; a : in STD_LOGIC_VECTOR C1 downto 0); b : in STD.LOGIC.VECTOR C1 downto 0); qjreg : out STDJLOGIC); end testl; architecture Behavioral of testl is signal a_reg, b_reg : stdJogic_vectorC1 downto 0); signal q : stdJogic; begin a_reg <= a when rising_edge(clk); b_reg <= b when rising_edge(clk); q <= Jl' when a = b else '0'; q_reg <= q when rising_edge(clk); end Behavioral; Листинг. Пример выражения с простой записью, приводящего к синтезу сложной схемы
390 Гла ва 7 Рис. 7.4. Результаты синтеза компаратора 32-разрядных сигналов Сравнение рис. 7.3 и 7.4 демонстрирует, что сложность схемы не вполне однозначно связана со сложностью реализуемого выражения, как оно воспринимается в математической записи. Несмотря на то что q <= (a and b) or ((с xor d) and (e or f)) создает впечатление сложного выражения, значение имеет только тот факт, что выход зависит от 6 одноразрядных входов. Поэтому при упрощении комбинационной логики следует обращать внимание именно на число входов. Кроме собственно LUT, в логических ячейках имеются дополнительные компоненты, упрощающие построение некоторых схем- Например, для мультиплексора 16-В-1 можно воспользоваться при-
Оптимизация проекта 391 ^еденными выше рассуждениями и отталкиваться от того, что 16 входов и 4 линии управления дадут в общей сложности 20 входных сигналов, которые потребуют не менее 4 LUT в первом слое преобразования. Выходы этих LUT необходимо будет объединить в LUT второго слоя, и общее число LUT в самой длинной цепочке будет равно двум. Однако на рис. 7.4 показана синтезированная схема, в которой видно, что для объединения выходов LUT одной секции задействованы встроенные в ячейки аппаратные мультиплексоры F7MUX и F8MUX. Мультиплексоры F7 объединяют выходы двух пар LUT, a их выходы, в свою очередь, объединяются мультиплексором F8. Это позволяет построить мультиплексор 16-В-1 всего на одной секции с сохранением одного слоя LUT. Можно отметить, что для распознавания мультиплексора надежнее использовать конструкции case и with .. select. process(clk) begin if rising_edge(clk) then case s is when 000" => dout <= din@); when 001" => dout <= din(l); when 010" => dout <= dinB); when 011" => dout <= dinC); when 100" => dout <= dinD); when 101" => dout <= dinE); when 110" => dout <= dinF); when 111" => dout <= dinG); when 000" => dout <= din(8); when 001" => dout <^= din(9); when 010" => dout <= dinA0); when 011" => dout <= din(ll); when 100" => dout <= dinA2); when 101" => dout <= dinA3); when 110" => dout <= dinA4); when others => dout <= din A5); end case; end if; end process; Листинг. Описание компаратора, ориентированного на синтез компонентов MUX логических ячеек Кроме мультиплексоров, логические ячейки имеют схемы ускоренного переноса, которые.служат для построения сумматоров и вычитателей. Несмотря на то что логику сумматора можно реализовать и на LUT, занеся в него соответствующее выражение, встро-
392 Г л а ва Рис. 7.5. Результат синтеза компаратора 16-В-1 енный аппаратный сумматор лучше подходит для этих целей. Синтезаторы автоматически используют эти ресурсы при обработке выражений вида a -f b или а — Ь. По аналогии с программированием может показаться, что замена высокоуровневых выражений на низкоуровневые приведет к повышению эффективности, однако в данном случае попытка замены аппаратного компонента сумматора на LUT общего назначения приведет к ухудшению характеристик. Поэтому знаки сложения и вычитания не только могут использоваться в арифметических выражениях без ограничений, но и рекомендуются к использованию. Конвейеризация является эффективным, хотя и не всегда применимым способом повышения тактовой частоты цифровой схемы. На рис. 7.6 показана простейшая иллюстрация к вопросу о конвейеризации. Как можно видеть на этом рисунке, длинная линия, содержащая два уровня логики, оказалась разрезана еще одним триггером, так что по обе стороны от него оказалось по одному уровню. Задержка распространения сигналов сократилась, и частота, таким образом, увеличилась примерно в 2 раза. В процессе синтеза схем может оказаться, что какое-то выражение вследствие большой сложности объективно не может быть
Оптимизация проекта 393 'МАХ ™" —• nMHz _ f 'МАХ ^ 2п MHz Рис. 7.6. К вопросу о сути конвейеризации реализовано на одной LUT (это довольно частое, если не повсеместное, явление). Эта проблема останется в проекте на всем его протяжении и не сможет быть принципиально устранена простым изменением настроек САПР. Поэтому для такого фрагмента схемы можно предусмотреть разделение длинной комбинационной цепочки триггером, как показано на рис. 7.6. Например, это может быть выполнено следующим образом: process(clk) begin if rising-edge(clk) then sum <= a + b + с + d; end if; end process; ~ Конвейеризованная схема: process(clk) begin if rising_edge(clk) then suml <= a + b; sum2 <= с + d; sum <= suml + sum2; end if; end process; Показанная конвейеризация не имеет смысла, если сумматор складывает одноразрядные сигналы. Тогда сигнал sum является функцией от 4 однобитовых сигналов и может быть получен в одной LUT. Однако если речь идет о многоразрядных сигналах, такое преобразование повысит тактовую частоту. В примере видно, что конвейеризация проведена путем коррекции исходного текста модуля, с введением промежуточных сигналов. Какие промежуточные точки выбрать для установки дополнительных регистров, решается индивидуально на основе анализа получаемой схемы.
394 ^ Можно обратить внимание, что на получение значения ы конвейеризованный пример требует два такта вместо одного. Однако после получения промежуточных сумм на вход этой схемы можно подавать следующий набор данных. Если говорить о частоте полу, чения новых данных, то она безусловно выросла, но задержка между подачей данных на вход и появлением результата на выходе (т. е латентность) также увеличилась. В зависимости от типа проекта увеличение латентности может быть приемлемым или нет. В целом можно говорить, что задачи цифровой обработки сигналов и телекоммуникационные приложения в целом нейтрально относятся к увеличению латентности, поскольку обработка данных происходит непрерывно или крупными пакетами. После задержки в несколько тактов данные начинают поступать на выход с увеличенной частотой, и на фоне увеличения тактовой частоты потеря нескольких тактов на старте не выглядит серьезным недостатком. В противоположность этому такая схема, как контроллер памяти, не обязательно получит выгоду от увеличения тактовой частоты, если при этом увеличивается и латентность. Предположим, что при частоте 100 МГц контроллер не использует конвейеризацию и после формирования адреса данные могут быть прочитаны уже на следующем такте. После добавления регистра частота по оптимистичной оценке поднимется до 200 МГц, однако для получения данных потребуется уже два такта. Это не представляет существенных проблем при чтении данных большими пакетами, однако при произвольном доступе придется терять половину тактов на ожидание прохождения данных по дополнительному регистру. В процессе разработки может возникнуть ситуация, когда объективная необходимость увеличить число тактов конвейера вступит в противоречие с невозможностью увеличения латентности из-за особенностей технического задания. Поэтому при необходимости достижения высокой тактовой частоты следует учитывать, что для этого вероятнее всего потребуется реализовывать схемы с увеличенной латентностью, поэтому такой прием проектирования не должен вступать в противоречие с техническими требованиями к проекту. По мере возрастания размеров FPGA становится актуален подход GALS (Globally Asynchronous, Locally Synchronous, т. е. глобально асинхронные, локально синхронные схемы). Он подразумевает, что проект состоит из нескольких синхронных подсистем, которые работают каждая на своей тактовой частоте. Номинально эти частоты могут быть и одинаковы, но если каждый тактовый сигнал формируется своим блоком ММСМ, то на практике фазы этих сигналов
ддтямизгащя проекта 395 зСе равно будут отличаться в разных областях кристалла. Поэтому необходимо заранее предусматривать способы передачи данных из одного тактового региона в другой. Семейство UltraScale изначально не предусматривает формирование общих тактовых сетей, которые могли бы распространяться на весь кристалл. В этом семействе каждый тактовый регион имеет свои модули для формирования стабильного в пределах региона тактового сигнала (см. рис. 7.6). Даже если на оба модуля подана одна и та же частота, каждый из модулей будет подстраивать фазу индивидуально, поэтому рано или поздно их выходные сигналы окажутся рассинхронизированы. Для ПЛИС серии 7 планирование нескольких независимых тактовых регионов пока не является технической необходимостью, однако может быть настоятельно рекомендовано. Это позволит избежать длительных процессов отладки на поздних этапах разработки проекта. Разделение проекта на тактовые подсистемы может быть произведено различными способами — например, по функциональному признаку или по отдельным каналам. В первом случае в проекте формируются такие подсистемы, как цифровые фильтры, коммуникационные и процессорные модули, каждая из которых использует собственный тактовый сигнал. Передача данных между подсистемами выполняется через двухпортовую блочную память, которая имеет физически независимые порты, в том числе обеспечивающие два независимых тактовых входа. Структурная схема проекта с архитектурой GALS показана на рис. 7.7. Обе подсистемы проекта, показанные на рисунке, являются локально синхронными, т. е. используют один локальный тактовый сигнал. При необходимости передачи данных между подсистемами используется схема защиты от метастабильности (тактируемая сигналом подсистемы-приемника) или BRAM с физически независимыми портами, каждый из которых тактируется собственным сигналом. Схема защиты метастабильн Подсистема 1 CLKlf Рис. 7.7. Структурная схема проекта с архитектурой GALS
396Гл ава 7.4. Управление настройками САПР 7.4.1. Настройки синтеза Операции синтеза в Vivado вынесены в отдельную группу на инструментальной панели. Выбор пункта «Synthesis Settings» от_ крывает диалоговое окно, позволяющее установить отдельные настройки или выбрать одну из готовых стратегий синтеза. Каждая стратегия имеет собственный набор настроек. Диалоговое окно настроек синтеза показано на рис. 7.8. Можно кратко перечислить показанные в нем пункты. Tcl.pre и tcl.post — имена файлов на языке Tel, которые должны выполняться перед и после синтеза соответственно. Flatten hierarchy (с вариантами full, none и rebuilt) — управление «разворачиванием» схемы. При выборе варианта full синтезатор полностью перестраивает схему, основываясь на встроенных алгоритмах оптимизации. Вариант попе означает, что при синтезе необходимо строго придерживаться иерархии модулей, следующей из RTL-представления, заданного разработчиком. По умолчанию установлен вариант rebuilt («перестроить»), который подразумевает обновление иерархии в соответствии с оптимизированным вариантом. Проблема управления иерархией связана с тем, что для сложных проектов, основанных на RTL, автоматические алгоритмы могут давать худшие результаты, чем иерархия модулей, выстроенная разработчиком с большим опытом проектирования. Свойство gated clock conversion управляет автоматическим преобразованием схем, известных как gated clock (соответствующий русскоязычный термин — «тактовый сигнал, проходящий через логический вентиль»). Появление такой схемы является безусловным негативным фактором, поскольку для распространения тактовых сигналов в ПЛИС используются специально выделенные цепи. Попытка управления тактовым сигналом, например, с помощью его отключения вентилем «И» на первый выглядит логически корректной, однако резко повышает вероятность нестабильной работы части схемы, которая теперь будет получать фронт тактового сигнала, отстающий по фазе от основного сигнала, распространяемого специальными цепями. Если включить преобразование цепей gated clock, то синтезатор будет автоматически заменять такие узлы на схемы, сохраняющие целостность тактового сигнала и выключающие его другими способами, например с помощью входа clock enable. Параметр bufg определяет число глобальных буферов для распространения тактового сигнала, которые должен установить синтезатор. Показанное на рис. 7.5 значение «12» соответствует макси-
Олтямизация проекта 397 Рис. 7.8. Настройки проекта — синтез мальному числу тактовых сигналов, которые разведены в каждый тактовый регион в ПЛИС серии 7. Параметр полезен, если в проекте имеются дополнительные компоненты, которые будут установлены позднее, и потребуют использования дополнительных тактовых сигналов. Параметр fanout Jimit устанавливает максимальное число входов, которые могут быть подключены к одному выходу (аналогичный русскоязычный термин — коэффициент разветвления по выхо-
398 Г л а ва ду). В данном случае речь не идет об электрической нагрузочной способности логической ячейки ПЛИС, поскольку в составе мик- росхемы имеются соответствующие буферные элементы. Негатив-, ный эффект от слишком большого значения fanout заключается в возможном увеличении длины трассировочных линий. Если будет обнаружено, что получаемый для некоторого сигнала fanout превышает величину, заданную в настройках синтеза, синтезатор автоматически продублирует источник такого сигнала. Копия источника может быть размещена в другой точке кристалла, ближе к основным потребителям, что улучшает качество трассировки. Значение 10000 на практике вряд ли будет превышено, поэтому при необходимости действительного управления дублированием сигналов следует выбирать значения в диапазоне 50-200. Параметр retiming разрешает работу алгоритмов балансировки внутренних цепей, чтобы добиться более высокой частоты работы конвейеризованной схемы. Параметр fsm_extraction управляет автоматическим выделением конечных автоматов (КА) из схемы. Возможные значения: off (КА не создаются), onejiot, sequential, Johnson, gray, auto. Последний вариант означает возможность автоматического выбора типа КА в зависимости от числа состояний. Остальные устанавливают соответствующий тип К А. Конечные автоматы являются эффективным средством описания синхронных схем и хорошо соответствуют архитектуре PPGA, поэтому их синтезу уделяется достаточно большое внимание. Параметр keep_equivalentjregisters может оказаться полезным для экспериментов. Установка этого параметра сохраняет в проекте копии регистров, которые формально были описаны как независимые, однако по результатам построения схемы их поведение совпало. Установка этого параметра может войти в противоречие с эффектом от дублирования регистров с целью получения их копии в разных частях кристалла (что улучшает характеристики трассировки). Трудно заранее предсказать, какой из вариантов глобальной стратегии окажется оптимальным, поэтому данный параметр и является кандидатом для экспериментирования. Параметры resourcejsharing и no Jc имеют схожее действие. Первый из них управляет обобщением арифметических выражений. Например, если в проекте имеется схема, вычисляющая сумму двух сигналов а + Ь, то ее выход будет использоваться в различных точках схемы. Положительной стороной является экономия ресурсов, но негативной — появление на кристалле точки, выход которой мо-
Оптимизация проекта 399 Рис. 7.9. Выбор стратегии синтеза жет быть соединен с множеством получателей этого сигнала, находящихся на удаленных сторонах кристалла. Параметр node расшифровывается как «no LUT combining». Этот процесс означает помещение двух логических функций в одну LUT в режиме частично совмещенных 5-входовых комбинационных выражений (там, где это применимо). Эффект от плотной упаковки логических выражений может также вступить в противоречие с требованиями трассировки, если результаты вычисления скомбинированных выражений требуются в противоположных частях кристалла. Эти параметры также являются предметом экспериментов, если результаты синтеза не устраивают разработчика. В целом можно отметить, что обобщение эквивалентных регистров, арифметических выражений и комбинирование LUT является одним из крайних подходов (компактная схема с минимальным объемом ресурсов, но чувствительная к результатам размещения и трассировки), а противоположный набор настроек дает возможность синтезатору создавать копии сигналов, что облегчает последующую трассировку, если проект имеет сложные связи между компонентами. На рис. 7.9 показано диалоговое окно выбора готовых стратегий синтеза. Каждая из стратегий предоставляет собственный набор настроек, которые могут быть скорректированы разработчиком с образованием собственной стратегии (User Defined Strategy). 7.4.2. Настройки размещения и трассировки (implementation) Выполнение синтеза и формирование проектных ограничений по расположению выводов позволяют выполнить размещение и трассировку проекта. Настройки процесса implementation показаны
400 Глава г Option-* Рис. 7.10. Настройки проекта — implementation на рис. 7.10. В выпадающем списке видно, что кроме настроек по умолчанию Vivado предлагает дополнительные стратегии, отличающиеся сочетанием времени работы САПР и качеством получаемых результатов. Часть настроек процесса Implementation схожа с аналогичными настройками синтеза. Например, это касается параметров сценариев tcl.pre и tcl.post, которые запускаются до и после реализации, аналогично тому, как это происходит для процесса синтеза. 7.4.3. Оптимизация проекта с помощью изменения настроек САПР Наличие в САПР Vivado нескольких стратегий при неоднозначных прогнозах их эффективности делает предпочтительным иссле-
Оптимизация проекта 401 Анализ результатов Рис. 7.11. Маршрут оптимизации проекта с применением сравнительного анализа результатов применения стратегий САПР довательский характер выбора оптимального сочетания настроек синтеза и implementation. На рис. 7.11 показан принцип применения такого маршрута оптимизации. Имея набор компонентов, описанных на уровне RTL, и IP-ядер, можно добавить к основному маршруту проектирования набор дополнительных вариантов синтеза, различающихся применяемыми стратегиями. Один или несколько результатов синтеза могут быть скомбинированы с процессами implementation (на рис. 7.11 показаны как P&R — Place and Route). Наличие нескольких вариантов финальной трассировки, отличающихся достигнутой тактовой частотой, использованными ресурсами и потребляемой мощностью, может быть использовано для анализа результатов, где разработчик должен иметь собственные критерии оптимальности. Чтобы избежать перебора настроек вручную, в САПР Vivado предусмотрен инструмент планирования списка запускаемых процессов. На рис. 7.12 показана кнопка на инструментальной панели (вкладка Design Runs). Нажатие кнопки с символом «+» открывает мастер создания списка процессов, которые должны быть запущены. Возможно создание сложного списка, в котором каждому варианту стратегии синтеза можно сопоставить собственный список вариантов Implementation. Для больших ПЛИС время синтеза и особенно Implementation может оказаться весьма длительным и достигать десятков часов для ПЛИС большого объема. Разумеется, это не относится к ПЛИС начального уровня. Тем не менее произвольное планирование перебираемых стратегий способно неоправданно увеличить время одной итерации разработки. Поскольку проверка стратегии представляет собой независимый процесс, в данном режиме Vivado способна в полной мере использо-
402 г лава 7 Рис. 7.12. Создание списка стратегий для запуска вать возможности многоядерных процессоров. При запуске созданного списка можно указать число ядер процессора, которые будут использованы для параллельной работы с несколькими выбранными стратегиями. В целом следует находить баланс между достижением оптимальных параметров проекта и временем его реализации. В данном случае разработчик и руководитель проекта имеют частично несовпадающие интересы, поскольку они оба в целом заинтересованы в достижении высоких технических показателей, но длительное время автоматической работы САПР для разработчика по сути означает ожидание результатов. Это может провоцировать неоправданное увеличение числа стратегий и частоты запусков режима их перебора. С организационной точки зрения рекомендуется устанавливать определенную регулярность подобных запусков или обуславливать включение такого режима достижением заранее определенных контрольных точек проекта. 7.5. Анализ проекта в САПР Vivado Кроме настроек САПР, разработчик имеет в своем распоряжении мощный инструмент управления деталями реализации проекта. Речь идет о проектных ограничениях (constraints), представляющих собой правила оценки временных характеристики проекта и расстановки компонентов на кристалле. В САПР Vivado был введен новый формат xdc (Xilinx Design Constrants), весьма близкий по структур6 и синтаксису к формату sdc (Synopsys Design Constraints), который используется при проектировании СБИС.
Оптимизация проекта 403 Проектные ограничения могут быть разделены на несколько групп. 1. Временные ограничения (timing constraints) задают глобальные правила проверки цепей проекта. 2. Временные исключения (timing exceptions) задают правила, перекрывающие по приоритету глобальные временные ограничения. Они применимы в ряде случаев, которые будут описаны в данном разделе. 3. Топологические ограничения (area constraints) — инструкции по правилам размещения компонентов на кристалле ПЛИС. С топологическими ограничениями разработчик знакомится в первом же проекте, подразумевающим загрузку конфигурации в ПЛИС, поскольку указание выводов ПЛИС, к которым необходимо привязать сигналы, также относится к топологическим ограничениям. Прежде чем добавлять проектные ограничения, необходимо проанализировать проект. В целом можно упомянуть, что привязка сигналов к выводам ПЛИС и установка глобальных ограничений (например, тактовой частоты, поданной на глобальную тактовую сеть) для многих проектов является достаточным набором. Если проект достигает заданной частоты и работоспособен, актуальность дополнительной работы с ним довольно сомнительна. У разработчика может возникнуть неверное впечатление, что проектные ограничения каким-то образом сами по себе способствуют улучшению характеристик проекта. В действительности они описывают дополнительные правила проектирования, которые должны быть выполнены САПР, но приведет ли выполнение этих дополнительных условий к улучшению характеристик проекта, целиком зависит от квалификации разработчика, особенностей проекта и даже ряда случайных факторов. Большое число компонентов на кристалле ПЛИС и множество трассировочных линий делает практически невозможным какие-либо алгоритмы полного перебора с поиском математически точных оптимальных решений. Поэтому для создания качественных проектов, работающих на высокой тактовой частоте, неприменим подход, основанный на «силовом решении» проблемы оптимизации. В целом Xilinx рекомендует приступать к управлению проектными ограничениями при соблюдении всех следующих условий: 1. Разработчик хорошо знает проект и предметную область. 2. Разработчик хорошо знает архитектуру компонентов используемого семейства ПЛИС.
404 Г л а ва г 3. Разработчик обладает опытом работы в САПР Vivado не менее двух лет. 7.5.1. Анализ результатов синтеза Оптимизация проекта в общем случае может быть выполнена по следующим основным показателям: • тактовая частота; • используемые ресурсы ПЛИС; • потребляемая мощность. Прежде чем приступать к управлению деталями реализации, необходимо выяснить, существует ли объективная возможность для улучшения выбранной характеристики проекта. Возможно, что достигнутый результат уже практически исчерпал возможные резервы даже в автоматическом режиме САПР и попытки улучшения его характеристик с помощью проектных ограничений приведут лишь к дополнительным затратам времени с сомнительными перспективами. После выполнения синтеза появляется возможность открыть синтезированный проект. При этом изменяется расположение и состав элементов управления в рабочей области, в частности появляется вкладка «Package», показывающая расположение выводов в корпусе ПЛИС и позволяющая выполнить их привязку к сигналам проекта. В панели навигации появляются дополнительные пункты, раскрывающиеся в меню Synthesized Design, как показано на рис. 7.13. Пункт Constraints Wizard запускает мастер создания проектных ограничений. Просмотреть имеющиеся в проекте ограничения можно с помощью следующего пункта, Edit Timing Constraints. Откро- ющееся окно редактирования временных ограничений показано на рис. 7.14. Следующая группа действий включает в себя генерацию отчетов по различным аспектам синтезированного проекта. • Set Up Debug — открывает мастер добавления в проект модуля отладки, который был рассмотрен в разделе 5.7; • Report Timing Summary — отчет по временным задержкам; • Report Clock Networks — отчет по тактовым сетям; • Report Clock Interaction — отчет по взаимодействию тактовых сетей; • Report Methodology — отчет по выполнению рекомендаций проектирования; • Report DRC — отчет по соблюдению правил проектирования (Design Rules);
Оптимизация проекта 405 Open Synthesized De's-cm Utilization Рис. 7.13. Процессы, доступные для синтезированного проекта • Report Noise — отчет по шумам; • Report Utilization —- отчет по использованию ресурсов ПЛИС; • Report Power — отчет по потребляемой мощности; • Schematic — генерация принципиальной электрической схемы по результатам синтеза. Содержимое отчетов, получаемое после синтеза, представляет собой предварительные оценки, поскольку после размещения и трассировки ряд параметров может измениться. Выполнение ряда проектов, однако, показывает, что оценки на данном этапе достаточно точны и вполне позволяют сформулировать требования к источникам питания, печатной плате и т. п. Команда Report Timing Summary дает общую информацию об оценке выполнения проектных ограничений. Главный параметр, на который стоит обратить внимание, — Worst Negative Slack. Этот параметр не должен быть отрицательным, поскольку он представляет собой запас по времени на распространение сигнала по самой медленной цепи проекта.
406 Г л а: Рис. 7.14. Окно редактирования временных ограничений проекта Рис. 7.15. Пример отчета для команды Report Timing Summary Команда Report Clock Networks показывает структуру тактовых цепей. Пример ее выполнения показан на рис. 7.16. На этом рисунке можно убедиться, что тактовые сигналы проходят через глобальные тактовые буферы BUPG. Важной командой является Report Clock Interaction. Выше уже упоминалось, что корректная организация передачи данных меж-
ПпТцмязация проекта 407 Рис. 7.16. Пример отчета для команды Report Clock Networks ду тактовыми доменами является важной задачей. Средства функционального моделирования неспособны показать проблемы такого рода, поскольку ориентируются на идеализированные параметры тактовых сигналов, задаваемые разработчиком. Однако можно проверить, существуют ли в проекте такие цепи, которые подключаются к выходу компонента, тактируемого одним сигналом, и к входу компонента, тактируемого другим тактовым сигналом. Такое взаимодействие (interaction) и проверяется в Vivado. В результате выполнения команды в основном окне САПР строится диаграмма, пример которой показан на рис. 7.17. Горизонтальные ряды помечены как Source Clock, т. е. домены-источники. Вертикальные колонки помечены как Destination Clock, т.е. домены-приемники. Главная диагональ, проведенная из левого верхнего в правый нижний угол, отмечена светлосерыми прямоугольниками. Она соответствует совпадению домена-источника и домена-приемника. Серый цвет означает наличие проектных ограничений, что естественно, потому что в синхронном проекте нет проблем с передачей данных между компонентами, тактируемыми одним и тем же сигналом.
I? Рис. 7.17. Пример проверки взаимодействия тактовых доменов командой Report Clock Interaction
пптямизация проекта 409 Однако два других прямоугольника, с несовпадающими источником и приемником, помечены темносерым. Этот цвет означает, чТо в проекте не заданы исключения, помечающие соответствующие цепи как несинхронные. Попытка анализа таких цепей даст некорректные результаты. Добавление проектных ограничений (исключений, timing exceptions) изменит цвет ячеек этой таблицы на оттенки синего (потребуется повторный запуск анализа для обновления результатов). @ Следует запускать команду Report Clock Interaction и добавлять проектные ограничения (timms exceptions) для показанных в отчете цепей вплоть до устранения проблем. Команда Report Noise оценивает уровень шумов, генерируемых на выводах ПЛИС. Эта оценка является приближенной и ориентируется на число выводов с теми или иными электрическими интерфейсами, установленных в каждом банке ввода-вывода. Изменение напряжения на выходах ПЛИС генерирует электромагнитное излучение, которое наводится на входы, расположенные рядом. При высокой частоте и плотной упаковке выводов в корпусе ПЛИС их взаимным влиянием уже нельзя пренебрегать. На рис. 7.18 показан пример выполнения команды Report Noise. Параметр remaining margin оценивает уровень запаса по напряжению в процентах. Это понятие, разъясняемое в Xilinx Answer Record 44394, иллюстрирует рис. 7.19. Надежное считывание логических уровней происходит, если логическая единица не снижается ниже напряжения Vih, а логический ноль не повышается выше Vil. Оба эффекта могут возникнуть Рис. 7.18. Пример выполнения команды Report Noise
410 Глава 7 remaining из-за электрических помех, наво-. noise тщ^щ димых от соседних выходов. У * вень запаса (margin) не должен Xt 100% 0ПУскаться ниже 0. Можно еще Maigin раз отметить, что оценка являет- /\ .,/>.. ся ориентировочной и при малых \ттмт^^тятттт^ положительных значениях запаса Рис. 7.19. Разъяснение пара- следует провести проверку с по- метра remaining margin со- мощью профессиональных САПР гласно Answer Record 44394 печатных плат, способных оценивать уровень взаимных электромагнитных помех для соседних выводов микросхем. Команда Report Power оценивает уровень потребляемой мощности. Диалоговое окно, показанное на рис. 7.20, позволяет задать дополнительные параметры для оценки. Например, в зависимости от числа слоев печатной платы и условий охлаждения температура ПЛИС будет меняться. Результаты анализа потребляемой мощности показаны на рис. 7.21. В отчете показаны отдельные составляющие потребляемой мощности. Статическое потребление зависит от используемой ПЛИС и является постоянным. Динамическое потребление пропорционально тактовой частоте проекта. Однако компоненты, не задействованные в проекте, не вносят свой вклад в динамическое потребление. Поскольку после синтеза число компонентов по основным группам уже известно, можно оценить динамическое потребление. Удобным инструментом анализа временных характеристик проекта является так называемая Slack Hystogram (вызываемая командой в консоли Tel «create-slackJiystogram -name hystl», где hystl — выбираемое пользователем имя для окна). Результат построения представлен на рис. 7.22. По горизонтальной оси расположено время, имеющееся в запасе у отдельных цепей проекта, а по вертикальной — число цепей, укладывающихся в такой запас. Зеленый цвет отдельных столбиков гистограммы свидетельствует о том, что все временные ограничения выполняются (в противном случае, при отрицательной величине параметра slack, соответствующая часть гистограммы окрашивается красным). На показанном примере видно, что для уменьшения периода тактового сигнала на 3 не необходимо улучшить характеристики 1072 сигналов (крайний левый столбик гистограммы). Это довольно много, поэтому надеяться на существенное улучшение данного проекта не стоит. С другой стороны, если бы в этом столбике было показано небольшое число линий (услов-
Оптимизация проекта 411 ::.:,ti:r>3te penes' a: Environment r'::¦', Device Settings commercial Environment Setiimfs Output load: Junction temperature: A>n fa ienf fempei¦ зtуf*r' Effective #JA; Airflow: H€;af «.ink; Board selection: 250 mechum '.>¦': :¦ niedfiini ¦ .V 0 25 25 2 !' t)f 197 '"C 484 °C.A ' i'" Л dumber of board layers; 12fo15 ' Board tempera tun legend User Defined Calculated Default Рис. 7.20. Диалоговое окно запуска анализа потребляемой мощности но, до 30-50), это бы свидетельствовало о наличии в проекте всего одной неудачно проведенной шины. Если бы разработчику удалось улучшить ее характеристики (здесь нужно отметить, что цепи, выбранные в окне гистограммы, будут также показаны и в других
412 Рис. 7.21. Результаты анализа потребляемой мощности Рис. 7.22. Гистограмма запаса по времени распространения сигналов (slack histogram) видах проекта), оказалось бы возможным уменьшить период тактового сигнала. Команда report_timing формирует отчет по наихудшим с точки зрения запаса по времени цепям. Пример такой команды приведен ниже: report .timing -delay -type minjmax -max-paths 10 -sort.by group -input_pins -name timing_2 В данном варианте с помощью дополнительных параметров установлено формирование списка из 10 наихудших цепей (-max.paths 10). Полный список дополнительных ключей и их действий, как и для других команд, можно получить, набрав в консоли Tel команду help report.timing.
Оптимизация проекта 413 Рис. 7.23. Результат выполнения команды report_timing На рис. 7.23 показан пример отчета в соответствии со сделанным запросом. Таким образом, с помощью команд Tel можно провести разносторонний анализ полученного проекта, проверить степень покрытия цепей проектными ограничениями, выявить критичные цепи. После этого можно провести уточнение проектных ограничений, облегчив САПР задачу трассировки. 7.5.2. Анализ результатов размещения и трассировки После выполнения процесса Implementation становятся доступны уточненные параметры проекта. Список возможных пунктов анализа остается тем же, что и для синтеза, однако результаты будут точнее из-за того, что известно не только число компонентов проекта, но и их расположение на кристалле ПЛИС, а также задержки трассировочных ресурсов. Внешний вид окна САПР Vivado с открытым проектом после процесса Implementation показан на рис. 7.24. Уточненные параметры проекта включают в себя, например, положительные значения запаса по задержкам (slack). Если после синтеза оценка проекта была отрицательной, то при трассировке проекта САПР разместила компоненты таким образом, чтобы обеспечить достижение заданной разработчиком тактовой частоты (рис. 7.25).
414 Глава Рис. 7.24. Внешний вид окна САПР Vivado после выполнения процесса Implementation Рис. 7.25. Детализированное представление размещения компонентов проекта в режиме Device View (изображение инвертировано)
Оптимизация проекта 415 7.6. Использование проектных ограничений формата xdc в САПР Vivado для работы с ПЛИС Xilinx 7.6.1. Роль проектных ограничений в маршруте проектирования для ПЛИС Одним из нововведений САПР Vivado, предназначенной для разработки проектов на базе ПЛИС Xilinx серии 7 и последующих поколений, является переход к формату xdc (Xilinx Design Constraints) для описания проектных ограничений. Этот формат полностью заменил использовавшийся ранее ucf (User Constraints File), следовательно, для полноценной работы с Vivado необходимо освоить xdc. Возможности этого формата, основанного на языке tcl и близкого к промышленному стандарту sdc, довольно обширны, поэтому применение его в практике проектирования может помочь разработчикам получать более качественные и воспроизводимые результаты. Переход к формату xdc обусловлен возрастающей сложностью проектов и необходимостью более полного контроля над процессами синтеза, реализации, установки проектных ограничений, формирования отчетов и пр. При работе с ПЛИС большого объема часто бывает удобно выполнять все стадии проектирования путем запуска единственного сценария. При этом разработчику более не требуется повторять все действия с интерфейсом САПР в правильном порядке, поскольку порядок действий определяется сценарием. Также за счет системы проектных ограничений результаты работы становятся более предсказуемыми. Можно представить процесс сборки проекта для ПЛИС серии 7 с сотнями тысяч и миллионами ячеек, отдельные стадии которого могут занимать несколько часов. Если разработчик будет вынужден следить за надлежащим выполнением каждой стадии, проверять результаты и вручную запускать следующий этап, производительность его работы заметно упадет. Кроме того, последовательные запуски синтеза и реализации (implementation) с разными наборами настроек (что может потребоваться для проектов со сложной структурой и жесткими временными ограничениями) довольно неудобно выполнять вручную. Именно для автоматизации подобных действий используется встроенный интерпретатор языка tcl, к синтаксису которого и приведен формат проектных ограничений xdc. В проекте может быть несколько наборов проектных ограничений, из которых активным является только один. Наборы организованы в отдельную подгруппу в файлах проекта, как показано
416 Soutces Рис. 7.26. Управление набором проектных ограничений в Vivado на рис. 7.26. Разработчик может оперативно переключаться между наборами. Это сделано для того, чтобы при экспериментах с проектными ограничениями не нужно было вручную удалять и комментировать временно неиспользуемые ограничения, если они приводят к проблемам или ухудшениям параметров проекта. При работе Vivado поддерживает базу данных компонентов проекта. Все используемые ресурсы ПЛИС подразделяются: • на ports — внешние порты проекта, т. е. внешние выводы ПЛИС, участвующие в реализации проекта; • cells (ячейки) — все аппаратные компоненты, включая логические ячейки, аппаратные примитивы, иерархические модули; • pins — выводы аппаратных компонентов всех уровней, т.е. в качестве pins рассматривается не только вход аппаратного примитива, но и вход иерархического модуля, который внутри подключается к этому входу; • nets — соединения между ports/pins в любых сочетаниях. Каждый объект проекта имеет множество свойств (property). Полный список свойств, имеющихся в расширениях tcl для Vivado, превышает 6500 наименований. Свойства имеют как компоненты проекта внутри ПЛИС, так и файлы проекта и другие возможные объекты. При задании проектных ограничений можно воспользоваться возможностями tcl по созданию списков из элементов, обладающих определенными свойствами. Например, команда get.cells -hier - filter {LIB-CELL == FDCE} создаст список аппаратных примитивов типа FDCE, использованных в проекте. Перечень команд tcl, формирующих списки компонентов, приведен в табл. 7.1.
Оптимизация проекта 417 Таблица 7.1 Команды tcl, формирующие списки компонентов проекта Команда get.cells get_pins get_nets get_ports all-inputs all-outputs allJffs all-latches alLdsps all_rams Описание Создает список ячеек проекта Создает список внутренних выводов Создает список цепей Создает список внешних выводов Создает список из всех входов проекта Создает список из всех выходов проекта Создает список из всех триггеров (FF, Flip-Flop) проекта Создает список из всех защелок (latch) проекта Создает список из всех модулей DSP48 проекта Создает список из всех модулей памяти проекта Все команды, перечисленные в табл. 7.1, могут комбинироваться с фильтрами. Например, команда get_ports -filter {DIRECTION == in && NAME =~ *clk*} создаст список внешних выводов проекта, являющихся входами (условие «DIRECTION == in») и одновременно не имеющих в своем имени фрагмента «elk» (условие NAME =~ *clk*). Создание списков компонентов важно для последующего задания временных или топологических ограничений. Использование регулярных выражений и команд разных типов позволяет более гибко формировать условия фильтрации объектов. Например, вместо указания цепей в виде «цепи с именами ппп» можно выполнить запрос на создание списка в стиле «все цепи, подключенные к входам ппп», или «все цепи, выходящие из группы примитивов ппп и приходящие на входы ттт». 7.6.2. Проектные ограничения для закрепления выводов ПЛИС Печатная плата, на которой установлена ПЛИС, разведена строго определенным образом, так что подключение внешних компонентов должно производиться к конкретным выводам, определяемым топологией этой платы. Поэтому каждый проект должен сопровождаться списком выводов ПЛИС, к которым подключаются те или иные сигналы схемы. С отказом от формата ucf этот список должен быть представлен в файле xdc. Описание свойств сигналов производится с помощью команды set.property. Основными свойствами, подлежащими определению, являются название вывода и электрический стандарт, который должен быть для него установлен. Пример приведен ниже: set.property PACKAGE.PIN V20 [get.ports wbClk] set.property IOSTANDARD LVCMOS18 [get.ports wbClk]
418 Гла в а 7 Необходимость обязательного определения электрического стандарта является новой по сравнению с ucf, который применяется в САПР ISE для семейства Spartan-б. Технически каждый банк ввода-вывода в FPGA имеет собственное питание, которое подается на все блоки такого банка. Указание напряжения в электрическом стандарте использовалось для оценки уровня шумов, а также для проверки того, что разработчик не разместил в одном банке выводы, для которых он предполагает разное напряжение питания. При работе FPGA напряжение будет подано «по факту», в зависимости от трассировки печатной платы, и указание в Ucf LVCMOS18 при действительном напряжении в 2,5 В не приведет к выходу из строя микросхемы, хотя реальные показатели помехоустойчивости и потребления мощности могут не совпадать с моделью, которая была основана на другом напряжении питания. Отсутствие явного указания электрического стандарта приводило к использованию стандарта «по умолчанию» — LVCMOS, при этом САПР не могла никак проконтролировать возможные ошибки разработчика. В файле xdc разработчик обязан указать, какие электрические стандарты он собирается использовать для каждого блока ввода- вывода. САПР контролирует совместимость стандартов для каждого банка, в частности, запрещая трассировку проекта, если в одном банке используются два и более напряжений питания. Кроме обязательных, в xdc могут быть установлены следующие параметры: DRIVE — установка выходного тока (в мА), параметр доступен для некоторых электрических стандартов; SLEW — установка скорости нарастания выходного сигнала; установка пониженной скорости нарастания улучшает помехоустойчивость проекта; IN.TERM — установка входного терминатора; OUT-TERM — установка выходного терминатора; DIFF.TERM — установка дифференциального терминатора; KEEPER — установка схемы удержания последнего состояния; PULLDOWN — установка «подтягивающего» резистора для обеспечения логического нуля; PULLUP — установка «подтягивающего» резистора для обеспечения логической единицы; DCLVALUE — определение поведенческой модели для ЮВ при создании IBIS-модели; DCLC ASCADE — определение набора master и slave банков ввода-вывода для образования цепочки опорного напряжения Vref;
Оптимизация проекта 419 INTERNAL.VREF — установка использования внутреннего опорного напряжения вместо его подачи с входов Vref; IODELAY.GROUP — группировка компонентов IDELAY и 10- DELAY для совместной работы с DELAYCTRL; IOBDELAY — установка задержки компонентов IDELAY и 10- DELAY; ЮВ — разрешение использования триггеров в блоках ввода- вывода. 7.6.3. Описание временных ограничений Временные ограничения являются практически обязательной частью любого сколько-нибудь сложного проекта на базе ПЛИС. Для многих проектов оказывается достаточным указания следующих глобальных параметров: • период тактовой частоты; • задержка распространения входного сигнала; • задержка распространения выходного сигнала. Тактовый сигнал описывается с помощью команды create_clock: create.clock -period 5 -name clk_pin_p [get.ports clk_pin..p] Цепи проекта, которые будут проанализированы после указания такого ограничения, показаны на рис. 7.27. Можно видеть, что указание периода тактового сигнала позволяет САПР проверить все цепи, соединяющие тактируемые этим сигналом компоненты. Смысл проверки ограничения create_clock заключается в следующем. Между двумя любыми тактируемыми компонентами, которые передают друг другу данные, образуется схема, подобная показанной на рис. 7.28. После записи данных в первый триггер происходят следующие события: • через время ?ckq сигнал, записанный в триггер, появляется на его выходе (время отсчитывается от момента прихода фронта тактового сигнала); • через время ?routei сигнал попадает на вход LUT; Clockperiod < > Clockperiod < —> D Q D Q D Q Рис. 7.27. Действие проектного ограничения create_clock
420 iia 7 Jcko Известно только после трассировки D Q Рис. 7.28. Структура задержки распространения сигнала в синхронной схеме • через время ?шт сигнал появляется на выходе LUT; • через время troute2 сигнал попадает на вход второго триггера. Для надежной записи сигнала во второй триггер сигнал должен появиться на его входе данных за время не менее ?setup («время установки сигнала»). Времена #ckq, ^lut и ?Setup известны для выбранной ПЛИС, поскольку характеризуют ее аппаратные компоненты. После синтеза схемы становится известно, как образована каждая цепь, поэтому можно оценить задержку, гарантированно внесенную уже примененными синтезатором компонентами. Задержки на отдельных сегментах трассировочных ресурсов в принципе также известны САПР. Однако неизвестно, где конкретно на кристалле ПЛИС будут выбраны места для показанных на рис. 7.28 компонентов, поэтому точное время, которое будет затрачено на распространение сигналов по трассировочным линиям, станет известно только на этапе Implementation, после выбора размещения компонентов проекта и конкретных трассировочных линий, которые будут использованы для их соединения. После сложения всех составляющих задержки будет получено некоторое значение. Для нормальной работы схемы эта сумма должна быть меньше, чем период тактового сигнала tperiod- Время, которое остается в запасе у анализируемой цепи, называется slack («слабина», «запас»). Для всех цепей проекта величина slack должна быть неотрицательной. Это проверяется алгоритмами временного анализа проекта, причем САПР может при необходимости изменять взаимное расположение компонентов, уменьшая при необходимости время tvoute- Как уже было указано, тактовая частота после синтеза оценивается по точным значениям задержек, вносимых компонентами
оптимизация проекта 421 ЦЛИС, и ориентировочным значениям задержек, которые могли бы быть внесены трассировочными линиями. Основанием для оценки ддйны этих линий является показатель fanout (коэффициент разветвления по выходу). Подразумевается, что для компонента, выход которого имеет единственный приемник, можно установить этот приемник в непосредственной близости. Однако если входов становится несколько десятков или сотен, какой-то из компонентов-приемников будет вынужденно находиться далеко. Может показаться, что решением проблемы достижения требуемой тактовой частоты является минимизация задержки на линии данных, в том числе путем тонкой подстройки фазы тактового сигнала. Однако в данном случае можно столкнуться с проблемой, берущей начало в особенностях микроэлектронных компонентов, выполняемых по глубоким технологическим нормам. Задержки на компонентах микросхемы (не только ПЛИС, но и любого кристалла) заметно изменяются при вариациях различных параметров. Основные факторы, влияющие на задержки, обозначают символами PVT (здесь могут возникнуть ассоциации с термодинамикой, однако совпадает только Т — температура). Расшифровка этой аббревиатуры следующая: • Process — вариации параметров технологического процесса, ведущие к разбросу «базовых» значений задержек между партиями микросхем и между микросхемами в одной партии; • Voltage — напряжение питания; • Temperature — температура кристалла. Наибольшие задержки образуются при минимальном напряжении питания (в пределах допуска, но вблизи нижней допустимой границы) и максимальной температуре. Это наиболее сложный режим работы для микросхем. В сочетании с худшими сочетаниями параметров самого кристалла (на границе допустимого по контролю качества) образуется комбинация условий, обуславливающих максимальную задержку. Если представить параметры PVT в виде трех осей, допустимые границы разброса параметров, напряжения и температуры образуют в этом пространстве параллелепипед. Сочетание параметров, при которой наблюдаются максимальные задержки, наблюдается в одном из углов этого параллелепипеда. В отчетах САПР можно увидеть строку «slow corner», которая и соответствует «наихудшему углу» в пространстве анализа. В отчетах САПР, проверяющих запас на распространение данных, учитывается именно это время, соответствующее «медленному
422Г л а в а углу». Иными словами, если в отчетах указано, что для проект запас по времени для наихудшей цепи все еще положителен и со- ставляет столько-то наносекунд, это относится к наиболее сложному для ПЛИС режиму работы. Что же произойдет, если условия работы будут соответствовать «средним», а тем более наилучшим (fast corner). Очевидно, что задержки распространения сигналов станут минимальными. Этот случай, тем не менее, не так безобиден, как может показаться. Дело в том, что кроме времени установки сигнала, синхронные компоненты имеют также и время удержания (hold time), в течение которого данные должны все еще присутствовать на входе после получения фронта тактового сигнала. Если цепь данных слишком короткая, а сочетание условий работы кристалла наилучшее, то данные могут смениться слишком быстро, и будет нарушено условие по времени удержания сигнала (hold time violation). Данная проблема получила актуальность для технологических процессов в нормами 28 нм — для Xilinx это серия 7. Если для более ранних поколений технологических процессов задержки распространения были достаточно велики, а их вариации еще не так су- ществены, на практике можно было добиваться только выполнения условий по времени установки сигнала. Поскольку с уменьшением технологических норм вариации задержек нарастают, проверки на время удержания также стали актуальны. Одним из важных преимуществ САПР Vivado по сравнению с ISE является улучшенный анализ hold time, т. е. времени удержания. Имеются множество прецедентов успешной работы проектов на ПЛИС среднего размера (Kintex-7 325), работавших нестабильно при применении ISE. Чтобы избежать проблем с временем удержания, разработчику в действительности достаточно выполнять простые ограничения: следовать методологии синхронного проектирования и не пытаться вмешиваться в тактовые сети, добавляя туда собственные компоненты. Анализ задержек, выполняемых для тактовых сетей, выполняется достаточно точно, и при задании параметров входного тактового сигнала будут произведены требуемые проверки как для slow corner (для времени установки), так и для fast corner (для временя удержания сигнала). Ш ПЛИС семейств UltraScale-h в действительности обладают возможностью тонкого управления фазой тактового сигнала для отдельных компонентов. Это дает возможность перераспределения временных задержек между ли-
Оптимизация проекта 423 ниями в цепочке синхронных компонентов (time borrowing, заем времени). Этот процесс выполняется САПР авто- матически с сохранением целостности тактовой сети и корректным анализом временных характеристик. На практике точность оценки тактовой частоты после синтеза может отличаться от достижимой после трассировки приблизительно на 30 % в любую сторону. Разработчик может улучшить задержки на трассировочных линиях, управляя взаимным расположением компонентов, образующих критические цепи. Этот процесс рассмотрен в разд. 7.7.5. Тактовые сигналы автоматически распространяются по проекту. Это означает, что описание сигнала, приходящего на вход компонента ММСМ или PLL, автоматически приведет к появлению корректных описаний выходных сигналов от этих блоков. При этом будут учтены такие факторы, как изменение номинального значения частоты, сдвиг фазы, коэффициента заполнения (Duty Cycle), вносимый джиттер и время нарастания фронта. Рекомендуется задавать проектные ограничения именно для входного тактового сигнала, а не для выходных сигналов, получаемых с помощью ММСМ/ PLL, поскольку в библиотеках Xilinx параметры ММСМ и PLL описаны более точно, чем это может сделать разработчик, руководствуясь своими соображениями. В отчете по тактовым сетям выходные сигналы, параметры которых автоматически определены САПР, помечаются символом «Р» (Propagated, распространенные). На рис. 7.27 также можно видеть, что задержка распространения сигнала от входов ПЛИС до триггеров и от выходов триггеров до выходов ПЛИС не учитывается при проверке ограничения по периоду тактового сигнала. Для задания этих ограничений используются команды set .input-delay и set_output_delay (в UCF они задавали проектные ограничения OFFSET IN и OFFSET OUT соответственно). Действие проектных ограничений setJnput_delay и set_output-delay показано на рис. 7.29. Указанные ограничения могут быть описаны в формате: set Jnput-delay 2 -clock elk [all-inputs] set _output .delay 3 -clock elk [alLoutputs] В данном случае числа 2 и 3 означают задержку в наносекундах, которая предполагается разработчиком за пределами ПЛИС. Иными словами, после момента фронта тактового сигнала пройдет 2 не, прежде чем соответствующий логический уровень появится на входе ПЛИС. САПР проверяет задержки внутри ПЛИС таким образом, чтобы этот уровень попал на вход соответствующего синхрон-
424 Г л а ва 7 Внешняя микросхема —1 Input delay ПЛИС Внешняя микросхема Output delay!— Clk Рис. 7.29. Действие проектных ограничений set Jnputjdelay и set .output .delay ного компонента до момента прихода следующего фронта тактового сигнала. Можно обратить внимание, что в формате ucf в аналогичном случае указывались максимально допустимые задержки внутри ПЛИС, т. е. от вывода ПЛИС до тактируемого компонента. Значения задержек, необходимых для приведенных команд, невозможно определить, пользуясь «внутренней» информацией о проекте. Внешняя по отношению к ПЛИС составляющая задержки может быть определена только на основе анализа печатной платы. При этом недостаточно ориентироваться только на длину проводников, поскольку в зависимости от импеданса источника, дорожки и приемника величина задержки распространения сигнала может существенно изменяться. Наилучшие характеристики для ограничений input_delay и output-delay могут быть достигнуты при установке в проект триггеров, расположенных непосредственно в блоках ввода-вывода. Для высокоскоростных внешних интерфейсов применение таких триггеров может быть рекомендовано. Тем не менее, если внешние интерфейсы имеют умеренные частоты, а тактовая частота для внутренних сигналов проекта, наоборот, предполагается высокой, отказ от триггеров IDDR, ODDR может повысить тактовую частоту за счет более компактного распространения триггеров. Суммируя, для каждого проекта базовыми временными ограничениями являются: • задание частоты каждого тактового сигнала командой create- clock; • определение задержек сигналов до входов ПЛИС командой set- input_delay;
Оптимизация проекта 425 • определение задержек сигналов после выходов ПЛИС командой set.output.delay. Если в проекте был добавлен тактовый генератор с помощью IP-ядра, настроенные тактовые частоты этого генератора будут автоматически добавлены к проектным ограничениям. Этот путь рекомендуется для практического проектирования, поскольку при изменениях параметров IP-ядра все настройки правильно отразятся в файле xdc. 7.6.4. Описание временных исключений (exceptions) Временные исключения (exceptions) представляют собой проектные ограничения, задающие особые правила анализа некоторых цепей. К основным исключениям относятся: • multicycle path; • max delay; • false path. Исключение multicycle path применяется для цепи, про которую разработчику точно известно, что распространение сигнала за один такт для нее не требуется. Пример показан на рис. 7.30. В этом примере межСЕ1 p""| CE2 N тактов ^ ду регистрами RegA и RegB имеется большая задержка рас- Рис. 7.30. Иллюстрация к понятию multicycle path пространения сигнала и эта цепь не удовлетворяет глобальному проектному ограничению по периоду тактового сигнала. Однако разработчик точно знает, что сигналы СБ1 и СЕ2, разрешающие запись в эти регистры, формируются с задержкой не менее чем N тактов. Поэтому сигнал, записанный в RegA, может и не распространяться за один период до входа RegB, поскольку к моменту следующего фронта тактового сигнала запись гарантированно не будет производиться. Цепь, соединяющая RegA и RegB, должна успевать распространить сигнал через много (multi) периодов, поэтому она и обозначается как multicycle path. Число тактов, за которые распространение сигнала все же должно завершиться, называется multicycle factor. В приведенном примере устанавливается multicycle factor, равный 2, для цепей, соединяющих <объект 1> и <объект 2>. Обратите внимание, что символ \ означает в xdc продолжение команды на следующей строке и введен в текст для улучшения читаемости. set_multicycle_path -from [<объект 1>) \ -to [<объект 1>] 2
426Г л а в а В показанном примере САПР будет проверять, что рКа находится в диапазоне между одним и двумя периодами тактового сигнала. Если по каким-то причинам задержка станет удовлетворять более жестким требованиям, появится ошибка hold violation т. е. слишком маленькое время удержания сигнала. Чтобы сделать допустимой любую задержку, не превышающую 2 такта, необходимо добавить также команду set _multicycle_path с ключом -hold. Параметром обычно является 1 (т. е. N-1), переносящий момент проверки времени удержания на нулевой такт (т. е. на фронт сигнала, предшествующий первому). set_multicycle_path -from [<объект 1>] \ -to [<объект 1>] 1 -hold Вопрос корректности установки multicycle factor для какой-то цепи целиком относится к ответственности разработчика. САПР в процессе анализа временных характеристик проекта будет использовать для отмеченных цепей не период тактового сигнала, а период, умноженный на multicycle factor. Проектное исключение max delay принудительно задает значение максимальной задержки распространения сигнала между объектами. set_maxjdelay <значение> -from [<объект 1>] \ -to [[<объект 2>] Так же, как и для multicycle path, задание максимальной задержки целиком относится к сфере ответственности разработчика, который должен быть уверен, что при соблюдении этого условия проект сохранит работоспособность. Наконец, исключение false path («ложная цепь») отменяет проверки для цепи и делает любое значение задержки приемлемым. Оно задается строкой вида set Jalse.path -from [get.clocks clkl] \ -to [get.clocks clk2] В данном примере объявляется, что все цепи, соединяющие компоненты, тактируемые сигналом clkl, с компонентами, тактируемыми сигналом clk2, являются false path, и проверки для этих цепей могут не проводиться. Такой пример является возможным способом указания проектных исключений для сигналов, передающих данные между тактовыми доменами, поскольку в этом случае задержка сигнала действительно не имеет значения, а корректная передача данных должна обеспечиваться выбором правильной архитектуры соединения. В качестве false path можно также помечать внешние цепи, подключающие механические переключатели или светодиоды (если речь идет о компонентах, предназначенных для оператора).
Оптимизация проекта 427 Status человека действительно несущественно, через сколько наносекунд будет распознано нажатие кнопки или загорится светодиодный индикатор, а соблюдение этих ограничений со стороны САПР может привести к дополнительным перестановкам компонентов на кристалле, что может ухудшить характеристики других цепей. На рис. 7.31 показан пример false path, образованной регистрами, работающими с внешней двунаправленной шиной. Подразумевается, что процессорная система внутри ПЛИС записывает состояние в регистр Status для его чтения внешним устройством. В режиме записи в ПЛИС внешнее устройство записывает данные в регистр управления Control. Прямая передача данных из Status в Control не предполагается, Contro < Рис. 7.31. Пример false path, образованной двунаправленной шиной и при работе процессора таких ситуаций не возникает. Тем не менее при временном анализе цепь, соединяющая эти регистры, попадет в список сигналов, подлежащих проверке по глобальному ограничению createxlock. Чтобы этого не происходило (а суммарные задержки на регистрах ввода-вывода вполне могут оказаться больше, чем период тактового сигнала), следует пометить цепь, соединяющую подобные регистры, как false path. 7.6.5. Описание топологических ограничений При создании сложных проектов может оказаться необходимым указать регион, в котором следует выполнять размещение конкретного модуля или непосредственно закрепить часть компонентов на кристалле. Понятие «модуль» может относиться как к группе компонентов, получаемой из одного файла, так и к произвольно создаваемой группе, выбираемой пользователем из всей иерархии проекта. Такая группа существует в рамках IDE Vivado и называется Р-блоком (P-block). В проекте может быть добавлено несколько Р-блоков. Процесс добавления поддержан в графическом интерфейсе Vivado и достаточно прост (рис. 7.32). Выделив объекты, которые требуется добавить в Р-блок, и нажав на инструментальной панели в окне Device View кнопку Draw Pblock, можно «протянуть» мышью прямоугольник с желаемой позицией для этих компонентов. САПР при этом
428 ____ Рис. 7.32. Процесс добавления Р-блока в проект добавляет в файл xdc специальные команды, запрещающие размещение выбранных компонентов за пределами этих координат. Можно заметить, что остальные компоненты по-прежнему могут помешаться внутрь координат Р-блока, если там есть свободное место. На рис. 7.33 показано размещение компонентов в проекте, пред- тавляемом в качестве примера. На этом рисунке тонкими наклонными линиями показаны соединения между модулями и внешними ьшодаъш ПЛИС, а толстые серые линии отмечают связи между модулями внутри кристалла. Однозначное решение по указанному рисунку принять доста- очно сложно с учетом того, что для показанных блоков могут су- ествовать различные требования к временным задержкам. Однако ожно заметить, что блок в правом верхнем углу находится близко выводам ПЛИС, поэтому для него можно ожидать хороших пока- ателей для ограничений input_delay и output jielay. В то же время блок внизу слева соединен в основном с выводами ПЛИС, находя- ися в центре противоположной стороны кристалла. Видимо, шим решением будет перемещение этого блока ближе к центру няжней части кристалла. Блок находящийся справа на рис. 7.33, имеет интенсивные свя- с тремя другими блоками. Можно попытаться разместить его приблизительно равном удалении от них, но также возможно, о он содержит 9^ие logic (что можно почти дословно перевести «г *«-*»*» или, что технически эквивалентно, «связывающая логи- \ иными словами, в данный блок по каким-то причинам были
П11Тимизация проекта 429 Рис. 7.33. Пример размещения компонентов в тестовом проекте собраны вспомогательные компоненты, которые по логике работы системы могут и не располагаться компактно. Более того, удаление связанных с этим Р-блоком топологических ограничений (т. е. разрешение размещать входящие в него ячейки в любых частях кристалла) может улучшить временные характеристики проекта в целом. Кроме стратегического управления компонентами, можно выполнять анализ критических цепей. После выполнения стадии implement и анализа задержек будет получен список цепей с наихудшими задержками (критических цепей). Разработчик может применять разные подходы для исправления ситуации, если такая цепь находится внутри одного иерархического модуля или же соединяет разные модули. Например, на рис. 7.34 показана цепь, соединяющая две логические ячейки внутри одного модуля. В показанном примере разработчик может выполнить следующее: Рис. 7.34. Размещение критической цепи внутри иерархического модуля
430 л ав а • изменить размеры модуля; • указать для модуля дополнительный Р-блок, разместив ческую цепь внутри этого блока; • установить топологические ограничения для привязки компонентов критической цепи к абсолютным координатам на кристалле или к относительным координатам блока. ! На рис. 7.35 показан при. [ мер, в котором критическая j ; цепь соединяет компоненты из j разных модулей. Очевидно, | что наилучшим вариантом бы- i i |в- , I i ло бы помещение двух компо- ¦•"•'• ~:~"«^j I нентов в соответствующие уг- г I ; лы своих Р-блоков, ближайшие j j \ друг к другу Однако для Р- \ j ; блоков выделены достаточно j й | : большие прямоугольники, что [ _:_::_- j \ формально разрешает предва- Рис. 7.35. Размещение критичес- рительное размещение компо- кой цепи между модулями. Ско нентов в любых частях выде- рее всего, это неудачное решение лвННЫХ областей. В ЭТОМ случае разработчику остается надеяться, что при последующей оптимизации алгоритмы Place&Route смогут автоматически найти правильное положение этих компонентов. Естественно, эту неопределенность можно устранить с помощью дополнительных мероприятий: • перенос критической цепи в один из Р-блоков; • создание дополнительного блока, содержащего оба компонента, формирующие критическую цепь, и выделение компактной области для этого компонента, гарантирующей достижение требуемых характеристик; • жесткая фиксация компонентов внутри Р-блоков. Для фиксации размещения компонентов используются следующие команды xdc (с примерами). Эта команда устанавливает положение {location, LOC) для компонента ramO, входящего в блок u_ctrlO: set .property LOC RAMB18 X0Y10 [get.cells u_ctrlO/ramO] Команда устанавливает для компонента конкретный «базовый элемент логики» {base element of logic, BEL). В данном примере указано, что компонент lutO в блоке u_ctrlO следует разместить в
ППтямизация проекта 431 таблице истинности С5 E-входовый режим LUT, третья LUT в секций согласно обозначениям А, В, С, D): set-property BEL C5LUT [get_cells u.ctrlO/lutO] Команда предписывает размещение регистров, содержащих в ямени mDatajreg, в блоках ввода-вывода: set-property IOB TRUE [get.cells mDatajreg*] Команда размещает две функции в одной физической LUT. Это возможно для некоторых логических выражений при условии, что часть входов у них являются общими, и суммарное число независимых входов не превышает 6: set-property LUTNM LO [get.cells {u_ctrlO/dmuxO u_ctrlO/dmuxl}] Команда запрещает (prohibit) использование ресурсов в указанных координатах. Это может быть полезно, если данные координаты необходимо зарезервировать для гарантированного размещения в них других компонентов: set_property PROHIBIT TRUE [get_sites {RAMB18JC0Y* RAMB36JC0Y*}] Описание проектных ограничений в формате xdc по сути представляет собой программирование на расширении языка Tel. Поэтому при конфликте команд последующая команда просто перекрывает действие предыдущей. Это свойство следует иметь в виду при анализе результатов действия сложных сценариев, в разных частях которых могут оказываться команды, дублирующие или отменяющие ранее установленные ограничения. Говоря о фиксации размещения (fix placement), следует отметить, что она достаточно трудоемка и при этом не гарантирует улучшения характеристик проекта. Корректнее было бы говорить о том, что при фиксации размещения временные характеристики определяются квалификацией разработчика, его уровнем понимания архитектуры ПЛИС и вниманием, проявленным к деталям конкретного проекта. Для больших схем чрезвычайно трудно уделить внимание всем аспектам размещения, поэтому прямое управление топологией следует рассматривать не как обязательный признак качественного проекта, а скорее как вынужденную меру, на которую разработчик идет в качестве «последнего средства» для достижения требуемых характеристик. Можно приблизительно указать, что для ПЛИС уровня 50 тысяч логических ячеек эффект от управления топологией проекта может быть заметен. Для небольших ПЛИС в целом можно полагаться на сочетание грамотного разбиения проекта на модули и управления стратегиями синтеза и implementation.
432 ^ва 7.7. Применение языка Tel для автоматизации процессов САПР Vivado Формат xdc является расширением языка Tel (Tool СощШапН Language), который пгароко используется в современных САПР, о даленным аналогом могут служить пакетные файлы MS-DOS (bat. файлы), назначением которых была организация последовательног запуска нескольких программ. Однако возможности tcl гораздо цщ. ре и включают в себя объявление переменных, структуры управления, работу с файлами и визуальными компонентами и т. п. Важно что tcl ориентирован на реализацию расширений с тем, чтобы конечный пользователь системы кроме собственно базового синтаксиса tcl использовал специфичные для своей области команды. Такие команды, предназначенные для управления САПР ПЛИС, и были добавлены программистами ХШпх для Vivado. Для управления проектом могут быть использованы два режима. Они соответствуют работе в GUI и пакетному режиму, в котором графическая среда разработки Vivado не запускается, а сборка проекта ведется в консольном режиме. Команды tcl для запуска процессов в Vivado приведены в табл. 7.2. Команды tcl для запуска процессов в Vivado Таблица 7.2 Создание проекта Синтез Реализация проекта (implementation) Работа в GUI create.project addJiles import Jiles launch-runs synthl launchjruns impll Консольный режим read_verilog read.vhdl synthjdesign opt _design power_opt .design place_design phys_opt .design routejiesign САПР Vivado содержит подробную справку по командам Tcl. Многие команды с требуемыми параметрами и сценарии запуска процессов генерируются автоматически или могут быть отредактированы разработчиком. В целом встроенный скриптовый язык достаточно полезен для сложных САПР.
8 Проектирование устройств с применением ПЛИС При практическом проектировании устройств, в которых предполагается использование ПЛИС Spartan-6/7 или Artix-7, необходимо решить ряд вопросов, относящихся к организации питания, загрузке конфигурации и подключении выводов, имеющих специальное или двойное назначение. Эти вопросы, включая также сведения о проектировании печатной платы и организации работ, сведены в данную главу. Проектирование систем для Zynq-7000, Kintex-7, Virtex-7, а тем более семейств UltraScale предполагает более жесткие требования к организации питания, трассировке скоростных цепей на печатной плате и сопутствующим вопросам, поэтому в данной публикации не ставится целью систематическое изложение порядка проектирования для ПЛИС верхнего сегмента. 8-1. Питание FPGA Spartan-б имеют три линии питания — для ядра (Vcore), периферийных (Vio) и вспомогательных (Vaux) устройств. Две последние могут быть объединены, таким образом для проекта будет достаточно источника 1,2 В для ядра и 3,3 В для периферии. Питание Vaux может быть выбрано в диапазоне 2,5...3,3 В, поэтому может потребоваться отдельный источник, если питание периферии по каким-то причинам установлено ниже этого диапазона. Напряжение Vio может быть подано в диапазоне 1,2...3,3 В. Потребляемый ток зависит от загруженного проекта и нагрузки, подключенной к выходам ПЛИС. Потребление ядра (линия 1,2 В) определяется в основном динамической составляющей, оно пропорционально тактовой частоте и числу использованных ресурсов ПЛИС. Точное значение может быть определено только экспериментально, однако можно указать характерные токи для типичных применений. Для микросхем LX4 и LX9 типичное потребление ядра составляет чуть меньше 100 мА. Уточненное значение потребляемого тока можно определить с помощью утилиты XPower, входящей в состав САПР ISE. В САПР Vivado потребляемая мощность оценивается на разных стадиях работы, от синтеза до трассировки, поэтому информация о потребляемой мощности присутствует в отчетах.
434 Глава8 Потребление периферийных модулей (линия Vio) зависит от на грузки, подключенной к ПЛИС. Максимальный ток, допустимый для одного выхода, обычно равен 12 мА, что можно использовать для оценки верхней границы потребления. В то же время не следую рассчитывать на нормальную работу ПЛИС, у которой все выводы работают в таком режиме. Питание ПЛИС проще всего обеспечить с помощью интегрального трехвывод- ного стабилизатора, например LM1117. Такие стабилизаторы выпускаются многими производителями и имеют варианты как с фиксированным выходным напряжением (в том числе 3,3 В), так и с регулируемым (adjustable). Интересно, что регулируемые стабилизаторы могут быть использованы Рис. 8.1. Внешний вид для получения напряжения питания ядра интегрального стабили- ^ 2 В) без дополнительных компонентов, затора в корпусе D-PAK v ' . ' поскольку если вход регулирования ADJ подключить к земле, стабилизатор будет выдавать опорное напряжение, которое составляет 1,23... 1,27 В. Для ПЛИС Spartan-б оно находится в пределах официально допустимого 10%-го допуска. Внешний вид интегрального трехвыводного стабилизатора в корпусе D- РАК показан на рис. 8.1. Некоторые интегральные стабилизаторы самовозбуждаются при малом потреблении тока, поэтому желательно организовать небольшую балластную нагрузку (примерно нескольких миллиампер). Также можно рекомендовать включить конденсатор небольшой емкости A0...100 нФ) между входом и выходом. Отдельным вопросом является применение импульсных источников питания. Они имеют более высокий к.п.д., однако добавляют высокочастотную составляющую помех на частоте внутреннего преобразователя. Обычно необходимость использования импульсных стабилизаторов связана с высокими токами нагрузки, но для ПЛИС начального уровня это не требуется. Тем не менее не существует принципиальных препятствий для использования импульсных стабилизаторов напряжения. В качестве примера можно рассматривать импульсные регуляторы МС33063А/МС34063А фирмы Texas Instruments. Эти микросхемы в 8-выводном корпусе требует внешнего дросселя, диода Шоттки, несколько резисторов и конденсаторов и способны обеспечить выходной ток до 1,5 А. Различие заключается в диапазоне температур эксплуатации.
проектирование устройств с применением ПЛИС 435 Характеристики различных источников питания Таблица 8.1 Характеристика К.п.д Сложность применения Шумы Стоимость Примерный ток нагрузки Интегральный трех- выводной стабилизатор Низкий Низкая Низкие Низкая 1 А Импульсный контроллер Высокий Средняя Средние Низкая-средняя 3...5 А Модуль питания Высокий Низкая Средние Высокая 10...20 А Применение готовых модулей питания может представлять интерес при необходимости обеспечить токи примерно 5... 10 А и более. В этом случае разработчик ожидает найти в таком модуле качественную защиту от перегрузки и перегрева, возможность управляемого отключения. Характеристики различных источников питания сведены в табл. 8.1. Приведенные токи нагрузки являются условными и показывают примерное соотношение величин. Проблемой интегральных стабилизаторов является низкий к.п.д., поскольку излишки напряжения падают на регулирующем элементе (транзисторе), что ведет к нагреву стабилизатора. С другой стороны, такие стабилизаторы хорошо подходят для проектов с небольшим потреблением из-за низкой цены и отсутствием вносимых самим источником питания помех из-за работы внутреннего импульсного генератора. При выборе тока потребления можно ориентироваться на данные анализа утилиты мощности, однако следует закладывать определенный запас. Условно, при оценке тока в 2,9 А не следует выбирать источник с максимальным током 3 А, поскольку запас слишком мал и отклонения реальных условий от используемых для оценки модели вполне могут привести к превышению этого значения. Также следует закладывать запас на будущие изменения проекта, так как увеличение числа работающих ресурсов и тактовой частоты проекта увеличат потребляемую мощность. Кроме того, при загрузке конфигурации все ПЛИС потребляют существенно больший ток, чем в процессе работы. Это связано с записью .bit-файла во внутреннюю статическую память, хранящую конфигурацию. Процесс записи характеризует повышенное потребление, поэтому источник питания должен допускать кратковременное повышение потребляемого тока. ПЛИС серии 7 могут использовать дополнительные линии питания. Прежде всего, напряжение питания ядра для серии 7 составляет 1 В (или 0,9 В для варианта low voltage). Допустимые
436 ГлаВа8 напряжения питания для банков ввода-вывода зависят от их типа Банки HR (High Range) допускают напряжение 3,3 В, а банки HP (High Performance) - 1,8 В. Для организации питания ПЛИС серии 7 рекомендуется обращаться к документации на соответствующие серии, поскольку фОр_ мат данной книги не подразумевает изложение точных справочных данных. Особенное внимание следует обратить на организацию питания высокоскоростных последовательных приемопередатчиков поскольку к нему предъявляются высокие требования по стабильности и уровню шумов. Для любой системы питания важно обеспечить фильтрацию помех. Кроме электролитических конденсаторов большой емкости служащих для подавления низкочастотных колебаний большой амплитуды, требуется также установка конденсаторов типа NP0 или X7R для фильтрации высокочастотных помех. Установка конденсаторов нескольких типов имеет серьезные основания. В идеальном случае считается, что фильтрующий конденсатор представляет собой идеальный компонент, обладающий только электрической емкостью. Однако отклонения реального конденсатора от идеальной модели на практике оказываются значимыми. На рис. 8.2 показана эквивалентная схема реального конденсатора. Кроме электрической емкости С реальный компонент обладает также эквивалентным последовательным сопротивлением (ESR, Equivalent Serial Resistance) и эквивалентной последовательной индуктивностью (ESL, Equivalent Serial Inductance). X ESR (эквивалентное Полное сопротивление (импеданс) этой последовательное схемы определяется активной составляющей у сопротивление) r (которая достаточно мала) и реактивной SSSSSS" сос^лякяцей. р индуктивность) Реактивные составляющие сопротивле- I q ния для этой схемы равны: Xl — ojL', Xc = 1/cdC, Рис. 8.2. Эквивалентная схема реаль- где и — циклическая частота, равная 2тг/. ного конденсатора Можно видеть, что компоненты реактивного сопротивления зависят от частоты противоположным образом. Если емкостная составляющая реактивного сопротивление уменьшается с ростом частоты, то индуктивная — растет. Частота, начиная с которой импеданс возрастает, определяется формулой Томсона
проектирование устройств с применением ПЛИС 437 В качестве примера можно рассмотреть паразитную индуктивность конденсатора в корпусе SMD (для поверхностного монтажа). Паразитная индуктивность складывается не только из собственной индуктивности компонента, обусловленной его геометрическими размерами, но и индуктивности печатных проводников (сюда вносят вклад и переходные отверстия). Паразитная индуктивность обычно находится в диапазоне 300...2000 нГн. Для конденсатора типа X7R емкостью 0,1 мкФ и паразитной индуктивностью 1,7 нГн частота, определяемая по формуле Томсона, составляет приблизительно 30,6 МГц. Зависимость импеданса от частоты для такого конденсатора показана на Рис. 8.3. Зависимость импеданса RLC- рИС. 8.3. Обе ОСИ Показаны В цепочки от частоты логарифмическом масштабе. Из этого графика видно, что эффективность фильтрующих кон- десаторов падает при повышении частоты. Чтобы увеличить диапазон рабочих частот, необходимо выбирать конденсаторы с меньшими значениями паразитной индуктивности и номинальной емкости. Однако паразитная индуктивность определяется конструктивными параметрами корпуса конденсатора и печатной платы, и доступными разработчику действиями является только размещение конденсаторов вблизи микросхемы и использование коротких печатных проводников (это снижает их индуктивность). Уменьшение номинального значения емкости снизит эффективность конденсатора, уменьшив накапливаемый им заряд. Установка нескольких одинаковых конденсаторов (при параллельном включении) увеличивает их суммарную емкость, но также увеличивает и паразитную индуктивность. Поэтому произведение LC не изменяется, однако импеданс, а следовательно, и уровень пульсаций, уменьшаются с каждым дополнительным конденсатором. Чтобы обеспечить фильтрацию помех на разных частотах, следует применять комбинацию конденсаторов разных типов. Конденсаторы типа NP0 имеют небольшой номинал емкости и низкую паразитную индуктивность, поэтому обеспечивают фильтрацию помех в высокочастотной области. Конденсаторы типа X7R с номиналом 0,1... 1 мкФ обеспечивают основной вклад в подавление помех
438 Гла в диапазоне 1...40 МГц. Для того чтобы снизить уровень пульса ций до 1 МГц, применяются электролитические конденсаторы ем костью 47...47000 мкФ (такой большой диапазон условен и определи, ется большим диапазоном возможных токов для ПЛИС различного логического объема). Свой вклад в фильтрацию питания вносят еще два компонента: собственная емкость печатных проводников и стабилизатор напряжения. Широкие проводники питания и земли, особенно расположенные в соседних слоях, представляют собой обкладки конденсатора. Хотя его емкость невелика, однако паразитная индуктивность проводников меньше, чем паразитная индуктивность SMD- компонентов, поэтому собственная емкость дорожек питания сохраняет эффективность на частотах свыше 500 МГц. Стабилизированный источник питания, имея регулирующий элемент, управляемый определенной частотой преобразования, напротив, эффективен для низких частот. Поэтому установка фильтрующих конденсаторов решает задачу обеспечения фильтрации в диапазоне частот от (условно) 5 кГц до 50...100 МГц. Внутри корпусов ПЛИС серии 7 и последующих установлены высококачественные фильтрующие конденсаторы. Их суммарная емкость невелика из-за ограничений по габаритам, однако расположение на минимальном удалении от выводов питания обеспечивает их эффективность на высоких частотах. Организация фильтрации питания для ПЛИС показана на рис. 8.4. Керамические конденсаторы небольшой емкости (например, 470 пФ типа NP0) устанавливаются в непосредственной близости от выводов питания ПЛИС. Возможна установка конденсаторов на противоположной стороне печатной платы, непосредственно под корпусом ПЛИС, однако между конденсатором и выводом питания следует использовать только одно переходное отверстие. Примеры кон- Источник питания FPGA Большие электролитические конденсаторы! Большие Маленькие кераматические кераматические конденсаторы: конденсатора Влияние емкости проводников Рис. 8.4. Организация фильтрации питания для ПЛИС
проектирование устройств с применением ПЛИС 439 площадок для конденсаторов 0,8 нГн 0,6 нГн 0,4 нГн з корпусе 0402 показаны на рис. 8.5. Установку больших керамических конденсаторов, например X7R емкое- | тью 0,1...0,47 мкФ, можно производить - - — чуть дальше от корпуса ПЛИС. На рис. 8.4 показано, что линия питания ОТ ПЛИС ДО ЭТИХ конденсаторов уже Рис- 8-5- Примеры кон- ймеет импеданс, которым нельзя пре- тактных площадок для кон- йт ^ > г- ^ денсаторов в корпусе 0402 небречь. Еще дальше от ПЛИС можно установить электролитические конденсаторы. Танталовые конденсаторы предпочтительнее по сравнению с алюминиевыми. В целом для небольших ПЛИС рекомендуется установить минимум 4-6 конденсаторов на выводы питания ядра и по 2-3 конденсатора на каждый банк питания (или на сторону корпуса QFP). В документе UG483 «7 Series FPGAs PCB Design Guide» приведены рекомендации по числу конденсаторов различных типов, требуемых для ПЛИС. 8.2. Сопряжение ПЛИС с другими микросхемами Часто ПЛИС используют питание интерфейсов ввода-вывода 3,3 В. Это касается семейства Spartan-б и недорогих семейств серии 7, использующих преимущественно банки ввода-вывода типа High Range (HR). Часто задаваемым вопросом в этой связи является «каким образом следует подключать ПЛИС к микросхемам с питанием 5 В?». В целом можно ответить, что ПЛИС могут работать совместно с 5-вольтовыми микросхемами, но с учетом некоторых ограничений. Рассмотрим несколько ситуаций: 1. ПЛИС читает данные с микросхемы, питающейся от 5 вольт. В данном случае возникает вопрос, не будет ли повреждена ПЛИС при подаче на нее напряжения с номиналом, большим, чем ее напряжение питания. Простейшей и официально рекомендованной схемой сопряжения является обычный токоограничивающий резистор, включаемый последовательно. Резистор подбирается таким образом, чтобы ограничивать ток величиной не более 10 мА. Резистор сопротивлением 180 Ом допускает подачу напряжения 5,1 В. Следует обратить внимание, что микросхемы с 5-вольтовым питанием и выходом ТТЛ в действительности не выдают на выходе 5 В
440 Гла в а 8 для состояния логической единицы. Напряжение холостого хода различных серий ТТЛ составляет от 3 до 3,5 В, что безопасно дд ПЛИС. Тем не менее применение резистора в 180 Ом может быть рекомендовано для всех входов, сопрягаемых с 5-вольтовым окру жением. Внутри ПЛИС в блоках ввода-вывода установлены защитные диоды, соединенные с линией питания ввода-вывода. Поэтому фор. мальных ограничений на входное напряжение не существует, до тех пор, пока внешний резистор ограничивает ток на уровне 10 мА. 2. Выход ПЛИС подключен к входу микросхемы, питающейся от 5 В. В данном случае возможность прямого подключения зависит от типа входа внешней микросхемы. Для входа ТТЛ с фиксированным порогом логической единицы возможно надежное чтение выхода ПЛИС без дополнительных компонентов. Напряжение холостого хода, замеряемое на выходе ПЛИС, обычно составляет 3...3,05 В (для сравнения, порог срабатывания микросхем ТТЛ составляет 2,4 В). Проблема может возникнуть при подключении к 5-вольтовой микросхеме, входы которой имеют уровни КМОП. При питании 5 В порог срабатывания может быть равен 4 или 4,5 В, и чтение выхода ПЛИС становится ненадежным. В этом (и только в этом) случае требуется преобразователь уровня. Это может быть специальная микросхема level shifter или буферный элемент с 5-вольтовым питанием и входами типа ТТЛ (например, 74hct244, но не 74hc244). На рис. 8.6 показана принципиальная электрическая схема буферного элемента 74hct244. Альтернативным вариантом является применение специальной микросхемы преобразователя уровней. На рис. 8.7 показан преобразователь уровней, обеспечивающий управляемую двунаправленную передачу данных с преобразованием уровня напряжения между Vcca и Vccb. На рис. 8.8 показана сводная схема подключения FPGA к внешним микросхемам различных типов. На этом рисунке видны схе- 19 Рис. 8.6. Схема буферного элемента 74hct244
Проектирование устройств с применением ПЛИС 441 DIR VCCA *ССВ Рис. 8.7. Преобразователь уровней SN74LVC1T45 мы сопряжения, используемые в описанных выше случаях. Отдельной рекомендацией является отказ от попыток прямого управления мощными полевыми транзисторами (например, существуют устройства с вышедшими из строя MOSFET), так как на практике выходное напряжение FPGA обычно недостаточно для перевода его в режим насыщения. В результате сопротивле- FPGA *~ 180 Ом -*— 4Z3- 5B ТТЛ 5B КМОП 180 Ом Рис. 8.8. Схема сопряжения FPGA с внешними устройствами с питанием 5 5 различных типов ние сток-исток для MOSFET не достигает минимальной величины, приводимой в его документации, хотя переключающий режим формально имеет место. При этом повышенное сопротивление сток- исток означает увеличение рассеиваемой мощности с преждевременным выходом MOSFET из строя. В данном случае правильным будет использование транзисторного ключа с интегрированным преобразователем, управляемым ТТЛ-уровнями, или использование дополнительного управляющего биполярного транзистора. 8.3. Загрузка конфигурации ПЛИС относится к устройствам со статической памятью. Это означает, что каждый раз после включения питания следует загрузить конфигурацию из внешнего энергонезависимого источника. Семейство Spartan-б поддерживает несколько видов внешней памяти и имеет дополнительно интерфейс JTAG. Для хранения одной конфигурации ПЛИС Spartan-6LX4 и LX9 достаточно устройства памяти емкостью 4 Мбит (точные значения: 2731488 и 2742528 битов соответственно). Дополнительно конфигурационный поток может быть сжат (применением соответствующей настройки в САПР), однако степень сжатия существенно зависит
442 Глава 8 от коэффициента использования ПЛИС. Минимальный объем к фигурационного потока для проекта, состоящего из одного црОв * да, соединяющего два вывода ПЛИС, составляет приблизитель 0,9 Мбит. Это ни в коей мере не означает, что память размеро 1 или 2 Мбит может быть заложена в проект на ранних стадиях разработки. Для ПЛИС большего логического объема необходимо использовать устройства хранения конфигурационного файла соответствующего объема. Диапазон размеров для семейства Artix-7 составляет 9,9...77,8 Мбит, а в семействе Virtex-7 имеется кристалл, требующий 447 Мбит данных для конфигурирования. В целом решение для конфигурирования укладывается в возможности современных микросхем флеш-памяти, но для ПЛИС большого объема можно рассмотреть альтернативные варианты, например реализацию контроллера загрузки на недорогой ПЛИС Spartan, Artix или Zynq, процессорная система которой загрузит более крупные микросхемы из SD-карты. Интерфейс для загрузки конфигурации содержит следующие выводы: CCLK — тактовый сигнал; в режиме Master является выходом, а в режиме Slave — входом; DIN — вход конфигурационных данных; PROGRAM — вход сброса, активный уровень низкий, служит для запуска процесса конфигурирования; INIT — двунаправленный вывод с активным низким уровнем, служащий для задержки загрузки данных (если извне подан уровень логического нуля), или сигнализирующий об ошибке контрольной суммы; DONE — выход готовности FPGA, принимает уровень логической единицы при успешном завершении загрузки; требует внешнего резистора (уровень нуля, поданный внешней микросхемой, задержит старт FPGA); DOUT — выход данных, конфигурационные данные с DIN появляются на этом выходе после завершения загрузки конфигурации; служит для формирования последовательных цепочек FPGA, где выход DOUT подключается к входу DIN следующей FPGA; МО, Ml — входы выбора режима конфигурирования; обычно к ним подключаются pull-up резисторы и «джамперы» замыкающие эти входы на землю, что позволяет установить любой режим конфигурирования. В итоге можно использовать следующие технические решения: 1. Флеш-память серии XCF производства Xilinx
проектирование устройств с применением ПЛИС 443 VCCOJ) Рис. 8.9. Подключение флеш-памяти семейства XCF к FPGA Spartan-6 Эта память специально спроектирована для загрузки FPGA Xi- linx. Она имеет интерфейс JTAG в дополнение к интерфейсу с FPGA и может быть подключена к FPGA с использованием минимального числа дополнительных компонентов (резисторов). Для микросхем LX4 и LX9 достаточно применения флеш-памяти XCF04S. Схема ее включения показана на рис. 8.9. 2. Флеш-память с интерфейсом SPI. Память такого типа обычно существенно дешевле, чем специализированные микросхемы семейства XCF. Подключение SPI-флеш к FPGA показано на рис. 8.10. При подключении программатора наличие внешней памяти может быть автоматически определено. В этом случае будет предложено выполнить также и программирование флеш-памяти. В настоящее время программатором Impact поддерживаются следующие семейства флеш-памяти: • Atmel AT45DB; • Nymonix M25P, М25РБ, М45РЕ;
444 Гла. Рис. 8.10. Подключение SPI-флеш к FPGA • Winbond W25Q. Сами FPGA не проверяют код микросхемы памяти при загрузке конфигурации. Например, успешно работают флеш-ПЗУ семейства SST25V, однако для всех микросхем, официально не поддерживаемых утилитой Impact, необходимо позаботиться о способе их программирования. Через JTAG может быть загружена конфигурация, обеспечивающая доступ к выводам, подключенным к флеш-памяти, а конфигурационный поток будет передан с помощью того же JTAG или пользовательского интерфейса (USB, Ethernet и т. д.). Можно обратить внимание, что выход FPGA DOUT подключен не к входу флеш-памяти DIN, а служит для образования цепочки из нескольких FPGA, чтобы загружать их из одной микросхемы. Тем не менее управление входом DIN требуется, чтобы управлять работой флеш-памяти. Для этого используется выход MOSI (Master Out, Slave In). Также следует обратить внимание на логические уровни входов МО, Ml. Для автоматической загрузки из флеш-памяти МО = 1» Ml = 0.
Проектирование устройств с применением ПЛИС 445 Кроме интерфейса, специально предназначенного для загрузки конфигурации, ПЛИС имеют интерфейс JTAG. Он использует выделенные линии TMS, TCK, TDI, TDO. Интерфейс предназначен прежде всего для отладки, но используется также для загрузки конфигурации. JTAG доступен в любом режиме, независимо от установленных уровней на МО, Ml. Сигналы TMS и ТСК подаются на все микросхемы с интерфейсом JTAG, установленные на плате, а сигналы TDI (вход данных) и TDO (выход данных) образуют цепочку, где выход TDO подключен к входу TDI следующей микросхемы. Если на плате только одна микросхема имеет интерфейс JTAG, ее сигналы TDI и TDO подключаются к одноименным выводам разъема. Внешние токоограничивающие резисторы для этого интерфейса не требуются, однако можно предусмотреть резисторы, согласующие длинную линию. На практике JTAG не является чрезмерно требовательным к длине или форме трассировочных линий. Это не означает, что на них можно не обращать внимания, но и нет необходимости размещать разъем JTAG на минимальном расстоянии от FPGA. Программатор, выпускаемый Xilinx (рис. 8.11), удобен в первую очередь тем, что позволяет использовать все возможности программирования и отладки, предлагаемые САПР Xilinx. При его наличии проектирование становится в полной мере сквозным, завершаясь непосредственно запуском полученной в САПР конфигурации на микросхеме, подключенной к программатору. Однако относительно высокая цена делает такой программатор не слишком подходящим приобретением для быстрого старта. Необходимо обратить внимание, что сигнал Vref является входом программатора. Он предназначен для контроля того, что на Рис. 8.11. Программатор USB-II Cable
446 Г л а в а 8 программируемую микросхему подано питание, поэтому необходим позаботиться о наличии такой точки (подключаемой к напряжению 3,3 В, как правило, Vio). Альтернативными вариантами могут быть: 1. Использование связки МК+ПЛИС, в которой микроконтроллер подключен к конфигурационному интерфейсу ПЛИС и имеет скоростной интерфейс (USB или Ethernet), позволяющий передать с ПК полученную в САПР конфигурацию и загрузить ее в ПЛИС по конфигурационному интерфейсу. В этом случае МК полезен тем что добавляет к проекту свои периферийные устройства, однако для передачи конфигурационного файла в такую систему необходимо разработать отдельные утилиты. Протокол USB предусматривает пакетную передачу данных со скоростью не более 1000 пакетов в секунду. Достигать высоких скоростей передачи данных можно только в том случае, если удается обеспечить соответствующее наполнение этих пакетов. Некоторые микросхемы преобразователей USB допускают независимое управление выводами (например, режим bit bang), что может навести на мысль об использовании такого режима для загрузки конфигурации. Однако в данном случае каждый пакет будет однократно переключать состояние выводов, а не формировать последовательность, к тому же программное управление линией CCLK потребует двух посылок. Поэтому скорость загрузки конфигурации окажется равной 500 бит/с, что крайне мало для нормальной работы с ПЛИС. Поэтому при использовании МК необходимо убедиться, что реальная скорость передачи пользовательских данных и воспроизведение протокола загрузки конфигурации будут происходить с приемлемой скоростью. 2. Модули программатора сторонних производителей. Некоторые компании выпускают готовые модули с интерфейсом JTAG, специально предназначенные для работы с ПЛИС ХШпх. На рис. 8.12 показан модуль USB-JTAG w производства Digilent. ™ о.л w ттог, ттлп 3. Модуль программатора на Рис. 8.12. Модуль USB-JTAG про- w * г ;_ изводства Digilent базе преобразователя USB-JTAG В настоящее время существует множество микросхем, реализующих преобразование интерфейса USB в более простые для использования интерфейсы. Преобразователи USB-UART уже были рас-
проектирование устройств с применением ПЛИС 447 ¦4 [ ]—•-4 I { "I. —-- ..~К*'М Ь* тек TDI TDO TMS TXD RXD Рис. 8.13. Подключение микросхемы FT2232H (фрагмент) смотрены выше, и они активно используются при разработке плат на базе ПЛИС и микроконтроллеров. Ввиду распространения JTAG в качестве интерфейса для отладки, преобразование USB- JTAG стало поддерживаться некоторыми производителями. Например, микросхема FT2232H представляет собой двухканальный преобразователь из USB, где каждый канал может выполнять функции не только UART, но и SPI, а также необходимый для ПЛИС JTAG. Здесь важно, что скорость обмена по JTAG оказывается достаточно высокой (загрузка для Spartan-6 LX4 занимает менее 1 с). Фрагмент схемы подключения микросхемы FT2232H показан на рис. 8.13. Порт А используется для реализации контроллера JTAG, а порт В — для UART. Номера выводов показаны для конкретного варианта корпуса (LQFP64). На схеме можно обратить внимание, что выводы питания VPHY и VPLL подключаются через дополнительные дроссели. Их применение настоятельно рекомендуется, поскольку уровень импульсных помех может оказаться достаточно высоким, чтобы нарушить нормальную работу контроллера. Показанные выводы используются
448 для питания преобразователя физического уровня интерфейса USR (PHY) и внутренней PLL. Применение такого контроллера в собственной разработке даст возможность использовать встроенный в Vivado программатор Именно это решение используется в модуле производства Digilent показанном на рис. 8.12. 8.4. Источники тактовых сигналов FPGA не имеют внутри высококачественного источника тактового сигнала. Формально среди аппаратных примитивов имеется генератор, используемый в Master-режимах загрузки конфигурации (когда PPGA является источником тактового сигнала для внешней флеш-памяти), однако он имеет большой разброс номинального значения частоты между отдельными микросхемами. Рекомендуемым решением является использование внешнего кварцевого генератора (рис. 8.14), подключаемого к входу, помеченному как GCLK (Global Clock). Тактовые генераторы внутри FPGA имеют собственный диапазон допустимых входных частот. Для Spartan-б он составляет 5...350 МГц. Это означает, что, например, популярная частота 4 МГц не может быть использована для DCM (что подтверждается экспериментально). Тем не менее сами DCM могут сформировать эту частоту из внешнего тактового сигнала. Для серки 7 диапазон входной тактовой частоты для входов GCLK составляет: 10....800 МГц для ММСМ и 19...800 МГц для PLL. При подключении генератора с высокой (свыше 100 МГц) частотой рекомендуется использовать дифференциальный интерфейс. Для этого необходим специальный выход генератора в виде дифференциальной пары выходов, подключаемых к входам FPGA GCLK-P и GCLK_N соответственно. Входы не могут быть выбраны произвольно среди всех Р и N тактовых входов, а должны образовывать Рис. 8.14. Внешний вид кварцевых генераторов
Проектирование устройств с применением ПЛИС 449 дифференциальную пару на кристалле. Ввод дифференциального сигнала в проект при этом выполняется с помощью специального буфера IBUFGDS (входной глобальный тактовый буфер с дифференциальным входом). Необходимо помнить, что как ММСМ, так и PLL обладают широкими возможностями генерации внутренних частот, поэтому чрезмерно повышать входную частоту нет необходимости. Популярными значениями частот внешних генераторов на отладочных платах являются 50, 100 и 200 МГц. 8.5. Трассировка печатной платы и целостность сигналов Печатные платы представляют собой диэлектрическую пластину, на поверхности которой находятся один или несколько слоев проводящего материала. Распространенными материалами являются стеклотекстолит PR-4 со слоями медной фольги. В зависимости от числа слоев фольги печатные платы подразделяют на односторонние, двусторонние и многослойные. В последнем случае с двух сторон основной стеклотекстолитовой пластины находятся пакеты из слоев фольги с разделяющими их слоями изоляционного материала. Толщина основной текстолитовой пластины обычно выбирается из стандартного ряда, однако на практике важнее тот набор толщин, который может предоставить конкретный производитель печатных плат. По умолчанию используется толщина 1,5 мм, хотя при необходимости можно применять большие или меньшие толщины. Толщина слоя фольги также представляет собой стандартный ряд, основанный на американской системе мер. Именно поэтому толщин фольги выглядят необычно в метрической системе. Основной единицей измерения является «унция на квадратный фут». Одна унция на квадратный фут соответствует толщине медной фольги 35 мкм. Соответственно, стандартный ряд включает 18, 35, 70 и 105 мкм. Обычно используется толщина фольги 18 мкм. Увеличение числа проводящих слоев печатных плат является одной из тенденций в электронной отрасли и позволяет разрабатывать платы со все более сложными соединениями. Многие производители в качестве многослойных печатных плат рассматривают платы с числом слоев до 16, 20, 24 и даже 64. Часто число слоев вплоть до максимального не влияет на стоимость изготовления платы, поэтому, приняв решение о применении многослойной печатной платы, можно свободно выбирать число слоев вплоть до определенного предела.
450 Гл, в а Сквозное Слепое Погребенное Рис. 8.15. Виды переходных отверстий в печатной плате Слои фольги могут соединяться переходными отверстиям» имеющими слой меди, осажденный на их внутренней поверхност ' Осаждение слоя меди необязательно. В этом случае отверстие и жет быть использовано для крепежа. Для многослойных печатных плат воз можно соединение не только внешних слоев, но и внутренних, или внешнего и одного из внутренних слоев. Соответствую- щие отверстия называются погребенными (buried) или слепыми (blind). Виды переходных отверстий показаны на рис. 8.15. При проектировании печатных плат важно знать допустимые параметры переходных отверстий, которые определяются технологией производства. Отверстия с чрезмерно малым диаметром трудны для изготовления, поэтому производитель указывает минимально допустимый диаметр. Обычно это 0,2...0,4 мм. Кроме того, при проектировании платы необходимо учитывать минимально допустимую ширину проводника, минимальный зазор между проводниками и минимальный диаметр внешнего пояса вокруг переходного отверстия. 8.5.1. Целостность сигналов При обсуждении правил проектирования высокочастотных цепей на печатных платах разработчик может полагать, что эти вопросы неактуальны для его проекта, потому что используемые частоты интерфейсов составляют единицы-десятки мегагерц. Однако вопрос заключается в формулировке понятия «высокочастотная цепь». Важнейшим параметром, определяющим понятие «высокоскоростной цепи», является время нарастания сигнала (rise time). Иллюстрация показана на рис. 8.16. В то время как период сигнала может быть достаточно большим, время нарастания определяется характеристиками выходного каскада микросхемы-источника. Обычно это время определяется не от нуля до максимального напряжения, а от уровня 10 % до 90 /о максимального напряжения. Это связано с тем, что наличие переходных процессов в цепях делает время достижения 100%-го уровня Рис. 8.16. Иллюстрация к понятию «время нарастания сигнала»
проектирование устройств с применением ПЛИС 451 напряжения бесконечным. В некоторых источниках используется диапазон 20...80 %. Время нарастания выходного сигнала, как уже упоминалось, зависит от типа электрического интерфейса, установленного для выхода микросхемы. Например, для ПЛИС Kintex-7 это время составляет от 400 до 1400 пс. С временем нарастания сигнала напрямую связано понятие «критическая длина» для электрического проводника. Бели длина проводника становится сопоставимым с расстоянием, которое проходит электрический сигнал за время нарастания, такой проводник уже нельзя считать идеальной линией, соединяющей источник и приемник. Скорость сигнала в электрической цепи не равна скорости света в вакууме. Для проводника, находящегося во внутреннем слое печатной платы, диэлектрическая постоянная окружающей среды е не равна 1. Для широко используемого материала печатных плат FR-4 е = 4,3. Для проводника, находящегося во внешнем слое печатной платы, с одной стороны находится воздух, поэтому эквивалентная диэлектрическая постоянная е = 3,3. При этом скорость распространения сигнала с = со/у/ё и составляет около 14,5 см/нс для внутренних слоев и 16,5 см/нс для внешних. Критическая длина проводника, при которой форма сигнала может претерпевать искажения, ориентировочно принимается равной 3 см при времени нарастания 1 не. Важно, что даже если период сигнала существенно больше времени нарастания (например, частота смены логического уровня составляет всего 1 МГц), малое время нарастания сигнала все равно может привести к искажениям его формы. Дело в том, что сигналы с малым временем нарастания имеют широкий спектр, определяемый в большей степени именно временем нарастания, и в меньшей — частотой следования импульсов. Поэтому говоря о частоте передачи данных в 1 МГц, разработчик на практике обеспечивает передачу синусоидального сигнала по этой линии, а для воспроизведения формы сигнала с малым временем нарастания линия должна обеспечивать полосу пропускания, ориентировочно определяемую по формуле F = 500/Trise, где F — полоса пропускания, МГц; TriSe — время нарастания сигнала, не.
452 Гл, Если разработчик стремится увеличить частоту обмена данными и устанавливает в качестве электри- ческого интерфейса наиболее скоро- Рис. 8.17. Эквивалентная схема СТНОЙ, ТО необходимо проверить, не линии с распределенными пара- будет ли сигнал искажен на стороне метрами приемника. Для ПЛИС Kintex-7 с интерфейсом LVCMOS18, высокой скоростью нарастания (Fast slew rate) и током 16 мА в банке HP время нарастания составляет 0 4 не и критическая длина будет равна всего 12 мм. Все проводники имеющие большую длину, следует рассматривать как «длинные линии». Эквивалентная схема «длинной линии», или линии с распределенными параметрами, показана на рис. 8.17. В данном случае важно, что показанные значения R, L, С не установлены на схеме в виде компонентов, а представляют собой параметры печатного проводника, относящиеся к каждому его бесконечно малому фрагменту. Для такой линии важнейшей характеристикой является импеданс, или «полное сопротивление», определяемое с учетом как активных, так и реактивных составляющих. Поскольку активное сопротивление металлического проводника сравнительно мало, интерес представляет именно реактивная составляющая. С ее учетом импеданс определяется по формуле Z- л/Ь/С. Импедансы дорожек на печатной плате обычно находятся в диапазоне 40..80 Ом. Наиболее часто встречающимся негативным эффектом в длинной линии является эффект переотражения сигнала (reflection). Он проявляется, если импеданс источника, линии и приемника отличаются. Реальная схема соединения источника и приемника показана на рис. 8.18. Как в источнике, так и в нагрузке присутствуют неустранимые импедансы, определяемые характеристиками выходного и входного каскадов соответственно. Основной проблемой является применение высокоомной нагрузки. На первый взгляд это может показаться странным, поскольку высокое входное сопротивление означает, что вход микросхемы потребляет очень маленький ток, т. е. не нагружает выход источника, Источник (source) Нагрузка (load) Рис. 8.18. Реальная схема соединения источника и приемника
проектирование устройств с применением ПЛИС 453 Рис. 8.19. Эквивалентная схема источника, подключенного к нагрузке с высоким входным сопротивлением а это выглядит положительным свойством. Однако в таком случае Zl ^> Zs и эквивалентная схема приближается к показанной на рис. 8.19. С точки зрения источника нагрузка практически отсутствует, но при этом к выходу подключена линия с распределенными параметрами, которая по сути является антенной, рассеивающей часть энергии в окружающее пространство. Для антенн существует понятие «полуволновой вибратор» — прямой проводник с длиной, равной половине длине электромагнитной волны. Выше было упомянуто, что электрический сигнал проходит в проводнике за 1 не расстояние около 15 см, поэтому достаточно длинные проводники начинают приближаться по своим свойства к полуволновому вибратору. В качестве аналогии можно представить волну жидкости, распространяющуюся по трубе с заглушкой на дальнем конце. Когда волна дойдет до заглушки, она отразится и вернется назад. При определенном сочетании частоты волны и длины трубы можно наблюдать стоячую волну. Для электрического проводника аналогичный процесс искажает форму сигнала, затрудняя его передачу к приемнику. Коэффициент отражения определяется как Предположим, что импеданс источника составляет 25 Ом, импеданс линии 50 Ом, а импеданс приемника 1 МОм. Тогда для источника р = B5 - 50)/B5 + 50) - -0,33, для приемника р= A06-50)/A06 Импеданс 25 Ом является хорошим приближением для выходного каскада ПЛИС стандарта LVTTL33_F12, поэтому подобная ситуация является достаточно характерной. Из приведенной формулы для коэффициента отражения видно, что нулевого отражения можно добиться, приравняв импеданс источника и линии и, для приемника, импеданс линии и приемника. Удобнее выбирать для длинных линий определенный импеданс (например, 50 Ом) и приводить источник и приемник к этому значению. Согласование импедансов источника и линии передачи проще всего выполнить с помощью резистора, включаемого последователь-
454 а 8 Рис. 8.20. Согласование им- педансов источника и линии Рис. 8.21. Согласование импедансов линии и приемника по схеме ТЪвенина но, как показано на рис. 8.20. Резистор необходимо установить как можно ближе к выходу, чтобы печатный проводник, соединяющий их, не являлся линией с распределенными параметрами. На стороне приемника проблема заключается в том, что импеданс приемника довольно высок — входы КМОП практически не потребляют тока. Поэтому следует обеспечить для линии нагрузку, подключив согласующий резистор («терминатор») к земле или питанию. Используется также схема Тевенина, показанная на рис. 8.21. Два резистора с номинальным значением R по сути соединены параллельно, если учесть, что между землей и Vdd подключен источник, близкий к идеальному (т. е. с малым внутренним сопротивлением). Поэтому эквивалентное сопротивление подключенных резисторов равно R/2. Можно также использовать только один из этих резисторов, в этом случае добавляемое сопротивление равно R. Резисторы также следует устанавливать возможно ближе к входу приемника, чтобы печатный проводник до входа микросхемы не вносил свой вклад в создание отражений. Устранение отражений сигналов в длинных линиях является важной, но не единственной задачей, которую необходимо решить при проектировании печатной платы. Важность борьбы с отражениями сигнала обусловлена достаточно малым временем нарастания сигнала, характерным для современных ПЛИС, и проблема искажения формы сигнала для печатных плат, разработанных без учета согласования импедансов, является актуальной. Вместе с тем, если предусмотреть хотя бы посадочные места для согласующих резисторов, у разработчика появляется возможность исправить ситуацию уже после монтажа компонентов и выявления проблемы. Дифференциальный интерфейс LVDS требует обязательного резистора, включаемого между выводами Р и N линии. Номинал резистора обычно составляет 100 Ом. В ПЛИС имеется ограниченная возможность управления импедансов выводов. С помощью проектных ограничений можно подключить к выводу резисторы PULL-UP и PULL-DOWN (с образова-
проектирование устройств с применением ПЛИС 455 Power Signall Signal2 GND Power Signall GND Power Signal2 GND - Сигналы находятся + Слой питания имеет внутри «конденсатора» находящийся рядом слой земли — Сигнальные слои + Сигнальные слои взаимодействуют изолированы Рис. 8.22. Варианты расположения слоев в многослойной печатной плате нием схемы по Тевенину), а также установить дифференциальный согласующий резистор для LVDS. Также немаловажный вопрос при проектировании заключается в выборе числа слоев печатной платы. Многие производители печатных плат устанавливают достаточно высокий верхний предел числа слоев. Может ли проект получить преимущества от применения дополнительных слоев? На рис. 8.22 показаны примеры расположения слоев в многослойной печатной плате. Оба варианта имеют два сигнальных слоя. В первом случае сигнальные слои являются внутренними, а на внешних слоях расположены цепи питания (Power) и земли (GND). Однако такое расположение имеет видимые недостатки. Во-первых, сигнальные слои находятся внутри обкладок конденсатора, образованного слоями питания и земли. Шумы по цепям питания будут наводить помехи на сигнальные линии. Кроме того, сами сигналы, находящиеся в соседних слоях, будут влиять друг на друга. Если увеличить число слоев, можно расположить сигнальные слои дальше друг от друга. Во втором случае сигнальные слои экранированы слоем земли, находящимся между ними. Лоэтому в данном случае увеличение числа слоев с 4 до б улучшит устойчивость сигнальных линий к помехам. Рекомендации по выбору числа слоев печатной платы являются предметом отдельного рассмотрения. Можно ориентироваться на отладочные платы Xilinx, для которых часто предоставляются проекты печатных плат. 8.5.2. САПР печатных плат Система проектирования печатных плат не входит в состав средств проектирования Xilinx. Однако в настоящее время существует множество САПР печатных плат, обеспечивающих полный
456 Г л а ва 8 }'¦,'¦',""{ AW-.УЛ,; -«f!.kf."iiv*. )„'¦*« *У,1 Шй Рис. 8.23. Внешний вид окна САПР Altium Circuitmaker маршрут проектирования — от ввода принципиальной электрической схемы до получения послойного представления печатной платы и, в ряде случаев, анализа целостности сигналов. Некоторые версии САПР предполагают бесплатный доступ на определенных условиях. Как правило, имеются в виду функциональные ограничения — по площади печатной платы, числу слоев, числу контактов и цепей. На рис. 8.23 и 8.24 показан внешний вид САПР, имеющих бесплатные версии, — Altium Circuitmaker и Autodesk Eagle. В целом же, однако, для проектирования печатной платы с ПЛИС большого объема и высокоскоростными цепями необходимо использовать профессиональные САПР, обеспечивающие анализ сигналов с учетом полученной трассировки проводников. Известными производителями таких инструментов являются компании Cadence, Mentor Graphics, Altium и др. Возможностей бесплатных САПР в целом достаточно для проектирования печатной платы с ПЛИС начального уровня. Впоследствии разработчик или организация могут принять решение о целесообразности самостоятельного проектирования печатных плат. 8.5.3. Особенности трассировки печатных плат для ПЛИС При проектировании печатных плат для ПЛИС следует учитывать ряд вопросов, специфичных для этой элементной базы. Реконфигурируемость выводов ПЛИС дает разработчику печатной платы довольно много свободы для маневра. В то же вре-
•9 s I о ¦а Рис. 8.24. Внешний вид окна САПР Autodesk Eagle
458 Глава МОЖНО ПОДКЛЮЧИЛ, МОЖНО ПОДКЛЮЧИТЬ рис. 8.25. Неопределенное™. сигнал к любому внешнюю цепь к назначении сигналов выво! выводу корпуса любому выводу корпуса дам ПЛИС при условии прХ тирования собственной печатной платы мя специалисты, осваивающие трассировку плат для ПЛИС, часто сталкиваются с необычной проблемой. Если при трассировке печатной платы для процессора, микроконтроллера или другой микросхемы с фиксированным расположением выводов в документации указаны выводы и подключенные к ним сигналы, то это дает начальную точку для проектирования. Вместе с тем ПЛИС возможность подключения сигнала на любой программируемый вывод может дезориентировать разработчика печатной платы. Совместное обсуждение специалистами, один из которых разрабатывает печатную плату, а другой — конфигурацию ПЛИС, может привести к ситуации, показанной на рис. 8.25. В данном случае оба специалиста готовы к гибкому стилю работы. Разработчик печатной платы может потребовать список выводов ПЛИС, к которым подключены сигналы, однако разработчик конфигурации ПЛИС может также запросить реализованную трассировку и список цепей, которые он внесет в проектные ограничения, обеспечив тем самым требуемые соединения внутри ПЛИС. В этом случае необходимо найти компромисс. Свобода, предлагаемая ПЛИС в части назначения выводов, на практике имеет особенности. Действительно, можно избежать путаницы и лишних переходных отверстий на печатной плате, возникающих при попытке «перевернуть» параллельную шину, порядок разрядов которой не совпадает с положением выводов корпуса. В этом случае возможность переназначения сигналов ПЛИС является полезным свойством. С другой стороны, при назначении сигналов одной и той же параллельной шины следует группировать их по банкам ввода-вывода. Тактовый сигнал для source-synchronous интерфейса должен подаваться на тот же банк, что и линии данных, которые он сопровождает (и на clock-capable вход). Также следует стараться группировать сигналы, избегая слишком далекого расположения сигналов, относящихся к одному модулю. Для всех корпусов BGA не следует сверлить переходные отверстия непосредственно в контактных площадках для выводов. Вмес-
проектирование устройств с применением ПЛИС 459 рис. 8.26. Параметры переходного отверстия печатной платы для корпуса типа BGA. Размеры, показанные на рисунке, приводятся в технической документации на каждый тип корпуса то этого необходимо вывести короткий проводник в центр квадрата, по углам которого находятся четыре контактных площадки, и разместить отверстие там. Рекомендованные параметры переходного отверстия приводятся в технической документации на корпуса BGA и зависят прежде всего от шага выводов, обозначенном е на рис. 8.26. Значения прочих параметров определяются технической документацией. Следует учитывать, что переходное отверстие является источником дополнительной индуктивности в цепи и влияет на ее импеданс. Для высокоскоростных интерфейсов следует применять подход: переходное отверстие в непосредственной близости от вывода корпуса ПЛИС (как показано на рис. 8.26), трассировка линии без переходных отверстий и резких поворотов, переходное отверстие в непосредственной близости от вывода, к которому производится подключение. После трассировки печатной платы рекомендуется создать тестовый проект в САПР ПЛИС, назначив все сигналы проекта внешним выводам. Можно использовать «заглушки», реализующие только внешние интерфейсы, без полной функциональности. Проведение синтеза схемы и, главное, размещения выводов (в процессе Implementation) позволит выявить потенциальные ошибки, связанные с отсутствием нужного режима у какого-либо вывода ПЛИС, ошибками в напряжениях банков и т. п. При установке внешних компонентов приоритет имеют резисторы для согласования импеданса. Затем следует установить керамические конденсаторы малой емкости, соединив их максимально короткими линиями с соответствующими выводами питания и земли. 8.6. Охлаждение В ряде случаев ПЛИС может потребовать дополнительного охлаждения. Повышенное потребление обычно не вызывает проблему для ПЛИС небольшого логического объема, однако использование ПЛИС Zynq, Kintex или Artix большого объема скорее всего
460 Г л а в а 8 II XILINX. Table 51 • Thermal Resistance Data-All Devices Package Spartan-7 FPGAs CPGA196 CPGA196 CPGA196 CPGA196 CSGA225 CSGA225 Package Body Size 8x8 8x8 8x8 8x8 13x13 13x13 Devices XC7S6 XA7S6 XC7S15 XA7S15 XC7S6 XA7S6 (ec/w) rcjtv) rc/w 151 151 15 1 151 17 4 17 4 35 0 35 0 35 0 35 0 32 2 32 2 8 46 8 46 8 46 8 46 10 6 10 6 Chapter 5 ¦—-. : Thermal Specifications GjA-Effective CC/WjW ~ > <§>250 LFM @500 LFM @750 LFM 301 301 301 301 26 7 26 7 286 279" 28 6 27 9 28 6 27 9 28.6 27 9 25 1 242 " 25 1 242 Рис. 8.27. Фрагмент таблицы со спецификациями теплового сопротивления приведет к тому, что ПЛИС перегреется без дополнительных мер по охлаждению. Информация о приблизительном потреблении предоставляется САПР Vivado уже на ранних стадиях проектирования. Каким образом можно использовать информацию о потребляемой мощности для определения температуры ПЛИС? В документе «7 Series FPGAs Packaging and Pinout Product Specification UG475» приведены сведения о тепловом сопротивлении (Thermal resistance). Пример таблицы показан на рис. 8.27. При расчете нагрева ПЛИС используется достаточно простая модель. Потребляемая мощность умножается на постоянный коэффициент, чтобы получить температуру дополнительного нагрева. Упрощенный характер такой модели заключается в том, что в действительности процессы теплового обмена достаточно сложны и должны учитывать прогрев окружающей среды (что снижает эффективность теплообмена), конвекционные потоки воздуха, потери на излучение и т. д. Однако в первом приближении простая линейная модель позволяет оценить уровень нагрева ПЛИС. Дополнительный нагрев ПЛИС определяется по формуле AT = Р0, где AT — дополнительный нагрев, °С; Р — потребляемая мощность, Вт; 0 — тепловое сопротивление, °/Вт. Физический смысл параметра «тепловое сопротивление» заключается в указании, на сколько градусов дополнительно нагреется ПЛИС при потребляемой мощности 1 Вт. В таблице на рис. 8.27 указаны три параметра:
проектирование устройств с применением ПЛИС 461 ®лв "" тепловое сопротивление «переход — плата» (junction — board); 0ja — тепловое сопротивление «переход — окружающая среда» (junction — ambient); 0jc — тепловое сопротивление «переход — корпус» (junction — case). При работе без дополнительного охлаждения применяется параметр 0ja, который в таблице максимален для каждого варианта корпуса. Рядом показаны варианты этого параметра при активном охлаждении. Варианты 250, 500 и 750 LFM (linear feet per minute, т. е. футов в минуту) соответствуют скорости потока воздуха, обеспечиваемой внешним вентилятором. Видно, что при активном охлаждении тепловое сопротивление падает. Тепловое сопротивление «переход — корпус» определяет минимальный уровень теплового сопротивления, определяемый тем, что кристалл ПЛИС не имеет идеального теплового контакта с крышкой корпуса. Это тепловое сопротивление останется даже при очень эффективном отводе тепла от корпуса ПЛИС. Видно, что это сопротивление, тем не менее, много меньше, чем 0ja. Тепловое сопротивление «переход — корпус» интересно тем, что в сочетании с радиатором оно образует новую цепочку: «переход — корпус», «корпус — радиатор» 0cs> «радиатор — окружающая среда» 0sa- Эти тепловые сопротивления необходимо сложить, чтобы получить итоговое тепловое сопротивление получившейся конструкции: 0 = ®jc + ©cs + ®sa- Если выбрать радиатор с низким тепловым сопротивлением, то получившаяся сумма окажется меньше, чем 0ja- Информация о тепловом сопротивлении радиаторов приводится их производителями. Можно рекомендовать ознакомление с системами охлаждения, применяемыми на отладочных платах и в промышленных изделиях на базе ПЛИС. Достижение точного значения теплового сопротивления на практике имеет сомнительную целесообразность, поскольку дополнительное снижение температуры способствует повышению надежности работы электронных компонентов. Поэтому имеет смысл проектировать систему охлаждения, с одной стороны, с некоторым запасом, а с другой — ориентируясь на аналогичные решения.
462Гл ава 8.7. Организационные аспекты проектирования Оценка эффективности разработчика при выполнении проекта на базе ПЛИС крайне сложна, поскольку включает в себя множество трудноопределимых факторов. При оценке трудоемкости создания и отладки программных продуктов иногда рассматривается мнение, что средняя производительность программиста, рассчитанная в числе строк кода в год приблизительно постоянна, оценивается в 3000 строк и не зависит от используемого языка [1]. Эта оценка относится не к способности разработчика набрать определенное число текста, а учитывает также время на отладку написанного кода, включая как исправление синтаксических ошибок с целью добиться успешной компиляции программы, так и поиск логических ошибок, которые формально не препятствуют выполнению программы, но приводят к ее неверному функционированию с точки зрения технического задания. Для языков описания аппаратуры в настоящее время не удалось обнаружить аналогичных оценок, что можно объяснить как меньшим объемом технической литературы, посвященной HDL как таковым, так и бблыпим кругом вопросов, которые должен решать разработчик проекта на ПЛИС по сравнению с программистом. Действительно, отладка проекта на ПЛИС заключается не только в отладке его функционального поведения в симуляторе, но и в достижении требуемых характеристик производительности, а также поиске ошибок на уровне печатной платы, источников помех, электрических наводок, исследование влияния подсистемы питания и т. п. Объем этих работ может оказаться достаточно большим. Поэтому оценку числа строк кода для проектирования на HDL следует корректировать, предполагая некоторый запас времени на устранение проблем, связанных с аппаратными компонентами проекта. Выразительные способности языков описания аппаратуры существенно зависят от уровня, на котором ведется описание. Если рассматривать RTL-уровень как базовый, то программирование на структурном уровне обычно можно считать менее выразительным, за исключением случаев, когда в структурном стиле описывается установка в проект IP-ядра. Такое ядро само по себе может иметь сложную функцию, которая при RTL или поведенческом описании потребовала бы большого объема текста. С оценкой времени на выполнение проекта тесно связана оценка технических рисков. В качестве утрированного примера (технически он корректен, но вряд ли будет полезен на практике) можно рассмотреть преобразователь PCI-Express — UART. Для данного
Проектирование устройств с применением ПЛИС 463 проекта необходимо выполнить следующие работы: 1. Настройку аппаратного ядра PCI Express. 2. Разработку контроллера UART. 3. Проектирование печатной платы с соблюдением жестких требований по трассировке печатных проводников. Если выполнять работы в порядке их упоминания, то выяснится, что настройка ядра PCI Express выполняется с помощью стандартного приложения IP Integrator, а контроллер UART представляет собой простой конечный автомат. На этом можно посчитать проект выполненным на 66 %. Однако последним пунктом указана разработка печатной платы для сопряжения высокоскоростных последовательных приемопередатчиков с краевым печатным разъемом PCI Express. Этот пункт требует существенно большего внимания и в приведенном списке может смело считаться основным источником ошибок, приводящих к неработоспособности устройства. Поэтому при начале работы над проектом следует выявить потенциально проблемные места, которые вызовут дополнительные сложности при реализации проекта, потребуют дополнительного времени, применения сложного контрольно-измерительного оборудования, привлечения дополнительных специалистов и т. п. Можно указать некоторые возможные причины появления технических рисков, способных существенно ухудшить показатели проекта по сравнению с ожидаемыми. 1. Жесткие требования к печатной плате для высокоскоростных интерфейсов. Данный источник рисков был рассмотрен выше в качестве примера сопряжения аппаратного ядра FPGA (не требующего сложной настройки) и внешнего компонента. Подобные же проблемы может вызвать память DDR2/3, дифференциальные интерфейсы и вообще внешние линии, работающие на частоте свыше 50... 100 МГц (цифра является весьма размытой, поскольку невозможно указать точное значение частоты, после которого проблемы качественной трассировки печатной платы выйдут на первый план). 2. Ориентация разработчиков на пиковые характеристики FPGA, электрических интерфейсов и САПР. При взгляде на таблицу характеристик FPGA естественным желанием является перемножить число интересующих разработчика блоков (секций DSP, приемопередатчиков) на их пиковую частоту/пропускную способность. Однако при этом необходимо делать поправки как на объективные технические параметры ПЛИС и особенности протоколов, так и на возможность достижения желаемых
464 Г л а ва 8 результатов за разумное время. Многие электрические интерфейсы заявляют скорости передачи данных без учета накладных расходов (например, на организацию пакетов). Интерфейсы Ethernet, USB и PCI Express представляют в этом плане хороший пример сильного несоответствия реальной пропускной способности и пиковых характеристик. Например, для Ethernet только часть передаваемого пакета представляет собой пользовательские данные, причем существует минимальный размер пакета и минимально требуемый интервал между пакетами. Для USB существует техническое ограничение в 1000 пакетов в секунду. В конечном итоге при реализации устройства разработчик может обнаружить, что его реальные характеристики серьезно отстают от ожидаемых. 3. Занижение сроков отладки и тестирования, «магия бренда». Встречается мнение о том, что распространенные ОС, протоколы обмена и программные технологии просты для освоения просто в силу своей распространенности. Для ПЛИС Xilinx действительно существуют успешные реализации изделий на базе ОС Linux и Android, поддерживающие большое число распространенных интерфейсов (Ethernet, WiFi, HDMI, PCI Express и т.д.). Однако необходимо иметь четкое представление о сроках реализации и трудоемкости создания собственного изделия, способного работать под управлением Linux или Android, поддерживать упомянутые технологии и отвечать требованиям стандартов, чтобы иметь возможность работать не только в лабораторных условиях, но и взаимодействовать с другими устройствами. В этом случае «магия бренда» проявляется в откладывании на поздние сроки реализации широко распространенных технологий. При этом разработчики необоснованно полагают, что если эти технологии используются в широко распространенных потребительских устройствах, то и они не встретят в этих областях серьезных препятствий. Рекомендуется использовать для освоения отдельных узлов макетные и отладочные платы, не ограничиваясь запуском примеров, поставляемых в комплекте с ними. 8.7.1. Подготовительные организационно-технические мероприятия 1. Промежуточные контрольные точки. При повышении сложности проекта все более важную роль начинают играть грамотно выбранные контрольные точки. Только проекты небольшого размера могут быть выполнены «от начала и до конца». Для сложных проектов контрольные точки следует
Проектирование устройств с применением ПЛИС 465 выбирать таким образом, чтобы они помогали выявить возможные проблемы на ранних этапах проектирования. В приведенном вы- ще примере с высокоскоростным интерфейсом контрольные точки должны выбираться с учетом именно его реализации. Например, обеспечение передачи пакетов по PCI Express является хорошей контрольной точкой, поскольку в этом случае становится понятно, что печатная плата реализована качественно и ядро настроено правильно. Эта точка делает возможным переход к отладке протоколов обмена. В то же время реализация модуля UART или регистров для вывода статуса на светодиоды не отвечает на вопросы о критических компонентах проекта. 2. Управление версиями и резервное копирование. Управление версиями получает все более широкое распространение в программных проектах. Если над описанием проекта работают несколько человек, могут возникать ситуации перекрестных и дублирующихся исправлений, которые в итоге приведут к путанице в модулях проекта, многочисленным откатам на ошибочные версии и трудоемким итерациям объединения исправлений, произведенных разными разработчиками в сделанных ими копиях одного и того же файла. В индустрии существует множество инструментов управления версиями, широко известных в среде программистов. 3. Стиль оформления кода. Правила оформления кода не носят характер технических требований. Однако они способны оказать влияние на эффективность процессов отладки и сопровождения проекта. Смыслом следования определенному стилю оформления является создание быстро идентифицируемых инженерами фрагментов кода, которые не заставляют их тратить дополнительное время на выяснение назначения конкретного участка. Повсеместно распространенной рекомендацией является использование отступов в тексте, выделяющих вложенные синтаксические конструкции. Следование стилю оформления кода не должно затруднять рабочий процесс, поэтому устанавливаемые правила нуждаются в разумном обосновании. Вопросы оформления кода часто освещаются в литературе по программированию, например [2]. 4. Комментарии. Комментирование модулей на языках описания аппаратуры, как и комментирование программ, не обязательно с точки зрения средств разработки, однако настоятельно рекомендуется при сколько-нибудь заметной сложности проектов. Комментарии для проектов на базе ПЛИС подразделяются на следующие типы.
Внешние комментарии (в терминологии Xilinx) — отдельны документы в форматах pdf, html, doc, статьи, книги (в случае особенно сложных компонентов). Такие комментарии, являющиеся ц0 сути техническими описаниями, призваны разъяснять разработчикам основы функционирования модулей. Комментарии уровня модуля обычно представляются в виде заголовочной части модуля, в которой приводится информация о его названии, версии, компании-разработчике и авторе модуля, краткое техническое описание и т. д. Размещение такого фрагмента в начале файла способствует единообразию в описаниях отдельных модулей что способствует быстрому анализу состояния проекта. Комментарии уровня группы строк описывают планируемое действие отдельного фрагмента. В данном случае было бы излишним дублировать информацию, которую можно легко получить из изучения фрагмента. Например, для счетчика на VHDL комментарий, утверждающий, что это счетчик, очевиден и не несет полезной информации^ — счетчик (пример малополезного комментария) process(clk) begin if rising_edge(clk) then if count = 99 then count <= 0; else count <= count + 1; end if; end if; end process; Гораздо полезнее была бы информация о том, какую роль в проекте играет этот счетчик и почему он считает от 0 до 99. Например, следующий комментарий не только разъясняет назначение реализованного счетчика, но и помогает отследить, действительно ли приведенный после комментария блок текста выполняет функцию, запланированную разработчиком. — формирование управляющего сигнала для контроллера SPI — входная частота 200 МГц, — получаемый стробирующий сигнал 2 МГц Бели впоследствии входная или требуемая частоты изменятся, приведенный комментарий позволит увидеть, что разработанный модуль перестал соответствовать своему назначению. Несмотря на то что он по-прежнему будет полностью корректен и сможет быть помещен в ПЛИС, выполняемое им действие перестанет отвечать требованиям проекта в целом. Без комментария отследить такие изменения было бы сложнее.
проектирование устройств с применением ПЛИС 467 Комментарии уровня строки служат аналогичной цели. Точно так же комментарий, дублирующий информацию, явно видную из RTL-представления, является излишним. Важнее поместить пояснение, почему выполняется именно это действие, или почему выбрана именно эта константа. Также полезно отметить параметры яли выражения, которые потребуют коррекции при изменении каких-либо условий, например разрядности сигналов, размеров буфера и т.п. Встроенные комментарии. К ним относятся выразительные имена переменных, сигналов и других объектов модуля, которые способствуют пониманию выполняемых действий. Например, следующее выражение выглядит очевидным: FinaLvalue <= initiaLvalue + delta; Его аналогом, корректным с точки зрения синтаксиса, может быть любое сложение с допустимыми именами сигналов: // синтаксически корректно, // однако сложно для восприятия Sdfqa <= erB).df + clloO; Имена сигналов намеренно выбраны так, чтобы продемонстрировать возможные затруднения в прослеживании корректности проводимого действия. Что именно складывается (и нужно ли вообще складывать эти значения) непонятно без дополнительного изучения кода. Во втором слагаемом использованы символы латинского алфавита, схожие по начертанию с цифрами, что дополнительно затрудняет и идентификацию имени сигнала. В целом такой практики необходимо тщательно избегать. Соглашения об именовании объектов во множестве используются в программировании (например, широко известная венгерская нотация), также удобно использовать идентификаторы сигналов, принятые в цифровой электронике (например, elk для тактового сигнала, d и q для входов и выходов соответственно и т.п.). 5. Тестирование и устранение ошибок. При разработке цифровых систем на базе ПЛИС применяются следующие виды тестирования. Моделирование представляет собой запуск программы-симуля- тора, демонстрирующей реакцию разрабатываемого устройства на входные воздействия в виде диаграмм сигналов и текстовых файлов. Моделирование интенсивно используется на ранних стадиях разработки, когда требуется уточнить поведение системы, проверить корректность разработанных описаний и убедиться, что реак-
468 Глава 8 ция на входные воздействия соответствует техническому заданию система в целом действительно решает поставленную задачу. Стендовые испытания (испытания в лабораторных условиях} подразумевают проверку работы устройства в контролируемой среде. При этом используются лабораторные генераторы, контрольно- измерительное оборудование, а специальные воздействия ограничиваются. Поскольку испытания проводятся на реальном экземпляре разрабатываемого изделия, становится возможным проверить адекватность функциональных моделей и убедиться, что использованные схемотехнические решения действительно работоспособны на реальной ПЛИС. На этом этапе могут быть выявлены отклонения от синхронного стиля проектирования (симулятор не может автоматически проверить уход фазы тактового сигнала, влияние джитте- ра, возникновение метастабильных состояний и прочие отклонения реального кристалла ПЛИС от идеализированной математической модели), проблемы в организации питания, отвода тепла от ПЛИС, влияние эффектов дискретизации по уровню и времени при обработке аналоговых сигналов. Интеграционные тесты проводятся для исследования влияния системных эффектов. Они проводятся при сопряжении прибора с реальными устройствами, причем на этом этапе может быть обнаружено, что синтетические тесты неадекватно отразили реальную ситуацию. Например, блок питания системы может иметь повышенный уровень шумов по сравнению с лабораторным источником питания, который использовался при отладке. Дополнительные шумы могут также генерироваться источниками, которые не были учтены при лабораторных испытаниях. Реальная коммуникационная среда может иметь другой уровень нагрузки (число пакетов, их состав, уровень потерь и т.п.). Это может привести к тому, что результаты лабораторного моделирования будут признаны неадекватно отражающими реальную картину. Испытания в полевых условиях подразумевает проведение тестовой эксплуатации устройства в реальных условиях. На этом этапе могут быть выявлены такие эффекты, как неработоспособность при реальных сочетаниях температуры эксплуатации, уровня помех, механических и электромагнитных воздействий, низкая эр- гономичность или ремонтопригодность. В целом можно отметить, что использование программ-симуля- торов и даже стендовых испытаний не является абсолютной гарантией работоспособности изделия в реальных условиях эксплуатации. Поэтому необходимо планировать дополнительное время на прове-
проектирование устройств с применением ПЛИС 469 дение испытаний в реальных условиях с последующей коррекцией схемы ПЛИС или даже конструкции изделия в целом. 6. Планирование длительных процессов САПР. Для ПЛИС большого логического объема время одной итерации работы САПР может измеряться часами. Увеличение коэффициента заполнения ПЛИС и ужесточение временных ограничений создает дополнительную нагрузку на алгоритмы размещения и трассировки, увеличивая время их работы. В конечном счете может возникнуть ситуация, когда в день коллектив разработчиков получает всего 1-2 варианта размещения проекта. При этом уже невозможно сохранять «стихийный» подход к отладке, когда разработчики начинают практически наугад пробовать варианты исправления наблюдаемых ошибок, повторяя полный цикл работы САПР. Подобный подход, который не слишком вредит при компиляции маленьких программ или трассировке ПЛИС небольшого объема, неприемлемо (а главное, непредсказуемо) затянет процесс доводки проекта. Поэтому при выявлении чрезмерно возросшей длительности создания проекта необходимо принять решение о систематизации процессов запуска САПР с целью получения нового варианта конфигурационного файла. Недостаток для разработчиков заключается в том, что появляющиеся предположения о способах коррекции исходных текстов проекта уже не могут быть проверены немедленно. В действительности, бессистемные правки исходных текстов в данной ситуации будут являться непроизводительной потерей времени, поскольку каждое редактирование, выполняющееся за 5... 10 минут, будет сопровождаться многочасовым процессом обновления файла конфигурации. Число итераций отладки сократится до 1-2 в течение рабочего дня. В такой ситуации совершенно необходимо, чтобы разработчики потратили дополнительное время на проверку внесенных изменений и определили, что именно они ожидают получить в результате. Ситуация с бессистемной и длительной компиляцией отражена в популярной серии комиксов xkcd, на одном из которых руководитель интересуется, почему его программисты не работают. Их ответ «Компилируется!» его полностью удовлетворяет, однако следует признать, что таким образом программисты, скорее всего, искусственно создают перерыв в работе, ссылаясь на необходимость дождаться завершения необоснованно запущенного ими длительного процесса компиляции. Для ПЛИС ситуация резко усугубляется, поскольку создание конфигурации ПЛИС обычно занимает больше времени, чем компиляция сопоставимого по сложности программного продукта.
470 Гла в a Если исходные модули проекта редактируются нескольким» разработчиками, может оказаться полезным заранее запланировать время запуска процесса implementation (например, в конце рабочего дня или даже в конце рабочей недели). В этом случае после идентификации проблем и анализа возможных методов их исправления коллектив сможет потратить время на выбор способов исправления моделирование нового варианта системы и подготовить новый вариант, включающий в себя максимальное число исправлений. Современные версии САПР Xilinx (Vivado и последние версии ISE) не только допускают, но и активно поддерживают использование скриптового языка Tel для организации автоматической сборки проекта. Скрипт на языке Tel позволяет полностью исключить работу с графическим интерфейсом, сохраняя при этом возможности установки параметров процессов synthesis и implementation, выбора ПЛИС, ее корпуса и класса скорости и т.д. Хорошая интеграция Tel в операционную систему допускает автоматизированный запуск скриптов, поэтому вполне возможна настройка рабочей станции таким образом, чтобы сборка проекта выполнялась ночью или в выходные дни. При таком подходе разработчики будут свободны для отладки проекта и выбора путей его коррекции в течение рабочего дня, а к следующему утру получат результаты проделанной работы. 8.7.2. Порядок разработки Для проектной деятельности применимы два взаимодополняющих подхода к разработке: «снизу вверх» (также bottom up) is. «сверху вниз» (top down). В первом случае модули проекта последовательно разрабатываются и отлаживаются, после чего производится их сборка и проверка корректности совместной работы. Процесс продолжается до тех пор, пока в результате объединения не будет получен верхний уровень схемы. При построении проекта «сверху вниз» спроектированный верхний уровень разбивается на субмодули до тех пор, пока не будет получен набор компонентов, каждый из которых достаточно прост для реализации. Категорическое следование одному из подходов обычно оказывается малоэффективным. При проектировании «снизу вверх» может оказаться, что разработчики сосредоточились на реализации малозначимых деталей, и по истечении длительного времени выяснилось, что к проектированию ключевых компонентов проекта так никто и не приступил (однако реализовано большое число элементарных субмодулей уровня «мультиплексор», «счетчик» и т.п.)- При проектировании «сверху вниз» можно оказаться в подобной си-
проектирование устройств с применением ПЛИС 471 ггуации, когда проект будет разбит на абстрактные модули «обработка», «интерфейс» и т. п., однако конкретные технические параметры, алгоритмы обработки, используемые сигналы так и не будут четко определены, чтобы разработчики смогли приступить к непосредственному кодированию. Разделение задач между разработчиками (если в проекте участвует более одного разработчика) можно выполнять различными способами. В литературных источниках, рассматривающих вопросы организации разработок, данный вопрос рассматривается в терминах проектной специализации и функциональной специализации. В целом предлагается устанавливать проектную специализацию для небольших коллективов. Это означает, что каждый разработчик полностью отвечает за выполнение проекта (одного или нескольких). Работа при этом производится независимо, и разработчики не обязаны участвовать в проектах коллег. Недостатком такого подхода является зависимость сроков и качества проделанной работы от индивидуальной квалификации. Однако разработчики получают возможность сосредоточиться на исполнении одного проекта, что минимизирует непроизводительные потери времени и несогласованность технических решений. Для больших коллективов (граница довольно размыта, в специализированной литературе упоминается размер в 20-30 технических специалистов) оптимальной будет функциональная специализация. В этом случае в организации существуют выделенные специалисты, занятые решением частных задач. Преимуществом данного подхода является возможность углубленного освоения сложных технологий, например построения интерфейсов PCI Express, памяти DDR или процессорных систем на базе MicroBlaze/ARM. Выделенные специалисты могут сосредоточиться на изучении конкретного инструмента, выполняя настройку соответствующих модулей для всех проектов в организации. Однако таких разработчиков вряд ли следует отвлекать для выполнения рутинных работ, например, по доводке приборов и отладке прикладного программного обеспечения. Именно поэтому углубленная специализация рекомендуется при наличии достаточно большого коллектива, который может позволить некоторое уменьшение числа параллельно выполняемых проектов. На практике можно ожидать использования смешанного подхода, при котором сложные технологии осваиваются специально назначаемыми инженерами, которые, сохраняя собственный пакет проектов, выполняют какие-то работы для всего коллектива. В оптимальном варианте следует выбрать такие технологии и узлы, pea-
472 Главка лизация которых не занимает слишком много времени, однако имеет множество нюансов, которые подлежат длительному изучению. Можно рекомендовать включить в данный список уже упомянутые выше PCI Express, контроллеры памяти DDR, высокоскоростные интерфейсы как таковые и, возможно, настройку процессорных подсистем. Конкретный список технологий и узлов, которые будут выполняться в организации специально подготовленными разработчиками, должен формироваться в индивидуальном порядке и не должен рассматриваться как окончательный. 8.8. Отладочные платы В данном разделе приводятся некоторые варианты отладочных плат, выпускаемых как Xilinx, так и основными производителями- партнерами. Наиболее интересными ресурсами являются сайты компаний Digilent, Inc. и сообщества zedboard.org, ориентированного на выпуск плат на базе ПЛИС Zynq. Стоимость плат существенно различается и находится в пределах от 69 USD до 2995 USD. Указанные цены являются справочными и приведены по данным компании- производителя на момент проверки сведений на официальной странице продукта. Общим правилом является добавление к подобным ценам величины таможенной пошлины и стоимости транспортировки в Россию. Поэтому розничные цены в России оказываются заметно выше, чем цены, приводимые производителями плат. 8.8.1. Платы на базе Spartan-6 (устаревающие) Семейство Spartan-б можно отнести к устаревающим. Благодаря наличию корпусов QFP и микросхем небольшой стоимости эти FPGA еще представляют интерес, однако для новых проектов с недорогими ПЛИС рекомендуется обращать внимание на серию 7. Плата Cmod S6 (рис. 8.28) Рис. 8.28. Плата Cmod S6
Проектирование устройств с применением ПЛИС 473 Характеристики платы: • установлена FPGA Xilinx Spartan-6 XC6SLX4-2CPG196; • внешняя микросхема 16 MB Spansion™ Quad SPI Flash для хранения конфигурации ПЛИС; • 46 выводов FPGA подключены к выводам разъема DIP; • два источника тактовых сигналов на плате • 4 светодиода и 2 кнопки; • встроенный программатор с портом USB. Плата Digilent Anvyl (рис. 8.29) Рис. 8.29. Плата Anvyl Характеристики платы: • установлена FPGA Xilinx Spartan-6 LX45 (XC6SLX45-CSG484-3); • внешняя память 128MB DDR2 SDRAM; • внешняя память 2MB SRAM; • внешняя микросхема 16 MB Spansion™ Quad SPI Flash для хранения конфигурации ПЛИС; • тактовый генератор 100 МГц; • микросхема 10/100 Ethernet PHY; • выход HDMI; • выход VGA разрядностью 12 битов; • аудиокодеке I2S с линейным входом, линейным выходом, входом микрофона и выходом наушников; • арограмматор Digilent USB-JTAG с портом USB-UART; • дисплей LCD с диагональю 4.3"; • дисплей OLED с разрешением 128x32 и диагональю 0.9"; • два 7-сегментных индикатора; • порты USB2 для устройств USB-HID (мышь, клавиатура); • клавиатура с 16 клавишами (символы 0-F) • 14 светодиодов, 8 переключателей, 8 DIP-переключателей и 4 кнопки; • макетное поле; • 32 вывода ПЛИС подключены к 40-выводному разъему DIP (частично обобщены с разъемами PMOD); • 7 разъемов PMOD.
474 Гла ва 8 8.8.2. Платы на базе Spartan-7 Семейство Spartan-7 может применяться для замены Spar tan-6. По сравнению с другим недорогим семейством Artix-7, ПЛИС Spartan-7 обладают меньшими возможностями организации внешних интерфейсов, однако их внутренние программируемые ресурсы аналогичны Artix-7. Плата Cmod S7 (рис. 8.30) Плата представляет собой модуль с двухрядным штыревым разъемом с шагом выводов 2,54 мм. Это очень удобно для применения в сочетании с базовой платой или просто для подключения разъемов, поскольку большой шаг делает доступ к выводам легкодоступным. Разъем MicroUSB используется и для питания платы, и для программирования, что также довольно удобно, если в распоряжении имеется только эта плата. Рис. 8.30. Плата Cmod S7 Характеристики платы: • установлена FPGA Xilinx Spartan-7 (XC7S25-1CSGA225C); • внешняя память 4 MB Quad-SPI Flash; • программатор USB-JTAG; • преобразователь USB-UART; • 4 светодиода, 1 RGB-светодиод, 2 кнопки; • 1 разъем PMOD; • разъем DIP с 48 выводами, 32 из которых подключены к ПЛИС; • 2 вывода разъема подключены к внутреннему АЦП (модуль XADC). Плата Digilent Arty S7 (рис. 8.31) Серия плат Arty включает в себя варианты для основных недорогих семейств ПЛИС Xilinx. Они имеют одинаковую компоновку и набор периферийных устройств. Характеристики платы: • установлена FPGA XC7S50-1CSGA324C или XC7S25-1CSGA324);
Проектирование устройств с применением ПЛИС 475 Рис. 8.31. Плата Arty S7 динамическая память 256 MB DDR3L; внешняя память 16 MB Quad-SPI Flash; программатор USB-JTAG; преобразователь USB-UART; 4 разъема PMOD; разъем для установки модулей расширения Arduino C,3 В); 4 светодиода, 2 RGB-светодиода, 4 переключателя, 4 кнопки; разъем Ethernet и микросхема PHY 10/100 Мбит/с; питание от разъема USB или внешнего нестабилизированного источника 7,..15 В. 8.8.3. Платы на базе Artix-7 Плата Arty A7 Плата Arty A7 (рис. 8.32) в целом аналогична плате Arty S7. Отличия заключаются в установленной ПЛИС. Это XC7A35TICSG324- 1L или XC7A100TCSG324-1. Рис. 8.32. Плата Arty A7
476 Глава 8 Плата Digilent Basys 3 Artix-7 Серия плат Basys производства Digilent (рис. 8.33) подходит для обучения основам проектирования цифровых схем. Большое число механических переключателей, кнопок и светодиодных индикаторов позволяет исследовать поведение несложных схем и наблюдать за их работой. Рис. 8.33, Плата Digilent Basys 3 Характеристики платы: • установлена FPGA XC7A35T-1CPG236C; • программатор USB-JTAG; • преобразователь USB-UART; • флеш-ПЗУ с последовательным интерфейсом; • выход VGA разрядностью 12 битов; • порты USB2 для устройств USB-HID (мышь, клавиатура); • 5 кнопок, 16 переключателей, 16 светодиодов; • 4 семисегментных индикатора; • 4 разъема PMOD, один из которых совмещен с входами внутреннего АЦП ПЛИС. Плата Digilent Nexus Video Серия плат Nexus предназначены для прототипирования проектов на базе ПЛИС Artix (рис. 8.34). Они оснащаются FPGA большой логической емкости и широким набором периферийных устройств. С помощью таких плат можно проверить принципиальную работоспособность IP-ядер, разработанных пользователем. В отличие от плат начального уровня, на данной плате есть разъем FMC, с помощью которого можно подключать платы расширения с высокой скоростью передачи сигналов. Разъем FMC широко используется в современных платах среднего и верхнего ценового диапазона. Характеристики платы: • установлена FPGA XC7A200T-1SBG484C; • динамическая память 512 MB 800 MHz DDR3;
проектирование устройств с применением ПЛИС 477 Рис. 8.34. Плата Digilent Nexus • внешняя память 32 MB Quad-SPI Plash; • программатор USB-JTAG; • преобразователь USB-UART; • вход HDMI; • выход HDMI; • разъем Mini Display Port; • аудиокодек с 4 разъемами 3,5 мм; • Ethernet PHY со скоростями передачи данных 10/100/1000 Мбит/с; • микросхема EEPROM; • монохромный дисплей OLED с разрешением 128x32 пикселов; • порты USB2 для устройств USB-HID (мышь, клавиатура); • 5 кнопок, 8 переключателей, 8 светодиодов; • разъем FMC LPC (Low Pin Count); • 4 разъема PMOD. Плата Xilinx AC701 Плата АС701, разработанная Xilinx (рис. 8.35), представляет собой один из стандартных вариантов компоновки, допускающий как установку в слот PCI Express, так и автономную работу. Рис. 8.35. Плата Xilinx AC701
478 Характеристики платы: • установлена FPGA XC7A200T-2FBG676C; • модуль динамической памяти 1GB DDR3 SODIMM; • память Quad SPI Flash 256Mb; • программатор USB-JTAG; • преобразователь USB-UART; • тактовый генератор с частотой 200 МГц; • программируемый тактовый генератор 10 МГц — 810 МГц; • разъем PCI Express x4; • разъем FMC HPC (High-Pin Count), частично подключенный к ПЛИС B приемопередатчика GTP выведены на линии разъема); • 4 разъема SMA, подключенных к высокоскоростным последовательным приемопередатчикам GTP; • модуль SFP; • выход HDMI; • Ethernet PHY со скоростями передачи данных 10/100/1000 Мбит/с; • символьный LCD 2x16 символов; • слот для SD-карты; • 5 кнопок, 4 переключателя; • 1 разъем XADC; • 1 разъем PMOD. Набор Artix-7 50T FPGA Evaluation Kit Особенностью платы (рис. 8.36) являются два разъема Ethernet. Рис. 8.36. Плата Avnet Artix-7 БОТ Характеристики платы: • установлена FPGA XC7A50T-1FTG256C; • динамическая память 256 MB DDR3; • память Quad SPI Flash 32 Mb; • память EEPROM объемом 32 KB с интерфейсом 12С; • тактовый генератор с частотой 200 МГц; • 2 интерфейса 10/100 Ethernet с поддержкой Support IEEE 1588; • программатор USB-JTAG; • преобразователь USB-UART;
проектирование устройств с применением ПЛИС 479 • память 512b EEPROM объемом 512 байт; • 16 входов модуля AMS (из них 12 подключены к PMOD); • 5 кнопок, 8 переключателей, 10 светодиодов; • 6 разъемов PMOD. 8.8.4. Платы на базе Zynq-7000 Платы на базе ППСНК Zynq-7000 достаточно разнообразны, поскольку аппаратный процессор ARM дает хорошую основу для разработки широкому кругу специалистов. Для программистов удобен маршрут проектирования в виде короткого этапа подключения и настройки периферийных модулей на базе IP-ядер, после которого разработка концентрируется в SDK Eclipse. Нельзя утверждать, что это единственный маршрут, однако он позволяет привлечь больше программистов к проекту, а этот навык освоен сейчас гораздо чаще, чем навык проектирования аппаратных компонентов. Семейство Zynq- 7000 довольно популярно и обеспечивает более простое вхождение в технологию по сравнению с FPGA. Плата Xilinx ZC702 ZC702 (рис. 8.37) — первая отладочная плата на базе ППСНК Zynq-7000, разработанная компанией Xilinx. Рис. 8.37. Плата ZC702 Характеристики платы: установлена ППСНК XC7Z020 CLG484-1; динамическая память 1 GB DDR3, подключенная к процессорной подсистеме ARM; память Quad SPI Flash 16 Mb; память EEPROM 1 Кбит с интерфейсом I2C; программатор USB-JTAG; преобразователь USB-UART (подключен к процессорной подсистеме); USB OTG (подключен к процессорной подсистеме); интерфейс CAN; тактовый генератор с частотой 200 МГц; программируемый тактовый генератор 10 МГц — 810 МГц; тактовый генератор 33,3 МГц; Ethernet PHY со скоростями передачи данных 10/100/1000 Мбит/с;
480 Г л а ва 8 • выход HDMI; • 2 разъема FMC LPC (Low Pin Count); • слот для SD-карты; • 2 разъема PMOD; • 3 кнопки, 2 переключателя, 8 светодиодов. Плата Digilent Arty Z7 Digilent Arty Z7 (рис. 8.38) является еще одной разновидностью плат серии Arty, обеспечивающей доступ к ППСНК Zynq-7000. На плате установлена ПЛИС XC7Z010-1CLG400C или XC7Z020-1CLG- 400С. Отличия от других плат Arty заключаются в следующем: • Динамическая память 512MB DDR3-1050 подключена к процессорной подсистеме ARM; • вход HDMI; • выход HDMI. Рис. 8.38. Плата Digilent Arty Z7 Плата Zedboard (рис. 8.39) Интернет-ресурс www.zedboard.org предоставляет доступ не только к ресурсам проектирования, но и представляет целый набор отладочных плат на базе ППСНК Zynq. Характеристики платы: • установлена ППСНК XC7Z020-CLG484-1; • динамическая память 512 MB DDR3, подключенная к процессорной подсистеме ARM; • память Quad SPI Flash 256 Mb; • программатор USB-JTAG; • преобразователь USB-UART (подключен к процессорной подсистеме); • USB OTG (подключен к процессорной подсистеме); • тактовый генератор с частотой 100 МГц; • тактовый генератор 33,3 МГц; • Ethernet PHY со скоростями передачи данных 10/100/1000 Мбит/с;
Проектирование устройств с применением ПЛИС 481 Рис. 8.39. Плата Zedboard • выход HDMI; • выход VGA; • дисплей OLED с разрешением 128x32 пикселов; • 1 разъем FMC LPC (Low Pin Count); • слот для SD-карты; • аудиокодек с набором разъемов (линейный вход, линейный выход, микрофон, наушники); • 7 кнопок, 8 переключателей, 8 светодиодов; • разъем AMS; • 5 разъемов PMOD. Плата Microzed Плата Microzed (рис. 8.40) может работать как автономно, так и в качестве модуля, устанавливаемого на разъем несущей платы (carrier board). Характеристики платы: • установлена ППСНК XC7Z010-1CLG400C; Рис. 8.40. Плата Microzed
482 ?±1»^ • динамическая память 1 GB DDR3, подключенная к процессорной под теме ARM; Ис~ • память Quad SPI Flash 128 Mb; • слот для Micro SD-карты; • Ethernet PHY со скоростями передачи данных 10/100/1000 Мбит/с; • программатор USB-JTAG; • преобразователь USB-UART (подключен к процессорной подсистеме); • USB OTG (подключен к процессорной подсистеме); • 100 программируемых выводов ПЛИС подключены к разъемам E0 на каждом разъеме); • переключатель и светодиод; • разъем PMOD. Плата Minized Плата Minized (рис. 8.41) на данный момент представляет собой одно из наиболее дешевых решений на базе Zynq-7000, поскольку она основана на семействе Zynq-7000S с одноядерной подсистемой ARM. Также интересно наличие на плате беспроводных интерфейсов — WiPi и BlueTboth. Рис. 8.41. Плата Minized Характеристики платы: установлена ППСНК ZC7007S-1CLG225C; динамическая память 512 MB DDR3L, подключенная к процессорной подсистеме ARM; память Quad SPI Flash 128 Mb; 8 GB eMMC; программатор USB-JTAG; разъем для модулей расширения Arduino; USB OTG; Wi-Fi 802.11b/g/n; Bluetooth 4.1 plus BDR and BLE (Bluetooth Low Energy); 2 двухцветных светодиода; датчик движения и температуры LIS2DS12; цифровой микрофон MP34DT05; 2 разъема PMOD.
проектирование устройств с применением ПЛИС 483 Ряд плат, представленных на www.zedboard.org, не рассмотрены, так как они представляют собой модули формата SOM (System- on-Module) и требуют базовой платы для работы. С ними можно ознакомиться на сайте. 8.8.5. Платы на базе Kintex-7 Плата Xilinx KC705. КС705 (рис. 8.42) — одна из первых отладочных плат на базе ПЛИС серии 7. Ее нельзя отнести к недорогим решениям в абсолютном выражении, однако сочетание логического объема ПЛИС и установленных на плате периферийных компонентов делает ее мощным средством прототипирования для относительно небольших организаций. Важно, что плата является достаточно распространенной и для нее выполнено множество проектов, в том числе и свободно предоставляемых сообществу разработчиков. Поэтому, несмотря на существенно более высокую цену по сравнению с рассмотренными выше отладочными платами, КС705 имеет смысл рассматривать в качестве отладочного средства хотя бы в перспективе. W Рис. 8.42. Плата Xilinx KC705 Характеристики платы: установлена FPGA XC7K325T-2FFG900C; модуль динамической памяти 1GB DDR3 SODIMM; память Quad SPI Flash 16Mb; память BPI Flash I Gb; память EEPROM 8 kb с интерфейсом 12С; слот для SD-карты; программатор USB-JTAG; преобразователь USB-UART; тактовый генератор с частотой 200 МГц; программируемый тактовый генератор 10...810 МГц; разъем PCI Express x8; разъем FMC HPC (High-Pin Count D приемопередатчика GTX выведены на линии разъема);
484 Гл а в а 8 • разъем FMC ДРС (Low-Pin Count) A приемопередатчик GTX выведен а линии разъема); • 4 разъема SMA, подключенных к высокоскоростным последовательным приемопередатчикам GTX; • модуль SFP; • выход HDMI; • Ethernet PHY со скоростями передачи данных 10/100/1000 Мбит/с; • символьный LCD 2x16 символов; • 4 кнопки, 5 переключателей, 8 светодиодов. 8.8.6. Платы на базе Zynq UltraScale+ MPSOC В данном издании рассмотрена также одна из отладочных плат с ППСНК Zynq UltraScale+. Несмотря на то что проектирование для ПЛИС UltraScale специально не рассматривалось, архитектура логических ресурсов этих семейств в целом соответствует серии 7. Плата Ultra96 (рис. 8.43) обладает крайне интересными характеристиками и выгодным соотношением цены и предоставляемых разработчику ресурсов. Рис. 8.43. Плата Ultra96 Характеристики платы: установлена ППСНК Zynq UltraScale+ MPSoC ZU3BG А484; динамическая память LPDDR4 2 GB, подключенная к процессорной системе ARM; модуль Wi-Fi 802.11b/g/n; модуль Bluetooth 4.2; слот для SD-карты; 1 порт USB 3.0 Micro-B upstream; 2 порта USB 3.0 downstream; lxUSB 2.0 downstream; Mini Display Port; 4 светодиода; разъем с 40 выводами; разъем с 96 выводами, программатор USB-JTAG.
Проектирование устройств с применением ПЛИС 485 Для платы разработаны варианты ОС Linux, поставляемые в комплекте. С учетом того, что процессорная система Zynq является автономной, плата начинает работу с Linux даже без загруженного проекта. Также можно обратить внимание, что ПЛИС подсемейства EG содержит в процессорной подсистеме графический ускоритель Mali 400. FPGA-составляющая этой ПЛИС содержит более 150 тысяч эквивалентных логических ячеек, 360 блоков DSP48 и 7,6 Мбит памяти в В RAM. Все это предоставляет разработчику мощную аппаратную платформу в компактных размерах (85x55 мм). 8.8.7. Другие производители отладочных плат Компания Trenz Electronic (Германия) производит различные модули формата SOM с установленными ПЛИС Xilinx (рис. 8.44). В линейке продукции присутствуют практически все актуальные семейства, как серии 7, так и UltraScale. Модули требуют применения несущей платы (carrier board). Размер составляет всего 4x5 см, при этом на модуле также размещена динамическая память и подсистема питания. Размещение критических с точки зрения трассировки печатной платы компонентов делает такие модули удобными для установки на плату-носитель собственной разработки. Рис. 8.44. Модуль компании Trenz Electronic с ПЛИС Artix-7 Китайская компания MYIR производит семейство плат Z-turn board на базе Zynq-7000. Процессорные модули на базе Zynq-7000 производит также российская научно-производственная компания «Атри». Российская компания LDM Systems выпускает отладочные платы на базе ПЛИС начального уровня (CPLD, Spartan-6, Zynq-7000). Инженерный центр при КТЦ «Инлайнгруп» рассматривает заказы на разработку и производство плат и модулей на базе ПЛИС начального уровня.
486 ?^?1^ В целом дать сколько-нибудь исчерпывающий перечень акту альных отладочных плат попросту невозможно. Разработкой и Щ) изводством отладочных плат и готовых встраиваемых модулей зани мается как непосредственно Xilinx, так и сторонние производители Кроме того, не рассмотрены платы на базе ПЛИС верхнего ценового сегмента и компании, специализирующиеся на разработке и производстве таких плат. 8.9. Оценка квалификации разработчика В области информационных технологий используется разделение «junior — middle — senior», копирующее зарубежную классификацию категорий специалистов. Можно привести аналог в виде «инженер — старший инженер — ведущий инженер». Трехуровневая система оценки является достаточно эффективной и позволяет осуществлять практическое управление проектами, распределяя работы в соответствии с уровнем квалификации сотрудников. В последнее время понятие «разработчик проектов на базе ПЛИС» приобретает несколько размытые черты. Оценка квалификации специалистов — сложный процесс, который обязательно должен учитывать многоплановость самой оценки и наличие нескольких неявно пересекающихся показателей. Инженер может иметь глубокую специализацию в одной из узких областей (например, реализация интерфейса PCI Express или настройка ОС Linux для платформы Zynq). С другой стороны, при среднем уровне общих навыков можно быть специалистом в предметной области, применяя ПЛИС как инструмент реализации алгоритма или подхода. В этом случае ценность специалиста определяется не столько глубиной знаний элементной базы, сколько высокой квалификацией при разработке реализуемых алгоритмов. Наконец, инженер может не иметь узкой специализации, однако хорошо владеть инструментами проектирования, грамотно использовать САПР и знать особенности семейств FPGA для подбора наиболее эффективных схемотехнических решений. Все эти «координатные оси» не обязательно имеют явно выраженную взаимосвязь. Более того, перечисленные критерии оценки не являются исчерпывающими. Тем не менее можно предложить перечень навыков, приемов и проверяемых критериев, по которым работодатель (или сам разработчик) могут оценить уровень навыков при использовании ПЛИС Xilinx, выбрать оптимальный крут задач и обязанностей и заплацировать повышение квалификации.
проектирование устройств с применением ПЛИС 487 8.9.1. Приблизительный перечень общих навыков Предполагается, что инженер уже обладает минимально необходимыми навыками. К ним относятся знание языков описания аппаратуры (VHDL и/или Verilog), понимание маршрута проектирования, умение привязать сигналы проекта к выводам ПЛИС и выполнить загрузку конфигурации с помощью рекомендуемого производителем программатора. На начальном уровне инженер: • умеет реализовать синхронный проект; • грамотно описывает базовые проектные ограничения по времени (timing constraints); • умеет подключать IP-ядра с требуемой для проекта функциональностью; • умеет интерпретировать отчеты САПР и оценивать возможность достижения требуемых технических характеристик; • при необходимости изменяет настройки САПР в разделах синтеза и трассировки для достижения требуемых характеристик или оптимизации проекта; • может реализовать простые варианты тестов (описание внешних воздействий и наблюдение за выходными сигналами). На среднем уровне квалификации инженер: • умеет спланировать и реализовать мультичастотный проект, разделив на этапе проектирования тактовые домены и применив схемы ресинхронизации, надежно работающие в условиях испытаний на стенде; • правильно описывает проектные исключения (exceptions) для мультичастотных проектов; • выбирает и настраивает требуемые для проекта IP-ядра, умеет применять встраиваемые процессоры и подсистемы, созданные в System Generator for DSP и Vivado HLS; • подбирает настройки САПР для достижения наилучших результатов; • умеет оценивать потребление энергии, уровень шумов в высокочастотных линиях с помощью встроенных утилит САПР, при необходимости формирует рекомендации по проектированию печатной платы, подсистем питания и охлаждения; • умеет использовать утилиты САПР, предназначенные для оценки эффективности проекта и прогнозирования достижимых характеристик; • использует моделирование на системном уровне с использованием внешних файлов с входными воздействиями.
488 JLiaaa 8 На высокопрофессиональном уровне инженер: • является экспертом как минимум в одном из подразделов проек тирования на базе ПЛИС Xilinx — встраиваемые системы (включая MicroBlaze, Zynq, системы под управлением Linux), системы цифровой обработки сигналов (например, КИХ и ВИХ- фильтры, ядра БПФ, сверточные преобразования, работа с матрицами), обработка изображений и видео, высокоскоростные цифровые интерфейсы (память DDR3/4, скоростные АЦП, дифференциальные интерфейсы, модули SBRDES), высокоскоростные последовательные приемопередатчики и интерфейсы на их основе (PCI Express, SATA); • использует как временные, так и топологические проектные ограничения для достижения наилучших результатов, использует инструменты анализа, такие как отчеты по критическим цепям, умеет применять приемы оптимизации «последней мили»; • умеет проектировать на системном уровне, применяет комбинации собственных модулей на языках описания аппаратуры, IP- ядер, процессорных систем (MicroBlaze, ARM), компонентов, созданных в System Generator и Vivado HLS, оптимально выбирая частные задачи для решения с помощью наиболее подходящего инструмента; • владеет навыками технического прогнозирования и ранней оценки применимости различных семейств ПЛИС Xilinx для успешной реализации проекта; • умеет применять архитектурные методы и средства оптимизации проекта — частичную реконфигурацию, совместное планирование подключения внешних выводов и внутренних топологических ограничений, снижение потребляемой мощности путем частичного отключения тактирования неиспользуемых узлов, разделив предварительно проект на тактовые регионы; • активно применяет средства автоматизации работы САПР, такие как сценарии Tel, автоматическая генерация отчетов, перебор стратегий синтеза и трассировки; • при необходимости использует моделирование на системном уровне с привлечением моделей из предметной области, описывая в моделях сигналов эффекты «реального мира». 8.9.2. Навыки работы с проектными ограничениями Для успешного создания конфигурационного файла инженер должен уметь описывать проектные ограничения в части подклю-
проектирование устройств с применением ПЛИС 489 чения внешних выводов, что является абсолютно необходимым навыком. Кроме того, на начальном уровне необходимо описывать глобальные временные ограничения — частоту поданных извне тактовых сигналов и задержки на внешних проводниках. На практике это сводится к добавлению команд: create_clock — описывает параметры внешнего тактового сигнала; set_input_delay — задает задержку распространения сигналов для входов; set.output.delay — задает задержку распространения сигналов для выходов. На среднем уровне квалификации инженеру необходимо уметь корректно описывать проектные ограничения, связанные с мульти- частотными узлами. Команда set.clockJnteraction в САПР Vivado позволяет выявить цепи, которые выполняют переход между тактовыми доменами. Для каждой из таких цепей (возможно групповое описание) необходимо корректно описать проектные исключения (timing exceptions), уведомляющие САПР о необходимости реализации данных узлов с применением соответствующих шаблонов размещения (если возможно). Отчет, формируемый командой set_clock_interaction, является в данном случае формальным подтверждением корректности описания проектных ограничений в части частотных переходов. Он может быть использован как разработчиком для оперативного контроля, так и для стороннего контроля качества проектирования узлов, реализующих частотные переходы. На высокопрофессиональном уровне инженеру следует использовать при необходимости топологические проектные ограничения. К ним относятся привязка к определенным координатам как отдельных модулей (обычно крупных — таких, как BRAM, DSP48, MGT), так и компонентов, сгруппированных по определенному признаку. В САПР Vivado используется понятие P-block, которое позволяет объединять компоненты разных типов и устанавливать для них определенные координаты или границы, в которых разрешена их установка. 8.9.3. Навыки планирования выводов ПЛИС Некорректная работа с планированием внешних выводов может привести к неработоспособности проекта (вплоть до повреждения ПЛИС) или к невозможности достижения требуемых характеристик. Ошибки, сделанные при проектировании, могут быть исправ-
490 Гла ва лены только изменением трассировки печатной платы, поэтому инженер, работающий с ПЛИС, должен своевременно сформулировать требования к ней. К обязательным требованиям можно отнести: • трассировку цепей питания и размещение достаточного числа фильтрующих конденсаторов в непосредственной близости от ПЛИС; • подключение интерфейса JTAG и внешней флеш-памяти (или другого устройства для загрузки конфигурации); • подключение тактовых сигналов к выделенным входам ПЛИС- • распределение цифровых сигналов по банкам ввода-вывода с учетом допустимых напряжений питания и типа блока (HR/HP, т.е. High-Range или High-Performance). При необходимости, если такие компоненты используются в проекте, необходимо запланировать и учесть подключения: • опорных напряжений Vref в банках ввода-вывода; • специальных интерфейсов для высокоскоростных последовательных приемопередатчиков; • встроенных АЦП; • аппаратных контроллеров памяти DDR2/3 (для Spartan-б) и компонентов, созданных в Memory Interface Generator, с учетом возможностей банков ввода-вывода и наличия в них выделенных выводов для некоторых сигналов интерфейса памяти (например, привязка байтовых групп к соответствующему сигналу DQS). На высокопрофессиональном уровне инженер должен уметь: • оптимизировать взаимное расположение внешних выводов и модулей внутри ПЛИС, выполняющих обработку соответствующих сигналов; • выполнять разделение внутренних модулей на субблоки (Р- blocks) для устранения временных ошибок путем тонкой оптимизации размещения компонентов ПЛИС. 8.9.4. Навыки работы с инструментами проектирования На начальном уровне достаточно ограничиться использованием RTL-описаний (т. е. работы HaVHDL или Verilog) с добавлением IP- ядер, генерируемых в САПР с помощью визуальных интерфейсов. Доскональное знание языков описания аппаратуры в данном случае не является самоцелью, поскольку для разработки практических схем часто достаточно знать несколько распространенных шаблонов описаний. Вопросы по особенностям синтаксиса VHDL/Verilog,
проектирование устройств с применением ПЛИС 491 задаваемые на собеседовании, могут скорее отсеять специалистов, способных выполнять практическую работу по проектированию, но не запомнивших материал справочного характера. В данном случае для инженера важнее освоение практики применения базовых конструкций. В общем случае при собеседовании проверка знания справочных данных или «официальных» определений дает тем менее адекватную оценку специалиста, чем больший уровень квалификации у него предполагается. Практическая деятельность разработчика не предполагает постоянной работы с листом бумаги или доской для маркера. Справочная система САПР, симуляторы и методические материалы постоянно доступны при нормальной деятельности, поэтому сомнительные и справочные вопросы инженер обычно оперативно проверяет. Вместе с тем соображения архитектурного проектирования, особенно применительно к условиям конкретного проекта, являются как раз предметом инженерного творчества и не поддаются формализации, поэтому беседа о взглядах на архитектурные решения, процесс проектирования и возможные способы оптимизации проекта и обхода проблем является более адекватным способом оценить квалификацию опытного специалиста. На среднем уровне от инженера ожидается знание одного из инструментов предметной области — SDK, System Generator for DSP, HLS. Первая из систем предназначена для добавления в проект процессорных подсистем, и от инженера в данном случае ожидается не столько разработка программного обеспечения (с чем справится программист), сколько подготовка и настройка аппаратной части, подключение периферийных устройств и проведение работы по разграничению аппаратно и программно реализуемых функций. Для разработки модулей, интенсивно использующих цифровую обработку сигналов, полезен такой инструмент, как System Generator for DSP, представляющий собой подсистему распространенного пакета Matlab. Возможности по проектированию в данном случае ограничены библиотекой компонентов, однако такие модули как БПФ и цифровые фильтры могут быть очень быстро реализованы с применением данного инструмента. Навык работы в нем можно считать отдельным пунктом среди навыков специалиста, поскольку с Згчетом ограниченных библиотеками возможностей данной системы от разработчика уже на раннем этапе требуется четкое понимание того, какую именно часть проекта он сможет реализовать. Аналогичные рассуждения можно применить и для инструмента HLS, который представляет собой отдельное приложение с собст-
492 Гла ва 8 венной средой разработки, позволяющее работать в стиле «C-to- RTL». HLS имеет более широкие возможности по сравнению с System Generator и позволяет разрабатывать не только системы цифровой обработки, но и модули общего назначения, а также быстро подключать их к процессору и внешним интерфейсам. Однако такое богатство возможностей может привести к неоправданному оптимизму в ранних прогнозах, поэтому для эффективного использования данного инструмента рекомендуется иметь в коллективе специалиста с опытом работы не только с HLS как таковым, но и с ПЛИС и цифровой электроникой вообще. На высокопрофессиональном уровне от инженера ожидается работа в качестве системного архитектора, т. е. специалиста, способного комбинировать описанные подходы к проектированию и выбирать сочетание инструментов, наиболее эффективно решающее задачу проектирования системы в целом. 8.9.5. Навыки моделирования Для начального уровня достаточно обладать навыком разработки и запуска простых моделей, предусматривающих подачу входных сигналов и наблюдение за выходами проекта. Такой навык позволит резко сократить время отладки по сравнению с проведением полного цикла создания конфигурационного файла, программирования ПЛИС и наблюдения за выходными сигналами с помощью осциллографа. На среднем уровне ожидается, что инженер будет способен повысить эффективность моделирования, поскольку постоянные итерации «редактирование-моделирование» зачастую способны решить только тактические проблемы. Например, для системы цифровой обработки сигналов интерес представляет не только тот факт, что компоненты ПЛИС работают правильно, но и метрологические характеристики созданной системы. Для их получения в модели необходимо создать набор тестовых сигналов, подать их на вход устройства и не только пронаблюдать временные диаграммы на выходе, но и построить соответствующие зависимости (например, зависимость ошибки от заданного уровня помех). Кроме этого, полезным навыком является способность разработки «самопроверяющихся тестов» (self-checking testbench). В то время как синтактически корректное описание устройства может проходить моделирование, в его работе могут существовать логические ошибки. Для их выявления может быть недостаточным просто наблюдение сигналов и потребуется воспроизведение комплекса
проектирование устройств с применением ПЛИС 493 условий — порядка появления входных воздействий, установки определенных режимов работы и т. п. Простейшим примером самопроверяющегося теста является лабораторная работа в одном из учебных курсов Xilinx, в которой создается тест, посылающий набор данных в модуль UART и контролирующий прием именно этих данных. В случае несоответствия результата эталону разработанный инженером тест самостоятельно выдает ошибку в консоль программы моделирования. Умение работать на данном уровне является полезным навыком, сокращающим время на поиск и исправление логических ошибок в проекте. На высокопрофессиональном уровне от инженера может потребоваться понимание процессов «реального мира» и соответствующий уровень описания моделей. Важной особенностью работы моделей является строгое воспроизведение параметров входных сигналов именно в том виде, в котором они были описаны. Например, если подать на два тактовых входа сигналы с одинаковой номинальной частотой, то фронты тактовых сигналов, показанных в симуляторе, будут строго совпадать. В то же время в реальном устройстве частоты не могут совпадать настолько точно и в процессе работы будет наблюдаться рассинхронизация. Если устройство спроектировано так, что одновременный приход фронтов тактовых сигналов является обязательным, идеальная модель не будет способна выявить проблему. В то же время при испытаниях на базе реальной ПЛИС рассинхронизация мгновенно приведет к отклонению от ожидаемого поведения. Реальные тактовые сигналы имеют: • отклонение действительного значения тактовой частоты от номинального (например, 99,9995 МГц вместо 100); • джиттер (jitter — дрожание), проявляющийся в колебаниях положения фронта относительно номинальной величины (например, вместо номинальных 10 ns период будет составлять 9,99... ...10,01 ns); • долговременный дрейф номинального значения частоты, вызванный изменениями температуры и старением кристалла кварцевого генератора (которое, впрочем, проявляется при длительной эксплуатации и имеет существенно меньшее влияние, чем изменения температуры). Любые входные сигналы также имеют определенную вероятность сдвига на тот или иной временной интервал. Кроме того, широко известен эффект «дребезга контактов» в механических кнопках, выражающийся в формировании серии импульсов (причем ха-
494 ЕЛ^^ рактеристики этой серии будут меняться с течением времени из- за окисления контактов, изменения механических свойств упругот элемента т.д.). На более высоком уровне можно указать появлени помех в сигналах, оцифрованных с помощью АЦП, или нерегулярность прихода сетевых пакетов. Для результатов аналого-цифрового преобразования можно указать, по крайней мере, два важных воздействия, которые следует учесть. Во-первых, это сам факт наличия шумов в АЦП. Например при идеализированном представлении синусоидального сигнала в нем будут наблюдаться строго определенные и регулярные переходы через ноль, четко выраженные положения максимума и минимума, монотонное поведение сигналов в пределах полупериодов и т. д. Очевидно, это не будет соответствовать поведению реального сигнала, в котором будут наблюдаться локальные возмущения, наличие множественных максимумов и минимумов, многократные переходы через ноль и т. п. При этом на базе идеализированного представления синусоидального сигнала по результатам моделирования можно будет сделать множество некорректных предположений о допустимых способах его обработки. В качестве примера можно привести попытки измерения частоты путем подсчета числа максимумов или переходов через ноль в единицу времени. Во-вторых, даже сигнал с не вполне корректной моделью шума также может представить неверные результаты моделирования. Например, добавление к сигналу шума небольшой амплитуды от встроенного в симулятор генератора псевдослучайных чисел вероятнее всего приведет к тому, что такие шумы смогут быть эффективно устранены несложными фильтрами. В то же время реальный объект может формировать, кроме белого шума, импульсные выбросы, источником которых в современной технике могут являться множество объектов — силовая электроника, ШИМ-регуляторы источников питания, высокочастотные схемы и многое другое. Для воспроизведения подобных эффектов следует сочетать простые методы добавления помех с другими моделями шумов. Можно обратить внимание на модель засорения данных Тьюки-Хубера, которая предполагает замену заранее определенного процента цифровых отсчетов точками с совершенно другим распределением — в данном случае имитацией импульсных выбросов. Эти и другие эффекты, проистекающие из неидеальности моделей входных воздействий, необходимо уметь правильно оценивать и по возможности описывать в тестах. Можно обратить внимание, что данный навык отнесен к высокопрофессиональному уровню. Это
проектирование устройств с применением ПЛИС 495 сВязано не с повышенной трудоемкостью процесса, а с тем, что выразительные свойства языков моделирования предоставляют большие возможности для описания различных процессов «реального мира». Бессистемное моделирование с добавлением проверок на несущественные эффекты может неоправданно увеличить время, потраченное на моделирование и сделать процесс практически бесконечным, с перспективой прекращения по организационным, а не техническим, причинам (т. е., например, из-за высоких рисков срыва сроков исполнения проекта в целом). Именно поэтому для грамотного планирования набора тестов рекомендуется привлечение специалиста с большим опытом работы, который сможет составить план моделирования и оперативно идентифицировать состояние проекта, добавляя проверки при необходимости. 8.10. Учебные курсы компании Xilinx Компания Xilinx уделяет большое внимание вопросам обучения специалистов. Вопросы образования являются достаточно сложными для обсуждения, и часто разработчик рискует сделать одну из ошибок — потратить дополнительные деньги на прохождение курса, не получив требуемых знаний и навыков, или сэкономить деньги и чрезмерно затянуть выполнение проекта, заложив в корне неверные архитектурные и частные решения, которых можно было бы избежать, прослушав соответствующий курс обучения. С точки зрения компании Xilinx, существуют следующие варианты обучения: 1. Официальные учебные курсы, разработанные и утвержденные специалистами Xilinx, читаемые в специализированных учебных центрах. Слушателям курсов выдается соответствующий сертификат. Такие учебные центры также обеспечивают методическое сопровождение по программе ХРА (Xilinx Productivity Advantage). Суть этой программы заключается в приобретении у Xilinx пакета поддержки проекта, включающего отладочные платы, лицензии на САПР и IP-ядра, а также учебные курсы, облегчающие освоение ПЛИС и инструментов проектирования. 2. Курсы повышения квалификации, которые обладают полной свободой создания учебных материалов и действуют без согласования с Xilinx, самостоятельно заключая со слушателями курсов коммерческие договоры на образовательные или консультационные услуги. 3. Учебные курсы вузов, создаваемые преподавателями и сотрудниками в рамках образовательных программ. Данные курсы также создаются без согласования с Xilinx.
496 Г л а в a В России действует официальный учебный центр, ведущий o6v чение по материалам, разработанным и утвержденным Xilinx. n подробными программами курсов этого центра можно ознакомить. ся по адресу https://plis2.ru/training.html Доступны следующие курсы. Языки проектирования: 1. Проектирование на VHDL. 2. Дополнительный тренинг по VHDL. 3. Проектирование на Verilog. 4. Проектирование на System Verilog. 5. Моделирование на System Verilog. 6. Основы языка Tel. Проектирование на PPGA: 1. Проектирование на FPGA в Vivado Design Suite ч. 1. 2. Проектирование на FPGA в Vivado Design Suite ч. 2. 3. Проектирование на FPGA в Vivado Design Suite ч. 3. 4. Проектирование на FPGA в Vivado Design Suite ч. 4. 5. Инструменты и техника частичной реконфигурации. 6. Проектирование на FPGA серии 7. 7. Проектирование на FPGA UltraScale и UltraScale-h 8. Методология проектирования UltraFast. 9. Vivado для пользователей ISE Project Navigator. 10. Продвинутый курс по XDC и статическому временному анализу в Vivado Design Suite для пользователей ISE. Проектирование встраиваемых процессорных систем: 1. Архитектура системы на кристалле Zynq-7000. 2. Zynq UltraScale-f MPSOC для системных архитекторов. 3. Построение встраиваемых процессорных систем. 4. Дополнительный курс по построению встраиваемых процессорных систем. 5. Проектирование на языке С. Синтез высокого уровня в среде Vivado HLS. 6. Zynq UltraScale-f MPSOC для разработчиков аппаратной платформы. 7. Методология и среда разработки SDSoC. 8. Дополнительные курс по среде разработки и методологии SDSoC. 9. Разработка программного обеспечения для встраиваемых процессорных систем. 10. Дополнительный курс по разработке программного обеспечения для встраиваемых процессорных систем.
проектирование устройств с применением ПЛИС 497 11. Проектирование встраиваемых процессорных систем с инструментами PetaLinux. 12. Zynq UltraScale+ MPSOC для разработчиков программного обеспечения. Проектирование устройств высокоскоростной передачи данных: 1. Обзор протокола PCI Express. 2. Проектирование систем с PCI Express. 3. Проектирование интерфейсов памяти на ПЛИС Xilinx. 4. Проектирование высокоскоростных интерфейсов на базе мультигигабитовых трансиверов. 5. Проектирование высокоскоростных интерфейсов на базе мультигигабитовых трансиверов UltraScale FPGA. 6. Проектирование устройств с контроллером Ethernet MAC. 7. Целостность сигналов и проектирование печатных плат для FPGA Xilinx. Проектирование устройств цифровой обработки сигналов: 1. Проектирование устройств цифровой обработки сигналов в System Generator. Список курсов приведен в состоянии, актуальном на момент подготовки книги к изданию. Компания Xilinx периодически обновляет список курсов. В частности, всегда существуют курсы по архитектуре FPGA выпускаемых семейств. Перечень дан с целью демонстрации уровня проработки учебных материалов и широты охвата тем. Ценность обучения в небольшой группе важна тем, что слушатель получает не просто комплект методических материалов, а взаимодействует с преподавателем, получая обратную связь. Практика преподавания показывает, что довольно часто важные вопросы остаются неосвоенными даже при наличии явных описаний явления или процесса. Обеспечить корректное применение разработчиками тех или иных приемов часто можно только после нескольких контролируемых итераций объяснения материала, получения обратной связи и обсуждения практических примеров. В материалах учебных курсов (и данной книги) имеется целый ряд вопросов, объяснение которых необходимо сопровождать контролем восприятия материала и предоставлением соответствующих иллюстраций и примеров, исключающих некорректные «обходные пути». Обучение проектированию только по книгам и видеоурокам обладает теми же недостатками, что и самостоятельное обучение плаванию по видеоурокам — изучение сведений о стилях плавания и просмотр записей соревнований не поможет человеку держаться на воде. Отладочные
498 Г л а ; ___ — __ платы и самостоятельное выполнение проектов соответствует самостоятельным попыткам плавания в безопасной обстановке, а курсы с преподавателем — практическим рекомендациям и помощи квалифицированного тренера. 8.11. Старт с ПЛИС Xilinx После изучения материалов книги может возникнуть закономерный вопрос: какие же конкретные шаги может предпринять отдельный разработчик или компания, заинтересовавшиеся технологией ПЛИС как таковой и продукцией Xilinx в частности? Является ли процесс освоения ПЛИС чрезмерно затратным или требующим длительного времени с неопределенными результатами? В целом можно утверждать, что освоение ПЛИС Xilinx и использование их в своих разработках, как любительских, так и профессиональных, является достижимым и способно дать ощутимые результаты без привлечения чрезмерных ресурсов. Шаг 1. Установка САПР ПЛИС. САПР ПЛИС в бесплатной версии (Webpack) свободно загружается с сайта Xilinx и способно работать на большинстве домашних компьютеров. В данном случае не требуются финансовые затраты. САПР, в составе которого имеется встроенный симулятор цифровых систем, позволит разрабатывать проекты на языках описания аппаратуры и производить их моделирование. При отсутствии опыта проектирования рекомендуется выполнить несколько учебных проектов, а при наличии идеи собственного устройства — разработку и моделирование этого устройства или его ключевых компонентов. При этом станут понятны достигаемые характеристики по частоте, потребляемой мощности и объему ресурсов ПЛИС. Шаг 2. Приобретение отладочной платы. Если достигнутые с САПР результаты представляются положительными и перспективными, настоятельно рекомендуется приобрести отладочную плату для создания прототипа изделия и освоения того семейства ПЛИС, которое предполагается для конечного продукта. Кроме того, недорогая отладочная плата может быть использована как персональный инструмент разработчика, в том числе для домашней лаборатории. Главное отличие отладочной платы от цифровой модели — возможность проверки эффектов «реального мира». Если в модели используются идеализированные представления входных воздействий, то подключение реальных сигналов позволит проверить корректность примененных методов по захвату асинхронных сигналов,
проектирование устройств с применением ПЛИС 499 передачи сигналов между тактовыми доменами, устойчивость схемы к помехам и т.д. Наконец, немаловажным является сам факт проверки идеи на реальном оборудовании. Наличие работающего прототипа изделия, воспроизводящего основную функциональность, является серьезным шагом на пути к выпуску промышленного образца. На данном этапе финансовые затраты заключаются в приобретении отладочной платы и, возможно, какого-то периферийного оборудования, требуемого для реализации прототипа в целом. Рекомендуется обращать внимание на наличие схемы программирования непосредственно на плате или, в крайнем случае, учесть возможность приобретения недорогого программатора. Шаг 3. Непосредственная деятельность по разработке и производству. Имея САПР ПЛИС и отладочную плату, индивидуальный разработчик или компания могут приступать к реализации своего проекта. В данном случае предварительные шаги, которые можно осуществить с небольшими финансовыми затратами, могут сформировать существенные основания для полномасштабных конструкторских работ. 8.11.1. Старт для индивидуального разработчика Для индивидуального разработчика, планирующего освоение ПЛИС в качестве хобби, создания основы для получения инвестиций в качестве предпринимателя или для последующего устройства на работу, вполне достаточно бесплатной версии САПР, с помощью которой можно проводить моделирование и выполнять учебные проекты. Последующее приобретение недорогой отладочной платы (например, Cmod или Arty) позволит проверять эти идеи на практике и к тому же демонстрировать полученные результаты. Полезными применениями для ПЛИС могут стать проекты домашней автоматизации. Многие датчики и исполнительные устройства имеют исполнение в виде модулей формата Arduino или PMOD (такие разъемы есть на платах Arty). 8.11.2. Старт для учебной организации Недорогие отладочные платы на базе ПЛИС являются удобным и универсальным инструментом для обучения. Иногда отладочные платы на базе ПЛИС чрезмерно приближают в сравнении к отладочным платам на базе МК, однако для учебных целей имеются существенные отличия.
500 Г л ав а 8 Наиболее важно то, что ПЛИС компании Xilinx при использова нии в учебном процессе не следует рассматривать как «инструмеат для обучения работе с продукцией компании Xilinx». Крайне важным является тот факт, что разработка на языках описания аппаратуры является стандартным способом проектирования цифровой аппаратуры как таковой. Поэтому ПЛИС в данном случае выступают в качестве гораздо более мощной альтернативы макетным платам для дискретных компонентов. На базе ПЛИС возможно обучение по следующим направлениям (не ограничиваясь этим списком): • проектирование цифровых устройств; • цифровая обработка сигналов; • обработка изображений; • измерительная техника; • системы управления; • робототехника и мехатроника; • процессорные системы; • параллельные вычисления. Во всех перечисленных случаях ПЛИС, предоставляя возможность как сборки проекта из готовых IP-ядер, так и разработки новых элементов, выступает в качестве альтернативы макетного поля или конструктора, но вместе с тем не требует безвозвратных затрат компонентов и материалов при проведении новой итерации проектирования. Компания Xilinx поддерживает специальную программу для высших учебных заведений, предоставляя преподавателям доступ к информационным ресурсам, лицензиям на САПР и, в ряде случаев, скидкам на поставку некоторых отладочных плат. Из-за сложностей таможенного оформления поставка плат в рамках университетской программы может оказаться затруднительной в оформлении для вуза, поскольку по условиям Xilinx при предоставлении скидок требуется отправка груза непосредственно на юридический адрес высшего учебного заведения, которое обязано самостоятельно провести таможенное оформление груза. Поэтому приобретение отладочных плат чаще имеет смысл произвести на коммерческой основе. В ряде случаев преподаватели, составляющие учебную программу, завышают требования к отладочным платам. Необходимо иметь в виду, что большие ПЛИС имеют большее время на одну итерацию создания конфигурационного файла. При освоении маршрута проектирования, пока обучаемые еще делают достаточно много ошибок базового уровня, число итераций до получения работоспособного проекта может быть слишком большим и студенты просто
проектирование устройств с применением ПЛИС 501 se уложатся в отведенное для выполнения проекта время. Поэтому для учебных целей стоит ориентироваться на платы с недорогими ПЛИС малого объема, обращая внимание на возможность подключения периферийного оборудования, требуемого для учебного курса. 8.11.3. Старт для проектной организации Даже предварительные предположения о возможности применения ПЛИС ХШпх являются основанием для обращения к дистрибьютору Xilinx в России (www.plis.ru) для ранней регистрации проекта. Наличие регистрации упрощает поставку микросхем в Россию, к тому же может служить основанием для предоставления доступа к некоторым коммерческим IP-ядрам и технической поддержке. Упомянутая в разделе 8.10 программа ХРА применима для организаций при условии работы с достаточно большим предполагаемым тиражом изделий. Важно, что ПЛИС как способ организации цифровых микросхем являются не только «продукцией еще одной зарубежной компании», а инструментом прототипирования собственного изделия. Фактически после выполнения проекта у разработчика появляется принципиальная электрическая схема, описанная на языке описания аппаратуры. Эти материалы могут быть использованы (при условии адаптации) и для производства собственной СБИС, в том числе на российской технологической базе. Именно поэтому высказывание «прототип системы реализован на ПЛИС Xilinx» в чем-то похоже на «проектная документация системы в процессе разработки выводилась на монитор Samsung». В данном случае производитель монитора никоим образом не обусловливает зарубежное происхождение проекта, выполненного российскими инженерами, точно так же, как и прототипирование устройства на базе ПЛИС по сути означает выполнение проекта силами российских инженеров, a Xilinx выступает только в качестве компании, обеспечившей средства проектирования, наряду с монитором, осциллографом и паяльной станцией. Получение конструкторской документации в принципе открывает возможность продолжения разработки на базе СБИС, в том числе российского производства, поэтому применение ПЛИС на ранних этапах исследования формирует меньшую зависимость от зарубежного производителя элементной базы по сравнению с применением процессоров, микроконтроллеров или других цифровых микросхем. Можно отметить, что даже при наличии планов замены зарубежного процессора на российский аналог этап прототипирования
502 Гла. __ _____ .—___ такой микросхемы на ПЛИС является практически необходимым шагом. В этом плане не следует отказываться от аппаратной платформы, обеспечивающей доступ к языкам описания аппаратуры, которые являются стандартным инструментом проектирования микросхем. Кроме того, выпуск небольших партий изделий с применением ПЛИС обеспечивает для производителя множество положительных свойств. Организация с большой долей наукоемких работ получает возможность реализации на конфигурируемой элементной базе собственных уникальных схемотехнических и архитектурных решений. Известным свойством ПЛИС является высокая производительность в параллельных вычислениях.
Заключение За пределами данной книги осталось достаточно много вопросов, которые представляют практический интерес. Например, кратко упомянуты ПЛИС большого логического объема и особенности работы с ними. Целый ряд интересных направлений изложены в постановочном виде. Например, цифровая обработка сигналов, процессорные системы, проектирование на HLS, обработка изображений, управление в технических системах и другие темы требуют отдельных изданий даже при ограничении рассматриваемых вопросов спецификой применения ПЛИС Xilinx. История развития ПЛИС, в том числе в российской технической среде, показала, что эта технология заняла устойчивую нишу и сформировала как рынок продукции, так и технические школы. ПЛИС перестали восприниматься как экзотические микросхемы, интересные только узкому кругу специалистов, и положительным моментом является то, что конфигурируемая элементная база позволяет специалистам в полной мере реализовать имеющийся творческий потенциал. В целом читателям этой книги хотелось бы пожелать освоения продукции Xilinx в качестве «конструктора» для воплощения своих идей.
Приложение 1. Проектирование для ПЛИС Xilinx на языке System Verilog в САПР Vivado Язык System Verilog был разработан на базе языков SuperLog и Open- Vera. Затем был принят стандарт IEEE 1800-2005, а актуальной версией на настоящий момент является ЩЕЕ 1800-2009. Предпосылками к разработке System Verilog стали необходимость повышения уровня абстрагирования при описании схем, а главное — увеличение сложности моделирования и верификации проектов. Поэтому возможности System Verilog до сравнению с его предшественником Verilog развивались в первую очередь в области верификации. Поддержка System Verilog добавлена в САПР Xilinx. В текущих версиях Vivado можно использовать System Verilog для описания схем. Моделирование на System Verilog находится в стадии реализации, однако могут быть использованы программные продукты других производителей (например, Questa Sim от Mentor Graphics). Несмотря на ограниченную поддержку в Vivado, налицо тенденция к распространению этого языка и внедрению его в практику разработки наряду с VHDL и Verilog. Поэтому может оказаться полезным изучение основных возможностей System Verilog, чтобы впоследствии осознанно принимать решения о необходимости и степени его использования в новых проектах. Поддержка типов данных В языке Verilog все типы данных относятся к одному из двух больших классов: цепи (net) и переменные (variable). Они различаются тем, что состояние цепей вычисляется и обновляется непрерывно (по мере изменения входных сигналов), а переменные вычисляются и обновляются только внутри процедурных блоков. System Verilog не добавляет ничего нового к этой классификации — его типы также относятся к одному из этих двух классов. Дополнения, вносимые System Verilog в систему типов, лежат в основном в сфере моделирования. В Verilog все сигналы имеют 4 возможных состояния O/1/x/z, где 'х* относится к состоянию «не определено / неизвестно», а V обозначает состояние высокого импеданса и может иметь физическое представление в блоках ввода-вывода FPGA (но не в логических ячейках). System Verilog вводит новые типы данных, каждый разряд которых может иметь два состояния — 0/1. Это ускоряет моделирование, что особенно актуально в случаях, когда разработчику интересно поведение сложного вычислительного модуля, в котором не используется состояние высокого импеданса, а состояния «не определено» устранены корректной моделью. Можно выполнять назначение данных, представленных 4 состояниями, объектам, представленным 2 состояниями — в этом случае состояния х и z преобразуются в 0. К стандартным типам с двумя состояниями относятся int,
приложение 1 505 Типы данных Verilog и System Verilog Таблица П1 Тип shortint int longint byte bit logic reg integer time Число состояний 2 2 2 2 2 4 4 4 4 Знаковый/ беззнаковый Знаковый Знаковый Знаковый Знаковый Беззнаковый Беззнаковый Беззнаковый Знаковый Беззнаковый Разрядность 16 32 64 8 Определяется разработчиком Определяется разработчиком Определяется разработчиком 32 64 Поддержка System Verilog System Verilog System Verilog System Verilog System Verilog System Verilog Verilog Verilog Verilog shortint, longint, bit и byte. Типы Verilog и System Verilog приведены в табл. П1. Назначение типов с двумя состояниями можно понять из их преимуществ и ограничений. Моделирование с помощью таких типов выполняется быстрее, потребность в памяти вдвое меньше (что позволяет моделировать более длительные процессы), но подразумевается, что электрические конфликты и неопределенности успешно устранены на других этапах проектирования. Переменная с 4 состояниями могла бы выявить эти конфликты, выведя х в соответствующих разрядах, но с двумя состояниями подобная ошибка будет замаскирована. Поэтому данные типы предназначены прежде всего для ускорения моделирования. Тип logic подобен типу reg в Verilog. Однако reg может быть только переменной, тогда как logic может быть явно приведен к классу net. Например: logic[15:0] data; // переменная wire logic [15:0] wire.data; // цепь (net) System Verilog допускает описание новых типов данных на основе существующих. Это может быть полезно в подобных случаях: 'ifdef FAST-MODEL typedef logic Tdata; 'else typedef bit Tdata; 'endif module my_module( input Tdata[7:0] input.data, // тело модуля endmodule; В примере показано, как в зависимости от установленного (с помощью define) параметра FAST_MODEL тип Tdata определяется как logic
506 Приложение 1 или как bit. Описываемый далее модуль my .module будет использовать представления с 4 или 2 состояниями, что будет актуально при синтезе и моделировании соответственно. При этом переключение режима сводит. ся к изменению строки ^define FAST_MODEL, которая может управлять и другими модулями проекта. Перечислимые (enumerated) типы задаются пользователем в виде списка всех возможных состояний: enum reg[2:0] {IDLE = 0, SI = 1, S2 = 2, S3 = 4} fem; Использование таких типов наглядно следует из приведенного примера, где перечислены состояния конечного автомата (FSM, Finite State Machine). Синтезаторы для FPGA эффективно распознают шаблоны конечных автоматов и применяют оптимальный тип кодирования состояний. Однако для этого следует представить состояния не в виде жестко заданных констант (как это показано в примере, однако только для того, чтобы продемонстрировать подобную возможность), а в виде перечня возможных состояний, для которых синтезатор способен выбрать номера. В примере принудительно задается нумерация по принципу one hot, что эффективно для КА с малым числом состояний. Если принудительные значения в перечисляемом типе не заданы, используется нумерация по умолчанию — последовательно, начиная с 0. Возможно описание групп состояний: typedef enum bit[2:0] {IDLE, WORK[3], DONE} fsmjstates; В этом примере задается список состояний конечного автомата, включающий в себя кроме состояний IDLE и DONE набор состояний WORK0, WORK1, WORK2, WORK3. В System Verilog применяется более строгий контроль типов, чем в Verilog, поэтому в ряде случаев требуется явное преобразование типов. Оно выполняется директивой $cast или оператором «'». Кроме этого, возможно описать приведение к знаковому /беззнаковому формату и приведение к определенной разрядности: $cast(fsmjstates, IDLE) // возвращает код состояния IDLE из множества fsmjstates signed'(а) // возвращает знаковое представление переменной/сигнала а 16'E) // возвращает константу 5, записанную в 16 двоичных разрядах Для удобства работы с данными добавлена поддержка структур (struct), объединений (union) и массивов (array). Эти понятия во многом похожи на свои аналоги в языке программирования Си. Пример структуры показан ниже: struct { int a; byte b; } my .struct; // пример использования
Приложение 1 507 my .struct, a = 1; my-struct = {1, 8Ъ10} ; Описание структуры действительно очень близко к синтаксису языка Си (используется ключевое слово struct). При этом в синтезируемом коде не создается каких-то специальных связанных между собой схем, а эффект от использования структур заключается в повышении читаемости кода и его более удобной организации. Структуры схожи с массивами, однако могут содержать объекты разных типов, тогда как массив представляет собой набор объектов одного и того же типа. По умолчанию структуры не упакованы. Это означает, что отдельные элементы находятся в различных ячейках памяти. Такой подход ускоряет моделирование и упрощает доступ, однако в памяти появляются пропуски. Для упакованных структур все данные, относящиеся к структуре, хранятся в виде непрерывной последовательности. Упаковка структур задается ключевым словом packed. packed struct { int a; byte b; } my_packed_struct; Поскольку на байт отводится 8 битов, а на int — 32, такая структура будет храниться в заранее прогнозируемом виде. К элементу а можно обратиться не только по его явному имени, но и как my_paked_struct[39:8] (элемент b займет, соответственно, my_packed_struct[7:0]). Кроме этого, можно явно указать, будут элементы упакованной структуры беззнаковыми (это подразумевается по умолчанию) или знаковыми. struct packed unsigned { int a; short int b; } my_unsigned_packedjstruct; struct packed signed { int ajsigned; shortint b_signed; } my_unsigned_packed_struct; Кроме структур, в System Verilog добавлены и объединения (union). Они имеют похожее объявление, но отличаются тем, что все элементы, входящие в объединение, разделяют общую область памяти. typedef union packed { bit[31:0] data; bit[3:0] [7:0] data.array; } union.type; union_type sample_data; // sample_data.data[23:16] относится к тем же данным, что и sample_dat a. dat а ^аггау [2]
508 Приложение 1 Объединения можно пометить ключевым словом tagged. Добавление тэга (tag) означает, что вместе с объединением будет храниться цра. знак, позволяющий узнать, какой именно из перечисленных типов данных был записан в объединение последним. typedef union tagged { int a; logic[31:0] b; } taggecLunion; taggecLdata data; // объявление тэгированных данных int data_out; data = tagged a 7; // установка тэга, чтобы отразить факт записи в поле а datajout = data.a; // корректно datajout = data.b; // неверно! Тэг не совпадает с типом данных, // к которому делается попытка доступа Так же, как и Verilog, язык System Verilog обеспечивает поддержку массивов (array). По сравнению с Verilog, имеется ряд улучшений. В стандарте Verilog-95 массивы могли иметь до двух измерений, причем одно из них является упакованным, а другое неупакованным. Verilog- 2001 допускает уже несколько измерений с неупакованными данными: reg[7:0] num [1023:0] [7:0]. System Verilog допускает несколько измерений упакованных данных. Элементами массивов могут быть также структуры и объединения. Добавлены и несинтезируемые конструкции (используемые только для моделирования) — динамические массивы, ассоциативные массивы и очереди. Для доступа к параметрам массивов удобно использовать встроенные функции: $left — возвращает левый индекс; $right — возвращает правый индекс; $low — возвращает наименьший индекс; $high — возвращает наибольший индекс; $ increment — возвращает 1, если $left больше или равно Sright, и -1 в противном случае; $size — возвращает размер массива; $dimensions — возвращает число измерений массива; $ unpacked _simensions — возвращает число неупакованных измерений массива. Перечисленные функции могут быть крайне полезны при разработке модулей, разрядность данных в которых подвержена изменениям в процессе отладки и уточнения функциональности. Например, если разработчик, используя 8-битовые данные, опрашивал значение старшего разряда как data[7]t то при переходе к 16-битовым данным ему придется вспомнить, что data[7] больше не является старшим разрядом. В то же время выражение $high(data) в любом случае вернет индекс старшего разряда.
Приложение 1 509 Аналогичное назначение имеют и остальные функции. Следует стремиться к тому, чтобы описывать доступ к данным, разрядность которых может измениться, в максимально общем виде. Следующие понятия являются несинтезируемыми и могут быть использованы только при моделировании. Динамические массивы: integer dyn.arraylQ; // описание пустого динамического массива dyn_arrayl = new[5]('{l, 2, 3, 4}); // заданы первые элементы массива dyn_arrayl = new[8](dyn_arrayl); // изменяется размер с сохранением предыдущих элементов Вызов функции size() возвращает текущий размер массива. Динамический массив можно удалить деструктором deleteQ. Очереди (queue) используются для описания массивов с автоматически изменяемым размером при добавлении и удалении данных. Очереди описываются как неупакованные массивы, но используют символ $ вместо размера массива. Этот символ также указывает на конец очереди. integer a[$]; // описание очереди, размер не указывается int b[$] = {1, 2, 3} ; // очередь с начальным состоянием logic c[$:15]; // очередь с максимальным размером 16 битов а[0] = 10; // записать 10 в начало очереди а b = {b, 4} ; // добавить 4 в конец очереди b а = {};// очистить очередь а Можно еще раз подчеркнуть, что динамические массивы и очереди используются только для моделирования. Они не могут быть синтезированы, поскольку это подразумевает наличие в ПЛИС памяти заранее неизвестного объема. Операторы Основной набор операторов System Verilog совпадает с операторами Verilog (и схож с операторами языка Си). Для удобства разработчика добавлены некоторые операторы, упрощающие запись арифметических и логических выражений. Операторы являются синтезируемыми, т.е. могут описывать не только тесты, но и схему в ПЛИС. Операторы присваивания -h =, — =, *=, /=, %=, ?=, |=, ~= аналогичны используемым в языке Си. Такой формат не поддерживается в Verilog. Очевидно, что эффект от этих операторов может быть достигнут и иначе — например, А += В означает то же самое, что А = А + В. Также операторы >>=, <<= используются для логического сдвига, а >>>=, <<<= для арифметического. Добавлены и известные в Си унарные операторы ++ и —. Они обозначают инкремент и декремент соответственно. Операторы проверки с учетом символом подстановки (wildcards) используются для проверки величин, принимающих 4 состояния. Разряды,
510 приложение 1 имеющие значения z или х, успешно проходят сравнение с любым заа чением O/1/z/x. А ==? В — проверяет равенство А и В; А !=? В — проверяет неравенство А и В. Оператор inside проверяет попадание величины в указанный список Результат равен 1, если проверяемая величина присутствует в списке. a inside {[1:8]} // проверка на попадание в интервал a inside {1, 2, 4, 8, 16} // проверка на равенство одному из перечисленных значений Потоковые операторы >> и << осуществляют упаковку данных в последовательность в заданном формате. int х = {"А", "В", "С", «D»}; {» {X}} // генерирует "А" "В" "С" "D" {« byte {X}} // генерирует "D" "С" "В" "Ан {« 16 {X}} // генерирует "С" "D" "А" "В" Структуры управления Синтезируемые процедурные блоки. В языке Verilog основным процедурным блоком является always. С его помощью можно описывать как комбинаторную логику, так и синхронные схемы. Возможности этого оператора расширены в System Verilog, где добавлены три его разновидности: • always-comb используется для описания комбинаторной логики; • alwaysJf описывает синхронную (тактируемую) логику; • alwaysJatch используется для описания защелок (однако Xilinx не рекомендует применять защелки в FPGA). Если сигналам присваиваются значения внутри одного из таких блоков, то этим сигналам уже не могут быть присвоены значения вне этого блока. Это ограничение не касается обычного блока always. Использование дополнительных блоков при разработке дает ряд преимуществ: • синтезатор может провести дополнительные проверки, например предупредить разработчика, что для блока always.ff в действительности не оказалось реализовано ни одного тактируемого компонента; • упрощается построение синтезаторов и средств моделирования, ускоряется их работа; • повышается читаемость и выразительность кода, облегчается его поддержка и отладка. Процедурные блоки для моделирования. В Verilog существуют блоки initial и always, предназначенные для описания внешних воздействий, происходящих в начале моделирования (initial) и циклически в процессе моделирования (always). System Verilog добавляет к ним блок final, выполняемый при завершении моделирования. Его применение выглядит следующим образом:
Приложение 1 511 Таблица П2 Различия в организации цикла for в языках Verilog и System Verilog Verilog Переменная-счетчик в Verilog должна быть объявлена до ее использования в цикле: reg [15:0] i; for (i = 0; i <= 15; i = i + 1) Вложенные циклы должны использовать собственные переменные-счетчики для каждого уровня вложенности Автоматических переменных не предусмотрено Множественные присваивания не поддерживаются System Verilog В System Verilog объявление переменной- счетчика допустимо внутри цикла: for (reg [15:0] i = 0; i <= 15; i = i + 1) На каждом уровне вложенности можно использовать одно и то же имя переменной-счетчика, которая будет определена локально на данном уровне цикла Переменные в цикле являются автоматическими — они создаются при входе и уничтожаются при выходе из цикла Поддерживаются множественные присваивания при инициализации цикла и на шаге цикла: for (int cnt=l, j=0, done=0; cnt*j < 128; cnt++, j++) final begin // операторы, например вывод сообщения в консоль $display (" Моделирование завершено"); end Расширенные возможности циклов в System Verilog. Возможности цикла for, имеющегося в Verilog, были несколько расширены в System Verilog. Кроме этого, добавлены несколько новых вариантов циклов. Отличия между Verilog и System Verilog приведены в табл. П2. Цикл do .. while не поддерживается в Verilog. Он выглядит следующим образом: do begin // операторы end луЫ1е(<условие>) Тело цикла выполняется по крайней мере один раз. После ключевого слова while записывается условие выхода из цикла. Цикл foreach (итератор) введен для упрощения описания действий с массивами. Итератор позволяет не указывать точный размер массива, а определяет его самостоятельно, например: foreach(x[i]) // действие для очередного элемента массива хЦ Для многомерных массивов можно указывать несколько переменных — счетчиков. Можно также не указывать переменные, для которых не требуется циклическое исполнение. int a[10][20][30] foreach(i,, k)
512 /I итерации будут повторяться для первого @..9) и третьего @..29) измерений массива Операторы передачи управления расширяют возможности описания управляющих структур. К этим операторам относятся: break — досрочное завершение цикла; continue — переход к концу итерации и проверка условия продолжения цикла; return — возврат из функции/задачи. Управление шифратором приоритета в операторе case позволяет описать непосредственно в синтезируемом коде особенности поведения схемы в том случае, если возможно выполнение более чем одного условия. Ниже приведен соответствующий пример. В данном случае конкретные действия не имеют решающего значения, важнее то, что отдельные условия не перекрываются, и в любом случае будет выполнен строго один оператор. always @(*) case(operation) 2Ъ00: х = а + Ь; 2Ъ01: х = а - Ъ; 2Ъ10: х = а | Ь; 2Ъ11: х = а & Ь; endcase Модификатор priority указывает, что возможно выполнение более чем одного условия, поэтому важно учитывать порядок их описания. Первое из описанных условий будет выполнено. В качестве примера приведен оператор case, в котором условия закодированы по правилу one-hot, т.е. каждый разряд соответствует признаку «операция выбрана». При этом возможна ситуация, когда будут установлены два и более разрядов. С ключевым словом priority будет выполнена первая из строк, для которой будет найден установленный разряд. always @(*) priority case(operation) 4Ъ???1: х = а + Ь; 4Ъ??1?: х = а - Ь; 4Ъ?1??: х = а | Ь; 4Ъ1???: х = а & Ь; endcase Модификатор unique указывает, что возможно выполнение только одного из условий (по соображениям, известным разработчику). При этом выполнение одного из условий обязательно. Модификатор uniqueO аналогичен unique, но допускается отсутствие совпадений. always @(*) unique case(operation) 4Ъ???1: х = а + Ъ;
Приложение 1 513 4Ъ??1?: х = а - b; 4Ъ?1??: х = а | Ь; 4Ъ1???: х = а & Ь; endcase Функции, задачи и пакеты Функции и задачи также несколько расширены в System Verilog. Дополнительно добавлена возможность описания пакетов (package), что приближает System Verilog к возможностям структурирования проектов, имеющимся в языке VHDL. Функции (function) и задачи (task) призваны обеспечить удобный вызов многократно исполняемого кода. Они в чем-то схожи с подпрограммами в языках программирования, а разделение на задачи и функции связано с их основными особенностями. Например, все операторы функции выполняются в течение одного временного слота, а задача может включать в себя операторы wait или # (т.е., #10 описывает в задаче задержку на 10 единиц времени, а внутри функции такой оператор не может быть использован). Кроме того, функция не может вызывать задачи, но задача может вызывать функции и другие задачи. Функция, как и в языках программирования, должна вернуть единственное значение и может быть использована в качестве элемента выражения. Задача не возвращает значения и не может быть использована в выражениях. В System Verilog для функций и задач введен ряд расширений. В частности, необязательны «операторные скобки» begin .. end, поддерживаются операторы управления исполнением break, continue, return <va- lue>. Кроме того, функции в System Verilog могут и не возвращать значение (иметь тип void), не иметь ни одного аргумента, или иметь аргументы с направлением передачи out, inout. В качестве аргументов допустимы структуры и объединения. По умолчанию функции и задачи являются статическими (static). Такой тип аналогичен обычным функциям в Verilog. Однако кроме статических, существуют также автоматические (automatic) и постоянные (constant) функции. Автоматические функции создаются в момент их вызова, и требуемые ими программные ресурсы освобождаются в момент их завершения. Речь идет, конечно же, о фазе моделирования. Каждый экземпляр автоматической функции имеет собственный набор ресурсов, что позволяет, например, выполнять рекурсивные вызовы. Ниже приведен текст с описанием функции, вычисляющей факториал, которая представляет собой широко распространенный пример, демонстрирующий возможности рекурсии (хотя в реальных проектах вычисление факториала удобнее заменять таблицей значений). module demo.automatic; function automatic integer factorial (input[31:0] operand);
514 integer i; if (operand > = 2) factorial = factorial(operand-l)*operand; else factorial = 1; endfunction Функции типа constant вычисляются только на этапе elaboration (он предшествует как синтезу, так и моделированию). Приведенный ниже листинг демонстрирует пример такой функции. Она не синтезирует схему, а требуется ^,ля более удобного задания размеров памяти. В процессе elaboration значение этой функции будет вычислено и подставлено в качестве константы в RTL-описание. function integer Iog2i(input[31:0] value); begin value = value - 1; for(log2i = 0; value > 0; Iog2i = Iog2i + 1) value = value >> 1; end endfunction Еще одним дополнением является возможность передачи аргументов в функцию по ссылке {pass by reference). В этом случае в функцию передается не текущее значение аргумента, а ссылка (адрес) этого аргумента. Приведенный ниже пример показывает практические различия при передаче аргумента по значению {pass by value) и по ссылке. module demo_args; int a; initial begin #10 a = 10; #10 a = 20; #10 a = 30; #10 $finish; end task automatic pass Joy _val(int x); forever @x $display("pass.by.val: X is %0d", x); endtask task pass_by_ref(ref int x); forever @x $display("pass-by_ref: X is %0dM, x); endtask initial pass-by_val(a) initial pass_byjref(a); endmodule
Приложение 1 515 Выводом этого модуля будет: pass_by_val: X is 10 pass_by_ref: X is 10 pass_by_ref: X is 20 pass_by_ref: X is 30 Можно увидеть, что аргумент, переданный по значению, оказался напечатан только один раз, вследствие того, что в процедурном блоке initial был произведен вызов pass_by_val(a). Находящаяся внутри функции конструкция @х неспособна выявить изменения аргумента, поскольку каждый раз функция получает его текущее значение, а не «историю изменений». Напротив, при передаче в функцию ссылки на сигнал а, все изменения сигнала приводят к срабатыванию @х, и каждое присваивание нового значения приводит к вызову функции pass_by_xef. Пакеты (packages) знакомы разработчикам на VHDL и введены в System Verilog с теми же целями — создание в проекте коллекций констант, типов, функций, задач, параметров и т.п., разделенных по областям видимости. Эффект от применения пакетов можно легко сравнить с подключением файлов директивой include, которая добавляет в проект все содержимое указанного файла. package ComplexPkg; typedef struct { float i, r; } Complex; function Complex add(Complex a, b); add.r = a.r -f b.r; add.i = a.i + b.i; endfunction function Complex mul(Complex a, b) mul.r = (a.r * b.r) - (a.i * b.i); mul.i = (a.r * b.i) + (a.i * b.r); endfunction endpackage : ComplexPkg Можно непосредственно указать на расположение описанной в пакете функции: ComplexPkg::Complex cout = ComplexPkg::mul(a, b); Описанные в пакете объекты можно также импортировать в другой модуль: import ComplexPkg::Complex; import ComplexPkg: :mul; Интерфейсы При разработке сложных устройств часто используется передача с помощью групп сигналов или шин. Например, тактовый сигнал, шина
516 Приложение 1 адреса, шина данных и сигналы управления могут образовывать системную шину процессорной системы. При этом для ведущего и ведомого устройств (master и slave) направление некоторых сигналов может отличаться. Понятие интерфейса служит в System Verilog для упрощения описания таких систем. Пример описания интерфейса: interface mem-bus; logic [31:0] write_data; logic write; logic [31:0] addr; endinterface Этот интерфейс в дальнейшем можно использовать в модулях: module mem_controller( mem_bus bus; // используется ранее объявленный интерфейс input elk; // другие сигналы ); В системах с ведущим и ведомым устройствами направления сигналов могут различаться. Указать эти направления можно с помощью модификаторов (modports), например: modport master( input elk, datajread, output data.write, addr, write_enable ); modport slave( input elk, data_write, addr, write.enable, output datajread ); В показанном примере ведущее устройство является источником адреса, данных для записи и сигнала разрешения записи. В свою очередь, ведомое устройство принимает эти сигналы и возвращает в ведущее устройство читаемые данные. Указать нужную модификацию можно в формате <interface> .<modport>> например memJ>us. master. Моделирование В начале было отмечено, что повышение эффективности моделирования было основной причиной разработки System Verilog. Поэтому в языке можно наблюдать разносторонние (и не обязательно используемые одновременно) возможности описания тестовых последовательностей, структурного и объектно-ориентированного программирования и т. п. Классы (class) являются широко известным элементом объектно- ориентированного программирования. Их применение призвано решить целый ряд задач по разграничению области видимости, автоматическому управлению выделением памяти и т. д. Классы в System Verilog могут
Приложение 1 517 быть использованы для описания тестовых воздействий и моделирования. Объявление класса начинается с ключевого слова class, за которым внутри «скобок» class/endclass описываются компоненты этого класса — переменные, функции и т.д. class MyDataClass; real x; real у; int a; function MyDataClass_Fimctionl(input real a); // ••¦ endfunction endclass Программы (program) предназначены для структурирования тестов путем обобщения функционально связанных процедурных блоков. Программа может содержать: объявления данных, классов, подпрограмм и один или несколько процедурных блоков initial/ final. Программа не может содержать: процедуры always, подключаемые модули и интерфейсы. Пример программы: program mitjsome_vars(mput a, b, с); initial begin а = 0; b = 0; с = 0; end endprogram Эту программу впоследствии можно вызывать из модуля; module testmodule; //... init_some_vars init_abc(c, d, e); В описании программы используется установка в 0 переменных, описанных как формальные параметры. Однако внутри модуля в программу передаются фактические параметры с, d, e, которые и будут обнулены. Программы могут быть полезны, если в тестовом модуле требуется описывать сложные действия, применяемые к различным переменным. Блок синхронизации (clocking block) служит для упрощения описания соотношения сигналов в тактируемых компонентах. Упрощенные поведенческие модели предполагают, что сигналы изменяются мгновенно, и так же мгновенно становятся доступными для считывания последующими компонентами в цепи. Это существенно ускоряет моделирование, однако при этом программы моделирования полагаются на то, что разработчик уже обеспечил требуемые времена распространения сигналов, и они окажутся в нужное время на соответствующих входах. Однако в действительности данные, записываемые в триггер, должны присутствовать на
518 Приложение 1 входе в течение времени ?setup (время установки) до фронта тактового сигнала, и удер. п — живаться в течение времени ?hoid (время устаЕи ™ ударения У***™) *осле ФРонта (Рис« П1)- Моде- лирующие программы могут учитывать эти Рис. П1. Время установки времена только в реЖиме Post-Route, когда и время удержания в работают с физическими моделями компо- тактируемых компонентах v л нентов на кристалле. Однако в этом режиме время моделирования существенно увеличивается, и общим подходом является искусственное указание времен распространения сигналов в более быстром поведенческом (behavioral) режиме моделирования. Это не означает, что САПР впоследствии будет стараться обеспечить именно такие времена распространения при синтезе схемы, однако поведенческий режим с искусственно введенными задержками дает все же более адекватную картину, чем моделирование без задержек вообще. Блок синхронизации является примером конструкции System Verilog, упрощающей и унифицирующей такое описание применительно к тактируемым компонентам. Блок синхронизации имеет следующий синтаксис: clocking master_cb ©(posedge elk) default input #lstep output #lns; // задержки по умолчанию input #2 d; // задержка отличается от установленной по умолчанию endclocking Конструкция fork-join используется для синхронизации нескольких процедурных блоков при моделировании. Be работу удобнее рассмотреть на практическом примере. Предположим, что в блоке описаны несколько событий, происходящих в разное время: initial begin: fork begin #2 $display(MTask Iй); end begin #1 $display(HTask 2M); end #3 $display("Task 3"); join #1 $display("Common task"); end Выводом данной модели будет: Task2 Taskl TaskS Common task
Приложение 1 519 Однако, рассматривая только времена, которые установлены для функции Sdisplay, можно заметить, что вывод должен был бы происходить в другом порядке — сначала должны сработать функции, которым установлена задержка в 1 единицу времени модели. Например, Common task должно выполниться раньше, чем Taskl и Tasks. Однако порядок выполнения определяется с учетом конструкции fork-join. В данном случае fork отмечает начало нескольких параллельно выполняющихся процессов, a join заставляет программу моделирования дождаться завершения всех этих процессов. В итоге оператор задержки #1 в строке Sdisplay ("Common task") будет отсчитывать время не от начала моделирования, а от срабатывания оператора join. Другая разновидность, оператор join_any, продолжит выполнение модели при срабатывании любого из вложенных в fork процессов. Наконец, join_none определяет, что дожидаться завершения запущенных процессов не следует, а остальная часть процедурного блока может быть запущена сразу же. Генерация случайных воздействий Усложнение проектов на базе цифровых микросхем делает все более актуальным их тестирование в процессе разработки. Для систем связи или цифровой обработки сигналов невозможно выполнить полное покрытие тестами из-за огромного числа сочетаний входных воздействий. Практичнее выполнять тесты, сочетающие в себе проверки распространенных фиксированных сценариев и контролируемые случайные воздействия {constrained random simulation). Контроль случайных воздействий нужен для того, чтобы сконцентрироваться на проверке наиболее вероятных сценариев — например, при передаче текстовых файлов в формате ASCII вероятнее появление в канале связи байтов, соответствующих буквам, цифрам и знакам препинания, а не всех символов набора ASCII в одинаковых пропорциях. Поэтому разработчику было бы удобно задавать желаемые законы распределения случайных значений. В Verilog существует функция $random(), возвращающая случайное (псевдослучайное) значение. Разница между случайным и псевдослучайным заключается в способе их получения. Строго говоря, случайное значение должно быть получено из источника, который физически способен его сформировать — например, генератор на тепловых шумах. Однако программные генераторы случайных чисел существенно проще в реализации и повсеместно распространены. Они формируют последовательности, которые на самом деле являются детерминированными, но регулярность в них не прослеживается на первый взгляд, поэтому на практике они могут служить рабочим инструментом для тестирования цифровых систем. Детерминированность псевдослучайных последовательностей полезна тем, что при одинаковых начальных условиях они повторяются, поэтому становится возможным воспроизводить какой-либо редкий эффект, возникающий только при определенном сочетании входных воздействий.
520 В дополнение к $random() System Verilog добавляет функции $uran- dom() и $random_range(). Функция $urandom (unsigned random) возвращает псевдослучайное число без знака (в диапазоне 0 .. 232—-1). Фун^ ция $random_ range (max, тгп) возвращает псевдослучайное число в диапазоне min..max. Генератор случайных чисел может быть настроен вызовом функции srandom(), которая принимает в качестве аргумента целое число. Функция randomize() служит для задания случайных значений отдельным объектам. Она входит в состав пакета std. Например, следующий вызов установит две переменные в случайные значения, которые будут укладываться в допустимый для их типа диапазон. reg [3:0] rl; reg [3:0] г2; initial begin std::randomize(rl, r2); end Для этой функции хорошо проявляются дополнительные возможности System Verilog. В частности, с помощью конструкции randomize .. with можно получать достаточно мощные эффекты. reg [3:0] rl; reg [3:0] r2; initial begin std::randomize(rl, r2) with { rl < r2; rl + r2 == 4; }; end Конструкция with задает набор условий, которые должны выполняться для псевдослучайных значений. Для описанных в примере условий подходящим вариантом является rl = 1, г2 = 3. При этом теоретически возможно задать такой перечень условий, который не сможет быть выполнен. В этом случае будет сформирована ошибка. Конструкция randcase служит для формирования псевдослучайных значений с заданными весами. 6 приведенном ниже примере переменная х принимает значения 1, 2 или 3, причем частота их появления пропорциональна весам, указанным в конструкции randcase (в примере это 3, 1 и 4 соответственно). randcase 3 : х = 1; 1 : х = 2; 4 : х = 3; endcase В качестве весов можно использовать не только числа, но и выражения и даже функции:
Приложение 1 521 а = 1; b = 2; randcase a + b: x = 1; a * b : x = 2; 4 : x = 3; endcase Случайные последовательности randsequence() удобны для моделирования конечных автоматов. В примере используется автомат, изначально находящийся в состоянии sO. Из этого состояния он может сформировать последовательность si —> s2 —> s3. В свою очередь, из si возможно попасть в состояния sla, sib, а из s2 — в s2a, s2b. initial randsequence (sO) sO : si s2 s3; si : sla | sib; s2 : sla | s2b; endsequence Для переходов можно задать весовые коэффициенты, регулирующие вероятность их возникновения: si : sla := 1 | sib := 9; Модификаторы rand и randc используются совместно с переменными для указания на то, что они являются случайными. Отличия этих модификаторов в том, что randc указывает на цикличность (cyclic, откуда в его название добавлен символ «с») значений, т.е. при их присваивании значения не будут повторяться, пока не примут все возможные состояния из допустимого для данной переменной предела. Пример: rand bit[3:0] a; Модификаторы можно дополнять ограничениями: randc bit [3:0] а; constraint num_constr { а > 10; а < 15; } Ограничения, кроме обычных условий, могут описывать и распределения вероятности появления отдельных значений: constraint constr.interval { a dist { [1:5] := 10; [6:10] := 5; [11:20] := 2;
522 Приложение 1 В этом примере после ключевого слова dist заданы интервалы значений для переменной а и весовые коэффициенты для вычисления вероятности попадания в эти интервалы. Вероятность каждого интервала определится как частное от весового коэффициента и суммы всех весовых коэффициентов. Кроме коэффициента для интервала можно также определить коэффициент для каждого значения из этого интервала. В этом случае вероятность будет тем выше, чем больше значений попадают в каждый диапазон. constraint constr.each_value { a dist { [1:5] :/ 10; [6:10] :/ 5; [11:20] :/ 2; Условные ограничения определяют соотношения между выполнением одного из условий и наличием ограничения для другой величины. Например, если объявлены случайные величины а и 6, можно задавать соотношения между ними при помощи оператора импликации ->, как показано в примере: constraint impll { а == 1 -> b < 5; } Это объявление означает, что если выполняется условие «а равно 1», то для b будет назначено случайное значение, меньшее 5. С оператором импликации связан оператор solve, управляющий порядком вычисления ограничений. constraint constrl {a -> b == 0;} constraint corder {solve a before b;} Данный пример задает соотношения между а и 6 таким образом, что, как только а примет значение «истина», 6 должно принимать значение 0. Приведенный ниже пример явно задает иной порядок действий — сначала определяется случайное значение для переменной 6, и только если она равна 0, становится возможным задание для а ненулевого значения. constraint constrl {a -> b == 0;} constraint corder {solve b before a;} Обеспечение покрытия тестами Покрытие тестами является важным аспектом организации тестирования сложных проектов. Часто оказывается, что перебрать все возможные сочетания входных параметров невозможно по объективным причинам ввиду их огромного числа. Тестирование проекта с заданием всех возможных значений занимало бы время, не просто нецелесообразное с точки
Приложение 1 523 зрения сроков выполнения проекта, но и просто технически недостижимое (например, если речь идет о числе сочетаний, определяемых факто- риальными выражениями). Поэтому весьма важным является составление плана верификации с перечислением конкретных функций, которые должны быть проверены. Численной характеристикой выполнения этого плана является процент тестов, которые были проведены. Эта величины называется покрытием тестами (coverage). Формирование тестов, которые должны быть проведены, очень трудно поддается автоматизации, поскольку при этом легко получить большое число тестов, проверяющих второстепенные функции, или многократно тестирующие узлы проекта, для которых достаточно однократной проверки. Поэтому возможности System Verilog по обеспечению покрытия тестами должны сочетаться с грамотной организационной работой. Базовой конструкцией здесь является понятие covergroup: covergroup eg; endgroup eg cgJnst = new; В примере описана группа сд и создан ее экземпляр cgAnst с помощью конструктора new. Группа содержит одну или более точек покрытия (coverage point). С ними ассоциированы «корзины» (bins), которые представляют собой счетчики событий, определяемые пользователем. Увеличение этих счетчиков происходит либо явным образом путем выполнения метода sample()> либо неявно, при наступления события, определенного в covergroup. Например, следующая строка описывает подсчет изменений переменной data. always ©(data) cginst.sampleQ; Корзины могут быть определены дополнительно. Приведенный ниже пример показывает определение дополнительных корзин для подсчета числа назначений переменной my_var значений в диапазоне 0..10 и 7. covergroup var_cg @(my_var); cov_point : coverpoint my_var { bins b_0_10 = {[0:10]} ; bins b.7 = {7} ; bins others = default; } endgroup var_cg my_var_cg; initial my_var_cg = new; Для корзин могут быть определены не только статические условия для подсчета числа состояний, но и последовательности. Например, если требуется проверить попадание конечного автомата последовательно в состояния SI, S2, S3, это можно определить следующим образом:
524 Приложение 1 bins my .cycle = (SI => S2 => S3); Допустимы синтаксические выражения, упрощающие определение сложных и повторяющихся переходов. Например, A, 5 => б, 7) эквивалентно любым переходам из левой части к правой: A => 6), A => 7), E => 6), E => 7). Выражение 5[*3] соответствует трехкратному повторению значения 5 E => 5 => 5). Переменное число повторений задается следующим образом: 3[*2:4] эквивалентно любому из этих списков C=> 3), C=> 3=> 3), C=> 3=> 3=> 3). Символ -> определяет списки, в которых второе значение может появляться не сразу же после первого: 3[-> 2] эквивалентно C=> ... 3). Конструкция ignoreJbins служит для задания значений, которые не должны подсчитываться. covergroup eg; coverpoint a { ignore_bins ignore_vals = {7, 8} ; ignore_bins ignore.trans = A => 3 => 5); } endgroup Кроме игнорирования значений, их можно трактовать как ошибочные. В этом случае появление значений или последовательностей будет формировать ошибку в процессе моделирования. covergroup eg; coverpoint a { illegaLbins ignore^vals = {7, 8}; illegaLbins ignore.trans = A => 3 => 5); } endgroup Одновременное изменение двух переменных подсчитывается при указании ключевого слова cross: covergroup eg ©(posedge elk); ab : cross a, b; endgroup Для определяемых корзин можно устанавливать параметры. Их список приведен в табл. ПЗ. Свойства могут быть определены в исходном тексте на System Ve- rilog. covergroup eg; a : coverpoint a_var; b: coverpoint b.var; endgroup initial begin eg egl = new; cgl.option.comment = "This is a comment"; end
Приложение 1 525 Параметры корзин Таблица ПЗ Параметр (тип) weight (number) goal (number) name (string) comment (string) atJeast (number) detect .overlap (boolean) auto_bin_max (number) cross_num_print _ missing (number) per_instance (boolean) Значение по умолчанию 1 90 name it и 1 0 64 0 0 Описание Весовой коэффициент служит для вычисления реального покрытия тестами при проведении моделирования. Число попаданий в корзину умножается на этот коэффициент Число попаданий, требуемое для достижения цели покрытия тестами Имя, заданное пользователем (если не задано генерируется автоматически) Комментарий Минимально требуемое число попаданий в корзину Если это свойство установлено в «истину», генерируется предупреждение, если одно условие попадает в две или более корзины Максимальное число автоматически создаваемых корзин Число пропущенных (не определенных) кросс-корзин, которые должны быть сохранены и выведены в отчете При установке в «истину» статистика собирается по каждому экземпляру covergroup После сбора статистики методом sample() или по результатам определенных в группе условий, можно воспользоваться следующими встроенными методами для получения результатов: get_coverage() — возвращает значение покрытия тестами для данного типа; get_inst-.coverage() — возвращает значение покрытия тестами для отдельного экземпляра. Метод start() йачинает сбор статистики, а метод stopQ приостанавливает его. Проверка утверждений Утверждения (assertions) являются основным инструментом верификации. Они располагаются в синтезируемом коде и описывают логические выражения, которые должны выполняться. Например, следующий фрагмент кода проверяет, что некий управляющий автомат находится в состоянии «запрос» (request), когда у него имеется по крайней мере один источник сигнала req. always ©(posedge elk) if (state == REQ) assert (reql || req2) else $error("Assert for REQUEST state failed");
526 Приложение 1 clock Г"I ГЛ ГП Г Такой формат оператора assert является наи- ¦ ¦ ¦ ¦ более простым. Он совпадает с аналогичным оператором в языке VHDL. Однако далеко не всегда имеется возможность проверить функции устройства, основываясь только на выполнении логических выражений. Возможности System Verilog Рис. П2. Пример (ЛЛЯ верификации существенно расширены имен- последователь- но в час*и описания последовательностей состоя- ности сигналов ний. На рис. П2 показан пример последовательности сигналов, в которой тактовый сигнал dock вызывает появление сигналов а, Ь, с. Для рис. П2 можно записать выражение на System Verilog, описывающее показанную последовательность: а ##1 Ъ ##1 с ##1 Символ ## используется для указания задержек в тактах (а не в единицах времени, которые задаются одинарным символом #). Таким образом, приведенное выражение описывает последовательность, в которой появляется сигнал а, на следующем такте должен появиться сигнал Ь и еще через такт — сигнал с. В сложных системах возможно появление сигналов не через строго определенные интервалы времени. Например, периферийное устройство может ответить на запрос через 1 такт, но спецификация шины может допускать ответ и через 5 тактов (для медленной периферии). Такое поведение описывается выражением req ##[1:5] ack В данном случае req и ack — примеры сигналов, а не элементы конструкции. Выражение определяет, что появление сигнала ack возможно в интервале от 1 до 5 тактов после появления req. Подобные выражения (последовательности) описываются внутри конструкции, определяемой ключевым словом sequence: sequence test_seq; а ##1 b; endsequence Вместо максимального значения можно использовать символ $ (т. е. req ##[1:$]). В данном случае максимальный интервал в тактах не задается, но подразумевается, что когда-нибудь этот сигнал все же появится. System Verilog вводит дополнительные синтаксические конструкции для упрощения описания сложных последовательностей. Например, а[*3] эквивалентно выражению а ##1 а ##1 а ##1 (задается три последовательных повторения сигнала а). Выражение (а ##1 Ь)[*1:5] означает, что последовательность а ##1 b должна повторяться от 1 до 5 раз.
Приложение 1 527 Оператор -> описывает повторения состояния сигнала, между которыми возможны пропуски. Например, следующая последовательность выполнится, если в течение трех тактов сигнал а будет равен 1, причем между состояниями единицы возможно любое число пропусков (нулей). sequence seql; а[-> 3]; endsequence Для описания последовательностей можно использовать функции, работающие с событиями (аналогом является event в VHDL). $rose(<signal> [, clock_event]) — возвращает 1, когда сигнал изменился и стал равен 1 (ср. с rising.edge в VHDL); $fell(<signal> [, clock_event]) — возвращает 1, когда сигнал изменился и стал равен 0 (ср. с falling_edge в VHDL); $stable(<signal> [, clock_event]) — возвращает 1, если сигнал не изменялся в течение последнего тактового периода; $changed( <signal> [, clock_event]) — возвращает 1, если сигнал изменялся в течение последнего тактового периода; $past(<signal> [, [number_oLticks][,[expression] [,[clocking_event]]]])) — возвращает значение сигнала в момент времени number.ofMcks до текущего момента, если expression принимает истинное значение. Над последовательностями допустимы логические операции. Оператор and (логическое И) возвращает истину, когда выполнились обе последовательности, для которых вычисляется этот оператор. Последовательности начинаются в одно и то же время, и не обязаны завершаться на одном и том же такте. В отличие от этого, оператор intersect требует, чтобы обе последовательности завершались одновременно. Оператор or (логическое ИЛИ) возвращает истину, когда хотя бы одна из последовательностей находится в состоянии истины. Оператор first «match возвращает истину только в момент первого выполнения условия, заданного в качестве его аргумента. Оператор throughout (дословно — «сквозь») проверяет выполнение некоторого условия в течение всей последовательности. Например, если проверяется корректность обмена по некоторой шине, то ее спецификация может требовать, чтобы сигналы записи и чтения никогда не были в активном состоянии одновременно в течение всего времени предоставления шины этому устройству (за пределами этого интервала их значения неважны). Это можно описать следующей последовательностью: sequence check.bus_access; (req) ##[1:5] gnt ##0 ((read ~ write) throughout (grant [*4])); endsequence Приведенная запись означает, что после запроса шины (req) сигнал подтверждения доступа (gnt) должен появиться в течение 1-5 тактов. Одновременно с этим (##0) должно выполняться условие: активен только
528 Приложение I один из сигналов read и write, причем в течение четырех тактов, пока действует сигнал gnt. Оператор within проверяет нахождение одной последовательности внутри другой, т. е. вложенная последовательность начинается не ранее и кончается не позднее, чем охватывающая. Например, таким способом можно проверить, что стробирующий сигнал находится «внутри» сигнала данных. sequence check_sljs2; si within s2; endsequence Следующей конструкцией для описания логических условий и правил является свойство (property). Свойства предоставляют возможности для описания более сложных соотношений между сигналами, которые не выражаются статическими проверками. Например, с помощью оператора импликации |-> можно проверить наличие корректной реакции схемы на определенные входные воздействия. Оператор импликации внутри свойства может быть записан следующим образом: property propl(x, у) х |-> у; endproperty Если появляется сигнал х, свойство проверяет наличие вследствие этого сигнала у. Можно обратить внимание, что в описании свойства присутствуют формальные параметры, следовательно, описанные свойства могут быть многократно применены при верификации с разными наборами фактических параметров. Специальная конструкция disable iff служит для описания условия, когда свойства не должны проверяться. Обычно это условие записывается в виде: ©(posedge elk) disable iff(reset) Смыслом этой записи является исключение проверки описанного свойства в то время, пока действует сигнал сброса. В момент сброса многие соотношения между сигналами могут не выполняться, поскольку разработчик мог запланировать для них специальное поведение. Следующий пример описывает свойство, которое позволяет проверять сигналы на минимальную длительность. Проверка не производится, если активен сигнал сброса. В теле свойства записан оператор импликации, который утверждает, что при выполнении функции $rose(a) (т.е. появление фронта на сигнале а) этот сигнал должен оставаться в состоянии логической единицы не менее пит тактов. Имя сигнала и число тактов являются формальными параметрами свойства, что позволяет ниже в тесте записать вызов этого свойства для фактического параметра s и убедиться, что его длительность составляет не менее 5 тактов. property min_width(a, reset, num);
Приложение 1 529 disable iff(reset) $rose(a) |-> a[*num]; endproperty assert property (min.width, s, reset, 5); Моделирование и верификация формируют обширное поле деятельности для разработчика, поэтому без учета специфики конкретного проекта невозможно описать сколько-нибудь исчерпывающую методологию верификации. Важнее здесь то, что современные средства проектирования расширяют список доступных разработчику инструментов для выражения различных подходов и методик. Добавление языка System Verilog в САПР Vivado отражает общую тенденцию все большего распространения средств проектирования на системном уровне. В данном случае возможности System Verilog концентрируются не столько в сфере описания проектов, сколько в сфере их моделирования и верификации, что позволяет разработчикам сократить число итераций до получения работоспособного устройства, полностью удовлетворяющего спецификациям. Язык привносит ряд особенностей, характерных для языков программирования, поэтому для его эффективного использования может потребоваться дополнительное время. В целом можно отметить, что новые возможности System Verilog концентрируются прежде всего в области моделирования и верификации, поэтому освоение данного инструмента актуальнее для разработчиков, использующих ПЛИС большого логического объема.
Приложение 2. Примерный перечень самостоятельных и учебных проектов Простые проекты призваны помочь освоению маршрута проектирования, инструментов разработки и основных операций с отладочными платами. Важным является получение навыка идентификации проблем — является ли неработоспособность проекта следствием ошибок в идее схемы, ее реализации, или же это просто эффект неплотного подключения кабелей? Начало работы с любой новой технологией призвано в том числе и способствовать появлению подобного опыта, который поможет правильно выбирать следующие шаги для исправления ситуации. 1. Освоение маршрута проектирования. Реализация комбинационной схемы, ее моделирование и проверка работы с помощью переключателей и светодиодов. 2. Простая синхронная схема. Установка в проект IP-ядра тактового генератора и реализация устройства из списка: • двоичный счетчик (с индикацией на светодиодах старших разрядов); • мигание светодиода с заданной частотой (например, 1 с); • «бегущие огни» — поочередное включение светодиодов в линейке, с вариантами повторения, смены направления и скорости и т. д.; • контроллер широтно-импульсной модуляции с управлением яркостью светодиодов; • собственный вариант синхронной схемы. Примечание: установка IP-ядра тактового генератора настоятельно рекомендуется для обеспечения предсказуемой работы схемы. 3. Простая коммуникационная схема. Реализация приемника UART и индикация принимаемых данных на светодиодах. Реализация передатчика UART и регулярная посылка данных от переключателей. Разработка коммуникационной программы для ПК. 4. Простая процессорная система. Сборка процессора MicroBlaze в режиме микроконтроллера (или процессорной системы ARM при наличии ППСНК Zynq) и запуск проекта Hello, world. Кроме «Hello, world» с выводом текста на LCD или в UART, существует и «аппаратный Hello, world», заключающийся в программной реализации мигания светодиода с заданной частотой. При этом проверяется настройка GPIO, настройки таймера и общая работоспособность системы. Проекты среднего уровня. Эти проекты могут занять дополнительное время и потребовать несколько итераций отладки вследствие неверной интерпретации технической документации или появления ошибок при соединении компонентов внутри ПЛИС. 1. Вывод статической текстовой строки на LCD. Модификация проекта с подключением UART. Модификация проекта с применением софт- процессора и программной реализацией протоколов вывода текста.
Приложение 2 531 2. Реализация графического контроллера с выводом изображения на VGA или графический LCD. 3. Система сбора данных на базе софт-процессора с подключением нескольких датчиков по SPI, I2C, GPIO (в сочетаниях), программным сбором данных и отправкой по UART. 4. Простой аппаратный ускоритель для процессорной системы. Разработка компонента, подключаемого к шине AXI (с помощью сгенерированных ядер slave-контроллеров) с возможностью выполнения простой математической операции над переданными операндами и возврата на шину результата. Сложные проекты могут занять длительное время, и в то же время имеют потенциал для развития. Такие проекты подразумевают специализацию на каком-либо направлении применения ПЛИС, поэтому реализация полного списка не представляется важной. Проекты описаны в варианте постановки задачи с указанием желаемого эффекта, но без ограничения на используемые компоненты ПЛИС или инструменты разработки. 1. Спектроанализатор. Источником данных может быть внешний АЦП, микрофон, поток данных по UART или внутренний генератор, реализованный на базе таблиц или IP-ядра CORDIC. 2. Ускоритель вычислений, демонстрирующий в специально выбранном алгоритме производительность, превышающую производительность ПК, на котором была запущена САПР. Проект не подразумевает ограничений по алгоритмам. Рекомендуется реализация алгоритмов цифровой обработки сигналов или вычислений с плавающей точкой. 3. Автономный контроллер «умного дома». Плата с установленной ПЛИС принимает программу или список действий по USB-UART, USB- BlueTooth или Ethernet и управляет подключенными устройствами (освещение, будильник, полив цветов) в течение длительного времени после отключения по управляющего ПК. Рекомендуется применение нескольких процессорных ядер для демонстрации высокой суммарной производительности и автономной работы отдельных узлов. 4. Прием и обработка изображений от источника любого типа (IP- камера, CPI- или MIPI-камера) с получением высокой производительности в операциях «умножение с накоплением». Приведенными примерами не ограничивается набор проектов, который может быть использован для освоения ПЛИС. По мере повышения квалификации рекомендуется включать в процесс проектирования также технико-экономический анализ и сравнение с аналогичными по назначению аппаратными платформами.
Литература 1. https://www.xilinx.com/support.html#documentation 2. Максфилд К. Проектирование на ПЛИС. Курс молодого бойца. — М.: Издательский дом «Додэка-ХХ1», 2007. — 408 с. (Серия « Программируемые системы»). 3. Хэррис Дэвид М., Хэррис Сара Л. Цифровая схемотехника и архитектура компьютера. Учебник. — 2-е изд. — Нью-Йорк: Elsevier Inc: Morgan Kaufman, 2012. — 1676 с. 4. Джонсон Г., Грэхем М. Конструирование высокоскоростных цифровых устройств: начальный курс черной магии. Пер. с англ. — М.: Вильяме, 2006. — 624 с. 5. Джонсон Г., Грэхем М. Высокоскоростная передача цифровых данных: высший курс черной магии. Пер. с англ. — М.: Вильяме, 2005. — 1024 с. 6. Шафер Д., Фатрелл Р., Шафер Л. Управление программными проектами: достижение оптимального качества при минимуме затрат: Пер. с англ. — М.: Издательский дом «Вильяме», 2004. — 1136 с. 7. Макконнелл С, Совершенный код. Мастер-класс / Пер. с англ. — М.: Издательство «Русская редакция», 2013. — 896 с. 8. Тарасов И.В. Разработка цифровых устройств на основе ПЛИС Xilinx с применением языка VHDL. — М.: Горячая линия — Телеком, 2005. — 252 с.
Оглавление От автора 3 Введение 4 1. Начальные сведения о цифровой электронике и архитектуре ПЛИС ХШпх 6 1.1. Основы схемотехники цифровых устройств 7 1.2. Архитектуры ПЛИС SPLD и CPLD 25 1.3. Архитектура ПЛИС FPGA 26 1.4. Аппаратный состав и области применения ПЛИС FPGA 33 1.5. Логические ячейки ПЛИС FPGA 43 1.6. Блоки ввода-вывода 50 1.7. Блочная память 56 1.8. Секции DSP48 59 1.9. Тактовые ресурсы 64 1.10. Высокоскоростные последовательные приемопередатчики 78 1.11. Аппаратные контроллеры PCI Express 81 1.12. Модуль DeviceDNA 82 1.13. Модуль AMS (Agile Mixed Signal, только для серии 7) 83 1.14. Таблицы характеристик ПЛИС ХШпх 84 1.15. ПЛИС с архитектурой CPLD 87 1.16. Условное обозначение микросхем ПЛИС ХШпх 89 2. САПР ISE и Vivado — быстрый старт 91 2.1. Быстрый старт в САПР Vivado 93 2.2. Быстрый старт в САПР ISE 109 3. Язык описания аппаратуры VHDL 118 3.1. Основы языка VHDL 122 3.2. Структура модуля на VHDL 123 3.3. Соединение модулей 125 3.4. Типы данных 129 3.4.1. Скалярные типы 130 3.4.2. Композитные типы 134 3.4.3. Преобразования типов 136 3.4.4. Указатели 139 3.4.5. Файлы (указатели на файлы) 139
534 Оглавление 3.5. Операторы языка VHDL 139 3.5.1. Логические операторы 140 3.5.2. Операторы отношения 140 3.5.3. Арифметические операторы 140 3.5.4. Операторы сдвига 141 3.5.5. Операторы сцепления 142 3.6. Конкурирующие (concurrent) операции 142 3.7. Процедурные блоки 143 3.8. Управляющие структуры 145 3.8.1. Оператор if 145 3.8.2. Оператор case 147 3.8.3. Оператор with..select 149 3.8.4. Оператор for..loop 150 3.8.5. Оператор while.Joop 151 3.9. Процедуры и функции 152 3.9.1. Процедуры 152 3.9.2. Функции 154 3.10. Условная и множественная генерация 155 3.11. Организация проекта и параметризованные модули .. 156 3.12. Пакеты и библиотеки 160 3.13. Моделирование на VHDL 161 3.13.1. Основы моделирования 161 3.13.2. Использование файловых операций 168 4. Язык описания аппаратуры Verilog 170 4.1. Основы языка Verilog 170 4.2. Типы данных 171 4.3. Формат представления значений 173 4.4. Массивы 177 4.5. Порты 178 4.6. Соединение модулей 179 4.7. Операторы языка Verilog 182 4.7.1. Побитовые операторы (bitwise) 182 4.7.2. Арифметические операторы (arithmetic) 183 4.7.3. Логические операторы (logical) 183 4.7.4. Операторы отношения (relational) 184 4.7.5. Операторы равенства/тождества (equality) 185 4.7.6. Операторы свертки (reduction) 185 4.7.7. Условный оператор (conditional) 185 4.7.8. Операторы сцепления/повторения (concatenation/replication) 186 4.7.9. Операторы сдвига (shift) 186
Оглавление 535 4.8. Приоритет операторов 187 4.9. Процедурные блоки 188 4.10. Блокирующее и неблокирующее присваивание в процедурных блоках 191 4.11. Управляющие структуры 194 4.11.1. Условный оператор if/then 194 4.11.2. Оператор case 197 4.11.3. Оператор for 198 4.12. Задачи и функции 199 4.13. Организация проекта и параметризованные модули .. 201 4.14. Условная генерация 204 4.15. Моделирование на Verilog 206 4.16. Создание отчетов и сообщений 212 5. Дополнительные инструменты проектирования на базе ПЛИС 216 5.1. IP Integrator 216 5.2. Работа с процессорной системой ARM 218 5.3. Порядок разработки программного проекта в SDK ... 223 5.4. Софт-процессоры 233 5.4.1. Процессор MicroBlaze 234 5.4.2. Процессор PicoBlaze 238 5.4.3. Перспективы применения многоядерных процессорных систем в проектах на ПЛИС 240 5.5. Vivado HLS (High-Level Synthesis) 241 5.5.1. Циклы в Vivado HLS 247 5.5.2. Массивы и работа с памятью 249 5.5.3. Поддержка языков высокого уровня 253 5.5.4. Быстрый старт в Vivado HLS 254 5.5.5. Vivado HLS в сравнении с другими средствами проектирования Xilinx 262 5.6. Отладка в реальном времени с помощью приложения ChipScope 264 5.7. Заключение 267 6. Примеры реализации схем на базе ПЛИС 268 6.1. Комбинационная логика 268 6.2. Мультиплексоры 270 6.3. Арифметические операции 272 6.4. Триггеры и регистры 273 6.5. Сдвиговые регистры 278 6.6. Счетчики 280 6.7. Делители частоты 285
536 Оглавление 6.8. Таймеры 286 6.9. Широтно-импульсная модуляция 289 6.10. Модули памяти 291 6.11. Конечный автомат 298 6.11.1. Конечные автоматы Мили и Мура 302 6.11.2. Особенности описания конечных автоматов для проектов в ПЛИС 303 6.12. Контроллер UART 307 6.13. Тактовый генератор 313 6.13.1. Настройка тактового генератора 313 6.13.2. Формирование выходного тактового сигнала 316 6.14. Синхронизация асинхронных сигналов 318 6.15. Подключение SPI 322 6.16. Параллельные интерфейсы, синхронизированные с источником — АЦП и CPI 327 6.17. Интерфейс VGA 333 6.18. Планирование сигналов сброса 341 6.19. Учет наборов управляющих сигналов для серии 7 343 6.20. Умножение 344 6.20.1. Умножение с помощью компонентов DSP48 345 6.20.2. Умножение с помощью таблиц 345 6.20.3. Умножение на константу 346 6.20.4. Последовательное умножение 347 6.20.5. Реализация параллельного умножения на базе логических ячеек ПЛИС 349 6.21. Деление 351 6.22. Операции с плавающей точкой 353 6.23. Трансцендентные функции 358 6.23.1. Табличное представление трансцендентных функций 358 6.23.2. Алгоритм CORDIC 359 6.24. Вычисление экспоненты 362 6.25. Простое процессорное ядро 363 6.25.1. Представление процессора в виде конечного автомата 363 6.25.2. Проектирование простого процессорного ядра 364 6.25.3. Примеры задач для простых процессорных ядер .. 373 6.26. Фильтр с конечной импульсной характеристикой 376 6.27. Сложные для самостоятельной разработки интерфейсы 381 6.27.1. Контроллер памяти DDR3/4 381
Оглавление 537 6.27.2. USB 382 6.27.3. Ethernet MAC 382 6.28. Выводы по главе 383 7. Оптимизация проекта 384 7.1. Методология оптимизации проекта 385 7.2. Использование аппаратных компонентов 386 7.3. Правила описания синхронных схем 387 7.4. Управление настройками САПР 396 7.4.1. Настройки синтеза 396 7.4.2. Настройки размещения и трассировки (implementation) 399 7.4.3. Оптимизация проекта с помощью изменения настроек САПР 400 7.5. Анализ проекта в САПР Vivado 402 7.5.1. Анализ результатов синтеза 404 7.5.2. Анализ результатов размещения и трассировки 413 7.6. Использование проектных ограничений формата xdc в САПР Vivado для работы с ПЛИС Xilinx 415 7.6.1. Роль проектных ограничений в маршруте проектирования для ПЛИС 415 7.6.2. Проектные ограничения для закрепления выводов ПЛИС 417 7.6.3. Описание временных ограничений 419 7.6.4. Описание временных исключений (exceptions) 425 7.6.5. Описание топологических ограничений 427 7.7. Применение языка Tel для автоматизации процессов САПР Vivado 432 8. Проектирование устройств с применением ПЛИС... 434 8.1. Питание 434 8.2. Сопряжение ПЛИС с другими микросхемами 439 8.3. Загрузка конфигурации 441 8.4. Источники тактовых сигналов 448 8.5. Трассировка печатной платы и целостность сигналов 449 8.5.1. Целостность сигналов 450 8.5.2. САПР печатных плат 455 8.5.3. Особенности трассировки печатных плат для ПЛИС 456 8.6. Охлаждение 459 8.7. Организационные аспекты проектирования 462 8.7.1. Подготовительные организационно-технические мероприятия 464 8.7.2. Порядок разработки 470 8.8. Отладочные платы 74
538 Оглавление 8.8.1. Платы на базе Spartan-б (устаревающие) 472 8.8.2. Платы на базе Spartan-7 474 8.8.3. Платы на базе Artix-7 475 8.8.4. Платы на базе Zynq-7000 479 8.8.5. Платы на базе Kintex-7 483 8.8.6. Платы на базе Zynq UltraScale+ MPSOC 484 8.8.7. Другие производители отладочных плат 485 8.9. Оценка квалификации разработчика 486 8.9.1. Приблизительный перечень общих навыков 487 8.9.2. Навыки работы с проектными ограничениями 488 8.9.3. Навыки планирования выводов ПЛИС 489 8.9.4. Навыки работы с инструментами проектирования .. 490 8.9.5. Навыки моделирования 492 8.10. Учебные курсы компании Xilinx 495 8.11. Старт с ПЛИС Xilinx 498 8.11.1. Старт для индивидуального разработчика 499 8.11.2. Старт для учебной организации 499 8.11.3. Старт для проектной организации 501 Заключение 503 Приложение 1. Проектирование для ПЛИС Xilinx на языке System Verilog в САПР Vivado 504 Приложение 2. Примерный перечень самостоятельных и учебных проектов 530 Литература 532