Verilogで順序回路を書く
(1)ここで学ぶ内容
ここでは、順序回路(クロックに同期して動く回路)の書き方を学ぶよ🐾
C言語などのソフト開発にはない「always文」が登場するから、しっかり理解していこう!
概要
目標
修了判定
- バイナリカウンタの記述を例に、簡単な順序回路の記述について学ぶ
- always 文や if 文の基本を理解する
目標
以下の項目を理解し説明できる
- reg 宣言
- always 文の記述
- if 文による条件分岐
- reg 信号への代入
- 定数の表現
修了判定
信号名を指定して、8ビットのダウンカウンタを記述する
条件:減算演算子を用いる
(2)バイナリカウンタの動作
4ビット・バイナリカウンタ
graph LR
subgraph 4ビット・バイナリカウンタ
CNT[counter
► ck] end RES[res] --> CNT CK[ck] --> CNT CNT -->|4| Q[q
4bit] style CNT fill:#e8f5e9,stroke:#388e3c,stroke-width:2px;
► ck] end RES[res] --> CNT CK[ck] --> CNT CNT -->|4| Q[q
4bit] style CNT fill:#e8f5e9,stroke:#388e3c,stroke-width:2px;
| q[3] | q[2] | q[1] | q[0] |
|---|---|---|---|
| 0 | 0 | 1 | 0 |
ck ┐ ┌┐ ┌┐ │┌┐ ┌┐ ┌┐ ┌┐ └──┘└──┘└──┼┘└──┘└──┘└──┘└ │ res ┌──┐ │ └──┘ │ │ q | 0 | 1 │ 2 | 3 | 4 | 5 │ q[0] ██┐ ┌────┤ ┌────┐ ┌ └─────┘ └────┘ └────┘ │ q[1] ██┐ │┌────┐ ┌ └──────────┼┘ └────────┘ │ q[2] ██┐ │ ┌──── └──────────┴──────────┘ │ q[3] ██┐ │ └──────────┴─────────────── │
※赤色ブロック(██)はリセット前の不定(Undefined)状態を示します。
※赤い縦線は q=2 (0 0 1 0) の瞬間を示しています。
(3)バイナリカウンタの記述
4ビット・バイナリカウンタ
graph LR
subgraph 4ビット・バイナリカウンタ
CNT[counter
► ck] end RES[res] --> CNT CK[ck] --> CNT CNT -->|4| Q[q
4bit] style CNT fill:#e8f5e9,stroke:#388e3c,stroke-width:2px;
► ck] end RES[res] --> CNT CK[ck] --> CNT CNT -->|4| Q[q
4bit] style CNT fill:#e8f5e9,stroke:#388e3c,stroke-width:2px;
加算演算子による4ビットカウンタ(非同期リセット)
module counter( ck, res, q );
input ck, res;
output [3:0] q;
reg [3:0] q;
always @( posedge ck or posedge res )
begin
if ( res==1'b1 )
q <= 4'h0;
else
q <= q + 4'h1;
end
endmodule
(4)ワンポイント・アドバイス
ここは超重要!『regとalways文はペア』『代入記号は <= (ノンブロッキング代入) を使う』🐾
これらはVerilogのルールの中でも特にバグを生みやすいポイントだから、しっかり覚えておいてね!
- 順序回路の記述には always 文を使う。
- 「regとalways文はペア」と覚えておこう。
regへの代入は、always文の中で行う。
wireへの代入は、always文の中では文法エラー。
- regへの代入記号は "<=" を使おう。
"=" も文法上使えるが、不具合の原因にもなる。(詳細はO2ユニット参照)
ただし、シミュレーション記述(テストベンチ)の時は、逆に "=" の方がよい。
回路記述
reg Q;
always @( posedge CK ) begin
Q <= D;
end
シミュレーション記述(テストベンチ)
initial begin
reset = 0;
#STEP reset = 1;
#STEP reset = 0;
end
📝 (補足)修了判定について
元の教材の(1)で言及されていた「修了判定」の設問は、E2ユニット用の画像(img_04相当)としては用意されていませんでしたが、内容は以下の通りです。
設問
信号名を指定して、8ビットのダウンカウンタを記述する。
条件:減算演算子を用いる。
module down_counter( ck, res, q ); input ck, res; output [7:0] q; reg [7:0] q; always @( posedge ck or posedge res ) begin if ( res==1'b1 ) q <= 8'h00; else q <= q - 8'h01; end endmodule
🌸
たいへん
よく
できました
よく
できました
