web-dev-qa-db-ja.com

unsignedとstd_logic_vectorの違い

以下の記述の違いについて誰か教えてもらえますか?.

signal A: **unsigned**(3 downto 0);
signal B: **std_logic_vector**(3 downto 0);
5
Kelvin Kalariya

std_logic_vectorunsignedはどちらもstd_logic制約のない配列です。 signedタイプも同様です。 std_logic_vectorstd_logic_1164パッケージで宣言されています。 unsignedsignedはパッケージnumeric_stdで宣言されています。 3つのタイプはすべて同じです。唯一の違いはそれらの名前です。

それで、そのポイントは何ですか?この点は、例によってよく示されています。

variable U : unsigned(3 downto 0);
variable S : signed(3 downto 0);
variable I : integer;

その後

U := "1111";
I := to_integer(U);

その結果、Iには値15が与えられますが、

S := "1111";
I := to_integer(S);

その結果、Iに値-1が与えられます。これは、unsignedタイプがunsigned番号を表すために使用されているためです。これは、正の値のみです。したがって、"1111"は数値15を表します。ただし、signed型は負の数も表すことができる必要があり、signed型では"1111"は-1を表します(2の補数このタイプでは表現が使用されます)。

したがって、同じ関数(to_integer)が"1111"で呼び出されたときに、引数のタイプがunsignedまたはsignedのどちらであるかに応じて、15または-1の2つの異なる結果を返すことがわかります。したがって、両方のタイプの違いは名前だけですが、両方のタイプを持つことのポイントを理解できます。

実際には、1つではなく2つのto_integer関数があります。 1つはunsigned引数を取ります。もう1つ(同じ名前のto_integer)はsigned引数を取ります。ご覧のとおり、動作は異なります。コンパイラーは、引数のタイプに基づいて、呼び出す必要のある関数を決定できます。コンパイラが引数のタイプに基づいて異なる(ただし同じ名前の関数)から選択できるこのアイデアは、オーバーロードと呼ばれます。これはソフトウェア言語では一般的です。

では、std_logic_vectorはどうですか?あなたが書いたとしましょう:

variable V : std_logic_vector(3 downto 0);
variable I : integer;

その後

V:= "1111";
I := to_integer(V);

to_integer関数からどのような結果を期待しますか? 15または-1?このジレンマは、上記のコードが違法であるために解決されます-コンパイルされません。 to_integerに対して定義されたstd_logic_vector関数のバージョンがないため、コンパイルされません-to_integer関数はタイプstd_logic_vectorに対してオーバーロードされていません。

したがって、正の数のみを表す必要がある場合は、unsignedタイプを使用することをお勧めします。負の数を表す必要がある場合は、signedタイプを使用する必要があります。ビットのパターンが数値ではないため、またはビットのパターンを計算していないため(単にある場所から別の場所に転送しているだけ)、本当に気にしない場合は、std_logic_vectorを使用するのが最善です。

https://www.edaplayground.com/x/2Qq4

11
Matthew Taylor