Tags: программирование  

ISBN: 978-617-568-009-4

Text
                    Хаханов В.И. Хаханова И.В. Литвинова Е.И.
ПРОЕКТИРОВАНИЕ W ВЕРИФИ]
ЦИФРОВЫХ СИСТЕМ НА КРИСТ
SYSTEM VERII


МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ УКРАИНЫ ХАРЬКОВСКИЙ НАЦИОНАЛЬНЫЙ УНИВЕРСИТЕТ РАДИОЭЛЕКТРОНИКИ ХАХАНОВ В.И. ХАХАНОВАИ.В. ЛИТВИНОВА Е.И. ГУЗЬ О.А. ПРОЕКТИРОВАНИЕ И ВЕРИФИКАЦИЯ ЦИФРОВЫХ СИСТЕМ НА КРИСТАЛЛАХ, VERILOG & SYSTEM VERILOG Учебное пособие Рекомендовано к опубликованию Ученым Советом Харьковского Национального Университета Радиоэлектроники Новое слово 2010
ББК 32.973 2 Б81 Проектирование и верификация цифровых систем на кристаллах. Verilog & System Verilog / В.И. Хаханов, И.В. Хаханова, Е.И. Литвинова, О.А. Гузь.- Харьков: ХНУРЭ.- 2010.- 528 с. Представлены языки описания аппаратуры, регистрового (Verilog) и системного уровней (System Verilog), ориентированные на верификацию, синтез и имплементацию проектируемых цифровых изделий в современные конструктивные компоненты на кристаллах в виде System on Chip (SoC) и System in Package (SiP) Дан аналитический обзор и сравнительный анализ преимуществ и недостатков HDL-языков для создания компактных и знерюсбере- гающих цифровых систем для рынка электронных технологий В качестве источников использованы наиболее популярные зарубежные и отечественные издания, IEEE стандарты, а также работы ведущих ученых и специалистов в области Hardware Design & Testing. Показаны маршруты решения проблем синтеза, анализа и верификации миниатюрных цифровых систем путем адаптации существующих технологий проектирования и создания новых моделей инфраструктуры языковой поддержки SoC и SiP Решение задач временного тестирования и верификации цифровых изделий в кристаллах демонстрируется на основе применения средств анализа и синтеза ведущих компаний планеты путем использования IEEE стандартов геаопригод- ного проектирования и механизмов ассерций, закладываемых в проект на стадии создания системных моделей. Состоятельность структур и маршрутов проектирования подтверждена рассмотрением многочисленных примеров HDL-описания, синтеза и верификации цифровых систем в паммах, таких как память, логика и функциональные модули. Книга предназначена для студентов, аспирантов и специалистов в области технологий HDL-проектирования и компьютерной инженерии встроенных систем и сетей, а также для широкою круга читателей, занимающихся разработкой и тестированием Hardware/Software для SoC и SiP Рис. 203. Табл. 57. Библиогр.: 77 назв. Рецензенты. ВП Тарасенко. д-р техн наук, проф. Национальною технического университета "КПИ" (i. Киев) В С Харченко, д-р техн. наук, проф Национальною аэрокосмического университета "ХАИ'' 0. Харьков) А В Дрозд, д-р техн. наук, проф Одесского Национального технического университета (г. Одесса) ISBN 978-617-568-009-4 © В.И. Хаханов, И.В. Хаханова, Е.И. Литвинова, О.А. Гузь, 2010
3 ВВЕДЕНИЕ Необходимость издания учебною пособия обусловлена повышенным интересом Hardware индусгрии и студенческой аудитории к языкам проектирования энергосберегающей, компактной и специализированной цифровой аппаратуры на основе SoC и SiP. Временные затраты аппаратной реализации проекта уже практически равны периоду создания аналогичного программного продукта. В последние годы различие time-to-market для Software и Hardware Design исчезает благодаря технологическим достижениям в нано- элекгронике силиконовых кристаллов и автоматизации процессов проектирования изделия на всех его стадиях (Gate level, RTL, System level) Как следствие, компьютерная и программная инженерия все более интегрируются на поле взаимных интересов, связанных с созданием компонентов SoC и SiP, и взаимно обогащаются своими методологиями, образуя Software/ Hardware Codesign или Electronic System Level (ESL) Design. Реализация идеи - в железо или программу - зависит от ее рыночной привлекательности, формирующей метрику проекта, быстродействие или i ибкость, специализация или универсализация, миниатюрные или дециметровые размеры цифровой системы, высокое или низкое энергопотребление. Выбор в сторону аппаратуры влечет промышленное использование аппаратно ориентированных и системных языков, таких как Verilog и SystemVenlog Тем не менее, среди студентов существует психологический барьер на пути к аппаратной реализации интересных для рынка функциональных решений, который авторы книги, по мере возможности, хотели бы устранить. Цель издания - предоставить читателю технологии проектирования, синтеза и верификации специализированных и миниатюрных компьютеров на основе индустриально-ориентированных языков Verilog и SystemVerilog за время, соизмеримое с периодом создания программного продукта Для достижения цели рассматриваются два языка описания аппаратуры: Verilog и SystemVenlog. Они не сложнее Software языка программирования C++ и во многом с ним сходны, но имеют и положительные отличия Языки описания аппаратуры ориентированы на существенное уменьшение времени верификации проекта на системном уровне (SystemVenlog), параллелизм и высокое быстродействие реализации функциональности на кристалле. Отличие данной книги от существующих издании: 1) Предоставление новейших технологий Design & Test для новых конструктивов SoC и SiP. 2) Сравнение и анализ возможностей всех языков описания аппаратуры для проектирования, тестовой и временной верификации цифровых систем на кристаллах. 3) Компактность и структурированность изложения материала с внедрением в текст англоязычных терминов. 4) Многообразие примеров HDL-описания, верификации, синтеза и анализа реальных цифровых компонентов 5) Использование минимального количества наиболее популярных зарубежных источников по проектированию и верификации цифровых сие-
4 тем, а также опыта чтения курса Hardware Design Automation в Харьковском Национальном университете радиоэлектроники Сущность издания - на фоне вентильной мощности силиконового кристалла, составляющей до 700 млн. транзисторов, показать пути системного и RTL- проектирования, тестовой и временной верификации, а также синтеза функциональных модулей на основе языков System Venlog и Venlog с использованием IEEE сшндартов тестопригодного проектирования и новейших ESL Design технологий. В общем случае системный подход означает использование языков описания аппаратуры: VHDL, Verilog, System С, System Verilog, UML, PSL, SVA, OVA; системного программирования- Сь+, Assembler, С, Web-дизайна - HTML, Flash, Java, .Net; Internet программирования: PHP, ASP, JSP, Java, .Net, C#; программирования баз данных- С#, Java, .Net. Тем не менее, авторы остановились на двух языках: System Verilog и Verilog, которых вполне достаточно для эффективного создания Hardware/Software компонентов SoC и SiP. Также в книге нашли отражение интересные, с точки зрения авторов, конструктивные решения в виде различных типов SoC и SiP, которые читатель должен видеть в качестве игога своих проектных работ при синтезе функциональных компонентов и цифровых систем. Структура издания представлена 5 частями, 24 разделами и 204 подразделами, в которых отражены: 1) Новые технологии и конструктивы для размещения цифровых систем в пакетах, а также модели системной верификации проектов на основе механизма ассерций. 2) Язык Venlog - для описания и синтеза функциональных компонентов и инфраструктуры диагностического обслуживания цифровых систем на основе IEEE I500 стандарта, testbench- технологий. 3) Язык System Verilog - для описания спецификации функцио- нальностей SoC и верификации проекта на основе использования testbench и ассерпионной избыточности 4) Временная верификация - рассматривает технологии синхронизации, моделирования и устранения состязаний в современных цифровых системах Все разделы включают практически ориентированные приложения, примеры синтеза, анализа и верификации цифровых компонентов. Вопросы и задания, представленные в конце каждого раздела, покрывают знания и умения, освещенные в нем Наиболее существенными и актуальными, с точки зрения авторов, задачами в области изучения и применения HDL-языков являются: 3) Классификация и различия синтаксических и семантических особенностей языков описания аппаратуры для проектирования SiP и SoC. 2) Системное описание иерархической инфраструктуры сервисного обслуживания цифровых систем в пакетах на основе IEEE стандартов тестопригодного проектирования в качестве дополнения к основной функциональности. 3) Разработка и описание системных моделей и технологий для тестирования, верификации и исправления ошибок в HDL-коде. 4) Эффективное использование системных библиотек ведущих компаний для верификации и синтеза цифровых изделий и компонентов SiP- память, логика, программные и управляющие модули.
5 ЧАСТЬ I. ПРОЕКТИРОВАНИЕ 1. ТЕХНОЛОГИИ РЕАЛИЗАЦИИ И ВЕРИФИКАЦИИ ЦИФРОВЫХ СИСТЕМ 1.1. Аппаратные средства для разработки цифровых систем Основная цель Hardware/Software Design and Test - предоставить широкому кругу пользователей технологии создания миниатюрных, специализированных, экономичных, мобильных и быстродействующих цифровых изделий, востребованных в мире. Внедрение или продвижение новых средств на рынке электроники начинается с апробации любого метода или алгоритма в системном исполнении кода в HDL-языках После достаточно полной верификации проект может быть выставлен на рынке в виде IP-core, что гарантирует авторские права разработчика. Следующим этапом может быть имплементация IP-core в кристалл профам- мируемой логики, что позволяет существенно повысить быстродействие, оставляя возможность перепрограммирования отдельных функций в процессе доработки, выявления и исправления ошибок. Исключительность технологического решения и рыночная привлекательность являются критерием для его имплсмен гации в кристалл ASIC. В этом случае быстродействие реализованной системы становится максимальным, но здесь уже невозможно исправлять ошибки, поэтому проект должен быть идеально корректным. Гаким образом, продвижение новой техноло! ии на рынке связано с эволюцией проекта от Software к Hardware (Hardwanng), который становится менее гибким для модификации, но более производительным для решения проблемы. Что касается кристаллов ПЛИС, то они предоставляют разработчикам новые возможности для проектирования быстродействующих специализированных встроенных цифровых систем. Доказательством перспективности программируемой логики служит появление новых, имеющих более совершенную архитектуру, поколений ПЛИС со встроенными процессорами и возрастание объема их выпуска ведущими зарубежными производителями. Анализ тенденции развития архитектур программируемой логики дает основания утверждать, что в ближайшее время основу элементной базы цифровых (ре- конфигурируемых) систем будут составлять CPLD, FPGA, HardCopy, догоняющие по производительности и стоимости ASIC, но не требующие затратной тестовой и верификационной методологии для обеспечения массового производства микросхем. На рынке электронных технологий существует причинно-следственная связь между тремя основными компонентами, влияющими на компьютерную продукцию. Это прежде всего - технология изготовления силиконовых пластин для кристаллов, типы предлагаемых на рынке чипов (микросхем) или кристаллов, языки описания цифровой и аналоговой аппаратуры и программных продуктов, EDA-средства для проектирования систем и сетей на кристаллах.
6 Учитывая, что каждый из трех основных типов кристаллов (PLD, ASIC, CPU) имеет недостатки, производители стараются уменьшить их влияние, объединив достоинства. Так появляются на рынке интересные комбинации: {PLD + ASIC} - Lucent Technologies (OR3TP12), Quick Logic (RAM, PCI, DSP), Cyprus Semiconductor (PCI), Altera (Stratix), Xilinx (Virtex® II-VI, Spartan® 4-6). Далее интегрируются такие компоненты как {PLD + CPU} - Atmel (FPSLIC), Triscend (E5, A7), Xilinx (Virtex II Pro), Altera (Excalibur), {ASIC + CPU} - микроконтроллеры, {PLD + ASIC + CPU}, которые интегрируют быстродействие ASIC, перепрофаммируемость PLD, гибкость и управляемость CPU. Пример, иллюстрирующий последние достижения функциональных возможностей PLD, приводится в табл. 1.1, которая предоставляет широкую палитру встроенных функциональностей или инструментов современным разработчикам [1]. Таблица 1.1. Характеристики кристаллов семейства Spartan®-6 Кристалл FPGA ХС 6SLX4 6SLX25 6SLXI50 6SLX25T 6SLX1501 Ячейки 3 366 23 770 147 456 23 770 147 456 Логические блоки Slices 526 3 714 23 040 3714 23 040 RAM,Kb 32 228 1358 228 1358 DSP 48AI 4 38 182 38 '82 Блоки RAM Kb 8 52 268 52 268 Max 144 936 4 824 936 4 824 Размер/l tlai выводов, мм 20x20/0,5 13x13/0,8 23x23/1,0 23x23/1,0 23x23/1,0 Семейство кристаллов Spartan®-6 оптимизировано для их применения в изделиях массового производства и обеспечивает широкие возможности при относительно низкой стоимости микросхем. В него входят два подсемейства, включающие 11 кристаллов плотностью от 3 400 до 148 000 логических ячеек с уменьшенным в два раза энергопотреблением, высокоскоростными и более гибкими трассировочными ресурсами. Подсемейство LX ориентировано для выполнения логических функций. LXT - для реализации высокоскоростных последовательных интерфейсов. Кристаллы семейства Spartan®- 6 выполнены по отработанной 45-нм КМОП технологии, позволяющей установить оптимальный баланс между стоимостью, мощностью и производительностью. В них используются новые, эффективные логические ячейки с шестивходовыми таблицами преобразования (Look-up Tables - LUTs) и двумя триггерами. Логические ячейки объединяются парами в секции (slices). Каждый конфигурируемый логический блок CLB содержит 4 таблицы LUT и 8 триггеров (2 секции). Имеется большой выбор встроенных блоков системного уровня (аппаратных ядер). Block RAM имеет память емкостью 18 кбит, который может быть сконфигурирован как два блока по 9 кбит. Второе поколение блока цифровой обработки сигналов DSP48A1 состоит из 18x18 умножителя, 48-битового аккумулятора, предсуммагора и регистров для конвейеризации, которые могут функционировать с частотой 250 МГц. SDRAM контроллеры памяти обеспечивают полосу пропускания до 12,8 Гбит/с. Имеется улучшенный блок управления и синтеза сигналов синхронизации (Clock Management Tile, CMT). Кристаллы обеспечивают поддержку
7 SelectIO™ технологии и содержат высокоскоростные GTP приемопередатчики с оптимизацией энергопотребления, а также встроенное оконечное устройство для PCI Express™. Также имеются усовершенствованные режимы управления питанием, автоматического определения конфигурации и усиленная защита проекта от несанкционированного доступа с использованием алгоритма шифрования конфигурационной последовательности AES и технологии Device DNA. Семейство кристаллов Virtex<E>-6 оптимизировано для использования в высокотехнологичной ашарагуре, характеризуется улучшенными свойствами и обеспечивает наибо.) ее широкие возможности на рынке FPGA. Применение инновационной архитектуры ASMBL™ (Advanced Silicon Modular Block), базируемой на колонках модульных логических блоков, позволило создать различные платформы (подсемейства), нацеленные на различные области применения (домены). Каждый домен включает набор приложений, разделяющих общие ресурсы, такие как высокоэффективная обработка сигналов, встроенный процессор, высокоскоростные межсоединения (рис. 1 1). Рис 1 I Многообразие платформ для различных областей применения Пользователь может выбрать платформу с оптимальным сочетанием функциональных возможностей и параметров для создания специализированной системы на кристалле. ASMBL™ архитектура позволяет реализовать технологию монтажа методом перевернутого кристалла (flip-chip) и устранить ограничения, связанные с особенностями традиционного проектирования кристаллов, например, зависимость между количеством выходных контактов и размерами матрицы. Архитектура также дает возможность устранить более жесткие ограничения на размещение цепей питания и заземления на кристалле. Как следствие - значительно уменьшается время разработки проекта, его стоимость и увеличивается надежность FPGA. Два подсемейства LXT и SXT включают 9 кристаллов различной логической ёмкости. LXT оптимизировано для выполнения быстродействующих логических операций и реализации высокоскоростных последовательных интерфейсов. Кристаллы SXT, прежде всего, ориентированы на выполнение быстродействующих операций цифровой обработки сигналов Высокая про-
8 изводительность логических ячеек обеспечивается использованием шести- входовых таблиц LUT, дополненных сдвоенным триггером FPGA семейства Virtex®-6 содержат широкий спектр встроенных блоков (аппаратных IP- ядер), позволяющих создавать законченные решения системного уровня. Block RAM - блок памяти емкостью 36 кбит можно сконфигурировать как два блока по 18 кбит. Он гакже может функционировать как FIFO и имеет встроенные ресурсы определения и исправления ошибок Третье поколение блока цифровой обработки сигналов DSP48E1 состоит из 25x18 умножителя, 48-бит-ового аккумулятора, предсумматора и регистров для конвейеризации. Блок может работать на частоте до 600 МГц Кристалл поддерживает SelectIO™ технологии с цифровым контролем импеданса и имеет также блок управления и синтеза сигналов синхронизации ММСМТ. System Monitor ориентирован на выполнение функций снятия характеристик чо напряжению питания, температуры внутри кристалла и на внешних микросхемах. В кристалле также имеются GTX - 6,5 Гбит/с приёмопередатчики, модуль PCI Express с поддержкой 8-lane Genl (2,5 Гбит/с) и 4- lane Gen2 (5,0 Гбит/с), ТЕМАС - 10/100/1000 Мбит/с Ethernet контроллер Напряжение питания ядра 1В (0,9 В - экономичный режим). Перечисленные средства позволяют достичь наиболее высокого уровня производительности и функциональности в цифровых системах, реализованных на основе FPGA. Выполненные по 40-нм КМОП технологии, кристаллы FPGA семейства Virtex®-6 являются реальной альтернативой технологии ASIC. Virtex®-6 FPGA представляет собой наилучшее решение для объединения возможностей высокопроизводительной логики, цифровой обработки сигналов в цифровой системе на кристалле. Характеристики отдельных кристаллов семейства Virtex<K>-6 приведены в табл. 1 2. Семейство FPGA Stratix® IV [2] компании Altera выполнено по 40-нм технологии и по своим возможностям превосходит существующие аналоги. Кристаллы характеризуются плотностью логических элементов, наибольшим количеством приемопередатчиков, наименьшим энергопотреблением (на 50% ниже, чем у аналогичных устройств FPGA, благодаря использованию технологии программируемого энергопотребления - Programmable Power Technology). FPGA Stratix® IV предназначены для реализации беспроводных и DSP приложений, требуюших высокой производительности. В состав семейства Stratix® IV входят 3 подсемейства, оптимизированные для выполнения различных функций: Stratix IV GX - ориентированы на прием и передачу информации, содержат до 531 200 лог ических элементов, до 48 полно- дуплексных приемопередатчиков, функционирующих на основе технологии синхронного восстановления данных (clock data recovery, CDR) и обеспечивающих скорость передачи до 8,5 Гбит/с; Stratix IV Е (Enhanced) - интерфейсы памяти, содержат до 681 100 логических элементов, до 27 376 Кбит встроенной памяти RAM и до 1 024 встроенных умножителей 18 х 18 биг; Stratix IV GT - оптимизированы для скоростного приема-передачи инфор-
9 мации, содержат до 531 200 логических элементов, до 27 376 Кбиг памяти RAM, до 1 228 встроенных умножителей 18x18 бит (табл. 1.3). Последовательные приемопередатчики поддерживают скорость передачи данных от 2,488 до 10,3125 Гбит/с. Устройства Stratix IV GT можно разделить на две группы в зависимости от скорости передачи данных на входе/выходе - 100/40 Гбит/с, которые содержат соответственно 48 (36) полнодуплексных CDR приемопередатчиков, 24 (12) из которых поддерживают скорость 10,3125 Гбит/с. Габариты кристаллов находятся в пределах от 35 до 43 мм Таблица 1.2. Характеристики кристаллов семейства Virtex®-6 Кристалл F-PGA ХС 6VLX75T 6VI Х240Т 6VLX550T 6VSX315T 6VSX475 Г Ячейки 74 496 241 152 549 888 314 880 476 160 Логические блоки Shoes 11640 37 680 85 920 49 200 74 400 RAM Kb 1045 3 650 6 200 5 090 7 640 DSP 48A1 288 768 864 1344 2016 Блоки RAM 18 Kb 156 416 720 704 1 064 Max Kb 5616 14 976 25 920 25 344 38 304 Выводов 23/240 29/400 42,5/840 42,5/720 42,5/840 Таблица 1.3. Характеристики кристаллов семейства Stratix® IV КрИСТАГП ЬР 4SGX70fF1152) 4SGX290(F1517) 4SGX530(F1932) 4SE110(F780) 4SE360(ril52) 4SF680(F1750) ''"и" 29 040 116 480 212 480 42 240 141440 272 440 Логические 72 600 291 200 53! 200 105 600 353 600 681 100 Память, Кбит 7 370 17 248 27 376 9 564 22 564 31 491 Встроенные умножите™ 364 832 1 024 512 1040 1 360 Входов/ 480 736 904 480 736 1.104 1.2. Технологические конструктивы цифровых систем Представлены основные современные конструктивы, используемые для создания цифровых систем для рынка электронных технологий в порядке возрастания их сложности. Показаны проблемы, подлежащие решению в части сервисного диагностического обслуживания функциональных блоков 1.2.1. Система на кристалле - System on Chip (SoC) - специализированное цифровое изделие, конструктивно исполненное на силиконовом кристалле (рис. 1.2), характеризуемое низким энергопотреблением, малыми размерами, высоким быстродействием и имеющее следующие компоненты: процессор (CPU), память (RegM, ROM, SRAM, DRAM), логику (UDL), интерфейс ввода-вывода (I/O, PCI, UART, USB, CAN), преобразователи информации (ADC, DSP, MPEG), шины обмена данными и инфраструктуру (I-IP) сервисного обслуживания на основе стандарта IEEE 1500 и технологии JTAG. Функциональные блоки SoC ориентированы на эффективное решение актуальной проблемы, в отличие ог микроконтроллера, представляющею универсальный вычислитель практически любой задачи. Преимущества SoC: прозрачность относительно всгроенных деструктивных компонентов; высо-
кая производительность при низком энергопотреблении; миниатюрные размеры; эффективное использование различных типов памяти, высокая надежность; низкая стоимость готового изделия и высокий коэффициент использования функциональное гей. Плата за описанные преимущества: существенное время тестирования и верификации проекта (70% от периода проектирования); высокая стоимость разработки и макетирования; сложность отладки и производства; интеграция IP-cores (интеллектуальной собственное!и) из различных источников. ,1 I/O j PCI UART j USB ] i UDL CPU DSP к\РЩ\ iLJ L—1 LJ !—Ij j JTAG MP j ADCI CAN lL_J_ 1 \ I 1 1 Jj ROM Рис 12 Современная структ>ра5оГ IP-Core - сложный уже протестированный, верифицированный и оптимизированный функциональный модуль, который может быть многократно использован в качестве компонента при проектировании более сложных цифровых изделий в целях сокращения времени их разработки [3]. Использование iP-Cores дает: 1) существенное уменьшение времени до момента появления цифрового изделия на рынке; 2) упрощение процесса проектирования путем создания интерфейса для связи системы с IP-Core. 3) минимизация риска проектирования благодаря включению уже отлаженных модулей; 4) уменьшение времени верификации всей системы. Области применения SoC: конфигурируемые специализированные открытые репрограммируемые изделия, индивидуальные специализированные миниатюрные серверы, ориентированные на конфиденциальность вычислительных процессов и хранение информации под защитой аппаратного ключа, интеллектуальная RAM; архитектуры для сотовых телефонов; мультимедийные, беспроводные и телекоммуникационные функциональности, нейронные, аналоговые и квантовые вычислители. Особый интерес рынок проявляет к появлению индивидуальных серверов на кристалле, которые ориентированы не только на конфиденциальное хранение информации, но и на защищенность вычислительных процессов от несанкционированного доступа. Подключив сервер размером чуть более Flash Memory к порту USB персональ-
11 ною компьютера, пользователь выполняет характерные для его профессиональной деятельности вычисления, сохраняя их затем на сервере Таким образом, микросервер на кристалле можно рассматривать как защищенную карту Flash Memory с расширенными функциями, ориентированными на выполнение пользователем профессиональных обязанностей Актуальность такой концепции подтверждается также низким коэффициентом использования универсального персонального компьютера, равным 5-10 % Существующие проблемы: i) Уменьшение стоимости изготовления SoC кристаллов путем увеличения выхода годной продукции. 2) Сокращение периода появления готового изделия на рынке (time-to-market) и уменьшение жизненного цикла готового изделия. Если каждые 18 месяцев меняются технологии, то срок эффективной службы изделия (3-4 года) нужно уменьшать, приближая его к 2 годам. В этом случае компании, по меньшей мере, будут на волне использования высокотехнологических продуктов, что означает и привлекательность собственной продукции для мировою рынка. 3) Рассматривая традиционные решения для достижения эффективного выхода i одной продукции на временной оси (15 месяцев), можно сделать следующий вывод: продукт, который разрабатывается более 15 месяцев (time-to-market), на рынок никогда не попадет. Сокращение данного периода (сдвиг кривой влево по оси абсцисс), равно как и уменьшение числа ошибок проекта (поднятие кривой вверх по оси ординат), гарантирует высокую рыночную привле- ка(ельность, а значит - дополнительные доходы для компании Заботиться о качестве и надежности изделия следует, начиная с системной стадии проектирования 1гутем создания новых и эффективных методов и средств тестирования и верификации, оптимизирующих процессы, которые относятся к этапу Design for Manufacturability. Yield Learning Curve показывает резервы для увеличения производства цифровых изделий (production ramp up), особенно путем внедрения технологий диагностирования и отладки итерированных в 1-IP. Чрезвычайно важной здесь представляется имплементация стандартов тестоприюдности в проект для встроенного тестирования, диагностирования и ремонта, которые существенно повышают выход годной продукции, даже при наличии дефектов на кристалле [4J. 1.2.2. Сеть на кристалле - Network on Chup (NoC) - специализированное мультиядерное цифровое изделие конвейерного типа, обладающее всеми свойствами системы на кристалле, дополненное интеллектуальной структурой коммуникаций, поддерживающей все архитектуры и уровни протокола параллельного обмена данными офисной сети. В качестве ядра выступает IP-core (процессор или блок памяти), который организуется в масштабируемые сегменты. Такой иерархии ставится в соответствие двухуровневая система коммуникаций и конвейеризации Поддержка всех уровней протокола обмена данными обеспечивает высокое быстродействие и пропускную способность информационных каналов Наличие интеллектуальных мультиядерной архитектуры и коммутаторов обеспечивает вы-
12 сокий уровень распараллеливания вычислительных процессов и приема/передачи данных. Наиболее распространенные архитектуры представлены на рис i 3' а - сеть или матрица, как правило, одинаковых процессоров, соединенная числом коммутаторов, равным количеству ядер; b - блочно- функциональная сегментация двухуровневой иерархии сети: с - многоугольная звезда, ориентированная на эффективный обмен данными между процессорными парами; d - нерегулярная структура двухуровневой иерархии, ориентированная на обслуживание процессоров различных приоритетов и функциональностей. Q- functional coie о swiMi (а) (Ь) (с) (d) Mesh BFT Octagon Irregular Рис 13 1иповыссф>кт>ры\оС Типичная система на кристалле имеет сегодня !5-20 (IP-cores) функциональностей Это порог ее сложности и практического применения Далее следует зона эффективного использования сети. В отличие от SoC кристалл NoC имеет многоуровневую архитектуру Как и глобальная (локальная) сеть, NoC стандарт имеет семь уровней протокола обмена информацией. NoC структура эффективна не тольг.о с позиции вычислительных процессов и обмена данными, но и с точки зрения энергосбережения и надежности цифровой системы в целом. Три уровня транзакций, транспортный и физический используются для разделения IP от данных, передаваемых по шинам. Первый необходим для передачи пакетированных сигналов. Второй организует маршруты прохождения пакета через систему коммутаторов. Третий ориентирован на обмен двоичной информацией по проводам Наличие системы приоритетов, коррекция ошибок в сети на кристалле, высокая защищенность интеллектуальной собственности (IP- core), ориентация на создание проектов масштабируемых систем большой размерности, эффективность обмена данными, низкое энергопотребление, высокая скорость выполнения операций, невысокая стоимость проектирова ния и другие сервисы, характерные для офисной сети, делают NoC очень привлекательной технологией для мирового рынка, где уровень продаж сетевых кристаллов в ближайшие пять чет достигнет 1 млрд. долларов. Сеть на кристалле представляется интересной парадигмой для проектировщиков на пути возможной интеграции большого количества вычислителей (IP-cores) и блоков памяти в одном чипе. Но путь адаптации SoC технологий к NoC структуре и практическая имплеменгаиия сети в кристалл ставит мно-
13 i о важных и еще не решенных проблем перед разработчиками, от носящихся к методоло[Иям проектирования, тестирования, а также создания новых средств CAD [5]. Как результат существенного повышения уровня интеграции функциональностей возникает проблема повышения эффективности межмодульных связей путем разработки инфраструктуры коммуникаций. В настоящее время существуют SoC проекты, содержащие мультипроцессоры, применяемые в TV-тюнерах, беспроводных базовых станциях, цифровом телевидении высокого разрешения, мобильных телефонах, устройствах обработки изображений (set-top boxes, wireless base stations, HDTV, mobile handsets and image processing). Упомянутые устройства фебуют or разработчиков эффективных решений в области проектирования регулярной и быстродействующей коммуникационной архитектуры для организации параллельных вычислений на мультиядерных системах в кристаллах. Различные архитектуры коммуникаций формируют типовые специфические шаблоны сетевых решений на кристалле. Наиболее интересные из них представлены на рис. 1.3. Следует заметить, что сложный кристалл SoC может рассматриваться как микросеть множества функциональных блоков, что позволяет исследователям позаимствовать сетевые модели и технологии параллельных вычислений для их последующего применения в архитектурах NoC. Библиотека «новых» компонентов NoC, включающая коммутаторы, маршрутизаторы, соединения и интерфейсы, обеспечивает разработчику дополнительную i ибкость в проектировании архитектуры NoC на основе процессорных модулей и блоков памяти (processor/storage cores). Конечно, для этого должны существовать соответствующие и достаточно выверенные средства и маршруты синтеза и анализа цифровых сетевых систем, поддерживающих все уровни обмена данными, от физического до гранзакционного Существенными характеристиками проекта являются энергетические затраты архитектуры межсоединений, их пропускная способность, время вдержки, а также аппаратная избыточность для их реализации. Все основные свойства NoC направлены на эффективное решение проблемы высокопроизводительных межсоединений между процессорными компонентами и модулями памяти на основе интеллектуальных коммутаторов, которые создают коммуникационные связи с высоким уровнем абстракции Тем не менее, задача обмена данными между компонентами сети (процессоры и память) становится все более сложной но мере роста размерности системы и обобщенной задержки межсоединений. Одн^м из возможных решений является представление системы межсоединений мультимодульной конвейерной платформой, где каждый коммуникационный модуль удовлетворяет по временным параметрам функционированию всей системы. При этом NoC архитектура поддерживает конвейерный тип, как внутрисегментных переключений соединений модулей, так и межблочных контактов структуры, определяемый конвейеризацией установления связей, переключений, инвариантных к задержкам компонентов сети
14 Тестирование NoC. Поскольку сеть происходит из системы на кристалле, то естественным представляется адаптация существующих SoC технологий и механизмов тестирования (ГАМ) к аналогичным проблемам с обязательным использованием методов и средств тестопригодного проектирования (DFT). Стратегия тестирования NoC систем ориентирована на решение трех основных проблем: 1) Тестирование функциональных модулей и блоков памяти и соответствующей им сети интерфейсов. Механизм ТАМ используется для транспортирования тестовых наборов из соответствующей памяти или генератора к тесшруемому модулю или блоку памяти. Благодаря регулярности сеги существует возможность одновременной и параллельной загрузки тестовых ресурсов для каждого модуля. Таким образом, время тестирования может быть уменьшено, благодаря использованию пространственных характеристик сети, дающих возможность распараллеливать процессы подачи тестов на функциональные блоки и их тестирование Наблюдаемость межсоединений является сравнительно низкой, поскольку они глубоко встроены в кристалл Ограничения на число внешних выводов кристалла влияют на число вход-выходных контактов, которые можно применять в процессе тестирования. NoC инфраструктура должна быть использована для тестирования собственных компонентов по рекурсивной процедуре - уже проверенные моцули необходимо использовать для транспортирования тестовых наборов к еще не проверенным блокам. Стратегия тестирования минимизирует применение дополнительных механизмов для транспортирования данных к компонентам сети, что позволяет уменьшить время тестирования, благодаря использованию параллельных путей для групповой передачи данных. Раздельное тестирование функциональных блоков и инфраструктуры межсоединений не является достаточным условием достижимости требуемого качества теста. 2) Проверка инфраструктуры межсоединений (межблочных и внутриблочных) Взаимодействия между функциональными модулями и структурой коммуникаций проверяется полными функциональными тестами. 3) Тестирование интегрированной системы в целом должно охватывать проверку вход-выходных функций каждого процессорного элемента, а также все функции маршрутов прохождения данных Для обеспечения качества и надежности NoC, по аналогии с SoC I-IP, необходимо создавать инфраструктуру сервисного обслуживания (I-IP) сети на основе использования ШЕЕ стандартов i S.49 и 1500, которая должна иметь следующие компоненты: 1) Мониторинг состояний внутренних и выходных линий в процессе функционирования, верификации и тестирования блоков на основе использования стандарта граничного сканирования IEEE 1500 [3J 2) Тестирование функциональных модулей, ориентированное на проверку дефектов или исправного поведения. 3) Диагностирование отказов путем анализа информации, полученной на стадии тестирования и использования специальных методов встроенного поиска неисправностей на основе стандарта IEEE 1500 [3] 4) Ремонт функциональных модулей и памяти цифровых систем на кристаллах после определения места и вида дефекта при вы-
15 полнении диагностирования. 5) Обеспечение надежности функционирования цифрового изделия с помощью диверсификации и дублирования функцио- 1 2 3. Система в пакете System in Package (SiP) - это набор кристаллов, размещенных на общей подложке, представляющий собой функциональность, реализованную в одном корпусе [4J SiP включает пассивные компоненты, такие как дискретные элементы; интегральные пассивные схемы; пассивные элементы, встроенные в подложку, а также компоненты специального назначения в виде фильтров на поверхностно-акустических волнах, электромагнитные экраны (EMI shields); пакетированные кристаллы, внешние соединители и механические элементы. Традиционное применение систем в пакете- управление питанием, сенсорные устройства, RF и wireless приложения для мобильной телефонии, устройства для высокопроизводительных вычислений, память, карманные компьютеры - PDA, глобальные системы навигации и определения местоположения - GPS, средства WiFi и Bluetooth™ [3]. Функциональные особенности силиконовых кристаллов для изготовления цифровых изделий могут быть классифицированы по следующим признакам [6,7,10] 1) Технология: цифровые, аналоювые, RF, оптоэлектронные. MEMS, пассивные; 2) Частота: от МГц диапазона для цифровых устройств и RF до ГГц для микроволновых компонентов; 3) Архитектура аналоговые устройства малой и большой мощности; цифровые структуры реального времени, управляемые событиями и данными. 4) Потребление энергии: портативные усфойства с малым потреблением энергии; 5) Другие факторы: форм-фактор, вес, выделение тепла. Традиционные технологии упаковки кристаллов характеризуются наличием ограничений по следующим характеристикам [7]. 1) Производительность системы на кристалле, определяемая задержками передачи сигнала между кристаллами, распространением и временем нарастания сигнала. 2) Миниатюризация, определяемая площадью посадочного места корпуса системы на кристалле, зазором между проводниками и количеством слоев топологии. Актуальными являются задачи уменьшения площади системы в пакете кристаллов и увеличения ее производительности. SiP представляет собой развитие более раньих технологий упаковки МСМ (Multichip Module), MCP - Muiti-Chip-Package и характеризуется наличием одного или более кристаллов, комбинированием технологий проводного монтажа и монтажа методом перевёрнутого кристалла выводами к подложке, размещением памяти и логики на одной подложке вместе с пассивными компонентами, фильтрами и антеннами. Многообразие компонентов МСМ модуля показано на рис. 1.4,а. В настоящее время рынок электронных технологий предлагает пять концепций трехмерной упаковки кристаллов [8. 9]:
16 1. «Multichip Package» [7. 10]. Кристаллы размещаются в горизонтальной плоскости (рис 1.4,6), могут накладываться друг на друга в виде этажерки или образовывать комбинированную 3D структуру в целях обеспечения минимального значения форм-фактора. Конструкция «Multicnip Package» характеризуется высокой производительностью, малыми размерами и весом, а также минимальной задержкой распространения сигнала. f !CF -л - Mt> Cn d нэскаде ^ - S ^ =* cn,ion о Тс о i - ^acxed <* ->- _ "~ф элементы д - Package-in-Ргскаде Structure РзсИзде> Through via Vsa to chip pad Ц^~~-- .~J x - Embedded chip package, pnn- i i С!'э,е з ™ Стек подложек «Thru silicon vias» Рис. 1 4 Конструктивы цифровых систем в макетах 2. «System-m-Package» [7.9,10] основана на метрике разновидностей SiP. 1) Использование компонентов, допускающих размещение в горизонтальной плоскости (side-by-side) (рис. 1.4,в); технология проводного монтажа и термокомпрессионной микросварки Wire Bond; монтаж кристаллов на гибкой ленте, выполненной из полимерною материала (полиимид) Таре Automated Bonding (TAB) и/или компонентов, монтируемых методом перевернутого кристалла flip-chip. 2) Использование компонентов, представляющих собой
17 сборочные единицы типа «составной кристалл» (Stacked Die) в виде BGA (Ball Grid Array) модулей с шариковыми выводами или монтируемых по технологии Wire Bond, а также компонентов Flip-chip (рис 1 4,г) 3) Использование встроенных в подложку компонентов. По сравнению с размещением в горизонтальной плоскости сборочные единицы типа Stacked Die позволяют увеличить быстродействие, уменьшить габаритные размеры, потребляемую мощность и улучшить температурный режим в рабочей зоне Отдельные кристаллы могут быть достаточно просто переведены из штатного режима в режим автономного тестирования Применение технологии монтажа компонентов методом переверну!ого кристалла даег возможность улучшить значение форм-фактора, уменьшить паразитные емкости и индуктивности между элементами топологии. 3. «Package-m-Package» (PiP) [9, 10]. Пакет состоит из набора или стека полностью проверенных модулей (Internal Stacking Module, ISM), размещенных в базовом сборочном пакете (Base Assembly Package, BAP) в цепях формирования единого конструктивного изделия (рис. 1.4,д). 4 «Package-on-Package» (PoP) [8, 9, 10]. Представляет собой структуру, в которой полностью проверенные пакеты установлены вертикально, друг на друга При этом степень интеграции может быть различной. Данная концепция получила наибольшее применение для создания цифровых или аналого- цифровых логических устройств с высокой плотностью упаковки, размещаемых в нижнем базовом пакете, с одним или несколькими запоминающими устройствами большой емкости, размещаемыми в верхнем пакете [8]. Лидером разработки и внедрения технологий трехмерной упаковки кристаллов (3D packaging technologies) является компания Amkor Technology. Пример конструктивного решения РоР, при котором верхний пакет - модуль памяти - размещается в корпусе FBGA (Fine Pitch BGA.) или Stacked CSP (Chip Scale Package), а нижний - логический модуль - в корпусе PSvfBGA (Package Stackable Very Thin Fine Pitch BGA) (рис. 1 4,e) 5 «Embedded chip technologies», «Substrate Technology» [7, 10]. Активные или пассивные кристаллы встраиваются в подложку (рис. 1 4,ж), где межсоединения реализуются с помощью микроотверстий. Технология «Wafer Level» [10] позволяет устанавливать кристалл на подложке, подложку на подложке (рис 1.4,з) и реализовывать технологию межсоединений Thru Silicon Vias (TSV) [8, 10]. Wafer Level технология характеризуется высокой степенью интеграции и, наряду с этим, имеет ряд недостатков [10]: высокая стоимость проектирования и производства цифровой системы в пакете кристаллов; использование компонентов от разных производителей, изготавливаемых по разл!гчным технологиям; сложность процесса восстановления работоспособности системы; относительно низкий процент выхода годных изделий по сравнению с другими технологиями Стандарт по применению многокристальных модулей IPC-MC-790 (Guidelines for Mullichip Module Technology Utilization) определяет три типа технологий изготовления подложки
18 многослойная (Laminated); керамическая (Cofired) с использованием технологии тонких пленок (Thick Film) и подложка, формируемая технологиями напыления (Deposited) Преимущества трехмерной упаковки кристаллов на основе технологий активного использования подложки [10]- 1) Миниатюризация - увеличение плотности упаковки и топологии, которые определяются следующим образом. Peff = Total Active Silicon Area/ Total Active SiP Area (%), где Peff - плотность упаковки; Total ActiveSiheon Area - активная плошадь кристалла. Total Active SiP Area - активная площадь цифровой системы в пакете кристаллов SiP; Wiring Density = Wiring Length /Silicon Area (cm /cm ), где Wiring Density- плотность топологии; WirmgLength- суммарная длина связей; Silicon Area - площадь кристалла 2) Увеличение производительности Для ее оценки на системном уровне используется следующий параметр - «время цикла»- CycIeTime=TimeforSemiconductor/ Time for Package, где Cycle Time - время цикла, Time for Semiconductor- время цикла для полупроводника; Time for Package- время цикла для пакета кристаллов 3) Уменьшение стоимости пакета за счет повышения процента выхода годных изделий и устранения этапа упаковки системы в корпус, а значит и исключения соответствующих операций из производственного процесса. 4) Улучшение надежности системы блаюдаря уменьшению суммарной длины связей и количества слоев пакета за счет размещения бескорпусных кристаллов непосредственно на многослойной подложке. Проблемы использования технологий подложки: I) высокая стоимость производства; 2) сложность процесса принятия решений (Decision Making Process), 3) невозможность использования существующих моделей; 4) негарантированное качество бескорпусных кристаллов; 5) низкий процент выхода годных изделий после операций сборки пакета кристаллов; 6) сложный процесс восстановления работоспособности; 7) ограниченный набор средств автоматизации проекгировачия (CAD Tools); 8} сложность обеспечения оши- малыюго теплового режима. Статистика современного рынка относительно используемых продуктов на основе SiP [10]: 33% - заказные специализированные изделия; 20% - средства телекоммуникации; 20% - компактные энергосберегающие вычислители, 10%- военного или авиакосмического назначения. Технолог ии подложки: 58% - керамическая - Cofired; 39% - многослойная - Laminated, 3% - напыление - Deposited Технологии монтажа. Wirebond. 1АВ. FiipChip. Технологии обеспечения тестопригодности- 50% - Boundary- Scan; 54% - в!гутрисхемное зондирование контрольных точек (Internal Test Points Probed), 69% - восстановление работоспособности дефектных SiP.
19 Типы неисправностей- наибольший процент дефектов связан с нарушением работоспособности кристаллов. 1ехнологии автоматизации тестирования- 46% - специальные тестовые наборы (Custom Test Sets), 37% - использование тестеров (1С Testers). Направления развития пакетных технологий, увеличение сложности кристалла до 700 млн транзисторов на кристалле; уменьшение площади кристалла; увеличение количества выводов до 10 К; использование шариковых выводов с шагом 50 мкм. 1.3. Технологии изготовления и тестирования цифровых систем Общая стратегия создания (производства) и тестирования цифровой системы в пакете (МСМ - Multi Chip Module) содержит пункты [7, 10], представленные на рис 1.5. Рис 1 5 Стратегия производства и тесшрования цифровой системы в пакете
i) Проверка 300-мм пластины после ее производства (изготовление, сортировка, распиливание). Параллельно во времени выполняются пункты 2 и 3 2) Создание подложки (проектирование, производство и тестирование). 3) Создание кристалла (mount in earner - установка кристаллов на носителе или кристаллодержателе, испытание на наличие дефектов, полное тестирование, удаление носителя). 4) Создание (ассемблирование) модуля МСМ из ранее созданных и проверенных компонентов (подложки - substrate и кристалла die): сборка, тестирование и диагностирование модуля, испытание, проверка после испытания, инкапсуляция компонентов в пакет, окончательное тестирование пакета модулей. Здесь же выполняется отбраковка компонентов в мусорную корзину или на переработку, если это допускается технологией. Определенный интерес представляет современное производство кремниевых пластин. Первый этап - формирование монокристалла кремния цилиндрической формы. Он выращивается на основе затравочного кристалла, который представляет собой идеальную (совершенную) структуру необходимой кристаллографической ориентации. Затравочный кристалл погружается в ванну (шгель) с расплавленным кремнием. Тигель и кристалл вращаются в противоположных направлениях для обеспечения равномерного распределения температуры и примесей по объёму расплава. Затем монокристалл медленно вытягивается из расплава. При этом происходит переход атомов из жидкой или газообразной фазы вещества в твердую фазу на их границе раздела и рост монокристалла. В результате получается кремниевый слиток высокой чистоты заданного диаметра В настоящее время для производства систем на кристалле используются заготовки диаметром 300 мм. К 2013 году планируется перейти на использование 450-мм кремниевых пластин. Стоимость одного нового завода - 2 млрд. долларов Второй этап - получение кремниевых пластин толщиной около 0,6 мм путем разрезания монокристалла с помошью кольцевой алмазной пилы Для получения необходимого значения шероховатости поверхности пластины подвергаются дополнительной обработке: I) шлифованием с помощью вращающихся стальных дисков и абразивного материала, при этом устраняются неровности высотой более 10 мкм; 2) травлением для удаления погрешностей в структуре кристалла; 3) полированием для получения зеркально гладкой поверхности с неровностями не выше 3 нм. Третий этап - нанесение защитной пленки диэлектрика (диоксида кремния, Si02), который является хорошим изолятором и выполняет защитную функцию при дальнейшей обработке подложки. Четвертый этап - нанесение фоторезиста в целях формирования на подложке защитного рельефа, не подвергаемого последующему травлению. Пятый этап - литография Под воздействием ультрафиолетового излучения, попадающего на определенные участки защитного слоя через маску, фоторезист изменяет свойства растворимости. После облу-
21 чения фоторезист подвергается проявлению Новая технология литографии EUV (Extreme UltraViolet — сверхжесткое ультрафиолетовое излучение), основанная на использовании ультрафиолетового излучения с длиной волны 13 им. позволяет формировать линии шириной до 30 нм. Шестой этап - травление в целях удаления пленки диоксида кремния с участков поверхности пластины, которые должны быть подвергнуты дальнейшей обработке. При производстве кристаллов используется метод сухого (плазменного) травления с применением ионизированного газа (плазмы), который вступает в реакцию с поверхностью диоксида кремния. Происходит разрушение диоксида кремния на участках, не покрытых защитным слоем, после чего оставшаяся часть фоторезиста удаляется Седьмой этап - диффузия легирующей примеси путем ионной имплантации. Ионы примеси «выстреливаются» из высоковольтного ускорителя и, обладая достаточной энергией, проникают в поверхностные слои кремния. Таким образом, формируется слой полупроводниковой структуры. Для создания нескольких слоев повторяют этапы с третьего по седьмой Восьмой этап - металлизация При формировании слоев на отдельных участках оставляют области, которые затем заполняются атомами металла - проводящие зоны, используемые для установления связи между слоями. Проводящие зоны формируют сложную трехмерную структуру межслойных соединений. Перед разрезанием кремниевой пластины на отдельные кристаллы ее толщину уменьшают (примерно на 33%) и удаляют загрязнения с обратной стороны. На тыльную сторону подложки наносится слой специального материала, улучшающего крепление кристалла к корпусу или криетадлодержате- лю. По окончании процесса формирования пластины она подвергается тестированию на установках зондового контроля в целях проверки качества выполнения технологических операций и выявления дефектных кристаллов. На контакты каждого кристалла накладываются контакты зонда и проводятся электрические тесты Специальное программное обеспечение позволяет формировать тестовые наборы и наблюдать состояние выходов кристалла Резка пластины на отдельные кристаллы осуществляется с помощью специальной прецизионной пилы. Дефектные кристаллы отбраковываются. Годные подвергаются нагрузочным испытаниям и тестированию, после чего они поступают на участок сборки многокристального модуля. По окончании процесса сборки модули тестируются и подвергаются дополнительно нагрузочным испытаниям Затем выполняется повторное тестирование для определения технического состояния устройства Исправные модули помещаются в индивидуальный корпус, который защищает кристалл от внешних воздействий и обеспечивает электрическое соединение с подложкой, на которую он впоследствии будет установлен Далее упакованный модуль подвергается завершающему тестированию, испытаниям при воздействии различных температурных, влажнестных режимов и электростатических разрядов в соответствии со спецификацией устройства. Неисправные модули отбраковываются Кристаллы, прошедшие тестирование, поступают на вы-
22 ходной контроль, задача которого - подтвердить, что результаты всех предыдущих проверок были корректными, а параметры усгройства соответствуют установленным требованиям. Многокристальные модули - пакеты, прошедшие выходной контроль, маркируются и упаковываются для доставки изделий заказчикам Современные микроэлектронные чипы, располагаемые на печатной плате, использовались в цифровых изделиях на протяжении 40 лет. В двумерном формате были разработаны замечательные средства для межсоединений кристаллов, питания, охлаждения и защиты. Сегодня система в пакете обеспечивает многообразие пакетирования для компьютеров, космоса и авиации, медицины и военных целей путем превращения платы в трехмерный пакет кристаллов, который уменьшает объем, повышает надежность и производительность системы в целом. Пакетирование электронных компонентов рассматривается как часть компьютерного системного проектирования. Наиболее известной является Mul- tichip module (MCM) технология пакетирования, которая интегрирует known good dies (KGD) на подложке с высокой плотностью размещения компонентов. На основе данной технологии в девяностые годы прошлого столетия разрабатывались мощные и профессиональные (high-end) компьютерные системы в 2D исполнении В конце девяностых появились 3D реализации технологии МСМ с высокой плотностью монтажа. Как расширение и развитие МСМ технология SiP становится широко распространенной, направленной на уменьшение форм-фактора, что делает ее перспективной в ближайшие 10 лет. Технологии тестирования пакетов жизнеспособны, производительны, но эффективны только для простых пакетов Что касается многокристальных гетерогенных системных структур, имеющих логику, память, аналоговые и радиочастотные компоненты, то их миниатюрное исполнение очень ожидаемо на рынке, как изделие, имеющее достоинства: невысокая стоимость и высокая производительность, незначительное время разработки и низкие энергетические затраты. Тем не менее, существует ряд проблем в области design and test, которые следует решать. Необходимы обобщенные EDA средства для интегрирования цифровых, смешанных mixed-signal и радиочастотных чипов, содержащихся в SiP. Средства для проектирования и анализа должны уметь выполнять моделирование электрических и температурных режимов, а также использовать KGD в качестве компонента, хотя отсутствие годного кристалла задерживает проектирование интегрированной системы в целом Еще одна проблема связана с распространением и имплементацией пассивных элементов в подложку пакета, что должно выполняться под руководством SiP производителей, которые обязаны ознакомить проектировщиков с семейством пассивных компонентов, что имеет высокую актуальность для эффективного создания систем в пакетах и их продвижения на рынок
23 Сейчас существует два направления в решении проблемы проектирования системы в пакете, разработка чипа и интегрирование пакета Особенно необходимы новые средства для пакетирования множества кристаллов, а также для тестирования уже интегрированной системы. Стратегия тестирования SiP отличается от проверки SoC, поскольку система в пакете интегрирует компоненты от различных производителей Создание новых технологий тестирования SiP является сегодня приоритетной проблемой, поставленной в среде практических ученых и исследователей, относящихся к design-and-test community. Самой перспективной стратегией является использование стандарта IEEE 1500 для встроенного тестирования функциональных компонентов. Обладая высокой производительностью и уровнем интеграции компонентов в небольшом объеме, пакеты содержат несколько кристаллов, соединенных проводными шинами, которые отрицательно влияют на прохождение сигналов в высокочастотном спектре Интеграция мультиядерных гетерогенных систем в пакет также ставит много вопросов перед design-and-test инженерами. Преодоление таких барьеров требует объединения усилий и средств со стороны специалистов и компаний, занимающихся цифровым аналоговым, RF- и тепловым (thermal) проектированием Существующие предложения по тестированию SiP связаны с адаптацией DFT-техпологий для проверки встроенных АЦП и ЦАП преобразователей чисто цифровыми тестами, которые более экономичны для конвертеров. Таким образом, успех цифровых систем в пакетах кристаллов (SiP) на рынке электронных технологий зависит от решения проблем, связанных с созданием средств проектирования 1етерогенных компонентов и их эффективного тестирования. SiP дизайн является привлекательной технологией для широкого круга применений, таких как: беспроводные устройства, сенсоры, графические преобразователи, сетевые пакетные переключатели. С точки зрения проектирования и производства конструктив SiP предлагает гибкие технологии для создания и изготовления пакетов из разнородных материалов' германий- кремниевый кристалл (SiGc) - для быстродействующей логики, CMOS - для аналоговых компонентов и памяти. Таким образом, появляются возможности создавать маленькие по размеру изделия высокой производительности и выпуском годных изделий. SiP также предполагает существенно снизить затраты на тестирование, поскольку каждый тип кристалла должен иметь собственный встроенный тестер. В дополнение к сказанному, каждый функциональный компонент должен быть ремонтируемым или реконфигурируемым в случае обнаружения дефектов. В настоящее время SiP дизайн не имеет инфраструктуры сервисною обслуживания (как в SoC) для унифицированного решения проблем проектирования на основе модели процесса, ориентированного на совместное создание функциональностей кристаллов пакета
24 1.4. Тестопрш одное проектирование SiP на основе стандарта IEEE 1500 Система в пакете интегрирует несколько кристаллов, произведенных, как правило, различными поставщиками и разработчиками. Поэтому тестирование SIP-структуры существенно отличается от проверки системы на кристалле Далее рассматриваются стратегии, основанные на использовании IEEE I500 стандарта, которые, по мнению экспертов [3], являются перспективными при решении проблем сервисного обслуживания SiP. Требования рынка диктуют компаниям разрабатывать изделия по метрике: быстрее, меньше, дешевле. Поэтому возникли технологии, способные оперировать миниатюрными компонентами, интегрируя их в набор функциональных модулей на одном кристалле. Парадигма системы на кристалле гарантированно выигрывает у цифровых систем на печатных платах в производительности, размерах и энергопотреблении. SoC-производители могут разрабатывать операционные модули самостоятельно или покупать готовые функциональные блоки (как IP) для последующего ассемблирования их в процессе проектирования специализированных цифровых систем. При этом производитель должен выпускать SoC крупными сериями в целях возмещения затрат инженерного труда, необходимо! о для разработки кристалла. С 1990-х годов концепция SoC постоянно возрастает в части ее привлекательности для рынка электронных технологий, благодаря интеграции на одном чипе функциональностей в виде логики, памяти, радиочастотных модулей и блоков питания. Со стороны средств проектирования следует заметить, что инструменты моделирования, верификации и валидации совершили 1игант- ский прыжок в сторону сложности обрабатываемых моделей Тестирование более сложных SoC потребовало таких платформ тестового оборудования, которые предлагают больше функциональных возможностей, а также специализированного встроенного тестового оборудования, необходимого для новых маршрутов тестирования SoC Имплементация компонентов в SoC есть выбор компромисса между оптимальными технологиями и бизнес целями. Поэтому важным представляется не только как можно быстрее выйти с новым изделием на рынок, но и иметь технологические средства замены неисправных компонентов. Переходя к системе в пакете, проектировщик и производитель получают: автономные IP чипы, исполненные как чистые кристаллы, наслоенные друг на друга и имеющие внутрипакетные соединения. Каждый кристалл может иметь отдельную функциональность или быть многофункциональным, содержащим совокупность IP-cores. SiP впитал в себя преимущества как печатной платы, так и системы на кристалле: 1) Компоненты могут быть изготовлены отдельно друг от друга на основе различных технологий, а затем пакетированы. 2) Это означает, что вся система будет иметь высокую производительность и простые маршруты (фазы) проектирования. 3) SiP- структура хорошо масштабируется и оптимизируется, а также все функциональные IP-модули имеют надежную защиту авторских прав производителя
25 Стратегия «разделяй и властвуй» (divide-and-conquer) здесь подходит как для производителя, так и для потребителя, которые должны придерживаться жесткого фафчка создания продукта - от определения спецификации до поставки готового изделия. Миллиарды цифровых систем в пакетах уже находятся в руках потребителей; это, прежде всего, мобильные коммуникационные изделия и различные виды «твердой» памяти. Тем не менее, тестирование SiP все еще требует пристального внимания со стороны ученых и экспертов. Активность специалистов направлена на адаптацию SoC технологий тестирования, использующих регистры граничного сканирования в качестве окружающей среды (core wrapper) и механизмы подачи тестов (test access mechanisms) как составные части тестопригодного проектирования. Для систем в пакетах сценарий тестирования отличается от описанного выше, поскольку он ориентирован на два уровня описания системы, тестирование кристаллов в отдельности, а затем - заключительная проверка ассемблированной системы в целом. Также в SiP имеются избыточные нефункциональные компоненты, обеспечивающие повышение управляемости и наблюдаемости сигналов, которые интегрируются в стратегию тестирования системы в целом. Для этого создаются специальные средства и структуры (подобно I- IP для SoC), обслуживающие функциональные блоки системы, включая аналоговые и смешанные - mixed-signal, технологические межсоединения кристаллов, а также проектные ограничения и технические условия, использующие новый стандарт !500 Standard for Fmbedded Coie Test (SECT). Парадигма тестирования SiP основана на предпосылке существования заведомо исправных кристаллов - known-good-die Это означает, что на уровне системы в пакете не всегда существует возможность протестировать все функциональности и структурные связи, как это можно сделать на уровне одного кристалла. Для этого существует несколько причин: ограниченный доступ ко всем тестовым режимам кристаллов, ввиду существования запретов на сверхлимитные расходы по времени и материальным затратам Другие нерешенные проблемы относятся к технологии тестирования соединений внутри подложки, которая имеет устойчивую тенденцию к усложнению структуры и увеличению числа внутренних компонентов, активных и пассивных. Последние элементы используются, в том числе, для соединения отдельных кристаллов в систему. Кроме того, важно иметь полные тесты для межсоединений на уровне одного кристалла, а также тесты верификации, чувствительные к параметрам пакетирования кристаллов В настоящее время SiP архитектуры ориентированы на исполнение ручных, вычислительных и мобильных устройств, которые требуют минимального пространства и слияния функциональностей, включая цифровые, аналоговые модули и управляемые вычислительным процессом блоки питания. В такой конфигурации SiP имеет несколько кристаллов различной природы и поддерживает следующие режимы 1) Одно или несколько вычислительных устройств (процессоры, специальные вычислители, кодеки, периферийные устройства, соединенные шинами) осуществляют поставку пользователю
26 своих функциональностей 2) Автономные кристаллы памяти (Flash, E2PROM, DRAM), производимые раздельно, затем могуч быгь ассемблированы для получения более сложных архитектур. 3) Аналоговые кристаллы и чипы питания предоставляют системам в пакетах возможность взаимодействовать с электромеханическими компонентами, а также осуществлять вывод информации на экран и аудиосистему. 4) RF кристаллы предоставляют системе возможность взаимодействия с работающим оборудованием и обеспечивают сохранность информации, полученной в процессе вычислений. 5) Подложка служит не только в качестве структуры межсоединений кристаллов дру! с другом на основе применения активных и пассивных элементов, но данная область может быть использована для повышения полноты тестовой стратегии SiP Процесс производства SoC и SiP для счадий создания кристаллов имеет больше общих моментов, чем различий, что также обусловливает адаптацию для SiP методов SoC тестирования. Более того, методы и механизмы проверки компонентов на уровне тестирования кристаллов являются общими для SoC и SiP [10]. Второй уровень тестирования SoC использует системный тест, ориентированный на проверку интерфейсов, межсоединений и всех структур в целом. Поскольку SiP имеет многокристальную архитектуру, маршрут системного тестирования состоит из следующих пунктов: 1) Определение требований к полноте тестирования подсистем. Каждый произведенный кристалл имеет собственный интерфейс тестирования и строгий порядок выполнения тестов. 2) Определение требований к качеству проверки системы. SiP архитектура обусловливает два важных аспекта. Во-первых, тестирование кристалла может быть ориентировано на общую структуру SiP во взаимодействии с другими компонентами, когда функциональность одного кристалла SiP может использоваться при тестировании другого. Во- вторых, необходимо иметь эффективные алгоритмы анализа результатов тестирования межсоединений кристаллов, используя архитектуру интерфейсов, доступную для подсистем тестирования. Последний уровень производственною тестирования отражает структурные различия между SoC и SiP. Здесь тестовая стратегия, разработанная для всей системы, переводится в Automatic Test Equipment (ATE) формат: уровень 3 - описание тестовой программы и тестовых воздействий; уровень 2 - тестовые программы, сгенерированные для проверки межсоединений между кристаллами и завершающего тестирования всей структуры SiP Стандарт iEEE 1500 SECT является эффективным решением производственного тестирования SoC В нем сосредоточена методология передачи тестовых данных, не зависящая от функциональности системы и позволяющая выполнять «plug-and-play» тестирование. Стандарт определяет: масштабируемую структуру интерфейса тестирования для IP-cores, входящих в состав SoC; язык тестирования IP-core - Core Test Language - CTL, который позво-
27 ляет описать архитектуру теста и протоколы обмена данными между фирмами производителями IP-core и системным интегратором. На уровне интеграции цифровой системы на кристалле IP-core, помещенный в тест-интерфейс (wrapper) IFEb 1500, подключается к специальной, определенной пользователем инфраструктуре тестирования благодаря наличию механизма тестового доступа (Test Access Mechanism ТАМ). Тестирование осуществляется через тест-интерфейс IEEE 1500, посредством которого внешнее оборудование передает тестовые наборы и получает отклики в установленном порядке. Используемые для SoC решения, основанные на стандарте !ЕЕЕ 1500, могут быть распространены на парадигму SiP путем применения представленных в стандарте структур для тестирования отдельных кристаллов, образующих систему в пакете, гарантируя, таким образом, возможность реализации тестирования на уровне кристалла и на системном уровне. Размещение тест-интерфейса на кристалле позволяет улучшить качество проекш, несмотря на то, что временные параметры и аппаратурные затраты изделия могут несколько ухудшиться. Предложенное в работе [3] решение по организации тестового доступа для SiP основано на иерархическом подходе, представленном в стандарте IEEE 1500. Преимущества указанного подхода. 1) простое и быстрое взаимодействие теста со слоями IP-cores и подсистемами независимо от типов компонентов, упрощение проектирования структуры теста для каждого моауля и подсоединение к компоненту ТАМ, 2) эффективная поддержка тестирования соединений между кристаллами в пакете, 3) определение стандартно*о подхода к 1енерации тестовых программ на уровне кристалла и SiP в целом. На рис 1 6 представлена примерная конфигурация теста для SiP, состоящей из 2-х кристаллов Subsystem onji chip | _ I Subbtrdte ~ ~ 1 J Test data if-put Arapper serial Test data contra! output Рис. 1 6 Механизм ГАМ для двухкрист&чьной сиоемы в пакете Здесь используется один последовательный канал для реализации механизма тестового доступа (минимум, определенный стандартом IEEE 1500). Предложенная стр>ктура может быть использована в двух случаях, когда кристалл тестируется отдельно путем его подключения непосредственно к ав-
28 тематическому тестовому оборудованию (ATE) и для тестирования функциональности SiP в целом. Тест-интерфейс обеспечивает возможность формирования тестовых данных для каждого IP-core и получение результатов, а также выполнение необходимых преобразований формата данных для передачи их в ГЛМ. начиная от ввода тестовых наборов и заканчивая их выводом. Шестиразрядная шина обеспечивает управление последовательными структурами интерфейса путем передачи данных к каждому кристаллу на основе стандартизированного протокола. На рис. 1.7 представлена предлагаемая структура интерфейса тестирования на основе стандарта IEEE 1500. Стандарт гребует имплементации минимального набора структур- 1) Регистр граничною сканирования (Wrapper Boundary Register, WBR) действует как boundary scan цепь на уровне IP-core. 2) Буферный регистр (Wrapper Bypass Register, WBY), обычно состоящий из одного триггера, который позволяет направлять тестовые данные к другому IP-core через интерфейс. 3) Регистр команд (Wrapper Instruction Register, WIR), принимающий кодовое слово для активизации одного из возможных регистров сканирования путем переключения мультиплексоров На рис. 1.7 показаны цепочки сканирования, добавленные в IP-core, которые подключены к системе и дополнительному параллельному порту для организации тестового доступа Рис 1 7 Boundary scan интерфейс для тестирования SiP- а- лслный доступ к цепочке граничного сканирования, б - тестирование межсоединений кристаллов Представленная архитектура интерфейса обеспечивает два режима функционирования, ориентированных на тестирование SiP: первый (рис.1.7,а) - предоставляет полный доступ к цепочке фаничного сканирования, когда имеется возможность тестирования межсоединений IP-cores внутри подсистемы на кристалле до и после сборки SiP; второй (рис. 1.7,6) - ориентирован исключительно на тестирование межсоединений между кристаллами и предоставляет доступ только к ячейке фаничного сканирования на первичных входах и выходах подсистемы на кристалле. Для представленного примера
29 линии: d[3] - d[4] и q[l] - q[2]. Описанная конфигурация повторяется для всех IP-cores подсистемы на кристалле, обеспечивает выполнение функцио- нальностей интерфейса IEEE 1500, окружающего кристалл в целом, без введения дополнительного аппаратного обеспечения или ухудшения характеристик Выбор конфигурации ячейки граничного сканирования - задача уровня тестирования пакетированной системы. Несмотря на то, что разработанный ранее кристалл, интегрированный в систему, может впоследствии потерять структуры тестового доступа, соответствующие стандарту IEEE 1500, имеется возможность получения доступа к верхнему уровню кристалла путем использования ячейки граничного сканирования, относящейся к другому кристаллу системы. Это позволяет применять тестовые наборы, предназначенные для тестирования соединений между кристаллами на основе интерфейса IEEE 1500, включенного в проект SiP. SiP предоставляет большое разнообразие возможных проектных решений, в которых используются компоненты, изготовленные разными производителями по различным технологиям. Даже для кристаллов, удовлетворяющих тестовым структурам стандарта IFEE 1500, множество дополнительных факторов могут влиять на разработку тестовых программ В зависимости от доступного автоматического тестового оборудования, конфигурации проекта и требований к нему, может быть использована стратегия с одним или несколькими проходами. Для ускорения тестовой интефации в процесс разработки SiP могут применяться программные средства автоматической генерации тесюв Основные параметры тестовых программ. 1) проверка совместимости описанных тестовых архитектур и существующих ограничении на доступные ATE и потребляемую мощность в процессе тестирования; 2) быстрая оценка времени тестирования SiP для заданной конфигурации теста; 3) автоматическая генерация тестовых программ для SiP ка заданном языке, включая формы сигналов, которые получены и переданы в ATE для выполнения теста Основное преимущество использования сервисного профамм- ного обеспечения заключается в возможности автоматической генерации тестовых профамм на уровне кристалла или системном уровне на основе описаний компонентов В качестве примера в [3] рассмотрена SiP, разработанная для спутниковой связи. Архитектура SiP включает подсистему на кристалле для прямой не- модулированной (base-band) передачи, разработанную гго 90nm технологии, и один или два дополнительных элемента памяти, буферная память объемом 128-Mbyte, dynamic RAM и энергонезависимая (E2PROM). В состав системы входят 4 кристалла, реализующие RF интерфейс и преобразование информации (рис 1.8) При тестировании системы были использованы решения, описанные выше, и средства автоматической генерации тестовых профамм на всех этапах производственного тестирования SiP. Тестирование подсистем на кристалле выполнялось через порт тестового доступа (ТАР) Для структурного тестирования SoC необходима память большого объема, а также аналоговые средства функциональной проверки встроенных функций обра-
30 ботки сигналов На уровне подложки для тестирования SoC с помощью тестера Agilent °3K требуется 7 секунд на один кристалл Указанное время увеличивается на 25%, если система на кристалле включает RF компоненты. Более тою, система в пакете подвергается испытаниям при различной температуре от 25 до 125°С. Для тестирования элементов памяти SiP были использованы стандартные средства тестирования и DFT. Для памяти E2PROM тестирование на уровне подложки выполнялось на специальном оборудовании с использованием тестера Credence Kalos Тестирование DRAM осуществлялось с применением стандартного автономного тестера серии Agilent V54 или Advantest. Для рассматриваемой системы был использован тестер Agilent 93К, в котором реализован метод параллельною тестирования, основанный на применении мультипоточного обмена данными. Метод позволяет подавать несколько независимых тестов на различные группы выводов параллельно, а также изолировать отдельные кристаллы при тестировании или тестировать их в отдельности, используя стандартную инфраструктуру. Рис ! 8 Система в пакете дтя спутниковой связи 1.5. Языки описания аппаратуры VHDL - аббревиатура от английского выражения VHSIC Hardware Description Language. В свою очередь, VHS1C происходит os названия программы Very High Speed Integrated Circuit (высокоскорост ные интегральные схемы). Эта программа, профинансированная Министерством Обороны США, ставила своей целью развитие нового поколения высокоскоростных интегральных схем Первая версия языка была представлена в 1985 году Впоследствии он был передан обществу IEEE для стандартизации. В 1987 году язык был утвержден в качеаве стандарта IEEE I076-1987 Через пять лет он был рассмотрен повторно, в результате чего новая версия 1076-93 содержит ряд дополнительных возможностей С тех пор VHDL пользуется постоянно возрастающей популярностью среди специалистов по автоматизированному проектированию (CAD) электронных систем Первые VHDL-приложения появились в начале 90-х годов. Для синтеза был разработан пакет IEEE 1164. На практике каждый крупный производитель систем автоматизированного проектирования поддерживает VHDL. Язык имеет академическую направленность, популярен в университетских лабораториях. VHDL позволяет описывать системы на различных уровнях. Он реализует методологию нисходящего проектирования, в которой система сначала опи-
31 сывается на высоком уровне и тестируется с помощью средств моделирования, после чего поэтапно она приводится к структурному описанию, тесно связанному с фактической аппаратной реализацией. Язык VHDL является инвариантным относительно многообразия технологий реализации. Если какой-то проект, описанный в VHDL, реализован для конкретной электронной технологии, то данное VHDL-описание может быть использовано в качест ве исходного для реализации устройства в новой технологии Verilog, или Verilog HDL - язык описания аппаратуры, разработан в 1985 году Филиппом Мурби (Philip Moorby), нуждавшимся в простом, наглядном и эффективном способе описания цифровых схем, моделирования и анализа их функционирования. Язык становится собственностью Gateway Design Automation, а затем Cadence Design Systems. Первый стандарт Veriiog появляется IEEE в 1995 году. Последнее обновление языка выполнено в 2005 году Veriiog имеет свою законную нишу на рынке EDA и более чем VHDL популярен в промышленности при проектировании ASIC-устройств Рис. 1.9 представляв схему конструкций, добавленных в язык Verilog на различных этапах его развития. В качестве ядра выделены базовые элементы, определенные стандартом 1995 юда. Собственно, они являются тем подмножеством, на котором разработана основная масса Verilog-проектов. SystemVenlog User Defined Port Block Labeling State Machine Dynamic Progress interface Assertion Packed Array 2/4 State Variable Structure limeunits Union unique'prioriry fork/case.' j \NSICst>leport standard file I/O generate Svalue Splusarg localparam tftidet elsit line 1 const func @* jj module Sfinish Sfopen Sclose initial Iparameter Sdisplay Swrite disable function/task Smonitor event j (always @ define ' ifdef else wait#(r Massign include-timescale forkjoir int enum shortim tvpedef shortrea casting double const if char i oid (* attributed muhidirr configuration signed u memory part select variable part select wire reg begin end integer real while time for iorcver packed arra 2D memoP break continue return goto ensional array **(po»er operator) repeat <: a 8 < § Рис. 1.9 Схема конструкций языка System Verilog Далее, в качестве расширения к ядру отмечены конструкции, дополняющие язык, благодаря стандарту 2001 года Verilog 1364-2001. И последняя часть - конструкции, образующие System Verilog. Эти элементы предназначены для создания сложных иерархических проектов, а также для описания дополнительных типов данных и операторов из языка Си. System Verilog появился в связи с постоянным увеличением размеров проектов и был разработан для описания устройств на системном уровне
1.5 1. Языки проектирования и верификации SoC. Различные языки разрабатывались для различных аспектов проектирования систем C/C++ преимущественно используются для разработки программного обеспечения встроенных систем. HDL-языки описания аппаратуры, VHDL и Verilog применяются для проектирования и синтеза цифровых схем. Языки Vera и е предназначены для функциональной верификации сложных специализированных интегральных схем (ASIC). Новый язык SystemVenlog является дополненной версией языка Verilog, предназначенной для решения типовых задач аппаратно-ориентированною системного проектирования. Среда Matlab, другие подобные инструменты и языки, такие как SPW и System Studio, широко используются для сбора системных требований и разработки алгоритмов цифровой обработки сигналов На рис. 1.10 представлены области использования языков системного проектирования. Requiremenb Transistors — -.EH Venlog I j vhdlI — Venlog j\feaT ~j Sugar r I Jcda SystemC Рис 1.10. Сравнение областей применения языков системного проектирования SystemC был создан для проектирования SoC - устройств на ESL-уровне (Electronic System-Level) для разработчиков, использующих С/С-н- Стандарт: IEEE Std. I666-2005 SystemC (Open SystemC Initiative (OSCf)) SystemC - это единый язык для проектирования и верификации, который позволяет представлять архитектурные и другие атрибуты модетей системного уровня в форме классов языка C++ с открытым исходным кодом. Это дает возможность выполнять проектирование и верификацию на системном уровне, независимо от каких-либо деталей реализации аппаратуры и программного обеспечения. Также имеется возможность выполнения совместной верификации с RTL-проектами. Высокий уровень описания позволяет значительно быстрее и продуктивнее выполнять анализ выбора компромиссного решения для архитектуры, чем это можно сделать на RT-уровнс. Более того, верификация системной архитектуры и других системных атрибутов происходит быстрее, чем при использовании точной по временным параметрам или расположению внешних контактов RTL-модели. System Verilog - первый язык описания и верификации аппаратуры (HDVL), который является расширением стандарта IEEE 1364 Verilog-2001 [12] и позволяет значительно повышать производительность проектирования состоящих из большого числа вентилей, с большой нагруженностыо шины проек-
33 тов. Стандарт IEEE Std. 1800-2005 [11] представляет язык SystemVerilog (Accellera), предназначенный, главным образом, для создания непрерывного процесса проектирования SoC, начиная от поведения и заканчивая GDSII- описанием. Тем не менее, System Verilog также поддерживает создание TLM- моделей. Такое совпадение свойств верификации между SystemC и SystemVenlog является основой для связей между системным уровнем и реализацией кристалла. Модуль SystemVenlog's Direct Programming Interface (DPI) позволяет вызывать функции C/C++/SystemC, и наоборот, выполнять совместное моделирование (см рис. 1.10) Verilog-моделей с SystemVenlog и SystemC блоками. SystemVenlog поддерживает полную среду верификации, используя Constraint Random Generation, Assertion Based Verification и Coverage Driven Verification Он может быть применен для HW-проектирования и верификации. SystemVenlog может быть частью среды Verilog or VHDL TestBench (ТВ), частью проекта или внешнего модуля. Например, проектировщик может использовать возможности Random Generation, включив некоторые из свойств SystemVenlog Random в текущий ТВ без необходимости иметь полную среду верификации. Таким же образом инженеры- проектировщики могут включить некоторые ассерции, как часть полного симулятора кристалла, для верификации правильности шины или протоколов. Язык е - первый коммерческий язык верификации Был создан разработчиками Yoav Hollander и Amos Noy. Основная идея его появления - предоставление возможности создания спецификации проекта (е для English), его тестирования и верификации. Для работы с языком е компанией Vensity был разработан инструмент Specman, который включат компилятор и debugger Язык е используется также для созданий testbench проектов, при этом инструмент Specman должен быть подключен к средству моделирования HDL- кода. Позже компания Vensity была куплена фирмой Cadence, a Specman был включен в более сложный пакет для верификации Incisive, разрабатываемый Cadence Язык е - это первый язык, в который введены псевдослучайный генератор, генератор тестов и возможность проверки результатов моделирования, чго дало возможность описывать testbench с помощью одного языка. Ранее для генерации псевдослучайных последовательностей использовались дополнительные средства, подключаемые к тестируемому устройству в виде специальных модулей. Язык е породил новую концепцию программирования - Aspect Onented Programming (AOP). Это дало возможность пользователям языка е расширять код. добавляя дополнительные константы, функциональности или перезаписывать функциональности. Различие между object onented и Aspect oriented технологиями заключается в возможности выполнять расширение функциональности только для некоторых аспектов базовых классов. Язык верификации Vera - это разработка компании Sun Micro Systems, которая использовала его для внутренней верификации ASIC-проектов. Позже язык VERA с компилятором VERA был продан фирмой System Science, от которой он впоследствии перешел к компании Synopsys В настоящее время
34 компания Synopsys выпустила новую версию языка Vera - Open Vera, которая поддерживается VCS компилятором Методология верификации SystemVenlog основывается на трех типах блоков, которые могут применяться отдельно или все вместе- 1) Stimuli. Проект, использующий автоматически 1екерируемые сценарии с псевдослучайными последовательностями (constrained-random - CR) генерирования тестов. 2) Check. Проверка функционального поведения проекта (ассерции) и выходных данных (scoreboard) на предмет верификации правильности операций. 3) Measure Метрика функционального покрытия для обеспечения обратной связи при генерировании и анализе выполнения процесса верификации. Использование методов верификации, которые включают процесс моделирования, отладки и оценки покрытия, называется Coverage Driven Verification. 1.5.2. Основы методологии TLM. Основной концепцией TLM (Transaction Level Modeling) является создание модели уровня детализации, достаточного для решения задачи проектирования компонентов системы. Анализ только отдельных деталей позволяет значительно повысить скорость верификации моделей. Концепция TLM является независимой от каких-либо языков, однако основывается на языках высокого уровня программирования, например, таких как SystemC или System Verilog. Transaction Level Modeling предлагает bit-true, address-map accurate, cycle-less модели. TLM определяет гранзакцию (SoC-событие), как мгновенную передачу данных (коммуникацию) или синхронизацию между двумя модулями, определенными hardware'softwarc системной спецификацией. Термин TLM определен для соответствующего ESL (Electronic System Level) уровня проектирования [17-21]. Предполагается использование язы ков программирования высокого уровня для моделирования аппараты на высоком концептуальном уровне, не вдаваясь в детали ее реализации. К таким языкам можно отнести SystemC, SpecC, Hpascal, System Verilog, Hard wareC. Модели абстракции. Основная концепция TLM - коммуникации между системами и подсистемами и их функциональность могут быть разработаны и детализированы независимо друг от друта. По принципу детализации коммуникаций и ф>ккциональностей модели могут быть поделены на Un-timed (UT), Approximately-timed (AT), Cycle-timed (CT) (рис. 1.11) [18]. Модели, поддерживающие детальное потактовое (cycle-timed) описание функциональностей и коммуникаций, являются сгруктурами уровня передачи данных (RTL - register-transfer level). Модели без использования детализации времени при описании функциональностей и коммуникаций (un-timed- модели"* называются SAM (System Architectural Model) моделями. SAM- модель является средством коммуникации между группами проектировщиков алгоритмов, программного обеспечения и аппаратуры К остальным четырем структурам, представленным на рис. 1.11 и обозначенным TLM, относятся модели с аппроксимированным временем (арогохь mately-timed) Они используют статическое или расчетное время, или временные требования подсистем.
35 В табл. 1.4 приведен список моделей абстракции, используемых при проектировании SoC. BFM (Bus Functional Ivlodel) модель является самой распространенной из TLM-моделей. Остальные три - не имеют общепринятых имен Для них использовались имена, определенные в публикации Gajski и Cai [18]. На практике все из предложенных моделей не являются обязательными для выполнения проектирования, как правило, используются две или три из них. На начальной стадии проектирования нет необходимости точного описания процесса передачи данных через шину, поэтому применяется модель, в которой этот шаг выполняется за одно событие или транзакцию (component-assembly model). (тш) (RTL) (тш) (тим) фт; (тш) Un-Timed Approximate- Cycle More Accurate Timed Timed Communication Рис 1 li Модели абстракции представления цифровых scipoilciB Таблица 1 4 Модели цифровых усгройсп Модель SAM Т L М Component assembly Bus arbitration Bus functional (BFM) Cycle-accurate computation RTL Коммуникации l___JiT UT AT CT AT CT Функциональность UT I A1 AT AT CT CT На следующем этапе проектирования может оказаться важным знание точного числа тактов при передаче информации для каждого сшнала внутри блоков. Однако процесс передачи данных по шине рассматривается при этом как одна транзакция или событие (модели bus-arbitration или cycle-accurate). Когда спецификация становится полностью определенной, шина моделируется с помощью транзакций или событий для изменения сигнала (bus functional or RTL model) В табл. 1.4 модель component assembly использует одно событие (1 event), которому в модели bus arbitration соответствует пять собьний (5 events), а в RTL-модели - около 75 событий (75 events). Точное число тактов зависит от алгоритма моделирования Диаграмма иллюстрирует гребования к вычисле- More Accurate Cycle Timed Ц Approximate- ^ Un-Timed
36 ниям в различных моделях и причину того, что многие команды проектировщиков работают с ТЪМ-моделями. Методология проектирования с TLM. Новая технология проектирования состоит из двух частей: стандартной - от RTL до создания или прошивки микросхемы (layout flow) и дополнительной - от системного уровня до RTL. Проектирование начинается с создания системной спецификации, представляемой в виде документа на бумаге. Основываясь на спецификации, системный проектировщик выполняет разделение архитектуры устройства на hardware/software составляющие. Следующим этапом является TLM Одним из предназначений TLM является обеспечение фазы параллельной разработки hardware/software. В этом случае TML служит как универсальная исходная точка для software и architecture команд проектирования, для обеспечения раннего проектирования программного обеспечения и структурного анализа архитектуры Она также используется командами тестирования для разработки среды верификации и тестов, обеспечивая, таким образом, их готовность на момент разработки RTL-платформы. Между тем проектировщики hardware создают RTL-проект для системы, разработанной на основе SoC RTL-платформы. Таким образом, достигается hardware/software совместное проектирование, что является одним из основных отличий новой методологии от классической Поскольку для проектировщика также является доступной RTL платформа, с ее помощью могут быть решены задачи: проверки совместимости при моделировании проекта с ожидаемыми параметрами, hardware верификации при низкоуровневой интеграции software с hardware. Эти задачи решаются параллельно с шагами эмуляции синтеза и анализа результатов имилементации. Тройная абстракция. Новая методология проектирования определяег структуру тройной абстракции- функциональный вид SoC; архитектурный SoC; микроархитектурный вид SoC 1) Функциональный SoC (SoC Fimctionai View). Самый высокий уровень абстракции, изучает поведение системы с точки зрения пользователя. Функциональный вид разрабатывается без внесения каких-пибо деталей реализации (архитектуры или адресного пространства). Модель представляет собой программы, реализующие алгоритм функционирования устройства. Параметры производительности системы описываются отдельно в виде бумажной спецификации.2) Архитектурный вид SoC (SoC Architecture View). Является более низким этапом проектирования, который реализуется TLM-моделями. Кроме того, архитектурный вид применяется инженерами верификации в качестве справочной модели, которая выступает в качестве золотого эталона для генерирования функциональных тестов, используемых для верификации устройства на дальнейших стадиях проектирования 3) Микроархитектурный вид SoC - это самый нижний уровень тройной абстракции. Содержит всю информацию для выполнения временного моделирования по синхротактам (cycle-accurate). Общепринятой практикой для этого уровня является использование RTL-моделей, созданных с помощью языков описания аппаратуры, таких как VHDL [13-15] или Venlog [15,16]. В [19] иллюстрируются ситуации использования микроархи-
тектурного вида SoC, а в [20] описываются пути применения многоуровневых моделей для создания проектов. В общем случае современный процесс проектирования может быть представлен схемой, изображенной на рис. 1 12. Проектирование начинается с создания Product Requirement Document (PRD), составляемого заказчиком или маркетинговой группой. На основе PRD разрабатывается SAM, на этом этапе вносятся необходимые изменения и уточнения в PRD Затем SAM преобразуется в один из видов TLM-моделей, например, сначала в component assembly модель, а затем в bus arbitration модель При выборе соответствующего языка для SAM такая модель может быть повторно использована (reuse) и путем детализации преобразована в TLM. 1 1 SW Design and Development - j4 й Requirement Definition i Requirements Document System Architecture Model Development . . ^ . SAW i Transaction Level Model Development 1 L__Ii^__ i HW Refinement I RTL to GDSII Пол —Г 1 -1 1 1 HW Verification Environment Рис. i 12 Современные этапы проектирования SoC Задачи, решаемые с помощью TLM-моделсй: 1) Определение свойств им- плементацни, таких как HW/SW partitioning; HW partitioning между ASIC, FPGA и board реализациями; разработка архитектуры шины; определение или выбор сопроцессора 2) Разработка платформы для системною программного обеспечения. 3) Создание золотого эталона для функциональной верификации аппаратуры 4) Разработка микроархитектуры аппаратуры и основ для создания детальной спецификации hardware. К преимуществам использования TLM-моделей относятся, возможность более ранней разработки software; раннее и качественное создание testbcnch для выполнения функциональной верификации, наличие единого и непрерывного пути про-
38 ектирования от требований пользователя до разработки детальной спецификации hardware и software. 1.6. Выводы по технологиям реализации SoC 1. Миллиарды компактных коммуникационных, вычислительных изделий и памяти, используемых в человеческой деятельности, позволяют сделать вывод о полном доминировании цифровых систем в пакетах (кристаллах) на рынке электронных технологий уже в ближайшие пять лет. Эволюционный путь преобразования SoC в SiP является хорошим примером для адаптации существующих технологий тестирования цифровых систем на кристаллах к новому конструктивному поколению - цифровых систем в пакетах 2. Актуальной для рынка электронных телнологий представляется проблема создания технологий, моделей и методов системного проектирования цифровых шделий в пакетах (кристаллах) на основе использования HDL-языков (Verilog, System Venlog) и стандартов тестопригодного проектирования программных продуктов в виде механизма ассерций. 3 Представлены сравнительные характеристики языков описания аппаратуры. Язык Venlog предназначен для эффективного описания функциональных компонентов и инфраструктуры диагностического обслуживания на основе IEEE 1500 стандарта, testbench-технологий, синтеза и имгыементации цифровых систем на кристаллах. Язык System Verilog - для описания спецификации функционалыюстей SoC и ассерционной избыточности с последующей верификацией проекта 4. Сформулированы наиболее существенные и актуальные, с точки зрения авторов, задачи в области изучения и применения HDL-языков: 1) Классификация и различия синтаксических и семантических особенностей языков описания аппаратуры. 2) Системное описание иерархической инфраструктуры сервисного обслуживания цифровых систем в пакетах на основе IEEE стандартов тестопригодного проекгирования в качестве дополнения к основной функциональности. 3) Разработка и описание системных моделей и технологий для тестирования, верификации и исправления ошибок в HDL- коде. 4) Эффективное использование системных библиотек ведущих компаний для верификации и синтеза цифровых изделий, э также компонентов SiP: памя1ь, логика, программные л управляющие модули. 1.7. Тестирование и верификация HDL-моделей компонентов SoC В подразд. 1.7-1.12 предлагаются технологии тестирования и верификации цифровых систем для диагностирования и исправления ошибок HDL- моделей, основанные на совместном использовании механизма ассерций и тестопригодного проектирования Предложенные модели и методы позволяют существенно повысить качество проектируемых компонентов цифровых систем на криетачлах и уменьшить время разработки. Ведущие компании планеты, такие как Cadence, Synopsys, Mentor Graphics большое внимание уделяют системной стадии создания цифровых изделий
39 на кристаллах, практически неподдающейся автоматизации Здесь на процесс отладки программного кода теряегся до 70% общего времени, определяемого как time-to-market Предлагается технология тестирования и верификации системных HDL-моделей, ориентированная на существенное повышение качества проектируемых компонентов цифровых систем на кристаллах (yield) и уменьшение времени разработки (time-to-market) путем использования среды моделирования, )естопригодного анализа логической структуры HDL-программы и механизма ассерций Технология позволяет осуществлять поиск ошибок с заданной глубиной в программном HDL-коде за приемлемое для разработчика время путем введения в критические точки программной модели ассерционной избыточности, вычисляемые с помощью синтезированных логических функций тесто- пригодности. Последние определяют качество программного кода путем синтеза дизъюнктивной нормальной формы (ДНФ), для которой оценка по Квайну формирует количественную характеристику тестопригодности компонента или программы, представленной последовательностью операторов Используемые в hardware design and test критерии тестопригодности (управляемость и наблюдаемость) применены для оценки качества программного кода в целях ei о улучшения и эффективного диагностирования семантических ошибок Цель -- улучшение технологии тестирования и верификации цифровых систем для диагностирования и исправления ошибок HDL-моделей путем синтеза гранзакционного графа программы, совместного использования механизма ассерций и технологий гестопригодного проектирования стандарта ШЕЕ 1500 Задачи исследования 1. Классификация технологий тесгопригодного проектирования и верификации системных HDL-моделей для создания цифровых систем на кристаллах. 2. Разработка обобщенной модели верификации и тестирования системной HDL-модели на основе использования ассерций как адаптация технологий IEEE 1500 стандарта к проверке программного HDL- кода. 3. Разработка метрики оценивания тестопригодности HDL-моделей на основе синтеза логических функций тестопригодности 4. Применение модели ассерций для верификации IP-core фильфа дискретного косинусного преобразования. 5. Практические результаты и дальнейшие исследования. Источники исследования: 1. Технологии и средства создания гестов и testbench представлены в работах [22-23]. 2. Модели и методы верификации системны моделей на основе механизма ассерций описаны в публикациях [24-27]. Тестопригодное проектирование программных продуктов использует стандарты IEEE [28-30], а также инновационные решения для верификации и анализа тестопригодности системных HDL-моделей [31-38]. 1.8. Тестопригодиость программно-аппаратных продуктов Инициирующим ядром появления новых технологий тестирования и вери фикации в программной и компьютерной инженерии следует считать силиконовый кристалл, являющийся основой для создания вычислительных и/или коммуникационных устройств. Кристалл рассматривается как испыта-
40 тельный полигон для апробации новых средств и методов трассировки, размещения, синтеза и анализа компонентов. Технологические решения, выдержавшие испытания временем в микроэлектронике, далее захватываются и адаптируются к макроэлектронике, представленной компьютерными системами и сетями. Вот некоторые исторические факты, связанные с преемственностью развития и взаимопроникновения технологических инноваций в программных и аппаратных продуктах. 1 Стандарты граничного сканирования [24, 26, 38] на уровне платы и кристалла привели к появлению механизма ассерций для тестирования и верификации программных продуктов [32-38]. 2. Метрику анализа тестопригодности [22,23] (управляемости и наблюдаемости) цифровых структур можно адаптировать для оценки программного кода в целях определения критических мест и последующего улучшения программного продукта относительно уменьшения времени верификации и повышения его качества. 3. Технолоши анализа качества покрытия [38] наперед заданных неисправностей тестовыми последовательностями используются для создания таблицы покрытия функциональностей программных продуктов модулем testbench в целях оценки достоверности тестов, установления диагноза и исправления ошибок. 4. Графовые модели регистровых передач Тэтта-Абрахама [35], С Г. Шаршунова [36-37] используются при тестировании программных продуктов, которые, путем их структурно-логического анализа, приводятся к более технологичной форме. Таковой является транзакшюнный граф как модель HDL-кода. записываемый в виде алгебраической формы представления графа для подсчета тестопригодности в целях определения критических компонентов (точек) программы для установки ассерций. 5. Разделение автомата на управляющую [22,27] и операционную части применяется для упрощения процесса синтеза testbench и верификации программного кода на основе синтеза графов управления и транзакционной передачи данных. 6. Кривая жизненного цикла аппаратного изделия [28,29] также адекватно отображает временные стадии изменения yield при создании, тиражировании и сопровождении программного продукта. 7. Платформенно-ориентированный синтез [21] HDL-кода (platform-based electronic system-level design) с использованием существующих наборов компонентов (chipset) под управлением GUI изоморфен технологии объектно-ориентированного программирования на основе использования наработанных ведущими компаниями библиотек. Применение технологии Electronic System Level (ESL) [21,31] в программировании дает возможность использовать программные компоненты готовых функциональностей из базовых библиотек, используемых для создания новых программных продуктов. В этом случае основная процедура проектирования заключается в выполнении мэппинга, который ориентирован на покрытие функций специфи-
41 кации существующими компонентами, где новый код составляет не более 10% проекта. 8. Понятие геста проверки неисправностей или функциональностей, используемое для тестирования аппаратных проектов, применяется в качестве testbench [32-38] для верификации и отладки программных продуктов, представленных описаниями на уровне системных языков (C++, SystemVenlog, Vera, e). 9. Платформенно-ориентированный синтез [21] testbench (platform-based test- bench synthesis) с использованием существующих библиотек тестов (AUNT; для reusable стандартизованных функциональных компонентов используется для генерирования тестов программных модулей на основе наработанных библиотек от ведущих компаний планеты. 10. Стандартные решения сервисного обслуживания функциональностей F- IP в рамках инфраструктуры I-IP [24-28] используются для создания инфраструктуры встроенной верификации компонентов программного продукта в целях устранения ошибок дефектного программного модуля. 11 Обеспечение двумерности структуры взаимосвязанных функциональных компонентов (IP-cores) создаваемого программного продукта ориентировано на использование мультиядерных архитектур для технологичною распараллеливания вычислительных процессов 1естирования и верификации [21,24,33,37], что существенно уменьшает параметр time-to-market. 12. Создание адресного пространства для функциональностей SoC, реализованных как в аппаратном, гак и в программном исполнении [29-31], предоставляет цифровой системе замечательное свойство самовосстановления работоспособности профаммных и аппаратных компонентов путем использования альтернативных или избыточных ресурсов инфраструктуры сервисного обслуживания I-IP. Примером тому может служить мультипроцессорное исполнение аппаратных продуктов, которое является устойчивым к возникающим дефектам. При этом отказавший адресуемый компонент может быть заменен резервным в процессе выполнения функциональности. Свойство адресуемости используется при создании критических профаммных продуктов, где наличие адресуемых диверсных (мультиверсных) резервных компонентов обеспечивает отказоустойчивость системы при возникновении дефектов 13. Интересной и рыночно-привлекагельной является проблема автономного внутрикристального встроенного тестирования, диагностирования и ремонта без применения внешних средств [29-31]. которой занимаются все ведущие компании. К решению проблемы привлекаются современные беспроводные и Internet технологии дистанционного сервисного обслуживания. Обратная сторона медали заключается в несанкционированном доступе к содержимому кристалла на расстоянии, что может привести к нежелательным деструктивным последствиям и выводу из строя цифрового изделия. Тем не менее, специфика современных цифровых систем на кристаллах заключается в удивительной возможности исправлять ошибки т расстоянии, благодаря нал и чию связи кристалла с внешним миром посредством Internet или беспровод-
ных технологий (wi-fi, wi-max, bluetooth, satellite), присутствующих в силиконе Дистанционная коррекция программных ошибок становится возможной благодаря использованию памяти (занимающей до 94% силикона) SoC для хранения программ, куда можно, в случае обнаружения некорректности, записать новый код, не имеющий ошибок. Дистанционная коррекция аппаратных ошибок стала возможной благодаря исполыованию программируемых логических интегральных схем, куда можно, в случае обнаружения неисправности, записать новый bit stream, не имеющий ошибок, который фактически создает новую аппаратуру путем повторного программирования кристалла. Сближение и взаимопроникновение технологий приводит к изоморфным методам проектирования, тестирования и верификации по oi ношению к программным и аппаратным комплексам, что по существу является закономерным процессом ассимиляции прогрессивных концепций и решений. Тому способствует факт, что наиболее важные параметры жизненного цикла изделия, такие как time-to-market и yield становятся соизмеримыми по времени и выходу годной продукции Кривая жизненного цикла аппаратного изделия, представленная на рис 1.13, с точностью до изоморфизма отображает временные этапы программного продукта, который проходит аналогичные стадии проектирование, увеличение объема выпуска продукции, производство с доработкой и сопровождением изделия. В контексте жизненного цикла существуют две актуальные проблемы, которые связаны с поднятием графика (кривой) вверх по оси ординат, а также с компрессией упомянутой кривой по временной оси, означающей уменьшение параметра time-to- market. Здесь повышение выхода годной продукции происходит на всех стадиях. 3) проектирование - за счет быстрого устранения ошибок путем внедрения новых 1Схнологий; 2) прототипированис - за счет исправления кода, имплементированного з память системы на кристалле, 3) производство за счет выпуска программ, корректирующих ошибки, посредством Internet или спутников. Проектирование Улучшение прототипа Коррекция изделия Рис 1 13. График жизненного цикла программно-аппаратного комплекса
43 Согласно [32-38J стоимость верификации программно-аппаратных продуктов на основе ASIC (Application-Specific Integrated Circuit - специализированная интегральная микросхема), IP-core (Intellectual Property Core - отлаженный функциональный аппаратный модуль, готовый к имплеметации в кристалл), SoC составляет 70% or общих затрат проектирования. Аналогичная оценка, около 80%, определяет размерность testbench-кода от общей длины формального описания проекта. Задачи, решаемые в процессе верификации, связаны с устранением ошибок проектирования как можно на более ранней его стадии в целях приведения кода прототипа в соответствие с его спецификацией. Пропуск ошибки увеличивает ее стоимость на порядок при переходе or уровня проектирования блока до уровня кристалла и далее к системе. Введение в проект программной избыточности - механизма ассер- ций [35-37] - позволяет выполнять анализ основных специфицированных условий в процессе моделирования проекта и диагностировать ошибки в случае их обнаружения на ранних стадиях проектирования программы (С+-, System Verilog, Vera) или аппаратуры (HDL) 1.9. Инфраструктура процесса верификации и тестирования проеша Модель процесса верификации проекта на системном уровне можно представить в виде обобщенного уравнения диагноза Т © S = L или более подробно для обнаружения ошибок в программных компонентах (i,F)0(S.A) = Ls. П.1) Здесь- T,F - тестовые воздействия функциональное покрытие эталонной модели с ожидаемыми реакциями; S,A проверяемая HDL-модель и механизм ассерций для верификации и точного диагностирования ошибок в программном коде. Тестирование аппаратной реализации основано на использовании ло!Ической операции суммы по mod 2 (Хог) для аналитического выражения (Т)Ф (S,B) = Lh., где В - избыточность в виде регистра граничного сканирования от стандарта IEEE 1500, используемая в качестве дополнения к функциональной модели для обеспечения требуемой глубины диагностирования компонентов цифровой системы на кристалле При этом Ц,Ц - списки ошибок, получаемые на стадиях верификации проекта и тестирования готового цифрового изделия. Для понимания соотношений между ключевыми понятиями: верификация. валидация, ассерция - вводятся следующие определения [33-35]. Верификация - есть процесс анализа системы или компонентов для определения корректности формальных преобразований входного описания в выходное на каждой стадии проектирования. Валидация - есть процесс определения работоспособности системы и ее компонентов путем проверки ее соответствия основным требованиям спецификации после выполнения каждой стадии проектирования. Сертификация - есть экспертная (юридическая) гарантия валидности системы (компонентов) требованиям спецификации при ее ис- потьзовании по назначению.
44 Ассерция - есть инверсное HDL-высказывание системного уровня, предназначенное для раннею определения ошибок проектирования относительно требований спецификации при моделировании проекта на тестовых воздействиях до и после выполнения синтеза. Типы и свойства ассерций. 1) Предельное число ассерций есть диверсная модель проекта, на пракжке число ассерционных операторов - 5% кода проекта. 2) Мгновенные или однотакт- ные (immediate) ассерций - принадлежат модели проекта, вставляются в текст программы в форме инверсных if-операторов и выполняются в общем порядке следования строк кода. 3) Параллельные ассерций (циклические или многотактные) - моделируются параллельно и независимо от исполняемой модели проекта. Вычислительный процесс организуется в циклы моделирования, что позволяет анализировать состояние проекта в моменты времени, определенные синхроимпульсами ввода ассерций. Assert операторы находятся в теле программы. Параллельная ассерция защищена от состязаний сигналов в модели наличием таймслота симуляции. Он задает моменты считывания (preponed) сигналов и вычисления (postponed) ассерций. 4) Внешние ассерций представляют собой диверскую модель проекта в виде отдельного модучя, записанного на языках System Verilog или PSL. Внешние ассерций наблюдают за сигналами портов функционального модуля и передают их из проекта в тестовую среду. 5) Ассерций, в общем случае, не являются синтезируемым подмножеством IIDL-языков Более того, механизм ассерций, функциональные покрытия и генераторы тестов, направленные на выявление ошибок проектирования, формируют HVL-языковую среду 6) Ассерций ориентированы на раннее выявление функциональных ошибок всех стадий преобразования модели, в том числе и послесинтезных ошибок, без выполнения процедуры синтеза. Формально ассерция записывается в виде предиката А, =Т, ®S, -»d(A,), который на множестве состояний эталонной реальной моделей принимает значения {true - 1, false - 0, don't care - X). Здесь X - неопредепенное состояние ассерций или ее отсутствие для анализируемого программного компонента В соответствии с упомянутым определением и по функциональной реакции d(A,) на сравнение состояний Т, Ф5, ассерций можно дифференцировать на три типа d(A,)- {Ac,A.g,Aw} - прекращение верификации HDL-модели, переход к проверке следующего программного блока, выдача сообщения на консоль. Механизм ассерций - есть система высказываний, представленная в виде вектора А = (Aj,A2>- -,A,....,An), а также средства их анализа d(A), предназначенные для верификации и поиска ошибок HDL- модели системного уровня в пространстве и во времени. Цель введения механизма ассерций - получение точного диагноза для устранения семантических ошибок HDL-кода программы. Вектор ассерций ориентирован на проверку функциональное гей и логического состояния компонентов HDL- модели во времени и пространстве. Такие же функции - повышение глубины диагностирования - имеют место быть и в стандартах граничного сканиро-
45 вания (ILEE 11.49, IEEE 1500), где тестирование компонентов цифровой системы регулируется контроллером тестового доступа (ТАР) Структурная модель процесса проектирования в части взаимодействия процедур вапидации и верификации представлена на рис. 1 14. Здесь следует отметить, что верификация определяет корректность выполненных преобразований на рассматриваемом этапе проектирования, а валидация определяет соответствие технического состояния системы требованиям спецификации на каждой стадии проектирования (Spec - спецификация, SL - System Level - системный уровень, RTL - Register Transfer Level - уровень регистровых передач, Proto - Prototype - прототип) Рис 1 14 Взаимодействие процессов ва тидацли и верификации Стратегии верификации и тестирования имеют различные модели для приложения технологий, ориентированных на сокращение параметра time-to- market. И|еративньш процесс верификации ориентирован на исправление ошибок HDL-чодсли системною уровня, полученной по спецификации изделия (рис 1.15). Конечный результат есть netiist или отлаженная HDL- модель регистрового уровня Следующий итеративный процесс - синтез и имплементация проекта в силиконовый кристалл Тестирование здесь проверяет корректность аппаратной имплементации HDL-модели в регистровый или вентильный уровень описания проекта в микросхеме программируемой логики. Для кристаллов ASIC такая технология нецелесообразна, поскольку перепрограммирование ошибки здесь будет стоить до миллиона долларов. С учетом приведенных определений и пояснений модель среды или макро- нроцесса верификации программной стадии проекта ориентирована на \меньшение времени создания изделия и повышение уровня выхода годной продукции за счет использования избыточности кода в виде механизма ас- серций и использования Testbench совместно с метрикой определения качества теста или функциональной полноты. Проектирование Имплементация Верификация Тестирование Рис 1.15 Стратегия разработки проекта
46 Инфраструктура тестирования и верификации HDL-модели представлена на рис. 1 16, где спецификация проекта, описанная на формальном языке высокого уровня, является исходной информацией для- создания метрики оценивания качества теста в виде функциональною покрытия, HDL-модели проекта, теста с эталонными реакциями - Testbench, асссрционной структуры, служащей дополнением к основной модели, что необходимо для ускорения проверки и отладки проекта ! Спецификация проекта i I I Testbench t Устранение | ошибок ' IZZ Рис 1 16 Среда верификации проекта Среда верификации представлена системой моделирования, блоком тестирования (Testbench), механизмом ассерций (Assertion Engine) и собственно системным кодом модели на языках VHDL, Verilog. System Verilog. Модуль Testbench задает входные стимулы и эталонные реакции на них, записанные на HDL-языках, ориентированные на проверку фу национальностей (переменные, функции, последовательности), параметры коюрых определяются в корзине функционального покрытия. Механизм ассерций - модельная избыточность, дополняющая Testbench, в части проверки внутренних по времени и пространству состояний проекта, представленная вход-выходными высказываниями и предназначенная для ускорения тестирования, верификации, диагностирования и исправпения ошибок проектирования в системном коде Ассерций можно оенерировать не только по спецификации, но и по HDL- модели, убирая ненужные конструкции, а остальные - модифицировать к форме ассерций При этом существует вероятность повторения в ассерций программной ошибки HDL-модели, которая не будет идентифицирована в процессе моделирования. Упрощенная структура взаимодействия механизма ассерций с другими компонентами среды верификации и диагностирования показана на рис 1.17 Testbench представляет собой эталонную модель объекта проектирования з виде входных и выходных реакций. Часто вместо Testbench используется уже проверенная и доступная модель другой компании, относительно которой проверяется верифицируемая модель (MUV - Model Under Verification). В этом случае необходимо иметь генератор входных последовательностей или Testbench без выходных реакций. Блок механизма ассерций является надстройкой для Testbench, верифицируемой модели и служит для сравнения результатов моделирования в целях формирования двоичного вектора экспе- Среда моделирования Ассерционная модель
ркментальной проверки, в качестве которою здесь выступает вектор (состояний) ассерций. A = (A1.A2,..,A,,.,An),A1 =T,©S„A1 = {0,1,Х}. Хотя ассерционные операторы могут присутствовать в теле программы Testbench или MUV, они не являются принадлежностью упомянутых программ Assert-операторы обрабатываются отдельно и параллельно с моделированием MUV, поэтому они не оказывают влияния на функционирование HDL-модели проекта. Кроме того, ассерций не являются синтезируемыми и заканчивают свое существование после отладки системного кода Имея аналоги операторов в HDL-языках в виде условных команд, assert-операторы предназначены для сравнения технических состояний компонентов эталонной и проектируемой моделей в целях последующего принятия решения о продолжении процесса моделирования, прекращения или перехода к выполнению анализа другого фрагмента программного кода Тест (Testbench) Верифицируемая модель -J С Механизм ассерций Рис 1 17. Технология использования ассерций для верификации проекта Интерес представляет и последовательность действий по созданию среды верификации, где единственным аргументом является спецификация проекта, все остальное - производные от нее. На рис. 1.18 изображена структура взаимосвязей процесса проектирования и диагностирования для исправления ошибок в 1 IDL-коде программы. j Спецификация Рис 1.18 Маршрут верификации проекта Практически, если выполнены условия тестопригодносги и правильно расставлены ассерций в критических точках программного кода для диатности- рования всех компонентов, то процедура совместного моделирования механизма ассерций и HDL-модели может однозначно идентифицировать последовательность строк программного кода с семантической ошибкой
48 Testbench и вектор (матрица) ассерций должны создаваться независимо от HDL-модели и другим разработчиком Это обеспечивает диверсификацию упомянутых моделей относительно единой спецификации, а также обнаружение и исправление ошибок в HDL-проекте. Таким образом, в процессе создания системного кода проекта разработчик должен ориентироваться па технологичные и простые процедуры процесса верификации HDL-модели, что означает - выполнять достаточно простые условия тестонригодности (см. рис. 1.17, 1 18). Здесь необходимо решать задачи: 1) Написание Testbench и генерирование функциональных покрытий. 2) Определение критических точек программного кода для установки ассерций. 3) Корректное написание самих ассерций 4) Создание эффективных алгоритмов диагностирования семантических ошибок в HDL-коде на основе анализа системы ассерций, как реакции на тест эталонной и реальной моделей в процессе моделирования проекта 1.10. Аналитическая модель инфраструктуры верификации Для идентификации обобщенного состояния HDL-модели формируются эталонные реакции (сигнатуры) критических точек (переменные, регистры, память) во времени и в пространстве. Затем выполняется анализ HDL-модели в целях ее диагностирования путем сравнения эталонных и экспериментальных реакций (сигнатур) для формирования ассерционного вектора, описывающею сравнение состояний (эталонного и реального) компонентов объекта во времени и в пространстве. Цетесообразно формировать ассерционный вектор независимо от HDL-модели проекта Ассерционная и функциональная модели обрабатываются параллельно и независимо дру! от друга средой моделирования Ассерционная модель определяе! отклонения от поведения объекта в существенных точках пространственно-временной эталонной структуры Формат ассерций должен соответствовать формату HDL-модели проекта Ассерций ориентированы на диагностирование семантических ошибок HDL-модели путем использования Testbench и MUV. Аналитическая модель инфраструктуры верификации представлена в следующем виде (Р - спецификация проекта, S - soft-модель, А - ассерционная модель, Т - Testbench, F - корзина покрытия функциональностей, d - модуль диагностирования ошибок и С - условия диагностирования ошибок) M = {P,S,A,T,F,d,C}, - I)S = fuP)-(SbS2,..,S„..,Sn), 2)F-f2(P,S) = {FbF2, .,!■„. ,Fn}; 3)T = f3(P,S,F) = {T1,r2,...,T1, ,Tn}; 4) A = f4(P,S,F,T) = (AbA2,...A1,..,An); 5)d = f5(P,S,F,T,A) = (L!,L2,...L!,. ,Ln) e {Ls,Lh};
49 6)C = [UF,eF = P]A[UTl6I=F]; .=1 .=1 (1 2) 7) Ls = (T,F) © (S, A); 8) Lh - (T) © (S,B) Формула 6 в (1.2) определяет условия полноты проверки функциональностей тестом (Testbench) относительно спецификации Уравнение 7 задает функцию вычисления ошибок проектирования при переходе от системного к регистровому уровню путем использования атрибутов верификационной инфраструктуры. Равенство 8 регламентирует нахождение неисправностей на стадии эксплуатации цифровой системы на кристалле Ассерционная избыточность является функцией от критических точек HDL- модели, предельное число которых может быгь равно количеству временных фреймов функциональных компонентов, определенных спецификацией Априорно координатам вектора ассерций присваиваются значения X. Затем определяются критические координаты, число которых будет достаточным для проведения верификационного эксперимента в целях поиска ошибочных программных блоков с заданной глубиной диа! ностирования. Такие координаты идентифицируются единицами. В процессе моделирования координаты вектора модифицируются в сторону уменьшения единиц. Каждой координате вектора А ставится в соответствие список всех вершин предшественников транзакционного графа программного кода. Координатам вектора соответствует матрица достижимостей транзакционного графа или списки вершин- предшественников, заданные в любой другой форме. По фактическому двоичному состоянию элементов веитора А выполняется безусловная процедура диагностирования списка L неисправных программных блоков d(A), определяемая следующими выражениями [38]- fLe(A) = ( П А,)\( U А,); j V!(A,-1) Vi(A,=0) ]Lm(A) = ( U A,)\( U A,). (L3> [ Vi(A,=l) Vi(A,=rO) Уравнения предназначены для поиска одиночных и кратных ошибок путем использования вектора ассерционных состояний. Длина ассерцчонного вектора равна числу вершин в графе или программных блоков в функционально-логической структуре HDL-кода Векторная модель среды верификации: РП Т2 1 Т, | Гм FsT |s2 1 s, |sn 1 1 1 _ 1 1 1 [a, I A2 A, LAnJ Fm 1 L2 LkJ Urn J В процессе моделирования выполняется сравнение реакций Testbench и HDL-модели. что формирует состояния координат ассерционного вектора: А, - f(r„S,) = T, ©S,, А, = Ю.1.Х}.
Затем существенные {0.1 }-координаты вектора ассерций маскируют матрицу достижимостей для получения списка программных блоков с ошибками путем выполнения одной из процедур, определенных в (I 3) 1 10 1 Диагностирование по матрице достижимостей фафа. Демонстрация технологии диагностирования неисправных блоков представлена следующим примером. Пусть имеется функционально-логический граф HDL- модели, изображенный на рис. 1.19. Рис 1 19 Ф)нкциоьально-логический граф HDL Структура взаимосвязей 1рафа представлена матрицей м 1 2 3 4 5 6 7 8 9 1!2 !3 .415 !б1?1819 1 1 ! 1 ! ! ! ! ' Г1 Г "Г Г 1 1 Г 1 1 i i[i i \ : i J 1 ! ! ] ! ! ! ! 1 ! j ! 1 ! ! 11! ! I ! "ГТП""ГТП"ГТ- 1Г1 Г "Г 1 Г ! Т1 Г 1 j Ti rv г 1: i ■*■ ги ! 1 ; 1 ! ! 1 ! 1 : , | 1 Векторная модель диагностирования, заданная выражением (1.4), содержит списки блоков-предшественников для каждой вершины фафа, которые получены из матрицы достижимостей. Каждой вершине графа ставится в соответствие ассерция, которая в процессе моделирования, может быть доопределена значением {0,1}. Векторная модель поиска ошибочных программных блоков (1 4) для графа, рис 1.19, трансформируется к виду: Ai = А7 = А,= А4 А5 = А6 = А7 А8 X = х = х ^0 -х = х = 1 = 1 и и = S, = Ь \ L3=S3 | L4 = ч = и = L7=SS L8=SbS2 L9=S2,S Si,s4 ! S2^5 1 S3.S6 j S2,§4,87 | S3,S5,S&^] 3,S5>Sf,,S9 | В результате выполнения диагностирования по системе уравнений (1.3). заключающейся в пересечении всех неисправных компонентов, соответствующих единичным координатам вектора ассерций, с последующим вычитанием объединения всех неисправных модулей, соответствующих нулевым
51 координатам вектора А, получается список дефектных программных блоков (при условии существования только одно! о ошибочного модуля). LS(A4 = О, А7 = 1, А8 = 1) = L7 n I 8 \ L4 = -S1,S2,S4,S7nSi,S2,S3,S5,S6,S8\S1.S4=S2 При использовании второго уравнения из выражения (1 3) можно получить список всех программных блоков, которые могут иметь ошибки, при условии существования нескольких дефектных компонентов- Lm{A4=0,A7 -l,A8=l) = L7uL8\L4 = = Sj,S2-S4,S7uSi,S2,S3,S5,S6,S8\Sj,S4=S2,83,85,85 S7,S8 Для иллюстрации следующего примера диагностического эксперимента можно убрать из рассмотрения первые два вектора, которые не являются существенными для процесса обработки списков неисправных блоков на основе анализа координат ассерционного вектора L = d(A,S). Процедура вычисления списка одиночных дефектов имеет вид. ГAt =X | 1 А2 = Х | Л3 = X J А4 = X | | А5 = 0 | рС=т] J А7 = 0 J Л8 = 1 1 [ А9 = 1 1 I 1 d Г Ll=Si 1 L2=S2 J L3=S5 | L4 = Sj ,S4 J l5 = s2,s5 ! 1 L6-S3,S6 | L7 = Sj.82,84,8-7 j L8 =Si,b2,S3,S5.S6.S8 | L9 =S2,83,85,S(,,S9 |П8пЬ9)- -(L5uL7) S3.S6 Для множественных неисправных блоков на одном и том векторе ассерций результат имеет большее число дефектных модулей- Га~Г=х | Л2=Х А3 = X I А4 = X I А5 = 0 j А6=Х| 1 А7 =- 0 | А8 = 1 | |_А9 = i j d 1 4=-s, 1 1 L2=S7 J ! L3=S3 j L4=Si,S4 j 1 L5=S2>S5 J | L6=s3-S6 ! t L7 = S;,S2,S4,S7 j j L8=SbS2,S3,S5,S6,S8 1 |_^£f^. %j%i %iSJ_J j(L8uL9)- |-lL5uL7) s3,s6,
1.10 2. Диагностирование по векторно-ло[ ической форме графа Интересна векторная форма модели проведения диагностическою эксперимента Здесь представлена магрица достижимостей, встроенная в модель диагностирования, где ассерции изображены в виде троичного вектора: А X X X X 0 X 0 1 1 l : 1; 2! з i 4 LJTT L2l [L3 [ L4!i ,_L4_. ul L7.l Щ1 Lg! J? [ Г"! Г J l I ! ! 1 i] Г —1ТГ~ fj j_I 1 ! 1 ! l ! i ! ! 1 ! 5 16 17 -!-r- il Г —туг- 1 L1 l j l ; l|i! ! i 1 8 19 __]__ 1 1 1 ; ! 1 Результат поиска программных блоков выполнен при условии существования в проекте одного неисправною модуля, который записан в последней строке Процедура диагностирования на основе ассерциошюго вектора А путем модификации (1.3) к выполнению векторных операций конъюнкции. дизъюнкции и отрицания Ц(А) = ( Л А,)л( v А,), ' Vi(A,=l) Vi(A,=0) Lm(A) = ( V А,)л( v A,) VifA =1) Vi(A,=0) определена в правой части матричной модели диагностирования. Аналогичные вычисления для случая существования кратных дефектов в программных модулях проекта дают следующий результат: 1 А X X X |х ! о |х 0 1 1 L lll2l3U!5l6l7l8l9! Lu{i Li ; ; j ! l L2 i ■ 1 1" i Г 1 , 1 ._LjJ_i L!J ! L J 1 Г L U ! 1 1 ! ' J 1 ! 1 . ! 1 Ц ! ИГ"! ИГ"! Т Г 1 Г L6 J I Г1] I L*J 1 Г J .-L-7j_LilL_Jii__L.J_Li._L_ h L8 !1 ! l ; i ! ! l j l , ! i j 1 Ц ! 1 i ! I ! ! i ! Г ! ! ! l | Lrn ,' ,' ! i ! ,' ' 1 j j i'j 1 | jLm=(L8vL9)A л (17717) = [=(001001011) = ! =S3-S6'S8>S9
53 В реальности результат диагностирования гарантирует наличие хотя бы одного дефектного блока из списка компонентов, подозреваемых в наличии неисправностей, определенных в [38] 1.10.3 Диагностирование по ал:ебрологической форме графа. Предлагается процедура диагностирования HDL-модели по сгруктурно-ло!ическому (транэакционному) графу, представленному алгебраической формой описания фафовых структур [38]. Ее преимущества заключаются в компактности задания матрицы достижимостей, которая к тому же обладает свойством структуризации фафа в форме задания всех путей, нагруженных на каждую вершину. Кроме того, сочетания дефектных компонентов, определяемые конъюнктивными термами, дают более точный результат диагностирования, по сравнению с заданием неисправных модулей в виде неупорядоченного множества 3^eveHTOB Для структуры, представленной на рис. 1 19, алгебраическая форма графа и вычисление списка одиночных неисправностей имеют следующий вид' г^г }х Iх Iх 1 х 1 ° Iх 0 1 1 L 1 L]=S, L2=S2 L3=S3 L4 = S]S4 L5=S2S5 L6 =S3S5 1 ^7 =SjS4S7 VS2S7 L8 = S]S8 v S2S5Sg v S3S6S8 j L9 = S2S5S9 v S3S6S9 | „ LS=S3,S6 | 1 Ls = (L8aL9)-(L5vL7) = U(S2S5VS3S6)-S2S5- |=S3S6 Процедура анализа логических функций фафовой структуры содержит три пункта: 1. Все термы и переменные в ДНФ, соответствующей нулевому значению ассерционной координаты, равны нулю. 2. В других ДНФ, соответствующих единичному значению ассерционной координаты, левая часть коньюнктивною терма, включая переменную, ранее определенную нулем, удаляется. 3. Для единичных функций выполняется пересечение (объединение) оставшихся термов, если выполняется диагностирование одиночных (кратных) неисправных блоков. Такие преобразования ДНФ путем специального моделирования нулевых сигналов переменных в единичных, относительно ассерций, логических функциях представления фафа в целях получения списка неисправных про- фаммных модулей приведены в правой части алгебрологической модели диагностирования Следующий пример также подтверждает состоятельность анализа логических функций для вычисления множественных неисправных блоков
A X IX 1 x X 0 IX 0 1 1 L , L,=S! L2=S2 1 L3=S3 L4 = S1S4 U=S2S5 L6-S3S6 L7 = 8)8487 V S2S7 Г Lg = SjSg v S?S5Sg v S3S6Sg i L9 =878589 VS3S5S9 Lm = S3-S6>S8>S9 ! Lm=(L8 vL9)-(L5vL7), (SjSg vS2S5S8 vS3S6S8 v ^828589 VS3S6S9)- -(S2S5vS!S4S7vS2S7) = =S3S6S8vS3S6S9 /Для полученной функции Lm применение дополнительной ассерционной точки Ag = S3S6 позволяет повысить глубину диагностирования до двух неисправных блоков: [S3S6 <- А6 = 1; Lm = S3S6S8 v S3b6S9 = < [S8vS9^-A6=Q Проверка ассерционной точки А$ = 1 не исключает блок S8 из списка неисправных, но гарантирует факт наличия ошибки в компонентах S3Sg Поэтому после процедуры исправления некорректностей в блоках $38^ необходимо повторять диагностический эксперимент Что касается проверки ассерционной точки Ag-О, то она исключает наличие ошибок в блоках S3S5- Поэтому нулевая проверка всегда доставляет более ценную информацию для. диатностическою эксперимента В целях уменьшения подозреваемою множества неисправных блоков следует еще одна проверка (A3 vA9). которая устанавливает точный диагноз: --$зЧ- = S8vS9 = -А3 =1: -А9 = -А9 = После устранения ошибок диагностический эксперимент повторяется для поиска других составляющих кратных неисправностей HDL-блоков, кого- рые могут присутствовать в программном коце [10] Предложенная технология верификации является достаточно простой, ориентирована на обработку HDL-моделей большой размерности, включающей тысячи строк кода, который описывает системные структуры на языках VHDL, Veniog.
55 Технопогический маршрут верификации программного кода предсгавлен матрицей выполнения последоваюльно-параллельных процедур. 1 2 3 4 5 F = f2(P,S) Р S=f,(P) G=f4(S,F) U = f5(G,S,F) A = f6(G,U,S,F,I) Ls = d(T,F,S,A) r = t3(P.s.r) которые имеют следующее содержание в виде 5 пунктов. 1. Создание HDL-модели, Testbench, функционального покрытия по спецификации проекта в параллельном режиме 2. Синтез транзакционного графа (вершины - элементы хранения информации и дуги HDL-операторы, выполняющие транзакции между вершинами), представляющего структуру программного кода в компонентах и операторах HDL-языка Операторы циклов размещаются в одном блоке Граф не должен содержать глобальных обратных связей 3 Определение тестопригодности графа путем подсчета наблюдаемостей всех вершин для планирования верификационного диагностического эксперимента 4 Размещение ассерций в п% (25%) вершин, имеющих минимальные оценки наблюдаемое гей. Их число должно обеспечивав заданную глубину диагностирования. Ассерций должны быть управляемыми, что обеспечивает их включение или отключение в процессе итеративной верификации в зависимости от результата предыдущей проверки. Данное свойство может существенно сократить время отладки программного кода. Такой подход условного (ассерционного) зондового диагностирования широко используется при тестировании сложных аппаратных цифровых изделий 5 Диагностирование и исправление ошибок путем совместного моделирования HDL-кода, ассерций, на тестовых последовательностях lestbench при условиях полноты, определенных функциональным покрытием. После устранения ошибок в дефектном блоке процедура моделирования и диаг ности- рования повторяется. 1.11. Анализ тестопригодности HDL-проектов Достаточно существенная избыточность HDL-модели предполагает ее эффективное использование в целях повышения тестопригодности структуры разработанного или написанного кода. Существующие стандарты тсстопри- годного проектирования аппаратуры (IEEL 1500, 11.49) можно адаптировать к верификации HDL-кода системных и регистровых программных моделей. Для этою используется граф регистровых или гранзакционных передач С Г. Шаршунова [30], который предоставляет пользователю информацию о взаимосвязях булевых и регистровых переменных, памяти и интерфейсных ишь.
56 называемых транзакторами. Данные для синтеза графа получаются путем синтаксического анализа строк HDL-кода на предмет установления источников и приемников информации, которые являются вершинами (транзакторами) графа, соединенными ориентированными дугами Каждая из д>г может быть отмечена количеством нагруженных на нее операторов. Построенный таким образом транзакционный граф (TG - Transaction Graph) [38] покрывает все функциональности (транзакции) прснраммной модели и задает связи между вершинами, которые соответствую г приему, передачи и преобразованию информации. Роль транзакционного графа заключается в создании модели передачи данных в целях определения тесгопршодности всех вершин. Затем выделяется подмножество вершин, которое имеет минимальное значение тестопршод- носги, удовлетворяющее условию: V = Vi[Q(V,) < Qmm] -» Ql > 01тт , где Ql - качество покрытия тестом (testbench) неисправностей (корзины функциональных покрытий) при модификации структуры цифрового проекта или HDL-кода путем дополнительного мониторинга состояний критических вершин, для которых аппаратурная (программная) избыточность в реальных проектах составляет порядка 5% (Yervant Zonan). Основными критериями эффективности проектирования изделия на рынке EDA являются выход годной продукции (Y Yield) и относительное время создания продукта Т - time-to-maiket Совместно с относительными аппаратурными затратами проекта Z они формируют оценку Е эффективности проектирования цифрового изделия, представленную в (1 6), как приведенное к общим временным затратам время, затраченное на создание программной и аппаратной функциональности Т (S), Г (Н), умноженное на аналогично приведенные программные и аппаратные затраты Z (S)xZ (H), а также на выход годной продукции Y. Последний параметр Y = (1 - P)n^-Q' зависит от тестопригодности (качества) проекта Q, вероятности Р существования в кристалле неисправных областей и числа необнаруженных дефектов п или D. Критерий временных за фат JL также определяв гея тестопригодностью проекта Q и размерностью его программной Z(S), аппаратной модели Z(H), приведенной к дневной или часовой производительности Z (S)[Z (H)] разработчика кода (аппаратуры). Коэффициенты kq,kV/ задают части временного интервала, необходимого для написания HDL-кода - kw =0.3 и верификации - kq =0,7 проекта, kq +kw =1. Па- рамефы T+(S),T+(H) определяют время создания программной и аппаратной функциональностей, a T~(S),T~(II) - затраты для их сервисного обслуживания, которые включают:
T(Fb)J(Ts),r(A),T(Gb) n(Fb).T(Tb),T(A),T(Gs)J - дополнительный период времени на создание функционального покрытия, тестовых последовательностей testbench, механизма ассерций [регистра граничного сканирования] и грапзакционного фафа профаммной [аппаратной] модели. Размерность HDL-кода и аппаратуры для проекта определяется про- фаммными [аппаратными] компонентами. />(S) = Z(S),Z(Fs),Z(T4),Z(A),Z(Gb) [ZZ(H) = Z(H),Z(Fh),Z(Th),Z(B),Z(Gh)], где в правой части равенства представтены компоненты: функциональность, функциональное покрытие, testbench [тест], механизм ассерций [регистр фаничною сканирования], трашакционный фаф программной [аппаратной] модели. Общая модель эффективности проектирования SoC имеет вид. Ь = 1(У-1Л-2Д), Y = (i-P)n0-O); D = I-Y^>; ТЛ -_ta(S)xTa(Hi; ZA =-Z'A(S)xZA(H); t\s) = —ГФ_,тА(Н) = -T!W-- T+(S) + T~(S) T+(H)+1~(H) I ql + Qj7,(S) T-(S)=1-QrZ(rs) , ATS) | ?(A) j| Z(GS) 1 + Q[z!(Fs) Z!(Tb) Z!(A)J Z'(GS)' I qi+QJz'(H) T-(H)^1~Q|"Z(Fh) i Z(jh) i Z(B) h Z(Qh) 1 + Q[z'(Fb) Z!(Th) Z!fB)J^Zi(Gh)' T(S) = T+ (S) +1" (S); T(H) = T+ (H) 4 Т" (H);
Za (S) = ^ , Z(S) + Z(FS) + Z(TS) + Z(A) + Z(GS) z д (H) = ?Ё . Z(H) + Z(Fh) + Z(Th)+ Z(B) + Z(Gh)' Zb(S) = Z(S) + Z(Fs) + Z(Ts) + 7(A)*Z(G4); ZS(H) = Z(H) + Z(Fh) + Z(Th)H Z(B) + Z(Gh), Q = {Qh.Q4)=~2(U1xN1). n i=l V J dxvtx VI J dfvtf Здесь (1 6) интегральная опенка тестопршоцности Q = {Q ,QS} транзакци- онных фафов HDL-кода и аппаратной модели регистрового уровня функционально зависит от управляемости и наблюдаемости их вершин U,,N,, где п - количество вершин транзакционного графа. Управляемость и наблюдаемость есть метрика оценивания тестопригодности не соединительных линий, а компонентов HDL-кода, таких как регистр, счетчик, память или массивы, вход-выходные шины, векторы, логические или арифметические переменные цифровою проекта. Управляемость вершины имеет функциональную зависимость от структурной глубины dx нахождения транзактора относительно входов или длины конъюнктивного терма - !х Наблюдаемость вершины имеет аналогичную зависимость dy v ty относительно выходов. Для подсчета тестопригодности можно использовать один из параметров dx,tx(d^,t^). Оценки управляемости и наблюдаемости зависят также от процентного отношения числа ко- манд - У, Т . имеющих входной (выходной X Т" ) доступ к веошине TJ=1 J TJ=1 J при анализе данной программы, к общему количеству команд т. где х,- количество команд, формирующих доступ к входной вершине, (у,) - число команд, определяющих вершину как источник данных. 1 естопригодность Q, представленная в (1.6), зависит от управляемости U, наблюдаемости (N), а также от стоимости реализации (Z) компонентов: метрика функционального покрытия (F), testbench (В;, механизм ассерций (А), функциональность (S) Управляемость (наблюдаемость) есть функция от числа операторов, входящих в вершину (исходящих из вершины) транзакционного графа, а также or структурной глубины рассматриваемою элемента - расстояния от входов
59 (выходов) или от количества временных тактов, необходимых для управления (наблюдения) компонента в заданном состоянии на временной оси Влияние мощности Lm линий мониторинга проекта на изменение (увеличение, уменьшение) всех существенных параметров процесса проектирования цифровой системы на кристалле определяется следующим выражением: [(Lm t-> (Z(B) T, Z(A) T, T(B> t. Т(А) Т)] -> [(Y T, Q T, Df t) & &(ТА i,Tb,m *,Т1-8еп i,Td,aS 4,T!-hw 1,1 V-SW i.Lud-f I)}. Вербальное и последовательное пояснение всех символов, входящих в выражение - увеличение числа точек наблюдения в программе или аппаратуре происходит за счег добавления аппаратной избыточности в виде регистра фаничною сканирования, программной избыточности в виде механизма ас- серций, а также за счет дополнительного времени создания упомянутых компонентов. Это дает возможность существенно увеличить выход iодной продукции, тестопригоднос гь проекта, глубину диагностирования дефектов и ошибок Кроме того, существенно уменьшается время' выхода изделия на рынок, моделирования неисправностей, генерации тестов, диагностирования дефектов и ошибок, тестирования функциональности аппаратуры и верификации профаммного кода Также существенно уменьшается число необнаруженных дорогостоящих дефектов и ошибок, которое влияет на выход годной продукции Yield [Возникает интересная задача, связанная с определением минимального числа точек контроля для проверки существующим тестом необнаруженных дорогостоящих дефектов путем построения фафа неисправностей в целях определения оптимального числа линий наблюдения, создающих условия для проверки упомянутых дефектов.] Ингефальная нормированная средняя адди!явная оценка эффекшвности процесса проектирования представлена суммой функционалов, формирующих затратные (f~) и выифышные (f+) функции, зависящие от числа линий мониторинга программного или аппаратного проектов: Z(B), f ~ = Z(A), С ■= Т(В), f ~ = Т(А)}; Y;f" =Q;f' =Df}; тЛ rJ- = Tsm-r =г( gen f" =idiag- '9 '10 '11 f+ =Tt hw r &Tv_sw f+ =Lud_f}_ , 12 13 14 f(Lm) =
60 Здесь коэффициент к, определяет весомозначность функционала в формировании интегральной оценки, которая используется для нахождения оптимизированной стратегии проектирования цифрового изделия. Интегральной оценке Б можно поставить в соответствие графики зависимостей наиболее существенных функционалов от числа линий мониторинга, которые представлены на рис. ! .20. Рис ! .20 Влияние точек контроля на эффективность проектирования В левой части рис. 1.20 представлены зависимости эффективностей (Yield - выход годной продукции, Testability - тестоприготность проекта. Т sim_gen - время моделирования, генерации тестов и поиска дефектов, Time-to-Market - время выхода изделия на рынок, HW/SW_Add - дополнительные аппаратные и программные затраты для реализации IEEE 1500 регистра граничного сканирования и механизма ассерций. Faults - количество непроверенных дефектов) от числа линий наблюдения в интервале [0-0,1] Правая часть рис 1 20 иллюстрирует поведение отдельных функционалов в укрупненном масштабе (10:1) интервала [0.9-1] по оси ординат левого графика. Приведенный в (1.6) критерий гестопригоднос1ч может быть также использован и для оценки качества фаф-схемы управления вычислительным процессом. Здесь рассматриваются операторные вершины, нагруженные входными условиями, а также позиция вершины по отношению к началу или окончанию схемы управления. Позиция операторной вершины коррелирует- ся с временным тактом управления вычислительным процессом. Количество условий выполнения совокупности операций в каждой вершине, объединенное операцией Or, повышает тестопригодность графа в части управляемости Аналогично вычисляется наблюдаемость, на которую влияет структурная глубина и мощность условий, создаваемая операциями And, Or. В общем случае тестопрш одность рассматриваемой вершины ориентированного графа может быть представлена логической функцией, задаьной в виде конъюнктивной нормальной формы (КНФ). При лом управляемость и наблюдаемость будет определяться оценкой но Квайну вычислительной сложности КНФ.
В общем случае логические функции управляемости и наблюдаемости текущей вершины (транзакционного) графа задаются конъюнкцией дизъюнктивных термов - первая строка в (1.7): п? х, пУ у, 1)14= a(vTM;N[ = a(vTL; i=1 j=I nj .=lj=i "J (1.7) 2)Ur =5(лТ,;р[= v(a ф. 1=1 H IJ i=l j=I 1J Здесь функция управляемости Ur (наблюдаемости Nr) определяется конъюнкцией всех вершин-предшественников пг (преемников п%), где каждая из них имеет х, входящих (исходящих у,) дуг-транзакций, соединенных знаками дизъюнкции. Мощность дизъюнктивных термов соответствует количеству входящих в вершину дуг, а число конъюнкций есть структурная глубина местоположения рассматриваемого компонента в транзакционном графе. Далее конъюнктивная форма преобразуется к виду ДНФ - вторая строка в (1.7), где число термов для функции управляемости (наблюдаемости) хг(уг) равно всем возможным путям формирования состояния рассматриваемой вершины, а длина терма управляемости (наблюдаемости) п?(п*) есть условие достижимости вершины - структурная глубина от входов (выходов). Интересным представляется нестандартное решение, когда критерии управляемости и наблюдаемости текущей вершины транзакционного графа вычисляются на основании построенных логических функций управляемости и наблюдаемости (U,.N,) и интегральной оценки тестопригодности (Q) при использовании аппарата - алгебраической формы представления графа [10] Формулы подсчет упомянутых оценок имеют следующий вид: 1 п?кГ , ( "■=- -*IS(tLx-t$+0; Wxnt i=l j=l ' ' lmaxxnt i=!J~! Q = i-i(DIxNi), где tmax»"*^*.!!:*] - конъюнктивный терм максимальной длины для определения критерия управляемости; количество термов в логической функции
62 управляемости; количество транзакций (букв) в текущем терме функции- мощность рассматриваемой транзакции в терме. Аналогичные обозначения используются и при подсчете критерия наблюдаемости - t^iax,n(',ky, tyl каждой вершины транзакционного графа Для фрагмента графа, представленного на рис. 1.21, преобразование конъюнктивной формы в дизъюнктивную структуру для вершин V] - V3 по выражению (1.7) формирует логические функции управляемости Uf(V,) = T1vT2vT3, Uf (V2> = (Т, vT2 v Г3)Т5 vT4 vТ6 = Т,Т5 vT2T5 vT3T5 vT4vT6; Uf (V3) = (Г, vT2 vT3)T5T8 v(T4 vT6)T8 v( I7 vT9) = = T,T5T8 v T2T5T8 v T3T5T8 v T4T8 v Г6Т8 v Г7 v To. Следуя правилам (1 8), определяем управляемость компонента V3 • U(V3) = —-1~-xZ2;(tmax-|t1j^l) = ^x(l + l + l + 2-2 + 3 + 3) = 0,61. *таххп1 i=l pi Для другого фрагмента графа, представленного на рис. 1 22, преобразование конъюнктивной формы в дизъюнктивную структуру позволяет определить логическую функцию наблюдаемости вершины V; Nf (V,) = Т6 vT7(T3 v I5 vT4(T, vT2) = T6 vT7T3 vl 7T5 vT7T4T, vT7 Г4Т2; Nf(V2) = T3vr5vT4(T1 vT2) = T3vr5vr4Tivr4T2, V3 =TS vT2 Рис 1.21 Фрагмент графа пя подсчета управляемости Рис 122 Фрагмент графа для полсчета наблютаечости По правилам (1.8) также определяется наблюдаемость компонента V;
63 Для случая, когда дуги в транзакцией ном фафе имеют весовые коэффициенты b* (Ьу), показывающие число операторов, задействованных в передаче информации между вершинами (мультидуги), формулы подсчета тесто- пригодности несколько усложняются: nfk* nfkf inb;(tmax-jtj|+i) znb;(tLx-|tj|+D U,=bLLl _ .. N,=blid (1.9) 4ахХ(1ПЬ;) t^xCinbX) 1.12. Верификация DCT IP-core, Xilinx Представленные модели верификации программного HDL-кода проверены на реальном проекте Xilinx (Open Source) DCT IP-core в целях определения наличия в нем ошибок При этом удалось получить положительный результат относительно неверной семантики работы программы для последующего исправления кода. Фрагмент модуля дискретного косинусного преобразования представлен листингом 1 1 [Xilinx.com]. Вся HDL-модель насчитывает 900 строк кода System Verilog. Листинг 1 1. module Xilinx 'timescale 1ns/10ps module dct ( CLK, RST, xin,dct_2d,rdy_out), output [11-01 dct_2d input CLK, RST input[7 0] xin; /* input */ output rdy_out, wire[11 0]dct_2d, Г The first 1D-DCT output becomes valid after 14 +64 cik cycles For the first 2D-DCT output to be valid it takes 78 + 1c!k to write into the ram + 1clk to write out of the ram + 8 elks to shift in the 1D-DCT values т icik to register tne 1D-DCT values + 1clk to add/sub + 1clk to take compliment + 1 elk for multiplying A 2clks to add proauct So the 2D-DCF output will be valid at the S4th elk rdy_out goes high at 93rd elk so that the first data is valid for the next block*/ endmodule В соответствии с правилами тестопригодного анализа, приведенными выше; спроектирован транзакционный граф, представленный на рис. 1.23, который для DCT-module Xilinx имеет 28 вершин-компонентов (входная и выходная шины, логические и регистровые переменные, векторы и память). Идентификатор дуги имеет верхний индекс, обозначающий число транзакций в программе между исходящей и входящей вершинами Для каждой
вершины строятся логические функции управляемости и наблюдаемости Пример вычисления функции управляемости для вершины Е$2 имеет следующий вид L'f (В2 ) = Tl2Ml^22T2^24 Ы v T6 v vTl41T264T|r98T!40vT14irjvT14!4)) = = ГЦ Г227Т222Т225Т244 Г4 v Т|Т]82 Г^71|2Т|,Т^4 v х!2х2 х2 х2 х4 х4х2х2х2х64х64х4х4 х64х8 т8 т8 г64х4 vT28T27T22T25T24T12M3M4Ti5T15 Т]7 Т18Т19Т20Т2] 122'2зг1 т7 v Т12Т2Т2Т2Т4Т4 х2х2х2х64х64х4х4 х64х8 х8 т8 ,4x64x8x8,4 , vT28T27T22T25T24T!2T13T!4T15T!5 Т17 Т!8Т19Т20Т2!Т22Т23 !11Т2 Т8Т9 FI0 v wT4TlT12T2 х2 т2 х4 т4х2х2т2 х64х64х4т4 х64т8х8х8 w vTll13I28T27T22T25 • 24т12ЧЗТ14Т15Т]5 Т17 Т18 М9Т20Т21 [22Т23 v , ,4 г1 , 12 г2 г2 х2 -,4 г4х2х2х2х64х64т4т4х64х8 х8 т8 v 1ц Ц128 •г-'Ггг'25'24I12T13T14Ti5'is т17 48 Ч9Т20 Т21Т?2Т^3 Рис 123 i ранзакционный граф Xilmx DCT-m
65 Для вершины L] ДНФ функции наблюдаемости имеет вид „f,, ч -г12х2 х2 х2 х4 х8 х8 г 8 х64т4 п 4 х64 г64х2 7 2-, 4Х64 N (Ь])= Г28Т27Т22Т25124Т23122121Х20 1!9118Г17 Х16 f1511417 ji • Синтезированные логические функции задают все возможные пуш управления как во времени, так и в пространстве, что можно считать новой аналитической формой описания тестопригодности проекта. По ДНФ. следуя выражениям (1.8), можно определить критерии управляемости (наблюдаемости) для всех компонентов HDL-модели. Здесь можно рассматривать два варианта (сценария) обсчета программной модели 1) Учитывается только графовая структура, где вес каждой дуги равен 1, независимо от числа транзакций в программном коде. 2). Все дуги графа отмечаются реальным количеством транзакций, имеющих место между двумя вершинами транзакционного графа. Оценки тестопригодности описанных процедур могут существенно отличаться друг от друга. Пользователь должен определиться, что важнее - только структура программного кода - применить первый сценарий, или иметь более сложную и точную модель транзакций, распределенных во времени, на множестве графовых компонентов В качестве примера ниже приводится процедура вычисления управляемости для В2' U(B2) = —!—x(6 + 6 + 19 + 22^ 19-19) = 0,54. 22x6 Применение аналогичных вычислений управляемостей (наблюдаемостей) для других вершин графа (см. рис. 1.23) дает результат в виде графика, представленного на рис. 1 24. которые позволяют определить критические точки для установки необходимых ассерций. Гакой вершиной может быть компонент R|5- если транзакционный граф представлен одиночными дугами. Для случая, когда дуги отмечены реальным количеством транзакций, критические вершины принадлежат компонентам, находящимся ближе к выходной шине В2- Здесь существенным представляется не структура графа, а вес- входящей дуги, который в большей степени оказывает негативное влияние, если структурная глубина рассматриваемого компонента достаточно высока Используется формула (1 8) вычисления тестопригодности U, xN,, что дает оценку ниже, чем любой из сомножителей (управляемость, наблюдаемость). После определения управляемостей и наблюдаемостей вершин транзакционного графа выполняется подсчет обобщенного критерия тестопригодности программного кода по формуле (1 8). Для Xilinx DCT-модели такая оценка равна 0.382. Она характеризует качество проектного варианта, чго представляется весьма существенным при сравнении нескольких альтернативных решений. В качестве примера позитивного использования разработанных моделей и методов был выполнен анализ тестопригодности программного кода дискретного косинусного преобразования (DCT) из Xilinx библиотеки. Построена транзакционная модель, вычислены характеристики тестопригодности и определены критические точки (R^R^RtbR-is)- В соответствии с
66 числом и типами компонентов было разработано функциональное покрытие, фрагмент которого представлен листингом 1 2. Рис 124 Графики тсстопригочности Xihnx DCT-модсли Листинг 1.2. сО coverpoint xin {bins nnnus_b!g={[128.235]}, bins minus_sm-{[236 255]}, bins plus_big={[21 127)}, bins pius_sm={[1 -20]}, bins zero={Q},} d coverpomt dct_2d {bins mmus_big={[128 235}}, bins mmus_sm={[236 255]}, bins plus_big={[21 127]}, bins plus_sm={[1 20]}, bins zero={0}, bins zero2=(0=->0),} endgroup Для критических точек, определенных в результате анализа гестопригодно- сти транзакционного графа, разработана ассерционная модель проверки ос-
67 новных характеристик дискретного косинусного преобразования Существенный фрагмент кода механизма ассерций представлен лист ишом 1 3. Листинг 1 3. sequence flrst( reg[7 0] a, reg[7 0]b), reg[7 0] d, (<RST,d=a) ##7 (b==d), enasequence property f(a,b), // disable !ff(RST||$isunknown(a)) first(a,b); <RST |=> first(a.b), endproperry odin assert property (f(xin,xs7jn)) // $display("Very good"), else $error("The end, xm =%b,xa7_m=%b", $past(xm, 7),xa7jn), В результате верификации программной HDL-модели дискретного косинус- ною преобразования в среде моделирования Active-HDL были найдены неточности в восьми строках исходного кода HDL-модели: // add_sub1a <= xa7_reg + xa0_reg,// Последующее исправление ошибок привело к появлению исправленного фрагмента кода, который показан в листинге 1.4. Листинг 1 4. add_sub1a <= ({xa7_reg[8],xa7_reg} + {xa0_reg[8],xa0_reg}), add_sub2a <= ({xa6_reg[8],xa6jreg} +{xa1_reg[8i,xa1_reg}), ada_sub3a <= ({xa5_reg[8j,xa5_reg} +{xa2_reg[8],xa2j-eg}); add_sub4a <= ({xa4_reg[8],xa4_reg} + {xa3_reg[8],xa3_reg}\ end else if (toggleA == 1'b0) begin add_sub1a <= ({xa7_reg[8],xa7_reg} - {xa0_reg[8],xa0_reg}); add_sub2a <= ({xa6_reg[8],xa6_reg} - {xa1_reg[8],xa1_reg}), add_sub3a <= ({xa5_reg[8j,xa5_reg} - {xa2_reg[8],xa2_reg}); add_sub4a <= ({xa4_reg[8},xa4_reg} - {xa3_reg[8],xa3_reg}); 1.13. Выводы по верификации HDL-кода на основе ассерций Рассмотрены инновационные технологии тестопригодного проектирования программных и аппаратных продуктов [22-37J, ориентированные на существенное уменьшение времени верификации системных программных моделей цифровых изделий на кристаллах. 3 Показаны основные направления использования технологий тестопригодного проецирования цифровых систем на кристаллах в задачах тестирования и верификации программных HDL- моделей. 2. Представлена универсальная модель программного компонента в виде транзакционного графа, на котором решаются задачи анализа и оценки тес гопригодности в целях определения кршических точек для установки ассерций и достижения требуемой глубины диагностирования HDL-кода. З.
Предложены логические функции тесгопригодности HDL-моделей на основе использования транзакционного графа в целях вычисления оценок >прав- ляемости и наблюдаемости профаммных HDL-моделей, что дает возможность определить критические точки для последующего улучшения кода проекта путем установки ассерций 4. Показаны примеры анализа тестопри- годности путем подсчета управляемости и наблюдаемости транзакционного и управляющего фафов в целях определения критических точек с последующим решением практической проблемы поиска и устранения ошибоь в реальном DSP-проекте от компании Xilinx. 5 Практическая значимость предложенных методик и моделей заключается в рыночной привлекательности и высокой заинтересованности технологических компаний в инновационных решениях проблемы тестирования и верификации программно- аппаратных изделий на системном уровне проектирования в целях уменьшения time-to-market и повышения выхода годной продукции - yield. 6. Дальнейшие исследования направлены на разработку интерфейсов для последующей интефации моделей, методов и профаммных продуктов в технологические маршруты проектирования цифровых систем на кристаллах 1.14. Вопросы и задания 1. Назовите четыре ведущих компании планеты в области EDA - Electronic Design Automation 2. Как называются модели, поддерживающие cycie-timed описание функциональности и комму никаций'? 3 Как называются модели с an-timed детализацией времени для функциональности и коммуникации} 4 Какая из TLM-моделей является самой распространенной на рынке EDA? 5. Дать краткую характеристику языка SystemC. 6. Дать краткую характеристику языка SystemVerilog 7. Назвать конструктивы исполнения цифровых систем на кристаллах. 8 Назвать основные типы функциональных компонентов цифровой системы на кристалле 9. Типовые структуры NoC и их назначение. 10. Цель и функции стандарта IEEE 1500 в инфраструктуре SoC. 11. Стадии производства и тестирования силиконовых кристаллов для создания цифровых систем. 12. Какое взаимное влияние оказывают технологии проектирования профаммных и аппаратных продуктов на два критерия- time-to-market, yield? 13. Нарисовать кривую графика создания продукта, включающего фазы проектирования, отладки и производства. 14. Дать определение понятиям: тестирование, верификация, валидацич, спецификация, ассерция 15. Что представляет собой транзакционный граф профаммного кода9 16. Какую смысловую нафузку тесгопригодности несет ДНФ управляемости и наблюдаемости?
69 17. Как вычисляется гестопригодность транзакционного графа но логическим функциям тестопригодности? 18. Какие методы диагностирования программного кода на основе ассерций используются для поиска дефектных блоков HDL-модели? 19. Как выглядит график тестопригодности графа при последовательном и параллельном соединении вершин? 20. Из каких компонентов состоит инфраструктура верификации программного кода? 1.15. Литература I. Spartan-6 Family Overview Advance Product Specification.- X1LINX.- February 2, 2009.- www.xilmx.com/ 2 Stratix IV Device Handbook. - Altera- 2009. www altera com/support 3. Appello D, Bernardi P., Grosso M., Reorda M.S. System-m-package testing problems and solutions // IEEE Design & Test of Computers - Vol 23, Issue 3.- May-June, 2006.- P. 203-211. 4. Yervant Zorian. Tutorial on EWDTS 2007. Embedding Infrastructure IP for SOC Yield Improvement // Proceedings of the 39th Design Automation Conference - New Orleans, LA. USA.- 2002.- P. 709-712 5. P.P. Pande. С Grecu, A. Ivanov. R. Saleh Destination network-on-chip // EDA lech Forum. University of British Columbia, chart the path from SoC to NoC- June, 2005. 6. Horgan J. SiP or System-m-Package EDACafe.- September 29, 200S - http://EDACafe.com 7. Zorian Yervant. Test Strategies for System-m-Package //1 he Plenary Paper of IEEE East-West Design & Test Symposium (EWDTS'08). Lviv, Ukraine- October 9-12, 2008. 8 L. Smith. 3D Packaging Applications, Requirements, Infrastructure and Technologies // Fourth Annual International Wafer-Level Packaging Conference. - San Jose, California. - September, 2007. 9 The next Step m Assembly and Packaging. System Level Integration in the package (SiP) / Editors. William Chen, W. R Bottoms, Klaus Pressel, Juergen Wolf// SiP White Paper V9.0.- International Technology Roadmap for Semiconductors. - 2007. 10. Проектирование и тестирование цифровых систем на кристаллах / В.И. Хаханов, Е.И. Литвинова, ОА. Гузь.- Харьков: ХНУРЭ.- 2009.-484 с. II. IEEE Std 1800-2005.- IEEE Standard for System Venlog - Unified Hardware Design, Specification, and Verification Language.- Published by The Institute of Electrical and Electronics Engineers, Inc.- USA.- 2005.- 664 p. 12. IEEE Std 1364-2001. (Revision of IEEE Std 1364-1995).- IEEE Standard Ve- niog Hardware Description Language - Published by The Institute of Electrical and Electronics Engineers, Inc.- USA - 2001.- 791 p.
70 13. Ashenden, Peter J. The designer's guide to VHDL - San Francisco, California. Moigan Kaufrnann Publishers. Inc, 1996.- 688 p 14 Pong P. Chu. RTL hardware design using VHDL. Coding for Ffficienc}, Portability, and Scalability.- Wiley-Interscience publication.- 2006.- 696 p. 15. Хаханов В.И., Хаханова И В. VHDL + Venlog = Синтез за минуты.- Харьков: СМИТ.- 2007 - 264 с 16. Donald E Thomas, Philip R. Moorby. The Verilog Hardware Description Language.- New York, Boston. Dordrecht, London, Moscow: Kluwer Academic Publishers-2001.-404 p 17. Schaumont P., Verbauwhere I. A Component-Based Design Environment for ESL Design.- Design & Test on computers.- 2006 - P 338 - 347. 18. L. Cai, D Gajski. Transaction Level Modeling: an overview // Hardware/ Software Codesign and System Synthesis.- 2003. P. 19-24 19. Chevallaz С , Mareau N. and Corner A. Advanced Methods for SoC Concurrent Engineering - In Proc. of Design, Automation and lest in Europe Conference (DATE'02).- 2002.- P. 59-63 20. Nicolescu G., Yoo S. and Jerraya A. Mixed-Level Co-simulation for Fine Gradual Refinement of Communication in SoC Design.- In Proc. of Design, Automation and Test in Europe Conference (DATE).- 2001 - P 754-759. 21 Douglas Densmore, Roberto Passerone, Alberto Sangiovanni-Vincentelh. A Platform-Based taxonomy for ESL design // Dcsign&Test of computers - September-October 2006.- P. 359-373 22. Abramovici M., Breuer M A. and Friedman A D Digital System Testing and Testable Design Computer Science Pi ess.- 1998- 652 p 23. Bayraktaroglu Ismet, Orailoglu Alex. The Construction of Optimal Deterministic Partitionings in Scan-Based BIST Fault Diagnosis- Mathematical Foundations and Cost-Effective Implementations // IEEE Transactions on Computers - 2005-P 61-75. 24. Francisco DaSilva, Yervant Zormn, Lee Whctsel, Kanm Arabi, Rohit Kapur. Overview of the IEEE PI 500 Standard // 1ГС Conference 2003. P.988-997. 25. Rashmkar P.. Paterson P., Singh L. System-on-chip Verification: Methodology and Techniques.- Kluwer Academic Publishers.- 2002 - 324 p. 26. Zonan Yervant. What is Infrastructure IP? // Design & Test.- 2002.- P. 5-7. 27. Zonan Yervant, Gizopoulos Dmytns. Gest editors* introduction: Design for Yield and reliability // IEEE Design & Test of Computet s.- 2004.- P. 177-182. 28. Zonan Yervant. Guest Editor's Introduction. Advances in Infrastructure IP // IEEE Design and Test of Computers.- 2003.- 49 p. 29. Thatte S.M . Abraham J.A. Test generation for microprocessors // IEEE Trans. Comput.- 1980 - C-29. No 6.- P 429-441. 30. Шаршунов С.Г Построение тестов микропроцессоров. 1. Обшая модель. Проверка обработки данных // Автоматика и телемеханика.- 1985.- №1 1.- С 145-155. 31 Jerraya A.A System Level Synthesis SLS. TIMA - 2002 - P 65-75
71 32. Frank Ghenassia. Transaction Level Modeling with SystemC. TLM Concepts and Applications for Embedded Systems. Published by Springer - 2005. - 282 p. 33. Bergeron, Janick. Writing testbenches: functional verification of HDL models.- Boston: Kluwer Academic Publishers - 200! - 354 p. 34. Janick Bergeron, Eduard Cerny, Alan Hunter, Andrew Nightingale Verification Methodology. Manual for SystemVerilog - Springer - 2005 - 528 p. 35. Harry Foster, Adam Krolnik, David Lacey Assertion-based design - Second edition.- Kluwer Academic Publishers - Springer- 2005 - 392 p. 36. Rashinkar P., Paterson P., Singh L. System-on-chip Verification Methodology and Techniques.- Kluwer Academic Publishers. 2002 - 393 p 37. Meyer A S Principles of Functional Verification. Elsevier Science.- 2004. 206 p
72 ЧАСТЬ II. VERILOG Рассматриваются конструктивные особенности, синтаксис и семантика языка описания аппаратуры Verilog, ориентированные на создание цифровых систем на кристаллах В разделах 2-8 представлены структуры проектов, конструкции операторов, (системных) директив, блоков, циклов, примеры создания моделей цифровых компонентов, интерфейсов и устройств поведенческого, регистрового и вентильного уровней описания. Цель - предоставление широкому кругу практически ориентированных читателей технологической культуры проектирования, анализа и синтеза специализированных цифровых систем на кристаллах путем использования эффективной языковой среды Veriiog и многочисленных примеров аппарат ной реализации алгоритмов. Задачи. 1. История создания языка Veriiog. 2. Основные понятия и конструкции, модуль как базовая единица языка Veriiog, уровни абстракции описания моделей, лексические соглашения, классы и типы данных, описание портов модуля, структурные модели, параметры, директивы компилятора 3. Средства описания моделей вентильного уровня: стандартные логические элементы, определяемые пользователем примитивы, задержки элементов; Dataflow моделей- оператор непрерывного назначения, оператор условною назначения, системные задачи и функции управления моделированием, поведенческие модели: блоки Initial и Always, процедурные операторы назначения, временное и событийное управление операторами в блоках, операторы управления (IF, Case, Case? и Casex), циклы, специальные свойства блоков, процедурные операторы непрерывного назначения. 4. Примеры поведенческих моделей устройств, подпрограммы Task и Function, автоматические функций и задачи, системные задачи работы с файлами, средства генерирования операторов, оператор generate и переменные genvar, оператор generate с циклом for, условный оператор generate, оператор generate с оператором case, примеры использования оператора generate, Programming Language Interface (PLI). Источники: стандарт языка описания аппаратуры Veriiog [1. 2]: язык описания аппаратуры Veriiog [4-6]; проектирование цифровой аппаратуры с помощью языка Veriiog [3, 9-10]; интерфейс программирования PLI [7, 8]. 2. ОСНОВНЫЕ ПОНЯТИЯ И КОНСТРУКЦИИ ЯЗЫКА VERILOG 2.1. Модуль - базовая единица языка Veriiog Основным элементом описания устройств в Veriiog является модуль, который состоит из деклараций и операторов [I. 2, 5, 6] Он начинается ключевым словом module и заканчивается - endmodule. Синтаксис модуля: // Старый стиль
73 module identifier (portsjist) ports_declaration, modute_body, endmodule // Новый стиль module identifier (ports_declaration), module_body, endmodule Листинг 2.1 содержит пример устройства, реализующего операцию логическое И для двух 4-разрядных входов а и Ь, где результат поступает на выход с. Листинг 2.1. Пример описания модуля // Старый стиль module module_1(a, b, с), input [3 Oj a, b , output [3 0]c, assign с = a & b, endmodule // Новый стиль module module_1 (input [3 0] a, b, output [3 OJ c), assign с = a & b, endmodule 2.2. Уровни абстракции описания моделей на Veriiog Для описания функций модуля могут быть использованы конструкции одного из четырех уровней абстракции: поведенческий или алгоритмический (behavioral); уровень передачи данных (dataflow); вентильный уровень (gate- level); транзисторный уровень (switch-level) [3,4] Поведенческий или алгоритмический - это верхний уровень описания проектов, отражающий алгоритм их функционирования без деталей реализации В данном случае модель поведения подобна описанию на языке Си. Dataflow - описывает процесс изменения данных при их передаче между регистрами. но не принадлежит к RTL (Register Transfer Level) описанию. RTL структуры предназначены для синтеза моделей, которые могут содержать конструкции поведенческого и dataflow-уровней абстракции. На вентильном уровне модель представлена логическими элементами и соединениями между ними Транзисторный уровень (switch-level) - это самый низкий уровень абстракции. В Veriiog допускается одновременное использование в модуле конструкций всех четырех уровней описания Листинг 2.2 представляет собой модель D-триггера на поведенческом уровне: d - вход данных, elk - вход синхронизации, q - выход. Для реализации функции устройства используется блок always, в котором q получает значение от входа d по каждому переднему фронту сигнала синхронизации elk. Листинг 2.2. Поведенческое описание Verilog-модели D-трш гера
module dff (input elk, d, output reg q), always @(posedge elk) q = d. endmodule Листинги 2 1 и 2.3 содержат примеры моделей устройств dataflow-уровня При этом листинг 2.3 реализует мультиплексор 4-в-1 с помощью булева уравнения: Out = Sell' SelO'-InO+Sell' SelO In 1+Sell SelO' In2+ Sell-SelO-In3 Листинг 2.3. Модель мультиплексора 4-в-1 уровня dataflow module mux4_to_1 //Декларация портов (output out, input iO, i1, i2, i3, // Входы данных mDut s1, sO), // Управляющие входы assign out = (-s1 & ~s0 & iO) | (-s1 & sO & И) | (s1&~s0&i2)|(s1&s0&i3), endmodule Листиш 2 4 представляет вентильное описание мультиплексора 4-в-1, соответствующее схеме на рис. 2 1 Модель состоит из встроенных в стандарт языка Vcnlog логических элемешов H(and), ИЛИ(ог) и Hfc(not). Рис 2 1 Вентильная схема мулыинлексора4-в-1 Листинг 2.4. Модель мультиплексора 4-в-1 вентильного уровня module mux_4_to_1 (output Out, input inO, И1, In2, In3, Sell, SelO), wireNotSelO NotSeH, wreYO, Y1,Y2, Y3, and (Y1,ln1,NotSeI1, SelO) not (NotSelO, SeiOj, and (Y3, in3, Sell SelO),
75 or(Out,Y0,Y1,Y2,Y3), and (YO, InO, NotSeH, NotSelO) not (NotSeM, Sell), and(Y2, in2, Sell.NotSelO), endmodule Рис. 2.2 содержит МОП-схему вентиля ИЛИ-НЕ (nor), а листинг 2 5 - ее Veniog-описание на транзисторном уровне. Му_пс- Рис 2 2 1 ранмсторная схема вешиля ИЛИ-НЬ (nor) Листинг 2.5. Модель элемента ИЛИ-НЕ вентильного уровня // Модель собственного nor вентиля moauie my_nor (output out, input а,Ь), //внутренние линии wire с, //создание линий питания и земли supply! pwr, // pwr соединяется с Vdd (питание) supplyO gnd, // gnd соединяется с Vss (земля) // реализации pmos-транзистор pmos (с, pwr, b), pmos (out, с, а), // реализации nmos-транзистор nmos (out, gnd, а), nmos (out, gnd, b), endmodule 2.2.1. Структурные модели. Verilog позволяет создавать иерархические модели, в которых описания более высокого уровня могут включать ссылки на компоненты более низкого уровня иерархии При этом используется структурный стиль описания. Лис-
76 гинг 2.6 представляет собой Verilog-код устройства, состоящего из двух D- триггеров (см. листинг 2.2). Имена inst 1 и mst 2 являются индивидуальными метками каждой копии компонента dff в устройстве top. Следующие за метками списки содержат имена фактических сигналов, которые будут соединены с указанными в заголовке модуля dff портами. Листинг 2.6. Пример структурной Verilog-модели устройства // модуль верхнего уровня, использующий компонент dff, см листинг 2 2 module top reg data, clock wire q„out, rset_1, dff insM (ciock, data, net_1), dff inst_2 (clock, net_1, q_out); endmodule 2.3. Лексические соглашения 2.3.1. Описание имен. Идентификатор имен в Veriiog: - может состоять из букв, цифр, S, символа подчеркивания "_"; - должен начинаться с буквы или символа подчеркивания; - не может содержать пробелы. В качестве примера можно привести следующие конструкции- reg enable- wire „ready, integer group__a, reg and5, tri c!k$1, Здесь жирным шрифтом выделены зарезервированные в Veriiog слова. 2.3.2. Комментарии. Для выделения комментариев, представляющих строку, используются две наклонные черты //. Символы звездочки /* и */ могут быть применены для того, чтобы отметить начало и конец блока комментариев. Операторы. По числу операндов в Veriiog различают унарные, бинарные и тернарные операторы. В унарном операторе символ операции размещается перед операндом, в бинарном - между операндами. Тернарный оператор использует двойной символ операции, разделяющий три операнда: а = ~Ь, // - - унарный оператор, b -операнд а = Ь&&с, //&&-бинарный оператор, bи с-операнды а = b ? с d, //"?- тернарный оператор, Ь, с и d - операнды 2.3.3. Задание численных значений Численные значения могут быть представлены с указанием или без указания размера, могут иметь или не иметь знак, быть целыми или вещественными. Синтаксис целых значений: [sign] [size] 'base nunrber
77 где sign - знак, size - число битов для представления значения number, base - система счисления: d (D) - десятичная, h (H) - шестнадцатеричная, о (О) - восьмеричная, b (В) - двоичная. Число может состоять из цифр 0-9 и символов X И Л Чтобы разделить группы цифр в числе для улучшения зрительного восприятия кода, можно использовать символ подчеркивания "_". Символ "?"- является альтернативой z и идентифицирует высокий импеданс При этом данный символ в шестнадцатеричной системе обозначает 4 бига, равных z, в восьмеричной - три, в двоичной - 1. Если беззнаковое число меньше отведенною для него числа разрядов, то число выравнивается по правому краю с дополнением нулями до указанного размера. Если левый старший значащий символ равен г или х, то дополнение будет выполнено этим символом. Примеры значений целого типа. 15 'hf 'o17 'd 15 'Ы111 'M_1_1J -5'M_1011 10'd20 8'h z 6'o 71 8'bO (8'bOOOOOOOO) 8'M (S'bOOOOOOOl) 8'bz (8'bzzzzzzzz) 8'bx (8'bxxxxxxxx) 4'M 0?*? (4'M Ozz) 8'h4? (8'bQ1 OOzzzz) 12'h13x //12-битовое шестнадцатеричное число, // у которого значение последних 4 битов неизвестно 6'hx // 6-битовое шестнадцатеричное число 32'bz // 32-разряда со значением высокого импеданса Знак в отрицательных числах ставится перед символом системы счисления. Числа представляются в дополнительном коде 4'd-2 // неправильное описание -8'd3 // отрицательное число представлено в дополнительном коде 8 разрядами Синтаксис вещественных типов дачных, sign unsignedjiumber unsignedjiumber sign unsignedjiumber unsigned_number e sign unsignedjiumber sign unsignedjiumber unsignedjiumber E sign unsignedjiumber Примеры вещественных значений. 17.5 10e5 0 5 0 5694_е-5 1 _000_000 О 2.3.4. Строки. Строковые значения в Verilog записываются в двойных кавычках: var = "Helio world!"; В строках могут быть использованы специальные символы: \п - новая строка \t - табуляция \\\ - символ \ \" - символ"
78 2.4. Классы и типы данных 2.4.1. Сигналы. В отличие от языка VHDL, в Verilog нет таких понятий, как сигнал и переменная [4] Все данные носят название переменных (variable) Выполнение операций назначения и сохранение состояний переменных определяются их классом (net или register) или способом записи оператора присваивания. Для моделирования поведения реальной аппаратуры предлагается четыре возможных значения переменной, представленных в табл. 2 1. Таблица 2.1. Значения си! налов Значение 0 1 Описание Лошческий 0, условие fabe Логическая 1, условие true Неизвестное значение Высокий импеданс Переменные в Verilog делятся на два класса: цепи (nets) и регистры (register). Цепи (nets) являются моделью физического проводника между структурными компонентами устройства, такими как вентили. Сама по себе цепь не хранит состояние. Она должна управляться драйвером, который реализуется с помощью оператора параллельного присваивания (continuous assignment) или вентиля. Если цепь не имеет драйвера, другими словами, переменная не получает значения, то она принимает состояние высокого импеданса t. Peine rp (register) тип данных является моделью элементов, способных сохранять значения между двумя выполнениями оператора присвоения. Ключевым типом данных в регистровом классе является регистр - reg По умолчанию переменная регистрового класса инициализируется значением х. Класс цепи В общем случае синтаксис цепей выглядит следующим образом: netjype [range] [delay3] list_of_netjdentifiers, Параметр netjype может принимать одно из следующих значений, обозначающих тип данных класса цепи: wire, tri. tril, supplyO, wand, triand, tnO, supply!, wor, trior или trireg. Параметр range позволяет создавать векторы указанных типов данных для моделирования шин. Они будут рассмотрены далее. Задержка линии описывается параметром delay3. Для разрешения конфликтов при одновременном присвоении значений в Verilog определены восемь уровней интенсивности (strength level) сигнала. Большинство из них используется для моделей транзисторного уровня. Синтаксис переменной класса цепи с указанием интенсивности (drive strength или charge_strength) выглядит следующим образом net_type [drive_strength] [range] [delay3] iist_of_net_dec!_assignments , Типы wire и tri применяются для моделирования соединительных линий между элементами. Они одинаковы по своему синтаксису и функциям. Два
79 имени в язык введены для различения цели использования переменных При эгом wire употребляется для сигналов, имеющих в качестве источника один трайвер или вентиль, a tn - для сигналов с несколькими драйверами Типы данных wand, wor, tnand и trior предназначены для моделирования монтажной логики, wand/triand - монтажное И, wor'tnor - монтажное ИЛИ. В табл. 2.2 описываются функции разрешения конфликтов, если переменная имеет несколько драйверов, при условии их одинаковой интенсивности. Таблица 2 2 Таблицы истинности для wire/tri, wand/triand и wor/trior 0 1 X / wire/tn 0 0 X X 0 1 х 1 X 1 X х X X X / 0 1 X 2 wand'tnand 0 1 X ? 0 0 0 0 0 1 0 1 X 1 X 0 X X X 2 0 1 X 2 0 1 X 2 0 0 1 X 0 X X 1 X X 2 0 1 X 2 Следующие типы данных созданы для моделей низкого уровня Тип trireg используется для описания заряда запоминающего узла (storage node). Цепи типов данных: triO и tril - представляют собой модели резистивных понижающих (pulldown) и повышающих (puliup) уровни сигналов устройств. SupplyO и supply 1 моделируют напряжение питания Примеры описания переменных класса цепи: wire a, // однобитовая линия а .«re b с, // две однобитовые линии Ь и с wire d = 1'bO, // однобитовая линия а с начальным значением О tn tnstate_buffer, // тристабильная линия tnstate_Duffer wand #5 sig_1, // однобитовая пиния с монтажной логикой И и задержкой 5 единиц Регистровый класс данных. В отличие от цепей регистровые переменные не нуждаются в драйвере, а сами хранят свое значение. К регистровым относится несколько типов данных Их синтаксис. reg [rangej list_ofjdentifiers, integer list_ofjdentifiers, real hst_ofjdent!fiers, nme list_pfjdentifiers realtime list_of_identifiers, Тип reg является основным для моделирования аппарат)ры. Все остальные - вспомогательные Типы данных reg и time хранят информацию в виде беззнаковых чисел Integer используется для манипулирования и хранения информации, которая не рассматривается как реальный регистр аппаратуры. Размер integer по умолчанию равен 32 битам, данные сохраняются в знаковой форме, арифметические операции выполняются в дополнительном коде. Тип Time подобен по функциям 64-битовому регистру и используется для хранения параметров времени.
80 Veriiog также имеет вещественный тип данных real. Он подобен остальным pei метровым типам, за исключением нескольких ограничений значение real разрешается для использования не во всех операторах Veriiog и по умолчанию инициализируется нулем (остальные регисгровые типы инициализируются символом х). Также в Veriiog существует вещественный аналог типа time для хранения вещественных значений времени - realtime. Пример регистровых данных: reg reset, integer i, time t, real r, realtime rt1, rt2, 2.4.2. Векторы. Векторы являются моделями шчн в аппаратуре и могут быть определены только для типов класса "цепи" и для регистрового типа reg. Синтаксис: netjype [msb . Isb] list_of_netjdentifiers, reg [msb Isb] listjsfjegisterjdentifiers; где msb (самый значащий бит) - константа, определяющая левую границ} вектора, a isb (самый младший бит) - правую. Константы msb и Isb могут иметь любое значение - положительное, отрицательное или нуль. Константа Isb может быть больше, равна или меньше, чем msb. Пример векторов: reg [3 0] addr, // 4-разрядный регистр addr wire [-3 4] d, // переменная d размером 8 битов состоит // из элементов d[-3] (msb), d[-2], d[-1], d[0], // d[1] d[2], d[3], d[4] (Isb). trt [5 0] x, y, z, busA[7] '/ элемент шины busA с индексом 7 По умолчанию векторы задают беззнаковые целые числа. Однако с использованием ключевого слова signed можно определять знаковые числа. Самый старший бит рассматривается как знак. Например: reg signed [3 0] signedjeg, задает 4-битовый вектор, который может принимать значения в диапазоне от -8 до 7. 2 4 3. Массивы. Допускается создание массивов из элементов регистровых типов (reg, integer, time, real, realtime) и цепей Элементы массива (или слова) доступны по его индексу. Присвоение и чтение значений памяти возможно только по словам, запрещено обращение к отдельным битам в слове, диапазону или целой памяти. Синтаксис памяти- reg memory_widih memoryjdentifier rnemory_depth, wire memory_w!dth memoryjdentifier memoryjjepth, integer ] time memoryjdentifier memoryjength, Параметр аппаратурного блока памяти memory depth задает размер памяти, memory_width - размер слова памяти типа reg. Одномерный массив регист-
81 ров является моделью аппаратурного блока памяти. Для обозначения таких конструкций используется термин память или массив. Примеры деклараций массивов: reg [7 01 merna[0 255], reg arrayb[7 0][0.255], wire w_array[7-0][5'0]; time chngjiist[1 1000] integer count[0 7] ieg[4 0]port_id[0 7], //декларация памяти mema размером 256 8-битовых слов // с индексацией от 0 до 255 // декларация двумерного массива однобитовых регистров // декларация двумерного массива линий // массив из 1000 значений типа time // массив из 8 слов целого типа //массив portjd из восьми пятиразрядных слов arrayb[1][0] = 0, // Присвоение 0 элементу с индексом [1][0] chng_hist[tjndex] = Stirne, // Занесение текущего времени //моделирования в ячейку массива с индексом tjndex count[5], // обращение к пятому элементу массива count port_id[3], // 3-й элемент массива portjd шириной в 5 битов reg [7 0] rr л [3 0], г // Регистры и память можно определять в одной строке // память mem из четырех 8-битовых слов и // 8-битовый регистр г // 8-битовый вектор vect типа reg // память array из 8 однобитовых слов типа reg // инициализация вектора значением 11001010 // Неправильное обращение к памяти // Правильная инициализация памяти mem[0] = 7, г = mem[3j, reg [7.0] vect, reg array [7 0J; vect = 8'b11001010; array=8'M1001010, array[7] = 1'M, array[6] = 1'M, array[5] = 1'bO, array[4] = 1 bO, array[3] = 1'M, array[2]-1'b0, array[1] = 1'M, array[0] = 1'b0 2.5. Описание портов модуля Для общения с внешней средой каждый модуль использует порты, имена которых должны быть перечислены в скобках после идентификатора имени модуля. Далее в декларативной части указывается режим и тип каждого пор- га. Синтаксис модуля для декларации портов и переменных имеет следующий вид: module name_of_module (port, port), (mput_declaration outputjjeclaration, TOutjJedaration),
82 [net_declaration] [reg_dec!aration] [time_declaration] [mteger_declaration] [real_deciarationj other module_body, endmoduie В Verilog определены три режима портов, input (вход), output (выход), inoul (двунаправленный). Если тип данных порта явно не указан, то он будет wire. В примере (листинг 2.7) для модуля описаны два 4-разрядных входа и один 4-разрядный выход типа wire, поскольку никакой другой тип данны < для них указан не был В примере, записанном в листинге 2.8, входные порты получают тип wire, а выходной - reg. Для портов естественно иметь тип wire, однако если выходной порт сохраняет свое значение, ему может быть присвоен тип reg He допускается использовать тип reg для портов с режимом input и inout Модуль может не иметь никаких портов. Листинг 2.7. Пример декларации портов module module_1 (input [3 0] a b, output [3 0] с), endmoduie Листинг 2.8 Пример декларации портов с явным указанием их типов module modu!e_1 (input [3 0]а Ь, output [3 Ojc), wire [3 0] a, b ; reg [3 0] c, endmoduie 2.6. С груктурные модели 2.6.1. Способы соединения сигналов в структурной модели. На рис. 2.3 в графической форме представлено соглашение по использованию типов портов и сигналов в случае, если модуль является компонентом другого, более сложного модуля. Как видно из рисунка, те линии, значения с которых только читаются (выход модуля и линия, соединенная со входом модуля), могут быть типа класса цепи и типа reg. Для остальных линий разрешены только типы класса цепи. Синтаксис оператора реализации копии модуля в структурной модели: module_name [parameter_assignment] name_pfjnstance (list_of_module_connections)- где parameter_assignment - фактические значения параметров (будут рассмотрены ниже), module_name - имя модуля name_of_mstance - имя копии
83 модуля, !ist_of module_conneetions - список фактических переменных Например' my_module #(7 25) insMfC'k, D, Q) reg/net input output net reg/net inout|net net Рис 2 3 Правчло соединения торшв Существует два способа соединения переменных, указанных в списке копии компонента, и фактических портов модуля, по порядку и по имени. При связи портов по порядку (листинг 2 9) соединение переменных с портами опре- геляется их расположением в списке. При этом первая переменная оператора реализации подключается к первому порту из списка описания модуля. Так, в примере переменная clock из модуля top будет подключена к порту elk модуля dff. В данном случае можно оставляв порты не связанными, тогда при моделировании предполагается, что на них подается значение z. Например, dff instjl (clock,, netj}, Листинг 2.9. Соединение по порядку module dff (input elk, d, output reg q); endmodule module top, reg data, clock, wire q_out, net_1, dff instj (clock, data, netj), dff inst_2 (clock, netj, q_out), endmodule Листинг 2.10 представляет собой пример соединения портов по имени. В данном случае вначале пишется имя порта, а затем в скобках - имя переменной, с которой он соединяется Пары порт-переменная могут располагаться в любом порядке. Несвязанные порты просто не указываются. Листинг 2 10. Соединение по имени module top, reg data, clock, wire q_out, netj.,
84 dff inst_1 ( d(data), q(net_1), clk(clock)), dffinst_2(cik(c!ock), d(net_1), a(q_oui)); endmodule Одним оператором можно создавать несколько копий компонента. Листинг 2 11 иллюстрирует случай создания четырех копий модуля my module в компоненте top, благодаря использованию 4-разрядных переменных и счетчика [3:0] в операторе реализации копии модуля. Листинг 2.11. Массив копий модулей module my_module (input а, b, output с), assign с = a & b, endmoduie module top (input [3 0] a, D, output [3 0] c), myjnodule inst [3-0] (a,b,c), // создает 4 копии модуля myjnodule endmodule 2 6 2. Иерархические имена. Verilog поддерживает иерархическую структуру проекта. При этом каждый модуль, его копия и сигнал имеют собственный идентификатор или, другими словами, имя. Каждый объект имеет уникальное место в структуре проекта, а использование иерархических имен позволяет задавать ему уникальное имя. Иерархическое имя представляет собой список идентификаторов, разделенных точкой (.), для каждого уровня иерархии. Таким образом, используя полное имя, можно обращаться к любому объек1у из любого места проекта. Описание самого верхнего уровня называется модулем и с его имени начинается иерархический идентификатор. Например, для устройства, представленного листингом 11, модуль top является верхним уровнем иерархии В нем объявлены идентификаторы а,Ь и с, а также реализована копия модуля my module с именем inst В модуле my_module, в свою очередь, определены собственные идентификаторы a, b и с В этом случае объекты модуля top будут иметь следующие иерархические имена: top a top b top с и top inst, а объекты модуля myrnoduie представляются списком: top inst a, top inst b и top inst с 2.7. Параметры Параметры не относятся к классу линий и/или pel метровых значений. Это константы и их нельзя использовать в качестве переменных. Значение параметра определяется индивидуально для каждой копии модуля на этапе компиляции. Декларация параметров выполняем перед описанием портов и переменных модуля.
85 Синтаксис. parameter [ signed ] [ range ] identifier = const_expr{, identifier = const_expr} parameter integer identifier = const_expr{, identifier = const_expr} parameter real identifier = const_expr{, identifier = const_expr}, parameter realtime identifier = const_expr{, identifier = const_expr}, parameter time identifier = const_expr{, identifier = const_expr>, Примеры определения параметров- parameter isb = 7, parameter size = 8 , word = 32 , parameter number = 3 92, frequency = 100, parameter clk_cycie = frequency / 2, parameter byte_size = 8, bytejnask = byte_size -1, parameter average_delay = (r + f) / 2, parameter signed [3 0] mux_selector = 0, parameter real r1 = 3 5e17 parameter p1 = 13'h7e parameter [31 0] dec_const = 1 M, // значение преобразуется в 32 бита parameter newconst = 3'h4, // используемый диапазон [2 0] parameter newconst = 4, // используемый диапазон [31 0] Листинг 2.12 содержит пример, в котором размер шин данных и задержка устройства определены с помощью параметров width и delay. Параметр width используется в описании портов модуля, a delay - в операторе assign, присваивающем значение входа D выходу Q с задержкой в 10 единиц времени. Листинг 2.12. Пример использования параметров module myjnodule (Clk, D, Q), #(parameter width = 2, delay = 10) (input [width -10] D, input Clk, output [width 0] Q), assign #delay Q = D, endmodule 2 7 1. Переопределение параметров. В операторе реализации модуля можно переопределить значение параметра для данной копии компонента. Также это можно сделать с помощью конструкции defparam Гогда необходимо будет указать иерархический путь к модулю и его параметру. Синтаксис, defparam hierarchical_path = constant_expression Листинг 2.13 представляет собой пример переопределения параметров в операторе реализации копии модуля my module (листинг 2.12). При этом параметры получают новые значения: width = 7, delay = 25. Листинг 2 14 иллюстрирует использование оператора defparam для изменения значения параметра width в дополнительном модуле override При изменении параметра, от которого зависят значения других параметров необходимо учитывать, что при изменении первого вторые автоматически обновляются
86 Листинг 2.13. Переопределение параметров в операторе модуля module top, reg Clk reg [7-0] D, wire [7 0] Q , myjnodule #(7, 25) inst_1(Clk, D, Q), endmodule Листинг 2.14. Переопределение параметров с помощью defparam module top; reg Clk, reg [7 0] D, wire [7 0] Q, my_modu!einst_1(C!k D, Q), endmodule module override, defparam top.in.st_1 width = 7, // иерархический путь top inst_1 указывает расположение параметра width // в структуре вложенных модулей endmodule 2.7 2 Локальные параметры Локальные параметры localparam - идентичны параметрам, за исключением того, что они не могут быть модифицированы с помощью defparam или оператора реализации модуля Локальные параметры могут получать значения в константных выражениях, содержащих параметры, которые допускают переопределение. Синтаксис- localparam [signed] [range] identifier = const_expr{, identifier = const_expr}, localparam integer identifier = const_expr{, identifier = const_exDrt: localparam real identifier = const_expr{, identifier = const _expr}, localparam realtime identifier = const_expr{, identifier = const_expr}, localparam time identifier = const_expr{, identifier = const_expr}, 2.8. Директивы компилятора В Venlog определены следующие директивы компилятора [5. 6J 2.8.1 Директива'define. Используется для определения текстовых макросов Она подобна #define конструкции языка Си. Синтаксис: 'define <text_macro_name> <MACRO_TEXT> В декларации и использовании текстовых макросов применяется символ обратного апострофа \ Например- defineTESTEQ1 4'М101 //определен текстовый макрос 1101 define myzero 0 // определяется текстовый макрос myzero, равный нулю assign mysig = myzero, //использование текстового макроса myzero //в любом месте Verilog-кода вместо нуля
87 define WORD_REG reg [31 0] // имя WORD_REG может быть теперь // использовано для определения 32-разрядных регистров define WORDSIZE 64 'eg [WORDSIZE-1 0] data_bus, Макросы могут содержать параметры и могут быть использованы для реализации функций. Следующие операторы представляют пример применения макроса для создания функции сравнения двух чисел define max(a b) ((a) > (b) "> (а) (Ь)) п = "max(p+q, r+s) 2.8 2 Конструкция'ifdef. Verilog предлагает использовать конструкцию ifdef и 'endif, выполняющую проверку деклараций текстовых макросов для проведения условной компиляции. Пример из листинга 2 15 иллюстрирует использование директивы 'ifdef для выбора способа реапизации функции И. Листинг 2 15. Пример использования директивы ifdef module and_op (a, b, с), output a, mout b, с; /' выбор между RTL/GATE моделями с помощью диреетивы ifdef •ifdef RTL wire a = b and c, 'else and a1(a, b, c), "endif endmodule 2.8.3 Директива 'include. Verilog позволяет разделить исходный код на несколько файлов. Для использования информации, содержащейся в другом файле, можно применять чирективу 'include: include' path/file-name-to-be-included" Если файл определен с помощью директивы include, он не требует добавления к проекту: 'include "/deslgn/library/cells v" include 7design/system/rest_of_system.v" 2.8.4. Директива 'timescale. Директива компилятора 'timescale используется для описания единиц измерения и точности вычисления параметров времени. Синтаксис. timescale timejjmt / time_precision где time_unit - единицы измерения времени; time__precision - точность вычисления (округления) Значение точности вычисления должно быть меньше или равно величине, указанной в единицах измерения времени. Допустимые численные значения. 1, 10 и 100; единицы измерения s ms. us, ns, ps и fs. Например:
"timescaie 10ns/100 ps assign #5 Q = D // Q полупит значение D после 10 ns задержки 2.9. Контрольные задания 1. Написать декларацию модуля для 4-разрядного риистра (рис 2 4) с именем shift reg. Описать входные порты без внутренней реализации устройства regjn [3 0]Г~ shift_reg (4 разряда) jreg_out [3 0] > Рис 2 4. 4-разрядный регистр shvft_reg 2 Создать модуль верхнего уровня stimulus со следующими переменными' REG_IN(4 бита) и СЬК(1-6ит) типа reg и REG_OUT(4 бита) типа wire. Создать в нем копию модуля shiffc_reg с именем sri. Использовать способ соединения портов по порядку. 3. Выполнить предыдущее задание, используя для соединения портов - соединение по имени. 4. Записать иерархическое имя переменных REG IN и REGOUT. 5 Написать иерархическое имя для копии компонента ы! Написать иерархическое имя для копии его портов Тестовые вопросы 1. Какой из языков лучше подходит для создания сложных иерархических проектов цифровых устройств? 2. Какой opi анизацией был разработан стандарт языка Verilog? 3. Что описывают модели поведенческого уровня? 4. Что описывают модели dataflow-уровня9 5. Что описывают модели вентильного уровня? 6. Какие классы переменных существуют в Verilog ? 7. Какой из атрибутов не является правильным Verilog-идентификатором'' 8. Какое описание соответствует 8-битовому вектору типа линия9 9 Какая из деклараций описывает память из 20 элементов целого типа9 10. Какое описание соответствует памяти из 20 слов целого типа9 11 Записан оператор присвоения: А-23456; какой формат имеет это число в Verilog? 12. Какое выражение описывает 16-битовое двоичное число? 13 Какой элемент вектора (reg [7:0] bus) содержит самый старший бит значения? 14. К переменной какого типа может быть подключен выход модуля при построении структурных моделей устройств9 15. Указать название стандартного примитива 16. Сколько выходов может иметь определенный пользователем примитив9 17. Как описывается поведение определенного пользователем примитива?
3. ВЕНТИЛЬНЫЙ УРОВЕНЬ ОПИСАНИЯ МОДЕЛЕЙ 3.1. Стандартные логические элементы и модели вентильного уровня Вентильные и транзисторные модели - это модели низкого уровня, которые точно описывают функцию и структуру схемы, используя лошческие элементы или примитивы МОП-транзисторов [9, 10]. Синтаксис для применения вентилей в Verilog-коде GATETYPE [strength] [delay] [name_ofjnstance] (terminals ), [name_ofjnstance] (terminals), Оператор GATETYPE представлен множеством, состоящим из следующих ключевых слов: and, nand, or, nor, xor, xnor, buf, bufifO, bufifl, not, notifl), notifl, pulldown, puliup, nmos, rnmos, pmos, rpmos, cmo\ rcmos, tran, rtran, traniTO, rtranifD, tranifl. rtranifl; strength - интенсивность драйвера, delay - задержка элемента; nameofmstance - необязательное имя копии логическо- ю элемента; terminals - список соединительных линий, который может содержать только один, описываемый первым выход, за которым следуют входные линии. Предлагаемые в Verilog логические элементы для построения моделей вентильного уровня представлены на рис. 3.1. -о- Buf -о- Not And Nand Or Nor Хог 3> Bufif1 BufifO Notifl NottfO Ю- Рис 3 1 Стандартные логические элементы Verilog Вентили bufifO bufifl notifl notifO используются для исправного моделирования тристабильных буферов, нагруженных на один общий выход При этом состояние общего выхода может принимать значения из множества си1 налов {/, 0, 1}. Представленные выше вентили имеют три терминальные линии, которые записываются в список terminals в следующем порядке: <выход вход данных, управляющий вход>. Табл. 3.1 представляет собой функции тристабильных вентилей, где символ L означает, что выход может принимать одно из двух значений 0 или Z, символ Н - 1 или Z. Задержки в Н и L подобны задержкам при переходе линии в состояние X.
90 Пример использования стандартных элементов для построения цифровых схем представлен листингом 2 4. Таблица 3.1. Таблицы истинности тристабильных вентилей jbuu.u D : Control || 0 1 х Л 0 г L LJ ! / Н Н notifD D t 0 ! Control |j 0 1 х Л \ / Н Н( 0 z L L '! ijbuini \ 0 1 И notif 1 [rJ 0 Control 0 1 х / /DLL 7 ! H H Control [ШЕЕ z ! H H z 0 L Ll 3.2. Модели комби] Листинг 3.1 представляет еще один вариант вентильной модели мультиплексора 4-в-1, которая состоит из 7 примитивов стандартных вентилей. В отличие от листинга 2.4, описания вентилей группируются по их типам, что делает модель более компактной и ясной для понимания. Листинг 3.1 Модель мультиплексора 4-в-1 вентильног о уровня module mux_4_to_i (output Out, input InO, In1, In2, In3. Sell, SelO), wire NotSelO, NotSeH, wireYO, Y1, Y2.Y3, and (Y1,ln1, NotSeH, SelO) (Y3.ln3, Sell, SelO), (Y0, InO, NotSeH, NotSelO) (Y2,ln2,Sel1,NotSei0), not (NotSelO, SelO), (NotSeH, Sell), or(Out,Y0,Yi,Y2,Y3). endmodule 3.3. Определенные пользователем примитивы Verilog позволяет проектировщику создавать свои собственные элементы - определенные пользователем примитивы (UDP User-defined primitives). Примитивы бывают двух типов- комбинационные и последовательностные Алгоритм их функционирования задается в шбличной форме. Для этою используются специальные символы (табл. 3 2) Все терминальные пинии должны быть однобитовыми. Входными значениями примитива может быть
91 0. 1 и х. Значение 7 принимается равным х. Для любого пользовательского примитива допускается описывать один или несколько входов (input), но только единственный выход (output), который идет первым в списке терминальных линий. Нельзя задавать портам режим mout Примитив описывается на том же уровне, что и модуль, поэтому он не может быть вложенным в последний. Синтаксис UDP-примитива: primitive udp_name ( portjist), output output_port, input list_of_imputs, initial output_port = value, // инициализация выходного значения table combinationa!_input_list output_vaiue, seauentialjnputjist current_sta?e next_state, endtable endpnmitive Листинг 3 2 представляет собой пример комбинационного примитива - мультиплексора 2-в-! (рис. 3 2). Состояние выходов таких примитивов зависит только от значений сигналов на его входах, поэтому они не имеют секции инициализации (ключевое слово initial) Таблица состояний содержит две, разделяемые двоеточием, части: область входных сигналов и область выходов Порядок следования столбцов в таблице определен соответствующим порядком записи входных переменных в списке портов port list Листинг 3 3 содержит пример UDP последовательностною примитива - D- трипера (рис. 3.3). Данная модель выполняет инициализацию выхода q путем тдания ему значения логического нуля. Таблица состояний последовательное гного примитива содержит три области: входы, текущее состояние и следующее состояние. Для того чтобы исключить возможность появления неопределенного значения х на выходе, необходимо покрыть в таблице все возможные комбинации входных сигналов. Таблица 3 2. Описание символов для таблиц состояний в UDP Симвш 0 1 х b ■> (vvv) * г f р п Интерпретация Логический 0 Логическая 1 1 Комментарий Неизвеспгае значение | Заменяем и 1 ЗаменяетО, 1 их Отс> тс пме изменений Переключение из значения v в w Эквивалентно (??) Эквивалентно (01) Эквивалентно (10) Эквивалентно (0!). ( Ох), ( xl) Эквивалентной 0)(1х),(х0) Не разрешается тля выхотов Используются с выходами посдедователыюстныхиОР Значения v и w могу т быть равны 0 1, Ь и '* Любое изменение значения* Передний фронт* Задний фронт* Положительный фронт * Отрицательный фронт* * Символы используются только для входов последовательноегаь.х 1JDP
92 Листинг 3.2. Примитив мультиплексора 2-в-1. primitive Mux_2to_1(Out, Sel, InO, In1), output Out, input Sel, InO, In1, // Нет инициализации Table // Sel InO In1 Out // 0 0 ? 0 II Если Se!=0, то значение с InO поступает на выход 0 1' 1, 1 ? 0 0, //Если Sel=1, то значение с 1п1 поступает на выход 1 "? 1 1, х ? 7 х , // Если Sel=x, то и значение выхода не определено // endtable endprimitive Sel Рис 3 2 Мультиплексор 2-в-1 Рис 3 3 D-трип ер с инверсным входом сброса Листинг 3.3 Примитив D-триггера primitive d_ff (q, d, elk, clr), input d, elk, clr, initial q=0, table // d elk clr q q+ // . _— "? ? 0 • 7 0 , // сброс триггера в 0 Or 1 "? • 0 , // запись 0 в по переднему фронту с!к 1 г 1 ' 1 , // запись 1 в по переднему фронту elk "? п 1 ">.-,// сохранение при переключении elk (10), (1х) или (хО) * ? 1 ? - , // сохранение значения при отсутствии изменение на elk // . ._.
93 endtable endprimitive Синтаксис оператора реализации копии примитива UDP точно такой же, как и для любого стандартного вентиля в Verilog. Листинг 3.4 представляет собой пример использования UDP-примитива Ж-триггера для создания модели схемы с рис 3.4. Каждой копии примитива присвоена необязательная метка BitO, Bit), Bit2 и B.t3 Рис 3.4 Пример схемы Листинг 3.4 Пример использования UDP-примитивов module Count4En (Q, C!r, Dk, En), output [3 0] Q, wire [3 0] Q input Clr, Clk, En, wire JK1 JK2, JK3 JKMS BitO (Q[0] Clr, Clk, En, En), JKMS Bit1 (Q[1] Clr, Clk, JK1, JK1), JKMS Bit2 (Q[2], Clr, Ok, JK2, JK2), JKMS Bit3 (Q[3J, Clr, Cik, JK3, JK3), and(JK1,Q[0],En), and (JK2, Q[1J JK1), and (J КЗ, Q[2] JK2), endmodule 3.4. Задержки элементов На практике любой электронной схеме необходимо конечное время на переключение выходов в ответ, на изменение входов (задержка элемента) или на распространение сш нала вдоль проводника (задержка линии). Вводятся следующие задержки переключения сигналов, задержка переднего фронта (rise delay) - время переключения в 1 (рис. 3 5, а); задержка заднего фронта (fall delay) - время переключения в 0 (рис. 3.5, б), задержка отключения (.turn-off) - время, ассоциирующееся со временем перехода выхода элемента из любого состояния в состояние z. Если значение выхода переключается в х, то для моделирования используется одна из описанных выше задержек, имеющая минимальную величину. При описании логических элементов задержка указывается после имени в формате: #(deiay)
#(nse_delay, fa!l_de!ay) #(rise_de!ay, fa!l_delay, tum-off_de!ay) ■a Рис 3 5 Модели задержек Когда указан один параметр, то для всех типов переключений будет использовано одно и то же значение. Если указать две величины, то они рассматриваются как задержки переднею и заднего фронтов, задержка отключения будет принята равной минимальному из указанных значений При записи всех трех параметров предполагается, что они идут в следующем порядке: <задержка переднего фронта, задержка заднего фронта, задержка отключения^ При этом каждое значение задержки может быть задано числом, идентификатором или в формате <минимальная : типичная : максимальная^: #(number) | #(identifier) | #(min typ max, mm typ max mm typ max) Если задержка не описана, она принимается равной нулю. Единицы измерения времени при записи задержек не указываются, они задаются для всего Verilog-кода директивой компилятора 'timescale Примеры описания задер- and #(5) a1(out, i1, i2), // задержка элемента для всех типов переключения равна 5 and #(4, 6) a2(out i1, й), '/ nse_deiay=4, fali_delay=6, turn-off_deiay=4 timescale 1 ns/1 ps and #{3, 4, 5) a3(out, i1, i2), // nse_delay=3 ns, fail_de!ay-4 ns, tum-off_delay=5 ns Листинг 3.5 иллюстрирует использование задержек элементов при построении модели устройства (рис 3.6) вентильного уровня. Рис 3 6 Испо 1ьзование задержек при описании венгитьных схем Временные диаграммы, полученные при тестировании модели, приведены на рис 3 7. Формирующий тестовые последовательности модуль верхнего уровня представлен листингом 3.6. Он не имеет портов, его внутренние переменные А, В и С, подключенные к входам модуля D, имеют тип reg и получают значение с помощью конструкции initial Операторы в блоке выполняются последовательно, начиная с нулевого момента времени. Единица измерения времени (1 ns) указана в директиве 'timescale Системная задача
95 Sfinish используется для завершения моделирования в 30 единиц времени после его начала. Листинг 3.5. Venlog-модель вентильного уровня с использованием описания задержек bmescale 1 ns /1 ps module D{out, a, b, c), // декларация входных портов output out, input a, b, c, wire e // внутренняя линия // реализация копии примитивов вентилей and #(5) a1(e, a, b) // задержка вентиля 5 единиц времени or #(4) o1(out, e, с), // задержка вентиля 4 единицы времени endmodule Name •■а »-Ь ^с 6 > . 5 . . 10 • • 15 . i . 20 25 . I I .< 5ns » ~~zn «-Afls-», - out I 1 1 Рис 3 7 Временные диа! раммы тестирования устройства из листинга 3 4 Листинг 3.6 Testbench для модуля D из листинга 3.4 bmescale ins/1 ps module stimulus_simple; // Декларация внутренних переменных гед А, В, С, wire OUT, // Реализация копии модуля Dd1(OUT,A, В, С), // Формирование тестовых последовательностей initial begin A=1'b0, B = 1'd0, C=1'b0, #10 A = 1'M, //A=1_10ns #5 6 = 1'M, //B=1 в 15 ns #5 A = 1'b0, //A=0_20ns #10 $finish, // Моделирование закончится в 30 ns end endmodule Veriiog предлагает дополнительный способ контроля для каждого типа id- тержек, позволяя описывать их минимальное, типичное и максимальное зна-
96 чения. Любая из этих величин может быть использована для моделирования Этот подход применяется для тестирования поведения устройств, чьи параметры задержек указываются диапазоном с минимальной и максимальной границами. Метод выбора значений для моделирования зависит от програм- мы-симулятора' and#{4 5 6)a1(out,i1,i2), and#(3.4 5,5 6 7)a2(out,i1 i2); and #(2 3 4,345, 4:5:6) a3(out, И, i2), 3.5. Контрольные задания 1. Создать свои собственные 2-входовые логические Verilog-элементы с именами my_and, my or и my_not, используя только 2-входовые вентили nand Протестировать их поведение, построить файл, генерирующий тестовую последовательность. 2. Вентиль хог на два входа может быть построен с помощью логических элементов my_and, my or и my_not Создать модуль my_xor, реализующий функцию z = ху' + х'у Написать тестовый модуль, подающий все четыре возможные комбинации х и у. 3. Однобитовый сумматор реализован булевыми уравнениями sum=a-b-c_in + a'-b-c_in, + a'-b' cjn + a-b' cm'; c__oui=a b+b-c_in+a-c_in. Построить схему однобитового сумматора, используя стандартные логические элементы and, not и or. Создать ее Verilog-описание. Написать тестовый модуль для всех возможных входных комбинаций a, b и c_in 4. На рис 3.8 представлена логическая схема RS-триггера и таблица переходов. Reset set 0 0 1 1 reset 0 1 0 I 4mi Чп 0 1 Рис 3 8 Логическая схема RS-триггера и таблица переходов Создать Veriog-описание для RS-триггера, задавая задержку в 1 единицу времени при создании копий вентиля nor. Написать тестовый модуль и проверить функционирование RS-триггера, используя его таблицу переходов
97 5 Создать модель мультиплексора 2-в-1, используя вентильные -элементы bufifO и bufifl, ьак показано на рис 3 9 Описание задержек для вентилей Ь1 и Ь2 приведено в табл 3.3. Рис 3 9 Вентильные элементы bufifli и bufifl Таблица 3.3. Задержки для вентилей Ы и Ь2 Rise Tall j Turnoff | Mm 1 3 5 Тур 2 4 6 Max 3 5 7 6. Используя стандартные примитивы, записать структурную модель схемы на рис. 3.10. Рис 3 10 Пример схемы 7. Разработать стандартный примитив, реализующий функцию. f=abc+bcd 8. Спроектировать примитив UDP мультиплексора 4-в-1. Устройство имеет управляющие сигналы sO и si, входы данных Ю, П. 12 и )3. выход out. Если управляющий сигнал sO или si равен х, то выход out ■= 0. 9. Написать таблицу истинности и создать UDP для функции Y - (А & В) j (С л D). Вход никогда не должен принимать значение х 10. Создать пользовательский примитив UDP, имеющий пять входов al. a2. аЗ, Ь1,Ь2 и один выход, поведение которого описано функцией: out = (а1 & а2 & аЗ ) | (Ы & Ь2) Выполнить моделирование устройства с использованием следующего блока для формирования тестовых значений и наблюдения за результатами: initial begin $momtor($time, а1, a2, аЗ, M, d2, out), for (i=0 i < 32, i=i+!)
98 #10{а1,а2,аЗ,Ы,Ь2} = 1 end 11. Создать примитив UDP RS-триггера. set reset 0 0 0 1 1 0 1 1 q„*. q» 0 12. Создать примитив JK-триггера с синхронизацией отрицательным фронтом, с асинхронными прямыми сигналами установки (preset) в 1 и сброса (clear) в О J К 0 0 0 1 0 1 I jjVi 1q^ 0 1 i q'n
99 4. DATAFLOW МОДЕЛИ ЦИФРОВОГО УСТРОЙСТВА 4.1. Dataflow модели и оператор непрерывного назначения Dataflow - no более высокий уровень описания моделей по сравнению с вентильным уровнем. В данном случае описывается способ передачи данных между регистрами [5. 6. 9] Основной конструкцией такого уровня моделей является оператор непрерывного назначения (continuous assignment) Его синтаксис. assign [dnve_strength] [delay] net_value = expression {net_value = expression}, где net value - скалярная или векторная величина класса net (цепь) или конкатенация этих элементов, 1де не допускается применение переменных класса register. В выражении expression могу г быть использованы операнды классов net и register или вызов функции. Оператор непрерывного назначения всегда активен Как только один из операндов с правой стороны изменяет свое значение, вычисляется новое значение выражения, которое присваивается переменной с левой стороны, assign out=i1&i2, assign addr[15 0]=addt1[15 Q]Aaddr2[15 0], assign {c_out, sum[3-0]}=a[3 0}+b[3-0]+cjr, В Venlog имеется возможность выполнять декларацию линии в одном операторе и присваивать ей значение: //Обычная форма Aire out, assign out - И & i2, //Упрощенная форма wire out = i1 & i2, Задержки в операторе назначения Описание задержек в операторе непрерывною назначения и их свойства аналогичны задержкам вентилей. wire ou, assign #10 out = И & i2, //Обычная форма wire #10 out = И & i2, //Упрощенная форма Задержку линии можно также указать в момент ее декларации: wire #10 out, //Задержка линии assign out = i1 & i2, // Значение линии out будет присвоено после // задержки, равной 10 единицам времени л 4.2. Операторы 3 Veriiog использованы символы для описания операторов, по аналогии с языком С. В табл 4 1 приведен их список в порядке убывания приоритета, а в табл. 4 2 - их описания
Таблица 4 1. Приоритеты операторов Оператор + - (binary) <<=>=> == 1^ === <==. I & ~& 1 -1 && 9 1 Описание Унарные Арифметические Бинарные . Сдвига Отношения Равенства and nand 01 ПОГ JIoi ическое and Условный оператор Таблица 4.2 Операторы Verilog | Арифметические J | Оператор || Описание | 1 а + b ((аплюеЬ ~\ I а - b а минус b а * b а умножить на b а / b (а разделить на b | 1 а%Ь ||а по модулю b | | Отно | Оператор I а<Ь а>Ь а<=Ь a=>b пения | Описание [ меньше | больше меньше или равно больше или равно | || Побитовые | Оператор { ~Ь а&Ь Я alb 1 алЬ [| а л - Ь. а ~л b j Описание | not and or xor | xnor j Равенства J Оператор а=^Ь II я »= Ь 1 d===b | a'=b Логические _Оператор_ J а && b jj а!| Ь | Описание aandb not a Описание равно 1 не равно равно не равно j ,i в табл. 4.2. Пример их использо- Арифметические операторы перечисле вания приводится ниже- А = 4'Ь0101, // определены 4-разрядные регистры А и В В=4'Ь0010, D = 5, Е = 4, // переменные целого типа D и Е А * В // результат операции умножения - 4'ЫОЮ D / Е // результат операции деления D на Е - 1 остаток отбрасывается А + В // результат операции умножения - 4'00111 А - В // результат операции вычитания - 4'Ь0011
101 Ест хотя бы один бит операнда равен х, результат арифметической операции будет неизвестен (равен ч): ml =4,Ы10х, in2=4'M010, sum = int + in2, // результат операции сложения - 4Ъх Результат операции по модулю представляет собой остаток от деления двух чисел. Знак результата совпадает со знаком первого операнда 10 % 3 // результат 1, остаток от деления 10 на 3 равен 1 17 % 3 // результат 2 остаток отделения 17 на 3 равен 2 12 % 3 // результат 0, нет остатка от деления -7 % 3 // результат -1 знак пеового операнда 11 % -3 // результат 2 -4'd12 % 3 // результат 1, операнд -4'd12 рассматривается как большое // положительное число, остаток от деления которого на 3 оавен 1 Для последнего примера число -'d!2 d в дополнительном коде будет представлено следующими пятью битами 'ЫОЮО, однако выражение -4'd!2 теряет старший знаковый разряд и принимает значение 4Ъ0100. А результат будет равен 4Ъ0100%3 = S. Логические операторы (табл. 4.2) используются для создания логических выражений, для объединения операций отношения и сравнения. Результатом применения логического оператора может быть 0 (false), I (true) или \ Для целочисленных типов данных результат операции логическое И (&&) будет 0, если один из операндов равен 0; результат операции логическое ИЛИ (J!) будет равен !. если один из операндов имеет ненулевое значение. Унарная логическая инверсия возвращает значение 1, если операнд равен 0, и 0 - в противном случае Пример такой операции может иметь вид- А=3; В=^0, А&&В=0 А;|В=1 "А=0 !В=1 А = 2Ъ0х, В = 2'М0, А && В /' Результат х, эквивалентно (х && 1) Операторы отношения (табл. 4.2) Результат операции может быть 0 (false) или 1 (true) Если один из разрядов операндов равен х или z, го результат оператора отношения равен х- reg [3 0] a, b, а = 4'М100; Ь = 4'Ь0110, а < d // равняется логическому 0 а > 8 // равняется логической 1 а <= b // равняется логическому 0 а >= 10 // равняемся логической 1 а < 4'Mzzz // результат равен х а < 4'Ы х01 // результат равен х
102 Операторы равенства (табл 4 2) Операторы ■= и != выдают значение \, если хотя бы один разряд операнда равен х или z Операторы -== и ,_= выполняют побитовое сравнение, разрешая использовать в операндах символы \ или 7 В этом случае результат все1да будет определенным, равным 0 или 1. и никогда не может принимать значение х. reg [3 0] а, Ь; а = 4'Ы100, Ь = 4'М01х, а==4'Ы100 //истина - логическая 1 а'=4Ы100 // ложь - логический 0 //результат равен х //результат равен х // истина - логическая 1 // ложь - логический 0 Поразрядные или побитовые операторы (табл 4.2 и 4.3). Оператор выполняет логические операции поразрядно над парами элементов, составляющих операнды. Если один из них короче, то он дополняется нулями со стороны старших разрядов. Символ / обрабатывается как х. Таблица 4 3. Таблицы истинности побитовых операторов Ь==4'М01х Ь'=4'М01х Ь===4'М01х Ь1==4'М01х & 0 0 г х z 0 0 0 0 0 0 I х ,| Щ I 0 0 I X L 0 ! х х ~л 0 0 1 х / 1 0 х х 0 1 х х Ч»■ - ! 0 X X Примеры использования побитовых операторов: reg [7 0] а, Ь а = 8'М 010x2X2, Ь = 8Ы0010011, а & b // операция поразрядного И, результат равняется 8'ЬЮООООхх а | b // операция поразрядного ИЛИ, результат равняется 8'Ы011хх11, а л b // операция поразрядного по модулю 2, результат равняется 8'Ь0011хххх, а ~Л b // операция поразрядного по модулю 2 с инверсией, результат равняется //8'ЫЮОхххх, - а //операция поразрядной инверсии, результат равняется 8 Ь0101хххх Операторы редукции или свертки. Группа унарных операторов: & (and), ~& (nand), | (or), ~| (nor). " (xor), Л~ или ~Л (хпог) возвращает одноразрядный результат, выполняя указанную логическую операцию между битами операнда. Пример применения операторов редукции к переменной х~4'Ы010: &х //1&0&1&0=1'Ь0 |х //1|0|1|0=1'Ы лх //1<ЧК1Л0=1Ь0 Следующий пример представляет использование операторов редукции для формирования контроля четности parity и равенства кота 11 . 1 a!I_ones.
103 module par (input [7 0] in, output parity, all_ones), assign parity = Ain, assign all_ones = & in, ' endmodule Операторы сдвига выполняют сдвиг операнда, записанною слева от оператора, на число разрядов, указанных справа 'х=4'Ы 100 /=х»1 //y=4'D0110 ,=х«1 //у=4'Ы000 у=х«2 //у=4'Ь0000 -eg (3 0] а, з = 4'М111, з«3 = 4ЬЮ00 з » 3 = 4 Ь0001 а « 1 bz = 4 bxxxx а » 1 bx = 4 bxxxx Оператор конкатенации {,} предлагает механизм соединения нескольких переменных в одну. Операнды записываются в фигурных скобках через запятую При декларации операндов для них явно должен быть указан размер Синтаксис- {expression | mu!tiplier{expression}, expression | multip!ier{expression}, } где expression операнд, который может быть класса net или register: однобитовый, вектор или диапазон векгора. Операндам можно задавагь константы повторения (multiplier): ,/А=ГМ,В=2*Ь00, С=2'Ы0 D3'D110 Y={B, С} //Y=4'bOQ1C Y={A, В, С, D, З'ЬООП //Y=11'D10010110001 Y={2{B}, С) //Y=6'bQ00010 Y={3{A}, 2{В}, С} //Y=9'b111000010 Листинг 4.1 содержит пример использования побитовых операюров и непрерывного оператора назначения для создания модели мультиплексора dataflow уроьня. Функция устройства описана в виде булева уравнения Листинг 4.1. Модель мультиплексора 4-в-1 уровня dataflow //С использованием логического уравнения module mux4_to_1 (out, Ю, И, i2, i3, s1, sO), //Декларация портов output out, input Ю, il i2 i3, // входы данных input s1, sO, // управляющие входы assign out = (~s1 & ~ч0 & Ю) | (~s1 & sO & И) I (s1 &-s0&i2)|is1 &s0&i3), endmodule
104 4.3. Оператор условного назначения Условный оператор (?:) может принимать три операнда. Его синтаксис: condition_expr "> true_expr false_expr, где conditionexpr - описывает условие, определяющее, какое из следующих выражений будет выбрано. Если condition_expr=l (имеет значение true), вычисляется выражение true_expr, иначе - выражение falseexpr Если условие равно х, то вычисляются оба выражения trueexpr и falseexpr и их значения сравниваются побитно. В каждой позиции, в которой биты различны, ставится х, иначе совпавшее значение битов. Листинг 4 2 содержит пример построения модели мультиплексора 2-в-] (рис. 2.2) с использованием условного оператора Выход out получи г значение от входа In 1, если Sel=l, иначе out =- InO Листинг 4.2. Условный оператор в модели мультиплексора 2-в-1 module mux_2to_1 (out, InO, In1, Sel), output Out, input InO, inl.Sel assign out = Sel "> In1 InO, endmodule Условные операторы могут быть вложенными один в другой Пример такого оператора, использованною для описания мультиплексора 4-в-1, приведен в листинге 4 3. Обе модели мультиплексора 4-в-1, представленные листингами 4 1 и 4 3, являются моделями dataflow-уровня. Тем не менее, для реализации функции устройства в них использовались различные операторы Venlog. Листинг 4.3. Модель мультиплексора 4-в-1 с условным оператором // Модель уровня передачи данных (dataflow) с применением условного оператора moaule mux4_to_1 (out, i0, i1, i2, i3, s1, sO), /Щеклаоация постов output out, input i0,i1,i2, i3, input s1 sO, //Вложенный условный оператор assign out = s1 "> (sO ? i3 i2) (sO "> i1 Ю), endmodule 4.4. Системные задачи и функции ДJIЯ управления моделированием 4.4.1. Sdisplay. В Verilog предлагается инструмент системных задач для запуска подпрограмм, позволяющих выполнять вывод информации на экран, мониторинг значений переменных, приостановку и завершение процесса моделирования [5j. Такие задачи записываются в формате Skeyvvord. Ниже рассмотрены решения, наиболее часто используемые на практике Системная задача Sdisplay служит для вывода информации на экран Ее син- Sdisplay I Sd'solavb | Sdisplayh | $dispiayo (p1, р2 рЗ ),
105 где pi. p2. рЗ,... - могут быть строками, переменными или выражениями По умолчанию для Sdisplay численные значения выводятся в десятичной форме. Управлять форматом представления чисел можно с помощью символов, перечисленных в табл 4 4 Варианты вызова задачи с окончаниями b, h и о означают, что данные, для которых не указан формат, будут выводиться в двоичной, шестнадцатеричной и восьмеричной системах счисления Листинг 4 4 представляет собой примеры для вывода информации и значений переменных с использованием системной задачи Sdisplay. Таблица 4.4 Символы представления формата для вывода данных Символ %d or %D %b or %B %h or %H %o or %0 %t or %C %v or %V %m or %M %sor%S %t or %T Описание формата Десятичный формат Двоичный формат Шестнадцатеричный формат Восьмеричный формат Символы в формате ASCII Интенсивности сигнала класса pet Иерархическое имя В виде строки Текущий формат времени Листинг 4 4 Примеры использования системной задачи Sdisplay //выводится строка из кавычек $display("He!lo Verilog World"), - Hello Verilog World //выводится текущее время моделирования $display($time), --230 // выводится время и значение параметра aadr в этот момент reg [0-40] addr, $display("At time %d address is %h", Stime, addr), - At time 200 address is 1fe0000001c // выводится значение 5-разрядного двоичного регистра reg [4 0J portjd, $disp!ay("!D of the port is %b", portjd), -:D of the port is 11001 // выводится в двоичной форме значение 4-битовой шины, содержащее символ х reg [3 0] bus, $d'splay("Bus value is %b", bus), -Bus value is 10xx // выводится иерархическое имя модуля, ьет необходимости указывать аргумент $dispiay("This stnng is displayed from %m level of hierarchy"), - This string is displayeo from top p1 level of hierarchy // выводятся специальные символы перевода строки и % $display("This is a \n multiline string with a %% sign")
106 -- This is a - multiline string with a % sign 4 4.2 Smonitor Задача Smonitor предлагает механизм мониторинга для наблюдения за изменениями сигналов. Ее синтаксис: Smonitor jSmomtorb | $monitorh |$monitoro(p1, p2, рЗ, ), где pi, р2, рЗ, .. - может быть имя переменной или строковое значение в кавычках. Данные выводятся при каждом изменении переменных, приведенных в списке Задачи с окончаниями b, h и о функционируют подобно аналогичным модификациям задачи Sdisplay Если в модели описано несколько операторов мониторинга, активным будет только последний из них. Для отключения и включения мониторинга могут быть использованы такие задачи- Smonitoron, // влючить мониторинг Smonitoroff, // выключить мониторинг По умолчанию, после запуска моделирования мониторинг считается активным. Далее приводится пример использования системной задачи Smonitor для наблюдения за сигналами синхронизации clock и сброса reset: // Мониторинг значения сигналов clock и reset с указанием времени // Сигнал clock переключается каждые 5 единиц времени // Сигнал reset установится в 0 в 10 единиц времени initial // блок инициализации $monitor($time "dock = %b, reset = %b", clock, reset); //Фрагмент выводимых при мониторинге данных - 0 clock = 0, reset = 1 -5 clock = 1, reset = 1 --10 clock = 0, reset = 0 Оператор initial описан в разд. 5 4 4.3. Sstop и Sfinish. Системные задачи Sstop и Sfinish сл}жат для управления процессом моделирования Задача Sstop позволяет выполнять моделирование в интерактивном режиме, приостанавливая его, после чего проектировщик может проверять значения сигналов в точке останова. Задача Sfinish завершает процесс моделирования и передает управление операционной системе. Синтаксис обеих задач: Sstop [(n)], Sfinish [{n)3, где п - выражение, определяющее условие приостановки или завершения процесса моделирования (табл. 4.5). Если этот параметр не указан, то по умолчанию его считают равным 1. Примеры использования- Sstop // приостановка процесса моделирования с выводом времени моделирования #150 $finish(2), // завершение процесса моделирования с выводом времени моделирования, времени работы процессора и размера использованной памяти
107 1 аблица 4 5 Режимы диагностических сообшений задам $stop и Slinish п 0 1 , Сообщение Отсутствует Время моделирования Время моделирования и работы СРП. размер испопьзуемои памяти 4.4 4 Spnnttimescale Следующие системные задачи и функции используются для отображения параметров времени моделирования Spnnttimescale [ ( hierarchicaljiame) ]; функции r.teger $time nteger $stime -ea! Srealtime Задача Sprinttimescale - выводит единицы измерения и точность вычисления времени для указанного модуля hierarchicaljiame Системные функции $time и Sstime возвращают текущее время моделирования в виде 64- и 32-битового целого числа, а функция Srealtime - в вещественном формате. Следующий код содержи г пример использования системной задачи Sprinttimescale- smescale 1 ms /1 us •module a_dat iiitial Spnnttimescale, endmodule 4.4.5. Srandom Системная функция Srandom обеспечивает механизм для псевдослучайной генерации значений. Размер возвращаемых значений соответствует типу integer. Типичный пример использования функции Srandom parameter SEED = 33, 'eg [31-0] vector, a-ways @(posedge clock) ' vector = Srandom (SEED), 4.5. Контрольные задания 1 Полное устройство вычитания имеет три входа: х (уменьшаемое), у (вычитаемое) и i (заем с предыдущего разряда) Выходы - D (разность) и В (заем) Функция может бы 1Ь описана булевыми уравнениями: D = x y-z+x у z + x у z + x у I, В - х у + х 1 + у-г . Разработать полное Verilog-описание устройства вычитания. Написать мотель верхнего уровня, сформировать тестовые последовательности из всех
108 восьми комбинаций входных переменных Выполнить верификацию устройства вычитания: 0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 1 0 1 1 I 0 I 1 1 в 0 1 1 0 0 0 D 0 1 0 1 0 0 2. Амплитудный компаратор, использующийся для сравнения чисел, имеет два 4-разрядных входа A[3.0J и В[3:0]. Сравнение может быть выполнено с помощью побитовой операции, которая соответствует операции хпог: х(0 = А(1) В(1) + Л(1)-В(1) При любом несовпадении операндов x(i) равно 0 Компаратор имеет три выхода: A_gt_B (Л>В), A_lt_B (A<B) и A_eq_B (A-B), значения которых вычисляются с помощью следующих уравнений: A_gt_B=A(3) В(3)+х(3) А(2) В(2)-гх(3) х(2) А(1) В(1)+х(3) х(2) х(1) Л(0) В(0), AJt_B=A(3)-B(3)+x(3)-A(2) В(2)+х(3)-х(2)-А(1)-В(1) + fx(3)-x(2) x(l) А(0)-В(0), A_eq_B = x(3)-x(2)-x(l)-x(0). Написать Verilog-модель компаратора и модуль верхнего уровня для выполнения верификации с использованием нескольких значений А и В. 3. Синхронный счетчик может быть построен с использованием двухступенчатого Ж-триггера. Ниже представлена вентильная схема Ж-триггера (рис. 4.1). Если clear = 0, то триггер устанавливается в нулевое состояние. Первая ступень триггера сохраняет значения по положительному фронту сигнала clock, вторая - по отрицательному. Для счетчика (рис 4.2) операция счета разрешена, когда сигнал countenable = 1. Разработать Verilog-модель счетчика dataflow-уровня. Разработать тестовый файл. Рис 4 1 ДвухступенчатыйЖ-триггер
Рис 4 2 Четырехразрядный синхронный счетчш - Каким будет результат выполнения следующего оператора? a) latch = 44112; Sdisplay("The current value of latch = %bW\ latch), 5) in_reg~3'd2. S-Tionitor($tmne, "In register value = %b \n" in_reg[2 0]), з> define MEM_S1ZE 1024, Saisplayfthe maximum memory size is %h", MEM_SIZE ), 5. В чем различие между системными задачами Sdisplay и Swrite? Тестовые вопросы. 1. Что означает оператор а == b в Verilog7 2. Что означает оператор а !~=~ b в Veniog9 3 Чему равен результат операции Y ■= {4{А}}, где А 1'Ъ\? 4 Чему равен результат операиии Y = {3{А}}, где А - 2'ЬО? 5 Чему равен результат операции XjY для переменных X = 5'blGiOl, Y=5'b00111? 6 Чему равен результат операции X&Y для переменных X = 5'Ы0101, Y = 5'bOOi U? 7. Чему равен результат операции XAY для переменных X = VblOlOl, Y = 5'b00111? 8 Чему равен результат операции &Х для X - 5'Ы0101? 9 Чему равен результат операции IX для X = 5'Ь10Ш1? 10 Чему равен результат операции Y={A, В, С, D, 3'В101} для А=ГЫ, В=ГЬ0,С=2'Ы1,1>=2'Ь00'' 11. Укажите правильный, описывающий задержку линии в Verilog, оператор: a) wire #10 out, _ б) wire #10 ns out в) w,re #(10 ps) out г) assign #10 ns out = ml & m2, 12 Укажите правильный оператор, описывающий задержку линии в Verilog: а) #10 and (out, a, b), б) wire #10 ns out, в) assign #10 out = in1 & in2, r) assign #10 ns out = in1 & in2
5. ПОВЕДЕНЧЕСКИЕ МОДЕЛИ 5.1. Блоки Initial и Always Поведенческие модели - это модели высокого уровня, которые описывают am оритм функционирования устройства без детализации на логические вентили или пути передачи данных [5, 6,9]. Их основными конструкциями являются initial и always, внутри которых размещаются все остальные операторы поведенческого уровня описания моделей. Операторы initial и always не могут быть вложенными Каждый из них представляет собой отдельный поток, который начинает свое выполнение в момент времени t=0. Присваивать значения в блоках initial и always можно только неременным класса register. Оператор инициализации начинается с ключевого слова initial. Он выполняется один раз, сразу после начала моделирования. Если операторов initial несколько, каждый функционирует и заканчивает свое выполнение независимо от другого. В случае, когда конструкция initial содержит более одного оператора, они записываются между ключевыми словами begin и end (листинг 5.1). Листинг 5.1. Пример использования инициализации moduie stimulus, гед х, у, a, b, // определение регистровых переменных begin #5 а = 1 "Ы, //а получит 1 в момент времени 5 // после старта моделирования #25 b = 1 'ЬО, // b получит значение 0 в момент времени 30 #10 х = 1 'ЬО, // х получит значение 0 в момент времени 10 #25 у = 1'М, //у получит значение 1 в момент времени 35 end initial #50 Sfinish, // завершение моделирования в момент времени 50 endmodule Операторы, содержащиеся в always, выполняются непрерывно, подобно циклу, начиная с момента времени г=0 (листинг 5 2). Если модуль не имеет выражений Sstop и Sfmish, моделирование происходит в бесконечном цикле. Листинг 5.2. Пример использования конструкции always module clock_gen, reg clock, // определение регистровой переменной dock = 1'Ь0, //Инициализация синхросигнала 0 always //Переключает clock с периодом 20 единиц времени
#10 clock = -clock, #1000Sfimsh, endmodule 5.2. Процедурные операторы назначения Процедурные операторы назначения сигнала используются в конструкциях mitia! и always и применяются для присвоения значений переменным класса register, reg, integer, reai, realtime и time. Синтаксис: registerjdentifier = expression, register^ identifier <= expression, где register identifier может быгь переменной или вектором регистрового типа, элементом памяти, фрагментом вектора регистрового типа или конкатенацией перечисленных элементов В выражении expression могут быть использованы переменные классов net и register. Различают два вида процедурных операторов назначения: блокирующие (=) и неблокирующие (<-) Блокирующие (blocking assignments) процедурные операторы назначения выполняются в порядке, как они записаны в последовательном блоке В параллельном блоке они не мешают выполнению следующих за ними операторов. В примере из листинга 5.3 в нулевой момент времени происходит инициализация скалярных перемеьных х, у и г.; переменной count, типа integer, и двух регистровых векторов rega и reg_b. Затем, через 15 единиц времени второй элемент вектора rega получает значение !. Следующий оператор выполнится после задержки в 10 единиц or текущею времени моделирования (15 единиц времени) в момент, равный 25 единицам времени. Затем переменная count получит значение з момент времени, равный 25 единицам, поскольку данный оператор имеет нулевую задержку Листинг 5 3. Пример использования блокирующих операторов гед х, у, z, гед [15-0] гед_а, гед_о, integer count initial begin // время выло пения операторов х=0, y=l,z=1, //time0 count=0, // time 0 гед_а=16Ъ0, reg_b = reg_a, // time 0 #15 reg_a[2]=1 'Ы, // time 15 #10 reg_b[15 13]={x, y, z} // time 25 count=count+1; / time 25 Неблокирующие операторы начинают выполняться одновременно со стартом всего содержащего их блока, в зависимости от указанного в них механизма управления Они позволяют моделировать несколько путей изменения данных, инициализируемых одним общим событием. В примере (листинг 5 4) для присвоения значений переменным reg_a[2J, reg_t>[15'13] и count используются неблокирующие операторы, запуск которых будет инициализи-
112 рован одновременно после выполнения указанных перед ними блокирующих операторов в момент времени 0. Переменная reg_a[2] получит значение после задержки в 15 единиц времени, a reg b[15:13] - после 10 единиц времени от начала моделирования Листинг 5 4. Пример использования неблокирующих операторов гед х, у, 2, гед [15 0} гед_а, гед__Ь, integer count, initial begin // время выполнения операторов x=0,y=1,z=1 count=0, гед_а=16'Ь0, reg__b = reg_a, #15 reg_a[2] <= 1 'Ы, // time 15 #10 reg_b[15.13] <= {x, y, z} // time 10 count <= count+1, // time 0 end Листинг 5 5 иллюстрирует механизмы выполнения блокирующих и неблокирующих операторов. В примере 1 использование блокирующих операторов приведет к возникновению гонок между переменными а и b В данном случае конкретное значение переменных будет зависеть от реализации программы моделирования. В примере 2 вычисленное значение заносится во временный буфер и только затем присваивается переменным, поэтому никаких конфликтов не возникает. Выполнение таких операторов равносильно использованию блокирующих операторов т примера 3. Листинг 5.5. Сравнение блокирующих и неблокирующих операторов // Пример 1 always @(posedge dock) a = b, always @(posedge clock) II Пример 2 always @(posedge clock) always @(posedge dock) // Пример 3 always @(posedge dock) tmp_a = а, //сохранение значения а во временной переменной tmp_a tmp_b = b, // сохранение значения b во временной переменной tmp_b а = tmp_b. // присвоение значения а временной переменной tmp_b b = tmp_a, // присвоение значения b временной переменной tmp_a
113 5.3. Временное и событийное управление операторами в блоках Существует три способа управления процессом выполнения операторов управление задержкой (delay control), использует символ #, управление событием (event control), использует символ @; управление значением (level- sensitive timing control), использует оператор wait 5.3 1. Управление задержкой Управление задержкой описывает время между чтением оператора и его выполнением. Синтаксис задержки такой же, как и при описании задержек вентилей и непрерывных операторов назначения: #NUMSER | identifier | #(mm гуртлах) Если оператору задана ненулевая задержка, то он будет выполнен через указанный промежуток модельного времени. Например гед х, у, begin х=0, // нет управления, выполнится сразу после начала моделирования // в time=0 #10 у = 1,11 задержка равна 10 единицам // Переменная у получит значение 1через 10 единиц времени // в момент времени time = 10 #у х=х+1,// используется идентификатор для указания величины // задержки, оператор будет выполнен в момент времени time = 10+у end Для устранения гонок операторов, вычисляемых одновременно, используется управление нулевой задержкой (zero-delay control), которое гарантирует последовательное их выполнение. На практике обычно не рекомендуется одновременное присвоение значения переменным в нескольких операторах. Тем не менее, нулевая задержка представляет собой удобный механизм для управления порядком выполнения операторов при моделировании: beg,n х=0, у=0, end begin #0 х=0 #0 у=0, 5.3.2. Управление событием (Event control) Событие - это изменение значения регистра или цепи. Существует четыре типа событийного управления порядком выполнения операторов обычное событийное управление (regular event control), именное событийное управление (named event control), событийное управление по ИЛИ (event OR control) и управление с использованием оператора цикла repeat
114 Обычное событийное управление (regular event control) для описания использует символ @ Выражение выполняется после изменения или появления фронта, указанного в скобках сигнала Для описания фронта применяются ключевые слова posedge и negedge. Posedge обозначав! положительный фронг - переключение из значения 0, х, z в 1 и из 0 в z или х (табл. 5.1). Negedge представляет собой отрицательный фронг - переключение из значения 1, х, z в 0 и из 1 в z или х. Примеры использования обычного событийного управления: @(clock)q=d; // q будет получать значение переменной d ■''-■'" // при любом изменении clock @(posedge clock) q=d, // q будет получать значение переменной d, // по положительному фронту clock @(negedge clock) q=d, // q будет получать значение переменной d, // по отрицательному фронту clock Таблица 5.1. Определение положительного и отрицательного фронтов Из\В 0 1 i. о | ш 1 1 posedge posedge posedge * 1 ' posedge posedge negedge negedge Событийное управление по ИЛИ (event OR control) позволяет задавать несколько сигналов через ключевое слово or. Выполнение оператора происходит при изменении хотя бы одного из этих сигналов: always @(reset or clock or d) li блок будет инициализирован при изменении хотя бы одного из сигналов if(reset) h' q=1'b0, ■*" else q=d. Новый стандарт позволяет заменять слово or запяюй Таким образом, представленный выше пример может иметь вид: always @(reset, clock, d) if(reset) q=1'b0, else q=d, Базовая форма комбинационной логики, реализованной с помощью процедурных операторов, представлена листингом 5.6 а). Список чувствительности оператора always должен в этом случае содержать все входные линии схемы. Распределенной ошибкой в таких моделях является не полностью описанный список чувствительности, в нем пропущены сигналы, значение которых читается в границах оператора always. В новой версии стандарта внесли изменения, которые позволяют упростить описание оператора и из-
115 бежать ошибок такого рода. Листинг 5 6 6^ содержит измеленную модель из листинга i с использованием конструкции @(*) Листинг 5.6 Пример комбинационной схемы э> —odule synCombmationalAlways (output reg f input a b, c), aways @ (a, b, c) if(a = 1) f=b, f = c, ancmodule - :oule synAutoSensitivity (output reg f, input a, b c), if(a==l) f = b, f = c, andmodule Именное событийное управление (named event control) требует выполнения декларации события и создания условий для его переключения Такое событие можно использовать как любое другое, однако оно не хранит никакого ■чачечия Для декларации используется ключевое слово event, для обозначения переключения - символ "-~*" Синтаксис- декларация события - =-t eventjdentifier { eventjaentsfier}, "эреключение события > э/entjdentifier, I.-.-хь eventjdentifier - имя собы'.ия Пример использования: -.. 5-it received_data, // определено событие с именем received_data = -.'.ays @(posedge c'ock) // проверка переднего фронта сигнала clock if (last_data_packet)->received_data, // если last_data_packet=1, // то происходит переключение ~nd II события received_data avrays @(received_data), // ожидает переключения события received_data datajbuf = {dataj)kt[0],data_pkt[1],data_pkt[2],data_pktf3]} Пример использования именных событий иллюстрируется моделью устройства генератора чисел Фибоначчи (листинг 5 1). Модуль numberGen формирует значение каждые 100 единиц времени я переключает событие ready. 'одуль fibNumCaic получает событие, к которому обращается через иерар- ;:ческое имя @ng.ready, где ng - имя копии модуля numberGcn's в струк- -.эной модели topFib Результатом моделирования модуля topHb являются
116 числа Фибоначчи numberOut, формируемые на основе значений number, которые генерируются модулем numberGen. Листинг 5.7. Генератор чисел Фибоначчи module topRb, wire [15 0] number, numberOut; s '■"*"■ ■■'■'•■"'- numberGen ng (number), v - >'' ; ^ ■-: fibNumCalc fnc (number, numberOut), : endmodule module numberGen (output reg [15 0] number = 0), event ready, // Декларация именного события always begin #50 number = number + 1, #50 -> ready, // Генерирование события end endmodule : module fibNumCalc (input [15 0] startingValue, output reg [15 0]fibNum), reg [15 0] count, oldNum, temp, always begin @ng ready // Ожидание события count = startingValue; oidNum = 1, for (fibNum - 0, count ■= 0, count = count -1) begin temp - fibNum, fibNum = fibNum + oidNum, : oldNum = temp end $display("%d, fibNum=%d", $time, fibNum), end endmodule 5 3.3. Временное управление значением. Управление значением (level-sensitive timing control) использует оператор wait, включающий в себя функции управления событием и цикла while. Оператор выполняется, если какое-то условие принимает значение истины. Синтаксис: wait (expression) statement_or_null где statementornull - обозначает какой-либо оператор или его отсутствие. В следующем примере выполнение оператора (#10 а - Ь;) будет отложено, пока переменная enable не станет равной 0: begin wait ('enable) #10 a = b.
117 #10c = d, end 5.3.4 Внутриоператорный контроль. По месту записи выражения, событийного или временного управления, в операторах присвоения значений выделяют внутриоператорное временное управление (intra assignment timing control) Ею синтаксис: regjvalue = [ delay_control | event_controi | repeat_event_control ] expression, или regjvalue <= [delay_conti-ol | event_control | repeat_event_control] expression, где delaycontro! - управление задержкой, eventcontro! - событийное управление, repeat event_control - конструкция repeat, которая будет рассмотрена в подразделе 5 4 "Циклы". При внутриоператорном управлении переменная получит значение после указанной задержки (управление задержкой) или выполнения условия (событийный контроль). Однако вычисление этого значения происходит сразу после прочтения оператора с текущими на тот момент значениями переменных. После этого полученное значение сохраняется программой моделирования до выполнения условия задержки или события. Например: reg х у, z; // Описание регистоовых переменных initial begin х=0, z=0, у = #5 х + z, end //Описанный блок эквивалентен следующему begin х=0, г=0, temp_xz = х + z, #5 у = х + z, end q = @(posedge clock) d, В следующем фрагменте кода, always @(posedge clock) begin regl <= #1 ml // в момент времени 1 reg2 <= @(negedge clock) m2 Л in3, // no заднему фронту clock reg3 <= #1 regl, // в момент времени 1 end После появления переднего фронта clock выполняется чтение расположенных с правой стороны переменных (inl, in2, in3, regl) Вычисляются значения выражений с правой стороны, которые сохраняются в памяти программы моделирования. Запись значений в переменные, расположенные с левой
118 стороны, будет выполняться в соответствии с описаниями задержек и событий. Для неблокирующих операторов порядок их выполнения не зависит от последовательности записи, а определяется только параметрами управления. Очередность выполнения операторов не повлияет на результирующее значение reg2, поскольку программа моделирования хранит старое значение reg!, которое было считано при поступлении события @(pobedge clock). 5.4. Операторы управления: if, case, casez и casex. Циклы 5.4.1. Оператор if Синтаксис оператора if: //Тип1 if (expression) true_statement, //Тип 2 if (expression) tme_statement, else faulse_statement, // Тип 3 if (expressionl) true_statementl, else if (expression2) true_statement2, eise if (expressions) true_statement3, .,., else default_statement, faulse_statement, Примеры использования оператора if представлены листингом 3.8. Листинг 5.8. Примеры использования оператора if .^ // Пршер 1 if (index > 0) if (rega > regb) result = rega else // ветвь else принадлежит предыдущему оператору if result = regb, // Пример 2 if (index >0) begin if (rega > regb) result = rega, else result = regb, // Пример З с использованием конструкции else if if fa) b = 4, // если а не равно 0, то b получит значение 4 else if (d) b = 5, // если а=0, a d не равно 0, то b получит значение 5 b = 1, // иначе, если а=0 и d=0, то Ь получит значение 4 // Пример 4 if (а) //ветвь будет выполнена если а ье равно 0 begin counter = counter + 1,
119 data_out = counter, data_out = 8'bz, "аимер 5 - counter > 10) // ветвь не имеет оператора (нулевой оператор) counter = counter + 1, f - 2 Оператор case Оператор case - это оператор множественного выбора Его синтаксис 2S5 ; expression) expression statementl, expression {, expression} statement?, default [ ] defau!t_statement, ":г-ющии пример иллюстрирует использование case для выбора различ- -.=. < операторов, в зависимости от значения двухразрядной переменной HTcress: •?: '.3] address, "Л5= 3ddress; 2'b00 statementl, 2'Ь01,2'Ы0 statement? default statement3; ~.-с-;'нг 5 9 содержит поведенческую модель мультиплексора 4-в-1 с ис- - -азованием оператора case. Для сравнения, листинги 3.5 и 3.7 представ- Ес- это устройство на уровне dataflow. Мультиплексор имеет два управ- f- лих входа s0 и si Чтобы использовать их как единый операнд в опера- .сс case, применяется конкатенация. Ветвь default будет выполнена, если •.эта бы один из управляющих входов получит значение, отличное от нуля и* единицы " «стинг 5 9. Модель мультиплексора 4-в-] с использовани'ем case -зг^е mux4_to_1 (out, Ю, И, i2, i3, s1, sO), //Декларация портов output out input Ю, i1,i2, i3, input s1,s0, reg out, // определение регистровой переменной выхода //для использования ее в операторе always - §>(s1 or sO or Ю or i1 or i2 or i3) - s1 s2}) // конкатенация учравляющих сигналов в 2-битовое значение 2 d0 out - Ю ?d1 out = 11
120 2'd2 out = i2, 2'd3 out = i3, default $display("lnvalid control signals"); endcase endmodule 5.4.3. Операторы casez и casex. В Verilog определены еще две разновидности оператора case- casex и casez. Они позволяют рассматривать отдельные биты в выражениях выбора как не имеющие значения. Такие позиции могут быть обозначены символом '">". Casez рассматривает все позиции с символом z как не имеющие значения, а для casex - это х и z. При использовании casex и casez выполняется сравнение только не-х и не-z позиций. Синтаксис casez (expression) expression statementl, expression {, expression} statemenr.2, default default_statemeni, endcase casex (expression) expression statementl; expression {, expression} statements, default default_statement, enacase Листинг 5.10 содержит примеры использования операторов casex и casez Пример 1 иллюстрирует применение оператора casex для декодирования битов состояния автомата Пусть encoding=4'bl0x7, тогда переменная next_state примет значение 3. Пример 2 представляет использование опера- гора casez. Декодирование операции выполняется по ее старшим значащим битам. Если самый значащий биг равен 1, то будет вызвана команда instruction!, независимо от значений остальных битов ir. В примере 3 с помощью оператора casex демонстрируется динамическое управление процессом моделирования. Благодаря использованию маски mask при г ~ 8'Ь01100110 будет выбрана задача stat2. Листинг 5.10 Примеры использования операторов casex и casez //Пример 1 гед [3:0] encoding, integer state, casex (encoding) 4'Mxxx next_state=3, 4'bx1xx next_state=2, 4'bxx1x next_state=1, 4'bxxxl next_state=0, default next_state=0, endcase
121 // Пример 2 reg [7 0] ir, casez (ir) 8'b01 ??""?? 8'ЬОООЮ'"'? e'bOOOOOf" endcase // Пример 3 reg [7 0] r. mask, mask = 8'bx0x0x0x0, casex (гл mask) // гл mask=8'bx1 xOxl xO для г=8'Ь01100110 8'b001100xx stall, 8'b1100xxOO stat2, 8'b00xx0011 stat3, 8'bxx010100 stat4, endcase 5.4.4. Константное выражение в операторе case. Если оператор case использует константные величины, то значения для вариантов выбора должны представлять собой выражения. Например, с использованием константного выражения может быть построен трехбитовый приоритетный декодер. Будет выбрана первая ветвь, для которой encode[i] -1: reg [2 0] encode; i,ase(1) encode[2] $display("Select Line 2"), encode[1] $dispiay("Select Line 1"), encode[0] $display("Select Line 0"), default' $disp!ay("Error Ore of the bits expected ON"), endcase 5 4.5 Циклы. Venlog предлатает четыре вида циклов: while, forever, repeat и for Их синтаксис while (expression) statement, forever statement; repeat (expression) statement; for (assignment, expression, assignment) statement, Цикл repeat повторяет выполнение оператора statement с числом раз, заданным выражением expression. Если значение последнею неизвестно или зафиксирован высокий импеданс, го оно принимается равным нулю. Это означает, что оператор никогда не будет выполнен Цикл while выполняется, пока выражение expression не примет значение false или 0. Конструкция forever выполняет выражение бесконечное число раз Для него необходимо использовать временное управление, иначе оператор может подвесить программу mstructionl(ir), instruction2(ir), mstruction3(ir), mstruction4(ir);
122 моделирования. В операторе for для управляющего параметра задается начальное значение, условие завершения и выражение модификации Листинг 5.11 содержит примеры описания различных циклов. В примере 1 цикл for использует управляющую переменную count, которая изменяется от О до 127 с шагом 1 Цикл forever из примера 2 применяется для формирования синхросигнала с периодом 20 единиц времени, сигнал clock переключает свое значение через каждые 10 единиц времени. В примере 3 операторы, содержащиеся в цикле repeat, будут обработаны 128 раз. Цикл while из примера 4 будет повторя гь выполнение операторов, пока tempreg = 1. Листинг 5.11. Примеры использования операторов цикла // Пример 1 integer counter, initial for(count=0, count<128, count=count+1) ; // Пример 2 initial begin clock=1'b0, forever #10 clock = -clock; // генерирует синхросигнал с периодом // 20 единиц времени end // Пример 3 integer count, initial begin count - 0, repeat{128) //цикл выполняется 128 раз begin "'": $dispiay("Count = %d", count), count = count + 1, end end // Пример 4 while (tempreg) begin if (tempreg[0]) count = count + 1, tempreg = tempreg » 1, end end Следующее выражение иллюстрирует использование оператора repeat для внутреннего событийного управления в неблокирующих операторах присвоения- а <= repeat(5) @(posedge elk) data,
123 Значение data будет сохранено сразу после появления оператора, переменная а получит свое значение после поступления пяти положительных фронтов синхросигнала elk (рис 5 1) 12 3 4 С1к 1 1 , А__ \ "UTJ~ . ^ ; „Г" Рис 5 1 Испо 1Ьзоваиие событийного контротя с операюоом repeat Аналогичным образом используется внутриоператорное событийное управ- тение с repeat в процедурном блокирующем операторе присвоения Для выражения а = repeat(num) @(clk) data, значение data будет храниться программой моделирования с момента появления оператора и до поступления num событий на elk, после чего оно будет присвоено переменной а 1акже в операторе repeat можно использовать сумму двух переменных, чтобы указать необходимое число повторений событий. э <= repeat(a+b) @(posedge phil or negedge prn2) data, 5.5. Специальные свойства блоков Блоки позволяют фуппировать несколько операторов, выполнение которых рассматривается как один В Veriiog есть два типа блоков. - последовательные, или begin - end блоки; - параллельные, или fork- jom блоки. В предыдущих примерах для группирования операторов использовались последовательные блоки с ключевыми словами begin-end В них последовательные операторы выполняются в том порядке, в котором очи описаны, за исключением команд с внутриоператорным временным контролем (mtra- assignment timing contiol). Если встречается задержка или событие, то время их выполнения отсчитывается от момента завершения предыдущею оператора Операторы в параллельных блоках выполняются одновременно: порядок выполнения операторов контролируется задержками и событиями Выполнение всех операторов начинается в момент входа в блок Поэтому задержки и события относятся к началу выполнения блока, порядок записи операторов в блоке является несущественным После завершения выполнения всех операторов в параллельном блоке управление передается за блок. Синтаксис блоков' 7 последовательный блок //параллельный блок cegin name fork name statement, statement,
124 end join Описание последовательных и параллельных блоков иллюстрируется листингом 5.12. Пример 1 показывает использование последовательного блока, не содержащего временного управления Операторы блока будут выполнены по порядку, сразу после его инициализации. Пример 2 содержит те же конструкции, что и пример 1, но с использованием механизма управления задержкой. Поэтому первый оператор будет выполнен в момент времени О, второй - в момент времени 5, третий - в 15, а последний - в 35. Пример 3 представляет параллельный блок, операторы которого обрабатываются параллельно после указанных в них задержек. Блоки могут быть вложенными или смешанными, пример 4 иллюстрирует данную ситуацию. Пример 5 рассматривает ситуацию, ко1да параллельный блок используется для проверки выполнения двух событий @Aevent и @Bevent, которые могу г происходить в любом порядке. После этого блок передает управление следующему за ним оператору. Если бы в примере вместо параллельного использовался последовательный блок, то очередность появления событий была бы очень существенна и приводила бы к различным результатам моделирования. Листинг 5.12. Примеры использования блоков //Пример 1 regx,y, reg[1.0]z, reg[2 0]w, initial begin х = ГЬ0, y = VM: z = {x, y}, w = {y.z}. end // Пример 2 - последовательный блок с задержками reg x,y, reg [1 0] z; reg [2 0] w, initial begin x = 1"b0, #5y = 1'M. #10 z = {x, y}, #20w = {y,z}, end //Пример З - параллельный блок fork #50 г = 1 ЬО, #100 г = 1'M, #150r=1'b0, #200 r= 1'M; #250 -> end_wave, join
125 11 Пример 4 - параллельный блок является вложенным в последовательный initial oegin х = 1'Ь0, fork #5 у = 1'M, #10z = {x,y}, join #20 w = {y, x} end // Пример 5 begin fork @Aevent, @Bevent, join areg = breg1 каждому блоку может быть поставлено в соответствие имя. Такие именные блоки являются частью иерархии проекта. Они могут иметь локальные переменные, которые будут доступны через иерархическое имя. К ним можно применять механизм приостановки или завершения выполнения блока: module top, begin blockl // последовательный блок с именем blockl integer i, // иерархическое имя top biokl i end *ork biock2 // параллельный блок с именем Ыоск2 reg i, // иерархическое имя top block2 \ join Оператор disable предоставляет способ для завершения выполнения блока. Он может быть использован для выхода из цикла, обработки условий ошибок, выхода из любого именного блока проекта. •'/ обнаруживает первый бит со значением 1 reg [15 0] flag, integer i, initial begin flag = 16'b0010_0000_0000_0000, i = 0, begin blockl while (i<=16) begin if (flag [i]) begin
126 Sdisplay ("Encountered a TRUE bit at element number %d", i), disable blockl, end i = i + 1. end end end 5.6. Процедурные операторы непрерывного назначения Процедурные операторы непрерывного назначения (procedural continuous assignments) (ключевые слова assign and force) - это операторы, которые позволяют выполнять непрерывную запись данных в переменные классов register или net. Их синтаксис assign regjvalue = expression, deassign regjvalue, force regjvalue = expression, force netjvalue = expression, release regjvalue, release netjvalue, В операторе assign, в левой части выражения, может быть использован регистр или конкатенация регистровых переменных, но нельзя применять переменные класса net, элементы памяти, отдельные биты или диапазон регистра Пара assign - deassign - перекрывает действие обычных процедурных операторов назначения. Применяется для управления сигналами в определенный промежуток времени. Например, она можег быть использована для моделирования асинхронных сигналов триггера (чистит 5 13). Оператор deassign отменяет действие оператора assign, после чего значение регистра остается неизменным, пока для него не будет выполнен оператор процедурного назначения Листинг 5.13. Поведенческая модель D-триггера module dff (q, qbar, d, clear preset, clock), output a, qbar, mput d, clear, preset, clock, reg q, qbar, always @(clear or preset) if (i dear) assign q = 0, /' сброс s 0, если clear = 0 else if ('preset) assign q = 1, // установка в 1, если preset = 0 else deassign q, // отмена действия оператора assign, если clear - 1 и preset=1 always @(posedge clock) begin q = d // прямой выход qbar - -d, // инверсный выход end endmodule
127 Пара force и release может быть использована для перегрузки значений, присваиваемых переменным классов net и register процедурными операторами назначения или непрерывного назначения В левой части выражения может быть использована переменная или конкатенация переменных, не допускается указывать элементы памяти, отдельные биты или диапазон вектора. Оператор force применяется при отладке в блоках, формирующих тестовые последовательности Не рекомендуется его использование в модулях проекта устройства. Регистровая переменная будет иметь значение, присвоенное выражением force до выполнения оператора release (листинг 5 14. пример 1) После этого она сохранит это значение до изменения его оператором назна чения. Для переменных класса net выполнение оператора release вернет переменной ее нормальное значение (листинг 5 14, примеры 2 и 3). Листинг 5 14 Примеры использования оператора force /; Пример 1 -для переменных класса register module stimulus, edge_dff dff(q, qbar, d, elk, reset), initial begin #50forcedffd = 1M, #50 release dff q end endmodule .7 Поимер 2 - для переменных класса net ^nodule top assign out = a & b & c, initial begin #50 force out = a | b | с #50 release out, erd erdmoduie '/ Пример 3 module test, reg a, b, с d, andandl (e, a b, c), initial begin $monitor("%d d=%b,e=%b" Sstlme, d, e), assign d = a & b & c, a = 1 b = 0,
128 c = 1; #10; force d = (a | b | с), force e = (a | b | c), #10 Sstop; release d, release e; #10 Sflnish. end endmodule Результат выполнения системной задачи Smonitor 0 d=0,e=0 10d=1,e=1 20 d=0,e=0 5.7. Примеры поведенческих моделей устройств В листинге 5.15 представлена модель счетчика, выполняющего счет на увеличение от 0 до 15 Для установки в начальное нулевое состояние используется вход clear, для проверки максимальной фаницы - операция по модулю 16. Лисгиш 5.15. Модель 4-разрядного счетчика module counter (Q, clock, clear), output [3 0] Q, input clock, clear reg [3 01 Q always @(posedge clear or negedge clock) if (dear) Q = 4'd0, else Q = (Q + 1) % 16, // s некоторых случаях оператор по модулю // можно не использовать endmodule Далее предлагается Venlog-модель управляющего светофором устройства. Светофор расположен на пересечении главной (Main highway) и второстепенной (Country road) магистралей. Главная магистраль имеет приоритет, поэтому на ней всегда по умолчанию горит зеленый свет. На второстепенной дороге зеленый свет загорается только на время, необходимое для пересечения машиной перекрестка. Если на второстепенной дороге отсутствуют машины (Х=0), то загорается красный свет светофора, пока датчик не обнаружит машину. Тогда он сгенерирует сигнал Х=1, который инициирует процесс переключения светофора. Граф переходов автомат и таблица значений выходов представлены на рис 5.2 Переключение между состояниями S! и
129 S2, S2 и S3, S4 и SO выполняется после контролируемой задержки. Листинг 5.16 содержит Vcnlog-код автомата. Для удобства и наглядности состояния автомата и значения выходов определены с помощью текстовых макросов с использованием конструкции 'define. В модели применяется оператор initial для инициализации начального состояния автомага и значения его выходов. Поведение устройства реализовано с помощью грех операторов always' для обновления по переднему фронту синхросигнала состояния автомата, для вычисления значений выходов, для определения следующего состояния автомата. Testbench автомата и результаты моделирования представлены листингом 5.17. Main Highway ■О \_J Рис 5 2 Граф состояний и таблица значений выходов автомата Листинг 5 16. Поведенческая Venlog-модель автомата Мура /' создание текстовых макросов для выходных функций автомата // красьый цвет светофора // желтый цвет светофора :т светофора CNTRY RED RED RED GREEN YELLOW State "so"] Si S2 S3 S4 Signals, Hwy G Y R R R Cntry R R R G Y define RED 2'dO 'aefine velLOW 2'd1 define GREEN 2'd2 //состояния автомата 'define SO 3'dO define S1 3'di define S2 ЗУ2 define S3 3'd3 define S4 3'd4 II Задержки define Y2RDELAY 3 define R2GDELAY 2 HWY // GREEN // YELLOW // RED //RED //RED // Задержка переключения из желтого в красный // Задержка переключения из красного в зеленый module sig _control(nwy entry X, clock, clear), //Описание входных и выходных портов output [1:0J hwy, cntry, reg [1 0] hwy, cntry, input X, input dock, clear; // Внутренние переменные для текущего и будущего состояний автомата reg [2 OJ state, next__state, initial // Инициализация состояния автомата и значений выходов beg-n state = SO, next_state= SO, hwy= GREEN, cntry = 'RED, end
always @{posedge clock) // обновление значения состояния автомата state = next_state, // по переднему фронту синхросигнала begin case (state) 'SO begin end *S1. begin end •S2 begin end 'S3 begin end S4 begin end endcase always @(state or clear о begin ■f (clear) next_ hwy = 'GREEN, entry = RED, hwy = 'YELLOW, entry = RED, hwy= RED, entry = RED, hwy ='RED, entry = GREEN, hwy ='RED, . •■..,.,, entry = 'YELLOW, irX) state = 'SO case (state) 50 if (X) next_state= S1, else next_state= SO, 51 begin repeat ( Y2RDELAY) @(posedge clock), next_state= S2, end "S2 Degin repeat ('R2GDELAY) @(posedge clock), next_state = 'S2, end 'S3 if (X) next_state = S1, else next_state = SO, S4 begin repeat ( Y2RDELAY) @(posedge clock), next_state= S2,
default next_state = SO, endcase ;нг 5 17. Testbench для проверки автомата Мура ^ "RUE 1'М -2cALSE1'bO . е stimulus, wire [1 0] MAIN_SIG, CNTRY_S!G reg CAR_ON_CNTRY_RD, // если сигнал равен TRUE это означает // что на второстепенной дороге находится автомобиль reg CLOCK, CLEAR, ss_control sc(MAIN_SIG, CNTRY_SIG, CAR_ON_CNTRY_RD, CLOCK, CLEAR), nzsi il Инициализация мониторинга Smonitor($time," Main Sig = %b Country Sig = %b car_on_cntry = %b", MAIN_S!G, CNTRY_SIG, CAR_ON_CNTRY_RD), Trai begin // Генерирование синхросигнала CLOCK = TALSE, forever #10 CLOCK = -CLOCK, = oegm // Управление сигналом сброса CLEAR = TRUE, repeat (5) @(negedge CLOCK i CLEAR = FALSE, = Deg'n // Генерирование входных импульсов CAR_ON_CNTRY_RD = FALSE, repeat (3) begin #200 CAR_ON_CNTRY_RD = TRUE, #100CAR_ON_CNTRY_RD= FALSE; end #100$stop, end э-vdmodule результаты моделирования для timescale 1ns/1ps * 0 Main Sig = 10 Country Sig = 00 car_on.entry = 0 * 200 Main Sig = 10 Country Sig = 00 car_on_cntry = 1 * 210 Main Sig = 01 Country Sig = 00 car_on_cntry = 1 = 270 Mam Sig = 00 Country Sig = 00 car_on_cntry = 1 £ 300 Main Sig - 00 Country Sig = 00 car_on_cntry = 0 S: 500 Main Sig = 00 Country Sig = 00 car_on_cntry = 1 = 600 Main Sig = 00 Country Sig = 00 car_ on_cotry = 0 = 800 Mam Sig = 00 Country Sig = 00 car_on_cntry = 1 = 900 Main Sig = 00 Country Sig = 00 car_on_cntry - 0 = RUNTIME RUNTIMEJ3069 stimulus v (36) $stop called
132 Таким образом, блоки initial и always это основные операторы поведенческих моделей. Все другие поведенческие операторы помешаются внутри этих струкгур Блоки позволяют группировать несколько операторов, выполнение которых рассматривается как один оператор. Блоки бывают последовательные и параллельные. Последовательные операторы выполняются в порядке их следования в коде профаммы. Операторы в параллельных блоках выполняются параллельно, порядок выполнения операторов контролируется задержками и событиями, задержки и события относятся к началу выполнения блока 5.8. Контрольные задания 1. Создать синхросш нал, равный нулю в начальный момент времени и переключающийся через каждые 30 единиц времени. Использовать для этого цикл forever 2 Применяя операторы initial и always, спроектировать синхросигнал с периодом 10 и длительностью рабочею цикла 25%. Начальное значение синхросигнала равно 0. 3 В какой момент времени будет выполнен каждый, приведенный ниже, оператор9 Чему равны промежуточные и окончательные значения сигналов а, Ь, с, d? begin а = ГЬО, b = #10 ГЫ, с = #5 ГЬО, d = #20 {a, b с}, end 4. В какой момент времени будет выполнен каждый, приведенный ниже, оператор? Чему равны промежуточные и окончательные значения сигналов а, Ь, с, d'> initial begin а<=1Ъ0, b<=#10 1'M, c<=#5 1'bO, d<=#20 {a, b, c}; end 5. Какой порядок выполнения операторов в следующем Verilog-коде'7 Указать окончательные значения сигналов а, Ь, с, d? initial begin а=1'Ь0,
133 #Oc=b, Ь = ГЫ, #0 d - a, • уззать конечное значение d в следующем примере -= :egm о = 1'Ы, с = 1'Ь0, #10Ь = ГЬ0, «■с d = #25 (b|c); Вычислить результат моделирования следующих блокирующих и небло- ■г'-ющич операторов: (output out), гпа cegin Smomtor ("time=%d a=%d b=%d c=%d e=%d \n",$time,a,b,c,d,e; a=0, b="l,c=0 d=0, e=1, #30 Sfinssh --3.sc = #5-c, a-esys @(posedge c) begin d<=e, e<=d, srnodule • Спроектировать D-триггер (DJT) с отрицательным фронтом и синхрон- гЛ1 сбросом, активным по 1. Использовать только поветенческие операто- -=» Спроектировать тестовый модуль с синхросигналом, имеющим период Спроектировать D-триггер (DFF) с отрицательным фронтом и асинхрон- -vm сбросом, активным по 1 Использовать только поведенческие операто- ■_ Спроектировать тестовый модуль с синхросигналом, имеющим период .3. 10. Построить D-триггер с синхронизацией по уровню (latch), используя оператор wait. Трип ер имеет вход данных d и вход синхронизации elk, один выходя.
134 11. Построить модель мультиплексора 4-в-1, используя операторы if-else. 12 Посфоить устройство управления светофором (см рис 5.2), применяя операторы if-else. 13 Используя оператор case, спроектировать ALU, выполняющее 8 функций. Устройство имеет два 4-разрядных входа данных а и Ь, один 3- разрядный вход выбора операции ОР, пятиразрядный выход out. Функции ALU описаны табл. 5 2. Таблица 5.2. Функции ALU ОР З'ЬООО ЗЪ001 З'ЬОЮ З'ЬОП З'ЫОО ЗЪ101 зъпо зъш Функция out= a out - а + b out - а - b out ~ a / b out - a % b out = a « b out = a » b out - (a > b), сравнение амплитуд 14 Используя оператор цикла while, построить генератор синхросигнала с начальным значением 0 и периодом 10. 15. Применяя оператор цикла for. выполнить 0 инициализацию памяти. 16. Используя оператор цикла foiever, построить генератор синхросигнала с начальным значением 0. периодом 10 и рабочим циклом 40% 17. Применяя оператор repeat, создать задержку выполнения операюра а - а + 1 на 20 положительных фронтов сигнала elk. 18 Преобразовать следующий цикл repeat в циклы for и while: parameter DivsLength = 31 parameter DivdLength 63 Darameter QuoLenght 31 oarameter HiOminimum = 32 repeat(DivsLength+1) begin quotient = quotient« 1 dividend = dividend « 1, dividend[DivdLength HiDminimum] = dividendpivdLength HiDminirnum] - divisor, if ('dividend [DivddLength]) quotient = quotient + 1, else begin dividendfDivdLength Himinimum] = dividend[DivdLength Himinimum] + divisor,
135 19 Когда закончится выполнение следующих вложенных последовательных и параллельных блоков? В каком порядке они будут выполнены? initial begin х =1'b0, #5у = 1'bO, fork #20 a = x, #15b = y, join #40x=1'b0, fork #10p = x begin #10a = y, #30 b = x, end #5m = y join end 20. Спроектировать 8-разрядный счетчик, используя цикл forever, именные блоки и оператор disable для выхода из биока Устройство начинает счет с 5 и заканчивает на 67, работает по потожительному фронту синхросигнала, период которого равен 10. Цикл счета выполняется только один раз, после чего с помощью оператора disable осуществляется выход из блока 21. Спроектировать D-триггер с синхронизацией по переднему фронту, с асинхронными сигналами сброса (reset) и усшновки (set) Использовать assign и deassign. 22 Построить модель полного сумматора, применяя стандартные логические элементы Venlog. 11остроить тестовый модуль, испопьзуя оператор force, назначить выходу значение (а & b & c_in) в промежуток времени 15-35 единиц. 23. Однобитовый сумматор определен логическими элементами и задержками: module fulladd(sum, c_out. a, b cjn) parameter d_>um = 0, d_cout = 0, //Декларация портов output sum, c_out, input a, b, cjn // Внутренние линии wires1,d,c2, Копии стандартных элементов xor(s1,a, b), and(d, a, b), xor #(d_sum) (sum s1,c_m), and(c2, s1,c_in), cr #(d_coutj (c_out c2 c1) endmoduie
136 Используя однобитовый сумматор, разработать структурную модель разрядного сумматора fulladd4. Установить значения параметров для коп модулей из табл 5.3. Таблица 5 3. Значения параметров для копий модулей Копия модуля faO fal fa2 fa3 Значения параметров d sum ■= 1, d cout = 1 d sum = 2, d cout = 2 d sum = 3, d cout = 3 d_sum = 4, d_cout = 4 а) Построить структурную модель fulladd4, используя оператор defparam для изменения значений параметров. б) Построить структурную модель fulladd4, переопределяя параметры в операторе создания копии модуля Построить тестовый модуль Выполнить верификацию обеих моделей. Сравнить результаты верификации обеих моделей. 24. Из модели полного сумматора (см. предыдущую задачу) создать проект, использующий условную компиляцию ( ifdef) Версия проекта с применением оператора defparam для изменения значений параметров компилируется, если в проекте с использованием директивы ('define) определен макрос DPARAM, иначе компилируется код с изменением параметров в операторах копий модулей. 25. Чему будет равна переменная result после выполнения следующих операторов, если rega = 16'd3? reg [15 0] rega reg [9-0] result; 16d0 result 16'd1 result 16'd2 result 16'd3 result = 10 16'd4 result 16 d5 result 16'd6 result =10' 16'd7 result =10' 16'd8. result =10' 16'd9- result =10' default result = 'bx, 'b011 'M01 'M10- Ы110' Ы11 Ы11 111, 26. Нарисовать временную диаграмму, которая будет получена в результате выполнения следующих операторов: initial х = 1 'ЬО, repeat (3) @{posedge elk) x=~x,
27. Какой сигнал будет сгенерирован после выполнения следующих операторов'' initial begin clock=1'b0, , forever #20 clock = -clock, 28 Каким будет результат выполнения оператора, если num = 2° а = repeat(num) @(posedge dk) data; £HL=D=J Рис 5 3 Временная диафамма 29 Каким будет результат выполнения оператора, если п а = repeat(num) @(clk) data, Рис 5 4 Временная диафамма
138 6. ПОДПРОГРАММЫ 6.1. Подпрограммы Task Function Как и в любом другом языке профаммирования, подпрофаммы позволяют разбивать большой код на отдельные фрагменты. Verilog располагает двумя типами подпрофамм: задачи (task) и функции (function) [5,6,9]. Основная цель функции - сгенерировать значение, которое может быть использовано в выражении. Она всегда возвращает одно значение и должна иметь хотя бы один входной аргумент. Задача может формировать несколько значений выходных переменных или вообше ни одного, может не иметь входных аргументов. В задачах допускается применение задержек, временного и событийного управления, в функциях - нег В функциях не должно быть операторов, которые начинаются с символов #, @ или wait В подпрофаммах для декларации аргументов используются такие же ключевые слова, как и для пор 108 модуля. Синтаксис- //Синтаксис описания функции function [ automatic ] [ signed ] [ range_or_type ] identifier, function_item_declaration {function_item_declaration} function_statement endfunction ;-- function [automatic] [signed] [rarge_or_type] identifier (function_portJis?) blockjtem_deciaration {b!ockjtem__declaration} function_statem ent endfunction // вызов функции functionjdentifier ( expression {, expression }) //Синтаксис описания задачи task [ automatic ] taskjdentifier, {task_item_declaration} statement endtask task [ automatic ] taskjdentifier (task_port_!ist); {block_item_deciaration} statement endtask task identifier, parameter_declaration, mpuMedarafion, output_deciaration, mout_declaration, register_declaration,
139 event_dec!aration, statement, endtask // Вызов задачи taskjdentifier [ ( expression {, expression}) ], Параметр identifier описывает имя функции или задачи. Для функции - это также имя возвращаемого значения, для которого параметром range jjfjype задается тип и размер Если последний (размер) проп>щен, то по умолчанию функция возвращает однобитовое значение типа reg Можно также присвоить возвращаемому значению тип- integer, real, realtime или time Аргументы задач, объявленные как inout и out, могут использоваться юлько в процедурных операторах и должны быть, переменной регистрового класса (reg, integer, real, realtime или time), памятью, конкатенацией регистров переменных памяти, элементом или диапазоном регистрового вектора Входы функции могут быть описаны одним из двух способов. В первом случае после имени функции ставится точка с запятой После этого следует описание одного или нескольких входных портов. Во втором случае описание входов записывается в круглых скобках, через запятую после имени функции. Пример определяет функцию getbyte, с использованием первого ^листинг 6 1 а)) или второю (листинг 6 1 б)) способа описания входных параметров. Аналогичным образом определяются входные параметры и для задач. Листинг 6.2 иллюстрирует оба способа определения задач на примере задачи my_task, которая имеет пять аргументов два входных, два выходных и один двунаправленный. Листинг 6 1. Примеры описания входных параметров функции a) function [7 0] getbyte, input [15 0} address; begin getbyte - resuit_expression, end endfunction 5) function [7.0] getbyte (input [15.0] address), begin getbyte = resuif_expression; end sndfunction Листинг 6 2. Примеры описания входных параметров задач г task myjask, input a b, inout с output d, e, :-egm
140 . // операторы, определяющие работу задачи с = fool, // присвоение результирующих значений d=foo2, Ч;" е = foo3, end endtask б) task myjask (input a, b, mout c, output d, e), begin -p:'" // операторы, определяющие работу задачи с = fool, // присвоение результирующих значений d = foo2; • •:., е = foo3, endtask ,-.,..;' , „ ,.>■•....' Оба вида подпрофамм определяются в модуле и являются локальными для него В табл. 6.1 приведена сравнительная характеристика свойств функций и задач. Подпрограммы могут иметь локальные переменные, но не допускается использование переменных класса цепи. Реализуются они только с помощью поведенческих операторов. Однако они не могут включать в себя конструкции always и initial, но способны вызываться из них или других подпрофамм (функции не могут вызывать задачи). Таблица 6.1 Свойства функций и задач 1 2 3 4 5 Функция Может вызывать др\гую функцию. Всегда выпожяется мгновенно Не может содержать временные is ж событийные оператору управления Имеет только входные аргументы (input) Всегда возвращает единственное Задача Может вызывать как задачи так и функции ha выполнение может потребовался ненулевой промежуток времени Может содержать временные и™ событийные операторы управления Может иметь арп/мешы типа input, output и Не возвращает значение, но может передавать через api уметы гипа output и mout В следующем выражении одна из ветвей условного оператора содержит конкатенацию двух вызовов одной функции, word = control "> {getbyte(msbyte), getbyte(lsbyte)} 0, Листинг 6.3 представляет собой пример использования в задаче параметров, событий, входных, выходных и двунаправленных аргументов. При вызове задачи первый аргумент должен быть значением типа integer, второй - 4- разрядной переменкой типа reg, третий - однобитовой переменной типа reg. Событие е, определенное в задаче first task, может быть доступно через иерархическое имя first task.e Листинг 6.4 содержит пример создания функции для вычисления вещественных значений. Еще один пример (листинг 6 5) иллюстрирует использова-
141 ние функций для создания модели светофора Функция управляет временем между переключениями цветов светофора Листинг 6.3. Пример создания и использования задачи Jask, parameter size^, input a, integer a, mout [size-1 Oj b. output c, reg [size-1 0] d, event e, d = b, c = |d, b = -b; // Входной аргумент // Двунаправленный аргумент /' Выходной аргумент // Внутренняя переменная // Декларация события rf(ia)->e. end endtask ^ integer x, -eg a, b, у -eg [3 Oj z, -eg[7 0]w, irst_task(x, z, y), // x - переменная integer, z - 4-разрядный вектор, //у- 1-битовый reg firstJasK(x, w[7 4], w[1]), // x - переменная integer, 4-разрядный диапазон // вектора w w[1] -1-битовый reg firstjask(1,{a,b,w[3], x[0]}, y), // константа типа integer оператор конкатенации // формирует- 4-разрядный вектор х[0 у - 1-битовый reg a'ways @(firstjask e) // Использования именного события из задачи count= count+1; Листинг 6.4 Пример использования функции *unction real multiply, input a, b, real a, b, multiply = ((1 2 * a) "(b* 0 17))* 51, endfunction initial begin a = multiply{1 5, a); end Листинг 6 5 Использование задачи для модели светофора module trafficjights
reg clock, reel, amber, green, parameter on = 1, off = 0, red_tics = 350, parameter amberjics = 30, green_tics = 200, // Инициализация значений цвета initial red = off initial amber = off, initial green = off, always begin // последовательность управления светофором red = op, // включение красного цвета hght(red, redjics), green = on, !ight(green, green_tics), amber = on, light(amber, amberjics), // ожидание // включение зеленого цвета // ожидание // включение желтого цвета // ожидание // Формируется задержка на tics // до включения света color фронтов синхросигнала output color, input [31:0] tics. repeat (tics) @ (posedge clock) // выключение а // формирование сигнала синхронизации end endtask always begin #100 clock = 0, ^ #100 clock = 1, end endmodule 6.2. Автоматические функции и задачи Задачи и функции без ключевого слова automatic реализуются как статические Таким образом, все элементы таких подпрограмм объявлены статическими и являю1ся общими для всех вызовов таких задач и функций. В автоматических задачах и функциях (объявленных с ключевым словом automatic) все элементы являются динамическими и создаются при каждом вызове подпрограммы. Автоматические функции позволяют реализовывать рекурсию. Элементы автоматических функций и задач не могут быть доступны через иерархическое имя. Для автоматических задач не разрешается использовать: 1) неблокирующие операторы; 2) непрерывные процедурные операторы assign к force: 3) внут- риоператорный контроль, 4) сканирование объектов с помощью системной задачи Smonitor. Листинг 6.6 представляет пример использования автоматической функции factorial для вычисления факториала с возвратом значения в 32-битовом регистре.
143 Листинг 6 6. Пример автоматической функции module tryfact, // описание функции function automatic [31 0] factorial, input [3 0] operand; reg [3 0] i factorial = 1, for (i = 2, i <= operand, i = i + 1) factorial = i * factorial, end • endfunction //использование функции integer result, integer n, begin for(n = 0, n<=7, n = n+1) begin result = factonal(n), $display('%0d factonal=%0d", n, result), end end endmodule // результаты использования системной задачи Sdisplay 0 1 2 3 4 5 6 7 factoria!=1 factona!=1 factonal=2 factorial=6 factorial=24 factorials 20 factonal=720 factorial=5040 6.3. Системные задачи работы с файлами 6.3.1 Запись информации в файл Verilog предлагает возможность выполнять работу с файлами с применением системных задач Открыть и закрыть файл можно с помощью Sfopen и Sfclose. Открытый файл может быть использован для задач вывода результатов и мониторинга. Sfdisplay и Sfmonitor, соответственно Синтаксис- integer $fopenf filename"), $fclose(mu!ti_channei_descnptor), fiie_output_task_names(muiti_channei_decnptor, iist_of_arguments), file__output_task_name = $fdisplay | Sfdisplayb | $fdisplayh j Stdisplayo | $fwnte I $ fwnteb | Sfwriten | Sfwnteo | Sfstrobe | $fstrobeb | Sfstrobeh | $fstrobeoj
144 $fmonitor | Sfmonitorb | $fmonitorh | Sfmonitoro Функция $fopen возвращает 32-битовый дескриптор файла multichanneidescnptor. имеющий целочисленный тип. Если файл невозможно открыть для записи, то функции Sfopen возвращает 0. " ' Для тестирования сумматора ha I разработан testbench (листинг 6.7) Результат моделирования записывается в файл ha_f_rslt.txt. Файл открывается и связывается с именем "info,\ Позже задача Sfmonitor записывает значения описанных переменных в открытый файл При завершении моделирования файл закрывается автоматически. Можно закрыть файл автоматически через процедуру Sclose(info). Листинг 6.7. Пример вывода результатов мониторинга в файл "timescale 1ns/1ps module ha_1 (input a,b, output s, ca), xor#(1,2)(s,a, b), and #(3,4) (ca, a b), endmodule //test-bench module tstha_f(), integer info; reg a,b, wire s,ca, ha_1 hh( s(s), ca(ca), a(a), b(b)), initial begin a = 0, b = 0, info = $foDen("baJ_rslt ba"), end always begin #5a = 1,b = 0 #5a = 0,b=1, #5a = 1,b = 1, #5 a = 0, b = 0, end initial -'-' $frnonitor(info, $tirne, "a = %b, b = %b, out carry = %b, outsum = %b", a, b, ca, s), initial begin #30 $disp!ay(info), #0 $stop, end endmodule Результаты мониторинга, полученные при моделировании полусумматора (см листинг 6.1) и записанные в файл ha_f_rslt.txt: 0а = 0, b = 0, out carry = х, outsum = х 2а = 0, b = 0, out carry = x, outsum = 0
145 4a = 5a =■ 6a = 10a = 15a = 17a = 18a = 20a = 24a = 25a = 28a = 0, b = 1,b = 1,b = = 0, b = = 1, b = = 1,b = = 1,b = -0, b = = 0, b = = 1,b = = 1,b = : 0, out carry = ; 0, out carry = : 0, out carry = = 1, out carry • = 1, out carry = = 1, out carry = = 1, out carry = = 0, out cary : = 0, out carry = = 0, out carry = = 0, out carry = :0, :0, 0, = 0, = 0, = 0, = 1, = 1, = 0, = 0 = 0, oufsum = outsurn = outsum = , outsum = , outsum = , outsum = outsum = , outsum = outsum = outsum = outsum = 0 0 1 = 1 = 1 = 0 = 0 = 0 = 0 = 0 и 6.3.2. Ввод информации в память Единственной формой ввода информации из файла, поддерживаемой IEEE 1364 Verilog HDL, являются системные задачи Sreadmemb и Sreademh, считывающие информацию прямо в память. Задачи Sreadmemb и Sreademh работают с двоичным и шестнадцатеричным форматом представления данных, соответственно. Синтаксис: Sreadmemh("file_nam", memory_name, [,start_addr, end _addr]]), Sreadmemb("fiie_rtam", memory_name, [,start_addr, end_addrj]), где filename - строковое имя файла; memrtame - описывает Venlog- идентификатор памяти для загрузки данных; start_addr - необязательный начальный адрес для записи данных. Если не указан, то используется левый адрес памяти. Если указан <fmish_adar>. то занесение данных в память заканчивается в этой позиции Формат данных в файле может быть двоичными или шестнадцатеричным. Длина и система счисления не указывается. Числа разделяю!ся пробелами. Разрешается использовать Verilog- комментарии. Листинг 6.8 представляет типичный пример использования функции Sreadmemb для считывания тестовых последовательностей из файла mem.dat для верификации полусумматора ha_l Листинг 6 8. Пример чтения данных из файла с помощью Sreadmemh moaule test_ha_i, reg [1 0] mem [1 16], reg a, b, wire s,ca, ha_l hh{ s(s), ca(ca), a(a) b(b)), $readmemh("mem dat", mem) initial begin $monitor("time=%d a = %b, b = %b cut carry = %b, outsum = %b", $time, a, b, ca s) for(i=1,i<H6,i = i+1) #5 {a b} = mem[ij; end endmodule
146 Начальный адрес для записи информации в память может быть также указан в файле в формате "@hhh.. h". Данные загружаются последовательно, начиная с указанного адреса Используется только шестнадцагеричный формат для представления адреса. Файл может содержать несколько начальных адресов, что позволяет загружать в память несколько подблоков. 6.4. Контрольные вопросы и задания 1. Создать функцию, вычисляющую факториал 4-битового числа. Результат - 32-битовое число. Написать тестовый модуль для вызова функции и проверки результата ее работы. 2. Создать функцию, умножающую два 4-битовых числа и формирующую 32-битовый результат Написать тестовый модуль для вызова функции и проверки результата ее работы. ... > 3. Создать функцию, моделирующую восьмиопераиионное АЛУ. Функция принимает 3-битовый код операции, два 4-разрядных операнда, а возвращает 5-битовый результат. Написать тестовый модуль для вызова функции и проверки результата ее работы. Таблица 6.2. Примеры функций ОР З'ЬООО ЗЪ001 зъою ЗЪ011 З'ЫОО ЗЪ101 зыю зъш Функция out = a out = a + b out = а - b out = a / b out = a % b out = a « b out = a » b out = (a > b), сравнени e амплитуд 5отать функцию, вычисляющую скалярное произведение двух векторов А и В по формуле С = £а, Ь, . Например: A[3:ll = (l,2,3);B[3.i] = (4, 5,6); С = 3-6 + 2-5 + Ь4 = 32. Вызов функции должен иметь вид DOT(A,B), где А и В - массивы элементов типа integer. Результат вычисления, возвращаемой функцией, также имеет тип integer 5. Для функции из задания 6.4 разработать testbench, в котором определены два массива А и В, используемые в качестве тестовых последовательностей. Массивы инициализируются значениями из файла '1nput_data.dat", информация в котором представлена в шестиадцагеричной форме
147 6 Создать задачу, вычисляющую факториал 4-битового числа Результат 32- биговое число назначается после задержки в 10 единиц времени Написать тестовый модуль для вызова задачи и проверки результата работы. 7 Создать задачу, выполняющую проверку на четность 16-битового числа Результат - 31-битовое число. На него поступает значение после грех положительных фронтов синхронизации Использовать оператор repeat. 8 а) Написать задачу, вычисляющую сумму квадратов входных значений А и В Входные значения имеют тип real. Задача возвращает значение через вещественную переменную sum_of_squares. б) Разработать testbench для тестирования работы задачи из п. а). Тестовые значения формировать с помощью системной функции Srandom Результаты моделирования выводить в текстовый файл в формате. А = значение В = значение sum_of_squares = значение Например А = 3 В = 2 sum_of_squares = 13 9 Написать задачу, генерирующую импульсы синхросигнала syn_ c!k длиной 1 ед. времени с периодом в 20 ед. времени Когда сигнал reset - 1, то задача переключает syn_c!k в 0 и возвращает управление.
148 7, ГЕНЕРИРОВАНИЕ ОПЕРАТОРОВ 7.1. Оператор generate и переменные genvar Оператор generate упрощает процесс создания параметризированных моделей. Имеется возможность проверки декларации переменных, функций и задач, а также создания копий модулей и примтивов, операторов непрерывного присвоения, блоков initial и always При этом также может быть использована условная форма данной конструкции. Каждая генерируемая копия имеет уникальное имя и может быть доступна через иерархическое имя [5, 6, 9]. Для индексации оператора generate используется индексная переменная genvar. Ее синтаксис, genvar list_of_genvar_identifiers , где hst_of_gcnvar_identifiers - список переменных genvar. Переменная декларируется в модуле, в котором используется Допускается ее определение в операторе generate и за em пределами. В последнем случае она можег быть использована несколькими блоками generate. Имеет целочисленный тип и может принимать значения больше или равные 0. Первое присвоение значения переменной genvar не должно относиться к правой границе переменной. Если два оператора generate используют одну и ту же переменную в качестве индекса, то они не могут быть вложенными. Параметры genvars существуют ч олько во время подготовки проекта к моделированию, во время моделирования они недоступны. Для поддержки межсоединений между структурными элементами и/или процедурными блоками в операюре generate допускается выполнять декларирование переменных следующих типов данных, net, reg, integer, real, time, realtime и event. Пример использования оператора generate представлен листингом 7 1 Модуль xorGen содержит параметры, определяющие число разрядов в устройстве width и величину задержки delay Для управления оператором generate определена переменная i, которая меняется в диапазоне от 1 до величины width, по умолчанию равной 4 Листинг 7 1. Генерирование копий операторов assign module xorGen ^(parameter width = 4, delay =10) (output [1 width] xout, input [1 width] xm1, xin2), generate genvar i, for (. = 1, i <= width; i=i + 1) begin xi assign #de!ay xout[i] = xini[i] л xm2[i], end endgenerate endmodule
149 Для рассмафиваемого примера (см листинг 7 1) генерируклся следующие четыре копии операторов непрерывного присвоения: assign #de!ay xout[1l] = xin1[1] A xin2[1], assign #deiay xout[2] = xm1[2J л xin2[2], assign #delay xout[3] = xm1l[3] л xin2[3], assign #delay xout[4J = xin1[4J л xm2[4], Поскольку оператор generate выполняется во время члаборании, эти четыре оператора становятся частью модуля xorGen, заменяя конструкцию generate . endgenerate 7.2. Оператор generate с циклом for Операторы, которые могут использоваться в конструкции generate, ограничиваются for, if-then-else и case Синтаксис оператора generate с циклом for generate { for ( genvar_assignment, constant_expression , genvar_assignment) begin generate_b!ockjdentifier {generatejtem} } endgenerate где genvar_assignment - начальное значение переменной genvar, con- stant_expression - условие завершения цикла, genvar_assignment - шаг цикла, generatejtem - генерируемые операторы Вложенный блок begin-end имеет обязательную уникальную метку generate_b!ock_identifier и может быть доступен через иерархическое имя. Фигурные скобки означают возможность присутствия нескольких копий ограничиваемых ими конструкций. Оператор generate может быть использован для создания копий логических элементов. Каждая копия получает индивидуальное имя, которое имеег в качестве суффикса строковое представление значения индекса genvar Например, код модели устройства, рассмотренного в листинге 7 1, с реализацией на вентилях хог может выглядеть следующим обра юм generate genvar i; for (i=1 ■<= widtn, i=i+1) begin, xi xor #deiay a (xout[i] xinl [i], xin2[i]), end endgenerate Аналогичным образом можно создавать копии оператора always: generate genvar i; for (i = 1, i <= vwdth; i=i+1) oegm xi always @(*) xout[i] = xir,1[iJAxin2fi] endgenerate
150 В результате будет сгенерировано 4 блока always с индексами от 1 до 4. Листинг 7.2, а), б) представляет еще один пример применения оператора generate с циклом for для создания модели преобразователя кода Грея в двоичный последовательный код gray2bini. Модули параметризируются параметром size, по умолчанию равным 8. Листинг 7.2. Преобразователь кода Грея в двоичный последовашльный код а) // с применением оператора непрерывного присвоения module gray2bir?1 #(parameter SIZE = 8) (output [SI2E-1 0] bin, input [SI2E-1 0] gray), .; . • genvar i, generate for {i=0, i<SiZE, i=i+1) begin bit assign bin[i] ^ Agray[SIZE-1 :i]; end endgenerate endmodule б) // с применением оператора always ^ -. .«.-■-; moaule gray2bin2 #(parameter SIZE = 8) (output [SIZE-1 0J bin, input [SIZE-1 0] gray), reg [SIZE-1 0] bin, genvar i, generate for (i=0, kSIZE; i=i+1) begin bit always @(gray[S!ZE-1 :i]) // fixed part select bin[i] = Agray[SIZE-1:i]; end endgenerate endmodule 7.3. Условный оператор generate Условный оператор generate использует конструкцию if-else-if, коюрая позволяет применять условия, вычисляемые на этапе элаборации, дтя созтания копий модулей, стандартных и пользовательских примитивов, непрерывных операторов присвоения, блоков. Синтаксис: generate if ( constant_expression ) generatejtem_or__null [else gerierate_item_or_null} endgenerate где constant_expression - условие генерирования операторов. В параметризируемой модели устройства умножения multiplier, представленной листингом 7.3, параметры a__width и b_width определяют разрядность операндов Если один из параметров имеет значение меньшее 8 (битов), создается устройство умножения CLA(carry look-ahead addei" - сумматор с предварительным просмотром в схеме ускоренного переноса) Если оба параметра a_width и b_width больше или равны 8 (битам), то используется устройст-
151 во умножения Wallace tree (Дерево Уоллеса) Генерируемое устройство имеет метку и 1 Листинг 7.3. Параметризируемое устройство умножения module multiplier #(parameter a_width = 8, b_width = 8) (input [a_width-1 0] a, [b_widtb-1 03 b, output [a_width+b_width-1 0] product), generate if((a_width < 8) || (b_width < 8)) CLA_multiplier#(a_width,b_width) u1(a, b, product), WALLACE_multiplier#(a_widtb,b_width) u1(a, b, product), endgenerate endmoduie 7.4. Оператор generate с оператором case Для условного выбора в операторе generate может быть также использована конструкция case. Как это сделано в примере (листинг 7.4), генерирующем различные копии сумматоров, в зависимости от параметра WIDTH: Листинг 7,4 Использование оператора case в конструкции generate generate case (WIDTH) i adder_1bit x1(co sjm, a, b, ci), // 1-битовый сумматор 2. adder_2bit x1(co, sum, a, b, ci), // 2-битовый сумматор default addenda #(WIDTH) x1(co, sum, a, b, ci), // сумматор CLA endcase endgenerate Синтаксис: generate case (cor>stant_expresston) genvar_casejtem {genvar_case_item } endcase genvar_case_item = constant_expression {, constant_expression}. generatejtem_or_nu!l | default [ ] generate_item_or_null endgenerate Для переопределения значения параметров используется формат ordered или named parameter = value assignment or defparam, который может быть также объявлен в пределах оператора generate. В декларативной части оператора(не в цикле) generate могут быть описаны задачи и функции При этом они должны иметь уникальное имя и могут быть доступны через иерархическое имя. Оператор generate может быть создан с использованием одного из трех методов generate-loop, generate- conditional or generate-ca.se.
152 7.5. Примеры использования оператора generate 7 5.1. Пример сумматора со сквозным переносом. Пример представляет реализацию вентильной модели сумматора со сквозным переносом (листин! 7.5). Оператором generate выполняется генерирование копий имен для вентилей хоп bit[0].gl, bit[l].gl, bit[2J.gl, bit[3].gl, bitL0].g2 bit[l],.g2 bit[2].g2. bit[3].g2, для вентилей and: bit[0j.g3, bit[l].g3, bit[2] g3, bit[3].g3. bit[0].g4, bit[lj.g4, bit[2].g4, bit[3].g4, для вентилей or: bil[0].g5 bit[l]g5 bit[2].g5 bit[3].g5. Сгенерированные копии вентилей соединяются с помощью многомерного массива t типа wire, определенного вне оператора generate (листинг 7.5 а)). В примере с листинга 7.5 б) для связи вентилей используются три линии tl, t2, t3. декларация которых выполнена внутри оператора generate. Для каждой итерации цикла создаются собственные копии этих переменных: bit[0].tl bit[l].tlbit[2Jtlbit[3].tl // bit[0J.t2 bit[1] t2 bit[2].t2 bit[3] t2 '/ b.t[0] t3 bit[1] t3 bit[2] t3 bit[3] t3 Листинг 7.5. Две модели сумматора со сквозным переносом a) module addergenl #(parameter SIZE = 4) (output [SIZE-1 0] sum, output со, input [SIZE-1 0] a, b, input ci) wire [SIZE 0]c, wire [SIZE-1 0] t [1 3]; genvar', assign c[0] = ci, generate forfi=0, «SIZE i=i+1) begin:bit xorgMt[1][i},a[i],b[i]), xorg2(sum[i],t[1][i],c[i]), andg3(t[2][.],a[i],b[ij), andg4(t[3][il,t[1l{i],c[i]), org5(c[i+1j,t[2J[i],t[3][i]), end endgenerate assign со = c[SIZEj; enamodule 6)module addergen2 ^parameter SIZE = 4) (output [SIZE-1 0] sum, output со, input [SIZE-1 Oj a, b, input ci), wire [SIZE OJc, genvar i; assign c[0] = ci, generate for(i=0, kSIZE, i=i+i) begm.bit xorg1(t1,a[i],b[i]), xorg2(suT)[i],t1,c[i]),
153 ana g3 (t2, a[i], b[i]) andg4(t3,t1,c[i]), or g5 ( cfi+1], t2, t3), end endgenerate assign со = c[SIZE], endmodule 7.5.2. Пример сумматора. Ниже представлен пример моделирования n-битового сумматора (где п>1), который также имеет условные выходы, обозначающие отрицательный результат, перенос или переполнение дополнительного кода (листинг 7.6) В этом случае не генерируются копии сумматора. Операторы if-then-else и case могут быть использованы для генерирования этих различных конфигураций Листинг 7.6 представляет модуль, использующий оператор case для создания различных конфигураций схемы сумматора adder в зависимости от того, какие биты будут генерироваться. Три различных ситуации обрабатываются отдельно. Для большинства состояний carry in соединяется с carry out предыдущею состояния. При вычислении младшего бита используется перенос в устройство (cin). Для самою старшего разряда (определяемого параметром width) должны быть реализованы, перенос в старший разряд (cOut). overFlow и neg. Листинг 7.6. Модель полного сумматора module adderWithConditionCodes #(parameter width = 1) (output reg [width-1 0] sum, output reg cOut, neg, overFlow, input [width-1 0] a, b, input cin), reg [width -1 0j c, generate genvar i, for (i = 0,1<= width-1, i=i+i) begin stage case(i) 0 oegir aiways @{*) begin sum[i]=a[ipb[i]Acln. c[i] = a[i]&b[i]|b[i]&cln!aM&c!n, end end width-1 begin aiways @(*) begin sum[i]=a[i]Ab[i]Ac[i-1], cOut = a[i]&b[il | b[i]&c[i-1] | a[i] & c[i-1]; neg = sum[i], overFlow = cOutA c[i-1], end
154 end default begin always @(*) begin sum[!]=a[ipb[i]*c[i-!], c[i] = a[il&b[i]!b[il&c[i-1]|a[,]&c[.-l], end end endcase end endgenerate endmodule 7 5.3. Использование вложенных операторов generate. Модель, представленная листингом 7.7, иллюстрирует использование вложенных циклических операторов, циклических и условных операторов generate. Листинг 7.7. Многоуровневый оператор generate parameter SIZE = 2, genvar i, j, k, m, generate for (i=0, kSIZE+1, i=i+1) begin B1 // область действия B1[i] M1 N1(), // копии B1[i] N1[i] компонента М1 for Q=0, j<SiZE, j=j+1) oegin B2 // область действия B1[i].B2[j] M2 N2(), // копии В1 [i] B2[j] N2 компонента М2 for (k=0, k<SIZE, k=k+1) begin B3 // область действия В1 [i] B20] B3[k] // копии B1[i]B2[j]B3[k]N3 M3 N3(), end end if (i>0) for(m=0, m<SIZE, m=m+1) begin В4 // область действия B1[i] B4[m] M4 N4(), // копии B1[i] B4[m] N4 end end endgenerate Ниже представлены некоторые имена генерируемых копий компонентов в многоуровневом операторе generate: B1[0]N1 B1[1].N1 В1[0] B2[0J.N2 B1[0] B2[1J N2 В1 [0] B2[0J B3[0J N3 B1[0] B2[0] В3[1] N3 B1[0jB2[1]B3[Q]N3 B1[1]B4[0]N4 B1[1]B4[1]N4 7.6. Контрольные задания I. Разработать структурную модель 32-битною двунаправленного трансиве- ра, использующую в качесчве компонента функциональную модель 1-
155 битного трансивера, который имеет два двунаправленных входа данных а и Ь. Асинхронный, активный по низкому уровню пор г разрешения выходов ое__п Порт направления dir. Когда ое_п = 0 и dir = 0, данные передаются из b в а, если ое_п = 0 и dir = 1, то данные передаются с а на Ь. Если ое_п = 1, то а и b имеют значение высокого импеданса 2. Нарисовать схему, соответствующую следующему оператору generate: generate genvar stage for (stage = 1, stage <= 4, stage = stage -4) begn Ui d_ff de!ay_ff (c!k(sys_clk), d(delayed_data[stage-1]), q(delayed_data[stage])), end endgenerate 3. Создать условный оператор generate, который соединяет переменную external_clk с сигналом internal_clk, если параметр positiveclk = 1. В противном случае на линию mternal_cik подается инверсное значение external_clk 4 Разработать структурную модель устройства, состоящую из п мультиплек- соров 2-в-1, соединенных параллельно (рис. 7 1). Входами устройства являются сигнал управления Sel, два n-битовых вектора Л и В Выход описан п- битовым сектором С. Величина п опредетена с помощью директивы define Ag _ Рис 7 1 Мультиплексоры 2-в-1, соединенные параллельно 5 Разработать структурную модель твоим ною счегчика со сквознь носом, реализованную на D-триггерах (рис. 7 2) Количество комп задается через параметр п, который по умолчанию равен 4
8. PROGRAMMING LANGUAGE INTERFACE (PLI) Программный интерфейс PLI (рис. 8.1) используется для [7, 8]. - создания дополнительных системных задач и функций1 задач мониторинга, генерации тестов, отладки фрагментов программы; - построения различных программных приложений: трансляторы, анализ временных параметров. - получения информации о проекте иерархия, связи; - специальных и пользовательских форм управления выводом информации; - создания подпрограмм, формирующих тестовые последовательности; - создания любого основанного на Vcnlog программного приложения. Venlog-код + Пользовательские системные задачи Venlog-компилятор ] Подключение задач Внутреннее | представление проекта j (струетуры данных) j Моделирование Доступ к внутренним структурам Управление моделированием I Вывод результатов Ьезул^татытестир^ Таблица пользовательских j системных задач Рис 8 1 PLI-интерфейс PLI позволяет пользователю читать и модифицировать структуры внутренних данных, получать доступ к среде моделирования Проектировщик пишет собственную пользовательскую системную задачу, применяя PLI-подпрограммы, прил. А. Она подключается к программе моделирования, которая обрабатывает ссылку на задачу, зная место расположения соответствующей функции на языке Си. Для иллюстрации механизма использования PL1 представлен пример создания элементарной пользовательской системной задачи Sweltometask и функции $my_function При вызове данная задача выводит сообщение "You are welcome!".
157 Сначала создается подпрограмма на языке Си с использованием библиотеки PLI. #mclude "venuser h' void weicorreJaskQ «, { iojDrintf("You are welcomel\n"), } intfunction_caII() J< { io_pnntf("This PL! function works '\n"), retain 0, } Для того чтобы программа моделирования знала о существовании подпрограммы welcome_task и могла вызвать ее, встретив конструкцию Swelcome task, необходимо выполнить подключение PLl-подпрограммы к Venlog-симулятору. Разные программы моделирования могут иметь различный механизм линковки PL1. Симуляторы Aldec Active-IIDL, Cadence Verilog-XL™, MTI ModelSim® предлагают механизм регистрации системных задач и функций с использованием массива veriusertfs Его синтаксис- sjfcell venusertfs[ ] = { {usertask | userfunction | userrealfunction, data, checktf, sizetf, cailtf, misctf, "$tfname"}, {0} } Первый параметр определяет, будет ли это пользовательская функция (userfunction, userrealfunction) или задача (usertask). Различные функции обратного вызова (checktf, sizetf, cailtf, and misctf) подробно описаны в стандарте Verilog IEEE Std 1364-1995 Они, как правило, являются необязательными к использованию. Программа моделирования оставляет только функцию cailtf, которая выполняется при вызове системной функции или процедуры в Veriiog-коде. Функция userfunction возвращает значение reg, a Uberrealfunction - значение типа real. Параметр "Stfhame" - это имя системной функции или задачи в Venlog-коде, которое должно начинаться с символа доллара ($). Каждая задача и функция должна иметь запись в таблице \enusertfs. Последним обязательным элементом является {0}. При подключении каждого PLI-приложения программа моделирования ищет экспортируемую таблицу veriusertfs. В случае, если она найдена, программа моделирования имеет возможность вызывать определенные в ней задачи и функции Далее представлен пример регистрации почьзовательскои задачи и функции- sjfcell veriuserffsQ = { {usertask, 0, 0, 0, welcomeJask, 0,' SwelcomeJask"}, {userfunction, 0, 0, 0, function_cail, 0, '$my_function"}, {0} // последний элемент должен быто 0 ;, }, Представленная выше таблица, определяющая подключение задачи welcome task и функции function_call, должна присутствовать в Си-файле
158 Для Microsoft Windows ориентированных версий программ моделирования PLI-ириложение должно быть откомпилировано и собрано в 32-разрядную динамическую библиотеку (DLL). Поэтому в коде Си необходимо определить следующую Windows-функцию DliMam()- BOOL WINAPI DIIMam(HINSrANCE hlnsiance.DWORD dwReason, LPVOID IpReserved) ,,f { return TRUE, } а также добавить в файл определения (PliApp.def) для проекта PliApp в MS Visual С н- следующую строку: EXPORTS venusertfs DATA Полностью код Си-программы, иллюстрирующей простейший способ использования функций PLI, представлен листингом 8.S. а пример применения в Verilog пользовательской системной задачи и функции - листингом 8.2. Листинг 8 1 Полная версия кода С из файла PliApp с include venuserh' #include "aldecpli h" #inc!ude <windows h> mt welcome_task() { io_printf("You are welcomet!\n"), return 0 } intfunction_ca!l() { !o_printf(°This PLI function works !\n ) return 0, } extern "C" declspec(dllexport) s_tfcell venusertfs[ 1 = { {usertask, 0, 0 0, weicomejask, 0, "Sweicomejask } {userfunction 0, 0, 0, function_cali, 0, "$my_function'}, {0} }, BOOL WINAPi D!IMam( HINSTANCE hinstance, DWORD dwReason, LPVOID IpReserved ] {return TRUE, } Листинг 8.2. Пример использования системной функции и задачи module start_PLI, initial begin $welcome_task, $my_funcbon, end endmodule // Результат моделирования модуля для среды ALDEC Active-HDL Simulation nas been initialized Selected Top-Level start_PLI (start_PLI)
159 You are welcome1 This PLi function works ' KERNEL Simulation has finished There are no more test vectors to simulate PLI-приложения должны включать файл venuser.h при использовании TF- подпрограммы и файл accuser.h - для АСС-подпрограмм. 8.1. Внутреннее представление данных в программе моделирования Программой моделирования модуль рассматривается как набор элементов, представляющих типы Veriiog-объектов, и может включать: копии модулей, порты модуля, pin-to-pin пути модуля, intermodule-пуги; модули верхнего уровня; копии примитивов, терминалы примитивов; цепи, регистры, параметры, specparam; регистры integer, tsme, reai; временное управление, именные события. Каждый тип имеет соответствующий набор, идентифицирующий объекты данного типа Рис. 8.2 отображает концепцию представления данных в си- муляторе. Каждый набор содержит все элементы типов объектов модуля. Наборы соединены между собой двунаправленными связями. Все внутренние структуры данных для получения информации о модуле могут быть просмотрены с помощью PLI-подпрограмм. Для иллюстрации представление структур данных используется модель мультиплексора 2-в-1 (рис. 8.3) Его код содержится з листинге 8 3. Внутреннее представление данных мультиплексора изображено на рис. 8.4. Module <Имя модуля> Рис 8 2 Концепция внутренне1 о представления данных Листинг 8 3. Модель мультиплексора 2-в-!. module mux2_io_.1(out, Ю, г1, s), output out;
160 input iO, И, input s, wire sbar y1, y2, not n1 (sbar, s), ;v, anda1(y1, Ю, sbar), and a2(y2, i1 s), oro1(out, y1,y2), endmodule Рис 8 3 Вентильная схема м>лыиплексора 2 I Terminal \*— Рис 8 4 Вн)треннес представление шнны\ л я мультиплексора 2-B-i
161 8.2. Подпрограммы библиотеки PLI PLI-библиотека предлагает стандартный ишерфейс для представления внутренних данных в проекте Существует два класса PLI-подпрограмм: доступа (access routine) и обслуживания данных (utility routine) (vpi - не рассматривается). Подпрограммы access routine обеспечивают доступ к представлению В1гут- ренних структур данных. Они позволяют просматривать и извлекать необходимую информацию о проекте. Обслуживающие подпрограммы (utility routine) главным образом используются для перемещения данных через Ver- 1 log/Programming Language границу и предоставляют пользователю разнообразные вспомогательные функции. Рис. 8.5 иллюстрирует роль обоих классов PLI-подпрограмм. Внутреннее представление проекта (структуры данных) Асе PLi-подпрограммы Использующая Р1.!-библиотеку пользовательская Си-подпрограмма Tf PLI-подпрограимы Пользовательское ( представление проекта I Рис 8 5 Использование подпрограмм доступа и обслуживания 8.3. Подпрограммы доступа (access routine) Подпрограммы доступа (access routine), обозначаемые асе, могут считывать информацию о каком-либо объекте из внутренних структур данных или записывать ее туда. Все имена начинаются с приставки асс_. Си-подпрограмма вначале выполняет инициализацию среды с помощью подпрограммы acc_mitialize(). Затем, по завершению данной фазы, необходимо закрыть среду путем использования подпрограммы acc_close(). Чтобы подключить файл с определениями подпрограмм доступа, код должен содержать строку #include "асе user h" Подпрограммы доступа для обращения к объектам используют понятие абстрактного идентификатора (handle). Он предназначен для предопределения типов данных, указывающих на отдельные объекты проекта. Любая информация о проекте может быть доступна, если получен его абстрактный идентификатор. Данное понятие подобно концепции абстрактных идентификаторов файлов для работы с ними из программ. Декларация идентификатора объекта начинается с ключевого слова handle: handle topjrandle, Существует шесть типов подпрограмм доступа: 1. Handle routine. Возвращает аосфактный идентификатор объекта в проекте Имя таких подпрограмм всегда начинается с acc_handle_.
142 2 Next routine Возвращает идентификатор следующего объекта из множества заданного типа объектов проекта. Всегда начинается с accjnext и получает ссылки на объекты в качестве аргументов 3 Value Change Link (VCL) routine. Позволяет пользовательской системной задаче добавлять и удалять объекты из списка наблюдаемых Всегда начинается с acc_vcl_ и не возвращает значение. 4 Fetch routine. Извлекает разнообразную информацию об объекте: полное имя иерархического пути, относительное имя. Начинается с acc_fetch_. .-. 5. Utility access routine Выполняет вспомогательные операции для подпрограмм доступа. Например, accinitiafoeQ и acc_close() 6. Modify routines. Может изменять внутренние структуры данных. ' " 8.3.1. Примеры использования подпрограмм доступа. В первом примере пользовательская системная задача применяется для чтения и подсчета портов в модуле, а во втором - для мониторинга значения цепи. Пример 8.1. Вначале описывается пользовательская системная задача $getj)orts. которая предназначена для поиска полных иерархических имен входных, выходных и двунаправленных портов. Код полпрограммы get_ports на языке Си представлен листингом 8.4 Для инициализации доступа к программе моделирования используется подпрограмма асеJnit'ai7e(). a acc_close() закрывает доступ. Подпрограмма acc_handle_tfrag возвращает аргумент, передаваемый в разрабатываемую пользователем функцию $get_j>orts. Для получения указателей на порты модулей использовалась функция асе handle_port, а асс_ next_port - для указа- 1елей на следующие по списку порты. В задаче асе fetchdirection, возвращающей направление портов, применяются соответствующие константы acclnput, accOutput, acclnout Вывод результатов реализуется с помощью функции ioprint ТЬкласса библиотеки PLI. Данная функция подобна функции printf и выполняет вывод сообщения в выходной канал вызывающего ее продукта. Листинг 8.5 содержит пример применения задачи $get_ports для анализа и подсчета портов заданного модуля. Листинг 8.4. Си-подпрограмма для поиска иерархических имен портов #mclude "acc_user h" *■;-:> int get_ports() { handle mod, port, int mput_ctr = 0, > t , .r■ . . int output_ctr = 0, int inout_ctr = 0, acc_initialize(), // Получение указателя на копию модуля через первый аргумент mod = acc_hand!ejfarg(1),
// Получение определителя первого порта модуля в списке port = acc_handle_port(mod,0), while (port>=null) // Цикл перебора всех портов { if (acc_fetch_direction(port) == accinput) // Входной порт { // Вывод полного иерархического имени входного порта io_printf("!nput Port %s \n", acc_fetch_fu!lname(port)), mput_ctr++, } else if (acc_fetch_direction{port) == accOutput) // Выходной порт { io_printf("Output Port %s \n", acc_fetch_fullname(port)), output_ctr++, } //Двунаправленный порт eise if (acc_fetch_direction(port) == acclnout) { io_pnntf("lnout Port %s \n", acc_fetch_fuilname(port)), mout_ctr++, } port = acc_next_port(mod, port) // Переход к следующему порту } io_pnntf("lnput Ports = %d Output Ports = %d, Inout ports = %d\n\n", input_ctr, output_ctr, mout_ctr), acc_ciose(), return 0, } // Строка инициализации задачи в структуре veriusenfsQ Си-кода {usertask, 0, 0, 0, getjrorts, 0, "$get_ports"}, Листинг 8.5. Veniog-модель module юр, wire OUT, reglO, 11, S, mux2_to_1 my_mux(OUT, 10,11, S), /*Копия модуля mux2_to_1*/ initial begin $get_ports("top my_mux"); /'Вызов задачи $get_ports генерирующей список портов*/ end endmodule // Результат моделирования # Output Port top2 my_mux out # input Port top2 my_mux Ю # Input Port top2 my_mux i1 # Input Port top2 myjnux s # input Ports = 3 Output Ports = 1, Inout ports = 0 Пример 8 2. Иллюстрирует использование подпрофамм доступа фуппы Value Change Link (VCL). Вместо применения стандартной задачи Smonitor
164 определена пользовательская задача $my monitor для наблюдения за отдельными линиями проекта (листинг 8 6) Мониторинг реализуется функцией acc_vlc_net, которая имеет следующий формат вызова: void acc_vci_add(object_handle, consumerjoutme, user_data, vci_f!ag); handle object_handie, int (*consumer_routine)(), char*user_data, .^, .„..,. ,.^ ,s.,...... mtvcl_Pag ••• W4f„V.V-*-"-;-:--;.. ■- .., • ■.-, где object_handle - определитель объекта, который добавляется в список мониторинга. Пользовательская функция, вызываемая при каждом измерении наблюдаемого объекта, задается с помощью указателя (*consumer_routine)(). В рассматриваемом примере - эго функция dispiay_net. Она выводит имя и время изменения сигнала Полное имя наблюдаемою объекта передается через строку *user_data. Четвертый параметр в функции avvvcladd - это флаг vcl_f)ag, который может принимать значения vclverilog logic для мониторинга изменения сигнала и vcl_veriIog_strength силы сигнала(в данном учебном пособии не рассматривается ). Листинг 8.6. Си-код пользовательской задачи мониторинга значений #include "acc_user h" char convert_to_char{), int display_net(), mt my_monitor() { handle net, char *netname, // указатель для хранения имени линии char *ma!loc(), accjnitialize(), //инициализация среды*/ net = acc_handie_tfarg(1), // Получение идентификатора // наблюдаемой линии*/ // Поиск и получение иерархического имени линии netname = malloc(strlen(acc_fetch_fullname{net))), strcopy(netname, acc_fetch_fullname(net)), // Вызов подпрограммы VCL для добавления сигнала // в список мониторинга acc_vcl_add{net, display_net, netname, vcl_venlog_logic) acc_close(), return 0, } При изменении значения линии подпрограмма acc_vcl_add вызывает модуль displaynet и передает )казатель на структуру данных типа p_vc_iecord. Пользовательская подпрограмма на языке Си выполняет действие, определенное пользователем при каждом вызове подпрограммы асе vcladd. Тип p_vc_record определен в файле acc_userh следующим образом, typedefstructt_vc_record . Уг: ... .,-.-,
165 {int vc_reason, // причина изменения значений . : у int vc_hightime, // Старшие 32-разряда и int vcjowtime, // младшие 32-разряда // 64-битового времени моделирования char *user_data, // Строка передаваемая аргументом 3 в acc_vcl_add union // Новое значение наблюдаемого сигнала {unsigned char logtc_value, double reai__value, handle vector_handle, s_strengths strengths_s, } out_ value, i *p_vc_record, В данном примере пользовательская подпрограмма displaynet просто выводит время изменения, имя и новое значение линии (листинг 8.7). Другая подпрограмма convert_to_char создана для преобразования значений логических констант в ASCII-символы. Листинг 8.7. Си-код дополнительных функций мониторинга Пользовательская подпрограмма '/Вызывается при каждом изменении наблюдаемых сигналов disp!ay_net(vc_record) o_vc_record vc_record, //Структура p_vc_record из пакета acc_user h { // Выводится время, имя и новое значение изменившейся линии io_printf ("%d New value of net %s is %c \n", vc_record -> vcjowtime, vcj-ecord -> user_data, convertjo_char(vc_record->out_valuelogic_value)), } И Смешанные подпрограммы для преобразования константы /.' предопределенного символа в ASCII символ char convertJo_char(iogic_va!) char logic_val, { char temp; switch(logic_val) { // vc10, vd 1, vdx предопределены в пакете acc_user h case vcIO temp = '0', break, casevch temp = T, case vclX temp = 'X', break, case vciZ. temp = 'Z', break; } return(temp), } Для проверки созданной пользовательской PLI-задачи применяется модуль мультиплексора 2-в-1 с рис. 8.3 Модуль верхнею уровня, формирующий
166 тестовые последовательности и использующий задачу $my_monitor, представлен листингом 8.8. Листинг 8.8. Использование подпрофаммы мониторинга module top, wire OUT, reglO, 11, S, ' mux2_to_1 my_mux(OUT, 10,11, S), // Копия модуля mux2_to_1 begin ,'/ Добавление сигнала в список мониторинга $my_monitor("top my_mux.sbar"), $my__monitor("top my_mux y1"), I0 = 1'b0,11 = 1'M,S = 1'b #5 10 = 1'M, 11 = 1'M,S = #5IO = 1'bO II = 1'M,S = #510 = 1'M, 11 =1'M,S = // Результат моделирования 0 New value of net top my_mux y1 is 0 0 New value of net top my_mux sbar is 1 5 New value of net top my_mux.y1 is 1 5 New value of net top my_mux sbar is 0 5 New value of net top my_mux y1 is 0 10 New value of net top my_mux sbar is X 15 New value of net top my„mux.y1 is X 15 New value of net top my_mux sbar is 0 15 New value of net top myjnux y1 is 0 8.4. Обслуживающие подпрограммы (utility routine) Обслуживающие подпрограммы (utility routine) - это разнообразные PLl- процедуры для передачи данных в обоих направлениях через границу "Venlog - Си-профамма пользователя". Также их часто называют tf- подпрофаммами, поскольку они всегда начинаются с приставки tf_. Если такие подпрофаммы используются в Си-коде, то к нему должен быть подключен файл venuser h. содержащий описание всех обслуживающих подпро- фамм- #include "venuser h" Задачи, решаемые с применением обслуживающих подпрограмм: - получение информации о вызванных системных задачах Venlog и о списке аргументов. Считывание и изменение значения аргумента для вызванной й задачи Наблюдение за изменениями значений аргументов;
167 - выполнение вспомогательных задач, таких как сохранение рабочей области, указателя на задачу; - выполнение сложных вычислений: - вывод сообщения; - получение информации о времени моделирования и очереди событий. Остановка, завершение, сохранение и восстановление процесса моделирования. В описанных выше примерах применялась только одна tf-подпрограмма io_printf(). Листинг 8.9 содержит пример использования обслуживающих подпрограмм для создания пользовательской системной задачи Smystopfinish, управляющей процессом моделирования. Veriiog имеет две системные задачи для остановки и завершения моделирования Sstop и Sftnish. Разработанная задача $my_stop_finish совмещает обе эти функции. Ее спецификация представлена в табл 8.1. Таблица 8.1 Спецификация для $my_stop_finish Аргументы 1-й 0 1 0 I 2-й Нет Нет Любое значение Действие Остановка моделирования. Вывод сообщения и Mf времени Завершение моделирования Вывод сообщения и n времени Остановка моделирования Вывод сообщения, имя которого был произведен вызов задачи и молельн Завершение моделирования Вывод сообщения, т которого быт произведен вызов задачи и моде ты отетьного модуля, из ого времени я чодута, из ого времени В данном примере функция tf_nump() используется для определения числа передаваемых в системную задачу аргументов, a tf_gerp() - для получения самих аргументов. Функция tf_a;ettime возвращает текущее время моделирования. Остановка и завершение процесса моделирования выполняется с помощью tf_dostop() и tf_dofinish(). При отсутствии аргументов пользовательская системная задача Smy_stop_finish() будет выдавать предупреждение, для чего используется функция tfwarningQ. Листинг 8.9. Си-код пользовательской системной задачи $my_stop_finish int my_stop_finish() { if(tf_nump() ~ 1) /' Если в задачу передается 1 аргумент, то //выводится только сообщение о времени моделирования {// Получение значения первого аргумента Если аргумеьт равен О, if (tf__getp(1 )==0) // моделирование останавливается { io_printf("Mymessage Simulation stopped at time %d\n", tf_gettime()), tf_dostop(), // Остановка моделирования } //Если аргумент равен 1, моделирование завершается else if (tf_getp(1) == 1) { io_pnntf("Mymessage. Simulation finisned at time &d\n", tf_gettime()), tf_dofinish{), // Завершение моделирования
// Вывод предупреждения tf_warnmg("Bad arguments to $my_stop_finish at time %d\n\ tf_gettime()), ■•.;..„• ■.-.- } // Если в задачу my_stop_finish передается два аргумента, . ,,,f //то выводится сообщение с именем модуля из которого ..... // выполнялся вызов задачи, и временем , else if (tf_nump() == 2) ' " ' {// Если аргумент равен 0, моделирование останавливается if(tf_getp(1)==0) { io_pnntf("Mymessage Simulation stopped at time %d in instance %s tf_gettime{), tf_mipname{)), t*_dostop(), // Остановка моделирования } //Если аргумент равен 1, моделирование завершается • elseif(tf_getp(1)==1) "- --■■■-'■■-■■-■■• { io_pnntf("Mymessage Simulation finished at time %d in instance %s \n", tf_gettimeO, tf_mipname()), , , . tf_dofinish(), // Завершение моделирования } //Вывод предупреждения tf_warnmg("Bad arguments to $my_stop_finish at time %d\n" tf_gettime{)) Листинг 8.10 представляет собой Vcrilog-модуль, использующий созданную задачу $my_stop_finish для тестирования устройства mux2_to_l. и результат моделирования. Листинг 8.10. Veniog-модуль для тестирования задачи $my_stop_finish module top, w.re OUT, reg 10,11, S. mux2_to_1 my_mux(OUT, ID, 11, S), // Копия модуля mux2_to_1 initial // Формирование тестовых наборов begin I0 = 1'b0,11 =1'b1,S = 1'b0, - "■' $my_stop_finish{0), // Остановка моделирования без вывода // имени копии модуля #5Ю = 1'Ь1,!1 =1'M;S = 1'M, $my_stop_finish(0 1), // Остановка моделирования, // выводится имя копии модуля '"'■''"■■ #5Ю = 1Ъ0, H=1'b1;S = 1'bx, Smy_stop_finish(2,1), // Задаче передано
169 //неправильное значение аргумента #5Ю = 1'Ы,11 = 1'b1,S = 1'b1, $my_stop_finish(1,1) // Завершение моделирования, // выводится имя копии модуля end endmodute // Результат тестирования Verilog-модуля программой Active-HDL # Myrnessage. Simulation stopped at time 0 # RUNTIME RUNTlME_Q069topv(9) Sstop called. # KERNEL Time 0 ps, iteration 0, Instance \. # KERNEL stopped at time Ops run # Myrnessage Simulation stopped at time 5 in instance top # RUNTIME RUNTIME_0069topv(9) Sstop called # KERNEL Time. 5 ps, Iteration 0, instance \ # KERNEL stopped at time 5 ps run # Bad arguments to $my_stopJinish at time 10 # ■: $my_stop_finish f:\My_Designs\new\my_new/src/top1 v{13) # Myrnessage Simulation finished at time 15 in instance top # RUNTIME RUNTIME_0068 topi v{15) Sfmish called # KERNEL Time 15 ps, Iteration" 0, Instance \ # KERNEL stopped at time 15 ps 8.5. Примеры создания пользовательских системных задач Пример 8 3. Пользовательская задача, представленная листингом 8.11, выполняет изменения задержек переднего и заднего фронта для примитива, получает три аргумента, первый из которых является именем вентиля, другие - константными значениями задержек Пример вызова такой функции: $timmg_task( "top g12", 8 4, 9 2 у. Первый аргумент считывается с помощью функции acc_handle_tfarg, остальные два — tfgetrealp. Подпрофамма acc_handle_tfarg возвращает определители для аргументов в текущей копии пользовательской системной задачи или функции. Аргументом может быть цепь, модуль или примитив. Аргумент задается номером, начиная с 1. Имя примитива задается в двойных кавычках, имена модуля и иепи - без кавычек: $mytask(top modi,"top modi nand6"), Листинг 8.11. Пользовательская задача: для работы с задержками примитива #mclude "acc_user h" newJimmgO { handle gate_hand!e; double new_nse, new_fall, // Подпрограммы доступа инициализации и конфигурации accjnitiaiizeO, acc__configure( accDevelopmentVersion, "1.6a"), acc_configure{accToHiZDelay, "max"),
// Получение определителя вентиля gatejiandle = accjiandlejfarg{ 1 ), ^ , // Получение величин новых задержек ""'._ new_nse = tf_getrealp( 2), new_fall = tf_getrealp( 3 ) // Передала новых задержек вентилей acc_repiace_deiays(gate_handle,new_nse,new_fall), . "_ io_pnntf("Pnmitive %s has new delays %d %d\n", ' " 4" acc_fetch_fuHname( gatejiandle), new_nse, newja!!), acc_close(), } ..-:«V..4. Пример 8.4. Возвращает определитель на реализацию родительского примитива или модуля для заданного объекта, для этого используется задача acc_handle_parent() (листинг 8.12). Родительским считается объект, который содержит другие объекты. Например, для терминалов примитива родительским считается примитив, которому они принадлежат. Модуль верхнего уровня не имеет роди гелей. Листинг 8 12. Пользовательская задача: для работы с задержками примитива #mclude "acc_user h" get_pnrr> iti ves(net_hand le) handle netjiandle, { handle primitivejiandle, ' ."„.,""* handle dnverjiandle, ■■■:•-■■': ■■-'■- i*5 // Получение примитива, которому принадлежит каждый терминал, •»,■ // который управляет линией ч driverJiandle = null, , 4 while( dnverjiandle = acc_next_dnver{ netjiandle, dnverjiandle )) ' { primitivejiandle = accjiandle_parent( dnverjiandle), io_pnntf( "Primitive %s drives net %s\n", accjetchjullname( pnmitive Jiandle), '•■"■ ■ ''■'•■''-< accjetchjullname( netjiandle)), } } 8.6. Контрольные вопросы и задания 1. Создать пользовательскую системную задачу $get_in_port, которая формирует сообщение о входных портах заданного модуля Иерархическое имя модуля будет входным параметром задачи 2. Написать пользовательскую системную задачу Scountandgates, которая подсчитывает число стандартных примиihbob and в модуле. Для тестирования использовать следующую модель мультиплексора: modulemux_4Jo_1 (Out, InO, In1, In2, In3, Sell, SelO), output Out, input InO, In1,ln2,ln3, Sell, SelO. wire NotSelO, NotSell, wireYO, Y1.Y2, Y3, and (Y1,ln1,NotSel1 NotSelO), ., . „ "„'
171 not (NotSelO, SelO), and(Y3 In3, Sell, SelO), or(Out,Y0,Y1,Y2,Y3), and (YO, InO, NotSei 1, NotSelO), not (NotSeH, Sell), and(Y2, ln2, Sell, NotSelO), endmodule 3 Создать пользовательскую системную задачу $monitor_mod_output, которая находит все выходные сигналы модуля и добавляет их в список наблюдения. После любого изменения выходного сигнала модуля должно выводиться сообщение "Output signal has changed" Использовать VCL- подпрограммы. 4 Создать функцию, которая бы выводила имя и список портов модуля, из которого она вызывается. 5. Создать функцию, которая бы выводила имя и список примитивов, из которого она вызывается 8.7. Литература 1. IEEE Std 1364-1995. IEEE Standard Hardware Description Language Based on the Verilog Hardv/are Description Language- IEEE Standard Verilog Hardware Description language.- IEEE Computer Society Sponsored by the Design Automation Standards Committee.- Published by The Institute of Electrical and Electronics Engineers, Inc.- USA.- 1996.- 675 p 2. IEEE Std 1364-2001. (Revision of IEEE Std 1364-1995).- IEEE Standard Verilog Hardware Description Language.- IEEE Computer Society Sponsored by the Design Automation Standards Committee- Published by The Institute of Electrical and Electronics Engineers. Inc.- USA.- 2001.- 79 J p. 3. Sanrr Palnitkar. Veriiog HDL. A guide tp digital design and synthesis.- SunSoft Press- 1996-396 p. 4 Хаханов В.И.. Хаханова И.В. VHDL + Verilog = Синтез за минуты.- Харьков. СМИТ.- 2007.- 264 с 5. Donald E. Thomas, Philip R Moorby. The Verilog Hardware Description Language.- New York. Boston, Dordrecht, London, Moscow: Kluwer Academic Publishers - 2002 - 404 p. 6. James M. Lee, VERILOG QUICKSTART. A Practical Guide to Simulation and Synthesis in Verilog.- New York, Boston, Dordrecht, London, Moscow: Kluwer Academic Publishers.- 2002.- 378 p. 7. Stuart Sutherland. The Verilog PLI Handbook. A User's Guide and Comprehensive Reference on the Verilog Programming Language Interface.- New York, Boston, Dordrecht, London, Moscow: Kluwer Academic Publishers.- 2002 - 809 P- 8. Venlog-HDL PLI Reference Manual- Open Verilog International-1991 - 350 p 9. Michael D. Ciletti Advanced Digital Design with the Verilog HDL.-Prentice, Hail of India.- 2005.- 1014 p. 10. Поляков А. К. Языки VHDL и Venlog в проектировании цифровой аппаратуры.- М: СОЛОН-Пресс- 2003 -320 с.
172 ЧАСТЬ III. СИНТЕЗ МОДЕЛЕЙ НА ЯЗЫКЕ VERILOG Рассматриваются основные этапы процесса логического синтеза цифровых систем на кристаллах средствами языка Venlog: преобразование Venlog- операторов в элементы и схемные конструкции RTL-уровня, а гакже технологии оптимизации послесинтезных решений В разд. 9-11 представлена современная методология проектирования SoC на основе HDL-модели цифровых устройств RTL-уровня, особенности преобразования Venlog-операторов в схему, состоящую из стандартных элементов, шаблоны комбинационных компонентов и последовательностной логики. Цель - изучение и практическое использование технологий синтеза специализированных цифровых систем на кристаллах на основе HDL-моделей компонентов, представленных на RTL-уровне описания средствами эффективной языковой среды Verilog, путем рассмотрения многочисленных примеров аппаратной реализации комплектующих компонентов Задачи: 1. Синтезируемые конструкции в Verilog: общее понятие синтеза, принципы построения синтезируемого кода; синтезируемые конструкции в Venlog. 2. Интерпретация операторов Verilog типы данных, массивы, использование векторов - присвоение вектору значения вектора меньшей длины, использование диапазона и отдельных элементов векторов; синтез комбинационных схем - оператор непрерывного назначения assign, поведенческий код, процедурные операторы назначения; синтез послсдовательчостных устройств - модели D-триггеров, реализация последовательностных схем с помощью always; особые ситуации синтеза - блокирующие и неблокирующие операторы, оператор sf, оператор case, использование операторов casex и casez, директива синтеза parallelcase, использование неконстантных вариантов выбора для оператора case; операторы циклов; локальное использование переменных: различие между блокирующими и неблокирующими переменными; операторы Assign и Deassign; синтез подпрограмм' использование параметров; использование значения х. 3. Шаблоны стандартных решений- комбинационные компоненты - мультиплексоры, дешифраторы, устройства сдвига, арифметические устройства, совместное использование ресурсов (Resource Sharing); последовательностная логика - триггеры с синхронизацией по фронту, триггеры-защелки, счетчики, сдвиговые регистры; автоматы; модели памяти. 4. Контрольные вопросы и задания. Источники: синтез цифровой аппаратуры с помощью языка Venlog [1,2]: язык описания аппаратуры Venlog [3,4]; стандарт языка описания аппаратуры Venlog [5-7].
173 9. СИНТЕЗИРУЕМЫЕ КОНСТРУКЦИИ В СРЕДЕ VERILOG 9.1. Общее понятие синтеза Синтез - это процесс преобразования высокоуровневого описания проекта в оптимизированную модель вентильного уровня, состоящую из элементов целевой библиотеки стандартных ячеек или компонентов программируемой логики, называемой также технологической или целевой библиотекой. Логический синтез существовал давно, с момента создания первых цифровых устройств. Однако раньше он выполнялся вручную. Появление же языков описания аппаратуры и создание специальных программ для преобразования HDL-кода в схемное представление привело к революции в проектировании вычислительных систем. Автоматизированное преобразование высокоуровневого представления модели в схему позволило значительно повысить производительность, сократить время проектирования и исключить ошибки, обусловленные человеческим фактором Работа, на выполнение которой ранее требовалось несколько месяцев, теперь может быть выполнена за часы. Не вызывает никаких затруднений создание нескольких версий реализации проекта с разными параметрами для выбора более оптимального варианта. Допустимо использование одного и того же проекта для различных технологий реализации. Фирмы, ориентированные на CAD (Computer-Aided Design), предлагают различные программы для выполнения синтеза логических схем из HDL-кода, например Synopsys Synplify Pro и Synplify Premier, Synopsys Design Compiler Ultra, Xilinx XST, Cadence Encounter HDL-Compiler, Mentor Graphics Leo- nardo Spectrum. Одни из них предназначены для проектирования на программируемой логике, другие - на ASIC. Они используют различные алгоритмы и принципы преобразования HDL-кода в схему, и как следствие, могут поддерживать отличающиеся подмножества конструкций языков описания аппаратуры и генерировать различные по размеру и быстродействию схемы. Типовая схема выполнения процесса синтеза изображена на рис. 9.1 [I.2J. Исходные данные представлены HDL-моделью цифрового устройства RTL- уровня. Первый этап Translation представляет собой процесс преобразования конструкций языка описания аппаратуры в схему, состоящую из стандартных элементов Программа заменяет операторы HDL своими библиотечными элементами, формируя схему RTL-уровня. Под стандартными элементами в одних программах (например, Synplify и XST) подразумеваются макросы: сумматоры, счетчики, автоматы, память. В других - это могут быть только логические элементы и триггеры. Как правило, по первому принципу выполняется RTL-синтез устройств, реализуемых на FPGA, а второй подход используется для ASIC. Этот этап зависит только от исходного HDL-кода, и для всех цепевых технологий реализации устройства программа синтеза будет генерировать одну и ту же схему. Следующим этапом является опт ими-
174 зация полученной схемы (блок Logic Optimization), результат преобразуется в схему, состоящую из элементов заданной технопоши Technology Mapping and Optimization. Это могут быть таблицы преобразований LU Г и триггеры (для FPGA) или стандартные ячейки (для ASIC). На этом этапе программы используют технологические библиотеки (блок Technology Library), описывающие реализацию стандартных элементов в заданном элементном базисе. Константы проектирования (Design Constraints) представляют механизм управления процессом синтеза и могут нести разнообразную дополнительную информацию по формированию результирующей схемы, как, например, требования к размеру или быстродействию устройства, расположению внешних контактов. Design Constraintsj- jRTL HDL Descriptioi RTI - synthesis and optimization -{Component Library! —[Technology Library) pptimized Gate-Levei] 1 Representation ) Рис 9 1 'Этапы смлеза 9.2. Принципы построения синтезируемого кода В настоящее время компании используют стандарты синтеза для VHDL (IEEE Std 1076.6-1999: IEEE Standard for VHDL Register Transfer Level (RTL) Synthesis) и Verilog (IEEE Std 1364 1-2002: IEEE Standard for Venlog Register Transfer Level Synthesis) [5-7]. Однако различные программы синтеза поддерживают различные подмножества конструкций языков описания аппаратуры. Одна и та же конструкция, применимая для одной программы, может быть не синтезируема в другой Тем не менее, существует некий единый подход к написанию синтезируемого HDL-кода, в основу которого положены общие принципы выполнения синтеза. 1. HDL-модель должна быть представлена на RTL-уровне Поведение устройства должно быть описано с точностью до такта синхросигнала. В общем случае, любая конструкция, которая моделирует работу устройства на каждом так re функционирования RTL-схемы. может быть синтезирована. 2 Не допускается использование конструкций, включающих временные параметры.
175 3. Не допускается применения механизмов инициализации средствами HDL- языка, только с помощью внешних входов, например, сброса и установки 4. Рекомендуется явно указывать размер (разрядность) данных. Самое [лавное, при написании кода очень важно, чтобы проектировщик ".редставлял, из каких аппаратных элементов будет состоять его проект, как он будет реализован в аппаратуре. Под аппаратными элементами подразумевается стандартный набор компонентов- триггеры, регистры, сумматоры, вентили, мультиплексоры, дешифраторы. 93. Синтезируемые конструкции в Verilog Набор поддерживаемых для синтеза конструкций языка Verilog представлен табл. 9.1 [3,4], однако он может меняться для различных программ синтеза. Таблица 9.1 Синтезируемые конструкции языка Veriiog Тип конструкции Модуль :;оРты 1араметры -еременные Гобыгия дикции и задачи -ьеленческое "вровень data flow Зентитьный уровень Ключевое с то во или описание module input, mout, output parameter reg, integer @() function, task always begin - end именные блоки disable always, lf-then-else, Цикл for Циклы while, forever, repeat assign Станлартныс примитивы Реализация модуля, реализация Примечания #( ) и defparam поддерживаются только на один уровень вниз Разрешены векторы и массивы Не поддерживаются именные события Игнорир>ются временные параметры, вызов системных задач и ф) нкций Initial игнорируется Не поддерживается fork-join, не разрешается использование disable для именных блоков | Не поддерживаются deassigrt, wait force, Поддерживается полностью Стандартом синтеза на поддерживаются Отдельные программы могут выполнять ] синтез с ограничениями i Информация о задержках игнорируется | Например, I raymux ml(out, i0, il, s), nand(out, a, b), Поскольку для синтеза не поддерживается предварительная инициализация лнных в HDL-коде, то в языке Verilog блок initial не является синтезируе-
176 мым. Для инициализации данных следует использовать механизм сброса, реализуемого с помощью специальных входов. При выполнении синтеза игнорируются все параметры времени, описываемые в формате #<задержка>. Все операторы языка Verilog, кроме === и !==, синтезируемы. Символы х и z не имеют значения в аппаратуре, поэтому = и !== являются специальными операторами для моделирования. При синтезе они заменяются на == и !=, соответственно. Программами синтеза поддерживаются только последовательные блоки, которые ограничиваются ключевыми словами begin и end Использование параллельных блоков fork-join не разрешено. "■ Поддерживается применение стандартных примитивов для описания вентильных схем. Однако определенные пользователем примитивы игнорируются. Более подробно реализация операторов Verilog при выполнении RTL- синтеза рассматривается в главе 10. Табл 9 2 представляет основные директивы компиляции языка Verilog и их интерпретацию программами синтеза. Таблица 9 2. Директивы компиляции Поддерживаются define include file, Imc 'undcf, indef, ekif, ifdef else endif default nettype Hi норируются 'timescale 1 rcsctaii 9.4. Контрольные вопросы и задания 1. Что происходит при синтезе временными параметрами модели? 2. Какие циклы являются полностью синтезируемыми? 3. Какие блоки синтезируются? 4. Можно ли в синтезируемых моделях использовать параметры? 5. Являются ли примитивы синтезируемыми?
177 10. ИНТЕРПРЕТАЦИЯ ОПЕРАТОРОВ VERILOG Далее на примерах рассмотрен первый этап синтеза - преобразование Verilog-операторов в элементы схемы RTL-уровня, которая составляется из стандартных библиотечных компонентов программы синтеза и не зависит от конкретной технологии реализации устройства. Для реализации примеров синтеза использовалась программа XST. 10.1. Типы данных Перечень поддерживаемых для синтеза типов данных Venlog представлен табл. 10.3 [3,4]. Типы данных integer и real рекомендуется применять для построения тестов или абстрактных моделей. Для создания же моделей реальной аппаратуры предпочтительнее использование типов reg или wire, которые позволяют точно описывать архитектуру устройства. В Veriiog 2001 векторы обоих типов данных могут быть использованы для создания как знаковых, так и беззнаковых данных: гед [3 0] arb_pnority, wire [31 0] arb_request, wire signed [8 0] arb_signed, Таблица 10.1. Поддерживаемые программами синтеза типы данных Класс данных Цепи (Net) Регистры (Reqister) XST wire, tn, triand/wand, tnor/wor supplyO, supply 1 reg, integer Synphfy wire, tn, supply 1, supplyO leg, integer time (64 bit reg) 10.1.1. Массивы. Массивы в Veriiog синтезируемы, разрешав! ся использовать массивы типов reg и wire, например: гед [3.0] mem_array [31 0], wire [7:0] mem_array [63 0], Поддерживаются многомерные массивы размером до трех измерений: a) wire [7 0] array2 [0.255Ц0 15], b) гед [63.0] гедаггау2 [255.0][7.0], c) wire [7:0] аггауЗ [0.15][0'255][0:15], Не допускается выполнять присвоение более чем одному элементу массива одновременно. В предыдущем примере разрешено обращение к массиву: а) 8-разрядными словами, Ь) 64-разрядными словами, с) 8-разрядиыми словами.
178 10.2. Использование векторов 10.2.1. Присвоение вектору значения вектора меньшей длины. Если вектор, получающий значение, имеет большую длину, чем вектор, из которого данные передаются, то вектор-источник дополняется битами со стороны старших разрядов по следующему правилу [3, 4]: 1) если вектор с правой стороны является знаковым, то вектор с левой стороны дополняется нулями, если он является положительным - единицами, наличие высокого импеданса - z. значение вектора не определено - х (рис. 10.1, а); 2) если вектор с правой стороны является беззнаковым, то вектор с левой стороны дополняется нулями (рис. 10.1, б); 3) если для констант z и х размер не указан, то они дополняются значениями l и х соответственно, при этом не имеет значения - знаковая или беззнаковая переменная с правой стороны выражения. а - для знаковых чисел б -для беззнаковых чисел Рис i 0 1 Расширение векторов 10.2.2. Использование диапазона и отдельных элементов векторов. В Verilog-моделях RTL-уровня можно свободно использовать как весь вектор целиком, так и его поддиапазоны или отдельные элементы (листинг 10.1). Листинг 10.1 Пример использования элементов вектора module Constantlndex (input[3 0] А, С, RegFile, output [3 01 ZCat), assign ZCat [2.0] ={A[2], C[3 2]} assign ZCat[0] = RegFile{3], endmodule Если в правой части выражения для выбора элементов вектора в качестве индекса используется неременная, то такое выражение реализуется мультиплексором (листинг 10.2, рис. 10.2). Если переменный индекс применяется с левой стороны выражения, то в результате синтеза формируется память. В примере (листинг 10.3, рис 10.3) аппаратурное устройство реализуется на триггерах-защелках с использова-
179 нием логических элементов для выбора необходимой ячейки для занесения значения. Листинг 10 2. Использование вектора с переменным индексом в выражении module NonComputeRight (input[0.3] Data, input [1 0] Index, output Dout), ■■-.: :u assign Dout = Data [Index]; endmodule Рис 10 2 Мультиплексор из вектора с переменным индексом Листинг 10.3. Использование вектора с переменным индексом module NonComputeLeft (input Data, input [2Ю] Addr, output reg [7-0] Mem); always ©(Data, Addr) Mem[Addr] = Data, endmodule fWh^ ~Ц СЕ5Ш> Рис 10.3 Результат синтеза (листинг 10 3) 10.3. Синтез комбинационных схем Модель комбинационного устройства может быгь описана с помощью [1-4]" 1) стандартных примитивов логических элементов (листинг 10.4, рис. 6); 2) операторов assign в data-flow моделях; 3) процедурного оператора always, при этом список чувствительности должен содержать все входы комбинационной функции (все переменные, у ка-
180 занные с правой стороны выражения или в качестве условия операторов if и саье) или иметь форму @(*). При использовании операторов if или саье необходимо, чтобы выходной сигнал получал значение при каждой возможной ситуации, т.е. при каждой итерации выполнения блока begin-end выходной сигнал должен обновлять свое значение. Листинг 10 4. Модель мультиплексора 4-в-1 вентильного уровня module mux_4Jo_1 (Out, InO, In1. In2, !n3, Sell, SelO), , output Out, input InO, In1, In2, In3, Sell, SelO, wireNotSelO, NotSell, wireYO, Y1.Y2.Y3, and (Y1,ln1,NotSel1, SelO); not (NotSeiO, SelO), and (Y3,ln3. Sell, SelO), or(Out,Y0,Y1,Y2,Y3), ana (Y0, InO, NotSell, NotSeiO); not (NotSell, Sell), and(Y2,ln2, Sell, NotSeiO), endmodule Рис 10 4 Результат синтеза (листинг 10 4) 10.3 1 Оператор непрерывного назначения assign Оператор непрерывного назначения assign используется для представления комбинационной логики. Например, для выражения- assign out=(a&b)lc, схема RTL-уровня будет иметь вид, представленный рис. 10.5 Если a, b и с - двухэлементные векторы, то будет сгенерировано две схемы в соответствии с рис. 10.5.
81 Арифметические операторы реализуются с помощью арифметических блоков, доступных в библиотеке программы. Например, рис. 10.6. представляет реализацию программой Synplify сумматора, описанного выражением: ;_out, sum} = а + b + cjn; Рис 10 5 Вентильная с: Рис 10 6 Реализация полного сумматора Условный оператор реализуется мультиплексором. Так, следующее выражение будет соответствовать рис. 10.7. assign out=(s)"? a b, Чтобы представить, сколько это устройство потребует аппаратуры, следует помнить, что мультиплексор 2-в-1 описывается булевым уравнением трех переменных, out^s'a+sb. Рис 10"7 Мультиплексор 10.3.2. Поведенческий код. Процедурные операторы назначения. Блок always может быть использован для реализации последовательной и комбинационной логики. Следующий пример представляет код комбинационного сумматора, результат синтеза которого представлен рис. 10.7- module mux_4_to_1 (output reg c_out, sum, input a, b, cjn), always @{*) {c_out, sum} = a + b + cjn, endmodule Допускается использование сокращенной записи описания всех портов в списке чувствительности: always @(*) // или always @* {c_out, sum} = а + b + c_in,
182 Данная конструкция генерирует схему, аналогичную предыдущей Использование блокирующих и неблокирующих операторов не окажет никакого влияния на результирующую схему, различие будет только в результатах моделирования. Рекомендуется для комбинационных схем использовать блокирующие операторы, а для последовательностных- неблокирующие 10.4. Синтез последовательностных устройств Для проектирования последовательностной логики используется оператор always [1-4] При написания качественного кода следует придерживаться следующих правил: П В списке чувствительности always допускается использовать проверку только событий синхросигналов или только фронтов синхросигналов. Указываются только сигналы, непосредственно влияющие на изменение состояния 2) В операторе always условия, соответствующие сигналам reset и preset, описываются первыми. 3) Внутри блока begm-end условие синхронизации не описывается. 4) Нельзя описывать в одном блоке комбинационную и последовательност- ную схемы. 5) Для моделей последовательностных схем предпочтительнее использование неблокирующих операторов "<-=". 10 4 1. Модели D-тригтеров. Для последовательной логики блок always должен управляться изменением сигнала elk Листинг 10.5 а) представляет D-триггер с синхронизацией по переднему фронту, его схема представлена ча рис. 10.8, а. Чтобы сгенерировать триггер-защелку с синхронизацией но уровню (рис 10.8,6), следует в управлении блока always указать синхросигнал и вход данных, а также включить в него оператор if (листинг 10 5, б). Листинг 10.5. Venlog -модели D-триггера a) module FlipFlop б) module Latch (input C, D, (input Clk D, output reg Q); output reg Q), always @(posedge C) always @(Clk, D) Q<=D, if(Cik)Q<=D; endmodule endmodufe Листинг 10.6 представляет модель D-триггера с асинхронным сбросом (рис 10.9). Для того чтобы программа синтеза не выдала ошибку, в списке чувствительности оператора always следует использовать проверку фронтов (negedge или posedge) для всех управляющих сигналов. Листинг 10 6. Venlog-модель тршгера с синхронизацией по заднему фронту и асинхронным сбросом module flopl
(input С, D, CLR, output reg Q), always @(negedge C, posedge CLR) if (CLR) = 1'bO, else Рис 10 8 Резчльгаш синтеза моделей D-тринера FDC 1 Рис 10 9 Триггер с синхронизацией по переднему фронту и асинхронным сбросом 10.4.2. Реализация последовательностных схем с помощью always. Список чувствительности может содержать события, определяющие фронт синхросигнала и управляющие сигналы. Блок always может включать только один оператор if-else. Асинхронная часть может появляться до синхронной части в первых ветвях if-else. В асинхронной части сигналы могут получать константные значения '0'. '1', 'X' или 'Z' или комбинацию этих значений. Листинг 10.7 представляет шаблон с асинхронными управляющими сигналами. Листинг 10.8 представляет модель 8-битовою реестра, использующего асинхронный управляющий сигнал сброса. Результат синтеза изображен на рис. 10 10 Листинг 10.7. Шаблон последовательностного устройства с асинхронными управляющими сигналами a>ways ©(posedge A, negedge В, negedge С,.. posedge Clock) if (А) //асинхронный сигнал А активный 1 <statement> //асинхронная логика //асинхронный сигнал В, активный О //асинхронная логика // асинхронный сигнал С, активный 0 // асинхронная логика //Любое количество конструкций else if else if ('В) <statement> else if ('С) <statement>
184 else // передний фронт Clock <statement> //синхронная логика Листинг 10.8. Регистр с асинхронным сбросом размером в 8-бит module EXAMPLE (input [7 0] Dl, input CLK, RST, output''eg [7 0] DO), always @(posedge CLK or posedge RST) if(RST==1'M) DO = 8'bOOOOOOOO, else DO = Dl, endmodule FDC Рис ! 0 10 Результат сишеза регистра (листиш 108) Листинг 10.9 представляет реверсивный счетчик, направление счета в котором зависит от синхронного управляющего сигнала UpDown. Разрядность счетчика задается с помощью параметра Numbits. Устройство содержит асинхронный сброс Clear, проверка переднего фронта этого синхросигнала указана в списке чувствительности. Синхронный сигнал Preset выполняет предварительную установку счетчика значением с входа Data. Рис. 10.11 изображает результат синтеза счетчика, интерфейс (рис. 10.11, а) и RTL- схему(рис. 10.11,6) Листинг 10 9. Счетчик с асинхронными и синхронными управляющими сигналами module AsynCounter #{paramater Num_bits = 2) (input Cik, Preset, UpDown, Clear, input [humjDits-1 0] Data, output reg [Num_bits-1 0] Counter) always @(posedge Clear, posedge Clk) . .. if (Clear) Counter <= 0, else if (Preset) Counter <= Data, else if (UpDown) Counter <= Counter + 1, else Counter <= Counter - 1; endmodule '""'":"'' ' " " 10.5. Особые ситуации синтеза 10 5.1. Блокирующие и неблокирующие операторы Не разрешается, чтобы сигнал получал значения с использованием блокирующих и неблокирующих операторов одновременно, например, как в следующем фрагменте ьода [1-4]-
185 always @C) if(in2)out1 -ml, else outl <= in2, Это же ограничение действует и для элементов или диапазонов вектора Нельзя использовать блокирующий и неблокирующий операторы для присвоения значений диапазонам одного вектора, даже если нет реального смешения стиля для отдельно взятых битов, например, таким образом: rf (in2) begin out1[0] = 1'b0, out1[1]<=in1; e begin out1[0} = m2, oui1[1]<=1'M, чика (листинг 10 9) Ю.5 J. Оператор if. СЛшератор if может генерировать комбинационную логику (листинг 10.10, а), рас 10.12) или последовательностную (листинг 10.10,6), рис 10.13). Здесь жяствует правило: если значение переменной явно определено во всех вет- ■Е1 оператора if, то при синтезе создается комбинационная схема, в против- ■ом случае - последовательностная Листинг 10.10. Использование оператор if * -odule ex1 б) module ех2 (input А, В, (input А, В, output reg Z), output reg Z),
always @(A B) if (A>B) Z=A, 186 always @(A B) if(A>B)Z=A, else Z=B, endmodule endmodule Оператор if может быть вложенным В этом случае на него действует го же самое правило. Пример с листинга 10.11 иллюстрирует использование вложенного оператора if и оператора always для создания модели и синтеза мультиплексора 4-в-1 (рис 10 14). Все входные переменные указаны в списке чувствительности always. ; 10 12 Комбинационная схема из оператора if Рис 10 13 Трип ер-защелка схема из оператора it Листинг 10 11. Вложенный оператор if для описания мультиплексора module mux* (input [1 0j sel, а, о, с d, output reg [1-0] outmux); always @(S6I, a b, c, d) begin if(sel[1]) if(sel[0]) outmux = d, else outmux = c. else if (sel[0]) outrpux = b, else outmux = a; шп>- [Щ^- Рис 10 14 М\льти1пексор (тистинг \Q\\)
187 10.5.3. Оператор case. Оператор case, подобно оператору if, может генерировать как комбинационную, так и последовательностную лот ику. Точно так же. как и для if, если значение переменной явно определено для всех вариантов выбора оператора case, при синтезе создается комбинационная схема (листинг 10.12, рис. 10 15), иначе - последовательностная (листинг 10.13, рис. 10.16). Реализация схемы с триггером-защелкой может быть различной и зависит от программы синтеза. ■жЛ: ^11 ™Г" :gh -пи J 3~ JT Рис 10 15 Комбинационное АЛУ Листинг 10 12. Оператор case для комбинационного АЛУ module ALU «(parameter ADD = 'Ь00 SUB = 'Ь01, MUL = 'M0 DiV = 'M1) (input [1:2] Op, input [0 1] A, B, output reg [0:1] Z), always @(Op, A, B) case (Op) ADD Z = A + B, SUB Z = A-B, MUL Z = A*B, DIV Z = A/2, endcase endmodule Листинг 10.13. Оператор case, который приведен к появлению триггеров module NextStateLogic (input [1 0] Toggle, output reg [1 0] NextToggle), always ©(Toggle) case (Toggle) 2b01 NextToggle = 2'M0, 2'MO NextToggle = 2'b01, endcase endmodule
Рис 10 16 Результат синтеза кода (листинг 10 13) С помощью атрибутов можно управлять процессом синтеза. Так, атрибут ful!_case позволит избежать появления триггера, даже если не все возможные варианты значений перебраны в операторе case В следующих примерах в коде листинга 10.14 используется ветвь default, а в коде листинга 10 35 - директива full_case. В результате синтеза генерируются комбинационные схемы (рис. 10.17 и 10.18). Листинг 10.14 Оператор case с ветвью default module NextStateLogic (input [1 0] Toggle, output reg [1 0] NextToggle), always ©(Toggle) case (Toggle) 2'b01 NextToggle = 2'M0, 2'MO NextToggle = 2'b01, default NextToggle = 2'b01, enacase endmcduie ROM ОшйШц>~- ~{ШШШШШ> Рис. 10 17 Результат синтеза кода (;н П5ШПШ>—i ' cL ' Рис. 10.18. Резульгат синтеза кода (листиш 10 15) Листинг 10 15 Оператор case с атрибутом full_case module NextStateLogic (input [1 0] Toggle, output reg [1 0} NextToggle)
//synthesis full_case 2'b01.NextToggle = 2'M0, 2'b10-NextToggle = 2'b01, endcase endmodule 10.5.4. Использование операторов casex и casez. В операторе casez символ z рассматривается как не имеющий значения Символы z и х не допускается использовать в переменной выбора оператора саге. Листингами 10.16 и 10.17 представлены примеры использования операторов casez и casex в моделях, результаты синтез изображены на рис. 10.19 и рис 10.20. Рис. 10 20. Резулыат синтеза кола (листиш 10.17) Листинг 10.16. Пример кода с оператором casez module Casez_Ex (input [0-3] Pr_Counter, output reg [0 1] DoCommand), always @(Pr_Counter) casez(Pr_Counter) 4 b'??1 DoCommand = 0, 4'b""10 DoCommand = 1, 4'b?100: DoCommand = 2, 4'M000 ■ DoCommand = 3, default DoCommand = 3,
190 endcase endmodule Листинг 10 17. Пример кода с оператором casex module PnontyLogic (input [2 0] Toggle, output reg [2 0] NextToggle), always ©(Toggle) casex (Toggle) 3'bxx1 NextToggle = 3'b010 3'bx1x NextToggle = 3'M 10, 3'Mxx NextToggle = 3't)Q01 default NextToggle = 3'bOOO, endcase endmodule 10.5 5 Директива синтеза parallel_ case. В Venlog оператор case имеет приоритетную природу Если несколько вариантов выбора удовлетворяют заданному значению, то будут выбраны операторы из первой по порядку ветви для оператора. Однако в Verilog есть механизм одновременного выбора оператора - параллельный case Его можно использовать в ситуации, ко:да невозможен одновременный выбор нескольких ветвей. Параллельный case реализуется с помощью атрибута parallel_c3se (листинг 10 18). В ряде случаев это позволяет получить более простую и быструю аппаратную реализацию (рис. 10 21) Листинг 10 18. Пример использования директивы parallel case module ParalielCase (input [2 0] Toggle, output reg [2 0] NextToggle), always ©(Toggle) casex (Toggle) // synthesis parallel_case 3'bxx1 NextToggle = 3'b010, 3'bx1x NextToggle = 3'M 10, 3'M xx NextToggle = 3'b001, default NextToggle = 3'd000, endcase endmodule Рис 10 21 Резутьтат синтеза модете (листинг IО 18)
191 Ш5б. Использование неконстантных вариантов выбора для оператора case. В Verilog возможна ситуация, когда варианты выбора оператора case представлены переменными и имеют неконстантные значения (листинг 10 19) В этом случае необходимо обязательно использовать директиву synthesis full case, чтобы избежать появления триггеров в процессе синтеза. На рис. 10 22 представлен результат синтеза такой Venlog-модели без использования директивы синтеза fullcasefullcase, а на рис 10.23 - с использованием В первом случае отсутствие директивы привело к появлению триггеров. Листинг 10 19. Использование оператора case с переменными значениями для вариантов выбора module Encoder (input [0 3] Bus, output reg [0:1] Address), always @(Bus) casez(1'b1) //synthesis full_case Bus[0] Address = 2'b00, Bus[1] Address = 2Ъ01, Bus[2] Address = 2'M0, Bus[3] Address = 2'M1, enacase endmodule Рис 10 22 Без использования директивы fullcase Избежать появления триггера можно с помощью инициализации переменной Address в операторе case: always @(Bus) Address = 2'b00, > — ^—^_ > — БдаО) Busm Bus<2> AdAessity Би*<0> Виц 0 Ш2) Ad*ess(l) Рис 10 23 С hciioj
192 10.6. Операторы циклов *••:.,•„•» •:> ,:е. ; s В языке Venlog присутствует четыре цикла: while for, forever и repeat [3,4]. Полностью для синтеза, как это указано и в стандарте, поддерживается цикл for, поскольку в нем точно и ясно задается число итераций (листинг 10.20) Для логики, соответствующей операторам, которые записаны в цикле, создается столько копий элементов, сколько итераций имеет цикл. Поэтому необходимо, чтобы границы цикла были представлены константами. Листинг 10.20. Пример использования циьла for module Multiplexer (input [1 0] Address, output reg [3 0] Line), integer J, always @(Address) for(J = 3,J>=0,J=J-1) if (Address == J) Line[J] = 1 else Line[J] = 0, endmodule Для примера с листинга 10.20 в момент синтеза обрабатывается 4 копии оператора if. if (Address == 3) Line[3] = 1,elsebne[3] = 0, ^ -,. if (Address == 2) Lme[2] = 1, else Line[2] = 0, " .. ... if (Address ==1) Line[1] = 1, else Lme[1] = 0 ■-.-. ■'•:...-' if (Address == 0) Lme[0] = 1 else Lme[0] = 0. Результат синтеза представлен на рис. 10.24. Рис 10 24 Рез>льтат синтеза оператора for
193 Синтез остальных трех видов циклов, если и поддерживается, то определяется только программами синтеза, и в различных системах могуг присутствовать различные требования и ограничения по записи таких операторов. Синтез оператора repeat возможен, если указано константное значение числа повторений. Запрещается использование конструкций вида repeat (n) @(event), где п - некоторое константное значение, a event - событие сигнала или проверка появления заданного фронта сиг нала. При использовании блоков always для повторения выполнения операторов может быть применен цикл while Он выполняет другие операторы, пока проверяемое выражение не примет значение false. Проверяемое выражение может быть любым выражением языка Verilog. Оператор disable не поддерживается. Листинг 10 21 представляет пример использования цикла while, a рис. 10.25 - результат его синтеза. а . ~<Ь wpietaOpntdenmieaili )_сш^1(йе(0)«жз«ая«3(0) ~СЙй!*ЁЁ*йМ1> иеза цикла while Листинг 10.21. Использование цик. module test1(lD_compiete, unidentified), input [3 0] Incomplete; output reg [3 0] unidentified, parameter P = 4, always @(iD_complete) begin UNIDENTIFIED integer i, reg found, unidentified = 0,
found = О, while (Ifound && (< < P)) begin "-'' ■•'■•"' " found = !ID_complete[iJ, unidentified[i] = 'Incompleted end •;. .;,-- end endmodule 10.7. Локальное использование переменных Даже если переменная объявлена глобально, но используется локально под управлением синхросигнала, то триггер для нее формироваться не будет [1-4]. В следующем примере (листинг 10.22) оператор always запускается по заднему фронту синхросигнала Clk. Первой значение получает переменная Temp, но оно сразу же используется в следующем неблокирующем операторе, присваивающем значение переменной NextState Поэтому для данною примера будет сгенерирован только один триггер для переменной NextState (рис.10 25). Листинг 10 22 Использование переменой без создания триггера module GlobalReg (input Clk, input [3 0] State, output reg [3 0] NextState), reg [3-0] Temo, always @(negedge Clk) begin Temp = State, NextState <= Temp end endmoduie Если в предыдущем примере (см листинг 10.22) поменять местами блокирующий и неблокирующий оператор (листинг 10.23), то значение переменной Temp будет сохраняться между итерациями выполнения блока always», что приведет к появлению дополнительного триггера (рис 10.27) FD 1 Рис 10 26 Результат ситеза модели (тистинг 10 22) Листинг 10.23. Использование переменой с созданием триггера, module GiobalReg (input Clk, input [3 0] State, output reg [3 0] NextState), ; reg [3 0] Temp, always @(negedge Clk)
195 NextState <= Temp Temp = State, end endmodule FD_1 , r~—i Рис 10 27 Результат синтеза моде™ (листит 10 23) Для локально определенных в блоке переменных, так же как и для остальных переменных, может генерироваться или не генерироваться триггер. Трип ер будет генерироваться, если значение переменной не полностью определено в операторах управления if или case и если переменная используется до присвоения ей значения и хранится до следующей итерации выполнения блока 10.8. Различия между блокирующими и неблокирующими переменными Основное различие между этими двумя формами оператора присвоения лежит в принципе их обработки во время моделирования В блокирующих операторах переменная получает значение до выполнения следующего за ним оператора (нет различия между двумя типами этих операторов, если он единственный в операторе always и initial) p, 4] В неблокирующих операторах переменная, стоящая с правой части выражения, получает новое значение только в конце цикла моделирования. В следующем примере блок always содержит три оператора: один блокирующий и два неблокирующих Поскольку все три присвоения выполняются под управлением синхросигнала, то для каждого из них генерируется триггер с синхронизацией задним фронтом. В листинге 10.24 переменная RightShift использ>ет для вычисления свое предыдущее значение, поэтому для нее при синтезе создается триггер (рис 10.28). Различие заключается в способе подсоединения информации к входам регистра Поскольку для переменной RightShift используется блокирующий оператор, то ее новое значение станет доступным раньше выполнения следующего оператора. Поэтому получается, что данные с входа триггера RightShift должны использоваться для вычисления значения поступающего на вход SelectFirst. А поскольку переменная SelectFirst получает значение в неблокирующем операторе, то на следующий триггер данные поступают с выхода SeiectFirst Листинг 10.24. Использование переменной без создания трипера module FB (mDut ClockB, Strobe, Xflag, Mask output reg RightShift, SelectFirst, CheckStop), always @(negedge ClockB) begin
RightShift = RightShiftл St-obe, SelectFirst «-= RightShift | Xflag, CheckStop <= SelectFirstл Mask, Рис 10 28 Результат синтеза (листинг 10 24) Листинги 10.25 и 10.26 иллюстрируют различие между блокирующими и неблокирующими операторами. В первом случае FCR получает значение с помощью неблокирующего оператора, поэтому в операторе if используется старое значение переменной FCR, а для FCR генерируется триггер (рис. 10.29). Во втором примере для FCR используются блокирующие операторы, поэтому при вычислении значения переменной Claim применяется обновленное значение FCR, а триггер для FCR не генерируется, поскольку нег необходимости хранить ее значение (рис. 10 30). Листинг 10.25 Пример с блокирующими и неблокирующими операторами module NonBlockingExample (input Clk, Merge, ER Xmit FDDI, output reg Claim); reg FCR; Clk) begin FCR<=ER|Xmit, if(Merge) Claim <= FCR & FDDI,
Рис 10 30 Результат синтеза (лист инг 10 26) Листинг 10 26 Пример с блокирующими и неблокирующими операторами module NonBlockmgExample (input Clk, Merge, ER, Xmit, FDDI, output reg Claim), reg FCR, always @(posedge Clk) FCR = ER|Xmit, if (Merge) Claim = FCR & FDDI, Claim = FDD!, 10.9. Операторы A&sign и Deassigo Синтез процедурных операторов assign/deassign поддерживается в XST [3,4]. Использование операторов assign/deassign представлено листингом 10.27, а результат - рис. 10.31. Листинг 10.27. Пример использования операторов assiga'deassign module assign (input RST, SELECT, CLOCK, input [0 3] DATAJN, output reg [0-3] STATE), always @ (RST) if(RST) assign STATE = л D0, else deassign STATE, always @ (posedge CLOCK) STATE = DATAJN, endmodule
198 FDC [SST> __J Рис 10 31 Pej> тьтаг синтеза операторов assign/deassign в XST На использование операторов assign/deassign накладываются ограничения" 1) Для одного сигнала допускается только одна конструкция assign/deassign (листинг 10 28, а). 2) Операторы asbign/deassign должны быть описаны в одном блоке always с помощью конструкции if-else (листинг 10.28, б) 3) Нельзя применять операторы assign/deassign, если вектор получает значения по частям (листинг 10.28, в). Синтез моделей, представленных листингом 10 28, приведет к ошибке синтеза. Листинг 10 28. Недопустимое использование операторов assign/deassign а) module dflop (input RST, SET, CLOCK.DATAJN, output reg STATE), always @ (RST) // block M if(RST) assign STATE = TbO, else deassign STATE, always @ (SET) // block M if(SET) assign STATE = 1'M, else deassign STATE, always @ (posedge CLOCK) // block b2 STATE = DATAJN, endmodule Сообщение об ошибке Analyzing top module <aftop> ERROR Xst 855 - "ml v" line 26 Unsupported procedural assignment for signal <STATE> б) module dflop (input RST, SET CLOCK.DATAJN, output reg STATE), always @ (RST or SET) // block M case ({RST.SET}) 2'dOO assign STATE = 1Ъ0, : : •'" 2'b01 assign STATE = 1'bO, -" 2'MO assign STATE = ГМ, 2'M1 deassign STATE, endcase always @ (posedge CLOCK) // Ыоск Ь2 STATE = DATAJN; endmodule Сообщение об ошибке Analyzing top module <dflop>
199 ERROR Xst 855 - "mi v" line 25 Unsupported procedural assignment for signal <STA7E> в) module assign (input RST, SET, CLOCK.DATAJN, output reg STATE), always @ (RST) // block M if (RST) assign STATE[0 7] = 8 bO, else deassign STATE [0 7], always @ (posedge CLOCK) // block b2 if (SELECT) STATE [0 3]= DATA_IN[0 3], else STATE [4 7]= DATAJN[4 7] endmodule 10.10. Синтез подпрограмм Функция синтезируется комбинационной схемой с одним выходом, который может быть скалярным или вектором (листиш 10 29, рис 10 32) [1-4] Листинг 10.29. Декларация и использование функции module сотЫ 5 (input [3.0] А, В, input CiN, output [3.0] S, output COUT), wire[1 0JS0, S1.S2, S3, function signed [1 0] ADD (input A, B, DN), reg S, COUT, begin S = А л В л CIN, COUT = (A&B) | (A&CIN) | (B&CIN), ADD = {COUT, S}, end endfunction assign SO = ADD (A[0j, B[0], CiN), S1=ADD(A[1J, B[1J,S0[1J), 52 = ADD(A[2], B[2J, S1[1]), 53 = ADD (A[3], B[3], S2[1]), S={S3[0], S2[0j, S1[0], S0[0]}, COUT = S3[1}, endmodule Функции все!да соответствует комбинационная схема Однако следующий код приведет к появлению latch-триггера (рис. 10.33), поскольку переменная у будет сохранять свое значение между итерациями выполнения оператора always: module latchlb (output reg у, input d, en), always @* у <= lat(d, en) function lat (input d, en), if(en)!at = d endfunction endmodule
Рис 10 33 Latch-трип ер Модель будет вести себя как триггер-защелка, но синтезироваться будет комбинационной схемой, чго приведет к различным результатам моделирования до и после синтеза. Задача может быгь представлена как комбинационной, так и последователь- ностной логикой в зависимости от контекста выполнения (листинг 10 30, рис 10 34). В задачах игнорируются все временные параметры Не допускается использовать именные события Листинг 10 30 Декларация и использование задачи module ex_task (input [3 0] А, В, input CIN, output reg [3 0] S, output reg COUT), reg [1.0] SO, SI, S2 S3, task ADD (input A, B, CIN, output reg [1 0] C), reg S, COUT, begin S=AA ACIN, COUT = (A&B) | (A&CIN) | (B&CIN); С = {COUT, S}, always <§KA, B, CIN) begin ADD (A[0] B[0], CIN, SO), ADD (A[1], B[1], S0[1] S1), ADD ГА[2], В[2] S1[1],S2) ADD (A[3], B[3], S2[1], S3), S = {S3[0],S2[0],S1[0],SO[0]}, COUT = S3[1], end endmodule
:hEo Рис 10 34 Результат синтеза (листинг 10 30) 10.11. Использование параметров В процессе синтеза параметры используются для определения размеров [1,2]: разрядности линий, количества элементов, кодирования состояний автомата. Задержки в синтезируемых моделях не задаются, поэтому параметры, определяющие временные параметры устройства, игнорируются. Значение параметра может быть переопределено в операторе реализации модуля через конструкцию rf( ). Также разрешено использование конструкции defparam, но не более чем на один уровень иерархии. В примере (листинг 10.31) с помощью параметра задается разрядность входной in и выходной out шин данных в модуле lmp_reg, которая по умолчанию равна 1 В модуле top в операторе реализации копии модуля Imp reg это значение переопределяется на 8 Рис 10.35, а представляет результат синтеза 1- разрядного регистра из модуля Ipm_reg, а рис. 10.35,6 - результат синтеза модуля top, формирующего 8-разрядный регистр из lpm_reg путем переопределения параметра SIZE. Листинг 10.31. Определение разрядности шин данных через параметр module lpm_reg Щ parameter SIZE = 1) (input [SIZE-1 0] in, input en, reset, elk, output reg [SIZE-1 0] out); always @(posedge elk, negedge reset) begin if ('reset) out <='bO, else if (en) out <= in, else out <= out; end endmodule module top (input [7 0] sysjn, output [7.0] sys_out input sys_en, sys_reset, sysc'k), ipm_reg #8 buf373 (sysjn, sys_en, sys_reset,sysclk, sys_out), endmodule
б Рис 10 35 Синтез 1-й 8-разрядных регистров 10.12. Использование значения х Присвоение значения х сигналу в Venlog сообщает программе моделирования, что сигнал находится в неопределенном состоянии, а программа синтеза рассматривает такую величину, как не имеющую значения [3, 4]. Таким образом, во время синтеза выполняется оптимизация вентилей, формирующих выходное значение, равное х. Это также означает, что результаты моделирования для сигналов, получающих х, до и после синтеза буду г различны. В примере (листинг 10.32) выход мультиплексора инициализируется в х, а затем обновляется, основываясь на значении сигнала sel. В проекте подразумевается, чго входной сигнал sel никогда не будет равен 2'Ы 1 Если в результате моделирования модели возникнет такая ситуация, то выходное значение у будет равно х, в то время как для модели после синтеза у - определенное значение 0 или 1. Листинг 10 32. Модель мультиплексора с использованием х module mux3_x (output гед у, input [2 Oj a, input [1 Oj sel), always @* begin у = 1'bx; // synthesis "don't-care" case (sel; 2'b00 у = a[0], 2'b01 y = a[1], 2'MO y = a[2], endcase end endmodule Использование значения х может быть полезным для поиска ошибок при выполнении постеннтезиого моделирования. Это также позволяет выполнять оптимизацию генерируемой схемы проекта, основываясь на неопределенных (don't care) значениях переменных (рис. 10 36 ) 10.13. Контрольные вопросы и задания 1 Знаковый или беззнаковый результат арифметической операции присваивается переменной типа reg?
203 list 1 I :i> rm 1 j Рис. 10.36. Использование х позвочило избежать появления триггера 2. Сколько триггеров будет сгенерировано из следующего кода, если допустить, что каждая переменная соответствует одному биту? always @(posedge CLK) begin STAGE1 =-A&B STAGE2<= STAGE 1|C 3 Будет ли синтезирован триггер-защелка из следующего кода? Если да, то сколько? always @(A, EN) begin Design integer Tmp, if (EN) begin Q <= Tmp, Tmp = A, end end 4 Какая логика будет синтезирована из следующего кода? reg [3 0] О, wire [3 0] Shift, wire [3 0] D, always @(posedge Clk) begin Q <= Shift» D, end 5. Будут ли синтезированы триггеры или триггер из следующего кода? always @(Sel) case (Sei) // synthesis fuil_case 2'b01 Out<=2'M0, 2'MO Out<=2'b01, endcase 6. Как разрешается конфликтная ситуация при использовании оператора casex, если значения выбора в различных ветвях совпадают или перекрываются? 7. Какая логика генерируется из следующего кода? wire en d, regq, always begin
' '204 wa.tferO, #10q<=d, ■- end 8. Следующий код моделирует два регистра. Результаты моделирования после синтеза не совпаж с результатами функционального моделирования. Почему9 always @(posedge CLK) always @(posedge CLK) if(CLK)A = A_m, if (CLK) В = Bjn; else A = B, else В = A, 9 Какая логика будет сгенерирована из следующего кода? always @ (Dm, E) if(E) assign Q = Din, else deassign Q, 10. Какая логика будет сгенерирована при синтезе следующего кода? wire [3 0] D, sel, reg Q, always @(R, sel) casez (sel)//synthesis parallel_case 4'b«'1 Q<=R[3], Wl? Q<=R[1], Л'Ь?^ Q<=R[0j, 4Wm Q<=R[2]; default Q<=1'bx, endcase 11 Какой знак будет иметь результат следующей операции? integer А, В, С, always @(A, В) С <= А + В, 12. Почему результаты моделирования после сшпеза не совпали с результатами моделирования до синтеза? always @(Ready) Stop <= Ready & Wait, 13. Комбинационной или последовательное!ной логикой реализуются операторы непрерывного назначения assign? 14. Что будет сгенерировано в результате синтеза следующего кода? always @(i*) begm if(m1)0 = m1, else О <= in2, end 15. Что будет сгенерировано в результате синтеза следующею кода? if (in2) begin outi [0] = inO, out1[1]<=m1, - . end ,.""■■", else begin
205 out1[0j = in2 out1[1]<=m3, end 16. Что будет сгенерировано в результате синтеза следующего кода9 module Logic (input [1 0] Т, output reg [1 0] Res), afarays @(*) :ase (T) 2'b01 Res = 2'b10, 2'ЫО Res = 2'b01, endcase erdmodule П. Что будет сгенерировано в результате синтеза следующего кода? —odule Logic (input [1 0] Т, output reg [1 0] Res), 3'Aays @(*) rase(T) 2*b01.Res = ?'b10, 2*b10 Res = 2*b01, default Res = 2'b01; errfcase IS. Что будет сгенерировано в результате синтеза следующего кода9 codule Logic (input [1 0] D, output reg [1 0] Q), aways @(*} case (D) //synthesis full_case 2'b01 Q = 2"b10, 2'ЫО Q = 2'b01, endcase endmodule
И. ШАБЛОНЫ СТАНДАРТНЫХ КОМПОНЕНТОВ 11.1. Комбинационные компоненты 11.1.1. Мультиплексоры Модель мультиплексора может быть описана с помощью оператора if (листинг 11.1. а) и саьс (листинг 11.1,6) [1-4]. Использование того или иного оператора является делом вкуса и принципиального значения для формируемой в результате схемы не имеет В обоих случаях результат синтеза одинаков (рис. 11.1). Удобнее, по мнению авторов, использовать оператор саье. ЛистингП! Мультиплексор 4-в-1 a) module muxjf б) module mux_case (input a,b,c,d, input [1 0] s, output reg o), always @(a, b, c, d, s) if (s == 2'b00) о = a, elseif(s==2'b01)o = b, else if (s==2'M0)o = c else о = d. endmodule (input a,b,c,d, input [1 0]s, output i ego) always @(a b, c, d, s) case (s) 2b00 o = a, 2'b01 o = b, 2'MO o = c default о = d, endcase endmodule Рис il I RTL-cxeMauyTbimuieKcopa Мультиплексор можег быть реализован с помощью тристабильных буферов В этом случае число управляющих входов равняется числу входов данных, при этом используется позиционный код для выбора активного входа (листинг 11.2, рис. 11.2). Листинг 11.2. Мультиплексор 4-в-1 на тристабильной логике, module mux_tn_ st (input a,b,c,d, input [3-0J s, output o), assign о = s[3] ' a 1'bz, assign о = s[2]' b .1'bz, assign o = s[ip с -1'bz, assign o = s[0] 'd 1'bz, endmodule
Рис 112 RTL-схеча мультиплексора на триетабильных буферах 11.1.2 Дешифраторы. Модели дешифраторов создаются с помощью оператора case. Предлагается два примера дешифраторов с прямыми (листинг 11.3, а)) и инверсными выходами (листинг 11.3, б)} Результат RTL-синтеза для обеих моделей одина- \ов и представлен рис. 11 3 Листинг 11.3 Venlog-модель деши) a i module ded (input [2 0] se! output reg [7 0] res) aftvays @(sel, res) =ase (sel) 3'bOOO res = 8b00000001, 3'b001 res = 8'b00000010, ЗЪОЮ res = 8b00000100, 3b011 res = 8b0000i000: З'ЫОО res = 8'b00010000, 3'Ы01 геь = 8'Ь00100000, 3M10 res = 8'b01000000; default res = 8b10000000, endcase e^module (One-Hot) 6) module decO (input [2 0] sel, output reg [7 0] res), always @(sel, res) case (sel) 3'bOOO res = 8'M1111110, 3'b001 res = 8'Ы1111101 З'ЬОЮ res = 8'M1111011 3'b011 res = 8'b11110111 З'ЫОО res = 8'b11101111 3'Ы01 res = 8'M1011111, З'ЫЮ res-8'b10111111, default res = 8'b0i111111 endcase endmodule Decoder Sb -4ИШ> Рис ИЗ RTL-схема дешифратора Если в дешифраторе используются не все возможные комбинации 2п, то -применение конструкции вида default: res _ 8'bxxxxxxx\; поможет получить оптимальную комбинационную схему, как это представлено в листинге I! 4 Листинг 11.4. Venlog-модель дешифратора со значением по умолчанию •nodule dec (input [2 0] sel, output reg [7 0] res), a-ways @(sel, res) case (sel) 3'bOOO res = 8b00000001, ЗЪ001 res = 8 ЬООООООЮ, З'ЬОЮ res = 8'b00000100 3'b011 res = 8'b00001000, 3M0O res = 8'b00010000, ЗЫ01 res = 8b00100000
//110 and 111 selector values are unused default res = 8'dxxxxxxxx, endcase endmodule 31 1.3 Устройства сдвига Xilinx проектирует логические схемы сдвига как комбинационную схему с двумя входами и одним выходом (рис. 11.4)- 1) первый вход DI - сдвигаемые данные: 2) второй вход SEL определяет число разрядов, на которые выполняется сдвиг. На выход SO поступает результат операции сдвша (листинг 11.5, рис 11 5) Следует использовать один тип операции сдвига Значение п для операции сдвига должно увеличиваться или уменьшаться только на 1 для каждого последующего двоичного значения селектора Значение п может быть только положительным Все значения селектора должны присутствовать. i О! [7 0] SO{7 0| i SEL[1 0] j Рис И 4 Интерфейс \стройства елвш а Листинг 11 5. Venlog-модель сдвига геля module Ishift (inDUt[7 0]DI,input[1 0]SEL, output reg [7-0] SO), always ©(DI, SEL) case (SEL) 2d00 SO^=Di, 2'b01 SO<=DI«1, 2'M0-SO<=DI«2, default SO<=DI«3, endmodule Рис 115 RTL-cxewa устройства сдвша 11 1.4 Арифметические устройства. Для синтеза разрешены арифметические операции сложение, вычитание и умножение, а также операция сравнения Операнды могут быть знаковые и
209 беззнаковые. Деление разрешено только, если делитель равен 2п, где п любое положительное число или 0, и аппаратно реализуется сдвигом на п разрядов вправо. Шаблоны описания арифметических устройств представлены: беззнаковыми и знаковыми сумматорами без переноса (листинг 11.6, рис.11.6), с переносами (листинг i 1.7, рис.! 1 7), устройством вычитания (листинг 11.8, рис.11.8), компаратором (листинг 119, рис. 11.9), устройством умножения (листинг 11.10. рис.11.10), устройс!вом деления (листинг 11.11) Листинг 11.6. Verilog-модели сумматора без переноса а) //беззнаковый 6) // знаковый module addeii module adder2 {input [7 0] A, B, (input signed [7.0] A, B, output [7 0] SUM); output signed [7:0] SUM), assign SUM = A + B, assign SUM = A + В endmodule endmodule Рис I i 6 RTL-c\e\m c\ мматора без переноса Листинг 11.7 Venlog-модель сумматора с переносом б) // в старший разряд а) //из младшего разряда module adder3 (input [7 0] А, В, input CI, output [7 0] SUM), assign SUM = endmodule A + B+CI, в) // из младшего и в старший разояды module adder (input CI, input [7 0] A, B, output [7 0] SUM, output CO), wire [8 0] tmp, assign tmp = A + В + CI, assign SUM = tmp [7 0], assign CO = tmp [8], endmodule Листинг 11.8 Venlog-модель устройст module subtr (input [7 0] A, B, output [7 0] РчЕЗ) module adder4 (input [7 0] A, B, output [7.0] SUM, output CO), wire [8 0] tmp, assign tmp = A + B, assign SUM = tmp [7 0], assign CO = tmp [8], endmodule
210 assign RES = A - В, endmodule б L~<> в Рис 117 R1L схема сумма гора с nepuiocovi [д-Т^ Рис i!8 КТЬ-с\сма\стройства вычитания Листинг 11.9. Venlog-модель компаратора module compare (input [7 0] А, В, output CMP) assign CMP = A >= В ? 1 'M 1 'bO, endmodule Рис 11 9 RTL-схема компаратора Листинг 11.10. Veniog-модель беззнакового умножителя module mult (input [7 0] A, input [3 0] B, output [11.0] RES), assign RES = A*B, endmodule Листиш 11.11. Veniog-модель делителя module divider (input [7 0] Di output F7 0] DO),
assign DO - endmoduie -^~1 Рис 1! 10 RTL-схема устройства умножения 1 i. 1.5 Совместное использование ресурсов (Resource Sharing) Цель уменьшить размер схемы, основываясь на принципе, что два подобных арифметических устройства могут быть реализованы ча одной схеме, если она никогда не используется ими одновременно. Выбор того или иною стиля определяется средствами среды проектирования XST поддерживает совместное использование ресурсов для сумматоров, вычитателей, сумматоров/вы читателей и умножителей. Модель простейшего АЛУ (рис. 1111, листинг 11 12) применяется для иллюстрации синтеза с совместным и раздельным использованием ресурсов (рис. 11.12 -11 13). А [7 0] RES [7 0] В [7 0] С [7 0] OPER Рис 1111 Совместное использование ресурсов для АЛУ Листинг 11 12 Veniog-модель простейшего АЛУ module addsub (input OPER, input [7 0] А, В, С, output reg [7 0] RES), always @(A or В or С or OPER) if (OPER==1 bO) RES = A + B; else RES = A - C, endmoduie 11.2. Последовательностная лог ика Далее представлены шаблоны описания трип еров. 11.2.1. Триггеры с синхронизацией по фронту. Модель D-триггера, управляемая передним фронтом, представлена листин- !Ом 11.13, а), результат синтеза - рис. 11.14. а. Интерфейс устройства включает следующие порты: С - вход синхронизации, D - вход данных, Q - выход данных. Следующая модель {листинг 11.13, б), рис. 1! 14, б) представляет устройство с синхронизацией по заднему фронту л использованием сигнала асинхронного сброса CLR Последние две модели иллюстрируют при-
менение синхронной установки S (листинг 1113. в), рис 11.14, в) и разрешения синхронизации СЕ (листинг 11 13, г), рис. 11.14, г). Рис И 12 RTI-схема АЛУ с Листинг 11.13. Venlog-модель D-триггера использованием ресурсов а) // D-триггер module flopl (input С, D, output reg Q), always @(posedge C) Q = D, endmoduie в) // С синхронной установкой module flop3 (input С, D, S, output reg Q), always @(posedge C) if<S) Q=1b1, else Q = D, endmoduie 6) // С асинхронным сбросом module flop2 (input C, D, CLR, output reg Q); always @(negedge C, posedge CLR) if{CLR)Q = 1'bO else Q = D, endmoduie г) // С сигналом разрешения синхронизации module flop4 (input С, D, СЕ, output reg Q), always @(posedge C) if(CE) Q = D, endmoduie
Рис 1 ] 13 R 1 L-схема ЛЛУ без совместного использования рес>рсов fd ...racj б FDE Рис 11 14 С интез моделей П-трш i ера с синхронизацией п<
11 2.2. Трип еры-защелки Триггеры-защелки описываются с помощью блока always [1-4] (листинг 11.14, а), рис 11.15, а), могут иметь асинхронный сшнал установки или сброса (листинг 11.14, б), рис. 11.15. б) Список чувствительности оператора always может иметь сокращенную форму always @(*). Листинг 11 14. Veniog-модель D-триггера-защелки а) // D-триггер-защелка б) // D-тригтерз-защелки со сбросом module latcM module iatch2 (>nput G, D, (input G, D, CLR, output reg Q), output reg Q). always @(G, D) always @(G D, CLR) if (G) if (CLR) Q = TbO, Q = D; elseif(G)Q=D, endmoduie endmodule rg>™_J<fc >-—Q5> Рис II 15 Синтез D-грип ера-защелки 11.2 3. Счетчики. Простейший 4-разрядный счетчик с асинхронным сбросом представлен лис- гишом 11.15, а) Если сигнал CLR равен 1, то выполняется сброс устройства в нулевое состояние, иначе по каждому переднему фронту синхросигнала значение счетчика увеличивается на 1. Результат RlL-синтеза изображен на рис. 11.16. Листинг 11.15, б) - это параметризируемая модель счетчика, разрядность которого задается параметром MAXJSQRT, а верхняя граница счета - параметром МАХ. Модель с синхронным входом S, по которому значение счетчика сбрасывается в 1111. представлеч листингом 11.16, а результат синтеза данного устройства изображен на рис. 11.17. Еще один пример счетчика (листинг 1117, рис. 11.18) имеет вход параллельной загрузки D, который может быть использован для установления начального состояния, когда сигнал ALOAD=l. Листинг 11.15 Беззнаковый счетчик с асинхронным сбросом а) module counter (.nput С, CLR, output reg [3 0] Q), aiways @(posedge C, posedge CLR) if (CLR) Q = 4'b0000, elseQ = Q + i'M, endmodule б) module v_counters_8 #(parameter MAX_SQRT = 4 MAX = MAX_3QRT*MAX_SQRT)
(input C, CLR, output [MAX_SQRT-1 0] Q) reg [MAX_SQRT-1 0] cnt, always @ (posedge С posedge CLR) if (CLR) cnt <= 0, else cnt <= (cnt+ 1)% MAX, assign Q = cnt, endmoduie JIhcthhi 1116. Беззнаковый вычитаюший счетчик с синхронной module counter (input С, S, output reg [3 0] Q), always @(posedge C) if (S)Q =4'Ы111, else Q = Q-1'M, endmoduie Pkc II 16 RTL-схема беззнакового счетчика с асинхронным сбросом -ШМ> 1 &rt3*0'Sj Н&л&Ш) h -| FDS >с Рис 1 17 RTL-c шгаюшею счетчика Листинг 1117. Беззнаковый счетчик с параллельной зафузкой module counter (input С, ALOAD, input [3 0] D, output reg [3 0] Q), always @(posedge C) if (ALOAD) Q = D elseQ = Q + 1'b1 endmoduie
Рис 10 18 RTL-cxewa беззнаковое счетчика с паралле гьной загрузкой Аккумулятор отличается от счетчика операндами, вычисляющими следующее значение. В счетчике это его текущее состояние и константа - шат счета Например, А <= А ■+■ 1. В аккумуляторе первый оператор - его текущее состояние, а второй - переменная: А <= А ->- В. Аккумулятор может работать на увеличение ceoeiO значения, на уменьшение или в обоих направлениях. Пример (листинг 11.18) представляет четырехразрядный суммир)ющий аккумулятор с асинхронным сбросом CLR. Для схем. представляющих в XSI результаты RTL-сингеза. используется специальный макрос (рис 11.19) Листинг 11.18 Аккумулятор с асинхронным сбросом module accum (input С, CLR, input [3 0] D, output reg [3 0] Q), always @{posedge C, posedge CLR) if (CLR; Q = 4'bOOOO, е!ье Q = Q + D, Рис 11 19 Аккумуляюр с асинхронным сбросом 11.2 4. Сдвиговые регистры. Существует несколько способов реализации сдвига при создании сдвиговых регистров, выбор которых определяется предпочтением проектировщика и решаемой задачей: 1. С помощью оператора конкатенации. Например, сдвиг влево (в сторону старших разрядов) на одну позицию с занесением значения SI в младший разряд может быть реализован оператором: shreg = {shreg [6 0), SI}, 2 С помощью операторов цикла Например, for (1=0, К =6 1=1+1) 1П 0 tO 6
217 begin shreg(i+1)<=shreg(i) end loop. shreg(O) <= SI, 3. С помощью определенных в языке операторов сдвига <■< и ». Примером использования этих операторов является листинг 11.19, который реализует сдвиговый 8- разрядный регистр с последовательным входом SJ и последовательным выходом SO (листинг 1119, а), рис 11.20, а), со входом разрешения (листинг 1119, б), рис. 11 20, б), с асинхронным сбросом (листинг 1! 19, в)), двунаправленный (листинг ! 1.19, г), рис. 11.20, в) Листинг 11.19. Модели 8-разрядного сдвигового pei истра а) II Последовательный регистр module shift"! (input C,SI, output SO), reg [7 0] tmp, always @(posedge C) begin tmp =tmp « 1, tmp[0] = SI end assign SO = trnp[7], endmodule в) //Последовательный регистр со сбросом module shift3 (input C,SI,CLR, output SO), reg [7 0] trtiD, alwavs @(posedge C, oosedge CLR) if(CLR) tmp = 8'b00000000, else tmp = {tmp[6 0], SI}; assign SO = tmp[7], endmodule б) // Со входом разрешения module snift2 (input C,SI, CE, output SO), reg [7 0J tmp, always @(negedge C) if (CE) begin tmp = tmp << 1, tmp[0] = SI, end assign SO = tmp[7], endmodule r) // Двунаправленный сдвиговый регистр module shift4 (input C,SI,LEFT_RIGHT, output [7 0] PO) reg [7-0] tmp, alwavs @(posedge C) if(LEFT_RIGHT==1'b0) tmp = {tmp[6 Oj, SI} else tmp = {SI, tmD[7 1]}, assign PO = tmp, endmodule Рис i I 20 Последователе
11.3. Автоматы В общем случае управляющий автомат может быть представлен комбинацией автоматов Мили и Мура (рис 11 21). При этом структура устройства делится на фи основных блока, двум из которых соответствует комбинационная схема (функции переходов и выходов), а третьему - последовательност- ная (регистр состояний). Входами для функции переходов являются текущее состояние автомата и входы. Функция выходов для автомата Мура з от текущего состояния устройства и входных сигналов [1. 2J. Reset! J Регистр Только для автомата Мили Рис IS 21 Структурная схема управляющею ai Для описания автомата могут быть использованы различные стили и приемы Программы синтеза имеют возможность определять в коде компонент автомата и применять специфические для данного типа устройств методы оптимизации В основном они затрагивают способ кодирования состояний Как правило, используется три способа кодировки: последовательный двоичный код, унарный (или позиционный) код и код Грея Выбор способа кодирования зависит от числа состояний в устройстве. Желательно при описании модели автомата отдельно описывать комбинационную часть устройства, а отдельно последовательностную Это упростит процесс тестирования устройств и сократит вероятность внесения ошибок Для написания качественного кода следует ознакомиться с документацией используемой системы синтеза и рассмотреть предлагаемые ею шаблоны написания кода В Venlog нет типов перечисления как в VHDL. Для записи состояний автомата и их двоичных кодов используют парамефы parameter или директиву компиляции 'define Пример автомата Мили (рис. 11.22, листинг 11.20) представляет наиболее распространенный способ описания кода модели состоящей из двух блоков always. Первый блок always моделирует pes истр состояний, второй соответ- ствуег комбинационным функциям переходов и выходов. Состояния автомата определены через параметры. Кодирование состояний выполняется трехразрядным унарным кодом Кроме этою, используется параметр deflt=3'bxxx, позволяющий получить оптимальную комбинационную схему функции переходов Результат синтеза представлен на рис 11.23. Первая схема (рис. 11 23, а) со- ответств>ет всему устройству и включает автомат с функциями выхода, вторая (рис 11.23, б) - расшифровывает блок FSM, содержащий peineф со-
219 стояний и реализацию функции переходов. Листинг 1121 представляет фрагмент отчета о синтезе схемы автомата Из него видно, что система синтеза обнаружила автомат и изменила предложенную Venlog-моделыо кодировку состояний. Вместо унарного кода используется последовательный, регистр состояний авюмага сокращен до двух разрядов. /~~~~\ Enable Pi , 3 FSM Enable '' Clk Rst f a Рис 1122 Интерфейс и ;раф перехода управляющего автомата Листинг 11.2С. Управляющий автомат с двумя блоками always module FSM1 // Определение меток состояний автомата и их кодирование Щ parameter defl'.=3'bxxx, idle=3'b001, read=3'b010, wnte=3'b100) (input elk, rst, enable, input [2 0] Di, output reg Out, F0, F1.F2), reg [2 0] state, next_state; // Оператор aiways>, описывающий последовательностную логику always @(posedge elk, negedge rst) if ("rst) state <= idle, else state <= next_state, // Оператор always, описывающий комбинационную логику always @Л // Значения выходов автомата по умолчанию F0 <= ГЬО, F1 <= 1'bO, F2 <= 1'ЬО, Out<=1'b0, case (state) idle ■ if (enable) begin F0<=1'b1, Out <= Di[0], next_state <= read, end else next_state <= idle, read if (enable) begin
F1 <=1'M, Out <= Di[1] next_state <= write, end else next_state <= read, write if (enable) begin F2<=VM, Out <= Di[2], next_state <= idle, end else next_state <= wnte, default next_state <~ deflt, Рис 11 23 Рез\льтаг синтеза модели автомата Листинг 11.21. Фрагмент отчета о синтезе XST Synthesizing Unit <FSM1> Found finite state machine <FSM_0> for signal <state> с дв>мя блоками aiways
| States | Transitions ] Inputs | Outputs ! Clock | Reset | Reset type | Reset State | Encoding | Implementation 13 | 16 ! И 1 13 | | elk (nsing_edge) | | rst (negative) j | asynchronous | |001 | | automatic | |LUT | Found 4x1-bit ROM for signal <F2> Found 4x1-bit ROM for signal <F1> Found 4x1-bit ROM for signal <F0> Summary inferred 1 Finite State Machine(s) inferred 3 ROM(s) Umt<FSM1> Analyzing FSM <FSM_0> for best encoding Optimizing FSM <state> on signal <state[1 2]> with gray encoding Macro Statistics #FSMs #ROMs 4x1-bit ROM Flip-Flops Venlog-модель автомата Мура (рис. 11.24) с использованием одного блока always представлена листингом 11.22. Надо учитывать, что в этом случае результирующая схема имеет дополнительные выходные регистры, в представленном примере - это блок FDP (рис 11.25) с результатами синтеза модели. Таким образом, количество трип-еров в схеме увеличивается, а выходные значения поступают на выход с задержкой на один синхрогакт по отношению к изменению состояния автомата. Листинг 11.22. Venlog-модель автомата с одним блоком module fsm_1xst #(parameter s1 = 2'b00, s2 = 2'b01, s3 = 2'M0,
222 s4 = 2'M1) (input dk, reset, x1, output reg outp), reg [1 0] state, always @(posedge elk or posedge reset) begin if (reset) begin state = s1, outp = 1'b1, case 'state) s1 begin if (x1==1'M) state = s2 else state = s3, outp = 1 b1, end s2 Degm state = s4, outp = 1'b1, end S3 begin state = s4, outp = 1'b0. s4 begin state = s1, outp = 1'b0, Рис 11 25 Результат синтеза модели автомата с оди
223 Листинг 11.22, также как и пример листинга 11 20, использует два блока always Однако отличие заключается в том, что один блок always реализует функцию переходов и регистр состоянии, а второй - комбинационную схему функции выходов Также этот пример иллюстрирует использование директивы компилятора define для определения состояний автомата. Рис 1126 представляет результат синтеза модели автомата (листинг 11.23). В лисгише 11.24 приводится фрагмент отчета о результате синтеза, из которого видно, что кодирование состояний автомата последовательным кодом сохранено, однако коды для состоянии s3 и ь4 изменились. Для описания комбинационных функций выходов может быть использован оператор непрерывного присвоения assign с условным оператором Например, второй блок always в листинге ] I 23 может быть заменен следующим оператором. assign outp = (state == s1)||(state == s2) ? 1'M 1'b0, В этом случае переменная outp должна иметь тип wire. .1ИСТИНГ 11.23. Модель автомата Мура aefine s1 2'b00 aefine s2 2'b01 define s3 2'M0 aefine s4 2'M 1 module FSM1 (input elk, reset, x1, output reg outp) reg [1 Oj state, initial state = 2'bOO, always @(posedge elk, posedge reset) if (reset) state <= s1, else case (state) s1 if(x1==1'M) state <= s2, else state <= s3, "s2 state <= 's4, "s3 state <='s4, s4 state <='s1, endcase 2"ways @(state) case (state) "s1 outp = ""'M, 's2 outp = 1'b1, 's3 outp = 1'b0, s4 outp = 1'b0, endcase endmodule
*т i | FOC ? I ! ! Л- J ft "V --=jj Рис i I 26 Результат синтеза модели автомата ( шел- Листинг 1 i 24. Фрагмент отчета о синтезе XS1 автомата Synthesizing Unit <FSM1> Found finite state machine -=FSM_0> for signal <state> ! States | Transitions | Inputs I Outputs 1 Clock | Rese? | Reset type i Reset State ! Power Ud State | Encoding | Implementation И i 15 | M I И I j elk (nsing_edge) | | reset (positive) j | asynchronous | 100 | 100 | ! automatic | |LUT | Summary inferred 1 Finite State Machme(s) Unit <FSM1> synthesized Analyzing FSM <FSM_0> for best encoding Optimizing FSM <s*ate> on signal <state[1 2]> with gray encoding i j Encoding Macro Statistics #FSMs Flip-Flcps 11.4. Модели памяти Далее представлены шаблоны моделей памяти Любая память имеет набор определяющих ее тип параметров, синхросигнал (elk), cm нал разрешения записи (we), адрес для операций чтения и записи (a, dpra), вход данных (di,), выход данных (do, spo, dpo) [1,2].
225 Чтение из памяти может быть асинхронным (листинги ! 1 25 и 11 27) или синхронным (листинги 11.26 и 11.28), т.е данные появляются на выходе сразу после поступления адреса или после прихода активного фронта синхросигнала. Сейчас в приложениях активно используется память с двумя портами для чтения (листинги 11.27 и 11.28). а также и для записи. Например, для построения буферной памяти между двумя устройствами Пример R1L- синтсза модели памяти представлен на рис 11 27 Аппаратная реализация памяти зависит от стиля ее описания, а также от выбранной для реализации технологии Листинг 11.25. Модель памяти с асинхронным чтением module raminfr (input elk, we, input [4.0] a, input [3 0] di, output [3 0] do), reg [3 0] ram [31 0], always ©(posedge elk) if (we) ram[a] <= di, endmodule Листинг ! 1 26. Модель памяти с синхронным чтением module raminfr (input elk, we, input [8 Oj a, input [3 0] di, output [3 0] do), reg [3 0] ram [512 0], reg [8.0] read_a, always @{posedge elk) begin if (we) ram[a] <= di, read_a <= a, end ' assign do = ram[read_aj; endmodule Листинг 11.27, Модель двухпортовой памяти с асинхронным чтением module raminfr (input elk, we, input [4 0] a, dpra input [3 0] di, output [3.0] spo, dpo), reg [3 0] ram [310], always @(posedge elk) begin if (we) ram[a] <= di, end assign spo = ramja], assign dpo = ram [dpra], endmodule Листинг 11.28. Модель двухпортовой памяти с синхронным чтением module raminfr (input elk, we, input [4 0] a, dpra, input [3 0] di, output [3 0] spo, dpo),
reg [3 0] ram [31 0] reg [4 0] read_a, read_dpra, always @(posedge c!k) begin if (we) ram[aj<=ai. read_a <= a, read_dpra <= dpra, assign spo = ram [read_a], assign dpo = ram [read_dpra], endmodule Рис 11 2? Результаг R1I -сингеза «одели п, 11.5. Контрольные вопросы и задания 1. Какой бток будет сгенерирован в результате с а следующег о кода0 (input С, D CLR, output >-eg Q), always ©(negedge С, poseoge CLR) if (CLR) Q = 1'b0, else Q = D, endmodule 2. Какой блок будет сгенерирован в результате синтеза следующего кода? module m (output OUT, input A, SEL), assign OUT = SEL ' A 1'bz; endmodule 3. Какой блок будет сгенерирован в результате сингеза следующего кода? mooule m (output reg [3 OJ COUNTER, input CLK, RESET), always @(posedge CLK. posedge RESET) if (RESET) COUNTER = 'd0. else COUNTER = COUNTER + 'd1, endmodule
227 4. Что будет сгенерировано в результате синтеза следующего кода9 moduie m (output reg Q, input D, CLK), always @{CLK, D) if (CLK) Q = D, endmodule 5. Какой блок буде! сгенерирован в результате синтеза следующего кода9 moduie m (output reg [7.0] Data_out, input [7 01 Datajn, input load, clock, reset), always @ (posedge reset, posedge clock) if (reset == 1'M) Data_put <= 8'bO else if (load==1'b1) Data_out <= Datajn, else Data_out <= {Data_out[6 0], Data_tn[7]}, endmodule 6. Записать синтезируемую Verilog-молель 16-разрядного сдвигового регистра с последовательными входом и выходом. SI - последовательный вход данных, EN - вход разрешения синхронизации и СК - синхронизация Сдвиг выполняется по переднему фронгу. Последовательный выход 50(рис.11.28). SRL16 Рис 1128 16-разрядный сдвиговый регистр 7. Записать синтезируемую Verilog-модель двунаправленного 4-разрядного ) регистра, который имеет вход сброса Clrb, асинхронный и актив- му уровню, отменяющий действие других управляющих вход- Все изменения состояния происходят по переднему фронту синхронизации Если управляющие входы SI = SO = I (табл. 11.1), то выполняется параллельная загрузка данных в регистр. Если S! - 1 и SO = 0 - сдвиг вправо и данные с SDR записываются в Q3. Если S1 = 0 и SO = 1, то выполняется сдвиг влево и данные с SDL записываются в Q0. Если Si - SO - 0, - сохранение сосгояния(рис 11 29). D, D2 D, D„ Ы SO SDR SDL Klk C1 0, Ch Qi Qo kJ Рис ! 1 29 Двунаправленный 4-разрятный сдвиговый pei исф
228 Таблица 11.1 Режимы работы сдвигового регистра Управляющие сигналы S1 0 0 1 1 SO 0 1 0 Следующее состояние 03' Q3 Q2 SDR D3 02^ 02 01 Q3 D2 01- Qi Q0 Q2 D1 Q0- Q0 SDL 01 DO Описание Сохранение состояния Сдвиг влево Сдвиг вправо Параллельная загрузка 8. Записать синтезируемую Verilog-модель 4-разрядного реверсивного десятичного счетчика с выходом Q и синхронизируемый передним фронтом CLK. кроме асинхронного сброса CLR. Когда CLR - 0. счетчик сбрасывается в 0, независимо от значений на других входах. Если LOAD = 0, то в счетчик загружаются данные от входа D. Если LOAD = ENT - ENP ■= UP = 1, то значение в счетчике увеличивается на 1. Если LOAD - ENT - ENP = 1 и UP = О, то значение в счетчике уменьшается на 1. Если ENT = UP - 1, выход переноса СО = 1, когда счетчик находится в состоянии 9. Если ENT = 1 и UP = О, выход переноса СО = 1, когда счетчик - в состоянии 0. 9 Записать синтезируемую Veiilog-модель N-битового двунаправленною сдвигового регистра, который имеет N-битовый параллельный вход и выход данных, левый последовательный вход LSI. правый последовательный вход RSL вход синхронизации и управляющие сигналы. Операция Load - параллельная загрузка данных в регистр, имеет больший приоритет, чем команды сдвига Когда Rsh-=1, выполняется сдвиг регистра вправо, а значение с I SI заносится в левый разряд. Если Lsh -1, л о означает сдвиг регистра влево и сигнал RSI поступает в правый разряд. 10. Записать синтезируемую Verilog-модель N-битового двоичною реверсивного счетчика с управляющими входами U и D При U - 1 - выполняется счет на увеличение: D = 1 - счет на уменьшение; U -= D = 0 - сохранение состояния, U = D = 1 - запрещенная комбинация. Значение N по умолчанию равно 8. 11. Разработать синтезируемую Verilog-модель конечного автомата, имеющего вход X, выходы D и В. На вход X последовательно подается двоичное 4-битовое число N, начиная с младшего бита D представляег 4-битовое число, равное N-2. Значение N поступает на выход, начиная с младшего разряда Во время приема четвертого бита выход В=1, если N-2 отрицательное число, В^=0 - в противном случае. Состояние автомата сбрасывается после поступления четвертого бита на вход X. Изменения сосюяния происходят по переднему фронту синхроимпульса. 12 Последовательный автомат Мура с двумя входами (XI и Х2) и одним выходом (Z) имеет следующую таблицу переходов и выходов.
229 1 2 00 01 10 11 12 2 1 2 12 1 Z 0 1 13. Написагь Verilog-код автомата, представленного таблицей переходов: 0,Q2 00 01 10 Х=0 Х-1 01 10 10 00 00 01 Z X -0 Х- 1 0 1 1 1 1 1 11.6. Литература 1. Samir Palnitkar. Verilog HDL A guide to digital design and synthesis,- SunSoft Press - 1996-396p 2. Bhasker J. Venlog HDL Synthesis. A Practical Primer. - Allentown. Stai Galaxy Publishing, 1998.-215 p. 3. Donald E. Thomas Philip R. Moorby. The Veniog Hardware Description Language - New York, Boston. Dordrecht, London, Moscow. Kluwer Academic Publishers.- 2002 - 404 p. 4. James M. Lee. VERILOG QUICKSTART. A Practical Guide to Simulation and Synthesis m Verilog. .-New Yoik, Boston, Dordrecht. London, Moscow: Kluwer Academic Publishers.- 2002.- 378 p. 5. IEEE Std 1364.1-2002. IEEE Standard for Verilog® Register Transfer Level Synthesis - IEEE Computer Society Sponsored by the Design Automation Standards Committee.- Published by The Institute of Flectncal and Electronics Engineers, Inc.- 3 Park Avenue, New York, NY 10016-5997, USA- 2002.-109 p. 6. IEEE Std 1364-1995. IEEE Standard Hardware Description Language Based on the Verilog Hardware Description Language- IEFE Standard Venlog Hardware Description Language.- IEEE Computer Society Sponsored by the Design Automation Standards Committee.- Published by The Institute of Electrical and Electronics Engineers, Inc.- 345 East 47th Street, New York, NY 10017-2394. USA - 1996-675 p. 7. IEEE Std 1364-2001. (Revision of IEEE Std 1364-1995).- IEEE Standard Verilog Hardware Description Language.- IEEE Computer Society Sponsored by the Design Automation Standards Committee- Published by The Institute of Electrical and Electronics Engineers, Inc.- 3 Park Avenue, New York, NY 10016-5997, USA-2001.-791 p.
230 Часть IV. МОДЕЛИРОВАНИЕ И ВЕРИФИКАЦИЯ ВРЕМЕННЫХ ХАРАКТЕРИСТИК ЦИФРОВЫХ КОМПОНЕНТОВ Рассматриваются вопросы, практически ориентированные на анализ временных параметров компонентов и цифровых систем на кристаллах в целом для выявления состязаний, гонок и рисков сбоев, которые деструктивно влияют на функциональные и временные характеристики проектируемых изделий Описываются примеры моделирования временных характеристик в среде Xiiinx ISE для идентификации состязаний в комбинационных и последова- тельностных базовых элементах, описанных на языке Venlog. Цель - изучение современных, практически ориентированных методов и средств моделирования для временной верификации цифровых систем на кристаллах и в пакетах, направленных на поиск и устранение временных коллизий, приводящих к потере быстродействия и к нарушению функциональных режимов проектируемого вычислительного устройства Задачи: 1. Анализ временных характеристик и типов задержек цифровой схемы: задержки вентиля и триггера; временные параметры последователь- ностных систем; обратная связь в триггере; время установки и хранения для внешних входов 2. Имплементация проекта в кристалл- эшпы имплемета- ции; использование пакета Xiiinx ISE; отчеты, формируемые в процессе им- гшементашм, Translate Report. 3 Моделирование параметров времени в среде Verilog Модели задержек- распределенная (distributed delay) и сосредоточенная (lumped delay). Задержка сигнала между выводами (pin-to-pin delay) и логического пути (path delay). Моделирование задержки пути в Verilog. Параллельное и полное соединение. Параметры времени specparam, чувствительные к фронту сигнала, и условные пути задержек - rise, fail и turn-off Обработка х-переходов. Проверка временных параметров для установки и хранения данных Влияние ширины импульса. 4. Последовательный сумма- гор. RTL- модель устройства, синтез управляющего автомата, синтез операционного устройства в целом; оценка временных параметров Источники: промышленный синтез и временная верификация цифровых систем на кристаллах и в пакетах с помощью языка Venlog [1, 2,4, 8]; синтаксис и семантика языка описания аппаратуры Venlog [3]: стандарт языка описания аппаратуры Venlog [5-7]. 12. ОПИСАНИЕ ВРЕМЕННЫХ ПАРАМЕТРОВ 12.1. Термины 1 Propagation Delay (задержка распространения) - период времени между событием на входе и появлением соответствующей реакции на выходе. Событием является любое изменение си! нала на линии
231 2. Setup Time (время установки) - период времени до появления активного фронта синхроси! нала, в течение которого описанный входной сигнал должен оставаться неизменным (рис 12.1). 3. Hoid Time (время хранения) - период времени после поступления ак! йеною фронта синхроимпульса, в течение которою входной сигнал не может изменять свое значение (рис. 12.1) Setup Hold' Рис 12! Время установки и время хранения 4 Release Time (время освобождения) минимальный промежуток времени между переключением асинхронною (set, reset) входною сигнала в состояние и появлением синхрофронта (подобно времени ; синхронных входов) (рис. 12 2) 2 2 Врс 5. Removal Time (recovery time, время восстановления) - минимальный промежуток времени между появлением синхрофронта и установкой асинхронного (set, reset) входного сигнала в активное значение (подобно времени хранения для синхронных сигналов) (рис. 12 3) Removal time Ciearban Removal time CtearbarJ/ Recovery Removal Рис 12 3 Время восстановления 6. Period - время между активными фронтами синхросинала (рис 12.4) Рис 12 4 Period
7. Width минимальная ширина импульса (рис 12.5). Width 8. Skew - представляет смещение между парой сигналов (рис 12 6) C№ew; С1к2 Г"~У~ 9. Неизменяемость (NOCHANGE) - минимальный параметр для проверки сохранения сигналом неизменного значения (рис. 12.7). Зга проверка родственна проверке ширины управляющего импульса. Период setup устанавливается до управляющего импульса, a hold - после. Сигнал, проверяемый относительно > правляющего сигнала, должен оставаться стабильным на протяжении setup period, ширины импульса и hold period. Обычно используется во временных моделях памяти, в которых адресная линия не должна изменяться во время появления сигнала записи, плюс дополнительное время до и после этого сигнала. Nochange check V Т1 ЯГ+! Т2 !«- Рис 12 7 Неизменяемость 10 Interconnect path delay - представляет внешнюю задержку линии до порта, или задержку межсоединений, которая упрощена до простой задержки линии рассматриваемого компонента. 12.2. Анализ временных характеристик цифровой схемы 12 2.1. Задержка вентиля. Для передачи сигнала через вентиль после изменения входа требуется конечное время, которое называется задержкой распространения. Чем меньше по размеру транзистор, тем меньше время его переключения. Поэтому ком-
233 пании, производящие полупроводниковые устройства, стараются минимизировать размеры транзисторов, чтобы повысить скорость работы устройства. Задержки распространения одновходового элемента на примере инвертора (рис 12 8): i) Tplh - время между событием на входе элемента и изменением его выхода из 0 в 1. Величина измеряется между 50% точками входного и выходного сигналов. Фрагмент индекса Ш обозначает изменение выходного сигнала; 2) ТрЫ - время между событием на входе элемента и изменением его выхода из 1 в 0. Величина измеряется между 50% гонками входною и выходною сигналов Фрагмент индекса hi обозначает изменение выходного сигнала. Rise time Fail time Рис 12 8 Задержки инвертора Для вентилей, имеющих более одного входа (рис 12 9). записываются задержки от каждого входа. A2Y_tplh, A2Y_tphl, B2Y_tplh, B2Y_tphl Эти параметры могут иметь различные значения. Для простоты может задаваться одно из них Ytpd В технической документации часто указывается типичная и максимальная задержки. Рис 12 9 Задержки вентиля 12.2 2. Задержки триггера. Задержки распространения последовательностных компонентов представлены на примере D-триггера (рис. 12.10) с асинхронными входами сброса (R) и установки (S): 1) TC2Q - время, необходимое на изменение выхода Q в ответ на изменение С. Выходное значение Q зависит от входа D; 2) TS2Q, TR2Q - время, необходимое на изменение выхода Q после изменения асинхронных входов S и R. Не существует задержки между синхронным входом D и выходом Q, поскольку при изменении значения на входе D значение выхода изменится только после поступления фронт синхросигнала - через период времени 1C2Q
234 Для синхронных входов (D) определяют время установки (tsu) и хранения (thd) по отношению к их входу синхронизации (рис 12 11). Setup Time - период времени до активного фронта синхросигнала, в течение которого синхронный вход D не должен изменять свое значение. Ho!d Time - период времени после активного фронта синхросигнала, в течение которого синхронный вход D не должен изменять свое значение. 12 10 Залержки последовагел Е Stable 5tat Рис 12 11 Время установки и хранения Если сигнал на входе D меняется во время установки (Setup) или хранения (Hold), то это может привести к неправильной работе триггера FF 12.2.3. Временные параметры последовательностных систем. Модель последовательностного устройства может быть представлена схемой, приведенной на рис. 12.12. Максимальная частота устройства определяется по формуле: Frcq max - l/(Td max), где Td max - самый длинный путь в последовательностной схеме, определяется на основе приведенных ниже параметров, из которых выбирается максимальный. 1) Clock-to-Outpuf задержка между сипхровходом и выходом Tc2q + Tcomb_Q20max, где Tcomb_Q20max - наиболее длинный путь от выхода триггера Q до любого выхода схемы, 2) Regibter-to-Rcgister. задержка между регистрами 3Tc2q + Tcomb_Q2Dmax + Tsu,
где Tcomb_Q2D - наиболее длинный путь от выхода триггера Qdff до любого входа триггера Ddff; 3) Pin-to-Pin комбинационный путь в схеме Tcomb I20max. i Ч K-bit Present State Value Combination Logic Circuit К DFF Q D К M, q K-bit Next State Value 3'k Рис 12 12 Стр\кт>рапослсдовательнос1ного>сфойства В большинстве схем второй из перечисленных параметров имеет максимальное значение и определяет рабочую частоту устройства. Зачастую все входы и выходы схемы являются регистровыми (рис 12 13). Таким образом, максимальная рабочая частота схемы практически всегда зависит от задержки Register-to-Regsster. Td шах - Tc2q - Tpd max + Tsetup. Комбинационная Tpd max -*r Tsetupl C2Q C2Q Рис 12 13 Устройство с pei исгровыми входами-выходами Для выполнения условия стабильности сигна щ после фронта (Hold time) минимальная задержка пути между регистрами должна удовлетворять условию (рис. 12.14.). Tc2q - Tpd mm >- Thold, хоторое, как правило, легко выполняется для последовательностных систем. Рис 12 14 Параметр Hold
236 12 2.4 Обратная связь и триггер Для трип ера с обратной связью (рис. 12.15) рассматриваются следующие параметры. 1) частота переключения Freq max = 3 / (C2Q -г Tsetup); 2) задержка, достаточная для выполнения условий стабильности сигнала Tc2q -[Tpd(mm)-»0] >= Thold • Задержка Tpd mm линии считается ничтожной и ее величина не учитывается, поэтому Fcq > Thold Гл 1—4 D —Щ Ор-> 1 Рис 12 15 Трип ер с обратной связью 12 2.5. Время установки и хранения для внешних входов. На пути между внешними входами и синхронными входами триггера находятся буферы, кроме этого может присутствовать некоторая комбинационная схема. Указанные элементы имеют собственную задержку распространения и оказывают влияние на величину времени распространения и хранения относительно внешних входов устройства. Наихудшая ситуация для времени установки Fsu, когда задержка комбинационного пуш (Tpd DIN) превышает задержку линии синхронизации (Tpd CLK) (рис. 12.16). Tpd DIN -+1 Tsu 4-ff^>—fCombI^n ![ Tpd CLK D >C Q H>I-y Рис. 12 16 Вычисление времени хранения для внешних входов Сшгхросигнал достигает входа триггера раньше, чем данные - вход D. Таким образом, на внешний вход данных DIN информация должна поступать раньше, чем активный фронт на вход CLK- Tsu DIN = Tsu + TpdDIN max - Tpd CLK min Наихудшая ситуация возникает, когда задержка пути синхронизации (Tpd CLK) превышает задержку комбинационного пути данных (Fpd DIN) (рис 12 17.). В этоу случае синхросигнал достигает входа трш гера с опозда-
нием, что приводит к необходимости дольше сохранять сигнал на входе данных: Thd DIN = Thd + Tpd CLK max - TpdDIN mm Если Tpd DIN mm превышает величину Thd + Tpd CLK max, го значение Thd DIN будет отрицательным. Эго соответствует ситуации, изображенной на рис. 12.18, когда значение входа может меняться до поступления синхросигнала. Отрицательные значения заменяются 0. Tpd DiN ■jj-£>—| Comb Log | С1К^г-[>—[ Comb Log \ j! Tpd CLK h-O^Y Рис 12!7 Вычисление времени хранения д thdn,N Stable Рис 12 18 Отрицательное значение времени хранения 12.3. Пример вычисления временных параметров Предлагается анализ временных параметров на примере схемы рис. 12.19, которая содержит два триггера (Ul, U2), три логических элемента (U3 - U5) и три буфера (U6 - U8) Временные параметры всех компонентов приведены на рис. 12.19. i Register-to-Register max: Ic2qU2 + TpdU3 ^ TsulJl - 5 + 8 f 3 = 16 ns. 3. Ahd- Tsu + TpdA2D max - TpdCLK min= = Тьи + (TpdU3 - I pdU7) - TpdU8 = 3 + (I 1 hd + TpdCLK max - TpdA2D min= = Thd 4 TpdU8 -(TpdU4 - TpdU7) -= 4 + 2 - (7 - П - 2 = -2 ns. 4. Clock-to-Out max: TpdU8 + Tc2qU2 т IpdU5 -r 'I pdU6 - 2 + 5 + 9 н 6 - 22 ns. 5. Pm-to-Pin max (от А до Y):
TPdU7 - TpdU5 + TpdU6 =1*9-6-16 n 1 / Max(Reg-to-Reg, Ciock-to-Out, Pm-to-Pm)- = 1 / Max(16, 22, 16) - 45.5 MH/ 2 ns Рис 12.19. Последовательтостная схема Полученные характеристики устройства представлены в табл 12.1 Таблица 12.1. Временные характеристики устройства (рис 12 19) Parameter Tcik Fclk Alsu Athd A2Y Ck2Y Description Clock period(период) Clock frcquencv A setup time A hold time A to Y Tpd Clock to Y Tpd 1 MitT"1 22 10 -2 Max 45.5 [_ 16 22 Units ns ~"мнГ| ns ns 1 „7 ns Улучшить временные характеристики устройства можно, преобразовав вход А и выход Y в регистровые. Для этого в схему (см рис. 12.19) добавляются два триггера U8 и U9 (рис. 12.20) Теперь схема не содержит комбинационного пути. Пример вычисления временных параметров для регистровых входов и выходов приведен ниже. 1. Registcr-to-Register max- Tc2qU2 + TpdU5 + TsuU9 -5 + 9 + 3-17 ns. 2. Asu: Tsu + TpdA2D max - TpdCLK mm = = Tsu + (TpdU7) - TpdU8 = 3 + (1) - 2 = 2 ns. 3.Ahd: Thd + TpdCLK max TpdA2D mm -= 1 hd ^ Tpdl)8 -(TpdU7) = 4 + 2 - (1) = 5 ns 4. Clock-to-Out max.
TpdU8 + Tc2qU10 + TpdU6 = 2 <- 5 ь 6 = 13 ns. 1 / Max(Reg-to-Reg, Clock-to-Out. Pin-to-Pm= -1/17 = 58.8 MHz U9 CLK-[> 2 ns Рис 12 20 Пример \стройства с регистровыми входами и выходами Полученные характеристики устройства представлены в табл 12.2 Таблица 12.2 Временные характеристики устройства (рис. 12 20) Parameter Так Freq Asu Ahd A2Y CLK2Y Description Clock репоё(перяод) Clock frequency A setup time A hold time A to Y 1 pd Clock to Y Tpd Mm 17 2 5 Max 58.8 13 Units ns MHz ns ns PS n<* 12.4. Имплементация проекта в силиконовый крис!алл В подразделе описываются этапы, выполняемые в процессе имплеметации -роектов для FPGA и CPLD Представлены временные модели и способы оценки временных параметров проектируемых устройств. -2 4 1. Этапы имплементации. Использование пакета Xilmx ISE. После синтеза формируется схема (netiist), состоящая из компонентов целе- ^го устройства (технологии) Для того чтобы поместить проект в микро- \ему необходимо выполнить операцию имплементации (Implementation). Пля микросхем программируемой логики имплементация включает сле- ;>ющие этапы (рис. 12.21) . ■ FPGA: Translate, Map, Place and Route, Configure, Is CPLD: Translate, F>t; Configure
Design Entry ! 1 j , i Synthesis j— 1 1 ' 'mp'ementation Translation FPGA - Mapping - Piasement - Routing CPLD Bitstream Gieneration Download to _ , I Back ! J Annotation Design Verification 1 j Functional j | Simulation j 1 _J Statik Timing | Analysis j J Timing j [ Simulation j in-Circuit | Verification | Рис 12 2! Этапы проектирования Mcciо имптсментации в процессе проектирования Translate - интерпретация проекта и проверка его на правильность описания (design rule check). Состоит из набора различных программ, которые используются для импортирования netlist проекта и подготовки его к размещению Набор программ может меняться от производителя к производителю, но, как правило, включает оптимизацию, трансляцию в физические элементы, проверку правильности модели (например, наличие требуемого числа синхро- буферов, входных/выходных портов). Этап трансляции обычно заканчивайся созданием отчета. Map (English) - вычисление и распределение ресурсов целевой микросхемы для разрабатываемого проекта. Place and Route - размещение CLB в логические позиции микросхемы и создание средств маршрутизации между ними. Большинство разработчиков предлагают автоматические инструменты Place and Route, поэтому у пользователя нет необходимости подробно вникать в детали этого процесса. Некоторые разработчики имеют инструменты, позволяющие выполнять операции Place and/or Route вручную для наиболее критических путей, сохраняя лучшие свойства автоматических инструментов. Одним из примеров таких инструментов является программа Floorplarmer из пакета Xilinx ISE. Процесс Place and Route требует значительных временных затрат, поскольку размещение большого проекта по компонентам микросхемы и выполнение
24! межсоединений, при обеспечении их правильности и соответствия требованиям проектировщика, являются достаточно сложной задачей. Fit (Fitting) - выполняется при проектировании на CPLD и означает подгонку ("Fit") проекта к целевому устройству, имеющему фиксированную структуру, из которой выбираются вентили и соединения для формирования проекта Обычно этот процесс не занимает много времени. Потенциальным источником проблем в данном случае является предварительное распределение входных/выходных контактов, обычно называемое Pin Locking Зачастую его формируют на предыдущих итерациях проектирования, распределение контактов зависит от топологии печатной платы Configure - создание двоичного файла конфигурации FPGA или JLD-фаила для программирования CPLD. Downloading or Programming - завершающий этап имплементации. Термин Download обычно относится к энергозависимым устройствам, таким как SRAM FPGAs. В этом случае выполняется загрузка конфигурации микросхемы в память устройства Передаваемый поток данных Bitstream содержит всю информацию об используемых ресурсах и является индивидуальным для каждого проекта. Поскольку SRAM устройства теряют свою информацию после выключения питания, конфигурация должна храниться в другом месте. Обычно для этого используется последовательное ПЗУ. Program - применяется для программирования энергонезависимых профаммируемых логических устройств, включая последовательные ПЗУ Программирование выполняет те же функции, что и загрузка, за исключением того, что информация о конфигурации сохраняется после выключения питания. Для анти- ±ьюзны\ компонентов программирование выполняется только один раз. Отсюда термин - однократно программируемое устройство - One-Time Programmable, ОТР). Загрузка конфигурации в FPGA и программирование CPLD выполняется в системе (In-System) через интерфейс JTAG или Boundary Scan, также известный как стандарт IEEE/ANSI 1149.Ы 190, который представляет собой набор правил проектирования для упрощения процесса тестирования, программирования и отладки микросхемы, платы или системы Преимущество программирования в системе заключается в том, что изменить конфигурацию устройства можно, не вынимая микросхему из платы. 12.5.2. Отчеты, формируемые в процессе имплементации. Translate Report. На каждом этапе имплементации генерируется отчет. I. Translate Report - показывает ошибки в проекте или UCF (User Constraints File). I Map Report - показывает ресурсы, используемые в проекте. Подробный отчет тар может быть задан в свойствах команды Он описывает trimmed сеченную) и merged (совмещенную) логику, а также показывает, где и ка- ■ гя часть проекта размещается в реальном устройстве Г Post-Map Static Timing Report - показывает только задержки элементов, не -,<тывая задержки линий. Если задержки логики не удовлетворяют времен-
242 ным параметрам, то добавленные к ней задержки связей только ухудшат ситуацию. 4. Place and Route Report - отображает пошагово процесс выполнения этапа Place&Route. Инструменты, выполняющие Place&Route, должны получить информацию о временных требованиях Отчет может содержать список oi - раничений (констант) и описание меры соответствия сформированной схемы заданным характеристикам. 5. Asynchronous Delay R.eport - содержит задержки наиболее длинного пути в проекте с учетом задержек элементов и путей 6 Pad Report - содержит список распределений внешних контактов с информацией о drive strength и стандарте сигнала 7. Post Place and Route Static Timing Report - учитывает задержки межсоединений проекта. 12.5.3. Тестирование устройства на разных стадиях проектирования. Functional Simulation (см рис 12.21) - используется для проверки поведения устройства. Если на этом этапе обнаруживаются ошибки, проектировщик исправляет их в модели и повторяет процесс моделирования На этот этап расходуется 50% времени разработки устройства. Затем выполняется синтез схемы устройства и постсинтезное моделирование его поведения, при котором проверяется правильность синтеза схемы из RTL. Производится анализ временных параметров, учитывающий задержки элемен гов. На этапе Place&Route программа 1 sming-Dnven Place&Route (TDPR) - дает возможность пользователю указывать временные параметры, которые будут применяться во время размещения проекта Static Timing Analyser - часть разрабатываемого пользователем программного обеспечения, позволяет получить информацию о логических путях распространения сигналов в проекте Кроме того, пользователь может получить подробную информацию о размещении проекта в микросхеме, которая может быгь передана обратно в программу моделирования вместе с точной информацией о временных параметрах системы. Этот процесс называется Back-Annotation и его преимущество заключается в точном описании временных параметров одновременно с поведением проекта В обоих случаях временные параметры будут отображать задержки и логических блоков, и межсоединений. 12.5. Контрольные вопросы 1. Какого из перечисленных временных параметров не существует для элемента, представленного на рис. 12 227 a) TC2Q - задержка изменения выхода Q после поступления фронта синхросигнала С;
6) 1S2Q - задержка изменения выхода Q после изменения асинхронною входа установки S; Рис ! 2 22 Пример устройства в) TR2Q - задержка изменения выхода Q после изменения асинхронного входа сброса R; г) TD2Q задержка изменения выхода Q после изменения синхронного входа D 2. Чему равна максимальная задержка пути между регистрами (Registei to Register delay) для схемы на рис. 12.23? ч£=- U5 CLKjyj. 5nV- UO ОС DFF: Tsu=3 ns Thd=4 ns Tc2q=5 ns 2 ns Рис 12 23 Пример схемы устройства 3. Чему равна задержка or синхросигнала до выхода (Clock to Output delay) для схемы на рис. 12.249 4. Чему равна задержка комбинационного пути (Pm to Pin delay) для схемы на рис 12 25? 5. Для цифрового устройства были получены следующие временные параметры а) Pm to Pm delay = 12 ns (задержка комбинационного пути); б) Clock to Output delay = 16 ns (задержка от синхросигнала до выхода), в) Register to Register delay = 15 ns (задержка между регистрами),
Чему равен минимальный допустимый для цифрового устройства период кит-нала9 ск-{> Рис i2 24. J 1ример схемы )стройства ск-> Рис 12 25 Пример схемы устройст
245 13. МОДЕЛИРОВАНИЕ ВРЕМЕННЫХ ПАРАМЕТРОВ ПРОЕКТА В СРЕДЕ VERILOG 13.1. Модели задержек в среде Verilog 13 1.1. Распределенная задержка (distributed delay) Описывается на основе информации о задержках элементов. Каждый элемент схемы имеет собственную задержку (рис. 13.1). Рис 13 1 Распределенная задержка Распределенная модель может быть построена путем присвоения задержек отдепьным вентилям (листинг 13.1, а) или в операторах assign (листинг 13 1,6). Листинг 13 1. Распределенная задержка а) // Распределенная задержка в модели вентильного уровня module M (output out, input a, b, с d), //Задержка распределяется по каждому вентилю and #5 а1 (е, а, Ь) nand #7 а2 (f, с, d), or #4 аЗ (out, e, f), endmodule б) // Распределенная задержка в модели dataflow-уровня module M (output cut, mput a b, с, d;, //Задержка описывается в операторе assign assign #5 е = а & b, assign #7 f = -(с & d), assign #4 out ~ e | f, enomodule 13 1.2. Сосредоточенная задержка (lumped delay) Сосредоточенная (схемная) задержка составляется на основе информации о задержках элементов. Она представлена максимальной задержкой среди всех логических путей, ведущих к выходу (рис. 13 2, листинг 13 2).
246 Листинг 13.2 Сосредоточенная задержка // Распределенная задержка в модели вентильного уровня module M (output out, input a, b, с, d), r, wire e f, and a1 (e, a, b), nand a2 (f, c, di, or #11 a3 (out, e, f), // Задержку имеет только выходной вентиль endmodule Рис 13 2 Сосредоточенная или схемная задержка 13.1 3 Задержка сигнала между выводами (pm-to-pin delay) или задержка логического пути (path delay). Задержка присваивается каждому логическому пути между входами и выходами схемной структуры (рис. 13.3 ) А __! -ч Е | c.=Oj ! T_a_out = 9, T_b_out = 9 T_c_put =11. T_d_out - 11 Рис 13 3 Задержка сиг нала между выводами Задержку сигнала между выводами часто получают из документации. Хотя такая задержка является очень детальной, для больших схем она является предпочтительней, чем распределенная задержка, поскольку проектировщику достаточно знать только входные и выходные контакты схемы без ее внутренней структуры. Последняя может быть представлена в виде описания вентильного, dataflow, поведенческого уровней или являться комбинацией различных уровней подробности. При эгом величина задержки пути остается неизменной. Задержка между вход-выходными выводами также называется задержкой пути (path delay).
247 13.2. Моделирование задержки пути в среде Verilog Задержка пути в Verilog описывается с помощью конструкции specify и endspecify Операторы внутри этого блока являются описательными и выполняют следующие задачи- 1) описывать задержк) между выводами; 2) выполнять проверку временных параметров в схеме. 3) определять константы specparam. Для примера (рис. 13.3), описание модели с задержкой между выводами представлено листингом 13 3. Описательный блок является независимым и че может появляться под управлением операторов initial или always Листинг 13.3. Задержка между выводами // Распределенная задержка в модели вентильного уровня module M (output out, input a, b, с, d), wire e, f, //Описание блока с задержками пути specify (a=>out) =9, (b=>out) =9, (с => out) =11, (d=>out) = !1, endspecify // копии вентилей and a1 (e, a, b), nand a2 (f, c, d), or a3 (out, e, f), endmodule В примере сигналы а, о. с и d представляют собой исходное поле (source field), out - поле назначения (destination field). 13.2.1. Параллельное и полное соединение. Параллельное соединение обозначается символом ~-> и имеет следующий синтаксис: (<source_field> => <destination_field>) = <aelay__vaiue> При параллельном соединении каждый бит из поля источника соединяется с каждым битом поля приемника (рис. 13 4). Если источник и приемник являются векторами, они должны иметь одинаковое число бит. Существует несколько видов соединений: 1) Однобитовое соединение, когда исгочник и приемник представляют собой одноразрядные переменные (a=>out) =9, 2) Векторное соединение, если а и out являются векторами размерностью [3.0]
248 (a => out) =9, ч го соответст вует результату (a[0j=>out[0]) = 9, (a[1]=>out[1]) = 9, (a[2] => out[2]) = 9, (a[3] -> out[3]) = 9, Полное соединение описывается символом *> и использует синтаксис. (<source_fie!d> *> <destmation_field>) = <dolay _va!ue> Source Fieid O 20 4)o s~. Destination ~KJ 1 Fieid -02 Рис 13 4 Параллельное соединение Каждый бит источника соединяется с каждым битом приемника (рис 13.5). В этом случае, если приемник и исючник представляют собой векторы, то они Fie обязательно должны быть одинаковой длины. :^Рс Source Field 2Q^ --V-N „ Destination ГЮ 1 Field ^0 2 Пример применен Рис 13 5 Полное С( я полного соединения представлен листингом !3 4. Листинг 13.4 Использование модели полного соединения module M (output out, input a, b, с, а) wire e, f, // full connection specify {a, b *> out) = 9, (c, d*>out) = l1, endspeafy and a1 (e, a, b), and a2 (f, c, d); and a3 (out, e, f). endmodule Еше один пример иллюстрирует преимущества использования полного соединения. Пусть а[31:0}~ это 32-разрядный входной вектор, a out [15-0] - 16- разрядный выходной вектор Задержка между изменением каждого входного бита и появлением реакции на выходах равна 9 единицам времени Для описания задержки можно использовать код с оператором полного соединения
249 specify (a *> out) = 9, endspecify Для сравнения необходимо отметить, что при описании данной ситуации потребовалось бы 32*16 =352 оператора параллельного соединения. 13.2 2. Параметры времени specparam. Конструкция specparam применяется внутри блока specify Вместо использования фиксированных значений для описания задержек pin-to-pin юраздо удобнее определить параметр, применяя конструкцию specparam и использовать его (листинг 13 5). Этот параметр часто служит для сохранения значений для инструментов, не являющихся симуляторами, а решающих задачи, например, вычисление задержек, логический синтез, размещение блоков Блок, содержащий параметры specparam. представлен листингом 13 5. Листинг 13 5. Использование specparam specify specparam d_to_q = 9, specparam clk_to_q = 11, (d => q) = d_to_q, (elk => q) = clk_to_q, endspecify Параметры specparam используются только в пределах блока, в котором они описаны Рекомендуется, чтобы все задержки бы пи заданы с применением параметров specparam. 13 2 3. Чувствительные к фронту сигнала пути Если путь модуля описывается с помощью фронта сигнала в качестве источника, его называют чувствительным к фронту Такие пути используются для моделирования задержек от входа к выходу, которые возникают при определенном фронте сигнала. Синтаксис: " Параллеланое соединение ([edgejdentifier] source_field => destination_fie)a [ polarity] data_source_exoression)) // Полное соединение ^edgejdentifier] source_field *> destination_field [ polarity] data_source_expression;) Параметр edgejdentifier может быть описан с использованием ключевого слова posedge или negedge и относится к входному и двунаправленному порту. Если порт является вектором, то фронт относится к младшему биту. Если фронт не указан, то путь рассматривается при любом изменении входного сигнала Чувствительный к фронту путь сигнала может быть описай с использованием полного (*>) или параллельного (->) соединения. Параметр data_source_expression является необязательным выражением, который служит для списания потока данных к пути назначения. Этот необязательный параметр не имеет влияния на реальную передачу данных иди события мо-
250 дели Параметр polarity указывает, является путь данных инверсным ипи не инверсным. Следующий код описывает чувствительный к фронгу муть с положительным оператором поляркости (posedge clock => (out + in )) = (10, 8), По положительному фронту синхросигнала clock значение с входа in к выходу out поступит через 10 единиц времени, если выход перехода из 0 -> 1, или через 10 единиц в противном случае Путь данных от входа in к выходу out прямой - значение от in не инвертируется при поступлении на выход out. Декларация чувствительного к фронту пути с оператором негативной полярности может выглядеть следующим образом: (negedge clock[0] => (out - in )) = (10, 8), В данном примере переключение устройства по заднему фронту ciockfO] использует задержку переднего фронта, равную 10, и задержку заднего фронта, равную 8. Полярность отрицательная, чго означает: величина с входа in инвертируется при передаче ее на выход out Следующий пример демонстрирует использование декларации чувствительно! о к фронту пути без идентификатора фронта' (clock->( out in ) ) = (10, 8). В этом примере выход должен изменяться при любом изменении clock 13.2 4. Условные пути задержек Величина задержки pin-to-pin может изменяться в зависимости от значения входного сш нала В этом случае при описании задержек используются условия Условную величину задержки часто называют зависящей от состояния задержкой пути (state dependent path delays(SDPD)). Синтаксис: if ( conditional_expression ) simple_path_declaration S if ( conditior,al_expression ) edge_sensitive_path_deciaration I ifnone simpie_path_dec!aratJon Операнды мсмут быть входом (input) или двунаправленным (mout) портом, скалярным вектором, элементом или диапазоном вектора класса цени и регистра, константой времени компиляции. В выражении могут быть использованы операторы: логические, побитовые, редукции конкатенации или условия. В операторе if не должно быть ветви else. Ключевое слово ifnone используется для обозначения пути, ко1да остальные условия для него имеют значение false, в этом случае может быть описан простой путь модуля Условный путь, соответствующий if, может быть либо простым путем модуля, либо чувствительным к уровню. Нельзя одновременно описывать один и тот же путь с помощью условного ifnone пути и безусловно? о пути. if(C1)(IN=>OUT) = (1,1), ifnone (IN => OUT) = (2,2), // add operation
251 if (opcode == 2'b00) (i1,i2 *> o1) = (25 0 25 0), // pass-through И operation it (opcode == 2 b01) (i1 => o1) = (5 6, 8 0), // pass-through i2 operation if (opcode == 2'MO) (i2 => o1) = (5 6, 8 0), /' a!l other operations ifrtone(i2=>o1) = (15 0, 15 0), (posedge CLK => (Q +■ D)) = (1,1), ifnone (CLK => Q) = (2,2), Следующее описание содержит ошибку, поскольку для пуги а =^> out описана задержка с использованием условного пути ifnone и безусловного пути if (a) (b => out) = (2,2) if (b) (a => out) = (2,2), ifnone (a => out) = (1,1), la -> out) = (1,1), Комбинационная схема (листинг 13 6) содержит описание условных задержек, результат ее моделирования представлен рис. 13 6. Листинг 13.6. Вентильная схема с условными задержками module M1 (out, a, b, с, d), output out, input a, b c, d, specify //различные задержки пути в зависимости от значения сигнала а if (a)(a -> out) = 9, if(-a)(a=>out) = 10, // условное выражение содержит два сигнала b и с it (b & c)(b => out) = 9, rf(~(b&c))(b=^oui)=i3, // использование операторов конкатенации и полного соединения if ({с, d} == 2'Ь01) (с, d *> out) =11, if ({с, d} '== 2'Ь01) (с, d *> out) = 13, endspecify and a1 (e, a, b), and a2 (f, c, d), or a3 (out, e, f), endmoduie Следующий пример представляет условный чувствительный к фронту путь, который описывает задержку триггера, имеющего управляющие сигналы reset и clear if ('reset && 'clear) (posedge clock => (out + in)) = (l0, 8), Если передний фронт clock случается, когда reset = 0 и clear = 0, пугь модуля распространяется от clock до out, используя задержку переднего фронта 10 и заднего - 8
Рис 13 6 Результат моде шрования Листинг 13 7 представляет три декларации для чувствительного к фронту пути. Каждый путь использует уникальный фронт или условие. Листинг 13.7. Множественные описания условного чувствительною к уровню фронта пу ги specify ( posedge elk => (q [0]. data)) = (10, 5 ), { negedge elk => (q[0] data)) = (20,12), if (reset) ( posedge clk=>(q[0] data)) = (15,8), endspecify Следующая декларация путей с двумя состояниями - неправильная, даже если они используют различные условия В первом случае выполняется декларация задержки для диапазона элементов вектора, а во втором - для единственного бита: specify if (reset) (posedge elk => (q [3 0}) data)) = (10,5), if ('reset) (posedge elk => (q[0j :data)) = (15, 8), endspecify 13.2.5. Rise, fa!! и turn-off задержки В модели задержек pin-to-pin может быть выполнено более детальное описание Для каждого пути может быть задано 1, 2, 3, 6 или 12 значений Не разрешено указывать 4, 5, 7, 8, 9, 10 или 11 параметров. При этом порядок описания задержек является фиксированным (листинг 13.8). Листинг 13.8. Модели задержек II Описание только одной задержки Используется для всех переходов specparam t__de!ay = 11, (elk => q) = t_delay //Описание двух задержек rise и fall //Rise используется для переключений 0->1, 0->z, z->1 //Fall используется для переключений 1->0,1->z, z->0 specparam tjise = 9, t_fal! = 13 (elk => a) = (t nse, tjall),
253 // Описание трех задержек rise, fall и tun-off //Rise используется для переключений 0->1, z->l //Fall используется для переключений 1->0 z->Q //Turn-off используется для переключений 0->z, 1->z specparam t_rise = 9, t_fall = 13, tjumoff =11, (elk => q) = (t_nse, t_fall, t Jurnoff), // Описание шести задержек //Задержки описываются в порядке 0->1,1->0, 0->z, z->1,1->г, z->0 //Порядок записи задержек нельзя изменять specparam t_0i = 9, МО = 13, t_0z =11, specparam t_z1 = 9, Mz = 11, t_zO = 13- (elk => q) = (t_01, MO, t_0z t_z1, Mz, t_zO), // Описание двенадцати задержек // Задержки описываются в порядке 0->1, 1->0, 0->z z->1,1->z, z->0 // 0->х, х->1,1->х, х->0, x->z, z->x specparam t_01 = 9, M 0 = 13, t_0z =11, specparam t_z1 = 9, Mz = 11, t. zO = 13, specparam t_0x = 4, t_x1 = 13, Mx = 5, specparam t_x0 = 9, t_xz = 11, t_zx = 7, (elk -> q) = (t_01, MO, t_Oz, t_z1, Mz, t_zO, t_0x, t_x1, Mx, t_xO, t_xz, t_zx}; Любая задержка может быть представлена в форме min.typrmax. Например / Описание трех задержек rise, fall и turn-off //Каждая задержка имеет min:typ max значение specparam t_nse = 8 9 10, t_fall = 12 13 14, tjumoff =10 1112 (elk => q) = (t_rise, Hall, tjumoff) По умолчанию при моделировании используется типичная величина задержки. Выбор минимальной, максимальной или типичной величины задержек задается программой моделирования. 13.2.6. Обработка х-переходов. Veriiog использует пессимистический метод при вычислении задержек для переходов в состояние х. Это означает, что если задержка х-перехода явно не описана, то для перехода из х в определенное состояние используется максимальная возможная задержка, а для перехода из определенного значения в х - минимальная возможная задержка При моделировании устройства, задержки которого описаны кодом- // Описание шести задержек //Задержки описываются в порядке 0 >1,1->0, 0->z, z->1,1->z, z->0 //Порядок записи задержек нельзя изменять specparam t_01 = 9, М 0 = 13, t _0z = 11, specparam t_z1 = 9, M z = 11, t_z0 = 13, (clK => q) = (t_01, MO, t_0z, t_z1, Mz, t_z0). для х-переходов между состояниями использованы значения из табл 13 !.
254 Таблица 13.1 Величина задержки для х-переходов Переход 0->х 1->х 7->Х х->0 х->1 \->z Величина задержки min(t_01,t_0z) = 9 min(t_10, t_lz) - И min_(t__zO, t=zl)_2_9 _ max(foi,t_zO) = 13 max(t_01,t_zl) = 9 max(t_Iz, t_0z) - 11 13.3. Проверка временных параметров Данная процедура используется для проверки возможности нарушения временных параметров во время моделирования. Это необходимо для проектирования критических ко времени высокоскоростных устройств, например микропроцессоров или DSP. В Verilog существ\ст большое количество системных задач для проверки временных параметров. Все проверки временных параметров могут быть выполнены только в блоке specify. 13.3 1. Проверка времени установки и хранения. Для проверки времени установки и хранения последовательностных элементов проекта используются задачи Ssetup и Shold, соответавенно. Синтаксис вызова системной задачи Ssetup- ■-■■•« $setup(data_event, reference_event, limit [,[ notifyjeg ]]), !де data__event - наблюдаемый сигнал, reference event - соответствующее событие, limit - значение времени установки. Сообщение об ошибке будет выдано, если: (Treference_event - rddta_event) < lim l{ • specify $setup(data posedge clock, 3), endspecify Пример (листинг 13.9) представляет использование функции Ssetup для проверки времени установки. Функция выполняет событие notif_reg, которое запускает блок always с функцией Sdisplay, выводящей сообщение о нарушении времени установки. Листинг 13.9 Модель с проверкой времени установки module m(), reg notif_reg, wire data, clock, specify $setup(posedge data poseage clock, 10, notif_reg), endspecify always @ notif_reg
255 $display("Setup violation in %m at time %f, $time), endmodule Синтаксис вызова системной задачи Shold $hold(reference_event, data_event, limit). Сообщение об ошибке будет выдано, если- (Tdata_event ~ * reference _ event) < !lmlt • specify Shold(posedge clear, data, 3), endspecify 13.3.2. Проверка ширины импульса. Иногда необходимо выполнять проверку ширины импульса. Системная задача Swidth используется для проверки соответствия длины импульса требованию к минимальной его ширине. Синтаксис задачи: $width (reference_event, limit), Параметр dataevent не указывается непосредственно при вызове системной задачи, он вычисляется как следующее событие сигнала referenceevent. Ошибка возникает, если (Tdata evcnt - Trefercnce_cvent) < lim it. specify Swidth (posedge clock, 6), endspeci*y 13.4. Системные задачи для определения временных параметров 1. Проверка времени установки Ssetup (data_event, reference_e^ent, timmg_checkjimit [, [ notify_reg ] ]), 2. Проверка времени хранения $noia (teference. event, aaia_event, tirning_cnecK_iirnit [, [ notify_reg j ] j, 3 Комбинированная проверка времени установки и хранения Ssetiiphoid (reference__event , data_event , timing jjheckjimrt , timing_check_limit [, [ notify_reg ] [, [ stamptime_condition ] [, [ checktime_condition ] [ [ deiayed_reference ] [, [ delayed_data]]]]J]), 4. Проверка параметров управляющих сигналов $tecovery (reference_event, data_event, timmg_checkjimit [, [ notify_reg ] j), Sremova! (reference_event, data_event, timmg_check_limit [, [ notify_reg j ]), Srecrem (reference_event, data_event, timing_checkjimit, timing_check_limit [, [ notify_reg ][, [ stamptime_condition ] [, [ checktime_condition j [, [ delayed_reference ] [, [ delayed_data ]]]]]]), 5 Проверка смещений между двумя сигналами Sskew (reference_event, data_event, tim'ng_check_limit [. [ notify jeg ] J), Stimeskew (reference_event, data_event timing_check_hmit [, [ notify_reg ] [, [ event_based_flag ] [, [ remain_active_flag j ] ] j), Sfuilskew (reference_event, data_event, timing_check_ limit, timing_check_limit I E notify_reg ] [, [ event_based_flag j [, [ remam_active_flag ]]]]), 6 Проверка периода синхросигнала
256 Spenod { controlled_reference_event, timing_check_limit [ [ notify_reg ] ];, 7. Проверка ширины импульса $width ( controlied_reference_event, timing_checkjimit, threshold [, [ notify_reg ] J}, 8. Проверка неизменяемости Snochange {reference_event, data_event, start_edge_offset, end_edge_offset [, [ notify_reg ] j), Листинг 13Л0 представляет пример использования системных задач для описания временных параметров триггера. Подобные модели применяются для описания устройств после имплементаиии при выполнении временного анализа системы. Листинг 13.10. Пример триггера, использующего блок specify primitive negdff(q, clock, data, preset, clear, notifier), output q, reg q, input clock, data, preset, clear, notifier, table //clock data p с notifier state q endpnrnitive module dff(q, qBar, elk, d, p, c), output q, qBar, input elk, d, p, c, reg notifier; and (e, p, c), not (qBar, udp_out), bur fq, udp_out), negdff n(udp_out, elk, d, p, c, notifier), specify // Определение значения временных параметров specparam specparam tsetup =10, thold = 2, telkwidth = 20, trecover = 5, t_pc_width, specparam tPLHc = 4:6:9, tPHLc = 5 811, specparam tPLHpc = 356, tPHLoc = 4 7:9; // Задержки пути данных (elk *> q, qBar) = (tPLHc, tPHLc), (p, с "> q, qBar) = (tPLHpc, iPHi-pc), // Проверка временных параметров $setup(d, posedge elk && e, tsetup, notifier),
257 $hold(d, negedge elk && e, thold, notifier), $penod(negedge elk, twidth, notifier), Swidth(negedge c, t_pc_width, notifier), $width(negedge p, t_pc_width, notifier), $recovery(posedge c, posedge elk, (recover, notifier), endspecify endmodule 13.5. Контрольные вопросы и задания 1. Какой тип задержки используется в схеме на рис 13.7' Разработать Venlog-описание модуля Y. Рис 13 7 Пример схемы устройства 2. Используя максимальную задержку модуля, преобразовать его модель в lumped delay. Написать Verilog-код модуля, применяя задержку lumped delay 3. Для задания 1 вычислить задержку от каждого входа до выхода. Создать Venlog-описание модуля, используя модель path delay. 4 D-триггер с синхронизацией задним фронтом и асинхронным сбросом представлен на рис 13.8. Созвать Veriiog-модель триггера D FF Показать только входные/выходные порты и описание задержек пути. Описать задержки пути, используя параллельное соединение. 1 D QJ Рис 13 8 D-триггер Параметры устройства: D -> Q = 5, D -> Qn = 5, С -> Q - 6, С -> Qn = 7, rst -> Q - 2, rst -> Qn = 3. 5. Модифицировать D-триггер из задачи 4 таким образом, чтобы все задержки пути от входов к выходам были равны 5 единицам времени Описать задержки, используя полное соединение для q и qbar. 6. Пусть для всех пугей указаны шесть значений задержек В блоке specify определены параметры t 01 = 4, t_10 = 5, t_0z = 7. tzl = 2, t_lz -~ 3, t_zO = 8 Использовать эти значения для модели D-триггера из задания 4 7. Модифицировать модель D-триггера из задачи 4, гаким образом, чтобы задержка устройства зависела от значения на входе d Если d~ 0, то clock - >
258 q = 5 и clock -> qbar - 4; иначе clock -> q = 6, a clock -> qbar = 7 В ос1аль- ных случаях задержка равна 5. 8 Для модели D-трипера из задачи 7 добавить проверку временных параметров Минимальное время установки для входа d равно 8, а время хранения -4. Сигнал reset активен по 1, минимальная длиьа импульса для сигнала reset равна 42. 9 Промоделировать значение выхода для следующей модели, которая использует блок specify: module dff(q, d, cik, reset), input elk, d, reset output a, specif)' specparam tRise_clK_q = 150, tFall_cik_q = 200, specparam tSetup = 70, (elk => q) = (tRise_clk_q, tFall_clk_q), (reset =>q) = (20,10), endspecify dffjogic dffi (a, d, elk, reset), endmodule module dff_logic(q, data, elk, reset), regq, output q, wire elk, reset, data, always @poseage elk ^. q = data, always @reset 'f {reset ==1) deassign q, e'se assign q = 0, endmodule
259 14. СИНТЕЗ И ВЕРИФИКАЦИЯ ПОСЛЕДОВАТЕЛЬНОГО СУММАТОРА 14.1. RTL- модель устройства Проектирование системы, состоящей из управляющего и операционного автоматов, представлено на примере последовательного 4-разрядного сумматора, структурная схема которого изображена на рис. 14.1. Два сдвиговых регистра используются для хранения чешрехбитных сла1аемых, X и Y. Квадрат слева о г каждого регистра изображает входы Sh (сдвиг), SI (посте- довательный вход) и Clock (синхронизация). Если Sh^l, при поступлении активного синхроимпульса значение S1 заносится в X3 (или в уз), а все содержимое регистра сдвигается вправо на одну позицию Регистр X является аккумулятором, и после выполнения четвертой операции сдвига он содержит сумму X + Y Второй регистр - это циклический сдвшовый регистр После четвертой операции сдвига он возвращается в начальное состояние и значение Y не теряется. Операция сложения реализуется полным сумматором и триггером, сохраняющим перенос. В один момент времени выполняется сложение одной пары битов. Когда Sh = 1. по заднему фронту синхроимпульса бит суммы заносится в аккумулятор, а бит переноса сохраняется в триггере. Дополнительные связи, необходимые для начальной загрузки регистров (X и Y) и для очистки триггера переноса, на рис. 14 1 не показаны. Рис 14 1 Структурная схема последовательною 4-разрятного сумматора Табл. 14.! описывает операции последовательною сумматора Здесь представлены моменты времени iq- до первого синхроимпульса, tj - после первого синхроимпульса, i2~ после второго синхроимпульса и т.д В начальный момент времени аккумулятор содержит число X, второй регистр содержит Y и триггер переноса находится в состоянии 0. Поскольку полный
260 сумматор - это комбинационная схема, то сложение xq = 1. уо = I и cq = 0 будет выполнено после небольшой задержки, например 10 ns, с формированием результата: sumn =0 и перенос cj = 1. После первого фронта синхросигнала сумма suniQ заносится в аккумулятор и оставшееся в нем число сдвигается вправо на одну позицию. Тогда же перенос с\ сохраняется в триггере и выполняется сдвш второго регистра вправо на 1 позицию. На входы полного сумматора поступает следующая пара битов: Х] = 0 и У] = 1. Результат сложения- surrn - 0 и с; =1 По второму синхроимпульсу сумма sum] поступает в аккумулятор cj сохраняется в триггере переноса, выпол няется циклический сдвиг второго регистра. Биты \j и у2 подаются теперь на входы сумматора, и процесс моделирования продолжается, пока не будет выполнено сложение всех пар битов После четвертого синхроимпульса в аккумуляторе находится сумма X и Y, а второй регистр возвращается в начальное состояние. 1 аблица 14.1 Операции последовательного сумматора to t. t. и и X 0101 0010 0001 1000 1100 Y 0111 1011 1101 3110 0111 с, 0 1 sum, 0 0 1 1 1 1 I 1 rzijiii <v, 1 1 1 0 (0) 1 Управляющая схема реализуется с помощью автомата Мура, граф переходов которого изображен на рис. 14 2. Устройство содержит один управляющий вход N и два выхода Sh и Load. Состояния автомата - S0-S5 В вершинах графа автомата указаны только re выходы, значения которых в данном состоянии равны 1. Например, в состоянии SI: Load - 1. a Sh = 0; в состоянии S2: Load - 0, a Sh = 1. I огда в состоянии SO Load ■= Sh = 0. Рис 14.2 Управляющий автомат с
26] Для управляющего автомата и регистров разработаны отдельные компоненты (листинги 14 1 и 14.2). Модель верхнего уровня, формирующая последовательный сумматор (листинг 14.3), содержит подключаемые компоненты, полный сумматор, который ре&тизован булевыми функциями в оператора assign, а также представленный оператором always регистр переноса Листинг 14 1. Venlog-модель управляющего автомата timescaie 1 ns/10ps module FSM (input Clk, Reset, N, output Sh, Load), // Определение меток состояний parameter S0=3'b000, parameter S1=3'b001, parameter S2=3'b010, parameter S3=3'b011, parameter S4=3'b100, parameter S5=3'M01, reg [2 0] state, next__state, // Блок Always для последовательностной логики always @(posedge Clk or posedge Reset) if (Reset) state <= SO, else state <= next_state, // Блок Always для комбинационной логики always @(state or N) case (state) 50 if(N)next_state<=S1, else next_state <= SO, 51 next_state <- S2 52 ncxt_state <= S3, 53 next_state <= S4 54 next_state <= S5, 55 • if (N) next_state <= S1, else next_state <= SO, default next_state <= SO, endcase assign Sh = (state==S2)||(state==S3)||(state==S4)||(state==S5)'? 1'Ы 1'bO, assign Load = (state—SI)"? 1 'Ы ч Ъ0, endmodule Листинг 14.2. Venlog-модель peracipa 'timescaie 1 ns/10 ps module register (input Clk, Load, Sh, SI, input [3 0] D, output reg [3-0] Q) always @(negedge Clk) if(Sh) Q<={SI, Q[31]}, else if (Load) Q<=D, endmodu'e
262 Листинг 14.3 Venlog-модель последовательного сумматора timescale 1 ns/10ps module seq_adder (input N elk, reset, input [3 0] X, Y, output [4 0] result), wire Sh, Load sum, Cout, reg Cin, wire [3 0] Xm, Yin FSMU1(Clk(clk), Reset(reset), N(N) Sh(Sh), Load(Load)), register Reg_X ( Clk(clk), Load(Load) Sh(Sh), Sl(sum) D(X), Q(Xin)), register Reg_Y ( Clk(clk), Load(Load) Sh(Sh) SI(Yin[0]) D(Y), Q(Vm)), // Full Adder assign sum = XinfO^YmCT^in, assign Cout = (Xin[0]&Yin[0])|(XintO]&Cin)|(Yin[Ol&Cin>, //flip-flop Cin always @(negedge elk or posedge Load) if (Load) On <=1'b0, else if (Sn) Cin<=Cout, assign result={Cm,Xin}, endmodule Для тестирования сумматора разработан testbench (листинг 14.4) Входные тестовые наборы описаны массивами константных значений X_test[5.0J и Y test[5.0], которые задаются в операторе initial Второй оператор initial используется для формирования синхросигнала и выполнения сброса в начальное состояние перед тестированием. Результаты моделирования представлены в табл 14 2 Листинг 14.4 Testbench для тестирования последовательного сумматора timescale 1 ns /10 ps module seq_adder_tb; // Декларации внутренних сигналов reg N, elk, reset, reg [3.0JX, Y, wire [4 OjresuU, reg [3 0] XJest [5 0], YJest [5 0], parameter period = 'd 20, reg ERROR, //Тестируемый модуль seo_adder UUT ( N(N), clk(clk), reset(reset), X(X) Y(Y), result(result)), initial begin Xjest [0] = 4'b0000, XJest [1] = 4'b0001, XJest [2] = 4'Ы 000 XJest [3] = 4'Ы 111, Xjest [4] = 4'b1010 XJest [5] = 4'b0101, YJest [0] = 4'b0000, YJest [1] = 4'b0001, YJest [2] = 4'Ы 000, YJest [3] = 4'Ы 111, YJest [4] = 4'Ы010 YJest [51 = 4'b0101,
// Формирование сигналов синхронизации и сброса initial end integer i clk=1'b0 reset=1'b1, #5reset<-1'b0, forever #{period/2) clk= .j; reg [3.0JA.B, reg [4-0] SUM, Sum_eta!on always for(i=0, K=5, fi+1) begin X = XJestfi] for(j=0, j<=5 ~cik, j=j+1 N = 1'b1, Y = Y_test[|], N = repeat (2) @(negedge elk) 1'b0, //чтение результатов сложения #(5*period) A=X, B=Y, SUM=resu!t, Sum_etalon={l'bO,X} + Y, ERROR = (SUM!=Sum_etalonp 1'Ы ГЬО, $display($time,° ns A=%d, B=%d, Res=%a, F= %b ' A, B, SUM, ERROR) end endmodule 14.2. Синтез управляющего автомата Для синтеза устройства использовалась программа ISE WebPack. На рис. 14 3 изображена схема RI L-синтеза устройс!ва Листинг 14.5 приводит фрагмент результата синтеза Из него видно, что система обнаружила авто- маг и для кодирования состояний использовала код Грея. Листинг 14.5. Фрагмент отчета о синтезе управляющего автомата HDL Analysis Analyzing top module <FSM> 50 = 3'bOOO 51 = 3'b001 52 = 3'b010 53 = 3'b011 54 = 3'M00 55 = 3'M01
264 Module <FSM> is correct for synthesis HDL Synthesis Synthesizing Unit <FSM> Found finite state machine <FSM_0> for signal <state> States Transitions Inputs Outputs Clock Reset Reset type Reset State Encoding Implementation 16 18 H 12 | Clk (nsmg_edge) | Reset (positive) | asynchronous | 000 | automatic JLUT Summary inferred 1 Finite State Machine(s; Unit <FSM> synthesized Advanced HDL Synthesis Analyzing FSM <FSM_0> for best encoding Optimizing FSM <state> on signal <state[1.3]> with gray encoding State | Encoding 000 |000 00" |001 010 |011 011 ,' 010 100 } 110 101 |111 Advanced HDL Synthesis Report Macro Statistics # FSMs 1 # Registers 3 Flip-Flops . 3
Рис 14 3 Послесинтезная RTL-схема управляющею автомата Таблица 14 2 i TIME 0 000 140 000 ns 280 000 ns 420.000 ns 560.000 ns 700 000 ns 840.000 ns 980 000 ns i 120 us 1 260 us 1 400 us 1 540 us 1.680 us 1.820 us 1.960'js 2.100 us 2.240 us 2.380 us 2.520 us 2 660 us 2.800 us 2 940 us 3 080 us 3.220 us 3.360 us 3 500 us 3 640 us 3.780 us 3.920 us 4.060 us 4.200 us . Результаты тестирования последовательного A "? 0 0 0 0 0 0 8 8 8 8 8 8 15 15 15 15 15 15 10 10 10 10 10 10 В ? 0 1 8 15 10 15 10 15 10 15 10 15 10 5 SUM ? 0 1 8 15 10 5 1 2 9 16 11 6 8 9 16 23 18 13 15 16 23 30 25 20 10 11 18 25 20 15 Sum_etalon 9 0 1 8 15 10 5 1 2 9 16 11 6 8 9 16 23 18 13 15 16 23 30 25 20 10 11 18 25 20 15 :умматора "ERROR 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 о 0 0 ! 0 о ! 0 0 0 I 0 0 о I о I 0 | о I
266 14.3. Синтез операционного устройства в целом Схема устройства, сформированная в результате RTL - синтеза, изображена на рис. 14 4 Частота устройства после синтеза: Minimum period 8 398ns (Maximum Frequency 119076MHz) Размер проекта из map-отчета (листинг 14 6) равен 189 эквивалентных вентилей. Используется 12 триггеров и 15 блоков LUf. Листинг 14.6. Фрагмент map-отчета Design Summary Number of errors. 0 Number of warnings 2 Logic Utilization. Number of Slice Flip Flops 12 out of 1,920 1% Number of 4 input LUTs 15 out of 1 920 1 % Logic Distribution Numoer of occupied Slices 8 out of 960 1% Number of Slices containing only related logic: 8 out of 8 ч 00% Number of Slices containing unrelated logic 0 out of 8 0% *See NOTES below for an explanation of the effects of unrelated logic Total Number of 4 input LUTs 15 out of 1,920 1% Number of bonded lOBs 16 out of 66 24% Number of GCLKs" 1 out of 24 4% Total equivalent gate count for design 189 Рис 14 4. Сформированная в рез>тьтате синтеза RTL-схсма >сфойсгва 14.4. Оценка временных параметров Временные характеристики устройства приведены в листинге 14 7. на основе которых получено, что максимальное значение'
1) Clock Clk to Pad = 7,396 ns; 2) Clock to Setup on destination clock Clk •= 8,106 ns. Таким образом, минимальный период сумматора равен 8.106 ns, а частота 123,3 МГц Л истиш 14 7. Фрагмент файла отчета Setup/ Hold to clock clk | Setup to | Hold to | I Clock | Source | clk (edge) | clk (edge) jlnternal Ciock(s) | Phase | N | x<o> ! X<1> | X<2> | X<3> | Y<0> I Y<1> J Y<2> | Y<3> I 1 616(R)| -0 111(R) !clk_BUFGP 1 111(F)| 0 293(F) |clk_BUFGP 0 665(F)! i 0 705(F)j 0 649(F) |clk_BUFGP 0 617(F) |clk_BlFGP 1 695(F)! -0 174(F) |cik_BUFGP 1211(F)! 0 866(F)! 0 953(F)! 1 174(F)) Clock clk to Pad | clk (edge) Destination | to PAD result<0> result<1> result<2> result<3> resuit<4> I 8 061(F | 8 106(F; | 7 893(F | 7 803(f; I 8 052(F; 0 213(F) |clk_BUFGP 0 489(F) |clk_BUFGP 0 419(F) jclk_BUFGP 0 242(F) |olk_BUFGP I i 0 0001 i 0 000! I 0 000! I 0 0Q0J | OGOOf i OOOOj | 0 0001 1 ooooi 1 0 000! ! Clock i jlnternal Clock(s) | Phase | i |cik_BUFGP ) !clk_BUFGP > |clk BUFGP ! |dk BUF-GP ; ) |cik__BUFGP ! 0.000] i 0 000! 1 OOOOj ! 0 000! 1 ooooi Clock to Setup on destination clock clk I Src Rise | Src Fall | Src Rise | Src Fall | Source CIock |Dest Rise |Dest Rise |Dest Fall jDest Fall | clk | 3 293 i | 3 698 I 3 000] 14.5. Контрольные вопросы 1. Какой программный продукт был использован для синтеза управляющего автомата? 2. Можно ли testbench для верификации последовательною сумматора ис- поньзовать при тестировании готового цифрового изделия на кристалле? 3 Как называется граф. в котором представлен управляющий автомат сумматора?
268 4. Сколько операций содержит цикл последовательного сумматора для выполнения функциональности'' 5. Какую функциональную нагрузку выполняют управляющий и операционный автоматы последовательно! о сумматора? 6 Сколько состояний имеет >правляющий автомат Мура последовательного сумматора9 7 Какую информацию предоставляет пользователю файл отчета о результатах синтеза? 14.6, Литература 1. Samir Painitkar Verilog HDL. A guide to digital design and synthesis.- SunSoft Press.-1996-396p. 2 Bha^ker J. Verilog HDL Synthesis A Practical Primer.- Allentown Star Galaxy Publishing, 1998.-215 p. 3 Donald E Thomas, Philip R. Moorby The Verilog Hardware Description Language.- New York, Boston, Dordrecht, London. Moscow Kluwer Academic Publishers.- 2002.- 404 p. 4. James M. Lee. Verilog Quickstart A Practical Guide to Simulation and Synthesis in Verilog - New York, Boston, Dordrecht, London, Moscow: Kluwer Academic Publishers - 2002.- 378 p. 5 IFLE Std 1364.1-2002. IEFE Standard for Verilog® Register Transfer Level Synthesis- IEFE Computer Society Sponsored by the Design Automation Standards Committee.- Published by The Institute of Electrical and Electronics Engineers, Inc.- J Park Avenue, New York, 2002.- 109 p 6 IEEE Std 1364-1995. IEEF Standard Hardwaie Description Language Based on the Verilog Hardware Description Language- 1ГЕЕ Standard Verilog Hardware Description Language.- IEEE Computer Society Sponsored by the Design Automation Standards Committee. Published by 1 he Institute of Electrical and Electronics Engineers, Inc.- 345 East 47th Street, New York. NY 10017-2394, USA - 1996.-675 p 7.1ELF Std 1364-2001. (Revision of IEEE Std 1364-1995)- IEEE Standard Verilog Hardware Description Language - IEEE Computer Society Sponsoied by the Design Automation Standards Committee.- Published by 1 he Institute of Electrical and Electronics Engineers, Inc. 3 Park Avenue, New York. NY 10016-5997, USA.-2001.-791 p 8. Cunningham P., Swinnen ML, Wilcox S Clock Concurrent Optimization.- February, 2009.- www azuro com
269 ЧАСТЬ V. SYSTEM VERILOG Рассматриваются конструктивные особенности, синтаксис и семантика языка описания аппаратуры SystemVerilog, ориентированные на проектирование и верификацию гетерогенных (цифровых) систем на кристаллах. В разд 15- 17 представлены типы данных SystemVeniog, струкгуры проектов, конструкции операторов, процедурных блоков, задач и функций, основы объектно-ориентированного программирования (ООП) Цель - предоставление уже не новичку, но еще не конструктору, технологической культуры от ведущих компаний планеты (Cadence. Synopsys, Mentor Graphics, Aldec) в части проектирования, анализа и синтеза специализированных цифровых систем на кристаллах путем использования языковой среды высокого уровня - SystemVeniog к описанию и функциональной верификации многочисленных примеров аппаратной реализации компонентов. Задачи изучения- 1 Типы данных SystemVeniog" пространства для декларации объектов в SystemVeniog - пакеты, понятие единицы компиляции, единицы времени и точность их вычисления; новшества в описании символьных значений - описание типов данных, встроенные типы данных, типы цепей (Net Types); логические типы; типы данных с двумя состояниями; строки; другие абстрактные типы данных System Veri log; преобразования типов, размер выражений; константы; пользовательские типы данных (User-defined types), совместно используемое определение типа typedef; типы перечисления - определение значений типов перечисления, последовательности меток в типе перечисления, задание базового гипа для типа меток, подпрограммы и функции для типов перечисления. 2 Сложные типы данных SystemVeniog: Arrays, Structures и Unions" струкгуры (Structures) - создание определенных пользова!елем сф^ктур, упакованные сгрук!уры. объединения (union) - упакованные объединения, пример использования структур и объединений, массивы фиксированного размера - декларация и инициализация, базовые операции массивов (for и foreach), базовые операции массивов (сору и compare), упакованные массивы (Packed arrays); назначение упакованных массивов: пример использования массивов, динамические массивы, очереди - методы очередей, параметризируемая память FIFO, ассоциативные массивы, методы ассоциативных массивов, связанные списки (Linked Lists) методы массивов - методы редукции массивов, методы местоположения. 3. Процедурные блоки, задачи и функции; Void функции; процедурные операторы и подпрограммы; операторы перехода - значения временных параметров. Finite State Machines, SystemVeniog иерархия проекта - прототип модуля, соединение портов, псевдонимы цепей, передача данных через порты модуля, ссылочные порты (Reference ports), параметризированные типы данных примеры использования интерфейсов и памяти, основы ООП - первый класс, место определения классов, ООП терминология, создание новых объектов; блоки синхронизации моделей и тестовых последовательностей
270 (Stimulus Timing), блок clocking: объединение блоков, пример Four-Port А ГМ Router; SystemVenlog Assertions - прямые (процедурные) ассерции, параллельные ассерции: создание случайных значений (Randomization), простейший класс с псевдослучайными переменными Источники: синтез, моделирование и верификация гетерогенных компонентов цифровой аппаратуры с помощью языковой среды SystemVenlog [5-8]; синтаксические и семантические особенности языка описания SystemVenlog [1-4. 9]; стандарт языка описания аппаратуры SystemVcrilog и его использование в технологических процессах EDA [1-1111]. Язык SystemVenlog особенно актуален в настоящее время, когда аппаратная реализация идеи для рынка электронных технологий представляется более предпочтительной. Свидетельством тому может служить опубликованная в журнале I£E Times [2009, December] топ десятка or Gartner Research Group (Gary Smith) наиболее актуальных технологий 1 Биологическая обратная связь или электроника, управляемая мыслью. 2 Печатная электроника на основе использования органических материалов. 3. Пластиковая память на основе полимеров, проявляющих ферроэдектриче- ские свойства. 4. Безмасочная литография на основе использовании электронного пучка для создания топологии схемы. 5. Параллельная обработка данных для многоядерных гетерогенных графических процессоров. 6. Сбор энергии от механических, электромагнитных и электрических процессов в окружающей среде. 7. Биоэлектроника и vvetware - сочетания биологических объектов и электроники для медицины. 8. Резистивное ОЗУ или мемристор, который демонстрирует эффект памяти и является четвертым пассивным элементом электронной схемы, наряду с резистором, конденсатором и индуктивностью. 9. Переходные отверстия в кремнии (fhrough-Silicon-Via - TSV) для создания реальных 3D-SiP и кристаллов. 10. Различные технологии изготовления батарей на основе никеля и лития. В топ-десятке нашли отражение только технологии, связанные с разработками на аппаратном уровне, хотя развитие программных технологий также будет оказывать существенное влияние на состояние рынка электроники. Глобально важными остаются технологии снижения потребляемой мощности и применение решений, направленных на уменьшение содержания ценных материалов в продукте Эти технологии выступают двигателями многих направлений развития электроники, связанных с человеческой деятельностью.
271 15. ТИПЫ ДАННЫХ SYSTEM VERILOG 15.1. Пространства для декларации объектов в SvstemVerilog 15.1 1. Пакеты Verilog позволяет определять переменные только внутри модуля или блоков (begin-end и fork-jom). В SysteraVeniog введены пакеты, имеющие аналоги в VHDL Пакеты в SystemVerilog определяются между ключевыми словами package-endpackage, могут включать синтезируемые конструкции, описание которых можег быть включено в пакет. 1) Определение параметров parameter и iocalparam. Параметр может быть переопределен, локальный параметр нет. Однако в пакете не допускается переопределение параметров, и в этом случае parameter и Iocalparam становятся синонимами. 2) Определение констант const. 3) Определенные пользователем типы данных typedef 4) Определение автоматических задач и функций (task и function). 5) Операторы импорта из других пакетов import 6) Определение перегрузки операторов Пакет может также содержать глобальные переменные, определения статических переменных и функций. Однако эти конструкции не синтезируемы. Пакет яв;1яетея независимым декларативным обьекгом и никогда не записывается внутри модуля Пример описания пакета представлен листингом 15 S. В нем используются новые типы данных, которые подробно будут рассмотрены далее 1) logic - 1-битовая переменная, имеющая 4 состояния, подобная типу reg языка Venlog, может быть испоаьзована для создания вектора любого размера; 2) enum - тип перечисления, представляющий собой множество меток; 3) typedef- определенный пользователем тип данных, создаваемый из встроенных и пользовательских типов тайных; 4) struct - коллекция переменных, к которым можно обращаться по отдельности и всем вместе. Листинг 15.1. Определение пакета package definitions, parameter VERSION = "1 '.", typedef enum {ADD, SUB, MUL} opcoaesj, typedef struct { logic [31 0] a, b, opcodes_t opcode, } instructionj, function automatic [31 0] multiplier (input [31.01 a, fa}, // code for a custom 32-bit multiplier goes here return a * b, // abstract multiplier (no error detection) endfunction endpackage Обращение к объектам пакета в модуле может быть выполнено через-
272 1) прямую ссылку, с помощью оператора области винимоеги (scope resolution( •) (листинг 15.2). 2) импорт элементов пакета в модуль или интерфейс (листинг 15 3), 3) групповой импорт элементов пакета в модуль или интерфейс (импортируются только используемые элементы) (листинг 15 4); 4) декларативное пространство Sunit. Листинг 15.2. Использование оператора области видимости module ALU (input definitions::instruction_t IW, input logic clock, output logic [31 0] result), al'Aays_ff @(posedge clock) begin case (IW opcode) definitions ADD result = IW а т !W b, definitions SUB result = IW a - IW b, definitions MUL result = definitions multiplier(iW a, IW b), endcase end endmodule Листинг 15.3 Импорт отдельных элементов // Импортирование для определения типов портов не допускается module ALU (.nput defmitions::instruction_t IW, input logic clock, input logic [31 0] result), import definitions ADD, import definitions SUB, import definitions-MUL, import definitions multiplier, always_comb begin case (IW opcode) ADD . result = IW a + IW b, SUB result = iWd-IW.b, MUL result = multiplior{IW a, IW b), endcase endmodule Листинг 15.4. Групповой импорт элементов module ALU (input definitions instruction J IW i^put logic clock, output log'c [31 Oj result), import definitions::*, // wildcard import always_comb begin case (IW.opcode)
273 ADD result = iW a + IW b, SUB result = IW a - IW b, MUL result = multiplier(IW a, IW b), endcase endrnodule 15.1 2 Понятие единицы компиляции. SystemVeniog вводит концепцию, называемую единицей компиляции (compilation unit), которая составляется из всех файлов, компилируемых в одно и го же время. Единица компиляции представляет собой средство для независимой компиляции блоков, составляющих целый проект SystemVeniog позволяет выполнять декларацию за границами пакета, модуля, интерфейса или программы. Гакая внешняя декларация является compilation-unit scope (область видимости единицы компиляции) и ее элементы доступны во всех модулях, декларируемых в то же самое время Область видимости единицы компиляции может включать 1) декларации единиц измерения и точности временных параметров; 2) декларации переменных, цепей и констант, 3) определенные пользователем типы данных, созданные с помощью конструкций typedef, cnum или class; 4) определения задач и функций. Пример из шсгинга 15.5 иллюстрирует использование внеи/них деклараций констант, пользовательского типа и функции. Данный код является несинте- зируемым Листинг 15 5. Внешние декларации в об пасти единиц компиляции // Внешняя декларация parameter VERSION = "1 2а", // внешняя константа i eg resetN = 1, // внешняя переменная (активная при 0;) typedef struct packed { // внешний, определенный пользователем тип reg [31 0] address, reg [31 0] data, reg [ 7 0] opcode; } instruction^ word_t, function automatic int log2 (input int n), // внешняя функция if(n<=1)retum(1) log2 = 0, while (n> 1) beg'n n = n/2, iog2++, end return(iog2), endfunction // Определение модуля
274 // внешние декларации используются для определения типов портов module register (output instruction word_t q, input instruction_word_t d, input wire clock), always @(posedge clock, negedge resetN) if (iresetN) q <= 0, // Использование внешнего сигнала сброса else q <= d endmoduie Нежелательно выполнять декларации в области видимости единиц компиляции Все декларации следует делать в пакетах, имеющих индивидуальные имена, а в области видимости выполнять импортирование эгого пакета Внешнее декларирование может быть использовано для упрощения описания портов модуля ALU из примера, представленного листингом 15 4, как показано в листинге 15.6 Листинг 15.6 Импорт пакета через декларативное пространство Sunit import definrtions::mstruchon_t module ALU (input instruction^ IW, input logic clock, output logic 131 0] result ). или //Символ группового импорта элементов пакета import definitions::* module ALU » ' (input instaiction_t IW /! input logic clock, output logic [3! 0] result ). 15.2. Единицы времени и точность их вычисления В Verilog при описании временных параметров в модели единицы измерения времени не указывались. Для их определения использовалась директива 'timescaie В этом случае величина задержек модулей, не имеющих директивы 'timescale, зависела от порядка компиляции файла (рис 15.1) В следующем примере задержка модуля В будет равна 5 ns или 5 ms. System Verilog разрешает указывать единицы измерения вместе с величиной задержки: forever #5ns clock = -clock, Определенные стандартом единицы измерения представлены табл 15.1. Не допускается ставить пробел между величиной задержки и единицами измерения: #3 2ps // legal #4 1 ps // illegal no space allowed
SystemVerilog разрешает выполнять объявление единиц измерения и точности временных параметров локально для каждого модуля, интерфейса или программы Например. module chip ( ), tirneunit 1 ns, timeprecision 10ps, 'timescaie 1ns/1ns module A ( ), nand#3(. ), endmodule module В ( ), nand#5( ), endmodule 'timescaie 1ms/1msj module С { ), nand #2 {...), endmodule [File В I compilation order 'timescaie 1ns/1ns module A ( .), nand#3( ), endmodule 'timescaie 1ms/1ms| module С ( .}; nand #2 ( }■ endmodule module В ( ), nand #5 ( ), endmodule Module В delays are in nanoseconds Module В delays are in milliseconds Рис 15 1 Зависимость единиц времени oi порядка компиляции модулей Таблица 15.1 Единицы измерения времени в System Venlog Unit s ms us пь ps fs step Description seconds milliseconds microseconds nanoseconds picoseconds femtoseconds the smallest unit of time being used by the software tool (used in SystemVerilog testbench clocking blocks) Как и для директивы 'timescaie, единицы измерения могу! быть представлены в масштабе 1, 10 ичи 100 Описание выполняется сразу по перед всеми осташными операторами' module adder (input wire [63 0] a, b, '" output reg [63-0] sum, outout reg carry);
timeunit 1ns, timeprecision 10ps; endmodule 15.3. Новшества в описании символьных значений В языке Verilog следующие операторы используют операции дополнения до 1 (ones complement operator) и до 2 (two's complement operator) для заполнения вектора единицами: data = -0, // обратный код data = -1 // дополнительный код В System Verilog для заполнения векторов значениями предлагаются специальные символы 1) '0 заполняет все биты с левой стороны 0; 2) '1 заполняет все биты с левой стороны 1; 3) V или 'Z заполняет все биты с левой стороны 7, 4) 'х или 'X заполняет все биты с левой стороны х. 15 3.1 Описание типов данных. В System Verilog введены следующие новые типы данных: 1) С двумя состояниями (ключевое слово bit): лучшая производительность, минимизация использования памяти 2) Очереди (Queues), динамические и ассоциативные массивы (dynamic и associative arrays), автоматическая память (automatic storage)" минимизация использования памяти, встроенная поддержка поиска и сортировки 3) Объединения (Unions) и пакеты (packed): предлатают множественное представление одних и тех же данных. 4) Классы и структуры (Classes и structures), поддерживают структуры абстрактных данных. 5) Строка (Strings) встроенная поддержка строк 6) Типы перечисления (Enumerated types): упрощение записи и анализа кода. 15 3.2 Встроенные типы данных Venlog-1995 содержит два класса типов данных: переменные (register) и цепи (net), которые содержат переменные четырех состояний: 0, 1, Z и X Код RTL использует переменные для сохранения комбинационных и последовательных значений. Переменные могут быть беззнаковые (rcg [7-0] m). знаковые 32-битовые переменные (integer), беззнаковые 64-битовые перемен- Hbie(time), с плавающей точкой (real). Переменные могут группироваться в массивы фиксированного размера. Вся память является сташческой, и подпрограммы не используют стек для хранения аргументов и локальных зна-
277 чений Цепи (net) применяются для соединения частей проекта, таких как вентильные примитивы и копии модулей SystemVenlog добавляет много новых гипов данных для проектирования и верификации аппаратуры 15 3.3 Типы цепей (Net Types) Venlog позволяет использовать переменные типа цепи без их декларации Однако это свойство может привести к трудно обнаруживаемым ошибкам. В Venlog-2001 появилась возможность с помощью директивы 'default jiettype none выполнять блокирование декларации типов данных цепи по умолчанию: defau!t_nettype none module first, 15.4. Логические типы В SystemVenlog расширили возможности типа данных reg, он теперь может получать значения в операторе непрерывного присвоения (continuous assignments), точно так же, как и типы данных цепи. Также он может быть неременной Такой модифицированный гип получил название logic: logic resetN, // 1-битоазя переменная с 4 состояниями logic [63"0] data, // 64-битовая переменная logic [0 7] array [0 255] // массив из 256 8-битовых переменных Единственное смраничение, введенное для типа logic он не можст управляться несколькими драйверами, которые использукнся для создания моделей двунаправленных шин В этом случае следует применять тип данных класса цепи, например wire Модуль из листинга 15.7 представляет пример использования типа данных logic. Листинг 15 7. Использование типа данных logic module iogic_data_type(input logic rst_h) parameter CYCLE = 20 logic q, qj, d, elk, rstj, initial begin elk <= 0, // Procedural assignment forever #{CYCLE/2) elk = -elk- end assign rstj = ~rstJ>, // Continuous assignment not n1{qj, q), // qj ,s driven by gate my_dff dlvq, d, elk, rstj), // d is driven by module endmodule 15.5. Типы данных с двумя состояниями Типы введены для повышения производительности процесса моделирования и минимизации применения памяти по сравнению с типами, имеющими 4
278 состояния. Они могут быгь использованы для описания моделей системного уровня и уровня транзакций. Определены следующие тпы. 1) bit- 1-битовый целочисленный тип с 2-мя состояниями, 2) byte - 8-битовый целочисленный тип с 2-мя состояниями, подобный типу char в Си; 3) shortmt 16-битовый целочисленный тип с 2-мя состояниями, подобный типу short в Си; 4) mt - 32-битовый целочисленный тип с 2-мя состояниями, подобный типу int в Си, 5) longmt - 64-битовый целочисленный гип с 2-мя состояниями, подобный типу long в Си. Самый простой из типов с 2-мя состояниями - беззнаковый тип bit Остальные 4 типа- byte, shortmt, int и longint являются знаковыми. Листинг 15 8. Типы данных с двумя состояниями bit о, // 1 бит с 2-мя состояниями bit [31 Oj Ь32, // 32-битовое беззнаковое целое число int i // 32-битовое знаковое целое число byte Ь8, // 8-битовое знаковое целое число shortmt s, //16-битовое знаковое целое число longmt I, // 64-битовое знаковое целое число Следует быть внимательным с попыткой замены выражения logic [7 0] на более короткое byte, поскольку первое из них беззнаковое, а второе - знаковое Таким образом, максимальное положшспьное число для объекта типа byte будет 127, а не 256. Нужно быть осторожным при соединении cm налов (особенно выходов) DUT с сигналами, имеющими два состояния Рекомендуется использовать оператор Sisunknown, возвращающий I в случае, если выражение равно X hjihZ. if (Sisunknownfiport) $display("@%Oa 4-state value detected on input port', Stime, iport;, Типы с двумя состояниями Motyr быть использованы в ситуации, когда нет необходимости в подробной детализации с помощью 4-х состояний. Например, для описания индексации в цикле for Даже в моделях RTL-уровня эта переменная не присутствует в реальной аппаратуре logic [7 0] busA, // переменная с 4-мя состояниями bit [31 0] busB, // переменная с 2-мя состояниями SystemVenlog предлагает возможносгь применения необязательного слова var перед описанием типа данных. Например: var logic [7 0] а, // 8-битовая переменная с 4-мя состояниями var bit [31 0] b, // 32-буповая переменная с 2-мя состояниями var int i // 32-битовая переменная с 2 состояниями
279 Слово var не виияет на моделирование, а делает код более читабельным- typedef enum bit {FALSE, TRUE} boolj, var boo!_t c, // variable of user-defined type По умолчанию использование ключевого слова var подразумевает тип logic. var [7 0] d, // 4-staie 8-bit variable Преобразование значений 4 состояний в значения 2 состояний приведено в табл 15 2. Таблица 15 2. Преобразование значений Значения 4 состояний 0 Z X Значения 2 состояний 0 1 0 0 Листинг 15.9 иллюстрирует использование переменных в моделях SystemVeriiog Листинг 15.9 Использование переменных module compare (output logic It, eq, gt, input logic [63 0] a b ), always @(a, b) if (a < b) It = 1'M, // Процедурное присвоение else It = 1"b0 assign gt = (a > b), // Непрерывное присвоение comparator ul (eq, a, b) // Создание копии модуля endmodu'e module comparator (output logic eq, input [63-0] a, b), always @(a, b) eq = (a==b), endmodule Гипы данных byte, shortmt, mt и longmt в SystemVenlog являются знаковыми Их можно преобразовать в беззнаковую форму с помощью ключевого слова unsigned: nt sjnt, // 32-битовая знаковая переменная mt unsigned ujnt // 32-битовая беззнаковая переменная 15.6. Строки Строковый тип данных string в SystemVeriiog поддерживает создание строк переменной длины. Каждый символ имеет тип byte Элемешы строки нумеруются начиная с нуля, строка длиной в N элементов будет иметь индексы 0 . N-1. Строки не содержат символ конца строки Для них используется динамическое выделение памяти. Расширены возможности оператора конкатенации для работы со строками Он может быть использован для объединения нескольких строк в сдау: string sv = "SystemVeriiog', stnng s,
280 s = {sv,"", "is easy"}, Sdisplay ("%s\n", s), // вывод строки «SystemVenlog is easy» s = {s,", enjoy"}, Sdisplay (' %s\n", s), // вывод строки «SystemVenlog is easy, enjoy» Методы и задачи System Verilog для работы со строками 1) getc(N) - возвращает значение с позиции N, 2) toupper - возвращает копию строки в верхнем регистре; 3) tolower - возвращает копию строки в нижнем pei истре, 4) фшурные скобки {} используются для операции конкатенации, 5) задача putc(M) записывает в строку в позицию М, которая для строки в N элементов можег принимать значение от 0 до N-1, 6) len - возвращает длину строки; 7) функция ^ubstr(start,end) извлекает символы из позиций от start до end Листинг 15.10 представляет использование операций над строками Листинг 15.10. Применение методов строк string s, initial begin = "SystemVenlog", display(s getc(0)), // Выводится «33 ('S> display(s.toupperO), // Выводится. «SYSTEMVERILOG» = {s, "3 1b"}, // «SystemVerilog3 lb» putc(s Ien()-1, "a"), // Замена символа b на а display(s substr(2, 5)}, // Выводится «stem» // Создается временная строка yJog(Spsprmtf("%s %5d', s, 42)), end task my_log(string message) // Выводится сообщение на консоль или в log-файл display{"@%0d %s", Stime, message), endtask Вместо функции Ssformat из Venlog-2001 может быть испочьзована функция Spsprmtf. Она возвращает форматированную временную строку, которая непосредственно может быть передана в другую функцию. 15.7. Другие абстрактные тины данных System Verilog Язык SystemVenlog также позволяет использовать дополнительные абстрактные типы данных. 1) void - означающий отсутствие сохранения, используемый для типа данных union и функций, которые не возвращают значений, 2) shortreal - короткое вещественное значение, имеющее длину 32 бита, в ог- личие от 64-битового типа real, который не является синтезируемым В Venlog-95 все переменные были статические, в Venlog-2001 появились автоматические переменные для функций и задач (листинг 15 II). В SystemVenlog можно явно объявлять переменные как сташческие (static)
281 (листинг 15.12) или автоматические (automatic) Такие описания являются частью декларации переменной и могут быть использованы в задачах, функциях, блоках begin .end и fork...join. Такие определения нельзя сделать на уровне модуля, все переменные на уровне модуля являются статическими. Листинг 15 11 Использование автомагических переменных в функции function int count_ones (input [31 0] data), automatic logic [31 0] count = 0, automatic logic [31 Oj temp = data, for (int i=0, i<=32, i++) begin if (temp[0]) count++ end return count, endfunction Листинг 15.12. Использование статической переменной в авюматнческой функции typedef struct pacKed { } packet_t, task automatic check_resuits (input packet J sent, received), output int totaLerrors), if (sent '== received) error_count++, totai_errors = error_count- ppdtask В SystemVeniog допускается инициализация значений в переменной вместе с декларацией как переменных модулей (разрешено и в Veniog), так и переменных функций и задач (в Veriiog запрещается) Однако окне конструкции не являются синтезируемыми Правила использования статических и автоматических переменных. 1) В блоках initial и always используются статические переменные, если они не имеют инициализации при декларации, и автоматические - в противном случае Такие переменные будут повторно инициализированы при каждом вызове блока 2) Если функции и задачи вьпьшаются несколько раз. то они должны быть автомагическими Переменные должны быть автоматическими, если только нет причины сохранять значение переменной между различными вызовами. Например, как для переменной, хранящей число вызовов процедуры. 3) Если задача или функция моделирует фрагмент аппаратуры, то они и их переменные должны быть объявлены как статические. 15.8, Преобразования типов В Venlog-2001 знаковое-беззнаковое преобразование типов выполнялось с помощью системной функции $signed и Sunsigned В System Veniog расши-
282 рены возможности преобразования значений между различными типами данных 1. Синтаксис преобразования типов в SystemVcnlog <type>'(<expression>) — преобразование значений в любой тип, включая пользовательские типы данных Например: 7+ int (20*3 0), // Значение (20*30) преобразуется в int и затем суммируется с 7 2 Синтаксис преобразования размеров в SystemVeniog <size> (<expression>) — преобразование значения в вектор указанной длины Например logic [15 01 а Ь, у, у = а + b**16'(2), // cast literal value 2 to be 16 bits wide 3 Синтаксис преобразования знака в System Veniog- <sign> (<expression>) — casts a vaiue to signed or unsigned Например shortint a, b, у = у - signed'({a,b}), // cast concatenation result to a signed value Поскольку операция преобразования типа относится ко времени компиляции, а реальное присваивание происходит в момент моделирования, то проверка совместимости типов и данных не выполняется. Для осуществления такой проверки в динамическом режиме может быть использована системная задача Scast, принимающая два аргумента переменная назначения, переменная источника Ее синтаксис $cast(dest_var, source_exp), Например- snt radius, area, always @(posedge clock) $cast(area 3 154 * radius ** 2) // В итоге результат операции // cast вещественное значение преобразуется в целое Ошибки, которые moivt. возникнуть в результате преобразования типов 1) присвоение вещественного числа целому, если первое больше разрядной сетки второго; 2) преобразование в тип перечисления, ко!да значение данного типа не существует. Например, при моделировании кода может возникнуть ситуация, typedef enum {S1, S2, S3} statesj, states_t state, next_state, aiwaysjatch begin Scast(next_state, state +1), end Scast может быть использована в формате системной функции typedef enum {S1, S2, S3} statesj, statesj state, next_state,
283 int status, always_comb begin status = $cast(next_state, state + 1), if (status == 0) // if cast did not succeed next_state = S1, end Системная задача/функция Scast не поддерживается синтезом. 15.9. Размер выражений Размер выражений определяется исходя из размеров операндов В примере (листинг 15.13) выполняется операция 1 И с использованием различных стилей Сумма А получена сложением двух однобитовых переменных, с такой точностью операторов 1+1=0. В сумме В использована 8-битовая точность операндов, поэтому результат будет также 8-битовый В этом случае 1+1=2 Сумма С применяет фиктивную константу, что приводит к использованию двухбитовой точности В последней сумме D первый операнд представляет собой приведение к двухразрядному значению, таким образом, 1+1=2 Листинг 15 13 Зависимость разрядности выражения от контекста bit [7 0] Ь8, bit one = 1'Ы,'/ Single bit $displayb(one + one), //A 1+1=0 b8 = one + one,//В 1+1 =2 $disp!ayb(b8) $displayb(one + one + 2 ЬО), // С 1+1=2 with constant Sdispiayb{2'(one) + one), // D 1+1=2 with cast Существует нескочько способов избежав проблемы потери значений. Во- первых, исключить ситуации, когда может потеряться перенос, как в сумме А Использовать временные переменные, как, например. Ь8, для того чтобы достиг нуть нужной разрядности результата. Также для этого может быть использован дополнительный операнд, как 2'ЬО. Последний способ - в SystemVenlog можно применить операцию приведения для получения операнда нужной разрядности. 15.10. Константы В Venlog существует три вида констант: 1) paiameter - константы, значение которых может быть переопределено в момент элаборации с помощью оператора defparam или при прямом переопределении; 2) specparam, значение которого может быть переопределено в момент элаборации значениями из файла SDF; 3) locaSparam - константы времени элаборации, которые не могут быть непосредственно изменены, но их значение может зависеть от значения других констант.
284 SystemVerilog позволяет определить любую переменную в качестве константы с помощью ключевого слова const Гакие константы получают значения после этапа элаборации и обладают следующими свойствами: 1) могут быть декларированы в динамических контекстах, таких как автоматические задачи и функции, 2) могуг получать значения переменных и линий, а не только константных выражений, 3) могут получать значения элементов, обьявленных в любом месте иерархии проекта Декларация констант const должна содержать декларацию типа данных Например: const logic [23 0] C1 = 7, // 24-битовая константа const int C2 = 15, // 32-битовая константа const real СЗ = 3 14, // Вещественная константа const C4 = 5, // Ошибка, тип не указан task automatic С, const int N = 5 // N - константа endtask В следующем примере инициализация colon выполняется при входе в блок initial- initial begin const byte colon ="", 15.11. Пользовательские типы данных (User-defined types) В SystemVerilog пользовательские типы данных определяются с помощью ключевого слова typedef. После определения новый тип может быть использован для создания переменных. Новый тип данных может быть задан локально в модуле, в пакете или в области видимости единицы компиляции. В следующем фрагменте кода определен пользовательский тип данных nibble, который используется при декларации переменной в модуле alu Поскольку nibble объявлен локально, его область видимости ограничивается только модулем altr module alu { ), typedef logic [3 0] nibble, nibble opA, opB // переменная типа nibble nibble [7 0] data, // 32-битовый вектор, созданный из // 8 элементов типа nibble endmodule
285 Можно создать модель ALU, которая в процессе компилирования будет сконфигурирована для работы с 8, 16, 24 или 32-битовыми операндами В языке Verilog это можно реализовать с помощью макроса (листинг 15 14). Листинг 15 14. Определенные пользователем типы данных в Venlog // Old Venlog style 'define OPSIZE 8 define OPREG reg fOPSIZE-1 Oj OPREG op_a, op_b, При этом реальный тип данных не создается, выполняется только замена одного текста на другой. System Venlog позволяет создавать новый тип данных (листинг 15 15). Листинг 15 15 Определенные пользователем типы данных в System Venlog /' New SystemVenlog style parameter OPSIZE = 8, xypedef reg [OPSIZE-1 0] opreg_t, opreqj op_a, odJd, Одним из наиболее полезных типов данных может быть беззнаковое целое с двумя значениями. Большинство значений в testbench являются положительными целыми числами, например, длина поля или количество полученных транзакций Разместив следующее определение uint в $root, можно получить возможность его использования в любом месте при моделировании tvpeaef bit [31 0] uint // 32-битовый беззнаковый с 2 состояниями typedef int unsigned uint, // Эквивалентное предыдущему определение 15.12. Совместно используемое определение типа typedef Естн необходимо, чтобы пользовательский тип был виден в нескольких модулях, то он определяется в пакете чли в единице компиляции Листинг 15.16 иллюстрирует создание пользовательского типа данных dtype_t в пакете. При этом применяется условная директива компиляции 'ifdef. которая позволяет определить тип данных dtype_t с помощью типа данных с 2-мя состояниями bit или типа данных с 4-мя состояниями logic. Листинг 15 16. Прямое обращение к шпу данных из пакета package chipjyoes, ifdefTWO_STATE typedef bit dtypej, else typedef logic dtypej, endpackage module counter (output chip_types::diypej [15 0] count, input chip_types--dtype_t clock, resetN}, always @(posedge clock negedge resetN)
286 if ('resetN) count <= О, else count <= count + 1, endrnodule Выражение для импортирования пакета можно разместить в пространстве единицы компиляции Sunit. Это удобно, когда большое количество портов определено с помощью пользовательского типа данных (листинг 15.17). Листинг 15.17 Импортирование определений пакета в пространство единицы компиляции Sunn package chipjypes, ifdefTWO_STATE typedef bit dtypej, 'else typedef logic dtype_t, endif endpackage import chip_types::dtype_t, // import definition into $>jnit module counter (output dtypej [15 0] count, input dtype_t clocK resetN), always ©(posedge clock, negedge resetN) if (i resetN) count <= 0, else count <= count + 1, endrnodule Если пакет содержит много определений пользовательских типов, можно применять специальный групповой символ: import chip_types *, // Групповой импорт 15.13. Типы перечисления Перечисление - это тип данных, который представляе! собой ограниченное множество специальных имен, таких как команды или состояния автомата Использование таких типов упрощает чтение кода. Простейшая декларация типа перечисления содержит список имен и одну или несколько переменных Таким образом, создается тип данных без имени. enum {RED, ВШЕ, GREEN} color С помощью typedef может быть создан именной гип перечисления (листинг 15 18). Листинг }5 18. 1ины перечисления // Создание типа данных для значений 0 1,2 typedef enum {INIT, DECODE, IDLE} fsmstate_e, fsmstaSe_e pstate, nstate, // declare typed variables initial begin case (pstate) IDLE nstate = INIT, // data assignment INIT nstate = DECODE,
287 default nstate = IDLE, endcase Sdisplay("Next state is %0s", nstate name), // Use name function end 15.13.1. Определение значений типов перечисления. Реальные значения соответствуют последовательности неогрицательных целых чисел, начиная с 0. Также элементам типа перечисления могут быгь присвоены любые произвольные значения. В следующем примере назначены: 0 для INIT, 2 для DECODE и 3 для IDLE" typedef enum {INIT, DECODE=2 IDLE} fsmtype_e, Константы перечисления, такие как INIT из предыдущего примера, используют те же правила видимости, что и переменные. Соотвеиственко, если используются одни и те же имена в нескольких типах перечисления (например, INIT в различных управляющих автоматах), они должны декларироваться в различных областях видимости, таких как модули, блоки программы, подпрограммы или классы. Метки типов перечисления хранятся как mt, если их тип не задан другим способом. Нужно быть осторожным при присвоении значений константам типов перечисления, гак как по умолчанию int получает значение 0. В примере (листин! 15.19, a) position инициализируется в О, чго не разрешено для переменной ordmal_e Такое поведение не является ошибкой среды - оно соответствует спецификации языка 1аким образом, следует всегда описывать константы типов перечисления со значением О (листинг 15 19, б), чтобы иметь возможность обнаружения этой ошибки Листинг 15 19 Примеры типов перечисления а }// Неправильное описание значений типов перечисления typedef enum {FRST=1, SECOND, THIRD} ordinal_e ordinate position, б) //Правильное описание значений типов перечисления typedef enum {ERR_O=0, FIRST=1, SECOND, THIRD} ordmal__e, ordinaire position, Листинг 15 20 представляет пример использования типа для определения состояний автомата Специальные процедурные блоки alwaysJT и always_comb, использованные в примере, будут рассмотрены далее Листинг 15.20. Использование типа перечисления для описания состояний управляющего автомата package chip_types, typedef enum {FETCH, WRITE, ADD, SUB, MULT, DIV, SHIFT, NOP } instr_t, endpackage import chip_types .*, // import package definitions into $unit module controller (output logic read, write, .nput instrj instruction, input wire clock resetiM), enum {WAITE, LOAD, STORE} State, NextState, always__ff @(posedge clock, negedge resetN)
288 if (!reseti\l) State <= WAITE else State <= NextState, always_comb begin case (State) WAITE NextState = LOAD, LOAD NextState = STORE, STORE NextState = WAITE, endcase end always_comb begin read - 0, write = 0, if (State == LOAD && instruction == FETCH) else if (State == STORE && instruction == WRITE) endmoduie 15 13.2. Последовательности меток в типе перечисления В дополнение к описанию множества и уникальных меюк SystemVenlog предлагает два упрощенных способа создания диапазона меток в типе перечисления (табл 15 3). Таблица 15 3. Описание последовательности меток типа перечисления state state [N] statcfN M] Создание одной метки с именем state Создание последовательности меток с именем stateO, statel,..., statcN-1 Создание последовательности меток, начинающихся stateN и заканчивающихся staicM Если N меньше М, последовательность будет увеличиваться от N до М Если К больше М, последовательность будет уменьшаться о г N до М Пример использования возможностей SystemVenlog для описания меток типа перечисления, enurn {RESET, S[5], W[6 9]} state, В данном случае переменная state может принимать одно из следующих значений: RESET, SO, SI, S2, S3, S4, W6, W7, W8, W9. 15.13 3. Задание базового типа для меток. Типы перечисления являются переменными или цепями с множеством значений меток По умолчанию базовым типом для перечисления является int (32-битовый с 2-мя состояниями). Для более детального представления аппаратуры разрешается явно задавать базовый шч для перечислений Например: //тип перечисления с 1- разрядным кодированием меток
289 // типом с 2-мя состояниями enum bit {TRUE, FALSE} Boolean, //тип перечисления с 2-разрядным кодированием меток // типом с 4-мя состояниями enum logic [1 0] {WAITE, LOAD, READY} state, Если метки mna перечисления имеют явное присвоение значений, их размер должен совпадать с размером базового типа: enum logic [2 0] {WAITE = 3'b001, LOAD = З'ЬОЮ, READY -= З'ЫОО} state Будет ошибкой присвоить метке значение, отличающееся по размеру от базового типа, как это сделано в следующем примере: enum {WAITE = 3,b001, //ОШИБКА' LOAD = 3 Ь010, READY = З'М 00} state, или же описать больше меток, чем может быть представлено базовым типом: enum logic {А=1'Ь0, В, С} Iist5, // ОШИБКА слишком много меток // для однооазрядного кода Если базовый гип имеет 4 значения, ю можно использовать для присвоения значения X или Z для меток перечисления, enum logic {ON=1'M, OFF=1'bz} out, При кодировании метки с применением значений X или Z следующая метка должна иметь явно заданный код. enum logic [1 0] {WAITE, ERR=2'bxx, LOAD, READY} state, // ОШИБКА Не определено значение для LOAD Гип перечисления может быть определен с помощью конструкции typedef (типизированный тип перечисления - typed enumerated type) - это дает возможность декпарировать с помощью такого типа несколько переменных. Иначе, тип перечисления является анонимным (anonymous enumerated type): tvpedef enum {WAITE, LOAD, READY} statesj, statesj state, next_state, 15.13.4 Подпрограммы и функции для типов перечисления SystemVerilog предлагает несколько методов для работы с элементами типов перечисления 1) first возвращает первый элемент; 2) last возвращает последний элемент, 3) next возвращает следующий элемент; 4) next(N) возвращает N следующих элементов; 5) prev возвращает предыдущий элемент; 6) prev(N) возвращает N предыдущих элементов. Функции next и prev идут по кругу, когда они достигают конца последовательности эчементов перечисления. Нет простого способа, чтобы выполнить перебор всех элементов типа перечисления в цикле for. Первый элемент может быть получен с помощью функции first, а следующие - с помощью функции next Проблема возникает
290 в определении последнею элемента последовашльносги Если использовать currentl-current last, то цикл завершится, не достигнув последнего элемента Использование выражения: current<=current last, приведет к созданию бесконечного цикла, так как функция next никогда не вернет значение, превышающее постеднее в последовательности. Для перебора значений может быть использован цик.1 do. .while, как это показано в примере из листинга 15.21. Листинг 15.21 Перебор всех элементов типа перечисления enum {RED, BLUE GREEN} color, color = color.first, do begin $display("Coior = %0d/%0s", color, color name), color = co'or next end while (color '= color first), /' Done at wrap-around Поскольку по умолчаьию метки типа перечисления представлены типом mt (2 значения), то значения переменных типов перечисления могу! быть присвоены переменным типов integer или mt. Однако не разрешается в SystemVenlog сохранять 4-значные integer в enum без выполнения преобразования типа. SystemVenlog требует явного приведения типа, чтобы исключить случайное присвоение значения, выходящего за границы типа (лиаинг 15.22) В примере функция Scast пытается выполнить присвоение правого значения в освую переменную Если присвоение выполнено успешно, го функция Scast возвращает 1, иначе 0 Листинг 15 22. Назначения между типами integer и перечисления typedef enurn {RED BLUE, GREEN} COLOR_E, COLOR_E color, c2, initial begin с = color, /' Преобразует из типа enum в integer C++, // Инкремент integer if {'$cast{color, с)) // Преобразование integer обратно в enum SdisplayfCast failed for c=%0d", c), Sdisplayf'Color is %0d / %0s", color, color name\ c2 = COLOR_E'(c), // Без выполнения проверки типа end Можно для преобразования типов использовать выражение type'(val), однако при этом не выполняется никакой проверки, таким образом, результат может выходить за допустимые границы. Данный стиль не рекомендуется использовать Листинг 15.23 иллюстрирует использование управляющего автомата с последовательностью состояний, которые могут быть перебраны с помощью
291 описанных выше функций. Пример представляет простейший скрытый счетчик, где: 1) выход m_sync изначально равен 0, когда счетчик достигает значения 8, in_sync устанавливается в 1; 2) если входы флагов compare и synced имеют значение false, то счетчик сохраняет текущее значение. 3) если флаги compare и synced имеют значение true, то счетчик увеличивается на 1. но не может быть больше 15; 4) если флаг compare имеет значение true, но флаг synced равен false, счетчик уменьшается на 2, но не может быть меньше О Листинг 15 23. Использование специальных методов для перемещения по списку типа перечисления module confidence__counter{mput logic synced, compare, resetN, clock, output logic m_sync) enum {cnt[0-15]} State, Next, always_ff @(posedge clock, negedge resetN) if (iresetN) State <= cntO, else State <= Next, always_comb begin Next = State // default NextState value case (StatP) cntO if (compare && synced) Next = State next cntl begin it (compare && synced) Next - State next, if (compare && 'synced) Next = State first, cnt15 (f (compare && 'synced) Next = State prev(2), default begin if (compare && synced) Next = State next, if 'compare && 'synced) Next = State prev(2), endcase end alwaysjf @(posedge clock, negedge resetN) if ('resetN) in_sync <= 0, else begin if (State == cnt8) injsync <= 1, if (State == cntO) in_sync <= 0, endmodule На печать может выводиться метка типа перечисления, или ею значение (листинг 15.24) Листинг 15 24. Печать значений и имен меток типов перечистения moduie FSM (input logic dock, resetN,
292 output logic [3 0] control), enum logic [2 0} {WAITE=3'b001, LOAD =3'b010, READY=3'b010} State, Next, always @(posedge clock, negedge resetN) if (iresetN) State <= WAITE, else State <= Next, aiways_comb begin $display("\nCurrent state is %s (%b)", State name, State), case (State) WAiTE Next = LOAD, LOAD Next = READY, READY Next = WAiTE, endcase $display("Next state will be %ь (%b)", Next name, Next), end assign control = State, endmodule 15,14. Контрольные вопросы и задания 1. Какие из перечисленных типов данных относятся к типам данных с двумя состояниями? bit, byte, shortint int, longint wire, reg, integer, time real, shortint 2. Ч го означает выражение: inr(2 0 * 3.0);9 3. Что означает выражение: signed'({a,b});9 4 Для че1 о предназначена функция Scast9 5. Какой номер имеет элемент RED в типе перечисления, определенного следующим образом? enum (RED, BLUE, GREEN} color, 6 Какая ошибка содержится в следующем выражении? typedef enum {FIRST=1, SECOND, THIRD} ordinal e, ordinate position, 7. Какие метки содержит следующий тип перечисления? enum {RESET, S[5], W[6 9]} state; 8. Какой тип данных имеют метки следующего типа перечисления? enum logic [1 0] {WAITE, LOAD, READY} state, 9. Какая ошибка содержится в следующем выражении? а) enum {WAITE = 3b001, LOAD = 3 ЬОЮ, READY = З'ЫОО} state, б) enum logic {A=1'b0, В, С} Iist5, в) enum logic [1.0] {WAITE, ERR=2'bxx, LOAD, READY} state,
293 16. СЛОЖНЫЕ ТИПЫ ДАННЫХ SYSTEM VERILOG: ARRAYS, STRUCTURES И UNIONS 16.1. Структуры (Structures) 16.1 1. Создание структур, определяемых пользователем. В SystemVerilog предоставлена возможность создания структур с помощью struct, подобных используемым в языке Си. Структуры удобны для объединения родственной информации, struct { mt a, b, // 32-bit variables opcode_t opcode, // user-defined type logic [23 OJ address, // 24-bit variable bit error, //1-Dit2-statevar } lnstruction_Word, Структуры считают вырожденными классами и в некоторых случаях рекомендуют отдавать предпочтение последним Несколько переменных можно объединить в сгрукгуру. Например, структура pixel имеет три беззнаковых байга для описания красной (г), зеленой (g) и i олубой (Ь) составляющих цвета: struct {bit [7 0] г, д, b,} pixel Данный пример создает юлько один элемент заданного типа. Для того чю- бы иметь возможность использовать данный тип для описания портов и в подпрограммах, его следует описать в виде нового типа данных tvpedef struct -fbit П 01 г, д, b,} pixel_s, pixel_s my_pixel, Наиболее полезен оператор typedef для создания гипов, объединений (unions), типов перечисления и виртуальных интерфейсов. Обращение к элементам структуры <structure__name> <vanabie_name> Например: "nstruction_Word address = 32 hF000001E, Структуры могут быть объявлены для переменных и цепей Для объявления структуры как переменной в общем виде может быть использовано ключевое слово var, а для цепей - wire- var stoict {// Переменная - структура logic [31 0] a, b logic f 7 0] opcode, logic [23 0] address, } instruction_Word_var,
294 wire struct {// Структура класса цепи ( net) logic [31 0] a, b, logic [ 7 0] opcode, ' • : •■■;■ logic [23 0] address, } lnstruction_Word__net, Элементы структуры могут быть инициализированы при создании переменной. Для этого используется конструкция '{and} (листинг 16 1, а) Можно присваивать значения отдельным попям структуры (листинг 16.1, б) или всей структуре в целом посредством оператора '{and} (листинг 16 1, в) Листинг 16 1. Присвоение значений элементам структуры а) // В момент декларации typedef struct { logic [31 0] a, b, logic [ 7 Oj opcode, logic [23 0] address, } instruction_word_t, instruction_word_t IW - '{100, 3, 8'nFF, 0}, б)// Присвоение значений отдельным элементам структуры typedef struct { logic [31 0] a b logic [ 7 0] opcode, logic [23 0] address } mstrj, instr_tiW, always @(posedge clock, negedge resetN) if (iresetN) begin ■'■'■■ iW a = 100 // Обращение к полю а структуры iW IW b = 5, i. iW oocode = 8 hFF. IW address = 0 end в) // Присвоение значений всей структуре always @(posedge clock, negedge resetN) if (iresetN) IW - '{100, 5, 8'hFF, 0}, else begin При этом присвоение выполняется по порядку следования элементов. Можно выполнить инициализацию значений с указанием их имени, как это сделано в следующем примере. IW = '{address 0, opcode 8'hFF, a 100 b 5}, Однако не допускается смешивать оба стиля описания: IW = '{address 0, 8'hFF 100, 5}, // ERROR
295 Можно инициализировать все элементы структуры с помощью оператора по умолчанию: IW = '{default 0}, // Установка всех элементов IW в 0 1акже допускается выполнять инициализацию данных определенного типа. typedef struct { reairO.rl, mt Ю, И logic [ 7 0] opcode, log'c [23 0J adaress, } instruct!on_word_t, instruction_word_t IW always @(posedge clock, negedge resetN) if ('resetN) IW = {real 1 0, default 0}, // Все вещественные переменные получат значение 1 0, // остальные элементы устанавливаются в 0 else begin end Существует приоритет присвоения значений данным, при этом опера юр default имеет самый низкий приоритет и переопределяется любым типом данных В следующем примере поле г0 получает значение 1.0, г 1 - 3 1415, а все остальные поля - 0: typedef struct { real rO, n, mt Ю, i1 logic [ 7 0] opcode, logic [23 03 address, } instfuchon_word_t, mstruction_word J IW IW = '{real 1 0 defaults, r1 3 U15} 16 1.2 Упакованные срумуры. SystemVerilog предоставляет возможность управлять способом сохранения данных в памяти, используя упакованные структуры Они храня!ся как непрерывное множество битов без дополнительною неиспользуемого пространства. Приведенная в предыдущих примерах структура struct содержит три значения и. следовательно, занимает три длинных слова, даже если реально достаточно трех байт Чтобы сэкономить намять, можно преобразовать структуру в упакованную typedef struct packed {bit {7 0] r, g, b,} pixei_p_s, Pixe!_p_s myjDtxel, Упакованные структуры используются, коиа базовые биты представляют численные структуры или когда выполняется попытка экономии памяти Например, можно упаковать вместе несколько битовых полей для формиро-
296 вания единого регистра. Можно упаковать вместе код команды opcode и поля операндов, получив, таким образом, единую инструкцию для процессора. Поскольку упакованные структуры хранятся в виде вектора, то математические и логические операции могут быть реализованы для упакованных структур, как и для векторов. 'ypedef struct packed { logic valid, logic [ 7 0] tag, logic [31 0] data, } aata_word_t, data_word_t packetjn, packet_out, always @(posedge clock) packet_out <= pack8t_.n « 2 Упакованная структура может быть объявлена как беззнаковая (unsigned) или знаковая (signed), что определяет способ ее обработки при реализации арифметических операторов: typedef struct packed signed { logic valid, logic [ 7 0] tag logic signed [31 0] data, } data_word_t, data_wora_t A, B, always @(posedge clock) if ( A < В ) // Знаковое сравнение Оба вида структур (упакованные и нет) являются синтезируемыми. 16.2. Объединения (union) В аппаратуре одни и те же данные, объединенные в решетры, могут иметь различные значения и форматы для обрабатывающего их устройства Например, через один и тот же регистр могут передаваться как команды, так и данные. В примере (листинг 16 2) целое i и вещественное f числа хранятся в одном и том же месте Листинг 16.2. Примеры объединений // Использование typedef для создания объединений typedef union {int i, real f, } num_u, un f = 0 0, // установка значений в формате с плавающей точкой // Переменная, имеющая тип объединения inti, int unsigned u, ) data, data.i = -5, Sdisplayfdata is %d', data.i);
297 dala.u = -5, Sriisplayfnowdata is %d", data u), typedef union {// typed union int unsigned u, } dataj, dataj a, b, // две переменные типа dataj Неупакованные объединения не синтезируются Могут содержать любые типы переменных, включая real, неупакованные структуры и массивы 16 2.1 Упакованные объединения. Объединения могут быть объявлены как упакованные, подобно аруктурам 'lot да количество битов, занимаемых каждым элементом, будет одинаковым, ч!0 позволяет упакованные пакеты сделать синтезируемыми. Пример, представленный листингом 16 3, определяет упакованное объединение, в котором данные могут быть представлены двумя способами как пакет данных (с помощью структуры) или как массив байтов (рис 16 1) Листинг 16.3. Пример упакованных объединений typedef struct packed { iogic [15 Oj source_address. logic [15 0] destination_address, logic [23 0] da»a logic [ 7 0] opcode \ oata_packetJ, union packed { oata_packet_t packet, // Упакованная структура logic [7 0][7 0] bytes, // Упакованный гиассив 63 47 31 7 О packed [~~~ sourceaddr | destination addr~ | data"""" jopcooe ] 63 55 47 39 31 23 15 7 0^ bytes [by tesf7i Ibytijej [Ьутё1?5Г |bytes[4j |bytes[3[ |bytes[2] |bytes[1] jbytesfOl | Рис 16 1. Упакованное объединение с двумя формами представления одних и гсх же данных 16 2 2 Пример использования структур и объединений. Листинг 16 4 содержит модель простейшего арифметического логического устройства, коюрая можег оперировать либо знаковыми, либо беззнаковыми данными. Структура, представляющая команду, содержит: код команды ALU, два операнда и флаг для индикации знаковых или беззнаковых данных. Устройство может оперировать одним из видов данных, но не обоими сразу. Листинг 16.4 Использование структуры и объединения package definitions, typedef enum {ADD, SUB, MULT, DIV SL, SR} opcode,t,
typedef enurn {UNSIGNED, SIGNED} operand_type_t, typedef union packed { logic [31-0] u_data, logic sgned [31 0] s_data, } dataj, typedef struct packed { opcodej ope, operandjypej opjype, data_t op_a, dataj op_b, endpackage import definitions *, // импорт пакета в пространство $unit module alu (input instrJIW, output data_t a!u_out), always @(iW) begin if (IW opjype == SIGNED) begin case (IW ope) ADD alu_out s_data = IW opa s_data + IW op_b s_data, SUB alu_out b_data = IW op_a s_data - IW op_b s_data, MULT aiu_out s__data = IW op_a s_data * IW op_b s_data, DIV alu_out s_data = IW op_a s__data / IW op_b s_daia, SL alu_out.s_data = IW op_a s_data <« 2, SR a!u_out s_data = IW op_a s_aata »> 2, end case (IW ope) ADD aiu_out.u_data = IW op_a.u_dat3 + iW,op__b u_data; SUB alu_out u_data = IW op_a u_data - iW op_b u_data MULT alu_out u_data = IW op_a u_data * IW op__b u_data DIV alu_out u_data = IW op_a u_data / IW op_b u_data, SL aiu_out u_data = IW op_a u_data « 2, SR alu_out u_data = IW op_a u_data » 2, endcase endmodule 16.3. Массивы фиксированного размера Базовый синтаксис массивов <data_type> <vector_size> <array_name> <array_dlmenslons-=• Например: reg [15 0] RAM [0 4095], // Массив памяти В Verilog-2001 разрешается создавать массивы переменных и цепей: // Одномерный неупакованный массив из 1024
299 // 1-битовых элементов класса net wire n [0 1023], // Одномерный неупакованный массив из 256f //8-битовых переменных reg [7 0] LUT [0 255], // Одномерный неупакованный массив из 1024 // вещественных переменных real г [0 1023], // 3- мерный неупакованный массив // из 32-битовых целочисленных переменных integer i [7 0][3 0][7 0], 16.3 I. Декларация и инициализация. Разрешается выполнять декларацию массива, указывая только его размер, подобно тому, как это делается в Си Следующие два выражения являются целиком равнозначными: mt lo_hi[0.15], //16 ints [0}..[15] intc_sty1e[16];//16ints[0] [15] Разрешается создавать многомерные массивы фиксированной длины, описывая размерность массива после имени переменной Эго неупакованные массивы (unpacked array) В примере создаю 1ся два двумерных массива целых чисел размером 8x4. Последний элемент массива аггау2 устанавливается в 3. Многомерные массивы были введены в VcnIog-2001, новшеством является возможность компактной декларации- int array2 [0 7][0:31, // Подробная декларация int аггауЗ [8][4], // Компактная декларация аггау2[7][3] = 1, // Установка значения последнего // элемента массива bit 163 0] d_array [I 128], // Массив векторов shortreal cosines [0 89]; // Массив вещественных чисел of floats tvpedef enum {Mo, Tu, We, Th Fr, Sa Su} Week Week Year [152]; // Массив элементов типа Week Каждый элемент в SystemVerilog сохраняется в виде длинного слова (32-bit) Таким образом, byte, shortint и mt сохраняются в одном доинном слове iongword, в то время как longmt - в двух (Симулятор часто сохраняет четырехзначные типы, такие как logic и integer в двух или более словах). Например, элементы следутоше! о неупакованного массива Dtt [7 0] b_unpacked[3J, будут занимать три длинных слова (рис J 6 2) Инициализация массивов может быть выполнена с помощью апострофа и фигурных скобок (листинг 16 5)
b_array[0)|[ Ь_апау[1]Г~ °Щ b_array[2]| 1 1 Unused space —1 1 inw^mm |7|6|514|3|2|1|0| Иб|5|4|3|2|1(01 Рис 16 2 Размещение неупакованно!о массива в памяти Листинг 16.5. Инициализация массива int ascend[4] = '{0,1,2,3}, // Инициализация 4 элементов int decend[5], intmd[2][3] ='{'{0,1,2}. {3,4,5}}, descend = '{4,3,2,1,0}, // Установка 5 элементов descend[0 2] = {5,6,7}, // Установка 3 элементов ascend = '{4{8}} // Четыре повторения значения 8 В отличие от Venlog в SystemVerilog разрешается обращаться ко всем> неупакованному массиву или диапазону неупакованного массива, int а1 [7 0][1 С23 0], // Неупакованный массив int а2 [1 8][1 -1024], // Неупакованный массив а2 = а1, // Копирование целого массива а2[3] = а1[0], // Копирование сектора массива 16.3.2. Базовые операции массивов, for и (breach В примере (листинг 16 6) переменная i является локальной для цикла for SystemVerilog функция Ssize возвращает размер массива В операторе foreach указывается имя массива и в квадратных скобках индекс SystemVerilog автоматически перебирает все элементы массива. Листинг 16.6. Использование массивов с циклами for и foreach initial begin bit [31 0] src[5], dst[5j, for (int i=0, KSsize(src), i+нЛ src[i] = i; foreach (dstfj]) dst[j] = srcfjj * 2; // dst doubles sre vaiues end Для мноюмерного массива синтаксис обращения к элементу [i,jj Листинг 16 7 представляет пример работы с эпеменгами многомерного массива Листинг 16.7. Инициализация и перебор элементов мноюмерного массива initial begin Sdisplayflnitial value"), foreach (md[i,j)) // Yes, this is the nght syntax $display("md[%0d][%0d] = %0d", i j, md[i)0j), $display("New value"), md = '{{9, 8, 7}, 3{5}}, // Replicate last 3 values foreach (mdpjj) // Yes, this is the nght syntax $dispiay("md[%0d][%0d] = %0d", i, j md[i]ij]),
301 // Результат моделирования Initial value md[0][0] = 0 md[0][1j = 1 md[0][2] = 2 md[1][0] = 3 md[1][1] = 4 md[1][2] = 5 New value mdfOJ[0] = 9 md[0][1] = 8 md[0][2] - 7 md[1][0] = 5 md[1][1J = 5 md[1][2] = 5 16 3 3. Базовые операции массивов copy и compare Разрешается выполнять операции сравнения и копирования массивов без использования циклов. Операция копирования работает с целыми массивами (листинг 16.8). Сравнение ограничено результатами равно и неравно. Листинг 16 8 Операции копирования и сравнения массивов initial oegin bit [31 0]src[5]-'{0,1,2,3 4}, dst[5] = '{5,4,3,2 1}, // Сравнение двух массивов if (src==dst) $display("src == dst"), SdispiayC'src '= dst"), // копирование элементов массива src в dst dst = src // Сравнение одиого элемента srciO] = 5, // Сравнение всех элементов массива и вывод сообщения об этом $display("src %s dst", (src == dst) ? "==" "!="); // Сравнивает последние элементы массива 1-4 $display("src[1 4] %s dst[1 4]", (src[1 4] == dst[1 4]) ? "==" "<=") end Нельзя выполнять объединение арифметических операций, таких как сложение массивов Вместо этого можно использовать циклы Для логических операций, таких как хог, используются циклы или упакованные массивы Vcrilog-1995 не разрешает использовать вместе слово и поддиапазоны В VenIog-2001 этого ограничения нет для массивов фиксированного массива В примере из лисшнга 16,9 распечатываются первый элемент массива (1012), младший бит (1) и следующие два старших бита (binary 10) Листинг 16.9. Использование слова и бита массива initial beg.n
302 bit Г31 0] src[5] = {5{5}}, Sdisplayb(src[Oj„ //М01илиУ5 src[0][0]„ //'Ы src[0][2 1]), //'Ы0 end 16.3.4. Упакованные массивы (Packed arrays) Упакованные массивы - непрерывные последовательности битов, которые не имеют неиспользуемых пространств в отличие от неупакованных массивов данных. Упакованные массивы - это удобный способ деления векторов на поля, доступ к которым становится возможным через индексы массива. Если упакованный массив объявляется как signed, то он рассматривается как один вектор с левым старшим битом в виде знака Размерность упакованных массивов задается перед именем Размерность описывается в формате [lo hi]. В примере (листинг 16.10, рис 16.3) переменная bytes представляет собой упакованный массив размером в одно длинное Листинг 16.10. Декларация и использование упакованного массива bit [3 0] [7 0] bytes, // 4 bytes packed into 32-bits bytes = 3? hdead _beef $displayh(bytes„ // Show all 32-bits bytes[3], // most significant byte "de" Dytes[3][7]), /' most significant bit "1" bytesj3j bytes[1][6] bytes Щ'^'з^ Рис 16 3 Структура упакованно! о массива Упакованные массивы могут бьаь созданы из битовых типов (logic, bit или reg), других упакованных массивов, структур и объединений, а также из цепей (wire, uwire, wand, tri, triand, trior, triO, tri 1 или trireg) typedef struct packed { iogic[7 0]crc, logic [63 0] data, } data_word data_word [7 0] aarray, // 1-D упакованный массив II из упакованных структур В упакованных массивах можно обращаться: ко всему массиву, к отдельным элементам или поддиапазонам: logic [3 0][7 0] data, // 2-D упакованный массив wire [31 0] out = data, // Целый массив wire sign = data[3][7], // Выделение бита wire [3 0] nib = data [0][3 0], /' Выделение диапазона byte nigh_byte, assign high_byte - data[3], // 8-битовый диапазон logic [15 0] word,
303 assign word = data[1 0], // 2 диапазон Можно смешивать упакованные и неупакованные измерения, например, для представления памяти, доступной по битам, байтам и длинным байтам В примере (листинг 16.11, рис. 16.4), barray - неупакованный массив из трех упакованных элементов. Листинг 16.11. Декларирование смешанных массивов bit [3 0] [7 0] barray [3], // Packed 3x32-bit barray[0] = 32 h0123_4567, barray[0][3] = 8'h01, barray[0][1][6]=1M, JagyjglBL^ barray[0][1][6] barray[0] |[7|'б1514|^1ШШ5Щэ|ШЩЩГ5ПТзГ2| 11оЁЖб^ГзЖтта barray[1] fWeГбНТзТг1110|J71бГ5|4|3|2j 11о]|7|6|5|4|3[ТПТо]!/TeTs[4jз"|2| 11 o] barray[2] FillSHFsTiFlToFl61 SU|3^T|^7|e|5|4ТЩЩоРТвТ5Т4Ш2ТТТо1 Рис 1 b 4. Структура 3-мерного упакованного массива При инициализации первым получает значение длинное слово barrayfO], следующим инициализируется байт данных barray[0j[3], последним - бит barray[0][l][6] Следует обратить внимание, что поскольку одно измерение описывается после имени, barray[3], то оно является неупакованным, поэтому необходимо использовать как минимум один индекс. Рис !6.5 иллюстрирует порядок записи индексов при обращении к массива со смешанной индексацией. Selection order for mixed packed/unpacked multt-demensiona! array logic [3 0] [7:0] mixecl_afray [0 7] [0 7] [0:7], m,xed_array [oj [ij [2] [3] 14]=1 M, Put 16 5 Порядок записи ин чексов в mhoi омерном массиве 16 3 5. Назначение упакованных массивов. Если необходимо выполнять преобразования в скалярные значения и наоборот, используются упакованные массивы. Например, при обращении к памяти побайтно или длинными словами С этой целью может быть использован описанный в примере (см. листинг 16.il) массив barray Упакованными могут быть только массивы фиксированного размера, поэтому, если необходимо использовать изменения внутри массива, следует применять упакованные массивы. Например, операция @ может быть использована со скалярными значениями и упакованными массивами. В рассмотренных выше примерах будет легальным использование оператора @ с переменной iw и массивом barray[0], но никак не с целым массивом barray. Однако допустимо выражение. @(barray[0] or barrayf 1 ] or barray[2]).
304 Инициализация упакованных массивов. logic [3 0][7 0] а = 32'hO, // Присвоение значений вектору logic [3 0J[7 0]b = {16'hz,16'hO} /'Оператор конкатенации log.c [3 0][7 0] с = {16{2'Ь01}}, // Оператор дублирования Инициализация неупакованных массивов выполняется с помощью конструкции '{and} для каждою измерения массива int d {0.1 ][0 3] = '{'{7,3,0,5}, '{2,0,1,6}}, // d[0)[C] = 7 // d[0][1] = 3 //d[0][2] = 0 // d[0][3] = 5 //d[1][0] = 2 //d[1][1] = 0 //d[1][2] = 1 //d[1][3] = 6 inte{0 1][0 3] = '{2{7,3,0,5}} // e[0][0] = 7 //e[0][1] = 3 ,</e(0][2] = 0 //e[0][3J = 5 //ei1][0] = 7 //e[1][1] = 3 //e[1][2] = 0 /7 e[1][3] = 5 Использование значения по умолчанию •nt al [0 7][0 1023] = '{default 8'h55}, Присвоение значений неупакованным массивам в SystemVerilog: byte a [0:3][0 3], a[1][0] = 8 h5, // Присвоение значений одному элементу а= '{'{0,1,2,3}, '{4,5,6,7} {7,6,5,4}, '{3,2,1,0}}, // Присвоение списка значений целому массиву а[3] = ThF, 'hA, 'hC, 'hE}, // Присвоение списка значении диапазону массива или с использованием значения по умолчанию: always @(posedge clock, negedge resetN) (f ('resetN) begin a = '{default 0}, // Инициализация целого массива a[0] = '{default 4}, // Инициализация диапазона массива else begin // end
В упакованных массивах значение можно присваивать всему массиву, отдельным элементам и поддиапазонам, logic [1 0][1 0]{7 0] а, // 3-мерный упакованный массив а[1][1][0] = 1 Ь0, // Присвоение значения одному биту а = 32'hF1A3C5E7, // Присвоение значений целому массиву a[1J[0J[3.0J = 4'nF. Ч Присвоение значений диапазону массива а[0] = 16 hFACE, // Присвоение значений сектору массива а = {15'bz, 16'ЬО}, // Присвоение конкатенации элементов ! 16 3 6 Пример использования массивов. Следующий пример (листинг 36.12) иллюстрирует использование упакованного массива для регистра из 32 инструкций Каждая инструкция представляет собой данные, описанные упакованной структурой. Операнды в инструкции могут быть знаковыми или беззнаковыми, для чего используются объединения двух типов. Входами регистра команд являются выбор операнда (separate operands), код команды (opcode) и флаг (flag) индикации знаковых или беззнаковых операндов. Модель загружает эги отдельные фрагменты данных в регистр инструкций. Выход модели - массив из 32 инструкций. Листинг 16.12. Использование массивов структур для создания модели регистра команд package definitions, typedef enum {ADD, SUB, MULT, DIV, SL, SR} opcodej, typedef enum {UNSIGNED SIGNED} operandjypej, typedef union packed { logic [31 0] ujjata, logic signed [31 0] s_data, } dataj, typedef struct packed { opcodej ope, operandjypej opjype, data J op_ a, dataj odJj, endpackage import definitions *, // Импорт пакета в пространство $unit module mstruction_register ( output mstrj [0'31] instrjeg, // Упакованные массивы структур input dataj operand__a, input dataj operand J3, input operandjypej opjype, input opcodej opcode, input logic [4 0] wrrte_pointer )■ always @(wnte_pomter) begin instr_reg[write_pointer] opjype = opjype, instr_reg[wnte_pointer] ope = opcode, // Использование opjype для определения типов операндов
// сохраненных в объединении входных операндов if (opjype == SIGNED) begin instr_reg[wnte_pointer] op_a s_data = operand_a s_data, instr_reg[wnte_pomter] op_b s_data = operand_b s_data else begin instr_reg[wnte_pomter].op_a u_data = operand_a u_data, mstr_reg(write_pointer] op_b u_data = operand_b u_data, endmoduie Специальные функции для работы с массивами !) Sdimensions(arrayjiame) - возвращает число измерений массивов; 2) $left(array_name, dimension) - возвращает самый левый индекс м logic [1 2J[7:0] word [0 3][4 1] $left(word,1) will 'eturn 0 $!eft(word 2) will return 4 Sleft(word,3) will return 1 $left(word,4) will return 7 3) $right(array_name, dimension) - возвращает самый правый индекс массива; 4) $iow(array_name, dimension) - возвращает самый младший бит массива: logic [7-0] word [V4], $!ow(wora 1} returns 1, and $low(word 2) returns 0 5) $high(array_name, dimension) - возвращает самый сгарший бит массива; 6"! $size(array_name, dimension) - возвращает число элементов массива; 7) $mcrement(array_name, dimension) - возвращает 1, ecu и Sleft - больше или равно Slight. -1. если Sleft меньше, чем $nght" logic [3 0][7 0] array [0 1023], tnt d = Sdimensions(array), if (d > 0) begip " объект является массивом for (int j = $nght(array 1), j = ($left(array 1)+ $increment(array,1)), j += $increment(array, 1}) begin end Например' Snght(array,1) //возвращает 1023 Sleft(array 1) // возвращает О $increment(array, 1) // возвращает -1 $bits(expression) // возвращает количество битов, // представленных выражением bit [63 0] а,
307 logic [63 0] b, wire[3 0][7 0]c[0 15J, struct packed {byte tag, logic [31 0] addr,} d $bits(a) // возвращает 64 Sbits(b) // возвращает 64 $bits(c) //возвращает 512 $bits(d) // возвращает 40 $bits(a+b) // возвращает 128 Описываемые далее типы массивов не синтезируемы Они предназначены для использования в testbench. 16.4. Динамические массивы Динамические массивы декларируются бе? указания их длины с пустыми скобками []. Для выделения памяти под массив используется оператор new[]. Если указать дополнительное имя в операторе new[], то значение будет копироваться в новый элемент (листинг 16.13 ) Листинг 16.13. Использование динамических массивов int dynQ, d2Q II Пустой динамический массив initial begin dyn = new[5j, // Выделение памяти для 5 элементов foreach (dyn[i]) dynfj] = !, // Инициализация элементов d2 = dyn, // Копирование динамического массива d2[0] = 5, // Изменение копии $dispiay(dyn[0j,d2[0]), // Зывод обоих значений (0 и 5) dyn = new[20j(dvn), // Увеличение размера и копирование dyn = new[100], // Выделение памяти для 100 новых // элементов Старые значения при этом будут потеряны dyn delete, // Удаление всех элементов end Функция Ssize возвращает размер массивов с фиксированной и динамической длинами Динамические массивы имеют несколько специальных методов, таких как delete и size (листинг 16.14.). Последний возвращает размер только для динамических массивов. Прототипы методов size и delete: function int size(), function void delete(), Листинг 16.14. Использование методов size и delete int j = addr size, addr = new[add- size()*4](addr), // увеличенный в 4 раза массив addr int abQ= new[N], // Создание временного массива в N элементов // Использование ab ab.delete, // Удаление содержимого массива $display ("%d", ab size), // Вывод 0
308 Можно задавать массивы фиксированной длины, не указывая их размер непосредственно. В этом случае элементы массива получают значения в момент его декларации, а компилятор вычисляет размер массива, исходя из количества указанных элементов. В листинге 16.15 массив mask получает значение девяти 8-битовых масок. Листинг 16.15. Использование динамического массива для создания списка bit [7 0] mask[] = ';8'b0000_0000, b0000_0001,8'b0000_0011, 8'b0000_0111,8'b0000_1111,8 b0001_ 1111, 8 b0011_1111, 8'b0111_1111,8'M 111_1111}, Можно присваивать между собой значения массивов с динамической и фиксированной длиной, если они имеют одинаковый тип данных mt и одинаковую длину. Если присвоить массив с фиксированной длиной динамическому массиву, то компилятор вызовет конструктор new[], чтобы выделить память под массив, а затем скопирует в нее новые значения. 16.5. Очереди Новый тип данных. Упрощает процесс поиска и сортировки в структурах. Такой же быстрый, как и массивы с фиксированной длиной, многообразен как связанный список Подобно динамическим массивам очереди могут увеличиваться и уменьшаться в размере во время моделирования, также можно тегко добавлять и удалять любые элементы, как это показано в следующем примере. Декларируется как массив, но с использованием символа доллара $ (листинг 16.16). Размер массива может быть указан, но это необязательно. Очередь может сохранять данные типа тех, которые он получил в момент декларации очереди: int q1 [$], //пустая очередь, без указания размера mt q2 |S] = {1,2,3,5,8}, // безразмерная очередь, '/ инициализируется пятью элементами tvpedef struct {int a b, bit flag} packetj, packetj q3 [$-16], //очередь размером в 16 элементов Листинг 16.16 Операции над очередями int j = 1, b[3] = {3 4}, q[$J = {0,2,5}, // {0,2,5} Инициализация очеоеди initial begin ■> ■ qinsert(1,j), //{0,1,2,5}, помещает 1 перед2 q msert(3 b), // {0,1,2,3,4,5}, помещает значение b[j после 2 q deietefl), // {0,2,3,4,5}, удаляет элемент с индексом 1 // Следующие операторы самые быстрые q push_froni(6), // {6,0,2 3,4,5}, добавляет элемент в начало списка j = q popjjack, // {5,0,2,3,4} j = 5 q pusn_back(8), // {6,0,2,3,4,8} добавляет элемент в конец списка j = q.pop_front /' {0,2 3,4,8} j = б foreach (q[ij) $display(q[i]J; end
309 Когда создается очередь, System Verilog выделяет дополнительное пространство, которое позволяет быстро добавлять элементы Для очередей нет необходимости использовать оператор new[]. Если в очередь добавляется больше элементов, превышая, таким образом, размер свободною пространства, SystemVerilog автоматически выделяет дополнительное место. Быстро выполняется операция чтения (pop) и записи (push) с начала или конца массива. Для ее выполнения используется фиксированное время Больше времени потребуется на выполнение этих операций из середины массива, особенно если он имеет большую длину, поскольку симулятору будет необходимо сместить половину массива. В очередь можно копировать значения массивов фиксированной и динамической длины. Очереди могут быть использованы для создания моделей FIFO, LIFO или других типов памяти с последовательным доступом 16.5 1. Методы очередей В SystemVerilog для очередей определены встроенные методы 1) lnsert(value) - добавляет элемент в указанную индексную позицию; 2) delete(value) - удаляет элемент из описанной индексной позиции; 3) push_front(<value>) - добавляет значение переменной в новую позицию в начале очереди; 4) push_back(<value>) - добавляет значение переменной в новую позицию в конце очереди; 5) variable = pop frontQ - удаляет первый элемент из очереди и возвращает в его значение; 6) variable - pop_back() - удаляет последний элемент из очереди и возвращает в его значение; 7) in;>ert(<mdex>,<va!ue>) - изменяет значение элемент в указанной позиции без изменения размера очереди, 8) variable = <queue_rmme>[<index>] - возвращает значение элемента из указанной позиции без изменения размера очереди; 9) variable = sizeQ - возвращает текущее количество элементов в очереди Запись в заполненную очередь и чтение из пустой очереди приведет к ошибке времени выполнения. 16.5.2. Параметризируемая память FIFO. Листинг 16.17 иллюстрирует использование очередей и их методов в моделях, разработанных с помощью SystemVerilog Пример представляет собой простейшую память FIFO, которая создается с применением очередей в SystemVerilog Размер и разрядность данных FIFO контролируется параметрами. Помещение в память и удаление данных из памяти FIFO, точно так же как и проверка элементов в FIFO, реализуется с помощью методов очередей.
310 Очередь также моделируется с помощью SystemVerilog типов с двумя состояниями int и bit Где содержание шины и разрешение цепи не важны, типы с двумя состояниями улучшат производигельность. В среде верификации очереди могут использоваться для сбора информационных данных Листинг 16 17. Модель FIFO с использованием очередей timescale Ins/ 1ns module FiFO #(parameter int DEPTH = 31, parameter int WIDTH = 8) ( •pput bit [WIDTH-1 0]DATA, input bit CLK, RSTb, WEMb, RENb, output bit FULL EMPTY, output bit [WIDTH-1 0]Q), bit [WIDTH-1 0] mem [$ DEPTH], '/ Запись данных в FIFO always @(posedge CLK, negedge RSTb) if (RSTb == 0) mem = '{b else if (WENb == 0 && mem size() < DEPTH) mem push_back(DATA), // Чтение данных из FIFO always @(posedge CLK) if (RENb == 0 && mem size() > 0) * Q <= mem pop_front() ! '"■ II FiFO control flags assign EMPTY = (mern.sizef) == 0) ° 1 0, assign FULL = (mem size() == DEPTH) ? 1 0, endmodule 16.6. Ассоциативные массивы Для хранения в памяти больших объемов данных SystemVerilog предлагает ассоциативные массивы, сохраняющие входы для разреженных матриц На рис.16.6 представлен массив, сохраняющий информацию в позициях 0 3, 42, 1000, 4521, 200 000 Дня создания его модели при использовании ассоциативных массивов пофеб>ется значительно меньше памяти, чем если бы это был массив с фиксированной и динамической длиной из 200 001 элементов. index 0 3 42 1000 4521 200 000 Рис 16 6 Пример ассоциативного массива Синтаксис декларации ассоциативного массива data_type arrayjd [indexjype], где data_typc - тип данных элементе массива, может быть любой run, разрешенный для массивов фиксированной длины: arrayjd - имя декларируемого массива; indextype - тип данных, используемый для индекса или *.
311 Символ * означает, чго массив можег индексироваться любым целым выражением При указании типа индекса используемое выражение для индексации должно быть только указанного типа Листинг 16.18 представляет декларирование, инициализацию и использование ассоциативных массивов. Их декларация выполняется с помощью групповою символа [*]. Листинг 16 18. Декларирование, инициализация и использование ассоциативных массивов initial begin logic [63 0] assoc[*], idx = 1, // Инициализация разрозненными значениями repeat (64) begin assoc[idx] = idx, idx = idx « 1, /' Перебор всех индексов с помощью foreach foreach (assocfjj/ $display("assoc[%h] = %h", i, assoc[i]), // Перебор всех индексов с помощью функции if (assoc first(idx)) begin // Получение первого индекса do $disDlay("assoc[%h]=%h", idx, assoc[idxj), while {assoc next(idx)) // Получение следующего индекса // Поиск и удаление первого элемента assoc first(iax), assoc delete(idx), end Ассоциативный массив assoc состоит hj рассеянных элементов 1, 2, 4, 8, lb Для перебора элементов не удобно использовав оператор for, для этой цели лучше подходит операция foreach Для более точно) о контроля можно также использовать функции first и next в цикле do while Эти функции принимают значение индекса в качестве аргумента и возвращают 0 или 1, в зависимости от наличия элементов в массиве. Ассоциативные массивы могут быть также адресованы с помощью строкового индекса В примере (листиш 16.19) выполняется чтение пар имен из файла в ассоциативный массив. Если попытаться прочитать элемент, который еще не существует, то SystemVerilog вернет 0 или X для типов с 2-мя или 4-мя значениями, соответственно. Функция exists может быть использована для проверки существования элемента. Листиш 16.19. Применение ассоциативного массива с индексом string /' Входной файл содержит 42 rrtin_address 42 max_address 1492 mt switch[stnng], min_address, max_address, initial begin
312 string s, file = $fopen("switch txt", "г"), while (' Sfeof(fife)) Degm r = $fscanf(file, "%d %s", i, s), swrtch[s] = i. end $fclose(fi!e), // Получение минимального адреса, по умолчанию О mid_address = switch["min_address"], /' Получение максимального адреса, по умолчанию 1000 if (switch exists("max_address")) rrax_address = switeh["max_address"], max_address = 1000, end Ассоциативный массив может быть сохранен симулятором в виде дерева. Кроме того, допускается использовать дополнительные служебные сигналы (overhead), когда необходимо сохранить массив с далеко стоящими значениями индексов, например для пакетов, адресуемых 32-разрядным или 64- разрядпым значениям данных 16 6.1 Методы ассоциативных массивов. Определено несколько методов для анализа и манипулирования элементами ассоциативных массивов. 1. Функция пшп()- function int num0. Метод num() возвращает число элементов в ассоциативном массиве. Возвращает 0, если массив пусгсй int item[*j, item[2'b3] = 1, iternf 16'hffff] = 2, item[4b1000] = 3, $display( "%0d entries\rf, imem nurn ), // pints "3 entries" 2 Функция delcte()- function void de!ete( [input index]), где index - необязательный параметр индекса соответствующею типа для массива. Если индекс описан, то метод dclete() удаляет элемент, соответствующий индексу; если удаляемый элемент не существует, никаких предупреждений сгенерировано не будет Если индекс не описан, то метод удаляет все эле- mt map[ stnng j, mapfsystemvenlog"] = 1, mapps"] = 2,
313 map["not easy"] = 3, map delete("sad"), // удаляет элемент с индексом "sad" map delete, // удаляет все элементы ассоциативного массива тар 3 Функция exists(): function mt exists( input index ), где index - значение соответствующего типа индекса массива. Функция existsQ проверяет существование в заданной индексной позиции элемента Возвращает 1, если -элемент есть, иначе 0. if ( map existb("SystemVenlog")) mapr'SysternVenlog"] += 1, else mapr'SysternVenlog"] = 0, 4. Функция first(): function mt first( ref index ), где index - значение соответствующего типа индекса массива. Метод first() передает через ссылочный параметр index значение первого (наименьшего) индекса массива. Возвращает 0, если массив пуст, и 1 - в противном случае: string s, if {map.first; s)) Sdisplay("First entry is map[ %s ] = %0d\n", s, map[s]), 5. Функция last() function mt iast( ref index ), где index - значение соответствующего шпа индекса массива. Метод last-О передает через ссылочный параметр index значение последнею (максимального) индекса массива. Возвращает 0. если массив пуст, и 1 - в противном случае: string s, if (map last( s )) Sdisplay("Last entry is map[ %s ] = %0d\n', s, map[s]), 6 Функция next(): function mt next( ref index ), где index - значение соответствующего типа индекса массива. Метод nextO выполняет поиск элемента, чей индекс больше заданного индекса. Если в массиве есть еще элементы, то выполняется связь с соседним элементом и функция возвращает 1 Иначе индекс не меняется, и функция возвращает 0: string s, rf (map first( s )) do $display("%s %d\n" s, map[s]), while (map next( s )i, 7. Функция prev(V function mt prev( ref index },
314 где index - значение соответствующего типа индекса массива. Метод prevQ выполняет поиск элемента, чей индекс меньше заданного индекса Если в массиве есть еще элементы, то выполняется связь с соседним элементом и функция возвращает 1. Иначе индекс не меняется, и функция возвращает О string s, if (map last( s )) do $d'sp!ay("%s %d\n", s, map[ s ]), while ( map prev( s )), Если аргумент, передаваемый в любой из четырех методов перемещения для ассоциативных массивов, меньше чем размер соответствующего индекса, то функция возвращает значение -1. Поэтому необходимо копировать столько данных, сколько может подойти аргументу. Например stnng aa[*j, byte ix, аа[1000] = "а", status = aa.first(tx), // status is -1 // ix is 232 (последние 8 значащих битов от 1000) 16.6.2 Связные списки (Linked Lists) SystemVenlog поддерживает связные списки, аналогичные STL (Standard Template Library) контейнерам списков Контейнер определяется как пара- метризированный класс. Это означает, что он может быть изменен для хранения данных тюбого типа. Однако в System Veniog связным спискам следует предпочитать очереди, которые эффективнее и проще в использовании. 16.7. Методы массивов Существует много методов массивов, когорые могут быть использованы для любых неупакованных массивов, фиксированных, динамических, очередей и ассоциативных 16 7.!. Методы редукции массивов Базовый метод редукции принимает массив данных и возвращает скалярное значение Самым общим методом редукции является sum, который складывает вместе все значения массива. Нужно быть осторожным с определением размера результата в SystemVenlog. По умолчанию, если сложить элементы однобитового массива, го результат будет одноразрядный (листинг 16 20) Однако если сложить или сравнить этот результат с 32-разрядным числом, то SystemVenlog выравнивает размеры в сторону увеличения. Листинг 16.20 Создание суммы массивов Ы. оп[10] // Массив битов
315 initial begin foreach (on[i]) onpj = i, // on[i] получает значение 0 или 1 // Вывод на печать однобитовой суммы $displayfon sum = %0d', on sum), // on sum = 1 // Сумма значений, присваивается 32-битовой переменной yum Sdisplayfsum = %0d', yum), // sum = 5 // Сравнение суммы с 32-битовым значением if {on sum >=32 d5) // True $displayfsum has 5 or more 1 's"); end Другие методы редукции- product, and, or и xor 16 7.2. Методы местоположения. Используются для поиска данных в неупакованных массивах Эти меч оды всегда возвращают очередь. Пример использует массив фиксированного размера f[6], динамический массив d[] и очередь q[$] Функции mm и max находят минимальный и максимальный элементы массива Эти методы также работают и для ассоциативных массивов. Метод unique возвращает очередь уникальных значений массива, дубликаты не включаются (листинг 16 21) Листинг 16.21 Использование методов, mm, max, unique mtf[6]= {1,6,2,6,8 b} mtq[$]= {1,3 5 7} tq[$j tq = qmin, //{1} tq = qmax, //{7} tq = f unique //{1,6,2,8} Можно выполнять операцию поиска с помощью оператора цикпа foreach, но в System Venlog проще выполниib по с помощью методов местоположения (locator) (листинг 16 22). Выражение with испочьчуется SystemVerilog для выполнения поиска Листинг 16.22. Использование метода местоположения find «Л ЧЦ = {9.1,8.3,4,4}, tq[$J, // Поиск всех элементов, больших чем 3 tq = d find with (item > 3) // {9 8,4,4} // Эквивалентный код tq delete, foreach (dp]) if(d[i]>3)tqpush_baek(d[i]), tq = d.findjndex with (item > 3), tq - d.findjirst with (item > 99), tq = d find_firstjndex with (item==8) tq = d find Jast with (.tem==4), // {0,2,4} // {} - элементы не найдены //{2}d[2]=8 //{4}
316 tq = d find_iast_mdex with ntem==4), // {6} d[6]=4 В листинге 16 23 оператор sum выдает количество, для которого выражение имеет значение истина. Для первого оператора возвращается число элементов больше 7 - это 9 и 8, поэтому count = 2. Следует обратить внимание, что sum-with - это оператор, а не выражение, таким образом, результат необходимо сохранять во временную переменную, а не использовать напрямую. Листинг 16.23 Примеры применения методов местоположения mt count, d[] = '{9,1,8,3,4,4}, count = d sum with (item > 7), // 2 {9, 8} count = d.sum with (item < 8), //4(1,3 4,4} count = d sum with (item == 4) // 2 {4 4} Выбор типов памяти (Choosmg a Storage Type) Выбор осуществляется на основе необходимых возможностей, гибкости, использования памяти, скорости и сортировки. Данные правила могут меняться в зависимости от компилятора Гибкость. В случае использования последовательных положительных индексов применяются массивы фиксированной или динамической длины: фиксированной длины, если размер массива известен на момент компиляции, и динамические - в противном случае 16.8. Контрольные вопросы и задания 1 Определена структура typedef struct { logic [31 0] a, b logic E 7 0] opcode , logic [23 0] address , } mstrj, instr J IW Что означают следующие выражения9 а) IW^ {100, 5, 8'hFF, 0}, б) IW = {address 0, opcode 8'hFF, a 100, b 5}, в) IW = '{address.0, 8'hFF, 100, 5}, r) IW = '{default 0}; : i ■ 2. Что такое упакованная структура9 3. Что означает выражение9 typedef struct packed {bit [7 0] r, g b} pixe!_p__s, 4 Что означает данный код? typedef struct packed { logic valid, logic [ 7 0] tag, logic [31 0] data } data_word_t, data_word_t packetjn, packet_out, always @{posedge clock) •■■. packet_out <= packetjn « 2,
317 5 Какие ограничения существуют при определении упакованных объединений? 6. Что означает данное выражение? а) wire n [0 1023], б) reg [7 0] LUT [0 255], в) real r [0 1023]; г) integer i [7 0][3 0][7 0], д) ml аггауЗ [8][4], 7. Дать понятие упакованного и неупакованно! о массивов. 8. Что означает следующее выражение? а) mt ascend[4] = {0,1,2,3}, б) mt md[2][3] = {'{0,1,2}, '{3,4,5}}, в) bit [3 0j [7 0] bytes, r) bit [3 01 [7 0] barray [3], д) foreach <dst[j]) 9 Что такое динамический массив9 30. Дать определение очереди. 11. Дать определение ассоциативного массива. 12 Что означает данное выражение? a) mt dynQ, d2Q, 6)b[S] = {3,4}, e)q[$] = {0,2,5}, !3. Что означает данное выражение? а) q[$] = {0 2,5}, qinsert(1,j), б) q[$] ■= {0,2,5}, qdelete(1); 14.Чго означает данное выражение? logic [63 0] assoc[*], idx = 1, 15. Какое значение получит переменная summ9 bit on[8], int summ, on= {1,0,0,1,1,1,0,0} 16 Какое значение получи г переменная tq? intff6] = '{1,6,2,6,8,6}, tq = f unique,
318 17. ПРОЦЕДУРНЫЕ БЛОКИ, ЗАДАЧИ И ФУНКЦИИ 17.1. Процедурные блоки Чтобы исключить неоднозначность блока always, в SystemVenlog добавлены гри специальных его версии: always_comb, always latch и always_ff. Эти три блока имеют бесконечную природу моделирования, как и оператор always. Однако они улучшают стиль описания аппаратуры и предназначены для разработки синтезируемых моделей RTL-уровня. Программным средствам нет необходимости определять тип аппаратуры из контекста описания операторов. Если стиль записи операторов не удовлетворяет характеру блока, то система разработки генерирует предупреждение 17 1.1. Комбинационный процедурный блок В отличие от обычного блока always, бток always_comb не требует указания специального списка чувствительности Он создается автоматически и в него включаются все переменные, значение которых читается в процедурном блоке, за исключением тех, что объявлены в нем В следующем примере оператор always_comb будет выполняться при каждом изменении переменных а или Ь: always_comb if ('mode) y = a + b else y-a-b, Листинг 17.1 представляет пример использования aiways__comb для описания комбинационных фрагментов схемы контроллера Листинг 17 1. Модель кошроллера с использованием always_comb module controller (output logic read, write, input instrj instruction, input logic clock, resetN), enum {WAITE, LOAD, STORE} State NextState, always @(posedge clock, negedge resetN) if ('resetN) State <= WAITE, else State <= NextState, always_comb begin case (State) WAITE NextState = LOAD LOAD NextState -= STORE, STORE NextState = WAITE endcase end always_comb begin read = 0 write = 0,
if (State == LOAD && instruction == FETCH) read = 1, else if (State == STORE && instruction == WRiTE) write = 1, end endmodule Существует различие в моделировании между always_comb и always. Первый выполняется один раз в нулевой момент моделирования, после активации всех процедурных блоков. Venlog-2001 предлагает использовать в списке чувствительности блока always групповой символ @* или @(*). Однако это только более короткая запись и не дает таких преимуществ, как always_comb (листинг 17 2) Листинг 17.2. Различие между always_comb и always always @* begin // Обозначает @(data) а1 = data « 1, Ы = decode {), s^comb begin a2 = data« 1, b2 = decode (), function decode, // Функция не имеет входов case (sel) 2'b01 decode = d I e, 2'MO decode ■= a & e default decode = c, endcase 17.1.2. Последовательностный процедурный блок always_latch Второй специализированный оператор always - always latch Это процедурный бток, моделирующий триггер-защелку, aiwaysjatch if (enable) q <= d, Пример из листинга 17.3 использует aiwaysjatch 5-битовый счетчик выполняет счет от 0 до 31. Вход ready контролирует начало выполнения счета, имеет значение 1 короткий период времени. Поэтому, когда ready переключается в 1, модель сохраняет это значение для внутреннего сигнала enable. Защелка сохраняет значение 1, пока счетчик Fie достигнет значения 21, и затем выполняется очищение сигнала enable, не давая счетчику выполняться снова, до следующего поступления сигнала ready. Листинг 17.3. Использование процедурного блока always latch module register_reaaer (input elk, ready, resetN, output logic [4 0] read_pointer), logic enable, // internal enable signal for the counter
320 logic overflow, /' internal counter overflow flag jl alwavsjatch begin // latch the ready input m if(iresetN) Щ enable <= 0, else if (ready) ,;. v,,-?H , ;...T enable <=1, ■•-r;.--; ;.'».;, else if (overflow) _,v. . enable <= 0, end always @(posedge cik, negedge resetN) begin // 5-bit counter if ('resetN) {overflow read_j>ointer} <= 0, else if (enable) {overflow,read_pointer} <= reao_pointer + 1 end endrnodule 17 1 3. Последовательностный процедурный блок Блоки, описывающие последовательностную логику, могут моделировать» с помощью always_ff aiwaybjf @(posedge clock, negedge resetN) if С resetN )q <= 0 else q <= d, Все сигналы в списке чувствительности должны быть записаны с указанием фронта posedge или negedge Событийный контроль внутри блока не доп\с- кается Блоки always_comb, ahvaysjatch и always_ff являются синтезируемыми 17.2. Задачи, функции и void-функцим Verilog проводит четкую границу между функциями и задачами Функции не могут содержать операторы, управляющие временем или событиями, всегда должны возвращать одно значение В System Verilog, если необходимо при выадве функции игнорировать во*- вращаемое значение, то ее результат описывается с помощыо void. Например, при игнорировании возвращаемого функцией значения void (my_func(42)) Некоторые симуляторы позволяют игнорировать возвращаемое значение без использования синтаксиса \oid Void-функции вызываются как задачи, в виде оператора, но на них налагаются такие же ограничения, как и на обыкновенные функции В них нельзя использовать события и задержки, из них не допускается выполнять вызов задач. Пример (листинг 17 4) представляет void-функцию, получающую данные в виде 64-разрядного входного вектора из элементов logic и возвращающую информацию в виде структуры packetj.
321 Листинг 17.4 Функция void typedef struct { logic valid, logic [ 7'0] check, logic [63 0] data, } packetj, function void fill_packet ( input logic }63 0] datajn, output packetj data_out), aata__out data = datajn for(-nti=0, i<=7, i++) data_out check[i] = Adata_in[(8*!}+ 8], data_out valid = 1, endfunction 17.2.1. Возврат из подпрограммы. В SystemVerilog, чтобы повысить контроль за последовательностью выполнения операторов подпрограммы, добавлен оператор return. В следующем примере (листинг 17.5) возврат из подпрограммы выполняется в случае наличия ошибки - неправильного значения оператора. Эту же задачу можно решить с помощью конструкции else, однако это усложнит чтение кода. Оператор return может быть использован и с функциями (листинг 17 6) Листинг 17 5 Использование оператора возврат в задаче task load_array(int len, ref int arrayfj), if (len <= 0) begin $display("Bad len"), // Остальной код задачи endtask Листиш 17.6 Возврат из функции function bit transmrt( ), // Передача транзакции return -ifс cb error, // Возврат статуса 0=error endfunctio" Ниже приведено сравнение стилей описания функции в Verilog (листинг 17.7, а) и System Verilog (листинг 17.7, б, в). Листинг 17.7. Функции Verilog и SystemVenlog а) // Пример Veniog-функции function [31 0] add_and_inc (input [31 0] a,b), begin add_and jnc = a + b + 1, end endfunction
322 б) // Пример System Venlog-функции function int add_andjnc (input int a, b), return a + b + 1, endfunction в) // Пример System Venlog-функции function int add_and_inc (<nput int a, b), add_and_inc = a ^ b, return ++add_and_inc, endfunction Venlog позволяет выполнять фуппирование выражений с помощью блока begin .end. В задачах разрешено также фуипировать несколько операторов, применяя fork .join. SystemVerilog позволяет обойтись без использования блоков, в этом случае операторы выполняются последовательно, function statesj NextState(statesJ State), NextState = State, // default next state case (State) WAITE. if (start) NextState = LOAD, LOAD if (done) NextState = STORE, STORE NextState = WAITE, endcase endfunction Допускается передавать аргументы функции через их имя. // Стил» System Verilog вызова функции always @(posedge clock) result <= divide( denommator(b) numerator(a)), В SystemVenlog по умолчанию функция возвращает значение, имеющее тип logic. Ьсли формальный аргумент получает значение в момент декларации то при вызове функции его можно не укашвать. function int mcrementer(int count=0, step=1), incrementer = count + step, endfunction Допускается передавать ссылку на аргумет с помощью конструкции ref. Это используется в автоматических функциях (листинг 17 8) Листаж 17.8. Пример использования автоматической функции module chip ( ), typedef struct { logic valid, logic [ 7 0] спеск logic [63 0] data, } packetj packetj data_packet, logic [7'0] raw_aata [0 7], always @(posedge dock) if (dataj-eady)
323 fill_packet (.data_in(raw_data), data_cut(data_packet)) function automatic void fill_packet ( ref logic [7 0] datajn [0 7], // ref arg ref packetj data__out), // ref arg for (mt i=0, i<=7, i++) begin data_out data[(8*i)+ 8] = data_m[i], data_out check[i] = Adata_m[i]; end data_out valid = 1, endfunction endmoduie 17.3. Процедурные операторы и подпрограммы SystemVenlog унаследовал много операторов из Си и Си+-* 17 3.1 Новые операторы. 1) И нкремент - декремент (габл 17 1). Таблица 17.1. Операторы инкремента и декремента Выражение 1 = 1-+ j--th, j-=i- ,. i=-'- ... Операция пост-инкремент прс-инкременг пост-лекремент пре-декремент Описание увеличивается на ) 1 увенчивается на 1 и ) попучаегобновтснное уменьшается на 1 i уменьшается на , и j получает обновленное Пример использования оператора инкремента в цикле for. for(i = 0,i<= 31,1++) begin Применение операторов инкремента в циклах while, while (i++ ^ LIMIT) begin: loopl // Последнее значение i должно быть LIMIT end while (++j < LIMIT) begin loop2 . // Последнее значение j должно быть LIMIT -1 Операторы инкремента ++ и декремента - обрабатываются программами моделирования как блокирующие Эго синтезируемые операторы. 2) Операторы присвоения. System Venlog получил несколько новых операторов (табл. 17.2), которые комбинируют арифметическую или логическую операцию с присвоением. Например, оператор г=: out ■*■= in,
324 суммирует in с out и присваивает результат assign out Оператор += - это короткая форма выражения- out = out + in, Таблица 17 2. Новые операторы присвоения в SystemVeniog Оператор - - >~ ^ &- Н '= «- »= «.- „>- Описание Суммируется оператор с левой стороны выражения с оператором с правой стороны, затем выполняется присвоение Из оператора с левой стороны выражения вычитается значение t правой стороны, затем выполняется присвоение Умножение Дечение оператора с левой стороны на значение выражения с правой Деление оператора с левой стороны на значение выражения с правой, Побитовая операция И между левым и правым операндом Побитовая операция ИЛИ между левым и правым операндом Побитовая операция по модуто чва между левым и правым операндом Сдвиг оператора с левой стороны влево выражения на количество бит, задаваемых правым операндом Сдвиг оператора с левой стороны вправо выражения на количество бит, задаваемых правым операндом Арифметический сдви! оператора с левой стороны влево выражения на котичество бит, задаваемых правым операндом I Арифметический сдвиг оператора с левой стороны вправо выражения на количество бит, задаваемых правым операндом | Операторы присвоения с дополнительной операцией моделируются как блокирующий процедурный оператор присвоения. Они MOiyT быть использованы в синтезируемых моделях, но с ограничениями (листинг 17 9). Листинг 17 9 Использование операторов присвоения в System Veniog package definitions, typedef enum logic [2 0] {ADD,SUB,MULT,DIV,SL,SR} opcodej, typedef enum logic {UNSIGNED, SIGNED} operandjypej, typedef union Dacked { logic [23 0] u_data logic signed [23 0] s_aata; } dataj, typedef struct packed { opcodej ope, operand_type_t op_type, data_t op_a, data_t op_b, } instruction^, endpackage import definitions::*; // Импорт пакета в пространство компиляции $unit
module a!u (input mstructionj instr, output dataj alu_out) a!ways_comb begin if (instr opjype == SiGNED) begin a!u_out s_data = instr op_a s_data, unique case ^instr ope) ADD alu_out s_data += instr op_b s_data, SUB alu_put s_data -= instr op_b s_data, MULT alu_out s_data *= instr op_b s_ data, DIV alu_out s_data /= instr op_b s_data, SL a!u_out.s_data «<= 2, SR alu_out s__data >»= 2, endcase end else begin alu_out u_data = instr op_a u_data, unique case (instr ope) ADD aiu_out u_data += instr op_b u_data, SUB . alu_out u_data -= instr.op_b u_data, MULT aiu_out u_data *= ms*r op_b u_data, DIV alu_out u_data /= instr op_b u_data, SL alu_out u_data «= 2, SR alu_outu_daia»=2, endcase endmodule 17.3.2. Операторы сравнения. Добавлены новые операторы ==? and ,=,? (wiidcaid equality operator). Для них Z и X только в правом операнде рассматриваются как групповой символ, который сравнивается с соответствующей позицией другого операнда (табл. 17 3) Таблица 17.3 Операторы сравнения в SystemVenlog а 0000 0000 010Z 010Z 010Х 01 ОХ b 0000 0101 0101 010Z 010Z оюх а~Ь true false unknown unknown unknown unknown a-=-b true false false true false true a=='B true false unknown true true true ai-b false true unknown unknown unknown unknown ai==b false true false faise true false a'=Ob faise true unknown false false false Пример. logic [7 0] opcode; if (opcode ==? 8'M 1011???) // маскируются только младшие биты
326 Оператор синтезируется, если маскирующий оператор является константой: logic [3 0] а, Ь, logic у1, у2, assign у1 = (а ==? Д м??1), '/ Синтезируемый assign у2 - (а ==? Ь), // Несинтезируемый 17 3 3 Оператор inside. SystemVerilog предлагает оператор inside, который предназначен для поиска значения переменной в заданном множестве logic [2 0] а, if (a inside {3'Ь001, 3 оОЮ, 3 МОП}) Такая форма упрощает запись множественных сравнений Без оператора inside представленное выше выражение будет выглядеть следующим образом: if ((а==3'Ь00"П || (а==3'Ь010) || (а==3 М00)) В операторе inside множество значений для сравнения может быть представлено множеством сигналов if { data inside fbusl, bus2, bus3, bus4} ) или быть массивом intd_array[01023], •H13,ns.de{d_afray}) В операторе inside значение Z можно заменять символом w9» Следующее выражение будет иметь значение истина, если а примет одно из значений 3'blGl, 3'blll, 3'blxl илиЗ'ЬШ. logic [2 0) а, if{ainside{3b"P1}) Точно так же, как и в операторе if, конструкция inside может быть исполью- вана в операторе case aiways_comb begin case (instruction) inside 4'bO?'?? ope = instruction^ 0], 4'MOOO, 4'M 100- ope = 3'bOOO, default орс=3'Ы11, endcase Оператор inside является синтезируемым 17.3 4 Цикл for. В SystemVerilog переменная, используемая для индексации цикла for, может декларироваться непосредственно в нем (листинг 17.10) В Verilog такая переменная должна была быть объявлена до создания цикла
Листинг 17.10 Сгили циклов SystemVerilog module chip ( ) alwaysjf @(posedge clock) begin for (Ы [4 0] 1 = 0,1 <= 15,i++) alwaysjf @(posedge clock) begin for (inti = 1,i<= 1024, i+=1) end endmodule Переменная, декларированная в операторе цикла, является автоматической К ней нельзя обращаться через иерархическое имя, и она не доступна за пределами цикла. Допускается выполнять объявление нескольких переменных в цикле, например: for (int i=1, j=0, i*j < 128, i++, j+=3) Переменные цикла могут иметь различные типы данных for (mt i=1, bytej=0, i*j< 128; i++, j+=3) Если блоки begm или fork имеют метки, то они могут быть присвоены и завершающим блок консфукциям end или join Это упрощает поиск начала и конца блока Метки могут иметь и другие операторы SystemVenlog, такие как endmodule, endtask, endfunction и другие Пример (листинг 17 1!) представляет использование некоторых новых консфукций Листинг 17.11. Использование меток begin example integer array[10], sum, j, // Декларация i для оператора for for (int 1=0 i<10 1++) //Инкремени аггауМ = i. // Суммирование значений элементов массива sum = array[9], J=8, do // Цикл do...while sum += arrayfj], // Аккумулятор while (j—), // Проверка j на равенство О Sd'spiay("Sum=%4d", sum), // %4d -количество символов end example // Метка конца блока 17.3 5 Новый цикл do .while В SystemVenlog добавлен новый цикл do .. while, отсутствующий в Verilog. Его синтаксис do <statement or statement block>
328 while (<condition>) Такой цикл выполняется как минимум один раз (листиш 17 12) Листинг 17.12. Пример использования цикла do always_comb begin do begin done = 0, OutOfBound = 0 out = mem[addr], if (addr < 128 || addr > 255) begin OutOfBound = 1, out = mem[128], else if (addr == 128) done = 1, addr-=1, end while {addr >= 128 && addr <= 255), Цикл do синтезируется, но с ограничениями. Перебор всех элементов массива в SystemVenlog можно выполнять также с помощью оператора foreach. 17.4. Операторы перехода В Verilog для выхода из именных блоков и циклов использовался оператор disable (листинг 17.13). Кроме того, оператор disable может гакже применяться для прерывания выполнения задач (листинг 17.14) Листиш 17 13 Использования disable для выхода из именных блоков // Поиск первого бита множества в заданном диапазоне битов always @* Degm begin loop first_bit = 0, for (i=0, i<=63; i=i+1) Degm oass if (i < startj-ange) disable pass, // Продолжается работа блоха iooo if (i > end_range) disable loop, // Выход из блока loop if (datap]) begin first_bit = i, disable loop, // Выход из блока loop end end // Завершение блока pass end // Завершение блока loop // Остальные операторы, обрабатывающие данные
329 Листинг 17Л4. Использование disable в задачах task add_up_to_max (input [ 5 0] max, output [63 0] result), integer i; begin result = 1, if (max == 0) disable add_up_to__max, // Выход из задачи for <i=1, i<=63, i=i+1) begin result = result + result, if (i =~= max) disable add_up_to_max, // Выход из задачи end end endtask В System Venlog добавляются операторы из языка Си: break, contmue и return, что дает возможность создавать понятный и компактный код Эти операторы могут быть применены и к текущему потоку. Оператор continue выполняет переход к следующей итерации цикла (листинг 17 15) При этом нет необходимости использовать именные блоки begin...end, как в случае применения опера юра disable Оператор break осуществляет немедленное завершение работы цикла (листинг 17.16). Листинг 17 15 Использование continue в цикле logic [15 0] array [0 255}; always_comb begin for (int i = 0, i<= 255, i++) begin loop if (array[i] == 0) continue, // Пропуск пустых элементов transform_function(array[i]), end // Конец цикла Листин! 17.16 Использование break для завершения цикла // Поиск первого бита множества в заданном диапазоне битов always_comb begin first_bit = 0, for (int 1=0, i<=63, i=i+1) begin if (i < startj-ange) continue, if (i > end_range) break, // Выход из цикла if (datap]) begin first_bit = i, break, // Выход из цикла end end // Конец цикла // Остальные операторы, обрабатывающие данные end
330 Оператор return (листинг 17 17) используется для возврата из non-void и void-функций и задач. Может быть применен в любой момент выполнения функции или задачи. Листинг 17 17 Использование оператора return для выхода из подпрограмм task add_up_to_max (input [ 5 0J max, output [63 0] result), result = 1 if (max == 0) return, // Выход из задачи for (int i=1 k=63, i=i+1) begin result = result + result, if (i == max) return; // Выход из задачи end endtask function automatic int log2 (input int n), if (n <=1) return 1 /' Выход из функции log2 = О while (n > 1) begin n = n/2, !og2++, end ( j return log2, endfunction В SystemVerilog разрешается использование оператора return для досрочного выхода как из задач, гак и из функций, в го время как оператор Venlog disable предназначен только для задач и не может появляться в функциях. В задачах и void-функциях оператор return не может иметь выражение для возврата, для non-void-функций наличие такого выражения обязагечьно Операторы перехода break, continue и return являются синтезируемыми конструкциями и обрабатываются так же, как disable в Verilog 17 4 1. Метки операторов. System Venlog позволяет использовать метки для операторов, что упрощает их идентификацию {листинг 17.18). Синтаксис <label> <statement> Листинг 17 18. Пример создания меток операторов always_comb begin decode_block decoder case (opcode) 2'b00 outerjoop for (int i=0, i<=15, i++) innerjoop for (int j=0 j<=15;j++) //.. // Декодирование остальных значений opcode enocase end docode_block
331 17 4 2 Модификаторы unique и priority. SystemVenlog предлагает специальные модификаторы unique и priority для операторов case, casex и casez: unique case (<case_expression>) // Метки оператора case endcase priority case (<case_expression>) // Метки оператора case endcase Оператор unique case указывает, что только одно значение выбора может и должно совпадать с выражением case. В этом операторе не учшывается приоритет для выбора операций- aiways_comb unique case (opcode) 2'bOO у = а + b, 2d01 y = a-b, 2'MO y = a*b, 2M1 y = a/b, endcase Оператор prionty case указывает, что как минимум одно значение выбора должно совпадать с выражением case, в случае совпадения более одного выражения будет выбрано первое совпавшее Модификатор unique if .else обозначает, что порядок условий не имеет значения logic [2:0] set, always_comb begin unique if fcel == "Vb001) mux_oui = a, else if (sel == 3 b010) mux_out = b, else if (sel == 3 MOO) mux_ojt = c, end Модификатор prionty if .else обозначает, что порядок усчовий важен: aiways_comb begin pnonty if (irqO) irq = 4'b0001, else if (irql) irq = 4'b0010, elseif(irq2)irq = 4b0100, elseif(irq3)irq = 4'M000, end 17.5. Значение временных параметров Наряду с директивой компилятора 'timescaie для определения параметров времени в SystemVenlog могут быгь использованы декларации timeunit и timeprecision Однако если используются директивы, то их необходимо указывать в каждом модуле, содержащем описание задержек SystemVenlog позволяет описывать задержки в формате 0.1пь или 20ps (листинг 17.19). Для
332 работы с временными параметрами можно использовать системные задачи Verilog: Stimeformat и Srealtime. Листинг 17 19. Символьное представление времени и Stimeformat module timing, timeumt 1ns, timeprecision 1ps, initial begin $timeformat(-9, 3, "ns", 8) #1 $aisplay('@%t", Srealtime), //@1 000ns #2ns Sdisplay("@%t", Srealtime), ,'/ @3 000ns #0 1ns $dispiay("@%f, Srealtime), // @3 100ns #41ps $display("@%t, Srealtime), // @3 141ns end endmodule 17.6. Finite State Machines Пример с листинга 17.20 представляет синтезируемую поведенческую модель автомата, использующую три процедурных блока для вычисления еле дующего состояния, значения выходной функции и регистра состояния Пример представляет простой контроллер светофора Три состояния автомата описаны с помощью переменной типа перечисления. Листинг 17 20 SystemVenlog-модель управляющего автомата module trafficjight (output logic greenjight, yellowjight, redjight, input [15 0] green_downcnt, yellow_downcnt, input clock, resetN) // Использование типа перечисления для переменных состояний enum {RED, GREEN YELLOW} State, Next, alwaysjf @(posedge clock neqedge resetN) if (tresetN) State <= RED, // Сброс в состояние RED else State <= Next, aways_comb begin set _next_state Next = State, // Значение по умолчанию unique case (State) RED- if (sensor) Next =• GREEN, GREEN if (green_downcnt == 0) Next = YELLOW, YELLOW- if (yellow_downcnt == 0) Nex* = RED, endcase end set_next_state a!ways_comb begin set_outputs {greenjight, yellowjight, redjight} = З'ЬООО, unique case (State) RED redjight = 1'M, GREEN greenjight = 1'M, YELLOW yellowjight = 1'M endcase end set_outputs endmodule
333 17.7. System Verilog FIFO example Представлен пример описания достаточно популярной синхронной памяти FIFO размером в четыре 16-битовых слова и простейшего testbench, ориентированною на проверку функциональности. FIFO, по существу, - это циклическая очередь, интерфейс которой представлен на рис. 17 1. 17.7.1. System Venlog-модель устройства. Устройство содержит указатели для точек записи (регистр head) и чтения (решстр tail) данных (листинг 17.21). Сче1чик count представляег собой количество информации, записанной в память FIFO. Сигналы emptyp (пустая память) и fillip (память заполнена) формируются на основе данных счетчика counts Сброс состояния памяти в начальное, кетда все регистры равны нулю, выполняется сигналом rstp=l. Вход din и выход dout данных описан с применением типа данных packet_t Этот же тип данных может быть использован при описании fifomem массива памяти Запись в память выполняется по фронту синхросигнала, если wntep=l. Процедура чтения данных управляется сигналом Интерфейс памяти FIFO Листинг 17.21 SystemVerilog-модель синхронной памяти FIFO typede> struct packed { mt dst, logic [31.0] data, } packetj, module fifo ( input elk, input rstp, input packeM dm, input readp, wntep output packeM dout, output logic emptyp, output logic fullp), mti, parameter DEPTH = 2, MAX_COUNT = (1«DEPTH), reg[(DEPTH-1)0]tail, reg[(DEPT4-1)0]head, reg [(DEPTH) 0] count, // 2-битовый параметр, задающий размер памяти, // т е 4 слова FIFO // Формирование максимального адреса FIFO // Указатель на точку чтения // Указатель на точку записи // Счетчик pi
334 packetj fifomem[0 MAX_COUNT], // Массив памяти always @(posedge elk) if(rstp==1) dout <=-{default 0}, else dout <= fifomem[tail]; // Обновление памяти FIFO always @(posedge c!k) if (rstp) fifomem='{defau!t 0} else if (wntep == 1'bl && fullp =- 1'bO) fifomem[head] <= dm, // Обновление указателя точки записи head always @(posedge elk) if (rstp == 1'M) head <= 0, eise if (wntep == 1'M && fullp == 1'bO) head <= head + 1, //WRITE // Обновление регистра чтения tail always @(posedge elk) if (/sip == 1'M) tail <= 0, else if (readp == 1'M && emptyp == 1'bO) tail <= tail +1, //READ // Обновление счетчика количества данных count always @(posedge elk) if (rstp == 1'M) count <= 0, case ({readp, wntep}) 2'b00 count <= count, 2'b01 // Запись данных if (ifulip; count <= count A 1, 2'MO // Чтение данных if (!emptyp) count <= count - 1, 2'b 11 // Одновременное выполнение операций // чтения и записи, // счетчик count не меняется endcase always @(count) if (count == 0) emptyp = 1'M else emptyp = 1'b0, always ©(count) if (count < MAX_COUNT) fullp =1'b0, else
335 fu«p= 1'M, endmodule 17.7.2 System Venlog FIFO tcstbench. Листинг 17.22 представляет собой testbench для верификации поведения FIFO. Он содержит две задачи" чтения (readword) и записи (write_word) данных в память, с помощью которых реализованы два последовательно выполняемых теста - testl и test2. Test2 моделирует нормальную работу FIFO с помощью двух параллельных потоков, выполняющих чтение и запись Поток Writer наблюдает за значением сигнала fullp и случайным образом формирует входные значения, а также задержку между подачей этих значений. Кроме того, он фиксирует количество записанных в память данных. Поток Reader наблюдает сигнал emptyp и выполняет считывание данных со случайным интервалом Значения флагов empty/full меняются в зависимости от задержки, формируемой случайным образом Листинг 17 22. Testbench для верификации поведения IIFO module test_fifo, reg elk, rstp, packetj packetjn, packet_out, reg readp, reg wntep, wire emptyp, fulip, parameter depth = 2, fifo#(depth+1)U1 (clk(cik) rstp (rsto), din (packetjn) readp (readp) wntep (wntep), dout (packet_out), erriDtyp (emptyp) fullp (fullp)) task read_A'ord @(negedge elk), readp = 1, ©(pObedge elk) #5, Sdispiay ("Read %h from FFO", packet „out sre), endtask task wnte_word(byte arc, dst, logic [3 0] data) @(negedge elk), packetjn = '{src.dst.data}, wntep = 1, @(posedge elk), Sdispiay ("Write %h to FIFO" sre), #5, packetjn = '{defaulf'z}, writep = 0, endtask initial begin cik = 0, forever #10 elk = -elk, initial begin
test"!, test2, packetj n = '{default 'z}, writep - 0, readp = 0, rstp=1, #50, rstp -- 0, #50, wnte_word(0,1,16'h1111), wnte_word(1,2,16'h2222), write_word(3,4,16'h3333), read_word, read_word, write_word (5,6,16'h4444), repeat (6) read_word, write_word (0,1,16'h0001), wnie_word(0,1,16'h0002), write_word(0,1,16'h0003), wr,te_word(0,1,16'h0004), write_word (0,1,16'h0005), wnte_word (0,i,16'h0006), write_word (0,1,16'h0007), wnte_word (0,1,16'h0008) repeat <8) rpsd_word $display("DoneTEST1 "), // Запись трех значений // Чтение двух значений // Запись значения re // Чтение пакета значений // Запись пакета значений task test2, reg[15 0]wnter_cou.nte-, begin packetjn = '{defauit.'z}, wnter_counter = 16'h0001; writep = 0, readp = 0, // Сброс rstp= 1, #50 rstp = 0, #50, fork begin: Writer repeat (500) begin @(negedge elk), // Запись значений в п;
337 if (fuilp == 1 'ЬО) begin write_word (Srandom,$random,$randnm), #5 writer_counter = wnter_counter + 1, end else Sdisplay ("WRITER 's waiting "), // Псевдослучайное значение задержки от Ons до 100ns #(50 + (Srandom % 50)), Sdisplay ("Done with WRITER fork ").; #200 Sftnish, begin Reader // Чтение информации forever beg'n @(negedge elk) if (emptyp == 1'b0) read_word, else Sdisplay ("READER is waiting "), // Случайным образом формирующееся значение задержки от 0ns до 100ns #(50 + (Srandom % 50)), end join endtask always @{fullp) Sdisplay ("fillip = %0b", fuilp), always @ (emptyp) Sdisplay ("emptyp = %0b', emptyp), always @(U1 head) Sdisplay ("head = %0h" U1 head) always @(U1 tail) Sdisplay ("tail = %0h", U1 tail), endmodule На рис. 17.2 представлены временные диаграммы тестирования и верификации основных режимов памяти путем визуализации ее переменных и параметров. 17.8. Конгрольные вопросы и задания 1. Что означает следующее выражение? logic [7 0] opcode, if (opcode =="? 8 Ы1011?-?"?) 2. Какое значение получит переменная у, если а=10019 assign у = (а =="? 4'Ы""1), 3. Какое значение получит переменная у, если а=11119 assigny = (a=='?4b1,"1),
338 4. Какое значение получит переменная у, если а-~0001? assign у = (а ==? -Wl), 5. Какое значение получит переменная у, если а^=1??1? assigny = (a==-?4'M'"1) 6. Какую ошибку содержит следующее выражение? а) always_comb @(clk) б) a!ways_ff @(clk) Рис 17 2 Временные диаграммы моделирования памяти
18. SYSTEM VERILOG ИЕРАРХИЯ ПРОЕКТА 18.1. Прототип модуля Прототип модуля создастся с помощью ключевого слова extern, за которым следует декларация модуля и его портов // Прототип модуля с использованием стиля Venlog-1995 extern module counter (cnt, d, dock resetN), // Прототип модуля с использованием стиля Verilog-2001 extern module counter #'parameter N = 15) (output logic [N 0] cnt, input wire [N 0i d, input wire cIock, load, resetN), Если прототип модуля существует, при его определении можно не повторять объявления портов, а использовать фупповой символ (.*) (листинг 18 1). Листинг 18 1. Создание модели модуля при использовании его прототипа extern modu'e counter #(parameter N=15) (output logic (N-0] cnt input wire [N 0] d, input wire dock, load, resetN), module counter ( *) always @(posedge clock, negedge resetN) oegin if (iresetN) cnt <= 0, else if (load) cnt <= d, end endmodule Имя модуля может быть указано в конце кода- endmodule <module_name> В SystemVerilog появляется возможность создавать вложенные модули, которые определяются внутри другого модуля (листинг 18,2. рис 18 1) Листинг 18.2. Иерархическая модель с вложенными модулями module chip (input wire clock), // Проект верхнего уровня dreg И (dock), ip_core i2 (clock), endmodule cnio module dreg (input wire clock), // Декларация глобального модуля endmodule dreg module ip_core (input wire clock), // Декларация глобального модуля suM u1 ( ), sub2 u2 (...) moduiesjM( ), // Декларация вложенного модуля
340 endmodule suM module sub2( ), // Декларация endmodule sub2 endmodule ip_core chip dicg j subl J sub2 Рис !8 1 Иерархическая модель Вложенные модули MOiyT быть расположены в разных файлах Для включения их в модель может быть использована директива 'include (листинг 18 3) Это упрощает анализ и работу с такими моделями Листинг 18 3 Использование директивы 'include для вложенных модулей module ip_core (input logic clock), include suM v // Вложенный модуль subl include sub2 v // Вложенный модуль sub2 endmodule module sub1( ), // Декларация модуля в файле suM v endmodule module sub2( ), // Декларация модуля в файле sub2 v endmodule После компиляции вложенный файл будет вк шчен в родительский модуль (листинг 18.4) Вложенные модули могут бьиь использованы внутри модуля, в котором они определены, и вниз от него по иерархии (рис 18 2). Листинг 18 4. Иерархическая модель с вложенными модулями module ip_core (input clock), subl u1 {...), II Копия вложенного модуля suM module subl ( ), // Определение вложенного модуля sub2 u2 0. endmodule subl module sub2, // Определение вложенного модуля // модуль sub2 не имеет портов, но может обращаться II к коду родительского модуля (ip_core) вложенного модуля _' . I .
341 sub3u3{ ), endmoduie sub2 module sub3 { ); // Определение вложенного модуля endmoduie sub3 endmoduie ip_core Рис 18 2 Иерархическая модель с вложенными компонентами 18.2. Соединение портов В Verilog использовалось соединение сигналов по позиции или по имени. System Verilog предлагает три упрощенные формы описания связей портов: 1) .name ("dot-name") соединение портов; 2) .* ("dot-star") соединение портов; 3) с помощью интерфейсов SystemVenlog выполняет соединение портов с совпадающими по имени сш- налами, упрощая выражение Verilog data(data) (листан! 18.5. а) до data в System Verilog (лисшш 18 5, б) Соединение * (листинг 18 5, в) связывает все порты с соответствующими по имени сигналами Листинг 18.5 Примеры соединений портов a) //Venlog стиль // Копия модуля с именным соединением портов pc_stack pes ( prograrn_counter(program_counter), .program_address(program_address), clk(clk), resetN(resetN), .instruct_reg(mstruct_reg), data_bus(data_bus), status_reg(status_reg)}, pram prom (dout(program_data), .clk(clk), address(program_address)), 6} II SystemVenlog стиль с использованием name II Копия модуля с соединением портов name pc_stack pes ( program_counter, program_address, elk, resetN, (nstruc!_>'eg, data_bus status_reg); prom prom (
342 dout(program__data), elk, address(program_adaress)) в)'/ SystemVenlog стиль с использованием * '/ Копия модуля с соединением портов * pc_stack pes (*), Drom prom (*, dout(program_data), address(program_address)), 18.3. Псевдонимы цепей Псевдонимы цепей позволяют использовать два различных имени для обращения к одной линии wire clock, wire elk, alias elk = clock, В следующем примере множественных псевдонимов wire reset, rst resetN, rstN, alias rst = reset; alias reset = resetN, alias resetN = rstN, все имена указывают на одну линию Не важно, в каком порядке выполняется связь имен, поскольку оператор alias не является оператором присваивания Псевдонимы могут быть использованы только для цепей и должны быть одно! о типа- wire [3 0][7 0] п2 aims n2 = n1, '/ Ш и п2 имеют размер 32 бита wire [39 0] djn, - wire [7 0j ere, wire [31 0] data, anas data = o_in[3i 0], // Цепь размером в 32 бита alias crc = d_in[39 32], // Цепь размером в 8 бит Использование псевдонимов с конструкциями .name и .* позволяет значительно упростить запись связей между портами в иерархических проектах. Листинг 18 6 представляет структурную SystemVenlog-модель устройства (рис 18.3) с использованием символа «.*» связи портов без псевдонимов. Этот же пример с применением псевдонимов приведен в листинге 18.7. Листинг 18 6. Использование соединения портов System Verilog * без псевдонимов module chip (input wire master_clock input wire master_reset ) wire [31.0] address, new_address, next_address, ROM i1 ( *, // Обозначает address(address) data(new_ address), clk(master_clock)), Dfogram_count i2 ( *, II Обозначает next_address(iext_address)
jump_address(new_address), clock(master_clock), reset_n(master_reset)), address_reg i3 ( *, // He соответствует никаким соединениям next, addr(next_address), current_addr( address), clk(master_clock) rstN(master_reset)), endmodule module ROM (output wire [31 0] data, input wire [31 01 address, input wire elk), endmodule module program_count {output logic [31 0] next_address, input wire [31 0J jump_address, input wire clock, reset_n) endmodule module address_reg (output wire [31 0] current_addr, input wire [31 0] next_addr, input wire c!k, rstN), endmodule I „Г ROM address oik new address Г . _ I. address program nextjaddress master reset next address Г I reg rstN Рис 18 3 Структурная схема усфойства Листинг 18 7. Использование соединения портов SystemVenlog .* с приме- л псевдонимов module chip (input wire master_c!ock, input wire master_reset, ), wire [310] address, data new_addrebs, jump_address, next_address next_addr, current_addr, alias cik = dock = master_clock, alias rstN = reset_n = master_reset, alias data = new_address = jump_address, alias next_address = next_addr alias current_addr = address, ROMil ( *),
344 program_count i2 ( *) address_reg '3 ( *) endmodule module ROM (output wire [31 0] data, input wire [31.0] address, input wire elk), endmodule module program_count (output logic [31 0] next_address, input wire [31 0] new_count, .,: input wire clock, reset_n), ; endmodule module address_reg (output wire [31.0] address, Input wire [31 0] next_address, input wire elk, rs4M), endmodule 18.4. Передача данных через порты модуля В SystemVerilog сняли офаничения на использование типов данных при связывании с входными и выходными портами в структурных моделях (листинг 18 8) Через порг могут быть переданы: 1) любые скалярные данные; 2) упакованные и неупакованные массивы любой размерности; 3) структуры и объединения Листинг 18 8 Передача структуры и массива через порты typedef struct packed { logic [ 3 0] opcode, logic [15 0] operand, } instruction^, module decoder (output logic [23 0] microcode, input instructional instruction input logic [23-0] LUT [0 (2**20) 1]), // Остальные операторы модели endmodule ;- moduleDSP : '■'■-• (input logic clock, resetN, input logic 13.0] opcode, ' " • input logic [15 0] operand, output logic [23 0] data ), logic [23 0] LUT [0 (2**20)-1J, // Определение таблицы instruction^ instruction, logic [23 0] microcode, ' ■■-.i\'- aecoder i1 (microcode, instruction, LUT), // Операторы модели endmodule
345 18.5. Ссылочные порты (Reference ports) В SystemVerilog добавлен четвертый тип портов - ссылочный, который обозначается как ref. В этом случае выполняется передача иерархической ссылки на порт вместо самого значения (листинг 18.9) Ссылочные порты не синтезируются. Листинг 18.9. Передача ссылки на массив через ref-порт модуля typecief struct packed { logic [ 3 0] opcode logic [15 0] operand, module decoder (output logic [23 0] microcode, input instructional instruction, ref logic [23.0] LUT [O.(2**20>1]). // Операторы модели endmodule module DSP (inDut logic clock, resetN, input logic [ 3 0} opcode, input logic [15 0] operand, output logic [23.0] data ), logic [23 0] LUT [0 (2"20)-1], // Определение таблицы instruction^ instruction, logic [23 0] microcode, decoder i1 (microcode, instruction LUT), //Операторы модели endmodule Два различных стиля описания портов: // Vertlog-2001 стиль module accum (inout wire [31 0} data, output reg [31 0] rcsjit, output reg со, input [31 0]a, b, input tn1 ci), endmodule /' SystemVerilog стиль module accum (wire [31 0] data, ....■■, output reg [31 0] result, reg со, input [31 0]a, b.tril ci); endmodule Если направление порта не указано, то в SystemVerilog по умолчанию используется тип порта inout. 18.6. Параметризированные типы данных Venlog позволяет использовать параметры и локальные параметры для настройки размеров типов данных. SystemVerilog предлагает параметризнро-
346 ванные типы данных, которые объявляются с помощью пары ключевых слов parameter type. Если в Verilog параметры использовались для определения размера векторов, то в System Verilog парамефизирусмые типы данных используются для изменения типов данных. Параметризируемые типы являются синтезируемыми, если используют синтезируемые типы данных. В примере (листинг 18.10) тип данных сумматора ADDERTYPE является параметризируемым и по умолчанию определяется как shonint. Модуль big_chip содержи! три копии сумматора Копия i! использует тип данных сумматора, «данный по умолчанию, создавая 16- разрядный знаковый сумматор. Копия i2 изменяе) тип неременной mi, формируя 32-разрядный знаковый сумматор Копия i3 преобразует тип переменной в tnt unsigned, формируя 32-битовый беззнаковый сумматор. Листинг 18 10 Полиморфный сумматор с параметризируемыми данными module adaer #{parameter type ADDERTYPE = shortint) (input ADDERTYPE a, b, /,' переопределяемый тип output ADDERTYPE sum, '/ переопределяемый тип output logic carry), ADDERTYPE temp, // локальная переменная переопределяемого типа // Функциональность сумматора endmodule module big_chip( ), shortint a b, r1, int c, a, r2, int unsigned e, f, r3; wire carry"!, carry2, саггуЗ, // 16-битовый беззнаковый сумматор adder И (a, b, r1, carryl) // 32- битовый знаковый сумматор adder #( ADDERTYPE(int)) i2 (c, d, r2, carry2), /< 32- битовый беззнаковый сумматор adder #( ADDERTYPE(int unsigned)) i3 (e, f, r3, саггуЗ) endmodule 18.7. Контрольные вопросы и задания 1 Какие методы связи портов отличные от Verilog, введены в SystemVenlog7 2 Создать прототипы компонентов и структурные модели устройства с использованием стилей name и.* (рис. 18.4). 3 Определить псевдонимы для reset_п и clr_n и структурные SystemVenlog- модели устройства (рис 18.5). Для компонентов записать только декларацию интерфейсов модулей
J47 4. Создать модель устройства умножения с параметризируемыми типами данных операндов. По умолчанию устройство должно работать 8-битовым вектором типа logic. Создать модуль верхнего уровня, подключающий копию компонента устройства умножения, в котором тип данных операндов переопределяется на int. mcrO valO_reg butt) Рис 18 4 Пример схемы устройства Рис 18 5 Пример схемы устройства
19. ИСПОЛЬЗОВАНИЕ ИНТЕРФЕЙСОВ 19.1. Концепция интерфейса Для выполнения связей между модулями Venlog использует поргь Дтя больших проектов запись такого способа соединений становится очень сложной Пример (рис. 19 1, листинг 19.1) представляет пять блоков, соединенных вместе с помощью шины mam_bus, кроме этого, присутствуют дополнительные прямые связи между отдельными блоками Internal Memory .,„ j Instruction Fetch Master Processor | main bus j j 1 j Test Generator Slave Processor j Рис 19 1 Структурная схема устройства с шинной архитектурой Листинг 19 1 Структурная Venlog-модель устройства // Модуль верхнего уровня module top (input wire clock, resetN test_mode), wire [15 0) data, address, program_address, jump_address, wire [ 7 0] instruction, nextjnstruciion, wire [ 3 0] slavejnstruction, wire slave_request, slave_ready, wire bus_request, bus__grant, wire memj-ead, mem_write, wire datajready, processor prod ( // Порты для связи с шиной mam_bus data(data), address(address), .slave__instruction{siave_instruction), slave_reauest(slavej"equest), ousjgrant(bus__grant), mem_read (m em__read), mem_wnte(mem_wnte), bus_requestCbus_request), slave_ready(slave_ready), // Остальные порты jump_address(jump_addressX instruction( instruction), clock(clock) resetN(resetN), test_mode(test_moae)), slave slavel { // Порты для связи с шиной main_bus data(data), .address(address), bus_request(bus_request),
349 slave_ready(slave _ready), mem_read(mem_read), mem_wnte(mem_wnte), slave_instruction{sIave_instruction), slave_request(slave_request), bus_grant(bus_grant), data_ready(data_ready), // Остальные порты clock(clock), resetN(resetN)), dual_port_ram ram { // Порты для связи с шиной mam_bus data(data), data_ready(aaia_ready), address(address), mem_read(mern_read), mem_wnte(mem_wnte), // Остальные порты program_address(program_address), data_b(next_instruction)); test_generator test_gen( II Порты длр связи с шиной main_bus daia(data), address(address), mem_write(mem_wnte), // Остальные порты c!ock(ctock), resetN(resetN), test_mode(test_rnode)), <nstruction_reg ir ( prograrn_address(program_address) instruciion(mstruction), jump_addressQump_address), nextjnstruction(nextjnstruction) с1осЦ clock), reseiN(resetN)), endmoduie // Определение модулей / module processor ( // Порты для связи с шиной main_DUS mout wire [15 0] data, output reg [15 0] address, output reg [ 3 0J slavejnstruction, output reg slave_request, output reg bus_grant, output wire mem_read, output wire merp_wnte, input wire bus_request, input wire siavej-eady, // Остальные порты output reg [15.0] jump_address, input wire [ 7 0] instruction,
350 input wire clock, input wire resetN, input wire test_mode), // Функциональный код модуля endmoduie module slave ( // Порты для связи с шиной main_bus in out wire [15 0] data, inout wire [15 0] address, output reg bus_request, output reg slave_ready, output wire mem_read, output wire mem_write, input wire [ 3 0J slavejnstructton, input wire slavej-equest, input wire bus^grant, input wire data_ready, // Остальные порты input wire clock, input wire resetN), // Функциональный код модуля endmoduie module dual_port_ram ( // Порты для связи с шиной main_bus inout wire [15 0] data, output wire data_ready input wire [15 0] address, input triO mem_read, input tnO mem_wnte, // Остапьные порты input wire [15 0J program_address, output reg [ 7 0] data_b), // Функциональный код модуля endmoduie module test_generator ( // Порты для связи с шиной mafn_bus output wire [15 0] data, output reg [15 0] address, output reg mem_read, output reg rnem_wnte, //Остальные порты input wire clock input wire resetN, input wire test_mode) // Функциональный код модуля endmoduie module instruction_reg { output reg [15 0] program_address.
351 output reg [ 7 0] instruction, input wire [15 0] jump_address, input wire [ 7 0] next instruction, input wire clock, input wre resetN), // Функциональный код модуля endmodule К недостаткам портов в больших Venlog проектах можно отнести: 1) декларации дублируются в нескольких модулях; 2) коммуникационные протоколы дублируются в нескольких модулях, что повышает возможность возникновения ошибки в декларациях различных модулей, 3) изменение в спецификации проекта требует выполнения модификации в нескольких модулях. SystemVcrilog предлагает новую мощную конструкцию для описания портов - интерфейс Интерфейс позволяет группировать сигналы вместе, при этом каждый модуль, использующий сигналы из интерфейса, рассматривает его как единый порт (листинг 19.2). В интерфейсе mambus описываются сигналы устройства, а в модуле верхнего уровня top создается копия интерфейса bus, которая выполняет связь компонентов. Кроме этого, декларация интерфейса указывается в списке портов каждого модуля Листинг 19 2. Выполнение связей модулей с помощью SystemVerilog // Декларация интерфейса interface mam_bus, wire [15 0] data, wire [15 0] address, logic [ 7 0J slavejnstruction, logic s!a\,e_request, logic bus_granf, logic bus_request, logic slave_ready; logic data_ready, logic memj-ead, logic mem_wnte, endmterface // . Модуль верхнего уровня module top (input logic clock, resetN test_mode), logic [15 0] program_address, |urnp_address, logic [ 7 Oj instruction, nextjnstruction, mam_bus bus (), // копия интерфейса с именем bus processor prod ( // Порты шины main_bus bus(bus), // Подключение интерфейса // Остальные порты jump_address(jump_address),
352 instruction(instruction) clock(clock), resetN(resetN), test_mode(test_mode)), slave slavel ( // Порты шины mainjws bus(bus), / / Подключение интерфейса // Остальные порты clock(clock), resetN(resetN)), dual_port_ram ram ( // Порты шины main_bus bus(bus), // Подключение интерфейса // Остальные порты program_address(program_address), data_b{nextjnstruction)), test_generator test_gen( // Порты шины main_bus bus(bus), // Подключение интерфейса // Остальные порты ciock(clock), resetN(resetN), test_mode(test_mode)), instruct!on_reg ir ( prograrn_address(program_address), mstruction(instruction), jump_address(]ump_address), nextjnstruction{next_jnstruction), clock(clock), resetN(resetN)), endmodule // Определение модулей module processor ( // Порты интерфейса main_bus main_bus bus, // Порты интерфейса // Остальные порты output logic [15 0] jump_aadress, i"put logic [7 0] instruction, input logic clock, input logic resetN, input logic testjnode), // Функциональный код модуля endmodule module slave ( // Порты интерфейса mam_bus mam_bus bus, // Порты интерфейса // other ports input logic clock, input logic resetN), II Функциональный код модуля endmodule module dual_port_ram ( II Порты интерфейса main_bus main_bus bus, // Порты интерфейса // other ports input logic {15 Oj program_address,
353 output logic [ 7 0] data_b), // Функциональный код модуля endmodule module test_generator ( // Порты интерфейса mam_bus main_bus bus, // Порты интерфейса // other ports input logic clock, input logic resetN, input logic testjnode), // Функциональный код модуля endmodule module instruction_reg ( output logic [15.0] program_address, output logic [ 7 0] instruction, input logic [15.0] jump_address, input logic [ 7 Oj next_instruction, inpui logic clock, input logic resetN), // Функциональный код модуля endmodule Интерфейс позволяет: дискретные сигналы и порты могут быть определены в одном месте; коммуникационный протокол; выполнять проверку и верификацию подпрограмм прямо в интерфейсе. Интерфейс может содержать декларацию типов, задач, функций, процедурных блоков, программных блоков и ассерций. Интерфейс позволяет определять множественные ею вилы. Например, для каждого модуля, подключаемою с помощью интерфейса, сигнал data_bus может быгь входом, выходом и двунаправленным портом. Предпочтительнее использовать тип logic для описания сигналов в интерфейсе, это позвалиi передавать им значения с помощью процедурных операторов. Основные отличия между интерфейсом и модулем- 1) интерфейс не может содержать описание иерархии проекта; 2) нельзя использовать модуль в списке портов, 3) интерфейс может включать конструкцию modport. Листинг 19.3 представляет определение интерфейса mambus, использующего три внешних сигнала, которые входят в интерфейс, clock, resetN и test_mode. Они могут быть подключены к каждому модулю через интерфейс без выполнения явно1 о соединения сигналов в каждом модуле. Для описания внешних сигналов (в примере это clock, resetN и testjnode) интерфейса используется тот же синтаксис, что и для соединения сигналов в модуле. Листинг 19 3 Определение интерфейса для mainbus с внешними входами //. Декларация интерфейса interface main_bus (input logic clock, resetN, testjnode), wire [15 0] data,
wire [15 0] address, logic [ 7-0] slavejnstruction, logic slave_request, logic bus_grant, logic bus_request, logic slave_ready, logic data_ready, logic mem_read, logic mem_wnte, endmterface // Модуль верхнего уровня module top (input logic clock, resetN, test_mode), logic [15 0] program_address, jump_address, logic [ 7 0] instruction, nextjnstruction, main_bus bus ( clock(clock), resetN(resetN), test_mode(test_mode)), // копия интерфейса processor prod (// main_bus ports bus(bus), // interface connection // other ports jump_address(jump_address), mstruction(instruction)), /*** remainder of netlist and module definitions are not ***/ /*** listed — they are similar to example 10-2, but ***/ /*** clock and resetN do not need to be passed to each "7 /*** module instance as discrete ports ***/ Упрощенное соединение портов System Verilog с помощью стилей name и .* может быть использовано и для интерфейса. Пример с листинга 19.4 может иметь более компактный вид, благодаря комбинации использования интерфейсов и соединения портов .*. Листинг 19.4. Упрощение соединения портов // Декларация интерфейса interface main_bus (input logic clock, resetN, testjnode), w,re [15 0) data, wire [15 0] address, logic [ 7 0] slavejnstruction, logic slave_request, logic bus_grant, logic bus_request, logic slave_ready, logic dataj-eady, logic mem__read, logic mem_wrste endmterface // Модуль верхнего уровня module top (input logic clock, resetN, test_mode), logic [15 0] program_address, jump_address,
355 logic [ 7 0] instruction nextjnstruction, data_b, main_bus bus { *), processor prod ( *), slave slavel ( *), instruct'on_reg т ( *), test_generator test_gen { *}, dual_port_ram ram ( *, data_b(nextjnstruction)), endmodule /*** remainder of netlist and module definitions are not **7 /*** listed — they are similar to example 10 2, but ***/ /*** cIock and resetN do not need to be passed to each ***/ /*** module instance as discrete ports ***/ 19.2. Описание портов с помощью интерфейса и обращение к ним Описание портов модуля может быть выполнено с помощью ключевого слова interface или указания конкретного типа интерфейса. Синтаксис: module <moduie_name> (interface <port_name>) или module <module_name> (<interface_name> <port_name>), Например: module CACHE (interface pins, // interface port input clock), endmodule interface chip_bus, endinterface module CACHE (chip_bus pins, // interface port input clock); endmodule Обращение к сигналам в интерфейсе выполняется с помощью иерархического имени, в первой части которого указывается имя копии интерфейса. Синтаксис intemaljnterface_s!gnal__name> <port_naTie> Сигналы интерфейса должны получать значения с помощью неблокирующих операторов. В примере определение интерфейса mam_bus содержит декларацию сигналов clock и resetN. Модуль slave использует интерфейсный порт с bus Модуль slave имеет доступ к переменной интерфейса clock, применяя ссылку bus clock Например, always @(posedge bus clock, negedge bus resetN) Листинг 19.5 представляет фра! мент кода модуля slave. Модуль содержит несколько обращений к сигналам интерфейса main_bus
Листинг 19 5. Обращение к сигналам интерфейса module slave ( // Порты интерфейса main_bus mam_bus bus // other ports), // internal signals logic [15 0] slave_data, slave_address, logic [15 0] operand_A, operand_B, logic mem_select, read, write, assign bus address = mem_select'? slave_address z, assign bus data = bus.slavej-eady? slave_data 'z enum logic [4 0] {RESET = 5'b00001, START = 5'b00010 REQ_DATA = 5'b00100, EXECUTE = 5'b01000, DONE = 5'ЫОООО} State, NexiState, always_ff @(posedge bjs clock, negedge bus resetN) begin FSM if (ibus resets State <= START, else State <= NextState end always_comb begin FSM_decode unique case (State) START if ('bus slave_request) begin bus bus_request = 0 NextState = State, else begin operand_A = bus data, slave_address = bus address, bus bus_request = 1, NextState = REQ_DATA, // decode other states endcase end FSM_decode endmodule 19 2 1. Соединение интерфейсов и портов. Для модуля, порты которого не могут быть изменены с использованием интерфейса, можно просто соединить сигналы интерфейса с отдельными портами, как это сделано для модуля arb__porr Листинг 19.6. Соединение сигналов интерфейса module top, bit elk; akvays #5 elk = ~clk, arbjf arbif(clk), // создание копии интерфейса arb_port a1 ( grant (arbtf grant), // подключение компонента к request (arbif request), // интерфейсу reset (arbif reset),
357 elk (arbif elk)), test tl(arbif), // подключение модуля, использующего интерфейс endmodule top 19.3. Группирование сигналов с помощью modport В предыдущих примерах применялось соединение без указания направления си1 нала в интерфейсе. Однако один и тот же сш нал в различных модулях может И! рать различную роль. Например, для одного он будет входом, а для другого выходом. В этом случае такой порт внутри интерфейса объявляется как modport Конструкция modport позволяет группировать сшналы и описывать их направление, что дает возможноеib выполнять дополнительную проверку при передаче информации и исключать связанные с эгим ошибки. Modport определяет направление порта, которое соответствует модулю. Интерфейс может содержать любое число деклараций modport, каждая описывает один или несколько модулей, рассматривая сигналы в интерфейсе. Листинг 19.7. Определение направления порта interface chip_bus (input logic clock, resetN), iogic mterruptj-equest, grant, ready, logic [31 0] address, wire [63 0] data, modoort master (input tnterrupi_request, input address output grant, ready inout data input dock resetN i, modport slave (output mterrupt_request, output address input grant, ready, inout data, input clock, resetN) endinterface В конструкции modport не указывают тип данных или размер вектора Эта информация указывается при декларации сигналов интерфейса. Декларация modport описывает только направление порта* input, output, mout или ref SystemVenlog предлагает два метода для указания применяемого вида modport: 1) в операторе реализации копии компонента; 2) в декларации портов модуля при его определении. Оба стиля спецификации являются синтезируемыми Первый стиль при создании копии модуля и копии интерфейса соединяется с портом копии модуля, при этом следующим образом может быть указан определенный modport: <имя копии модуля> <имя modporo Например. г" chip_bus bus, // instance of an interface primary it (bus master), // use master moaoort
Пример (листинг 19 8) иллюстрирует соединение двух модулей вместе с интерфейсом chip_bus. Модуль primary соединяется с интерфейсом в режиме mabter, а модуль secondary- в режиме slave Листинг 19.8 Выбор режима modport в момеш создания копии модуля interface chip_bus (input logic clock, resetN), modport master ( ), modport slave ( ), ( endinterface module primary (interface pins), // Абстрактный порт интерфейса endmodule module secondary (chip_bus Dins), // Определенный порт интерфейса ' endmodule ,. module chip (input logic clock, resetN), .. chip_bus bus (clock, resetN), // Копия интерфейса Drimary i1 (bus master), // Использование режима modport secondary i2 (bus slave), // Использование режима slave endmodule Если modport указывается в декларации интерфейса модуля, то применяется синтаксис <имя интерфейса> <имя modport> Например, для листинга 19.8 module secondary (chip_bus slave pins), endmodule В эгом случае должно быть указано явное имя интерфейса Тогда в операю- ре реализации копии модуля приводится только имя копии интерфейса без описания режима modport. Пример (листинг 19.9) представляет запись режима modport в декларации портов модуля. Листинг 19.9. Выбор режима modport в момент описания портов модуля interface chip_bus (input logic clock, resetN), modport master ( ), modport slave ( ); endinterface module primary (chip_bus> master pins), // Использование режима master endmodule module secondary (chip_bus slave pins) // Использование режима s! endmodule module chip (inout logic clock, resetN), chip_bus bus (clock, resetN), primary it (bus), // Копия интерфейса // Использование режима master
359 secondary i2 (bus), // Использование режима slave endmoduie Гаким образом, выбрать modport можно либо для копии модуля, либо при описании его портов, но никогда одновременно (листинг 19.10). В один момент допускается указывать тип modport только в одной из этих двух конструкций. Если направления портов не описаны, то по умолчанию все поргы интерфейса имеют режим inout и тип ref. Кроме зтого, в интерфейсе можно объявлять внутренние сигналы, являющиеся локальными для него. Листинг 19.10. Использование интерфейса с конструкциями modport // Определение интерфейса interface main_bus (input logic clock, resetN, test_mode), wire [15 0] data, wire [15 0] address, logic [ 7 0] slavejnstruction, logic siave_request, bus_ grant, bus_request, logic slave_ready. dataj-eady, logic mem_read, mem_write, modport master (inout data, output address, output slavejnstruction, slave_ request, output bus_grant, output memjead, mem_wnte, input busjequest, input slave_ready, dataj-eady, input clock, resetN, input testjnode 5, modport slave (irout data, inout address, output mem_read, mem_wnte output bus_request, siave_ready inout slavejnstruction, s!ave_request, input bus__grant, input data_ready input clock, resetN modport mem (inout data, output dataj-eady, input address, input mem_read mem_wnte ), endinterface //. Модуль верхнего уровня module top (input logic clock, resetN, test_mode), logic [15 0] program_address, jump__address, iogic [ 7 0] instruction nextj.nstruciion, data__b, main__bus bus ( * ), // Копия интерфейса
360 processor prod (,bus(bus master) *), slave slavel ( bus(bus siave), *), instnjction_reg ir ( *), test_generator test_gen ( bus(bus) *) dual_port_ram ram ( bus(bus mem), *, data_b(next_instruction)), endmodule 19.4. Использование задач и функций в интерфейсе Интерфейс может наследовать все детали коммуникационного протокола между блоками. Например, протокол mambus из предыдущего примера (см. листинг 19.10) содержит сигнал установления связи между главным процессом (master processor) и подчиненным устройством (slave) Главный процессор s Verilog модели должен был содержать код, который мог быть исполыован для установления и удаления сигнала квитирования в соответствующие моменты времени и отслеживания его изменения для второстепенного процессора. Описание всего протокола при создании интерфейса модуля ведет к возможности возникновения повторов кода. 19.4 1. Импорт задач и функций Бели интерфейс связывается через modport, то для импортирования методов необходимо использовать ключевое слово import, при ■этом они применяются как часть определения modport Простейшая форма импортирования задачи или функции просто описывает ее имя Синтаксис, modport (import <task function_name>), Пример использования modoorf in (import Rpad import panty_gen, input clock, resetN ) Второй стиль декларации import описывает полный прототип аргументов задачи или функции. Этот стиль требует, чтобы ключевые слова task или function следовали за ключевым словом import. 1акже требуется, чтобы за именем задачи и функции присутствовало множество формальных аргументов. Базовый синтаксис modport (import task <task_name>(<task_formal_argumepts)), modport (import function <function _narrm> (<formai_args>)), Например: modport in ( import task Read (input [63 0] data, output [31 Oj adaress), import function parity_gen (input [63 0] data), input clock, resetN), Вызов импортированных методов: <interface_port_name> <method_name>
361 Конструкция modport предлагает способ использования различных методов и протоколов в одном интерфейсе. Интерфейс может содержать различные методы, которые применяют различные протоколы или типы Следующий фрагмент кода иллюстрирует интерфейс mathbus. В интерфейсе определены различные методы чтения, работающие с целыми и вещественными типами данных. Два модуля вызывают integer_math_imit и floating_point_unit, оба имеют один и тот же интерфейс шины. Каждый модуль имеет доступ к различным типам информации Листинг 19.1 ]. Использование в интерфейсе modport для выбора альтернативных методов interface math_bus (input logic clock, resetN), int a_int, bjnt, resultjnt, real a_real, b_real, result_real, task IniegerRead (output int a int, bjnt), // Установление связи для захвата значений а и b endtask task FloatingPointRead (output real a_real, Ь_геаП, // Установление связи для захвата значений а и b endtask modport intjo (import IntegerRead, input clock, resetN, output resultjnt), modport fpjo (import FloatingPointRead, inpu* cIock, resetN output result_real), endmterface // , Модуль верхнего уровня module dualjnu (input logic clock, resetN), math_bus bus_a (clock, resetN), // Первая копия интерфейса math_bus bus_b (clock resetN), // Вторая копия интерфейса mteger_math_unit i 1 (bus_a intjo) // Подключение к интефейсу с использованием типа integer floatmg_pomt_unit i2 (bus_b fpjol, // Подключение к интефейсу с использованием типа real endmodule // Определение модуля module integer _math_unit (interface ю), int a_reg, b_reg, always @(posedge ю clock) begin io !ntegerRead(a_reg, b_reg), // Вызов метода интерфейса // Остальные математические операции end endmodule module fioatingjpointjjnit (interface ю),
362 real a_reg, b_reg, always @(posedge ю clock) io FloatingPomtRead(a_reg, b_reg), // Вызов метода интерфейса // Остальные математические операции endmodule Модули с импортированными из интерфейса функциями и задачами являются синтезируемыми. Системы синтеза создают локальную копию для каждой функции. Импортируемые задачи и функции должны быгь автомашчески- 19.4 2. Экспортирование задач и функций. SystemVenlog предлагает возможность выполнять определение задач и функций в одном модуле, а затем экспортировать их в другие модули через интерфейс (листинг 19.12 и 19.13). Экспортируемые задачи не синтезируются, допускается их использование только в абстрактных моделях Листинг 19.12 Экспорт функции из модуля через modport интерфейса interface chip_bus (input logic clock reseiN), logic request, grant ready logic [63 0] address, data, modport master (output request export check), modport slave (input request, import check ) endinterface module CPU (chipjaus master io), function check (Input parity 'nput [63:0] data) endfunction endmodule Конструкция export позволяет экспортировать задачи и функции из модуля в интерфейс через использование modport интерфейса Задача и функция может также экспортироваться в интерфейс без использования modport Это делается с помощью декларации внешнего прототипа задачи или функции. Листинг 19.13. Экспорт функции из модуля в интерфейс interface chtp_bus (input logic clock, resetN), logic request, grant, ready, logic [63'0] address, data, extern function check(mput logic panty, input logic [63 0] data), modport master (output request, ), modport slave (input request, import function check (input logic panty, input logic [63 0] data)), endinterface
363 module CPU (chip_bus master to), function check (input logic parity, input logic [63 0] data), endf unction endmodule Ограничения в экспортировании задач и функций. 1) Нельзя выполнять экспорт одного и того же имени функции из различных копий модуля 2) Нельзя экспортировать имя задачи из нескольких интерфейсов, использ>я декларацию extern forkrom. Задачи и функции могут быть определены в интерфейсе (листинг 19 14) или в одном, или в нескольких подключенных к интерфейсу модулях Это позволяет выполнять моделирование на более абстрактном уровне Например, "read" и "wiste" могут быть определены как задачи, без обращения к каким, либо линиям, a master может просто вызывать эти задачи. В конструкции modport такие задачи декларируются с помощью import. Прототип функции или задачи описывает тины данных и направления аргументов, возвращаемое значение функции, которая может быть определена в любом месте. При импорте функции или задачи только одно выражение может содержать конструкцию import Задача (и только, но не функция) может быть определена в модуле, который инициализируется дважды или ботее раз Такие задачи декларируются в интерфейсе с помощью конструкции extern forkjoin Листинг 19.14 Пример использования задачи в интерфейсе interface sinr:ple_Dus (input bit elk) // Определение интерфейса logic req, art logic [7.0] addr, data, logic [1-0] mode, logic start, rdy, task masterRead(mput logic [7 0] raddr), // метод masterRead // метод slaveRead // Используется абстрактный интерфейс // Сигнал elk из интерфейса // Сигналы gnt и req из интерфейса endtask masterRead task slaveRead, endtask slaveRead endmterface sirnpiej>us module rnemMod(interface a), logic ai/ail, always @(posedge a elk) always @(a start) a slaveRead endmodule module cpuMod(interface b),
enum {read, write} instr, logic [7 0] raddr, always @(posedge b elk) if (instr == read) b masterRead(raddr), // Вызов метода интерфейса endmodule module top, logic elk = 0, simple_bus sbjntf(clk) // Копия интерфейса memMod mem(sbjntf), cpuMod cpu(sb_intf); endmodule Пример интерфейса (листинг 19.15) представляет способ записи сигналов в modport для контроля их направления, а также задач доступа к сигналам для выполнения операций чтения/записи (read/write) Листинг 19.15. Пример использования задач в конструкции modport interface simple_bus (input bit elk), // Определение интефейса logic req, gnt, logic [7 0] addr, data, logic [1 0] mode; logic start, rdy, modport slave (input req, addr, mode, start, elk, output gnt, rdy, import slaveRead, slaveWnte), // Импорт в модуль, использующий данный modport modport master(input gnt, rdy, elk, ouiput req, addr, mode, start ref data, // Импорт задач в модуль, использующий данный modport import masterRead, masterWrite) task masterRead(mput logic [7 0] raddr), // Метод masterRead endtask task slaveRead, // Метод slaveRead endtask task masterWnie(input logic [7 0] waddr), endtask task slaveWnte, endtask endinterface' simple_bus module memMod(interface a), // Использование только интерфейса
logic avail, always @(posedge a elk) a gnt <= a req & avail, always @(a start) if(amode[0]==1'b0) a slaveRead, // Сигнал elk из интерфейса // Сигналы gnt и req из интерфейса a slaveWnte, endmodule module cpuMod( interface b), enum {read, write} instr = Srand(), logic [7 0] raddr = $rand{), always @(posedge b elk) if (instr == read) b masterRead(raddr), // Вызов метода интерфейса else b masterWnte(raddr), endmodule module omniMod( interface b), // Копия интерфейса // Доступ только к задачам slave // Доступ только к задачам master // Доступьь1 все задачи интерфейса endmodule omniMod module top, logic с!к = 0, simple_bus sbjntf(clk), memMod mem(sb_mtf slave), cpuMod cpu(sb_intf master), omniMod omni(sbjntf), endmodule Пример интерфейса с листинга 19 16 представляет способ определения задач в одном модуле и выполнения их вызова в другом, при этом управление доступом к задачам осуществляется через modport. Листинг 19.16. Пример экспортирования задач и функций interface simple_bus (input bit elk), // Определение интерфейса logic req, gnt, logic [7 0] addr, data, logic [1 0] mode, logic start, rdy, modport slave( input req, addr, mode, start, elk, output gnt, rdy, export Read,Write), //Экспорт! modport master(mput gnt, rdy, elk output req, addr, mode, start, ref data, import task Read(input logic [7 0] raddr), модуля, использующего modport
366 task Wnte(mput logic [7 0] waddr)), // Импорт требует // полного прототипа задачи endinterface simple_bus module memMod(interface a), // Использование абстрактного интерфейса task a Read, // Метод Read avail = 0, endtask task a Write, avail = 1, endtask endmodule module cpuMod(interface b) enum {read, write} instr logic [7 0) raddr, always @(poseage b elk) if (instr == read) b Read(raddr), // Зызов метода через интерфейс else bWnte(raddr), endmodule module top, logic elk = 0, simple_bus sbjntf(clk), // Копия интерфейса memMori mem{sb_intf slave), // Экспоот задач Read и Write cpuMod cpu(sb_intf master), // Импорт задач Read и Write endmodule 19 4 3 Пример множественного экспорта задачи Ошибкой является ситуация, если более одного модуля экепор1ируют одинаковую по имени задачу. Тем не менее, существуют ситуации, ко1да необходимо использовать несколько копий одного и того же типа modport, например, модулей памяти. Такие задачи должны быть определены с помощью ключевых слов extern forkjoin. Вызов extern forkjom task counts!aves(), будет вести себя как следующий оператор: fork top mem1 a countslaves, top mem2 a countslaves, join Для задачи чтения read task только о тин модуль создаст активный ответ при ее вызове, г е. только один будет содержать соответствующий адрес. Задачи в других модулях будут возвращаться без эффекта Только после этого будет
367 вызвана активная задача для записи переменных результата. В отличие ог задач, множественный вызов функций не разрешается, поскольку они всегда возвращают результат. Эффект использования оператора disable в задаче, которая определена extern forkjom task, будет следующим: 1) Ьсли обращение к задаче выполняется через копию интерфейса, то все вызовы задач будут завершены. 2) Если к задаче обращаются через копию модуля, го только одна задача, соответствующая этому модулю, будет завершена Рели интерфейс содержит задачу extern forkjoin task и ни один модуль, определяющий задачу, не подключен к интерфейсу, то каждое обращение к такой задаче приведет к появлению ошибки времени выполнения. Пример интерфейса (листинг 19.17) представляет задачи, определенные в нескольких модулях, и их вызов через extern forkjom. Механизм экспортирования множественных задач также может быть использован для подсчета копий определенного типа modport, которые подключены к каждой копии интерфейса. Листинг 19.17 Пример экспортирования задач и функций ■■■■ interface simple_bus {input bit elk), // Определение интерфейса logic req, gnt, logic [7 0] addr, data, logic [1 0] mode, logic start, rdy, int slaves - 0 // Задачи выполняемые параллельно, как блок fork/join extern forkjom task countS>aves(), extern forkjoin task Read (input iogic [T 0] raddr) extern forkjom tasK Write (input logic [7 0] wadarj, modport slave (input req.addr, mode, start, elk, output gnt, rdy, ref data, slaves, // Экспорт из модуля, использующего modport export Read, Write, countSlaves), modport master (input gnt, rdy, elk, output req, addr, mode, start, ref data, // При импорте требуется полный прототип задачи, * import task Read(mput logic [7 0] raddr), task Wnte(mput logic [7 0] waddr)), mitial begin countSlaves, • Sdisplay ("number of slaves = %d", slaves), end endmterface simple_bus
368 module mernMod #{parameter int minaddr=0, maxaddr=0,} (interface a), logic avail = 1, logic [7 0] mem[255 0], .. ■■<■■ task a countSlaves(), , v t -• as!aves++, endtask task a Read(mput logic [7 0] raddr), // Метод Read if (raddr >= minaddr && raddr <- maxaddr) begin avail = 0, #10 a data = memf/addr], ava'i=i, , ,-,:■ , endtask task a Writefinput logic [7 0] waddr), // Метод Write if (waddr >= minaddr && waddr <= maxaddr) begin avail = 0 #10mem[waddrl = adata, 1 avail =1, endtask endmodule module cpuMod(interface b), typedef enum {read, write} instr, instr inst, logic [7 0] raddr, integer seed, always @(posedge b cik) beg,n inst = instr'(Sdist_iiniform(seed, 0, 1)), raddr = $dist_uniforrn(seed 0 3), if (inst == read) begin $display("%t begin read %h @ %h", Stime, b data, raddr), cailr b Read(raddr), Sdisplay("%t end read %h @ %n", $time, b data, raddr), else begin $display("%t begin write %h @ %h", Stirne b data, raddr) b data = raddr, callwb VVrite(raddr), $displayf%t end write %h @ %h", Stime, b data, raddr); end end endmodule module top, logic elk = 0, function void interrupt), disable mem1 a Read, // Задача из копии модуля disable sbjntf Write, // Задача из копии интерфейса if (meml avail == 0) Sriisplay ("meml was interrupted"),
369 if (mem2 avail == 0) $display ("mem2 was interrupted'), endfunctson always #5 clk++, initial begin #28 interrupt), #10interrupt(), #100$finish, end simpie_bus sb_intf(clk), memMod#(0,127) mem1(sbjntf slave), memMod #(128, 255) mem2(sb_intf slave), cpuMod cpu{sb_intf master); endmodule 19.5. Реконфигурируемые интерфейсы Интерфейс может содержать процедурные блоки (always, always_comb, al- ways_ff, alwaysjatch, initial или final) и операторы непрерывного присвоения (assign) Интерфейсы могут использовать параметры для настройки размеров, которые могут меняться при создании копии интерфейса (листинг 19 18 и 19.19) Листинг 19.18. Параметризированные типы данных в интерфейсе interface math_bus #(parameter type DTYPE = int) (input logic clock), DTYPE a, b result, // Пзраметризированный тит task Read (output DTYPE a, b), // Считывание значений а и b endtask modport irttjo (import Read, input clock, output result), modport fpjo (import Read, input clock, output result); endinterface module top (input logic clock, resetN), math_bus bus_a(c!ock) // Использование данных int matb_bus (# DTYPE(real)} bus_b(clock), // Использование данных real integer_math_umti1 (bus_a mt_io), // Подключение к интерфейсу, использующему целочисленный тип floating_pcint_unit i2 (bus_b fpjo) // Подключение к интерфейсу, использующему вещественный тип floating_point_unit i2 (bus_b fp jo); endmodule//end of module top Листинг 19.19. Использование параметров в интерфейсе interface simple_bus #(AWIDTH = 8, DWIDTH = 8) (input bit elk),
370 logic req grit, ' logic [AW iDTH-1 0J addr, logic [DWIDTH 10] data, logic [1 0] mode, logic start, rdy modport slave( input req, addr, mode, start, cik, output grit, rdy, '"■'" ref data, import task slaveRead, // Импорт задач в модуль, task slaveWnte), // использующий данный modport modport master(mput gnt, rdy, elk, output req, addr mode, start ■'■-•'" '■'■'''- '' ref data, // Импорт требует полного прототипа задачи ...,-., import task maste>-Read(:nput logic [AWiDTH-1 0] raddr), task masterWrite{input logic [AWIDTH-1 0] waddr)), task masterRead(input logic [AWIDTH-1 0] raddr), // Метод masterRead // Метод slaveRead к masterWnte(mput logic [AWIDTH-1 0] waddr), левого слова interface endtask endinterface simDle_bus module memMod(interface a), // Исг logic avail; always @(posedge a elk) /' Сигнал elk из интерфейса a gnt <= a -eq & avail; // Сигналы gnt и feq из интерфейса always @(a start) if (a mode[0] == 1 bO) a siaveRead, a slaveWnte, endmodule module cpuMod(mterface b), enum {read, write} instr, logic [7 0] raddr, always @(posedge b elk) if (instr == read) ■) // Вызов метода интерфейса b masterWnte(raddr),
371 endmodule module top, logic elk = 0, // Копия интеофейса с параметрами по умолчанию simple_bus sbjntf(clk), // Интерфейс с 16-разрядными данными simple_bus #( DWIDTH(16)) wide_intf(clk), initial repeat(10) #10 c!M-t-, memMod mem(sb_mtf slave), // Доступна только задача slaveRead cpuMod cpu(sb_intf .master), // Доступна только задача masterRead memMod memW(widejntf slave), // 16-разрядная память cpuMod cpuW(wide_mtf master), //16-разрадное cpu endmodule 19.6. Компромиссы интерфейса Интерфейс не может содержать никаких вложений - копий модулей или других интерфейсов Существуют отличия в использовании интерфейсов с modport по сравнению с градационным соединением портов Преимущества: 1) Интерфейс идеален для повторного использования Когда для коммуникации применяется протокол, сигналы повторяются. 2) Интерфейс собирает множество разнообразных сигналов, которые декларируются в различных модулях или программах, и размещает их в одном месте, что уменьшает возможность ошибки неправильного подключения сигналов. 3) Чтобы добавить новые сигналы, достаточно объяви!ь их только в интерфейсе, что также позволяет минимизировать вероятность ошибки. 4) Modport позволяет модулю более простым способом связывать сигналы с интерфейсом. Можно описывать направление сигнала для дополнительной проверки. Недостатки 1) Для соединения point-to-pomt интерфейс, использующий modport, имеет почти такой же большой размер, как и применение портов в списке сш налов. Однако все декларации находятся в одном мегле, уменьшая вероятность внесения ошибки. 2) Необходимость использования имени интерфейса в дополнение к имени сигнала, что увеличивает размер модуля. 3) Бели два блока проекта соединяются с помощью одного протокола, который не будет повторно использоваться, го построение интерфейса потребует больше усилий, чем непосредственное соединение портов 4) Достаточно сложно выполнить соединение двух различных интерфейсов. Новый интерфейс (bus if) может содержать, в добавление к новым сигналам, все сигналы, которые существуют в другом интерфейсе (arb_if) Но по-
372 скольку интерфейсы не могут быть иерархическими, можно раскрыть отдельные сигналы и направить их соответствующим образом. 19.7. Модели памяти Листинг 19.20 представляет простейшую модель памяти, в которой реализованы функции чтения и записи с помощью задач ReadMem и WnteMem. В момент инициализации выполняется сканирование памяти на правильность выполнения операций чтения из записи Для этого в операторе initial реализуется цикл for, который содержит два блока fork-join. Если операция записи/чтения завершилась успешно, то признак ошибки Е = 0. Иначе Е = 1. Через 1000 ед. времени управление передается следующему за блоком fork-jom оператору. Листинг 19.20. Подсистема памяти с задачами чтения и записи module TopTasks, logic [20 0] А, logic [15 0]D, logic E, parameter LOWER = 20'h0000Q, parameter UPPER = 20'h7ffff, logic [15 0] MemfLOWER UPPER], task ReadMem(mput logic [19 0] Address output logic [15 0] Data, output bit Error), if (Address >= LOWER && Address <= UPPER) begin Data = Mem[Address], Error = 0, task WriteMem(input logic [19 0] Address, input logic [15.0] Data output bit Error), if (Address >= LOWER && Address <^ UPPER) begin MemfAddress] = Data, Error = 0, else Error = -|; endtask initial begin // 2 операции чтения записи/чтения выполняются без ошибки $dispiay("\nExpect 2 write/read transactions with no errors,"); // 2 операции чтения записи/чтения с ошибкой Sdisplay("followed by 2 write/read transactions with bus errors \n"), for (A = 0, A < 21'hlOOOOO, A = A + 21'h40000) begin fork #1000, WnteMem(A[19 0], 0, E), // Операция записи
373 if (E) Sdisplay ("%t bus error on write %h", $time, A), else Sdisplay ("%t write OK %h*, $time, A), fork #1000, ReadMem(A[19 0], D, E), // Операция чтения if (E) Sdisplay ("%t bus error on read %h", Stime, A), else Sdisplay ("%t read OK %h", $time, A), SfiniSh, end endmodule TopTasks Результаты моделирования 1000 write OK 000000 2000 read OK 000000 3000 write OK 040000 4000 read OK 040000 5000 bus error on write 080000 6000 bus error on read 080000 7000 bus error on wnte 0c0000 8000 bus error on read OcOOOO 39.7.1. Создание модепи уровня гранзакции с применением интерфейса В следующем примере (листинг 19.21, рис. 19 2) система памяти делится на гри подблока- два модуля и один testbench. Модули соединяются с помощью интерфейса. В этом проекте область адресов определена в компонентах памяти. В один момент времени только одна память отвечает за операцию чтения или записи Если нет модуля, ответившего на запрос о транзакции, то выдается ошибка шины. Широковещательный запрос с одним ответом может быть легко промоделирован с помощью конструкции extern forkjotn task в интерфейсе SystemVenlog, которая обрабатывается подобно ioik ..jom, содержащий множественный вызов задач. Однако различие между ними заключается в том, что в первом случае количество вызовов подпрограмм неопределенно, а это дает возможность применять один и гот же код интерфейса для любого количества компонентов памяти. Выходные значения записываются в актуальные аргументы вызова каждой задачи, и соответствующая задержка вызова задачи задерживает ответ, таким образом, происходит перезапись неправильных значений. Листинг 19.21. Две подсистемы памяти, подключенные к интерфейсу module TopTLM, Membus Mbus() Tester T(Mbus), Memory #( Lo(20'h00000) M1(Mbus), Hi(20'h3ffff)> // Младший адрес
374 Memory #( Lo(20'h40000), Hi(20'h7ffff)) M2(Mbus), // Старший адрес endmodule TopTLM // Заголовок интерфейса interface Membus, extern forkjoin task ReadMem (input logic [19 0] Address, output logic [15 0] Data bit Error), extern forkjoin task WnteMem (input logic [19 0] Address, input logic [15 0] Data, output bit Error), endinterface module Tester (interface Bus), logic [15 0] D, logic E, intA; initial begin Sdisplay("\nExpect 2 write/read transactions with no errors,"), $display("fol!owed by 2 write/read transactions wth bus errors \n"), for (A = 0, A < 21'h100000, A = A + 21'h40000) begin fork #1000, Bus WnteMem(A[19 0], 0, E), if (E) Sdisplay ("%t bus error on wnte %h", Stime A), else Sdisplay ("%t write OK %h", Stime A), fork #1000 Bus ReadMem(A[19 0], D E), join if (E) Sdisplay ("%t bus error on read %h" Stime A), else Sdisplay ("%t read OK %h", Stime, A), end Sdisplayf"), Sfmisn, end endmodule // Модули памяти module Memory(interface Bus), parameter Lo = 20'h00000, parameter Hi = 20'h3ffff, iogic[15 0]Mem[LoHi]; task Bus ReadMemf.nput logic [19 0] Address, output logic [15-0] Data, output bit Error), if (Address >= Lo && Address <= Hi) begin #100 Data = MemfAddress], Error = 0, end
375 else Error = 1, endtask task Bus WnteMem(input logic [19 0] Address, input logic [15 0] Data, output bit Error), if (Address >= Lo && Address <= Hi) begin #100 MemfAddress] = Data, Error = 0, end else Error = 1, endtaok endmodule Результаты моделирования 1000 write OK 000000 2000 read OK 000000 3000 write OK 040000 4000 read OK 040000 5000 bus error on wnte 080000 6000 bus error on read 080000 7000 bus error on wnte OcOOOO 8000 bus error on read OcOOOO ! M1 i Memory ! Module | tasks ! ReadMem ! WriteMem Щ I T i | TopTLM I Tester i | Module I Module Рис i9 2 Структурная схема модели уровня транзакций 19.8. Управление доступом к шине Если существуег два master компонента шины, необходимо предотвратить одновременный доступ обоих устройств master к шине. Контроль над шиной в каждый момент времени может иметь только одно устройство. Абстрактным механизмом для моделирования таких общих ресурсов является «семафор». В SystemVenlog включен встроенный класс semaphore. Тем не менее, в данном примере используется модель интерфейса, которая иллюстрирует, как поведение семафора моделируется с помощью интерфейса и его методов (листинг 19.22). Интерфейс Semaphore в следующем примере содержит количество ключей keys, соответствующее ресурсам - по умолчанию один За- , I I tasks , j extern ReadMem j J ReadMem j -j extern Writeiflem >- J WriteMem «tern WriteP|en
376 дача get ждет доступный ключ, а затем забирает его. Возвращае! ключ задача put. Пример содержит модуль Arbiter, в котором испо1ьзуется семафор. Иначе, семафор мог быть размещен в интерфейсе, но такая модель не будет соответствовать RTL уровню. Листинг 19.22 TLM-модель с арбитражем шины с помощью семафора module TopArbTLM, iMembus Mbus(), Tester T1(Mbus), Tester T2(Mbus), Arbiter A(Mbus), Memory #( Lo(20ti00000), Hi(20'h3ffff)) M1(Mbus), Memory #( Lo(20t<40000), Hi(20'h7ffff)) M2(Mbus), endmodule TopArbTLM interface Membus, // Повторение примеоа IS 20 extern forkjom task ReadMem (input logic [19 0] Address, output logic [15 0] Data, bit Error); extern forkjom task WriteMem (input logic [19 0] Address, input logic [15 0] Data, output bit Error), extern task RequestQ, extern task Relinquish{), endinterface interface Semaphore #(parameter int unsigned mitial_keys = 1), int unsigned keys = initial_keys, taskget(.nt unsigned n = 1), wait (n <= keys), keys -= n, endtask task put (int unsigned n = 1) keys += n, endtask endmterface module Arbiter (interface Bus), Semaphore s (), // Для встроенного типа semaphore эта строка бы // имела вид semaphore s = new, task Bus.RequestQ sget(): endtask task Bus Relinquish^), sputO, endtask enarroduie module Tester (interface Bus); logic [150] D, logic E, int A,
377 initial begin test_b!ock $dispiay("\nExpect 2 sets of double-wnte/double-read transactions with no errors,") $display("followed by 2 sets of double-wnte/double-read transactions with bus errors \n"), for {A = 0, A < 2УМ00000, A = A + 21'h40000) begin loop fork #1000, begin Bus Request, Bus.WnteMem(A[19 0], 0, b), if (E) $display("%t bus error on write %h", $time, A), else $display {"%t write OK %h", $time, A), Bus Relinquish, end join fork #1000, begin Bus Request, Bus ReadMem(A[19.0], D, E), if (E) $display{"%t bus error on read %h", Stime, A), else $disp!ay ("%t read OK %h", Stime, A), Bus Relinquish, end end loop $display{""), Sfinish, end test_block endmodule // Модули памяти module Memory (interface Bus), // Повторение примера 19 20 parameter Lo = 20'hOQOOO, parameter Hi = 20'h3ffff, logic [15 0] Mem[Lo.Hi], task Bus ReadMem(input logic [19 0] Address, output logic [15 0} Data output bit Error), if (Address >= Lo && Address <= Hi) begin #100 Data = Mem[Address], Error = 0, end else Error = 1 endtask task Bus WnteMem(input logic [19 0] Address, input logic [15 0] Data, outout bit Error);
if (Address >= Lo && Address <= #100 Mem[Address] = Data, Error = 0, end else Error = 1, endiask endmodule // Результаты моделирования 100 write OK 00000000 200 wr.te OK 00000000 1100 read OK 00000000 1200 read OK 00000000 2100 write OK 00040000 2200 wnte OK 00040000 3100 read OK 00040000 3200 read OK 00040000 4000 bus error on wnte 00080000 4000 bus err 5000 bus err 5000 bus err 6000 bus err 6000 bus err 7000 bus err 7000 bus err or on write 00080000 •or on read 00080000 or on read 00080000 or on write OOOcOOOO or on write OOOcOOOO or on read OOOcOOOO or on read OOOcOOOO 19.9. Транзактор, адаптер и функциональные модели шины При использовании TLM-блоков для проектирования аппаратуры их подключают к RTL-моделям с помощью конструкций, называемых транзакто- рами, адаптерами или функциональными моделями шины (bus functional models (BFMs)) Адаптеры могут работать в режиме master или slave, в зависимости от направления управления. Master адаптер содержит задачи для подсистем TLM master, которые инкапсулируют протокол и манипулируют сигналами для коммуникации с RTL-моцелью slave-подсистемы. Slave- адаптер содержит процессы, которые наблюдают за изменениями сигналов RTL-модели master подсистемы и вызывают задачи или функции в TLM подсистемах slave. 19.9.1. Master-адаптер в виде модуля Однчм и} способов создания адаптеров является оформление их в виде модулей, которые переводят интерфейс уровня транзакций в интерфейс контактов, и наоборот (листинг 19.23). Адаптер имеет два интерфейсных порта - уровня транзакций (TLM) и уровня контактов (TLM) Листинг 19.23. Модель с адаптером в виде модуля module TopTLMPLM, //Реализация копии интерфейса для уровня транзакций
379 Multibus TLMbus(), //Реализация копии интерфейса для нижнего уровня Multibus PLMbus(), Tester T(TLMbus), //Блок инициализации тестирования MultibusMaster MM (TLMbus, PLMbus), //Адаптер MultibusArbiter MA (PLMbus), //Арбитр Clock Cik(PLMbus), MultibusMomtor MO(PLMbus), MemoryPIN #( Lo(20'h00000), Hi(20"h3ffff)) M1 (PLMbus ADR, PLMbus DAT, PLMbus MRDC, PLMbus MWTC, PLMbus XACK, PLMbus BCLKJ, MemoryPIN #( Lo(20'h40000), Hi(20'h7fflf)) M2 (PLMbus ADR, PLMbus DAT, PLMbus MRDC, PLMdus MWTC, PLMbus XACK, PLMbus BCLK); endmoduie TopTLMPLM Архитектура модели изображена на рис 19.3 Tester - инициализирует процесс тестирования памяти. Адаптер MultibusMaster - реализует операции чтения и записи, запроса и освобождения шины Арбитр MultibusArbiter следит за порядком выделения шины В модулях памяти не используется интерфейс и он реализуется на нижнем уровне. Два вспомогательных блока. Clock и MultibusMomtor генерируют синхросигнал и наблюдаюг за изменением линий интерфейса, соответственно. Интерфейс Multibus (листинг 19.24) является упрощенной версией шины, к которой может быть подключено несколько master компонентов, каждому го которых соответс1вует линия запроса из массива 8RLQ. идущая ь арбитру, и входная линия приоритета BPRN, идущая от арбитра. Таким образом, применяется техника параллельных приоритетов. Рис 19 3 Архитектура i и с отдельным а.
380 Листинг 19.24. Модель шины с множественными master и slave interface Multibus, parameter int MASTERS = 1, / Параметр задает количество master, // подключенных к шине // Структурные коммуникации tn[19 0] ADR, //Адресная шина (инвертируется) tn [15 0] DAT, // Шина данных (инвертируется) wand /*active0*/ MRDC, MWTC, //Команды чтения/записи в память wand /*activeG7 XACK, // Подтверждение передачи wand ractiveO*/ f 1 MASTERS] BREQ, // Вектор запросов // master шины wand /*active0*' CBRQ // Общий запрос иичы wire /*active0*/ BUSY, // Признак занятости шины wire /*active07 (1 MASTERS] BPRN // Шина приоритетов master logic BCLK, // Синхросигнал шины, // упоавляется одним master logic CCLK, // Постоянный синхросигнал wand INIT, // Инициализация // Задачи - Поведенческие коммуникации extern task Request (input int n), extern task Relinquish (input mt n), extern forkjoin task ReadMem (input logic [19 0] Address, output logic [15 0] Data, bit Error), extern forkjoin task WriteMem (input logic [19 0] Address, input logic [15 0] Data, output bit Error) endinterface module Clock (Multibus Bus), always begin // Синхронизация #50 Bus CCLK = 0 #50 Bus CCLK = 1, endmodule Clock AaarrrepMultibusMabter реализует задачи, которые управляют линиями и работают со slave прототипом уровня транзакций Если только один драйвер разрешен для линии, то может быть использован тип данных logic Иначе, если разрешены множественные драйверы, то адаптер нуждается в операторе непрерывного назначения для буферизирующей линии Если master не имеет разрешения на управление шиной, то он формирует запрос к арбитру, ожидает приоритет, который будет ему назначен, и загем, если необходимо, освобождение шины предыдущим master устройством. Эти действия инкапсулируются в задаче GetBus. Если ни один slave не соответствует адресу, возникает тайм-аут (превышение времени выполнения задачи) и возвращается флаг ошибки (листинг 19 25). Листинг 19.25. TLM-модель шины с адаптером в виде модуля module MuitibusMaster (inte>1ace Tasks interface Wires) // Номер mastsr, получаюшего доступ к шине
381 parameter int Number = 1, enum {IDLE, READY, READ, WRITE} Master_State logic [19 0] adr = 'z, assign Wires ADR = adr, 'ogic [15 0] dat = 'z, assign Wires DAT = dat, logic mrdc = 1, assign Wires MRDC = mrdc, // Чтение logic mwtc = 1, assign Wires MWTC = mwtc, //Запись logic breq = 1 assign Wires BREQ[NumberJ = breq, logic cbrq = 1, assign Wires CBRQ = cbrq, // Общий запрос шины logic busy=1, assign Wires BUSY = busy,//Шина заьята assign Wires BCLK = Wires CCLK, task Tasks ReadMem (input logic [19 0] Address, output logic [15 0] Data, output bit Error), if (Master_State == IDLE) GetBusQ, eise assert (Master_State == READY), Master_State = READ, Data = "x, Error = 1, // Значение по умолчанию, // если не получен ответ от slave adr = -Address, #50 mrdc = 0, //Минимальная задержка fork begin ok @(negedge Wires XACK) Data = - Wires DAT, EndReadO, @(posedge Wires XACK) Error = 0, disable timeout, begin timeout // Тайм-аут, если не пришло подтверждение запроса #900 Error = 1, EndRead(), disable ok, end join FreeBus(), endtask task Tasks WriteMem (input logic [19 0] Address, inDut logic [15 0] Data, output bit Error), if (Master_State == IDLE) GetBusQ, else assert (Master_State == READY), Master_State = WRITE Error = 1, // Значение по умолчанию, // если не получен ответ от slave GetBusQ, adr = -Address, dat = -Data, #50 mwtc = 0, fork
ie Wires XACK) EndWnte(), ; .,-.:- ie Wires XACK) Error = 0, disable timeout, end begin timeout '/ Тайм-аут, если не пришло подтверждение запроса #900 Error =1, EndWrite(), disable ok, FreeBusQ, endtask task EndReadO, #50 adr = 'z, - • endtask task EndWrite(), mwtc = 1, #60adr = 'z, dat = 'z; endtask @(negedge Wires BCLK) breq = 0, // Формирование запроса шины cbrq - 0, // Формирование общего запроса п. @(negedge Wires BPRN[Numberj), @(negedge Wires BCLK iff 'Wires BPRN[Numbor]) #50 busy = 0, endtask task FreeBus(), breq = 1, if (Wires CBRQ) Master_State = READY, else begin Master _State = IDLE busy =1, // Освобождение шины, если установлен // общий запрос шины CBRQ end endtask endmodule MultibusMaster module Tester (interface Bus), logic [15 0]D; r-: •- '•--: ■:.. ira A, initial begin $disp!ay{"\n*** Expected results are " ***\n"), for (A = 0, A < 2i'h100000, A = A + 21'h40000)
383 fork #1000, BusWnteMem(A[19 0], 0, E), if (E) Sdisolay ("%t bus error on write %h", $time A) else $display ("%t write OK %h", $tirne, A), fork #1000, BusReadMem(A[19 0j, D, E), if (E) Sdtsplay ("%t bus error on read %h", $time. A), else $disolay ("%t read OK %h", Stime A), end end initial # 10000 Sfmish, endmodule module MultibusArbiter #(parameter MASTERS = 1)(interface Bus), // массив master, для запросов шины logic [1 MASTERS] bprn = '1, assign Bus BPRN = bprn, mt last = 0 // Последний отработавший master always @(negedge Bus BCLK) if (Bus CBRQ == 0) begin // Общий запрос шины , = last+1, forever begin if(i> MASTERS) i = 1, if (Bus BREQ[:j == 0) break, //Запросов нет // Ассерция выдает сообщение об ошибке, если i = last assert (i != last) else Sfatal{0 "no bus master"), if (i > MASTERS) i = 1, last = i, #50 bprn H = 0, $display("bprn[%b] = %b", i, bprn) else if (Bus BUSY == 0) begin // Освобождение системного ресурса #50 bprn [last] =1, endmodule. MultibusArbiter module MultibusMonitor (interface Bus), initial $monitor( "ADR=%h DAT=%h MRDC=%b MWTC=%b XACK=%b BREQ=%b CBRQ=%b BUSY=%b BPRN=%b" Bus ADR, Bus DAT, Bus MRDC, Bus MWTC, Bus XACK, Bus BREQ, Bus CBRQ, Bus BUSY, Bus BPRN), endmodule
// Memory Module with pin level interface module MemoryPIN ( input [19 0] ADR, // Адресная шина moot [15 0] DAT, //Шина данных input /*active07 MRDC, //Чтение из памяти input /'activeO*/ MWTC, // Запись в память output logic /*activeOV XACK, // Подтверждение запроса input CCLK ). parameter Lo = 20'h00000, parameter Hi = 20'h3ffff, logic [15 0]MemiLo:Hi], logic [15 0] Bufdat, logic Bufena = 0, // Буфер по умолчанию отключен initial XACK = 1, // Признак ответа системы, по умолчанию ответа i assigr DAT = Bufena "> Bufdat "z. always @(posedge CCLK) automatic logic [19 0] Address = -ADR, if (MRDC == 0 && Addiess >= Lo && Addiess <= Hi) // Чтение begin Bufdat <= ~Mem[Address], Bufona <= 1, XACK <= 0 end else if (MWTC == 0 && Address >= Lo && Address <= HO begin // Запись Mem[Address] = -DAT, XACK <^ 0 end else begin XACK<=1, Bufena <= 0, endmodule MemoryPIN 19.9.2. Адаптер в интерфейсе Другим способом создания модели адаптера является размещение его в интерфейсе. В этом случае используется один адаптер, из-за возможного конфликта имен в противном случае Slave-адаптеры, с другой стороны, вызывают задачи или функции в slave, и может возникнуть ошибка элаборации, если slave будет отсутствовать. Таким образом, необходима обновленная версия интерфейса. Листинг 19.26 представляег пример адаптера в интерфейсе. Структурная схема компонентов такой модели представлена рис. 19.4 Данная модель относится к уровню TLM
MuitibusArbiter i MultibusMonitor M IT MemoryPIN j | MemoryPIN I Рис 19 4 Архитектура модели с адаптером в интерфейсе Листинг 19 26 Пример простой Multibus TLM с master-адаптером, j ванным в интерфейсе module ToplnterfaceAdapter, Multibus Mbus() Tester T(Mbus), MuitibusArbiter MA(Mbus), Clock Clk(Mbus), MultibusMonitor MO(Mbus), MemoryPIN #( Lo(20'h00000), Hi(20'h3ffff)) Ml (Mbus ADR, Mbus DAT Mbus MRDC, Mbus MWTC Mbus XACK, Mbus BCLK), MemoryPIN #( Lo(20'h40000), Hi(20'h7ffff)} M2 (Mbus ADR Mbus DAT Mbus MRDC, Mbus MWTC Mbus XACK Mbus BCLK), endmoduie TopinterfaceAdapter // Заголовок интерфейса interface Multibus, parameter int MASTERS = 1 parameter int Number = 1 // Структурные коммуникации tn [19 0] ADR, tn [15 0] DAT wand /*active07 MRDC, MWTC, wand/*achve0*/ XACK, wand/*activeO*/ [1 MASTERS] BREQ, wand TactiveO*/ CBRQ, wire /*active07 BUSY, wire /*active07 [1 MASTERS] BPRN, logic BCLK, logic CClK, wand INIT, // Master-адаптер преобразует вызов ReadMem/WnteMem // во временные диаграммы enum {IDLE, READ, WRITE} Master_State, logic [19 0]adr ='z, assign ADR = adr, '/ Число master ш // Адресная шина // Шина данных // Команды чтения/записи // Подтверждение приема
logic [15 0] dat = 'z, assign DAT = dat, logic mrdc = 1, assign MRDC = mrdc logic mwtc = 1, assign MWTC = mwtc, logic breq = 1, assign BREQ[Number] = breq, logic cbrq = 1, assign CBRQ = cbrq, logic busy=1, assign BUSY = busy, task ReadMem {input logic [19 0] Address, output log'c [15 0] Data, output bit Error), assert (Master_State == IDLE), Master_State = READ, Data = 'x, Error = 1, //По умолчанию, если ни один slave не ответил GetBus(), adr = -Address, #50 mrdc = 0, // Минимальная задержка fork begin ok @(negedge XACK) Data = - DAT, EndReadO, @(posedge XACK) Error = 0, disable timeout, end begin timeout// Время простоя, если нет подтверждения приема #900 Error = 1, EndReadO, FreeBus(), Master_State = IDLE, endtask task WnteMem (input logic [19-0] A input logic [15 0] Data, output bit Error), assert (Master_State == iDLE), Master_State = WRITE, Error =1, //По умолчанию если ни один slave не ответил GetBus{), adr = -Address, dat = -Data, #50 mwtc = 0, fork begin ok @{negedge XACK) EndWnteQ, @(posedge XACK) Error = 0, disable timeout. end
387 begin timeout//Время простоя если нет подтверждения приема #900 Error =1, EndWriteO, disable ok, FreeBusQ, Master_State - IDLE, endtask task EndRead{), mrdc= 1, #50 adr = 'z, endtask task EndWnteQ, mwtc = 1, #60 adr = 'z, ddt = *z, enatask task GetBusQ, cbrq = 0, @(negedge BCLK iff iBPRN[Number]), #50 busy = 0, cbrq = 1, endtask task FreeBusQ, busy- 1, endtask endinterface module Clock (Multibus Bus), always begin // Синхронизация #50 Bus BCLK = 0, #50 Bus BCLK = 1 end initial* 10000 $fimsh, endmodule Clock module Tester (interface Bus), logic [15 0| D, logic E, mtA initial begin for (A = 0, A < 21'h100000, A = A + 21'h40000) begin fork #1000, BusWriteMem(A[19 0],0 E),
if (E) Sdisplay ("%t bus error on write %h", Stime, A), else Sdisplay ("%t write OK %h", Stime, A), #1000, Bus ReadMem(A[19 0J, D, E), if (E) $display ("%t bus error on read %h", Stime, A), else Sdispiay ("%t lead OK %h", Stime, A), endmodule module MuitibusArbiter #(parameter MASTERS = 1)(interface Bus), logic [1 MASTERS] bprn = '1, assign Bus BPRN = bprn, always @{negedge Bus BCLK) if (Bus CBRQ == 0) begin i = iast+1 forever begin if (i> MASTERS) i = 1, if (Bus.BREQW == 0) break, assert (i != last); else $fatal(0, "no bus if (i> MASTERS) i=1, #50 bprn [i] = 0, //$display("bprn[%b] = %b" ,, bprn), end else if (Bus BUSY =- 0) begin //Освобождение системного ресурса #50 bprn [last] = 1, endmodule MuitibusArbiter module MuffibusMonitor (interface Bus) initial $rnonitor( "ADR=%h DAT=%h MRDC=%b MWTC=%b XACK=%b BREQ=%b CBRQ=-%b BUSY=%b BPRN=%b", Bus ADR, Bus DAI, Bus MRDC, Bus MWTC, Bus XACK, Bus BREQ, Bus CBRQ, Bus BUSY, Bus BPRN), endmodule // Memory Module with pin level interface module MemoryPIN ( input [19 0] ADR, // Адресная шина inout[15 0] DAT, //Шина данных input /*activeO*/ MRDC, // Чтение из памяти input /*active07 MWTC, // Запись в память output logic /*active0*/ XACK, // Подтаерхдение запроса input CCLK ). parameter Lo = 20'h00000,
389 parameter Hi = 20'h3ffff, logic [15.0] MemfLo Hi], logic [15 0] Bufdat, logic Bufena = 0, // Отключение буферов по умолчанию initial XACK =1, //По умолнчанию ответов нет assign DAT = Bufena ? Bufdat 'z, always @(posedge CClK) begin automatic logic [19 0] Address = -ADR, if { MRDC == 0 && Address >= Lo && Address <= Hi) // Чтение begin Bufdat <= ~Mem[Address], Bufena <= 1, XACK <= 0, else if (MWTC == 0 && Address >= Lo && Address <= Hi) begin // Запись Mem[Address] = -DAT, XACK <= 0, else begin XACK<=1, Bufena <= 0, end end endmodule MemoryPIN Представленные модети транзакции являются простыми в том плане, что только одна [раязакция может иметь место в один момент времени Это означает, что жизненный цикл транзакции соответствует жизненному циклу транзакции, вызывающей ее Задача содержит данные, соответствующие транзакции, например, такие как начальное время В системах допускав!ся начинать выполнение новой транзакции до завершения предыдущей (перекрыше времени или конвейер) Они даже могут позволять асинхронное выполнение (деление транзакций) В таком случае данные о транзакции не могут содержался в одной задаче. Либо новый процесс(поток) должен быть порожден для управления или мониторинг транзакции и содержать соответствующие данные, либо объект динамических данных должен быть создан для хранения информации о транзакции. 19.10. Контрольные вопросы и задания 1. Дать определение назначения конструкции интерфейс. 2. Какое соотношение аппаратурных затрат для компонентов «память- логика» в современных цифровых системах на кристаллах? 3 Что такое modport? В каких случаях используется данная конструкция? 4. Разработать модель и структурную модель устройства на рис. 19.5. 5. Как реализуется импорт и экспорт задач в интерфейсе? Привести примеры использования.
390 6 Приведите структуру описания портов модуля 7. Опиши ie существующие модели памяти 8. Опишите архитектуру модели с отдельным адаптером 9 Опишите архитектуру модели с адаптером в интерфейсе 10. Каким образом осуществляется управление доступом к шине? 11. Поясните структуру TLM-модели с арбитражем шины с помощью с 12. Перечислите технологии изготовления памяти 13 Каким образом используются параметризированные типы данных в интерфейсе9 14 Как можно предотвратить одновременный доступ нескольких устройств master к шине? rst с1к 1 I rst c!k A В resuit 4— ► ► —► —& rst elk A 8 result modulel" interface modulet Рис. 19.5 Архитектура модели с адашером в интерфейсе
391 20. ОСНОВЫ ОБЪЕКТНО- ОРИЕНТИРОВАННОГО ПРОГРАММИРОВАНИЯ 20.1. Определение класса в SystemVeriiog Понятие класса позволяет объединять данные вместе с подпрограммами, манипулирующими ими. Простейший синтаксис /'список аргументов endclass Листинг 20.1 Представляет класс BusTran, описывающий типичный сетевой пакет, который включает адрес источника и назначения, а также массив значений данных. Класс BusTran содержит функции для вывода содержания пакета и вычисления CRC (cyclic redundancy check) данных. Для того чтобы можно было легко определить начало и конец класса, используются метки Листинг 20.1. Простейший класс BusTran class BusTran. bit [31 0]addr, crc data[8], function void display, $display("BusTran %h", addr), endfunctson display function void caic_crc, :" crc = addr л data xor, endfunction caic_crc endclass BusTran В SystemVeriiog классы могут быть объявлены в program, module, package или в другом месте. Они могут быть использованы в программах и модулях Программы содержат один тест и включаю! в себя testbench, блок initial для создания, инициализации и запуска тес га. Многие фуппы верификации размещают автономный класс или группу родственных классов в файл Набор классов оформляется в пакет package Например, вместе в один пакет мо1ут быть аруппированы все транзакции SCSI/ AT А. Пакет может быть скомпилирован отдельно, независимо ог теста системы. Неродственные классы, такие, как транзакции, scoreboards или различные протоколы, должны быть оформлены в отдельные файлы 20.2. Обьектно-ориентировашше программирование (ООП). Терминология ООП 1. Класс -основной блок, содержащий подпрограммы и переменные Аначо- гом в Verilog является модуль. 2. Объект - копия класса Подобно созданию в Verilog копии модуля возможности его последующего использования.
392 3 Определитель (Handle) - ука$атель на объект. В Venlog используется имя копии модуля для обращения к сигналам и подпрограммам вне модуля. Указатель в ООП подобен адресу на объект, но он хранится в указателе, который можег ссылаться на любой тип. 4. Свойства (Property) - переменные, сохраняющие данные В Venlog - это сигналы, регистры или цепи. 5. Метод (Method) - процедурный код для манипулирования переменными, оформляемый в виде задач и функций. В Venlog модули содержат задачи и функции, а также блоки initial и always 6. Протожпы (Prototype) заголовки подпрограмм, содержащие имена, типы и списки аргументов. Тело подпрограммы содержит выполняемый код. 20.3. Создание новых объектов В следующем примере b - это определитель (handle) объекта типа BusTran. BusTran b // Декларация объекта класса b = new, // Выделение места под объект BusTran В момент декларация определитель b инициализируется нулевым указателем null Затем для создания объекта BusTran может быть вызвана функция new, которая выделяет просгранство под BusTran, инициализирует переменные значением по умолчанию (0 - для 2-значных переменных и X - для 4- значных) и возвращает адрес объекта В System Venlog для каждого класса создается функция new, предназначенная для выдепения памяти и инициализации значений объектов 20.3 1. Пользовательские конструкторы. SystemVerilog позволяет пользователю создавать свою функцию new (листинг 20 2) Ока не имеет типа, поскольку всегда возвращает объект того же типа, чго и класс Листинг 20.2. Определение пользоватетьской функции new class BusTran, logic {31 0] addr, crc, data[8], function new, addr = 3 foreach (data[ij) data[i] = 5, endfunction enddass Здесь функция присваивает переменным addr и data определенные значения, но оставляет для переменной сгс значение по умолчанию X (SystemVenlog выделяет место для объекта автоматически). Можно указывать для аргументов функции значения по умолчанию чтобы сделать конструктор более гибким (листинг 20.3)
393 Листинг 20.3. Функция new с аргументами class BusTran, logic [31.0] addr, crc, data[8], 'unction new(!ogic [31 0] addr=3, d=5), this addr = addr, foreach (datafij) datap] = d, endfunction endciass initial begin BusTran b, b = new{10), // поле data получает значение 5 по умолчанию end В примере (листинг 20.4) выполняется вызов new для BusTran из конструктора Driver. Поскольку bt - это дескриптор типа BusTran, SystemVenlog создает объект, имеющий тип BusTran. Листинг 20.4. Вызов функции new в классе class BusTran, endciass BusTran class Driver, BusTran bt, function newQ, // Функция new класса Driver Dt = newQ, // Вызов функции new класса BusTran endfunction endciass Driver Слетует избегать выполнения в одном операторе декларации дескриптора и вызова конструктора new. Хотя это допустимо с точки зрения синтаксиса, но может создать ряд проблем, так как констриктор вызывается до выполнения операторов, особенно, если необходимо выполнить декларацию объекта в определенном порядке Если не использовать режим automatic storage, конструктор будет вызван в начале моделирования. 20 3.2. Освобождение объектов. Кома дескриптор прекращает указывать на объект, то он удаляется из памяти. Например BusTran b, // Создание определителя b = new, // Выделение памяти под объект b = new, // Выделение памяти под второй объект, первый удаляется b = null, // Удаление второго объекта Во второй строке вызов конструктора new выделяет память под объект и присваивает указатель на нею дескриптору b Следующий вызов конструктора new создает новый объект и записывает адрес на него в Ь, переназначая предыдущее значение и удаляя первый объект. В четвергой строке происходит удаление второго объекта
394 SystemVeniog никогда не удаляет объект, на который указывает дескриптор. Удаление необходимо делать вручную с помощью оператора null 20 3 3. Использование объектов. Для доступа к переменным и подпрограммам класса можно использовать обозначение точки " ". Например- BusTran b, // Создание определителя BusTran b = new, // Вызов конструктора BusTran b addr = 32М2, // Присвоение значения переменной b disp!ay(), // Вызов подпрограммы В строгом ООП доступ к переменным осуществляется только через публичные (public) методы, например get() и put(). Эго повышает стабильность разрабатываемых программ, исключая случайное изменение потей, однако снижает гибкость, необходимую для построения testbench. Поэтому для языков верификации лучшим решением является наличие прямою доступа к переменным класса. 20.4. Статические и глобальные переменные В SystemVeniog имеется возможность создавать статическую переменную, являющуюся общей для всех копий класса В листинге 20 5 статическая переменная count хранит количество созданных на данный момент объектов (рис. 20.1) Она инициализируется в 0 при декларации, потому что в начале моделирования отсутствуют транзакции. Каждый раз, при создании нового объекта, значение count увеличивается на 1 В примере (рис 20 1) присутствует только одна копия статической переменной count, независимо от того, сколько объектов BusTran будет создано Переменная id не является статической, поэтому каждый объект BusTran имеет свою собственную копию, и нет необходимости в создании глобальной переменной для count. Листинг 20.5 Класс со статической переменной class BusTran, - static int count = 0, // Счетчик создаваемых объектов mt id, // Уникальный 10 копии объекта function new, id = count++, // Установка ID с помощью счетчика endfunction endclass BusTran M, b2, initial begin Ы = new, // Первая копия, id=0 Ь2 = new; // Вторая копия, id=1 $disp!ay{"Second id=%d, count=%b", b2 id, b2 count), end Статические переменные, как правило, инициализируются в момент декларации. Нельзя использовать для этого функцию new, поскольку она вызывается каждый раз при создании новой копии класса. Для более сложной инициализации может быть использован блок initial. Необходимо только гаран-
395 тировать, что статическая переменная инициализирована до создания первой копии класса. В примере (листинг 20.6) дескриптор s равен null в момент вызова функции initialize. Это допустимо, поскольку задача исполыует топько статические переменные, которые не создаются конструктором. 1 1 ПсГо I class BusTran, И count static int count = 0,1 ' > int ^a' L-ГТм—' endclass Pjld 1 ' ! c°4ni I Рис ?0 1 Статическая переменная в Kiacce Листинг 20 6 Инициализация статической переменной с помощью задачи class MyStatic, static mt count, task initiahzfc(int vai), MyStatic s, s initiahze(42), 20.5. Подпрсмрамчы или методы класса Подпрограммы или методы (task или function) класса определяются внутри него Листин! 20.7 представляет пример определения подпрограммы displayO Д-1Я пассов BusTran и PCIJTran. SystemVerilog вызывает подпрограмму, основываясь на типе дескриптора. Листинг 20.7. Подпрограммы в классе class BusTran, bit [31:0] addr, crc, <iata[8], function void displayO Sdispiay("@%0d' BusTran addr~%h. crc=%h", addr, crc), $wnte("\tdata[0-7K), foreach (datap]) $wnte(data[i]), $disp!ay(), endfunction endclass class PCIJf>an, bit [31 0] addr, data, function void displayO, $display("@%0d- PCI addr=%h data=%h" addr data), endfunction endclass BusTran b, PCIJTran pc, ■> -: , initial begin b = new(), // Конструктор BusTran b display(), // Вывод значения BusTran
396 pc = new(), // Конструктор транзакции РСТ рс display() II Вывод значений транзакции PCI Подпрограммы в классе всегда используют автоматическое распределение памяти, следовательно, они не нуждаются в применении модификатора automatic. 20.5.1. Определение подпрограмм за пределами класса. Эмпирическое правило гласит: «Чтобы код программы был понятным, он должен быть не больше одной страницы». В SystemVerilog подпрограмму можно разбивать на прототип (имя подпрограммы и аргументы) внутри класса и тело (процедурный код), которое может быть записано вне класса. В этом случае перед именем подпрограммы в классе добавляется слово extern. При определении тела подпрограммы перед ее именем ставится имя класса, отделенное от него двумя двоеточиями (•:) Классы с листинга 20 7 можно было бы определить с использованием подхода, представленного листингом 20.8. Листинг 20 8 Внешнее определение подпрограмм class BusTran, bit [31 0] addr, crc, data[8], extern funct'on void display(), endclass function void BusTrarr.displayO, $displayf"@%0d BusTran addr=%h crc=%h", addr, crc), $wnte("\tdatd[0-7]="), foreach (datafj]) $write(data[ij), $display(), errafuncnon class PCI_Tran, bit [31 OJaddr, data, extern function void dispia/() endclass function void PCI_Tran..dispiay(), $display("@%0d PCI addr=%h, data=%h", addr data), endf unction 20.6. Правила границ видимости SystemVenlog придерживается основных правил Verilog. но имеет ряд дополнений. Границы видимости определяются блоками кода, такими как мо- дупь, программа, задача, функция, класс или блок begin-end. Для циклов for и foreach автоматически создается блок. Таким образом, индексные переменные являются локальными для этой области видимости Новые переменные могут быть определены внутри блока. SystemVenlog допускает создание переменных ч безымянных блоках begin-end. Имя может быть относительным или абсолютным, начинается с Sroot. Для относи г ель-
397 ных имен SystemVenlog просматривает список границ видимости, пока не найдет совпадение Для того чтобы избежать двусмысленности, следует использовать Sroot перед именем. В следующем примере (листинг 20.9) применяется одно и то же имя в различных областях видимости. Имя limit соответствует глобальной переменной, переменной программы, класса, задачи и локальной переменной в блоке initial. Последний из них является безымянным блоком, поэтому имя метки, связанной с именем переменной, зависит от среды симулятора. Листинг 20.9 Границы видимости имен ir»t limit // Sroot limit program p int limit, // Sroot p limit class Foo, mt limit, arrayfj, // $root p Foo limit task print (mt limit), // $root p Foo print limit for (mt i=0, i<limit, i++) Sdisplay("%rn- array[%0d]=%0d", i, arrayfij), endfunction endclass initial begm mt limit = $root limit, // Sroot p $unnamed limit Foo bar, bar array = new[limit], bar print (limit), end endprogram Следует выполнять декларирование классов за пределами программы или модуля. Листинг 20 10 представляет функцию Bug-.-display, которая не декларирует переменную цикла i, а вместо этого используе! переменную i программного уровня, обращаясь к ней с помощью иерархического имени test i. Листинг 20 10 Недопустимое использование внешних переменных в классе program test, int i, // Переменные программного уровня class Bug, logic [31 0] data[9], I! Calling this function changes the program variable function void display, // Forgot to declare i in next statement for (i = 0, Kdata size, i++) $display("data[%0d]=%x", i, datafi]), endfunction endclass endprogram Ключевое слово this позволяет избежать неоднозначности при определении переменных в классе, а в случае использования одинаковых имен - различ-
398 ных областей видимости Например, в следующем коде oname является локальной переменной функции и переменной класса Scoping class Scoping, string oname, function new(stnng oname), this oname = oname, // Переменьая класса получает // значение локальной переменной erdfunction endclass Следуст быть осторожным при определении переменных. Если компилятор не находит переменную внутри блока, он ищет ее извне Это может привести к одновременному использованию одной переменной несколькими потоками, и ошибка будет обнаружена только на этапе моделирования Листинг 20.11. Неправильное использование общей переменной программы program bug, class Buggy, mtdata[10}, task transmit, fork for (i=0, i<10, i++) // Переменная i не объявлена в классе send(data[i]), endtask endclass int i // прогоаммный уровень Buggy b, event receive, initial begin Ь=пел for (i=0 K10, i++)baata[i] = i, b transmit for(i=0,i<i0,!++) @(recieve) $display{data[i]), end endprogram 20.7. Использование одного класса в пределах друюго Один класс может содержаib копию другого, используя дескриптор в качестве объекта, подобно тому, как модуль в Verilog может содержать друг ой модуль. Основная идея применения вложений заключается в возможности повторного использования и управления сложностью проста Например, каждая транзакция может содержать блок сташстики с воеменными метками начала и завершения транзакции, а также информацию обо всех транзакциях (рис 20 2. листинг 20.12).
399 data [B],J class Statistics, time startT, stopT, static int ntrans = 0, static time total_elapsed_time, endciass Рис 20 2. Вложенные объекты JImcihh! 20 12 Использование класса в классе // Класс Statistics class Statistics' time startT, stopT, // Время транзакции static int ntrans = 0, // Счетчик тоэнзакций static time total_elapseci_time = 0, function time howjong, howjong = stopT - startT, ntrans++, total_elapsed_time +- howjong, endfunct'on function void start, startT = $time, endfunction endciass // Использование класса Statistics в классе BusTran class SusTran, bit [31.0] addr,crc,data[8] Statistics stats, // Определитель класса Statistics function new{), scats = newf) // Выделение памяти под объект stats endfunction task create_packet(), // Заполнение пакета данными stats start() // Передача пакета endtask enaclass Внешний класс BusTran может обращаться к элементам класса Statistics с помощью иерархического синтаксиса, например stats start Необходимо помнить, что значение дескриптора вложенной копии объекта равно null и вызов start приведет к ошибке. Инициализацию копий впоженных классов лучше сделать в конструкторе внешнего класса BusTran 20.8. Порядок компиляции Если необходимо выполнить компиляцию класса до определения вложенного в него класса, го последний может быть объявлен с помощью конструкции typedef, например, следующим образом' с ass BusTran, bit [31.0] addr, crc, Statistics stats, -*[ endciass
400 // Использование оператора typedef для объявления класса typedef class Statistics, // Декларация класса нижнего уровня class BusTran, Statistics stats, // Использование класса Statistics endclass class Statistics, //Описание класса Statistics endciass 20.9. Понятие динамического объекта При вызове подпрограммы в нее передается дескриптор на объект, но не сам объект. На рис. 20.3 задача generator вызывает задачу transmit. Два дескриптора generator.b и transmitbtrans ссылаются на один и тот же объект. task generator, BusTran b b=new, transmit (b), J task transmit (BusTran b), j endtask i Рис 20 3. Передача опредепте гей и объектов между подпрограммами При вызове подпрограммы со скалярными переменными и использованием ключевого слова ref System Veriiog передаег адрес Иначе - SystemVenlog передает копию переменных При этом их ишенения в подпрограмме не повлияют на оригинальные значения переменных В примере, представленном лисшнгом 20 13, в блоке initial создается объект BusTran, который вызывает задачу transmit с определителем, указывающим на объект. С помощью определителя задача transmit может читать и записывать данные в объект. Тем не менее, если transmit попытается модифицировать дескриптор, результат не будет виден в блоке initial, поскольку bt не объявлен как ref Подпрограмма можег модифицировать объект, даже если аргумент дескриптора не имеет модификатора ref. Как показано ниже, функция transmit может записать timestamp в объект. Если нет необходимости модификации объекта в подпрограмме, можно передать его копию. Листинг 20.13 Пассивные объекты // Передача пакета в 32-битовую шину task transmit(BusTran bt), CBbus rx_data <= bt data, bt.timestamp = Stime, endtask BusTran b, initial begin
401 b = new() // Выделение памяти под объект b addr = 42, // Инициализация значения transmit(b), // Передача объекта в задачу end 20.10. Изменение определителя в задаче Частой ошибкой кодирования является пропуск ключевого стова ref в описании аргументов подпрограммы. Например, в следующем коде аргумент b не имеет модификатора ref, таким образом, любые его изменения не будут видны в вызывающем коде. task create_packet(BusTran bt), // Неправильная декларация аргументов // функции, пропущен ref bt = new<); bt addr = 42, // Initialize other fields endtask BusTran b, initial begin create_packet(b), // Вызов подпрограммы с ошибкой $dispiay(b addr), // Приводит к ошибке, потому что b=nuil Хотя create_packet изменил аргумент bt, определитель b должен оставаться равным null. Чтобы исправить ситуацию, api уменг bt должен быть объявлен как ref task create_packet(ref BusTran bt), // Правильно endtask 20.11. Изменение объектов «на лету» Еще одной часто возникающей ошибкой является отсутствие создания нового объекта при выполнении каждой транзакции В примере задача generatejrans создает объект BusTran со случайным значением и передает ею в проект, что занимает несколько тактов. // Неправильное описание генератора task generator_bad(int n) BusTran b, b = new(), // Создание одного нового объекта repeat (n) begin b addr = $random(), // Инициализация переменных $dispiay("Sending addr=%h", b addr), transmit(b), // Передача объекта s DUT end endtask Код создает только один объект BusTran Таким образом, каждый раз в цикле происходит изменение объекта gencrator_bad одновременно с его передачей. В момент использования Sdisplay выведет много значений addr, но в BusTrans будет передано одно и то же состояние addr Ошибка возникает,
402 если transmit сохраняет объект и хранит его даже после возврата из transmit. Если задача transmit хранит ссылку на объект, то он может быть использован снова и снова Необходимо создавать новый объект BusTran при каждом проходе цикла II Правильное описание генератора task generator_goorf(int n), BusTran b, repeat (n) begin b = new(), // Создание одного нового объекта b addr = $randorn(), // Инициализация переменных Sdisplayf'Sendmg addr=%h', b addr), transmit(b) // Передача объекта в DUT end endtask 20.12. Массивы определителей Testbench может оперировать многими объектами Можно создать массив дескрипторов, каждый из которых ссылается на свой собственный объект. Пример представляет способ хранения десяти фанзакции шины в массиве. ,'/ Использование массива дескрипторов task generator(), BusTran Ьатау[10], foreach (barrayfij) begin barrayfij = new() // Конструктор каждого объекта transmit(barraypj); endtask Массив barray создан из дескрипторов, но не объектов, поэтому необходимо создавать каждый объект массива до его использования. Нет возможности применять функцию new для целого массива. 20.13. Копирование объектов 20 13 1. Копирование объекта с помощью оператора new. Использование new для копирования объектов - простое и надежное решение. Создается новый объект, а значения всех переменных копируются в него из существующего объекта // Копирование простого класса с помошью new class BusTran, bit [31 0] addr, crc data[8], endclass BusTran sre, dst, initial begin sre = new, // Создание первого объекта dst = new sre // Создание копии с помощью new end
403 Так создается простая копия. Если класс содержит дескрипторы на объекты других классов, го только объекты верхнего уровня будут скопированы, а объекты более нижних уровней - нет. В примере (листинг 20.14) класс BusTran содержит дескриптор на класс Statistics, представленный листингом 20.12 Листинг 20 14. Копирование сложного класса с помощью оператора new Dit [31.0] addr, cr static int court = Statistics stats, function new, stats = endclass BusTran src tnitiai begin с stats startT = 42, dsi stats startT = 84, // Создание первого объекта // Копирование src в dst II Изменение stats для dst и src itial создает первый объект BusTran и объекте Statistics (рис 20.4) одифицируег переменную во bGD-g Ь Рис 20 4 Объекты и определители до копирования с помощью new Использование new создает копию объекта BusTran, но не объекта Statistics Поэтому при обращении к функции new не выполняется вызов собственной функции new (рис. 20 5). Вместо значений переменных копируется дескриптор. Таким образом, оба объекта BusTran указывают на один и тот же объект Statistics и имеют одно и го же 31 src dst _* id-3 stats — id=3 stab — ~«» startT-42 e копирования с помощью ti'
404 20.] 3.2. Создание собственной функции копирования Если класс не содержит ссылок на другие аналоги, то функция копирования сору может иметь вид листинга 20.15 Листинг 20.15. Простейший класс с функцией копирования ciass BusTran, bit [31 0] addr, crc, data[8j, function BusTran copy, copy = new, // Конструктор для копии copy adar = addr, // Заполнение значений данных cooy crc = crc, copy data = data, // Копия массива endfuncbon endclass // Использование функции copy BusTran src, dst, initial begin src = new, // Создание первого объекта dst = src copy, end Для более сложных классов следует иметь собственные функции копирования сору Например, необходимо создать функцию копирования тля класса Statistics и опя каждого класса иерархии (рис. 20.6. листиш 20 16) startT=42 1 L^a^.JzJ-»jstartT^%] Рис 20 6 Объекты и определители после копирования (листи Листинг 20.16 Сложные классы с функцией сору class BusTran, bit [31 Ojaddr, crc, data[8], Statistics stats, static mt count = 0, int id; function new, stats = new, id = count++, endfunction function BusTran copy, copy = new; /' Конструктор для копии copy addr = addr, // Заполнение значений данных copy crc = crc, copy data - data,
405 copy stats = stats copy, // Создание первого объекта id = count++, endfunction endclass 20.14. Публичные или приватные объекты классов Обычные языки профаммирования, использующие идею ООП, предполага ют, что все объекты класса являются приватными (невидимыми за пределами класса), если они не объявлены как pubhe. Для построения testbench необходима большая гибкость, поэтому в SystemVenlog все объекты являются публичными (public), если только они не объявлены как приватные (private) 20.15. Наследование и подклассы Ключевым свойством классов SystemVeniog является наследование, которое позволяет создавать классы, основанные на других аналогах. Таким образом, они автоматически включают некоторые члены родительского класса. Например, в следующем коде (листинг 20 17) Circle наследует свойства класса Shapes. Часть базового класса всегда создается первой и удаляется последней Часть подкласса конструируется последней и удаляется первой Листинг 20.17. Пример наследования классов class Shapes // К"аждь'й объект должен содержать размер и начало координат mt tota!_size int start_x, start_y, bit[70] color, //Для каждой фигуры необходимы функции рисования и даеиы цвета task draw(), endtask // Определение кода в данном месте является необязательным //для наследуемых методов, поскольку здесь они являются // виртуально(ми и будут переписаны позже в классах-наследниках task setcolor (bit [7 0] color), this color = color, endtask endclass class Circle extends Shapes, bit [30 0] circle_d_data, function new(int size = 4), totalize = size * 3, endfunction task dravv(), // Код, выполняющий рисование круга, записывается здесь $display("drawmg a circle \n"), endtask endclass
406 Ключевое слово super используется из порожденного класса для доступа к элементам родительского класса (листинг 20.18) Листинг 20.18 Применение ключевого слова super class Packet, II Родителвский класс integer vaiue, function integer delayQ, delay = value * value, endfunction endciass class LinkedPacket extends Packet, // Класс наследования integer value function integer deiayO delay = super delay()+ vaiue * super value, endfunction endciass Элемент класса может быть декларирован на уровень выше или наследован классом на один уровень выше Получить доступ на более высокий уровень иерархии нет возможности. Например, недопустимо использование конструкции super.super.count. Подклассы или порожденные аналоги - это классы, наследующие текущий аналог Конструкция super.new должна быть первой в выполняемом конструкторе. Это необходимо потому, что суперкласс должен быть инициализирован до текущего класса. Если пользовательский аналог не реализует инициализацию суперкласса, то компилятор добавляет конструкцию super new автоматически. Порожденный класс преследует достижение двух целей. Первая - расширить функциональность базового класса, вторая - сократить, ограничить или уточнить функциональность базового класса Виртуальные классы не могут быть использованы напрямую для сознания объектов, но моппг быть применены как базовые классы. Все переменные из них и методы (функции классов) совместимы со всеми объектами порожденных классов. 20.16. Примеры использования массивов классов 20 16.1. Примеры ассоциативных массивов. Следующий пример (листинг 20.19) представляет использование определителя класса. В нем применяется ассоциативный массив объектов класса с индексацией строкой string. Когда копия нового класса заносится в массив, то в нем реально сохраняется определитель на него При этом можно получить два варианта моделирования. Первый выполняется без вызова метода (функции класса) new между каждым присвоением значения массиву Значение, которое будет получено, является текущим значением класса При втором выполнении реализуется вызов метода (функции класса) new между каждым присвоением значения
407 массиву. Выполнение функции каждый раз создает новый указатель Каждый элемент в массиве имеет различный определитель и представляет собой значение, сохраняемое в классе в указанное время В результате модетиро- вания массиву определителей классов будут присвоены три различных значения. Листинг 20 19 Использование ассоциативных массивов объектов классов module top oass nam_dat, string name, int data endclass narr>_dat class mcnreg, // Ассоциативный массив nam_dat со строковым индексом string nam_dat reg_fields[stnngj task add Jield (input nam_dat field), reg_fie!ds[fieid.name] = field, endtask-add_field endclass men_reg nam_dat field, men_reg foo = new, stnng s, initial begin field = new // Создание поля First field name = "Verilog" field data = 99 // Занесение значения field в динамический массив foo foo.add_field(field) 'ifdefPELD endif field name = "Systemvenlog", // Создание поля Second field data = 199 foo.addjield(field), ifdef FIELD field = new field name = "VHDL", II Создание поля Third foo addjield(field), if (foo regjields.first( s )) do $display( "%s %d\n" s, foo reg_fields[ s 1), while {foo regjields next(s)),
408 20.17. Контрольные вопросы и задания 1. Создать класс, определяющий интерфейс процессора Класс должен содержат ь поля- instruction [17 01 m_Dort [7 0], interrupt, address [9 0], portjd [7 0], wnte_strobe, out_port [7 0], read_strobe, interrupt_ack 2. Разработать класс, описывающий транзакции для передачи и чтения данных из памчти FIFO. Класс должен содержать поля. width - разрядность шины данных; depth = log2{n), где п - глубина памяти; Data [width-1, 0] - шина данных; wr_en - сигнал разрешения записи, rd_en - сигнал разрешения чтения; sinit - инициализация памяти; Doutj4vidth-1.0] - выход данных; full - признак того, что память заполнена полностью; empty - признак того, что память nycia; data_count[depth-l:0] - количество данных, записанных в память; консфуктор, инициализирующий размер памяти и разрядное 1ь шины; методы для передачи информации в память, чтения результатов, определения количества данных в памяти. 3 Для класса, представленного в задании 2, создать функцию копирования данных сору. 20.18. Литература 1 IEEE Std. 1364-1995, IEEE Standard Hardware Description Language Based on the Verilog" Hardware Description Language 1995. ISBN 0-7381-3065-6 IEEE Product No WE94418-TBR. 2 IEEE Std 1364-2001 (Revision of IEEE Std 136^-1995) - IEEE Standard Ver ilog Hardware Description Language - IEEE Computer Society Sponsored by the Design Automation Standards Committee. Published by The Institute of Electrical and Electronics Engineers, Inc - 3 Park Avenue, New Yo^k, NY 10016-5997, USA.-2001.-79! p 3. IEEE Std 1800-2005 - IFEE Standard for System Venlog - Unified Hardware Design, Specification, and Verification Language - Sponsor Design Automation Standards Committee of the IEEE Computer Society and the IEEE Standards Association Corporate Advisory Group - Published by The Institute of Electrical and Electronics Engineers. Inc.- 3 Park Avenue. New York, NY 10016-5997, USA.- 2005 - 664 p. 4. System Verilog 3.1a. Language Reference Manual - Accellera's Extensions to Verilog®.- Accellera Organization, Inc. 1370 Trancas Street #163, Napa, CA 94558, USA - 2004.
409 5. Spear C. System Venlog for Verification A Guide to Learning the Testbench Language Features, 2nd ed.- Sprmger-Verlag, New York, Inc Secaucus, NJ, USA.-2006-429 p 6. Mintz M , Ekendahl R. Hardware Verification with System Venlog An Object- Oriented Framework.- New York • Springer.- 2007.- 314 p 7. Bergeron J. Writing Testbenches using SysternVenlog.- Springer US-2006- 414p 8. Bergeron J, Cemy E., Hunter A, Nightingale A Verification Methodology. Manual for SysternVenlog.- Springer US.-2005 - 510 p. 9. Sutherland S, Mills D Venlog and SysternVenlog Gotchas. 101 Common Coding Errors and How to Avoid Them - New York : Springer - 2007.- 214 p 10. Vijayaraghavan Snkanth, Ramanathan Meyyappan A Practical Guide for SysternVenlog Assertions.- Springer US.- 2005.- 334 p 11. Haque F., Michelson I, Khan K. The Art of Verification with System Venlog Assertions. - Verification Central First ed.- 2006
410 21. СРЕДА ВЕРИФИКАЦИИ Представлены модели, методы и типовые HDL-процедуры, основанные на широких возможностях языка System Vcriiog конструировать эффективные решения для верификации цифровых проектов, описанных на системных языках описания аппаратуры. Цель - создание технологичных процедур, маршрутов и структур верификации, ориентированных на поиск семантических ошибок, изменяющих функционирование устройства и приводящих проект в неработоспособное состояние относительно заданной спецификации Задачи - изучение наиболее технологичных процедур верификации путем использования широких возможностей языка System Veiilog, ориентированных на проверку аппаратных решений проектируемых цифровых систем на кристаллах. Источники: [5-11] - методы тестирования и верификации различных типов цифровых структур; [1-11] - технологии программирования процедур для создания среды верификации проектов на основе System Verilog 21.1. Методология и инфраструтура верификации SoC Для создания среды верификации используются следующие принципы: 1. Псевдослучайные тестовые последовательности 2. Функциональное покрытие. 3 Разделение testbench на слои с использованием трачзакторов 4. Общие конструкции testbench для всех тестов 5. Код, ориентированный на создание тестов, поддерживающий решения, отличные or tes>tbench 21.1.1. Псевдослучайные тестовые последовательности Случайный (псевдослучайный) тест (рис. 21.1) всегда покрывает большее пространство состояний, чем узконаправленный или детерминированный. В завершение тестирования можно использовать специальные тесты, для верификации областей, недоступных или непроверенных случайным тестом. Add constraints Constrained random tests Direct testcase t Minima! code modifications --— — different seeds i 4 Functional coverage 1 4 Identify holes Рис 2! 1 Взаимодействие тес га и покрытия
411 Основные типы ошибок, обнаруживаемых случайными тестами. - это неверные пути передачи данных, возможно, с ошибками разрядности. Ниже представлены исходные данные о проекте, которые необходимо учитывать при создании или выборе тестов' 1. Конфигурация устройст ва (Device configuration). 2. Конфигурация среды (Environment configuration) 3 Входные данные 4. Исключения в протоколах. 5. Задержки 6. Ошибки и исключения при подаче некорректных входных сигналов. Случайный тест используется с обратной связью (рис 21 2), которая позволяет оценить полноту покрытия тестом функциональности и скорректировать генерирование последующих входных наборов. Для реализации данной стратегии существует «coverage-driven verification». Подобные обратные связи широко используются в промышленных системах моделирования, Magellan (Synopsys, 2003). 100% Рис 2! 2 Процесс тестирования с использованием обратных связей и Ge* них 2!. 1.2 Компоненты testbench. Testbench - специализированная структура операционно!о устройства, реализованная в HDL-коде, предназначенная для тестирования и верификации цифрового проекта с помощью средств моделирования, ассерциовной избыточности, а также компонентов, обеспечивающих управление, наблюдение и принятие решения о техническом состоянии проверяемого объекта. Он включает сгенерированные вручную или автоматически входные и выходные данные, описывающие идеальную модель устройства и составляющие основу testbench (рис. 21.3). Testbench Рис 21 3 Testbench в качестве среды верификации Блок testbench основан на использовании множества функциональных моделей шины Виь Functional Model (BFM). Если реальное устройство подключается к шинам AMBA, USB, PC1 и SPI, можно строить конструктивные ком-
412 понекты testbench, которые будут генерировать тесты и анализировать результаты моделирования (рис. 21.4) Здесь не используется детальная, синтезируемая модель проекта. Вместо этого применяется высокоуровневый гран- зактор (преобразователь), который подчиняется протоколу шины тестирования, но выполняется значительно быстрее. В случае создания прототипа устройства на основе FPGA или эмулятора BFM не будет синтезирован. Testbench! дмвА I fusi" CEOf Г1рГ~Ш Design Under Test Рис 2! 4 Компонешы testbench 21.1.3. Многоуровневый testbench (layered testbench). Многоуровневый подход - это ключевая концепция современной методологии верификации. Несмотря на видимые усложнения процесса верификации, проблема проверки устройства существенно упрощается за счет разделения задачи на несколько простых подзадач, составляющих иерархию инфраструктуры тестирования, которые рассматриваются далее от нижнего уровня иерархии к высшему. 1) Сигнальный и командный уровень (рис. 21.5). ровни Самым нижним является уровень сигналов, который представляет собой тестируемое устройство Design Under Test (OUT) и сигналы, соединяющие его с testbench. Следующий уровень - командный (command layer). Входы DUT управляются драйвером (driver), который выполняет отдельные команды, такие как чтение и запись шины. Выходы DU Г наблюдаются монитором (monitor), получающим изменения сигналов и формирующим из них команды. Лссерции (assertions) принадлежат обоим уровням (command/signal layer), они наблюдают за отдельными сигналами и осуществляют поиск изменений в течение исполнения всего кода. 2) Функциональный уровень (рис. 21.6) Функциональный слой управляет командным уровнем. Блок-агент (agent block), называемый также транзактором, получает высокоуровневые транзакции, такие как прямое чтение и запись в память, а загем разбивает их на отдельные команды. Они передаются драйверу, а также посылаются в scoreboard, который предсказывает результат транзакции. Про-
верочный блок получает значения от монитора и отправляет для анализа в scoreboard. Functional Command Signal Agent • •" i Driver 1 |-*j Scoreboard J+-I [ Assertions [ 1 1 ntir 1 Checker 1 7777^777... Monitor | 1 Рис 21 6 Сигнальный, к< 3) Уровень сценария (рис. 21.7). и функциональный уровни Scenario J Functional I Command! 1 Generator Agent j Driver 1 Environment |-»| Scoreboard (*-]_ J 1 Assertions j 1 Checker | ттттгтт*... Monitor J DUT Рис 21 7 Сигнальный, командный, функциональный и уровень сценария Функциональный слой управляется генератором сценарного уровня Здесь формируется задание с параметрами ограничений для псевдослучайной генерации тестов. Блоки, выделенные пунктиром, создаются в начале этапа разработки Они могут модифицироваться, дополняться функциями, но никогда не изменяются при выполнении отдельного теста. 4) Уровень теста создает полную и замкнутую инфраструктуру верификации проектируемого изделия совместно с функциональным покрытием, сценарием тестирования, проверяемым устройством и компонентами, обслуживающими процесс тестирования (рис 21 8} Таким образом, на основании рассмотренных структур верификации можно сделать следующие практически важные обобщения. Компоненты каждого уровня иерархии представляют собой транзакторы. Подобная организация открывает широкие возможности по обработке данных и повторному использованию компонентов. Тестовый уровень иерархии состоит из тестовых компонентов или слоев: 1) Test - компонент верхнего уровня, задает ограничения генератору последовательностей и конфигурирует режимы моделирования при каждом запуске 2) Уровень сценариев содержит генератор (generator), который создает последовательности с ограничениями, полученными от test, а также все сценарии по псевдослучайной генерации гестов 3) Функциональный уровень формирует структуры данных для их обработки и передачи на командный (command) уровень. Здесь проверяется правильность
данных, выдаваемых DUT, с помощью компонентов, агент (agent), счетчик (scoreboard) и анализатор (checker) Scenario Generator Functional Agent t-J Scoreboard U-j Checker Рис 2i 8 Slo-шый testbench со всеми слоями иерархии Агент используется для обработки данных, передаваемых драйверу (driver). Счегчик верификационной среды содержит высокоуровневую «золотую» модель проекта. Он получает одинаковые с DUT тестовые последовательности и определяет корректную реакцию DUT. Анализатор сравнивает выходную информацию из DUT, доставленную посредством монитора (monitor) с ожидаемой эталонной реакцией, полученной от счетчика; 4) Командный уровень обеспечивает связь с DU Г Драйвер управляет значениями на входах DUT. Монитор следит за выходной информацией из DUT и отправляет ее анализатору. Внешние ассерции используются как составляющая часть проекта командного уровня 5) Сигнальный (signal) уровень содержит верифицируемое усфойство и интерфейс входных, выходных сигналов. Ассерции - опоки, добавляемые в исходный код проекта для наблюдения и управления поведением модели проекта. Они могут быть представлены операторами if для сообщений об ошибках, проявляющихся в процессе тестирования DUT. Ассерции создаются разработчиком или могут быть взяты из существующих библиотек для проверки типовых функций. Фирма Synopsys поставляет систему моделирования VCS с библиотекой SystemVerilog-ассерций. SystemVenlog позволяет реализовать два вида ассерции: мгновенные и параллельные. Мгновенные запускаются сразу при передаче управления соответствующему оператору в исходном коде. Параллельная ассерция проверяет выражение по каждому импульсу синхросигнала и срабатывает в случае фиксации ложности выражения. Ассерции, помещенные в код DUT, называются внутренними, в тестовую среду - внешними. Они следят за сигналами, передаваемыми между DUT и тестовой средой Язык System Vcrilog имеет возможность для подключения проекта к модулю, содержащему внешние ассерции. Повышение уровня абстракции проекта для ранней верификации есть путь к сокращению времени выхода годной продукции на рынок. Статистика компании Synopsys показывает стоимость ошибок в кристалле: де-
415 фекты из-за ошибок проектирования составляют 82%; дефекты от ошибок спецификации - 47%: дефекты от ошибок многократно используемых IP- cores компонентов - 14%. Модель верификационной среды. В HDL Veriiog базовая функциональная единица - это модуль, содержащий структуру и интерфейсы для подключения к другим модулям. Ключевая возможность модуля - формирование границы вокруг структуры, дающей средства общения с внешним миром через однозначно определенный интерфейс. Модуль - это конструкция, которая зависит от конкретного языка Компонент - независимый объект, обладающий свойством инкапсуляции Например, компоненты строятся из модулей SystemVcnlog и SystemC, но могут быть построены на классах в 0+ или entity/architecture в VHDL Эффективные повторно используемые компоненты - это «черные ящики», связываемые между собой через интерфейсы. Транзакция - это количество активности, возникающее в модели за определенный период времени или единица информации при передаче управления или данных между двумя компонентами (запись/чтение шины, передача пакета данных), имеющая структуру, размещение, извлечение и передача. Иерархию верификационной среды можно представить в виде организации компонентов, представленной на рис 21.9. Внутренняя часть есть DUT компонент RTL-уровня абстракции, к которому подключается верификационное окружение TLM-уровчя посредством верификационных компонентов- тракзакторов. Роль каждого из них - конвертирование потока данных TLM- уровач для их восприятия на RTL-уровне, и наоборот Окружение (см. 21.9) - набор высокоуровневых компонентов с транзакционными интерфейсами, которые предоставляют все необходимое для функционирования DUT. Компоненты окружения - генераторы тестов, ведущие (masters) и ведомые (slaves) блоки. г— Контроллер окружения 4 Генератор (ведущий) Сборщик _! покрытия 1 ! | '< -тН Драйвер 1 Монитор Монитор т гг~—— 11, | Рис 21 9 С р зац DUT RT ия всрифик -. t ! 1 Ответчик "~*1 Ведомый J Изменение уровня абстракции! ннс Транза го окр> же.) <ционный уровень
416 Генераторы тестовых воздействий создают поток транзакций для моделирования DUT Они могут быть псевдослучайными, детерминированными или смешанными; самостоятельными или иметь управляющие сигналы; независимыми или синхронизированными. Простейший генератор выполняет псевдослучайную функцию синтеза тестов, которые отправляет драйверу. Генератор сценариев создает детерминированные или смешанные последовательности, которые направлены на инициализацию специфических функций тестируемым устройством Ведущий - двунаправленный компонент, отсылает запросы и принимает отклики, инициализирует активность, анализирует отклики для задания следующего сценария Ведомый - двунаправленный компонент, обрабатывает запросы и возвращает отклики. Анализаторы (scoreboard - золотая модель, coverage collector - полнота тестового покрытия транзакций, адресного пространства, количества ошибок) получают информацию о верификационной среде и делают заключение о правильности и окончании процесса верификации. Контроллер формирует поток данных в верификационной среде и управляет ее активностью, пересылает данные от счетчика и коллектора покрытия компонентам окружения, запускает и останавливает генератор тестов. Выделение операционного и анализирующего доменов Компоненты объектно-ориентированной верификационной среды удобно рассматривать в принадлежности к двум доменам' операционному и управляющему (анализирующему) (рис. 21.10) Операционный домен - это набор компонентов, которые создает среду для выполнения процесса тестирования устройства DUT. Генераторы тестовых воздействий, а также ответчик и драйвер создают сигнапы, управляющие моделированием. Управляющий домен содержит набор компонентов (мониторы, счетчики, сборщики покрытия, контроллер), которые выполняют анализ процесса верификации и принимают решение о техническом состоянии проекта Операционный домен i Рис 21 !0 Выделение операционного и анализирующего д<
417 Сборшик покрытия (coverage collector) и счетчик подключаются к выходу монитора через порт анализа (рис. 21.11) Функция покрытия - определить полноту или качество теста относительно проверенно! о множества состояний тестируемого объекта. Если при заданной 100% полноте относительно введенных состояний или неисправностей верификационная среда не выдала ошибок, делается вывод об исправности модели проектируемого изделия. ™Р Г*! Драйвер W DUT М Монитор Пример среды со сборщиком покрыт ия Обобщение приведенных структур верификации создает ESL (Electronic System Level design) технологию, основанную на SystemVenlog, которая позволяет получить высокоуровневую TLM-модель (TLM - Transaction Level Model), эмулирующую поведение SoC. TLM-структура дает возможность начать процесс разработки и верификации задолго до наличия проекта R i L уровня или кремниевого прототипа устройства. TLM-модель работает на уровне функциональных запросов и передач пакетов данных, задающих системное поведение проекта. Верификационные среды, созданные на System Venlog TLM, интегрируются в любую архитектуру: SoC TLM или SoC HDL Это дает возможность, используя верификационную среду, определить оптимальную архитектуру программно-аппаратных средств рассматриваемого проекта. TLM методология ускоряет интеграцию верификационных решений и позволяет быстро менять целевые проекты, используя TLM-шаблон, как легко модифицируемую базовую платформу. Уровень абстракции TLM намного выше, чем RTL, который в деталях отражает внутриблоковые схемные состояния, наносекундную точность передач и побитовые изменения шин Как следствие, использование TLM ускоряет программную верификацию и HW/SW ко-верификацию в 1000 и более раз по сравнению с RFL. Ряд зарубежных компаний имеет интересные разработки в области системной верификации: Cadence, Synopsys, Mentor Graphics, Aldec Последняя из них является лидером в области создания аппаратных и программных решений для верификации проектов, реализуемых на технологиях ASIC (Application-Specific Integrated Circuits) и FPGA (Field Programmable Gate Arrays). Одно из направлений - это обеспечение полной поддержки актуального стандарта SystemVenlog'2009 Интересный маршрут проектирования от Aldec представлен на рис. 21.12, который интегрирует лучшие технологии, в том числе от Cadence, S\nopsys, Mentor Graphics.
418 Инфрасфуктура использует опыт и технолоши от ведущих компаний планеты в области тестирования и верификации цифровых проектов. Здесь основные компоненты: семейство языковых средств для ввода проекта; компиляторы с языков описания аппарагуры; средства отладки проекта; ориентированные на пользователя средства управления проектом и компоненты визуализации результатов моделирования. Ввод проекта rtj , Edito-- j 1_C Средства отладки \и Управление прсекто! VHDL EDIF компилятор | j Компилятор | j Компилятор| Design Browser i Design Flow Manager Визуализация результатов моделирования Рис 21 !2 Инфраструктура верификации проектов компании Aldec 21.2. Программы (Program) Модуль - основная конструкция для создания компонентов аппаратуры в Verilog и SystemVeriiog Он может содержать иерархические подключения других модулей, линий, декларации задач и функций, процедурные операторы в блоках always и initial. Эти конструкции хорошо подходят и для описания аппаратной модели. При построении testbench акцент делается не на детали аппаратного ) ровня, линии, структурную иерархию и межсоединения, а на создание среды верификации. Внимание уделяется инициализации переменных, синхронизации выполнения операций, устранению возможности возникновения гонок между проектом и testbench, автоматизации генерирования входных сигналов, повторному использованию существующих библиотечных моделей. Для решения задач в SystemVeriiog вводится специальная конструкция - program, задачи которой: 1 Обеспечить точку входа для выполнения testbench. 2 Формирование области, являющейся оболочкой данных, задач и функций. 3. Обеспечить синтаксическое содержание, описывающее порядок формирования и подачи тестов, а также анализ результатов тестирования 4. Устранить возможность появления гонок между проект ом и testbench. Программа служит четким разделителем проекта от testbench. Вместе с блоками синхронизации программа создает свободные от гонок взаимосвязи
419 между проектом и testbench и позволяет использовав уровни абстракции, такие как циклическое (cycle) моделирование и транзакционный уровень обмена данными. Конструкции абстракции и моделирования в SystemVeniog упрощают создание и использование testbench Возможность создания программных экземпляров и выполнение их индивидуального подключения позволяет использовать программы в качестве обобщенной модели. Программа можег содержать декларации типов и данных, подпрограммы соединении с проектом, один или ьесколько потоков процедурного кода. Связи между проектом и testbench реализуются с помощью механизмов соединения портов в SystemVerilog, включая интерфейсы. Синтаксис программ program [static | automatic] programjdentifier [ parameter_Dort_iist 3 list_of_ports j [ list_of_port_declarations ], [ timeunits_declarat!on ] {programjtem } endprogram [ programjdentifier] или program programjdentifier ( *), [ timeunrtsjjeclaration ] {programjtem } endprogram [ programjdentifier ] К program_item относится декларация портов и описание следующих конструкций: {attnbutejnstance} continuous_assign/7 операторы непрерывного назначения | {attnbutejnstance} module_or_generatejtem_declaration // копии модулей или // операторы generate | {attnbutejnstance} mitial_construct // констукции initial или final I {attnbutejnstance} final_construct | {attribu'ejnstapce } concurrentjassertionjtem // Параллельные ассерции! 1 ioop_generate j»nstruct | conditional_generate_construct | generate_region Например, декларации заголовков программ с использованием портов и интерфейса: program test (input elk, input [16 1] addr, inout [7 0] data), initial endprogram или program test (interface devicejfc); initial endprogram В программе можно размещать задачи, функции, классы и блоки initial, но нельзя использовать блоки always Программа имеет одн> или несколько точек входа и заканчивает свою работу после завершения последнего блока initial. Вместо always, если необходимо бесконечное выполнение операций, можно использовать «initial fore\er». а завершать работу с помощью chcicm- ной задачи Sexit.
420 21.3. Шаги моделирования систем в SysfemVerilog В Verilog большинство событий выполняется в активный период (Active region) Также существуют периоды для неблокирующих присвоений и PLI интерфейса. В System Verilog предлагается новое деление временных слотов (рис. 21.13, табл. 21 1) Первый период временного слота является подготовительным - prepone region, используемым для testbench. В этот момент собираются значения сигналов перед активным периодом. Следующий за ним активный период (active region) предназначен для выполнения событий проекта В данный период обрабатывается RTL и вентильный код. а также генератор синхросигнала. Третий - период наблюдения (observed region) служит для анализа ассерций - специализированных конструкций формальной верификации. Последним является период реактивации (reactive region), в котором опять выполняется testbench. Указанный порядок периодов не является строгим. События из периодов наблюдения и реактивации могут возникать ранее событий проекта из активного периода. From previous J prepone J time slot ^ (sample) j F=ri 1 Active (^Jdesign) J I Observed [ (assertions) j p=£ ц | Reactive j [ (testbench) J Looo back if more events To next > Рис 21 13 Этапы моделирования в пределах одного временного шага Таблица 21.1. Области планирования работ (primary scheduling regions) Период Подютовительный (prepone) Активации (active) Наблюдения (Observed) Реактивации (reactive). Действие Считывание значений еш палов то активности проекта. Д.1Я входов testbetch Моделирования кода проекта, описанного в мопелях Вычисление ассерций Вычисление кода в testbench. описанного в программе 21.4. Синхронизация тестовых последовательностей (Stimulus Timing) 21.4.1. Блок синхронизации (clocking). Это новый блок для описания синхросигналов и требований к временным параметрам и синхронизации модели. Он упрощает использование времени. Блок clocking использует cycle-based методологию и позволяет писать моде-
421 ли на более высоком абстрактном уровне. Вместо того чтобы обращать внимание на сигналы и транзакции во времени, блок тестирования може! оперировать понятием такта и транзакции. В зависимости от среды (environment) testbench может включать один или несколько блоков clocking, каждый из которых содержит один синхросигнал и необязательные дополнительные сигналы Блок clocking отделяет описание временных параметров и синхронизации о; структурных. ф>нкциональных н процедурных элементов Таким образом, время для получения и управления сигналами блока становится более ясным и зависит от соответствующего блока Множество ключевых операций может быть записано более кратко без прямого использования синхронизации или указания временных параметров. К таким операциям относятся: события синхронизации, получение входных значений, драйверы синхронизации Синтаксис- [ default ] clocking [ identifier ] clk_event, { default input c!k_skew | output elk _skew | input clk_skew output clk_skew; ! input [ clk_skew ] | output [ c!k_skew ] | input [ clk_skew j outout [ cik_skew ] | inout signaljdentifier [ = expression ] {, signaljdenfifier [ = expression ]}, } endclocking[ clockingjdentifier ] Здесь identifier - имя блока, а событие синхронизации clk_event может быть представлено в форме @ identifier I @ ( event_expression ) Фигурные скобки ^указывают на повторяющиеся элементы, а квадратные - на необязательные. Смещение cikskew определяет задержку по отношению к событию синхросигнала, когда может быть получено или передано значение сигнала. Входное смешение всегда отрицательно, поскольку относится ко времени до фронта синхронизации, в то время как выходной сигнал относится к периоду после фронта (рис. 21.14). Смещение может быть задано в формате- poseage | negedge [# detey_value | # ( mmtypmax_expression )] j # delay_value , # ( rpintypmax_expression) Общее смешение определяется с помошью ключевого слова default. Момент считывания Морлент формирования значения * ■ * выходного значения Входное •«_*:♦_»: Выходное смещение ' ' ' смещение Рис 21 14 Моменты поступления входных тестов и считывания результатов Листинг 21.1,а представляет блок, сшналы которого по умолчанию управляются передним фронтом elk. Входы имеют смещение на один шаг (1 step) - значение на вход должно быть подано за один шаг моделирования до поступления переднего фронта синхросигнала. Выходные значения считыва-
422 ются по заднему фронту. Во втором примере (листинг 21.1,6) не указан фронт, поэтому по умолчанию событием синхронизации будет считаться любое изменение сигнала elk Выходы, как и в предыдущем случае, управляются задним фронтом. Первая строка в третьем примере (листинг 21.1,в) объявляет блок синхронизации с именем bus, который управляется передним фронтом синхросигнала clock 1. Вторая линия указывает, что по умолчанию все входные сигналы имеют смешение, равное 10ns, а выходные - 2ns Третья линия задает управляемые синхронизацией входные сигналы data, ready и enable; последний из них связан с иерархическим сигналом top mem I.enable. В четвертой линии добавляется информация о сигнале ас'к, управляемом задним фронтом, что переопределяет заданное по умолчанию значение. Последняя строка добавляет входной сигнал addr и переопределяет заданное по умолчанию смещение таким образом, что сигнал подается за один шаг (step) до переднего фронта синхросигнала. Это означает, что сигнал становится стабильным сразу перед появлением фронта. Последний пример (листинг 2! 1,г) представляет блок синхронизации dram, где значение на вход address должно быть подано за ips до появления события на elk. Для остальных входов этот параметр равен 5 единицам времени На выходах информация должна быть готова через 6 единиц времени после переключения elk. Листинг 21 1. Примеры синхроблоков а) clocking ck1 @{posedge elk) default input #1step output negedge, // выходы управляются задним фронтом elk input , output , endclockmg б) clocking ck2 @(cik;, // Фронт не описан default input #1step output negedge; input , output , endclockmg в) clocking bus @(posedge clockl); default input #10ns output #2ns, input data, ready, enable = top.meml enable, output negedge ack, input #1 step addr, endclockmg r) clocking dram @(clk), input #1ps address input #5 output #6 data; endclockmg 21.4.2. Интерфейсы и блоки синхронизации. Время между testbench и модулем должно быть тщательно спланировано.
423 Интерфейс может содержать блоки синхронизации, по одному на каждый синхродомен. Можно описать используемую по умолчанию синхронизацию, применяя оператор default. По умолчанию входной сигнал поступает до начала выполнения операций проекта, а выходной передается обратно в проект во время текущего временного слота. При описании синхронизации testbench может использовать выражение вида @my_interface.cb вместо определения точного значения синхросигнала или фронта. В примере (листинг 21 2) блок синхронизации cb декларирует, что все сигналы в блоке активны по переднему фронту синхросигнала. Направление сигнала зависит от modport Таким образом, request - выход блока TEST modport и grant - вход в modport. Листинг 21.2 Интерфейс с блоком синхронизации interface arb jf(input bit elk;, logic [1 0] grant, request, logic reset, clocking cb @(posedge elk), // Declare cb output request, input grant, endclocking modport TEST (clocking cb /' Use cb output reset), modport DUT (input request, reset, output grant), endinterface Блоки синхронизации являются оболочкой для множества сигналов использующих один и тот же синхросигнал. Применение таких блоков в интерфейсах позволяет значительно сократить количество кода, необходимого для подключения testbench. Более того, гак как направления сигналов в блоках синхронизации интерфейсов становятся зависимыми от testbench, а не от тестируемого устройства, то декларация modport может соответствующим образом описать одно из этих направлений. Программа testbench может использовать порты интерфейса в зависимости от назначения каждого блока синхронизации Линии интерфейса в блоке синхронизации должны иметь то же направление, которое описано в блоке для стороны testbench (modport test), или быть инверсными по отношению к стороне DUT (modport dut). Описанная ситуация представлена в листинге 21.3. Листинг 21.3. Использование блоков синхронизации для тестовых блоков interface bus_A (input elk», •ogic [15.0] data, logic write, modport test (input data, output write), modport dut (output data, input wnte), endinterface interface bus _B (input cik),
424 logic [8 1] cmd, logic enable, modport test (input enable); modport dut (output enable), endinterface program test( bus_A test a, bus_B test b ), clocking cd1 @(posedge a.clk); input a data, output a write, inout state = top cpu state, endclocking •"* docking cd2 @(posedge b cik), input #2 output #4ps b cmd, input b enable; endclocking initial begin // Операторы программы // Могут быть использованы cd1 a data , cd2 b cmd , etc end endprogram Компоненты проекта описываются в виде модулей, testbench - в виде про- i раммы. interfaces - представляет сигналы, которые могут быть использованы для связи между отдельными блоками. Все компоненты обьединяются в модуле верхнего уровня (листинг 21 4). Листинг 21.4 Объединение компонентов системы в модуле верхнего уровня moduse top, logic phil, phi2, hus_Aa(phi1): bus_B b{phi2), test mam( a, b ) cpu cpu1( a ), memmeml(b), endmodule Иначе, в описанном примере (листинг 21.3), блок clocking мог быть реализован с использованием иерархических имен из интерфейса: clocking cd1 @(oosedge a elk), input data = a data, output wnte = a write, inout state = top cpu state; endciockmg clocking cd2 @(posedge b cIk), input #2 output #4ps cmd = b cmd, input enable = b enable, endclocking
425 21.4.3 Описание событий через блок синхронизации. События синхронизации блока clocking становятся непосредственно доступными через использование имени блока clocking, безотносительно к реальному событию синхронизации, декларированному в блоке clocking Например: clocking dram @(posedge phil), inout data, output negedge #1 address, endclocking События синхронизации clocking-блока могут быть использованы для описания события: @(dram), что эквивалентно записи @(posedge phil) Оператор ## служит для описания задержки на указанное количество событий синхросигнала или синхротактов - циклической задержки (Cycle delay: ##) Синтаксис операторов задержки синхрот-актов. Ш integraljiumber | Ш identifier | Ш ( expression ) Выражение expression может быть любым из SystemVenlog. значение которого вычисляется как положительное целое число. Циклическая задержка соответствует синхронизации по умолчанию. Если для текущего модуля, интерфейса или программы не описана синхронизация по умолчанию, то компилятор выдает сообщение об ошибке Примеры описания задержек. #4 5; // ожидание 5 синхрособытий с использованием синхронизации по умолчанию ## 0 + 1), // ожидание j-*-1 синхрособытий с использованием синхронизации // по умолчанию Один блок clocking может быть указан как синхронизация по умолчанию для всех операций синхрозадержки в модуле, интерфейсе или программе Синтаксис оператора спецификации синхронизации по умолчанию: // Огисание в модуле существующего блока синхронизации default с!оскюд clockingjdenb'ier, // Декларация блока синхронизации [ default ] clocking [ clockingjdeniifier ] ciockmg_event, {clockingjtem} endclocking [ clockingjdentitier ] Здесь ciocking_identifier должен быть именем блока clocking Только один clocking-блок может быть описан как блок синхронизации по умолчанию в программе, модуле или интерфейсе. Запись выражения default clocking более одного раза в одной программе или модуле может привести к ошибке компиляции. Конструкция default clocking имеет силу только в границах области, содержащей ее описание. Эти границы включают модуль, интерфейс или программу, которая содержит декларацию, точно так же, как вложенный модуль или интерфейс Это не касается реализации копии модуля и интерфейса Листинги 21.4 и 215 представляют декларацию блока синхронизации по
426 умолчанию внутри программы в первом случае, с использованием для эгой цели внешнего блока - во втором. Листинг 21.5 Декларация синхронизации по умолчанию program test( input bit cik input reg [15 0] data ), default clocKing bus @(posedge elk), mout data, endclocking initial begin ##5, if( bus data ==10) ##1, else end endprogram Листинг 21.6. Использование существующего блока clocking для синхронизации по умолчанию module processor clocking busA @(posedge elk 1), endclocking clocking busB @(negedge clk2), endclocking module cpu( interface у), ->, default clocking busA initial begin ## 5, // use busA => (posedge c!k1) „„, end endmodule endmodule Все входы блока clocking (mput или mout) являются тестами, которые синхронизируются событием синхросшнала Когда сигнал появляется в выражении, его значение заменяется входным, которое было подано в последней точке. Когда сигнал появляется в нескольких clocking, каждый блок clocking считывает значения сигнала по своему событию синхронизации 21.4.4. Синхронизация событий и управление ими. Управление порядком выполнения операторов включает управление задержкой. # delay_valise | # ( mmtypmax_expression ), и управление событием @ identifier | @ ( expression ) | @*! @ (*) | @ sequencejnstance где sequencejnstance - последовательность, новая форма описания сложных событий в SystemVerilog. рассматривается ниже.
427 Также для управления с помощью повторяющихся событий может быть использован цикл repeat ( expression ) event_control Выражение expression может включать несколько событий, перечисленных через оператор or или запятую: event or event I event, event Допускается использование ключевых слов, описывающих передний и задний фронты: posedge и negedge Выражения, применяемые в управлении событиями, могут обозначать входы блока clocking (input или mout) или его сектора. Секгор может включать динамические индексы, которые вычисляются, ко* да вычисляется @- выражение. Ниже приведены некоторые примеры выражений синхронизации: 1. Ожидание изменения сигнала ackl, который синхронизируется блоком clocking rambus: @{ram_bus ack_1), 2. Ожидание следующего события блока clocking гат_Ьиь. @(ram_bus) 3 Ожидание переднего фронта сигнала ram_bus.enabie' @(posedge ram_bus enable), 4. Ожидание заднего фронта однобитового сектора dom sign[a] • @( negedge dorn.signfa]), 5. Ожидание переднею фронт dom.sigl или изменения сигнала dom sig2. @(posedge dom sigl or dom sig2), 6. Ожидание заднего фронта dom.sigl или переднего фронта dom.sig2: @(negedge dom sigl or posedge dom sig2), SystemVeniog к событийному управлению @ добавляет спецификатор iff Событие выражения будет вычисляться, если выражение после iff будет иметь значение «истина» В описанном ниже примере, если enable = 1, module latch (output logic [31 0] у input [31 0] a input enable), always @(a iff enable == 1) у <= а, //триггер-защелка в режиме приема данных endmodule Так же, как и в подобных событийных выражениях, оператору iff может предшествовать выражение or. Приоритет может быть указан ботее явно с помощью скобок. Если выражение указывает на input или snout, синхронизируемый блоком clocking, го оператор событийного конгролк использует синхронные значения сш нала, которые являются входными последовательностями, полученными в момент появления события синхронизации. Выражение может также управляться именным блоком синхронизации.
428 Переменные, используемые с событийным контролем, могут быть любого интегрального типа или строкой, простыми переменными или ссылочными ref (переменными, передаваемыми по ссылке), они могут быть элементами массива, ассоциативным массивом или объектом класса Событийное выражение должно возвращать единичное значение Члены объекта или объединенных элементов могут быть любого гипа, но результат выражения должен быть скалярным значением. Если событийное выражение обращается к определителю (handle) простого объекта, то событие фиксируется, когда значение, записываемое в переменную, не равно предыдущему. В событийных выражениях допускается использование невиртуальных и встроенных методов или системных функций, если они возвращают единичное значение и метод определен как функция, а не задача. Изменения значений элементов объектов или размеров динамических массивов приводит к повторному вычислению событийного выражения: real AORQ, // Динамический массив вещественных значений byte stream[$j // Очередь из байтов initial wait(AOR.size() > 0).. , // Ожидание, пока под массив не будет выделена память initial W3it($bits(stream) > 60)..., // Ожидание, пока общее число битов в потоке станет // больше чем 60 Packet p = new, // Пакет 1 Packet q = new, // Пакет 2 initial fork @(p status), // Ожидание изменение статуса status пакета 1 @q, // Ожидание изменения определителя q # 10 q = p, // Изменение @q II теперь ожидание @{p.status) для пакета 2 не будет отличаться от пакета 2 join 21.4.5. Управление сигналами в интерфейсе. Асинхронные сигналы, такие как reset, передаются через интерфейс без задержки. Для синхронизации сигналов в testbench используются операторы @ и wait (листинг 21.7). Листинг 2! 7. Синхронизация сигналов program automatic tesi(bus_if ТВ bus), initial begin @bus cb, // Выполнение продолжается по активному фронту // блока синхронизации repeat (3) @bus cb, // Ожидание трех активных фронтов @bus cb grant, // Ожидание любого изменения сигнала grant @(pcsedge bus cb grant), // Ожидание переднего фронта сигнала @(negedge bus cb grant), // Ожидание заднего фронта сигнала wait (bus.cb grant==1), // Ожидание выполнения условия // Задержки не будет, если условие имеет уже значение ИСТИНА @(posedge bus cb grant or negedge bus reset), // Ожидание событий
429 // для нескольких сигналов end endprogram Следующий пример (листинг 21.8) передает значения grant в DUT из arb. Листинг 21.8. Синхронизированная передача значений через интерфейс program test(arb_rf TEST arbif), initial begin $momtor("@%0d grant=%h", $time, arbif cb.grant), #50, end endprogram module arb(arb_if DUT arbif), initial begin arbif grant = 1, // @ 0ns #12 arbif grant = 2, // @ 12ns #18 arbif grant = 2, //@ 30ns end endmodule На временной диаграмме (рис 21.15) показано, что в программе сигнал arbif cb grant получает значение до фронта синхросигнала. При изменении входа интерфейса, при появлении фронта синхросигнала (time 30ns), значение не передается в testbench до следующего синхроцикла. Ниже представлена простейшая версия арбитра тес га программы. CUT аФ grant iJ^^XZIZTZZZTTTSfC Ti TEST arbif cb grant "ЩУ 1 XT" ■ T)f~3 10 20 30 40 Рис 21 15 Получение значений в синхронизированном интерфейсе Листинг 22.9. Testbench, использующий интерфейс, в котором определен блок синхронизации program automatic test (arbjf TEST arbif), initial begin arbif cb request <=2'b01, $d>sp!ay("@%0d Drove req=01", $time), repeat (2) @aroif.cb, if (arbif cb grant !=2'b01) $disp!ay("@%0d a1 grant '=2'b01", $time), end endprogram test
430 Любой сигнал синхронизации, подобный request, должен иметь две приставки: имя интерфейса (arbif) и имя блока синхронизации(сЬ), если этот сигнал не используется более чем в одном блоке синхронизации. Таким образом, arbif.cb grant - правильное имя, a arbif.grant нет. Интерфейсные сигналы должны всегда получать значения в неблокирующих операторах <-, так что сигнал проекта не изменяется непосредственно после выполнения присвоения, поскольку testbench изменяется только в период реактивации, в то время как код проекта изменяется только в период активности. Если testbench формирует сигнал arbif cb.request в момент времени iOOrss, одновременно и согласно операциям arbif.cb, clocking, @(posedge elk изменяется сигнал request. Но если testbench попытается изменить arbif.cb request в момент времени 101ns, то это изменение не будет распространяться до следующего синхро- цикла Таким образом, драйверы всегда синхронизированы. В примере из листинга 21.10 arbif grant получает значение из модуля и может получать значения в блокирующем операторе. Если testbench управляет синхронизированными сигналами интерфейса по активному фронту, значение передается немедленно в проект, потому что по умолчанию выходная задержка равна #0. В противном случае изменения будут выполнены по следующему активному фронту синхросигнала: // Передача значений сигналам интерфейса busif cb reauest <= 1, // Неблокирующее синхронное присвоение .;,._.. busif cb cmd <= cmd_Duf, // Неблокирующее синхронное присвоение ,.~«<: Пример (листинг 21.10) информирует, что произойдет при задании chi налов в тестовом блоке и передаче их через интерфейс в модуль арбитра arb. Листинг 21.10. Передача тестовых значений через синхронный интерфейс program test(arbjf.TEST arbif), initial begin # 2 arbif cb request <= 3, // @ 2ns #10 arbif cb request <= 2, // @ 12ns #18 arbif.cb request <= 1, // @ 30ns #50 finish, end endprogram module arb(arb_if DUT arbif); initial $monitor("@%0d req=%h", $t!me, arbif request), endmodule Если необходимо подождать два синхротакта до выполнения присвоения сигнала, можно использовать конструкцию repeat (2) @bus cb, или задержку цикла 4#2. Эта конструкция работает только с сигналами в синхронизированном блоке, поскольк) необходимо знать, какой синхросигнал используется для задержки (рис. 2) .16). // Передача значений сигналам интерфейса ##2 arbif cb.request <= 0, // Ожидание два такта до выпопнения присвоения ##3, // Неправильно, необходимо использовать вместе с присвоением
21.4.6. Двунаправленные в интерфейсе. В Veriiog, если необходимо управлять двунаправленным сигналом и связать его с регистровой переменной из процедурною кода, то применяется оператор непрерывного назначения, чтобы соединить переменные типов данных reg с wire В System Veriiog синхронные двунаправленные сигналы в интерфейсе реализуются с помощью непрерывного оператора присвоения. Когда в программе создается переменная класса линия, SystemVeriiog генерирует временную переменную для ее управления. Программа читает непосредственно из wire значения, которые передаются из всех драйверов. Код проекта в модулях также использует переменные класса register и непрерывные операторы присвоения (листинг 21.11). TEST arb cb request_ DUT arbif request Рис 21 16 Передача значений в синхронный инiерфейс Листинг 21.11 Двунаправленные сигналы в программе и интерфейсе interface masterjf (input bit elk), wire [7 0] data, clocking cb @(posedge elk), inout data, endclockmg modport TEST (docking со), endinterface // Двунаправленные сигналы program test(masierjf mif), initial begin mif cb dal Sdispiayh(mif cb data), @mif cb, mif cb data <= 7'h5a, @Tiif cb, mif cb data <= 'z, // Тристабильная шина // Чтение данных с шины // Передача значений на шину // Освобождение шины endprogram 21.5. Пример. Four-Port ATM Router Четырехпортовый ATM маршрутизатор. Его схема подключения к testbench для выполнения тестирования изображена на рис. 21 S7.
ATM IXI £3 *j Rx2 router Tx2 ^Щ Рис 2117. Интерфейс ATM маршрутизатор и testbench Следующий пример представляет группы линий, которые используются для соединения модуля уровня RTL с testbench. Листинг 21.12 Заголовок модели маршрутизатора ATM без интерфейса module atm_router( // 4 х Level 1 Utopia ATM layer Rx Interfaces output Rx_clk_0, Rx_clk_1, Rx_clk_2, Rx_clk_3 input [7 0] Rx_data_0,Rx_data_1,Rx_data_2,Rx_data_3, input Rx_soc_0, Rx_soc_1, Rx_soc_2, Rx_soc_3, output Rx_en.O, Rx_en_1, Rx_en_2, Rx_en_3, input Rx_clav_0,Rx_ciav_1 ,Rx_clav_2,Rx_clav_3, // 4 x Level 1 Utopia Tx Interfaces output Tx_clk_0, Tx_cik_1, Tx_clk_2, Tx_clk_3, output [7 0] Tx_data_0,Tx_data_1 Tx_data_2,Tx_data_3, output Tx_soc_ 0, Tx__soc_1 , Tx_soc_2, Tx__soc_3, output ">"x_en_0, Tx_en_1, Tx_en_2 Tx_en_3, mput Tx_clav_0,Ty_clav_1 ,Tx_ciav_2,Tx _c<av_3 // Miscellaneous control interfaces input rst, elk), endmodule Блок верхнего уровня, объединяющий компоненты системы, приведен в тише 21.13. Листинг 21.13 Модуль верхнего уровня без использования интерфейса bit elk, always #5 elk = 'c'k, //ire Rx_clk_0, Rx_cik_1, Rx_clk_2, Rx_clk_3, Rx_soc_0, Rx_soc_1, Rx _soc_2, Rx_soc_ 3, Rx_en_0, Rx_en_1, Rx_en__2, Rx_en_3, Tx_clk_0, Tx_clk_1, Tx_clk_2, Tx_c!k_3, Tx_soc_0, Tx_soc_1, Tx_soc_2, Tx_soc_3, Tx_en_0, Tx_en_1, Tx_en_2, Tx_en_3, Tx_clav_0, Tx_clav_1, Tx_c!av__2, Tx_clav_3, rst, wire [7 0] Rx_data_0, Rx_data_1, Rx_data_2, Rx_data_3, Tx_data_0, Tx_data_1, Tx_data_2 Tx_data_3, atm_routera1(Rx_clk_0, Rx_clk_1, Rx_elk_2, Rx_clk_3, Rx__data_0,Rx_data_1,Rx_data_2,Rx_data_3, Rx_soc_0, Rx_soc_1 Rx_soc_2, Rx_soc_3,
433 Rx_enJ), Rx_en_1, Rx_en_2, Rx_en_3, Rx_clav_0,Rx_clav_1,Rx_clav_2,Rx_clav_3, Tx_clk_0, Tx_clk_1, Tx_clk_2, Tx_clk_3, Tx_data_0,Tx_data_1 Tx_data_2,Tx_data_3, Tx_soc_0, Tx_soc_1, Tx_soc_2, Fx_soc__3, Tx_en_0. Tx_en_1, Tx_en_2, Tx_en_3, Tx_clav_0,Tx_c'av_1,Tx_clav_2,Tx_clav_3, rst, elk), test» (Rx_clk_0, Rx_cIk_1, Rx_clk_2, Rx_clk_3, Rx_data_0,Rx_data_1,Rx_data_2,Rx_data_3, Rx_soc_0, Rx_soc_1, Rx_soc_2, Rx_soc_3, Rx_enJ), Rx_en_1, Rx_en_2, Rx_en_3, Rx_clav_0,Rx_clav_1,Rx_clav_2,Rx_ciav_3, Tx_clk_0. Tx_clk_1. Tx_cik_2, Tx_clk_3, Tx_data_0,Tx_data_1,Tx_data_2,Tx_data_3, Tx_soc_0, Tx_soc_1, Tx_soc_2, Tx_soc_3, Tx_en_0, Tx_en_1 Tx_en_2, Tx_en_3, Tx_clav_0,Tx_clav_1,Tx_dav_2,Tx_clav_3, rst, cik); endmodule Листинг 21.14 представляет тестовый модуль Поргы и линии в нем занимают основную часть кода Листинг 21 14 Использование портов testbench module test( // 4 х Level 1 Utopia ATM layer Rx Interfaces input Rx_clk_0, Rx_ clk_1 Rx_clk_2, Rx_cik_3, output reg [7 0] Rx_data_0.Rx_data_1,Rx_data_2 Rx_data_3, output reg Rx_soc_0, Rx_soc_1, Rx_soc_2, Rx_soc_3, input Rx_en_0, Rx_en_1, Rx_en_2, Rx_en_3, output reg Rx__clav_0,Rx_c!av_1 ,Rx_clav_2,Rx_clav_3, 114%. Level 1 Utopia Tx Interfaces input Tx_cik_0, Tx_clk_1, Tx__clk_2, Tx_clk_3, input [7 0] Tx_data_0, Tx_data_1 ,Tx_data_2,Tx_data_3, input Tx_soc_0, Tx_soc_1, Tx_soc_2, "Tx__soc_3, input Tx_en_0, Tx_en_1, Tx_en_2, Tx_en_3, output reg Tx_clav_0, Tx_clav_1,Tx_cJav_2,Tx_ciav_3, // Miscellaneous control interfaces output reg rst input clkl. initial begin // Reset the device rst<=1, Rx_data_0 <= 0, end endmodule Использование интерфейса упрощает описание модели Применчются два интерфейса R\ и Тх с конструкциями modports и clocking (рис. 2! .18)
Рис. 21 18. Иию"1ьзование интерфейса для подключения testbench Описание портов устройства с использованием интерфейсов представлено в листинге 21.15 Листинг 21.15. Rx- и Тх-интерфейсы // Rx- интерфейс с конструкциями modport и блоками синхронизации interface Rxjf (input logic elk), logic [7 0] data, logic soc, en, clav, rcik, clocking cb @(posedge elk), output data, soc, clav, // Направление относительно testbench input en, endclocking • cb modport DUT (output en, rcik, input data, soc, clav), modport ТВ (clocking cb), endmtenace Rxjf // Тх- интерфейс с конструкциями modport и блоками синхронизации interface Txjf (input logic elk), iogic [7.0] data logic soc, en, clav, telk, clocking cd @(posedge elk); input data, soc, en, output clav, endclocking cb modoort DUT (output data, soc en, telk, input elk, clav), modport ТВ (clocking cb), endinterface Txjf // ATM router model with interface using modports module atm_router{Rxjf.DUT RxO, Rx1, Rx2 Rx3, xx_ifDUTTxO,Tx1,Tx2,Tx3, input logic elk, rst); // Модель верхнего уровня с и module top bit elk, rst, always #5 cik = 'elk
435 Rxjf RxO (elk), Rx1 (elk) Rx2 (elk), Rx3 (elk), Txjf TxO (elk), Tx1 (elk), Tx2 (elk), Tx3 (elk); atm_routera1 (RxO, Rx1, Rx2, Rx3 TxO,Tx1,Tx2,Tx3, elk, rst), test» (RxO, Rx1,Rx2, Rx3, TxO,Tx1,Tx2,Tx3, elk, rst) endmodule top 21.5 1. ATM testbench с интерфейсом. Листинг 21.16. представляет часть testbench, которая охватывает входные ячейки, идущие от портов ТХ-маршрутизатора Листинг 21.16 Testbench-ингерфейс с блоком синхронизации program test(Rxjf.TB RxO, Rxl, Rx2 Rx3, Tx_ifTBTxO,Tx1,Tx2, Tx3, input logic elk, output logic rst), bit [7 OJ byteb[ATM_CELL_SI2E], initial begm // Reset the device rst <= 1, RxO cb data <= 0, reeeive_cel!0(), end tasK receive_cellO(), @(TxO cb), TxO cb clav <= 1, // Assert ready to receive wait (TxO.cb soc == 1), // Wait for Start of Cell for (int i=0; i<ATM_CELL _SIZE i++) begin wait (TxO.cb en == 0), // Wait for enable @(TxO cb), bytesfi] = TxO cb data, @(TxO cb), TxO cb clav <= 0, // Deassert flow control end endtask receive_celiO endprogram test 21.6. Контрольные вопросы и задания 1. Что такое профамма? Чем профамма отличается от модуля? 2. Какие объекты в testbench относятся к уровню сигналов? 3. Какие объекты в testbench относятся к уровню команд? 4. Какие объекты в testbench относятся к функциональному уровню9 5. Какие объекты в testbench относятся к уровню сценария? 6. В чем отличие псевдослучайных и детерминированных методов генерации тестов для цифровых систем? 7. Дайте характеристику одиночным константным и функциональным неисправностям цифровых устройств.
436 22. АССЕРЦИИ Представлены модели, методы и типовые ассерционные HDL-процедуры наблюдения и управления процессом отладки программного кода, основанные на широких возможностях языка System Verilog конструировать эффективные решения для сокращения времени тестирования цифровых проектов, описанных на системных языках описания аппаратуры. Цель - исследование технологий создания процедур, маршрутов и структур ассерционной верификации, ориентированных на поиск семантических ошибок, изменяющих функционирование устройства и приводящих проект в неработоспособное состояние относительно заданной спецификации. Задачи - определение наиболее технологичных структур и процедур ассерционной верификации путем использования широких возможностей языка System Verilog, ориентированных на раннюю проверку аппаратных решений проектируемых цифровых систем на кристаллах. Источники. [1-5] - методы и структуры ассерционной верификации различных типов цифровых структур; [6-11] — технологии программирования процедур для создания среды ассерционной верификации проектов на основе System Verilog. 22.1. Последовательности (Sequence) SystemVenlog имеет возможность описания специфических последовательностей булевых выражений с явными временными взаимоотношениями между ними. Для определения совпадения последовательностей булевы выражения вычисляются в каждой точке считывания значений, определяемой синхросигналом, связанным с рассматриваемой последовательностью. Простейшее послетовательное поведение является линейным Линейная последовательность - это конечный список булевых выражений System Verilog в порядке возрастания времени. Говорят, что линейная последовательность имела место на конечном интервале следующих друг за другом синхрособы- тий, если первое логическое выражение принимает значение «истина» на первом синхрособытии, второе логическое выражение получает значение «истина» при поступлении второго синхрособытия, и так далее, вплоть до последнего логического выражения, которое должно принять значение «истина» на последнем синхрособытии. Примером простой линейной последовательности является булево выражение. Fro присутствие на указанном синхрособытии означает, что оно принимает значение «истина» в данный момент времени. Более сложное поведение в SystemVeriiog описывается с помощью последовательности (sequence), которая определяется как упорядоченная совокупность булевых выражений, включающая множество нулей, конечное или бесконечное число линейных последовательностей. Если хотя бы одна из них. входящих во множество, имеет место в конечном интервале последова-
437 тельных синхрособытий, то считаегся, что последовательность произошла на данном интервале времени. Самое базовое последовательное выражение - это порядок - «а следует за b на следующем синхротакте» на SystemVenlog может выглядеть так' :.., а##1 b В этом примере «##1» обозначает задержку на один синхротакт между следующим булевым выражением. В SystemVenlog каждый элемент последовательности может быгь либо булевым выражением, либо другой последовательностью. В 1ерминах последовательности булево выражение - это упрощенный вырожденный случаи последовательности длиной в 1 Таким образом, выражение конкатенации последовательностей s1 ##1 s2 обозначает, что последовательность s2 начинается на синхротакт после завершения последовательности si, как это изображено на рис. 22.1. В примере перекрывающихся последовательностей s1##0s2 упорядоченный набор s2 начнет свое выполнение в синхротакте, в котором последовательность si завершит свою функцию (рис 22.2). ~ЗЕЕ пш sl*#)s2 Рис 22 1 Перекрытие после ювательностей Хотя последовательности полезны для описания временных отношений между выражениями, важным является их оформление в виде элементов языка таким образом, чтобы они могли быть повторно использованы или на них можно было ссылаться. SystemVenlog определяет такой элемент языка - sequence. Кроме перечисленных возможностей, последовательности могут быть использованы при построении других упорядоченных наборов или как часть свойств ассерций. 22.1.1. Булевы выражения в последовательностях. Используемые в последовательностях выражения вычисляются на основе значений переменных, которые представлены в выражении Результат вы-
438 числения имеет булев тип и интерпретируется аналогично оператору if Существует ряд ограничений для выражений, которые применяются в последовательностях и ассерциях. В булевых выражениях, составляющих последовательности, не разрешены нецелочисленные данные (shortreai, real и realtime), строки, события, chandle, классы, ассоциативные и динамические массивы. Выражения позволяют включать вызовы функций, но существуют некоторые семантические ограничения. Функции, которые появляются в выражениях, не могут содержать выходной аргумент ссылочного типа ref (разрешаются const ref). Функции должны быть автоматические или защищены от статической информации. Массивы фиксированного размера, упакованные или нет, могут быть использованы полностью, в виде диапазонов или по отдельным элементам. Индекс может быть константой, параметром или переменной. Следующий пример показывает некоторые допустимые формы сравнения компонентов структур и объединений Пусть выполнено определение" typedef mt [4] array typedef struct {int a, b, c, d} record, union {record r array a,} p, q, Тогда следующее выражение является легальным: р а == q a или р г == q r Примеры использования массивов в выражениях: logic [7 0] аггауА [0 15], аггауВ[0 15], атауА == аггауВ, аггауА '= аггауВ; arrayA[i] >= аггауВЦ]; arrayB[i]Q+ 2] =- arrayA[k][m- 2], (arrayAp] & (-аггауВЦ])) == 0, Появляющиеся в выражениях переменные должны быть статическими переменными проекта или вызовами функций, возвращающих значения допустимых типов. Статические переменные, объявленные в программах, интерфейсах или блоках синхронизации могут быть также использованы в ассерциях. Если ссылка на статическую переменную декларируется в задаче, то значение такой переменной может быть прочитано в любой момент времени, независимо от вызова функции Разрешены все операторы, которые могут быть использованы с допустимыми в последовательностях типами данных, кроме операторов присвоения, инкремента и декремента. SvstemVerilog содержит операторы из языка Си, такие как ->-=, ++ and ~ Они не могут быть использованы в вычислении выражений, которые применяются в ассерциях.
439 22 1.2 Синтаксис Последовательность может быть задекларирована в модуле, интерфейсе, программе, блоке синхронизации, пакете и области единицы компиляции SystemVenlog синтаксис для декларирования и создания копий последова- гельностей: // Декларация sequence sequenoejdentifier [ ([ tf_port_iist ]) j, {assertion. vanabie_declaration} // Будут рассмотрены ниже sequence_expr, endsequence [ sequenoejdentifier ] // Создание копии последовательности sequencejdentifier [ ([ list_of_arguments ]) ] Необязательный список формальных параметров позволяет описывать последовательности, как общие временные взаимоотношения Формальные аргументы заменяются актуальными, которые передаются в последовательность при создании копии. Например, последовательность sequence seql (a, b), a##2b, endsequence представляет набор из двух выражений Когда создается копия последовательности seq1(e,f), актуальные аргументы е и f заменяют формальные аргумешы (а и Ь, соответственно), определенные в последовательности. Таким образом, временные взаимоотношения между е и f будут выглядеть как e##2f Табл. 22.1 объединяет операции, которые могут быть использованы в последовательностях Последовательности могут содержать синхрособытия Последовательность может декларироваться с помощью необязательных формальных аргументов. Когда создается копия последовательности, реальные аргументы взамен формальных передаются в последоватетьность. Актуальные аргументы могут быть представлены: идентификатором, выражением, выражением событийного контроля, верхним уровнем, как $(upper range as S). Переменные, используемые в последовательностях, не являющиеся фор- мальными аргументами, обрабатываются согласно области видимости для границ, в которых последовательность декларируется sequences'!, @(posedge elk) a ##1 b ##1 с, endsequence sequence s2, @(posedge elk) d ##1 e ##1 f, endsequence sequence s3, @(negedge elk) g ##1 h ##1 i endsequence
В примере последовательности si и s2 вычисл? elk, a s3 - по заднему. i по переднему фронту Таблица 22.1. Операции последовательностей 1 Операции I Конкатенация Перекрытие [Обнаружение | конца последовательности Повторение Обнаружение первого совпадения ИЛИ И Пересечение Уточнение условием В рамках Синтаксис seql ##1 seq2 seql ##0 seq2 seql ##1 seq2 ended seq1[*nm] first_match(seq1) seql or seq2 seql and seq2 seal intersect seq2 cond throughout seq seql within seq2 Объяснение Последовательность seq2 начинается со следующего синхротакта после завершения seql Последовательность seq2 начинается в том же синхротакте, в котором заканчивается последовательность seql Последовательность seq2 завершается на один синхротакт после завершения последовательности seql, независимо от момента начала последовательности seq2 Последовательность seql повторяется минимум п и максимум m раз Может йзормировать множественное совпадение последовательностей Если последовательность seql имеет множество совпадений, используется первое из них и игнорируются оставшиеся Формирует поспедовательность, которая возвращет значение "истина", если обнаружена хотя бы одна из последовательностей seql или seq2 Формирует последовательность которая возваращает значение "истина", если одна последовательность появляется до или после появления друой последовательности Matches | Возваращает значение "истина" в синхроииклах где выполняются обе последовательности seal I nseq2 | Условие cond имеет значение "истина" для каждого синхротакта seq Последовательность seql начинается вместе или после начала последовательности seq2 и заканчивается вместе с ней или до ее завершения _J Пример декларации последовательности, содержащей аргументы: sequence s20_1(data,en), ('frame && (data—data_bus)) ##1 (c_be{0 3] == en), endsequence Последовательность s20_I не включает описания синхронизации. В этом случае синхросигнал должен быть унаследован от внешнего источника, такого как оператор property или assert. К последовательности можно обращаться по имени. Может быть использовано иерархическое имя При описании задержек в последовательностях могут применяться операторы повторения:
441 1) Последовательное повторение (consecutive repetition ( [*)). Обозначает повторение последовательности. Например, (а ##1 b [*3J ##1 с) соответствует (а ##1 b ##1 b ##1 b ##1 с) Для описания конечного, но неограниченного числа повторений используется символ доллара (S) Например, а ##1 Ь П $] ## ■ с 2) Повторение переходом (goto repetition ([->)). В качестве операндов чаще используются булевы выражения, а не последовательности. Описывают итеративные совпадения булевых выражений по синхрособытиям, которые не обязательно являются последовательными и заканчиваются на последней итерации, возвращающей значение «истина». Например, (а ##1 b [->2 10] ##1 с) соответствует (а ##1 (('Ь[*0 $] ##1 Ь) [*2 10]) ##1 с) 3) Непоследовательное построение (nonconsecutivc repetition ([= )). Подобно повторению переходом, за единственным отли«ием чго проверка повторений не обязательно должна заканчиваться на последнем выражении, возвращающем значение «истина». Например, (а ##1 b [=2 10] ##1 с) соответствует (а ##1 (('Ь [*0 $] ##1 Ь) 1*2 10]) ##1 'Ь[*0 $] ##1} 22.1.3. Локальные переменные в последовательностях. Последовательности описывают временные взаимоотношения между сигналами. Тем не менее, чтобы описать сложное поведение, необходимо явно сохранять значения в некоторых точках последовательности таким образом. чтобы к ней можно обращаться позже. Рассмотрим последовательность «когда данные поступают в конвейер, они будут переданы наружу через 3-5 синхротактови увеличены на 1» sequence s5, intd, @(posedqe elk) (d = data, valid) ##[3.5] (dout == (d+D); endsOequence Когда данные поступают на конвейер и несколькими (3-5) тактами позже на выходе из конвейера dout метки правильного значения сигнала допжны быть равны входным данным, увеличенным на 1. Значение сшнала, поступающее в конвейер, сохраняется, а через 3-5 синхротактов выход конвейера dout должен быть равным входному значению, увеличенному на 1 Захват данных, выполненный в последовательности, позволяет избежать построения отдельного автомата или другого вспомогательного кода для захвата данных и необходимости редактирования его для каждой последовательности. Также нет необходимости сообщать другим инструментам, что вспомогательный код не является частью проекта, что упрощает использование таких инструментов 22 1.4. Событие последовательности (Sequence events). Копия конструкции sequence может быть использована в событийном выражении для управления выполнением процедурных операторов, основанных на положительном результате сравнения последовательностей Это позволя-
442 ет точке завершения именной последовательности sequence переключать множественные действия в других процессах Когда копия sequence описывается в событийном выражении, то процесс, выполняющий событийный контроль, должен блокироваться, пока указанная последовательность не достигнет конечной точки. Последовательность достигает точки завершения всякий раз, когда происходит совпадение с целой последовательностью. Процесс продолжает выполнение observe region, в котором конечная точка была обнаружена. Пример использования последовательности sequence для событийного управления: sequence abc, @(posedge elk) a ##1 b ##1 c, endsequence program test, initial begin @ abc $display( "Saw a-b-c"), L1 endprogram Ко1да именная последовательность abc достигнет конечной точки, блок initial в программе test будет разблокирован Выполнится оператор Sdisplay, выводящий строку "Saw a-b-c", и следующий за ним оператор с меткой L1. В этом случае конечная точка последовательности sequence рассматривается как переключение, являющееся событием. Для синхронизации используется точка выхода из последовательности, а точка входа игнорируется. Аргументы должны быть статическими, автоматические переменные приведут к ошибке. 22.1 5 Последовательности и события поспедовятельностей (Level-sensitive sequence controls). Выполнение процедурного кода может быть приостановлено, пока статус завершения последовательноеги не примет значение истина Это реализуется путем использования чувствительного к уровню оператора wait совместно (в конъюнкции) с встроенным методом triggered, который возвращает статус текущего конца именной последовательности (листинг 22.1.) Метод triggered возвращает значение «истина», если данная последовательность достигает конечной точки в определенный момент времени (текущий шаг моделирования), и «ложь» - в противном случае Статус переключения для последовательности устанавливается в области наблюдения (observe region) и продолжается в течение оставшегося временного шага (до следующего времени моделирования). Листинг 22. i. Использование методов последовательностей sequence abc @(posedge elk) a ##1 b ##1 c, endsequence
443 sequence de, @(negedge elk) d ##[2 5] e, endsequence program check, initial begin wait( abc.tnggered || de triggered ), if( abc triggered ) $display( "abc succeeded"), if( de.triggered ) $display( "de succeeded"), L2 end endprogram В представленном примере блок initial проверяет оператором wait завершение последовательности abc или de. Когда одно из вычисленных выражений примет значение «истина», опера юр wait разблокирует процесс, выведет сообщение и продолжит выполнение следующих операторов, начиная с метки L2. 22. 2. Ассерции в SystemVerilog Ассерции SystemVerilog разработаны для предоставления возможности описания поведения проекта з явной и однозначной манере. Ассерции в основном используются для проверки поведения проекта. Кроме того, они могут быть использованы для получения информации о функциональном покрытии и генерации входных стимулов для проверки Ассерции реализуются подобно другим б юкам проекта и активны для всего процесса моделирования. Программа моделирования отслеживает изменения ассерции. чтобы собрать функциональное покрытие данных SystemVerilog имеет встроенные эффективные унифицированные ассерции, которые могут быть использованы дтя моделирования и формальной верификации Основные преимущества их использования заключаются в следующем- 1) Легко настраиваются, потому что строятся на подобном языке и синтаксисе 2) Код ассерции - неболвшой по размеру, благодаря автоматическому концептуальному пониманию управляющей логики проекта. 3) Простое создание связей между ассерциями и testbench без необходимости разработки специального интерфейса. 4) Настройка и управление выводимыми сообщениями, возможность описания нескольких уровней ошибок 5) Возможность связи между Verilog и функциями языка С. 6) Возможность избежать рассогласования между моделированием и формальным вычислением с определенной семантикой распределения работ. 7) Возможность повышения производительности процесса верификации. Семантика SV^ определена так, что вычисление ассерции гарантирует эквивалентность между моделированием, которое основано на событии (cvent- bas»ed), и ассерциями, основанными на использовании синхротакта (cycle- based). Это гарантирует, что различные инструменты будут интерпрегиро-
444 вать поведение SVA одним и тем же способом. Кроме того, унификация ассерций с кодом проектирования и верификации повышает мощность инструмента ассерций, благодаря непрерывному процессу В частности, SystemVerilog позволяет ассерциям связывать информацию с testbench и дает возможность последнему реагировать на состояния ассерций без использования дополнительного интерфейса SystemVerilog поддерживает два типа ассерций: прямые (процедурные) и параллельные. Прямые (мгновенные) ассерций испопьзуют семантику моделирования событий и выполняются, как операторы в процедурном блоке Прямые ассерций, в первую очередь, предназначены для верификации в процессе моделирования проекта. Параллельные ассерций основаны на семантике синхронизации и захвате значений переменных в определенные моменты времени. Одной из задач ассерций в SystemVerilog является обеспечение общей семантики, чтобы они могли быть использованы для управления различными проектами и инструментами верификации Реальная мощность SVA, для моделирования и формальной верификации, заключается в возможности краткого описания последовательного поведения и вычисления ассерцион- ных значений в дискретных точках процесса моделирования, обычно по синхротакгу. Концепции и компоненты, составляющие параллельные ассерций, могут рассматриваться как множество слоев, из которых каждый строится на нижележащем слое (рис. 22.3). Базовая функция ассерций описывает множество поведений, которые должны иметь значение истины для данного проекта или компонента Слой булевых выражений является самым базовым и описывает значения элементов в конкретной точке времени, в то время как слой последовательностей строится на булевом уровне и описывает временные взаимосвязи между элементами на протяжении периода времени. Слой свойств использует последовательности для описания реального поведения, а слой директив ассерций связывает это поведение с инструментами верификации и проектирования. Assertion Directives Property Declarations Sequential Reguiar Expressions Seauential Regular Expressions Рис 22 3 Сл assert, cover, bind declarative instantiation procedural instantiation disable iff, not. implicabon repetition, delay, and, or, intersect, first_rnatch, within, through <expr>, <function> endea, matched, <temporal_edge_function> m построения ассерций 22.2.1 Выборка значений переменных (Sampling). Для обеспечения устойчивости между системой моделирования и инструментами формальной верификации параллельные ассерций в SystemVerilog используют выборку значений сигналов для вычисления выражений. Эти образцы определены как значения сигналов в конце последнего шага моде-
445 лирования перед появлением синхрособы гия. Таким образом, может быть получен предсказуемый результат, независимо от внутренней реализации очередности и вычисления событий симулятором Возможность возникновения гонок - это недостаток семантики планирования событийного моделирования в Veriiog, который позволяет нескольким событиям случаться в заданный период моделирования. Поскольку инструменты синтеза и формальной верификации используют синхронный подход к проекту, условия гонок всегда разрешаются согласно семантике считывания значений для построения ассерции в SystemVenlog. Это означает, что ассерции дают пользователю постсинтезный взгляд на проект во время до- синтезной RTL верификации, исключая возможность возникновения различного поведения проекта до и после синтеза. 22.3. Прямые (процедурные) ассерции Мгновенные (прямые) ассерции используются в процедурном коде в любом месте блоков initial и always. Синтаксис прямых ассерции- assert ( expression ) [[ pass_stmt ] else fait_stmt ], Выражение вычисляется сразу, при выполнении оператора. Операторы, содержащиеся в ветвях раьч и fail, если они присутствуют, выполняются мгновенно после вычисления выражения Процедурный код testbench может проверять значения сигналов проекта, переменных и выполнять необходимые действия, в случае обнаружения ошибки Например, в проекте выполняется проверка запроса шины request и ожидается, что ответ будет получен двумя тактами позже Тестирование эгой ситуации можно выполнить с помощью оператора if: // Проверка сигнала с помощью оператора if bus cb reques* <= 1, @bus cb, if (bus cb grant '=2'b01) $display("Error, grant|= 1"), // Остальная часть теста Оператор ассерции более компактен, чем оператор if. При этом значение условия есть противоположное, записываемому в if Другими словами, если условие имеет значение «истина», то выполнение ассерции было успешным: // Простая процедурная ассерция bus.cb. request <= 1, @bus cb, a1: assert (bus cb grant == 2'b01), // остальной код теста Если сигнал grant получен правильно (grant=2'b01), тестирование будет продолжено. Иначе будет выдано следующее сообщение: "test sv", 7 top tl a1 started at 55ns failed at 55ns Offending '(bus cb grant == 2'bl)
446 Сообщение говорит, чго в линии 7 файла testsv ассерция top tl al начала свое выполнение в момент 55ns для проверки сигнала bus cb.grant и сразу же обнаружила ошибку. Процедурные ассерции имеют ветви then- и else-, а при необходимости в них могут быть добавлены операторы: '/ Создание пользовательского сообщения об ошибке а1 assert (bus cb grant ==2'b01) eise $error("Grant not asserted"); Если сигнал grant не имеет ожидаемого значения, то будет выведено соответствующее сообщение- "testsv" 7 top t1 a1 started at 55nsfailed at 55ns Offending '(bus cb grant == 2'b1)' Grant not asserted SystemVerilog имеет четыре функции для вывода сообщений" Sinfo, $warmng, Serror и Sfatal, которые могут быть использованы только в операторе ассерции Можно применять ветвь then для записи количества успешных выполнений оператора ассерции. // Создание пользовательского сообщения об ошибке а1 assert (bus cb grant ==2'b01) grants_received++, // Количество успешных выполнений else $error("Grant not asserted"), Операторы прямых ассерции выполняют тестирование указанных условий в момент своего выполнения в процедурном коде Выражение интерпретируется тем же способом, что и условие в операторе if Если значение выражения равно X, Z или 0. оно рассматривается как «ложь» и ассерция не прошла Tail), иначе - «истина» и ассерция прошла (pass). Оператор, связанный с успешным выполнением ассерции, записывается первым, называется pass- оператором и выполняется, если значение выражения есть «истина» Pass- оператор может, например, записывать число успешных проходов в файл отчета (log), но может вообще отсутствовать Если оператор для ветви успешного выполнения ассерции не указан, то никакие действия в этом случае выполняться не будут Оператор, ассоциируемый с веткой else, называется fail-оператор и выполняется, если значение выражения есть «ложь». Присутствие этого оператора также является необязательным. Указанные действия выполняются мгновенно, после вычисления ассерции. Необязательная метка оператора создает именную конструкцию, и она может быть выведена с помощью символа форматирования %т. Например, assertjbo assert(foo) $display("%m passed") else $display("%m failed"); Поскольку ассерция - это оператор, который может принимать значение «пожь», то провал ассерции должен иметь связанный с ним уровень серьезности ошибки. По умолчанию, такой уровень равен епог. Задать или явно указать уровень ошибки можно, включая одну из следующих системных задач, реализующих уровень серьезности провала ассерции: Sfatal - фаталь-
447 ная ошибка; Serror - ошибка времени выполнения; Swaming - предупреждение о чрезмерном времени выполнения задачи сиаемой моделирования; $mfo - означает, что провалу асссрции не назначен определенный уровень серьезности. Все эти задачи должны выводить определенные сообщения, обозначающие уровень серьезности провала ассерции и определенную информацию, которая должна включать следующее 1) имя файла и номер линии оператора ассерции; 2) иерархическое имя оператора ассерции. если он имеет имя, или границы видимости ассерции, если нет метки Для инструментов моделирования эти задачи должны сообщать суточное время моделирования задачи. Каждая системная задача может также включать дополнительную, описываемую пользователем информацию, используя тот же самый формат представления данных, что и оператор Veriiog Sdisplay. Если ветвь else содержит более чем одну из этих системных задач, то каждая из них должна быть описана указанным способом В следующем примере задача уровня серьезности выполняется не в момент провала ассерции, но, тем не менее, выведено реальное время обнаружения ошибки, time t, always @(posedge elk) if (state == REQ) assert (real || req2) else begin t = $time, #5 $error("assert failed at time %0t",t), end Если ассерция провал и гея в момент времени 10, сообщение об ошибке будет выведено в момент времени 15, но при этом содержать оно бучет ''assert failed at time 10". Вывод информационных сообщений и предупреждений может контролироваться опциями, формируемыми командами Поскольку fail-операторы, как и pass-операторы, являются легальными процедурными операторами SystemVenlog, то они могут быть также использованы для формирования условий выполнения ассерции в другой части testbench: assert (myfunc(a,b)) countl = count + 1, else ->event1, assert (y==0) else flag = 1, 22.4. Параллельные ассерции Другой тип - параллельные ассерции выполняют проверку сигнала в течение всего процесса моделирования. При их описании используется синхронизация. Параллельные асссрции отличаются от прямых двумя важными аспектами. Во-первых, в дополнение к прямой записи в проекте, подобно операторам в блоках always или initial, они могут быть реализованы декларативно, на уровне непрерывных операторов присвоения и реализации модулей (подобно непрерывному присвоению) за границами процедурных блоков. Второе отличие заключается в том, чго параллельные ассерции позволяют опи-
448 сывать поведение системы во времени вместо комбинационных условий в прямых ассерциях. Синтаксис: assert property ( sequentiai_expr_or_prop8rty) [[ pass_stmt ] else fai!_stmS ] Ключевое слово property отличает параллельную ассерцию от прямой. Последовательное выражение вычисляется с использованием значений сигналов и позволяет операторам pass/fail связываться с testbench. Поскольку ас- серции являются внутренней частью языка, эти операторы могут применять SystemVerilog в полном объеме для переключения событий, записи информации о покрытии или других воздействий на порядок кода верификации, включая вызов функций языка С. Отдельный язык ассерций эффективен только в режиме «read-only». Он позволяет наблюдать за поведением проекта, но не допускает элементов воздействия на проект и testbench. В следующем примере выполняется проверка ассерций - сигнал арбитра не принимает значение X или Z, кроме ситуации сброса устройства, когда reset=l (листинг 22.2). Листинг 22 2. Параллельная ассерция для проверки значения X/Z interface arbjf{input bit elk), logic [10] grant, request logic reset, property request 2state, @(posedge elk) disable iff (reset) $isunknown(request) == 0, endproperty assert_request_2state assert pioperty request_2state endmterface Параллельные ассерций описывают поведение, которое охватывает большой промежуток времени В отличие от прямых ассерций, обработка модели основывается на синхронизации Параллельная ассерция вычисляется только при появлении события синхронизации. При этом используется выборка значений переменных. Независимо от внутреннего механизма обработки событий симулятором, в результате вычислений может быгь получен предсказуемый результат. Эта исполнимая модель соответствует также синтезируемой модели аппаратной реализации RTL-онисания. Значения переменных, используемых в ассерциях. собираются в подготовительный период (Preponed) временного слота, ассерций вычисляются в периоды наблюдения (Observe). Если переменная, используемая в ассерций, является входной для блока синхронизации, то ее значение считывается # lstep шагом управления. Любые другие типы выборок для переменных блоков синхронизации приведут к ошибке Ассерций, использующие переменные блоков синхронизации, не создают свой способ выборки значений, а применяют процедуру, указанную в блоках синхронизации Временные модели, применяемые в спецификациях параллельных ассерций, основаны на синхрособытиях и используют обобщенное понятие синхротак-
449 га. Определение синхронизации, как правило, создается пользователем и можег изменяться от одного выражения к другому. Событие синхронизации это отдельный момент времени, который сам не имеет длительности. Событие синхронизации может иметь место только один раз в течение любого времени моделирования. Значения выборки сигналов для этого периода моделирования используются при вычислении параллельных ассерции. Рис. 22.4 представляет состояние переменной при изменении синхронизации. Ш1ПШШШ 1 12 13 14 Рис 22 4 Периоды получения значений Значения сигнала req равны нулю в моменты событий синхронизации 1 и 2. При событии 3 значение выборки переключается в единицу и остается в таком состоянии до синхрособытия 6. Значение переменной req в момент события 6 становится равным нулю и остается таким для событий 7, 8 и 9. Синхрособытие 9 происходит вместе с переключением сигнала req, однако значение выборки для этого момента остается равным нулю, поскольку, согласно семантике языка, значение считывается за один шаг (istep) до появления события Выражение, используемое в ассерциях, всегда связано с определением синхронизации Значения выборки, используемые для вычисления изменяемых или булевых выражений, необходимы для обнаружения последовательности. Для параллельных ассерции нужно выполнять следующие условия 1. Гарантировать свободное от сбоев определение поведения синхросигнала. В противном случае могут быть получены ошибочные значения выборок. 2. Если переменная, которая появляется в выражении синхронизации, также появляется в ассерции, то значение переменной может быть различным. Текущее ее значение иепольз\ется в выражении синхронизации, в то время как значение выборки переменной используется внутри ассерции. Выражение синхронизации, которое контролирует вычисление последовательности, может быть более сложным, чем просто имя одного сигнала. Для описания синхронизации могут быть использованы выражения вида: (elk && gating_signal) и (elk iff gatmgsignal). Возможны другие, более сложные конструкции Однако в целях обеспечения правильного поведения системы и соответствия семантике синхронного моделирования, сигналы в выражениях синхронизации должны быть свободны от рисков сбоев и иметь только одно переключение. Пример параллельной ассерции приведен ниже. base_rule1 assert property (cont_prop(rst,in1 ,ir>2)) $display("%m, passing"), else $display("%m, failed"); Свойство может выполнять проверку одной или нескольких последовательностей, стартующих в различное время. Вычисление каждый из них начинается с поиска совпадения начала последовательности на заданном синхросо-
450 бытии Чтобы определить наличие совпадения последовательности, вычисляются соответствующие булевы выражения, начиная с определенного син- хрособытия, и продолжаются при каждом последующем синхрособытии, пока выражения имеют значение «истина». Если зафиксировано значение «ложь», то совпадения нет. 22,5. Свойства (Properties) Во многих случаях последовательности позволяют описывать поведение системы. Задавать проверку поведения можно с помощью свойств Они по- звочяют инвертировать смысл последовательности, отключить ее вычисление или применить последовательность к другим событиям. Для определения свойств используется следующий синтаксис: // Декларация свойств property name [ (formaijtem {, formaljtem }) ], {assertion_variab!e_declaration} property_spec, endproperty [ name] Описание свойств состоит из последовательностей или их импликации, а также других свойств: property_spec = [clocking_event] [disable iff( expression )] [ not ] property_expr property_expr ::= sequence_expr | imphcabon_expr Определение свойств выполняется в границах property-endproperty и поддерживает формальные аргументы поведения последовательности. Например. property р1, <: @(posedge elk) disable iff (test) not abort_seq, endproperty Оператор not инвертирует смысл последовательности abortseq, таким образом, выражение будет иметь значение «ложь» при появлении последовательности abortseq. Выражение disable iff отключает вычисление последовательности, если и только если сигнал test=l Возможно повторное использование ключевых слов disable и iff, которые применяются в других конструкциях SystemVerilog Это свойство должно интерпретироваться как «пока сигнал test=0, следует проверять отсутствие появления последовательности abortseq». Другая полезная поведенческая концепция - «это исключается» (that of implication). Пусть необходимо проверить появление последовательности после фиксации initseq. Такое свойство может быть описано следующим образом. @(posedge elk) inii_seq |=> abort_seq, где \=> неперекрываемый оператор импликации. Это выражение свойств утверждает, что каждая успешно завершенная последовательность mitseq первого операнда подразумевает, что abort_seq из второго операнда выполняется на следующем синхротакте Для каждого такта, в котором успешное
451 завершение последовательности первого операнда не присутствует, последовательность второго операнда не будет вычислена и свойство рассматривается как «истина». Свойство определяет поведение проекта. Оно может быть использовано для верификации, как спецификация предположения, проверки или покрытия. Для того чтобы использовать поведение для верификации, применяются операторы assert, assume или cover. Декларация свойства не приводит к результату. Свойство property, как и последовательность, декларируется с необязательными формальными аргументами. Когда свойство вычисляется, в него передаются фактические аргументы. Механизм их передачи в свойства аналогичен передаче аргументов в последовательность Здесь она получает расширение с реальными аргументами, заменяющими фор.мальные аргументы. Результат вычисления свойств: «истина» или «ложь». Существует семь видов свойств, последовательность (sequence), отрицание (negation), дизъюнкция (disjunction), конъюнкция (conjunction), if. .else, импликация (implication) и создание копии (instantiation) 1) Свойство типа последовательность является последовательностью, вычисляемой при значении «истина», если и только если существует непустое совпадение последовательности. Если она допускает пустое совпадение, то такой результат недопустим для свойств, поскольку совпадение существует, если и только если существует первое совпадение. Вычисление такого свойства есть полное трансформирование sequencc_expr в first_ match (sequencc_expr) Как только первое совпадение sequence_expr обнаруживается, вычисление свойства рассматривается как «истина» и нет необходимости в поиске других совпадений. 2) Свойство типа отрицание имеет следующий вид: not property__expr При каждой попытке вычисления свойств вычисляется property ехрг Ключевое слово not обозначает, что при его вычислении возвращается противо положное значение для property_expr. Таким образом, если property_expr принимает значение «истина», то not property expr соответствует значению «ложь», и если property_ехрг оценивается как «ложь», ю not property_expr будет «истина». 3) Дизъюнкция свойств имеет следующий вид: property_expr1 or property_expr2 Свойство соответствует значению «истина», если и только если одно из свойств property_exprl и property_expr2 «истина». 4) Конъюнкция свойств имеет следующую форму property_expr1 and property_expr2 Свойство оценивается как «истина», если и только если property_expr 1 и property_expr2 имеют значение «истина». 5) Свойство « if ..else» имеет следующую форму, if (expression_or_dist) property_expr1
452 или if (expression_or_dist) property_expr1 else property_expr2 Свойство в первом случае оценивается как «истина», если и только если expression_or_dist принимает значение «ложь» или property_exprl - «истина» Во втором случае свойство возвращает значение истина, кома expression_or_dist и property_exprl возвращают значение «истина», иначе expression^ ordist вычисляется в «ложь», a property^ expr2 - «истина». 6) Свойство типа импликанта имеет следующую форму: sequence_expr |-> property_expr или ssquence_expr |=> property_expr 7) Копия именного свойства может быть использована в выражении property_expr or property_spec. В общем случае, использование копии является законным, если тело именного свойства propertyspec может заменить его копию в property_expr or property_spec, подставляя реальные параметры, вместо формальных аргументов и игнорируя локальные переменные. Если копия именного свойства используется как операнд propertyexpr в любом формирующем свойство операторе, то это свойство не должно включать выражение disable iff. Аналогичным образом, события синхронизации в именных свойствах должны соответствовать правилам мультисинхронной поддержки, в случае если свойство входит в выражение propertyexpr (property_spec), которое также управляется другим сичхрособытием. Табл. 22.2 представляет списки операторов для последовательностей и свойств, начиная с самого высокого приоритета, и показывает сочетаемость для неунарных операторов Выражение disable iff может быть подключено к (a property_expr), чтобы сформировать property_spec: disable iff (expression_or_dist) property_expr Выражение disable iff называется условием сброса (reset expression) и позволяет описывать приоритетный сброс. Для вычисления property_spec оцениваются составляющие property^ ехрг. Если до завершения такого вычисления выражение сброса принимает значение «истина», то состояние свойства propertyspec - «истина». В противном случае значение propertyspec зависит от результата вычисления propertyexpr. Сброс выражения проверяется независимо для различных попыток вычисления property spec. Значения сигналов в выражении сброса являются значениями переменных в текущем цикле моделирования, а не их выборками. Выражения могут содержать ссылку на конечную точку последовательности с помошью метода ее переключения. Методы сравнения и обнаружения конца последовательности и локальные переменные не могут быть использованы в выражении сброса. Если значение выборки функции используется в
453 выражении сброса, то синхронизация выборки должна быть явно описана в списке актуальных аргументов. Таблица 22.2. Операторы последовательностей и свойств Sequence operators П. Н. М ## throughout within intersect and or Property operators not and ___ ] or if else l->, l=> Associativity - Left Right Left Left Left Left Riqht Right Свойства никогда не вычисляются для проверки выражений. Их используют в операторе верификации, который устанавливает одну из следующих функций: assert - для проверки описания свойства, чтобы обеспечить его место в проекте; assume - для описания свойств в качестве предположения для среды; cover- для мониторинга вычисления свойств покрытия. 22.6. Системные функции, используемые в ассерциях Ассерции используются для вычисления специфических особенностей реализации проекта, например, определенный сигнал содержит только одну единицу. Следующие системные функции введены для описания функциональности ассерции $onehot (<expresbion>) возвращает значение «истина», если только один бит выражения равен 1; SonehotO (<expression>) возвращает значение «истина», если как минимум один бит выражения равен 1; Sisunknown (<expression>) возвращает значение «истина», если любой бит выражения равен X или Z 1то эквивалентно Л <expression> •= 'bx Все перечисленные системные функции возвращают значение типа bit Возвращение значения 1'Ы соответствует «истине», а значения ГЬО - «ложь». Другая полезная функция, предоставляемая для логического выражения Scountones, подсчитывает количество единиц в битовом векторе: $countones(expression) Значения X и Z не засчитываются в число единиц. 22.7 Параллельные и прямые ассерции На практике большинство мгновенных (immediate) ассерции выражается в некоторой форме импликации, что требует их записи ддя формирования предыдущего выражения в целях его переключения. Как указывалось ранее, одно из ключевых преимуществ ассерции - простота их встраивания в проект для инженеров-проектировщиков. Тем не менее, декларация ассерции часто требует дополнительных усилий от проектировщика для эффективного их использования. Далее рассматривается модель управляющего автомата Ассерции в данном типе проектов часто формируют высказывания «если это
454 состояние, то должно произойти» и <^если в состоянии АСК некоторая переменная foo равна 1, тогда регистр должен сохранять значение 0 в течение 5 синхротактов» Параллельная ассерция для проверки данного условия может быть записана следующим образом: Р1 assert property( @(posedge elk) (st = АСК) && (foo == 1) |-> 'req[*5]), При этом RTL-код автомата должен выглядеть следующим образом: always @(posedge elk) case (st) АСК if (foo ==1) begin // в этом состоянии req=0 в течение 5 синхротактов end endcase Получаются два фрагмента информации, которые дублируются в проекте, также ассерции: синхронизации и переключения состояний. Вместо того, чтобы требовать от проектировщика дублирования этой информации, ассерции, являющиеся частью языка проектирования, могут быть процедурно встроены в R1 L-код и автоматически выводить информацию при их использовании, например ^,._ always @(posedge cik) case (st) АСК ■f(foo==1) begin P2. assert property ('req[*5]), end Прямая ассерция (Р2) является семантически эквивалентной декларации параллельной ассерции (Р1), приведенной выше, но гораздо проще в использовании и обслуживании. Пооцедурные встроенные ассерции используют полученные значения сигналов для оценки условий переключения, как делают это декларативные ассерции. Правила логического вывода для предшественников включают в себя case и jf-else операторы, что позволяет вводить в процедурные ассерции переключения произвольной сложности. В результате преимущество процедурных ассерции есть простое обслуживание Если изменяется код конечного автомата, условия переключения для ассерции автоматически обновляются, а пользователю следуе! модифицировать код вручную, чтобы обновить переключения, соответствующие декларативным ассерциям.
455 22.8.Взаимодействие ассерций и testbench Как указывалось ранее, преимуществом ассерций, взаимодсйств\юших с проектом и языком верификации - это возможность для ассерций передавать информацию в testbench. В отдельном языке ассерций не с\ шествовало талого механизма коммуникаций. В Sy»temVeriiog в ветвях pass и fail ассерций могут выполнять любые процедурные операторы, позволяя пользователю передавать информацию в testbench о выполнении последовательности, обновлять счетчики покрытия, делать установку значений сигналов, вызов методов обьектов класса, или даже вызов кода Си. Пусть шина включает свойство «новый цикл шины не может начаться раньше, чем через 2 синхротакта после появления сигнала завершения цикла abort_cycle» Это свойство может кодироваться как property wait_after_abort, @(posedge elk) abort_cyc!e |=> |cycle_start[*2], endproperty P3 assert property (wait_after_abort), Когда появляется последовательность abort_cycle, свойство диктует, что сигнал eyeSe start будет равен нулю в течение двух синхротактов. Свойство РЗ кодирует это поведение и может быть использовано для мониторинга во время моделирования и проверки поведения, а также в формальных инструментах, чтобы доказать невозможность некоторого состояния Тем не менее, еспи это свойство определяет поведение интерфейса верхнего уровня, testbench будет генерировать транзакцию шины для подтверждения состояния интерфейса. Инженеры верификации, создавая testbench, могут повторно использовать информацию ассерций, как константу, которая помогает гарантировать, что генерируемые символы никогда не нарушат поведение Такой testbench может выглядеть подобным образом: program rnanual_stimulus_generator, repeatdOOO) begin generate_transaction(addr,data), while(wait_ cnt > 0) @<posedge elk) wait_cnt~. end endprogram Счетчик wait_cnt используется для описания задержки между транзакциями шины, i енерируемыми модулем testbench. Последовательность abort_cycle может быть применена для установки счетчика, используя директиву покрытия: cover property( aDort_cycle ) wa.t_cnt = 2, Использование cover позволяет обнаруживать последовательность abort_cycle без формирования ошибки, если она не присутствует. Если последовательность обнаружена, то счетчик \vait_cnt устанавливается в 2, за-
456 ставляет testbench ждать 2 такта до генерирования следующей транзакции. Семашика формирования порядка обработки событий SystemVerilog гарантирует, что здесь не будет гонок между выполнением pass statement и testbench, что нельзя было бы гарантировать, если бы ассерции были реализованы с помощью другого языка. . .,._. .._ SystemVeniog включает возможность описания явного синхронного интерфейса между testbench и проектом. Конструктор области синхронизации определяет, когда относительно синхронизации testbench будет захватывать и передавать тестируемому устройству (DUT) сигналы. По умолчанию, захват значений сигналов в testbench аналогичен захвату с использованием ассерции, что гарантирует - testbench имеет доступ к тем же значениям, что и ассерции. Это не только позволяет избежать гонок между ассерциями testbench, ассерциями и тестируемым устройством, но также дает testbench преде гавление о «post-synthesis» поведении устройства относительно гонок, согласно правилам синтеза, во время RTL-верификании, выполняемой до синтеза. 22.9. Поддержка мноюдомениой синхронизации ~"''—"' Последовательности и свойства могут использовать мкогодоменную синхронизацию. 22 9.1. Последовательности с множественной синхронизацией (Multiply- clocked sequences) Последовательности с множественной синхронизацией строятся путем конкатенации нескольких наборов с помощью оператора конкатенации с единичной задержкой Ш\ Этот оператор не перекрывает и не синхронизирует соединение синхросигналов двух последовательностей. Единичная задержка, обозначаемая ##1, понимается как задержка между окончанием первой последовательности, которая управляется первым синхросигналом, и ближайшим активным событием или фронтом второго синхросигнала, с которого начинается выполнение второй синхропоследовательности Например, @(posedge clkO) sigO ##1 @(posedge clkl) sigl Поиск последовательности начинается со сравнения sigO после появления переднего фронта clkO. Затем 4Ь\ инициирует задержку до ближайшего переднего фронта sigl. Поиск последовательностей завершается с окончанием набора sigl. Если clkO и clkl не идентичны, то синхрособытие переключается после ##!. Иначе, если clkO и clkl равны, синхронизирующее событие не изменяется после ##1 и представленная последовательность эквивалентна набору с одним синхросигналом: @(posedge dkO) sigO ##1 sigl Когда выполняется конкатенация различно синхронизированных последовательностей, максимальный набор с единичной синхронизацией необходим, чтобы допустить непустое совпадение Если последовательности si и s2 являются выражениями наборов без событий синхронизации, то то1да последовательность с множественной синхронизацией
457 @(posedge clkl) s1 ##1 @(posedge cik2) s2 допустима, если si или s2 совпадают с пустым словом. Событие переднего фронта синхросигнала elk J применяется на всем протяжении поиска последовательности si, в то время как передний фронт clk2 является событием синхронизации во время поиска последовательности s2 Если совпадение si - не пусто, то это событие является конечной точкой совпадения переднего фронта clkl. Синхронизация между конечной точкой последовательности и появлением переднего фронта cik2 после этого достигается с помощью оператора ##!. Передний фронт clk2 является начальной точкой поиска последовательности s2. 22.9.2. Свойства с мультисинхронизацией (Multiply-clocked properties). Для свойств с мулыисинхронизацией результат вычисляется так же. как и для случая с единственным синхросигналом. Свойства с множественной синхронизацией могут быть описаны в несколько способов Последовательность с мультисинхронизацией является сама по себе свойством с мульти- синхронизацией. Например, @(posedge clkO) sigO #41 @(posedge clkl) sigl есть свойство с множественной синхронизацией. Если последовательность с множественной синхронизацией вычисляется как свойство, начинающееся в некоторой точке, вычисление возвращает значение истины, если и только если существует совпадение в последовательности с множественной синхронизацией в этой точке. Булевы операторы свойств (not, and, or) могут быть использованы свободно для комбинирования одно- и мультисинхронного свойства Значения операторов булевых свойств равны единице, как и для случая отдельно синхронизируемых свойств. Например, (@(posedge clkO) sigO) and (@(posedge clkl) sigl) мультисинхронное свойство, но не мультисинхронная последовательность. Это свойство возвращает true в точке, если и только если две последовательности @(posedge c!kO) sigO @(posedgecik1)sig1 совпадают в начале этой точки. Два неперекрывающихся оператора импликации |=> можно использовать для создания мультисинхронного свойства из предшествующей последовательности и последующих свойств, что означает их мультисинхронизиро- ванпость. Значения мультисихронизированной и односинхронизируемой неперекрывающихся импликаций подобны. Например, если sO, si - последовательности с несинхронизируемым событием, тогда @(posedge clkO; sO |=> @(posedge clkl) si |-=> синхронизируются передним фронтом clkO и clkl. Начиная с точки, в которой импликация была вычислена, каждое совпадение sO синхронизируется с
458 сигналом clkO. При этом изменения в точке происходят по переднему фронту clkl. Кроме того, для формирования значения точки должно выполняться совпадение si с синхросигналом ciki в промежутке времени между передними фронтами clkO и clkl. Начиная с точки, в которой вычисляется импликация, для каждого совпадения sO, синхронизированного сигналом clkO, время движется от конечной точки совпадения к ближайшей, которая будет активизирована передним фронтом clkl. При этом здесь должно существовать совпадение сигнала si с синхросигналом clkl. Синхронизация между отдельными синхросигналами всегда требует строгого предшествования во времени Два оператора, создающих свойства, требуют специадьное свойство с множественной синхронизацией для перекрытия импликацией |-> и если if/ if...else. Позже импликация |-> должна обеспечивать синхронизацию перекрытия конца предшественника с началом преемника. Например, если clkO и clkl не идентичны и sO, s3, s2 - это последовательности с несинхрони- зированными событиями, тогда @(posedge clkO) sO |-> @(posedge clkl) s1 ##1 @(posedge clk2) s2 не есть правильное выражение, но (§Hposedge clkO) sO |-> @(posedge clkO) s1 ##1 @(posedge cik2) s2 является правильным. 22.9.3. Синхропоток (Clock flow). Синхропоток позволяет масштабировать события синхронизации для того, чтобы распространять его обычным способом через различные части муль- тисинхронных последовательностей и сокращать число мест, в которых одинаковые события синхронизации должны быть описаны. Поток синхронизации обеспечивает в мультисинхронной последовательности или свойстве масштабируемость события синхронизации, идущею слева направо через линейные операторы (повторение, конкатенация, отрицание, импликация). Кроме того, выполняется распределение операндов через операторы ветвления (конъюнкция, дизъюнкция, пересечение, if... else), пока процесс не будет заменен новым событием синхронизации. Например, @(c)x!=>@(tfy##l@(d)z может быть записано в более простой форме @(c)x|=>y##l@(d}z, потому что синхросигнал с является проходящим через | =>. Синхропоток избавляет разработчика от необходимости записывать синхрособытия в позициях, где не допускается изменение синхронизации. Например- @(c)x!->@{c)y##1@(d)z может бы гь записано как @(c)xj->y##1@£d)z, что означав - усилить ограничения на то. что синхронизация не изменится при переходе через , -> Аналогично конструкция @(с) if (Ь) @(с) w ##1 @(о) х else @(с) у ##1 @(d) z
459 может быть записана, как @(с) if (b) w ##1 @(d) x else у ##1 @(d) z, что означает - усилить ограничения на то, что синхронизация не изменится с булевым условием b с, а также с условием ветвления if и else свойства. Син- хропоток также делает соединенные отношения между конкатенацией и импликацией ясными для мультисинхронных свойств: @(c)x##1y]=>@(d)z эквивалентно выражению @(c)x|=>y|=>@(d)z @(с) х ##0 у |^> @(d) z эквивалентно выражению @(c)x|->y(=>@(d)z Границы событий синхронизации соответствуют подвыражениям, ограниченным скобками, и если подвыражение является последовательностью, она также передается слева направо, через скобки подвыражения Тем не менее, пределы видимости событий синхронизации ограничиваются скобками. 22.9.4 Примеры. Примеры мультисинхронного описания (multiple-clock specifications): sequences'!, @(posedge clkl) a ##1 b, // последовательносгь с единственным синхросигналом endsequence sequence s2, @(posedge cik2) с ##1 d, // последовательность с единственным синхросигналом endsequence 1) Мультисинхронная последовательность: sequence inuli_s, @(posedge elk) a ##1 @(posedge c'kl) s1 ##t @(posedge clk2) s2, endsequence 2) Свойство с мультисинхронной последовательностью: property mu!t_p1, @(posedge elk) a ##1 @(posedge clkl) s1 ##1 @(posedge clk2) s2, endproperty 3) Свойство с именной мультисинхронной последовательностью : property mult_p2, mult_s, endproperty 4) Свойства с импликацией мультисинхронизации: property mu!t_p3, @(posedge elk) a ##1 @(posedge clkl) s1 |=> @(posedge clk2) s2, endproperty 5) Свойства с именными последовательностями, имеющими различную синхронизацию. В этом случае, если si содержит сихросигнал, то он должен
460 быть идентичным (posedge clkl). Подобным образом, если s2 содержи! синхросигнал, он должен быть идентичным (posedge clk2): property mult_p5 @(posedge clkl) s1 |=> @(posedge clk2) s2; endproperty 6) Свойства с импликацией, где предшественник и последователь являются именными мультисинхронными последовательностями: property mult_p6, mult_s |=> mult__s, endproperty 7) Свойство, использующее синхропоток и перекрывающуюся импликацию: property mirtjD?, @(posedge elk) a ##1 b |-> с ##1 ©(posedge clkl) d; endproperty Здесь a, b и с синхронизируются передним фронтом elk. 8) Свойство, использующее синхропоток и if. else property mult_p8, ©(posedge elk) a ##1 b |-> if fc) (1 l=> ©(posedge clk1)d) else e##1 ©(posedge cik2)f, enaproperty Здесь а, b, с и е синхронизируются передним фронтом elk 22.10. Контрольные вопросы и задания 1. Создать последовательность (набор) проверяющую одновременное выполнение наборов seql и seq2, управляемых передним фронтом синхросигнала elk. 2 Создать последовательность, проверяющую выполнение хотя бы одного из двух наборов seql и seq2, управляемых передним фронтом elk. 3. Написать параллельную ассерцию, выполняющую проверку значений А~С1, set=l, по переднему фронту elk, выводящую сообщения в случае удачного и неудачного выполнения ассерции с указанием метки ассерции. 4. Написать прямую именную ассерцию, выполняющую проверку значений А=01, set=l, выводящую сообщения в случае удачного и неудачного выполнения ассерции с указанием метки ассерции. 5. Написать параллельную ассерцию, выполняющую проверку значений, что сигнал grant представлен унарным кодом. set=l, если reset не равен 1. Осуществить вывод сообщения об ошибке в случае неудачного выполнения ассерции. 6. Написать параллельную ассерцию, выполняющую проверку следования сигнала а=1, через 5 тактов после d=l или Ь-=1 Управляется задним фронтом elk. В случае неуспешное выполнения ассерции выводить предупреждение.
461 7 Написать параллельную ассерцию, выполняют) ю проверку следования сигнала а=1, через 2-5 тактов после с=1 и b~i. Управляется задним фронтом elk В случае неуспешного выполнения ассерции выводить пред) преждение 8 Написать параллельную ассерцию, выполняющую проверкл следования сигнала а=1 или Ь=1, через 3 такта после с=1. Управляется передним фронтом cik. В случае неуспешного выполнения ассерции выводить предупреждение. 9 Написать параллельную ассерцию, выполняющую проверку следования сш нала а=1, через 5 тактов после d=l и через 8 тактов после Ь=1 Управляется передним фронтом elk В случае неуспешного выполнения ассерции выводить предупреждение. 10. Написать параллельную ассерцию, выполняющую проверку следования сигнала а=1 или d=l и через такт после b^l. Управляется передним фронтом elk В случае неуспешного выполнения ассерции выводить сообщение о фатальной ошибке. 11. Создать последовательность без перекрытия, соединяющую последовательности а и Ь, обозначить наборы с помощью формальных параметров, которые позволят их переопределить при использовании последовательности. 12. Создать набор, проверяющий последовательность через 2 такта следования друг за другом через события a, b и с, управляемую передним фронтом синхросигнала elk. 13 Написать параллельную ассерцию, выполняющую проверку появления set=-i и через такт- А=01. управляемую передним фронтом elk. Активизировать вывод сообщения с указанием метки ассерции в случае удачного и неудачного ее выполнения. 14. Написать прямую ассерцию, выполняющую проверку значений grant=01 и request=i. Активизировать вывод сообщения в случае удачного и неудачного выполнения ассерции с указанием ее метки 15. Написать параллельную ассерцию, выполняющую проверку значений, что сигнал grant содержит как минимум одну «1», если сигнал reset не равен «1». Активизировать вывод сообщения об ошибке в случае неудачною выполнения ассерции 16. Написать параллельную ассерцию, выполняющую проверку следования сигнала а=1, через 2-5 тактов после с=1 и Ь-=1. Управление осуществляется задним фронтом elk. В случае неуспешного выполнения ассерции выводить предупреждение. 17. Написать параллельную ассерцию, выполняющую проверку следования сигнала а=1 или Ь=1, через 3 такта после с=1. Управление осуществляется передним фронтом с!к. В случае неуспешного выполнения ассерции выводить предупреждение.
462 22.11. Литература 1. IEEE Std. 1364-1995, IEEE Standard Hardware Description Language Based on the Venlog" Hardware Description Language 1995. ISBN 0-7381-3065-6. IEEE Product No. WE94418-TBR. 2. IEEE Std 1364-2001. (Revision of IEEE Std 1364-1995).- IEEE Standard Ver- llog Hardware Description Language.- IEEE Computer Society Sponsored by the Design Automation Standards Committee.- Published by The Institute of Electrical and Electronics Engineers, Inc.- 3 Park Avenue, New York, NY 10016-5997, US A.-2001.-79 Ip 3. IEEE Std 1800-2005.- IEEE Standard for System Venlog - Unified Hardware Design, Specification, and Verification Language.- Sponsor: Design Automation Standards Committee of the IEEE Computer Society and the IEEE Standards Association Corporate Advisory Group - Published by 1 he Institute of Electrical and Electronics Engineers, Inc.- 3 Park Avenue. New York, NY 10016-5997, USA.- 2005.- 664 p. 4. SystemVeniog 3.1a. Language Reference Manual. - Accellera's Extensions to Venlog®.- Accellera Organization, Inc. 1370 Trancas Street #163, Napa, CA 94558, USA.-2004. 5. Spear C. SystemVeniog for Verification: A Guide to Learning the Testbench Language Features, 2nd ed.- Springer-Veriag, New York, Inc. Secaucus, NJ. USA.- 2006 - 429 p. 6. Mintz M., bkendahl R. Hardware Verification with System Venlog. An Object- Oriented I ramework.- New York : Springer.- 2007 - 31^ p ". Bergeron J. Writing Festbenehes using SystemVeniog.- Springer US.-2006.- 414 p. 8. Bergeron J., Cerny E., Hunter A., Nightingale A Verification Methodology. Manual for SystemVeniog.- Springer US.-2005.- 510 p. 9. Sutherland S., Mills D. Venlog and SystemVeniog Gotchas 101 Common Coding Errors and How to Avoid Them.- New York : Springer.- 2007.-214 p 10. Vyayaraghavan Snkanth, Ramanathan Meyyappan A Practical Guide for SystemVeniog Assertions.- Spnngei US - 2005 - 334 p. 11. Haque F., Michelson J., Khan K. The Art of Verification with System Venlog Assertions.- Verification Central. First ed- 2006.
463 23. ПСЕВДОСЛУЧАЙНОЕ ТЕСТИРОВАНИЕ Представлены модели и процедуры создания различных типов псевдослучайных тестов (randomization) для верификации цифровых проектов, описанных на системных языках описания аппаратуры Цель - создание технологичных процедур синтеза псевдослучайных тестов, ориентированных на поиск дефектов как детерминированных во времени, так и перемежающихся неисправностей, изменяющих функционирование устройства и приводящих проект в неработоспособное состояние. Задачи - изучение наиболее технолотчных процедур синтеза псевдослучайных тестов, ориентированных на проверку аппаратных решений цифровых систем на кристаллах. Источники- [1, 2] - методы синтеза детерминированных и псевдослучайных тестов для различных типов цифровых структур; [3-13] технологии программирования процедур создания псевдослучайных тестов на основе HDL языков описания аппаратуры. В процессе разработки программного кода проектировщики допускают большое количество некорректностей. Их можно разделить на следующие основные категории: 1) неизбежные синтаксические ошибки и опечатки в исходном программном коде, обнаруживаемые практически мгновенно при запуске компилятора, 2) мелкие технические ошибки, возникающие при начальной сборке измененных частей программы, обнаруживаемые при первых запусках на выполнение, 3) логические ошибки в функциональности программы, не обнаруживаемые по состояниям выходов, но часть из них может быть выявлена в процессе тестирования; 4) ошибки и недостатки алгоритмов и моделей, которые проявляются во время выполнения программного кода в виде повышенного расхода оперативной памяти, неприемлемых временных затрат на выполнение программы. Первые две категории синтаксических неточностей обнаруживаются разработчиками относительно быстро, однако семантические ошибки последних двух категорий специфичны для решаемой задачи и требуют использования продуманной стратегии тестирования Основная сложность при тестировании цифровых систем состоит в неочевидности симптомов многих некорректностей. Если ошибка проявляется в виде неправильных результатов моделирования, визуально обнаружить ее и устранить намного сложнее. Решение находится с помощью специальных средств дополнительного анализа, основанного на создании тестов, покрывающих функциональные режимы и/или неисправности заданного класса. В языке System Veriiog тест создается с помощью перенастраиваемого генератора псевдослучайных значений (Constrained-Random Tests - CRT). Проблемно-ориентированный или прямой гест (directed test) предназначен для поиска наперед заданных дефектов, в то время как CRT-recr обнаруживает случайные или незапланированные ошибки- 1) конфигурации устройств
464 (Device configuration); 2) конфигурации среды (Environment configuration), 3) исходных входных данных (Primary input data); 4) инкапсулированных входных данных (Encapsulated input data); 5) исключений протоколов (Protocol exceptions); 6) задержек (Delays); 7) статуса транзакций (Transaction status); 8) неисправности и противоречия (Errors and violation) 23.1. Простейший класс кода с псевдослучайными переменными Простейший класс, формирующий псевдослучайные последовательности, которые проверяют функциональность теста, представлен листингом 23.1. Листинг 23.1. Простейший класс рандомизации class Packet, // Случайные переменные rana bit [31-0] s^c, dst, data[8], randc bit [7 0] kind, // Ограничение значений src constraint с {src > 10, src < 15,} endclass Packet p, initial begin p = new, // Создание пакета assert (p randomizeO); iransmit(p); end Класс имеет четыре переменные с псевдослучайными значениями. Первые три используют модификатор rand, таким образом, что каждый раз, при рандомизации класса, переменные могут получать новые значения или повторять какие-либо из предыдущих. Переменная kind описывается как randc, что означает псевдослучайный цикл, где формируемые значения не будут повторяться, пока не будут перебраны все возможные Ограничивающее выражение constraint группируется с помощью фигурных скобок {}. Они используются для идентификации декларативного кода, но не процедурного, где необходимо применять begin...end. Функция randomize возвращает 0, если проблема использует ограничения Для проверки результатов формирования случайных значений применяются прямые ассерции. Листинг 23.2 содержит класс кода с псевдослучайной генерацией значений с ограничениями. Листинг 23.2. Псевдослучайный класс с ограничениями c'ass Stim; const bit [31-0] SRC_CONGEST_ADDR = 42, typedef enum {READ, WRITE, CONTROL} stimj randc stim J type, // Переменная типа перечисления rand bit [31 :Q] len, src, dst, bit congestionjest, constraint c_stim { len< 1000, len > 0,
465 src inside {0, [2 10], [100 107]}, if (congestion Jest) { dst inside {[CONGEST_ADDR-100 CONGEST_ADDR+100]}; } } endclass В примере (листинг 23.3) представлен класс кода с блоком ограничений, который содержит несколько выражений. Первые два контролируют значения для переменной len Как видно из примера, переменная може г появляться во множественных выражениях. На одно выражение допускается использовать только один оператор отношения (<, <-, =~=, >-=, или >) Листинг 23.3. Переменные ограничения описаны в определенном порядке class bad, rand bit [15 0] a, b, с, constraint good {0 < a, // Правильное описание a<b b<c,} constraint bad {0 < a < b < с,} // Неправилвно, приведет к ошибке endclass Множество значений может быть создано с помощью опегатора inside (листинг 23.4). SystemVeniog создает значения переменных с равной вероятностью, если нет других условий или ограничений для переменных. Можно также использовать переменные для указания множества Строка len inside {[1.999]} замещает описанные выше выражения. Листинг 23.4 Псевдослучайное множество значений rand int с, // Псевдослучайная переменная int lo, hi, // Обычная переменная используемая для описания границ constraint c_range { с inside {[lo hi]}, // lo <= с и с <= hi } В примере переменные 1о и hi определяют диапазон возможных значений. При этом описывается инверсный диапазон - выбираются значения, не входящие в указанное множество: constraint c_range { '(с inside {[(о hi]}); //с< !оили c>hi } Все значения множества имеют одинаковую вероятность выбора, даже если они появляются в тексте несколько раз. constra'nt c_even_wesght { (с inside {0,1,1,1,1,1}), // 0 и 1 имеют одинаковую вероятность } Если необходимо придать другой вес некоторым значениям переменных, это можно сделать с помощью оператора dist
466 23.2. Использование массивов в качестве границы множества псевдослучайных значений Допускается выполнять выбор значения из множества, представленного массивом. В примере (листинг 23.5) - это выбор дня недели, описанного списком перечислений. Список choices может быть легко изменен, если сделать его псевдослучайной переменной. В случае использования оператора randc система генерирования перебирает все возможные значения перед повтором уже присвоенных чисел. Листинг 23.5. Выбор из множества возможных значений class Days, typedef enum {SUN, MON, TUE, WED, THU, FRI, SAT} DAYS_E; "• '' DAYS_E choices[$], rand DAYS_E choice, constraint cday {choice inside choices,} endclass Days days, initial begin , -: * >;; '•' days = new, days choices = '{Days SUN Days SAT}, assert (days randomize(}); $disp!ay{"Random weekend day %s\n" days choice name), aays choices = {Days. MON, Days TUE, Days::WED, Days THU, Days::FRI}, assert (days randomize})); ">">"■ $disp!ay("Random week day %s", days choice name), *'/*'"i end Если необходимо динамически добавить или удалить данные из множества, то следует осторожно использовать оператор inside из-за его особенностей. Например, существует множество значений в очереди, из которых должно быть выбрано и удалено только одно. Это потребует создать N ограничений, где N - количество элементов, остающихся в очереди. Предпочтительней использовать randc (листинг 23.6), что связано с массивом выборов. Выбор значения randc занимает значительно меньше времени, тогда как создание большого числа ограничений требует значительных временных затрат, особенно если констант больше 10. Листинг 23.6 Использование randc для выбора значений массива в случайном порядке class Randclnside; intarrayO, // Значения для выбора randc bit [15.0] index, // Индексация массива function new(input int aQ), // Конструктор и инициализация array = а- endfunction function int pick, // Возвращение нового результата выбора return arrayfmdex] ,.-,'. . •■.-■■■■•: г;- endfunction
467 constraint c_size {index < array size,} endclass initial begin Randclnside n, n = new{'{1,3,5,7,9,11 13}), repeat (n array size) begin assert(n randomizeO), $display("Picked %2d [%0d]", n pick() n index), end end 23.3. Взвешенное распределение Оператор dist позволяет задавать взвешенное случайное генерирование значений таким образом, что некторые числа (коды) будут появляться чаще, чем другие. Оператор dist (листинг 23 7) принимает список значений и весов, разделенных символами := или :/. Значения и веса мо!ут быть константами или переменными. Значение может быть задано числом или диапазоном вида [lo:hi] Оператор :- означает одинаковый вес для каждою описанного диапазона, в то время как./ означает - вес должен быть поделен между всеми значениями диапазона. Вес определяется процентами и не может быть в сумме больше 100. В примере (листинг 23.7) src получает значения 0, 1, 2 или 3. Вес 0 равен 40, а I, 2 и 3 - 60, всего в сумме получается 220. В этом случае вероятность выбора 0 равна 40/220, а вероятности появления 1, 2 или 3 - 60/220 Далее dst получает значения 0, 1, 2 или 3. Вес 0 равен 40, а 1, 2 и 3 разделили общий вес 60, следовательно, полный вес всех значений равен 100 В этом случае вероятность выбора нуля равна 40'100, а вероятность выбора i. 2 или 3 равна 20/100. Листинг 23.7. Взвешенное псевдослучайное генерирование значений rand int src, dst, constraint c_dist { src dist {0.=40,|1 3]:=60}, /'/ src = 0, weight = 40/220 //src=1 weight = 60/220 // src = 2, weight = 60/220 // src = 3, weight = 60/220 dst dist {0 /40, [1 3] /60} //dst = 0, weight = 40/100 // dst =1, weight ^20/100 //dst = 2 weight = 20/100 //dst = 3, weight = 20/100 } Использование переменных для веса выбора значения позволяет динамически менять распределение случайных переменных, как это представлено в листинге 23 8
468 Листинг 23.8 Динамическое изменение распределения весов '"' // Операторы шины длиной в байт, слово или длинное слово class BusOp, // Длина операндов typedef enum {BYTE, WORD, LWRD} lengthj; rand lengthj len, // Псевдослучайные веса для ограничений dist bit [31.0] w_byte=1, w_word=3, w_lwrd=5; constraint cjen { len dist {BYTE = w_byte, // Выбор псевдослучайного значения WORD =w_word, // Использование длины LWRD = wjwrd}, // Переменный вес } endclass 23.4. Двунаправленные ограничения В следующем примере (листинг 23.9) SystemVerilog рассматривает все четыре ограничения на переменные одновременно: b меньше d, которое, в свою очередь, меньше 30. Но b имеет ограничение на равенство с, которое должно быть больше 25. Даже если здесь нет прямого ограничения на минимальное значение d, данное обстоятельство формирует ограничение для переменной с (табл. 23 1). Листинг 23.9. Двунаправленные ограничения rand logic [15:0] b, с d, constraint c_bidir { b<d, ■::• c==b, • ..-■■■•' ■-.. d<30, c>25, } Таблица 23.1. Решения для двунаправленных Офаничений Решение b с d 1 26 26 27 2 27 27 28 3 28 28 29 23.5. Условные ограничения Обычно ограничения неременных активны на всем промежутке времени тестирования. В ситуациях, когда необходимо отключи гь действие офаничений на некоторое время, System Venlog предлагает два условных оператора -> и tf-else: // Блок ограничений с оператором импликации class BusOp, constraint cjo { • '•'■'■
469 (io_space_mode) -> addr[31] -= 1'M, } Если присутствуют выражения для обеих ветвей условия true-false, то предпочтительней использовать оператор if-else: // Блок ограничений с оператором if-else class BusOp, constraint c_len_rw { if (op =-- READ) ten inside {[BYTE LWRDj}, else len == LWRD, } В блоках ограничения используются фигурные скобки {}, поскольку jto декларативный код. В процедурном коде применяемся begin...end. 23.6. Использование арифметических операторов Для офаничений могут быть использованы простые арифметические операторы: сложение, вычитание, выделение битов, сдвиг По умолчанию ограничения имеют размер 32 бита. Также для задания офаничений может быть использован оператор solve...before (листинг 23.10). Конструкция solve ..before не влияет на пространство выбора решений, а только на вероятность формирования значений переменных Выбор состояния х выполняется с равной вероятностью для (0. 1) Из ! 000 случайных значений х 500 будет равно 0, а 500 1 Koi да х равно 0, у должен быть равен 0. Когда х принимает значение 1, то у может быть 0, 1, 2 или 3 с равной вероятностью (табл 23.2) Таблица 23.2. Значения х и у для офаничений solve x before у Решение Л В j с D Е F G Н X 0 0 0 0 1 1 1 1 У 0 1 г 2 3 0 1 2 3 Вероятность 1'2 0 0 0 1/8 1/8 1'9 1/8 Листинг 23.10. Класс с импликацией и solve, .before class SolveBefore, rand bit x, // 0 or 1 rand bit [1 0] y, //0,1, 2, or 3 constraint c_xy {
470 Сх==0) -> у==0, solve x before y, endclass По в случае использования ограничения solve у before x будет получено другое распределение, заданное табл. 23.3 Таблица 23.3 Значения х и у для ограничений solve у before x Решени? А В с D Е F G Н X 0 0 0 0 1 1 1 ! у _ , 1 2 3 0 1 2 ~1 3 Вероятность 1/8 1 о 0 0 1/8 1/4 1/4 1/4 23.7. Управление несколькими блоками ограничений Класс может содержать несколько блоков офаничений. Например, одна группа управляет разрядностью данных транзакции, а другая - длиной транзакции Тогда можно применять метод constraint^mode() для тою, чтобы включать или отключать Офаничения. При использовании формата <имя orpaHH4eHHH>.con»traint_mode() этот метод управляет единственным ограничением Листинг 23.11 Использование constramtmode -/•" class Packet, rand int length, constraint c_short {length inside {[1 32]},} constraint cjong {length inside {[1000 1023]},} endclass Packet p, initial begin p = new, // Создание длинных данных Song через отключение ограничений для коротких short р c__short constraint_mode(0), assert (p randomize?)) transmit(o), // Создание коротких данных "ерез отключение всех ограничений, // а затем разрешается использование ограничений для коротких данных р constraint,_mode(0), р c_shortconstramt_mode(1); assert (p randomize?)), transmit(p), end
471 23.8. Ограничения для управления правильностью данных Ограничения могут быть использованы для управления формированием только допустимых тля модели значений переменных Например, в следующем коде операция read-modify-write разрешена только для длинных данных. // Проверка длины переменной с использованием ограничения valid class BusTrans rand enum {BYTE, WORD, lWRD, QWRD} length; rand enum {READ, WRITE, RMW, INTR} ope; constraint vahd_RMW_LWRD { (ope == RMW; -> length == LWRD, } endclass 23 8.1. Линейные ограничения. Дополнительное управление ограничениями реализуется с помощью конструкции random!/e() with (листинг 23.12). Листинг 23.12. Оператор randomizeQ with class Transaction, rand bit [31 0] addr, data constraint d {addr msideflO 100],[1000 2000]},} endclass Transaction t = new(), initial begin mts, t = new() //addr может принимать значения 50 100, 1000-1500, data < 10 assert{t randomizeQ with {addr >= 50, addr <= 1500, data < 10,}), dnveBus(t), // Формирование определенного значения для addr, data > 10 assert(t randomize^ with {aodr == 2000 aata > Ю;}), driveBus(t), end В целях отключения конфликтующих ограничений для переменных можно использовать функцию constraint mode 23.9. Функции prerandomize и post randomize SystemVenlog имеет функции для нелинейного распределения случайно генерируемых данных (рис. 23 1). Это void-функции - функции, не возвращающие значение Однако в отличие от задач, они не допускают использования параметров времени. С помощью данных функций можно выполнять действия перед запуском функции формирования псевдослучайных условий или сразу после нее (листинг 23.13) Листинг 23 13 Встроенное U-образное распределение class Bathtub, mt value, // Псевдослучайная переменная с U-образным распределением
mt WIDTH = 50, DEPTH=4, seed=1; ;-.,л, function void pre_randomize() // Вычисление левой части кривой value = $dist_exponential(seed, DEPTH), if (value > WIDTH) value = WIDTH, // Псевдослучайная расстановка точек в левой или правой ч; if ($urandom_range(1)) value = WIDTH - value, endfunction £ "TO it 0 IN ' v 'J \X Sum is a // X^v. bathtub // Left \--^, ^J' ExponentiaP^^^^^^-^Kight ^^^__^--^><C^-Exponential __ __-_^_. __ Рис 23 l. Встроенное U-образное распределение Здесь существуют следующие функции: Sdistexponentiai - экспоненциальное затухание (см. рис 23.1); $dist_normal - колоколообразное распределение; $distj>oisson - колоколообразное распределение, Sdist_uniforrn - плоское распределение; Srandom - плоское распределение, возвращает знаковое 32-бшовое значение; Surandom - плоское распределение, возвращает беззнаковое 32-битовое значение; Surandom_range - плоское распределение через диапазон 23.10. Настраиваемые тесты со случайной тенерацией Для указания границ псевдослучайной генерации могут быть использованы переменные: class bounds, rand mt size, mtrr x_size = l00: constraint c_size { size ins'de {[1 rr } По умолчанию, класс присваивает случайной переменной size значения от 1 до 100. Изменяя величину переменной maxsize, можно модифицировать верхнюю границу диапазона Имеется также возможность использовать переменную с ограничениями di>t для включения и отключения значений и диапазонов В примере (листинг 23.14), каждая команда шины имеет различные весовые переменные.
Листинг 23.14 Ограничения dsst с весами переменной typedef enum (READ8, READ16 READ32) readj, class ReadCommands, rand read J read_cmd, mt read8_wt=1, read16_wt=i, read32_wt=1, constraint c_read { read_cmd dist {READ8 •= read8_wt, READ16-=read16_wt, READ32 =read32_wt}, } endciass 23.11. Использование неслучайных значений Оператор randjnode позволяет сделать переменную детерминированной во времени или неслучайной (листинг 23.15). Листинг 23.15. Отключение псевдослучайной генерации значений с помощью randmode // Класс Packet с переменными length и payioad class Packet, rand bit [7 0] length; rand Ы [7 0] payloadQ; constraint c_valid {length > 0, payioad size == length } function void disp!ay(string msg), $wnte("Packet len=%0d, payicaa size=%0d, bytes = ", length, pay- load size), for(mt i=0, u<4 && Kpayioad size), i++) $write(" %0d", payload[ij); Sdisplay, endfunction endciass Packet p, initial begin p = new(), // Псевдослучайное генерирование всех переменных assert (p.randomize{)), p displayfSimpie randomise") // Отключение псевдослучайной генерации значений length, затем // генерирование значений для пакета р length randjnode(O), p.iength = 42 assert (p.randomizeQ); p.dispiayfRandomize with rand_mode"), end Если выполняется псевдослучайное генерирование значений сигналов объекта, а затем некоторые переменные модифицируются, то необходимо вы- проверку выполнения ограничений Вызов handle.randomi/e(null)
474 SystemVenlog рассматривает все переменные как неслучайные и гарантирует, чго все офаничения будут выполняться (листинг23 16). Лисгиш 23 16. Включение и отключение офаничений constramt_mode class Instruction rand OPCODE J" opcode, . ; , „ constraint c_no__operands { opcode == NO"3 || opcode == HALT,} L ■■■ constraint c_one_operand { opcode == CLR || opcode == NOT;} endclass Instructon >nstr -;* •■'•■■■' '■•■!'>"' -v ч» l:-' •'•-■> •■'■ initial begin mstr = new, // Генерирование instruction без операндов instr constraint_mode(0), // Отключение всех ограничений mstrc_no_operands.constraint_fpode{1) assert (instr randomizeO), .,,.,- // Генерирование instruction с одним операндом instr constraint_mode(0), // Отключение всех офаничений instr c_one_operand.constraint _mode{1), assert (instr randomize()), 23.12. Использование внешних определений ограничений Офаничения определяются за фаницами пакета В примере (листинг 23.17) объявлены офаничения cexternal, которые заданы в профамме test Листинг 23.37. Класс с внешними офаничениями и их использование // Определение класса class Packet, rand bit [7 0] length, rand bit [7 0] payloadO, constraint c_valid {length > 0, payload size == length,} - constraint c_external, endclass // Определение внешних ограничений в программе program test, constraint Packet::c_exiemal {length == 1,} endprogram 23.13. Проблемы рандомизации В примере (листинг 23.18) офанкчение totaljen определяет, что сумма пары переменных (pktljen ■+- pk2 Jen) не должна превышать 64. При этом допустимы значения (32, 32) и (2, 62). Однако этому условию удовлетворяет также пара значений (-64, 128) Если необходимо избежать появления отрицатель-
475 ных значений, то следует использовать в тесте беззнаковые типы данных (листинг 23.19). Листинг 23.18 Знаковые переменные являются причиной проблем псевдослучайной генерации class SignedVars, rand byte pktljen, pk2_len, constraint totaljen { pktljen + pk2_len == 64, } endclass Листинг 23.19. Формирование значений для беззнаковых 32-битовых переменных class Vars32, rand logic [31 0] pktljen, pk2Jen, // беззнаковый тип constraint totaljen { pktljen + pk2Jen == 64, } endclass Даже данная версия кода приводит к ошибкам Большие значения pktljen и pkt2Jen, как 32"h8000Q040 и 32'h80000000. при сложении дают 32'd64 Следует подумать о сложении другой пары констант для ограничения значений этих двух переменных. Но лучший подход - сделать их меньшей длины и избежать использования 32-биювых переменных в ограничениях (листинг 23.20) Листинг 23 20 Формирование значений для беззнаковых 8-битовых переменных class VarsB, rand logic [7 0] pktljen, pk2Jen; constraint totaljen { pktl Jen + pk2Jen == 8'd84 } 23.14. Ограничения, итеративные и массивов Форму распределения значений сигналов можно менять с помощью оператора foreach и нескольких функций массивов. Простейшим ограничением является функция size Она применяется при определении количества элементов для динамического массива или очереди: class dyn_ssze, rand reg [31 0] dD constraint d_size {d size inside {[1 10]},} endclass // 8-битов // 8-битов
476 В примере использование ограничения inside позволяет задать нижнюю и верхнюю границы массива. 23.14.1. Сумма элементов. Можно послать случайный массив данных в проект или использовать его для управления потоком. Например, задан интерфейс, который передает четыре слова данных Слова могут быть посланы последовательно или в течение нескольких циклов Сигнал strobe обозначает наличие правильных данных. Существует несколько допустимых шаблонов стробирования, которые могут быть использованы для передачи значений во время выполнения десяти циклов (рис. 23.2. листинг 23 21). Эти шаблоны могут быть созданы с помощью случайных массивов. Ограничения используют четыре бита и функцию суммирования sum. Листинг 23.21. Использование шаблона стробирования // Класс для формирования псевдослучайного шаблона стробирования parameter MAX_TRANSFER_LEN = 10, class StrobePat, rand bit strobe[MAX_TRANSFER_LEN]: constraint c_set_four {strobe sum == 3'h4,} endciass // Использование класса шаблона стробирования initial begin StrobePat sp, int count = 0, // Индекс в sp = newQ, assert (sp.randomize); foreach (sp strobe[ij) begin bus.cb strobe = sp strobe[i], // If strobe is enabled drive cut next d; if (sp strobefj]) bus.cb.data = da?a[count++] Рис 23 2 Случайная форма сигналов стробирования Таким образом, в разделе рассмотрены типовые процедуры создания псевдослучайных тестов на основе использования конструкций языка System
477 Verilog. Процедуры могут быть весьма полезными при создании тестов проверки исправности для функциональных модулей цифровых систем на стадии проектирования архитектуры изделия. 23.15. Контрольные вопросы и задания 1. Где применяется псевдослучайная генерация значений переменных? 2. Чем отличается генерирование значений переменных при использовании ключевых слов rand и randc? 3. Создать класс, содержащий поля а и Ь, которые могут принимать случайные значения чисел в интервале от 0 до 100 При этом значение а должно быть всегда меньше Ь. 4. Создать класс, который содержит поле а, принимающее значения !, 10, 20 и 100 Вероятность появления значения 1 равна 10. вероятность появления чисел 10 и 20 равна 20, а вероятность значения 100 равна 50. 5. Создать класс, который содержит поле а, значения которого выбираются из массива Ь, длиной 20.
478 24. ФУНКЦИОНАЛЬНОЕ ПОКРЫТИЕ Представлены модели и процедуры создания различных типов функциональных покрытий, необходимых для оценки качества тестирования и верификации цифровых проектов, описанных на системных языках описания аппаратуры. Цель - разработка избыточных относительно HDL-модели структур данных для оценивания качества тестов верификации проектируемых цифровых изделий, ориентированных на исчерпывающую проверку функциональностей, поиск константных дефектов и перемежающихся неисправностей, приводящих устройство в неработоспособное состояние Задача - создание типовых процедур для синтеза корзины (множества наиболее существенных параметров и режимов) функционального покрытия проектируемого изделия для оценки качества тестов, ориентированных на проверку компонентов цифровых систем на кристаллах Источники: [1-5] - методы моделирования неисправностей для оценки качества детерминированных и псевдослучайных тестов цифровых структур; [6- 11] - технологии и программные процедуры создания функциональных покрытий на основе применения System Verilog для оценки качества тестировании и верификации проектируемых цифровых систем 24.1. Покрытия (Coverage) Покрытие (тестом функционального пространства и неисправностей) есть модельная избыточность функционального HDL-кода, ориентированная на оценку качества проектируемого изделия путем моделирования тестов для определения полноты покрытия (проверки) функциональных и специальных режимов цифровых систем на кристаллах, заданных спецификацией Для решения задачи функциональной верификации существует большое количество программных ресурсов, ориентированных на подтверждение правильности функционирования сложных систем или выявление ошибок в процессе проектирования. Одной из основных технологий оценивания качества тестирования является полнота покрытия тестом функциональных режимов управления, передачи и преобразования данных, что позволяет определить в процентах, какая часть верифицируемого объекта проверена и свободна от ошибок проектирования. Существует две метрики покрытия для оценивания качества тестов или качества верификации: 1) code coverage - автоматически генерируется список существенных переменных для проверки на основе анализа кода проекта; 2) functional coverage применяет пользовательскую метрику, определяющую часть спецификации проекта, которая подлежит проверке и указана в плане тестирования Используется для измерения в процентах интересуемого сценария, исключительных ситуаций, компонентов спецификации и условий, которые были проверены и оценены относительно правильного функционирования проектируемого изделия
479 Имеется два типа функционального покрытия: 1) Определяется пользователем и не может быть получен автоматически из кода проекта. 2) Основывается на спецификации проекта и не зависит от реального кода модели или структуры Поскольку свойства функционального покрытия полностью определяются пользователем, то для их описания не требуется больших временных затрат Здесь необходим структурный подход к верификации. Хотя функциональное покрытие сокращает в целом временные затраты по верификации и повышает производительность труда разработчика и качество проектирования, его недостатки, связанные с синтезом и анализом тестов, могут помешать его применению. SystemVerilog предлагает конструкции, упрощающие создание спецификации для функционального покрытия модели изделия Спецификация может быть эффективно создана с помощью SystemVerilog-симулягоров Она позволяет осуществлять манипулирование данными из покрытия и предлагает инструменты анализа, повышающие производительность разработки качес;- венного теста. Улучшенное множество входных наборов может выполнять тестирование функциональности устройства в исключительных ситуациях и по требуемому сценарию. Конструкции функционального покрытия в SystemVerilog позволяют выполнять следующие действия: !) Сбор информации о покрытии переменных и выражений, а также изучение перекрестного покрытия между ними. 2) Автоматическое или пользовательское создание корзин покрытия. 3) Фильтрация условий на нескольких уровнях иерархии покрытия. 4) Использование событий и последовательностей для автоматического переключения условия для сбора значений (sampling) покрытия. 5) Получение покрытия вызовов, процедур и очередей 6) Использование необязательных директив для управления и регулирования покрытием. 24.2. Определение модели покрытия: eovergroup Конструкция coveigroup наследует спецификацию модели покрытия и может включать- 1) События синхронизации, определяющие моменты считывания значений. 2) Множество точек покрытия (coverage points). 3) Перекрестное покрытие между точками моцели для оценки качества тестов. 4) Необязательные формальные аргументы. 5) Опции покрытия. Конструкция eovergroup является типом, определенным пользователем. После формирования записи конструкция может иметь несколько копий, которые могут быть реализованы в различных контекстах Конструкция eovergroup создается в пакете, модуле, программе, интерфейсе или классе. Она может собирать значения любых видимых переменных программы или модуля, сигналов из интерфейса или любых других сигналов с помощью иерархических имен. Группа покрьпия класса может наблюдать его переменные и встроенных классов. Синтаксис, eovergroup eovergroupjdenffier [ ([ tf_port_hst ]) ] [ coverage_event ],
480 {{attnbutejnstance} coverage_spec | {attnbutejnstance} coverage_option : } endgroup [ covergroupjdentifier ] Здесь covergroup_identifier - имя группы покрытия, tfport Jist - список формальных параметров, coverage_event - событие синхронизации для выборки значений наблюдаемых переменных. Тело группы покрытия может включать опции coveragejspec, записываемые в формате: option mernberjdenlifier = expression | type_option memberjdentifier = expression, а также опции покрытия coverageoption, описывающие его точки ити пере- кресное покрытие. Для создания копии групп покрытия используется оператор new. covergroupjdentifier [vanabiejdentifie<- ] = new [ (hst_ofjarguments ) ], где list_of_arguments - список реальных аргументов. Идентификатор, связанный с декларацией covergroup, определяет имя модели покрытия. Используя это имя, можно создать произвольное число копий моделей покрытия. Например, // Декларация группы covergroup eg, endgroup // Создание копии группы покрытия и инициализация eg cgjnst = new, В предложенном примере определена модель покрытия covergroup с именем eg. С помощью оператора new создана cg_inst копия eg. Конструкция covergroup может содержать список необязательных аргументов Они вычисляются после выполнения оператора new. Аргумент ref позволяет различать переменные, наблюдаемые каждой копией covergroup Входные аргументы передают значения для оператора new. Если указано событие синхронизации, то оно определяет моменты времени для сбора значений с точек покрытия. В противном случае пользователь должен задавать синхронизацию с помощью процедурных операторов, например, через встроенный метод sampieQ. Опция strobe может быть использована для изменения моментов считывания данных. Когда опция strobe не установлена, значения точек покрытия считываются по событию копии его модели. Если событие синхронизации встречается несколько раз во время моделирования, то значения точек покрытия должны быть также считаны несколько раз. В качестве альтернативы для синхронизации может быть использовано выражение блокового события, где считывание контрольных точек покрытия может быть выполнено в начале или конце работы заданного именного блока, задачи, функции или метода класса. Если выражение блокового события начинается с ключевого слова begin, за которым следует иерархический идентификатор, обозначающий именной блок, задачу, функцию или метод класса, то событие переключается до выполнения первого
481 оператора указанных конструкций. Выражение блокового события, которое описано с помощью ключевого слова end, выполняется сраз\ после последнего оператора указанной конструкции. Группа покрытия covergroup может содержать одну или несколько точек, которые задаются переменной или выражением. С каждой точкой покрытия связывается множество значений переменной, необходимых для проверки, которое оформляется в структурный компонент покрытия, называемый корзиной Она может быть явно определена пользователем или автоматически создана с помощью инструментов моделирования: enutn {red green, blue} color covergroup gl @{posedge elk}- с coverpoint color, endgroup Предыдущий пример представляет группу покрытия gl с одной точкой, связанной с переменной color Значение color выбирается по обозначенному событию синхронизации - положительному фронту elk. Поскольку точка покрытия не имеет явно определенных корзин, го инструмент автоматически создает три упомянутых компонента, по одному для каждого значения типа перечисления. Группа покрытия может задавать перекрестные точки между двумя или более точками покрытия или переменными. Допускается использование любых комбинаций более, чем двух переменных или предварительно декларированных точек покрытия. Например enum {red, green, blue} color, bit [3 0] pixei_adr pixe!_offset, p«ei_hue, covergroup g2 @(posedge elk); Hue coverpoint pixel_hue: Offset coverpoint pixei_offset; AxC. cross color, pixe!_adr, //пересечение 2 переменных (явное декларирование точек покрытия) ail cross color, Hue, Offset, // пересечение 1 переменной и 2 точек покрытия endgroup В примере создается группа покрытия §2, которая содержит две точки и две декларации пересечения покрытий cross Явно заданные точки покрытия с метками Offset и Hue определены для переменных pixel offset и pixelhue. Для переменных color и pixel_adr задается анализ совместного покрытия. В группе покрытия мглут быть также описаны одна или несколько опций, контролирующих и регламентирующих структуру и способ сбора информации о покрытии. Опции могут быть заданы для группы покрытия в целом или для отдельных ее пунктов. В SystemVerilog группа покрытия должна быть определена на соответствующем уровне абстракции Он может разграничивать testbench и проект в транзакторе, выполняющем чтение и запись данных или в классе, конфигурирующем среду. Захват любых транзакций необходимо выполнять при реальном получении их из модели проекта DUT. Если внести ошибку в транзакцию, которая приводит к ее о iмене, необходимо опреде-
482 литься, как эта ситуация будет влиять на функциональное покрытие. Следует использовать различные точки покрытия, которые будут созданы для управления ошибками. Класс может содержать несколько групп покрытия. Это позволяет применять различный набор групп покрытия, разрешая или запрещая их в случае необходимости. Группы могут иметь рахпичные переключатели, которые позволяют собирать данные из различных источников Пример из листинга 24.1 представляет описание и использование группы покрытия CovPort в программе. Листинг 24.1. Функциональное покрытие простых объектов program automatic test(busifc ТВ ifc), class Transaction, rana bit [31 0] data, rand bit [ 2 0] port, // Номер одного из восьми портов endclass covergroup CovPort, coverpoint tr port, // Точка, наблюдаемая группой покрытия endgroup Transaction tr = new, initial begin CovPort ck = new, // Создание копии группы repeat (32) begin // Выполнение нескольких циклов ' "' assert(tr randomize), //Создаьие транзакции ifc.cb port <= tr port // и передача v' ifc cb data <= tr data // в интерфейс CKsample(), // Сбор данных о покрытии @ifc cb, /' Wait a cycle endprogram В следующем примере (листинг 24.2) группа покрытия размещена в клас поэтому она не требует для себя отдельного имени реализации. Листинг 24.2. Функция покрытия внутри класса class Transactor, Transaction tr; mailbox mbxjn; covergroup CovPort, coverpoint tr.port, endgroup function new(mailbox rnbxjn), CovPort = new, // Создание копии группы покрытия this mbxjn = mbxjn, endfunction task main, forever begin tr = mbxjn get, // Получение следующей транзакции ifc cb port <= tr port, // Передача данных в DUT
483 ifc.cb data <= tr.data, CovPort samp!e() // Сбор покрытия end endtask endclass 24 2.1 Переключение группы покрытия Существует два основных момента в функциональном покрытии - это получение данных и время их приема Когда данные готовы, testbench выполняет переключение группы покрытия. Это можно сделать с помощью задачи sample() (листинги 24.! и 24.2) или блокирующего оператора в определении фуппы покрытия covergroup Блокирующее выражение может использовать wait или @ для блокирования сигналов или событий Метод sampieQ применяется для простого переключения фуппы покрытия или когда существует несколько реализаций фуппы покрытия, переключаемых отдельно. Блокирующие операторы covergroup следует применять в случае необходимости использования существующих сигналов или событий для переключения фуппы покрытия. 24.3. Применение группы покрытия с классами Размещение фуппы покрытия в определении класса обеспечивает простейший способ создания подмножества покрытия для свойств данного класса. Интеграция покрытия в класс обеспечивает интуитивный и ясный механизм для определения модели покрытия, связанной с классом. Например, в листинге 24.3 показано, что значения полей гл_х и т_у класса xyz собиракмся при каждом изменении переменной m_z. Если группа покрытия определяется внутри класса и в ней нет явной декларации переменной данной группы в пределах класса, то она создается автоматически и имеет имя, которое фуп- па получила при описании. Таким образом, в упомянутом примере переменная covi соответствует группе покрытия cov! Листинг 94.3 Использование группы покрытия в классах class xyz, bit [3 0] m_x, bit m_z covergroup covi @m_z, /' Встроенные группы покрытия coverpoint m_x, coverpoint m_y; endgroup function new() covi = new, endfunction endclass Встроенная в класс фуппа покрытия может определять модель покрытия для защищенных и локальных свойств данного класса без возможности ее переопределения в классе-наследнике. Последний может иметь несколько фупп покрытия. Еще один пример (листинг 24.4) представляет класс МС,
484 содержащий две группы покрытия Первая группа cvi является членом масса, где зьачение переменной т_х собирается по каждому положительному фронту сигнала elk. Значения локальной переменной m_z собирается группой cv2. Каждая из них использует различные события синхронизации. Листинг 24.4. Несколько групп покрытия в классе class MC; Ьдю [3.0] m_x, local logic m_z, bit m_e, covergroup cv1 @(posedge elk), coverpomt m_x, endgroup covergroup cv2 @m_e; coverpomt m_z, endgroup enaclass Встроенная группа покрытия должна быть явно реализована с помощью метода new. В противном случае она не создается, что означает отсутствие сбора данных. В следующем примере (листинг 24 5) группа встроенного покрытия не имеет передаваемых в нее аргументов и использует явную реализацию для синхронизации с другими объектами. В примере группа покрытия Cov принадлежит классу MyCiass, который также содержит объект класса Helper с именем m_obj. Событие синхронизации для встроенной группы покрытия относится к полю m_ev объекта mobj. Поскольку группа Cov использует m_obj, то последний создается до копирования группы Cov. Передача аргументов во встроенную группу покрытия иллюс грируется примером из листинга 24.6 Листинг 24.5. Инициализация группы покрытия в конструкторе class Helper, int m_ev, endclass class MyCiass, Helper m_ob/, int m_a, covergroup Cov @(m_obj m_ev); coverpomt m_a, endgroup function new{); m_obj = new; Cov = new, // Создание встроенной группы покрытия после объекта //класса m_obj endfunction endclass
485 Листинг 24 6. Использование группы покрытия с аргументами class С1, bit [7 0] х, covergroup cv (in! arg) @(posedge elk), option atjeast = arg, coverpoint x; endgroup function new(int p1), cv = new(p1), endfunction endciass ■nitiai begin CI obj = new{4); end 24.4. Сбор данных Для сбора данных используются специальные корзины Информация заносится в них в процессе моделирования, а затем на основе собранной информации формируются статистические данные. 24.4.1. Отдельные корзины. Для вычисления покрытия в точке необходимо определить общее число возможных значений, которые называются доменом Дтя одной корзины это может быть одно или несколько значений. Покрытие определяется числом собранных данных, разделенным на количество корзин в домене Точка покрытия, которая является 3-битовой переменной, имеет 0 7 доменов и обычно делится на 8 корзин Если во время моделирования в семь корзин заносятся значения, огчег будет - 7/8 или 87,5% покрытия в данной точке. Все такие точки объединяются для формирования покрытия всей группы, а затем все группы соединяются для определения качества покрытия (в %), что заносится в базу данных моделирования. 24.4.2. Автоматическое создание корзин. SystemVeniog автоматически создает корзины для точек покрытия /Для всех значений, имеющих n-разрядов, существует 2п возможных значений. Таким образом, для 3-разрядного порта имеется 8 возможных значений сигналов Ограничение на число корзин связано с опцией autobm max, которая задает максимальное количество автоматически создаваемых корзин. По умолчанию - это 64. Если домен значений точки покрытия переменной или выражения больше описанных в опции, то SystemVenlog выполняет деление диапазона между корзинами. Например, если 16-битовая переменная имеет 65 536 возможных значений, то каждой из 64 корзин будет соответствовать 1024 значения. В реальности этот подход может оказаться непрактичным. Поэтому лучше ограничивать возможное число корзин до 8-16 или явно указывать их количество. В следующем примере параметр auto binmax устанавливается равным 2. Входной порт имеет размер 3 разряда, что соответст-
486 вует 8-ми возможным значениям. Первой корзине соответствуют 4 младших, а второй - 4 старших значения: // Использование auto_bin_max, установленного в 2 covergroup CovPort, coverpoint tr port { options auto_b,n_max = 2,} //Деление на 2 корзины endgroup // Пример отчета моделирования Bin # hits at least auto[0 3j 15 1 auto[4 7]17 1 Пример использует опцию autobin max для одной точки покрытия Эта опция может быть применена для целой группы // Использование auto_bin_.max для всех точек покрытия covergroup CovPort, options auto J»n_max = 2, // Действует для port и data coverpoint tr port, coverpoint tr data, endgroup 24.4 3 Наблюдение выражений. *-1 Можно наблюдать простые выражения, но всегда следует проверять отчет покрытия, чтобы быть уверенным в получении ожидаемых значений Может также потребоваться настройка разрядности для итогово' о выражения. Пример (листинг 24 7) представляет группу покрытия, которая собирает общую длину транзакции. Точка покрытия имеет метку, облегчающую чтение отчета покрытия Выражение также имеет дополнительную макетную (dummy) константу. Таким образом, длина транзакции вычисляется с точностью 5 бит для максимального числа (32) автоматически генерируемых корзин. Листинг 24.7 Использование выражения в точке покрытия class Transaction, rand bit [2 0] ndrjen, // диапазон 0 7 rand bit [3 0] payloadjen, //диапазон 0 15 endclass Transaction tr, covergroup CovLen, !en16 coverpoint (tr ndrjen + tr payloadjen), ien32 coverpoint (tr ndrjen + tr payloadjen + 5 bO), endgroup 24.4.4. Пользовательские корзины находят ошибки. Автоматически генерируемые корзины приемлемы для анонимных значений данных, таких как счетчик, адрес Для друых значений следует явно указы-
487 вать имя корзины в целях улучшения точности анализа и облегчения формирования отчета покрытия SystemVerilog автоматически создает имена корзин не только для типов данных перечисления, но и для других типов, в случае необходимости Простейший способ определения имен корзин с помощью синтаксиса скобок [ ] (листинг 24 8). Листинг 24.8. Определение корзин для длины транзакции covergroup CovLen, ien coverpomt (tr hdrjen + tr.payload_ ien + 5 bO) {bins lenQ = {[0 23]},} endgroup // Отчет о покрытии для длины транзакции Bin # hits at least !en_00 13 1 !en_01 36 1 len_Q2 51 1 ien_03 60 1 lenJM 72 1 ien _05 88 1 !enj)6 127 1 len_07 122 1 len_08 133 1 len_09 138 1 Ien_0a1151 len_0b 128 1 ten_0c1251 len_0d 1111 !en_0e115 1 ien_0f 134 1 ien_10 107 1 len_11 102 1 len_12 70 1 ien_13 65 1 len_15 30 1 !en_16 19 1 !en_17 0 1 24.4.5. Имена корзин точек покрытия. Листинг 24.9 представляет 4-битовую переменную Kind, которая имеет 16 возможных значений. Первая корзина имеет имя zero и выполняет подсчет моментов, когда переменная kind равна 0. Следующие три значения 1-3 группируются в одну корзину 1о. Старшие 8 значений 8-15 соответствуют отдельным корзинам hi_8. hi_9, hi a, hi_b, hi_c, hid. hie и hi f. Последняя
корзина misc хранит все остальные значения, которые не попали в предыдущие корзины - 4-7 Дополнительная информация группируется с помощью {} фигурных скобок. Листинг 24.9. Описание имен корзин covergroup CovKmd, coverpomt tr kind { bins zero = {0}, bins Ю = {[1 3]}, bins hiQ = {[8 $]}, bins misc = default, endgroup // CoverKind // Отчет для представления имен корзин Bin # hits at least hi_8 0 1 hi_9 5 1 // Корзина для kind==0 '/ Одна корзина для значений 1 3 // 8 отдельных корзин // Одна коозина для всех остальных Данные, не попавшие в корзины, игнорируются Для определения функционального покрытия учитываютсч только данные, попадающие в корзину. Можно и желательно использовать корзину default для всех остальных дачных. 24 4 6 Условное покрытие. Используя ключевое слово iff, можно создавать условия для выбора значений при формировании покрытия Например, в коде листинга 24 10, а сбор информации не выполняется в момент сброса устройства, когда reset =1. Иначе, можно использовать функции start и stop для контролирования отдельных реализаций групп покрытия, как эт< 24.10,6. Листинг 24 10 Использование условий для сб> а) IIС использованием ключевого слова iff covergroup CoverPort, // Информация о покрытии не собирается,« coverpoint port iff ('busjf reset), endgroup б) С использованием функций stop и start сделано в примере а информации о покрытии
489 initial begin CovPort ck = new, // Создание копии группы покрытия /' Выполнение сброса останавливает сбор данных о покрытии #1 ns busjt reset = 1, ck stop(), #100ns busjf reset = 0, // Завершение сброса ck start(), end 24 4.7 Создание корзин для типов перечисления. Для типов перечисления SystemVerilog создает корзину для каждого возможного значения (листинг 24.11). Листинг 24.11. Функциональное покрытие типа перечисления typedef enum {INIT, DECODE, IDLE}fsmstate_t, fsmstate_t pstate, nstate, // declare typed variables covergroup cg_fsm, coverpoint pstate; endgroup // Отчет для auto_bin_max, равного 2 Bin # hits at least auto_DECODE 11 1 autoJDLE 11 1 autoJNIT 10 1 Если необходимо группировать нескольких значений в одну корзину, то для этого следует определить собственную корзину. Опция auto binmax для типов перечисления не работает. 24.4.8 Покрытие переходов. Можно описывать определенный переход дня точек покрытия. В этом случае можно задавать не только определенные значения, чо и порядок их следования Например, в следующем коде выполняется проверка переключения сигнала port из 0 в 1,2 или 3: //Описание переходов для точки покрытия covergroup CoverPort coverpomt port { bins tl = (0 => 1), (0 => 2), (0 => 3), } endgroup Несколько переходов можно легко описать с помощью диапазона Выражение (1,2 => 3,4) соответствует четырем переходам (1=>3), (i=>4). (2~>3) и (2=>4) Допускается описывать переходы любой длины Каждое значение в переходе должно бьпь получено единожды. Таким образом, (0 => 1 => 2) отличается от (0 => 1 => 1 => 2) или (0 => 1 => 1 => 1 => 2) Если есть необходимость в повторении значения 3 раза, следуе! использовать форму (0 ->
490 1[*3] =^ 2). Чтобы иметь возможность повторения значения единицы 3, 4 или 5 раз, можно использовать выражение 1[*3.5]. 24.4.9. Групповые символы для описания состояний и переходов. Для сознания множественных состояний и переходов используются групповые символы Любой символ х, 7. или ? рассмафивается как 0 или 1: // Корзины для групповых символов в точке покрытия bit [2 0] port, covergroup CoverPort, coverpomt corf { wildcard bins even = {З'Ь^О}, wildcatd bins odd = (3 d"1}; } endgroup 24.4.10. Игнорируемые значения Если в некоторой точке нельзя достигнуть всех возможных значений, то можно указать игнорируемые значения с помощью корзины ignorebms: bit [2 0] !ow_ports_0_5; // Используются только значения 0-5 covergroup CoverPort, coverpoint iow_ports_0_5 { ignore_bins hi = {[6,7]}, // Игнорирование верхних двух корзин } endgroup Оригинальный диапазон low_ports_0_5 имеет 3-разрядные значения из 0 7. В примере игнорируются последние две корзины, что позволяет сократить диапазон до 0:5. Если используется опция autohinrnax и указываются т- норируемые корзины, то последние не учитываются при вычислении полноты покрытия" //Точки покрытия с опцией auto_bm_max и игнорированием корзин ignore_bins bit [2 0] !ow_ports_Q_5, //"Используются только значения 0-5 covergroup CoverPort, coverpoint low_parts_0_5 { options auto_bin_max = 4, // 0 1 2 3, 4 5, 6 7 ignore_bms hi = {[6,7]}, // Игнорируются старшие 2 значения } endgroup 24.4 11. Недопустимые корзины. Некоторые примеры значений не только игнорируются, но не дотжны появляться. Их лучше указать в коде монитора для testbench или с помощью illegaibms. Это есть дополнительная проверка правильности определения корзин или построения testbench. // Точки покрытия с i!legal_bins bit [2 0] low_ports_0_5, // Используются только значения 0-5 covergroup Coverport,
491 coverpoint low_ports_0_5 { illegal_bms hi = {[6,7]}, // Сообщение об ошибке если значение появится } endgroup 24.5. Перекрестное покрытие В SystemVenlog конструкция cross позволяет комбинировать значения двух или более точек покрытия в группу. Оператор cross допускает только точки покрытия или простые имена переменных. Если необходимо использовать выражения, иерархические имена или переменные, го их следует отметить оператором coverpoint, а затем применять эту метку в операторе cross В примере (листинг 24.12) создаются точки покрытия для переменных tr kind и tr point. Затем эти точки используются для создания условий перекрестного покрытия для всех возможных комбинаций. SystemVerilog создает 128 (8x16) корзин. Testbench с псевдослучайной генерацией данных создает 200 транзакций и формирует отчет о покрытии. Следует обратить внимание, если были сгенерированы все возможные значения kind и port для перекрестного покрытия, то только 1/8 часть всех возможных комбинаций не была достигнута. Листинг 24.12 Базовое перекрестное покрытие class Transaction, rand bit [3.0] kind, rand bit [2-0] port, endclass Transaction tr, covergroup CovPort, kind coverpoint tr kind, // Создание точки покрытия kind port coverpoint tr port // Создание точки покрытия port cioss kind, port // Перекрещивание точек kind и port endgroup // Отчет о суммарном покрытии для базового перекрестного покрытия Cumulative report for Transaction CovPort Summary Coverage 95 83 Goal 100 Coverpoint Coverage Goal Weight kind 100 00 100 1 port 100 00 100 1 Cross Coverage Goal Weight Transaction CovPort 87 50 100 1 Cross Coverage report CoverageGroup Transaction CovPort Cross Transaction CovPort Summary
492 Coverage' 87 50 Goal 100 '"'• ' ''"-'• •' Coverpomts Crossed kind port Number of Expected Cross Bins 128 Number of User Defined Cross Bins 0 Number of Automatically Generated Cross Bins 112 Automatically Generated Cross Bins kind port # nits at least auto[0] auto[0] 1 1 auto[0] autofl] 4 1 auto[0] auto[2] 3 1 autofO] auto[5] 1 1 24.5.1 Метки корзин перекрестного покрытия. Для повышения читаемости кода перекрестного покрытия корзины могут иметь метки, представленные в листинге 24.13. Листинг 24.13. Описание имен корзин для перекрестных покрытий covergroup Coi/PortKind, port, coverpoint tr.poft {bins ponO = {[0-$]}, } kind coverpoint tr kind {bins zero = {0}. // Корзина для kind==0 bins lo = {[1 3]}, // Одна корзина для значений 1 3 bins hiQ = {[8-$]}, // Восемь раздельных корзин bins misc = default, // Одна корзина для всех оставшихся } cross k.nd, port, endgroup // Отчет о перекрестном покрытии с метками корзин Summary Coverage 90 91 Number of Coverpomts Crossed 2 Coverpomts Crossed: kind port Number of Expected Cross Bins 88 Number of Automatically Generated Cross Bins 80 Automatically Generated Cross Bins pert kind # hits at least port_0 hi_8 3 1 port_0 hs_a 1 1 port_0 hi_b 4 1 port_0 hi_c 4 1 port_0 hi_d 4 1 port_0 hi_e 1 1
port_0 I о 7 1 port_0 misc 6 1 port_0 zero 1 1 port_1 hi_8 3 1 Сокращение числа возможных корзин при использовании перекрестного покрытия выполняется с помощью игнорирования корзин ignore bins (листинг 24.14). Листинг 24.14. Исключение корзин из перекрестного покрьпия covergroup CovCovport, port coverpoint tr port {bins porta = {[0-$]}, kind coverpoint tr kind { bins zero = {0}, bins lo = {[1 3]}, bins hiQ = {[8 $]}, bins misc = default, // Корзина для kmd==0 // Одна корзина для значений 1 3 // Восемь раздельных корзин /' Одна корзина для всех оставшихся } cross kmd, port{ ignore_bms hi = binsof(port) intersect {7}, ignore_bins md = binsof(port) intersect {0} && binbof(kind) intersect {[9 10]}, ignore_bins lo = binsof(kmd lo) } endgroup 24.5.2. Исключение точек покрытия из общей метрики покрытия. Общее значение покрытия для группы основывается на испоньзовании всех простых точек перекрестного покрытия. Если некоторые значения необходимо исключить, то им можно присвоить нулевой вес (листинг 24 15) Листинг 24 15. Описание веса перекрестно! о покрытия covergroup CovPort, kind coverpoint tr kmd {bins kindfj = {[0 $]}, weight = 0, } port coverpoint Ir port {bins zero = {0}, bins lo = {[1-3]}, bins hiQ =- {[8 $]}, bins misc = default, // He учитываются veight = 5, //Учитываются } ;ross kind, port {weight = Ю,} // Придание тс м пересечения дополнительного веса
494 24.5.3. Смешивание данных из различных доменов. Основная проблема для перекрестного покрытия может заключаться в необходимости захвата значений из различных временных доменов Может потребоваться информация о получении процессором события о половине заполнения кэш-памяти. Аппаратура, управляющая прерываниями, скорей всего будет реализована отдельным блоком, который использует другие временные домены по отношению к кэш-памяти. Решением будет создание независимых временных доменов для кэш-памяги и аппаратуры прерывания. Затем создаются копии сигналов в виде временных переменных. Они ис пользуются для создания группы, формирующей перекрестное покрьпие. 24.6. Опции покрытия Дополнительная информация может быть описана с помощью опций Они могут быть помещены в группу. В этом случае опции будут принадлежать всем точкам покрытия группы или будут привязаны к одной точке для лучшего управления процессом анализа, что представлено ниже 1) Задание комментариев для упрощения анализа: covergroup CoverPort, option comment = "Section 3 2 14 Port numbers", coverpoint port endgroup 2) Если testbench по умолчанию создает копии групп покрытия несколько раз, то System Venlog собирает значения покрытия от всех реализаций группы Но в проекте может быть несколько генераторов, каждый из которых создает различные потоки транзакций, что требует дополнительного анализа отдельных отчетов. Следующая группа может быть реализована в различных генераторах, а информация о покрытии будет сохраняться для каждой копии: covergroup CoverLengtn, coverpoint tr length option perjnstance = 1, endgroup 3) Порог покрытия с использованием at_least (см. листинг 24 6). 4) Печать пустых корзин По умолчанию в отчет о покрытии выводятся только корзины, содержащие элементы. Опция cross_num_prmt_missmg предлагает программе моделирования и инструментам отчета показывать все корзины, особенно те, которые оказались пустыми- //Отче-1- о корзинах, включая пустые covergroup CovFort, kind coverpoint tr kind, port coverpoint tr port cross kind, port option cross_num_pnnt_missing = 1_000, endgroup
495 5) Цель покрытия. Целью каждой группы или точки является уровень, на котором группы или точки рассматриваются как полностью покрытые. По умолчанию - эю 100% покрытие. Если установить уровень ниже 100%, то запрос будет меньше полного покрытия, которое может быть недостижимым Опция действует только для отчета покрытия: // Описание цели покрытия covergroup CoverPort, coverpoint port, option goal = 90, // Установка для частичного покрытия endgroup 24.7. Параметризация группы покрытия 24.7 1. Передача параметров через значение. В примере (листинг 24 16) используется значение, которое делит данные по двум корзинам. Значение формируется при создании группы с помощью функции new. Листинг 24.16 Пример параметра bit [2.0] port, //Значения 0 7 covergroup CoverPort (int mid), coverpoint port {bins !o = {[0 mid-1]}, bins hi = {[mid $]}, } endgroup CoverPort cp, initial cp = new(5), // lo=0 4, hi=5 7 24.7.2. Передача параметров через ссылку. Можно описать переменную значений, которые наблюдаются с помощью pabs-by-reference (листаж 24.17). Листинг 24.17. Передача параметров по ссылке bit [2 0] port_a, port_b, covergroup CoverPort (ref bit [2 0] port, int mid), coverpoint port { bins lo = {[O.mid-1]}, bins hi = {[mid:$]}, } endgroup CoverPort cpa, cpb, initial begin cpa = new(port_a, 4), // port_a lo=0 4, hi=5:7 cpb = new(port_b, 2), // port_b, lo=0.1, hi=3 7 end 24.8. Контрольные вопросы и задания I .Какие виды покрытий используются при верификации и в чем их отличия?
496 2. Какие опции могут быть использованы в группах покрытия? 3. Управляющий автомат содержит 9 состояний. Определить тип данных State и переменную St, описывающие состояния автомата, а также группу покрытия, собирающую значения St. 4. Создать класс, содержащий 8-битовые поля а н b Определить в классе группу покрытия для проверки значений этих полей и метод new() для инициализации данной группы. 5. Создать класс, содержащий 8-битовые поля а и Ь. Определить в классе группы покрытия для каждого поля и метод new() для их инициализации. Первая группа должна собирать информацию по переднему фронту elk, a вторая - по заднему. 24.9. Литература 1. Michael Nicolaidss, Yervant 7onan, Dhiraj К. Pradan On Line-Testing for VLSI. - Kluwer Academic Publishers. - 1998. -168 p 2. Samiha Mourad, Yervant Zonan. Principles of testing electronic systems.- Wiley, John &. Sons, Incorporated.- 2000 - 444 p. 3 IEEE Std 1364-1995, IEEE Standard Haidware Description Language Based on the Venlog" Haidware Description Language 1995. ISBN 0-7381-3065-6. IEEE Product No. WE94418-TBR. 4 IEEE Std 1364-2001. (Re\is(on of IfcEF Std 1364-1995).- IEEE Standard Ver- llog Hardware Description Language - IEEE Computer Society Sponsored by the Design Automation Standards Committee.- Published by The Institute of Electrical and Electronics Engineers, Inc - 3 Park Avenue, New York, NY 10016-5997, USA.- 2001. -791 p. 5. IEEE Std S 800-2005.- IEEE Standard for System Verilog - Unified Hardware Design, Specification, and Verification Language.- Sponsor. Design Automation Standards Committee of the IEEE Computer Society and the IEFE Standards Association Corporate Advisory Group.- Pubhshcd by 1 he Institute of Electrical and Electronics Engineers, Inc.- 3 Park Avenue New York. NY 10016-5907. USA- 2005 - 664 p. 6. SystemVeniog 3.1a. Language Reference Manual. - Accellera's Extensions to Venlog'®.- Accellera Organization, Inc 1370 Trancas Street #163, Napa, CA 94558, USA - 2004. 7. Spear С SystemVeniog for Verification- A Guide to Learning the Testbench Language Features, 2nd ed.- Springer-Verlag, New York, Inc. Secaucus, NJ, USA - 2006 - 429 p. 8 Mintz M , Ekendahl R. Hardware Verification with System Venlog. An Object- Oriented Framework - New York : Springer.- 2007. - 314 p.
497 9 Bergeron J. Writing Testbenches using System Venlog- Springer US. 2006.- 414 p. 10. Bergeron J., Cerny E., Hunter A., Nightingale A. Verification Methodology. Manual for SystemVenlog.- Springer US.-2005.- 510 p. 11. Sutherland S., Mills D. Venlog and SystemVenlog Gotchas. 101 Common Coding Errors and How to Avoid Them.- New York ■ Springer.- 2007.- 214 p. 12. Vijayaraghavan Snkanth, Ramanathan Meyyappan A Practical Guide for SystemVenlog Assertions.- Springer US - 2005.- 334 p. 13. Haque F., Michelson J., Khan K. The Art of Verification with System Venlog Assertions.- Verification Central. First ed. - 2006.
498 ЗАКЛЮЧЕНИЕ Учебное пособие представляет собой итог эволюции субъективных знаний авторов о современных технологиях проектирования, тестирования и верификации цифровых систем на кристаллах на основе языков описания аппаратуры (Verilog") и архитектурных решений (System Verilog). Сущность изложенного материала состоит в представлении языковых средств, технолотий, моделей, методов и процедур проектирования и верификации цифровых систем на кристаллах, имплементированных в современные и компактные конструктивы. Большая часть предложенного материала есть переработанные под точку зрения авторов научные и образовательные издания ведущих ученых и университетов планеты, ориентированные на повышение технологической культуры студенческой молодежи, изучающей курсы по направлению «Компьютерная инженерия». Важное место в книге занимает достаточно свежая технология упреждающей, системной верификации цифровых проектов, идущая от компаний Mentor Graphics. Synopsys, Cadence, Aldec и использующая тесгопригодный механизм ассерций, ориентированный на существенное уменьшение времени исправления ошибок в HDL-коде. Рыночная привлекательность издания определяется заметным ростом интереса со стороны IT-индустрии и университетов постсоветского пространства к проблеме создания специализированных энергосберегающих компактных цифровых изделий, как альтернатива программному продукту, для функционирования которого необходимо наличие универсального, дорогою и энергозатратного компьютера. Содержание издания по существу или технологически покрывает традиционно устоявшиеся курсы, связанные с автоматизацией проектирования и цифровой техникой. «Языки описания аппаратуры». «Прикладная теория цифровых автоматов», «Автоматизация проектирования компьютерных систем», «Проектирование систем на программируемой логике», «Проектирование устройств цифровой обработки сигналов» Апробация материала, изложенного в книге, на студентах факультета Компьютерной инженерии Харьковского Национального Университета Радиоэлектроники дает основание к изданию данного пособия в качестве учебника на украинском языке, ввиду отсутствия аналогов в формате соединения технологий с языками описания аппаратуры и верификации. Определенное влияние на содержание книги и ее появление оказали несомненные авторитеты, коллеги и друзья по цеху компьютерной инженерии: Владимир Тарасенко, Стенли Гайдук, Раймунд Убар, Yervant Zorian, Paolo Prmetto, Дмитрий Сперанский, Аркаций Закревский, Вячеслав Харченко, Геннадий Кривуля, Алексей Романкевич, Анжела Матросова, Юрий Скоб- цов, Александр Дрозд, Александр Баркалов. Выражаем также благодарность коллегам и друзьям по университету: Александре Петровне Гужве, Светлане Чумаченко, Ирине Побеженко, Василине Василенко. Юле Хахановой, Сергею Зайченко, Диме Мельнику, Алексею Сушанову, которые оказали неоценимую помощь в подготовке, оформлении и проверке рукописи
499 СПИСОК СОКРАЩЕНИЙ АС - Assertion Controller- контроллер ассерций Ad-Hoc - специализированные и проблемно-ориентированные технологии ADTG - Adder Test Generator- генератор тестов для сумматора AMBA - Advanced Microcontroller Bus Architecture ASIC - Application-Specific Integrated Circuit A.SSP - Application Specific Standard Product CAD - Computer-Aided Design - САПР CLB - Complex Logic Block CPLD - Complex PLD CPU - Central Processor Unit CTL - Core Test Language DFM - Design-for-Manufacturability DFT - Design-for-Testability DSP - Digital Signal Processing EDA - Electronic Design Automation ESL - Electronic System Level FDT - Fault Detection Table таблица неисправностей F-IP - Functional Intellectual Property FPGA - Field Programmable Gate Array FS - Fault Simulator FV - Formal Verification - формальная верификация GUI - Graphical User Interface HDL- Hardware Description Language - язык описания аппаратуры HDTV - High Definition Television HfcS™ - Hardware Embedded Simulator HFS - Hardware Fault Simulator IIW-SW - Hardware-Software IEEE -Institute of Electrical and Electronics Fngmeers I-IP - Infrastructure Intellectual Property IP-core - Intellectual Property Core LUT - Look-up Table MCP - Multichip Package - многокристальный пакет NoC - Network on Chip - сеть на кристалле PCI - Peripheral Connect Interconnect PiP - Package-in-Package PLD - Programmable Logic Device- программируемое логическое устройство PoP - Package-on-Package PRTG - Pseudo-Random Test Generator - генератор псевдослучайных тестов RAM - Random Access Memory RTL Register-Transfer Level
500 SAM - System Architectural Model SiP - System m Package - система в пакете кристаллов , • SoC - System on Chip - система на кристалле STA - Static Timing Analysis ТАМ - Test Access Mechanism TAP - Test Access Port Controller '' '"'" "'":""' TLM - Transaction-Level Modeling VHDL - Very high speed integrated circuits Hardware Description Language VLSI - Very Large Circuit Integrated БИС - большая интегральная схема ВИН - вектор подозреваемых неисправностей . , ВЭП - вектор экспериментальной проверки ГРП - граф регистровых передач ДИ - диагностическая информация ДНФ - дизъюнктивная нормальная форма ДС - древовидная структура КНФ - конъюнктивная нормальная форма КП - кубическое покрытие МП - микропроцессор МТН - многозначная таблица неисправностей ОЗУ- оперативное запоминающее устройство ОКН - одиночная константная неисправность ПЛИС - программируемая логическая интегральная схема ППЗУ - постоянное запоминающее устройство ПЭ - примитивный элемент СБИС - сверхбольшая интегральная схема СДНФ - совершенная дизъюнктивная нормальная форма ТН - таблица неисправностей ТФН - таблица функций неисправностей ЦАП - цифро-аналоговый преобразователь ЦС - цифровая система ЦУ - цифровое устройство
501 ПРИЛОЖЕНИЕ А. СПРАВОЧНИК PLI- ПОДПРОГРАММЫ АЛ. Обозначения Таблица А. 1 Обозначение char * format char* аргумент с подчеркиванием * Значение Передача форматированной строки Передача имени объекта в виде строки Наличие аргумента не обязательно Указатель на тип данных Больше аргументов одного типа А.2. Подпрснраммы доступа А.2.1. Handle Routines. Возвращают абстрактные идентификаторы или определители объектов Имя функций данной группы всегда начинается с приставки acc_handle_. 1 аблица А.2 Возвращаемый тип данных handle handle handle handle Имя ace handle by name ace handle condition ace handle conn acc_handle datapath Список аргументов (char *name, handle scope) (handle object) (handle terminal) (handle modport) Описание Возвращает определитель объекта, заданно! о именем и областью видимости Возвращает определитель на выражения условия для пути модуля или временной проверки Возвращает определитель на шнию, подключенную к примитиву, к пути модуля или терминалу проверки временных параметров Возвращает определитель | пути данных ]
502 Продолжение габл. А.2 Возвращаемый тип данных handle handle handle handle handle handle handle handle Имя ace handle hiconn ace handle interactive scope ace handle loconn ace handle modpath ^cc handle notiner ace handle object ace handle parent accjiandle path Список аргументов (handle port) 0; (handle port) (handle module, char *src, char *dest): или (handle module, handle sre, handle debt); (handle tchk): (handle object), (handle output, handle i л port), (handle output, handle inport): Описание Возвращает иерархическую старшую линию, подключенную к модулю порта У казател ь н а теку щ> ю j область видимости среды моделирования | Получение иерархически | младшей линии, подключенной к порту модуля 1 Получение определителя J для пути модуля, для I которого описан источник или приемник. Путь модуля может быть описан по имени или по указателям Получение объявления ] регистров, связанных с определенной временной проверкой j Получение определителя любого объекта, заданного через полное или относительное иерархическое имя 1 Получение определителя 1 родительского объекта для ( примитива, модуля или [ объекта Получение определителя [ для пути между выходом одного и входом дру гого модуля 1
503 Продолжение табл А 2 | Возвращаемый тип данных handle j handle handle 1 handle 1 handle ! handle handle handle handle Имя ace handle pathout ace handle port ace handle score acchandle simulated net ace handle tchk ace handle tchkarg2 ace handle terminal ace handle tfarg ace handle tfinst Список аргументов (handle modpath); (handle module, int port#); (handle object); (handle collapsed neth andle), (handle module, int tchktype, char*netnamel, int edge!, ..); (handle tchk); (handle module, int terminal*), (int arg#); (); Описание Потучение определителя для первой линии, подключенной к выходу модуля Возвращает определитель порта модуля Рогг#-эю номер порта, начиная с 0 Возвращает определитель на область видимости объекта j Возвращает определитель на | линию, связанную со слабой линией Возвращает определитель для указанной временной проверки модуля иди ячейки Возвращает линию, j связанную со вторым аргументом временной проверки Получение определителя для ! терминала примитива. Terminal - позиция в списке аргументов Получение определителя для 1 аргумента arg# системной задачи или функции, вызывающей PL1- подпрограмму Получение определителя для 1 текущей, определенной пользователем, системной задачи или функции !
504 A.2.2. Next Routines. Возвращают определитель для следующего объекта в связанном списке заданного типа. Подпрограммы данного класса всегда начинаются в acc_next_ и принимают ссылки на объекты в качестве аргументов Таблица А.З Возвра- | данных ! handle handle handle handle handle handle handle handle handle Имя ace next ace next bit ace next ce1! ace next ceil load ace next child ace next driver ace next hiconn ace next input ace next load Список аргументов (intobj tvpe arrav[], handle module, handle current object); (handle vector, handle current bit): (handle module, handle current cell); (handle net, handle current cell load). (handle module, handle current child): (handle net. handle currem_dn ver_term in a!); (handle port, handle current net): (handle path_or__tchk. handle current terminal), (handle net. handle currentjoad): Описание Возвращает следующий объект на некоторый тип данных в заданной области видимости. Типы объектов, такие как accNet accRegister, определены в obj type arra> Возвращает следующий бит в векторе или массиве Возвращает копию следующей ячейки в модуле Ячейки определяются в библиотеке Возвращает следующую ячейку, загружаем) ю линией Возвращает копию следующего модуля в структурной модели Получение следующего 1 терминала примитива, управляющего линией | Пол\ чение следующего j высокого соединения линии | Получение следующего входного терминала для описанного временного пути или временной проверки Получение следующего терминала примитива, управляемого линией, независимой от иерархии j
505 Продолжение табл А 3 Г Возвращаемый тип данных handle handle J handle j handle handle handle handle handle handle handle handle handle handle Имя ace next ioconn ace next modpath ace next net ace next output ace next parameter ace next port ace next portout ace next primitive ace next scope ace next specparam ace next tchk ace next terminal ace next topmod Список аргументов (handle port, handle current net): (handle module handle path); (handle module, handle current net); (handle path, handle current terminal); (handle module, handle current (handle module, handle current port): (handle module, handle current port); (handle module, handle (handle module, handle current scope); (handle module, handle current specparam); (handle module, handle current tchk); (handle primitive, handle (handle current topmod). Описание Поту чение следу ющего соединения низкой линии для ПОрТОВ МОДУЛЯ Получение следующего порта вн\три модуля Получение следующей линии в модуле Получение следующего выходного терминала пути модуля или пути данных Получение следующего параметра в модуле Получение следующего порта в списке портов модуля Получение следующего | порта output или inout в модуле Получение следующего J примитива в модуле Получение следующей области видимости по отношению к текущей Получение следующего specparam. декларированного в модуле Получение следующей 1 временной проверки в модуле Получение следующего 1 терминала в примитиве Получение следующего вверх по уровню модуля в j проекте |
506 A.2.3. Value Change Link (VCL) Routines Подпрограмма VCL позволяет системным задачам добавлять и удалять объекты из списка объектов для наблюдения. Гакие подпрофаммы всегда начинаются с приставки acc_vcl_ и не возвращают значений. Таблица А.4 Возвращаемый данных void void Имя асе vcl add асе vcl delete Список аргументов (handle object, int (*consumer__routine) (), char *user_data, int VCL flags); (handle object, int (*consumer_routine) (), char *user data, int Описание Сообщает Verilog-симулятор для вызова пользовательской подпрограммы с измененным значением информации при каждом изменении значения объекта Удаляет указанный объект из списка наблюдения А.2.4. Fetch Routines Fetch-подпрограмма позволяет получать различную информацию об объектах, такую как полное иерархическое имя, относительное имя и друг ие атрибуты Подпрограммы данной группы начинаются с префикса acc_fetch_. Таблица А.5 Возвра- шаечый тип данных char ** double Имя асе fetch arg\ асе fetch argc асе fetch attribute Список аргументов 0; 0; (handle object, char *attribute, double default): Описание Получить количество аргументов командной строки Получить массив арг> ментов командной строки вызоез Получить атрибуты параметра или specparam
507 Продолжение 1абл. А.5 Возвращаемый гип char ** [int boo! int int char* int Имя ace fetch defname ace fetch delay mode ace fetch delays ace fetch direction ace fetcn edge ace fetch fullname ace fetch_fulltype Список ар[ументов (handle module). (handle module): (handle object, double *rise, double *fall. double *tumofl): (handle object, double *dl,*d2. *d3. *d4, *d5, *d6): (handle object): (handle path_or_tchk_ter m;; (handle object), (handle object); Описание Получить имя определения для копии мод)ля или примитива Получить режим задержки копии мод% ля Получить типичные значения задержек для примитивов, путей модуля, временной проверки или входных портов модуля Получить направление порта или терминала - input, output, inout Получить заданный тип фронта дтя пути терминала входа или выхода, или временной проверки 1 входного терминала Получение полного иерархического имени для любого именного объекта или пути модуля Получение типа данных объекта. Возвращает предопредеченные константы, обозначающие | типы данных |
Продолжение табл А,5 Список аргументов (handle port or ti 'Получение индекса для порта, или терчинши для вентиля, переключателя, копии UDP, модуля и т.п. Ноль [возвращается для первого [терминала /асе fetch location Jfyjocation iocj), ^handle object), Возвращает расположение объекта в исходном файле Verilog. Предопределенный 'тип plocation является 'структурой, содержащей имя 1файла и. номер линии в файле! (Пол> чение копии объекта или пути мочудя в модуле асе fetch paramtype (handle Получение типа данных [параметра, integer, string, real ;г); |и т.д. асс_ fetch paramval Получение значения параметра или specparam. Должна возвращать значение [(handle parameter); integer, string или double ace fetch polarity (handle path), Получ< e полярности п>т> : fetch precision liiL. [Получить точность вычисления времени юделирован)' : fetch pulsere Получить значение (handle path, ёоиЫе!импульсного контроля для rl, double Ael, пути модул: double *r2, double значения отражения и .]; {значения для передачи Получение наиболее и наименее значимых битов msb.'\Tu*\sby. \вектора
509 Продолжение табл. А 5 1 Возвращаемый тип [_данных_ lint double lint char* void int char* char* Имя ace fetch size ace fetch tfarg ace fetch tfarg int ace fetch tfarg str acc_fetch timescale info ace fetch type ace fetch type str ace fetch value Список аргументов (handle object); (int arg#): (int arg#); (int arg#); (handle object, p_timescale_info timescale p): (handle object), (handle object); (handle object, char *format) Описание Получение котичества битов для цепи, регистра или порта Получение значения аргументов для системной задачи или функции индексированного arg# Получение строкового значения для аргумента системной задачи или функции индексированного arg# 11олучение значения integer для аргумента системной задачи или функции индексированного arg# Пол> чение информации о масштабе времени для объекта p_timescale_info, который является указателем на предопределенную ] структуру временной шкалы Получение типа объекта. | Возвращает предопределенную целую константу, такую как accIntegerVar, accModuie Получение типа объекта в строковом формате. Возвращает строку accIntegerVar, accPararneter | Получение логического 1 значения или силы для цепи, регистра или переменной в | описанном формате |
510 A.2.5. Utility Access Routines Утилиты доступа выполняют разнообразные задачи, относящиеся к доступу Таблица А.6 Возвращаемый тип данных void handle" boo! void int void Имя ace close ace collect ace corrmare handles ace configure ace count ace free Список аргументов 0; (handle *next_routine, handle refobject, int *count): (handle object I, handle object2); (int config _param, char *config_value) (handle *next_routme, handle ref object); (handle *object handle s); Описание Освобождает внутреннюю память, используемую подпрограммами доступа, и сбрасывает все параметры конфигурации в значения, заданные по умолчанию Собирает все объекты, относящиеся к определенному ссылочному объекту, для успешного вызова для подрограммы acc_next. Возвращает массив определителей Возвращает значение истина, если оба определителя 1 относятся к одному и тому же объекту Устанавливает параметры, | которые контролируют | операции для различных | подпрограмм доступа 1 Подсчитывает количество объектов в ссылочном объекте, таком как модуль, Объекты подсчитываются при успешном вызове подпрограммы асе next Освобождает память, выделенную асе collect для сохранения определителей объектов 1
511 Продолжение табл. А 6 Возвращаемый тип данных void boo! boo! int char* int void handle void char* Имя ace nitialize ace object in t>peiisl ace object in type ace pioduct type ace product version ace release object ace reset buffer acc_set interactive scope ace set scope ace version Список аргументов 0, (handle object, mt object typefl); (handle object, int object type); 0; 0, (handle object); 0; 0; (handle module, [char Amodu!e name] ); 0; Описание Сброс параметров конфигурации для всех подпрограмм доступа. Вызывается в начале пользовательской PLI- подпрограмы Ищет наличие указанного свойства или типа объекта в массиве свойств или типов Сравнивает свойство или тип) объекта с аданным свойством или типом Возвращает тип используемого программного продукта Возвращает версию используемого программного 1 продукта Перераспределение памяти, 1 связанной с путем входа и выхода терминала Сброс буфера строки Установка интерактивной облас ги видимости для реализации программы Установка области видимости для поиска объектов в иерархии проекта Получение версии ] используемой подпрограммы доступа |
512 A.2.6. Modify Routines Подпрограммы могут модифицировать внутреннюю структуру данных. Таблица А.7 Возвращаемый 1 данных void boo! void bool void void Имя ace append delays ace append pulsere ace replace delays ace replays pulsere ace set pulsere ace set value Список аргументов (handle object, double rise, double fall, double z); или (handle object, double dl,..., double d6); или (handle object double hmit),H;iH (handle object double delay []): (handle path, double rl,. ., double rl2, double el,.... double el2); [handle object, double rise, double fall, double z); или (handle object doubled!. ., double d6); или (handle object, double ПтИ);или (handle object double de!ay[]); (handle path, double rl,..., double r!2. double el... . double el2), (handle path, double reject, double e), (handle object, 3_setvai_value value P. Описание Добавить задержку к существующей задержке примитивов, путям модуля, временной проверке или входным путям модуля. Можно задавать rise/fall/turn- off или 6 задержек, временную проверку или формат min typ.max Добавить значение о пути модуля к существующему импульсному контролю Заменить существующие задержки примигивов, путей модуля, временной проверки | или входных портов модуля Можно задавать rise/fall/turn- off или 6 задержек, временную проверку или формат min.rvp:max. Устанавливает значение j импульсного контроля для пути модуля в процентах от задержки пути Устанавливает проценты ! импульсного контроля для 1 пути модуля Устанавливает значение для ! регистра ити 1 последовательной UDP |
513 А.З. Служебные подпрограммы (Utility (tf_) Routines) Служебные (tf J подпрограммы используются для передачи данных в обош направлениях через фанииу Verilog/Си. Все tf_ подпрограммы, предполагают, что операции будут выполняться для текущих копий. Каждая tf- подпрофамма имеет tf 1 прототип, где указатель копии, в которой выполняется операция, передается в качестве дополнительного аргумента в конец списка аргументов. А.3.1. Get Calling Task/Function Information Таблица А 8 Г Возвращаемый тип данных char* char* char* Имя tf getinstance tf ispname tf mipname Список аргументов 0, 0; 0, Описание Получение указателя на текущую копию задачи или ф>нкции моделирования, которая вызывается пользовательской РЫ-профаммой Получение имени иерархического пути модуля, содержащего вызов пользовательской PLI-программы Потучение имени иерархического пути области видимости, содержащей вызов пользовательской РЫ-программы А.3.2. Get Argument List information Таблица А 9 Возвращаемый тип данных int int int t tfexpnnfo* t tfexpnnfo* Имя tf nump tf typep tf sizep tf expinfo tf nodeinfo Список apry ментов 0, (mtparam mdex#). (mtparam index#): (int param _mdex#. struct t_tfexprinfo *exprinfo p); (int param jndex*. struct t_tfe\pnnfo *exprinfo p), Описание Получить число параметров в списке аргументов Получить тип у казанного параметра в списке аргументов Получить длину параметров в битах Получить информацию о выражении параметров Получить информацию о значении параметров уз та
514 A.3.3. Get Parameter Values Таблица А 10 Возвращаемый тип данных int double int char* char* void Имя tf getp tf getrealp tf getlongp tf strgetp tf getcstringp tfevaluatep Список аргументов (int param index#); (int param index#); (int *aof_highvaIue, int para index#); (int param_index#, char format character); (int param index#); (int param index#); Описание Получение значения параметра в целочисленной форме Получение значения параметра в формате с плавающей точкой с двойной точностью Получение значения параметра в 64-битовой целочисленной форме ! Получение значения параметра в виде Си строки символов 1 Получение значения параметра в виде форматированной строки Вычисление выражения 1 параметров и получение результатов | А.3.4. Put Parameter Values Таблица А. 11 Возвращаемый тип данных void void void Имя tf putp tf putlongp tf_putrealp Список аргументов (int param_index#, int value); (int param_index#, double value); (int paramjndex^, int lowvaiue, int highvalue); Описание Передача назад целого значения для вызывающей задачи или функции Передача назад вещественного значения с двойной точностью в формате с плавающей точкой для вызывающей задачи чпи функции i Передача назад целого значения с двойной точностью 64 бита для вызывающей задачи или функции |
515 Продолжение табл. А 11 Возвращаемый тип данных void int int int Имя tf propagatep tf strdelputp tf strrealdelputp tf strlongdelputp Список аргументов (int param index#); (int paramindexff, int bitiength, char formatchar, int delay, int delaytype, char *value d); (int param_index#, int bitiength, char formatchar, int delay, double delaytype, char *value p); (int paramjndex^, int bitiength, char format char, int lowdelay, int highdelay. double deiaytype, char *value p): Описание Распрос гранение значения параметра узла Передача назад значения и расписания событий параметра. Значение представляется в виде форматированной строки и задержки, как целого Передача назад значения строки с добавленной : вещее геенной задержкой Передача назад значения строки с добавленной задержкой в формате длинного вещественною числа j
516 A.3.5. Monitor Parameter Value Change Таблица А 12 j Возвращаемый ! ran данных void jvoid void ivoid int int int int Имя tf asynchon tf asynchoff tf synchronise tf rosynchronize tf getpchange tf copypvc flag tf movepvc flag tf testpvc flag Список аргументов С), 0; 0, 0; (int param index#); (int param index#); (int param index#): (int param jndex#); Описание Разрешает пользовательской PLI- подрофамме быть вызванной при каждом изменении значения параметра Отключает асинхронный вызов Синхронизирует изменение параметров с окончанием текущего временного слота Синхронизирует изменение параметров и запрещает генерирование новых событий в j течение текущего временного слота моделирования Получает номер параметра, изменившего значение Копирует флаг изменения значения параметра Сохраняет флаг изменения значения параметра Тестирует флаг изменения значения параметра |
517 A.3.6. Synchronize Tasks Таблица A. 13 Возвра- данных tnt int mt char* mt int mt mt Имя tf gettime tf getrealtime tf getiongtime tf strgettime tf getnextlongtime tf setdela> tf setlongdclav tf setrealdelav ti^scale longdelay Список- аргументов 0 0; (int *aof hightime); 0 (int *aofJowtime, int *aof hightime), (int delay). (mt lowdelay. int highdelay); (double delay, char *mstance). (char *instance, mt lowdelay. int hidelay, int *aof_Iowtimc, mt *aof_hightime); Описание Получение текущего времени моделирования в целочисленной форме Тоже Получение текущего времени моделирования в виде длинного целого Получение текущего времени моделирования в виде строки Получение времени следующего события в списке Приводит к реактивации пользовательской задачи в будущий момент моделирования, представленный в иите целочисленною значения задержки Приводи! к реактивации пользовательской задачи not ie целочисленной задержки значение которого представтено в виде длинног о целого Активация misctf-приложения в , указанное время моделирования { Преобразует 64-бшовую целочисленн>ю задержк> во | внутренний масштаб представления времени
518 Продолжение табл Л. 13 1 Возвращаемый | данных void void void void int int Имя if scale reaidelay tf unscale longdelay tf unscale reaidelay tf clearaildelays tf strdelputp tf strrcaldelputp tf strlongdeloutp Список аргументов (char* instance, double delay, double *aof reaidelay), (char * instance, int lowdelay, int hidelay, int *uof lowtime, int *aof hightime); (char "instance, double delay, double *aof reaidelay). 0- (tnt param_ index*/, int bitlength, char format_char, int delay, int deiaytype, char *value p); (mt paramjndexS. int bitlength, char formatchar, int delay, double deiaytype, char *value p): (int param_index#, nt bitlength, char formai_char, int 1 o\vde)a>, mt highdelay, mt deiaytype, char *value_p) j Описание Преобразует задержку в формате с двойной точностью и плаваюшей точкой во ] внутренний масштаб представления времени | Преобразует задержку из внутреннего представления во временную шкалу заданно! о модуля Преобразуй задержку из j внутреннего представления во временную шкалу заданного модуля Очистка всех задержек 1 реактивации Передача назад значений и заснисания событий для параметра. Значение представляется в виде форматированной строки 1 символов, а задержка - целочистенным значением 1 Передача назад с i рокового значения с задержкой в вещественном формаю Передача назад строково! о значения с задержкой в формате длинного ucioi о |
519 A.3.7. Long Arithmetic Таблица A. 14 Возвращаемый данных voicL___j void void void int char* void void Имя tf add long tf subtract long tf multiply long tf divide long tf compare long tf longtime tostr tf real to long tf long to real Список аргументов (int *aof low], int *aof_highl,intlow2, int high2); (int *aof_lowl, int *aof highl, int iow2, int high2); (int *aof_Iowl,int *aof high!, int !ow2, int high2): (int *aof_lowl, int *aof_highl, intlow2, int high2), (int *aofJo\v), int *aof high 1, int low2, int high2), (int lowtime, int hightime); (double real, int *aof_low, int *aof high); (int low, mt high, double *aofreal). Описание Выполняет сложение двух 64- биговых чисел Выполняет вычитание одного 64-битового целого числа из другого Выполняет умножение двух длинных целых чисел Делит одно длинное число на другое Сравнивает два длинных Преобразует длинное целое число в сгроку Преобразует вещественное j число в 64-битовое целое j Преобразует длинное целое число в вещественный формам А.3.8. Display Messages Таблица А 15 Возвращаемый тип данных void Имя io print Список аргументов (char *format, argl,..); Описание Вывод сообщений в стандартный вывод и в log- файл
520 Продолжение табл. А. 15 Возвращаемый данных vod void void void void Имя ю mcdprint tf error tf warning tf message tf text Список аргументов (char *forrnat, argl,...), (char *format, argi,...); (char *format, argl,...); (int level, char facility, char code, char *message); (char*format, argi,. ); Описание Вывод сообщений в многоканальный файл дескриптора Выводит сообщение об ошибке Выводит сообщение с предупреждением Сообщает об ошибке и предупреждает, используя стандартные возможности обращения с ошибками j программы моделирования Verilog j Сохраняет информацию о I сообщениях об ошибке в буффере. Выводится при вызове tf message j А.3.9. Miscellaneous Utility Routines Таблица \Л6 Возвращаемый тип данныч void void char* Имя tf dostop tf dofmish mc_scnplus Список аргументов 0; 0; (char *startarg); Описание Останавливает моделирование и переводит систему в интерактивный режим Завершает моделирование Возвращает командна ю линию плюс (+) опции, введенные пользователем в интерактивном режиме
521 Продолжение габл. А. 16 Возвращаемый тип данных void int void void char* Имя tf write save tf read restart tf read restore tf dumpflush tf dumpfilename Список аргументов (char *biockptr, int blocklength); (char *b!ockptr, int blocklength), (char *blockptr, int blocklength); 0; 0: Описание Записать данные PLI- приложения в файл Получить блок данных, ранее сохраненных в файле Восстановить данные, сохраненные в файле Изменяет значение параметра в системном dump-файле Получить имя системною dump-файла А.3.10. Housekeeping Task Таблица А. 17 Возвращаемый данных void char* void char* void char* Имя tf setworkarea tf getworkarea mc setroutine tf getroutlne tf settflish tf rgettflish Список- аргументов (char *workarea), 0; (char (*routine)()), ()■ (char *tflist); 0; Описание Сохранить указатель на рабочую область копии задачи или функции PLI-приложения Восстановить указатель на рабочую область Сохранить указатель на задачу или функцию PLI-приложения Восстановить указатель на задачу или функцию PLI-приложения Сохранить указатель на задачу или функцию PLI-приложения Восстановить указатель на копию залачи или функции PLI- приложения |
содержание ~ " ;; --------- --- ■--, - ВВЕДЕНИЕ % 3 ЧАСТЬ I. ПРОЕКТИРОВАНИЕ 5 1. ТЕХНОЛОГИИ РЕАЛИЗАЦИИ И ВЕРИФИКАЦИИ ЦИФРОВЫХ СИСТЕМ 5 1.1. Аппаратные средства для разработки цифровых систем 5 1.2. Технологические конструктивы цифровых систем 9 1.3. Технологии изготовления и тестирования цифровых систем 19 1 4. Тестопригодное проектирование SiP на основе стандарта IEEE 1500 24 1.5. Языки описания аппаратуры 30 1 6. Выводы по технологиям реализации SoC 38 1.7 Тестирование и верификация HDL-моделей компонентов SoC 38 1 8. Тестопригодность программно-аппаратных продуктов 39 1.9. Инфраструктура процесса верификации и тестирования проекта 43 1.10. Аналитическая модель инфраструктуры верификации .-t -■..■ 48 1.11. Анализ тестопригодности HDL-проектов 55 1.12. Верификация DCT IP-core, Xilinx 63 1.13. Выводы по верификации HDL-кода на основе ассерций 67 1.14. Вопросы и задания 68, 1 15. Литература , 69 ЧАСТЬ II VERILOG 72 2. ОСНОВНЫЕ ПОНЯТИЯ И КОНСТРУКЦИИ ЯЗЫКА VERILOG 72 2.1. Модуль - базовая единица языка Venlog 72 2.2. Уровни абстракции описания моделей на Venlog 73. 2 3. Лексические соглашения 7Ш 2.4. Классы и типы данных 78 2.5. Описание портов модуля 81, 2.6. Структурные модели 82 2.7 Параметры - 84< 2 8 Директивы компилятора "" '" '86 2 9 Конгродьные задания 88 3 ВЕНТИЛЬНЫЙ УРОВЕНЬ ОПИСАНИЯ МОДЕЛЕЙ 89 3.1. Стандартные логические элементы и модели вентильного уровня 89 3 2. Модели комбинационных схем 90 3.3. Определенные пользователем примитивы 90 3 4 Задержки элементов 93 3 5. Контрольные задания 96 4. DATAFLOW МОДЕЛИ ЦИФРОВОГО УСТРОЙСТВА 99 4.1. Dataflow модели и оператор непрерывного назначения 99 4 2 Операторы 99 4 3. Оператор условного назначения 104 4 4 Системные задачи и функции для управления моделированием 104
4.5. Контрольные задания 107 5. ПОВЕДЕНЧЕСКИЕ МОДЕЛИ ПО 5 1. Блоки initial и Always 110 5 2. Процедурные операторы назначения 111 5.3 Временное и событийное управление операторами в блоках 113 5 4. Операторы управления: if, ease, casez и casex. Циклы 118 5.5 Специальные свойства блоков 123 5 6. Процедурные операторы непрерывно1 о назначения 126 5.7. Примеры поведенческих моделей устройств 128 5.8. Контрольные задания 132 6. ПОДПРОГРАММЫ 138 6.1. Подпрограммы Task Function 138 6.2. Автоматические функции и задачи 142 6.3. Системные задачи работы с файлами 143 6.4. Контрольные вопросы и задания 146 7 ГЕНЕРИРОВАНИЕ ОПЕРАТОРОВ 148 7.1. Оператор generate и переменные genvar 148 7.2. Оператор generate с циклом for 149 7 3. Условный оператор generate 150 7.4. Оператор generate с оператором case 151 7 5 Примеры использования оператора generate 152 7.6. Кон грольные задания 154 8. PROGRAMMING LANGUAGE IN I bRt АСЬ (PLI) 156 8.1. Внутреннее представление данных в программе моделирования 159 8.2 Подпрограммы библиотеки PLI 161 8.3 Подпрограммы доступа (access routine) 161 8.4 Обслуживающие подпрограммы (utility routine) 166 8.5. Примеры создания пользовательских системных задач 169 8 6. Контрольные вопросы и задания 170 8 7 Литература 171 ЧАСТЬ 111. СИНТЕЗ МОДЕЛЕЙ НА ЯЗЫКЕ VERILOG 172 9. СИНТЕЗИРУЕМЫЕ КОНСТРУКЦИИ В СРЕДЕ VbRiLOG 173 9 1. Общее поня гие синтеза 173 9 2 Принципы построения синтезируемого кода 174 9.3. Синтезируемые конструкции в Verilog • 175 9.4. Контрольные вопросы и задания 176 10. ИНТЕРПРЕТАЦИЯ ОПЕРАТОРОВ VERILOG 177 10.1. Типы данных 177 10.2 Использование векторов 178 10.3. Синтез комбинационных схем 179 10 4. Синтез последовательностных устройств 182 10.5. Особые ситуации синтеза 184 10.6. Операторы циклов 192 10 7. Локальное использование переменных 194 10 8 Различия между блокирующими и неблокирующими 195 переменными
10 9. Операторы Assign и Deassign 197 10.10. С интез подпрограмм 199 10.11. Использование параметров 201 10.12 Использование значения х 202 10.13 Контрольные вопросы и задания 202 11. ШАБЛОНЫ СТАНДАРТНЫХ КОМПОНЕНТОВ - 206 11.1 Комбинационные компоненты 206 11.2 Последовательностная логика ь. 211 11.3. Автоматы 218 11.4. Модели памяти 224 11.5. Контрольные вопросы и задания 226 11.6. Литература 229 Часть IV. МОДЕЛИРОВАНИЕ И ВЕРИФИКАЦИЯ ВРЕМЕННЫХ ХАРАКТЕРИСТИК IЩФРОВЫХ КОМ! ЮНЕН ГОВ 230 12 ОПИСАНИЕ ВРЕМЕННЫХ ПАРАМЕТРОВ 230 12.1. Термины 230 12.2. Анализ временных характеристик цифровой схемы 232 12.3. Пример вычисления временных параметров 237 12.4. Имплементация проекта в силиконовый кристалл 239 12.5. Контрольные вопросы 242 13. МОДЕЛИРОВАНИЕ ВРЕМЕННЫХ ПАРАМЕТРОВ ПРОЕКТА В СРЕДЕ VER1LOG 245 13.1. Модели задержек в среде Verilog 245 13.2. Моделирование задержки пути в среде Verilog 247 13.3. Проверка временных параметров ;ч 254 13.4 Системные задачи для определения временных параметров 255 13.5. Контрольные вопросы и задания 257 14. СИНТЕЗ И ВЕРИФИКАЦИЯ ПОСЛЕДОВАТЕЛЬНОГО СУММАТОРА 259 14.1. RTL- модель устройства 259 14.2. Синтез управляющего автомата 263 14.3. Синтез операционного устройства в целом 266 14.4 Оценка временных параметров 266 14.5. Контрольные вопросы 267 14.6 Литература 268 ЧАСТЬ V. SYSTEM VEPvILOG 269 15. ТИПЫ ДАННЫХ SYSTEM VERILOG 271 15.1. Пространства для декларации объектов в System Verilog 271 15.2. Единицы времени и точность их вычисления 274 15 3 Новшества в описании символьных значений 276 15.4. Логические типы . 277 15.5. Типы данных с двумя состояниями 277 15.6 Строки 279 15 7. Другие абстрактные типы данных SystemVenlog 280 15.8. Преобразования типов 281 15.9 Размер выражений 283
15.10 Константы 283 15.11 Пользовательские типы данных (User-defined types) 284 ! 5.12. Совместно используемое определение типа typedef 285 15.13. Типы перечисления 286 15.14. Контрольные вопросы и задания 292 16. СЛОЖНЫЕ ТИПЫ ДАННЫХ SYSTEM VERILOG: ARRAYS, STRUCTURES И UNIONS 293 16.1. Структуры (Structures) 293 16.2. Объединения (union) 296 16 3. Массивы фиксированного размера 298 16 4. Динамические массивы 307 16.5. Очереди 308 16.6. Ассоциативные массивы 310 16.7 Методы массивов 314 16.8. Контрольные вопросы и задания 316 17 ПРОЦЕДУРНЫЕ БЛОКИ, ЗАДАЧИ И ФУНКЦИИ 318 17.1. Процедурные блоки 318 17.2. Задачи, функции и void функции 320 17.3. Процедурные операторы и подпрограммы 323 17 4. Операторы перехода 328 17.5. Значение временных парачегров 331 17.6 Finite State Machines 332 17.7. System Venlog FIFO example 333 17 8 Контрольные вопросы и задания 337 18. System Verilog иерархия проекта 339 18.1. Прототип модуля 339 18.2. Соединение портов 341 18.3. Псевдонимы цепей 342 18.4. Передача данных через порты модуля 344 18.5. Ссылочные порты (Reference ports) 345 i 8.6. Параметризированные типы данных 345 18.7 Контрольные вопросы и задания 346 19. ИСПОЛЬЗОВАНИЕ ИНТЕРФЕЙСОВ 348 19.1. Концепция интерфейса 348 19.2. Описание портов с помощью интерфейса и обращение к ним 353 19.3. Группирование сигналов с помощью modport 357 19.4. Использование задач и функций в интерфейсе 360 19.5. Реконфигурируемые интерфейсы 369 19 6 Компромиссы интерфейса 371 19.7. Модели памяти 372 19.8. Управление доступом к шине 375 19.9. Транзактор, адаптер и функциональные модели шины 378 19. i 0. Контрольные вопросы и задания 389 20 ОСНОВЫ ОБЪЕКТНО-ОРИЕНТИРОВАННОГО ПРОГРАММИРОВАНИЯ 391 20.! Определение класса в System Verilog 391
20.2. Объектно-ориентированное профаммирование (ООП). Терминология ООП ,: 391 20 3. Создание новых объектов 392 20.4. Статические и глобальные переменные 394 20.5, Подпрограммы или методы класса .. , 395 20 6. Правила фаниц видимости 396 20.7. Использование одного класса в пределах дру гого 398 20 8 Порядок компиляции 399 20 9 Понятие динамического объекта 400 20 10. Изменение определителя в задаче 401 20. i 1. Изменение объектов «на лету» ,_: , 401 20.12 Массивы определителей 402 20.13 Копирование объектов , • 402 20 14. Публичные или приватные объекты классов 405 20 15. Наследование и подклассы 405 20.16. Примеры использования массивов классов 406 20.17. Контрольные вопросы и задания 408 20 18. Литература 408 21. СРЕДА ВЕРИФИКАЦИИ 410 21.1. Методология и инфраструктура верификации SoC 410 21.2. Профаммы (Program) 418 21.3. Шаги моделирования систем в SystemVerilog 420 21.4. Синхронизация тестовых последовательностей (Stimulus Timing) 420 21.5. Пример. Four-Port AIM Router 431 21 6. Контрольные вопросы и задания 435 22. АССЕРЦИИ 436 22.1. Последовательное ги (Sequence) 436 22.2. Ассерции в System Verilog 443 22 3. Прямые (процедурные) ассерции 445 22.4. Параллельные ассерции ... 447 22.5. Свойства (Properties) 450 22 6 Системные функции, используемые в ассерциях 453 22.7 Параллельные и прямые ассерции 453 22 8. Взаимодействие ассерции и testbench 455 22.9. Поддержка многодоменной синхронизации 456 22.10. Контрольные вопросы и задания 460 22.11. Литература 462 23. ПСЕВДОСЛУЧАЙНОЕ ТЕСТИРОВАНИЕ 463 23.1. Простейший класс кода с псевдослучайными переменными 464 23.2. Использование массивов в качестве фаницы множества псевдо- 466 случайных значений 23.3. Взвешенное распределение 467 23 4. Двунаправленные Офаничения 468 23.5. Условные ограничения 468 23.6. Использование арифметических операторов 469 23.7. Управление несколькими блоками ограничений 470
23.8. Ограничения для управления правильностью данных 471 23.9. Функции prerandormze и postjrandomize 471 23.10 Настраиваемые тесты со случайной генерацией 472 23.11. Использование неслучайных значений 473 23.12 Использование внешних определений ограничений 474 23.13. Проблемы рандомизации 474 23.14. Ограничения, итеративные и массивов 475 23.15. Контрольные вопросы и задания 477 24. ФУНКЦИОНАЛЬНОЕ ПОКРЫТИЕ 478 24.1. Покрытия (Coverage) 478 24.2. Определение модели покрытия: covergroup 479 24.3. Применение группы покрытия с классами 483 24.4. Сбор данных 485 24.5. Перекрестное покрытие 491 24.6. Опции покрытия 494 24.7 Параметризация группы покрытия 495 24.8. Контрольные вопросы и задания 495 24.9 Литература 496 ЗАКЛЮЧЕНИЕ 498 СПИСОК СОКРАЩЕНИЙ 499 ПРИЛОЖЕНИЕ А. СПРАВОЧНИК РП-ПОДПРОГРАММЫ 501
ПРОЕКТИРОВАНИЕ И ВЕРИФИКАЦИЯ ЦИФРОВЫХ СИСТЕМ НА КРИСТАЛЛАХ. VERILOG & SYSTEM VEMLOG ХАХАНОВ Владимир Иванович ХАХАНОВА Ирина Витальевна ЛИТВИНОВА Евгения Ивановна ГУЗЬ Олеся Алексеевна Редактор О П Гужва Дизайн-макетування СI Литвинова Художник Е Б Лук'янченко Комп'клерний na6ip га верстка ХНУРЬ Пшписано до др\ ку 17 0' 2010 Формат 60r84!/s. Умов друк арк 61,15 Зач X°371 Тираж 500 прим Цжа до] оварна ХНУРЕ, 61166, Харкш, прост Лента, 14 Друк - вндавншгво «НОВОЕ СЛОВО»