検索
連載

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

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

Share
Tweet
LINE
Hatena

長大なリストをスマートにする

 で、動く動かないでいえばこれできちんと動いたのだが、もう少しスマートに記述したいところ。そこでList 2をFunction文と条件演算子を使ってもう少し短くに書き換えたのがList 3となる。

 最初のSeg_DisplayというFunctionは、pos_cntrにあわせてseg_cntr1/seg_cntr2のどのセグメントを点灯するかを割り当てるもので、Functionの戻り値でこれを反映することになる。ちなみにここでは条件演算子を使うことで、長大なcase文からは逃れられるようになった。

 2つ目のMap_DisplayというFunctionは、表示したい数字にあわせて実際のLEDの点灯パターンを返すものだ。1桁だとわざわざFunctionにする必要はないのだが、複数桁ある場合は桁の数回分だけこれを繰り返す事になるので、ここをFunctionでまとめた形だ。

 
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[3:0] pos_cntr;
    reg[7:0] seg_cntr1;
    reg[7:0] seg_cntr2;
    reg[9:0] disp_cntr;
    reg[1:0] dig_cntr;
 
function [9:0] Seg_Display(
    input [3:0] pos_cnrt,
    input    [7:0] seg_cntr1,
    input [7:0] seg_cntr2
);
    begin
	if (pos_cntr[3] == 1'b1) begin
	    Seg_Display[9] = 1'b1;
	    Seg_Display[8] = 1'b0;
	    Seg_Display[7] = (pos_cntr == 8)?seg_cntr2[7] : 1'b1;
	    Seg_Display[6] = (pos_cntr == 9)?seg_cntr2[6] : 1'b1;
	    Seg_Display[5] = (pos_cntr == 10)?seg_cntr2[5] : 1'b1;
	    Seg_Display[4] = (pos_cntr == 11)?seg_cntr2[4] : 1'b1;
	    Seg_Display[3] = (pos_cntr == 12)?seg_cntr2[3] : 1'b1;
	    Seg_Display[2] = (pos_cntr == 13)?seg_cntr2[2] : 1'b1;
	    Seg_Display[1] = (pos_cntr == 14)?seg_cntr2[1] : 1'b1;
	    Seg_Display[0] = (pos_cntr == 15)?seg_cntr2[0] : 1'b1;
	    end
	else begin
	    Seg_Display[9] = 1'b0;
	    Seg_Display[8] = 1'b1;
	    Seg_Display[7] = (pos_cntr == 0)?seg_cntr1[7] : 1'b1;
	    Seg_Display[6] = (pos_cntr == 1)?seg_cntr1[6] : 1'b1;
	    Seg_Display[5] = (pos_cntr == 2)?seg_cntr1[5] : 1'b1;
	    Seg_Display[4] = (pos_cntr == 3)?seg_cntr1[4] : 1'b1;
	    Seg_Display[3] = (pos_cntr == 4)?seg_cntr1[3] : 1'b1;
	    Seg_Display[2] = (pos_cntr == 5)?seg_cntr1[2] : 1'b1;
	    Seg_Display[1] = (pos_cntr == 6)?seg_cntr1[1] : 1'b1;
	    Seg_Display[0] = (pos_cntr == 7)?seg_cntr1[0] : 1'b1;
	    end
	end
endfunction
function [7:0] Map_Display(
    input [3:0] dec_cntr
);
    begin
	case (dec_cntr)
		0 : Map_Display = 8'b00000100; // 1111011
		1 : Map_Display = 8'b11100111; // 0011000
		2 : Map_Display = 8'b01001000; // 0110111
		3 : Map_Display = 8'b11000001; // 0111110
		4 : Map_Display = 8'b00100011; // 1011100
		5 : Map_Display = 8'b10010001; // 1101110
		6 : Map_Display = 8'b00010000; // 1101111
		7 : Map_Display = 8'b11000111; // 0111000
		8 : Map_Display = 8'b00000000; // 1111111
		9 : Map_Display = 8'b10000001; // 1111110
		default : Map_Display = 8'b11111111; // 0000000
	endcase
    end
endfunction
 
    
    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;
		seg_cntr1 = Map_Display(dec_cntr1);
		    dec_cntr1 <= dec_cntr1 + 1;
		    if (dec_cntr1 == 9) begin
			dec_cntr1 <= 0;
			dec_cntr2 <= dec_cntr2 + 1;
			seg_cntr2 = Map_Display(dec_cntr2);
			    if (dec_cntr2 == 9) begin
				dec_cntr2 <= 0;
			    end
			end
		end    
	    else begin
		pos_cntr <= pos_cntr + 1;
		dig_cntr <= 1;
		disp_cntr = Seg_Display(pos_cntr, seg_cntr1, seg_cntr2);
	    end
	end
    end    
    
    assign Arduino_IO4 = disp_cntr[9] ;
    assign Arduino_IO5 = disp_cntr[8] ;
    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
 
List3

Copyright © ITmedia, Inc. All Rights Reserved.

ページトップに戻る