web-dev-qa-db-ja.com

長いstd_logic_vectorをゼロと比較する

シミュレーションでは、これは完璧に機能します。これは、合成可能なコードのゼロをチェックするための最良の方法ですか。生成されるリソースは何ですか?

signal vector_slv : std_logic_vector(2048 downto 0);
...
if (vector_slv = (vector_slv'range => '0')) then
  -- do something...

(最適なリソース使用率で)ハードウェアマッピングを考慮して、このソリューションを実装する他の最適な方法はありますか?.

使用されているリソースを理解することにもっと興味があります。

12
powernest

合成に多かれ少なかれ意味をなす方法はありません。あなたの意図を最もよく表すコードを書いてください。

すべてゼロのベクトルを比較している場合、以下はすべて同じ結果を生成するか、ツールに対して重大なバグを報告する必要があります。

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ではありません:)

6
Martin Thompson

サンプルコードのように範囲が利用できる場合、提案ソリューションは問題ないように見えます。合成ツールはこのような構造を処理するように作られていると思います。

範囲が利用できない場合は、ゼロとの比較を次のように行うことができます。

library ieee;
use ieee.numeric_std.all;
...
  if unsigned( {std_logic_vector expression of any length} ) = 0 then
    -- do something...

合成ツールは、(vector_slv'range => '0')と比較した場合と同じようにこれを処理すると思います。

7
Morten Zilmer

合成に関する限り、そうです、そのような単純な構成は通常、ツールによってかなりうまく最適化されます。もちろん、正確なハードウェアレイアウトは、ターゲットが何であるか(FPGA、ASICなど)によって異なります。

私の提案は、合成結果を確認することです(たとえば、アルテラFPGAのテクノロジーマップビューアー)。合成がそれを覆い隠している場合は、利用可能なテクノロジープリミティブを考慮して、ゼロとの比較のバイナリツリーに手動で変換できます。ただし、これは思ったよりもはるかに難しい場合があります。特にFPGA(そこではLUT以上のものがあります)の場合は、まともなツールでは必要ありません。

1
zennehoy

これを行うことで、述語と割り当てを分離することもできます。

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」が元の比較の遅延バージョンになったことを考慮に入れてください。

1
Thomas

単項演算子を使用できます。例:

  • そして
  • ナンド
  • または
  • また
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;
0
tim