2012-12-03 89 views
1

我想乘以一個U0.8格式常量的U4.10格式定點數並截斷我的結果到U4.10。我想,我想是這樣的:VHDL語法刪除乘法餘數

signal A, B : unsigned(13 downto 0); 
signal MULT : unsigned(7 downto 0); 

...

B <= (A * MULT)(21 downto 8); 

但是,這並不編譯。兩個問題:

  1. 什麼是我正在嘗試做的正確語法?
  2. 如果我改變我的變量類型中的位數,是否有一種很好的方式來使用某些符號屬性或某些方法來使代碼更易於維護?
+0

有你看在固定點庫? http://www.eda-stds.org/fphdl/ –

+0

我沒有 - 謝謝你的鏈接。 – blueshift

回答

2

使用正確寬度的中間信號。這是醜陋但可靠和易於維護。

如果你不止一次這樣做,在一個函數中隱藏醜陋;如果您有多個功能或在多個地方使用它們,請將它們放在一個包中。

例如;

package DSP is 
    subtype Data is unsigned(13 downto 0); 
    subtype Coeff is unsigned(7 downto 0); 

    function Mul_Coeff (A:Data, M:Coeff) return Data; 
end package DSP; 

package body DSP is 
    function Mul_Coeff (A:Data, M:Coeff) return Data is 
     variable Temp : unsigned (Coeff'Length + Data'High downto 0) := A * M; 
    begin 
     return Temp (Temp'High downto Coeff'Length); 
    end Mul_Coeff; 
end package body DSP; 

...

B <= Mul_Coeff(A, Mult); 

正如你所看到的,這也採用了類型系統來保護你從有關數據字寬的決策的變化。

後來,當你意識到四捨五入給出比截斷誤差下,你只需要修改這些功能...

1

IMO這個要求的屬性:

procedure mul_fixed (
    signal a : in unsigned_fixed; 
    signal b : in unsigned_fixed; 
    signal c : out unsigned_fixed 
    ) is 
constant a_temp : unsigned(a'length - 1 downto 0) := to_unsigned(a); 
constant b_temp : unsigned(b'length - 1 downto 0) := to_unsigned(b); 
variable result : unsigned(a'length + b'length - 1 downto 0); 
-- notice this might be negative if a, b are (? downto +n), which is correct 
constant num_fractional : integer := 0 - a'right - b'right; 
-- c integral might be bigger than integral/fractional part, make sure we only access valid indices in result 
constant result_left : integer := min(result'length - 1, num_fractional + c'left); 
constant result_right : integer := max(0    , num_fractional + c'right); 
begin 

    result := a_temp * b_temp; 
    c <= (others => '0'); -- make sure all bits are defined 
    c(result_left - num_fractional downto result_right - num_fractional) <= result(result_left downto result_right); 

end procedure mul_fixed; 

type unsigned_fixed is array(range <>) of std_logic; 

和無符號轉換函數存在。

所以你會

... 
signal a : unsigned_fixed(3 downto -10); -- 4Q10 
signal b : unsigned_fixed(-1 downto -8); -- 0Q8 
signal c : unsigned_fixed(3 downto -10); -- 4Q10 

mul_fixed(a, b, c); 

我知道,所有這些屬性看起來很嚇人的在第一,但我經常發現自己寫癡癡很多包,只是因爲我有不同的數據類型: -/ IMO一個應該花時間思考關於這一次,找出一個通用的解決方案並繼續前進 - 畢竟這就是VHDL的屬性。

  • 請注意,我沒有進入到測試環境,而寫這,所以有可能會或可能不會需要到c分配結果的時候要一個類型轉換。

此外,如果可以的話,您至少應該看看定點庫。或者使用VHDL-2008和定點軟件包。

+0

定點包不限於VHDL 2008是嗎? –

+0

你提到的那個被整合到VHDL-2008中,但是有重大的變化。它應該在VHDL-1993中使用上述軟件包,或使用VHDL-2008和內置軟件包,具體取決於供應商。 – FRob

2

如果我的評論上述由未來的讀者被忽視:

有做這類活動的標準方法 - 使用定點庫從這裏:

http://eda-stds.org/fphdl