Menu

Verilog クロック同期ロジック:flip-flop、register、パイプライン

クロック同期alwaysブロックからregister、カウンタ、shift register、パイプラインを構築する方法。すべての同期デジタル設計の主役パターン。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

構成要素:D flip-flop

同期設計のすべてが1つの小さなハードウェア、D flip-flopに戻ります。クロック入力、データ入力、データ出力を持ちます。各クロック立ち上がりエッジでDの値を捕捉し、次のエッジまで保持します。それだけです。

Verilogでは:

always @(posedge clk) begin
    q <= d;
end

3行、1つのflip-flop。<=は非blockingで、これがまさに実際のflip-flopの振る舞いです(Blocking vs Non-blockingで扱いました)。posedge clk感応性が順序を作ります。

組み合わせロジックを挟んで多数を積み重ねれば、構築したい任意の同期回路ができます。

reset付きregister

実際の設計には常にresetが必要です。電源投入時や要求時にシステムを既知のstateにする方法:

これは 同期reset です。reset条件が他の入力と同様にクロックエッジで評価されます。合成ツールはデータ入力に2-to-1 muxを持つflip-flopを生成します。resetが高のときmuxはゼロを、そうでないときはdを供給します。

ほとんどの設計では、同期resetが正しい選択です。タイミングがシンプルで、FPGAとうまく付き合い、reset signalはどこから来ても構いません - 専用のクロック整列ソースは不要です。

イネーブル付きregister

時に、何かが指示したときだけ更新するregisterが欲しくなります。クロック同期ブロック ifを使い、欠落したelseの暗黙の「前の値を保持」動作に頼ります:

これが定番の「ロードイネーブル付きregister」です。あちこちに登場します。設定register、下流が準備できたときだけ進むパイプラインステージ、一時停止と再開するカウンタ。最後のelseの省略はクロック同期ブロック内では意図的かつ安全です。flip-flopはすでに前の値を覚えているので、「何もしない」は「保持」を意味します。

組み合わせブロックで同じコードはラッチを推論します。異なるルール、同じ構文。

カウンタ

カウンタは、次の値が現在値プラス1のregisterです:

カウンタはenableが高のときすべてのクロックサイクルでインクリメントします。16サイクル後、0にラップして戻ります(4ビットと宣言し、15 + 10にオーバーフローするから)。そのラッピングはNビット算術に内在し、実ハードウェアカウンタの振る舞いそのものです。

Shift Register

flip-flopを積み重ねるとshift registerになります。コツは、すべてのシフトを1つの非blocking文で行うことです:

本体はout <= {out[WIDTH-2:0], in} - 現在のoutの下位ビットと新しいinを連結し、全体を代入します。非blockingなので、右辺は左辺が更新する前に 古い outを読みます。効果は1クロックサイクルでのきれいなNビットシフトです。

これはshift registerパターンの最小形です。LFSR、シリアル送信器、デシリアライザ、データがクロックごとにflip-flopチェーンを通って動くあらゆる設計に一般化します。

パイプライン

パイプラインは、組み合わせロジックで分離されたregisterのチェーンです。各ステージは前のステージのデータを処理し、次のステージに供給します:

3ステージ、3サイクルのレイテンシ、しかしパイプラインが満ちれば1サイクルごとに新しい結果。データは3つのflip-flopを通るのでレイテンシは3クロック、3ステージすべてが異なる入力で同時に動くのでスループットは1演算/クロックです。

これが高性能設計がスループット目標を達成する方法です。ステージを短く保ち、より深くパイプライン化し、並列処理に仕事をさせます。

非同期reset(必要なときに)

resetをアサートするのにクロックエッジを待てない場合があります。チップが電源オフされている、クロックがゲートされている、外部ウォッチドッグが線を引っ張っている。その場合:

always @(posedge clk or negedge reset_n) begin
    if (~reset_n) q <= 0;
    else          q <= d;
end

感応リストにクロックエッジ resetエッジの両方があります。flip-flopはどちらにも即座に反応します。reset_nは慣例によりactive-low(低のときアサート)なので、テストが~reset_nです。

非同期resetにはトレードオフがあります。タイミング解析が難しく、解除時に注意深く扱わないとメタステーブルが起こり、すべてのFPGAアーキテクチャでポータブルではありません。デフォルトで同期resetを使い、設計が要求するときだけasyncを使ってください。

次に読むもの

これで任意の同期データパスを構築できます。次のドキュメント有限状態機械は、クロック同期registerとcase文を組み合わせて標準FSM慣用句を生成します。すべてのコントローラ、プロトコルエンジン、デジタル設計の意思決定ブロックの主役です。

よくある質問

Verilogのクロック同期ロジックとは?

更新がクロックsignalでゲートされるロジック。標準慣用句はalways @(posedge clk) target <= next_value;で、clkの各立ち上がりエッジでtargetnext_valueを捕捉します。その1行がハードウェアのflip-flopを記述します。組み合わせロジックを挟んで多数を積み重ねれば、カウンタ、shift register、パイプライン、つまりあらゆる同期設計を構築できます。

Verilogの同期resetと非同期resetの違いは?

同期resetはalways @(posedge clk) if (reset) ...を使い、resetは他の入力と同様クロックエッジでサンプルされます。非同期resetはalways @(posedge clk or negedge reset_n) if (~reset_n) ...を使い、ブロックはクロックエッジまたはresetアサートのどちらかで起動するので、resetが即座に効きます。同期がデフォルトの選択で、非同期はクロックが死んでいてもresetが効くことが保証されなければならないときに使います。

Verilogでパイプラインを構築するには?

always @(posedge clk) stageN_reg <= stageN_combinational;の複数ステージを積み重ねます。各ステージの組み合わせロジックが次のステージのregisterに供給され、すべてのregisterが同じクロックエッジで捕捉します。結果は、毎サイクル新しいデータが入り、Nサイクル後に出てくるパイプラインで、クロックごとに1結果のスループットです。

Verilogのshift registerとは?

各flip-flopの出力が次のflip-flopの入力に供給されるflip-flopのチェーンです。各クロックエッジですべてのビットが1位置シフトします。Verilogの定番版は非blocking代入を使います:out <= {out[N-2:0], in};。その1行で、inから毎サイクル1ビットを取るNビットshift registerを作ります。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める