大俠好,歡迎來(lái)到FPGA技術(shù)江湖,江湖偌大,相見(jiàn)即是緣分。大俠可以關(guān)注FPGA技術(shù)江湖,在“闖蕩江湖”、"行俠仗義"欄里獲取其他感興趣的資源,或者一起煮酒言歡。
今天給大俠帶來(lái)Verilog HDL 語(yǔ)法學(xué)習(xí)筆記,話不多說(shuō),上貨。
關(guān)于詳細(xì)的VHDL語(yǔ)法以及Verilog HDL語(yǔ)法可參見(jiàn)往期文章。
一周掌握 FPGA VHDL Day 7 暨匯總篇
一周掌握FPGA Verilog HDL語(yǔ)法 匯總篇
Verilog HDL 語(yǔ)法學(xué)習(xí)筆記
一、Verilog HDL 簡(jiǎn)介
1.1 Verilog HDL 的歷史
Verilog HDL 語(yǔ) 言 最 初 是 作為 Gateway Design Automation 公 司 ( Gateway DesignAutomation 公司后來(lái)被著名的 Cadence Design Systems 公司收購(gòu))模擬器產(chǎn)品開(kāi)發(fā)的硬件建模語(yǔ)言。
開(kāi)始 Verilog HDL 只是一種專(zhuān)用語(yǔ)言,隨著 Gateway Design Automation 公司模擬、仿真器產(chǎn)品的廣泛使用,Verilog HDL 便于使用、實(shí)用的語(yǔ)言逐漸為眾多設(shè)計(jì)者所接受。1995年 Verilog HDL 正式成為 IEEE 標(biāo)準(zhǔn),稱(chēng)為 IEEE Std 1364-1995。
1.2 Verilog HDL 的特點(diǎn)
Verilog HDL 語(yǔ)言不僅定義了語(yǔ)法,而且對(duì)每個(gè)語(yǔ)法結(jié)構(gòu)都定義了清晰的模擬、仿真語(yǔ)義。使用這種語(yǔ)言編寫(xiě)的模型可以方便地使用 Verilog 仿真器進(jìn)行驗(yàn)證。Verilog HDL 從 C 語(yǔ)言中繼承了多種操作符和結(jié)構(gòu)。Verilog HDL 提供了擴(kuò)展的建模能力和擴(kuò)展模塊。Verilog HDL 語(yǔ)言的核心子集非常易于學(xué)習(xí)和使用,這對(duì)大多數(shù)建模應(yīng)用來(lái)說(shuō)已經(jīng)足夠。
Verilog HDL 之所以成為和 VHDL 并駕齊驅(qū)的硬件描述語(yǔ)言,是因?yàn)樗哂腥缦绿攸c(diǎn):
? 基本邏輯門(mén)和開(kāi)關(guān)級(jí)基本結(jié)構(gòu)模型都內(nèi)置在語(yǔ)言中;
? 可采用多種方式對(duì)設(shè)計(jì)建模,這些方式包括行為描述方式、數(shù)據(jù)流方式、結(jié)構(gòu)化方式;
? Verilog HDL 中有線網(wǎng)(Wire)數(shù)據(jù)類(lèi)型和寄存器(Reg)數(shù)據(jù)類(lèi)型兩類(lèi)數(shù)據(jù)類(lèi)型,線網(wǎng)類(lèi)型表示構(gòu)件間的物理連線,而寄存器類(lèi)型表示抽象的數(shù)據(jù)存儲(chǔ)元件;
? 能夠描述層次設(shè)計(jì),可使用模塊實(shí)例結(jié)構(gòu)描述任何層次;
? 設(shè)計(jì)的規(guī)??梢允侨我獾模Z(yǔ)言不對(duì)設(shè)計(jì)的規(guī)模大小施加任何限制;
? Verilog HDL 不再是某些公司的專(zhuān)有語(yǔ)言而是 IEEE 標(biāo)準(zhǔn);
? Verilog HDL 語(yǔ)言的描述能力能夠通過(guò)使用編程語(yǔ)言接口(Programme LanguageInterface,簡(jiǎn)稱(chēng) PLI)機(jī)制進(jìn)一步擴(kuò)展,PLI 允許外部函數(shù)訪問(wèn) Verilog 模塊內(nèi)信息、允許設(shè)計(jì)者與模擬器交互的例程集合;
? 設(shè)計(jì)能夠在多個(gè)層次上加以描述,從開(kāi)關(guān)級(jí)、門(mén)級(jí)、寄存器傳送級(jí)(RT L)到算法級(jí),包括進(jìn)程和隊(duì)列級(jí);
? Verilog HDL 能夠監(jiān)控模擬驗(yàn)證的執(zhí)行,即模擬驗(yàn)證執(zhí)行過(guò)程中設(shè)計(jì)的值能夠被監(jiān)控和顯示,這些值也能夠用于與期望值比較,在不匹配的情況下打印報(bào)告消息。
二、Verilog HDL 程序基本結(jié)構(gòu)
模塊是 Verilog 的基本描述單位,描述某個(gè)設(shè)計(jì)的功能或結(jié)構(gòu)及其與其他模塊通信的外部端口。一個(gè)模塊的基本語(yǔ)法如下:
modulemodule_name//模塊名稱(chēng) (port_list);//輸入輸出信號(hào)列表 //說(shuō)明 reg//寄存器 wire//線網(wǎng) parameter//參數(shù) input//輸入信號(hào) output//輸出信號(hào) inout//輸入輸出信號(hào) function//函數(shù) task//任務(wù) . . .//語(yǔ)句 Initialstatement Alwaysstatement Moduleinstantiation// Gateinstantiation// UDPinstantiation// Continuousassignment// endmodule
說(shuō)明部分用于定義不同的項(xiàng),例如模塊描述中使用的寄存器和參數(shù)、語(yǔ)句定義設(shè)計(jì)的功能和結(jié)構(gòu)。說(shuō)明部分和語(yǔ)句可以放置在模塊中的任何地方,但是變量、寄存器、線網(wǎng)和參數(shù)等的說(shuō)明部分必須在使用前出現(xiàn)。為了使模塊描述清晰和具有良好的可讀性, 最好將所有的說(shuō)明部分放在語(yǔ)句前。
圖 1 所示的是一個(gè)半加器。

圖 1 半加器
這個(gè)半加器用 Verilog HDL 實(shí)現(xiàn),代碼如下:
moduleHalfAdder(A,B,Sum,Carry); inputA,B; output Sum, Carry; assign#2 Sum = A ^ B; assign#5 Carry = A & B; endmodule
模塊的名字是 HalfAdder。模塊有 4 個(gè)端口:兩個(gè)輸入端口 A 和 B,兩個(gè)輸出端口 Sum 和Carry。由于沒(méi)有定義端口的位數(shù),所有端口大小都為 1 位;同時(shí)由于沒(méi)有各端口的數(shù)據(jù)類(lèi)型說(shuō)明,這 4 個(gè)端口都是線網(wǎng)數(shù)據(jù)類(lèi)型。模塊包含兩條描述半加器數(shù)據(jù)流行為的連續(xù)賦值語(yǔ)句。從這種意義上講,這些語(yǔ)句在模塊中出現(xiàn)的順序無(wú)關(guān)緊要,因?yàn)檫@些語(yǔ)句是并發(fā)的。每條語(yǔ)句的執(zhí)行順序依賴(lài)于發(fā)生在變量 A 和 B 上的事件。
三、Verilog HDL 語(yǔ)言的數(shù)據(jù)類(lèi)型和運(yùn)算符
本篇介紹 Verilog HDL 語(yǔ)言的基本要素,包括標(biāo)識(shí)符、注釋、數(shù)值、編譯程序指令、系統(tǒng)任務(wù)和系統(tǒng)函數(shù)、兩種主要的數(shù)據(jù)類(lèi)型。
3.1 標(biāo)識(shí)符
Verilog HDL 中的標(biāo)識(shí)符可以是任意一組字母、數(shù)字、$符號(hào)和_(下劃線)符號(hào)的組合,但標(biāo)識(shí)符的第一個(gè)字符必須是字母或者下劃線。另外,標(biāo)識(shí)符是區(qū)分大小寫(xiě)的。以下是標(biāo)識(shí)符的幾個(gè)例子:
Piero PIERO / /與 Piero 不同。 _a1_b2 c00_68 ABC$
3.2 數(shù)據(jù)類(lèi)型
Verilog HDL 有兩大類(lèi)數(shù)據(jù)類(lèi)型:
? 線網(wǎng)類(lèi)型,表示 Verilog HDL 結(jié)構(gòu)化元件間的物理連線,它的值由驅(qū)動(dòng)元件的值決定,例如連續(xù)賦值或門(mén)的輸出,線網(wǎng)的缺省值為 z(高阻態(tài));
? 寄存器類(lèi)型,表示一個(gè)抽象的數(shù)據(jù)存儲(chǔ)單元,它只能在 always 語(yǔ)句和 initial 語(yǔ)句中被賦值,并且它的值被保存下來(lái),缺省值為 x(未知狀態(tài))。
1)線網(wǎng)類(lèi)型
線網(wǎng)數(shù)據(jù)類(lèi)型包含下述不同種類(lèi)的線網(wǎng)子類(lèi)型:wire、tri、wor、trior、wand、triand、trireg、tri1、tri0、supply0、supply1。簡(jiǎn)單的線網(wǎng)類(lèi)型說(shuō)明語(yǔ)法為:
net_kind[msb:lsb]net1, net2, . . . , netN;
net_kind 是上述線網(wǎng)類(lèi)型的一種。msb 和 lsb 是用于定義線網(wǎng)范圍的常量表達(dá)式,范圍定義是可選的;如果沒(méi)有定義范圍,缺省的線網(wǎng)類(lèi)型為 1 位。下面是一個(gè)線網(wǎng)類(lèi)型說(shuō)明實(shí)例。
wireRdy,Start;//2 個(gè) 1 位的連線。 wand [2:0]Addr;//Addr 是 3 位線與。
2)寄存器類(lèi)型
有 5 種不同的寄存器類(lèi)型:reg、integer、time、real 和 realtime。寄存器數(shù)據(jù)類(lèi)型 reg是最常見(jiàn)的數(shù)據(jù)類(lèi)型。reg 類(lèi)型使用保留字 reg 加以說(shuō)明,形式如下:
reg[msb: lsb]reg1, reg2, . . . regN;
msb 和 lsb 定義了范圍,并且均為常數(shù)值表達(dá)式。范圍定義是可選的,如果沒(méi)有定義范圍,缺省值為 1 位寄存器。例如:
reg[3:0] Sat; //Sat 為4位寄存器。 regCnt; //1位寄存器。 reg[1:32] Kisp, Pisp, Lisp;
3.3 模塊端口
模塊端口是指模塊與外界交流信息的接口,包括 3 種:
? in:模塊通過(guò)這個(gè)接口從外界環(huán)境讀取數(shù)據(jù),是不可寫(xiě)的;
? out:模塊通過(guò)這個(gè)接口向外界環(huán)境輸出數(shù)據(jù),是不可讀的;
? inout:模塊可以通過(guò)這個(gè)接口從外界環(huán)境讀取并輸出數(shù)據(jù),數(shù)據(jù)可以雙向流通。
3.4 值集合
Verilog HDL 有下列 4 種基本的值:
? 0:邏輯 0 或“假”;
? 1:邏輯 1 或“真”;
? x:未知;
? z:高阻。
這 4 種值的解釋都內(nèi)置于語(yǔ)言中。如一個(gè)為 z 的值總是意味著高阻抗,一個(gè)為 0 的值通常是指邏輯 0。在門(mén)的輸入或一個(gè)表達(dá)式中的為“z”的值通常解釋成“x”。此外,x 值和 z 值都是不分大小寫(xiě)的。也就是說(shuō),值 0x1z 與值 0X1Z 相同。Verilog HDL 中的常量是由以上這四類(lèi)基本值組成的。
Verilog HDL 中有 3 類(lèi)常量:整型、實(shí)數(shù)型和字符串型。下劃線符號(hào)(_)可以隨意用在整數(shù)或?qū)崝?shù)中,它們就數(shù)量本身沒(méi)有意義。它們能用來(lái)提高易讀性;惟一的限制是下劃線符號(hào)不能用作為首字符。
1)整型數(shù)
整型數(shù)可以按如下兩種方式書(shū)寫(xiě):簡(jiǎn)單的十進(jìn)制數(shù)格式和基數(shù)格式。
簡(jiǎn)單的十進(jìn)制形式的整數(shù)定義為帶有一個(gè)可選的“+”(一元)或“-”(一元)操作符的數(shù)字序列。下面是這種簡(jiǎn)易十進(jìn)制形式整數(shù)的例子:
32;// 十進(jìn)制數(shù) 32 -15;// 十進(jìn)制數(shù)-15
基數(shù)格式的格式為:
[size]'base value
size 定義以位計(jì)的常量的位長(zhǎng),base 為 o 或 O(表示八進(jìn)制)、b 或 B(表示二進(jìn)制)、d或 D(表示十進(jìn)制)、h 或 H(表示十六進(jìn)制),value 是基于 base 的值的數(shù)字序列。值 x 和 z以及十六進(jìn)制中的 a 到 f 不區(qū)分大小寫(xiě)。下面是一些具體實(shí)例:
5'O37;// 5 位八進(jìn)制數(shù) 4'D2;//4 位十進(jìn)制數(shù) 4'B1x_01;// 4 位二進(jìn)制數(shù) 7'Hx;//7 位 x(擴(kuò)展的 x),即 xxxxxxx 4'hZ;// 4 位 z(擴(kuò)展的 z) , 即 zzzz 4'd-4;//非法,數(shù)值不能為負(fù) 8'h 2A;//在位長(zhǎng)和字符之間,以及基數(shù)和數(shù)值之間允許出現(xiàn)空格 3' b001;//非法: `和基數(shù) b 之間不允許出現(xiàn)空格 (2+3)'b10;// 非法:位長(zhǎng)不能夠?yàn)楸磉_(dá)式
2)實(shí)數(shù)
實(shí)數(shù)可以用下列兩種形式定義:
? 十進(jìn)制計(jì)數(shù)法,例如 2.0、5.678、1、1572.12;
? 科學(xué)計(jì)數(shù)法,例如 23_5.1e2(其值為 23510.0,忽略下劃線)、3.6E2(360.0)。
3)字符串
字符串是雙引號(hào)內(nèi)的字符序列。字符串不能分成多行書(shū)寫(xiě),例如:
"INTERNAL ERROR" " REACHED->HERE "
用 8 位 ASCII 值表示的字符可看作是無(wú)符號(hào)整數(shù)。因此字符串是 8 位 ASCII 值的序列。為存儲(chǔ)字符串“INTERNAL ERROR”,變量需要 8 * 1 4 位。
reg [1 : 8*14] Message; . . . Message ="INTERNAL ERROR"
反斜線()用于對(duì)確定的特殊字符轉(zhuǎn)義。
換行符 制表符 \字符本身 "字符" 206八進(jìn)制數(shù)206對(duì)應(yīng)的字符
3.5 表達(dá)式
表達(dá)式是 Verilog HDL 語(yǔ)言中進(jìn)行邏輯運(yùn)算和表達(dá)最基本的元素。表達(dá)式由操作符和操作數(shù)按照一定的規(guī)則組合而成,下面進(jìn)行詳細(xì)介紹。
1)操作數(shù)
操作數(shù)的類(lèi)型包括:常量、參數(shù)、線網(wǎng)、寄存器、存儲(chǔ)器單元和函數(shù)調(diào)用等。
常量的使用規(guī)則在3.4 中進(jìn)行說(shuō)明,下面是一些實(shí)例:
256,7//非定長(zhǎng)的十進(jìn)制數(shù) 4'b10_11, 8'h0A// 定長(zhǎng)的整型常量 'b1, 'hFBA// 非定長(zhǎng)的整數(shù)常量 90.00006// 實(shí)數(shù)型常量 "BOND"http:// 串常量;每個(gè)字符作為 8 位 ASCII 值存儲(chǔ)
表達(dá)式中的整數(shù)值可被解釋為有符號(hào)數(shù)或無(wú)符號(hào)數(shù)。參數(shù)類(lèi)似于常量,并且使用參數(shù)聲明進(jìn)行說(shuō)明。下面是參數(shù)說(shuō)明實(shí)例:
parameterLOAD=4'd12, STORE = 4'd10;
LOAD 和 STORE 為參數(shù)的例子,值分別被聲明為 12 和 10。
線網(wǎng)在表達(dá)式中可以分別按照標(biāo)量和向量?jī)煞N方式使用,下面是線網(wǎng)說(shuō)明實(shí)例:
wire [0:3]Prt;//Prt 為 4 位向量線網(wǎng) wireBdq;//Bbq 是標(biāo)量線網(wǎng)
線網(wǎng)中的值被解釋為無(wú)符號(hào)數(shù)。例如在連續(xù)賦值語(yǔ)句中:
assignPrt = -3;
Prt 被賦于位向量 1101,實(shí)際上為十進(jìn)制的 13,例如在下面的連續(xù)賦值中:
assignPrt =4'HA;
Prt 被賦于位向量 1010,即為十進(jìn)制的 10。
寄存器也是可以按照標(biāo)量和向量?jī)煞N方式使用。寄存器變量使用寄存器聲明進(jìn)行說(shuō)明,例如:
integer TemA, TemB; reg[1:5]State; timeQue[ 1:5 ];
整型寄存器中的值被解釋為有符號(hào)的二進(jìn)制補(bǔ)碼數(shù),而 reg 寄存器或時(shí)間寄存器中的值被解釋為無(wú)符號(hào)數(shù),實(shí)數(shù)和實(shí)數(shù)時(shí)間類(lèi)型寄存器中的值被解釋為有符號(hào)浮點(diǎn)數(shù)。例如下面的寄存器代碼:
TemA= -10; //TemA 值為位向量10110,是10的二進(jìn)制補(bǔ)碼 TemA= 'b1011; //TemA 值為十進(jìn)制數(shù)11 State= -10; //State 值為位向量10110,即十進(jìn)制數(shù)22 State= 'b1011; // State 值為位向量01011,是十進(jìn)制值11
在 Verilog HDL 語(yǔ)言中,對(duì)于向量形式的線網(wǎng)和寄存器,都可以采用部分選擇的方式使用向量中需要的部分。在部分選擇中,向量的連續(xù)序列被選擇,形式如下:
net_or_reg_vector [msb_const_expr:1sb_const_expr]//部分選擇的語(yǔ)法形式 State[1:4]//寄存器部分選擇 Prt[1:3]// 線網(wǎng)部分選擇
存儲(chǔ)器單元的定義形式如下:
memory [word_address]//定義形式 reg [1:8]Ack,Dram[0:63] ;//例子 . . . Ack=Dram[60];//存儲(chǔ)器的第 6 0 個(gè)單元
不允許對(duì)存儲(chǔ)器變量值部分選擇或位選擇。例如:
Dram[60][2]//使用錯(cuò)誤 Dram[60][2:4]//使用錯(cuò)誤
在存儲(chǔ)器中讀取一個(gè)位或部分選擇一個(gè)字的方法如下:將存儲(chǔ)器單元賦值給寄存器變量,然后對(duì)該寄存器變量采用部分選擇或位選擇操作。
2)操作符
Verilog HDL語(yǔ)言中的操作符包括:
? 算術(shù)操作符 +(加法)、-(減法)、×(乘法)、÷(除法)和%(取模)。
? 關(guān)系操作符 >(大于)、<(小于)、≥(大于等于)和≤(小于等于),計(jì)算結(jié)果為真(1)或者假(0)。
? 相等操作符 ==(邏輯相等)、!=(邏輯不相等)、===(邏輯全等)和!==(非全等)。
? 邏輯操作符 &&(邏輯與)、||(邏輯或)、?。ㄟ壿嫹牵?。
? 按位操作符 ~(一元非)、&(二元與)、|(二元或)、^(二元異或)和~^(二元異或非)。
? 移位操作符 <<(左移)、>>(右移)。
? 條件操作符 條件操作符根據(jù)條件表達(dá)式的值選擇表達(dá)式。
四、Verilog HDL 語(yǔ)言的描述語(yǔ)句
Verilog HDL 語(yǔ)言的描述語(yǔ)句有結(jié)構(gòu)化建模方式、數(shù)據(jù)流建模方式和行為建模方式 3 種。
4.1 結(jié)構(gòu)化建模方式
Verilog HDL 中可以使用內(nèi)置基本門(mén)來(lái)進(jìn)行硬件描述。Verilog HDL 中提供下列內(nèi)置基本門(mén):
? 多輸入門(mén) and(與門(mén))、nand(與非門(mén))、or(或門(mén))、nor(或非門(mén))、xor(異或門(mén))。
? 多輸出門(mén) buf(緩沖門(mén))、not(取反)。
? 三態(tài)門(mén) bufif0、bufif1、notif0、notif1。
? 上拉、下拉電阻 pullup(上拉電阻)、pulldown(下拉電阻)。
? MOS 開(kāi)關(guān) cmos、nmos、pmos、rcmos、rnmos、rpmos。
? 雙向開(kāi)關(guān) tran、tranif0、tranif1、rtran、rtranif0、rtranif1。
門(mén)級(jí)邏輯設(shè)計(jì)描述中可使用具體的門(mén)實(shí)例語(yǔ)句。下面是簡(jiǎn)單的門(mén)實(shí)例語(yǔ)句的格式:
gate_type[instance_name](term1, term2, . . . ,termN ) ;
其中 instance_name 是可選的,gate_type 為前面列出的某種門(mén)類(lèi)型。各 term 用于表示與門(mén)的輸入/輸出端口相連的線網(wǎng)或寄存器。同一門(mén)類(lèi)型的多個(gè)實(shí)例能夠在一個(gè)結(jié)構(gòu)形式中定義。語(yǔ)法如下:
gate_type [instance_name1] (term11, term12, . . .,term1N ) , [instance_name2] (term21, term22, . . .,term2N ) , . . . [instance_nameM] (termM1, termM2, . . .,termMN)
下面是一個(gè)用結(jié)構(gòu)化建模方式實(shí)現(xiàn)的多路選擇電路的例子,如圖 2 所示。

圖 2 多路選擇電路
多路選擇電路如果用結(jié)構(gòu)化建模方式實(shí)現(xiàn),代碼如下:
moduleMUX4x1 (Z , D0 , D1 , D2 , D3 , S0 , S1) ; inputD0 , D1 , D2 , D3 , S0 , S1; outputZ; and(T0 , D0 , S01 , S11) , (T1, D1 , S01, S1) , (T2, D2 , S0 , S11) , (T3, D3 , S0 , S1) , not(S01, S0) , (S11, S1) ; or(Z , T0 , T1 , T2 , T3) ; endmodule
4.2 數(shù)據(jù)流建模方式
Verilog HDL 中的數(shù)據(jù)流建模方式一般用連續(xù)賦值語(yǔ)句來(lái)實(shí)現(xiàn)。Verilog HDL 中有兩種形式的賦值方式:連續(xù)賦值和過(guò)程賦值。其中過(guò)程賦值用于順序行為建模,而組合邏輯電路的行為最好使用連續(xù)賦值語(yǔ)句建模。
連續(xù)賦值語(yǔ)句將值賦給線網(wǎng)(連續(xù)賦值不能為寄存器賦值),它的格式如下:
assignLHS_target=RHS_expression;//定義格式 //例子 wire [3:0] Z, Preset, Clear;//線網(wǎng)說(shuō)明 assignZ=Preset & Clear;//連續(xù)賦值語(yǔ)句
連續(xù)賦值的目標(biāo)為 Z,表達(dá)式右端為“Preset & Clear”,連續(xù)賦值語(yǔ)句中的關(guān)鍵詞為assign。只要在右端表達(dá)式的操作數(shù)上有事件(事件為值的變化)發(fā)生時(shí),連續(xù)賦值語(yǔ)句即被計(jì)算,如果結(jié)果值有變化,新結(jié)果就賦給左邊的線網(wǎng)。在上面的例子中,如果 Preset 或 Clear變化,就計(jì)算右邊的整個(gè)表達(dá)式。如果結(jié)果變化,那么結(jié)果即賦值到線網(wǎng) Z。
如圖 3 所示的是主從觸發(fā)器。

圖 3 主從觸發(fā)器
主從觸發(fā)器用連續(xù)賦值語(yǔ)句實(shí)現(xiàn)的代碼如下:
moduleMSDFF_DF (D, C, Q, Qbar) ; inputD, C; outputQ, Qbar; wireNotC, NotD, NotY, Y, D1, D2, Ybar, Y1, Y2 ; assignNotD = ~ D; assignNotC = ~ C; assignNotY = ~ Y; assignD1 = ~ (D & C) ; assignD2 = ~ (C & NotD) ; assignY = ~ (D1 & Ybar ) ; assignYbar = ~ (Y & D2) ; assignY1 = ~ (Y & NotC ) ; assignY2 = ~ (NotY & NotC) ; assignQ = ~ (Qbar & Y1) ; assignQbar = ~ (Y2 & Q) ; endmodule
4.3 行為建模方式
行為建模方式是用過(guò)程賦值語(yǔ)句來(lái)實(shí)現(xiàn)的。下面對(duì)行為建模方式的各個(gè)部分進(jìn)行詳細(xì)介紹。
1)過(guò)程結(jié)構(gòu)
Verilog HDL 中的主要行為通過(guò)兩種語(yǔ)句來(lái)控制進(jìn)行:
? initial 語(yǔ)句;
? always 語(yǔ)句。
initial 語(yǔ)句在模擬開(kāi)始時(shí)執(zhí)行,即在 0 時(shí)刻開(kāi)始執(zhí)行。initial 語(yǔ)句只執(zhí)行一次,它的語(yǔ)法如下:
initial [timing_control] procedural_statement
這里的時(shí)序控制可以是延時(shí)控制,即等待一個(gè)確定的時(shí)間;或事件控制,即等待確定的事件發(fā)生或某一特定的條件為真。initial 語(yǔ)句的各個(gè)進(jìn)程語(yǔ)句僅執(zhí)行一次。initial 語(yǔ)句根據(jù)進(jìn)程語(yǔ)句中出現(xiàn)的時(shí)間控制在以后的某個(gè)時(shí)間完成執(zhí)行。下面是一個(gè) initial 語(yǔ)句實(shí)例:
parameterSIZE=1024; reg [7:0] RAM [0:SIZE-1] ; reg RibReg; initial begin: SEQ_BLK_A integerIndex; RibReg=0; for(Index=0; Index
與 initial 語(yǔ)句相反,always 語(yǔ)句可重復(fù)執(zhí)行。與 initial 語(yǔ)句類(lèi)似,always 語(yǔ)句語(yǔ)法如下:
always [timing_control]procedural_statement
下面是一個(gè) always 語(yǔ)句的實(shí)例。
reg [0:5] InstrReg; reg [3:0] Accum; wire ExecuteCycle; always@ (EcecuteCycle)//發(fā)生在某個(gè)時(shí)鐘沿 begin case(InstrReg[0:1])//多路條件分支 2'b00:Store(Accum, InstrReg[2:5]) ;//存儲(chǔ) 2'b11: Load (Accum, InstrReg[2:5]) ;//讀取 2'b01: Jump (InstrReg[2:5] ) ;//跳轉(zhuǎn) 2'b10: ; endcase end
2)時(shí)序控制
Verilog HDL 中進(jìn)行時(shí)序控制分別通過(guò)下面兩種方式進(jìn)行:
? 延時(shí)控制;
? 事件控制。
延時(shí)控制的語(yǔ)法如下:
#delay procedural_statement
延時(shí)控制定義為執(zhí)行過(guò)程中首次遇到該語(yǔ)句與該語(yǔ)句的執(zhí)行的時(shí)間間隔。延時(shí)控制表示在語(yǔ)句執(zhí)行前的“等待時(shí)延”。下面是一個(gè)延時(shí)控制的例子:
initial begin #3 Wave = 'b0111;//3 個(gè)時(shí)間單位后執(zhí)行 #6 Wave = 'b1100; //6 個(gè)時(shí)間單位后執(zhí)行 #7 Wave = 'b0000; //7 個(gè)時(shí)間單位后執(zhí)行 end
事件控制有兩種方式:邊沿觸發(fā)事件控制和電平敏感事件控制。邊沿觸發(fā)事件是指指定信號(hào)的邊沿發(fā)生跳變時(shí)發(fā)生指定的行為,下面是邊沿觸發(fā)事件控制的語(yǔ)法和實(shí)例:
@ event procedural_statement //實(shí)例 time RiseEdge, OnDelay; initial begin //等待,直到在時(shí)鐘上發(fā)生正邊沿: @ (posedge ClockA) ; RiseEdge =$time; //等待,直到在時(shí)鐘上發(fā)生負(fù)邊沿: @ (negedge ClockA) ; OnDelay =$time- RiseEdge; $display("The on-period of clock is %t.", Delay) ; end
在電平敏感事件控制中,進(jìn)程語(yǔ)句或進(jìn)程中的過(guò)程語(yǔ)句一直延遲到條件變?yōu)檎婧蟛艌?zhí)行。下面是電平敏感事件控制的語(yǔ)法和實(shí)例:
wait(Condition) procedural_statement //實(shí)例 wait(Sum >22) //直到 Sum 大于22時(shí)發(fā)生 Sum =0; wait(DataReady) //直到 DataReady 為高時(shí)發(fā)生 Data = Bus; wait(Preset) ;//直到 Preset 為高時(shí)才能執(zhí)行后面的語(yǔ)句
3)語(yǔ)句塊
Verilog HDL 在執(zhí)行語(yǔ)句時(shí)分為順序和并行兩種方式。在順序語(yǔ)句塊中,語(yǔ)句按給定次序順序執(zhí)行;在并行語(yǔ)句塊中,語(yǔ)句并行執(zhí)行。
順序語(yǔ)句塊的語(yǔ)法和實(shí)例如下:
begin [:block_id{declarations} ] procedural_statement(s) end //實(shí)例 //產(chǎn)生波形 begin #2 Stream = 1; #5 Stream = 0; #3 Stream = 1; #4 Stream = 0; #2 Stream = 1; #5 Stream = 0; end
并行語(yǔ)句塊的語(yǔ)法和實(shí)例如下:
fork [:block_id{declarations} ] procedural_statement(s) ; join //實(shí)例 //生成波形,生成的波形和前面使用順序語(yǔ)句塊的例子一樣 fork #2 Stream = 1; #7 Stream = 0; #10 Stream = 1; #14 Stream = 0; #16 Stream = 1; #21 Stream = 0; join
4)過(guò)程性賦值
過(guò)程性賦值是在 initial 語(yǔ)句或 always 語(yǔ)句內(nèi)的賦值,它只能對(duì)寄存器數(shù)據(jù)類(lèi)型的變量賦值。過(guò)程性賦值如下兩類(lèi):
? 阻塞性過(guò)程賦值:賦值在其后所有語(yǔ)句執(zhí)行前執(zhí)行,即在下一語(yǔ)句執(zhí)行前該賦值語(yǔ)句完成執(zhí)行;
? 非阻塞性過(guò)程賦值:對(duì)目標(biāo)的賦值是非阻塞的(因?yàn)闀r(shí)延),但可預(yù)定在將來(lái)某個(gè)時(shí)間發(fā)生。
阻塞性過(guò)程賦值用操作符“=”完成,例如下面的實(shí)例:
always @ (AorBorCin) begin: CARRY_OUT reg T1,T2 , T3; T1 = A & B; T2 = B & Ci n; T3 = A & Ci n; Cout = T1|T2|T3; end
T1 賦值首先發(fā)生,計(jì)算 T1;接著執(zhí)行第二條語(yǔ)句,T2 被賦值;然后執(zhí)行第三條語(yǔ)句, T3被賦值,依此類(lèi)推直到最后。
非阻塞性過(guò)程賦值用操作符“<=”完成,例如下面的實(shí)例:
initial begin Clr<= #5?1; ? ??Clr?<= #4?0; ? ??Clr?<= #10?0; ??End
第一條語(yǔ)句的執(zhí)行使 Clr 在第 5 個(gè)時(shí)間單位被賦于值 1;第二條語(yǔ)句的執(zhí)行使 Clr 第 4 個(gè)時(shí)間單位被賦值為 0(從 0 時(shí)刻開(kāi)始的第 4 個(gè)時(shí)間單位);最終第 3 條語(yǔ)句的執(zhí)行使 Clr 在第10 個(gè)時(shí)間單位被賦值為 0(從 0 時(shí)刻開(kāi)始的第 1 0 個(gè)時(shí)間單位)。這 3 條語(yǔ)句都是在 0 時(shí)刻執(zhí)行的。
5)流程控制語(yǔ)句
流程控制語(yǔ)句包括:
? if 語(yǔ)句;
? case 語(yǔ)句;
? 循環(huán)語(yǔ)句。
if 語(yǔ)句的語(yǔ)法如下:
if(condition_1) procedural_statement_1 {elseif(condition_2) procedural_statement_2} {else procedural_statement_3}
如果對(duì) condition_1 求值的結(jié)果為一個(gè)非零值,那么 procedural_statement_1 被執(zhí)行,如果 condition_1 的值為 0、x 或 z,那么 procedural_statement_1 不執(zhí)行。如果存在一個(gè) else分支,那么這個(gè)分支被執(zhí)行。
下面是一個(gè) if 語(yǔ)句的例子:
if(Sum60) ? ??begin ? ? ? Grade?=?C; ? ? ? Total_C?=?Total_c?+?1; ? ??end else?if(Sum?75) ? ??begin ? ? ? Grade?=?B; ? ? ? Total_B?=?Total_B?+?1; ? ??end else ? ??begin ? ? ? Grade?=?A; ? ? ? Total_A?=?Total_A?+?1; ? ??End
case 語(yǔ)句是一個(gè)多路條件分支形式,其語(yǔ)法如下:
case(case_expr) case_item_expr{ ,case_item_expr} :procedural_statement . . . . . . [default:procedural_statement] endcase
case 語(yǔ)句首先對(duì)條件表達(dá)式 case_expr 求值,然后依次對(duì)各分支項(xiàng)求值并進(jìn)行比較,第一個(gè)與條件表達(dá)式值相匹配的分支中的語(yǔ)句被執(zhí)行。可以在 1 個(gè)分支中定義多個(gè)分支項(xiàng),這些值不需要互斥。缺省分支覆蓋所有沒(méi)有被分支表達(dá)式覆蓋的其他分支。
下面是 case 語(yǔ)句的一個(gè)實(shí)例:
always@ (AorBorOpCode) case(OpCode) ADD_INSTR: Z = A + B; SUB_INSTR: Z = A -B; MULT_INSTR: Z = A * B; DIV_INSTR: Z = A / B; endcase endmodule
Verilog HDL 中提供 4 種循環(huán)語(yǔ)句:forever 循環(huán),repeat 循環(huán),while 循環(huán)和 for 循環(huán)。
forever 循環(huán)語(yǔ)句連續(xù)執(zhí)行過(guò)程語(yǔ)句。因此為跳出這樣的循環(huán),中止語(yǔ)句可以與過(guò)程語(yǔ)句共同使用。同時(shí),在過(guò)程語(yǔ)句中必須使用某種形式的時(shí)序控制,否則 forever 循環(huán)將在 0 延時(shí)后永遠(yuǎn)循環(huán)下去。forever 循環(huán)語(yǔ)句語(yǔ)法和實(shí)例如下:
forever procedural_statement //實(shí)例 initial begin Clock =0; # 5 forever #10 Clock = ~Clock; end
這一實(shí)例產(chǎn)生時(shí)鐘波形:時(shí)鐘首先初始化為 0,并一直保持到第 5 個(gè)時(shí)間單位;此后每隔10 個(gè)時(shí)間單位,時(shí)鐘反相一次。
repeat 循環(huán)語(yǔ)句執(zhí)行指定循環(huán)次數(shù),如果循環(huán)計(jì)數(shù)表達(dá)式的值不確定,即為 x 或 z 時(shí),那么循環(huán)次數(shù)按 0 處理。下面是 repeat 循環(huán)語(yǔ)句語(yǔ)法和實(shí)例如下:
repeat(loop_count) procedural_statement //實(shí)例 repeat(Count) @ (posedgeClk)Sum=Sum+1;//在時(shí)鐘上升沿時(shí)每次加一
while 循環(huán)執(zhí)行過(guò)程賦值語(yǔ)句直到指定的條件為假。如果表達(dá)式在開(kāi)始時(shí)為假,那么過(guò)程語(yǔ)句便永遠(yuǎn)不會(huì)執(zhí)行。如果條件表達(dá)式為 x 或 z,它也同樣按 0(假)處理。
下面時(shí) while 循環(huán)的語(yǔ)法和實(shí)例:
while(condition) procedural_statement //實(shí)例,一直執(zhí)行直到 BY 小于等于 0 while(BY > 0 ) begin Acc = Acc <1; ? ? ? ? By = By - 1; ? ? ? End
for 循環(huán)照指定的次數(shù)重復(fù)執(zhí)行過(guò)程賦值語(yǔ)句。下面是 for 循環(huán)的語(yǔ)法和實(shí)例:
for(initial_assignment ; condition ; step_assignment) procedural_statement //實(shí)例中,MAX_RANGE 為循環(huán)計(jì)次的上限,每次循環(huán)加一 for(K=0; K < MAX_RANGE ; K = K +1) begin if(Abus[K] ==0) Abus[K] =1; elseif(Abus[k] ==1) Abus[K] =0; else $display("Abus[K] is an x or a z"); end end
-
仿真器
+關(guān)注
關(guān)注
14文章
1051瀏覽量
87260 -
Verilog
+關(guān)注
關(guān)注
30文章
1374瀏覽量
114520 -
HDL
+關(guān)注
關(guān)注
8文章
332瀏覽量
48972 -
C語(yǔ)言
+關(guān)注
關(guān)注
183文章
7644瀏覽量
145569
原文標(biāo)題:Verilog HDL 語(yǔ)法學(xué)習(xí)筆記
文章出處:【微信號(hào):HXSLH1010101010,微信公眾號(hào):FPGA技術(shù)江湖】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
verilog語(yǔ)法學(xué)習(xí)心得
FPGA入門(mén):Verilog/VHDL語(yǔ)法學(xué)習(xí)的經(jīng)驗(yàn)之談
FPGA實(shí)戰(zhàn)演練邏輯篇35:語(yǔ)法學(xué)習(xí)的經(jīng)驗(yàn)之談
勇敢的芯伴你玩轉(zhuǎn)Altera FPGA連載29:語(yǔ)法學(xué)習(xí)的經(jīng)驗(yàn)之談
Verilog HDL入門(mén)教程
【特權(quán)同學(xué)推薦】Verilog HDL語(yǔ)法學(xué)習(xí)教程及135個(gè)設(shè)計(jì)實(shí)例
Verilog代碼的基本程序框架
Verilog_HDL的基本語(yǔ)法詳解(夏宇聞版)
Verilog HDL語(yǔ)法學(xué)習(xí)筆記
評(píng)論