在verilog中,always塊是一種常用的語句,可以是很簡單的功能模塊,也可以是結構最復雜的部分。
一般always語句可以分為兩類電路。一種是組合邏輯。一種是時序邏輯。
第一類:組合邏輯
//-----1.1 組合邏輯 --------
Always @ (*)
Begin
If(a>b)
Q = 1;
Else
Q = 0;
end
//------- end -------------//
如1.1所示,就是一個簡單的組合邏輯always塊,它應該是被綜合成一個一位的比較器。
//---- 1.2 組合邏輯 缺少敏感信號 ------
Always @ (a)
Begin
If(a>b)
Q = 1;
Else
Q = 0;
end
//------- end -------------//
代碼 1-2 也是一個組合邏輯,與 1-1 不同的是,敏感信號列表中只有a沒有 b。
我們知道,在 Verilog 語法中, always 塊的含義是一個重復執行的語句。
那么 1-2 會綜合成一個比較器:
- 當 a 發生變化時,q 發生變化
- 當 b 發生變化,由於 b 不再敏感信號列表中,所以 q 不變
這是一個徹頭徹尾的軟件思維,世界上不存在這種電路,綜合器多半會綜合一個與代碼 1-1 一樣的電路,然后報一個警告。
編寫組合邏輯的 always 塊,使用 * 代替敏感信號列表是一個簡單方便而且不容易出錯的好辦法。
第二類:時序邏輯
//----- 2-1 時序邏輯 -------
reg [1:0] q;
always @ (posedge clk)
begin
q <= q + 1'b1;
End
注意:這里使用的是阻塞賦值,我們的 q 這個時候被綜合成一個寄存器,而不是一個軟件上的變量。
代碼 2-1 是一個時序邏輯單元,它應該被綜合成一個計數器,每當時鍾的上升沿,q 自增一。綜合后的 部分 RTL 圖如下:
// 2-2 時序邏輯 ,帶異步復位
reg [1:0] q;
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
q <= 2'b00;
else
q <= q + 1'b1;
End
綜合后的 RTL 圖如下:
代碼2-2綜合成一個帶有清零端的 D 觸發器,其余與 2-1 無異。
轉載地址:https://blog.csdn.net/weixin_36590806/article/details/117255196
always語句注意點:
1、不要在不同的always塊內為同一個變量賦值。即某個信號出現在<=或者=左邊時,只能在一個always塊內。
2、不要在同一個always塊內同時使用阻塞賦值(=)和非阻塞賦值(<=)。
3、在使用always塊描述組合邏輯時使用阻塞賦值(=);使用always塊描述時序邏輯時使用非阻塞賦值(<=)。
4、任何在always塊內被賦值的變量都必須是寄存器型(reg)。
5、always的敏感列表中可以同時包括多個電平敏感事件,也可以包括多個邊沿敏感事件,但不能同時有電平和邊沿敏感事件。另外,在敏感列表中,同時包括一個信號的上升沿敏感事件和下降沿敏感事件是不容許的,因為這兩個事件可以合並為一個電平事件。
HHH~~~~