當(dāng)前位置:首頁(yè) > 百科知識(shí) > 電子工程 > 正文

Verilog HDL

  Verilog HDL是一種硬件描述語(yǔ)言(HDL:Hardware Description Language),以文本形式來(lái)描述數(shù)字系統(tǒng)硬件的結(jié)構(gòu)和行為的語(yǔ)言,用它可以表示邏輯電路圖、邏輯表達(dá)式,還可以表示數(shù)字邏輯系統(tǒng)所完成的邏輯功能。 Verilog HDL和VHDL是世界上最流行的兩種硬件描述語(yǔ)言,都是在20世紀(jì)80年代中期開(kāi)發(fā)出來(lái)的。前者由Gateway Design Automation公司(該公司于1989年被Cadence公司收購(gòu))開(kāi)發(fā)。兩種HDL均為IEEE標(biāo)準(zhǔn)。

  發(fā)展歷史

  參見(jiàn):SystemVerilog

  Verilogs是由Gateway設(shè)計(jì)自動(dòng)化公司的工程師于1983年末創(chuàng)立的。當(dāng)時(shí)Gateway設(shè)計(jì)自動(dòng)化公司還叫做自動(dòng)集成設(shè)計(jì)系統(tǒng)(Automated Integrated Design Systems),1985年公司將名字改成了前者。該公司的菲爾·莫比(Phil Moorby)完成了Verilog的主要設(shè)計(jì)工作。1990年,Gateway設(shè)計(jì)自動(dòng)化被Cadence公司收購(gòu)。

  1990年代初,開(kāi)放Verilog國(guó)際(Open Verilog International, OVI)組織(即現(xiàn)在的Accellera)成立,Verilog面向公有領(lǐng)域開(kāi)放。1992年,該組織尋求將Verilog納入電氣電子工程師學(xué)會(huì)標(biāo)準(zhǔn) 。最終,Verilog成為了電氣電子工程師學(xué)會(huì)1364-1995標(biāo)準(zhǔn),即通常所說(shuō)的Verilog-95。

  設(shè)計(jì)人員在使用這個(gè)版本的Verilog的過(guò)程中發(fā)現(xiàn)了一些可改進(jìn)之處。為了解決用戶(hù)在使用此版本Verilog過(guò)程中反映的問(wèn)題,Verilog進(jìn)行了修正和擴(kuò)展,這部分內(nèi)容后來(lái)再次被提交給電氣電子工程師學(xué)會(huì)。這個(gè)擴(kuò)展后的版本后來(lái)成為了電氣電子工程師學(xué)會(huì)1364-2001標(biāo)準(zhǔn),即通常所說(shuō)的Verilog-2001。Verilog-2001是對(duì)Verilog-95的一個(gè)重大改進(jìn)版本,它具備一些新的實(shí)用功能,例如敏感列表、多維數(shù)組、生成語(yǔ)句塊、命名端口連接等。目前,Verilog-2001是Verilog的最主流版本,被大多數(shù)商業(yè)電子設(shè)計(jì)自動(dòng)化軟件包支持。

  2005年,Verilog再次進(jìn)行了更新,即電氣電子工程師學(xué)會(huì)1364-2005標(biāo)準(zhǔn)。該版本只是對(duì)上一版本的細(xì)微修正。這個(gè)版本還包括了一個(gè)相對(duì)獨(dú)立的新部分,即Verilog-AMS。這個(gè)擴(kuò)展使得傳統(tǒng)的Verilog可以對(duì)集成的模擬和混合信號(hào)系統(tǒng)進(jìn)行建模。容易與電氣電子工程師學(xué)會(huì)1364-2005標(biāo)準(zhǔn)混淆的是加強(qiáng)硬件驗(yàn)證語(yǔ)言特性的SystemVerilog(電氣電子工程師學(xué)會(huì)1800-2005標(biāo)準(zhǔn)),它是Verilog-2005的一個(gè)超集,它是硬件描述語(yǔ)言、硬件驗(yàn)證語(yǔ)言(針對(duì)驗(yàn)證的需求,特別加強(qiáng)了面向?qū)ο筇匦裕┑囊粋€(gè)集成。

  2009年,IEEE 1364-2005和IEEE 1800-2005兩個(gè)部分合并為IEEE 1800-2009,成為了一個(gè)新的、統(tǒng)一的SystemVerilog硬件描述驗(yàn)證語(yǔ)言(hardware description and verification language, HDVL)。

  以模塊為基礎(chǔ)的設(shè)計(jì)

  描述復(fù)雜的硬件電路,設(shè)計(jì)人員總是將復(fù)雜的功能劃分為簡(jiǎn)單的功能,模塊是提供每個(gè)簡(jiǎn)單功能的基本結(jié)構(gòu)。設(shè)計(jì)人員可以采取“自頂向下”的思路,將復(fù)雜的功能模塊劃分為低層次的模塊。這一步通常是由系統(tǒng)級(jí)的總設(shè)計(jì)師完成,而低層次的模塊則由下一級(jí)的設(shè)計(jì)人員完成。自頂向下的設(shè)計(jì)方式有利于系統(tǒng)級(jí)別層次劃分和管理,并提高了效率、降低了成本。“自底向上”方式是“自頂向下”方式的逆過(guò)程。

  使用Verilog描述硬件的基本設(shè)計(jì)單元是模塊(module)。構(gòu)建復(fù)雜的電子電路,主要是通過(guò)模塊的相互連接調(diào)用來(lái)實(shí)現(xiàn)的。模塊被包含在關(guān)鍵字module、endmodule之內(nèi)。實(shí)際的電路元件。Verilog中的模塊類(lèi)似C語(yǔ)言中的函數(shù),它能夠提供輸入、輸出端口,可以實(shí)例調(diào)用其他模塊,也可以被其他模塊實(shí)例調(diào)用。模塊中可以包括組合邏輯部分、過(guò)程時(shí)序部分。例如,四選一的多路選擇器,就可以用模塊進(jìn)行描述。它具有兩個(gè)位選輸入信號(hào)、四個(gè)數(shù)據(jù)輸入,一個(gè)輸出端,在Verilog中可以表示為:

  module mux (out, select, in0, in1, in2, in3);output out;input [1:0] select;input in0, in1, in2, in3;//具體的寄存器傳輸級(jí)代碼endmodule

  設(shè)計(jì)人員可以使用一個(gè)頂層模塊,通過(guò)實(shí)例調(diào)用上面這個(gè)模塊的方式來(lái)進(jìn)行測(cè)試。這個(gè)頂層模塊常被稱(chēng)為“測(cè)試平臺(tái)(Testbench)”。為了最大程度地對(duì)電路的邏輯進(jìn)行功能驗(yàn)證,測(cè)試代碼需要盡可能多地覆蓋系統(tǒng)所涉及的語(yǔ)句、分支、條件、路徑、觸發(fā)、狀態(tài)機(jī)狀態(tài),驗(yàn)證人員需要在測(cè)試平臺(tái)里創(chuàng)建足夠多的輸入激勵(lì),并連接到被測(cè)模塊的輸入端,然后檢測(cè)其輸出端的表現(xiàn)是否符合預(yù)期(諸如SystemVerilog的硬件驗(yàn)證語(yǔ)言能夠提供針對(duì)驗(yàn)證專(zhuān)門(mén)優(yōu)化的數(shù)據(jù)結(jié)構(gòu),以隨機(jī)測(cè)試的方式進(jìn)行驗(yàn)證,這對(duì)于高度復(fù)雜的集成電路設(shè)計(jì)驗(yàn)證可以起到關(guān)鍵作用)。實(shí)例調(diào)用模塊時(shí),需要將端口的連接情況按照這個(gè)模塊聲明時(shí)的順序排列。這個(gè)頂層模塊由于不需要再被外界調(diào)用,因此沒(méi)有輸入輸出端口:

  module tester;reg [1:0] SELECT;reg IN0, IN1, IN2, IN3;wire OUT;mux my_mux (OUT, SELECT, IN0, IN1, IN2, IN3); //實(shí)例調(diào)用mux模塊,這個(gè)實(shí)例被命名為my_muxinitial //需要仿真的激勵(lì)代碼 begin endendmodule

  在這個(gè)測(cè)試平臺(tái)模塊里,設(shè)計(jì)人員可以設(shè)定仿真時(shí)的輸入信號(hào)以及信號(hào)監(jiān)視程序,然后觀察仿真時(shí)的輸出情況是否符合要求,這樣就可以了解設(shè)計(jì)是否達(dá)到了預(yù)期。

  示例中的對(duì)模塊進(jìn)行實(shí)例引用時(shí),按照原模塊聲明時(shí)的順序羅列了輸入變量。除此之外,還可以使用或者采用命名端口連接的方式。使用這種方式,端口的排列順序可以與原模塊聲明時(shí)不同,甚至可以不連接某些端口:

  mux my_mux (.out(OUT), .select(SELECT), .in0(IN0), .in1(IN1), .in2(IN2), .in3(IN3));//使用命名端口連接,括號(hào)外面是模塊聲明時(shí)的端口,括號(hào)內(nèi)是實(shí)際的端口連接//括號(hào)外相當(dāng)于C語(yǔ)言的形式參數(shù),括號(hào)內(nèi)相當(dāng)于實(shí)際參數(shù)endmodule

  上面所述的情況是,測(cè)試平臺(tái)頂層模塊的測(cè)試變量直接連接了所設(shè)計(jì)的功能模塊。測(cè)試平臺(tái)還可以是另一種形式,即測(cè)試平臺(tái)并不直接連接所設(shè)計(jì)的功能模塊,而是在這個(gè)測(cè)試平臺(tái)之下,將激勵(lì)模塊和功能模塊以相同的抽象級(jí)別,通過(guò)線網(wǎng)相互連接。這兩種形式的測(cè)試平臺(tái)都可以完成對(duì)功能模塊的測(cè)試。大型的電路系統(tǒng),正是由各個(gè)層次不同模塊之間的連接、調(diào)用,來(lái)實(shí)現(xiàn)復(fù)雜的功能的。

  語(yǔ)言要素

  Verilog的設(shè)計(jì)初衷是成為一種基本語(yǔ)法與C語(yǔ)言相近的硬件描述語(yǔ)言。這是因?yàn)镃語(yǔ)言在Verilog設(shè)計(jì)之初,已經(jīng)在許多領(lǐng)域得到廣泛應(yīng)用,C語(yǔ)言的許多語(yǔ)言要素已經(jīng)被許多人習(xí)慣。一種與C語(yǔ)言相似的硬件描述語(yǔ)言,可以讓電路設(shè)計(jì)人員更容易學(xué)習(xí)和接受。不過(guò),Verilog與C語(yǔ)言還是存在許多差別。另外,作為一種與普通計(jì)算機(jī)編程語(yǔ)言不同的硬件描述語(yǔ)言,它還具有一些獨(dú)特的語(yǔ)言要素,例如向量形式的線網(wǎng)和寄存器、過(guò)程中的非阻塞賦值等??偟膩?lái)說(shuō),具備C語(yǔ)言的設(shè)計(jì)人員將能夠很快掌握Verilog硬件描述語(yǔ)言。

  基本規(guī)范

  空白符

  空白符是指代碼中的空格(對(duì)應(yīng)的轉(zhuǎn)義標(biāo)識(shí)符為\b)、制表符(\t)和換行(\n)。如果這些空白符出現(xiàn)在字符串里,那么它們不可忽略。除此之外,代碼中的其他空白符在編譯的時(shí)候都將會(huì)被視為分隔標(biāo)識(shí)符,即使用2個(gè)空格或者1個(gè)空格并無(wú)影響。不過(guò),在代碼中使用合適的空格,可以讓上下行代碼的外觀一致(例如使賦值運(yùn)算符位于同一個(gè)豎直列),從而提高代碼的可讀性。

  注釋

  為了方便代碼的修改或其他人的閱讀,設(shè)計(jì)人員通常會(huì)在代碼中加入注釋。與C語(yǔ)言一樣,有兩種方式書(shū)寫(xiě)注釋。第一種為多行注釋?zhuān)醋⑨審?*開(kāi)始,直到*/才結(jié)束;另一種為單行注釋?zhuān)⑨審?/開(kāi)始,從這里到這一行末尾的內(nèi)容會(huì)被系統(tǒng)識(shí)別為注釋。

  某些電子設(shè)計(jì)自動(dòng)化工具,會(huì)識(shí)別出代碼中以特殊格式書(shū)寫(xiě)、含有某些預(yù)先約定關(guān)鍵詞的注釋?zhuān)倪@些注釋所提取有用的信息。這些注釋不是供人閱讀,而是向第三方工具提供有關(guān)設(shè)計(jì)項(xiàng)目的額外信息。例如,某些邏輯綜合工具可以從注釋中讀取綜合的約束信息。

  大小寫(xiě)敏感性

  Verilog是一種大小寫(xiě)敏感的硬件描述語(yǔ)言。其中,它的所有系統(tǒng)關(guān)鍵字都是小寫(xiě)的。

  標(biāo)識(shí)符及保留字

  Verilog代碼中用來(lái)定義語(yǔ)言結(jié)構(gòu)名稱(chēng)的字符稱(chēng)為標(biāo)識(shí)符,包括變量名、端口名、模塊名等等。標(biāo)識(shí)符可以由字母、數(shù)字、下劃線以及美元符($)來(lái)表示。但是標(biāo)識(shí)符的第一個(gè)字符只能是字母、數(shù)字或者下劃線,不能為美元符,這是因?yàn)橐悦涝_(kāi)始的標(biāo)識(shí)符和系統(tǒng)任務(wù)的保留字沖突。

  和其他許多編程語(yǔ)言類(lèi)似,Verilog也有許多保留字(或稱(chēng)為關(guān)鍵字),用戶(hù)定義的標(biāo)識(shí)符不能夠和保留字相同。Verilog的保留字均為小寫(xiě)。變量類(lèi)型中的wire、reg、integer等、表示過(guò)程的initial、always等,以及所有其他的系統(tǒng)任務(wù)、編譯指令,都是關(guān)鍵字??梢圆殚喒俜轿墨I(xiàn)以完整的關(guān)鍵字的列表。

  轉(zhuǎn)義標(biāo)識(shí)符

  轉(zhuǎn)義標(biāo)識(shí)符(又稱(chēng)轉(zhuǎn)義字符),是由\開(kāi)始,以空白符結(jié)束的一種特殊編程語(yǔ)言結(jié)構(gòu)。這種結(jié)構(gòu)可以用來(lái)表示那些容易與系統(tǒng)語(yǔ)言結(jié)構(gòu)相同的內(nèi)容(例如"在系統(tǒng)中被用來(lái)表示字符串,如果字符串本身的內(nèi)容包含一個(gè)與之形式相同的雙引號(hào),那么就必須使用轉(zhuǎn)義標(biāo)識(shí)符)。下面列出了常用的幾種轉(zhuǎn)義標(biāo)識(shí)符。除此之外,在反斜線之后也可以加上字符的ASCII,這種轉(zhuǎn)義標(biāo)識(shí)符相當(dāng)于一個(gè)字符。常用的轉(zhuǎn)義標(biāo)識(shí)符有\(zhòng)n(換行)、\t(制表位)、\b(空格)、\\(反斜杠)和\"(英文的雙引號(hào))等。

  數(shù)據(jù)類(lèi)型

  四值邏輯

  邏輯值及其解釋

  0:邏輯低電平,條件為假

  1:邏輯高電平,條件為真

  z:高阻態(tài),浮動(dòng)

  x:未知邏輯電平

  信號(hào)強(qiáng)度(從強(qiáng)到弱)及其屬性

  supply:驅(qū)動(dòng)

  strong:驅(qū)動(dòng)

  pull:驅(qū)動(dòng)

  large:存儲(chǔ)

  weak:驅(qū)動(dòng)

  medium:存儲(chǔ)

  small:存儲(chǔ)

  highz:高阻態(tài)

  上面列出了Verilog采用的具有八種信號(hào)強(qiáng)度的四值邏輯(four-valued logic),數(shù)字電路中的信號(hào)可以用邏輯值、信號(hào)強(qiáng)度加以描述。當(dāng)系統(tǒng)遇到信號(hào)之間的競(jìng)爭(zhēng)時(shí),需要考慮各組信號(hào)的狀態(tài)和強(qiáng)度。如果驅(qū)動(dòng)統(tǒng)一線網(wǎng)的信號(hào)強(qiáng)度不同,則輸出結(jié)果是信號(hào)強(qiáng)度高的值;如果兩個(gè)強(qiáng)度相同的信號(hào)之間連接到同一個(gè)線網(wǎng),將會(huì)發(fā)生競(jìng)爭(zhēng),結(jié)果為不確定值x。

  線網(wǎng)與寄存器

  Verilog所用到的所有變量都屬于兩個(gè)基本的類(lèi)型:線網(wǎng)類(lèi)型和寄存器類(lèi)型。[2]

  線網(wǎng)與我們實(shí)際使用的電線類(lèi)似,它的數(shù)值一般只能通過(guò)連續(xù)賦值(continuous assignment),由賦值符右側(cè)連接的驅(qū)動(dòng)源決定。線網(wǎng)在初始化之前的值為x(trireg類(lèi)型的線網(wǎng)是一個(gè)例外,它相當(dāng)于能夠儲(chǔ)存電荷的電容器)。如果未連接驅(qū)動(dòng)源,則該線網(wǎng)變量的當(dāng)前數(shù)值為z,即高阻態(tài)。線網(wǎng)類(lèi)型的變量有以下幾種:wire、tri、wor、trior、wand、triand、tri0、tri1、supply0、supply1、trireg,其中wire作為一般的電路連線使用最為普遍,而其他幾種用于構(gòu)建總線,即多個(gè)驅(qū)動(dòng)源連接到一條線網(wǎng)的情況,或搭建電源、接地等。當(dāng)進(jìn)行模塊的端口聲明時(shí),如果沒(méi)有明確指出其類(lèi)型,那么這個(gè)端口會(huì)被隱含地聲明為wire類(lèi)型。因此,在聲明輸出端口時(shí)應(yīng)該注意是否有必要加上reg關(guān)鍵字。以下面的代碼片段為例:

  module my_moule (out1, out2, in1, in2); //該模塊具有兩個(gè)輸出端口 output reg out1; //out1端口被聲明為為reg類(lèi)型,它可以保存當(dāng)前值 output out2; //out2端口隱含地被聲明為為wire類(lèi)型,它的數(shù)值必須依賴(lài)連續(xù)賦值語(yǔ)句維持endmodule

  寄存器與之不同,它可以保存當(dāng)前的數(shù)值,直到另一個(gè)數(shù)值被賦值給它。在保持當(dāng)前數(shù)值的過(guò)程中,不需要驅(qū)動(dòng)源對(duì)它進(jìn)行作用。如果未對(duì)寄存器變量賦值,它的初始值則為x。Verilog中所說(shuō)的寄存器類(lèi)型變量與真實(shí)的硬件寄存器是不同的,它是指一個(gè)儲(chǔ)存數(shù)值的變量。如果要在一個(gè)過(guò)程(initial過(guò)程或always過(guò)程)里對(duì)變量賦值,這個(gè)變量必須是寄存器類(lèi)型的。寄存器類(lèi)型的變量有以下幾種:reg(普通寄存器)、integer(整數(shù))、time(時(shí)間)、real(實(shí)數(shù)),其中reg作為一般的寄存器使用最為普遍。利用寄存器變量的數(shù)組,還可以對(duì)ROM進(jìn)行建模。

  關(guān)于選擇線網(wǎng)類(lèi)型還是寄存器類(lèi)型,需要符合一定的規(guī)定。模塊的輸入端口可以與外界的線網(wǎng)或寄存器類(lèi)型的變量連接,但是這個(gè)模塊輸出端口只能連接到外界的線網(wǎng)。再簡(jiǎn)單點(diǎn),就是在兩個(gè)模塊的信號(hào)連接點(diǎn),提供信號(hào)的一方可以是寄存器或者線網(wǎng),但是接受信號(hào)的一方只能是線網(wǎng)。此外,在initial、always過(guò)程代碼塊中賦值的變量必須是寄存器類(lèi)型的,而連續(xù)賦值的對(duì)象只能是線網(wǎng)類(lèi)型的變量。

  數(shù)字的表示

  在Verilog里,當(dāng)一個(gè)變量的類(lèi)型確定,即已經(jīng)知道它是寄存器類(lèi)型或者是線網(wǎng)類(lèi)型,當(dāng)把具體的數(shù)值賦值給它時(shí),需要利用下面所述的數(shù)字表示方法。數(shù)字表示的基本語(yǔ)法結(jié)構(gòu)為<位寬>'<數(shù)制的符號(hào)><數(shù)值>。其中,位寬是與數(shù)據(jù)大小相等的對(duì)應(yīng)二進(jìn)制數(shù)的位數(shù)加上占位所用0的位數(shù),這個(gè)位數(shù)需要使用十進(jìn)制來(lái)表示。位寬是可選項(xiàng),如果沒(méi)有指明位寬,則默認(rèn)的數(shù)據(jù)位寬與仿真器有關(guān)(最小32位);數(shù)制需要用字母來(lái)表示,h對(duì)應(yīng)十六進(jìn)制,d對(duì)應(yīng)十進(jìn)制,o對(duì)應(yīng)八進(jìn)制,b對(duì)應(yīng)二進(jìn)制。如果沒(méi)有指明數(shù)制,則默認(rèn)數(shù)據(jù)為十進(jìn)制數(shù)。例如:

  12'h123:十六進(jìn)制數(shù)123(使用12位)

  20'd44:十進(jìn)制數(shù)44(使用20位,高位自動(dòng)使用0填充)

  4'b1010:二進(jìn)制數(shù)1010(使用4位)

  6'o77:八進(jìn)制數(shù)77(使用6位)

  如果某個(gè)數(shù)的最高位為x或z,那么系統(tǒng)會(huì)自動(dòng)使用x或z來(lái)填充沒(méi)有占據(jù)的更高位。如果最高位為其他情況,系統(tǒng)會(huì)自動(dòng)使用0來(lái)填充沒(méi)有占據(jù)的更高位。

  另外,如果需要使用reg表示負(fù)數(shù),可以在位寬之前添加一個(gè)負(fù)號(hào),但是需要注意后面的數(shù)值為所需負(fù)數(shù)的二進(jìn)制補(bǔ)碼。為了防止出錯(cuò),可以直接使用整數(shù)integer或?qū)崝?shù)real,二者都是帶符號(hào)數(shù),再利用省略位寬和數(shù)制的十進(jìn)制數(shù)來(lái)表示負(fù)數(shù)。

  向量

  向量形式的數(shù)據(jù)是Verilog相對(duì)C語(yǔ)言較為特殊的一種數(shù)據(jù),但是這種數(shù)據(jù)在硬件描述語(yǔ)言中十分重要。在Verilog中,標(biāo)量的意思是只具有一個(gè)二進(jìn)制位的變量,而向量表示具有多個(gè)二進(jìn)制位的變量。如果沒(méi)有特別指明位寬,系統(tǒng)默認(rèn)它為標(biāo)量。

  在真實(shí)的數(shù)字電路,例如將兩個(gè)四位二進(jìn)制數(shù)相加的進(jìn)位加法器中,我們可以發(fā)現(xiàn),其中一個(gè)數(shù)是通過(guò)四條電線(每條線表示四位中的某一位)連接到加法器上的。我們可以用一個(gè)向量來(lái)表示這個(gè)多位數(shù),分別用這個(gè)向量的各個(gè)分量來(lái)表示“四條電線”,即四位中的某一位。這樣做的好處是,可以方便地在Verilog代碼的其他地方選擇其中的一位(位選)或多位(域選)。當(dāng)然,如果沒(méi)有進(jìn)行位選或域選,則這個(gè)多位數(shù)整體被選擇。

  向量的表示需要使用方括號(hào),方括號(hào)里的第一個(gè)數(shù)字為向量第一個(gè)分量的序號(hào),第二個(gè)數(shù)字為向量最后一個(gè)分量的序號(hào),中間用冒號(hào)隔開(kāi)。向量分量的序號(hào)不像C語(yǔ)言的數(shù)組一樣必須從0開(kāi)始,不過(guò)為了和數(shù)字電路里二進(jìn)制數(shù)高低位的表示方法一致,我們常常讓最低位為0(即對(duì)于四位二進(jìn)制數(shù),其最高位為第3位,次高位為第2位,次低位為第1位,最低位為第0位),當(dāng)然這只是一種習(xí)慣。例如,上面提到的四位二進(jìn)制數(shù)用向量表示為:

  wire [3:0] input_add; //聲明名為input_add的4位wire型向量wire [4:1] input_add1; //也是4位wire型向量,但是分量序號(hào)從4到1wire [0:3] input_add2; //也是4位wire型向量,但是分量序號(hào)從0到3

  上面的向量聲明之后,我們就可以方便地選擇其中的某幾個(gè)分量進(jìn)行操作。請(qǐng)注意用于域選的方括號(hào)的位置在向量名稱(chēng)之后,方括號(hào)內(nèi)的數(shù)字為所需的位數(shù)。例如我們可以進(jìn)行以下操作:

  input_add [3] = 1'b1; //將1賦值給input_add向量的第三位(最高位)input_add [1:0] = 2'b01; //將0和1分別賦值給input_add向量的第1、0位(最低兩位)

  當(dāng)對(duì)向量進(jìn)行賦值時(shí),如果右邊的數(shù)值位寬大于左邊的變量,則多出來(lái)的位被丟棄;如果右邊的數(shù)值位寬小于左邊的變量,則不夠的位用0填補(bǔ)。

  數(shù)組

  Verilog中的幾種寄存器類(lèi)型的數(shù)據(jù),包括reg、integer、time、real,以及由這幾種數(shù)據(jù)構(gòu)成的向量,都可以構(gòu)成數(shù)組。聲明數(shù)組時(shí),方括號(hào)位于數(shù)組名的后面,括號(hào)內(nèi)的第一個(gè)數(shù)字為第一個(gè)元素的序號(hào),第二個(gè)數(shù)字為最后一個(gè)元素的序號(hào),中間用冒號(hào)隔開(kāi)。如果數(shù)組是由向量構(gòu)成的,則數(shù)組的其中某個(gè)元素是向量。同樣,出于習(xí)慣考慮,我們一般讓數(shù)組第一個(gè)元素的序號(hào)為0,后面元素的序號(hào)依次遞增。此外,和C語(yǔ)言類(lèi)似,用戶(hù)可以聲明多維數(shù)組。例如:

  integer number [0:100]; //聲明一個(gè)有101個(gè)元素的整數(shù)數(shù)組number [25] = 1234; //將1234賦值給25號(hào)(第26個(gè))元素reg [7:0] my_input [65535:0]; //聲明一個(gè)有65536個(gè)元素的8位向量寄存器my_input [97] = 8'b10110101; //將10110101分別賦值給97號(hào)(第2個(gè))元素的7至0位reg my_reg [0:3][0:4]; //聲明一個(gè)具有20個(gè)元素的二維寄存器數(shù)組my_reg [1][2] = 1'b1; //將1賦值給上述二維數(shù)組的第2行、第3列元素

  由于數(shù)組和向量的表示都使用了方括號(hào),因此使用時(shí)需要注意這個(gè)變量或向量的名稱(chēng)在最初被聲明為何種類(lèi)型的數(shù)據(jù)。上面第三行的例子是65536個(gè)8位向量組成的向量數(shù)組,它可以描述一個(gè)64KB的存儲(chǔ)器。

  表示數(shù)組某個(gè)元素時(shí),允許使用變量來(lái)表示元素的索引(如number [i] = 1234;),但是表示一個(gè)向量的一位或者幾位時(shí),只允許使用數(shù)字來(lái)表示位的索引;此外,使用數(shù)組時(shí)一次只能對(duì)一個(gè)元素進(jìn)行操作,而不能向向量那樣同時(shí)對(duì)連續(xù)的幾個(gè)位進(jìn)行操作,例如my_input [65535][7:4] = 4'b1010;將一個(gè)四位二進(jìn)制數(shù)賦值給第65536個(gè)元素的高四位。

  參數(shù)

  可以通過(guò)parameter關(guān)鍵字聲明參數(shù)。參數(shù)與常數(shù)的意義類(lèi)似,不能夠通過(guò)賦值運(yùn)算改變它的數(shù)值。在模塊進(jìn)行實(shí)例化時(shí),可以能夠通過(guò)defparam,即參數(shù)重載語(yǔ)句塊來(lái)改變模塊實(shí)例的參數(shù)。另一種方法是在模塊實(shí)例化時(shí),使用#()將所需的實(shí)例參數(shù)覆蓋模塊的默認(rèn)參數(shù)。局部參數(shù)可以用localparam關(guān)鍵字聲明,它不能夠進(jìn)行參數(shù)重載。

  在設(shè)計(jì)中使用參數(shù),可以使得模塊代碼在不同條件下被重復(fù)利用,例如四位數(shù)全加器和十六位數(shù)全加器可以通過(guò)參數(shù)實(shí)例化同一個(gè)通用全加器模塊。

  字符串

  Verilog中的字符串總體來(lái)說(shuō)與C語(yǔ)言中的字符串較為類(lèi)似,其中每個(gè)字符以ASCII表示,占8位。字符串存儲(chǔ)在位寬足夠的向量寄存器中。字符串中的空格、換行等特殊內(nèi)容,以轉(zhuǎn)義標(biāo)識(shí)符(參見(jiàn)前面提到過(guò)的轉(zhuǎn)義標(biāo)識(shí)符)的形式表示。

  流程控制

  為了使設(shè)計(jì)人員方便地使用寄存器傳輸級(jí)描述,Verilog提供了多種流程控制結(jié)構(gòu),包括if、if...else、if...else if...else等形式的條件結(jié)構(gòu),case分支結(jié)構(gòu),for、while循環(huán)結(jié)構(gòu)。這些流程控制結(jié)構(gòu)與C語(yǔ)言有著相似的用法。不同的循環(huán)結(jié)構(gòu)可能造成不同的邏輯綜合結(jié)果。

  Verilog也提供了一些C語(yǔ)言中沒(méi)有的流程控制結(jié)構(gòu)以適應(yīng)硬件描述語(yǔ)言的需要,例如casex、casez兩種選擇結(jié)構(gòu),前者可以條件數(shù)值中的x、z均作為無(wú)關(guān)值,后者僅將z作為無(wú)關(guān)值;此外還提供了forever、repeat兩種循環(huán)結(jié)構(gòu),分別用于無(wú)限循環(huán)和指定次數(shù)循環(huán)。數(shù)字電路的邏輯功能描述常常使用到這些流程控制結(jié)構(gòu),例如,case結(jié)構(gòu)可以清晰地描述一個(gè)數(shù)據(jù)選擇器。

  運(yùn)算符

  Verilog的許多運(yùn)算符和C語(yǔ)言類(lèi)似,但是有一部分運(yùn)算符是特有的,例如拼接運(yùn)算符、縮減運(yùn)算符、帶有無(wú)關(guān)位的相等運(yùn)算符等。

  Verilog的常見(jiàn)運(yùn)算符隱藏▲

  按位

  按位取反(~):1個(gè)多位操作數(shù)按位取反。例如:a=4'b1011,則~a的結(jié)果為4'b0100

  按位與(&):2個(gè)多位操作數(shù)按位進(jìn)行與運(yùn)算,各位的結(jié)果按順序組成一個(gè)新的多位數(shù)。例如:a=2'b10,b=2'b11,則a&b的結(jié)果為2'b10

  按位或(|):2個(gè)多位操作數(shù)按位進(jìn)行或運(yùn)算,各位的結(jié)果按順序組成一個(gè)新的多位數(shù)。例如:a=2'b10,b=2'b11,則a|b的結(jié)果為2'b11

  按位異或(^):2個(gè)多位操作數(shù)按位進(jìn)行異或運(yùn)算,各位的結(jié)果按順序組成一個(gè)新的多位數(shù)。例如:a=2'b10,b=2'b11,則a^b的結(jié)果為2'b01

  按位同或(~^或^~):2個(gè)多位操作數(shù)按位進(jìn)行同或運(yùn)算,各位的結(jié)果按順序組成一個(gè)新的多位數(shù)。例如:a=2'b10,b=2'b11,則a~^b的結(jié)果為2'b10

  邏輯

  邏輯取反(!):對(duì)1個(gè)操作數(shù)進(jìn)行邏輯取反,如果這個(gè)操作數(shù)為0,則結(jié)果為1;如果這個(gè)操作數(shù)不為0,則結(jié)果為0

  邏輯與(&&):對(duì)2個(gè)操作數(shù)進(jìn)行邏輯與,如果二者同為0或同不為0,則結(jié)果為1,否則為0。例如:3 && 0的結(jié)果為0。

  邏輯或(||):對(duì)2個(gè)操作數(shù)進(jìn)行邏輯或,如果二者其中至少有一個(gè)不為0,則結(jié)果為1,否則為0。例如:3||0的結(jié)果為1。

  縮減

  縮減與(&):對(duì)一個(gè)多位操作數(shù)進(jìn)行縮減與操作,先將它最高位與次高位進(jìn)行與操作,其結(jié)果再與第二次高位進(jìn)行與操作,直到最低位。例如:&(4'b1011)的結(jié)果為0

  縮減與非(~&):對(duì)一個(gè)多位操作數(shù)進(jìn)行縮減與非操作,先將它最高位與次高位進(jìn)行與非操作,其結(jié)果再與第二次高位進(jìn)行與非操作,直到最低位。例如:~&(4'b1011)的結(jié)果為1

  縮減或(|):對(duì)一個(gè)多位操作數(shù)進(jìn)行縮減或操作,先將它最高位與次高位進(jìn)行或操作,其結(jié)果再與第二次高位進(jìn)行或操作,直到最低位。例如:|(4'b1011)的結(jié)果為1

  縮減或非(~|):對(duì)一個(gè)多位操作數(shù)進(jìn)行縮減或非操作,先將它最高位與次高位進(jìn)行或非操作,其結(jié)果再與第二次高位進(jìn)行或非操作,直到最低位。例如:|(4'b1011)的結(jié)果為0

  縮減異或(^):對(duì)一個(gè)多位操作數(shù)進(jìn)行縮減異或操作,先將它最高位與次高位進(jìn)行異或操作,其結(jié)果再與第二次高位進(jìn)行異或操作,直到最低位。例如:^(4'b1011)的結(jié)果為1

  縮減同或(~^or^~):對(duì)一個(gè)多位操作數(shù)進(jìn)行縮減同或操作,先將它最高位與次高位進(jìn)行同或操作,其結(jié)果再與第二次高位進(jìn)行同或操作,直到最低位。例如:~^(4'b1011)的結(jié)果為0

  算術(shù)

  加(+):2個(gè)操作數(shù)相加

  減(-):2個(gè)操作數(shù)相減或取1個(gè)操作數(shù)的負(fù)數(shù)(二進(jìn)制補(bǔ)碼表示)

  乘(*):2個(gè)操作數(shù)相乘

  除(/):2個(gè)操作數(shù)相除

  求冪(**)}}:2個(gè)操作數(shù)求冪,前一個(gè)操作數(shù)為底數(shù),后一個(gè)操作數(shù)為指數(shù)

  關(guān)系

  大于(>):比較2個(gè)操作數(shù),如果前者大于后者,結(jié)果為真

  小于(<):比較2個(gè)操作數(shù),如果前者小于后者,結(jié)果為真

  大于或等于(>=):比較2個(gè)操作數(shù),如果前者大于或等于后者,結(jié)果為真

  小于或等于(<=):比較2個(gè)操作數(shù),如果前者小于或等于后者,結(jié)果為真

  邏輯相等(==):2個(gè)操作數(shù)比較,如果各位均相等,結(jié)果為真。如果其中任何一個(gè)操作數(shù)中含有x或z,則結(jié)果為x

  邏輯不等(!=):2個(gè)操作數(shù)比較,如果各位不完全相等,結(jié)果為真。如果其中任何一個(gè)操作數(shù)中含有x或z,則結(jié)果為x

  case相等(===):2個(gè)操作數(shù)比較,如果各位(包括x和z位)均相等,結(jié)果為真

  case不等(!==):2個(gè)操作數(shù)比較,如果各位(包括x和z位)不完全相等,結(jié)果為真

  移位

  邏輯右移(>>):1個(gè)操作數(shù)向右移位,產(chǎn)生的空位用0填充

  邏輯左移(<<):1個(gè)操作數(shù)向左移位,產(chǎn)生的空位用0填充

  算術(shù)右移(>>>):1個(gè)操作數(shù)向右移位。如果是無(wú)符號(hào)數(shù),則產(chǎn)生的空位用0填充;有符號(hào)數(shù)則用其符號(hào)位填充

  算術(shù)左移(<<<):1個(gè)操作數(shù)向左移位,產(chǎn)生的空位用0填充

  拼接({,}):2個(gè)操作數(shù)分別作為高低位進(jìn)行拼,例如:{2'b10,2'b11}的結(jié)果是a'b1011

  重復(fù)({n{m}}):將操作數(shù)m重復(fù)n次,拼接成一個(gè)多位的數(shù)。例如:A=2'b01,則{2{A}}的結(jié)果是4'b0101

  條件(?:):根據(jù)?前的表達(dá)式是否為真,選擇執(zhí)行后面位于:左右兩個(gè)語(yǔ)句。例如:(a>b)?(a=a-1):(b=b-2),如果a大于b<code>,則將a-1的值賦給a,否則將b-2的值賦給b

  系統(tǒng)任務(wù)

  系統(tǒng)任務(wù)可以被用來(lái)執(zhí)行一些系統(tǒng)設(shè)計(jì)所需的輸入、輸出、時(shí)序檢查、仿真控制操作。所有的系統(tǒng)任務(wù)名稱(chēng)前都帶有美元符號(hào)$使之與用戶(hù)定義的任務(wù)和函數(shù)相區(qū)分。

  例如,$display用于顯示指定的字符串,然后自動(dòng)換行(用法類(lèi)似C語(yǔ)言中的printf函數(shù));$monitor用于監(jiān)視變量,一旦被監(jiān)視的變量發(fā)生變化,會(huì)顯示指定的字符串;而$time可以提取當(dāng)前的仿真時(shí)間。完整的列表請(qǐng)查閱參考工具、Verilog手冊(cè)或標(biāo)準(zhǔn)文檔。

  編譯指令

  Verilog具有一些編譯指令,它們的基本格式為`<keyword>,注意第一個(gè)符號(hào)不是單引號(hào),而是鍵盤(pán)上數(shù)字1左邊那個(gè)鍵對(duì)應(yīng)的撇號(hào)。常用的編譯指令有文本宏預(yù)定義`define、`include,它們的功能與C語(yǔ)言中類(lèi)似,分別提供文本替換、文件包含的功能。Verilog還提供了`ifdef、`ifndef等一系列條件編譯指令,設(shè)計(jì)人員可以使得代碼在滿(mǎn)足一定條件的情況下才進(jìn)行編譯。此外,`timescale指令可以對(duì)時(shí)間單位進(jìn)行定義。詳細(xì)的編譯指令清單請(qǐng)參閱相關(guān)參考書(shū)籍。

  寄存器傳輸級(jí)描述

  參見(jiàn):寄存器傳輸級(jí)

  兩種過(guò)程

  在Verilog中,可以聲明兩種不同的過(guò)程:always過(guò)程和initial過(guò)程。過(guò)程可以是包含時(shí)序的過(guò)程描述,而不包含時(shí)序的過(guò)程還可以表達(dá)組合邏輯。always過(guò)程從關(guān)鍵字always開(kāi)始,可以連續(xù)多次運(yùn)行,當(dāng)過(guò)程的最后一行代碼執(zhí)行完成后,再次從第一行代碼開(kāi)始執(zhí)行。如果沒(méi)有使用系統(tǒng)任務(wù)$finish,always過(guò)程將不斷循環(huán)執(zhí)行。initial過(guò)程從關(guān)鍵字initial開(kāi)始,它只能執(zhí)行一次。

  一個(gè)模塊中可以包含多個(gè)過(guò)程,各個(gè)過(guò)程相互之間是并發(fā)執(zhí)行的。不過(guò),過(guò)程不能夠嵌套使用。如果過(guò)程中有多個(gè)語(yǔ)句,則需要使用關(guān)鍵字begin、end或fork、join將它們組成一個(gè)代碼塊。這兩種關(guān)鍵字組合代表著順序代碼塊和并行代碼塊,后面的部分會(huì)講述這兩種結(jié)構(gòu)。

  例如,利用always過(guò)程循環(huán)執(zhí)行的特點(diǎn),可以為模塊提供一個(gè)時(shí)間脈沖(注意第一個(gè)initial過(guò)程為時(shí)鐘的初始化,這個(gè)過(guò)程只需要進(jìn)行一次):

  initial a = 1'b0;always #1 a=~a;end

  雖然,always代碼塊和while語(yǔ)句、forever語(yǔ)句都能提供循環(huán)功能,但是alway代碼塊的循環(huán)更側(cè)重過(guò)程的循環(huán)執(zhí)行,而后二者更側(cè)重代碼的循環(huán)執(zhí)行。因此,為了使代碼更具條理,過(guò)程的循環(huán)應(yīng)當(dāng)用always語(yǔ)句描述。當(dāng)然,在實(shí)際使用過(guò)程中,強(qiáng)制使用其中的某一種在功能實(shí)現(xiàn)上都是可行的。

  寄存器變量的過(guò)程賦值

  在Verilog中,有兩種賦值運(yùn)算,一種叫做阻塞賦值(blocking assignment),其運(yùn)算符為=;另一種叫做非阻塞賦值(non-blocking assignment),其運(yùn)算符為<=。在順序代碼塊中使用阻塞賦值語(yǔ)句,如果這一句沒(méi)有執(zhí)行完成,那么后面的語(yǔ)句不會(huì)執(zhí)行;如果在順序代碼塊中使用非阻塞賦值,則執(zhí)行這一句的同時(shí),并不會(huì)阻礙下一句代碼的執(zhí)行。而且,如果后一個(gè)語(yǔ)句涉及前面一個(gè)非阻塞賦值語(yǔ)句中的變量,由于這兩個(gè)語(yǔ)句“同時(shí)”執(zhí)行,因此后一個(gè)語(yǔ)句所用到的是前面一個(gè)語(yǔ)句執(zhí)行前變化的數(shù)值。非阻塞賦值是Verilog作為硬件描述語(yǔ)言與普通編程語(yǔ)言的一個(gè)重大區(qū)別。

  帶有兩個(gè)觸發(fā)器輸出端的簡(jiǎn)單示例如下

  always @ (posedge reset or posedge clock)begin a <= b; b <= a;endendmodule

  上面的例子如果沒(méi)有使用非阻塞賦值,而使用阻塞賦值,那么flop1和flop2的數(shù)值就不能被交換。flop1和flop2在執(zhí)行完畢后的數(shù)值都與之前flop2的數(shù)值相同。在傳統(tǒng)的編程語(yǔ)言中,可能需要一個(gè)臨時(shí)的變量,或者使用指針,才能夠達(dá)到交換兩個(gè)變量的目的。這里使用了非阻塞賦值,相當(dāng)于引入了一個(gè)隱含的臨時(shí)變量。第二個(gè)非阻塞賦值右邊的a是第一句賦值之前的數(shù)值,變量交換的目的得以實(shí)現(xiàn)。信號(hào)邊緣敏感的過(guò)程語(yǔ)句塊內(nèi)常使用非阻塞賦值,使語(yǔ)句塊的諸賦值語(yǔ)句同時(shí)進(jìn)行,雖然功能上似乎可以用阻塞賦值實(shí)現(xiàn),但是仿真時(shí)會(huì)產(chǎn)生不正常的結(jié)果。

  通常的過(guò)程賦值語(yǔ)句往往只有在觸發(fā)或循環(huán)等情況,即賦值語(yǔ)句被執(zhí)行到時(shí)候,才會(huì)使左邊的寄存器變量改變一次;而線網(wǎng)變量的連續(xù)賦值則一直“監(jiān)視”右邊表達(dá)式的變化,一旦其結(jié)果發(fā)生變化,立即會(huì)左邊的線網(wǎng)變量更新為此結(jié)果。如果需要對(duì)寄存器變量進(jìn)行過(guò)程連續(xù)賦值,則可以使用Verilog提供的assign或force關(guān)鍵字“強(qiáng)制地”將賦值運(yùn)算符右邊表達(dá)式的結(jié)果連續(xù)不斷地施加在左邊的寄存器變量上。

  線網(wǎng)變量的連續(xù)賦值

  對(duì)線網(wǎng)類(lèi)型變量的連續(xù)賦值是數(shù)字電路數(shù)據(jù)流建模的重要步驟,數(shù)字系統(tǒng)不含時(shí)的組合邏輯部分可以使用線網(wǎng)的連續(xù)賦值描述。線網(wǎng)不能夠像寄存器那樣儲(chǔ)存當(dāng)前數(shù)值,它需要驅(qū)動(dòng)源提供信號(hào),這種驅(qū)動(dòng)是連續(xù)不斷的,因此線網(wǎng)變量的賦值稱(chēng)為連續(xù)賦值,這與寄存器變量在過(guò)程中的單次賦值不同,而且所用的運(yùn)算符也有區(qū)別。在Verilog里,線網(wǎng)連續(xù)賦值的關(guān)鍵字為assign,下面為一個(gè)例子:

  module andwire out;wire in1, in2;assign out = in1 & in2;

  在這個(gè)例子中,線網(wǎng)變量out在系統(tǒng)運(yùn)行過(guò)程中總為兩個(gè)輸入線網(wǎng)變量in1和in2邏輯與的結(jié)果。

  線網(wǎng)的連續(xù)賦值可以在關(guān)鍵字assgin附加延遲信息,例如上面的代碼可以改為:

  assign #5 out = in1 & in2; //in1和in2邏輯與的結(jié)果在5個(gè)時(shí)間周期后才施加在out上

  時(shí)序控制

  參見(jiàn):時(shí)序邏輯電路

  Verilog能夠描述過(guò)程中的時(shí)序特性,這也是硬件描述語(yǔ)言與普通計(jì)算機(jī)編程語(yǔ)言的重要差別之一。過(guò)程的時(shí)序控制可以通過(guò)三種方式實(shí)現(xiàn):延遲時(shí)序控制、事件時(shí)序控制以及電平敏感時(shí)序控制。

  過(guò)程中的時(shí)序控制可以控制代碼的執(zhí)行時(shí)間。在Verilog中,除了過(guò)程中的時(shí)序控制,還可以定義元件、路徑的延遲。這些延遲請(qǐng)參見(jiàn)本條目后面有關(guān)邏輯門(mén)級(jí)延遲的部分。

  延遲時(shí)序控制

  在代碼中使用關(guān)鍵字#和延遲的時(shí)間,就可以通過(guò)延遲來(lái)進(jìn)行時(shí)序控制。延遲的時(shí)間可以是數(shù)字、變量或者表達(dá)式。延遲時(shí)序控制又分為兩種:常規(guī)延遲和內(nèi)嵌延遲。

  常規(guī)延遲在賦值語(yǔ)句的左邊,系統(tǒng)執(zhí)行到這一行代碼時(shí),系統(tǒng)先進(jìn)行延遲,延遲完成后,再計(jì)算表達(dá)式,并將結(jié)果賦值給左邊的變量;而內(nèi)嵌延遲在賦值語(yǔ)句的右邊,系統(tǒng)執(zhí)行到這一行代碼時(shí),系統(tǒng)先立即計(jì)算表達(dá)式,再進(jìn)行延遲,最后把表達(dá)式的結(jié)果賦值給左邊的變量。在上述兩種延遲方式中,設(shè)計(jì)人員需要注意表達(dá)式的自變量在延遲過(guò)程中可能發(fā)生變化。常規(guī)延遲是先延遲再計(jì)算表達(dá)式,這時(shí)表達(dá)式的自變量可能已經(jīng)發(fā)生了變化;而內(nèi)嵌延遲在延遲前就已經(jīng)進(jìn)行了計(jì)算,表達(dá)式的自變量在延遲過(guò)程中發(fā)生的變化,對(duì)已經(jīng)計(jì)算的表達(dá)式結(jié)果沒(méi)有影響,延遲只是指這個(gè)結(jié)果需要等待一段時(shí)間再賦值給左邊的變量。

  下面的代碼片段分別展示了常規(guī)延遲和內(nèi)嵌延遲:

  parameter latency = 8;initialbegin x = 1; y = 2; #5 x = 3; //使用常規(guī)延遲:等待5個(gè)系統(tǒng)周期后對(duì)x賦值 #latency y = 4; //使用變量進(jìn)行常規(guī)延遲,再等待8個(gè)系統(tǒng)周期后對(duì)y賦值 z = #10 (x+y); //使用內(nèi)嵌延遲:先用當(dāng)前時(shí)刻的x、y數(shù)值計(jì)算(x+y),再等待10個(gè)系統(tǒng)周期后對(duì)z賦值end //z的最終數(shù)值為3

  在順序語(yǔ)句塊(begin...end)中,由于語(yǔ)句是從上到下、一行一行地執(zhí)行,而所有常規(guī)延遲時(shí)間都是實(shí)際執(zhí)行時(shí)間相對(duì)于這一句本來(lái)應(yīng)該開(kāi)始執(zhí)行的時(shí)間(也是上一句執(zhí)行完成之時(shí))的延遲值。因此,在上面的代碼示例中,對(duì)變量y的賦值時(shí)間相對(duì)于上一句結(jié)束延遲了8個(gè)系統(tǒng)周期,而上一句相對(duì)系統(tǒng)零時(shí)刻已經(jīng)延遲了5個(gè)系統(tǒng)周期,因此對(duì)y的賦值發(fā)生在第13個(gè)系統(tǒng)周期。不過(guò),如果順序語(yǔ)句塊中存在非阻塞賦值,由于這個(gè)結(jié)構(gòu)有著類(lèi)似并行語(yǔ)句塊的特點(diǎn),因此需要特別考慮。

  在并行語(yǔ)句塊(fork...join)中,由于所有語(yǔ)句都是并發(fā)執(zhí)行的,而所有常規(guī)延遲時(shí)間都是實(shí)際執(zhí)行時(shí)間相對(duì)于這一句本來(lái)應(yīng)該開(kāi)始執(zhí)行的時(shí)間(也是上一句執(zhí)行完成之時(shí))的延遲值,因此各個(gè)常規(guī)延遲所指的時(shí)間都是相對(duì)于系統(tǒng)零時(shí)刻。

  事件時(shí)序控制

  事件時(shí)序控制的意思是,如果指定的事件發(fā)生,則代碼被觸發(fā)執(zhí)行。它的關(guān)鍵字為@,后面可以加變量或者事件名稱(chēng)。參見(jiàn)下面的例子:

  @(clk) x = 1; //當(dāng)變量clk發(fā)生變化,則將1賦值給x@(posedge clk) y = 2; //在變量clk的上升沿,將2賦值給yz = @(negedge clk) (x+y); //先立即計(jì)算表達(dá)式(x+y),然后在變量clk下降沿,將表達(dá)式的結(jié)果賦值給z

  上面@后面括號(hào)里的是常規(guī)事件。Verilog允許設(shè)計(jì)人員通過(guò)關(guān)鍵字event和觸發(fā)符號(hào)->定義自己所需要的命名事件觸發(fā):

  event bigger_than_two;always @(posedge clock)begin if(a > 2) ->bigger_than_two; //如果a大于2,則事件bigger_than_two被觸發(fā)endalways @(bigger_than_two) //當(dāng)bigger_than_two被觸發(fā),執(zhí)行下面的過(guò)程begin //過(guò)程的代碼end

  一種經(jīng)典的用法結(jié)構(gòu)如下,可以理解為“在整個(gè)仿真過(guò)程中,一旦某變量發(fā)生變化,就執(zhí)行某操作”:

  always @(a)begin x = x+1;end

  另一種用法稱(chēng)為OR事件時(shí)序控制,其代碼結(jié)構(gòu)為@(a or b)或@(a, b),即當(dāng)a或b其中任意一個(gè)變量發(fā)生變化時(shí),代碼或代碼塊才被觸發(fā)執(zhí)行。監(jiān)視的變量如果有3個(gè),則其代碼結(jié)構(gòu)變?yōu)锧(a or b or c)或@(a, b, c),以此類(lèi)推。如果需要監(jiān)視的變量很多,則可以使用@*或@(*),它表示對(duì)之后代碼塊中的所有輸入變量敏感。此外,敏感列表中除了變量,還可以是前面所提到過(guò)的常規(guī)事件、命名事件。

  電平敏感時(shí)序控制

  Verilog中還有一種電平敏感時(shí)序控制方式,即使用wait(a),當(dāng)變量a為真,則執(zhí)行后面的代碼塊。

  順序代碼塊與并行代碼塊

  begin、end組合代表了這個(gè)代碼塊的各行代碼是順序執(zhí)行的,這種代碼塊稱(chēng)為順序代碼塊;后面的fork、join代表了這個(gè)代碼塊的各行代碼是并發(fā)執(zhí)行的,這種代碼塊稱(chēng)為并行代碼塊。與模塊、過(guò)程不同,兩種代碼塊是可以嵌套,即順序代碼塊中可以包含并行代碼塊。下面的例子展示了這兩種代碼塊嵌套使用的效果:

  initialfork x = 1; y = 2; begin z = 3; w = 4; endjoin

  由于這個(gè)initial過(guò)程使用了關(guān)鍵字fork、join,其中x、y的賦值同時(shí)于系統(tǒng)零時(shí)刻發(fā)生,而z和w由于位于一個(gè)順序代碼塊中,因此w的賦值在z的賦值后才進(jìn)行。

  在使用并行代碼塊的時(shí)候,有可能引起代碼的競(jìng)爭(zhēng),例如兩個(gè)語(yǔ)句對(duì)一個(gè)變量同時(shí)進(jìn)行賦值。雖然理論上兩個(gè)語(yǔ)句同時(shí)執(zhí)行,但是具體的情況是必然有一句先執(zhí)行,但這與順序語(yǔ)句塊的“先后”有本質(zhì)區(qū)別。實(shí)際的先后順序取決于所用的仿真系統(tǒng)。這并不是Verilog硬件描述語(yǔ)言本身的缺陷,并行語(yǔ)句塊是一種人為設(shè)定的功能,這可以讓設(shè)計(jì)人員更容易地描述某些過(guò)程,當(dāng)然他們必須認(rèn)真考慮競(jìng)爭(zhēng)帶來(lái)的潛在問(wèn)題。

  任務(wù)和函數(shù)

  如果某部分代碼需要在不同地方多次使用,可以在模塊中定義任務(wù)或函數(shù)。

  任務(wù)通過(guò)關(guān)鍵字task來(lái)聲明。任務(wù)可以有零個(gè)或者多個(gè)輸入變量,但是沒(méi)有輸出返回值。調(diào)用任務(wù)時(shí),將按照任務(wù)內(nèi)指定的方式處理這些變量。由于它相當(dāng)于一個(gè)子過(guò)程,因此任務(wù)中賦值的變量只能是寄存器類(lèi)型的,而且只能使用過(guò)程賦值語(yǔ)句。任務(wù)可以具有時(shí)序結(jié)構(gòu),例如延遲、非阻塞賦值等。任務(wù)中可以調(diào)用任務(wù)和函數(shù)。與模塊的聲明不同,任務(wù)的聲明沒(méi)有類(lèi)似模塊端口列表的輸入變量列表。盡管如此,調(diào)用任務(wù)的時(shí)候,還是需要在括號(hào)里按照任務(wù)聲明時(shí)的順序羅列輸入變量。在某種程度上,任務(wù)和C語(yǔ)言中沒(méi)有返回值的函數(shù)有些類(lèi)似。

  函數(shù)通過(guò)關(guān)鍵字function來(lái)聲明。任務(wù)不僅有輸入變量,還有一個(gè)返回值作為輸出變量,這個(gè)返回值的名稱(chēng)與函數(shù)的名稱(chēng)相同。函數(shù)與任務(wù)不同,它是一個(gè)只有邏輯功能的部分,不能包含時(shí)序結(jié)構(gòu)。函數(shù)中只能調(diào)用函數(shù)。Verilog中的函數(shù)與C語(yǔ)言中有返回值的函數(shù)有些類(lèi)似。通常將函數(shù)放在賦值運(yùn)算符的右邊,它的返回值被賦值給左邊的變量。

  如果任務(wù)或函數(shù)同時(shí)在多個(gè)地方被調(diào)用,則需要使用automatic關(guān)鍵字聲明,這樣系統(tǒng)可以為不同地方的調(diào)用分配獨(dú)立的內(nèi)存空間。

  邏輯門(mén)級(jí)描述

  邏輯門(mén)級(jí)描述的抽象級(jí)別較低,僅次于晶體管級(jí)。實(shí)際的硬件電路往往都是以邏輯門(mén)級(jí)網(wǎng)表作為基礎(chǔ)構(gòu)建的,而設(shè)計(jì)人員常常會(huì)在進(jìn)行更高抽象級(jí)別的設(shè)計(jì)。盡管如此,邏輯門(mén)級(jí)的設(shè)計(jì)還是更接近真實(shí)電路形式。Verilog提供了一系列邏輯門(mén)原語(yǔ)(Primitive)供用戶(hù)使用。例如,非(not)、與門(mén)(and)、或門(mén)(or)、與非門(mén)(nand)、或非(nor)、異或(xor)、同或(xnor)。邏輯門(mén)原語(yǔ)和模塊類(lèi)似,可以通過(guò)實(shí)例引用的方式使用。

  晶體管級(jí)描述

  Verilog能夠在低抽象級(jí)別對(duì)電路進(jìn)行描述,是它的一個(gè)重要特點(diǎn)。Verilog中提供了多種晶體管級(jí)(也稱(chēng)開(kāi)關(guān)級(jí))元件類(lèi)型,包括N型金屬氧化物半導(dǎo)體場(chǎng)效應(yīng)管(關(guān)鍵字為nmos)、P型金屬氧化物半導(dǎo)體場(chǎng)效應(yīng)管(關(guān)鍵字為pmos)、互補(bǔ)式金屬氧化物半導(dǎo)體(關(guān)鍵字為cmos)、帶阻抗的互補(bǔ)式金屬氧化物半導(dǎo)體(關(guān)鍵字為rcmos)、電源單元(關(guān)鍵字為supply1)、接地單元(關(guān)鍵字為supply0)等。所有的晶體管都可以設(shè)置延遲屬性。設(shè)計(jì)人員可以利用這些低抽象級(jí)元件構(gòu)建所需要的邏輯門(mén)或直接構(gòu)成其他高級(jí)組件。

  延遲

  邏輯門(mén)和晶體管的延遲

  真實(shí)的硬件電路不可避免地都存在延遲現(xiàn)象。在Verilog中,可以對(duì)邏輯門(mén)、晶體管這些元件的延遲信息進(jìn)行描述。可以為元件的延遲指定一個(gè)時(shí)間,則上升、下降、關(guān)斷的延遲都使用這個(gè)時(shí)間;也可以按照先后順序分別指定上升延遲、下降延遲,而關(guān)斷延遲取二者較小值;當(dāng)然也可以為上升、下降、關(guān)斷各指定一個(gè)時(shí)間。例如,下面的代碼為與門(mén)實(shí)例添加了三個(gè)延遲時(shí)間,分別對(duì)應(yīng)上升、下降、關(guān)斷:

  and #(1, 2, 3) my_and (out, in1, in2);

  邏輯門(mén)和晶體管的延遲屬于“慣性延遲”。它的意思是,邏輯門(mén)和晶體管獲得外部輸入之后,延遲指定的時(shí)間后,才會(huì)將結(jié)果呈現(xiàn)在輸出端上。在延遲期間,如果輸入改變,但是這個(gè)信號(hào)的持續(xù)時(shí)間小于指定延遲的時(shí)間,則不會(huì)影響邏輯門(mén)和晶體管的輸出;如果這個(gè)信號(hào)的持續(xù)時(shí)間大于指定延遲的時(shí)間,則之前的結(jié)果將不會(huì)呈現(xiàn)在輸出端,改變輸入信號(hào)后的結(jié)果將經(jīng)過(guò)延遲后將呈現(xiàn)在輸出端

  Verilog還允許設(shè)計(jì)人員為每個(gè)延遲時(shí)間設(shè)置最大值、典型值、最小值,在編譯階段可以通過(guò)編譯代碼選擇其中一個(gè)。

  線網(wǎng)延遲

  在聲明線網(wǎng)或?qū)€網(wǎng)進(jìn)行連續(xù)賦值的時(shí)候,可以為線網(wǎng)添加延遲信息。這樣,所有連續(xù)賦值給線網(wǎng)的表達(dá)式都會(huì)立即計(jì)算出結(jié)果,但是這個(gè)結(jié)果在延遲時(shí)間后才會(huì)賦值給線網(wǎng)。如果在這段延遲時(shí)間內(nèi),右側(cè)表達(dá)式的結(jié)果發(fā)生變化,則用于賦值的表達(dá)式結(jié)果取變化后的。另外,如果如果輸入變量變化的脈沖寬度小于延遲的時(shí)間,其變化不會(huì)對(duì)輸出造成影響。這種延遲被稱(chēng)為“慣性延遲”,邏輯門(mén)和晶體管的延遲也是這種情況。

  過(guò)程延遲

  過(guò)程延遲在前面的延遲時(shí)序控制一部分講述過(guò)。過(guò)程賦值語(yǔ)句中的延遲主要分為常規(guī)延遲(又稱(chēng)為外部延遲)和內(nèi)嵌延遲(又稱(chēng)為內(nèi)部延遲)兩種,其中前者先延遲,再計(jì)算表達(dá)式、賦值給左邊的變量;而后者先立即計(jì)算表達(dá)式,經(jīng)過(guò)延遲后再將結(jié)果賦值給左邊的變量。

  路徑延遲

  設(shè)計(jì)人員可以在模塊中關(guān)鍵字specify、endspecify之間對(duì)路徑延遲進(jìn)行描述。與元件的延遲不同,路徑延遲是指信號(hào)在某兩個(gè)寄存器類(lèi)型或線網(wǎng)類(lèi)型變量之間傳遞所需的延遲時(shí)間。在specify代碼塊中可以使用條件結(jié)構(gòu)來(lái)根據(jù)情況選擇所需的延遲時(shí)間值。與元件延遲相同的是,延遲的時(shí)間值可以指定上升、下降、關(guān)斷的情況,同時(shí)也可以包含最大值、典型值、最小值。

  邏輯綜合

  主條目:邏輯綜合

  概念簡(jiǎn)介

  設(shè)計(jì)人員編寫(xiě)的Verilog代碼通常是在較高抽象級(jí)別的,例如寄存器傳輸級(jí)。這一抽象級(jí)別包含了對(duì)電路信號(hào)在寄存器之間傳輸情況的描述。但是邏輯門(mén)級(jí)的網(wǎng)表,即邏輯門(mén)的相互連接形式,才最接近真實(shí)的硬件電路。這一形式與寄存器傳輸級(jí)的描述,在功能上是等效的。為了給后續(xù)硬件制造人員提供這種低抽象級(jí)別的描述,需要將高抽象級(jí)別的Verilog代碼轉(zhuǎn)換為低抽象級(jí)別的邏輯門(mén)級(jí)網(wǎng)表。這一過(guò)程稱(chēng)為邏輯綜合(Logic Synthesis)。

  在自動(dòng)化邏輯綜合工具出現(xiàn)之前,盡管人們可以用硬件描述語(yǔ)言進(jìn)行設(shè)計(jì),但是還是需要人工進(jìn)行邏輯綜合。例如,如果電路模塊只有少數(shù)幾個(gè)輸入端,我們可以使用類(lèi)似卡諾圖的方法來(lái)對(duì)邏輯函數(shù)進(jìn)行化簡(jiǎn)。隨著電路規(guī)模不斷增加,人工邏輯綜合的容易出錯(cuò)、耗費(fèi)大量時(shí)間的缺點(diǎn)逐漸凸顯。同時(shí),在某種特殊器件工藝下最優(yōu)化的綜合結(jié)果不一定在另一種工藝下還合適,如果需要采用另外的工藝,設(shè)計(jì)人員需要花費(fèi)很長(zhǎng)時(shí)間重新進(jìn)行邏輯綜合。隨著自動(dòng)化邏輯綜合工具的出現(xiàn),硬件描述語(yǔ)言、所需器件工藝信息(工藝庫(kù))可以直接被邏輯綜合工具讀取,通過(guò)其內(nèi)部的自動(dòng)綜合算法,輸出符合設(shè)計(jì)約束(通常包括時(shí)序、功耗、面積的約束)的邏輯門(mén)級(jí)網(wǎng)表。借助自動(dòng)綜合工具,設(shè)計(jì)人員可以將更多的精力放在高抽象級(jí)別的硬件描述語(yǔ)言設(shè)計(jì)。

  可綜合代碼

  邏輯綜合工具不能接受所有的Verilog代碼。設(shè)計(jì)人員需要確保硬件描述語(yǔ)言代碼是周期到周期的寄存器傳輸級(jí)描述。諸如while的循環(huán)結(jié)構(gòu)必須通過(guò)信號(hào)邊緣的形式(如@(posedge clock))提供終止條件;initial結(jié)構(gòu)可能也不能被轉(zhuǎn)換。如果不指明數(shù)字的位寬,那么系統(tǒng)可能默認(rèn)它為一個(gè)較大的值(如32位),這就可能產(chǎn)生規(guī)模非常龐大的邏輯門(mén)級(jí)網(wǎng)表,其中一部分是不必要的,這將造成資源的浪費(fèi)。與未知邏輯x、高阻態(tài)z有關(guān)的運(yùn)算符不能被轉(zhuǎn)換,例如===、!==此外,條件結(jié)構(gòu)如果只有if而沒(méi)有對(duì)else的情況進(jìn)行設(shè)計(jì),或者選擇結(jié)構(gòu)缺少默認(rèn)情況default,很可能產(chǎn)生預(yù)期之外的鎖存器。由于需要使用與工藝相關(guān)的邏輯門(mén),因此用戶(hù)自定義的原語(yǔ)很可能不能被轉(zhuǎn)換。設(shè)計(jì)人員需要采取良好的代碼風(fēng)格,以獲得更優(yōu)化的邏輯綜合結(jié)果。為了適應(yīng)符合可重用設(shè)計(jì)思想的系統(tǒng)芯片、IP核設(shè)計(jì),設(shè)計(jì)人員還應(yīng)該遵循更嚴(yán)格的編碼規(guī)范。

  不可綜合結(jié)構(gòu)

  結(jié)構(gòu)類(lèi)型

  注

  initial

  只用于仿真測(cè)試文件(test bench)

  events

  Events對(duì)于同步測(cè)試文件的各個(gè)組件比較有意義

  real

  Real數(shù)據(jù)類(lèi)型不可綜合

  time

  Time數(shù)據(jù)類(lèi)型不可綜合

  force和release

  Force和release不可綜合

  assign和deassign

  reg類(lèi)型的assign和deassign操作不可綜合,但是wire類(lèi)型的assign操作可以綜合

  fork join

  使用非阻塞賦值可以獲得同樣效果

  primitive

  只有門(mén)級(jí)的原語(yǔ)(primitives)可綜合

  table

  用戶(hù)自定義原語(yǔ)(UDP)及table不可綜合

  #1

  延遲只用于仿真,綜合器一般直接忽略延遲

  高級(jí)功能

  用戶(hù)自定義原語(yǔ)

  除了系統(tǒng)提供的26種邏輯門(mén)、晶體管原語(yǔ),Verilog也提供用戶(hù)自定義原語(yǔ)(User Defined Primitive, UDP)。原語(yǔ)與模塊的層次結(jié)構(gòu)類(lèi)似,但是原語(yǔ)的輸入輸出關(guān)系是完全通過(guò)查表實(shí)現(xiàn)的。組合邏輯的用戶(hù)自定義原語(yǔ)的核心是真值表,時(shí)序邏輯的用戶(hù)自定義原語(yǔ)的核心是激勵(lì)表。設(shè)計(jì)人員需要在狀態(tài)表中羅列可能出現(xiàn)的輸入和輸出情況。如果在實(shí)際使用過(guò)程中,遇到狀態(tài)表中沒(méi)有定義的情況,則輸出不確定值x。使用自定義原語(yǔ)很直觀,但是如果輸入變量較多,狀態(tài)表就會(huì)變得很復(fù)雜。在很多情況中,用戶(hù)自定義原語(yǔ)并不能被邏輯綜合工具轉(zhuǎn)換。

  編程語(yǔ)言接口

  編程語(yǔ)言接口(Program Language Interface, PLI)提供了通過(guò)C語(yǔ)言函數(shù)對(duì)Verilog數(shù)據(jù)結(jié)構(gòu)進(jìn)行存儲(chǔ)、讀取操作的途徑。

  Verilog編程語(yǔ)言接口的發(fā)展先后經(jīng)過(guò)了三代,其中第一代為任務(wù)或函數(shù)子程序,它可以在C程序和Verilog設(shè)計(jì)之間傳遞數(shù)據(jù);第二代為存取子程序,它可以在用戶(hù)自定義C程序和Verilog的內(nèi)部數(shù)據(jù)表示的接口上被使用;第三代為Verilog過(guò)程接口,它進(jìn)一步擴(kuò)展了前兩代編程語(yǔ)言接口的功能。

  通過(guò)使用編程語(yǔ)言接口,設(shè)計(jì)人員可以自定義接口的功能,然后通過(guò)類(lèi)似調(diào)用系統(tǒng)任務(wù)的方式調(diào)用這些自定義功能。這樣,設(shè)計(jì)人員可以很大程度地?cái)U(kuò)展他們能使用的功能,例如監(jiān)視、激勵(lì)、調(diào)試功能,或者用它來(lái)提取設(shè)計(jì)信息、顯示輸出等。

  相關(guān)電子設(shè)計(jì)自動(dòng)化工具

  參見(jiàn):電子設(shè)計(jì)自動(dòng)化

  Verilog作為業(yè)界使用最廣泛的硬件描述語(yǔ)言之一,有大量的電子設(shè)計(jì)自動(dòng)化工具對(duì)它予以支持。通過(guò)使用集成開(kāi)發(fā)環(huán)境,設(shè)計(jì)人員可以在常見(jiàn)的Windows或其他圖形化系統(tǒng)中進(jìn)行設(shè)計(jì)、仿真、驗(yàn)證,例如Cadence和Synopsys等公司提供的集成電路計(jì)算機(jī)輔助設(shè)計(jì)系統(tǒng)。

  與VHDL的比較

  參見(jiàn):VHDL

  VHDL——VHSIC(Very High Speed Integrated Circuit) HDL,由美國(guó)DOD支持開(kāi)發(fā)的HDL,1987

  年成為IEEE 1076-1987 標(biāo)準(zhǔn),后修訂為IEEE 1076-1993 標(biāo)準(zhǔn)。

  Verilog來(lái)自C 語(yǔ)言,易學(xué)易用,編程風(fēng)格靈活、簡(jiǎn)潔,使用者眾多,特別在ASIC領(lǐng)域流行;

  VHDL 來(lái)自ADA,語(yǔ)法嚴(yán)謹(jǐn),比較難學(xué),在歐洲和國(guó)內(nèi)有較多使用者;

  兩者描述的設(shè)計(jì)層次有所不同:

  VHDL:系統(tǒng)級(jí)、行為級(jí)、RTL 級(jí)、門(mén)級(jí)

  VerilogHDL:行為級(jí)、RTL 級(jí)、門(mén)級(jí)、開(kāi)關(guān)級(jí)

  不支持:電路級(jí)(spice)、版圖級(jí)(GDSII/CIF)

  簡(jiǎn)介

  Verilog HDL是一種硬件描述語(yǔ)言,用于從算法級(jí)、門(mén)級(jí)到開(kāi)關(guān)級(jí)的多種抽象設(shè)計(jì)層次的數(shù)字系統(tǒng)建模。被建模的數(shù)字系統(tǒng)對(duì)象的復(fù)雜性可以介于簡(jiǎn)單的門(mén)和完整的電子數(shù)字系統(tǒng)之間。數(shù)字系統(tǒng)能夠按層次描述,并可在相同描述中顯式地進(jìn)行時(shí)序建模。

  Verilog HDL 語(yǔ)言具有下述描述能力:設(shè)計(jì)的行為特性、設(shè)計(jì)的數(shù)據(jù)流特性、設(shè)計(jì)的結(jié)構(gòu)組成以及包含響應(yīng)監(jiān)控和設(shè)計(jì)驗(yàn)證方面的時(shí)延和波形產(chǎn)生機(jī)制。所有這些都使用同一種建模語(yǔ)言。此外,Verilog HDL語(yǔ)言提供了編程語(yǔ)言接口,通過(guò)該接口可以在模擬、驗(yàn)證期間從設(shè)計(jì)外部訪問(wèn)設(shè)計(jì),包括模擬的具體控制和運(yùn)行。

  Verilog HDL語(yǔ)言不僅定義了語(yǔ)法,而且對(duì)每個(gè)語(yǔ)法結(jié)構(gòu)都定義了清晰的模擬、仿真語(yǔ)義。因此,用這種語(yǔ)言編寫(xiě)的模型能夠使用Verilog仿真器進(jìn)行驗(yàn)證。語(yǔ)言從C編程語(yǔ)言中繼承了多種操作符和結(jié)構(gòu)。Verilog HDL提供了擴(kuò)展的建模能力,其中許多擴(kuò)展最初很難理解。但是,Verilog HDL語(yǔ)言的核心子集非常易于學(xué)習(xí)和使用,這對(duì)大多數(shù)建模應(yīng)用來(lái)說(shuō)已經(jīng)足夠。當(dāng)然,完整的硬件描述語(yǔ)言足以對(duì)從最復(fù)雜的芯片到完整的電子系統(tǒng)進(jìn)行描述。

  用途

  Verilog HDL就是在用途最廣泛的C語(yǔ)言的基礎(chǔ)上發(fā)展起來(lái)的一種硬件描述語(yǔ)言,它是由GDA(Gateway Design Automation)公司的PhilMoorby在1983年末首創(chuàng)的,最初只設(shè)計(jì)了一個(gè)仿真與驗(yàn)證工具,之后又陸續(xù)開(kāi)發(fā)了相關(guān)的故障模擬與時(shí)序分析工具。1985年Moorby推出它的第三個(gè)商用仿真器Verilog-XL,獲得了巨大的成功,從而使得Verilog HDL迅速得到推廣應(yīng)用。1989年CADENCE公司收購(gòu)了GDA公司,使得VerilogHDL成為了該公司的獨(dú)家專(zhuān)利。1990年CADENCE公司公開(kāi)發(fā)表了Verilog HDL,并成立LVI組織以促進(jìn)Verilog HDL成為IEEE標(biāo)準(zhǔn),即IEEE Standard 1364-1995.

  Verilog HDL的最大特點(diǎn)就是易學(xué)易用,如果有C語(yǔ)言的編程經(jīng)驗(yàn),可以在一個(gè)較短的時(shí)間內(nèi)很快的學(xué)習(xí)和掌握,因而可以把Verilog HDL內(nèi)容安排在與ASIC設(shè)計(jì)等相關(guān)課程內(nèi)部進(jìn)行講授,由于HDL語(yǔ)言本身是專(zhuān)門(mén)面向硬件與系統(tǒng)設(shè)計(jì)的,這樣的安排可以使學(xué)習(xí)者同時(shí)獲得設(shè)計(jì)實(shí)際電路的經(jīng)驗(yàn)。與之相比,VHDL的學(xué)習(xí)要困難一些。但Verilog HDL較自由的語(yǔ)法,也容易造成初學(xué)者犯一些錯(cuò)誤,這一點(diǎn)要注意。

  歷史

  Verilog HDL語(yǔ)言最初是于1983年由Gateway Design Automation公司為其模擬器產(chǎn)品開(kāi)發(fā)的硬件建模語(yǔ)言。那時(shí)它只是一種專(zhuān)用語(yǔ)言。由于他們的模擬、仿真器產(chǎn)品的廣泛使用,Verilog HDL 作為一種便于使用且實(shí)用的語(yǔ)言逐漸為眾多設(shè)計(jì)者所接受。在一次努力增加語(yǔ)言普及性的活動(dòng)中,Verilog HDL語(yǔ)言于1990年被推向公眾領(lǐng)域。 Open Verilog International (OVI)是促進(jìn)Verilog發(fā)展的國(guó)際性組織。1992年,OVI決定致力于推廣Verilog OVI標(biāo)準(zhǔn)成為IEEE標(biāo)準(zhǔn)。這一努力最后獲得成功,Verilog 語(yǔ)言于1995年成為IEEE標(biāo)準(zhǔn),稱(chēng)為IEEE Std 1364-1995。完整的標(biāo)準(zhǔn)在Verilog硬件描述語(yǔ)言參考手冊(cè)中有詳細(xì)描述。

  發(fā)展歷史

  1、1981年Gateway Automation(GDA)硬件描述語(yǔ)言公司成立。

  2、1983年該公司的Philip Moorby首創(chuàng)了Verilog HDL,Moorby后來(lái)成為Verrlog HDL-XL的主要設(shè)計(jì)者和Cadence公司的第一合伙人。

  3、1984-1985年Moorby設(shè)計(jì)出第一個(gè)關(guān)于Verilog HDL的仿真器。

  4、1986年Moorby對(duì)Verilog HDL的發(fā)展又做出另一個(gè)巨大的貢獻(xiàn),提出了用于快速門(mén)級(jí)仿真的XL算法。

  5、隨著Verilog HDL-XL的成功,Verilog HDL語(yǔ)言得到迅速發(fā)展。

  6、1987年Synonsys公司開(kāi)始使用Verilog HDL行為語(yǔ)言作為綜合工具的輸入。

  7、1989年Cadence公司收購(gòu)了Gateway公司,Verilog HDL成為Cadence公司的私有財(cái)產(chǎn)。

  8、1990年初Cadence公司把Verilong HDL和Verilong HDL-XL分開(kāi),并公開(kāi)發(fā)布了Verilog HDL.隨后成立的OVI(Open Verilog HDL International)組織負(fù)責(zé)Verilog HDL的發(fā)展,OVI由Verilog HDL的使用和CAE供應(yīng)商組成,制定標(biāo)準(zhǔn)。

  9、1993年,幾乎所有ASIC廠商都開(kāi)始支持Verilog HDL,并且認(rèn)為Verilog HDL-XL是最好的仿真器。同時(shí),OVI推出2.0版本的Verilong HDL規(guī)范,IEEE接收將OVI的Verilong HDL2.0作為IEEE標(biāo)準(zhǔn)的提案。

  10、1995年12月,IEEE制定了Verilong HDL的標(biāo)準(zhǔn)IEEE1364-1995.

  任何新生事物的產(chǎn)生都有它的歷史沿革,早期的硬件描述語(yǔ)言是以一種高級(jí)語(yǔ)言為基礎(chǔ),加上一些特殊的約定而產(chǎn)生的,目的是為了實(shí)現(xiàn)RTL級(jí)仿真,用以驗(yàn)證設(shè)計(jì)的正確性,而不必像在傳統(tǒng)的手工設(shè)計(jì)過(guò)程中那樣,必須等到完成樣機(jī)后才能進(jìn)行實(shí)測(cè)和調(diào)試。


內(nèi)容來(lái)自百科網(wǎng)