デジタル回路のカウンタ

デジタル回路のカウンタ

 カウンタとは、数を数える回路です。何を数えるのかは、回路によって違います。ベルトコンベアの上を流れる製品を数えたり、クロックの数を数えたり、キーボードを押した回数を数えたり。デジタル回路で数を数える回路というのは、頻繁に出てきます。

 カウンタ回路はいろいろな方式があります。ここでは、実践で数を数える事を学びますので、カウンタ回路の方式については述べません。カウンタとは何か、どのような場面で使うのかを学んでください。

 数を数える=カウンタ回路 は厳密にいえば2つの回路に分かれます。「数を数える回路」と「数を読む回路」です。デジタル回路は有限です。数学は無限なので、数を数えろ。といえば、0から始まって100でも1000でも永遠に数えることができますが、デジタル回路は有限なので、指定されたビット数までしか数えられません。

 ビットとカウンタの関係および数を読む回路の関係を理解する必要がありますので、カウンタの理解と設計の手順を学んでください。

ビット数の決定

 カウンタのビット数は、「いくつ数えるか」で決まります。実は、意外にいくつ数えるのか。というのは難しい問題です。本ブログではすべて同期設計を前提にしていますが、同期設計の基本である、クロックと「いくつ数えるか」というのには、関係があります。

 仕様書で「何個数える」と明記してある場合は、悩む必要はありません。その数分をカウンタで数えれば良いです。仕様書に100個と書いてあれば、0~99までの100個を数えるようなカウンタを設計すれば良い事になります。この場合、最大は99(10進:dec)になりますので、これを2進数(バイナリ)に変換すると、1010(bin)になります。つまり、0~99(dec) = “0000”~”1010″(bin)までを数えますので、4bitになります。必要なカウンタは4ビットです。

 難しいのは、時間などクロックに関係する場合です。100msecを測りなさい。つまり、100msec数えなさい。とか、100msec毎に何かをしなさい。などの場合には、クロックを基準に100msecを数える必要があります。クロックが10MHzであるなら、100msecを測るには・・・

 10MHz = 1usec なので、100msec / 1usec = 100000(dec)になります。これを16進数にすると、186a0(hex)です。186a0(hex)を数えるには、17ビット必要になります。

 最近のFPGAであれば10MHzで17ビットを数ええる事は問題ありません。しかし、これが100MHzや200MHzというようにクロック周波数があがれば、100msecを測るためのカウンタに必要なビット数は大きくなります。クロック周波数が高くなって、カウンタのビット数が大きくなる場合には、コンパイルレポートをよく読んで、カウンタが設計通りに動作するのかを確認する必要があります。

数とビット

 初心者がカウンタで躓くのは、数とビットの関係が結びつかないからです。2進数は高校生で習いますので、それ自体は理解しているはずですが、2進数とビットが結びつかない事が多いようです。

 10進数の”10″は2進数で”1010″というのは高校生の数学で習います。一番右側が2^0の位。その左が2^1の位。そして、2^2の位。一番左が2^3の位です。ここまでが高校生の数学です。下図のようになっています。

 いきなり10進数の”10″を2進数にしましたが、10進数で”0”から数えるように2進数で0から数えてみると、
“0”,”1″,”10″,”11″,”100″,”101″,”110″,”111″,”1000″,”1001″,”1010″
のように数えられると思います。この2進数の動きをクロックに合わせた同期カウンタで表すと次のようになります。

 赤文字でビットを’0’と’1’に記載しました。rcount(0)が2^0の位。rcount(1)が2^1の位。rcount(2)が2^2の位。rcount(3)が2^3の位になるように並べてあります。これがカウンタの動作です。一番左から、”0000″,”0001″,”0010″~”1010″という動きになっているのがわかると思います。

 このように2進数で”1010″を数える。というのは、4ビットを2^0の位から一つずつカウントアップしているという事が理解できたでしょうか。2進数にさえ変換できれば、どんな数でも数える事ができます。

 そして、VHDLやVerilogなどのハードウェア言語では、2^0や2^1といったべき乗表現ではなく、上図のように、位を()内の添え字で表します。上図の場合には、rcountという名前で添え字が(0)~(3)までの4ビット存在することになります。

 さらに、上図の一番下に記載したように、rcountのように添え字を省略した場合には4ビットをまとめて記述するルールになっています。

有限のカウンタ

 デジタル回路は有限の数しか数えられません。どこまで数えるのかはビット数で決まります。予め”1010″(bin)まで数える。とわかっていれば、”1010″(bin)まで数えて、カウンタを止めるなり、リセットするなりすれば良いですが、4ビットのカウンタをフリーに動かすとどのようになるでしょうか。

 上の図のように”0000″から”1111″まで数えると、”0000″に戻ります。これをいつまでも繰り返します。

 このように、カウンタはビット数で数える数が決まる。ビット数を溢れたカウンタは”0”に戻る。という動作をします。したがって、通常カウンタを使う場合には、定められた数までを数える。という動作か、途中で停止する。などの動作を伴います。よって、カウンタを読む必要がでてきます。

カウンタを読む

 カウンタを読む。というのは、カウンタのビットをまとめて2進数として扱う。という事になります。先ほど出てきた図のようにrcountというカウンタの各ビットをまとめて2進数として扱えば良いだけです。

 たとえば、rcount = “1010” といった具合です。基本は2進数で読みますが、16進数で読むこともできます。

 例題として、”1010″まで数えたら、”0″に戻るカウンタを設計してみます。

process (clock,nreset) begin
	if nreset = '0' then
		rcount <= (others => '0');
	elsif clock' event and clock = '1' then
		if (rcount = "1010") then
			rcount <= (others => '0');
		else
			rcount <= rcount + '1';
		end if;
	end if;
end process;

 カウンタを設計する際に、カウンタの初期値を入れるようにします。不定から始まるカウンタはどのように動作するのか、予測が付きません。必ず、初期値を与えて、そこから始まるカウンタにします。上のソースコードの場合、リセット信号で初期値を”0000″にしています。

 ソースコード5行目でカウンタが”1010″になった時にカウンタをリセットしています。このようにする事で、常に”0000″~”1010″までを数えるカウンタになります。

 このようにカウンタをある数でリセットする。ある数でカウンタを停止する。というような使い方が多くなります。いずれにしても、カウンタの基本形は上のソースコードのようになります。