最後がassignで記述した部分である。便宜的に「出力割り当て宣言」と書いたが、実は必ずしも出力でなくても良い。assingは「配線の割り当て」を定義するもので、この例で言えばLED1/3/5にはdec_cntrの値をそのまま流し、LED2/4には値を反転して流す事を指定している。ここで注意されたいのは、assignの動作は「同時」であることだ。
assign LED1 = dec_cntr ; assign LED2 = !dec_cntr ; assign LED3 = dec_cntr ; assign LED4 = !dec_cntr; assign LED5 = dec_cntr ;
先のdiv_cntr2の部分であるが、以下のブロックでもしdiv_cntr2が762だった場合、(1)div_cntr2に0を代入する、(2)half_sec_pulseに1を代入するという順番で処理は進む。 ところがassignは処理ではなく接続なので、動き出すタイミングで既に配線が済んでおり、同時に行われる事になる。
if (div_cntr2 == 762) begin div_cntr2 <= 0; half_sec_pulse <= 1; end
これはブロック図で見た方が分かりやすいかもしれない。Photo01はこのプログラムのコンパイル後にブロックのマッピングを表示させたものだ。dec_cntrという緑のブロックは、要するにdec_cntrの値を保持する1bitのラッチであるが、その出力がLED1〜outputからLED5〜outputの5つのバッファに直接つながっている。ただしLED2とLED4には、論理反転を示す○がついているのがお分かりかと思う。なのでLED1〜5の出力は、dec_cntrのラッチの出力が変化した瞬間、同時に変化することがお分かり頂けるかと思う。
ということで、文章で書くと案外に長くなるが、ArduinoあるいはC/C++のプログラミング経験がある方なら、所々作法に違いがあるとはいえ、理解そのものはそう難しくないと思う。もちろん、これはVerilog HDLの文法の一部の話であって、C/C++系とは異なる概念なども少なくないのだが、この連載はそうした部分を網羅的にカバーするのが目的ではないので、この先も新しい概念なり何なりが出てきたらその都度説明する形で進めてゆく予定だ。
網羅的に知りたい、という方は検索エンジンで「Verilog HDL 文法」などと検索すれば日本語での解説を探すことができるし、Altera自身もサンプルを公開している(英語なので読み解くのが手間かもしれないが)。
最後に今回紹介した回路全体のマッピングを示したのがこちら(Photo02)である。ラッチの数がかなりあるのは仕方ないが、それよりも異様に長いのは二重ループの上にLED制御をちょっと面倒な形でやっている部分もあるためである。次回はこのあたりにちょっと手をいれてみたい。
Copyright © ITmedia, Inc. All Rights Reserved.