對於阻塞賦值以及非阻塞賦值的一些理解

2021-10-23 13:37:37 字數 2022 閱讀 5079

最近在看別人的fpga卷積程式時有一段程式邏輯不太理解,主要是對於非阻塞賦值理解的不夠深刻。現在基本弄清楚了,寫個筆記記錄一下~

首先這段程式如下:

always @(posedge clk) begin

if(!local_rst_n) begin

wr_addr <=

16'h0000;

user_wr_rdy_n <=

1'b1;

wr_state <=

wr_rst

; pre_port_wr_rdy <=

1'b0;

endelse begin

pre_port_wr_rdy <= wr_port_rdy_n;

case

(wr_state)

wr_rst

:begin

user_wr_rdy_n <=

1'b1;if(

!user_rd_start_n)

wr_state <=

wr_rdy

;else

wr_state <=

wr_rst

; end

wr_rdy

:begin

user_wr_rdy_n <=

1'b0;if(

(!wr_port_rdy_n)

&&(pre_port_wr_rdy))//

wr_state <=

wr_done

;else

wr_state <=

wr_rdy

; end

wr_done

:begin

user_wr_rdy_n <=

1'b1;

wr_state <=

wr_rst

; wr_addr <= wr_addr +

1'b1;

end

endcase

endif

(wr_addr ==

12'b000000000010) //(wr_addr[10:0] == 11'b10000000000)

work_led <=1;

else

work_led <=0;

end

可以無視這段**的變數名稱,單純看邏輯。這裡

pre_port_wr_rdy <= wr_port_rdy_n;
wr_port_rdy_n對pre_port_wr_rdy做了乙個非阻塞賦值,然後下面的條件判斷語句

if((

!wr_port_rdy_n)

&&(pre_port_wr_rdy)

)

這裡的reg型變數pre_port_wr_rdy是被賦值前的pre_port_wr_rdy還是被賦值後的pre_port_wr_rdy?

答案當然應該是賦值前的pre_port_wr_rdy,不然條件判斷語句就沒有意義,可為什麼呢?

這關於非阻塞賦值的定義:非阻塞賦值分為兩個過程,rhs的計算為第一步,lhs的賦值為第二步;但由於兩步時間非常短,表現出來就是在時鐘邊沿瞬間完成,故表現結果非阻塞和阻塞一樣。

但如果條件判斷式中含有非阻塞賦值的reg型變數,結果就不一樣了。條件判斷式中的條件相當於取樣,而被取樣的reg變數使用了非阻塞賦值,非阻塞賦值完成有兩個步驟,在某乙個**節拍(不是乙個**週期),被取樣的還沒有賦值完成(處在rhs的計算階段),而取樣時同時進行,這樣,取樣到的就是上乙個週期的reg變數的值,雖然馬上在邊沿完成賦值,但取樣已經結束了,所以條件判斷語句裡的reg變數是被賦值前的值。

通過對這段程式的行為級**,我們也能驗證之前的說法:

這裡還需注意的是 wr_port_rdy_n在時鐘沿上公升的同時下拉,pre_port_wr_rdy並不是同時被下拉而是延後了乙個時鐘週期。

阻塞賦值和非阻塞賦值

阻塞賦值 阻塞賦值操作符用等號 即 表示。為什麼稱這種賦值為阻塞賦值呢?這是因為在賦值時先計算等號右手方向 rhs 部分的值,這時賦值語句不允許任何別的verilog 語句的干擾,直到現行的賦值完成時刻,即把rhs 賦值給 lhs 的時刻,它才允許別的賦值語句的執行。一般可綜合的阻塞賦值操作在rhs...

阻塞賦值和非阻塞賦值

2017 12 01 在verilog語言中,賦值語句經常使用,阻塞賦值和非阻塞賦值經常帶給我們很多困擾。在此討論兩種賦值方式的差異性。首先根據表面含義深刻理解阻塞和非阻塞 阻塞 在程序語句塊中 initial或者always或者其他 當前賦值語句的執行阻塞了後面語句的執行。即後面語句的賦值需要等到...

阻塞與非阻塞賦值

李秋鳳,華清遠見嵌入式學院 講師。稍微接觸過verilog hdl的都對阻塞與非阻塞賦值略知一二,也是我們經常強調的重點之一,在課堂上還是有學員問什麼不一樣呢,為什麼我用阻塞賦值也能得出正確的結果呢?在編寫可綜合 的時候,建議大家不要忘了開啟rtl網表檢視器看看我們自己綜合出來的電路是不是自己想要的...