Ошибка UVM при использовании нескольких секвенсоров с использованием конструкции l oop - PullRequest
0 голосов
/ 14 июля 2020

У меня есть что-то вроде следующего кода в теле моей виртуальной последовательности UVM:

begin:
  for(int x=0; x<8; x++) begin
    
    fork begin
      automatic int x_idx = x;
        for(int i=0; i<100; i++) begin
          if(!my_sequence[x_idx].randomize() with {...}
          my_sequence[x_idx].start(p_sequencer.my_sequencer[x_idx];
        end
    end join_none
  end
end

Информация о коде:

  1. У меня есть 8 секвенсоров, каждый из которых получает свою собственную последовательность. Отсюда первое «for l oop» с 8 итерациями.
  2. После изучения некоторых руководств я понял, что с помощью fork-join я могу запустить 8 последовательностей на 8 секвенсоров параллельно.

Но когда я запускаю код, я получаю ошибку в строке кода «if (! My_sequence ...». Ошибка:

The object is being used before it was constructed/allocated.

Я также протестировал код, избавившись от external для l oop и вместо этого использует следующие номера индексов:

    fork begin
      automatic int x_idx = x;
        for(int i=0; i<100; i++) begin
          if(!my_sequence[0].randomize() with {...}
          my_sequence[0].start(p_sequencer.my_sequencer[0];
        end
    end join_none

    fork begin
      automatic int x_idx = x;
        for(int i=0; i<100; i++) begin
          if(!my_sequence[0].randomize() with {...}
          my_sequence[1].start(p_sequencer.my_sequencer[1];
        end
    end join_none
    ...

Кажется, это работает. Но я хочу написать лучший код для l oop.

Другая информация : Во время отладки с использованием DVE я увидел, что значение x_idx равно 8. Не уверен, почему оно отображается как 8, а также не уверен, что это причина ошибки.

1 Ответ

1 голос
/ 14 июля 2020

Ваша проблема в том, что вы разместили объявление x_idx внутри блока begin/end, который находится внутри fork/join_none. Вы не хотите, чтобы инициализация происходила, когда параллельные потоки начинают выполняться; вы хотите, чтобы это происходило при выполнении каждой итерации for l oop. Вы должны записать его как

begin
  for(int x=0; x<8; x++)
    fork
      int x_idx = x;
      for(int i=0; i<100; i++) begin
         if(!my_sequence[x_idx].randomize() with {...}
         my_sequence[x_idx].start(p_sequencer.my_sequencer[x_idx];
      end
   join_none
end

Кроме того, нет необходимости использовать ключевое слово automatic внутри класса - все переменные, объявленные внутри метода класса, имеют неявное автоматическое c время жизни.

Обратите внимание, что объявления внутри fork / join инициализируются при попадании в блок fork, а не когда операторы внутри fork начинают свои потоки. Объявления не являются отдельными потоками. Вы также можете записать как:

begin
  for(int x=0; x<8; x++) begin
    int x_idx = x;
    fork
      for(int i=0; i<100; i++) begin
         if(!my_sequence[x_idx].randomize() with {...}
         my_sequence[x_idx].start(p_sequencer.my_sequencer[x_idx];
      end
   join_none
  end
end

В обоих случаях существует новый экземпляр x_idx для каждой l oop итерации, но операторы внутри fork/join_none не начинают выполняться до тех пор, пока после все итерации завершены.

...