(原創) 深入探討blocking與nonblocking (SOC) (Verilog)
Abstract
Verilog雖然是個語法簡單的語言,但是blocking與nonblocking卻是大家學習Verilog時永遠的痛,即時是很資深的IC Designer,也未必完全搞清楚兩者的差異,本文試著以simulator與synthesizer的角度去探討之。
Introduction
使用環境:NC-Verilog 5.4 + Debussy 5.4 v9 + Quartus II 7.2
軟體的語言都是一行一行依序執行,這與Verilog的blocking觀念一樣,但偏偏Verilog還有個nonblocking,而且在寫同步電路時,還一定得用nonblocking寫,到底blocking與nonblocking有什麼不同呢?我在(筆記)如何使用blocking與nonblocking assignment? (SOC) (Verilog)這篇討論過幾個簡單的原則,基本上只要依照這幾個原則去寫RTL,就能保證simulation的與synthesis的結果一致,但當時我並沒有討論其原因,只是將規則背下來而已。
在正式討論之前,請各位先做個小測驗,考驗您的觀念是否正確:
blocking.v / Verilog
2 (C) OOMusou 2010 http://oomusou.cnblogs.com
3
4 Filename : blocking.v
5 Simulator : NC-Verilog 5.4
6 Description : blocking assignment in always block
7 Release : Jul/30/2010 1.0
8 */
9
10 module blocking (
11 clk,
12 rst_n,
13 a_i,
14 b_i,
15 a_o,
16 b_o
17 );
18
19 input clk;
20 input rst_n;
21 input a_i;
22 input b_i;
23 output a_o;
24 output b_o;
25
26 reg a;
27 reg b;
28
29 assign a_o = a;
30 assign b_o = b;
31
32 always@(posedge clk or negedge rst_n) begin
33 if (~rst_n) begin
34 a = a_i;
35 b = b_i;
36 end
37 else begin
38 a = b;
39 b = a;
40 end
41 end
42
43 endmodule
blocking_tb.v / Verilog
2 (C) OOMusou 2010 http://oomusou.cnblogs.com
3
4 Filename : blocking_tb.v
5 Simulator : NC-Verilog 5.4
6 Description : testbench of blocking assignment in always block
7 Release : Jul/30/2010 1.0
8 */
9
10 `include "blocking.v"
11
12 module blocking_tb;
13
14 reg clk;
15 reg rst_n;
16 reg a_i;
17 reg b_i;
18 wire a_o;
19 wire b_o;
20
21 initial begin
22 clk = 1'b0;
23 rst_n = 1'b0;
24 a_i = 1'b1;
25 b_i = 1'b0;
26 #5;
27 rst_n = 1'b1;
28 #100;
29 $finish;
30 end
31
32 always #10 clk = ~clk;
33
34 initial begin
35 $fsdbDumpfile("blocking.fsdb");
36 $fsdbDumpvars(0, blocking_tb);
37 end
38
39 blocking blocking_0 (
40 .clk(clk),
41 .rst_n(rst_n),
42 .a_i(a_i),
43 .b_i(b_i),
44 .a_o(a_o),
45 .b_o(b_o)
46 );
47
48 endmodule
nonblocking.v / Verilog
2 (C) OOMusou 2010 http://oomusou.cnblogs.com
3
4 Filename : nonblocking.v
5 Simulator : NC-Verilog 5.4
6 Description : nonblocking assignment in always block
7 Release : Jul/30/2010 1.0
8 */
9
10 module nonblocking (
11 clk,
12 rst_n,
13 a_i,
14 b_i,
15 a_o,
16 b_o
17 );
18
19 input clk;
20 input rst_n;
21 input a_i;
22 input b_i;
23 output a_o;
24 output b_o;
25
26 reg a;
27 reg b;
28
29 assign a_o = a;
30 assign b_o = b;
31
32 always@(posedge clk or negedge rst_n) begin
33 if (~rst_n) begin
34 a <= a_i;
35 b <= b_i;
36 end
37 else begin
38 a <= b;
39 b <= a;
40 end
41 end
42
43 endmodule
nonblocking_tb.v / Verilog
2 (C) OOMusou 2010 http://oomusou.cnblogs.com
3
4 Filename : nonblocking_tb.v
5 Simulator : NC-Verilog 5.4
6 Description : testbench of nonblocking assignment in always block
7 Release : Jul/30/2010 1.0
8 */
9
10 `include "nonblocking.v"
11
12 module nonblocking_tb;
13
14 reg clk;
15 reg rst_n;
16 reg a_i;
17 reg b_i;
18 wire a_o;
19 wire b_o;
20
21 initial begin
22 clk = 1'b0;
23 rst_n = 1'b0;
24 a_i = 1'b1;
25 b_i = 1'b0;
26 #5;
27 rst_n = 1'b1;
28 #100;
29 $finish;
30 end
31
32 always #10 clk = ~clk;
33
34 initial begin
35 $fsdbDumpfile("nonblocking.fsdb");
36 $fsdbDumpvars(0, nonblocking_tb);
37 end
38
39 nonblocking nonblocking_0 (
40 .clk(clk),
41 .rst_n(rst_n),
42 .a_i(a_i),
43 .b_i(b_i),
44 .a_o(a_o),
45 .b_o(b_o)
46 );
47
48 endmodule
以上為完整的RTL與testbench,其實真正的差異只有以下兩部份,其他部分完全一樣:
1.在always block使用blocking
if (~rst_n) begin
a = a_i;
b = b_i;
end
else begin
a = b;
b = a;
end
end
2.在always block使用nonblocking
if (~rst_n) begin
a <= a_i;
b <= b_i;
end
else begin
a <= b;
b <= a;
end
end
請先把你自己當成simulator,實際模擬一下結果為何。
以下為使用NC-Verilog + Debussy所模擬的結果:
blocking.v
nonblocking.v
你所預期的結果與simulator一樣嗎?
以Simulator角度探討blocking與nonblocking
blocking
if (~rst_n) begin
a = a_i;
b = b_i;
end
else begin
a = b;
b = a;
end
end
先討論較好理解的blocking,所謂的blocking,就是一行程式執行完才能執行下一行,所以在clk rising edge時,先將b的值給a,然後再將a的值給a,也就是說,在clk rising edge之後,a = b = 0,這與C的觀念一樣。
nonblocking
if (~rst_n) begin
a <= a_i;
b <= b_i;
end
else begin
a <= b;
b <= a;
end
end
再來討論nonblocking,在clk rising edge時,a <= b,b <= a,這到底要怎麼理解呢?這必須牽涉到simulator的event queue如何處理這些event。
在討論evnet之前,先解釋兩個專有名詞,RHS與LHS。
RHS:在 = 或 <= 右邊的運算式或變數
LHS:在 = 或 <= 左邊的運算式或變數
由於電腦軟體本身是依序執行(也就是如C一樣程式一行一行的執行),但硬體電路卻可併行執行,simulator是軟體寫的,卻要能夠模擬出硬體電路的的並行執行,也就是如在5 ns時,同時有很多信號被處理,所以才有event queue的概念,將同一個time step要處理的信號放在一個event queue,simulator再依序處理,處理完後再處理下一個time step,這樣就能使依序執行的simulator可以模擬出並行執行的硬體電路。
在IEEE Verilog standard定義了以下的event queue讓simulator廠商實作,至於該如何實作是各廠商的商業機密。
絕大部分的event都會放在Active Events queue內,包括blocking assignments、blocking的RHS、continuous assignments、$display()..等,也就是說當某個time step到達時,會執行Active Events queue的event,但Verilog IEEE standard並沒有保證在Active Events queue內event的執行順序(所以一些不良的coding style可能會造成race condition,這又是另外一個Verilog很惱人的issue,再另闢專文討論),值得注意的是nonblocking的RHS是放在Active Events queue,但沒有包含nonblocking的LHS。
在IEEE standard有定義演算法介紹其他Event queue如何加進Active Events,在這就不多談,這裡的重點是有一個Nonblocking Events queue專門放nonblocking的LHS,會在適當的時機加入Active Events queue執行。
所以由此可知,由於RHS of nonblocking放在Active Events,所以會先執行,之後等在Nonblocking Events queue的LHS of nonblocking進入Active Events queue後再執行。
因此整個nonblocking可視為兩個步驟的行為:
1.在clk rising edge的一開始執行RHS。
2.在clk rising edge快結束時執行LHS。
所以在 a <= b, b <= a時,clk rising edge一開始先執行RHS,也就是a = 1,b = 0,然後再執行LHS,因此a = 0,b = 1,因此nonblocking不會如blocking因為a已經更新了,因而改變了b的值。可以發現,blocking會因為程式的撰寫順序而有不同的值,但nonblocking卻不會因為程式的撰寫順序而有影響,原因是nonblocking的執行是2個步驟,而blocking的執行是1個步驟。
以Synthesizer角度探討blocking與nonblocking
寫Verilog最擔心的是simulation時正常,但synthesis後卻不是你要的,因此我們實際在Quartus II跑看看,看看經過P&R之後,是否與NC-Verilog的結果一樣,並使用RTL Viewer看看Quartus II如何synthesis。
blocking.v
nonblocking.v
除了加上delay外,基本上波形與NC-Verilog所模擬的一樣。
blocking.v
雖然在code中宣告了2個reg,但synthesizer只會合成出1個register,也就是a = b, b = a只delay了1個clk。
nonblocking.v
會合成出2個register,符合我們的預期,也就是 a <= b, b <= a會delay 2個clk。
完整程式碼下載
blocking.7z (NC-Verilog + Debussy)
blocking_quartus_ii.7z (Quartus II)
nonblocking.7z (NC-Verilog + Debussy)
nonblocking_quartus_ii.7z (Quartus II)
Conclusion
本文試著用最淺顯易懂的方式解釋blocking與nonblocking的差異,並從simulator與synthesizer的角度同時去思考,若想得知更完整的資訊,可參考Reference的paper與書籍。
See Also
(筆記)如何使用blocking與nonblocking assignment? (SOC) (Verilog)
(筆記) Cliff Cummings的paper大全 (SOC) (Verilog)
(筆記) $dispaly()、$strobe()、$monitor() 、$fwrite()與blocking / nonblocking的關係 (SOC) (Verilog) (Debussy) (Verdi)
Reference
Clifford E. Cummings 2000, Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kills, Sunburst Design, Inc.
夏宇文 2008, Verilog數字系統設計教程, 北京航空航天大學出版社
(原創) 深入探討blocking與nonblocking (SOC) (Verilog)相关推荐
- (原創) 如何解決DE2_LCM_CCD上下顛倒左右相反與無法設定曝光值的問題? (SOC) (DE2)...
AbstractDE2_LCM_CCD是友晶科技為DE2和其130萬像素CMOS與彩色LCD所寫的範例,但官方的範例會造成上下顛倒左右相反與曝光值無法設定的問題,本文提出解決方式. Introduct ...
- (原創) 如何使用SignalTap II觀察reg與wire值? (SOC) (Verilog) (Quartus II) (SignalTap II)
Abstract 撰寫Verilog時,雖然每個module都會先用ModelSim或Quartus II自帶的simulator仿真過,但真的將每個module合併時,一些不可預期的『run-tim ...
- signature=ae83778c2aa4dd8b9deb3ee108c1263d,何品達多媒體作品發表會含輔助文件《奎》原創作品與註釋...
摘要: <奎>為結合樂器現場演出與即時影音處理的多媒體音樂作品,以宗教信仰與藝術的關聯為發想,將台西溪頂明聖宮魁星爺神像於日治時期遭日人查扣焚燒,歷劫歸來的過程,引申為逆境求生之精神並以多 ...
- (原創) 如何正確的使用迴圈(使用for_each)? (C/C++) (STL) (template)
Abstract之前在(原創) 如何使用for_each() algorithm? (C/C++) (STL) 曾經討論過for_each(),不過當時功力尚淺,只談到了皮毛而已,這次看了effect ...
- (原創) 如何使用ModelSim-Altera對Nios II仿真? (SOC) (Nios II) (SOPC Builder) (ModelSim) (DE2)...
Abstract 在剛學習Nios II時,每次在Run As Nios II Hardware下方,看到Run As Nios II ModelSim就覺得很好奇,Nios II明明是嵌入式系統,怎 ...
- Chris Hadfield現身《ABS 2020》,各方菁英和THORBOT 雷神量化機器人一同進行深入探討
雖然新冠肺炎疫情,在 2020 上半年嚴重衝擊了全球的實體經濟,但這同時也是一個向世界展示區塊鏈技術的重要機會.包括實現無現金社會.醫療物資追蹤,乃至於疫情的資訊共享,THORBOT 雷神量化機器人在 ...
- (原創) Quartus II安裝新觀念:如何將Quartus II安裝在VirtualBox內? (SOC) (Quartus II) (VirtualBox)...
Abstract VM並不是什麼新的觀念,透過VM我們可以在一個OS去執行其他OS,若我們將Quartus II也裝在VM中,將可解決一些長久以來Quartus II使用上所遇到的問題. Introd ...
- Android 4.3安全機制探討
http://www.tshopping.com.tw/thread-232697-1-1.html http://loda.hala01.com/2013/08/android-4-3%E5%AE% ...
- (原創) 如何將編譯結果,統一放在一個目錄下? (SOC) (Quartus II)
Abstract Quartus II預設會將所有檔案都放在project的根目錄下,導致根目錄檔案過多,管理不便,若能將編譯的結果統一放到其他目錄下,將有助於日後管理. Introduction 使 ...
最新文章
- 深入理解PHP原理之变量(Variables inside PHP)
- tomcat源码分析_Tomcat源码分析(一)--Tomcat的初始化
- 代码收藏——js+asp 的屏幕滚动脚本
- Java SE 7、8、9 –推进Java
- pe常用软件_装机不求人之打造自己的全功能PE系统维护优盘
- Codevs 1200 同余方程 2012年NOIP全国联赛提高组
- 计算机时间校对更改原因,计算机时间校准方法
- 《管理学》第十周阶段性回顾
- 微信小程序入门(一)微信小程序注册申请
- 暑期机器学习小组读书报告----机器学习概述
- 使用FFmpeg将一张图片和一段音频转换成视频
- Electron中主进程和渲染进程之间的通信
- 刘强东的“百亿补贴” 被指“雷”声大雨点小
- 中国移动呼叫转移设置
- Java最新面试题100道,包含答案示例(1-10题)
- ClassDiagram类图举例 明 继承图
- 阿里智能语音翻译和科大讯飞(机译)语音翻译的结果对比
- DWI图像 从DICOM Tag识别 b value 的方法
- 苹果虚拟机装vmware tool
- BZOJ 2386: [Ceoi2011]Team
热门文章
- Android 抓包的一些命令 及 adb使用的一些注意事项
- Windows Phone 8初学者开发—第12部分:改进视图模型和示例数据
- 入手一个windows ce系统的可以打电话的HPC,测试在上面发表博客
- python简单爬虫程序分析_[Python专题学习]-python开发简单爬虫
- 利用SoapUI 测试web service的一些问题总结
- Java中PreparedStatement和Statement的用法区别
- 我来谈谈PHP和JAVA在web开发上的的区别
- PO、BO、VO、DTO、POJO、DAO的区别
- Java String,StringBuilder和StringBuffer的区别 StringBuilder StringBuffer String
- (转)Vix_API 操作 VMware