Verilog的Blocking與Non-Blocking

2023-06-09
Verilog

Blocking

blocking assignment 是用 = 將等號右邊的值assign到等號左邊,會照著code的順序一行一行執行下去,但是是在同一個時間平行的執行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module tb;
reg [7:0] a, b, c, d, e;

initial begin
a = 8'hAA;
$display ("1 t:%0d a:0x%x b:0x%x c:0x%x", $time, a, b, c);
b = 8'hBB;
$display ("2 t:%0d a:0x%x b:0x%x c:0x%x", $time, a, b, c);
c = 8'hCC;
$display ("3 t:%0d a:0x%x b:0x%x c:0x%x", $time, a, b, c);
end

initial begin
d = 8'hDD;
$display ("4 t:%0d d:0x%x e:0x%x", $time, d, e);
e = 8'hEE;
$display ("5 t:%0d d:0x%x e:0x%x", $time, d, e);
end
endmodule

例子中有兩個initial block,他們會在simulation開始的時候同時執行

Output

1
2
3
4
5
6
# run 1000
# 1 t:0 a:0xaa b:0xxx c:0xxx
# 2 t:0 a:0xaa b:0xbb c:0xxx
# 3 t:0 a:0xaa b:0xbb c:0xcc
# 4 t:0 d:0xdd e:0xxx
# 5 t:0 d:0xdd e:0xee

上面的例子結果都是在t:0輸出,並照著程式碼的順序執行下來

Non-Blocking

Non-Blocking assignment 是用 <= 將等號右邊的值assign到等號左邊,他不會卡住接下來要執行的程式碼。把上面的code全部改成non-blocking的話:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module tb;
reg [7:0] a, b, c, d, e;

initial begin
a <= 8'hAA;
$display ("1 t:%0d a:0x%x b:0x%x c:0x%x", $time, a, b, c);
b <= 8'hBB;
$display ("2 t:%0d a:0x%x b:0x%x c:0x%x", $time, a, b, c);
c <= 8'hCC;
$display ("3 t:%0d a:0x%x b:0x%x c:0x%x", $time, a, b, c);
#1
$display ("#1 t:%0d a:0x%x b:0x%x c:0x%x", $time, a, b, c);
end

initial begin
d <= 8'hDD;
$display ("4 t:%0d d:0x%x e:0x%x", $time, d, e);
e <= 8'hEE;
$display ("5 t:%0d d:0x%x e:0x%x", $time, d, e);
#1
$display ("#1 t:%0d d:0x%x e:0x%x", $time, d, e);
end
endmodule

執行結果如下:

1
2
3
4
5
6
7
8
# run 1000
# 1 t:0 a:0xxx b:0xxx c:0xxx
# 2 t:0 a:0xxx b:0xxx c:0xxx
# 3 t:0 a:0xxx b:0xxx c:0xxx
# 4 t:0 d:0xxx e:0xxx
# 5 t:0 d:0xxx e:0xxx
#1 t:1 a:0xaa b:0xbb c:0xcc
#1 t:1 d:0xdd e:0xee

上面全部的output都印出”xx”,因為在non-blocking右邊(RHS)的statement會先全部被capture起來然後移動到下一個statement,然後這些右邊的值會等到這個timestamp最後才assign到左邊(LHS)。

再一個例子可以如上面第一個initial blocking,a是在timestamp最後才被assign值,所以第一個display的output中a是unknown值,所以會看見a是在第二個display之後才會是AA,相同的道理b也是在第三個display值才會是BB。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module tb;
reg [7:0] a, b, c, d, e;

initial begin
a <= 8'hAA;
$display ("1 t:%0d a:0x%x b:0x%x c:0x%x", $time, a, b, c);
#10
b <= 8'hBB;
$display ("2 t:%0d a:0x%x b:0x%x c:0x%x", $time, a, b, c);
#10
c <= 8'hCC;
$display ("3 t:%0d a:0x%x b:0x%x c:0x%x", $time, a, b, c);
end

initial begin
d <= 8'hDD;
#5
$display ("4 t:%0d d:0x%x e:0x%x", $time, d, e);
#5
e <= 8'hEE;
$display ("5 t:%0d d:0x%x e:0x%x", $time, d, e);
end
endmodule
1
2
3
4
5
6
# run 1000
# 1 t:0 a:0xxx b:0xxx c:0xxx
# 4 t:5 d:0xdd e:0xxx
# 2 t:10 a:0xaa b:0xxx c:0xxx
# 5 t:10 d:0xdd e:0xxx
# 3 t:20 a:0xaa b:0xbb c:0xxx