- 輸入聲明
input[msb:lsb]端口1,端口2,端口3,……
- 輸出聲明
output[msb:lsb]端口1,端口2,端口3,……
- 輸入輸出聲明
inout[msb:lsb]端口1,端口2,端口3,……
信號類型聲明
常用的信號類型有連線性(wire)、寄存器型(reg)、整形(integer)、實型(real)、時間型(time)等
功能描述
1.用assign語句實現 eg.assgin a=b&c;
2.用實例元件實現 eg. and u1(q,a,b) 其中a,b為輸入,q為輸出
3.用always塊實現帶有異步清除端的D觸發器
always @(posedge clk or posedge clr)
begin
if(clk)q<=0;
else q<=d;
end
- 用initial塊實現,與always塊語句類似,不過在程序中initial塊語句只能被執行一次,一般用于電路的初始化
常量
- 整形常量
x:未知,z:高阻
6'B10X1Z0 //6位二進制數
92 //十進制數
'H67 //位寬為32位的十六進制數
5'O37 //5位八進制數
- 實行常量
7.56 ,34.56e2 6E-2
- 字符串常量
"hello!"
\n換行符
\t制表符Tab鍵
\\符號\
\*符號*
\ddd 三位八進制數表示的ASCII碼
%%符號%
- 參數常量
parameter PI=3.14,A=8'B10110101,WORD_LENGTH=16;
變量
- wire型
輸入、輸出信號在默認情況下自動定義為wire型
wire[msb:lsb]變量1,變量2,…,變量n
eg.wire[7:0]m,n;
- reg型
reg[msb:lsb]變量1,變量2,…,變量n
eg.reg[7:0]m,n;
reg型變量和wire型變量的區別是:wire型變量需要持續地驅動,而reg型變量保持最后一次的賦值
- memory型
memory型是存儲器型,是通過建立reg型數組來描述的
eg.
reg[8:1]RAM[3:0];
RAM[0]=8'H1A;
RAM[1]=8'H00;
RAM[2]=8'H55;
RAM[3]=8'H31;
- integer型
integer是32位帶符號整形變量,用于對循環控制變量的說明,典型應用是高層次的行為建模,它與后面的time和real類型一樣是不可綜合的,也就是說這些類型是數學的抽象描述,不與任何物理電路相對應。
eg.integer d[1:8];//定義了一個含有8個數據的整形數組
- time型
time類型用于儲存和處理時間,是64位無符號數
time 變量1,變量2,…,變量n;
- real型
real型是64位帶符號實型變量,用于儲存和處理實型數據
real 變量1,變量2,…,變量n;
運算符
- 算術運算符
+,-,*,/,%
- 邏輯運算符
&&,||,!
- 關系運算符
<,<=,>,>=
- 等值運算符
==邏輯相等,!=邏輯不等(可能為1,0,x),===全等(按位比較),!==非全等
- 位運算符
~,&,~&,|,~|,^(異或),~^(同或)
- 縮減運算符
~,&,~&,|,~|,^(異或),~^(同或)
縮減運算符與邏輯運算符的法則是一樣的,但縮減運算符是對單一操作數按位進行邏輯遞推運算的,運算結果為1位二進制數。
- 移位運算符
>>,<<
eg.
i=8;
m=3;
i<<m;//結果為64
i>>m;//結果為1
- 條件運算符
條件? 表達式1:表達式2
eg.
a=10,b=20;
y=a>b?a:b;
- 拼接運算符
X={a[7:4],b[3],c[2:0]};
- 運算符的優先級
賦值語句
- 連續賦值語句
連續賦值語句用來驅動wire型變量,這個變量必須事先定義過。
eg.
wire a,b,c;
assign c=a&b;
- 過程賦值語句
過程賦值語句是在initial或者always語句塊內賦值的,它對reg型、memory型、integer型、time型、real型變量進行賦值,這些變量在下一次過程賦值之前保持原來的值。
- 阻塞型賦值
在該語句結束時就完成賦值操作
變量=賦值語句;
- 非阻塞型賦值
在塊結束時才完成賦值操作
變量<=賦值語句;
條件語句
- if else語句
- case語句
case(控制表達式)
分支表達式2:語句2;
分支表達式3:語句3;
…
分支表達式m:語句m;
endcase
循環語句
- forever循環語句
forever循環語句常用語產生周期性的波形,與always不同的地方在于它不能獨立寫在程序中,必須寫在initial塊中,常用于產生仿真測試信號。
eg.
initial
begin
end
- repeat循環語句
repeat循環語句是用于執行指定循環次數的過程語句,格式如下:
repeat(表達式)語句
eg.
initial
begin
end
- while循環語句
while循環執行過程中賦值語句直到指定的條件為假
- for循環語句
結構聲明語句
- initial說明語句
initial語句常用于對各變量的初始化,一個程序模塊中可以有多個initial語句,所有的initial語句在程序一開始同時執行,并且只執行一次。
- always說明語句
always語句和initial語句一樣可以有多個always語句,always語句也是在程序一開始的時候就被執行,不同的是always語句不斷重復運行。但是always語句后跟的語句是否執行,要看其敏感事件列表是否滿足,若有條件滿足,則運行一次語句。電平觸發的always塊常用于說明組合邏輯的行為,而在邊沿觸發的always塊常用于描述時序行為。
eg.
reg[7:0] count
always @(posedge clk)
begin
end
- task說明語句
任務類似于高級語言中的子程序,用來單獨完成某項任務,并被其他模塊或者其他任務調用。
- 任務定義
task 任務名;
endtask
- 任務調用
任務名(端口名列表);
任務的定義和調用必須在同一個模塊內
任務定義時,task語句后沒有端口名列表,輸入輸出端口名是通過端口聲明語句進行順序聲明的;一個任務也可以沒有輸入輸出端口
當任務被調用時,任務被激活,如果一個任務有輸入輸出端口,調用時需列出端口名列表,其順序和類型應該與任務定義中的完全一致
進行任務調用時參數的傳遞是按值傳遞的,不能按地址傳遞
一個任務可以調用別的任務或函數,可調用的任務和函數的個數不受限制
- function說明語句
function語句用來定義函數,單獨完成某項具體的 操作。
- 函數的定義
function <返回值得類型或范圍> 函數名;
endfunction
- 函數的調用
函數名(端口名列表)
函數只能有一個返回值,而任務可以有多個或者沒有返回值。
函數至少有一個輸入變量
函數只能與主模塊共用一個仿真時間,而任務可以定義自己的仿真時間單位
函數不能調用任務,而任務能調用其他函數或任務
編譯預處理語句
- 宏定義('define和'undef)
eg.
'define BYTE 8
…
wire ['BYTE-1:0]bus;
…
'undef BYTE
- 文件包含('include)
eg.
'include "d:\eda\s1.v"
- 時間尺度('timescale)
eg.
'timescal 10ns/100ps
…
always #1.55 clock=~clock;
- 條件編譯('ifdef,'else,'endif)
eg.
'ifdef COMPUTER_SIZE-PC
'else
'endif
模塊化設計
module count_dec(clk,clr,en,cout,q);
input clk,clr,en;
output [15:0]q;
output cout;
reg[15:0]q;
reg cout;
wire[3:0]q1,q2;
wire x;
count4 u1(clk,clr,en,x,q1);
count4 u2(clk,clr,x,cout,q2);
dec_seg7 u3(q1,q[7:0]);
dec_seg7 u4(q2,q[15:8]);
endmoudle