クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

クロックとカウンター回路

このレッスンのあとで: クロックの立ち上がりで数が変わるカウンターを記述できる。

55分のレッスンコマンド4件デジタル設計のラボ:Verilog、VHDL、yosys を 1 台の専用 Ubuntu VM で

クロックで数が増える回路

カウンターは、クロックが1回刻まれるたびに、数を1つ増やす回路です。時計も、信号機も、走行距離の表示も、クロックの刻みで状態が変わります。

クロックの立ち上がりの瞬間にだけ値が変わる、という決まりが、順序回路の核心です。

このレッスンのゴール

メモ

クロックの立ち上がりで数が変わるカウンターを記述できる。

重要な言葉

ことばいみ
クロック0と1を一定の間隔で繰り返す信号
立ち上がりエッジクロックが0から1に変わる瞬間
フリップフロップ立ち上がりで1ビットを覚える部品
同期リセット次の立ち上がりで、値を0に戻す仕組み
順序回路過去の値を覚えて、出力を決める回路

学生が入力するセルは、このプレビューでは空白です。

順序回路は前の値を覚える

これまでの回路は、入力が変われば、すぐ出力が変わりました。カウンターは違います。前の数を覚えていて、それに1を足します。

覚える部品がフリップフロップです。クロックが0から1に変わる立ち上がりエッジの瞬間に、1ビットを取り込みます。次の立ち上がりまで、値は変わりません。

4ビットのカウンター

コード: c
module counter(input clk, input rst, output reg [3:0] q);
  always @(posedge clk)
    if (rst) q <= 4'd0;
    else q <= q + 4'd1;
endmodule

always の行を読む

always @(posedge clk) は、clk の立ち上がりのたびに、下の文を実行するという意味です。q <= ... は、立ち上がりのあとに q を更新します。

4'd0 は、4ビットの10進数の0です。rst が1なら q は0に、そうでなければ1増えます。

同期リセットは次の刻みで効く

rst を1にしたら、q はすぐ0になるでしょうか。このカウンターでは、ならないはずです。リセットも、立ち上がりのときに調べられます。

下の Run は、ラボの counter.v に、刻みを1回ずつ与えます。刻みの前後で q を表示して、確かめましょう。

ラボのフォルダに入る

コマンド
cd ~/hdl

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

テストベンチを書く

コマンド
printf 'module edge_tb;\n  reg clk = 0, rst = 1;\n  wire [3:0] q;\n  counter dut(.clk(clk), .rst(rst), .q(q));\n  initial begin\n    #1 $display("start      q=%%0d", q);\n    #1 clk = 1;\n    #1 $display("edge 1     q=%%0d (rst was 1)", q);\n    rst = 0; #1 $display("rst=0      q=%%0d", q);\n    #1 clk = 0; #1 clk = 1;\n    #1 $display("edge 2     q=%%0d", q);\n    #1 clk = 0; #1 clk = 1;\n    #1 $display("edge 3     q=%%0d", q);\n    rst = 1; #1 $display("rst=1      q=%%0d", q);\n    #1 clk = 0; #1 clk = 1;\n    #1 $display("edge 4     q=%%0d", q);\n  end\nendmodule\n' > /tmp/edge_tb.v

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

回路とテストベンチを準備

コマンド
iverilog -o /tmp/edge counter.v /tmp/edge_tb.v

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

刻みごとの q を見る

コマンド
vvp /tmp/edge

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

4ビットは15の次に0へ戻る

4ビットで表せる最大の数は15です。15に1を足すと、5ビット目が必要になりますが、q は4ビットしかありません。そのため、0に戻ります。

下の表は、13から数えたときの q です。Python で同じ動きを確かめてみましょう。

13から数えたカウンター

刻みq(10進数)q(2進数)
1131101
2141110
3151111
400000
510001

学生が入力するセルは、このプレビューでは空白です。

Python で真似する

コード: python
# 4ビットのカウンターを、Python で真似します。
q = 13
for edge in range(5):
    print("刻み", edge + 1, "q =", q)
    # 15 の次は 16 ではなく 0 に戻ります。
    q = (q + 1) % 16
# q の最初の値を 0 に変えて、もう一度実行しましょう。

よくある間違い

注意

rst を1にした瞬間に、q が0になると思いがちです。同期リセットは、次の立ち上がりまで待ちます。それまで q は前の値のままです。先の Run でも、rst を1にしたとき、q は2のままでした。

さらに挑戦: 割り算のカウンター

課題が通ったら、LIMIT を6に変えて、0から5まで数えるカウンターにしましょう。時計の「分」の下の桁は、10で0に戻ります。

LIMIT を10にして、run(8, [[0,1],[0,1],[0,1]]) が何になるか、先に予想してから確かめましょう。

このラボとソースについて: デジタル設計のラボ:Verilog、VHDL、yosys を 1 台の専用 Ubuntu VM で

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。