如何快速在Verilog和VHDL之間互轉


Verilog語言和VHDL語言是兩種不同的硬件描述語言,但並非所有人都同時精通兩種語言,所以在某些時候,需要把Verilog代碼轉換為VHDL代碼。本文以通用的XHDL工具為例對Verilog轉換到VHDL過程中存在的問題進行了總結,歡迎批評指正。

當我們剛開始學習FPGA時,一定會遇到一個問題:

 

學習Verilog還是VHDL?

等我們學習FPGA到一定程度參加面試時,面試者也會問你一個問題:

你以前用Verilog還是VHDL開發?

你已經習慣某種語言,也發現語言不是學習FPGA時需要考慮的問題,它僅僅是硬件描述語言工具而已。可是,當你發現一份和你使用語言不同的代碼作為參考時,你又開始想:

我以后的工作是不是要二種語言都會,這樣工作才會得心應手?

事實上,兩種語言之間是可以相互轉換的。

對於我們做FPGA開發人員來說,如何快速在Verilog和VHDL之間互轉,加快開發產品的進度,而不是因為只懂某一種語言而局限了自己的開發。

Vivado可以看兩種語言的差異
Verilog與VHDL語法是互通且相互對應的,如何查看二者對同一硬件結構的描述,可以借助EDA工具,如Vivado,打開Vivado后它里面的語言模板后,也可以對比查看Verilog和VHDL之間的差異。

XHDL軟件

轉換所用軟件如下圖所示:

上圖是把轉換成VHDL格式的代碼,再轉換回verilog后與原代碼對比的圖,可以看出,一些注釋之類的信息都沒有了,原來的代碼規范和風格也發生了變化。

在轉換的過程,該軟件對代碼中的漢語注釋不支持,如果出現漢字就無法轉換。

筆者之前就曾試着寫過Verilog轉VHDL代碼的工具,見:Verilog HDL代碼轉VHDL代碼,無奈因為不是軟件開發出身,寫出來的東西通用性和完善性很差。寫到此處,再次想起漢天下董事長楊清華所說的話,互聯網講究的是差異化的商業模式,很牛的產品定義,早期不看銷售額而看流量,越快越好。這對IC是很可怕的事情,讓整個產業變得很浮躁。互聯網的模式,在某種程度上是毒瘤。發展集成電路芯片,需要把互聯網的模式認知去除。芯片行業需要長期積累、持續關注,需要八年、十年的積累,這個耐心和耐性很重要。

試想一下,如果這么一個簡單的小軟件是互聯網領域經常用到的,估計早已經遍地都是了吧,並且也都很好用呢!

以下僅對Verilog轉VHDL過程中出現的問題進行說明。

Xhdl軟件轉換后狀態機的問題
含有狀態機的Verilog代碼被xhdl軟件轉換后會出現兩種情況:

1、當verilog代碼中parameter常量寫在緊挨着端口位置時,xhdl軟件會將其轉換為vhdl中的generic內的可傳遞的參數,如圖:

 

2、當parameter在其它地方出現時,xhdl會將其轉換為constant常量,如圖:

 

無論哪種方式,將其中有錯誤的地方改正后,都不會出現狀態機運行出錯,也就是不用將這種狀態機書寫方式更改為vhdl語法中專門的狀態機書寫方式。

function轉換位置出現問題
在用xhdl軟件完成轉換后會出現function寫在了process塊內的情況,出現此問題應將function改在architecture下面(與定義信號在相同的位置)。

信號只能賦值給與它位寬類型相同的信號

如下圖中的兩個信號:

在verilog中此種賦值方式意思是將a的前3位賦值給b,但是在vhdl中此種賦值方式會報出位寬不匹配的錯誤,應將其更改為:

同時需要注意a、b的數據類型必須相同,如圖中必須都為std_logic_vector類型。

沒有邏輯與,需用其它辦法解決

在vhdl中沒有邏輯與(verilog中的&&),只有按位與(verilog中的&,vhdl中的and),所以verilog中的邏輯與,在vhdl中有時需要用等價的方式替換,比如:

 

需要替換為:

 

注意數據類型轉換符號使用的是否正確

在vhdl中有多種數據類型,它們之間可以通過數據類型轉換符號相互轉換。在xhdl軟件中,數據類型轉換一般都會出現錯誤,具體的原因是轉換符號使用錯誤,而在vhdl的語法書上介紹的並不全面。下面介紹幾中常用的數據類型轉換符號:

1、IEEE.std_logic_1164.all庫中包含的:

(1)bit_vector to std_logic_vector :

= to_stdlogicvector(bv_sig);

(2)std_logic_vector to bit_vector :

= to_bitvector();

2、IEEE.std_logic_arith.all庫中包含的:

integer to std_logic_vector :

= CONV_STD_LOGIC_VECTOR(,);

3、IEEE.std_logic_signed.all庫中包含的:

std_logic_vector to integer :

= CONV_INTEGER();

注意:選用某種數據類型轉換符號的時候一定要確認是否包含了相應的庫。

其它轉換符號可以在如下圖的ise軟件相應的目錄下查找

if后的判斷語句在某些情況會出現語法沒錯誤邏輯出現錯誤

此種情況比較少見,但是一般很難發現,只有通過大量仿真找到錯誤。具體情況如下圖:

原verilog代碼:
if((MDR_port_i & outport) == 32'b0)

Xhdl軟件轉換后語法無錯誤邏輯出現錯誤:
IF((MDR_port_i /= "0000000000000000000000000000000") AND outport /= "0000000000000000000000000000000" = false)

修改后:
IF((MDR_port_i AND outport) = "0000000000000000000000000000000" )

個人總結:在原verilog代碼中,當if后的判斷句出現按位與(&)時,Xhdl軟件轉換成vhdl后很大可能會出現語法正確邏輯錯誤。

並置運算時遇到的問題
由於在verilog語法中,位寬不同的兩個信號也可以相互賦值,但是在vhdl中對此有嚴格要求位寬相同,而xhdl軟件在轉換的時候不會檢測這些,所以經常會出現位寬不匹配的情況,尤其是在並置運算時,所以要嚴格檢查並置后的位寬與所賦值信號是否相同。

在verilog中某一信號可以賦值給幾個並置的信號,但是在vhdl中不允許這么做,除非左側並置的都為std_logic類型信號,右側為std_logic_vector類型信號,注意此時在vhdl中並不是用“&”這個並置運算符,而是“,”。(bit以及bit_vector是否有相似功能暫時未知)具體情況如圖:

錯誤,因為b是std_logic_vector類型

 

正確情況如下圖:

 

Bool類型的運用以及會出現的問題
在verilog中幾個信號經過關系運算后返回的值是1或者0,但是在vhdl中返回的確是bool類型的值,也就是說返回的是true或者false。

1、vhdl中在if后的判斷條件最后必須為布爾類型,如圖:

2、verilog和vhdl中信號經過關系運算后返回值的區別,如圖:

When-else語句不能用在process塊內
軟件轉換后的when-else語句常常被放在process塊內,導致出現問題。因為when-else語句是並行信號賦值語句,它本身就相當於一個進程process,因此不能放在進程體中。進程是不能夠嵌套的。

位移操作左側為bit類型,右側為integer類型
Verilog中的位移運算經xhdl軟件轉換后必出現錯誤,錯誤的原因是轉換成vhdl代碼后位移符號兩側數據類型出錯,如圖

錯誤情況:

修改后的正確格式:

位移符號左側應該是bit類型,所以將std_logic_vector類型的信號轉換為bit類型,數字“63”默認為integer類型,位移后的結果仍然為bit類型,所以需要將其裝換為std_logic_vector類型,並賦值給相同類型的信號。

真雙口RAM的IP核的使能信號

注意真雙口RAM的IP核的使能信號的數據類型,在頂層例化時要注意要只取使能信號第0位的與信號連接的方式。

 

由於真雙口RAM在例化后“wea”“web”為std_logic_vector(0 downto 0),所以要取這兩個端口的0位與信號連接。

while循環
在vhdl中不要使用while循環,會出現問題,將while循環換為for循環

top層輸入輸出端口不接信號的情況
1、在top層,例化的某個模塊輸出端口不連信號時,只需要在例化此模塊處將此端口刪除或注釋掉即可,如圖:

 

2、當在top層例化的某一模塊的輸入端口無信號連接時,必須將此端口處連接“U(未初始化)”狀態(理論上講將“U”換為“Z”也可以,但實際上會報出語法錯誤,在vhdl語法書上說是連接“open”狀態,實際測試也會報錯),如圖:

 

case語句的注意事項
在vhdl的case語句的語法中,只有分支將所有條件都覆蓋后才可以不使用“when others =>”(相當於verilog的default),但是實際中幾乎不可能包括所有情況(因為必須連高阻,不定態等狀態都包含進去),所以需要在case語句分支條件增加“when others =>”。對於原verilog代碼中default后沒有任何表達式的情況,在vhdl中對應的地方寫上“null”,如圖:

 

組合邏輯轉換時遇到的問題
當含有“always(*)”這類組合邏輯的verilog代碼經xhdl軟件轉換后以下兩種情況需要注意:

1、當是三段式狀態機中的“always(*)”被轉換時,注意去除其中的狀態常量。

2、由於vhdl規定case后的判斷條件必須是單一信號,所以當原verilog代碼中,case后面的判斷條件不是單一信號,而是幾個信號的組合時,xhdl軟件會將這幾個信號的組合用組合邏輯賦給一個新的信號,后將新的信號放在case的判斷邏輯處,此時需要注意查看組合邏輯塊的觸發信號是否包含此新生成的信號,具體如圖:

 

仿真時注意時鍾的問題(上板不會出現此問題)
在使用modelsim對vhdl代碼進行仿真時,會出現如圖的情況:

 

具體的操作就是對c_o信號打拍,可以發現第一拍沒有打上(實際是打上了),該測試程序的原理圖如圖:

C將時鍾clk_c_to_b和一個信號c_o傳遞給b,c_o使用時鍾clk生成的,在b內用c給的時鍾來給c_o打拍。最后發現仿真之所以會出現上面的情況,主要是因為在模塊c內對時鍾clk進行了一次處理后賦給b(如在c內部進行了clk_c_to_b

如果你在使用VHDL與Verilog轉換過程中遇到了上面沒有提到的問題,歡迎留言討論。或者你有更好的辦法完成兩種語言之間的轉換,也請不吝賜教!

編輯:hfy


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM