接口(Interface)
Verilog模塊之間的連接是通過模塊端口進行的。 為了給組成設(shè)計的各個模塊定義端口,我們必須對期望的硬件設(shè)計有一個詳細的認識。 不幸的是,在設(shè)計的早期,我們很難把握設(shè)計的細節(jié)。 而且,一旦模塊的端口定義完成后,我們也很難改變端口的配置。 另外,一個設(shè)計中的許多模塊往往具有相同的端口定義,在Verilog中,我們必須在每個模塊中進行相同的定義,這為我們增加了無謂的工作量。
SystemVerilog提供了一個新的、高層抽象的模塊連接,這個連接被稱為接口(Interface)。 接口在關(guān)鍵字interface和endinterface之間定義,它獨立于模塊。 接口在模塊中就像一個單一的端口一樣使用。 在最簡單的形式下,一個接口可以認為是一組線網(wǎng)。 例如,可以將PCI總線的所有信號綁定在一起組成一個接口。 通過使用接口,我們在進行一個設(shè)計的時候可以不需要首先建立各個模塊間的互連。 隨著設(shè)計的深入,各個設(shè)計細節(jié)也會變得越來越清晰,而接口內(nèi)的信號也會很容易地表示出來。 當(dāng)接口發(fā)生變化時,這些變化也會在使用該接口的所有模塊中反映出來,而無需更改每一個模塊。 下面是一個接口的使用實例:
1 interface chip_bus;// 定義接口
2
3 wireread_request, read_grant;
4
5 wire [7:0]address, data;
6
7 endinterface: chip_bus
8
9
10
11 module RAM(chip_bus io, // 使用接口
12
13 inputclk);
14
15 //可以使用io.read_request引用接口中的一個信號
16
17 endmodule
18
19
20
21 module CPU(chip_busio, input clk);
22
23 ...
24
25 endmodule
26
27
28
29 module top;
30
31 reg clk = 0;
32
33 chip_busa; // 實例接口
34
35 //將接口連接到模塊實例
36
37 RAM mem(a,clk);
38
39 CPU cpu(a,clk);
40
41 endmodule
實際上,SystemVerilog的接口不僅僅可以表示信號的綁定和互連。 由于SystemVerilog的接口中可以包含參數(shù)、常量、變量、結(jié)構(gòu)、函數(shù)、任務(wù)、initial塊、always塊以及連續(xù)賦值語句,所以SystemVerilog的接口還可以包含內(nèi)建的協(xié)議檢查以及被使用該接口的模塊所共用的功能。
全局聲明和語句
在Verilog中,除了一個模塊可以作為模塊實例引用其他模塊外,并不存在一個全局空間。 另外,Verilog允許任意數(shù)目的頂層模塊,因此會產(chǎn)生毫無關(guān)聯(lián)的層次樹。
SystemVeriog增加了一個被稱為root的隱含的頂級層次。 任何在模塊邊界之外的聲明和語句都存在于root空間中。 所有的模塊,無論它處于哪一個設(shè)計層次,都可以引用$root中聲明的名字。 這樣,如果某些變量、函數(shù)或其它信息被設(shè)計中的所有模塊共享,那么我們就可以將它們作為全局聲明和語句。 全局聲明和語句的一個使用實例如下:
1 reg error_flag; // 全局變量
2
3 function compare(...); // 全局函數(shù)
4
5 always@(error_flag) // 全局語句
6
7 ...
8
9 module test;
10
11 chip1 u1(...)
12
13 endmodule
14
15
16
17 module chip1(...);
18
19 FSM u2(...);
20
21 always@(data)
22
23 error_flag= compare(data, expected);
24
25 endmodule
26
27
28
29 module FSM(...);
30
31 ...
32
33 always @(state)
34
35 error_flag= compare(state, expected);
36
37 終端模塊
時間單位和精度
在Verilog中,表示時間的值使用一個數(shù)來表示,而不帶有任何時間單位。例如:
forever #5clock= ~clock;
從這一句中我們無法判斷5代表的是5ns? 5ps? 還是其他。 Verilog的時間單位和精度是作為每一個模塊的屬性,并使用編譯器指令timescale來設(shè)置。使用這種方法具有固有的缺陷,因為編譯器指令的執(zhí)行依賴于源代碼的編譯順序,編譯器總是將它遇到的最后一個timescale設(shè)置的時間單位和精度作為之后的標(biāo)準(zhǔn)。 那么,假如有些模塊之前沒有使用`timescale設(shè)置時間單位和精度,這就有可能出現(xiàn)同一個源代碼的不同仿真會出現(xiàn)不同結(jié)果的情況。
SystemVerilog為了控制時間單位加入了兩個重要的增強。首先,時間值可以顯式地指定一個單位。時間單位可以是s、ms、ns、ps或fs。時間單位作為時間值的后綴出現(xiàn)。例如:
forever #5nsclock= ~clock;
其次,SystemVerilog允許使用新的關(guān)鍵字(timeunits和timeprecision)來指定時間單位和精度。 這些聲明可以在任何模塊中指定,同時也可以在$root空間中全局指定。 時間單位和精度必須是10的冪,范圍可以從s到fs。 例如:
時間單位 1ns;
timeprecision 10ps;
4. 抽象數(shù)據(jù)類型
Verilog提供了面向底層硬件的線網(wǎng)、寄存器和變量數(shù)據(jù)類型。這些類型代表了4態(tài)邏輯值,通常用來在底層上對硬件進行建模和驗證。線網(wǎng)數(shù)據(jù)類型還具有多個強度級別,并且能夠為多驅(qū)動源的線網(wǎng)提供解析功能。
SystemVerilog包括了C語言的char和int數(shù)據(jù)類型,它允許在Verilog模型和驗證程序中直接使用C和C++代碼。VerilogPLI不再需要集成總線功能模型、算法模型和C函數(shù)。SystemVerilog還為Verilog加入了幾個新的數(shù)據(jù)類型,以便能夠在更抽象的層次上建模硬件。
l char:一個兩態(tài)的有符號變量,它與C語言中的char數(shù)據(jù)類型相同,可以是一個8位整數(shù)(ASCII)或short int(Unicode);
l int:一個兩態(tài)的有符號變量,它與C語言中的int數(shù)據(jù)類型相似,但被精確地定義成32位;
l shortint:一個兩態(tài)的有符號變量,被精確地定義成16位;
l longint:一個兩態(tài)的有符號變量,它與C語言中的long數(shù)據(jù)類型相似,但被精確地定義成64位;
l byte:一個兩態(tài)的有符號變量,被精確地定義成8位;
l bit:一個兩態(tài)的可以具有任意向量寬度的無符號數(shù)據(jù)類型,可以用來替代Verilog的reg數(shù)據(jù)類型;
l logic:一個四態(tài)的可以具有任意向量寬度的無符號數(shù)據(jù)類型,可以用來替代Verilog的線網(wǎng)或reg數(shù)據(jù)類型,但具有某些限制;
l shortreal:一個兩態(tài)的單精度浮點變量,與C語言的float類型相同;
l void:表示沒有值,可以定義成一個函數(shù)的返回值,與C語言中的含義相同。
SystemVerilog的bit和其他數(shù)據(jù)類型允許用戶使用兩態(tài)邏輯對設(shè)計建模,這種方法對仿真性能更有效率。由于Verilog語言沒有兩態(tài)數(shù)據(jù)類型,因此許多仿真器都通過將這種功能作為仿真器的一個選項提供。這些選項不能夠在所有的仿真器之間移植,而且在需要時用三態(tài)或四態(tài)邏輯的設(shè)計中強制使用兩態(tài)邏輯還具有副作用。SystemVerilog的bit數(shù)據(jù)類型能夠極大改進仿真器的性能,同時在需要的時候仍然可以使用三態(tài)或四態(tài)邏輯。通過使用具有確定行為的數(shù)據(jù)類型來代替專有的仿真器選項,兩態(tài)模型能夠在所有的SystemVerilog仿真器間移植。
SystemVerilog的logic數(shù)據(jù)類型比Verilog的線網(wǎng)和寄存器數(shù)據(jù)類型更加靈活,它使得在任何抽象層次上建模硬件都更加容易。logic類型能夠以下面的任何一種方法賦值:
l 通過任意數(shù)目的過程賦值語句賦值,能夠替代Verilog的reg類型;
l 通過單一的連續(xù)賦值語句賦值,能夠有限制地替代Verilog的wire類型;
l 連接到一個單一原語的輸出,能夠有限制地替代Verilog的wire類型;
由于logic數(shù)據(jù)類型能夠被用來替代Verilog的reg或wire(具有限制),這就使得能夠在一個更高的抽象層次上建模,并且隨著設(shè)計的不斷深入能夠加入一些設(shè)計細節(jié)而不必改變數(shù)據(jù)類型的聲明。logic數(shù)據(jù)類型不會表示信號的強度也不具有線邏輯的解析功能,因此logic數(shù)據(jù)類型比Verilog的wire類型更能有效地仿真和綜合。
有符號和無符號限定符
缺省情況下,Verilog net和reg數(shù)據(jù)類型是無符號類型,integer類型是一個有符號類型。Verilog-2001標(biāo)準(zhǔn)允許使用signed關(guān)鍵字將無符號類型顯式地聲明成有符號類型。SystemVerilog加入了相似的能力,它可以通過unsigned關(guān)鍵字將有符號數(shù)據(jù)類型顯式地聲明成有無符號數(shù)據(jù)類型。例如:
int unsigned j;
....
SystemVerilog語言簡介
SystemVerilog是一種硬件描述和驗證語言(HDVL),它基于IEEE1364-2001 Verilog硬件描述語言(HDL),并對其進行了擴展,包括擴充了C語言數(shù)據(jù)類型、結(jié)構(gòu)、壓縮和非壓縮數(shù)組、 接口、斷言等等,這些都使得SystemVerilog在一個更高的抽象層次上提高了設(shè)計建模的能力。 SystemVerilog由Accellera開發(fā),它主要定位在芯片的實現(xiàn)和驗證流程上,并為系統(tǒng)級的設(shè)計流程提供了強大的連接能力。 下面我們從幾個方面對SystemVerilog所作的增強進行簡要的介紹,期望能夠通過這個介紹使大家對SystemVerilog有一個概括性的了解。
接口(Interface)
Verilog模塊之間的連接是通過模塊端口進行的。 為了給組成設(shè)計的各個模塊定義端口,我們必須對期望的硬件設(shè)計有一個詳細的認識。 不幸的是,在設(shè)計的早期,我們很難把握設(shè)計的細節(jié)。 而且,一旦模塊的端口定義完成后,我們也很難改變端口的配置。 另外,一個設(shè)計中的許多模塊往往具有相同的端口定義,在Verilog中,我們必須在每個模塊中進行相同的定義,這為我們增加了無謂的工作量。
SystemVerilog提供了一個新的、高層抽象的模塊連接,這個連接被稱為接口(Interface)。 接口在關(guān)鍵字interface和endinterface之間定義,它獨立于模塊。 接口在模塊中就像一個單一的端口一樣使用。 在最簡單的形式下,一個接口可以認為是一組線網(wǎng)。 例如,可以將PCI總線的所有信號綁定在一起組成一個接口。 通過使用接口,我們在進行一個設(shè)計的時候可以不需要首先建立各個模塊間的互連。 隨著設(shè)計的深入,各個設(shè)計細節(jié)也會變得越來越清晰,而接口內(nèi)的信號也會很容易地表示出來。 當(dāng)接口發(fā)生變化時,這些變化也會在使用該接口的所有模塊中反映出來,而無需更改每一個模塊。 下面是一個接口的使用實例:
interface chip_bus;// 定義接口
wireread_request,read_grant;
有線 [7:0] 地址、數(shù)據(jù);
端界面:chip_bus
module RAM(chip_bus io, // 使用接口
輸入);
//可以使用io.read_request引用接口中的一個信號
終端模塊
模塊CPU(chip_busio,輸入方);
...
終端模塊
模塊頂部;
注冊 clk = 0;
chip_busa; // 實例接口
//將接口連接到模塊實例
RAM mem(a,clk);
中央處理器(a,clk);
終端模塊
實際上,SystemVerilog的接口不僅僅可以表示信號的綁定和互連。 由于SystemVerilog的接口中可以包含參數(shù)、常量、變量、結(jié)構(gòu)、函數(shù)、任務(wù)、initial塊、always塊以及連續(xù)賦值語句,所以SystemVerilog的接口還可以包含內(nèi)建的協(xié)議檢查以及被使用該接口的模塊所共用的功能。
全局聲明和語句
在Verilog中,除了一個模塊可以作為模塊實例引用其他模塊外,并不存在一個全局空間。 另外,Verilog允許任意數(shù)目的頂層模塊,因此會產(chǎn)生毫無關(guān)聯(lián)的層次樹。
SystemVeriog增加了一個被稱為root的隱含的頂級層次。 任何在模塊邊界之外的聲明和語句都存在于root空間中。 所有的模塊,無論它處于哪一個設(shè)計層次,都可以引用$root中聲明的名字。 這樣,如果某些變量、函數(shù)或其它信息被設(shè)計中的所有模塊共享,那么我們就可以將它們作為全局聲明和語句。 全局聲明和語句的一個使用實例如下:
reg error_flag; // 全局變量
function compare(...); // 全局函數(shù)
always@(error_flag) // 全局語句
...
模塊測試;
芯片 1 u1(...)
終端模塊
模塊 chip1(...);
FSM u2(...);
總是@(數(shù)據(jù))
error_flag=比較(數(shù)據(jù),預(yù)期);
終端模塊
模塊有限狀態(tài)機(...);
...
總是@(狀態(tài))
error_flag=比較(狀態(tài),預(yù)期);
終端模塊
時間單位和精度
在Verilog中,表示時間的值使用一個數(shù)來表示,而不帶有任何時間單位。例如:
永遠 #5clock= ~clock;
從這一句中我們無法判斷5代表的是5ns? 5ps? 還是其他。Verilog的時間單位和精度是作為每一個模塊的屬性,并使用編譯器指令timescale來設(shè)置。使用這種方法具有固有的缺陷,因為編譯器指令的執(zhí)行依賴于源代碼的編譯順序,編譯器總是將它遇到的最后一個timescale設(shè)置的時間單位和精度作為之后的標(biāo)準(zhǔn)。那么,假如有些模塊之前沒有使用`timescale設(shè)置時間單位和精度,這就有可能出現(xiàn)同一個源代碼的不同仿真會出現(xiàn)不同結(jié)果的情況。
SystemVerilog為了控制時間單位加入了兩個重要的增強。首先,時間值可以顯式地指定一個單位。時間單位可以是s、ms、ns、ps或fs。時間單位作為時間值的后綴出現(xiàn)。例如:
永遠 #5nsclock= ~clock;
其次,SystemVerilog允許使用新的關(guān)鍵字(timeunits和timeprecision)來指定時間單位和精度。這些聲明可以在任何模塊中指定,同時也可以在$root空間中全局指定。時間單位和精度必須是10的冪,范圍可以從s到fs。例如:
時間單位 1ns;
時間精度10ps;
抽象數(shù)據(jù)類型
Verilog提供了面向底層硬件的線網(wǎng)、寄存器和變量數(shù)據(jù)類型。這些類型代表了4態(tài)邏輯值,通常用來在底層上對硬件進行建模和驗證。線網(wǎng)數(shù)據(jù)類型還具有多個強度級別,并且能夠為多驅(qū)動源的線網(wǎng)提供解析功能。
SystemVerilog包括了C語言的char和int數(shù)據(jù)類型,它允許在Verilog模型和驗證程序中直接使用C和C++代碼。VerilogPLI不再需要集成總線功能模型、算法模型和C函數(shù)。SystemVerilog還為Verilog加入了幾個新的數(shù)據(jù)類型,以便能夠在更抽象的層次上建模硬件。
l char:一個兩態(tài)的有符號變量,它與C語言中的char數(shù)據(jù)類型相同,可以是一個8位整數(shù)(ASCII)或short int(Unicode);
l int:一個兩態(tài)的有符號變量,它與C語言中的int數(shù)據(jù)類型相似,但被精確地定義成32位;
l shortint:一個兩態(tài)的有符號變量,被精確地定義成16位;
l longint:一個兩態(tài)的有符號變量,它與C語言中的long數(shù)據(jù)類型相似,但被精確地定義成64位;
l byte:一個兩態(tài)的有符號變量,被精確地定義成8位;
l bit:一個兩態(tài)的可以具有任意向量寬度的無符號數(shù)據(jù)類型,可以用來替代Verilog的reg數(shù)據(jù)類型;
l logic:一個四態(tài)的可以具有任意向量寬度的無符號數(shù)據(jù)類型,可以用來替代Verilog的線網(wǎng)或reg數(shù)據(jù)類型,但具有某些限制;
l shortreal:一個兩態(tài)的單精度浮點變量,與C語言的float類型相同;
l void:表示沒有值,可以定義成一個函數(shù)的返回值,與C語言中的含義相同。
SystemVerilog的bit和其他數(shù)據(jù)類型允許用戶使用兩態(tài)邏輯對設(shè)計建模,這種方法對仿真性能更有效率。由于Verilog語言沒有兩態(tài)數(shù)據(jù)類型,因此許多仿真器都通過將這種功能作為仿真器的一個選項提供。這些選項不能夠在所有的仿真器之間移植,而且在需要時用三態(tài)或四態(tài)邏輯的設(shè)計中強制使用兩態(tài)邏輯還具有副作用。SystemVerilog的bit數(shù)據(jù)類型能夠極大改進仿真器的性能,同時在需要的時候仍然可以使用三態(tài)或四態(tài)邏輯。通過使用具有確定行為的數(shù)據(jù)類型來代替專有的仿真器選項,兩態(tài)模型能夠在所有的SystemVerilog仿真器間移植。
SystemVerilog的logic數(shù)據(jù)類型比Verilog的線網(wǎng)和寄存器數(shù)據(jù)類型更加靈活,它使得在任何抽象層次上建模硬件都更加容易。logic類型能夠以下面的任何一種方法賦值:
l 通過任意數(shù)目的過程賦值語句賦值,能夠替代Verilog的reg類型;
l 通過單一的連續(xù)賦值語句賦值,能夠有限制地替代Verilog的wire類型;
l 連接到一個單一原語的輸出,能夠有限制地替代Verilog的wire類型;
由于logic數(shù)據(jù)類型能夠被用來替代Verilog的reg或wire(具有限制),這就使得能夠在一個更高的抽象層次上建模,并且隨著設(shè)計的不斷深入能夠加入一些設(shè)計細節(jié)而不必改變數(shù)據(jù)類型的聲明。logic數(shù)據(jù)類型不會表示信號的強度也不具有線邏輯的解析功能,因此logic數(shù)據(jù)類型比Verilog的wire類型更能有效地仿真和綜合。
有符號和無符號限定符
缺省情況下,Verilog net和reg數(shù)據(jù)類型是無符號類型,integer類型是一個有符號類型。Verilog-2001標(biāo)準(zhǔn)允許使用signed關(guān)鍵字將無符號類型顯式地聲明成有符號類型。SystemVerilog加入了相似的能力,它可以通過unsigned關(guān)鍵字將有符號數(shù)據(jù)類型顯式地聲明成有無符號數(shù)據(jù)類型。例如:
不帶符號的 j;
值得注意的是unsigned在Verilog中是一個保留字,但并沒有被Verilog標(biāo)準(zhǔn)使用。
用戶定義的類型
Verilog不允許用戶定義新的數(shù)據(jù)類型。SystemVerilog通過使用typedef提供了一種方法來定義新的數(shù)據(jù)類型,這一點與C語言類似。用戶定義的類型可以與其它數(shù)據(jù)類型一樣地使用在聲明當(dāng)中。例如:
typedefunsigned int uint;
單元 a, b;
一個用戶定義的數(shù)據(jù)類型可以在它的定義之前使用,只要它首先在空的typedef中說明,例如:
typedef int48; // 空的typedef,在其他地方進行完整定義
int48 c;
枚舉類型
在Verilog語言中不存在枚舉類型。標(biāo)識符必須被顯式地聲明成一個線網(wǎng)、變量或參數(shù)并被賦值。SystemVerilog允許使用類似于C的語法產(chǎn)生枚舉類型。一個枚舉類型具有一組被命名的值。缺省情況下,值從初始值0開始遞增,但是我們可以顯式地指定初始值。枚舉類型的例子如下:
枚舉{紅、黃、綠} RGB;
枚舉 {WAIT=2'b01, LOAD, DONE} 狀態(tài);
我們還可以使用typedef為枚舉類型指定一個名字,從而允許這個枚舉類型可以在許多地方使用。例如:
typedefenum {FALSE=1'b0, TRUE} 布爾值;
布爾值準(zhǔn)備就緒;
布爾測試完成;
結(jié)構(gòu)體和聯(lián)合體
在Verilog語言中不存在結(jié)構(gòu)體或聯(lián)合體,而結(jié)構(gòu)體或聯(lián)合體在將幾個聲明組合在一起的時候非常有用。SystemVerilog增加了結(jié)構(gòu)體和聯(lián)合體,它們的聲明語法類似于C。
結(jié)構(gòu){
reg [15:0] 操作碼;
注冊 [23:0] 地址;
} 和;
工會{
詮釋我;
短實 f;
} N;
結(jié)構(gòu)體或聯(lián)合體中的域可以通過在變量名和域名字之間插入句點(.)來引用:
IR.opcode = 1; // 設(shè)置IR變量中的opcode域
N.f = 0.0; // 將N設(shè)置成浮點數(shù)的值
我們可以使用typedef為結(jié)構(gòu)體或聯(lián)合體的定義指定一個名字。
typedefstruct{
reg [7:0] 操作碼;
注冊 [23:0] 地址;
} instruction; // 命名的結(jié)構(gòu)體
instruction IR; // 結(jié)構(gòu)體實例
一個結(jié)構(gòu)體可以使用值的級聯(lián)來完整地賦值,例如:
指令={5,200};
結(jié)構(gòu)體可以作為一個整體傳遞到函數(shù)或任務(wù),也可以從函數(shù)或任務(wù)傳遞過來,也可以作為模塊端口進行傳遞。
數(shù)組
在Verilog中可以聲明一個數(shù)組類型,reg和線網(wǎng)類型還可以具有一個向量寬度。在一個對象名前面聲明的尺寸表示向量的寬度,在一個對象名后面聲明的尺寸表示數(shù)組的深度。例如:
reg [7:0] r1 [1:256]; // 256個8位的變量
在SystemVerilog中我們使用不同的術(shù)語表示數(shù)組:使用“壓縮數(shù)組(packed array)”這一術(shù)語表示在對象名前聲明尺寸的數(shù)組;使用“非壓縮數(shù)組(unpacked array)”這一術(shù)語表示在對象名后面聲明尺寸的數(shù)組。壓縮數(shù)組可以由下面的數(shù)據(jù)類型組成:bit、logic、reg、wire以及其它的線網(wǎng)類型。無論是壓縮數(shù)組還是非壓縮數(shù)組都可以聲明成多維的尺寸。
bit [7:0] a; // 一個一維的壓縮數(shù)組
bit b [7:0]; //一個一維的非壓縮數(shù)組
bit [0:11] [7:0] c; //一個二維的壓縮數(shù)組
bit [3:0] [7:0] d [1:10]; // 一個包含10個具有4個8位字節(jié)的壓縮數(shù)組的非壓縮數(shù)組
非壓縮尺寸在壓縮尺寸之前引用,這就允許將整個壓縮數(shù)組作為一個單一的元素進行引用。在上面的例子中,d[1]引用非壓縮數(shù)組的一個單一元素,這個元素是一個包含4個字節(jié)的數(shù)組。
在為命名的塊中聲明
Verilog允許變量在一個命名的begin-end或fork-join語句組中聲明。相對于語句組來說,這些變量是本地的,但它們可以被層次化地引用。在SystemVerilog中,既可以在命名的塊中也可以在未命名的塊中聲明。在未命名的塊中,不能夠使用層次名來訪問變量。所有的變量類型,包括用戶定義的類型、枚舉類型、結(jié)構(gòu)體和聯(lián)合體都可以在begin-end或fork-join語句組中聲明。
常量
在Verilog中有三種特性類型的常量:parameter、specparam和localparam。而在SystemVerilog中,允許使用const關(guān)鍵字聲明常量。例如:
常量字符=“:”;
可重定義的數(shù)據(jù)類型
SystemVerilog擴展了Verilog的parameter,使其可以包含類型。這個強大的功能使得一個模塊中的數(shù)據(jù)類型在模塊的每一個實例中重新定義。例如:
模塊 foo;
(參數(shù) typeVAR_TYPE = 短線;)
(輸入邏輯[7:0] i,輸出邏輯[7:0] o);
VAR_TYPE j = 0; // 如果不重新定義,j的數(shù)據(jù)類型為shortint
……
終端模塊
模塊欄;
邏輯 [3:0] i, o;
foo#(.VAR_TYPE(int)) u1 (i, o); // 重新將VAR_TYPE定義成int類型
終端模塊
模塊端口連接
在Verilog中,可以連接到模塊端口的數(shù)據(jù)類型被限制為線網(wǎng)類型以及變量類型中的reg、integer和time。而在SystemVerilog中則去除了這種限制,任何數(shù)據(jù)類型都可以通過端口傳遞,包括實數(shù)、數(shù)組和結(jié)構(gòu)體。
字母值
在Verilog中,當(dāng)指定或賦值字母值的時候存在一些限制。而SystemVerilog則為字母值如何指定作了下面的增強:
l 一個字母值的所有位均可以使用0、1、z或x作相同的填充。這就允許填充一個任意寬度的向量,而無需顯式地指定向量的寬度,例如:
位 [63:0] 數(shù)據(jù);
data = `1; //將data的所有位設(shè)置成1
l 一個字符串可以賦值成一個字符數(shù)組,象C語言一樣加入一個空結(jié)束符。如果尺寸不同,它象C中一樣進行左調(diào)整,例如:
char foo[0:12] = “你好世界”;
l 加入了幾個特殊的串字符:
v:垂直TAB
f:換頁
a:響鈴
x02:用十六進制數(shù)來表示一個ASCII字符
l 數(shù)組可以使用類似于C初始化的語法賦值成字符值,但它還允許復(fù)制操作符。括號的嵌套必須精確地匹配數(shù)組的維數(shù)(這一點與C不同),例如:
int n[1: 2] [1:3] = {{0, 1, 2}, {3{4}}};
強制類型轉(zhuǎn)換
Verilog不能將一個值強制轉(zhuǎn)換成不同的數(shù)據(jù)類型。SystemVerilog通過使用’操作符提供了數(shù)據(jù)類型的強制轉(zhuǎn)換功能。這種強制轉(zhuǎn)換可以轉(zhuǎn)換成任意類型,包括用戶定義的類型。例如:
int’ (2.0 *3.0) // 將結(jié)果轉(zhuǎn)換為int類型
mytype’ (foo) // 將foo轉(zhuǎn)換為mytype類型
一個值還可以通過在強制轉(zhuǎn)換操作符前指定一個10進制數(shù)來轉(zhuǎn)換成不同的向量寬度,例如:
17’(x- 2) // 將結(jié)果轉(zhuǎn)換為17位寬度
也可以將結(jié)果轉(zhuǎn)換成有符號值,例如:
signed’(x) // 將x轉(zhuǎn)換為有符號值
操作符
Verilog沒有C語言的遞增(++)和遞減(--)操作符。 而SystemVerilog加入了幾個新的操作符:
l ++和--:遞增和遞減操作符;
l +=、-=、*=、/=、%=、&=、^=、|=、<<=、>>=、<<<=和>>>=賦值操作符;
唯一性和優(yōu)先級決定語句
在Verilog中,如果沒有遵循嚴(yán)格的編碼風(fēng)格,它的if-else和case語句會在RTL仿真和RTL綜合間具有不一致的結(jié)果。 如果沒有正確使用full_case和parallel_case綜合指令還會引起一些其它的錯誤。
SystemVerilog能夠顯式地指明什么時候一條決定語句的分支是唯一的,或者什么時候需要計算優(yōu)先級。 我們可以在if或case關(guān)鍵字之前使用unique或requires關(guān)鍵字。 這些關(guān)鍵字可以向仿真器、綜合編譯器、以及其它工具指示我們期望的硬件類型。 工具使用這些信息來檢查if或case語句是否正確建模了期望的邏輯。 例如,如果使用unique限定了一個決定語句,那么在不希望的case值出現(xiàn)的時候仿真器就能夠發(fā)布一個警告信息。
位 [2:0]a;
唯一 if((a==0) ||(a==1))y= in1;
否則如果 (a==2) y=in2;
else if (a==4) y=in3; // 值3、5、6、7會引起一個警告
優(yōu)先級如果 (a[2:1]==0) y = in1;a是0或1
否則如果 (a[2]==0) y = in2;a是2或3
else y = in3; // 如果a為其他的值
獨特案例 (A)
0, 1: y = in1;
2: y = in2;
4: y = in3;
endcase // 值3、5、6、7會引起一個警告
優(yōu)先級案例z(a)
2'b00?: y = in1;a是0或1
2'b0??: y = in2;a是2或3
default : y = in3; //如果a為其他的值
尾殼
底部檢測的循環(huán)
Verilog包含for、while和repeat循環(huán),這幾個循環(huán)都是在循環(huán)的起始處檢測循環(huán)條件。 SystemVerilog加入了一個do-while循環(huán),這種循環(huán)在執(zhí)行語句的結(jié)尾處檢測循環(huán)條件。
跳轉(zhuǎn)語句
在語句的執(zhí)行過程中,C語言提供了幾種方式來跳轉(zhuǎn)到新的語句,包括:return、break、continue和goto。 在Verilog中除了通過使用disable語句跳轉(zhuǎn)到語句組的尾部外,沒有提供任何其它跳轉(zhuǎn)語句。 使用disable語句執(zhí)行中止和繼續(xù)功能要求加入塊的名字,并且會產(chǎn)生不直觀的代碼。 SystemVerilog加入了C語言的break和continue關(guān)鍵字,這兩個關(guān)鍵字不要求使用塊名字。 另外,SystemVerilog還加入了一個return關(guān)鍵字,它可以用來在任何執(zhí)行點上退出一個任務(wù)或函數(shù)。
l break:退出一個循環(huán),與C語言相同;
l continue:跳轉(zhuǎn)到一個循環(huán)的尾部,與C語言相同;
l return 表達式:退出一個函數(shù);
l return:退出一個任務(wù)或void類型的函數(shù)。
SystemVerilog沒有包含C語言中的goto語句。
塊名字和語句標(biāo)簽
在Verilog中,我們可以通過在begin或fork關(guān)鍵字之后指定名字來為begin-end或fork-jion語句指定名字。 這個指定的名字代表整個語句塊。 SystemVerilog還允許在end或jion關(guān)鍵字之后指定一個匹配的塊名字。 這種機制很容易將end或jion與對應(yīng)的begin或fork聯(lián)系起來,尤其是在一個長的塊或嵌套的塊中。 塊結(jié)尾處的名字是可選的,但如果使用的話,它必須與塊起始處的名字相同。 例如:
begin: foo // 在begin之后的塊名字
……
fork: bar // 具有名字的嵌套的塊
……
jion: bar // 必須具有相同的名字
……
end: foo // 必須具有相同的名字
SystemVerilog還允許像C語言一樣為單個語句設(shè)置標(biāo)簽。 語句標(biāo)簽放置在語句的前面,用來標(biāo)識這條語句。 例如:
初始開始
測試1: read_enable = 0;
……
測試2:對于(I=0;I<=255;I++)
……
結(jié)束
對事件控制的增強
Verilog使用@標(biāo)記來控制基于特定事件的執(zhí)行流,SystemVerilog增強了@事件控制。
l 有條件的事件控制
@標(biāo)記的一個基本應(yīng)用就是推斷一個具有使能輸入的鎖存器。 下面的例子演示了一個鎖存器建模的基本風(fēng)格。
始終 @(數(shù)據(jù)或 en)
如果 (en)y<=data;
這種編碼風(fēng)格對仿真來說是效率低下的,因為即使在使能輸入無效的時候,數(shù)據(jù)輸入的每次改變都會觸發(fā)事件控制。
SystemVerilog在事件控制中加入了一個iff條件。 只有iff條件為真的條件下,事件控制才會被觸發(fā)。 通過將使能判斷移入到事件控制里面,使得只有在鎖存器輸出能夠改變的時候事件控制才會被觸發(fā)。 例如:
始終 @(a 或 en iff en==1)
y<=a;
l 事件控制中的表達式
Verilog允許在@事件控制列表中使用表達式,例如:
始終 @((a * b))
總是@(內(nèi)存[地址])
在第一個例子中,是當(dāng)操作數(shù)發(fā)生改變的時候還是只有當(dāng)運算結(jié)果發(fā)生改變的時候才會觸發(fā)事件控制? 在第二個例子中,是當(dāng)memory的地址發(fā)生變化的時候還是只有當(dāng)memory的值發(fā)生變化的時候才會觸發(fā)事件控制? 當(dāng)@事件控制中包含表達式的時候,IEEE Verilog標(biāo)準(zhǔn)允許仿真器進行不同的優(yōu)化。 這就可能導(dǎo)致在不同的仿真器間有不同的仿真結(jié)果,可能還會導(dǎo)致仿真與綜合之間的結(jié)果不一致。 SystemVerilog加入了一個changed關(guān)鍵字,在事件控制列表中它被用作一個修飾符。 @(changed (表達式))能夠顯式地定義只有當(dāng)表達式的結(jié)果發(fā)生改變的時候才會觸發(fā)事件控制。 例如:
總是 @(更改 (a * b))
總是@(更改了內(nèi)存[地址])
l 事件控制中的賦值
Verilog不允許在事件控制中使用賦值。 SystemVerilog允許在事件控制中使用賦值表達式。 事件控制僅僅敏感于賦值表達式右側(cè)的變化。 例如:
始終 @(y = a * b)
新的過程
Verilog使用always過程來表示時序邏輯、組合邏輯和鎖存邏輯的RTL模型。 綜合工具和其它軟件工具必須根據(jù)過程起始處的事件控制列表以及過程內(nèi)的語句來推斷always過程的意圖。 這種推斷會導(dǎo)致仿真結(jié)果和綜合結(jié)果之間的不一致。 SystemVerilog增加了三個新的過程來顯式地指示邏輯的意圖。
l always_ff:表示時序邏輯的過程;
l always_comb:表示組合邏輯的過程;
l always_latch:表示鎖存邏輯的過程。
例如:
always_comb@(aor b 或 sel) 開始
如果 (sel) y = a;
否則 y = b;
結(jié)束
軟件工具能夠檢查事件控制敏感列表和過程的內(nèi)容來保證邏輯的功能匹配過程的類型。 例如,工具能夠檢查一個always_comb過程能夠敏感過程內(nèi)讀取的所有外部值,對邏輯的每一個分支的相同變量進行賦值,并且檢查分支是否覆蓋了所有可能的條件。 如果任何一個條件沒有滿足,軟件工具均會報告該過程沒有正確建模組合邏輯。
動態(tài)過程
Verilog通過使用fork-jion提供了一種靜態(tài)的并發(fā)過程。 每一個分支都是一個分離的、并行的過程。 fork-jion中任何語句的執(zhí)行必須在組內(nèi)的每一個過程完成后才會執(zhí)行。 例如:
初始開始
叉
send_packet_task (1,255, 0);
send_packet_task(7 128人,5人);
watch_result_task (1,255, 0);
watch_result_task(7 128人,5人);
jion // 所有的任務(wù)必須完成后才會到達這里
結(jié)束
SystemVerilog通過process關(guān)鍵字加入了一個新的、動態(tài)的過程。 它為一個過程產(chǎn)生分支,然后繼續(xù)執(zhí)行而無需等待其他過程完成。 過程不會阻塞過程或任務(wù)內(nèi)的語句執(zhí)行。 這種方式能夠建模多線程的過程。 例如:
初始開始
進程send_packet_task (1,255, 0);
processsend_packet_task(7, 128, 5);
processwatch_result_task(1, 255, 0);
processwatch_result_task(7, 128, 5);
end //所有的過程并行運行
任務(wù)和函數(shù)增強
SystemVerilog為Verilog的任務(wù)和函數(shù)作了幾個增強。
l 靜態(tài)和自動的存儲
缺省情況下,在Verilog任務(wù)或函數(shù)內(nèi)的所有存儲都是靜態(tài)的。 Verilog-2001允許將任務(wù)和函數(shù)聲明成自動的。 在SystemVerilog中:(1). 在一個靜態(tài)任務(wù)和函數(shù)內(nèi)的特定數(shù)據(jù)可以顯式地聲明成自動的。 聲明成自動的數(shù)據(jù)在塊中具有完整的生命周期,并且在任務(wù)和函數(shù)調(diào)用的入口處初始化; (2). 在一個自動的任務(wù)或函數(shù)中的特定數(shù)據(jù)可以顯式地聲明成靜態(tài)的。 自動的任務(wù)或函數(shù)中聲明成靜態(tài)的數(shù)據(jù)在一個塊的本地范圍內(nèi)具有靜態(tài)的生命周期。
l 從任何點返回
Verilog在一個任務(wù)或函數(shù)中執(zhí)行到endtask或endfunction關(guān)鍵字的時候返回。 函數(shù)的返回值是給函數(shù)名賦的最后一個值。 SystemVerilog加入了一個return關(guān)鍵字,使用這個關(guān)鍵字,一個任務(wù)或函數(shù)可以在任何點上返回。
l 多語句
Verilog要求一個任務(wù)或函數(shù)只具有一個語句或語句塊。 多條語句必須組合到一個單一的begin-end或fork-jion塊中。 SystemVerilog去除了這種限制。 因此,多條語句可以在一個任務(wù)或函數(shù)中列出而無需使用的begin-end或fork-jion。 每有分組的語句就像在begin-end中一樣順序執(zhí)行。 我們還可以產(chǎn)生一個沒有語句的任務(wù)或函數(shù)定義。
l void函數(shù)
Verilog要求一個函數(shù)具有一個返回值,函數(shù)的調(diào)用接收這個返回值。 SystemVerilog加入了一個void數(shù)據(jù)類型,這個數(shù)據(jù)類型可以作為一個函數(shù)的返回值類型。 void函數(shù)可以像Verilog任務(wù)一樣進行調(diào)用,而無需接收一個返回值。 void函數(shù)和任務(wù)的差別在于函數(shù)存在幾個限制,例如沒有時間控制等。
l 函數(shù)的輸入和輸出
Verilog標(biāo)準(zhǔn)要求一個函數(shù)至少具有一個輸入并且函數(shù)只能具有輸入。 SystemVerilog去除了這些限制。 函數(shù)可以具有任意數(shù)目的輸入、輸出以及輸入輸出,也可以什么也沒有。
連續(xù)賦值的增強
在Verilog中,連續(xù)賦值語句的左側(cè)只能是線網(wǎng)類型,例如wire。 連續(xù)賦值語句被認為是線網(wǎng)的驅(qū)動源,而線網(wǎng)可以擁有任意數(shù)據(jù)的驅(qū)動源。 SystemVerilog允許除reg類型以外的任何數(shù)據(jù)類型用于連續(xù)賦值語句的左側(cè)。 與線網(wǎng)不同,所有其它數(shù)據(jù)類型被限制為只能有一個連續(xù)賦值語句驅(qū)動。 為相同的變量混合使用連續(xù)賦值語句和過程賦值語句是不被允許的。
$bit系統(tǒng)函數(shù)
在Verilog中沒有類似于C語言中sizeof的函數(shù)。 SystemVerilog加入一個新的$bit內(nèi)建函數(shù)。 這個函數(shù)返回保存一個值所需的硬件位的數(shù)目(一個四態(tài)值要求一個硬件位),這個函數(shù)還可以用來確定一個結(jié)構(gòu)體所代表的硬件位的數(shù)目。
`define的增強
SystemVerilog增強了define編譯器指令的能力以便支持將字符串作為宏的參數(shù)。宏的文本字符串中可以包含一個隔離的引號,它的前面必須具有一個反勾號(”),這就允許字符串中包含宏參數(shù)。 宏文本可以在行的尾部包含一個反斜杠(’’)來表示在下一行繼續(xù)。 如果宏文本字符串中包含反斜杠,則反斜杠應(yīng)該被放在兩個反勾號之間,這樣它就不會被認為是Verilog轉(zhuǎn)義標(biāo)識符的開始。 宏文本字符串還可以包含雙反勾號(``),它允許標(biāo)識符能夠從參數(shù)中構(gòu)建。 這些增強使得define指令更加靈活。例如:include指令后可以緊跟一個宏名字來替代一個字符串。
“定義 F1”../project_top/opcode_defines”
include F1
狀態(tài)機建模
SystemVerilog允許在更高的抽象層次上對狀態(tài)機建模。 這些結(jié)構(gòu)包括:
l 枚舉類型
l 一個特殊的state數(shù)據(jù)類型;
l 一個遷移語句
l 一個遷移操作符
斷言
SystemVerilog中加入了斷言的功能來改善系統(tǒng)的驗證過程。
結(jié)論
SystemVerilog為Verilog-2001標(biāo)準(zhǔn)提供了一系列的擴展。 這些擴展使得大型設(shè)計的建模和驗證更加容易。
-
模塊
+關(guān)注
關(guān)注
7文章
2728瀏覽量
47614 -
接口
+關(guān)注
關(guān)注
33文章
8669瀏覽量
151536 -
Verilog
+關(guān)注
關(guān)注
28文章
1351瀏覽量
110193 -
System
+關(guān)注
關(guān)注
0文章
165瀏覽量
37005
原文標(biāo)題:System Verilog的概念以及與verilog的對比
文章出處:【微信號:Hack電子,微信公眾號:Hack電子】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論