ステートメントデバウンサーの例を生成する
VHDL の generate ステートメントは、コードのブロックを、同一のシグナル、プロセス、およびインスタンスを持つクロージャーに自動的に複製できます。これは、連鎖プロセスまたはモジュール インスタンスを作成できるアーキテクチャ領域の for ループです。
プロセスまたはサブプログラムにのみ存在できる通常の for ループとは異なり、generate ステートメントは VHDL ファイルのアーキテクチャ領域に直接配置されます。ジェネリックと一緒に使用すると、設計間で再利用できるカスタマイズ可能な VHDL モジュールを設計するための強力なツールになります。
ステートメント構文の生成
generate ステートメントの構文は次のとおりです。
[label :] for <constant_name> in <range> generate
[declarations_local_to_each_loop_iteration]
[begin]
<processes_and_instantiations>
end generate [label];
角括弧で囲まれた部分はオプションです。したがって、宣言領域と begin を省略できます。 ローカル オブジェクトを宣言したくない場合は、キーワード。 <範囲> プレースホルダーは、to を使用して標準の整数範囲を表します または downto .
1 ビット スイッチ デバウンサー
generate ステートメントを開始する前に、この記事全体で例として使用する簡単なモジュールを紹介します。これは、単一のスイッチ入力をデバウンスできるデバウンサーです。
任意のクロック速度で使用できるようにするために、timeout_cycles という名前の汎用入力を追加しました .この定数は、スイッチ入力が変化した後のタイムアウトのクロック サイクル数を指定します。デバウンサーは、タイムアウト期間中のスイッチ値の追加の変更を無視します。
以下のリストは、デバウンサーのエンティティを示しています モジュール。弾むスイッチがあります 入力、そしてきれいな switch_debounced があります 出力。
entity debouncer is
generic (
timeout_cycles : positive
);
port (
clk : in std_logic;
rst : in std_logic;
switch : in std_logic;
switch_debounced : out std_logic
);
end debouncer;
デバウンサー モジュールは、整数カウンターに依存してタイムアウト期間を達成します。 カウンターの長さ signal はジェネリック定数に従います。これが、インスタンス化中に指定されたタイムアウト期間が行うことです。
switch_debounced の値を読み取る必要があるため debounced という名前のシャドウ シグナルを宣言しました。 、代わりに使用します。これは、inout を設定する他のオプションよりもクリーンなソリューションです。 switch_debounce のモード
最後に、以下のコードに示すように、1 つのプロセスでデバウンス動作を実装します。
architecture rtl of debouncer is
signal debounced : std_logic;
signal counter : integer range 0 to timeout_cycles - 1;
begin
-- Copy internal signal to output
switch_debounced <= debounced;
DEBOUNCE_PROC : process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
counter <= 0;
debounced <= switch;
else
if counter < timeout_cycles - 1 then
counter <= counter + 1;
elsif switch /= debounced then
counter <= 0;
debounced <= switch;
end if;
end if;
end if;
end process;
end architecture;
以下の波形は、デバウンスのシミュレーションを示しています ModelSim のモジュール。 switch_debounced が 出力は切り替えに従います 入力されますが、最初の変更直後のバウンス動作は無視されます — 信号をデバウンスします。
以下のフォームを使用して、この記事から VHDL コードをダウンロードしてください。電子メール アドレスを入力すると、テストベンチとクイック ラン スクリプトを含む ModelSim プロジェクト全体を含む Zip ファイルが届きます。 VHDLwhiz から今後のアップデートを受け取ります。いつでも購読を解除できます。
インスタンス化による for ループの生成
スイッチの配列のデバウンサーを作成するには、generate ステートメントを使用して、1 ビット デバウンサー モジュールの複数のインスタンスを作成します。
以下のリストは、新しい配列またはベクトル デバウンサー モジュールのエンティティを示しています。 1 ビット デバウンサーに似ていますが、追加の汎用入力があります:switch_count .作成するデバウンサー モジュールのインスタンスの数を指定します。スイッチごとに 1 つある必要があります。
さらに、スイッチの入力と出力の名前を単語の複数形に変更し、単一ビットではなくベクトルになりました.
entity debouncer_gen_inst is
generic (
switch_count : positive;
timeout_cycles : positive
);
port (
clk : in std_logic;
rst : in std_logic;
switches : in std_logic_vector(switch_count - 1 downto 0);
switches_debounced : out std_logic_vector(switch_count - 1 downto 0)
);
end debouncer_gen_inst;
アーキテクチャでは、generate ステートメントを使用します。これは、通常の for ループのように機能しますが、「ループ」という単語が「生成」という単語に置き換えられているだけです。ただし、通常の for ループとは異なり、モジュールのインスタンス化を含めることができます。
for ループはコンパイル時に実行され、反復ごとにデバウンサー モジュールのインスタンスを 1 つ生成します。ただし、「i」定数は反復ごとに異なるため、以下に示すように、これを使用して、デバウンサーの入力と出力をスイッチ ベクトルの個々のビットにマッピングできます。
architecture rtl of debouncer_gen_inst is
begin
MY_GEN : for i in 0 to switch_count - 1 generate
DEBOUNCER : entity work.debouncer(rtl)
generic map (
timeout_cycles => timeout_cycles
)
port map (
clk => clk,
rst => rst,
switch => switches(i),
switch_debounced => switches_debounced(i)
);
end generate;
end architecture;
generate ステートメントにラベルを付けるのはオプションですが、そうするのが賢明かもしれません。ラベルはシミュレーター階層と合成ログに表示されるため、デバッグ時に特定のインスタンスを簡単に識別できます。
以下の波形は、ベクトル デバウンサーのシミュレーションを示しています。 「MY_GEN」ラベルがここに再表示され、8 つのデバウンサー インスタンスのそれぞれにインデックスが追加されていることがわかります。
このテストベンチは、スイッチ番号 3 の入力のみを変更します。これが波形に表示され、MY_GEN(3) グループのみを展開した理由です。
ModelSim がインストールされている場合は、この例をコンピューターですばやく実行できます。以下のフォームを使用して、ソース コードと ModelSim プロジェクトをダウンロードしてください!
プロセスを含む for ループを生成
この記事の最後の例では、generate ステートメントを使用して、一連の同一のプロセスを作成します。 1 ビット デバウンサー モジュールのインスタンスを作成する代わりに、そこから VHDL コードを取り出しました。エンティティは前の例と同じで、動作も同じですが、実装が異なります。
DEBOUNCE_PROC プロセスを generate ステートメント内に移動し、以下のコードでわずかに変更したことがわかります。今回は、generate ステートメント内で 2 つのローカル シグナルを宣言しています:debounced そして反撃 .
for ループを反復するたびに、シグナルとプロセスの追加のコピーが作成されます。プロセス内でこれらのシグナル名を使用すると、その特定のループ反復のエンクロージャーにスコープされたシグナルが参照されます。
最後に、debounced を割り当てます std_logic switches_debounced の正しいビットに信号を送る プロセスの上の並行ステートメントを使用したモジュール出力。
architecture rtl of debouncer_gen_proc is
begin
MY_GEN : for i in 0 to switch_count - 1 generate
signal debounced : std_logic;
signal counter : integer range 0 to timeout_cycles - 1;
begin
switches_debounced(i) <= debounced;
DEBOUNCE_PROC : process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
counter <= 0;
debounced <= switches(i);
else
if counter < timeout_cycles - 1 then
counter <= counter + 1;
elsif switches(i) /= debounced then
counter <= 0;
debounced <= switches(i);
end if;
end if;
end if;
end process;
end generate;
end architecture;
モジュールのインスタンス化を使用した前の例とまったく同じに見えるため、シミュレーション波形は省略しました。動作は同じです。
以下のフォームを使用して、すべてのコードをダウンロードできます。電子メール アドレスを入力すると、VHDLwhiz からの更新を購読することになります。でも心配はいりません。送信するすべてのメールに登録解除リンクがあります。
共有するステートメントを生成するための別の便利なアプリケーションがある場合は、下にコメントを残してください! ?
VHDL