Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Верификация цифровых устройств. Курс лекций. Учебное пособие
.pdf
даже в другой файл при необходимости. Тогда, чтобы указать, что
реализуется функция из класса, перед именем функции ставится
имя класса и
class bus_operation;
endclass: bus_operation
function void bus_operation∷display();
$display("Addr: %h Data: %h ", addr, data);
endfunction
∷ .
bit[31:0] addr, cmd,data[32];
extern function void display();
3.2.2. Наследование
В работе достаточно часто может возникать необходимость в
создании похожих классов. Например, операции чтения и записи на
шине могут иметь много общих полей и методов, таких как вычисление контрольной суммы, передача адреса и т.п. Создание двух
разных классов – это дополнительная работа и возможность внесения новых ошибок.
Для решения таких задач SystemVerilog поддерживает механиз-
мы наследования. В примере ниже можно выделить общие данные
и методы операций чтения и записи в отдельный класс, а затем
унаследовать от него два класса для каждой операции. Пример
наследования:
class bus_operation;
bit[31:0] addr, data[32];
...
endclass
class write_bus_operation extends bus_operation;
const bit[31:0] cmd = 1;
...
endclass
class read_bus_operation extends bus_operation;
constbit[31:0] cmd = 2;
...
endclass
– 31 –

Классы-наследники будут иметь все те же поля и методы, кото-
рые были у базового класса. Если конструктор базового класса
имеет какие-либо аргументы, то конструктор в классе-наследнике
должен иметь свой конструктор и вызывать конструктор базового
класса в первой строке своего конструктора, используя ключевое
слово super:
super.new(init);
Как и в С++, в SystemVerilog можно переопределять функции в
классах-наследниках. Для этого функция в базовом классе должна
быть помечена как виртуальная. Пример перегрузки функций:
class bus_operation;
virtual function void display;
$display("Addr: %h Data: %h ", addr, data);
endfunction
endclass
class write_bus_operation extends bus_operation;
virtual function void display;
super.display();
$display("cmd = %d",cmd);
endfunction
endclass
При вызове функции display для экземпляра класса
write_bus_operation вызовется функция, описанная в этом классе,
а не функция родительского класса.
С классами-наследниками можно работать, используя дескриптор на базовый класс. Поскольку класс-наследник копирует все поля базового класса, то обращения к таким полям доступны на основе любого дескриптора.
bus_operation bo;
write_bus_operation wbo;
wbo = new();
bo = wbo;
$display(bo.addr);
bo.display;
– 32 –

При обращении к полю адреса будет успешно напечатан адрес
операции. Но, несмотря на то, что используется дескриптор на базовый класс, вызов функции
display вызовет функцию класса-
наследника, так как она была переопределена. В SystemVerilog для
функций, объявленных виртуальными, для определения типа вызываемой функции используется не тип дескриптора, а тип объекта,
на который он показывает. Если не указывать функцию как
al, то будет вызываться функция, соответствующая типу дескрип-
virtu-
тора.
Если рассмотреть обратную ситуацию, когда дескриптор классанаследника показывает на объект базового класса, то это недопустимо и вызовет ошибку компилятора. Соответственно, если необходимо присвоить классу-наследнику значение дескриптора из базового класса, необходимо выполнять проверку, что тот указывает
на верный объект. Для этого применяется функция
$cast:
wbo = new();
bo = wbo;
if(!$cast(tmp, bo))$display("cannot assign tmp to bo ");
Дескриптор tmp будет указывать на объект, только если его тип
соответствует типу дескриптора; т.е., если объявить
read_bus_operation tmp;
то присвоение выполнено не будет и функция $cast вернет false в
качестве результата.
SystemVerilog позволяет создавать абстрактные классы – это
классы, которые используются как основа для других классов, но
при этом нельзя создавать объекты такого типа. В рассмотренном
выше примере класс bus_operation можно объявить абстрактным.
Для этого надо при объявлении класса указать ключевое слово
virtual.
virtual class bus_operation;
pure virtual function void display();
...
endclass
– 33 –

Можно создать дескриптор с типом bus_operation, но не объект
такого типа. Методы виртуальных классов не обязательно должны
быть реализованы. Они могут быть объявлены как чисто виртуальные методы с использованием ключевого слова pure. Такие методы
обязательно должны быть перегружены в классах-наследниках,
чтобы иметь возможность создать объекты данного типа.
3.2.3. Параллельные потоки
В простом Verilog есть два способа группировки операторов – с
помощью операторов
ры
begin ... end выполняются последовательно, а операторы
fork ... join – параллельно. Последние очень ограничены в том,
что все операции внутри
того, как программа сможет продолжаться. SystemVerilog представляет два новых способа создания потоков – с помощью операторов
fork ... join _none и fork ... join_any. join_none не
ждет завершения потоков и продолжает работу сразу после их создания,
join_any ждет завершения одного любого потока.
initial begin
$display("@%0t: start fork...join example", $time);
#10 $display("@%0t: sequential after #10", $time);
fork
$display("@%0t: parallel start", $time);
#50 $display("@%0t: parallel after #50", $time);
#10 $display("@%0t: parallel after #10", $time);
begin
#30 $display("@%0t: sequential after #30", $time);
#10 $display("@%0t: sequential after #10", $time);
end
join
$display("@%0t: after join", $time);
#80 $display("@%0t: finish after #80", $time);
end
Все операции между fork-join будут выполняться параллельно,
операции между
join может быть заменен на join_none или join_any. Результаты
при работе с разными типами join представлены ниже:
begin ... end или fork ... join. Операто-
fork ... join должны завершиться до
begin ... end выполняются последовательно.
– 34 –

fork ... join join _none join_any
@0: start fork...join example
@10: sequential after #10
@10: parallel start
@20: parallel after #10
@40: sequential after #30
@50: sequential after #10
@60: parallel after #50
@60: after join
@140: finish after #80
@0: start fork...join
@10: sequential after #10
@10: after join
@10: parallel start
@20: parallel after #10
@40: sequential after #30
@50: sequential after #10
@60: parallel after #50
@90: finish after #80
@0: start fork...join example
@10: sequential after #10
@10: parallel start
@10: after join
@20: parallel after #10
@40: sequential after #30
@50: sequential after #10
@60: parallel after #50
@90: finish after #80
– 35 –

Лекция 4. UVM структура тестового окружения
Введение
В лекции представлена методология UVM. Описана история ее
создания и предшествующие этому процессы. Рассмотрена общая
архитектура тестового окружения, построенного в соответствии с
данной методологией. Основу взаимодействия внутри этого окружения составляет механизм TLM. Также подробно рассмотрен
принцип работы TLM, типы и назначение основных видов портов и
протоколы взаимодействия.
4.1. История UVM
Универсальная методология проверки (Universal Verification
Methodology (UVM)) – стандартизированная методология верификации интегральных схем. UVM является развитием OVM (Open
Verification Methodology – методологии открытой верификации),
которая в значительной степени основана на eRM (e Reuse
Methodology).
Методология e Reuse (eRM) была первой методологией верификации, ориентированной на повторное использование верификационного окружения. eRM использовала язык everification language,
разработанный Verisity Design в 2001 г. и выпущенный в 2002 г.
Методология была составлена из методических рекомендаций по
таким темам, как:
• «Соглашения об именах файлов»;
• «Функциональное разбиение тестового стенда»;
• «Рекомендации по упаковке кода»;
• «Библиотеки последовательностей и классов сообщений».
Методология eRM получила широкое распространение и одобрение среди инженеров-верификаторов.
В 2006 г. компания Mentor Graphics выпустила библиотеку базовых классов, написанную в SystemVerilog, – «Усовершенствованная методология проверки» (Advanced Verification Methodology –
AVM). Чуть позже, в 2007 г., Cadence выпускает свою библиоте-
– 36 –

ку – URM (Universal Reuse Methodology) – «Универсальная методология повторного использования». Из основных особенностей
обеих библиотек можно отметить использование TLM транзакций
и open-source реализацию.
В 2008 г. Mentor и Cadence совместно выпускают Open Verification Methodology (OVM) – «Открытая методология верификации».
OVM имела несколько версий, последняя версия, OVM 2.1.2, выпущена в 2011 г.
Заключительный на данный момент шаг развития – библиотека
классов UVM. Она значительно упрощает разработку верификационных окружений, автоматизируя многие процессы, например, генерацию последовательностей и базовые операции с данными –
такие как копирование, сравнение, упаковка. Данная методология в
отличие от предыдущих разрабатывалась независимо от поставщиков симуляторов. Она является стандартом компании Accellera с
поддержкой нескольких поставщиков: Aldec, Cadence, MentorGraphics и Synopsys.
4.2. Архитектура тестового окружения UVM
Библиотека классов UVM предоставляет базовые элементы, такие как иерархия компонентов, модель транзакций (TLM), конфигурационная база данных и т.д., которые позволяют разработчику
ускорить создание тестового окружения. На рис. 4.1 представлена
обычная архитектура тестового окружения, построенного на базе
UVM. Она соответствует общим рекомендациям для тестового
окружения для случайного тестирования.
Верхний модуль Testbench предназначен для подключения тестируемого устройства DUT и тестового окружения. Test является
компонентом UVM верхнего уровня в тестовом окружении. Тест
UVM обычно выполняет три основные функции: создание тестового окружения, его настройку и формирование тестовых последовательностей. Как правило, создается один базовый класс теста с
подключенным объектом тестовой среды и другими общими для
всех тестов компонентами, а затем создаются отдельные тесты как
наследники базового.
– 37 –

Рис. 4.1. Тестовое окружение UVM
Environment – тестовое окружение. Его задача – объединение
всех остальных компонент тестового окружения. При этом может
быть несколько уровней Environment. Для каждого интерфейса может быть свое тестовое окружение, затем они могут объединяться
по подсистемам и наконец – общая среда верхнего уровня.
Задача Scoreboard – проверять поведение DUT. Он принимает
транзакции с входов и выходов DUT, выполняет транзакции через
некую эталонную модель для получения ожидаемых результатов, а
затем сравнивает ожидаемый результат с фактическим выходом.
Agent работает с отдельными интерфейсами DUT. Как правило,
агент включает в себя генератор последовательностей Sequencer
для управления потоком сигналов, драйвер Driver – для формирования воздействия на физическом уровне и монитор Monitor – для
наблюдения за интерфейсом.
– 38 –

Генератор последовательностей управляется последовательностями. Они не входят в иерархию тестового окружения. Последовательности могут иметь свою иерархию, где одна последовательность запускает несколько других. Последовательности могут относиться к одной транзакции и создаваться как на время, так и работать постоянно все время моделирования.
4.3. TLM
Как отмечалось ранее, при разработке тестового окружения
важно правильно выбирать необходимые уровни абстракции в работе с данными. При тестировании устройства, которое обрабатывает пакеты данных, для того чтобы получить эти пакеты, нет
необходимости задумываться о физическом уровне и сигналах шины, которые будут эти пакеты передавать. Хотя фактический интерфейс к тестируемому устройству в конечном итоге представляет
собой отдельные сигналы, но формирование пакетов и поверка результатов должны выполняться на уровне транзакций.
UVM предоставляет набор интерфейсов и каналов связи на
уровне транзакций, которые можно использовать для соединения
элементов верификационного окружения на уровне транзакций –
TLM. Использование универсального интерфейса для передачи
данных между компонентами позволяет безболезненно заменять
одни элементы другими.
Эта концепция также позволяет собрать тестовое окружение по
UVM с моделью DUT на уровне транзакций, а затем повторно использовать это же окружение для тестирования RTL. Все, что требуется – это заменить модель уровня транзакций на RTL, добавив
необходимый интерфейс.
В библиотеке UVM предусмотрены две версии TLM. TLM-1 –
система передачи сообщений. Эти интерфейсы не связаны между
собой. Ни один из интерфейсов не обеспечивает явных аннотаций
синхронизации. TLM-2.0, хотя и позволяет передавать данные и
синхронизировать их передачу между независимыми процессами, в
основном предназначен для высокопроизводительного моделиро-
– 39 –

вания систем на основе шины с отображением в памяти. В данном
курсе рассматривается только TLM-1.
В UVM транзакция – это объект класса, который включает любую информацию, необходимую для моделирования единицы связи между двумя компонентами. Количество и тип информации в
транзакциях определяется уровнем абстракции, на котором данная
транзакция используется. При этом транзакции могут включать в
себя в том числе и другие транзакции более низких уровней абстракции.
Предположим, что стоит цель – разработать тестовое окружение
для проверки IP-ядра последовательного интерфейса UART. IPядро имеет две линии – Rx и Tx – для передачи данных через последовательный порт и простой шинный интерфейс для подключения к процессору. Отдельные транзакции через последовательный
интерфейс тогда можно описать следующим образом:
class uart_trans extends uvm_sequence_item;
byte data;
bit crc;
...
endclass
Класс транзакции унаследован от uvm_sequence_item – базового
класса элементов последовательностей. Про последовательности
речь пойдет позже. В простейшем случае генератор последовательностей должен формировать элементы и передавать их на исполнение в драйвер. Для взаимодействия генератора и драйвера в таком
случае как раз и применяется интерфейс TLM-1.
TLM интерфейсы определяют набор методов, которые используют объекты транзакции в качестве аргументов. Для каждого интерфейса определяется понятие порта (port) и экспорта (export).
TLM порт определяет набор методов (интерфейс прикладного
программирования (API)), который будет использоваться для
конкретного соединения, в то время как TLM экспорт обеспечивает реализацию этих методов. Подключение порта к экспорту
позволяет выполнить реализацию при вызове метода порта
(рис. 4.2).
– 40 –
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
