SystemVerilog語言簡介

admin @ 2014-03-26 , reply:0

    SystemVerilog是一種硬體描述和驗證語言(HDVL),它基於IEEE 1364-2001 Verilog硬體描述語言(HDL),並對其進行了擴展,包括擴充了C語言數據類型、結構、壓縮和非壓縮數組、 介面、斷言等等,這些都使得SystemVerilog在一個更高的抽象層次上提高了設計建模的能力。SystemVerilog由Accellera開發,它主要定位在晶元的實現和驗證流程上,並為系統級的設計流程提供了強大的連接能力。下面我們從幾個方面對SystemVerilog所作的增強進行簡要的介紹,期望能夠通過這個介紹使大家對SystemVerilog有一個概括性的了解。

1. 介面(Interface)
    Verilog模塊之間的連接是通過模塊埠進行的。為了給組成設計的各個模塊定義埠,我們必須對期望的硬體設計有一個詳細的認識。不幸的是,在設計的早期,我們很難把握設計的細節。而且,一旦模塊的埠定義完成後,我們也很難改變埠的配置。另外,一個設計中的許多模塊往往具有相同的埠定義,在Verilog中,我們必須在每個模塊中進行相同的定義,這為我們增加了無謂的工作量。
    SystemVerilog提供了一個新的、高層抽象的模塊連接,這個連接被稱為介面(Interface)。介面在關鍵字interfaceendinterface之間定義,它獨立於模塊。介面在模塊中就像一個單一的埠一樣使用。在最簡單的形式下,一個介面可以認為是一組線網。例如,可以將PCI匯流排的所有信號綁定在一起組成一個介面。通過使用介面,我們在進行一個設計的時候可以不需要首先建立各個模塊間的互連。隨著設計的深入,各個設計細節也會變得越來越清晰,而介面內的信號也會很容易地表示出來。當介面發生變化時,這些變化也會在使用該介面的所有模塊中反映出來,而無需更改每一個模塊。下面是一個介面的使用實例:
interface chip_bus; // 定義介面
wire read_request, read_grant;
wire [7:0] address, data;
endinterface: chip_bus

module RAM (chip_bus io, // 使用介面
input clk);
// 可以使用io.read_request引用介面中的一個信號
endmodule

module CPU(chip_bus io, input clk);
...
endmodule

module top;
reg clk = 0;
chip_bus a; // 實例介面
// 將介面連接到模塊實例
RAM mem(a, clk);
CPU cpu(a, clk);
endmodule
    實際上,SystemVerilog的介面不僅僅可以表示信號的綁定和互連。由於SystemVerilog的介面中可以包含參數、常量、變數、結構、函數、任務、initial塊、always塊以及連續賦值語句,所以SystemVerilog的介面還可以包含內建的協議檢查以及被使用該介面的模塊所共用的功能。

2. 全局聲明和語句
    在Verilog中,除了一個模塊可以作為模塊實例引用其他模塊外,並不存在一個全局空間。另外,Verilog允許任意數目的頂層模塊,因此會產生毫無關聯的層次樹。
    SystemVeriog增加了一個被稱為$root的隱含的頂級層次。任何在模塊邊界之外的聲明和語句都存在於$root空間中。所有的模塊,無論它處於哪一個設計層次,都可以引用$root中聲明的名字。這樣,如果某些變數、函數或其它信息被設計中的所有模塊共享,那麼我們就可以將它們作為全局聲明和語句。全局聲明和語句的一個使用實例如下:
reg error _flag; // 全局變數
function compare (...); // 全局函數
always @(error_flag) // 全局語句
...
module test;
chip1 u1 (...)
endmodule

module chip1 (...);
FSM u2 (...);
always @(data)
error_flag = compare(data, expected);
endmodule

module FSM (...);
...
always @(state)
error_flag = compare(state, expected);
endmodule

3. 時間單位和精度
    在Verilog中,表示時間的值使用一個數來表示,而不帶有任何時間單位。例如:
forever #5 clock = ~clock;
    從這一句中我們無法判斷5代表的是5ns? 5ps? 還是其他。Verilog的時間單位和精度是作為每一個模塊的屬性,並使用編譯器指令`timescale來設置。使用這種方法具有固有的缺陷,因為編譯器指令的執行依賴於源代碼的編譯順序,編譯器總是將它遇到的最後一個`timescale設置的時間單位和精度作為之後的標準。那麼,假如有些模塊之前沒有使用`timescale設置時間單位和精度,這就有可能出現同一個源代碼的不同模擬會出現不同結果的情況。
    SystemVerilog為了控制時間單位加入了兩個重要的增強。首先,時間值可以顯式地指定一個單位。時間單位可以是s、ms、ns、ps或fs。時間單位作為時間值的後綴出現。例如:
forever #5ns clock = ~clock;
    其次,SystemVerilog允許使用新的關鍵字(timeunits和timeprecision)來指定時間單位和精度。這些聲明可以在任何模塊中指定,同時也可以在$root空間中全局指定。時間單位和精度必須是10的冪,範圍可以從s到fs。例如:
timeunits 1ns;
timeprecision 10ps;

4. 抽象數據類型
    Verilog提供了面向底層硬體的線網、寄存器和變數數據類型。這些類型代表了4態邏輯值,通常用來在底層上對硬體進行建模和驗證。線網數據類型還具有多個強度級別,並且能夠為多驅動源的線網提供解析功能。
    SystemVerilog包括了C語言的char和int數據類型,它允許在Verilog模型和驗證程序中直接使用C和C++代碼。Verilog PLI不再需要集成匯流排功能模型、演算法模型和C函數。SystemVerilog還為Verilog加入了幾個新的數據類型,以便能夠在更抽象的層次上建模硬體。
         char:一個兩態的有符號變數,它與C語言中的char數據類型相同,可以是一個8位整數(ASCII)或short int(Unicode);
         int:一個兩態的有符號變數,它與C語言中的int數據類型相似,但被精確地定義成32位;
         shortint:一個兩態的有符號變數,被精確地定義成16位;
         longint:一個兩態的有符號變數,它與C語言中的long數據類型相似,但被精確地定義成64位;
         byte:一個兩態的有符號變數,被精確地定義成8位;
         bit:一個兩態的可以具有任意向量寬度的無符號數據類型,可以用來替代Verilog的reg數據類型;
         logic:一個四態的可以具有任意向量寬度的無符號數據類型,可以用來替代Verilog的線網或reg數據類型,但具有某些限制;
         shortreal:一個兩態的單精度浮點變數,與C語言的float類型相同;
         void:表示沒有值,可以定義成一個函數的返回值,與C語言中的含義相同。
    SystemVerilog的bit和其他數據類型允許用戶使用兩態邏輯對設計建模,這種方法對模擬性能更有效率。由於Verilog語言沒有兩態數據類型,因此許多模擬器都通過將這種功能作為模擬器的一個選項提供。這些選項不能夠在所有的模擬器之間移植,而且在需要時用三態或四態邏輯的設計中強制使用兩態邏輯還具有副作用。SystemVerilog的bit數據類型能夠極大改進模擬器的性能,同時在需要的時候仍然可以使用三態或四態邏輯。通過使用具有確定行為的數據類型來代替專有的模擬器選項,兩態模型能夠在所有的SystemVerilog模擬器間移植。
    SystemVerilog的logic數據類型比Verilog的線網和寄存器數據類型更加靈活,它使得在任何抽象層次上建模硬體都更加容易。logic類型能夠以下面的任何一種方法賦值:
         通過任意數目的過程賦值語句賦值,能夠替代Verilog的reg類型;
         通過單一的連續賦值語句賦值,能夠有限制地替代Verilog的wire類型;
         連接到一個單一原語的輸出,能夠有限制地替代Verilog的wire類型;
    由於logic數據類型能夠被用來替代Verilog的reg或wire(具有限制),這就使得能夠在一個更高的抽象層次上建模,並且隨著設計的不斷深入能夠加入一些設計細節而不必改變數據類型的聲明。logic數據類型不會表示信號的強度也不具有線邏輯的解析功能,因此logic數據類型比Verilog的wire類型更能有效地模擬和綜合。

5. 有符號和無符號限定符
    預設情況下,Verilog net和reg數據類型是無符號類型,integer類型是一個有符號類型。Verilog-2001標準允許使用signed關鍵字將無符號類型顯式地聲明成有符號類型。SystemVerilog加入了相似的能力,它可以通過unsigned關鍵字將有符號數據類型顯式地聲明成有無符號數據類型。例如:
int unsigned j;
    值得注意的是unsigned在Verilog中是一個保留字,但並沒有被Verilog標準使用。

6. 用戶定義的類型
   Verilog不允許用戶定義新的數據類型。SystemVerilog通過使用typedef提供了一種方法來定義新的數據類型,這一點與C語言類似。用戶定義的類型可以與其它數據類型一樣地使用在聲明當中。例如:
typedef unsigned int uint;
uint a, b;
    一個用戶定義的數據類型可以在它的定義之前使用,只要它首先在空的typedef中說明,例如:
typedef int48; // 空的typedef,在其他地方進行完整定義
int48 c;

7. 枚舉類型
    在Verilog語言中不存在枚舉類型。標識符必須被顯式地聲明成一個線網、變數或參數並被賦值。SystemVerilog允許使用類似於C的語法產生枚舉類型。一個枚舉類型具有一組被命名的值。預設情況下,值從初始值0開始遞增,但是我們可以顯式地指定初始值。枚舉類型的例子如下:
enum {red, yellow, green} RGB;
enum {WAIT=2’b01, LOAD, DONE} states;
    我們還可以使用typedef為枚舉類型指定一個名字,從而允許這個枚舉類型可以在許多地方使用。例如:
typedef enum {FALSE=1’b0, TRUE} boolean;
boolean ready;
boolean test_complete;

8. 結構體和聯合體
    在Verilog語言中不存在結構體或聯合體,而結構體或聯合體在將幾個聲明組合在一起的時候非常有用。SystemVerilog增加了結構體和聯合體,它們的聲明語法類似於C。
struct {
  reg [15:0] opcode;
  reg [23:0] addr;
} IR;

union {
  int I;
  shortreal f;
} N;
    結構體或聯合體中的域可以通過在變數名和域名字之間插入句點(.)來引用:
IR.opcode = 1; // 設置IR變數中的opcode域
N.f = 0.0; // 將N設置成浮點數的值
    我們可以使用typedef為結構體或聯合體的定義指定一個名字。
typedef struct {
  reg [7:0] opcode;
  reg [23:0] addr;
} instruction; // 命名的結構體
instruction IR; // 結構體實例
一個結構體可以使用值的級聯來完整地賦值,例如:
instruction = {5, 200};
    結構體可以作為一個整體傳遞到函數或任務,也可以從函數或任務傳遞過來,也可以作為模塊埠進行傳遞。

9. 數組
    在Verilog中可以聲明一個數組類型,reg和線網類型還可以具有一個向量寬度。在一個對象名前面聲明的尺寸表示向量的寬度,在一個對象名後面聲明的尺寸表示數組的深度。例如:
reg [7:0] r1 [1:256]; // 256個8位的變數
    在SystemVerilog中我們使用不同的術語表示數組:使用“壓縮數組(packed array)”這一術語表示在對象名前聲明尺寸的數組;使用“非壓縮數組(unpacked array)”這一術語表示在對象名後面聲明尺寸的數組。壓縮數組可以由下面的數據類型組成:bit、logic、reg、wire以及其它的線網類型。無論是壓縮數組還是非壓縮數組都可以聲明成多維的尺寸。
bit [7:0] a; // 一個一維的壓縮數組
bit b [7:0]; //一個一維的非壓縮數組
bit [0:11] [7:0] c; //一個二維的壓縮數組
bit [3:0] [7:0] d [1:10]; // 一個包含10個具有4個8位位元組的壓縮數組的非壓縮數組
    非壓縮尺寸在壓縮尺寸之前引用,這就允許將整個壓縮數組作為一個單一的元素進行引用。在上面的例子中,d[1]引用非壓縮數組的一個單一元素,這個元素是一個包含4個位元組的數組。

10. 在為命名的塊中聲明
    Verilog允許變數在一個命名的begin-end或fork-join語句組中聲明。相對於語句組來說,這些變數是本地的,但它們可以被層次化地引用。在SystemVerilog中,既可以在命名的塊中也可以在未命名的塊中聲明。在未命名的塊中,不能夠使用層次名來訪問變數。所有的變數類型,包括用戶定義的類型、枚舉類型、結構體和聯合體都可以在begin-end或fork-join語句組中聲明。

11. 常量
在Verilog中有三種特性類型的常量:parameter、specparam和localparam。而在SystemVerilog中,允許使用const關鍵字聲明常量。例如:
const char colon = “:”;

12. 可重定義的數據類型
SystemVerilog擴展了Verilog的parameter,使其可以包含類型。這個強大的功能使得一個模塊中的數據類型在模塊的每一個實例中重新定義。例如:
module foo;
  # (parameter type VAR_TYPE = shortint;)
  (input logic [7:0] i, output logic [7:0] o);
  VAR_TYPE j = 0; // 如果不重新定義,j的數據類型為shortint
  …
endmodule

module bar;
  logic [3:0] i, o;
  foo #(.VAR_TYPE(int)) u1 (i, o); // 重新將VAR_TYPE定義成int類型
endmodule

13. 模塊埠連接
    在Verilog中,可以連接到模塊埠的數據類型被限制為線網類型以及變數類型中的reg、integer和time。而在SystemVerilog中則去除了這種限制,任何數據類型都可以通過埠傳遞,包括實數、數組和結構體。

14. 字母值
    在Verilog中,當指定或賦值字母值的時候存在一些限制。而SystemVerilog則為字母值如何指定作了下面的增強:
         一個字母值的所有位均可以使用`0、`1、`z或`x作相同的填充。這就允許填充一個任意寬度的向量,而無需顯式地指定向量的寬度,例如:
bit [63:0] data;
data = `1; //將data的所有位設置成1
         一個字元串可以賦值成一個字元數組,象C語言一樣加入一個空結束符。如果尺寸不同,它象C中一樣進行左調整,例如:
char foo [0:12] = “hello worldn”;
         加入了幾個特殊的串字元:
v:垂直TAB
f:換頁
a:響鈴
x02:用十六進位數來表示一個ASCII字元
         數組可以使用類似於C初始化的語法賦值成字元值,但它還允許複製操作符。括弧的嵌套必須精確地匹配數組的維數(這一點與C不同),例如:
int n [1: 2] [1:3] = {{0, 1, 2}, {3{4}}};



[admin via 研發互助社區 ] SystemVerilog語言簡介已經有10799次圍觀

http://cocdig.com/docs/show-post-42985.html