【FPGA】Verilog HDLで電子サイコロを作ってみた
久しぶりにFPGAのネタです。
ちょっと前にFPGAのボードを購入したという話をしましたが、あれから全く触っていませんでした(;^ω^)
【関連記事】
・FPGAの勉強のために揃えた物
なので、電子サイコロなるものを作ってみたので、今日はその件について記事を書こうと思います。
目次
スポンサーリンク
使用しているボード
使用しているのは、DE0というボードです。
@DE0 その1
@DE0 その2
詳しくは関連記事をご覧ください。
電子サイコロについて
ボタンを押すと、ランダムで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に動画を貼ったので、そちらをご覧ください。
まとめ
俺氏「またしょうもない物を作ってしまった・・・(石川五右衛門風に)」
多分、乱数ってこんな風に作られてるんでしょうね。クロック数に合わせて高速でカウントしていって、止まったときの数がランダムに見えるという仕組みなんでしょうね。
パチンコの「体感器」という装置は、こういった乱数の盲点を突いているんだと思います。
以上です!
ノシ
スポンサーリンク
関連記事