2019年6月5日 星期三

Verilog Edge vs. Level, Blocking vs. non-Blocking

edge_blocking


// edge 觸發 會生成 clock 和 flip-flop
// 中間過程的 blocking 運算都循序運行並即刻得出最後的結果
// blocking 的模式表示所有的運算步驟都會在這次 clock tick 之內完成

module edge_blocking(
input clk, x, 
output y);
reg a, b, c, d, e;
assign y = e;
always @ (posedge clk) 
begin
a = x;
b = a;
c = b;
d = c;
e = d; 
end
endmodule


edge_non_blocking
// edge 觸發 會生成 clock 和 flip-flop
// 中間過程的 non-blocking 運算會循序串聯
// 每個 clock 的 edge 會同時對 "<=" 右邊的symbols取值,並賦予"<=" 左邊的 symbols.
// 所以 non-blocking 模式 其實是一種 parallel 模式
// 特徵是 共用一個 clock 訊號,所以一個 tick 只能作動一次

module edge_non_blocking(
input clk, x, 
output y);
reg a, b, c, d, e;
assign y = e;
always @ (posedge clk) 
begin
a <= x;
b <= a;
c <= b;
d <= c;
e <= d; 
end
endmodule




edge_blocking_non_blocking
//  中間 b = a 的 blocking 指令被當作 組合邏輯 短路跳過了
module edge_blocking_non_blocking(
input clk, x, 
output y);
reg a, b, c, d, e;
assign y = e;
always @ (posedge clk) 
begin
a <= x;
b = a;  
c <= b;
d <= c;
e <= d; 
end
endmodule



edge_blocking_non_blocking (2)
module edge_blocking_non_blocking(
input clk, x, 
output y);
reg a, b, c, d, e;
assign y = e;
always @ (posedge clk) 
begin
a <= x;
b = a + 1'b1;
c <= b;
d <= c;
e <= d; 
end
endmodule



level_non_blocking
// level 觸發 不會生成 clock 和 flip-flop
// 中間過程的 non-blocking 運算其實和 blocking 運算 並無差別 
// 等同於 對 wire 做 assign 的效果,是一種組合邏輯的方式
// level 的觸發方式之下,使用 non-blocking 和 blocking 並無差別
// non-blocking 只對於 flip-flop 這種有記憶性,有時間差的線路 才有意義
// 對於 level觸發的 組合邏輯線路,無法做到 non-blocking
// blocking vs. non-blocking 的說法是有點誤導的,應該說是 sequential vs. parallel.
// level 觸發 一律使用 sequential (blocking) 的模式
// edge 觸發 才會使用 clock 和 flip-flop,才會需要區分  sequential (blocking)  和 parallel (non-blocking) 模式。
// 

module level_non_blocking(
input clk, x, 
output y);
reg a, b, c, d, e;
assign y = e;
always @ (*) 
begin
a <= x;
b <= a;
c <= b;
d <= c;
e <= d; 
end
endmodule




level_blocking
module level_blocking(
input clk, x, 
output y);
reg a, b, c, d, e;
assign y = e;
always @ (*) 
begin
a = x;
b = a;
c = b;
d = c;
e = d; 
end
endmodule



level_mixed
// 因為只有對 clk sensitive,所以 clk 會有 latch 的作用
// clk 是 level sensitive ,所以不是使用 flip-flop 的方式製作,而是使用 latch 的模式

module level_mixed(
input Din, clk,
output s3);

reg s1, s2;

always @ (clk)
if (clk)
begin
s1 <= Din;
s2 = s1;
s3 <= s2;
end
endmodule



level_mixed - 2
// 因為只有對 clk sensitive,所以 clk 會有 latch 的作用
// clk 是 level sensitive ,所以不是使用 flip-flop 的方式製作,而是使用 latch 的模式

module level_mixed(
input Din, clk,
output s3);

reg s1, s2;

always @ (clk)
if (clk)
begin
s1 <= Din;
s2 <= s1;
s3 <= s2;
end
endmodule