標(biāo)題: FPGA實(shí)現(xiàn)貪吃蛇游戲源程序 VGA顯示模塊 QuartusⅡ9.1代碼 [打印本頁(yè)]
作者: dlh、、 時(shí)間: 2022-3-5 20:12
標(biāo)題: FPGA實(shí)現(xiàn)貪吃蛇游戲源程序 VGA顯示模塊 QuartusⅡ9.1代碼
VGA原理簡(jiǎn)介
2.1.1 VGA定義
VGA即視頻圖像陣列的意思,時(shí)IBM公司在1987年隨ps/2一起推出的一種視頻傳輸標(biāo)準(zhǔn),具有分辨率高、顯示速度快、顏色豐富等優(yōu)點(diǎn),在彩色顯示領(lǐng)域得到了廣泛的應(yīng)用。VGA顯示器時(shí)陰極射線管顯示器,通過(guò)VGA顯示器接口和計(jì)算機(jī)內(nèi)部的顯卡相連。
2.1.2 VGA規(guī)格參數(shù)
實(shí)驗(yàn)用到的顯示器規(guī)格為640*480,具體參數(shù)如下:
行同步:
場(chǎng)同步:
2.1.3 彩色原理
人眼是根據(jù)所看見(jiàn)光的波長(zhǎng)來(lái)識(shí)別顏色的,這些顏色是根據(jù)三種基色按照不同的比例相互混合得到的,三種基本光色為紅、綠、藍(lán)三原色光,當(dāng)這三種光以不同的顏色比例混合,得到了不同的顏色(比如相同比例得到白色)。
在VGA顯示器上,R、G、B三種基色分別接到電子槍的陽(yáng)極,通過(guò)陰極發(fā)射電子,然后在電場(chǎng)的作用下,電子轟擊熒光粉層,熒光粉層發(fā)出不同強(qiáng)度的三種顏色光,根據(jù)空間混色法將三個(gè)基色光同時(shí)照射同一表面相鄰很近的三個(gè)點(diǎn)上進(jìn)行混色,可以產(chǎn)生不同的顏色,利用人眼在超過(guò)一定距離后分辨率下降的原理,可以得到較為清晰的顏色。
對(duì)于本實(shí)驗(yàn),只能顯示八種顏色,就是RGB分別用一位二進(jìn)制數(shù)表示,從而顯示8中顏色。
2.1.4 消隱脈沖和同步脈沖
同步脈沖:場(chǎng)同步和行同步
消隱脈沖:場(chǎng)消隱和行消隱
計(jì)算機(jī)顯示器采用逐行掃描顯示,從屏幕的左上方開(kāi)始,按照從左到右、從上到下的順序進(jìn)行掃描。每掃描完一行,行同步信號(hào)進(jìn)行行同步,會(huì)到下一行的起點(diǎn)進(jìn)行掃描。掃描完所有行后,即顯示了整個(gè)屏幕,用場(chǎng)同步信號(hào)進(jìn)行場(chǎng)同步,并且掃描回到屏幕左上方,進(jìn)行下一幀的刷新。
當(dāng)電子槍從某一行的末尾轉(zhuǎn)到下一行的開(kāi)頭時(shí),或者從屏幕最下面一行最后一個(gè)像素轉(zhuǎn)到左上角第一個(gè)像素位置時(shí),都需要一定的時(shí)間,這期間不需要發(fā)射電子,否則會(huì)干擾畫(huà)面。所以行同步場(chǎng)和同步信號(hào)要在需要顯示區(qū)域驅(qū)動(dòng)顯示器顯示,通過(guò)對(duì)行同步和場(chǎng)同步的設(shè)置,實(shí)現(xiàn)行消隱和場(chǎng)消隱。
2.1.5 VGA顯示原理
對(duì)于640*480*60hz的顯示器,工業(yè)標(biāo)準(zhǔn)的時(shí)鐘頻率為25.175hz,行周期為800個(gè)周期,場(chǎng)周期為525個(gè)周期,這些周期數(shù)也就對(duì)應(yīng)著時(shí)間。
計(jì)算機(jī)顯示器采用逐行掃描顯示,從屏幕的左上方開(kāi)始,按照從左到右、從上到下的順序進(jìn)行掃描。每掃描完一行,行同步信號(hào)進(jìn)行行同步,會(huì)到下一行的起點(diǎn)進(jìn)行掃描。掃描完所有行后,即顯示了整個(gè)屏幕,用場(chǎng)同步信號(hào)進(jìn)行場(chǎng)同步,并且掃描回到屏幕左上方,進(jìn)行下一幀的刷新。
每行800個(gè)時(shí)鐘脈沖,前640個(gè)時(shí)鐘頻率對(duì)應(yīng)前640個(gè)點(diǎn),在不同的時(shí)間輸出不同的顏色,在640到800時(shí)鐘頻率RGB輸出低電平,行計(jì)數(shù)器為648時(shí),場(chǎng)計(jì)數(shù)器加一或清零,行計(jì)數(shù)器為656到752時(shí),行同步信號(hào)為低電平,其他時(shí)刻為高電平;場(chǎng)計(jì)數(shù)器為490到492時(shí),場(chǎng)同步信號(hào)為低電平,其他時(shí)刻為高電平。因?yàn)檎麄(gè)過(guò)程是循環(huán)進(jìn)行的,從而顯示正常。
3 信號(hào)發(fā)生器設(shè)計(jì)
3.1軟件環(huán)境介紹
本實(shí)驗(yàn)使用的軟件是QuartusⅡ9.1。QuartusⅡ 是Altera公司為FPGA/CPLD芯片設(shè)計(jì)的集成化專用開(kāi)發(fā)工具,在QuartusⅡ上可以設(shè)計(jì)輸入、HDL綜合、布線布局、仿真、下載和硬件測(cè)試等整個(gè)設(shè)計(jì)流程,功能強(qiáng)大,被廣泛使用。
在早期, Max+plusⅡ 是Altera公司的開(kāi)發(fā)工具,現(xiàn)在已經(jīng)被QuartusⅡ代替。并且Max+plusⅡ已經(jīng)不再支持Altera公司的新器件,同時(shí),QuartusⅡ也放棄了對(duì)老器件的支持。QuartusⅡ具有Max+plusⅡ界面,上手簡(jiǎn)單,界面友好、使用便捷。
Altera Quartus Ⅱ提供了完整的設(shè)計(jì)環(huán)境,設(shè)計(jì)工具完全支持VHDL、Verilog和AHDL設(shè)計(jì)流程。QuartusⅡ也可以使用第三方的綜合工具,并且可以直接調(diào)用這些綜合工具;同時(shí)QuartusⅡ也支持第三方的仿真工具,如Modelism;QuartusⅡ與Matlab和DSP Builder結(jié)合,也可以進(jìn)行DSP系統(tǒng)開(kāi)發(fā)。
除此之外,Quartus還包含許多LPM模塊,在SOPC設(shè)計(jì)中被大量使用,也可以在普通設(shè)計(jì)文件一起使用。例如DSP模塊、PLL、各類(lèi)片上存儲(chǔ)器等。
QuartusⅡ還支持第三方EDIF文件輸入,并且提供了很多EDA軟件接口,支持層次化設(shè)計(jì),解決了原理圖和HDL混合輸入問(wèn)題。
3.4 VGA貪吃蛇游戲顯示設(shè)計(jì)
3.4.1模塊功能
VGA顯示模塊:主要實(shí)現(xiàn)VGA的顯示,hcnt,vcnt,hs,vs的設(shè)置。
靜態(tài)圖片模塊:這里顯示在貪吃蛇撞身顯示the end靜態(tài)圖案。
游戲背景模塊:貪吃蛇邊界設(shè)計(jì),設(shè)計(jì)了四堵墻,在顯示器顯示,在墻外有自己的名字英文縮寫(xiě)DLH顯示。
游戲控制模塊:貪吃蛇蛇身移動(dòng)及運(yùn)動(dòng)方向處理,蛇身撞身處理,蛇身吃到后自增處理和蛇身上限處理,隨機(jī)出現(xiàn)的食物方塊處理。這一模塊最為重要,將會(huì)重點(diǎn)進(jìn)行說(shuō)明。
連線模塊:將這些模塊連到一起,使最終下載到顯示器上的是可以顯示正確的圖案。
3.4.2貪吃蛇設(shè)計(jì)
VGA顯示模塊:
(1)分頻模塊:
這里通過(guò)二分頻,clk為輸入50mhz的頻率,在clk上升沿對(duì)clk25取反,就得到二分頻的clk25,頻率為25mhz:
always@(posedgeclk or negedge rst)
if(!rst) clk_25M=0;
else clk_25M=~clk_25M;
(2)顯示模塊:
設(shè)置了行計(jì)數(shù)器和場(chǎng)計(jì)數(shù)器hcnt、vcnt,行信號(hào)和場(chǎng)信號(hào)hs、vs。
按照先通過(guò)行同步頭/場(chǎng)同步頭,再通過(guò)后沿,再通過(guò)顯示區(qū)域,再到前沿完成一整個(gè)周期來(lái)計(jì)算:
hs行信號(hào)hcnt>=639+16并且hcnt<639+16+96輸出為0,其他輸出1;
vs場(chǎng)信號(hào)在vcnt>=479+10并且vcnt<479+10+2輸出為0,其他輸出1。
設(shè)置了坐標(biāo)位置,xpos和ypos,分別為hcnt-96-48和vcnt-2-33用于后面位置的表示。
當(dāng)hcnt和vcnt在顯示區(qū)域輸出rgb_sig, rgb_sig與后面的相對(duì)應(yīng)。
always@(posedgeclk_25M or negedge rst) begin
if(!rst) begin
h_cnt<=0;
v_cnt<=0;
end
else begin
if(h_cnt==(H_CNT_MAX-1))begin
h_cnt<=0;
if(v_cnt==(V_CNT_MAX-1))v_cnt<=0;
elsev_cnt<=v_cnt+10'd1;
end
else h_cnt<=h_cnt+10'd1;
end
end
靜態(tài)圖片和游戲背景模塊:
設(shè)置了the end和DLH靜態(tài)圖案,設(shè)置了四堵墻,這些設(shè)置方法基本相同,都是通過(guò)對(duì)hcnt和vcnt的范圍進(jìn)行設(shè)置,這里可以直接使用xpos和ypos,在規(guī)定的范圍內(nèi)填充RGB色彩即可。
例如對(duì)我的名字縮寫(xiě)而言,d的設(shè)置包括兩橫兩豎,對(duì)xpos和ypos進(jìn)行設(shè)置即可:
左右為10上下為20:
assign d1 = ((vga_xpos > 40 ) &&(vga_xpos < 50 ) && (vga_ypos > 20 ) && (vga_ypos < 40) );
左右為10上下為40:
assignd2 = ((vga_xpos > 70 ) && (vga_xpos < 80 ) && (vga_ypos> 0 ) && (vga_ypos < 40 ) );
左右為40上下為5:
assignd3 = ((vga_xpos > 40 ) && (vga_xpos <80 ) && (vga_ypos> 20 ) && (vga_ypos < 25 ) );
左右為40上下為5:
assignd4 = ((vga_xpos > 40 ) && (vga_xpos < 80 ) && (vga_ypos> 35 ) && (vga_ypos < 40 ) );
這樣就得到了小寫(xiě)d,通過(guò)這樣一直將背景和四堵墻的顯示設(shè)置好。對(duì)于四堵墻,這里只設(shè)置了在顯示器中顯示,而對(duì)四堵墻的邊界格擋作用,在游戲控制模塊進(jìn)行說(shuō)明。
游戲控制模塊:
(1)時(shí)鐘控制:在時(shí)鐘上升沿(25mhz頻率的時(shí)鐘),i自增,當(dāng)i到達(dá)摸個(gè)數(shù)值的時(shí)候,i清零,同時(shí)temp取反,這樣在后面的貪吃蛇移動(dòng)模塊,通過(guò)在temp上升沿移動(dòng),從而可以通過(guò)i的最大值來(lái)實(shí)現(xiàn)對(duì)速度的控制,這里設(shè)置i為4999999,如果想要更快,只需要慢速度即可。
(2)運(yùn)動(dòng)模塊:
首先設(shè)置了四種狀態(tài),來(lái)標(biāo)識(shí)運(yùn)動(dòng)方向,這四個(gè)狀態(tài)和ps/2鍵盤(pán)相連接,來(lái)完成對(duì)運(yùn)動(dòng)的控制。
if(P_left)
state<= left;
elseif(P_right)
state<= right;
elseif(P_down)
state<= down;
elseif(P_up)
state<= up;
我這里設(shè)置每個(gè)小貪吃蛇由10*10的像素方塊組成。設(shè)置了兩個(gè)數(shù)組m和n,代表左上角坐標(biāo),m數(shù)組代表左邊坐標(biāo),n代表上邊坐標(biāo)。
蛇頭運(yùn)動(dòng):對(duì)于貪吃蛇蛇頭運(yùn)動(dòng),通過(guò)rst信號(hào)對(duì)貪吃蛇初始位置進(jìn)行設(shè)定。當(dāng)貪吃蛇出邊界時(shí)(我們上面設(shè)置的四堵墻就是這里的邊界),四堵墻上下左右邊界值分別為:60,420,40,600。例如當(dāng)出左邊界時(shí)即m[0]<40的時(shí)候m【0】=600,實(shí)現(xiàn)當(dāng)出邊界時(shí)可以從對(duì)應(yīng)邊界回來(lái)。當(dāng)未出邊界時(shí),與上面的上下左右四種運(yùn)動(dòng)標(biāo)識(shí)對(duì)應(yīng),實(shí)現(xiàn)運(yùn)動(dòng)(加減10):
if(!rst)
beginm[0]<=200; n[0]<=200;end
elseif(m[0] > 600)
m[0]<= 40;
elseif(m[0] < 40)
m[0]<= 600;
elseif( n[0] > 420)
n[0]<= 60;
elseif( n[0] < 60)
n[0]<= 420;
elseif(hit)
beginm[0]<=0; n[0]<=0;the_end=1;end
else
begin
case(state)
left: m[0] <= m[0] - 12'd10;
right: m[0] <= m[0] + 12'd10;
down: n[0] <= n[0] + 12'd10;
up:n[0] <= n[0] - 12'd10;
default: m[0] <= m[0]+12'd10 ;
end case;
蛇身運(yùn)動(dòng):每當(dāng)設(shè)運(yùn)動(dòng)一次,m[a+1]就會(huì)代替m[a]的位置:
for(long_cnt=0; long_cnt<(2**N-1);long_cnt=long_cnt+1) begin
m[long_cnt+1]<= m[long_cnt];
n[long_cnt+1]<= n[long_cnt];
end
(3)撞身模塊:當(dāng)蛇頭和蛇身相撞時(shí),即為m[0]=m[a],n[0]=n[a]時(shí),結(jié)束游戲顯示屏顯示the end 界面。
(4)食物隨機(jī)出現(xiàn):設(shè)置一個(gè)初始的食物出現(xiàn)位置(300,300),通過(guò)吃到食物所用用的時(shí)鐘時(shí)間,來(lái)判斷下一個(gè)食物的位置。
設(shè)置了四個(gè)信號(hào)o,p,o_temp ,p_temp。在時(shí)鐘上升沿o_temp ,p_temp加10,當(dāng)吃到才會(huì)將o_temp 和p_temp賦值給o,p,實(shí)現(xiàn)了根據(jù)吃到食物所用的時(shí)間變位置(其實(shí)是一個(gè)偽隨機(jī)),其中change是用來(lái)判斷是否吃到的信號(hào),吃到為1,未吃到為0。
if(!rst)begin
p <= 300;//lie
o <= 300;//hang
end
else if(change)
begin
p <= p_temp;
o <= o_temp;
end
else if(o_temp > 400)
o_temp <= 100;
else if(o_temp <100)
o_temp <= 400;
else if(p_temp > 400)
p_temp <= 80;
else if(p_temp < 80)
p_temp <= 400;
else
begin
o_temp <= o_temp+ 10;
p_temp <= p_temp+ 10;
(5)吃食物:當(dāng)o和p和蛇頭坐標(biāo),m[0],n[0]對(duì)應(yīng)時(shí)吃到食物。吃到食物后相應(yīng)的蛇身也要增長(zhǎng):
(6)貪吃蛇顯示:貪吃蛇左上坐標(biāo)為m[a],n[a],坐標(biāo)在xpos和ypos的范圍內(nèi),例如蛇頭為m[0] <xpos < m[0] + 10并且n[0] < ypos < n[0] + 10這樣就可以在VGA上顯示。
連線模塊:這里就是將這些模塊,設(shè)置的信號(hào),連在一起,例如將每個(gè)模塊設(shè)置的顏色和VGA顯示模塊顏色先對(duì)應(yīng)、貪吃蛇坐標(biāo)對(duì)應(yīng)行計(jì)數(shù)器和場(chǎng)計(jì)數(shù)器等等。
此程序用Cyclone Ⅲ EP3C40Q240C8對(duì)應(yīng)引腳分配圖:
51hei.png (72.66 KB, 下載次數(shù): 70)
下載附件
2022-3-5 20:11 上傳
51hei.png (6.74 KB, 下載次數(shù): 83)
下載附件
2022-3-5 20:11 上傳
上圖壓縮包代碼下載,僅供參考:
基于FPGA的貪吃蛇小游戲(1).7z
(6.38 MB, 下載次數(shù): 33)
2022-3-5 20:10 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
歡迎光臨 (http://www.torrancerestoration.com/bbs/) |
Powered by Discuz! X3.1 |