Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Верификация цифровых устройств. Курс лекций. Учебное пособие
.pdf
при активном сбросе. Для этого используется ключевое слово
disable iff:
property handshake;
@(posedgeClk)disableiff (Reset) req_sq|->ack_sq;
endproperty
assert property(handshake);
Механизм утверждений позволяет рассматривать достаточно
сложные последовательности. Последовательность представляет
собой список логических выражений, расположенных в порядке
возрастания времени. Последовательность истинна, если логические выражения истинны на конкретных тактах синхронизации.
Выражения, используемые в последовательностях, интерпретируются так же, как условие процедурного оператора if. Рассмотрим
несколько простых примеров последовательностей. Оператор ##
задерживает выполнение на указанное количество тактовых событий или тактов.
«a» должно быть истинным на текущем такте, а «b» – на следующем:
a ## 1 b
«a» должно быть истинным на текущем такте, а «b» – на N-м:
a ## N b
«a» должно быть истинным на текущем такте, и «b» – хотя бы
на одном из четырех следующих:
a ##[1: 4] b
Оператор * используется для указания последовательного повторения левого операнда:
a ## 2 b) [* 2] // то же что и (a ## 2 b ## 1 a ## 2 b)
– 81 –

$ может использоваться для расширения временного окна до
конечного, но неограниченного диапазона. В данном примере между «а» и «с» может быть сколько угодно «b»:
a ## 1 b [* 1: $]## 1 c
[-> – оператор непоследовательного повторения:
a## 1 b[-> 1: 3]## 1 c
Это означает, что за «a» следует любое количество тактовых
импульсов, где «c» должно быть ложным, а «b» соответствует истине от одного до трех тактов, причем последний раз «b» должен
быть истинным за такт до установки в истину «c».
[= – оператор непоследовательного повторения, аналогичен
оператору [->, но выражение «b» не обязательно должно быть истинным за такт до установки в истину «c»:
a## 1 b[= 1: 3]## 1 c
Есть несколько операторов, которые можно использовать между
последовательностями. Бинарный оператор and используется, когда утверждается, что обе последовательности будут истинными,
но время их окончания может быть различным. Время окончания
операции – это время окончания последовательности, которая заканчивается последней.
Оператор intersect используется, когда оба выражения операнда
ожидаются успешными, и время окончания выражений операнда
должно быть одинаковым.
Если ожидается совпадение хотя бы одной из двух последовательностей операндов, используется оператор or.
Оператор first_match сопоставляет только первое совпадение
из, возможно, нескольких совпадений для попытки оценки выражения последовательности. Это позволяет исключить все последующие совпадения из рассмотрения.
Два наиболее интересных оператора – throughout и within – это
сокращения более сложных записей. Рассмотрим примеры использования операторов:
– 82 –

s1 and s2
s1 intersect s2
s1 or s2
first_match(s1
##[1:2] s2);
e1 throughout s1
s1 within s2
Истинно, если обе последовательности истинны, но завершаются они необязательно одновременно.
Истинно, если обе последовательности завершаются успешно и одновременно.
Истинно, если хотя бы одна последовательность истинна.
Аналогично or, но выдает срабатывание только
на первое совпадение.
должно быть истинно на каждом такте во
e1
время последовательности
Означает, что s1 должна происходить хотя бы
один раз полностью в
s1.
s2.
Резюмируя, можно отметить, что утверждения – это мощнейший инструмент верификации, который позволяет при правильном
использовании обнаруживать и исправлять огромное количество
ошибок.
8.2. Функциональное покрытие
При разработке тестов неизменно возникает вопрос: как определить, что весь требуемый функционал проверен? Для этих целей во
время моделирования должен выполняться сбор функционального
покрытия.
Если говорить в упрощенной форме, то функциональное покрытие – это определяемое пользователем отображение каждого функционального признака, подлежащего тестированию, в так называемую «точку покрытия» coverpoint, и эти точки покрытия имеют
определенные условия (диапазоны, определенные переходы и т.д.),
которые должны быть выполнены до того, как пойдет речь о 100 %
покрытии функционального признака во время моделирования. Все
эти условия для точки покрытия определены в форме ячеек bins.
– 83 –

Во время моделирования, когда определенное условие точки
покрытия выполняется, соответствующая ячейка помечается как
покрытая. После выполнения нескольких тестов может быть сгенерирован отчет для анализа функционального покрытия, и составлен
план для закрытия непокрытых элементов. Несколько точек покрытия могут быть объединены в одной группе покрытия –
covergroup, а все группы покрытия вместе обычно называются мо-
делью функционального покрытия.
Конструкция covergroup является определяемым пользователем
типом. Определение типа записывается один раз, а затем несколько
экземпляров этого типа могут быть созданы. Подобно классу,
группы покрытия являются динамическими объектами, и для их
создания требуется вызов метода new. Приведенный ниже пример
определяет группу покрытия с именем cg. Затем создается экземпляр cg – cg_inst.
covergroup cg;
...
endgroup
cg cg_inst = new;
Группы покрытия не собирают информацию о покрытии постоянно. Их необходимо активировать, после чего группа «защелкнет»
текущее значение контролируемых ей параметров и, при необходимости, увеличит покрытие. Запуск группы можно выполнить явно, используя метод sample ()
cg_inst.sample();
:
Также для запуска работы группы покрытия может использоваться список чувствительности, аналогичный
covergroupcg@(posedgeclk);
...
endgroup
always @ блокам:
Группа покрытия может содержать одну или несколько точек
покрытия. Точка покрытия может быть целочисленной переменной
или целочисленным выражением. Точка покрытия создает иерархическую область и, опционально, может иметь метку:
– 84 –

program main;
bit[0:2] y;
bit[0:2]values[$]= '{3,5,6};
covergroup cg;
cp_y :coverpoint y;
endgroup
cg cg_inst =new();
initial
foreach(values[i])
begin
y = values[i];
cg_inst.sample();
end
endprogram
В приведенном выше примере выбираем точку покрытия y.
Точка покрытия называется cp_y. В отчете о покрытии вы увидите
это имя. Группа покрытия cg определена, и ее экземпляр cg_inst
создан. Значение y выбирается при вызове метода
cg_inst.sample(). Общие возможные значения для Y составляют
0, 1, 2, 3, 4, 5, 6, 7. Переменной y назначены только значения 3, 5, 6.
После выполнения указанного фрагмента в отчете о покрытии будет отображено, что точка cp_y покрыта на 37,5 %.
Точка покрытия может быть целочисленной переменной или
выражением. SystemVerilog позволяет указывать точки покрытия
различными способами:
coverpoint top.DUT.uart_bus.addr;
coverpoint addr[31:2];
coverpoint(a*b);
coverpoint funcation_call();
covergroup (refint r_v) cg;
cover_ref:coverpoint r_v;
endgroup
В последнем примере переменная, которая будет использоваться
в качестве точки покрытия, передается как параметр конструктора
группы.
Также для точек покрытия можно добавлять условия их работы,
чтобы не собирать покрытие в состоянии сброса. Например, пере-
– 85 –

менная r в примере ниже будет покрыта, только если выражение в
скобках истинно, т.е. reset==0:
covergroup cg;
coverpointr iff(!reset);
endgroup
Точки покрытия, в свою очередь, содержат ячейки покрытия.
Ячейки состоят из имени, счетчика и соответствующего им набора
значений или последовательности. При достижении точки покрытия определяется значение и увеличивается счетчик соответствующей этому значению ячейки. Для последовательностей значения
счетчика увеличиваются при достижении конца последовательности. Ячейки могут быть созданы неявно или явно.
В приведенных выше примерах использовалось неявное создание ячеек. Количество ячеек соответствовало количеству допустимых значений переменной, т.е. для bit[0:2] y созывалось восемь
ячеек.
Можно ограничить максимальное количество точек. Тогда все
допустимые значения будут разделены пропорционально по созданным ячейкам:
covergroup cg;
cp_y :coverpoint y;
{ options.auto_bin_max = 2;}
endgroup
Для данного примера будут созданы две точки, соответствующие значениям y от 0 до 3 и от 4 до 7. Соответственно, для 100 %
покрытия такой точки достаточно, чтобы y приняла два значения –
по одному для каждой ячейки.
В реальности, как правило, не все значения интересны для покрытия, поэтому, когда инженер знает точные значения, которые
ему необходимо охватить, он может использовать явные ячейки.
При этом им могут быть присвоены имена:
program main;
bit[0:2]y;
bit[0:2]values[$]= '{3,5,6};
covergroup cg;
– 86 –

cp_y:coverpoint y {
bins a ={0,1};
bins b ={2,3};
bins c ={4,5};
bins d ={6,7};
}
endgroup
cg cg_inst =new();
initial
foreach(values[i])
begin
y = values[i];
cg_inst.sample();
end
endprogram
В этом примере ячейки создаются явно, получают имена и соответствующе им значения. Ячейки можно объединять в массив:
covergroup cg;
cp_y:coverpoint y {
binsa[4]={[0:7]};
}
В данном случае будет создано четыре ячейки, и значения будут
распределены по ним равномерно.
Ячейка по умолчанию – это ячейка, которая не связана ни с одним из заданных значений. Ячейка по умолчанию захватывает значения точки покрытия, которые не лежат ни в одном из определенных интервалов. Однако расчет покрытия для точки не принимает
во внимание покрытие, захваченное ячейкой по умолчанию. В следующем примере создаются только две ячейки, чтобы покрыть
значения от 0 до 4. Остальные значения находятся в ячейке по
умолчанию, которая не используется при расчете процента покрытия. Тогда, получив одно значение в диапазоне от 0 до 4, будет достигнуто 50 % покрытие:
cp_y:coverpoint y {
bins a[2]={[0:4]};
bins d=default;
}
– 87 –

Точки покрытия позволяют проверять достижения не только
конкретных значений, но и заданных переходов. SystemVerilog
позволяет указывать один или несколько наборов переходов в качестве ячейки покрытия. Рассмотрим возможные типы переходов.
Переход с одним значением:
cp_y:coverpoint y {bins bin3to4 =(3=>4); }
Последовательность переходов:
cp_y:coverpoint y { bins bin3to4to5=(3=>4=>5); }
Набор переходов. В данном примере любой переход из 3 или 4 в
5 или 6 будет покрывать ячейку:
cp_y:coverpoint y { bins bin34to56 =(3,4=>5,6); }
Повторения. Ячейка будет покрыта при пятикратном повторении значений 3:
cp_y:coverpoint y { bins do3_5times=(3[*5]); }
Также можно задавать переменное количество повторений.
Данная ячейка покроется при повторении значения 3 от трех до
пяти раз:
cp_y:coverpoint y { bins do3to5times=(3[*3:5]); }
Можно указать как цель покрытия повторения с пропусками:
cp_y :coverpoint y {bins do13335=((1=>3[->3]=>5); }
В данном примере для покрытия ячейки должна выполняться
последовательность, в которой будет покрыто значение 1, затем
через произвольное число выборок трижды получено значение 3.
После последней 3 должна следовать 5. Если необходимо допустить пропуски между заключительной 3 и 5, то используется следующая конструкция:
cp_y :coverpoint y {bins do13335=((1=>3[=3]=>5); }
– 88 –

Набор значений или переходов, связанных с точкой покрытия,
можно явно исключить из покрытия, указав их как игнорируемые:
covergroup cg;
cover_point_y :coverpoint y {
ignore_bins ig ={1,2,3,4,5};
}
Значения от 1 до 5 будут игнорироваться, и в покрытии будут
участвовать только 0, 6 и 7.
Набор значений или переходов, связанных с точкой покрытия,
можно пометить как недопустимый, указав их недопустимыми. Все
значения или переходы, связанные с недопустимыми ячейками,
исключаются из покрытия. Если происходит недопустимое значение или переход, выдается ошибка:
covergroup cg;
cover_point_y :coverpoint y {
illegal_bins ib = {7};
}
В модели UVM за рассмотренные в данной лекции задачи контроля и покрытия отвечают мониторы и табло. Мониторы контролируют корректность работы, достижение и покрытие целей на
уровне отдельных интерфейсов, а табло позволяет формировать
более общее покрытие функциональности всего проекта.
Использование функционального покрытия требует хорошо
проработанного плана тестирования и много времени для создания
групп покрытия, анализа результатов и изменения тестов для создания необходимых воздействий. Это может казаться лишней работой, но для достаточно больших проектов в реальности потребовалось бы значительно больше усилий для написания эквивалентных направленных тестов.
– 89 –

Список литературы
[1] Universal Verification Methodology (UVM) 1.2 User’s Guide
[Электронный ресурс]. – Режим доступа: https://accellera.org/
images/downloads/standards/uvm/uvm_users_guide_1.2.pdf (дата обращения: 01.06.2020).
[2] Chris Spear. SystemVerilog for Verification. A Guide to Learning the Testbench Language Features. Second Edition // Springer Science+Business Media, 2008.
[3] Дэвид М. Харрис, Сара Л. Харрис. Цифровая схемотехника
и архитектура компьютера //ДМК-Пресс, 2018 г.
[4] Ashok B. Mehta SystemVerilog Assertions and Functional Coverage Guide to Language, Methodologyand Applications //Springer Science+Business Media, New York, 2014.
[5] SystemVerilog Tutorials [Электронный ресурс]. – Режим доступа: https://www.doulos.com/knowhow/sysverilog/tutorial/ (дата обращения: 01.06.2020).
[6] Verification Methodology Cookbooks [Электронный ресурс]. – Режим доступа: https://verificationacademy.com/cookbook
(дата обращения: 01.06.2020).
– 90 –
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
