УДК 621.3.049.77
РАЗРАБОТКА ТЕСТОВОГО ОКРУЖЕНИЯ ДЛЯ ФУНКЦИОНАЛЬНО-ЛОГИЧЕСКОЙ ВЕРИФИКАЦИИ ЯТЬ-МОДЕЛЕЙ КОМПОНЕНТОВ МИКРОКОНТРОЛЛЕРА
НА БАЗЕ ОУМ-МЕТОДОЛОГИИ
Ю.А. Шкондин
Разработана система функциональных тестов на базе OVM (открытая методология верифицирования) для функционально-логической верификации RTL-моделей ядра и ряда периферийных компонентов микроконтроллера
Ключевые слова: функционально-логическая
тодология
Введение. Высокая конкуренция на рынке микроэлектронных устройств требует от разработчиков создания все более сложных и многофункциональных сверхбольших интегральных схем (СБИС) и сокращения сроков их проектирования. Эти противоречивые требования привели к появлению нового единого языка для описания и тестирования аппаратуры SystemVerilog (IEEE Std 1800™-2005), расширяющего возможности языка Verilog. Кроме того, появилась новая методология тестирования современных СБИС, предполагающая использование следующих возможностей языка SystemVerilog[1].
1. Использование формальных утверждений (SystemVerilog Assertions (SVA)) о предполагаемом поведении устройства, проектируемого на языке Verilog. SVA предлагает два основных преимущества для разработчика. В частности, SVA позволяет вставить требуемые утверждения о должном поведении блока устройства в HDL-описание устройства, чтобы при последующем моделировании или при использовании средств формальной верификации иметь возможность проверить соответствие созданной RTL-модели заданному набору утверждений. (Правильно ли это работает?)
2. Функциональное покрытие - это набор специальных конструкций и методов для работы с SVA и элементами устройства, чтобы в процессе тестирования устройства иметь информацию о том, какие операции с какими элементами устройства тестом выполнялись, а какие нет. Например, можно увидеть, что запись в регистр производилась, а чтение нет, и т.д. Иными словами, функциональное покрытие позволяет оценить качество проверки отдельных функций устройства. Эта информация может использоваться разработчиком теста для его дополнения таким образом, чтобы выполнялись все возможные операции со всеми элементами устройства.
3. Случайное тестирование с наложением внешних ограничений - набор методов для формирования случайных тестовых воздействий на уст ройство, ограниченных внешними параметрами.
Шкондин Юрий Александрович - ВГТУ, аспирант, ФГУП НИИ электронной техники, начальник лаборатории, тел. 8(904)211-16-77
верификация, RTL-модель, 8-битный микроконтроллер, OVM ме-
Появление данного инструмента было вызвано возрастающей сложностью создаваемых устройств и невозможностью за разумное время вручную протестировать все функции этих устройств. Так как тестирование при использовании данного метода происходит случайным образом, единственная адекватная шкала для оценки качества тестирования - это опять же функциональное покрытие. Таким образом, 100 %-е функциональное покрытие блока означает, что случайный тест покрыл все возможные воздействия на СБИС, которые разработчик предусмотрел, при этом случайное тестирование покрывает и множество комбинаций, которые разработчик не предвидел.
4. Объектно-ориентированное программирование (ООП) для создания высокоуровневых моделей и тестов. Максимальное заимствование кода, благодаря механизмам наследования, упрощенная интеграция с поведенческими моделями на языке C, благодаря механизму DPI (Direct Programming Interface - прямой интерфейс программирования), поддержке моделирования на уровне транзакций TLM (Transaction-level modeling - моделирование уровня транзакций) и т.д.
Все эти новшества позволяют повысить качество проверки проектируемого устройства, ускорить процесс отладки ошибочной ситуации, так как разработчик сразу может видеть, где и какая возникла проблема. Благодаря поддержке технологии случайного тестирования с внешними ограничениями и ООП у инженеров появляется возможность повысить скорость формирования тестов для сложных устройств.
В последнее время в области тестирования моделей аппаратуры все большее распространение получает технология OVM, совместно разработанная компаниями Mentor Graphics и Cadence Design Systems. Предшественниками OVM являются два основных подхода: AVM (от Mentor Graphics) и URM (от Cadence Design Systems).
OVM представляет собой первый открытый промышленный метод разработки тестов на основе языка SystemVerilog[2].
Основным средством OVM является библиотека классов на языке SystemVerilog (в дальнейшем планируется поддержка SystemC), позволяющая создавать модульные тестовые системы, допускающие многократное использование.
Рис. 1. Верификационное окружение модуля DUT.
В рамках технологии OVM тестовая система собирается из специальных блоков, называемых OVC (Open Verification Component - открытые верификационные компоненты). Каждый блок инкапсулирует тестовое окружение для отдельного модуля аппаратуры и состоит из полного набора компонентов, обеспечивающих генерацию стимулов, проверку правильности поведения и оценку полноты тестирования. Если тестируемая модель аппаратного обеспечения получается путем интеграции нескольких модулей, тестовая система для нее строится путем объединения соответствующих OVC-блоков и построения над ними специального синхронизирующего контроллера (виртуальный генератор тестовых последовательностей). На рис.
1 приведена схема верификационного окружения модуля DUT[3].
Постановка задачи. Цель данной работы -разработка верификационного окружения для ряда компонентов микроконтроллера на базе методологии OVM и выполнение функциональнологической верификации RTL-модели микроконтроллера в составе разработанного окружения.
Разработка верификационного окружения начинается с анализа требований к верификационному окружению. В данном случае от него требуется:
- подключение тестируемого модуля;
- задание глобальных сигналов (тактовый сигнал, сигнал сброса) и подача их на тестируемый модуль;
- создание компонентов OVC для каждого теста, обеспечивающего контроль откликов тестируемого модуля и, в случае необходимости, создание входных воздействий и подачу их на тестируемый модуль;
Следующим этапом является создание виртуального интерфейса к экземпляру тестируемого модуля. Ниже приведено его описание:
interface dut_if (); int test = 0;
// Test name string
// Actual Signals
logic
logic
logic
logic
logic
test_name =
reset;
clk_in;
clk_out;
pen;
paren;
wire [7:0] port_a;
wire [4:0] port_g;
reg [7:0] reg_port_a;
reg [4:0] reg_port_g;
'ifndef IFV import ovm_pkg::*;
'endif
assign port_a = reg_port_a;
assign port_g = reg_port_g; endinterface : DUT if
Далее создается модуль верхнего уровня (TOP LEVEL). Ниже приведено описание модуля верхнего уровня:
'include "sv/dut_if.sv" module dut_tb_top;
'include "sv/dut.svh"
'include "test_lib.sv"
parameter TRUE = 1’b1; parameter FALSE = 1’b0; parameter TRISTATE = 1’bz;
int counter;
dut_if xi0();
DUT_top dut( xi0.reset, xi0.clk_in, xi0.clk_out, xi0.pen, xi0.paren, xi0.port_a, xi0.port_b, xi0.port_c, xi0.port_d, xi0.port_e, xi0.port_f, xi0.port_g
);
initial begin run_test(); end
initial begin counter = 0;
xi0.reg_port_a <= {8{TRISTATE}}; xi0.reg_port_b <= {8{TRISTATE}}; xi0.reg_port_c <= {8{TRISTATE}}; xi0.reg_port_d <= {8{TRISTATE}}; xi0.reg_port_e <= {8{TRISTATE}}; xi0.reg_port_f <= {8{TRISTATE}}; xi0.reg_port_g <= {5{TRISTATE}}; xi0.reset <= TRUE; xi0.clk_in <= TRUE; xi0.pen <= FALSE; xi0.paren <= FALSE;
#100 xi0.reset <= FALSE;
#670000 xi0.reset = TRUE; end
//Generate Clock always
#15 xi0.clk_in = ~xi0.clk_in; // 33 MHz endmodule
В приведенном модуле создан экземпляр xi0 виртуального интерфейса dut_if, создан экземпляр dut модуля DUT_top, выводы которого подключенного к выводам виртуального интерфейса xi0, осуществлена генерация тактового сигнала и подача его на модуль dut, проведен сброс и осуществлен запуск теста run_test.
После этого разрабатывается класс транзакций dut_transfer, экземпляры которых, в случае необходимости задания входных воздействий, будут создаваться в генераторе последовательностей транзакций (sequncer) и передаваться драйверу (driver), который, в свою очередь, осуществляет
преобразование транзакций в сигналы, подающиеся непосредственно на тестируемый модуль [4]. Пример класса транзакций приведен ниже:
class DUT_transfer extends ovm_sequence_item;
parameter TRISTATE = 1’bz;
rand reg [7:0] port_a; rand reg [7:0] port_b; rand reg [7:0] port_c; rand reg [7:0] port_d; rand reg [7:0] port_e; rand reg [7:0] port_f; rand reg [4:0] port_g;
rand int unsigned setup_delay = 0; rand int unsigned hold_delay = 1;
'ovm_object_utils_begin(DUT_transfer) 'ovm_field_int (port_a, OVM_ALL_ON) 'ovm_field_int (port_b, OVM_ALL_ON) 'ovm_field_int (port_c, OVM_ALL_ON) 'ovm_field_int (port_d, OVM_ALL_ON) 'ovm_field_int (port_e, OVM_ALL_ON) 'ovm_field_int (port_f, OVM_ALL_ON) 'ovm_field_int (port_g, OVM_ALL_ON) 'ovm_field_int (setup_delay, OVM_ALL_ON) 'ovm_field_int (hold_delay, OVM_ALL_ON) 'ovm_object_utils_end
// new - constructor
function new (string name =
"DUT_transfer_inst"); super.new(name); endfunction : new
endclass : DUT_transfer
Следующим этапом является разработка тестов на языке ассемблер либо C каждого из структурных компонентов. Цель теста - проверка функционирования компонента целиком или, если компонент сложный, проверка одного из его структурных составляющих либо одного из режимов его работы. При разработке теста необходимо решить задачу, каким образом будет осуществляться контроль статуса выполнения теста. Эту задачу каждый разработчик решает по разному. В рамках данной работы определимся, что в случае удачного прохождения теста на один из портов микроконтроллера будет передаваться код PASSED, а в случае ошибки на порт будут выдаваться коды ошибок: FAILED_1, FAILED_2. Наличие этих состояний позволят тестовому окружению определить, что тест пройден, и сообщить ему статус теста.
Ниже приведен фрагмент теста порта ввода-вывода микроконтроллера, разработанная на языке ассемблер:
.include "dut_def.inc"
.org 0
rjmp reset
.org INT1addr
rjmp int_INT1
reset:
clr r16
out ddra,r16
//INT1
//70
//test
//code
test:
//test
//code
out ddrb,rl6 cpse rl6,r20
out ddrc,rl6 rjmp err
out ddrd,rl6 ret
out ddre,rl6
sts ddrf,rl6 int INT1:
sts ddrg,rl6 clr rl6
ser rl6 out MCUCR,rl6
out porta,rl6 out EIMSK,rl6
out portb,rl6 reti
out portc,rl6 err:
out portd,rl6 ser rl6
out porte,rl6 out ddrb,rl6
sts portf,rl6 out portb,r2l
sts portg,rl6 end: rjmp loop
clr rl6 ser rl6
sts $40,rl6 out ddrb, rl6
nop ldi rl6, $77 //
nop out portb, rl6
ldi rl6,low(RAMEND) rjmp loop
out SPL,rl6
ldi rl6,high(RAMEND) loop
out SPH,rl6 rjmp loop
for rising edge ldi out ldi
rl6,(l<<ISCl0)|(l<<ISCll)
rl6,(l<<SE)
MCUCR,rl6
sts
ser
out
ldi
out
sei
sleep
nop
EICRA,rl6
rl6
EIFR,rl6
rl6,(l<<INTl)
EIMSK,rl6
const in r20
error in r2l
ldi r20,$00
ldi r2l,$Fl ;
rcall nop nop nop test
rjmp end
const in r20
error nop nop nop in r2l
in rl,pina
in r2,pinb
in r3,pinc
in r4,pind
in r5,pine
in r6,pinf
lds rl6,ping
andi rl6,$lF
cpse rl,r20
rjmp err
cpse r2,r20
rjmp err
cpse r3,r20
rjmp err
cpse r4,r20
rjmp err
cpse r5,r20
rjmp err
cpse r6,r20
rjmp err
andi r20,$lF
Тест, фрагмент которого приведен выше, отвечает за контроль подаваемых входных воздействий на порт. В конце теста, в соответствии с методикой контроля статуса описанной выше, на порт B микроконтроллера выдается либо статус PASSED (0x77), либо статус FAILED (0xF1).
После того, как тест разработан, приступаем к разработке компонента OVC верификационного окружения. Компонент должен содержать генератор транзакций, библиотеку транзакций из которой генератор будет осуществлять выборку транзакций, драйвер и монитор.
Ниже приведено описание класса генератора транзакций и класса транзакции одного вида из библиотеки классов транзакций.
class dut_prt4_master_sequencer extends
ovm_sequencer #(dut_transfer);
// The virtual interface used to drive and view HDL signals.
protected virtual dut_if xmi;
// Master Id protected int master_id;
'ovm_sequencer_utils_begin(dut_prt4_master_seq
uencer)
'ovm_field_int(master_id, OVM_ALL_ON) 'ovm_sequencer_utils_end
// new - constructor
function new (string name, ovm_component parent);
super.new(name, parent);
'ovm_update_sequence_lib_and_item(dut_transfer
)
endfunction : new // assign_vi
function void assign_vi(virtual interface dut_if xmi);
this.xmi = xmi; endfunction
endclass : dut_prt4_master_sequencer
class prt4_seq extends ovm_sequence
#(dut transfer);
parameter SET = 1’b1; parameter CLR = 1’b0; parameter TRISTATE = 1’bz; parameter H_AA = ’haa; parameter H_55 = ’h55;
function new(string name="prt4_seq");
super.new(name); endfunction : new
'ovm_sequence_utils(prt4_seq,
dut_prt4_master_sequencer)
prt4_set_pd1_seq prt4_set_pd1_seq0; prt4_set_all_seq prt4_set_all_seq0;
virtual task body();
p_sequencer.ovm_report_info(get_type_name(), $psprintf("%s starting...", get_sequence_path()), OVM_MEDIUM);
// 1. CLEAR PORTD[0] BIT 'ovm_do_with(prt4_set_pd1_seq0,
{ prt4_set_pd1_seq0.temp == CLR; prt4_set_pd1_seq0.setup_del == 48; prt4_set_pd1_seq0.hold_del == 7; } )
// 2. SET PORTD[0] BIT 'ovm_do_with(prt4_set_pd1_seq0,
{ prt4_set_pd1_seq0.temp == SET; prt4_set_pd1_seq0.setup_del == 0; prt4_set_pd1_seq0.hold_del == 20;} )
// 3. CLEAR ALL PORTS 'ovm_do_with(prt4_set_all_seq0,
{ prt4_set_all_seq0.temp == {8{CLR}}; prt4_set_all_seq0.hold_del == 35; } )
// 4. SET ALL PORTS 'ovm_do_with(prt4_set_all_seq0,
{ prt4_set_all_seq0.temp == {8{SET}}; prt4_set_all_seq0.hold_del == 35; } )
// 5. SET ALL PORTS IN 0xAA 'ovm_do_with(prt4_set_all_seq0,
{ prt4_set_all_seq0.temp == H_AA;
prt4_set_all_seq0.hold_del == 35;} )
// 6. SET ALL PORTS IN 0x55 'ovm_do_with(prt4_set_all_seq0,
{ prt4_set_all_seq0.temp == H_55;
prt4_set_all_seq0.hold_del == 21;} )
// 7. PD1 = 1, SET TRISTATE ON ALL PORTS 'ovm_do_with(prt4_set_pd1_seq0,
{ prt4_set_pd1_seq0.temp == SET; prt4_set_pd1_seq0.setup_del == 0; prt4_set_pd1_seq0.hold_del == 20;} )
endtask : body
endclass : prt4_seq
В классе prt4_seq создается последовательность данных 1-7, подаваемых на порт, и сопровождаемых заданием требуемых значений переменных setup_del и hold_del, из которых первая переменная отвечает за задержку на определенное количество тактов подачи данных на порт, а вторая представляет собой количество тактов, в течение которых необходимо удерживать требуемые данные.
В данном тесте монитор, обычно входящий в состав компонента OVC, не выполняет никаких функций, поэтому его описание не приводиться.
class dut_prt4_master_driver extends
ovm_driver #(dut_transfer);
parameter TRISTATE = 1’bz;
// The virtual interface used to drive and view HDL signals.
protected virtual dut_if xmi;
// Master Id protected int master_id;
// Provide implmentations of virtual methods such as get_type_name and create
Sovm_component_utils_begin(dut_prt4_master_dri
ver)
'ovm_field_int(master_id, OVM_ALL_ON) Sovm_component_utils_end
// new - constructor
function new (string name, ovm_component parent);
super.new(name, parent); endfunction : new
// assign_vi
function void assign_vi(virtual interface dut_if xmi);
this.xmi = xmi; endfunction : assign_vi
// run phase virtual task run(); fork
get_and_drive(); reset_signals(); join endtask : run
// get_and_drive
virtual protected task get_and_drive(); @(negedge xmi.reset);
@(posedge xmi.reset); forever begin
@(posedge xmi.clk_in); seq_item_port.get_next_item(req); $cast(rsp, req.clone()); rsp.set_id_info(req); drive_transfer(rsp); seq_item_port.item_done(rsp); end
endtask : get_and_drive // reset_signals
virtual protected task reset_signals(); forever begin
@(posedge xmi.reset); xmi.reg_port_a <= {8{TRISTATE}};
end
endtask : reset_signals // drive_transfer
virtual protected task drive_transfer (dut_transfer trans);
if (trans.setup_delay > 0) begin
repeat(trans.setup_delay) @(posedge
xmi.clk_in); end
repeat(trans.hold_delay - 1) @(posedge
xmi.clk_in) drive_data(trans); endtask : drive_transfer
// drive_address_phase
virtual protected task drive_data
(dut_transfer trans);
// xmi.reg_port_a <= trans.port_a;
if(trans.port_a[0] || !trans.port_a[0])
xmi.reg_port_a[0] <= trans.port_a[0]; else xmi.reg_port_a[0] <= 1’bz; if(trans.port_a[1] || !trans.port_a[1] )
xmi.reg_port_a[1] <= trans.port_a[1];
else xmi.reg_port_a[l] <= l’bz; if(trans.port_a[2] II !trans.port_a[2] )
xmi.reg_port_a[2] <= trans.port_a[2];
endtask : drive_data
endclass : dut_prt4_master_driver
Класс драйвера содержит две процедуры: get_and_drive и reset_signals. Процедура get_and_drive обеспечивает получение транзакции от генератора транзакций (sequencer), вызов процедуры drive_transfer и передачу отклика генератору транзакций. Процедура drive_transfer выполняет задержку процедуры drive_data на setup_delay циклов и выполняет эту процедуру в течение hold_delay циклов. Процедура drive_data выполняет преобразование транзакции в сигналы, подаваемые на тестируемую модель.
Инициализация трех классов - драйвера, монитора, генератора транзакций, а также коммутация драйвера и монитора осуществлены в классе агента, описание которого приведено ниже:
class dut_prt4_master_agent extends ovm_agent;
ovm_blocking_put_port #(test_cmp_err)
put_port_tce;
protected virtual dut_if xi;
protected ovm_active_passive_enum is_active = OVM_ACTIVE;
protected int master_id;
dut_prt4_master_monitor monitor;
dut_prt4_master_driver driver;
dut_prt4_master_sequencer sequencer;
// build
function void build(); super.build();
monitor =
dut_prt4_master_monitor::type_id::create("moni tor", this);
if(is_active == OVM_ACTIVE) begin
sequencer = dut_prt4_master_sequencer ::type_id::create("sequencer", this);
driver =
dut_prt4_master_driver::type_id::create("drive r", this); end
endfunction : build
function void connect(); moni-
tor.put_port_tce.connect(put_port_tce); if(is_active == OVM_ACTIVE) begin driv-
er.seq_item_port.connect(sequencer.seq_item_ex
port);
end
endfunction : connect
// assign the virtual interfaces of the agent’s children
function void assign_vi(virtual interface dut_if xmi); xi = xmi;
if (is_active == OVM_ACTIVE) begin sequencer.assign_vi(xmi); driver.assign_vi(xmi); monitor.assign_vi(xmi);
end
endfunction : assign_vi endclass : dut_prt4_master_agent
В состав компонента OVC также входит класс bus_monitor, отвечающий, для данного теста, за контроль состояния статуса теста:
class dut_prt4_bus_monitor extends
ovm_monitor;
ovm_blocking_put_port #(test_done)
put_port_td;
// The virtual interface used to view HDL signals.
protected virtual dut_if xbmi; protected int done = 0; test_done td;
// The following two bits are used to control whether checks and coverage are
// test_done both in the bus monitor class and the interface.
bit checks_enable = 0;
parameter logic [7:0] TE ST_PAS SED = 8’b01110111;
parameter logic [7:0] TEST_FAILED = 8’b11110001;
// Assign the virtual interface variable function void assign_vi(virtual interface dut_if xi);
xbmi = xi; endfunction
// run phase task run(); fork
td = new();
observe_end_of_test(); join endtask : run
task observe_end_of_test(); forever begin
@(posedge xbmi.clk_in);
if(((xbmi.port_b == TEST_FAILED) ||
(xbmi.port_b == TEST_PASSED)) && !done) begin done = 1; td.set();
put_port_td.put(td);
end
end
endtask : observe_end_of_test endclass : dut_prt4_bus_monitor
В заключении созданы классы компонента OVC - dut_env, тестбенча - dut_tb и библиотеки тестов test_lib. В первом создаются экземпляры агента и монитора шины (bus_monitor), во втором создается экземпляр компонента OVC - класса dut_env. Библиотека тестовых классов состоит из базового класса и класса, производного от базового, относящегося непосредственно к тому или иному тесту.
class dut_base_test extends ovm_test; Sovm_component_utils(dut_base_test)
ovm_table_printer printer;
tlm_fifo #(test_done) ff_td; tlm_fifo #(test_cmp_err) ff_tce;
test_done td; test_cmp_err tce;
string test_name; string test_info;
reg [7:0] TEST_FAILED_1; reg [7:0] TEST_PASSED;
integer testlogfile; task check_status_test();
@(negedge dut_tb_top.xi0.reset);
@(posedge dut_tb_top.xi0.reset); forever begin
@(posedge dut_tb_top.xi0.clk_in); begin
dut_tb_top.xi0.counter++;
if(ff_tce.try_get(tce) &&
tce.compare_error == 1) begin
test_info = {test_name, " FAILED:"}; ovm_report_info(get_type_name(),
test_info, OVM_LOW);
$fdisplay(testlogfile, test_info); if(tce.port_a == 1) begin
ovm_report_info(get_type_name(), " > PORT_A COMPARE ERROR", OVM_LOW);
$fdisplay(testlogfile, " > PORT_A
COMPARE ERROR");
end
global_stop_request();
end
if(ff_td.try_get(td) && td.done == 1) begin
if((dut_tb_top.xi0.port_b ==
TEST_FAILED_1) test_info = {test_name, "
FAILED"};
else if(dut_tb_top.xi0.port_b ==
TEST_PASSED) test_info = {test_name, "
PASSED"};
else test_info = {test_name, "
PASSED, END_FLAG NOT FOUND"};
$fdisplay(testlogfile, test_info); ovm_report_info(get_type_name(),
test_info, OVM_LOW);
global_stop_request();
end
end
end
endtask
task run();
testlogfile = $fopen("tests.log", "a"); td = new(); tce = new(); check_status_test(); endtask : run
endclass : dut_base_test
class test_port_4 extends dut_base_test; Sovm_component_utils(test_port_4) dut_prt4_tb dut_prt4_tb0;
function new(string name = "test_port_4", ovm_component parent=null);
super.new(name,parent); endfunction : new
virtual function void build();
super.build();
TEST_FAILED_1 = ’hF1;
TEST_PASSED = ’h77;
test_name = "TEST_PORT_4";
dut_tb_top.xi0.test_name = test_name;
// Create the tb
dut_prt4_tb0 =
dut_prt4_tb::type_id::create("dut_prt4_tb0", this);
// Set the default sequence for the master
set_config_string("dut_prt4_tb0.dut_env_prt4.m aster.sequencer",
"default_sequence", "prt4_seq"); endfunction : build
function void connect();
dut_prt4_tb0.put_port_td.connect(ff_td.blockin
g_put_export);
dut_prt4_tb0.put_port_tce.connect(ff_tce.block
ing_put_export);
endfunction : connect endclass : test_port_4
Тестовый библиотечный класс (в данном случае - test_port_4) присваивает переменныем TEST_PASSED и TEST_FAILED требуемые значения, выбирает требуемую последовательность транзакций из библиотеки, создает экземпляр тест-бенча dut_tb.
Для других тестов разрабатываются соответствующие компоненты OVC, а также соответствующие модификации базового теста в библиотеке тестов. В итоге получен готовый состав верификационного окружения, разработанного на базе методологии OVM.
Для выполнения функционально-логической верификации используем приложение IRUN для запуска симулятора ncsim, входящий в состав пакета Incisive Enterprise Simulator САПР ф. Cadence. Запуск приложения IRUN осуществляем следующей командой:
irun \
-64bit \
-assert -sv \
-access r \
-v93 \
-f cmp_files.f \
-f $TEST_PATH/compile_ius.f \
+incdir+/misc/cadence/incisiv92/IUS92/tools/ov m/src \
-gui
Файл compile_ius.f содержит имя запускаемого теста из файла библиотеки тестов и имя модуля верхнего уровня:
mavr_tb_top.sv
+OVM_TESTNAME=test_port_4
+OVM_VERBOSITY=OVM_LOW
-ovm
-q
На рис. 2 представлен результат моделирования теста портов ввода-вывода.
л 1u ° fc x I"® I***! *• ^
Search Names Signal ▼ a № Search Times: | Value w\\~ Q
TimeA » - 1676,413.653Щ fs * kHis- a ^ ^ § DO 676,440,000,000fs . 7 Ш
Ш ft; Baseline ▼« 676,440,000,000fs u I rr Cursor - Baseline » «-26,346,916fs
00,000fs |671,000,00Q,000fs |672,000,Q00,000fs |673,000,000,000fs
#• s',mto лm чШа- so
Time: gft 1670,360,449,215fS
Baseline - 676,440,000,OOOfs I TimeA-- 676,413,653,084fs I
I E) PORTA 'h FF
1 a portb 'h 88
1 0 PORTC •h rr
E ] fe* PORTD •h FF
PORTD[7J H
»* PORTDp] И
Ш* PORTD|5J И
B»P0RTD(4] H
PORTDPl К
W* PORTD|2] н
П* PORTDPl 1
PORTDPl и
E ] %♦ PORTE ■h гг
E ] PORTF •h FF
E ] %* PORTG 'h IF
■41 RESET 1
НИ XTAL1 1
E ] instructon_code_reg 'h CFFF
E ' : ■h 0079
FF *00 \rr I** 155 I rr j]
n Xoo І FF ЇЛА X 55
4 FF jl 00 1 rr I” і rr l|
— FF In FF і:™ Л» FF
ішшшшіи
тшжшжат шшшг^ттшпжш-пшшшжш^штттж^ v.-A'.-ii'. ;. °°=»
Ті RZU*
0 objects selected
Рис. 2. Результат моделирования портов ввода-вывода
На временной диаграмме отображена подача различных состояний на порты ввода-вывода, в конце теста на порту В появляется значение 0x88 -статус успешного прохождения теста.
Применение методологии ОУМ позволило осуществлять тестирование на системном уровне, благодаря выполнению моделирования на уровне транзакций (ТЬМ), а также обеспечило возможность оптимизировать время разработки верификационного окружения за счет легкости модификации копии готового компонента ОУС при адаптации ее под соответствующий разрабатываемый тест.
Заключение. *При тестировании разрабатываемого отечественного 8-разрядного микроконтроллера внедрена ОУМ методология для верификации ЯТЬ-моделей ядра и периферийных компонентов микроконтроллера.
*Применение методологии OVM позволило оптимизировать время, затрачиваемое на разработку верификационного окружения.
*Применение методологии OVM позволило осуществлять тестирование RTL-модели на системном уровне.
Литература
1. Новожилов Е.Е Формальные методы верификации RTL-моделей сверхбольших интегральных схем. -Программные продукты и системы, №4, 2008
2. Я.С. Губенко, А.С. Камкин, М.М. Чупилко Сравнительный анализ современных технологий разработки тестов для моделей аппаратного обеспечения. - Труды Института системного программирования РАН
3. OVM User guide, version 2.1.1, March 2011
4. OVM Class Reference, version 2.1.1, March 2010
Воронежский государственный технический университет ФГУП НИИ электронной техники, г. Воронеж
DESIGN OF TEST ENVIRONMENT FOR FUNCTIONAL-LOGIC VERIFICATION BASED ON
THE OVM METODOLOGY
Y.A. Shkondin
The system of functional tests based on OVM methodology for functional-logic verification RTL models of core and some peripheral components was designed
Key words: OVM methodology, 8-bit microcontroller, functional-logic verification
138