• 正文
    • 一、Verilog HDL 簡介
    • 二、Verilog HDL 程序基本結(jié)構(gòu)
    • 三、Verilog HDL 語言的數(shù)據(jù)類型和運(yùn)算符
    • 四、Verilog HDL 語言的描述語句
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

Verilog HDL 語法學(xué)習(xí)筆記

02/05 13:17
1226
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

大俠好,歡迎來到FPGA技術(shù)江湖,江湖偌大,相見即是緣分。大俠可以關(guān)注FPGA技術(shù)江湖,在“闖蕩江湖”、"行俠仗義"欄里獲取其他感興趣的資源,或者一起煮酒言歡。

今天給大俠帶來Verilog HDL 語法學(xué)習(xí)筆記,話不多說,上貨。

一、Verilog HDL 簡介

1.1 Verilog HDL 的歷史

Verilog HDL 語言最初是作為 Gateway Design Automation 公 司 ( Gateway DesignAutomation 公司后來被著名的 Cadence Design Systems 公司收購)模擬器產(chǎn)品開發(fā)的硬件建模語言。

開始 Verilog HDL 只是一種專用語言,隨著 Gateway Design Automation 公司模擬、仿真器產(chǎn)品的廣泛使用,Verilog HDL 便于使用、實用的語言逐漸為眾多設(shè)計者所接受。1995年 Verilog HDL 正式成為 IEEE 標(biāo)準(zhǔn),稱為 IEEE Std 1364-1995。

1.2 Verilog HDL 的特點

Verilog HDL 語言不僅定義了語法,而且對每個語法結(jié)構(gòu)都定義了清晰的模擬、仿真語義。使用這種語言編寫的模型可以方便地使用 Verilog 仿真器進(jìn)行驗證。Verilog HDL 從 C 語言中繼承了多種操作符和結(jié)構(gòu)。Verilog HDL 提供了擴(kuò)展的建模能力和擴(kuò)展模塊。Verilog HDL 語言的核心子集非常易于學(xué)習(xí)和使用,這對大多數(shù)建模應(yīng)用來說已經(jīng)足夠。

Verilog HDL 之所以成為和 VHDL 并駕齊驅(qū)的硬件描述語言,是因為它具有如下特點:

? 基本邏輯門開關(guān)級基本結(jié)構(gòu)模型都內(nèi)置在語言中;

? 可采用多種方式對設(shè)計建模,這些方式包括行為描述方式、數(shù)據(jù)流方式、結(jié)構(gòu)化方式;

? Verilog HDL 中有線網(wǎng)(Wire)數(shù)據(jù)類型和寄存器(Reg)數(shù)據(jù)類型兩類數(shù)據(jù)類型,線網(wǎng)類型表示構(gòu)件間的物理連線,而寄存器類型表示抽象的數(shù)據(jù)存儲元件;

? 能夠描述層次設(shè)計,可使用模塊實例結(jié)構(gòu)描述任何層次;

? 設(shè)計的規(guī)模可以是任意的,語言不對設(shè)計的規(guī)模大小施加任何限制;

? Verilog HDL 不再是某些公司的專有語言而是 IEEE 標(biāo)準(zhǔn);

? Verilog HDL 語言的描述能力能夠通過使用編程語言接口(Programme LanguageInterface,簡稱 PLI)機(jī)制進(jìn)一步擴(kuò)展,PLI 允許外部函數(shù)訪問 Verilog 模塊內(nèi)信息、允許設(shè)計者與模擬器交互的例程集合;

? 設(shè)計能夠在多個層次上加以描述,從開關(guān)級、門級、寄存器傳送級(RT L)到算法級,包括進(jìn)程和隊列級;

? Verilog HDL 能夠監(jiān)控模擬驗證的執(zhí)行,即模擬驗證執(zhí)行過程中設(shè)計的值能夠被監(jiān)控和顯示,這些值也能夠用于與期望值比較,在不匹配的情況下打印報告消息。

二、Verilog HDL 程序基本結(jié)構(gòu)

模塊是 Verilog 的基本描述單位,描述某個設(shè)計的功能或結(jié)構(gòu)及其與其他模塊通信的外部端口。一個模塊的基本語法如下:

module module_name//模塊名稱  (port_list);//輸入輸出信號列表  //說明  reg //寄存器  wire//線網(wǎng)  parameter//參數(shù)  input//輸入信號  output//輸出信號  inout//輸入輸出信號  function//函數(shù)  task//任務(wù)  . . .//語句  Initial statement  Always statement  Module instantiation//  Gate instantiation//  UDP instantiation//  Continuous assignment//endmodule

說明部分用于定義不同的項,例如模塊描述中使用的寄存器和參數(shù)、語句定義設(shè)計的功能和結(jié)構(gòu)。說明部分和語句可以放置在模塊中的任何地方,但是變量、寄存器、線網(wǎng)和參數(shù)等的說明部分必須在使用前出現(xiàn)。為了使模塊描述清晰和具有良好的可讀性, 最好將所有的說明部分放在語句前。

圖 1 所示的是一個半加器。

圖 1 半加器

這個半加器用 Verilog HDL 實現(xiàn),代碼如下:

module HalfAdder(A,B,Sum,Carry) ;        input A,B;    output Sum, Carry;        assign #2 Sum = A ^ B;    assign #5 Carry = A & B;    endmodule

模塊的名字是 HalfAdder。模塊有 4 個端口:兩個輸入端口 A 和 B,兩個輸出端口 Sum 和Carry。由于沒有定義端口的位數(shù),所有端口大小都為 1 位;同時由于沒有各端口的數(shù)據(jù)類型說明,這 4 個端口都是線網(wǎng)數(shù)據(jù)類型。模塊包含兩條描述半加器數(shù)據(jù)流行為的連續(xù)賦值語句。從這種意義上講,這些語句在模塊中出現(xiàn)的順序無關(guān)緊要,因為這些語句是并發(fā)的。每條語句的執(zhí)行順序依賴于發(fā)生在變量 A 和 B 上的事件。

三、Verilog HDL 語言的數(shù)據(jù)類型和運(yùn)算符

本篇介紹 Verilog HDL 語言的基本要素,包括標(biāo)識符、注釋、數(shù)值、編譯程序指令、系統(tǒng)任務(wù)和系統(tǒng)函數(shù)、兩種主要的數(shù)據(jù)類型。

3.1 標(biāo)識符

Verilog HDL 中的標(biāo)識符可以是任意一組字母、數(shù)字、$符號和_(下劃線)符號的組合,但標(biāo)識符的第一個字符必須是字母或者下劃線。另外,標(biāo)識符是區(qū)分大小寫的。以下是標(biāo)識符的幾個例子:

PieroPIERO / /與 Piero 不同。_a1_b2c00_68ABC$

3.2 數(shù)據(jù)類型

Verilog HDL 有兩大類數(shù)據(jù)類型:

? 線網(wǎng)類型,表示 Verilog HDL 結(jié)構(gòu)化元件間的物理連線,它的值由驅(qū)動元件的值決定,例如連續(xù)賦值或門的輸出,線網(wǎng)的缺省值為 z(高阻態(tài));

? 寄存器類型,表示一個抽象的數(shù)據(jù)存儲單元,它只能在 always 語句和 initial 語句中被賦值,并且它的值被保存下來,缺省值為 x(未知狀態(tài))。

1)線網(wǎng)類型

線網(wǎng)數(shù)據(jù)類型包含下述不同種類的線網(wǎng)子類型:wire、tri、wor、trior、wand、triand、trireg、tri1、tri0、supply0、supply1。簡單的線網(wǎng)類型說明語法為:

net_kind [msb:lsb] net1, net2, . . . , netN;

net_kind 是上述線網(wǎng)類型的一種。msb 和 lsb 是用于定義線網(wǎng)范圍的常量表達(dá)式,范圍定義是可選的;如果沒有定義范圍,缺省的線網(wǎng)類型為 1 位。下面是一個線網(wǎng)類型說明實例。

wire Rdy, Start; //2 個 1 位的連線。wand [2:0] Addr; //Addr 是 3 位線與。

2)寄存器類型

有 5 種不同的寄存器類型:reg、integer、time、real 和 realtime。寄存器數(shù)據(jù)類型 reg是最常見的數(shù)據(jù)類型。reg 類型使用保留字 reg 加以說明,形式如下:

reg [msb: lsb] reg1, reg2, . . . regN;

msb 和 lsb 定義了范圍,并且均為常數(shù)值表達(dá)式。范圍定義是可選的,如果沒有定義范圍,缺省值為 1 位寄存器。例如:

reg [3:0] Sat; //Sat 為 4 位寄存器。reg Cnt; //1 位寄存器。reg [1:32] Kisp, Pisp, Lisp;

3.3 模塊端口

模塊端口是指模塊與外界交流信息的接口,包括 3 種:

? in:模塊通過這個接口從外界環(huán)境讀取數(shù)據(jù),是不可寫的;

? out:模塊通過這個接口向外界環(huán)境輸出數(shù)據(jù),是不可讀的;

? inout:模塊可以通過這個接口從外界環(huán)境讀取并輸出數(shù)據(jù),數(shù)據(jù)可以雙向流通。

3.4?值集合

Verilog HDL 有下列 4 種基本的值:

? 0:邏輯 0 或“假”;

? 1:邏輯 1 或“真”;

? x:未知;

? z:高阻。

這 4 種值的解釋都內(nèi)置于語言中。如一個為 z 的值總是意味著高阻抗,一個為 0 的值通常是指邏輯 0。在門的輸入或一個表達(dá)式中的為“z”的值通常解釋成“x”。此外,x 值和 z 值都是不分大小寫的。也就是說,值 0x1z 與值 0X1Z 相同。Verilog HDL 中的常量是由以上這四類基本值組成的。

Verilog HDL 中有 3 類常量:整型、實數(shù)型和字符串型。下劃線符號(_)可以隨意用在整數(shù)或?qū)崝?shù)中,它們就數(shù)量本身沒有意義。它們能用來提高易讀性;惟一的限制是下劃線符號不能用作為首字符。

1)整型數(shù)

整型數(shù)可以按如下兩種方式書寫:簡單的十進(jìn)制數(shù)格式和基數(shù)格式。

簡單的十進(jìn)制形式的整數(shù)定義為帶有一個可選的“+”(一元)或“-”(一元)操作符的數(shù)字序列。下面是這種簡易十進(jìn)制形式整數(shù)的例子:

32;// 十進(jìn)制數(shù) 32-15;// 十進(jìn)制數(shù)-15

基數(shù)格式的格式為:

[size ] 'base value

size 定義以位計的常量的位長,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ū)分大小寫。下面是一些具體實例:

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),即 xxxxxxx4'hZ;// 4 位 z(擴(kuò)展的 z) , 即 zzzz4'd-4;//非法,數(shù)值不能為負(fù)8'h 2 A;//在位長和字符之間,以及基數(shù)和數(shù)值之間允許出現(xiàn)空格3' b001;//非法: `和基數(shù) b 之間不允許出現(xiàn)空格(2+3)'b10;// 非法:位長不能夠為表達(dá)式

2)實數(shù)

實數(shù)可以用下列兩種形式定義:

? 十進(jìn)制計數(shù)法,例如 2.0、5.678、1、1572.12;

? 科學(xué)計數(shù)法,例如 23_5.1e2(其值為 23510.0,忽略下劃線)、3.6E2(360.0)。

3)字符串

字符串是雙引號內(nèi)的字符序列。字符串不能分成多行書寫,例如:

"INTERNAL ERROR"" REACHED->HERE "

用 8 位 ASCII 值表示的字符可看作是無符號整數(shù)。因此字符串是 8 位 ASCII 值的序列。為存儲字符串“INTERNAL ERROR”,變量需要 8 * 1 4 位。

reg [1 : 8*14] Message;. . .Message = "INTERNAL ERROR"

反斜線()用于對確定的特殊字符轉(zhuǎn)義。

n 換行符t 制表符 字符本身" 字符"206 八進(jìn)制數(shù) 2 0 6 對應(yīng)的字符

3.5?表達(dá)式

表達(dá)式是 Verilog HDL 語言中進(jìn)行邏輯運(yùn)算和表達(dá)最基本的元素。表達(dá)式由操作符和操作數(shù)按照一定的規(guī)則組合而成,下面進(jìn)行詳細(xì)介紹。

1)操作數(shù)

操作數(shù)的類型包括:常量、參數(shù)、線網(wǎng)、寄存器、存儲器單元和函數(shù)調(diào)用等。

常量的使用規(guī)則在3.4 中進(jìn)行說明,下面是一些實例:

256,7 //非定長的十進(jìn)制數(shù)4'b10_11, 8'h0A // 定長的整型常量'b1, 'hFBA // 非定長的整數(shù)常量90.00006 // 實數(shù)型常量"BOND" // 串常量;每個字符作為 8 位 ASCII 值存儲

表達(dá)式中的整數(shù)值可被解釋為有符號數(shù)或無符號數(shù)。參數(shù)類似于常量,并且使用參數(shù)聲明進(jìn)行說明。下面是參數(shù)說明實例:

parameterLOAD = 4'd12, STORE = 4'd10;

LOAD 和 STORE 為參數(shù)的例子,值分別被聲明為 12 和 10。

線網(wǎng)在表達(dá)式中可以分別按照標(biāo)量和向量兩種方式使用,下面是線網(wǎng)說明實例:

wire [0:3] Prt; //Prt 為 4 位向量線網(wǎng)wire Bdq; //Bbq 是標(biāo)量線網(wǎng)

線網(wǎng)中的值被解釋為無符號數(shù)。例如在連續(xù)賦值語句中:

assign Prt = -3;

Prt 被賦于位向量 1101,實際上為十進(jìn)制的 13,例如在下面的連續(xù)賦值中:

assign Prt = 4'HA;

Prt 被賦于位向量 1010,即為十進(jìn)制的 10。

寄存器也是可以按照標(biāo)量和向量兩種方式使用。寄存器變量使用寄存器聲明進(jìn)行說明,例如:

integer TemA, TemB;reg [1:5] State;time Que [ 1:5 ] ;

整型寄存器中的值被解釋為有符號的二進(jìn)制補(bǔ)碼數(shù),而 reg 寄存器或時間寄存器中的值被解釋為無符號數(shù),實數(shù)和實數(shù)時間類型寄存器中的值被解釋為有符號浮點數(shù)。例如下面的寄存器代碼:

TemA = -10; //TemA 值為位向量 10110,是 10 的二進(jìn)制補(bǔ)碼TemA = 'b1011; //TemA 值為十進(jìn)制數(shù) 11State = -10; //State 值為位向量 10110,即十進(jìn)制數(shù) 22State = 'b1011; // State 值為位向量 01011,是十進(jìn)制值 11

在 Verilog HDL 語言中,對于向量形式的線網(wǎng)和寄存器,都可以采用部分選擇的方式使用向量中需要的部分。在部分選擇中,向量的連續(xù)序列被選擇,形式如下:

net_or_reg_vector [msb_const_expr:1sb_const_expr]//部分選擇的語法形式State [1:4] //寄存器部分選擇Prt [1:3] // 線網(wǎng)部分選擇

存儲器單元的定義形式如下:

memory [word_address] //定義形式reg [1:8] Ack, Dram [ 0 : 6 3 ] ;//例子. . .Ack = Dram [60]; //存儲器的第 6 0 個單元

不允許對存儲器變量值部分選擇或位選擇。例如:

Dram [60] [2] //使用錯誤Dram [60] [2:4]//使用錯誤

在存儲器中讀取一個位或部分選擇一個字的方法如下:將存儲器單元賦值給寄存器變量,然后對該寄存器變量采用部分選擇或位選擇操作。

2)操作符

Verilog HDL語言中的操作符包括:

? 算術(shù)操作符 +(加法)、-(減法)、×(乘法)、÷(除法)和%(取模)。

? 關(guān)系操作符 >(大于)、<(小于)、≥(大于等于)和≤(小于等于),計算結(jié)果為真(1)或者假(0)。

? 相等操作符 ==(邏輯相等)、!=(邏輯不相等)、===(邏輯全等)和!==(非全等)。

? 邏輯操作符 &&(邏輯與)、||(邏輯或)、?。ㄟ壿嫹牵?。

? 按位操作符 ~(一元非)、&(二元與)、|(二元或)、^(二元異或)和~^(二元異或非)。

? 移位操作符 <<(左移)、>>(右移)。

? 條件操作符 條件操作符根據(jù)條件表達(dá)式的值選擇表達(dá)式。

四、Verilog HDL 語言的描述語句

Verilog HDL 語言的描述語句有結(jié)構(gòu)化建模方式、數(shù)據(jù)流建模方式和行為建模方式 3 種。

4.1 結(jié)構(gòu)化建模方式

Verilog HDL 中可以使用內(nèi)置基本門來進(jìn)行硬件描述。Verilog HDL 中提供下列內(nèi)置基本門:

? 多輸入門 and(與門)、nand(與非門)、or(或門)、nor(或非門)、xor(異或門)。

? 多輸出門 buf(緩沖門)、not(取反)。

? 三態(tài)門 bufif0、bufif1、notif0、notif1。

? 上拉、下拉電阻 pullup(上拉電阻)、pulldown(下拉電阻)。

? MOS 開關(guān) cmos、nmos、pmos、rcmos、rnmos、rpmos。

? 雙向開關(guān) tran、tranif0、tranif1、rtran、rtranif0、rtranif1。

門級邏輯設(shè)計描述中可使用具體的門實例語句。下面是簡單的門實例語句的格式:

gate_type[instance_name] (term1, term2, . . . ,termN ) ;

其中 instance_name 是可選的,gate_type 為前面列出的某種門類型。各 term 用于表示與門的輸入/輸出端口相連的線網(wǎng)或寄存器。同一門類型的多個實例能夠在一個結(jié)構(gòu)形式中定義。語法如下:

gate_type[instance_name1] (term11, term12, . . .,term1N ) ,[instance_name2] (term21, term22, . . .,term2N ) ,. . .[instance_nameM] (termM1, termM2, . . .,termMN)

下面是一個用結(jié)構(gòu)化建模方式實現(xiàn)的多路選擇電路的例子,如圖 2 所示。

圖 2?多路選擇電路

多路選擇電路如果用結(jié)構(gòu)化建模方式實現(xiàn),代碼如下:

module MUX4x1 (Z , D0 , D1 , D2 , D3 , S0 , S1) ;
  input D0 , D1 , D2 , D3 , S0 , S1;    output Z;    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ù)賦值語句來實現(xiàn)。Verilog HDL 中有兩種形式的賦值方式:連續(xù)賦值和過程賦值。其中過程賦值用于順序行為建模,而組合邏輯電路的行為最好使用連續(xù)賦值語句建模。

連續(xù)賦值語句將值賦給線網(wǎng)(連續(xù)賦值不能為寄存器賦值),它的格式如下:

assign LHS_target = RHS_expression;//定義格式//例子wire [3:0] Z, Preset, Clear; //線網(wǎng)說明assign Z = Preset & Clear; //連續(xù)賦值語句

連續(xù)賦值的目標(biāo)為 Z,表達(dá)式右端為“Preset & Clear”,連續(xù)賦值語句中的關(guān)鍵詞為assign。只要在右端表達(dá)式的操作數(shù)上有事件(事件為值的變化)發(fā)生時,連續(xù)賦值語句即被計算,如果結(jié)果值有變化,新結(jié)果就賦給左邊的線網(wǎng)。在上面的例子中,如果 Preset 或 Clear變化,就計算右邊的整個表達(dá)式。如果結(jié)果變化,那么結(jié)果即賦值到線網(wǎng) Z。

如圖 3 所示的是主從觸發(fā)器。

圖 3 主從觸發(fā)器

主從觸發(fā)器用連續(xù)賦值語句實現(xiàn)的代碼如下:

module MSDFF_DF (D, C, Q, Qbar) ;
    input D, C;    output Q, Qbar;        wire NotC, NotD, NotY, Y, D1, D2, Ybar, Y1, Y2 ;        assign NotD = ~ D;    assign NotC = ~ C;    assign NotY = ~ Y;    assign D1 = ~ (D & C) ;    assign D2 = ~ (C & NotD) ;    assign Y = ~ (D1 & Ybar ) ;    assign Ybar = ~ (Y & D2) ;    assign Y1 = ~ (Y & NotC ) ;    assign Y2 = ~ (NotY & NotC) ;    assign Q = ~ (Qbar & Y1) ;    assign Qbar = ~ (Y2 & Q) ;    endmodule

4.3?行為建模方式

行為建模方式是用過程賦值語句來實現(xiàn)的。下面對行為建模方式的各個部分進(jìn)行詳細(xì)介紹。

1)過程結(jié)構(gòu)

Verilog HDL 中的主要行為通過兩種語句來控制進(jìn)行:

? initial 語句;

? always 語句。

initial 語句在模擬開始時執(zhí)行,即在 0 時刻開始執(zhí)行。initial 語句只執(zhí)行一次,它的語法如下:

initial[timing_control] procedural_statement

這里的時序控制可以是延時控制,即等待一個確定的時間;或事件控制,即等待確定的事件發(fā)生或某一特定的條件為真。initial 語句的各個進(jìn)程語句僅執(zhí)行一次。initial 語句根據(jù)進(jìn)程語句中出現(xiàn)的時間控制在以后的某個時間完成執(zhí)行。下面是一個 initial 語句實例:

  parameter SIZE = 1024;    reg [7:0] RAM [ 0:SIZE- 1 ] ;  reg RibReg;    initial  begin: SEQ_BLK_A    integer Index;      RibReg = 0;    for (Index = 0; Index < SIZE; Index = Index + 1)      RAM[Index] = 0;  End

與 initial 語句相反,always 語句可重復(fù)執(zhí)行。與 initial 語句類似,always 語句語法如下:

always[timing_control]procedural_statement

下面是一個 always 語句的實例。

    reg [0:5] InstrReg;    reg [3:0] Accum;        wire ExecuteCycle;        always@ (EcecuteCycle) //發(fā)生在某個時鐘沿    begin        case(InstrReg[ 0 : 1 ] )//多路條件分支            2'b00: Store (Accum, InstrReg[2:5]) ;//存儲            2'b11: Load (Accum, InstrReg[2:5]) ;//讀取            2'b01: Jump (InstrReg[ 2 : 5 ] ) ;//跳轉(zhuǎn)            2'b10: ;        endcase    end

2)時序控制

Verilog HDL 中進(jìn)行時序控制分別通過下面兩種方式進(jìn)行:

? 延時控制;

? 事件控制。

延時控制的語法如下:

#delay procedural_statement

延時控制定義為執(zhí)行過程中首次遇到該語句與該語句的執(zhí)行的時間間隔。延時控制表示在語句執(zhí)行前的“等待時延”。下面是一個延時控制的例子:

initialbegin  #3 Wave = 'b0111;//3 個時間單位后執(zhí)行  #6 Wave = 'b1100; //6 個時間單位后執(zhí)行  #7 Wave = 'b0000; //7 個時間單位后執(zhí)行end

事件控制有兩種方式:邊沿觸發(fā)事件控制和電平敏感事件控制。邊沿觸發(fā)事件是指指定信號的邊沿發(fā)生跳變時發(fā)生指定的行為,下面是邊沿觸發(fā)事件控制的語法和實例:

  @ event procedural_statement  //實例  time RiseEdge, OnDelay;    initial  begin      //等待,直到在時鐘上發(fā)生正邊沿:      @ (posedge ClockA) ;      RiseEdge = $time;      //等待,直到在時鐘上發(fā)生負(fù)邊沿:      @ (negedge ClockA) ;      OnDelay = $time - RiseEdge;      $display ("The on-period of clock is %t.", Delay) ;  end

在電平敏感事件控制中,進(jìn)程語句或進(jìn)程中的過程語句一直延遲到條件變?yōu)檎婧蟛艌?zhí)行。下面是電平敏感事件控制的語法和實例:

wait (Condition)procedural_statement//實例wait (Sum > 22) //直到 Sum 大于 22 時發(fā)生Sum = 0;wait (DataReady) //直到 DataReady 為高時發(fā)生Data = Bus;wait (Preset) ; //直到 Preset 為高時才能執(zhí)行后面的語句

3)語句塊

Verilog HDL 在執(zhí)行語句時分為順序和并行兩種方式。在順序語句塊中,語句按給定次序順序執(zhí)行;在并行語句塊中,語句并行執(zhí)行。

順序語句塊的語法和實例如下:

  begin    [:block_id{declarations} ]    procedural_statement(s)  end  //實例  //產(chǎn)生波形  begin    #2 Stream = 1;    #5 Stream = 0;    #3 Stream = 1;    #4 Stream = 0;    #2 Stream = 1;    #5 Stream = 0;  end

并行語句塊的語法和實例如下:

  fork    [:block_id{declarations} ]    procedural_statement(s) ;  join  //實例  //生成波形,生成的波形和前面使用順序語句塊的例子一樣  fork    #2 Stream = 1;    #7 Stream = 0;    #10 Stream = 1;    #14 Stream = 0;    #16 Stream = 1;    #21 Stream = 0;  join

4)過程性賦值

過程性賦值是在 initial 語句或 always 語句內(nèi)的賦值,它只能對寄存器數(shù)據(jù)類型的變量賦值。過程性賦值如下兩類:

? 阻塞性過程賦值:賦值在其后所有語句執(zhí)行前執(zhí)行,即在下一語句執(zhí)行前該賦值語句完成執(zhí)行;

? 非阻塞性過程賦值:對目標(biāo)的賦值是非阻塞的(因為時延),但可預(yù)定在將來某個時間發(fā)生。

阻塞性過程賦值用操作符“=”完成,例如下面的實例:

??always @?(A?or?B?or?Cin)  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ā)生,計算 T1;接著執(zhí)行第二條語句,T2 被賦值;然后執(zhí)行第三條語句, T3被賦值,依此類推直到最后。

非阻塞性過程賦值用操作符“<=”完成,例如下面的實例:

  initial  begin    Clr <= #5 1;    Clr <= #4 0;    Clr <= #10 0;  End

第一條語句的執(zhí)行使 Clr 在第 5 個時間單位被賦于值 1;第二條語句的執(zhí)行使 Clr 第 4 個時間單位被賦值為 0(從 0 時刻開始的第 4 個時間單位);最終第 3 條語句的執(zhí)行使 Clr 在第10 個時間單位被賦值為 0(從 0 時刻開始的第 1 0 個時間單位)。這 3 條語句都是在 0 時刻執(zhí)行的。

5)流程控制語句

流程控制語句包括:

? if 語句;

? case 語句;

? 循環(huán)語句。

if 語句的語法如下:

if(condition_1)procedural_statement_1{else if(condition_2)procedural_statement_2}{elseprocedural_statement_3}

如果對 condition_1 求值的結(jié)果為一個非零值,那么 procedural_statement_1 被執(zhí)行,如果 condition_1 的值為 0、x 或 z,那么 procedural_statement_1 不執(zhí)行。如果存在一個 else分支,那么這個分支被執(zhí)行。

下面是一個 if 語句的例子:

  if(Sum < 60)    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 語句是一個多路條件分支形式,其語法如下:

case(case_expr)case_item_expr{ ,case_item_expr} :procedural_statement. . .. . .[default:procedural_statement]endcase

case 語句首先對條件表達(dá)式 case_expr 求值,然后依次對各分支項求值并進(jìn)行比較,第一個與條件表達(dá)式值相匹配的分支中的語句被執(zhí)行??梢栽?1 個分支中定義多個分支項,這些值不需要互斥。缺省分支覆蓋所有沒有被分支表達(dá)式覆蓋的其他分支。

下面是 case 語句的一個實例:

  always @?(A?or?B?or?OpCode)  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)語句:forever 循環(huán),repeat 循環(huán),while 循環(huán)和 for 循環(huán)。

forever 循環(huán)語句連續(xù)執(zhí)行過程語句。因此為跳出這樣的循環(huán),中止語句可以與過程語句共同使用。同時,在過程語句中必須使用某種形式的時序控制,否則 forever 循環(huán)將在 0 延時后永遠(yuǎn)循環(huán)下去。forever 循環(huán)語句語法和實例如下:

  forever  procedural_statement  //實例  initial  begin      Clock = 0;      # 5 forever      #10 Clock = ~Clock;  end

這一實例產(chǎn)生時鐘波形:時鐘首先初始化為 0,并一直保持到第 5 個時間單位;此后每隔10 個時間單位,時鐘反相一次。

repeat 循環(huán)語句執(zhí)行指定循環(huán)次數(shù),如果循環(huán)計數(shù)表達(dá)式的值不確定,即為 x 或 z 時,那么循環(huán)次數(shù)按 0 處理。下面是 repeat 循環(huán)語句語法和實例如下:

repeat(loop_count)procedural _ statement//實例repeat(Count)@ (posedge Clk) Sum = Sum + 1;//在時鐘上升沿時每次加一

while 循環(huán)執(zhí)行過程賦值語句直到指定的條件為假。如果表達(dá)式在開始時為假,那么過程語句便永遠(yuǎn)不會執(zhí)行。如果條件表達(dá)式為 x 或 z,它也同樣按 0(假)處理。

下面時 while 循環(huán)的語法和實例:

    while(condition)    procedural_statement    //實例,一直執(zhí)行直到 BY 小于等于 0    while (BY > 0 )      begin        Acc = Acc << 1;        By = By - 1;      End

for 循環(huán)照指定的次數(shù)重復(fù)執(zhí)行過程賦值語句。下面是 for 循環(huán)的語法和實例:

  for(initial_assignment ; condition ; step_assignment)  procedural_statement  //實例中,MAX_RANGE 為循環(huán)計次的上限,每次循環(huán)加一  for (K=0 ; K < MAX_RANGE ; K = K + 1)    begin      if(Abus[K] == 0)        Abus[K] = 1;      else if(Abus[k] == 1)        Abus[K] = 0;      else        $display( "Abus[K] is an x or a z");    end end

 

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

任何技術(shù)的學(xué)習(xí)就好比一個江湖,對于每一位俠客都需要不斷的歷練,從初入江湖的小白到歸隱山林的隱世高人,需要不斷的自我感悟自己修煉,讓我們一起仗劍闖FPGA乃至更大的江湖。