Современные методы верификации и особенности их применения

Современные методы верификации и особенности их применения

М.М. Ровнягин, ЗАО «МЦСТ», инженер, НИЯУМИФИ, студент, rovnyagin@gmail. com, Mikhail.M.Rovnyagin@mcst. ru;

М.С. Лебедев, ЗАО «МЦСТ», инженер, ИНЭУМ, аспирант, Mikhail.S.Lebedev@mcst.ru;

А.Л. Чудновский, ЗАО «МЦСТ», инженер, ИНЭУМ, аспирант, Alexander.L.Chudnovskiy@mcst.ru

Введение

Сложность разрабатываемых аппаратных блоков заметно возросла за последние несколько десятков лет. Появление современных средств проектирования и разработки цифровой аппаратуры позволило существенно повысить автоматизацию процесса проектирования, переведя его на новый уровень абстракции. Специальные языки описания аппаратуры (HDLs, Hardware Description Languages [1]) облегчают задачу разработчика, состоящую в описании функциональности проектируемого устройства, однако не страхуют от ошибок.

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

Верификация (от лат. verus — истинный, facere — делать) — это подтверждение соответствия конечного продукта предопределенным эталонным требованиям.

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

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

цифрового устройства заключается в описании его структуры на языке HDL (составление RTL кода), то и верификация в основном осуществляется на этом уровне

Функциональная верификация подразделяется на три типа:

• Formal method-based verification — формальная верификация [2]

• Simulation-based verification— верификация моделированием

• Гибридный метод верификации.

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

Системная верификация

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

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

Системная верификация микропроцессора требует существенных временных затрат, которые необходимо минимизировать. Далее будет рассмотрен один из возможных способов упрощения обнаружения ошибок и, как результат, временных затрат.

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

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

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

Для того, чтобы связать модель устройства и его RTL-описанием, используется интерфейс PLI (Programming Language Interface [3]), который позволяет вызывать С или С++ функции из кода Verilog (язык описания аппаратуры). Функция, вызываемая в Verilog-коде называется системным вызовом. Примерами таких функций могут являться $display, $stop, $random. PLI позволяет пользователю создавать собственные системные вызовы, которые не позволяет реализовать синтаксис Verilog. Для правильной работы PLI, код на С должен иметь доступ к внутренним данным симулятора Verilog. Для обеспечения этого механизма PLI предлагает нечто, называемое процедурным доступом.

C/C++ code

void call_me

l/ Verilog code

Shared object or static linked

$call_me

Verilog Simulator

Рис. 1. Механизм работы PLI

Системная верификация микропроцессора «Эльбрус^»

Для системной верификации многоядерного процессора «Эльбрус-2S» была применена описанная выше методика, с небольшими изменениями. Модель была заменена библиотекой, с тем же набором функций, что и у модели, но без собственной памяти. В библиотеке (при отсутствии собственной памяти) можно реализовать прямое обращение к регистрам без вовлечения программы формирования трассы теста, что значительно упрощает верификацию.

Модель тактируется синхросигналом, формируемым в RTL-описании. Зная параметры команды в тесте (в частности ее IP), возможно определить одну и ту же команду, исполняемую на модели и RTL. По формату команды (адресу исходного регистра «source» и адресу регистра результата «destination», а также хранимых в них значениях) можно легко определить, где именно в тесте модель и RTL повели себя по-разному. При нахождении расхождения в тесте, его выполнение моментально останавливается. Программа может указать адрес памяти, из-за обращения в который возникла ошибка.

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

Автономная верификация

В отличие от системной верификации задачей автономной верификации является проверка составной части устройства (RTL-описания модуля или группы модулей). Процесс автономной верификации состоит из нескольких этапов (рисунок 2). Сначала верификатор составляет тест-план в соответствии со спецификацией модуля. Далее разрабатывается тестовое окружение - специальная программа, предназначенная для связи RTL-описания и модели устройства, позволяющая создавать тесты и настраивать конфигурацию. На рисунке 2 к составу окружения можно отнести: тестовую среду, генератор входных воздействий, поиск ошибок. Также тестовое окружение может содержать любые другие специальные модули.

Рис. 2. Этапы автономной верификации

После отладки и исправления найденных ошибок верификатор оценивает покрытия двух типов: тест-плана и RTL-описания. Покрытие тест-плана определяется интуитивно (все ли тестовые случаи реализованы, все ли особенности устройства учтены). Покрытие RTL-описания можно оценить более четко - в симуляторах обычно есть специальные инструменты [4] для количественного измерения покрытия. Использовав их, можно оценить количество строк кода выполненных в процессе работы, статистику прохождения ветвлений, полноту вариантов использования различных комбинаций аргументов и т.п.

Таким образом, процент покрытия может служить показателем качества верификации. Однако не следует полностью опираться на этот показатель. С одной стороны, несмотря на большой процент покрытия кода, разработанные верификатором тесты могут не нести большой смысловой нагрузки и не проверять реальную работу модуля. А с другой стороны, почти всегда существуют ситуации, которые невозможно реализовать, либо которые не имеет смысла проверять. Так что верификатору не следует «гнаться» за высоким процентом покрытия RTL-описания.

Тестовое окружение должно содержать несколько необходимых блоков, например, генератор входных воздействий и алгоритм поиска ошибок. Окружения можно создавать с помощью различных языков программирования: C++, SystemC, Verilog. Больше всего для этих целей

подходят специальные языки верификации, такие как SystemVerilog [5] и Vera.

Помимо этого, для написания окружений часто используются специальные методологии верификации. Наиболее популярные из них: UVM (Universal Verification Methodology), OVM (Open Verification Methodology), VMM (Verification Methodology Manual). Каждая из этих методологий [6] предоставляет верификатору определенные правила и инструментарий для разработки тестовых окружений.

Методология UVM (рисунок 3) была разработана в 2010 году на основе методологии OVM (совместная разработка корпораций Cadence и Mentor Graphics). Она представляет собой набор классов на языке SystemVerilog. При построении окружения используется так называемое моделирование на уровне транзакций, Transaction-Level Modeling (TLM). Смысл этой технологии заключается в абстрагировании от конкретных интерфейсов, которые зачастую являются сложными для работы и понимания. Вместо набора сигналов верификатор оперирует набором более простых пакетов. Пакеты передаются от одного блока к другому через специальные порты. Типичное тестовое окружение изображено на рисунке 3.

Рис. 3. Пример тестового окружения

Основные компоненты тестового окружения UVM (OVM):

1. DUT (Device Under Test) - RTL-модель тестируемого устройства.

2. Пакеты данных (data items) - структуры данных, подаваемые на вход тестируемого устройства (на рис. 3 не изображены). Могут содержать различные сигналы, инструкции, другие пакеты.

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

4. Последовательность (sequence) - последовательность тестовых воздействий. В зависимости от устройства и тестов она может быть как полностью задана разработчиком, так и частично или полностью произвольной.

5. Генератор последовательностей (sequencer) - компонент, контролирующий выполнение последовательностей и передающий пакеты данных в драйвер.

6. Монитор (monitor) - компонент, который собирает результаты работы устройства. Как и драйвер, монитор имеет доступ к интерфейсу. Он не подает сигналы в устройство, а только ведет проверку выходных сигналов и собирает данные о покрытии.

7. Компаратор (scoreboard, analysis и т.д.) - компонент, анализирующий полученные результаты работы устройства. Проводит оценку правильности функционирования.

8. Агент (agent) - компонент, содержащий генератор последовательностей, драйвер и монитор. Агент представляет собой универсальный компонент и используется для уменьшения времени разработки новых окружений, так как разработчику не требуется разбираться в работе его составляющих и подключать их проекту поодиночке. Агенты могут различаться по функциям и назначению, к примеру, одни их них могут подавать сигналы в устройство, а другие - собирать и оценивать результаты.

9. Окружение/среда (environment) - компонент самого высокого уровня. Состоит из набора агентов и других более низкоуровневых компонентов. Среда содержит параметры, позволяющие конфигурировать ее топологию и функции (например, отключать или подключать отдельные компоненты).

Для быстрой разработки компонентов окружения UVM (OVM) предоставляет библиотеку классов. Каждому описанному выше блоку соответствует один из классов. Широкие возможности языка SystemVerilog позволяют не использовать при разработке окружения какую-то определенную структуру или классы, а создавать для каждого

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

Использование UVM на примере верификации контроллера прерываний APIC микропроцессора «Эльбрус^».

Методология UVM была использована для верификации контроллера прерываний APIC [7] системы на кристалле «Эльбрус^». APIC состоит из следующих частей:

• LAPIC является принадлежностью конкретного ядра и выполняет две основные функции: получение прерываний от внутренних источников и устройства, работающего с IOAPIC, в виде сообщений для дальнейшей передачи на обработку в процессор; прием и отправка межпроцессорных сообщений в многопроцессорных конфигурациях.

• SAPIC

• APIC_IO предназначено для передачи сообщений о прерываниях от ЮАРГСа в LAPI& процессоров, а также передачи ответных сообщений в IOAPIC.

Рис. 4. Структурная схема тестового окружения APIC

Для автономной верификации контроллера прерываний АР1С было создано тестовое окружение (рисунок 4) в соответствии с идеологией

UVM (OVM). Для APIC каждого из 4-х ядер процессора спроектированы драйвера и сиквенсеры. Управление этими модулями осуществляется с помощью системного (виртуального) сиквенсера, который управляет сиквенсерами ЛРГСов на уровне тразакций(ТЬМ). Результаты работы устройства сравниваются с моделью контроллера прерываний, написанной на языке C++. Модульность тестового окружения UVM (OVM) позволяет легко вносить поправки в отдельные блоки устройства и окружения не перепроектируя систему в целом.

Возможности OVM (UVM) для верификации сложных устройств.

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

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

В рамках проекта по созданию высокопроизводительного многоядерного процессора «Эльбрус-2S», в частности, выполняется автономная верификация модулей кэша второго уровня микропроцессора с использованием OVM [8]. Одним из таких устройств является очередь отложенных запросов в память (Write Back Queue, WBQ [9]).

Основной задачей WBQ является обработка Write Back (WB) запросов, которые генерируются, когда требуется удалить строку из кеша и записать в оперативную память. Почти всегда причиной возникновения WB являются CPU-запросы на чтение данных, которые при промахе в L2 кэше освобождают место для требуемых данных, вытесняя "старую" строку в память. WB выполняется в 2 этапа. Сначала соответствующий банк L2 кэша генерирует WB-запрос, который через WBQ поступает в арбитр кэша (L2_Arbiter). На следующем этапе арбитр по WB-запросу считывает данные из кэша и отправляет их в память. Для связи с памятью каждое ядро имеет отдельное усройство - Memory Access Unit (MAU).

Помимо обработки WB-запросов, WBQ поддерживает работу с запросами из STMB (STore Miss Buffer) и запросами поддержания когерентности (snoop). Большое количество «соседних» с WBQ устройств (32 интерфейса, 6 устройств), высокая сложность организации взаимодействия между ними, а также малая

информативность линий интерфейса между WBQ и L2_Arbiter усложняют проектирование окружения.

Структурная схема тестового окружения приведена на рисунке 5. На схеме пунктирными стрелками показана основная последовательность обработки STMB и WB запросов. Такую последовательность можно было бы легко организовать с помощью виртуального сиквенсера, если бы в интерфейс с L2_Arbiter разработчики устройства добавили дополнительные линии, сигнализирующие о типе выдаваемого WBQ запроса (работа с половиной или целой кэш-строкой).

От того, какого типа запрос, зависит последовательность его обработки: L2_Arbiter, принимая STMB запрос на считывание половины кэш строки, выставляет один сигнал об успешной передаче (taken). В процессе приема транзакции на считывание целой кэш строки сигнал taken выставляется дважды.

Рис. 5. Структурная схема тестового окружения WBQ

Проблема была решена с помощью использования механизма портов (ovm_analysis_port) между драйверами STMB и ARB (показан на рисунке штрихпунктирной линией). Передав запрос на чтение половины или целой кэш-строки, драйвер STMB информирует об этом ARB-драйвер. Получив по ARB_O-интерфейсу пакет, ARB-драйвер проверяет список полученных по ovm_analysis_port уведомлений и устанавливает на ARB_O и ARB_IN нужное количество сигналов taken и vdat соответственно.

Применение подобного механизма позволило решить проблему формирования адреса snoop-запроса SNSW-драйвером. В некоторых тестах адрес snoop-запроса должен совпадать с адресами WB-запросов находящихся в WBQ на момент получения snoop-запроса устройством. Создан класс Singleton, экземпляр которого содержит информацию о всех WB запросах находящихся в устройстве WBQ. Перед тем, как SNSW-драйвер устанавливает значение на адресную шину, он выбирает произвольный адрес из массива, хранящегося в Singleton. Обновление информации в Singleton обеспечивают драйвера MAU и WB (связи изображены на рисунке 5 пунктирными стрелками).

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

Заключение

Использование современных методологий верификации (OVM/UVM) для создания тестовых окружений позволяет существенным образом ускорить разработку программ тестирования устройств различной сложности, улучшить модернизационные возможности тестового окружения. Стандартизованность применяемых методологий позволяет повысить также понятность кода для сторонних разработчиков.

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

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

Литература

1. Интернет-ресурс по современным методологиям верификации и языкам описания аппаратуры. - http://testbench.in/;

2. Hardware Design Verification: Simulation and Formal Method-Based Approaches, William K. Lam, Prentice Hall PTR, March 03, 2005;

3. The Verilog PLI Handbook Second Edition, Stuart Sutherland, USA New York, 2002;

4. Coverage Technology User Guide, Synopsys, August 2011;

5. SystemVerilog for Verification, Chris Spear: Marlboro, USA, Springer Science+Business Media, 2008

6. Интернет-ресурс по современным методологиям верификации. -http://verification-academy.mentor.com/

7. Mentor Graphics UVM/OVM Documentation (verification methodology cookbook), July 2011;

8. Документация на APIC системы на кристалле «Эльбрус^».

9. Документация на WBQ кэша L2 системы на кристалле «Эльбрус^».