順序回路の書き方基礎
概要: 順序回路の基本単位であるD-FFとラッチの記述を学び、2種類の代入文と同期/非同期リセットを理解する。
目標:
- D-FF、ラッチの回路記述ができる
- 順序回路用の真理値表を理解できる
- ブロッキング代入とノンブロッキング代入について理解し記述できる
- 非同期リセットと同期リセットについて理解し記述できる
- 非同期リセットを使用するメリットを理解できる
- D-FF、ラッチを記述する際の注意点を理解できる
修了判定: D-FFの記述の空欄を埋めて完成させる
1. DフリップフロップのPosedge記述
いよいよ「順序回路」の登場だよ!クロックに合わせて動く、記憶を持った回路だね🐾
C言語などのソフト開発にはない「ハードウェア特有の動き」だから、じっくり理解していこう!
DフリップフロップはクロックCKの立ち上がりで入力Dの値を出力Qに転送します。CKの立ち上がり以外の期間はalways文が実行されないため、Qの値は保持されます。
module DFF ( CK, D, Q );
input CK, D;
output Q;
reg Q;
always @( posedge CK ) begin
Q <= D;
end
endmodule
| タイミング | 動作 |
|---|---|
| CKの立ち上がり(posedge) | 入力DをQに転送 |
| それ以外の期間 | Qの値を保持 |
2. DフリップフロップのNegedge記述
クロックの立ち下がりで転送するD-FFは、イベント式にnegedge CKと記述します。回路図ではCKの入力に○(反転記号)を付けます。
module DFF ( CK, D, Q );
input CK, D;
output Q;
reg Q;
always @( negedge CK ) begin
Q <= D;
end
endmodule
| 記述 | 転送タイミング |
|---|---|
posedge CK | CKの立ち上がり |
negedge CK | CKの立ち下がり |
3. ラッチの記述
ラッチは入力Gの値が1の期間に入力Dの値を出力Qに転送します。D-FFと異なりクロックエッジではなくレベルで動作します。
module LATCH ( G, D, Q );
input G, D;
output Q;
reg Q;
always @( G or D ) begin
if( G==1'b1 )
Q <= D;
end
endmodule
- センシティビティリストは
G or D(GまたはDが変化したときに実行) - G==1'b1 のとき:DがQに転送される
- G==1'b0 のとき:if文が実行されないのでQは保持
- if条件を
G==1'b0にすると「Gが0のときに転送」するラッチになる
4. ブロッキング代入とノンブロッキング代入
「=」と「<=」の違いは、Verilogで一番つまづきやすいポイントなんだ🐾
順序回路を書くときは『絶対に <= (ノンブロッキング代入)を使う!』ってルールを叩き込んでね!
always文内でのレジスタ信号への代入には2種類あります。
| 代入方式 | 記号 | 動作 |
|---|---|---|
| ブロッキング代入 | = | 1行ずつ順番に実行。前の代入が終わってから次の行へ |
| ノンブロッキング代入 | <= | CKエッジ時点の右辺の値を全て同時に左辺へ代入 |
ブロッキング代入
wire DIN;
reg A, B, C;
always @( posedge CK )
begin
A = DIN; // まずAにDINを代入
B = A; // 次にBにA(=DINの値)を代入
C = B; // 次にCにB(=DINの値)を代入
end
// 結果: A=B=C=DIN(同じ値になる)
ノンブロッキング代入
wire DIN;
reg A, B, C;
always @( posedge CK )
begin
A <= DIN; // CKエッジ時のDINをAへ
B <= A; // CKエッジ時の(旧)AをBへ
C <= B; // CKエッジ時の(旧)BをCへ
end
// 結果: A=DIN, B=旧A, C=旧B(シフトレジスタ動作)
ブロッキング代入で逆順(C=B; B=A; A=DIN;)に書けばノンブロッキング代入と同じ回路になりますが、それはむしろミスにつながるため、順序回路には常にノンブロッキング代入(<=)を使用してください。
- ブロッキング代入(= で順順): DINから全FFs(A,B,C)が同じCKエッジ後に同一値になる(並列構造)
- ノンブロッキング代入(<=): DIN→A→B→Cと1クロックずつずれて転送される(シフトレジスタ構造)
5. 非同期リセットと同期リセット
フリップフロップをリセットする方法には非同期リセットと同期リセットの2種類があります。
順序回路用の真理値表の読み方
| 記号 | 意味 |
|---|---|
| x | DON'T CARE(1でも0でも構わない) |
| ↑ | クロックの立ち上がり |
| ↓ | クロックの立ち下がり |
非同期リセット付きDFF(DFF_ASYNC)
| RB | D | CK | Q |
|---|---|---|---|
| 0 | x | x | 0(RBが0ならCKに関係なくリセット) |
| 1 | 1 | ↑ | 1 |
| 1 | 0 | ↑ | 0 |
module DFF_ASYNC ( CK, D, Q, RB );
input CK, D, RB;
output Q;
reg Q;
always @( posedge CK or negedge RB )
begin
if ( RB==1'b0 )
Q <= 1'b0;
else
Q <= D;
end
endmodule
同期リセット付きDFF(DFF_SYNC)
| RB | D | CK | Q |
|---|---|---|---|
| 0 | x | ↑ | 0(CK立ち上がりかつRB=0のときリセット) |
| 1 | 1 | ↑ | 1 |
| 1 | 0 | ↑ | 0 |
module DFF_SYNC ( CK, D, Q, RB );
input CK, D, RB;
output Q;
reg Q;
always @( posedge CK )
begin
if ( RB==1'b0 )
Q <= 1'b0;
else
Q <= D;
end
endmodule
@(posedge CK or negedge RB))にリセット条件(negedge RB)を記述すれば非同期リセット、記述しなければ同期リセットになります。
6. 非同期リセットのメリット・デメリット
ASIC設計ではフリップフロップやカウンタ等の初期化に非同期リセットを多く用います。
✅ メリット
- 回路の初期化にクロックが不要
- チップ上のフリップフロップ全体の初期化が簡単
- SYSRESB信号を0にするだけでリセット可能 → シミュレーションの初期設定パターンが短くて済む
⚠️ デメリット
- 非同期リセット付きFFは通常のFFより回路規模が大きい
- チップ全体にリセット信号を引き回す必要があるため、レイアウトが難しくなる
7. 記述上の注意点(ワンポイント・アドバイス)
以下の記述は論理合成ツールでエラーになります(文法エラーではないためRTLシミュレーションは通る):
// ❌ NG例1: 複数のクロックを定義
always begin
@( posedge CK1 )
Q <= D;
@( posedge CK2 )
Q <= 1'b1;
end
// ❌ NG例2: 同一クロックで立ち上がりと立ち下がりの両方
always begin
@( posedge CK )
Q <= D;
@( negedge CK )
Q <= 1'b1;
end
実際の回路では電源投入直後の出力状態(0 or 1)は不定です。initial文は論理合成ツールでエラーになります。
// ❌ NG例: initial文は論理合成できない
initial
Q <= 1'b0;
always @( posedge CK ) begin
Q <= D;
end
| 注意点 | RTLシミュレーション | 論理合成 |
|---|---|---|
| 複数クロック定義 | 正常終了 | ⛔ エラー |
| 両エッジ定義 | 正常終了 | ⛔ エラー |
| initial文による初期値 | 正常終了 | ⛔ エラー |
8. 修了判定
設問: 真理値表を参考にして、非同期リセット付きのD-FFを記述する。
立ち下がりクロックで転送され、R が1のとき出力Qは0にリセットされる。
| R | D | CK | Q |
|---|---|---|---|
| 1 | x | x | 0(Rが1ならCKに関係なくリセット) |
| 0 | 1 | ↓ | 1 |
| 0 | 0 | ↓ | 0 |
▶ 解答を見る
module DFF_ASYNC ( CK, D, Q, R );
input CK, D, R;
output Q;
reg Q;
always @( negedge CK or posedge R )
begin
if ( R==1'b1 )
Q <= 1'b0;
else
Q <= D;
end
endmodule
- 立ち下がりクロックなので
negedge CK - 非同期リセットなので
posedge Rもイベント式に追加 - R==1'b1 のときリセット(アクティブHigh)
📝 C4 まとめ: 順序回路の基礎
| 項目 | 記述方法 | ポイント |
|---|---|---|
| D-FF(立ち上がり) | always @(posedge CK) | 最も一般的なFF |
| D-FF(立ち下がり) | always @(negedge CK) | CK入力に○マーク |
| ラッチ | always @(G or D) if(G) Q<=D; | Gが1の期間転送 |
| ノンブロッキング代入 | <= | 順序回路では必須 |
| 非同期リセット | イベント式に negedge RB を追加 | ASIC設計で多用 |
| 同期リセット | イベント式にリセット条件を書かない | CK立ち上がりのみリセット |
