初探Verilog


Verilog是一種硬體描述語言(HDL, Hardware Description Language),在不用真正架設電路或繪製電路圖的前提之下,利用其特有的語法,便可描述硬體的組成架構、或是描述硬體的行為;同時也可以用來架設虛擬的驗證平台,對描述的硬體進行驗證,以確定硬體的行為符合預期。

如下的電路,若以電路圖的形式來管理與開發,當電路越來越複雜時,往往變得不易維護。以下分別就硬體描述語言的「起源」、「用途」及「特性」分別說明。由於在業界使用Verilog的機會較高,因此後面會以Verilog為例來做說明。

                                 

                                                    (圖片來源:https://www.pexels.com)


一. 硬體描述語言的起源


早在1970年代末期,因應數位電路的設計日趨複雜,美國國防部為了方便電子電路技術文件的管理與開發,便發展了VHSIC(Very High Speed Integrated Circuit)的計劃,希望制定一個標準的文件格式及語法,將來便以標準來描述及開發設計的電路。而後經過種種的改良,於1982年推出VHDL(VHSIC Hardware Description Language),並在1986年成為IEEE的標準之一,編號為IEEE Standard 1076


不久之後的1984年,美國的Gateway Design Automation公司也推出了名為「Verilog」的硬體描述語言,相較於早兩年推出 - 目的在制定電路設計標準的VHDL,Verilog則是規劃以程式語言的介面,建立一個電腦輔助設計的自動化電路設計(EDA, Electronic Design Automation)流程。因此Gateway公司除了參考C語言的設計,推出一套標準的Verilog語法之外,也開發了一套模擬的工具Verilog-XL,提供使用者在利用Verilog開發數位電路的同時,也能設計電路的各種輸入的場景,透過模擬工具來模擬電路的行為,以驗證電路的功能正確性。在1995年,Verilog也成為IEEE的標準之一,編號為IEEE Standard 1364


VHDL與Verilog在數位電路的設計上各有優勢,今天的業界也各有其擁護者。然而就電路功能驗證來說,2005年成為IEEE Standard 1076標準、在Verilog基礎之上發展System Verilog及後續以System Verilog建構的函式庫UVM(Universal Verification Methodology),引入軟體物件導向(OOP, Object-Oriented Programming)及設計模式(Design Pattern)的思維,相較VHDL而言,則具有更好的可復用性與靈活度。



二. 硬體描述語言的用途:


與電腦程式語言不同,硬體描述語言描述硬體或是架設驗證平台時,分別代表的意義也不同。


描述硬體架構/行為

  • 硬體架構:描述的是一張展開的電路圖,包含各個結構及邏輯閘的輸入/輸出關係,是一個靜態的描述,不含有任何時間的觀念。
  • 硬體行為:描述硬體的運算行為,至於實際的架構則由邏輯綜合(Logic Synthesis)工具來實現。行為描述可以對在clock edge或變數有改變的情況下,描述硬體所做的運算,但僅是用來描述硬體受到觸發時,所進行的運算,整體的描述仍沒有時間流逝的觀念。

                

一個半加法器,兩個輸入A、B,及輸出Sum與進位(C, Carry)的數學表達式如下:   

                                                  

{S, C} = A + B;


但若攤開成硬體的架構,就是像下面這張電路圖:


  

架設驗證平台及描述驗證場景:  

  • 驗證平台:驗證平台就好像一張工具桌,待測的硬體放到平台上進行驗證。要架設一個驗證平台,就要做好包含生成clock訊號、連接驗證平台與硬體輸入與輸出訊號,以及建立描述硬體行為的模型...等等的工作。等到平台準備好了以後,就可以在上面做驗證了。
  • 驗證場景:驗證場景則是一個動態的行為描述,從開始的reset、生成各式各樣的激勵,就像實際操作硬體一樣。硬體描述語言可將激勵做到隨機化(randomization),以涵蓋各種激勵的組合。

以上的灰色區塊即是待側的硬體,被包在驗證平台內,平台內淺黃色的區塊即是驗平台的模型和計分版模組;驗證平台外的是驗證場景。
注意這裡所有描述都是用程式碼來表示,並非真正有一個實體的硬體及驗證平台。


三. 硬體描述語言的特性:


以下就Verilog的資料型態(Data Type)硬體描述方式,與後起的System Verilog分別說明。   

資料型態與狀態

就Verilog而言,考量到要用來描述硬體的架構,將資料型態分成線網、變量兩大類。

為描述硬體行為,引入X(未知)、Z(高阻抗)兩種狀態,兩種數據類型都有0、1、X、Z四種狀態。


  • 線網類型(Net Type):描述硬體架構的組成之間的物理連線,物理連線的值不具有存的性質,會隨著連線一端的值改變而跟著變動,類型包含了有wire, tri,...等等。線網的初始值若未特別設定,預設為未接線的高阻抗狀態Z。
    • 例如:
                宣告變數input_a為線網類型:

wire input_a;   


     將input_a連至port_a:

assign input_a = port_a;


     之後若port_a的值變動了,不需重新連線,input_a的值也會跟著變動。


對於線網類型的變數,一般是在描述硬體的架構,例如各個模組之間的連線時使用,必須使用連續性賦值(continuous assignment)的「assign」來為變數賦值。

  • 變量類型(Variable Type):變量類型包含reg, integer, time, realtime,在描述硬體架構中的暫存器、或是儲存變數時使用。在描述硬體架構中的暫存器、或是儲存變數時使用。變量值只有在賦值時才會更新,否則便會維持既有的值。要為變量賦值,除了在初始狀態賦值外,電路內要在always區塊用程序賦值(procedural assignment)來為變量類型的變數賦值。reg在硬體架構內常用來表示暫存器(register),一個陣列的暫存器即為一塊記憶體(memory)。暫存器及記憶體的若未特別設定,初始值均為未知狀態的X。  
        always區塊描述了電路在指定的觸發條件下,所執行的賦值。語句為:
always @(觸發條件) begin

賦值語句... 

end

    • 例如:

描述一個3bit的計數器,在每個clock的正緣時更新。

便可先宣告計數變量count,並設定初始值為0:

reg [2:0] count = 0; 


在always區塊內,每個clock的正緣(Posedge)都會加1,用如下always區塊表示:

always @(posedge clock) 

begin

count <= count+1;

end

   

其中的 ” <= “ 便為程序性賦值中的非阻塞型賦值(non-blocking assignment),程序性賦值還包含” = “阻塞型賦值(blocking assignment),兩者差別在賦值順序。

 

例如:

非阻塞型賦值:

B <= A;

C <= B;

右式的A, B同時賦值給左式的B, C,在同一區塊內的非阻塞賦值同時執行。

              

阻塞型賦值:

B = A;

C = B;

右式的A先賦值給左式的B,再執行下一句,B再賦值給左式的C。前一個阻塞賦值執行完後,才會再執行下一個阻塞賦值。



硬體描述方式

在描述一個電路時,可以用從數據的流向行為結構這三種觀點來描述,用上面提到的半加法器電路來說明。

                                    

                                    

    • 數據流描述:透過連續性賦值(continuous assignment)的方式來描述數據的流向。先宣告變數A,B,S,C:

    input wire A,B;

    output wire S,C;


    再用assign語句及邏輯運算子描述output與input的關係:

    assign S = A ^ B;

    assign C = A & B;


    • 行為描述:透過程序性賦值(procedural assignment)的方式來描述電路行為。由於程序性賦值的變數型態必須為變量型態,因此宣告S,C為reg型態。

    先宣告變數A,B,S,C:

    input wire A,B;

    output reg S,C;


    再用always區塊描述行為:

    always @ (A or B) begin

    S <= A ^ B;

    C <= A & B;

    end

    或可以再精簡成

    always @ (A or B) begin

    {S,C} <= A + B;

    end


    • 結構描述:透過模組的輸入、輸出來表示硬體的結構。 Verilog內建有switch(pmos, nmos,...)及logic gate(and, or, xor,...),可以從底層的模組來建立上層的結構。

    半加法器由一個xor及一個and gate組成:

    xor XOR1(S,A,B);

    and AND1(C,A,B);

    這個完成的半加法器,也可以當做一個更上層結構的一個子模組,再拼湊出上層所要的結構。

    同一個電路,可以用三種不同的方式來描述。然而在多層次的電路中,較底層的電路一般會用「行為描述」來表示電路;較高層次的電路,再用「結構描述」的方式,來組成更高層次所需要的結構。


    從硬體「描述」到硬體「驗證」

    在硬體的「驗證」上,重點則放在電路模擬的效能、驗證平台及場景的可復用性、靈活性,以及驗證的完整程度,和最後驗證成果的量化上。System Verilog,便在這幾個方面上加強了原先Verilog所沒有的功能。
    • 提升電路模擬的效能:System Verilog引入了2-type,即只有0, 1兩種狀態的變數型態,節省記憶體空間,以達到更加的模擬效能。同時也引入了queue,dynamic arrayassociative array等等的資料型態,對於驗證平台在建立模型、計分版時,能做到更靈活的資料配置。
    • 提升驗證平台及場景的復用性與靈活性:System Verilog引進了軟體物件導向(OOP, Object-Oriented Programming)觀念,使用OOP的封裝特性來為驗證平台及場景做模組化與抽象化,並可使用OOP的繼承、多態來為模組做擴充、重寫,使得驗證環境能做到更佳的復用性及靈活性。時程控制上也引入了事件(Event), fork join_any, fork join_none,...等等的流程控制與描述方式,以達到更佳的資料傳遞與流程管控。
    • 提升驗證完整程度及量化驗證成果:引入Constrained Randomization(約束隨機)來為驗證場景做各種更有意義的約束(Constraint),透過在bit level層級設計各種約束,便能從更高的抽象層級設計驗證場景,在有意義的範圍內大量的隨機化。量化驗證成果方面,也提供覆蓋組(Cover Group)針對硬體的各個功能分撰寫,並在覆蓋率報告(Coverage Report)內檢查功能是否在驗證場景涵蓋。
    對於商業上的開發,通常一套驗證環境會套用在不同硬體設計的計畫案上,並使用不同的define MACRO做區隔,驗證環境的靈活性及可復用性便相當重要。若驗證平台的基礎能做到良好的可復用性,在不同的計畫案便能使用軟體的設計模式(Design Pattern)思維來為平台重寫,客製化每個計畫案的場景、約束,及行為模型,便能更有效地同時維護不同的計畫案。

    硬體描述語言自1984年發展至今,已能從各個層級來描述硬體的功能;
    而硬體描述語言在驗證的應用也在2005年後快速進展,並陸續推出各種函式庫(VMM, UVM),能從更抽象的層級來開發驗證環境,使設計及驗證的環境開發更加完備及高效。


    參考資料:
    1. 硬體描述語言VHDL & Verilog設計導論, 蔡宏儒   
    2. Verilog HDL入門(第3版), 夏宇聞,甘偉譯, J.Bhasker著
    3. SystemVerilog驗證(第2版), 張春, 麥宋平, 趙益新譯, Chris Spear著

    留言