エッジ検出回路は、デジタルICおよびFPGA設計における基本かつ重要な構成要素であり、同期制御、イベント捕捉、状態遷移トリガなど、多様な用途で不可欠です。本稿では、HDLbits平台上の代表的な3つの課題(edgedetect、edgedetect2、dualedge)を軸に、エッジ検出の論理的根拠、合成可能な実装手法、および実務で直面する課題への対応策を体系的に解説します。
1. 単一エッジ検出の基礎構造
エッジ検出の本質は、信号の「変化」を1クロック周期のパルスとして抽出することです。これは、入力信号とその1サイクル遅延した値との論理演算によって実現されます。
1.1 立ち上がりエッジ検出(HDLbits: edgedetect)
8ビット入力に対して立ち上がりエッジを検出するモジュールは、以下のようになります:
module top_module (
input logic clk,
input logic [7:0] in,
output logic [7:0] pos_edge
);
logic [7:0] prev_in;
always_ff @(posedge clk) begin
prev_in <= in;
end
assign pos_edge = in & ~prev_in;
endmodule
この実装では、prev_inが前クロック周期の入力値を保持し、in & ~prev_inにより「現在が1で過去が0」である瞬間のみ出力がアサートされます。出力は1周期だけ有効なパルスとなり、他の同期ロジックへ安全に伝搬可能です。
1.2 その他の基本検出パターン
同一レジスタ構造を流用して、異なるエッジ条件に対応できます:
| 検出タイプ | 論理式 | 動作条件 |
|---|---|---|
| 立ち上がり(rising) | current & ~previous |
0 → 1 の遷移 |
| 立ち下がり(falling) | ~current & previous |
1 → 0 の遷移 |
| 任意変化(any change) | current ^ previous |
0↔1 のどちらかの遷移 |
2. 任意変化検出とタイミング特性
2.1 HDLbits: edgedetect2
入力信号の任意の値変化(立ち上がり・立ち下がり両方)を検出する場合、XOR演算が最も簡潔かつ効率的な選択です:
module top_module (
input logic clk,
input logic [7:0] in,
output logic [7:0] change_pulse
);
logic [7:0] delayed_in;
always_ff @(posedge clk) begin
delayed_in <= in;
end
assign change_pulse = in ^ delayed_in;
endmodule
この回路は、組み合わせ論理の遅延を除けば、最小限のフリップフロップとXORゲートで構成され、FPGA上で極めて低いLUT/FF消費で実装可能です。出力パルスの幅は、常に1クロック周期に固定されます。
3. ダブルエッジサンプリングの実現と制約
3.1 HDLbits: dualedge — 合成可能な代替手法
クロックの立ち上がり・立ち下がりの両方でデータをサンプルしたい場合、always @(posedge clk or negedge clk) は多くの合成ツールで非対応です。代わりに、2つの単一エッジFFを交互に駆動する構成が標準的です:
module top_module (
input logic clk,
input logic d,
output logic q
);
logic q_r, q_f;
// 立ち上がりエッジで更新されるFF
always_ff @(posedge clk) begin
q_r <= d ^ q_f;
end
// 立ち下がりエッジで更新されるFF
always_ff @(negedge clk) begin
q_f <= d ^ q_r;
end
assign q = q_r ^ q_f;
endmodule
この構成は、理論的には2相クロックによるデータラッチを模倣しており、内部状態がクロックの両エッジで更新されるため、「等価的に」ダブルエッジ動作を実現します。ただし、実際のハードウェアでは、立ち上がり・立ち下がりのタイミング差(duty cycle歪みやskew)に注意が必要です。
4. 実装上の注意点と検証戦略
実際の設計では、以下の点が信頼性に直結します:
- 非同期入力への対応:外部から入る信号は、必ず2段以上の同期化FFでメタステーブル性を抑制する
- パルス幅保証:高速ロジックで短すぎるパルスが検出漏れを引き起こすため、必要に応じてパルス伸長回路を追加
- テストカバレッジ:単一ビット変化だけでなく、複数ビット同時変化、連続変化(glitch-like)、ランダムシーケンスを含むテストベンチを構築
例えば、ランダムな入力パターンを生成し、期待出力と比較する検証コードの断片は以下の通りです:
initial begin
in = 8'h00;
repeat (50) begin
#10 in = $random;
@(posedge clk);
end
end