Verilog カウンタ回路と分周回路

こんにちはkeymaleです。
前回はQuartusの使い方について書いていきました。
今回はverilogでのカウンタ回路と分周回路について説明していきます。カウンタ回路にはif文が含まれており、そちらについてはこちらで説明しています。

とりあえず以下にカウンタ回路兼分周回路のソースコードを記しておきます。

最初なんで、逐一説明していきます。
verilogは基本的にmodule endmoduleの間に回路を記述していきます。
この間に書いた回路が一つのブロックだと思ってください。
最初の構成要素から見ていきましょう。

まずmoduleの右にcounterと書いてあります。ここにはmodule名を記載してください。ここに記載した名前と基本的に同じファイル名で保存してください。ここではcounterとしました。
counterの後に();で囲まれた箇所にinputやらoutputやら書いてあります。ここにはmoduleの入出力ピンを記載してください。input は入力、outputは出力です。そして、inputとoutputのそれぞれの右にピン名を記載してください。今回は入力にclkとreset、出力にoutを用意しました。
outputとピン名のoutの間にregという文字を書いてあるのがわかるかと思います。verilogでは、すべてのネット名はregかwireに分類されます(System verilogではlogicなどほかの分類がありますが、それは後日書いていきます)。wireは組み合わせ回路、regは順序回路で使います。よくわからない方は、後述する
・assignで代入できるのはwire
・alwaysで代入できるのがreg
と覚えていてください。次に

上記要素について説明します。入出力以外のネットはここに記載してください。この回路では
と記載しています。これはカウンタ回路のカウント部分を収納するレジスタと思ってください。
reg、wireともに言えることですが、ビット列で記述することができます。
reg[ビット数]ネット名
となります。wireでもreg部分をwireに変えるだけで同様のルールです。今回はビット数のところに7:0と書いてあります。これは[0]、[1]、[2]、[3]、[4]、[5]、[6]、[7]の8ビットを示しています。0から始まるため、7ビットではない点に注意してください。
次にinitial begin ~ endの部分ですが、ここは最初に一回だけ行う動作を記述します。ここではcntとoutに0を代入しています。cntには0ではなく、8’d0と記述しているのがわかります。verilogではここで0と書いても実は問題ないのですが、あえて説明のために書いています。これは8ビットのdecimal(10進数)で0という意味です。他の記述方法では8’b00000000(2進数のbinary)や8’o0(8進数のoctal)や8’f0(16進数のhexadecimal)などがあります。どちらにせよ0を代入しています。

最後の要素ですが、まずalways@(posedge clk)begin~endから見ていきます。これの意味はclkの立ち上がりエッジにごとにalways~endまでの動作を毎回行うということです。verilogではこのalways分を多用して同期回路を作っていきます。posedgeとなっていますが、negedgeとすれば立下りエッジとなります。
次にif(reset)begin~endの部分ですが、ここはif分となります。if()の中にresetが入っているので、resetがHIGHつまり1の時に実行する内容になります。
次にend else begin~endですが、これは先ほどのif分が成立しなかったときに実行する内容になります。ここではcnt <= cnt + 8’d1;と記述し、resetが0の時に、clkの立ち上がりごとに1づつcntが増えていく記述となります。今回は5回カウントしたら0になるものとして、if(cnt == 8’d4)beginと記述します。ここでも0もカウントに入るので、5回カウントは4と記述する点に注意してください。5回カウント後にcnt <= 0;とすることで、5回カウントが永遠にループします。またこの時にout <= ~out;と記述することでoutの出力が反転するため、分周回路となります。
ここで代入の際に<=という記号を使っていますが、これはノンブロッキング代入といいます。代入の際に=だけの記述をブロッキング代入といいます。それぞれ

・ノンブロッキング代入は一斉に代入する(<=)
・ブロッキング代入は逐次的に代入する(=)

と覚えておいてください。わからなければ、assignは=、alwaysは<=で代入としておけば、ミスが少ないでしょう。

以上でカウンタ回路と分周回路の説明を終わりにします。しかし、この分周回路は少し欠点があり、1回カウントで2分周、2回カウントで4分周、3回カウントで6分周、4回カウントで8分周、5回カウントで10分周となっており、奇数分周ができません。次回は奇数分周の方法modelsimの使い方を説明していこうと思います。

最後まで読んでいただきありがとうございました。