VHDLを使用して組み合わせロジックのブロックを設計したいのですが、合成結果に意図しないラッチが含まれることがあります。
シンセサイザがラッチを推論しないようにするには、どのコーディングガイドラインに従う必要がありますか?
例:コードの小さなセグメントで、if-elseステートメントを使用する必要がありますか?
VHDLを使用して組み合わせロジックのブロックを設計したいのですが、合成結果に意図しないラッチが含まれることがあります。
シンセサイザがラッチを推論しないようにするには、どのコーディングガイドラインに従う必要がありますか?
例:コードの小さなセグメントで、if-elseステートメントを使用する必要がありますか?
回答:
ラッチを回避するには、すべての出力がコードの可能なすべての分岐に割り当てられていることを確認する必要があります。
例えば、
if a = '1' then
b(0) <= '1';
else
b(1 downto 0) <= "00";
end if;
最初の条件ではb(1)の値が指定されていないため、ラッチが生成され、コンパイラーはb(1)の以前の値をそこに保持することを決定しました。これを作成してラッチを生成しない方法の1つは、次のとおりです。
if a = '1' then
b <= prev_b;
b(0) <= '1';
else
b(1 downto 0) <= "00";
end if;
...
if rising_edge (clk)
prev_b <= b;
end if;
ここでは、bが古い値を保持する必要があることを明示的に述べ、b(0)を新しい値で上書きします。
もう1つの方法は、@ TomiJの回答のように、デフォルト値を指定することです。
あなたがラッチを取得しているコードを投稿する場合、私たちはあなたが特定の理由を見つけるのを助けることができます。
b <= b
それでも信号の状態を保持する必要があるため、のアプローチではラッチを回避できないと思います。
組み合わせロジックにプロセスを使用している場合(そしてこの理由のために私はそれをお勧めしません)、プロセスを通るすべてのパスが、プロセスが駆動するすべての信号に何かを割り当てることを確認してください。プロセスが実行された「前回」の出力に依存する可能性のある出力はありません。
そうしないと、次にプロセスがスケジュールされたときに、前回新しい値を取得しなかった信号の値を保持する必要があるため、ラッチを推測します。
純粋な組み合わせロジックを継続的な割り当てとして保持し、クロックロジックのプロセスを使用したいのですが、ラッチが取得されません。
ラッチを回避するための4つのルール:
さらに、複数の組み合わせプロセスがある場合は、ループを作成しないようにしてください。
@TomiJの回答のスタイルなど、いくつかのコーディングスタイルがこれらのルールを守るのに役立ちます。@Martin Thompsonが指摘しているように、組み合わせロジックをすべて一緒に回避することをお勧めします。代わりに、すべてをクロックプロセスに入れます。
@fboと@Martin Thompsonによって指摘されているように、プロセスによって駆動されるすべての信号にプロセスのすべてのブランチで何らかの値が割り当てられていることを確認する必要があり、その値は出力の以前の状態に依存していてはなりませんプロセスの。
これを確実にする最も簡単な方法は、たとえば、プロセスの最初に各出力にいくつかのデフォルト値を割り当てることです(たとえば、fboの例をco-opting)。
COMBO: process(a)
begin
b <= (others => '0'); -- Assign default value to b
if a = '1' then
b(0) <= '1';
else
b(1 downto 0) <= "00";
end if;
end process COMBO;