
1 module bnbasm (/*AUTOARG*/ 2 // Outputs 3 q1, q2, 4 // Inputs 5 clk_osc 6 ) ; 7 input clk_osc; 8 output [7:0] q1,q2; 9 10 reg [7:0] q1,q2; 11 always @(posedge clk_osc) 12 begin 13 q1=q1+8'd1; 14 q2=q1; 15 end 16 endmodule //
這段代碼綜合出的RTL模型為:
將過程塊中的賦值語句改成非阻塞賦值:

1 always @(posedge clk_osc) 2 begin 3 q1<=q1+8'd1; 4 q2<=q1; 5 end
則綜合出來的RTL模型為:

阻塞語句和非阻塞語句的認識是教科書上的:阻塞賦值語句在所在的塊中是按從上到下執行,而非阻塞賦值為並發執行。難理解的地方在於阻塞賦值的“從上到下執行”,這個說法很容易會被理解成時間上的先后順序,會認為這些賦值語句之前會有延時存在。但是這個延時是指的什么延時,怎么安排的這些延時,會往這方面去想,覺得哪里都不合理,因此會產生疑惑。
仔細觀察兩個RTL模型,就感覺恍然大悟,原來阻塞賦值的“從上到下執行”是通過空間邏輯結構來實現的,延時什么的根本跟這個沒有關系。
至於通常的說法“組合邏輯使用阻塞賦值,時序邏輯使用非阻塞幅值”並不是准確的。阻塞賦值跟非阻塞賦值的混用也有可能會是設計的需要,至於Quartus里面對兩種賦值混用的報警,設計者應該檢查下是不是無意的行為,因為這個可能是會導致意外的結果的。
注:初學verilog的時候沒有多關注這些小細節,沒有多使用RTL viewer這些有用的工具,以后還是要多補補課啊。
《Verilog HDL 應用程序設計實例精講》是一本好書啊,感覺比夏宇聞的那本入門書好多了。