VHDLでクロック駆動プロセスを構築:実践ガイド
大多数のVHDL設計はクロックドロジック、いわゆる同期またはシーケンシャルロジックを採用します。クロックドプロセスは、マスタークロックのエッジのみで活性化し、他の入力信号の変化に関係なく動作します。
クロックドロジックの基本要素はフリップフロップです。本チュートリアルでは、負リセット付き正エッジトリガーフリップフロップに焦点を当てます。以下の回路図を参照:
サンプル・アンド・ホールドデバイスとして、フリップフロップは立ち上がりクロックエッジで入力値を取り込み、次の立ち上がりエッジまたはリセット信号アサートまでその値を保持します。
注意: この投稿はBasic VHDL Tutorialsシリーズの一部です。
すべてのクロックドプロセスはユニゾンでトリガーされ、同時に入力をサンプリングします。クロックは離散タイムステップを確立し、設計者が複雑なロジックを明確なサイクル単位のイベントに分割できるようにします。
フリップフロップ、またはその配列はレジスタとも呼ばれます。
クロックドプロセスの感度リストには通常クロック信号のみが含まれます。プロセスはクロックフランキのみでウェイクアップするためです。追加入力はトリガー目的では無視されます。
以下は同期リセット付きクロックドプロセスの再利用可能なテンプレートです:
process(Clk) is
begin
if rising_edge(Clk) then
if nRst = '0' then
<reset all output signals here>
else
<main logic here>
end if;
end if;
end process;
演習
付属のビデオチュートリアルでは、VHDLでクロックドプロセスを作成する手順を解説します。
テストベンチコード
フリップフロップの最終テストベンチ:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity T17_ClockedProcessTb is
end entity;
architecture sim of T17_ClockedProcessTb is
constant ClockFrequency : integer := 100e6; -- 100 MHz
constant ClockPeriod : time := 1000 ms / ClockFrequency;
signal Clk : std_logic := '1';
signal nRst : std_logic := '0';
signal Input : std_logic := '0';
signal Output : std_logic;
begin
-- Device Under Test (DUT)
i_FlipFlop : entity work.T17_FlipFlop(rtl)
port map(
Clk => Clk,
nRst => nRst,
Input => Input,
Output => Output
);
-- クロック生成
Clk <= not Clk after ClockPeriod / 2;
-- テストベンチシーケンス
process is
begin
-- DUTをリセットから解放
nRst <= '1';
wait for 20 ns;
Input <= '1';
wait for 22 ns;
Input <= '0';
wait for 6 ns;
Input <= '1';
wait for 20 ns;
-- リセット適用
nRst <= '0';
wait;
end process;
end architecture;
フリップフロップモジュール
負リセット付き正エッジフリップフロップの実装:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity T17_FlipFlop is
port(
Clk : in std_logic;
nRst : in std_logic; -- 負論理リセット
Input : in std_logic;
Output : out std_logic
);
end entity;
architecture rtl of T17_FlipFlop is
begin
-- 同期リセット付きフリップフロップ
process(Clk) is
begin
if rising_edge(Clk) then
if nRst = '0' then
Output <= '0';
else
Output <= Input;
end if;
end if;
end process;
end architecture;
波形観察
ModelSimでシミュレーション実行しタイムラインをズームインすると、出力が立ち上がりクロックエッジのみで更新されることが明確にわかります:

分析
出力は立ち上がりクロックエッジでのみ変化します。2つの立ち上がりエッジ間で発生する入力遷移(例:約45nsから始まる負パルス)は取り込まれません。フリップフロップはエッジでのみサンプリングするためです。
以下は入力、クロック、出力の関係を視覚化したアニメーションです:

主な観察点:
- 20nsの1クロック周期入力パルスはクロックと同期しており、出力に遅延応答を生じさせます。
- シミュレーションではイベントがゼロタイムステップ(デルタサイクル)で発生。フリップフロップが同じデルタサイクルで入力を読み出力を更新するため、エッジ直前の入力値を取り込みます。
実践では、フリップフロップはクロックエッジの前後で入力が安定している短い期間、すなわちセットアップとホールドタイムを必要とします。これらの制約は、VHDLをネットリストに変換する際に合成ツールが自動的に処理します。
シミュレーションタイムステップの詳細についてはデルタサイクル解説を参照。
まとめ
- 同期リセット付きクロックドプロセスの感度リストにはクロックのみを含める。
if rising_edge(Clk)を使用すると、クロックの立ち上がりエッジで厳密に活性化されることを保証。- 同期設計では、すべての状態変化がアクティブクロックエッジで発生する。
知識をテストする準備はできましたか? Basic VHDL Quiz – part 3を受けるか、次のチュートリアルへ進む。
VHDL
- VHDLで文字列リストを作成する: ベスト・プラクティスと実装例
- Tcl駆動テストベンチでVHDLコード・ロック・モジュールを検証する
- VHDLテストベンチ・シミュレーションを優雅に終了させる方法
- VHDLでPWMコントローラを実装: 設計、シミュレーション、FPGAデモ
- VHDLで乱数生成: 一様分布からOSVVMまで
- ブロックRAMにおける堅牢なVHDLリングバッファFIFOの設計
- VHDLで自己検証テストベンチを構築する実践ガイド
- VHDLで保護型とアクセスポインタを用いた動的リンクリスト実装
- プロセス内プロシージャでVHDLステートマシンをクリーンに設計
- VHDLにおける不純関数の活用:FSMの可読性と保守性向上
- VHDL関数マスター:効率的な設計のための実践ガイド