シミュレーションでは、これは完璧に機能します。これは、合成可能なコードのゼロをチェックするための最良の方法ですか。生成されるリソースは何ですか?
signal vector_slv : std_logic_vector(2048 downto 0);
...
if (vector_slv = (vector_slv'range => '0')) then
-- do something...
(最適なリソース使用率で)ハードウェアマッピングを考慮して、このソリューションを実装する他の最適な方法はありますか?.
使用されているリソースを理解することにもっと興味があります。
合成に多かれ少なかれ意味をなす方法はありません。あなたの意図を最もよく表すコードを書いてください。
すべてゼロのベクトルを比較している場合、以下はすべて同じ結果を生成するか、ツールに対して重大なバグを報告する必要があります。
signal vector_slv : std_logic_vector(2048 downto 0);
constant zeros : std_logic_vector(vector_slv'range) := (others => '0');
...
if vector_slv = (vector_slv'range => '0') then
-- do something...
if vector_slv = zeros then
-- do something...
if unsigned(vector_slv) = to_unsigned(0, vector_slv'length) then
-- do something...
実際、整数に収まる短いベクトルの場合:
if intvar = 0 then
32ビットのベクトル比較とまったく同じになります。
(ところで、if
条件の前後に括弧は必要ないことに注意してください-VHDLはCではありません:)
サンプルコードのように範囲が利用できる場合、提案ソリューションは問題ないように見えます。合成ツールはこのような構造を処理するように作られていると思います。
範囲が利用できない場合は、ゼロとの比較を次のように行うことができます。
library ieee;
use ieee.numeric_std.all;
...
if unsigned( {std_logic_vector expression of any length} ) = 0 then
-- do something...
合成ツールは、(vector_slv'range => '0')
と比較した場合と同じようにこれを処理すると思います。
合成に関する限り、そうです、そのような単純な構成は通常、ツールによってかなりうまく最適化されます。もちろん、正確なハードウェアレイアウトは、ターゲットが何であるか(FPGA、ASICなど)によって異なります。
私の提案は、合成結果を確認することです(たとえば、アルテラFPGAのテクノロジーマップビューアー)。合成がそれを覆い隠している場合は、利用可能なテクノロジープリミティブを考慮して、ゼロとの比較のバイナリツリーに手動で変換できます。ただし、これは思ったよりもはるかに難しい場合があります。特にFPGA(そこではLUT以上のものがあります)の場合は、まともなツールでは必要ありません。
これを行うことで、述語と割り当てを分離することもできます。
signal is_zero : boolean;
signal vector_slv : std_logic_vector(2048 downto 0);
...
process(clk)
begin
if rising_Edge(clk) then
is_zero <= vector_slv = (vector_slv'range => '0');
if is_zero then
...
end if;
end if;
end process;
これにより、タイミングが大幅に改善されます。述語「is_zero」が元の比較の遅延バージョンになったことを考慮に入れてください。
単項演算子を使用できます。例:
signal vector_slv: std_logic_vector(2048 downto 0);
...
if nand vector_slv then
-- Do something for all 0...
elsif and vector_slv then
-- Do something for all 1...
elsif nor vector_slv then
-- Do something for at least one 0...
elsif or vector_slv then
-- Do something for at least one 1...
end if;
または、 std_logic_1164 で定義されている関数を使用することもできます。例:
function "and" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
function "nand" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
function "or" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
function "nor" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
use ieee.std_logic_1164.all;
...
signal vector_slv: std_logic_vector(2048 downto 0);
...
if nand(vector_slv) then
-- Do something for all 0...
elsif and(vector_slv) then
-- Do something for all 1...
elsif nor(vector_slv) then
-- Do something for at least one 0...
elsif or(vector_slv) then
-- Do something for at least one 1...
end if;