Перейти к содержанию
    

Динамическое изменение полей в uvm_sequence/uvm_sequence_item

Всем здравствуйте,

Разбираюсь с UVM. В какой-то момент перешел к "боевому" проекту. Задача следующая:

Нужно передать в GMII порт(-ы) набор Ethernet пакетов. В каждом пакете существуют поля mac destination и mac source. Поле mac source допускается задавать статично на этапе сборки, с этим проблем нет. Я хочу динамически менять поле mac destination. На текущем этапе в классе uvm_sequence_item я состряпал функцию set_dmac (bit [47:0] mac).

Не уверен, что это правильный способ. Да и не слишком удобно - приходится вызывать эту функцию в uvm_sequence, куда, в свою очередь, опять нужно динамически передавать нужный MAC адрес.

Собственно, вопрос: как, с точки зрения UVM, правильно изменять значения в uvm_sequence во время runtime?

ЗЫ. Открыл для себя `uvm_do_with, поэтому часть вопроса снимается)

ЗЗЫ. Пока писал, немного посветлело в голове. Пришел к выводу, что под каждый порт должны создаваться несколько sequence со статичными MAC source. И уже в них передавать MAC destination. Выглядит логично, хотя и очень громоздко

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добрый день.

немного offtop.

А в чём смысл использования UVM? Понятно, что универсальность и всё такое. Но все же.

Чем он лучше ситуации, когда тестовое воздействие берётся из файла и результат сравнивается с опорными значениям.

Или основная идея, что тестовое воздействие создаётся с помощью SystemVerilog и результат сравнения получается в нём же?

Типа не нужно сторонних софтов, а-ля Matlab, VS и других. Но тогда все существующие тестовые воздействия надо на SV переносить.

 Если есть возможность, объясните пожалуйста. 

Спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, Tpeck said:

А в чём смысл использования UVM?

Я буквально недавно начал серьезно погружаться. После того, как разрабатываемое тестовое окружение выросло до неприличных размеров и стало не управляемо и не масштабируемо. Здесь, конечно, есть проблема и кривых рук. Но отлаживать и, самое главное, верифицировать Н-портовый Ethernet коммутатор стало почти физически больно.

От UVM ожидаю получить более-менее структурированное окружение, облегчение описания и проведения наборов тестов, упрощение работы с недетерминированным порядком передачи и задержками в данных. Плюс встроенные инструменты подсчета ошибок, репортов и т.д.

Насколько это всё спасёт и упростит верификацию - пока не знаю, время покажет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 minutes ago, nice_vladi said:

Я буквально недавно начал серьезно погружаться. После того, как разрабатываемое тестовое окружение выросло до неприличных размеров и стало не управляемо и не масштабируемо. Здесь, конечно, есть проблема и кривых рук. Но отлаживать и, самое главное, верифицировать Н-портовый Ethernet коммутатор стало почти физически больно.

А раньше каким образом вы проводили тестирование?

В моих приложениях, по сути, один вход - один выход. Может по-этой причине мне не очевидны преимущества UVM.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 minutes ago, Tpeck said:

А раньше каким образом вы проводили тестирование?

В моих приложениях, по сути, один вход - один выход. Может по-этой причине мне не очевидны преимущества UVM.

Сначала всё в одном модуле лепил. Потом начал выносить в отдельные таски. Последний этап до UVM - собрал некоторое подобие UVM. С внешними классами, интерфейсами и т.д. Посмотрел внимательно, понял, что изобретаю велосипед, и решил попробовать UVM.

Пока решил следующим образом.

В тесте:

for (int i = 0; i < pN_PORTS; i++) begin
  eth_seq[i] = eth_sequence::type_id::create($sformatf("eth_seq[%0d]", i));
  eth_seq[i].randomize();
  eth_seq[i].dmac = pMAC_DST[i];
end
...
eth_seq[i].start(m_env.m_agent[idx].m_sqr);
...

В sequence:

virtual task body();
  frame_h = eth_frame_broad::type_id::create("frame_h");
  start_item(frame_h);
  assert(frame_h.randomize());
  frame_h.set_dmac(dmac);
  finish_item(frame_h);
endtask : body

И внутри самого uvm_sequnce_item:

function set_dmac (bit [47:0] mac);
	this.dmac = mac;
	this.fcs_upd();
endfunction : set_dmac

На мой взгляд, достаточно коряво. Но, в целом, приемлемо. Все изменения будут сделаны в высокоуровневых файлах тестов, в глубь лезть не надо.

В мануалах не нашел ничего интереснее. uvm_config_db более громоздко и менее производительно (основываясь на рекомендациях из док).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, nice_vladi said:

Собственно, вопрос: как, с точки зрения UVM, правильно изменять значения в uvm_sequence во время runtime?

Примерно, так :

class x extends uvm_sequence #(y_seq_item);

   `uvm_object_utils(x)
   function new (string name="x");
     super.new(name);
   endfunction : new

   y_seq_item req;

   task body;

     req = y_seq_item::type_id::create("req");

    forever begin

       start_item(req);

       // присваиваем значения полям

       finish_item(req);

    end

  endtask : body

endclass : x

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 7/14/2021 at 1:24 PM, nice_vladi said:

Собственно, вопрос: как, с точки зрения UVM, правильно изменять значения в uvm_sequence во время runtime?

Лучше переделать uvm_sequence. В принципе, вы можете получить handle к sequence'у через sequencer. Но лучше переделать код так, чтобы необходимое вам поле было  в uvm_sequence_item'е.

uvm_sequence_item передаётся по ссылке. Поэтому, изменения в них надо делать аккуратно. Т.е. если какие-то модули расчитывают на исходные данные, а вы их поменяли, у вас будут проблемы. В этом случае uvm_sequence_item можно скопировать (если это приемлемое решение).

Изменено пользователем one_eight_seven

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 7/14/2021 at 2:37 PM, nice_vladi said:

На мой взгляд, достаточно коряво. Но, в целом, приемлемо

Если от поля dmac ничего не зависит, то приемлемо.
Если от этого поля зависят другие поля при рандомизации, то лучше его ограничить на момент рандомизации, ну или, если оно вам нужно фиксированным, а не рандомизированным (как в примере), то можно задать его значение перед рандомизацией, а саму рандомизацию этого поля - отключить:
 

class_object.variable_name.rand_mode( 0 );

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...