meideru blog

家電メーカーで働いているmeideruのブログです。主に技術系・ガジェット系の話を書いています。

【FPGA】Verilog HDLで電子サイコロを作ってみた

      2018/10/20

久しぶりにFPGAのネタです。

ちょっと前にFPGAのボードを購入したという話をしましたが、あれから全く触っていませんでした(;^ω^)

【関連記事】
FPGAの勉強のために揃えた物

なので、電子サイコロなるものを作ってみたので、今日はその件について記事を書こうと思います。

使用しているボード

使用しているのは、DE0というボードです。

@DE0 その1
DE0の箱

 

@DE0 その2
DE0

 

詳しくは関連記事をご覧ください。

電子サイコロについて

ボタンを押すと、ランダムで0~6の数字が出るようにします。

参考にした本

「入門Verilog HDL記述」という本を参考にしました。

この本の中に「電子サイコロ」という項目があったので、それをベースにプログラムを書いてみました。

と言っても、ほとんど私が自作して書いたので、本の内容とは違うプログラムになっています。

ソースコード

主に3つのソースコードから構成されています。

Main.v

/* 全体部 */
module Main(
	input CLOCK_50,		// クロック信号
	input [2:0] BUTTON,	// ボタン(プルダウン)
	output [6:0] HEX0_D	// 7セグ
);

/* 配線 */
wire button;	// ボタン

/* レジスタ */
reg [3:0] cnt, cnt2;

/* モジュール */
RemChat RemChat1(CLOCK_50, BUTTON[0], button);	// チャタリング除去
Seg7Decoder Seg7Decoder1(cnt2, HEX0_D);		// 7セグデコーダ

/* ボタン入力 */
always @(negedge button)begin
	cnt2 <= cnt;
end

/* さいころを回転させておく */
always @(posedge CLOCK_50)begin
	if(cnt == 4'd6)
		cnt <= 4'd0;
	else
		cnt <= cnt + 4'd1;
end

endmodule

 

Main.vは全体部です。これがメインのソースコードとなります。

RemChat.v

/* チャタリング除去回路 */
module RemChat(
	input CLK,					// クロック信号
	input BTN,					// ボタン入力信号
	output reg OUT				// 出力信号
);

/* 50MHz→40Hzに分周する */
reg [20:0] cnt;
wire en40hz = (cnt==1250000-1);

/* cntのカウントアップとリセット */
always @(posedge CLK) begin
	if(en40hz)
		cnt <= 21'b0;
	else
		cnt <= cnt + 21'b1;
end

/* ボタン入力をFF2個で受ける */
reg ff1, ff2;

/* スイッチの値を取り込む */
always @(posedge CLK) begin
	if(en40hz) begin
		ff2 <= ff1;
		ff1 <= BTN;
	end
end

/* ボタンは押すと0なので、立下りを検出 */
wire temp = ~ff1 & ff2 & en40hz;

/* 念のためFFで受ける */
always @(posedge CLK) begin
	OUT <= temp;
end

endmodule

 

RemChat.vは、ボタンを押したときのチャタリングを除去するプログラムです。

ボタンが押されてから20ms遅延させることによってチャタリングを除去するという仕組みです。

Seg7Decoder.v

/* 7セグのデコーダ */
module Seg7Decoder (
	input	[3:0]	DIN,			// 入力信号
	output reg [6:0] OUT		// 出力
);

/* デコード部 */
always @* begin
	case(DIN)
		4'h0:	OUT = 7'b1000000;
		4'h1: OUT = 7'b1111001;
		4'h2: OUT = 7'b0100100;
		4'h3: OUT = 7'b0110000;
		4'h4: OUT = 7'b0011001;
		4'h5: OUT = 7'b0010010;
		4'h6: OUT = 7'b0000010;
		4'h7: OUT = 7'b1011000;
		4'h8: OUT = 7'b0000000;
		4'h9: OUT = 7'b0010000;
		4'ha: OUT = 7'b0010000;
		4'hb: OUT = 7'b0000011;
		4'hc: OUT = 7'b1000110;
		4'hd: OUT = 7'b0100001;
		4'he: OUT = 7'b0000110;
		4'hf: OUT = 7'b0001110;
		default:OUT = 7'b0000000;
	endcase
end

endmodule

 

Seg7Decoder.vは、7セグのデコーダです。

仕組み

50MHzのクロック信号に合わせて、さいころの目をカウントしていき、ボタンを押した瞬間のカウントを7セグに表示します。

実際の動作

YouTubeに動画を貼ったので、そちらをご覧ください。

まとめ

俺氏「またしょうもない物を作ってしまった・・・(石川五右衛門風に)」

多分、乱数ってこんな風に作られてるんでしょうね。クロック数に合わせて高速でカウントしていって、止まったときの数がランダムに見えるという仕組みなんでしょうね。

パチンコの「体感器」という装置は、こういった乱数の盲点を突いているんだと思います。

 

以上です!

ノシ

 - 技術系