それ自体は順次「実行」されませんが、シンセサイザーはコードを順次解釈し、そのような解釈に適合するハードウェア設計を作成します。
たとえばsignal
、クロックプロセス中に2回に値を割り当てると、最初の割り当ては単に無視され、2番目の割り当てが有効になります(aはステートメントsignal
の最後でのみ割り当てられ、すぐには割り当てられないことに注意してください)。process
signal a : UNSIGNED(3 downto 0) := (others => '0');
(...)
process(clk)
begin
if(rising_edge(clk)) then
a <= a - 1;
a <= a + 1;
end if;
end process;
上記のプロセスは常に1ずつ増加a
します。同様に、ステートメント内に2番目の割り当てがある場合、シンセサイザーは、ステートメントがいっぱいになったときのデクリメントと、いっぱいになったときのインクリメントのif
2つのパスを作成します。a
if
変数を使用する場合、考え方は同じです。変数はすぐに新しい値を取得するため、中間値が使用されます。
しかし、結局のところ、シンセサイザーは、ユーザーprocess
を順番に解釈し、説明したことを実行するハードウェアを生成するというすべての「魔法」を実行します。
あなたの例は基本的にd-フリップフロップを説明しています(ザイリンクスFPGAツールiircは、フリップフロップがエッジセンシティブであり、ラッチがレベルセンシティブであるという点でラッチとフリップフロップを区別します)が、通常推奨される方法とは異なります。
基本的に次のように同じコードを書くことができます:
process(clk)
begin
if(rising_edge(clk)) then
q <= d;
end if;
end process;
それ以外の場合は、自動的にその値を保持します。これは、FPGA内のフリップフロップとして実装されます。ほとんどのFPGAは、ルックアップテーブルとフリップフロップのブロックで構成されており、これらに非常に多くの異なるハードウェアをマッピングできます。上記のコードは、ルックアップテーブルをバイパスし、ブロックの1つのフリップフロップを使用するだけです。
特定のFPGAのデータシートを参照すると、内部動作について詳しく知ることができます。たとえば、Spartan3シリーズFPGAの場合は、ザイリンクスSpartan3FPGAファミリデータシートの24ページを参照してください。