verilog中的阻塞語句和非阻塞語句什么區別
賦值的類型的選擇取決于建模的邏輯類型 在時序塊的 RTL 代碼中使用非阻塞賦值。
非阻塞賦值在塊結束后才完成賦值操作,此賦值方式可以避免在仿真出現冒險和競爭現象。在組合的 RTL 代碼中使用阻塞賦值。
使用阻塞方式對一個變量進行賦值時,此變量的值在在賦值語句執行完后就立即改變。使用非阻塞賦值方式進行賦值時,各個賦值語句同步執行;因此,通常在一個時鐘沿對臨時變量進行賦值,而在另一個時鐘沿對其進行采樣。
下面的模塊綜合為觸發器,其中采用了阻塞賦值方式:module bloc(clk,a,b); input clk, a; output b; reg b; reg y; always @(posedge clk) begin y=a; b=y; end endmodule 下面的模塊綜合為兩個觸發器 ,其中采用了非阻塞賦值方式:module nonbloc(clk,a,b); input clk, a; output b; reg b; reg y; always @(posedge clk) begin y bend endmodule 上面的兩個例子的綜合的結果不同,左邊的例子使用了阻塞賦值方式,綜合器將其綜合為一個觸發器。右邊的例子使用了非阻塞賦值方式,綜合器將其綜合為兩個觸發器,y 將出現在綜合列表中,作為第二個觸發器的輸入。
非阻塞過程賦值 module swap_vals; reg a, b, clk; initial begin 過程賦值有兩類 a = 0; b = 1; clk = 0; 阻塞過程賦值 end always #5 clk = ~clk; 非阻塞過程賦值 always @( posedge clk) begin a b end endmodule 阻塞過程賦值執行完成后再執行在順序塊內下一條語句。 非阻塞賦值不阻塞過程流,仿真器讀入一條賦值語句并對它進行調度之后, 就可以處理下一條賦值語句。
若過程塊中的所有賦值都是非阻塞的,賦值按兩步進行: 1. 仿真器計算所有RHS表達式的值,保存結果,并進行調度在時序控制指 定時間的賦值。 2. 在經過相應的延遲后,仿真器通過將保存的值賦給LHS表達式完成賦 值。
非阻塞過程賦值(續) 阻塞與非阻塞賦值語句行為差別舉例1 module non_block1; 輸出結果: reg a, b, c, d, e, f; initial begin // blocking assignments 0 a= x b= x c= x d= x e= x f = x a = #10 1; // time 10 2 a= x b= x c= x d= x e= 0 f = x b = #2 0; // time 12 c = #4 1; // time 16 4 a= x b= x c= x d= x e= 0 f = 1 end initial begin // non- blocking assignments 10 a= 1 b= x c= x d= 1 e= 0 f = 1 d 12 a= 1 b= 0 c= x d= 1 e= 0 f = 1 e f end initial begin $monitor($ time,," a= %b b= %b c= %b d= %b e= %b f= %b", a, b, c, d, e, f); #100 $finish; end endmodule 非阻塞過程賦值(續) 阻塞與非阻塞賦值語句行為差別舉例2 module pipeMult(product, mPlier, mCand, go, clock); input go, clock; input [7:0] mPlier, mCand; output [15:0] product; reg [15:0] product; always @(posedge go) product = repeat (4) @(posedge clock) mPlier * mCand; endmodule module pipeMult(product, mPlier, mCand, go, clock); input go, clock; input [7:0] mPlier, mCand; output [15:0] product; reg [15:0] product; always @(posedge go) product endmodule。
HDL 阻塞與非阻塞語句
VHDL語言里沒有阻塞與非阻塞之分。相比Verilog,VHDL更適合行為級建模。
Verilog HDL中,有兩種過程賦值方式,即阻塞賦值(blocking)和非阻塞賦值(nonblocking)。阻塞賦值執行時,RHS(right hand statement)估值與更新LHS(left hand statement)值一次執行完成,計算完畢,立即更新。在執行時阻塞同塊中的其他語句的執行。阻塞式(blocking)的操作符為 “ = ”。它的執行很像傳統程序設計語言。非阻塞賦值RHS估值與更新LHS值分兩步執行。在單位仿真周期開始時RHS估值,在同一單位仿真周期末更新LHS值,不阻塞同塊中其他語句的執行。非阻塞式(non-blocking)的操作符為 “
阻塞賦值和非阻塞賦值有什么本質的區別
(1)在描述組合邏輯的always塊中用阻塞賦值,則綜合成組合邏輯的電路結構;(2)在描述時序邏輯的always塊中用非阻塞賦值,則綜合成時序邏輯的電路結構。
原因:這是因為要使綜合前仿真和綜合后仿真一致的緣故。 、阻塞賦值操作符用等號(即 = )表示。
“阻塞”是指在進程語句(initial和always)中,當前的賦值語句阻斷了其后的語句,也就是說后面的語句必須等到當前的賦值語句執行完畢才能執行。而且阻塞賦值可以看成是一步完成的,即:計算等號右邊的值并同時賦給左邊變量。
例如: 當執行“x=next_x;”時,x會立即的到next_x的值。而下一句“y=x;”必須等到“x=next_x;”執行完畢才能被執行。
由于這兩條語句都沒有延遲(相當于導線),導致他們的等價語句為“y=next_x;”。 賦值是實時的,計算完右面的馬上賦值給左邊的,然后再執行下一句,操作時串行的,且在一個alway內完成。
2、非阻塞賦值操作符用小于等于號 (即 <= )表示。“非阻塞”是指在進程語句(initial和always)中,當前的賦值語句不會阻斷其后的語句。
非阻塞語句可以認為是分為兩個步驟進行的: ①計算等號右邊的表達式的值,(我的理解是:在進入進程后,所有的非阻塞語句的右端表達式同時計算,賦值動作只發生在順序執行到當前非阻塞語句那一刻)。 ②在本條賦值語句結束時,將等號右邊的值賦給等號左邊的變量。
例如: 當執行“x<=next_x;”時,并不會阻斷語句“y<=x;”的執行。因此,語句“y<=x;”中的x的值與語句“x<=next_x;”中的x的值不同:語句“y<=x;”中的x是第一個D觸發器的初值(Q0)。
而語句“x<=next_x;”中的x的值是D觸發器經過一個同步脈沖后的輸出值(Q1)。基于此這個進程產生了與阻塞賦值進程截然不同的結果,即:產生了移位寄存器的效果,next_x à x à y。
簡單理解就是,阻塞賦值是按需執行,非阻塞賦值是并行執行。
深入理解阻塞和非阻塞賦值的區別
阻塞與非阻塞賦值的語言結構是Verilog語言中最難理解的概念之一。
有這樣的兩個要點:
(1)在描述組合邏輯的always塊中用阻塞賦值,則綜合成組合邏輯的電路結構;
(2)在描述時序邏輯的always塊中用非阻塞賦值,則綜合成時序邏輯的電路結構。
這樣做的原因是:
這是因為要使綜合前仿真和綜合后仿真一致的緣故。
為了更好地理解上述要點,我們需要對Verilog語言中的阻塞賦值和非阻塞賦值的功能和執行時間上的差別有深入的理解。我們定義下面的兩個關鍵字:
RHS——方程式右手方向的表達式或變量可分別縮寫成 RHS表達式或RHS變量;
LHS ——方程式左手方向的表達式或變量可分別縮寫成LHS 表達式或LHS變量。
IEEE Verilog標準定義了有些語句有確定的執行時間,有些語句沒有確定的執行時間。若有兩條或兩條以上的語句準備在同一時間執行,但由于語句的排列順序不同,卻產生了不同的輸出結果。這就是造成Verilog模塊冒險和競爭的原因。為了避免產生競爭,理解阻塞和非阻塞賦值在執行時間上的差別是至關重要的。
1、阻塞賦值
阻塞賦值用等號(=)表示。為什么稱這種賦值為阻塞賦值呢?因為在賦值時先計算RHS部分的值,這是賦值語句不允許任何別的Verilog語言的干擾,直到現行的賦值完成時刻,即把RHS賦值給LHS的時刻,它才允許別的賦值語句的執行。
一般可綜合的賦值操作在RHS不能設定延時(即使是0延時也不允許)。從理論上講,它與后面的賦值語句只有概念上的先后,而無實質的延遲。若在RHS上加延遲,則在延遲時間會阻止賦值語句的執行,延遲后才進行賦值,這種賦值語句是不可綜合的,在需要綜合的模塊設計中不可使用這種風格的代碼。
所謂阻塞的概念是指在同一個always塊中,其后面的賦值語句從概念上是在前一句賦值語句結束之后再開始賦值的。
2、非阻塞賦值
非阻塞賦值用小于等于號((1)在賦值開始時,計算非阻塞賦值RHS表達式;
(2)在賦值結束時,更新非阻塞賦值LHS表達式。
非阻塞賦值操作只能用于對寄存器類型變量進行賦值,因此只能用在“initial”塊和“always”塊等過程塊中,而非阻塞賦值不允許用于連續賦值。
阻塞式賦值和非阻塞式賦值有什么不同
1、阻塞賦值操作符用等號(即 = )表示。
“阻塞”是指在進程語句(initial和always)中,當前的賦值語句阻斷了其后的語句,也就是說后面的語句必須等到當前的賦值語句執行完畢才能執行。而且阻塞賦值可以看成是一步完成的,即:計算等號右邊的值并同時賦給左邊變量。
例如:當執行“x=next_x;”時,x會立即的到next_x的值。而下一句“y=x;”必須等到“x=next_x;”執行完畢才能被執行。
由于這兩條語句都沒有延遲(相當于導線),導致他們的等價語句為“y=next_x;”。賦值是實時的,計算完右面的馬上賦值給左邊的,然后再執行下一句,操作時串行的,且在一個alway內完成。
2、非阻塞賦值操作符用小于等于號 (即 <= )表示。“非阻塞”是指在進程語句(initial和always)中,當前的賦值語句不會阻斷其后的語句。
非阻塞語句可以認為是分為兩個步驟進行的:①計算等號右邊的表達式的值,(我的理解是:在進入進程后,所有的非阻塞語句的右端表達式同時計算,賦值動作只發生在順序執行到當前非阻塞語句那一刻)。②在本條賦值語句結束時,將等號右邊的值賦給等號左邊的變量。
例如:當執行“x<=next_x;”時,并不會阻斷語句“y<=x;”的執行。因此,語句“y<=x;”中的x的值與語句“x<=next_x;”中的x的值不同:語句“y<=x;”中的x是第一個D觸發器的初值(Q0)。
而語句“x<=next_x;”中的x的值是D觸發器經過一個同步脈沖后的輸出值(Q1)。基于此這個進程產生了與阻塞賦值進程截然不同的結果,即:產生了移位寄存器的效果,next_x à x à y。
簡單理解就是,阻塞賦值是按需執行,非阻塞賦值是并行執行。為了更好地理解上述要點,我們需要對Verilog 語言中的阻塞賦值和非阻塞賦值的功能和執行時間上的差別有深入的了解。
為了解釋問題方便下面定義兩個縮寫字:RHS – 方程式右手方向的表達式或變量可分別縮寫為: RHS表達式或RHS變量。 LHS – 方程式左手方向的表達式或變量可分別縮寫為: LHS表達式或LHS變量。
IEEE Verilog標準定義了有些語句有確定的執行時間,有些語句沒有確定的執行時間。若有兩條或兩條以上語句準備在同一時刻執行,但由于語句的排列次序不同(而這種排列次序的不同是IEEE Verilog標準所允許的), 卻產生了不同的輸出結果。
這就是造成Verilog模塊冒險和競爭現象的原因。為了避免產生競爭,理解阻塞和非阻塞賦值在執行時間上的差別是至關重要的。
阻塞賦值 阻塞賦值操作符用等號(即 = )表示。為什么稱這種賦值為阻塞賦值呢?這是因為在賦值時先計算等號右手方向(RHS)部分的值,這時賦值語句不允許任何別的Verilog語句的干擾,直到現行的賦值完成時刻,即把RHS賦值給 LHS的時刻,它才允許別的賦值語句的執行。
一般可綜合的阻塞賦值操作在RHS不能設定有延遲,(即使是零延遲也不允許)。從理論上講,它與后面的賦值語句只有概念上的先后,而無實質上的延遲。
若在RHS 加上延遲,則在延遲期間會阻止賦值語句的執行, 延遲后才執行賦值,這種賦值語句是不可綜合的,在需要綜合的模塊設計中不可使用這種風格的代碼。阻塞賦值的執行可以認為是只有一個步驟的操作:計算RHS并更新LHS,此時不能允許有來自任何其他Verilog語句的干擾。
所謂阻塞的概念是指在同一個always塊中,其后面的賦值語句從概念上(即使不設定延遲)是在前一句賦值語句結束后再開始賦值的。如果在一個過程塊中阻塞賦值的RHS變量正好是另一個過程塊中阻塞賦值的LHS變量,這兩個過程塊又用同一個時鐘沿觸發,這時阻塞賦值操作會出現問題,即如果阻塞賦值的次序安排不好,就會出現競爭。
若這兩個阻塞賦值操作用同一個時鐘沿觸發,則執行的次序是無法確定的。下面的例子可以說明這個問題。
[例1]. 用阻塞賦值的反饋振蕩器 module fbosc1 (y1, y2, clk, rst); output y1, y2; input clk, rst; reg y1, y2; always @(posedge clk or posedge rst) if (rst) y1 = 0; // reset else y1 = y2; always @(posedge clk or posedge rst) if (rst) y2 = 1; // preset else y2 = y1; endmodule 按照IEEE Verilog 的標準,上例中兩個always塊是并行執行的,與前后次序無關。如果前一個always塊的復位信號先到0時刻,則y1 和y2都會取1,而如果后一個always塊的復位信號先到0時刻,則y1 和y2都會取0。
這清楚地說明這個Verilog模塊是不穩定的會產生冒險和競爭的情況。非阻塞賦值 非阻塞賦值操作符用小于等于號 (即 <= )表示。
為什么稱這種賦值為非阻塞賦值?這是因為在賦值操作時刻開始時計算非阻塞賦值符的RHS表達式,賦值操作時刻結束時更新LHS。在計算非阻塞賦值的RHS表達式和更新LHS期間,其他的Verilog語句,包括其他的Verilog非阻塞賦值語句都能同時計算RHS表達式和更新LHS。
非阻塞賦值允許其他的Verilog語句同時進行操作。非阻塞賦值的操作可以看作為兩個步驟的過程:1) 在賦值時刻開始時,計算非阻塞賦值RHS表達式。
2) 在賦值時刻結束時,更新非阻塞賦值LHS表達式。非阻塞賦值操作只能用于對寄存器類型變量進行賦值,因此只能用在"initial"塊和"always"塊等過程塊中。
非阻塞賦值不允許用于連續賦值。
verilog case語句 可以用非阻塞賦值嗎
下面的代碼是我根據你的需求功能寫的,當然也不是什么“標準寫法”,僅僅是用于參考。
因為我沒有測試過,如果功能與需求不符,可以作一點修改,但結構上是可用的。
無論是串行風格,還是并行風格,當寫出一段verilog代碼,一定要知道描述的是一個什么器件。
C/C++ code?
// 超時標志
wire wait_timeout = autoNego_wait_timer >= FLP_INTERVAL_MAX_TIME;
// 有效flp脈沖,即在計數區間內到來的link_code_rx_done_flag
wire valid_flp_pulse = (autoNego_wait_timer FLP_INTERVAL_MIN_TIME) &&
link_code_rx_done_flag;
// state_m_autoNego_rx -- 狀態機:寄存器
always @( posedge clk ) begin
if( flp_cnt > 10 ) begin
state_m_autoNego_rx 10) || wait_timeout || valid_flp_pulse ) begin
autoNego_wait_timer
verliog 語句中, 一個非阻塞賦值語句a<=a+1; 需要幾個clk周期 才能
assign語句后的賦值會生成組合邏輯,也就是從b到a會生成一條導線,將他們連接,b的值如果改變,a的值同時也會改變;a<=b這種賦值方式為“非阻塞賦值”,這種方式是等所在的*塊執行完畢后,才會把b的值賦給a,在這之前,a的值仍然保持原值。
例如:假設a中的值為十進制數10,b為15,c為20;beginb=a;//b的值立即改變,現在b的值為10c=b;//c的值立即改變,現在c的值為10end但是,以下例子又不同:假設a中的值為十進制數10,b為15,c為20beginb<=a;//b的值不立即改變,現在b的值仍為15c<=b;//c的值不立即改變,現在c的值仍為20endbegin塊結束后,b被賦給a的值,b為10,c被賦給b的值,c為15。發現了嗎?實際上阻塞賦值生成了一個移位寄存器。