FPGA模擬擲骰子

2021-08-20 19:56:05 字數 3446 閱讀 7914

每按同乙個按鍵時會隨機得到乙個1—6中的乙個隨機數字,並用數碼管顯示得到的數值。對兩次按鍵得到的數值進行比較,若前者大,則最低兩位led顯示為「亮」、「滅」,後者較大,則最後兩位led顯示狀態改為「滅」、「亮」。

本次課程設計的實質是使數碼管隨機顯示乙個數字,以達擲骰子時隨機出數的效果,因此在小組討論並查閱資料後我們總結出以下兩種方案:

1.     查詢fpga中是否含有類似於c語言中rand()的隨機函式,並搞清楚其用法和效果,弄清楚後進行實驗,並在按下按鍵後使隨機函式發生作用,並顯示該資料,再將資料存入內部變數,並在其內部進行比較,將比較結果對映到led最後兩位進行顯示。

2.     類似於***一樣,讓數碼管顯示1~6六個數字,並高速滾動,然後通過按鍵暫停並顯示,由於數碼管顯示數字在高速滾動狀態下,人眼無法準確分清楚此時是什麼數字,所以根據概率學來說六個數字每個具有等可能性,這樣就能保證暫停的數字具有隨機性,儲存和比較模組原理與方案1相似。

方案選擇

由於第一種方案在實施起來時沒有像第二種的***一樣,使人感覺有互動性,並且用函式隨機顯示數字會讓人感覺突兀,並像是在「出千」。因此我們選用第二種方案進行本次課程設計

由於cyclone iv板載系統時鐘為50mhz,時鐘頻率過大,無法表現出程式效果(或者效果不明顯),所以我們需要分頻。

分頻器原理:以系統時鐘上公升沿為標準,對系統時鐘的上公升沿計數,並給出乙個訊號變數(或普通變數)給出初值,計夠一定次數以後對其變數電平反轉,即通過電平反轉重新造出來乙個方波,以達到分頻的目的。例如:對50mhz時鐘二分頻,就是對系統時鐘上公升沿計數,當機構2499999個數時對電平變數chz1進行反轉,即可得到乙個以0.5ms為週期的方波,則分頻計算公式:

分頻器程式:

ck:process(clk)                            --分頻器程式

begin

ifrising_edge(clk) then

ift="0000011010111100000111111" then—此處數值沒有具體計算

t<="0000000000000000000000000";

clk1hz<=notclk1hz;

else

t<=t+1;

endif;

endif;

end process ck;

結構體中數字掃瞄:將數字掃瞄模組寫在結構體中,使fpga在執行程式時能夠迴圈掃瞄數字,使數碼管高速滾動數字。達到每個在暫停時,停止的每個數字具有等可能性。

結構體中數字掃瞄:

output<="1111001"wheninput="0001"else—本程式寫在結構體的begin下

"0100100"wheninput="0010"else

"0110000"wheninput="0011"else

"0011001"wheninput="0100"else

"0010010"wheninput="0101"else

"0000011"wheninput="0110";

程序中數字掃瞄:定義中間變數,對其進行1-6的迴圈加一計數,然後再將其送到數碼管顯示。

程序中數字掃瞄:

if (clk1hz'event and clk1hz='1')then

if(a='1' and b='1') then

tmp:=tmp+1;

if(tmp=7) then

tmp:=1;

endif;

case tmp is

when 1=> input<="0001";

when 2=> input<="0010";

when 3=> input<="0011";

when 4=> input <="0100";

when 5=> input<="0101";

when 6=> input<="0110";

when others => input<="0000";

end case;

endif;

end if;

本次課程設計我們想用撥碼開關以代替按鍵,本以為撥碼開關不需要按鍵消抖但最終的實驗效果卻不盡如人意,仍需要按鍵消抖,所以本次設計時我們改了一下,利用兩個按鍵對其進行暫停。如果用乙個按鍵或撥碼開關,必須要加按鍵消抖,否則會有一定干擾。

消抖原理:類似於51微控制器按鍵消抖,先檢驗其是否按下,若被按下則延時一定時間,將其電平振盪的時間「濾」掉(在fpga則數5ms的系統時鐘過濾掉電平振盪的時間)。

按鍵暫停以及儲存程式:

if(a='0') then

tim:=tim+1;

if(tim=1) then

ran1<=tmp;

elsif(tim=2) then

ran2<=tmp;

endif;

endif;

注意:本模組程式未加按鍵消抖程式,如用單一按鍵需對按鍵加消抖程式。

乙個按鍵的暫停草稿程式(加有消抖,但並未實踐)

if(a='0') then

ifrising_edge(clk) then

ift="0010011010111100000111111" then--此處數值沒有具體計算

t<="0000000000000000000000000";

else

t<=t+1;

endif;

endif;

waituntil(t=」0010011010111100000111111」);

if(a=」0」)then

tim:=tim+1;

if(tim=1) then

ran1<=tmp;

elsif(tim=2) then

ran2<=tmp;

endif;

endif;

end if

在程式內部定義兩個變數(由於總開關為閉合狀態所以不用考慮掉電保護問題),用於儲存先後兩次按鍵按下的數字,然後對其變數進行比較若前者較大對映到led則最後兩個燈顯示為「亮」、「滅」,反之後者大則led顯示為「滅」、「亮」。

比較模組程式:

compare:process(ran1,ran2)

begin

if (ran1>ran2) then

led<="01";

elsif (ran1led<="10";

elsif (ran1=ran2) then

led<="00";

end if;

end process compare;

在本次設計中,我們對兩種方案進行考量,最終選擇較為方便實現的方案,並且具有一定互動性。個人認為該方案的實現效果更好,但唯一的遺憾就是沒有用乙個按鍵實現數字暫停。因為在當時的情況下本人事情較多,無法考慮更多的情況,對於消抖的延時沒有想清楚原理,所以沒有大膽的實踐。時間緊任務重只能選擇最優方案。

模擬擲骰子(Python)

模擬擲骰子實際是抽取 1 6之間的 隨機數問題,涉及random模組,後面版本的資料視覺化主要應用matplotlib.pyplot模組。1.0 模擬乙個骰子的結果。首先定義roll dice 函式,從1 6之間隨機抽取乙個整數作為擲骰子的結果。在主函式中定義乙個長度為6的列表 初始值為0 記錄每個...

使用Pygal模擬擲骰子

將使用python視覺化包pygal來生成可縮放的向量圖形檔案。對於需要在尺寸 不同的螢幕上顯示的圖表,這很有用,因為它們將自動縮放,以適合 者的螢幕。使用pygal來建立直方圖 from random import randint class die 表示乙個骰子的類 def init self,...

leetcode演算法題 擲骰子模擬

動態規劃 dp i j k 表示投擲第i次,點數為j,k表示連續次數狀態轉移 j出現一次的組合數等於上一輪投出非點數j的所有情況和 dp i j 1 sum dp i 1 j 本輪投出連續k次的點數j的數量情況等於上一輪連續投出k 1次的點數j的數量情況 dp i j k dp i 1 j k 1 ...