2014-01-16 316 views
2

我正在設計一個設計,我相信可能會發生一些我需要處理的溢出問題。爲了解決我的問題,我需要了解VHDL如何處理二進制溢出。一些示例代碼如下。VHDL如何處理溢出?

signal temp : std_logic_vector (7 downto 0) := "11111111"; 
signal temp_2 : std_logic_vector (7 downto 0) := "11111111"; 
signal result : std_logic_vector (8 downto 0) := "000000000"; 

result <= temp + temp_2 ; 

很明顯,這並沒有調用相關的庫,但它提供了我正在使用的代碼的概念。我的問題是:這個二進制加法如何工作(temp + temp_2),即運行此代碼後信號result會是什麼?現在,編輯中出現錯誤,因爲result是9位,期望8位。任何關於這個二進制加法如何工作的解釋都會非常有幫助!

+0

您應該使用'signed'和'unsigned'而不是'std_logic_vector'進行數學運算。增加兩個'std_logic_vector's不是標準的VHDL(有一個**非標準**庫允許你這樣做,但你不應該使用它)。 – zennehoy

回答

6

VHDL是強類型的。任何時候你分配一個信號,你需要匹配類型和寬度。

對於類型:您不能將整數類型的信號分配給std_logic_vector信號,編譯器會引發錯誤。您必須先將整數轉換爲std_logic_vector。

對於寬度:您需要始終完全匹配寬度分配。在你的情況下,這個工具對你很生氣,因爲你將一些8位寬的東西分配給9位寬的信號結果。

爲了完成你想要的,你必須使用符號擴展。你的輸入是簽名還是未簽名?如果它們是無符號的,只需在最高有效位位置添加一個「0」。如果他們簽約,你必須確定的第7位的標誌,然後再擴展到這一點位的位置8.

這裏是你如何能在這兩種情況下做到:

temp_extended_unsigned <= '0' & temp(7 downto 0); 
temp_extended_signed <= temp(7) & temp(7 downto 0); 

temp_2_extended_unsigned <= '0' & temp_2(7 downto 0); 
temp_2_extended_signed <= temp_2(7) & temp_2(7 downto 0); 

result <= temp_extended_unsigned + temp_2_extended_unsigned; -- unsigned case 
result <= temp_extended_signed + temp_2_extended_signed; -- signed case 

注意添加1位位置的作品加法罰款,但乘法呢?您必須考慮要執行的操作...將兩個8位寬的向量相乘會產生一個16位寬的結果,因此您必須在該示例中對高8位進行符號擴展。

+4

另請注意,ieee.numeric_std包中的resize()函數可以正確地擴展帶符號的向量(並且在縮小它們時也保留該符號): data_out <= resize(data_in,data_out'length); (在std_logic_arith包中有符號擴展函數SXT(),但這不是標準庫,也有點隱晦。) – mbschenkel

+0

這似乎最初解決了這個問題,但現在我已經意識到它已經引入了結果中有兩個時鐘週期的延遲。這是因爲完成二進制加法和創建新的向量所花費的時間?還是還有別的東西我失蹤了? – srohrer32

+0

如果通過將其置於時鐘進程中來創建註冊邏輯,那麼會創建額外的延遲。你可以把它放在流程之外,它會創建組合邏輯。 – Russell