XILINXのIP Core, ILAは1ビットのprobeを定義しても
component ila
port (
clk : in std_logic;
probe0 : in std_logic_vector(0 downto 0)
);
end component;
のように std_logic_vector になっている。
インスタンスに std_logic の信号を接続するときには
signal probe0 : std_logic_vector(0 downto 0);
probe0(0) <= some_signal;
i_ila : ila
port map (
clk => clk,
probe0 => probe0
);
のようにしても良いのだけれど、probe0のsignal をいちいち定義するのも面倒。
知っている人には「何を当たり前のことを言っているんだ」かも知れないけど
i_ila : ila
port map (
clk => clk_in,
probe0 => (0 => some_signal)
);
のようにすれば probe0 を定義しなくても直接 ILA のインスタンスに接続でき簡単。
意外とこういう接続方法ってやらないので、知っておくとちょっと便利な書き方です。
2015/4/2追記
probe0 => (0 => some_signal)
と書くとVivado 2014.4ではシミュレーション時エラーとなる。Synthesis, ImplementationはOK。
probe0(0) => some_signal
と書けばシミュレーション時も問題なく通る。シミュレーションもかけるならこちらの方が良い。
2015年3月21日土曜日
2014年10月27日月曜日
VHDLのnumeric_stdについてのメモ
久々に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を見ると良い。コンパクトなのですぐに理解できる。
だいぶ前から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を見ると良い。コンパクトなのですぐに理解できる。
登録:
投稿 (Atom)