“本文主要分享了在Verilog設(shè)計過程中一些經(jīng)驗與知識點(diǎn),主要包塊語句、阻塞賦值和非阻塞賦值以及結(jié)構(gòu)說明語句(initial, always, task, function)?!?/span>
01
—
塊語句
順序塊 begin…end
塊內(nèi)的語句是按照順序執(zhí)行的;
塊內(nèi)的每條語句延時控制都是相對于上條語句結(jié)束的時刻;
仿真時,執(zhí)行到最后一條語句該語句塊執(zhí)行結(jié)束。
并行塊fork…end
塊內(nèi)的語句是按照獨(dú)立的同時開始執(zhí)行的;
塊內(nèi)的每條語句延時控制都是相對于程序進(jìn)入該語句塊的時刻而言;
仿真時,所需最長時間的語句執(zhí)行結(jié)束后,該語句塊執(zhí)行結(jié)束。
例:
仿真結(jié)果如下:reg [7:0] l1,l2;
reg[7:0]k1,k2;
initial
begin
l1=0;l2=0;
#15l1=2;
#10l2=8;
end
initial
fork
k1=0;k2=0;
#15k1=2;
#10k2=8;
join
02
—
阻塞賦值和非阻塞賦值
-
阻塞賦值(Blocking)
-
非阻塞賦值(Non_Blocking)
例1:組合邏輯中的阻塞與非阻塞
阻塞代碼如下:仿真結(jié)果如下:always@(a,b,c,d)
begin
i1 = a & b;
i2 = c & d;
i3 = i1 & i2;
end
always@(a,b,c,d)
begin
i1 <= a & b;
i2 <= c & d;
i3 <= i1 & i2;
end
仿真結(jié)果如下:
可以看出i1和i2在阻塞和非阻塞中結(jié)果相同,但是i3的結(jié)果卻不同。這是因為在阻塞賦值中,i3的賦值使用的是i1和i2更新后的值,而非阻塞賦值中i3的賦值則使用的是i1和i2更新前的值。要想解決這一問題,則需要將“always@(a,b,c,d)”改成“always@(a,b,c,d,i1,i2)”代碼如下:
仿真結(jié)果如下:always@(a,b,c,d,i1,i2)
begin
a&b; =
i2 <= c & d;
i3 <= i1 & i2;
end
例2:時序邏輯中的阻塞和非阻塞。
以反饋振蕩器的代碼為例。非阻塞賦值代碼:
always@(posedge clk,posedge rst)
begin
if(rst) a1 <=0;
else a1 <=a2;
end
always@(posedge clk,posedge rst)
begin
if(rst) a2 <=1;
else a2 <=a1;
end
阻塞賦值代碼:
always@(posedge clk,posedge rst)
begin
if(rst) b1 = 0;
else b1 = b2;
end
always@(posedgeclk,posedgerst)
begin
if(rst) b2 = 1;
else b2 = b1;
end
仿真結(jié)果如下:
可以看出阻塞賦值語句并不能達(dá)到我們想要的效果;而且綜合后阻塞賦值語句中,無法確定哪個always塊中的時鐘沿先到達(dá),哪個always塊中的時鐘后到達(dá),所以存在一個冒險競爭的問題。綜上,時序邏輯中更適合用非阻塞賦值語句。
03
—
結(jié)構(gòu)說明語句(initial, always, task, function)
-
語句initial
一般initial語句用于測試文件的編寫;但是隨著編譯器的進(jìn)步,現(xiàn)在也可以綜合,常用于一些變量的初始化。無論是用在什么場景,initial語句只執(zhí)行一次。initial begin
// Add code here
end
-
語句always
例1:生成仿真時的信號波形
always可以用于仿真時的波形生成:always #5 clk = ~clk;這個例子就形成了一個周期為10ns(時間單位ns根據(jù)`timescale確定)的方波,常用來描述時鐘信號(如果將#5去掉,那么會生成一個延遲為0的無限循環(huán)跳變過程,會發(fā)生仿真鎖死,這是不推薦的)。仿真結(jié)果如下:
例2:
實(shí)現(xiàn)鎖存器和觸發(fā)器
多個敏感事件可以用“or”或者“,”區(qū)分(rst為復(fù)位信號,可以是posedge也可以是negedge)。always@(posedge clk or posedge rst)
begin
if(rst) cnt <= 0;
else cnt <= cnt + 1;
end
或
always@(posedge clk , posedge rst)
begin
//add codes
end
例3:實(shí)現(xiàn)組合邏輯
利用always實(shí)現(xiàn)組合邏輯時,要將所有的信號放進(jìn)敏感列表,而時序邏輯中則不需要。上面的代碼表示,a、b、c中任意電平發(fā)生變化,begin…end語句就會被觸發(fā)。仿真結(jié)果如下所示:always@(aorborc)
begin
x=x+1;
end
如上所示,因為敏感列表比較長,容易寫錯,所以Verilog又提供了兩個特殊的符號:@*和@(*)。簡化代碼如下:always@(a or b or c or d or e)
begin
out = a + b + c + d + e;
end
仿真結(jié)果如下圖所示:always@(*)
begin
a+b+c+d+ e; =
end
-
語句task
task <任務(wù)名>;
<端口及數(shù)據(jù)類型聲明語句>;
<語句1>;
…
<語句n>;
endtask
示例代碼如下:
仿真結(jié)果如下圖所示:reg [7:0] j,k,i,x;
clk or posedge rst)
begin
if(rst)
begin
i <= 0;
j <= 0;
k <= 0;
x <= 0;
task1(i,j,k);
end
else
begin
i <= i + 1;
x <= i + 10;
task1(i,j,k);
end
end
task task1;
input [7:0] i;
output [7:0] j1;
output [7:0] k1;
begin
j1 = i + 10;
k1 = i + 11;
end
endtask
-
語句function
語句function的定義:
function<返回值的類型或范圍>(函數(shù)名)
<端口說明語句>
<變量類型說明語句>
begin
…
end
endfunction
示意代碼如下:
reg [7:0] i,j;
reg [8:0] sum_data;
clk or posedge rst)
begin
if(rst)
begin
i <= 100;
j <= 31;
sum_data <= sum(i,j);
end
else
begin
i <= i + 1;
j <= j + 2;
sum_data <= sum(i,j);
end
end
function [8:0] sum;
input [7:0] i1;
input [7:0] j1;
begin
sum = i1 + j1;
end
endfunction
仿真結(jié)果如下圖所示:
注意:initial、always、task和function都是可以綜合的。
審核編輯:郭婷
-
Verilog
+關(guān)注
關(guān)注
28文章
1352瀏覽量
110425
原文標(biāo)題:Verilog基礎(chǔ)知識學(xué)習(xí)筆記(二)
文章出處:【微信號:zhuyandz,微信公眾號:FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
Verilog語言中阻塞和非阻塞賦值的不同
Verilog過程賦值語句提問
verilog中g(shù)enerate語句的用法分享
在verilog語句中,非阻塞賦值和小于等于均使用符號“<=”,如何區(qū)分<=所表示的含義?
FPGA視頻教程之Verilog中兩種不同的賦值語句的資料說明
![FPGA視頻教程之<b class='flag-5'>Verilog</b>中兩種不同的<b class='flag-5'>賦值</b><b class='flag-5'>語句</b>的資料<b class='flag-5'>說明</b>](https://file.elecfans.com/web1/M00/8C/D8/pIYBAFya6JGAIFTtAACKzsQF8FM908.png)
verilog中阻塞賦值和非阻塞賦值到底有什么區(qū)別
![<b class='flag-5'>verilog</b>中阻塞<b class='flag-5'>賦值</b>和非阻塞<b class='flag-5'>賦值</b>到底有什么區(qū)別](https://file.elecfans.com/web1/M00/BB/65/pIYBAF6jncyAeVqnAAUztjamFUQ215.png)
Verilog中的賦值語句的區(qū)別
![<b class='flag-5'>Verilog</b>中的<b class='flag-5'>賦值</b><b class='flag-5'>語句</b>的區(qū)別](https://file.elecfans.com/web1/M00/C8/54/pIYBAF9t_PqAHfkkAAB733jnm2M175.jpg)
Verilog HDL語言中連續(xù)賦值的特征
![<b class='flag-5'>Verilog</b> HDL語言中連續(xù)<b class='flag-5'>賦值</b>的特征](https://file.elecfans.com/web1/M00/E3/63/o4YBAGBB4h6AcVvEAAAnj1HqAMY967.png)
評論