iT邦幫忙

2021 iThome 鐵人賽

DAY 9
1
Software Development

verilog or very lag系列 第 9

【Day09】Blocking & Non-Blocking 的差異

Blocking vs Non-Blocking

在寫一般軟體語言時,都與 Verilog 中的 blocking 語句相同,是一行一行由上至下執行的,但 verilog 又有一個 non-blocking,而 non-blocking 則是同步執行的,而撰寫時也要把握以下原則,才不會產生誤用的情形。

  • always 用 clock 觸發的區塊要使用 nonblocking。
  • always 沒有用 clock 觸發(組合邏輯)的區塊要使用 blocking。
  • assign 語句一律使用 blocking。
  • 在同一個 always block 中不可同時出現 nonblocking 及 blocking。

來看下面這個例子

non-blocking:

module blockingVSnonblocking(
  clkSys, 
  rst_n
);
input clkSys;
input rst_n;
reg [1:0]a;
reg [1:0]b;
reg [1:0]c;
always@(posedge clkSys or negedge rst_n)begin
  if(!rst_n)begin
    a <= 2'd1;
    b <= 2'd2;
    c <= 2'd3;
  end
  else begin
    a <= c;
    b <= a;
    c <= b;
  end
end
endmodule

testbench:

`timescale 10ns/1ns
module tb();
reg clkSys;
reg rst_n;

blockingVSnonblocking UUT(
  .clkSys(clkSys), 
  .rst_n(rst_n)
);

initial begin
  clkSys = 0;
  rst_n = 0;
  repeat(3)@(posedge clkSys)rst_n = 0;
  rst_n = 1;
  #100 $stop;
end

always #5 clkSys = ~clkSys;

endmodule

上方的執行結果會是

reset 後,clk 正緣來臨時,程式會同步的執行,所以 {a, b, c} 的值會同步到 {c, b, a} 。


blocking:

module blockingVSnonblocking(
  clkSys, 
  rst_n
);
input clkSys;
input rst_n;
reg [1:0]a;
reg [1:0]b;
reg [1:0]c;
always@(*)begin
  if(!rst_n)begin
    a = 2'd1;
    b = 2'd2;
    c = 2'd3;
  end
  else begin
    a = c;
    b = a;
    c = b;
  end
end
endmodule

而上方的執行結果則會是

可以看出 {a, b, c} 最後都變成了 2'd3,這就是使用了 non-blocking,使程式變得有順序性,第一行 a=c,導致第二行 b=a 時也等同 b=c 了,最後一行也是如此。


上一篇
【Day08】for 迴圈在硬體的使用及該注意的那些事
下一篇
【Day10】模組化及引用模組
系列文
verilog or very lag30

尚未有邦友留言

立即登入留言