過程塊
- always過程塊
模板:
always @(<敏感信號表達式>)
begin
//過程賦值
//if語句
//case語句
//while、repeat、for語句
//task、function調用
end
當敏感信號表達式的值改變時候,就執行一遍塊內語句。同時always過程塊是不能夠嵌套使用的。
關鍵字posedge
與negedge
關鍵字分別是上升沿以及下降沿
例如:同步時序電路的時鐘信號爲clk,clear爲異步清零信號。敏感信號可寫爲:
//上升沿觸發,高電平清0有效
always @(posedge clk or posedge clear)
//上升沿觸發,低電平清0有效
always @(posedge clk or negedge clear)
例如當negedge clear
表示當clear==0
時
always @(posedge clk or negedge clear)
begin
if(!clear)//當clear==0時候,always會由事件驅動
qout=0;
else
qout=in;
end
- initial過程塊
initial模板:
initial
begin
語句1;
語句2;
......
end
對變量和存貯器初始化
initial
begin
reg1=0;
for(addr=0;addr<size;addr=addr+1)
memory[addr]=0;
end
initial語句主要面向功能模擬,通常不具有可綜合性。
模擬0時刻開始執行,只執行一次
同一模塊內的多個initial過程塊,模擬0時刻開始並行執行。
initial與always語句一樣,是不能嵌套使用的。即在initial語句中不能再次嵌套initial語句塊。
連續賦值
用連續賦值語句表達的是: assign val=newval;
任何一個輸入的改變都將立即導致輸出更新;
module orand(out,a,b,c,d,e);
input a,b,c,d,e;
output out;
assign out=3&(a|b)&(c|d);
endmodule
過程賦值語句
過程賦值語句常用於對reg變量進行賦值。一般分爲兩種,阻塞賦值與非阻塞賦值
阻塞與非阻塞賦值
賦值的類型選擇取決於建模的邏輯類型。
在時序塊的RTL代碼中使用非阻塞賦值
<=
。非阻塞賦值在塊結束後才完成賦值操作。此賦值方式可以避免在仿真出現魔仙和競爭現象。在組合的RTL代碼中使用阻塞賦值
=
。使用阻塞賦值方式對一個變量進行賦值時,此變量的值在賦值語句執行完後才能之後就立即改變。
compare
使用非阻塞賦值方式進行賦值時,各個賦值語句同步執行;因此通常在一個時鐘沿對臨時變量進行賦值,而在另一個時鐘沿對其進行採樣。因爲在相同的時鐘沿採樣賦值,採樣的還是原來的值,賦值操作是在塊結束時進行。
- 阻塞賦值
下面模塊會綜合成爲觸發器
module block(clk,a,b);
input clk,a;
output b;
reg b;
always @(posedge clk)
begin
y=a;
b=y;
end
endmodule
- 非阻塞賦值
下面的模塊會綜合成兩個觸發器
module block(clk,a,b);
input clk,a;
output b;
reg b;
always @(posedge clk)
begin
y<=a;
b<=y;
end
endmodule
上圖左側是阻塞賦值的綜合結果,右側則爲非阻塞賦值。相比左側,右側的例子會造成一個時鐘週期的延遲。