2007年08月13日
VHDL TIPS 「std_matchの使用法」
例えば2つのSTD_LOGICを単純に比較すると'1'や'0'の時は何も疑問なく結果が出ると思う。ただSTD_LOGICは'U'や'-'などの状態も存在する。
これらが含まれた比較を行った場合はどうなるか?
シミュレーションでは単純に=(イコール)で比較した場合は正確に同じ状態でないとイコールとはならない。
合成ツール(XST)では'-'や'X'はドントケアとして処理し最適化される。
この事から、シミュレーションと実機の動作不一致が発生する。これを回避するために「numeric_std」に含まれる「std_match」ファンクションが使用できる。
std_matchは'-'をドントケアとするだけでなく'U'などの不定値が一致した場合でもイコールとしないような動作をして実機と一致させている。
(XSTは'X'をドントケア、std_matchは不定値として処理するので動作が一致していないが、numeric_stdを参考にテーブルを少し変えるだけで簡単に新たなファンクションを作成できる)
しかし、そもそも'-'(ドントケア)と比較する事自体、意味が無いなんて思われるかもしれない。それはその通りなのだが、データがベクタタイプになると意味が出てくる。例えば、あるビットだけ比較しなくて良い場合などはその部分を'-'をドントケアとして比較すれば一度に記述する事が出来る("0-01--10"等)
以下にstd_matchの動作を紹介する。
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity test is
end test;
architecture behavior of test is
signal result_match : boolean := FALSE;
signal result_equ : boolean := FALSE;
signal testdata : std_logic_vector(2 downto 0) := (others => '0');
begin
-- 固定値
testdata(2) <= '1';
testdata(0) <= '0';
-- std_logicの全ての状態を繰り返す
process begin
testdata(1) <= 'U';
wait for 10 ns;
testdata(1) <= 'X';
wait for 10 ns;
testdata(1) <= '0';
wait for 10 ns;
testdata(1) <= '1';
wait for 10 ns;
testdata(1) <= 'Z';
wait for 10 ns;
testdata(1) <= 'W';
wait for 10 ns;
testdata(1) <= 'L';
wait for 10 ns;
testdata(1) <= 'H';
wait for 10 ns;
testdata(1) <= '-';
wait for 10 ns;
end process;
-- イコール(=)で比較した場合
process begin
if ( testdata = "1-0" ) then
result_equ <= TRUE;
else
result_equ <= FALSE;
end if;
wait on testdata;
end process;
-- std_matchを使った場合
process begin
if ( std_match(testdata, "1-0")) then
result_match <= TRUE;
else
result_match <= FALSE;
end if;
wait on testdata;
end process;
end behavior;
これの結果は、
このように、単純に=(イコール)で比較した場合は完全に一致した"1-0"の場合だけTRUEになり、std_matchを使用した場合はtestdata(2)とtestdata(0)だけの比較になるので常時TRUEになる。