仿真器角度理解阻塞赋值和非阻塞赋值
|
![clip_image001[6] clip_image001[6]](http://images.cnblogs.com/cnblogs_com/jimix/201212/201212012231442821.gif)
![clip_image003[9] clip_image003[9]](http://images.cnblogs.com/cnblogs_com/jimix/201212/201212012231444249.jpg)
该如何理解上面简单的几行字?
仿真器为了模拟硬件的并行执行,故意分为了一个一个time step,每个time step又是由一系列需要执行的event组成的event queues;仿真器根据调度算法依次执行;
Time step只可以向前执行,不可以倒退
当前time step的event queues中所有event执行完才能继续下一个time step执行;
当所有event queues中都执行完时,仿真器完成执行;
在time t中的任何一个event可以调度time t中的其他event执行,或者另外一个time t+n;
RHS:在 = 或 <= 右邊的運算式或變數
LHS:在 = 或 <= 左邊的運算式或變數
由於電腦軟體本身是依序執行(也就是如C一樣程式一行一行的執行),但硬體電路卻可併行執行,simulator是軟體寫的,卻要能夠模擬出硬體電路的的並行執行,也就是如在5 ns時,同時有很多信號被處理,所以才有event queue的概念,將同一個time step要處理的信號放在一個event queue,simulator再依序處理,處理完後再處理下一個time step,這樣就能使依序執行的simulator可以模擬出並行執行的硬體電路。
在IEEE Verilog standard定義了以下的event queue讓simulator廠商實作,至於該如何實作是各廠商的商業機密。
alt=nonblocking06 title=nonblocking06 border=0 v:shapes="_x0000_i1025">
絕大部分的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,值得注意的是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個步驟。