連載
よろしいならばダイナミック点灯だ――FPGAでLEDをダイナミックにLチカさせる:MAX 10 FPGAで学ぶFPGA開発入門(5)(4/6 ページ)
単純なLチカならばFPGAでもそう難しくない。ただ、ダイナミック点灯やそれに伴うソースの最適化については“ならでは”のポイントが散見される。今回も連載で利用している「MAX 10 FPGA 評価キット」の読者プレゼントをご用意。
2桁のダイナミック点灯に挑戦
1桁がうまく行ったので、ではこれを2桁にしてみよう。
今度は0.1秒周期で0.0〜9.9秒まで順にカウントアップである。まず配線は図2の様に変更した。ダイナミック点灯を利用したので、今度はアノードコモンにあたる13・14番ピンは本体のJ5.3とJ5.4の2つに接続され、これを切り替える事でどちらの7セグメントが点灯するかが切り替わる。一方、各セグメントにつなぐ配線は2つの7セグメントで共通という形だ(Photo02)。
配線はそれでいいのだが、問題はプログラムの方である。以下のList 2はList 1をさらに力技で拡張したものである。基本は同じなのだが、
- 表示すべき数字(dec_cntr)が2桁(dec_cntr1, dec_cntr2)になり、これにあわせて処理も2倍に
- LEDの表示パターン(seg_cntr)も2つに(seg_cntr1, seg_cntr2)に。
- disp_cntrそのものは変わらないが、小ループが8回から16回に更新。これにあわせて、disp_cntrがseg_cntr1/seg_cntr2のどちらを反映するかで場合分けが必要になった結果、case文が長大に。
といった弊害が出ている。
他に変更点としてはリフレッシュ頻度が挙げられる。1桁だとダイナミック点灯は1ms間隔の更新で間に合ったが、2桁になるとさすがに間に合わない。そこで更新頻度は0.5msに高速化した。また、今度は10分の1秒単位での表示となるので、div_cntr2は1秒ごとに1回ではなく、0.1秒ごとに1回カウントアップしている。
MAX10 FPGAによるLEDのダイナミック点灯(2)
module top( //Clock from oscillator input Clock, //Arduino I/Os inout Arduino_IO4, inout Arduino_IO5, inout Arduino_IO6, inout Arduino_IO7, inout Arduino_IO8, inout Arduino_IO9, inout Arduino_IO10, inout Arduino_IO11, inout Arduino_IO12, inout Arduino_IO13 ); reg[14:0] div_cntr1; reg[7:0] div_cntr2; reg[3:0] dec_cntr1; reg[3:0] dec_cntr2; reg[4:0] pos_cntr; reg[6:0] seg_cntr1; reg[6:0] seg_cntr2; reg[7:0] disp_cntr; reg[1:0] dig_cntr; initial begin div_cntr1 = 0; div_cntr2 = 0; dec_cntr1 = 0; dec_cntr2 = 0; seg_cntr1 = 0; seg_cntr2 = 0; pos_cntr = 0; dig_cntr = 0; end always@(posedge Clock) begin div_cntr1 <= div_cntr1 + 1; if (div_cntr1 == 25000) begin div_cntr1 <= 0; div_cntr2 <= div_cntr2 + 1; if (div_cntr2 == 200) begin div_cntr2 <= 0; case (dec_cntr1) 0 : seg_cntr1 <= 7'b0000100; // 1111011 1 : seg_cntr1 <= 7'b1100111; // 0011000 2 : seg_cntr1 <= 7'b1001000; // 0110111 3 : seg_cntr1 <= 7'b1000001; // 0111110 4 : seg_cntr1 <= 7'b0100011; // 1011100 5 : seg_cntr1 <= 7'b0010001; // 1101110 6 : seg_cntr1 <= 7'b0010000; // 1101111 7 : seg_cntr1 <= 7'b1000111; // 0111000 8 : seg_cntr1 <= 7'b0000000; // 1111111 9 : seg_cntr1 <= 7'b0000001; // 1111110 default : seg_cntr1 <= 7'b1111111; // 0000000 endcase dec_cntr1 <= dec_cntr1 + 1; if (dec_cntr1 == 9) begin dec_cntr1 <= 0; dec_cntr2 <= dec_cntr2 + 1; case (dec_cntr2) 0 : seg_cntr2 <= 7'b0000100; // 1111011 1 : seg_cntr2 <= 7'b1100111; // 0011000 2 : seg_cntr2 <= 7'b1001000; // 0110111 3 : seg_cntr2 <= 7'b1000001; // 0111110 4 : seg_cntr2 <= 7'b0100011; // 1011100 5 : seg_cntr2 <= 7'b0010001; // 1101110 6 : seg_cntr2 <= 7'b0010000; // 1101111 7 : seg_cntr2 <= 7'b1000111; // 0111000 8 : seg_cntr2 <= 7'b0000000; // 1111111 9 : seg_cntr2 <= 7'b0000001; // 1111110 default : seg_cntr2 <= 7'b1111111; // 0000000 endcase if (dec_cntr2 == 9) begin dec_cntr2 <= 0; end end end else begin pos_cntr <= pos_cntr + 1; case (pos_cntr) 0 : begin dig_cntr <= 1; disp_cntr[7] <= 1; disp_cntr[6] <= seg_cntr1[6]; disp_cntr[5] <= 1; disp_cntr[4] <= 1; disp_cntr[3] <= 1; disp_cntr[2] <= 1; disp_cntr[1] <= 1; disp_cntr[0] <= 1; end 1 : begin dig_cntr <= 1; disp_cntr[7] <= 1; disp_cntr[6] <= 1; disp_cntr[5] <= seg_cntr1[5] ; disp_cntr[4] <= 1; disp_cntr[3] <= 1; disp_cntr[2] <= 1; disp_cntr[1] <= 1; disp_cntr[0] <= 1; end 2 : begin dig_cntr <= 1; disp_cntr[7] <= 1; disp_cntr[6] <= 1; disp_cntr[5] <= 1; disp_cntr[4] <= seg_cntr1[4] ; disp_cntr[3] <= 1; disp_cntr[2] <= 1; disp_cntr[1] <= 1; disp_cntr[0] <= 1; end 3 : begin dig_cntr <= 1; disp_cntr[7] <= 1; disp_cntr[6] <= 1; disp_cntr[5] <= 1; disp_cntr[4] <= 1; disp_cntr[3] <= seg_cntr1[3] ; disp_cntr[2] <= 1; disp_cntr[1] <= 1; disp_cntr[0] <= 1; end 4 : begin dig_cntr <= 1; disp_cntr[7] <= 1; disp_cntr[6] <= 1; disp_cntr[5] <= 1; disp_cntr[4] <= 1; disp_cntr[3] <= 1; disp_cntr[2] <= seg_cntr1[2] ; disp_cntr[1] <= 1; disp_cntr[0] <= 1; end 5 : begin dig_cntr <= 1; disp_cntr[7] <= 1; disp_cntr[6] <= 1; disp_cntr[5] <= 1; disp_cntr[4] <= 1; disp_cntr[3] <= 1; disp_cntr[2] <= 1; disp_cntr[1] <= seg_cntr1[1] ; disp_cntr[0] <= 1; end 6 : begin dig_cntr <= 1; disp_cntr[7] <= 1; disp_cntr[6] <= 1; disp_cntr[5] <= 1; disp_cntr[4] <= 1; disp_cntr[3] <= 1; disp_cntr[2] <= 1; disp_cntr[1] <= 1; disp_cntr[0] <= seg_cntr1[0] ; end 7 : begin dig_cntr <= 1; disp_cntr[7] <= dec_cntr1[0] ; disp_cntr[6] <= 1; disp_cntr[5] <= 1; disp_cntr[4] <= 1; disp_cntr[3] <= 1; disp_cntr[2] <= 1; disp_cntr[1] <= 1; disp_cntr[0] <= 1; end 8 : begin dig_cntr <= 2; disp_cntr[7] <= 1; disp_cntr[6] <= seg_cntr2[6]; disp_cntr[5] <= 1; disp_cntr[4] <= 1; disp_cntr[3] <= 1; disp_cntr[2] <= 1; disp_cntr[1] <= 1; disp_cntr[0] <= 1; end 9 : begin dig_cntr <= 2; disp_cntr[7] <= 1; disp_cntr[6] <= 1; disp_cntr[5] <= seg_cntr2[5] ; disp_cntr[4] <= 1; disp_cntr[3] <= 1; disp_cntr[2] <= 1; disp_cntr[1] <= 1; disp_cntr[0] <= 1; end 10 : begin dig_cntr <= 2; disp_cntr[7] <= 1; disp_cntr[6] <= 1; disp_cntr[5] <= 1; disp_cntr[4] <= seg_cntr2[4] ; disp_cntr[3] <= 1; disp_cntr[2] <= 1; disp_cntr[1] <= 1; disp_cntr[0] <= 1; end 11 : begin dig_cntr <= 2; disp_cntr[7] <= 1; disp_cntr[6] <= 1; disp_cntr[5] <= 1; disp_cntr[4] <= 1; disp_cntr[3] <= seg_cntr2[3] ; disp_cntr[2] <= 1; disp_cntr[1] <= 1; disp_cntr[0] <= 1; end 12 : begin dig_cntr <= 2; disp_cntr[7] <= 1; disp_cntr[6] <= 1; disp_cntr[5] <= 1; disp_cntr[4] <= 1; disp_cntr[3] <= 1; disp_cntr[2] <= seg_cntr2[2] ; disp_cntr[1] <= 1; disp_cntr[0] <= 1; end 13 : begin dig_cntr <= 2; disp_cntr[7] <= 1; disp_cntr[6] <= 1; disp_cntr[5] <= 1; disp_cntr[4] <= 1; disp_cntr[3] <= 1; disp_cntr[2] <= 1; disp_cntr[1] <= seg_cntr2[1] ; disp_cntr[0] <= 1; end 14 : begin dig_cntr <= 2; disp_cntr[7] <= 1; disp_cntr[6] <= 1; disp_cntr[5] <= 1; disp_cntr[4] <= 1; disp_cntr[3] <= 1; disp_cntr[2] <= 1; disp_cntr[1] <= 1; disp_cntr[0] <= seg_cntr2[0] ; end 15 : begin dig_cntr <= 2; disp_cntr[7] <= dec_cntr2[0] ; disp_cntr[6] <= 1; disp_cntr[5] <= 1; disp_cntr[4] <= 1; disp_cntr[3] <= 1; disp_cntr[2] <= 1; disp_cntr[1] <= 1; disp_cntr[0] <= 1; end default: begin dig_cntr <= 0; disp_cntr[7] <= 1; disp_cntr[6] <= 1; disp_cntr[5] <= 1; disp_cntr[4] <= 1; disp_cntr[3] <= 1; disp_cntr[2] <= 1; disp_cntr[1] <= 1; disp_cntr[0] <= 1; end endcase end end end assign Arduino_IO4 = dig_cntr[1] ; assign Arduino_IO5 = dig_cntr[0] ; assign Arduino_IO6 = disp_cntr[6] ; assign Arduino_IO7 = disp_cntr[5] ; assign Arduino_IO8 = disp_cntr[4] ; assign Arduino_IO9 = disp_cntr[7] ; assign Arduino_IO10 = disp_cntr[3] ; assign Arduino_IO11 = disp_cntr[2] ; assign Arduino_IO12 = disp_cntr[1] ; assign Arduino_IO13 = disp_cntr[0] ; endmodule
List2
Copyright © ITmedia, Inc. All Rights Reserved.