Неожиданное поведение с указанием силы внутри задачи интерфейса - PullRequest
1 голос
/ 01 апреля 2019

Я вижу побочные эффекты других несвязанных сигналов, которые затрагиваются, когда я использую силу внутри задачи.В приведенном ниже примере я пытаюсь принудительно установить 2 независимые переменные «a» и «b» внутри модуля «dut».Для этого я использую вспомогательную задачу «force1» внутри интерфейса «intf».Однако я считаю, что изменение «b» также приводит к изменению «a», как показано в выходных данных.

Контрольный пример на edaplayground.https://www.edaplayground.com/x/23LM


    module dut(intf i1);
        logic a;
        logic b;
    endmodule
    interface intf;
       task force1(bit sel, int value);
         if(sel == 0) begin
            $display("[%0t]:forcing a to %0d", $stime, value);
            force dut1.a = value;
        end
        else begin
            $display("[%0t]:forcing b to %0d", $stime, value);
            force dut1.b = value;
        end
       endtask
    endinterface
    module test();
       intf intf1();
       dut dut1(intf1);
       always@(dut1.a) begin
           $display("[%0t]:Changing value of a=%0d", $stime, dut1.a);
       end
       always@(dut1.b) begin
           $display("[%0t]:Changing value of b=%0d", $stime, dut1.b);
       end
       initial begin
            intf1.force1(.sel(0), .value(1));// Change value of a to 1
            #10;
            intf1.force1(.sel(1), .value(0));// Change value of b to 0
            #10;
            $finish;
        end
    endmodule

[0]:forcing a to 1
[0]:Changing value of a=1
[10]:forcing b to 0
[10]:Changing value of a=0     ----------> WHY DID THIS CHANGE?
[10]:Changing value of b=0

I expected the output 'a' not to change to 0.

1 Ответ

2 голосов
/ 01 апреля 2019

Проблема в том, что value является статической переменной. Когда вы объявляете задачу в Verilog, если вы не укажете задачу равной automatic, все переменные в задаче будут статическими, то есть каждый вызов задачи, которая изменяет переменную, делает это для всех вызовов этой задачи (например, создание статической локальной переменной в C).

Также важно отметить, что процедурные присвоения force не только разрешают RHS и устанавливают LHS на это значение, но вместо этого вынуждают LHS устанавливать выражение в RHS. Таким образом, назначение типа force A = B; сделает A равным B в момент применения force, а также в любое время, когда B может быть обновлено после. Поместив это вместе с информацией выше (value является статическим), вы не устанавливаете dut1.a равным 1 с вашим force, но устанавливаете значение value. Как только value изменится при следующем вызове вашей задачи, dut1.a также изменится в соответствии с ним.

Теперь, к сожалению, вы не можете просто сделать задачу automatic или просто сделать value automatic для решения проблемы, поскольку force требует статического выражения (т. Е. Выражения только статических переменных или констант) для Работа. Одним из решений является создание статического заполнителя для значений, которые вы хотите, который отключает ваш force от ввода вашей задачи value; Вы можете сделать это с массивом:

task force1(bit sel, int value);
  static int values[1 << $bits(sel)]; // <- Make sure no matter the width of sel, there are enough places in the array, could just be values[2]
  values[sel] = value;
  if(sel == 0) begin
    $display("[%0t]:forcing a to %0d", $stime, value);
    force dut1.a = values[0];
  end
  else begin
    $display("[%0t]:forcing b to %0d", $stime, value);
    force dut1.b = values[1];
  end
endtask
...