Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Верификация цифровых устройств. Курс лекций. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
06.09.2026
Размер:
1 Мб
Скачать
при активном сбросе. Для этого используется ключевое слово
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 Learn­ing the Testbench Language Features. Second Edition // Springer Sci­ence+Business Media, 2008.
[3] Дэвид М. Харрис, Сара Л. Харрис. Цифровая схемотехника и архитектура компьютера //ДМК-Пресс, 2018 г.
[4] Ashok B. Mehta SystemVerilog Assertions and Functional Cov­erage Guide to Language, Methodologyand Applications //Springer Sci­ence+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 –