Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> Verilog

Блокирующие и неблокирующие назначения в Verilog: ключевые различия

Блокирующие назначения (=)

Блокирующие назначения выполняются с помощью = и выполняются последовательно внутри процедурного блока. Однако это не предотвращает выполнение операторов в параллельных блоках.

module tb;
  reg [7:0] a, b, c, d, e;
  initial begin
    a = 8'hDA;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    b = 8'hF1;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    c = 8'h30;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
  end
  initial begin
    d = 8'hAA;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
    e = 8'h55;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
  end
endmodule

Обратите внимание: два блока initial выполняются параллельно при старте симуляции. Операторы выполняются последовательно в каждом блоке, и оба блока завершаются в 0 нс. Конкретно: a назначается первой, затем $display, затем остальные операторы. Это видно в выводе: в первом $display переменные b и c равны 8'hxx, так как их назначения еще не выполнились.

Simulation Log

ncsim> run
[0] a=0xda b=0xx c=0xx
[0] a=0xda b=0xf1 c=0xx
[0] a=0xda b=0xf1 c=0x30
[0] d=0xaa e=0xx
[0] d=0xaa e=0x55
ncsim: *W,RNQUIE: Simulation is complete.

В следующем примере добавим задержки, чтобы увидеть поведение.

module tb;
  reg [7:0] a, b, c, d, e;
  initial begin
    a = 8'hDA;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    #10 b = 8'hF1;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    c = 8'h30;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
  end
  initial begin
    #5 d = 8'hAA;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
    #5 e = 8'h55;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
  end
endmodule

Simulation Log

ncsim> run
[0] a=0xda b=0xx c=0xx
[5] d=0xaa e=0xx
[10] a=0xda b=0xf1 c=0xx
[10] a=0xda b=0xf1 c=0x30
[10] d=0xaa e=0x55
ncsim: *W,RNQUIE: Simulation is complete.

Неблокирующие назначения (<=)

Неблокирующие назначения позволяют планировать назначения без блокировки выполнения следующих операторов. Обозначаются символом <=. Тот же символ используется как оператор отношения в выражениях и как оператор неблокирующего назначения. Если в первом примере заменить все = на <=, вывод изменится.

module tb;
  reg [7:0] a, b, c, d, e;
  initial begin
    a <= 8'hDA;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    b <= 8'hF1;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    c <= 8'h30;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
  end
  initial begin
    d <= 8'hAA;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
    e <= 8'h55;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
  end
endmodule

Все $display выводят 'h'x. Причина: RHS каждого неблокирующего оператора на данном временном шаге захватывается, затем выполняется следующий оператор. Захваченное значение присваивается LHS только в конце временного шага.

Simulation Log

ncsim> run
[0] a=0xx b=0xx c=0xx
[0] a=0xx b=0xx c=0xx
[0] a=0xx b=0xx c=0xx
[0] d=0xx e=0xx
[0] d=0xx e=0xx
ncsim: *W,RNQUIE: Simulation is complete.

Разбор потока выполнения:

|__ Блок 1: initial
| |___ Время #0ns: a <= 8'DA — неблокирующее, запоминаем RHS (8'hDA), идем дальше
| |___ Время #0ns: $display() — блокирующее, выполняем: a еще не получил значение, a=8'hx
| |___ Время #0ns: b <= 8'F1 — запоминаем RHS (8'hF1), идем дальше
| |___ Время #0ns: $display() — b еще не получил значение, b=8'hx
| |___ Время #0ns: c <= 8'30 — запоминаем RHS (8'h30), идем дальше
| |___ Время #0ns: $display() — c еще не получил значение, c=8'hx
| |___ Конец временного шага: присваиваем захваченные значения a, b, c
|__ Блок 2: initial
| |___ Время #0ns: d <= 8'AA — запоминаем RHS (8'hAA), идем дальше
| |___ Время #0ns: $display() — d еще не получил значение, d=8'hx
| |___ Время #0ns: e <= 8'55 — запоминаем RHS (8'h55), идем дальше
| |___ Время #0ns: $display() — e еще не получил значение, e=8'hx
| |___ Конец временного шага: присваиваем захваченные значения d, e
|__ Конец симуляции в #0ns

Теперь второй пример с задержками, но с неблокирующими назначениями.

module tb;
  reg [7:0] a, b, c, d, e;
  initial begin
    a <= 8'hDA;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    #10 b <= 8'hF1;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    c <= 8'h30;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
  end
  initial begin
    #5 d <= 8'hAA;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
    #5 e <= 8'h55;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
  end
endmodule

Вывод снова отличается от блокирующего варианта.

Simulation Log

ncsim> run
[0] a=0xx b=0xx c=0xx
[5] d=0xx e=0xx
[10] a=0xda b=0xx c=0xx
[10] a=0xda b=0xx c=0xx
[10] d=0xaa e=0xx
ncsim: *W,RNQUIE: Simulation is complete.

Разбор выполнения:

|__ Блок 1 в #0ns: initial
| |___ Время #0ns: a <= 8'DA — запоминаем RHS (8'hDA), идем дальше
| |___ Время #0ns: $display() — a еще не получил значение, a=8'hx
| |___ Конец временного шага: присваиваем a = 8'hDA
| |___ Ждем 10 единиц времени до #10ns
| | |___ Время #10ns: b <= 8'F1 — запоминаем RHS (8'hF1), идем дальше
| |___ Время #10ns: $display() — b еще не получил значение, b=8'hx
| |___ Время #10ns: c <= 8'30 — запоминаем RHS (8'h30), идем дальше
| |___ Время #10ns: $display() — c еще не получил значение, c=8'hx
| |___ Конец временного шага и блока: присваиваем b, c
|__ Блок 2 в #0ns: initial
| |___ Ждем 5 единиц до #5ns
| | |___ Время #5ns: d <= 8'AA — запоминаем RHS (8'hAA), идем дальше
| |___ Время #5ns: $display() — d еще не получил значение, d=8'hx
| |___ Конец временного шага: d = 8'hAA
| |___ Ждем 5 единиц до #10ns
| | |___ Время #10ns: e <= 8'55 — запоминаем RHS (8'h55), идем дальше
| |___ Время #10ns: $display() — e еще не получил значение, e=8'hx
| |___ Конец временного шага и блока: e = 8'h55
|__ Конец симуляции в #10ns

Verilog

  1. Освоение Verilog: полное руководство по проектированию цифровых схем
  2. Освоение конкатенации в Verilog: практическое руководство
  3. Мастерство функций в Verilog для эффективного RTL дизайна
  4. Понимание задач (Tasks) в Verilog: отличия от функций, синтаксис и применение
  5. Генератор тактового сигнала в Verilog: проектирование и реализация
  6. Мастерство математических функций Verilog для эффективного аппаратного дизайна
  7. Мастерство $timeformat в Verilog: точность и контроль отображения времени
  8. Понимание и печать timescale в Verilog в любой области видимости
  9. Работа с файлами в Verilog: открытие, чтение, запись и закрытие
  10. Verilog для начинающих: пример Hello World