Пример счетчика
Рассмотрим пример небольшого устройства - счетчика, на Verilog- и SystemC-моделях которого мы будем иллюстрировать основные шаги разработки тестов. Интерфейс счетчика состоит из двух двоичных входов inc и rst и одного целочисленного выходного регистра cnt.
Рис. 4.Схема входов и выходов счетчика.
В ответ на фронт сигнала inc, устройство увеличивает содержимое регистра cnt на единицу, на фронт rst - обнуляет регистр cnt. Срезы сигналов не обрабатываются. Для упрощения спецификации и тестирования будем считать, что поведение устройства при одновременном возникновении фронтов сигналов на обоих входах не определено.
Рассмотрим спецификацию счетчика на языке SeC. Спецификационная модель данных включает в себя текущие значения входных сигналов inc и rst, а также выходного регистра cnt:
Если в тесте есть тестовое воздействие, включающее фронт (срез) некоторого сигнала, то в нем должно присутствовать тестовое воздействие, включающее срез (фронт) этого сигнала. // спецификационная модель данных счетчика typedef struct { bool inc; // текущее значение сигнала // на входе inc bool rst; // текущее значение сигнала // на входе rst int cnt; // текущее значение регистра cnt } Model;
Спецификационные функции описывают поведение устройства в ответ на фронты и срезы сигналов inc и rst. Ниже приводится спецификационная функция inc_posedge_spec, описывающая реакцию на фронт сигнала на входе inc. Остальные функции определяются аналогичным образом. // спецификация реакции на фронт сигнала на входе inc specification void inc_posedge_spec(Model *model) updates cnt = model->cnt, inc = model->inc { pre { return model != NULL && inc == false && cnt < INT_MAX; } coverage C { return {single, "Single branch"}; } post { return inc == true && cnt == @cnt + 1; } }
Рассмотрим сценарий тестирования счетчика. В качестве состояния конечного автомата для нашего примера будем просто использовать состояние спецификационной модели, то есть текущие значения входных сигналов inc и rst, а также выходного регистра cnt.
В этом случае функция вычисления состояния конечного автомата будет выглядеть как показано ниже.
static List* scenario_state() { List* list = create_List(&type_Integer);
append_List(list, create_Integer(model.inc)); append List(list, create Integer(model.rst)); append List(list, create Integer(model.cnt));
return list; }
Чтобы ограничить число состояний конечного автомата, запретим подачу фронта inc в состояниях, в которых значение регистра cnt больше или равно десяти. Остальные стимулы (фронт rst, срезы inc и rst) сделаем допустимыми во всех достижимых состояниях. В начальном состоянии теста устанавливаем низкие уровни сигналов inc и rst, а значению регистра cnt присваиваем ноль. Ниже приводится сценарная функция для фронта inc. Остальные функции определяются аналогичным образом.
scenario bool inc_posedge_scen() { if(model.cnt < 10) { if(pre_inc_posedge_spec(&model)) inc posedge spec(&model); }
return true; }