ラベル vhdl の投稿を表示しています。 すべての投稿を表示
ラベル vhdl の投稿を表示しています。 すべての投稿を表示

2015年3月21日土曜日

XILINX ILAの1ビットprobe(0 downto 0)にsignalを繋ぐ簡単な方法

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
と書けばシミュレーション時も問題なく通る。シミュレーションもかけるならこちらの方が良い。

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を見ると良い。コンパクトなのですぐに理解できる。