module aoi(a,b,c,d,f);/*模塊名為aoi,端口列表a、b、c、d、f*/
input a,b,c,d;/*模塊的輸入端口為a,b,c,d*/
output f;;/*模塊的輸出端口為f*/
wire a,b,c,d,f;/*定義信號的數據類型*/
assign f=~((a&b)|(~(c&d)));/*邏輯功能描述*/
endmodule
- veirlog hdl 程序是由模塊構成的。每個模塊的內容都嵌在module和endmodule兩個關鍵字之內,每個模塊實現特定的功能。
- 每個模塊首先要進行端口定義,并說明輸入口和輸出口(input 、output或inout),然后對模塊
- Verilog HDL程序書寫格式自由,一行可以寫幾個語句,一個語句也可以分多行寫
- 除了endmodule等少數語句外,每個語句的最后必須有分號。
- 每個Verilog HDL程序包括4個主要部分:模塊聲明、端口定義、信號類型聲明和邏輯功能定義。
module <模塊名稱> (<輸入輸出兩邊>);
input 輸入端口列表;
output 輸出端口列表;
/*定義數據、信號的類型、函數聲明,用關鍵字wire、reg、task和function等*/
wire 信號名;
reg 信號名;
//邏輯功能定義
assign <結果信號名>=<表達式>;
//用always塊模式邏輯功能
always @(<敏感信號表達式>)begin//過程賦值//if-else、case語句;for循環語句//task、function調用end
//調用其他模塊
<調用模塊名><例化模塊名>(<端口列表>)
//門元件例化
門元件關鍵字 <例化元件名>(<端口列表>)
endmodule
1.模塊聲明
模塊聲明包括模塊名稱、模塊輸入、輸出端口列表。模塊定義格式如下:
module 模塊名稱(端口1,端口2,端口3,...);
模塊結束的標志為關鍵字endmodule。
2.端口定義
對模塊的輸入、輸出端口要明確說明,其格式為:
input 端口名1,端口名2,...,端口名n;//輸入端口
output 端口名1,端口名2,...,端口名n;//輸除端口
inout 端口名1,端口名2,...,端口名n;//輸入/輸出端口
定義端口時應注意:
- 每個端口出來要聲明是輸入、輸出還是雙向端口外,還要聲明其數據類型,是wire型、reg型,還是其他類型。
- 輸入和雙向端口不能聲明為reg型。
- 在測試模塊中不需要定義端口。
3.信號類型聲明
對模塊中所有用到的信號都必須進行信號類型的定義。如果信號的數據類型沒有定義,則默認為wire型。
reg cout;
可將端口定義和信號類型聲明仿真一條語句中完成。
output reg cout;
還可以將端口定義和信號類型聲明仿真模塊列表中,而不是放在模塊內部。
module aoi(input a,b,c,d,output f);
assign f=~((a&b)|(~(c&d)));
endmodule
4.邏輯功能定義
模塊中最核心的部分就是邏輯功能定義。有多種方法可以在模塊中描述和定義邏輯功能,還可以調用函數(function)和任務(task)來描述邏輯功能,幾種基本方法為:
1.用assign 持續賦值語句定義,進行描述數據流
用數據流描述方式對一個設計建模的最基本的機制就是使用連續賦值語句。在連續賦值語句中,某個值被指派給線網變量。 連續賦值語句的語法為 :
assign [delay] LHS_net = RHS_ expression;
2.用always過程定義,進行描述行為
always過程語句既可以用來描述組合電路,也可以用來描述時序電路。
此語句總是循環執行 , 或者說此語句重復執行
只有寄存器類型數據能夠在這兩種語句中被賦值。寄存器類型數據在被賦新值前保持原
有值不變。所有的初始化語句和 always語句在0時刻并發執行。
3.用initial過程定義,進行描述行為
此語句只執行一次。
4.調用元件(元件例化),進行描述結構
- 可以調用Verilog HDL內置門元件(門級結構描述)
- 可以調用開關級元件(開關級結構描述)
- 在多層次結構電路設計中,高層次可以調用低層次模塊
5.混合描述
在模塊中,結構的和行為的結構可以自由混合。也就是說,模塊描述中可以包含實例化的門、模塊實例化語句、連續賦值語句以及 a l w a y s語句和 i n i t i a l語句的混合。它們之間可以相互包含。來自 a l w a y s語句和 i n i t i a l語句(切記只有寄存器類型數據可以在這兩種語句中賦值)的值能夠驅動門或開關,而來自于門或連續賦值語句(只能驅動線網)的值能夠反過來用于觸發always語句和initial語句。