Verilog HDL学习笔记
目錄
- 1 硬件描述語言簡介
- 1.1 概述
- 1.2 HDL語言特點
- 2 程序的基本語法
- 2.1 Verilog HDL 程序結構
- 2.1 Verilog HDL 程序規則
- 模塊
- 連續賦值語句assign
- 過程塊initial和always
- 3 Verilog HDL 基本語法
- 3.1 Verilog HDL 基本語言要素
- 3.1.1 空白符
- 3.1.2 注釋符
- 3.1.3 關鍵字
- 3.1.4 標識符
- 3.2 常量
- 3.2.1 四種基本邏輯數值
- 3.2.2 整形
- 3.2.3 實數
- 3.2.4 字符串
- 3.2.5 參數
- 3.3 變量及其數據類型
- 3.3.1 wire型(線網型)
- 3.3.2 reg型(寄存器型)
- 3.4 運算符
- 3.4.1 算數運算符
- 3.4.2 關系運算符
- 3.4.3 邏輯運算符
- 3.4.4 位運算符
- 3.4.5 條件運算符
- 3.4.6 位拼接運算符
- 4 Verilog HDL 基本語句
- 4.1 選擇語句
- 4.1.1 if 語句
- 4.1.1 case 語句
- 4.2 重復語句
- 4.2.1 for 循環語句
- 4.2.2 while 循環語句
- 4.2.3 repeat 循環語句
- 4.2.4 forever 循環語句
- 4.3 任務和函數語句
- 4.3.1 task 任務
- 4.3.2 function 函數
- 5 Verilog HDL 數據流建模
- 5.1 連續賦值語句 assign
- 6 宏定義寫法
- 7 文件包含寫法
1 硬件描述語言簡介
1.1 概述
硬件描述語言HDL(Hardware Description Language)是一種形式化方法老描述數字電路和數字邏輯系統的語言。數字邏輯電路設計者可以利用這種語言來描述自己的設計思想。然后用EDA工具進行仿真,在自動綜合到門級電路,最后用ASIC/FPGA來實現其功能。
1.2 HDL語言特點
- HDL語言既包含一些高層次程序設計語言的結構形式,同時也兼顧描述硬件線路連接的具體構件。
- 通過使用結構級或行為級描述,可以在不同的抽象層次(系統級、算法級、寄存器傳輸級、邏輯級、電路級)描述設計,支持自頂向下的數字電路設計方法。
- HDL語言是并發的,即具有在同一時刻執行多任務的能力。一般來講編程語言(例如C語言)是順序執行的,但在實際硬件中許多操作都是在同一時刻發生的,因此HDL語言具有并發的特征。
- HDL語言有時序的概念。一般來講編程語言沒有時序的概念的,但在硬件電路中,從輸入到輸出總是有延遲存在的,為此HDL語言需要引入時序的概念,提供描述電路時序的要求能力。
2 程序的基本語法
2.1 Verilog HDL 程序結構
Verilog HDL程序由模塊(Module)組成,類似于C語言程序由函數組成。模塊用于描述某個設計的功能和結構,及其與其他模塊通訊(連接)的外部端口。在Verilog HDL語言中,一個電路就是一個Module。
2.1 Verilog HDL 程序規則
-
程序嚴格區分大小寫,關鍵字只能用小寫。逗號、分號、引號。圓括號等均使用半角應為符號。
-
除了endmodule語句(以及編譯器指令)外,每個語句以分號結束。
-
一行可以寫多個語句,一個語句也可以分寫多行。
-
Verilog HDL 采用 begin、end 來圍住順序語句塊(且begin、end后面也沒有分號)。而{ }則被 Verilog HDL另用作拼接符。
-
Verilog HDL 定義了一些列的關鍵保留字,關鍵字都是小寫,在編程時,注意給變量或者標識符命名不同于關鍵字。
模塊
連續賦值語句assign
過程塊initial和always
3 Verilog HDL 基本語法
3.1 Verilog HDL 基本語言要素
3.1.1 空白符
Verilog HDL 空白符包括:空格(\b)、制表符(\t)、換行符(\n)。如果空白符不出現在字符串中,則空白符被忽略,空白符除了器分割的作用外,還可以在必要的地方插入相應的空白符,一方便讀者閱讀和修改。
筆記:剛開始學習Verilog HDL程序時,以為程序編程方式和Python一樣是段落式結構,以此來區分不同的包含關系?,F在看來,僅僅是為了方便閱讀,但是編程過程中,仍然要保留這種編寫方式。
3.1.2 注釋符
單行注釋://
多行注釋:/* … */
筆記:Verilog HDL 中的注釋用法和C語言中的注釋用法相同。
3.1.3 關鍵字
和一些軟件編程語言相似,Verilog HDL也有自己的關鍵字,又稱保留字,用戶不可以卵用。所有的關鍵字都使用小寫字母。
常見的關鍵字
| always | – |
3.1.4 標識符
標識符是程序代碼中對象的名字,設計人員使用標識符來訪問對象。Verilog HDL 標識符可以是任意的字母、數字、下劃線和$ 的組合。但是標識符第一個字符必須是字母或下劃線。標識符是區分大小寫的。
3.2 常量
3.2.1 四種基本邏輯數值
| 1 | 高電平 | 真 |
| x | 未知邏輯 | |
| z | 高阻態 |
3.2.2 整形
- 全面描述格式:<位寬>'<進制><數字>
- 默認位寬,具體由系統決定,至少32位:'<進制><數字>
- 默認進制,采用十進制:<數字>
| 4’b1001 | 位寬4位二進制數1001 |
| 5’o36 | 位寬5位八進制數36 |
| 3’d98 | 位寬3位十進制數98 |
| 2’hb2 | 位寬2位十六進制數b1 |
注:進制的字母和“ ’ ”之間不能有空格。在數字串中間可以任意加入下劃線,提高長數字的易讀性。
3.2.3 實數
- 十進制數表示方式:3.14
- 科學計數法表示方式:1.5E2 (表示數字1.5×102=150)
Verilog HDL定義了實數如何隱式轉換為整數。實數通過四舍五入轉換為相近的整數。(例如:12.4→12;90.5→91)
3.2.4 字符串
字符串是雙引號內的字符序列,不能分行寫,例如:“ASDF”。一個字符可以看做其ASCLL編碼對應的8為無符號整數。因而4個字符組成的字符串"ABCD"可以用位寬為8×7的變量來存儲,字符串變量屬于reg型變量。
3.2.5 參數
參數是一個被命名的常量,稱為符號常量。在Verilog HDL中可用parameter定義參數。
格式:parameter 參數名1 = 表達式,參數名2 = 表達式,…,參數名n = 表達式; 例如:parameter S0 = 2'b01 , s1 = 2'b02 , s3 = 2'b03;定義位置:
- 模塊內部
- 模塊開頭
- 端口列表之前
3.3 變量及其數據類型
3.3.1 wire型(線網型)
wire型變量常用來表示以assign關鍵字指定的組合邏輯信號。
程序的輸入/輸出信號類型默認為wire型。
對綜合器來說,wire型變量取值可為0,1,x,z,如果沒有連接到驅動源,則默認初始值是高阻抗z。
wire型信號可以用作任何方程式的輸入,也可做assign語句或實例元件的輸出。
聲明格式
wire [n-1:0] 變量名1,變量名2,...變量名i; //共有i條總線,每條總線內有n條線路。 /*其中[n-1:0]也可以寫成[n:1],代表該變量的位寬有多少位,若省略方括號部分, 則表示位寬為1位。一次定義多個變量是,變量名之間用逗號分隔開,語句最后用分號結束。*///例如 wire a,b; //定義2個1位的wire型變量a和b wire [7:0] c; //定義1個8為的wire型變量線網型變量的賦值(也就是驅動)不能在always塊內對其賦值,只能通過數據流assign操作來完成。
wire [3:0] w1; //定義1個8為的wire型變量 assign w1 = 4'b1011; //要用assign來賦值,此句不能出現在always塊內在端口說明中被聲明為 input,inout 型的端口只能被定義為線網型變量,被聲明為 output 型的端口可定義為線網型或寄存器型。如果不加定義,默認為線網型。
3.3.2 reg型(寄存器型)
reg型變量是最常用的 variable 型變量。
寄存器是存儲數據存儲單元的抽象。
reg 型變量并不意味著一定對應著硬件上的觸發器和寄存器,而是根據具體情況來確定其映射為寄存器或連線。
在always塊內被賦值的每一個信號都必須定義為 reg 型,而 reg 行也暗示了被定義的信號將用在 always 塊內。
3.4 運算符
3.4.1 算數運算符
| + | 加 |
| - | 減 |
| * | 乘 |
| / | 除 |
| % | 取余 |
| ** | 乘方 |
3.4.2 關系運算符
| > | 大于 |
| < | 小于 |
| >= | 大于等于 |
| <= | 小于等于 |
| == | 邏輯相等 |
| != | 邏輯不相等 |
| === | 全等 |
| !=== | 非全等 |
3.4.3 邏輯運算符
| && | 邏輯與 |
| || | 邏輯或 |
| ! | 邏輯非 |
3.4.4 位運算符
| & | 按位與 |
| | | 按位或 |
| ~ | 按位非 |
| ^ | 按位異或 |
3.4.5 條件運算符
x ? a : b/*通過判斷條件表達式x的真假,從2個表達式中選1個作為輸出結果。 */ 偽代碼: 變量 = 條件表達式 ? (表達式1):(表達式2) /* 如果表達式結果為真,則輸出表達式1,否則輸出表達式2 *///if寫法 if(條件表達式) {;//表達式1 } else {;//表達式2 }3.4.6 位拼接運算符
位拼接運算符可以將兩個或更多信號的某些位拼接起來進行運算操作。
{信號1的某幾位,信號2的某幾位,…,信號n的某幾位}
4 Verilog HDL 基本語句
4.1 選擇語句
4.1.1 if 語句
if(條件表達式)語句1; else語句2;if(條件表達式1)語句1; else if(條件表達式2)語句2; else if(條件表達式3)語句3; else語句4;“語句1”和“語句2”都可以換成用begin和end之間的語句塊。
“語句1”和“語句2”如果都是 if 語句,其 else 語句可有可無,這樣會形成嵌套,看起來比較復雜,甚至會產生歧義。
4.1.1 case 語句
case(控制表達式)分支表達式1: 執行語句1;分支表達式2: 執行語句2;...分支表達式n-1: 執行語句n-1;default : 執行語句n; endcasecase語句和C語言中的switch語句相似,且功能相同,但是用法不同。
4.2 重復語句
4.2.1 for 循環語句
for(i=0;i<6;i++) begin循環語句1;循環語句2; end4.2.2 while 循環語句
while(i<3) begin$ display("Hello word, %d",i);i = i + 1; end4.2.3 repeat 循環語句
repeat(循環次數) 過程語句;
- 這種循環語句執行指定的循環次數的過程語句。
- 如果循環次數表達式的值不確定,即為x或z時,那么循環次數按0處理。
4.2.4 forever 循環語句
- orever 必須寫在 initial 過程塊中;
- 用法和 repeat 循環語句相同;
4.3 任務和函數語句
4.3.1 task 任務
定義格式:
task 任務名輸入和輸出聲明; // 聲明的順序很重要,決定了被調用時傳遞給任務的變量順序局部變量聲明;begin...end endtask定義格式:
4.3.2 function 函數
function <返回值的類型或者函數聲明> 函數名輸入聲明; // 聲明的順序很重要,決定了被調用時傳遞給任務的變量順序局部變量聲明;begin...end endfunction5 Verilog HDL 數據流建模
5.1 連續賦值語句 assign
用數據流描述方式建模,最基本的機制就是使用連續賦值語句 assign 語句。在連續賦值語句中,某個值被指派給線網型變量。
連續賦值語句的主要特點如下:
- 連續賦值語句等號左邊的變量必須是線網型(wire型)的,不能是寄存器型(reg型)的。寄存器型變量的賦值只能是在過程塊(initial / always)中進行。
- assign 不能出現在過程塊(initial / always)中。
- 等號右邊的表達式中,操作數可以是線網型變量或寄存器型變量。
- 連續賦值語句總是處于激活狀態。只要等號右邊的表達式中任意一個操作數發生變化,表達式就會立即重新計算,并檢結果賦給等號左邊的線網型變量。
- 連續賦值語句是并發執行的,多個 assign 語句之間的執行次序與出現次序無關。
6 宏定義寫法
`define W_IDLE 4'd0 // 定義常量 `define end_trp cnt_clk == TRP_CLK // 定義表達式7 文件包含寫法
`include "sdram_para.v" //調用里面的定義,end_trsc I_DONE I_TRSC 均為里面的宏定義 init_state <= (`end_trsc) ? `I_DONE : `I_TRSC;未完待續…
引用:
【1】 劉昌華,班鵬新,周勁.數字邏輯原理與FPGA設計[M]. 北京:北京航空航天大學出版社,2021.1
總結
以上是生活随笔為你收集整理的Verilog HDL学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多点温度监控:ESP32+MAX3186
- 下一篇: matlab总线,MATLAB SIMU