2016-10-25 3 views
0

я шел через SV LRM section 9.3.2 и получил это сомнение, я вставив пример ниже для справкиможет кто-то объяснить fork и loop в системном verilog?

for(int j=1; j <=3; ++j) 
    fork 
     automatic int k = j; 
     begin 
      .... # use k here 
     end 
    join_none 
  • Может кто-нибудь объяснить мне, что на самом деле происходит?

  • Что произойдет, если я переместю переменную automatic за пределы вилки?

    for(int j=1; j <=3; ++j) begin 
        automatic int k = j; 
        fork 
         begin 
          .... # use k here 
         end 
        join_none 
    end 
    
  • Что произойдет, если я переведу петлю внутри вилки?

    fork 
        for(int j=1; j <=3; ++j) begin 
         automatic int k = j; 
         begin 
          .... # use k here 
         end 
        end 
    join_none 
    

Спасибо заранее.

+0

Чтобы получить представление о том, что происходит, модифицирует пример в LRM и запустить моделирование: 'Ок $ записи ("% 0D", к),' 'на # (4-к) $ display ("k:% 0d j:% 0d", k, j); '. Вы заметите, что порядок 'k' является почитанием из примера в LRM и что' j' одинаково в каждом экземпляре. Не существует правильного значения для 'j', поскольку оно не определено для LRM, поэтому разные тренажеры могут отображать другое значение. – Greg

ответ

4

Перемещение автоматической переменной за пределы вилки, но все же внутри блока begin/end петли for имеет такой же эффект. Каждая итерация цикла получает свою локальную копию k, инициализированную текущим значением цикла j. Таким образом, вы получаете три копии k со значениями 1,2 и 3. И каждый процесс, порожденный fork/join_none, привязан к каждой локальной копии k. Поскольку fork/join_none находится внутри цикла, вы создаете три процесса.

Если вы переместите петлю for внутри вилки, вы получите только один процесс, порожденный fork, который имеет петлю. Тогда не имеет значения, используете ли вы j или k, потому что код внутри цикла выполняется последовательно.

0

Эффект 1, 3 будет таким же, и каждый поток fork...join примет правильные значения j (j = 1,2,3 ... все будет принято).

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

Вот пример кода для каждого из ваших случаев.

// Code 1 
for(int j=1; j <=3; ++j) 
    fork 
     automatic int k = j; 
     begin 
      $display("Current Value - %0d", k); 
     end 
    join_none 
    wait_fork; 

// Output of Code 1 
Current Value - 1 
Current Value - 2 
Current Value - 3 

// Code 2 
for(int j=1; j <=3; ++j) 
begin 
    automatic int k = j; 
    fork 
     begin 
      $display("Current Value - %0d", k); 
     end 
    join_none 
end 
wait_fork; 

// Output of Code 2 
Current Value - 3 
Current Value - 3 
Current Value - 3 

// Code 3 
fork 
    for(int j=1; j <=3; ++j) 
     begin 
     automatic int k = j; 
     $display("Current Value - %0d", k); 
     end 
join_none 
wait fork; 

// Output of Code 3 
Current Value - 1 
Current Value - 2 
Current Value - 3 
+0

Ваше наблюдение за кодом 2 противоречит комментарию, который сделал Дейв. Код 1 и код 3 дают тот же результат, мы могли бы не заметить, что код 1 фактически работает в fork, а код 3 работает последовательно. – justrajdeep

+0

Yup, но это выход с инструментом VCS. И я думаю, каждый код откроет потоки и не будет запускаться последовательно. –

Смежные вопросы