検索
連載

よろしいならばダイナミック点灯だ――FPGAでLEDをダイナミックにLチカさせるMAX 10 FPGAで学ぶFPGA開発入門(5)(4/6 ページ)

単純なLチカならばFPGAでもそう難しくない。ただ、ダイナミック点灯やそれに伴うソースの最適化については“ならでは”のポイントが散見される。今回も連載で利用している「MAX 10 FPGA 評価キット」の読者プレゼントをご用意。

Share
Tweet
LINE
Hatena

2桁のダイナミック点灯に挑戦

 1桁がうまく行ったので、ではこれを2桁にしてみよう。

 今度は0.1秒周期で0.0〜9.9秒まで順にカウントアップである。まず配線は図2の様に変更した。ダイナミック点灯を利用したので、今度はアノードコモンにあたる13・14番ピンは本体のJ5.3とJ5.4の2つに接続され、これを切り替える事でどちらの7セグメントが点灯するかが切り替わる。一方、各セグメントにつなぐ配線は2つの7セグメントで共通という形だ(Photo02)。

2桁のダイナミック点灯を行う配線図 図2 2桁のダイナミック点灯を行う配線図
Photo02 配線はやや複雑化した。LEDの裏にも1本配線を通している Photo02 配線はやや複雑化した。LEDの裏にも1本配線を通している

 配線はそれでいいのだが、問題はプログラムの方である。以下の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.

ページトップに戻る