久々にVHDLを使って回路を記述することになった。これまでVHDLで算術演算をするばあいにはstd_logic_unsigned、std_logic_signed、std_logic_arith パッケージを呼び出して使用していた。
だいぶ前からXILINX社のISEが作成するテンプレートファイルはnumeric_stdパッケージを使用するよう薦めてくる。
そこでnumeric_stdパッケージを使用する際の簡単な覚書をメモしておく。
まず、numeric_stdパッケージではstd_logic_vectorを使用して四則演算や比較演算などを行うことはできない。
つまりこれまでは
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
...
signal x : std_logic_vector(31 downto 0);
signal y : std_logic_vector(31 downto 0);
signal z : std_logic_vector(31 downto 0);
...
z <= x + y; -- numeric_stdではこれはできない。
のような記述ができたが、numeric_stdを使用する場合はこれができないことになる。
必ずunsignedかsignedにキャスト(型変換)して使用する。また再度std_logic_vectorに戻すためのキャストも必要になる。
use ieee.numeric_std.all;
...
signal x : std_logic_vector(31 downto 0);
signal y : std_logic_vector(31 downto 0);
signal z : std_logic_vector(31 downto 0);
...
z <= std_logic_vector((unsigned(x) + unsigned(y));
unsigned、signedはnumeric_std内で以下のように定義されていてこれはstd_logic_arithの場合と同じ。
type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
type SIGNED is array (NATURAL range <>) of STD_LOGIC;
四則演算は基本的にはstd_logic_arithパッケージで定義されているものと同じだがstd_logic_arithは戻り値がstd_logic_vectorになる関数も定義しているのに対し、numeric_stdパッケージでは戻り値はsignedまたはunsignedのみである。
つまりnumeric_stdはより型に厳格になったパッケージと言えるだろう。必要な場合はユーザーが明示的にキャストする必要がある。
例として足し算はstd_logic_arithでは
function "+"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED;
function "+"(L: SIGNED; R: SIGNED) return SIGNED;
function "+"(L: UNSIGNED; R: SIGNED) return SIGNED;
function "+"(L: SIGNED; R: UNSIGNED) return SIGNED;
function "+"(L: UNSIGNED; R: INTEGER) return UNSIGNED;
function "+"(L: INTEGER; R: UNSIGNED) return UNSIGNED;
function "+"(L: SIGNED; R: INTEGER) return SIGNED;
function "+"(L: INTEGER; R: SIGNED) return SIGNED;
function "+"(L: UNSIGNED; R: STD_ULOGIC) return UNSIGNED;
function "+"(L: STD_ULOGIC; R: UNSIGNED) return UNSIGNED;
function "+"(L: SIGNED; R: STD_ULOGIC) return SIGNED;
function "+"(L: STD_ULOGIC; R: SIGNED) return SIGNED;
function "+"(L: UNSIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR;
function "+"(L: SIGNED; R: SIGNED) return STD_LOGIC_VECTOR;
function "+"(L: UNSIGNED; R: SIGNED) return STD_LOGIC_VECTOR;
function "+"(L: SIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR;
function "+"(L: UNSIGNED; R: INTEGER) return STD_LOGIC_VECTOR;
function "+"(L: INTEGER; R: UNSIGNED) return STD_LOGIC_VECTOR;
function "+"(L: SIGNED; R: INTEGER) return STD_LOGIC_VECTOR;
function "+"(L: INTEGER; R: SIGNED) return STD_LOGIC_VECTOR;
function "+"(L: UNSIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR;
function "+"(L: STD_ULOGIC; R: UNSIGNED) return STD_LOGIC_VECTOR;
function "+"(L: SIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR;
function "+"(L: STD_ULOGIC; R: SIGNED) return STD_LOGIC_VECTOR;
と定義されているのに対しnumeric_stdでは
function "+" (L, R: UNSIGNED) return UNSIGNED;
function "+" (L, R: SIGNED) return SIGNED;
function "+" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
function "+" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
function "+" (L: INTEGER; R: SIGNED) return SIGNED;
function "+" (L: SIGNED; R: INTEGER) return SIGNED;
のみが定義されている。
これをみると符号の有り無しの型を混在させることもできない。行う場合は符号有り無しどちらに合わせるかをユーザーが明示的にキャストで指示する必要がある。
一方符号の有り無しが一致すればintegerやnaturalといったVHDLの標準データ型と混在させることはできる。
比較演算も同様でstd_logic_arithでは許された符号有り無しの型の混在はnumeric_stdでは許されない。行う場合は符号有り無しどちらに合わせるかをユーザーが明示的にキャストで指示する必要がある。
例えばstd_logic_arithでは
function "<"(L: UNSIGNED; R: UNSIGNED) return BOOLEAN;
function "<"(L: SIGNED; R: SIGNED) return BOOLEAN;
function "<"(L: UNSIGNED; R: SIGNED) return BOOLEAN;
function "<"(L: SIGNED; R: UNSIGNED) return BOOLEAN;
function "<"(L: UNSIGNED; R: INTEGER) return BOOLEAN;
function "<"(L: INTEGER; R: UNSIGNED) return BOOLEAN;
function "<"(L: SIGNED; R: INTEGER) return BOOLEAN;
function "<"(L: INTEGER; R: SIGNED) return BOOLEAN;
なのに対し、numeric_stdでは
function "<" (L, R: UNSIGNED) return BOOLEAN;
function "<" (L, R: SIGNED) return BOOLEAN;
function "<" (L: NATURAL; R: UNSIGNED) return BOOLEAN;
function "<" (L: INTEGER; R: SIGNED) return BOOLEAN;
function "<" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
function "<" (L: SIGNED; R: INTEGER) return BOOLEAN;
のみとなる。
またintegerやnaturalといったVHDLの標準データ型とsigned, unsigned間の変換は
function TO_INTEGER (ARG: UNSIGNED) return NATURAL;
function TO_INTEGER (ARG: SIGNED) return INTEGER;
function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED;
function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED;
が定義されている。
同じく符号の有り無しの型の混在は無い。
その他の演算子(関数)についてはネットで検索してnumeric_std.vhdlを見ると良い。コンパクトなのですぐに理解できる。
0 件のコメント:
コメントを投稿