淺談VHDL/Verilog的可綜合性以及對初學者的一些建議

admin @ 2014-03-26 , reply:0

概述
一、HDL不是硬體設計語言過去筆者曾碰到過不少VHDL或VerilogHDL的初學者問一些相似的問題,諸如如何實現除法、開根號,如何寫循環語句等等。在這個論壇上,也時常能看到一些網友提出這一類的問題。……

一、HDL不是硬體設計語言
過去筆者曾碰到過不少VHDL或Verilog HDL的初學者問一些相似的問題,諸如如何實現除法、開根號,如何寫循環語句等等。在這個論壇上,也時常能看到一些網友提出這一類的問題。

對於這些問題,首先要明確的是VHDL和Veriglog並非是針對硬體設計而開發的語言,只不過目前被我們用來設計硬體。HDL是Hardware Description Language的縮寫,正式中文名稱是“硬體描述語言”。也就是說,HDL並不是“硬體設計語言(Hardware Design Language)”。別看只差這一個單詞,正是這一個單詞才決定了絕大部分電路設計必須遵循RTL的模式來編寫代碼,而不能隨心所欲得寫僅僅符合語法的 HDL代碼。

二、HDL的來歷
之所以是“硬體描述語言”,要從HDL的來歷說起。

VHDL 於1980年開始在美國國防部的指導下開發,完成於1983年,並於1987年成為IEEE的標準。當初開發這種語言,是出於美國國防部採購電子設備的需要。美軍的裝備採購自私人企業,時常要面對這樣一種風險:如果某種武器大量裝備部隊,而其中某個零件的供應商卻在幾年後倒閉了,那這種武器的再生產、維修和保養都會出現大問題。而電子設備、尤其是集成電路的內部結構較為複雜,若出現前面所說的情況要找其他公司生產代用品非常困難。於是美國防部希望供應商能以某種形式留下其產品的信息,以保證一旦其破產後能由其他廠商迅速生產出代用品。

顯然,當初的設計文檔顯然是不能交出來的,這在美國會涉及商業機密和知識產權問題。於是美國防部就想出了一種折衷的方法——描述硬體的語言,也就是VHDL。通過VHDL,供應商要把自己生產的集成電路晶元的行為描述出來:比如說,加了什麼樣的信號後過多少時間它能輸出什麼等等。這樣,如果有必要讓其他廠商生產代用品,他們只需照著VHDL文檔,設計出行為與其相同的晶元即可。這樣的代用品相當於是新廠商在不了解原產品結構的情況下獨立設計的,所以不太會涉及知識侵權。

Verilog HDL也形成於差不多的年代,是由Gateway Design Automation公司大約在1983年左右開發的。其架構同VHDL相似,但主要被用來進行硬體模擬。或許私人公司更注重實用,Verilog要比VHDL簡潔得多。

由此可見,這兩種最流行的用於電路設計的語言,沒有一種是為了設計硬體而開發的(更何況80年代還沒有現在的那些功能強大的EDA軟體呢)。因此,當初制訂 HDL語言標準的時候,並沒有考慮這些代碼如何用硬體來實現。換句話說,有些代碼寫起來簡單,實現起來卻可能非常複雜,或者幾乎不可能實現。

三、HDL代碼的可綜合性
現在回到最初的問題上。為什麼諸如除法、循環之類的HDL代碼總是會出錯?

由上一部分可知,任何符合HDL語法標準的代碼都是對硬體行為的一種描述,但不一定是可直接對應成電路的設計信息。行為描述可以基於不同的層次,如系統級,演算法級,寄存器傳輸級(RTL)、門級等等。以目前大部分EDA軟體的綜合能力來說,只有RTL或更低層次的行為描述才能保證是可綜合的。而眾多初學者試圖做的,卻是想讓軟體去綜合演算法級或者更加抽象的硬體行為描述。

比如說,要想實現兩個變數相除的運算,若在代碼中寫下C=A/B,你將會發現只有一些模擬軟體在前模擬中能正確執行這句代碼,但幾乎任何軟體都不能將其綜合成硬體。不要怪軟體太笨。試想一下,如果我們自己筆算除法是怎麼做的?從高位到低位逐次試除、求余、移位。試除和求余需要減法器,商數和餘數的中間結果必須有寄存器存儲;而此運算顯然不能在一個時鐘周期里完成,還需要一個狀態機來控制時序。一句簡單的C=A/B同所有這些相比顯得太抽象,對於只能接受RTL或更低層次描述的EDA軟體來說確實太難實現。而如果代碼是類似於(Verilog):
always @(posedge clk)
c<=A/B;
這樣的,要求除法在一個時鐘延上完成,那更是不可能實現的。(註:有些FPGA的配套軟體提供乘除法的運算模塊,但也只能支持直接調用,不支持把形如C=A/B的語句綜合成除法模塊。)

又比如,一個很多初學者常見的問題是試圖讓HDL進行循環運算,形同(Verilog):
for (i=0; iparity = parity xor data[i];

一些功能比較簡單的綜合軟體會完全拒絕綜合循環語句;而一些功能較強的軟體僅當wordlength是常數的時候能綜合;當wordlength為變數時,任何軟體都不能綜合上面的語句。這是因為硬體規模必須是有限的、固定的。當綜合軟體遇到循環語句時,總是將其展開成若干條順序執行的語句,然後再綜合成電路。若wordlength是常數,則展開的語句數是確定的,具有可綜合性;而若它是變數時,展開的語句數不確定,對應的硬體電路數量也不能確定,無法被綜合。或許有人說用計數器就能實現變數循環,但這情形又和上面的除法運算相同。那需要額外的硬體,用來存儲中間結果和進行時序控制,象上面那樣的循環語句對此描述得太抽象,軟體接受不了。

四、如何判斷自己寫的代碼是可綜合的?
用一句簡單的話概括:電腦永遠沒有你聰明。具體來說,通常EDA軟體對HDL代碼的綜合能力總是比人差。對於一段代碼,如果你不能想象出一個較直觀的硬體實現方法,那EDA軟體肯定也不行。比如說,加法器、多路選擇器是大家都很熟悉的電路,所以類似A+B-C,(A>B)?C:D這樣的運算一定可以綜合。而除法、開根、對數等等較複雜的運算,必須通過一定的演算法實現,沒有直觀簡單的實現方法,則可以判斷那些計算式是不能綜合的,必須按它們的演算法寫出更具體的代碼才能實現。此外,硬體無法支持的行為描述,當然也不能被綜合(比如想在FPGA上實現DDR內存那樣的雙延觸發邏輯,代碼很容易寫,但卻不能實現)。

不過,這樣的判斷標準非常主觀模糊,遇到具體情況還得按設計人員自己的經驗來判斷。如果要一個相對客觀的標準,一般來說:在RTL級的描述中,所有邏輯運算和加減法運算、以及他們的有限次組合,基本上是可綜合的,否則就有無法綜合的可能性。當然,這樣的標準仍然有缺陷,更況且EDA的技術也在不斷發展,過去無法綜合的代碼或許將來行,某些軟體不支持的代碼換個軟體或許行。比如固定次數的循環,含一個常數參數的乘法運算等等,有些EDA軟體支持對它們的綜合,而有些軟體不行。

所以,正確的判斷仍然要靠實踐來積累經驗。當你可以較準確判斷代碼的可綜合性的時候,你對HDL的掌握就算完全入門了。

作者:董培良
電機和電子工程系博士生
英國University of Nottingham




[admin via 研發互助社區 ] 淺談VHDL/Verilog的可綜合性以及對初學者的一些建議已經有4705次圍觀

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