1

U4.10形式の固定小数点数にU0.8形式の定数を掛けて、結果をU4.10に切り捨てたいと思います。私が欲しいと思うのは次のようなものです:

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

..。

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

しかし、これはコンパイルされません。2つの質問:

  1. 私がやろうとしていることの正しい構文は何ですか?
  2. 変数型のビット数を変更した場合に、コードをより保守しやすくするために、いくつかのシンボリック属性などを使用する良い方法はありますか?
4

3 に答える 3

3

正しい幅の中間信号を使用してください。醜いですが、信頼性が高く、保守が簡単です。

これを複数回行う場合は、関数の醜さを隠してください。複数の機能がある場合、またはそれらを複数の場所で使用する場合は、それらをパッケージに入れます。

例えば;

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);

ご覧のとおり、これも型システムを使用して、データ ワード幅に関する決定の変更からユーザーを保護します。

後で、切り捨てよりも丸めの方が誤差が少ないことに気付いたら、これらの関数を変更するだけで済みます...

于 2012-12-03T16:52:11.860 に答える
2

上記の私のコメントが将来の読者に気付かれない場合:

この種のアクティビティを行う標準的な方法があります - ここから固定小数点ライブラリを使用します:

http://eda-stds.org/fphdl

于 2012-12-04T10:14:32.073 に答える
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を使用します。

于 2012-12-03T22:34:50.063 に答える