【Verilog】基于FPGA的打地鼠小游戏设计(VGA显示、附代码、演示视频)
生活随笔
收集整理的這篇文章主要介紹了
【Verilog】基于FPGA的打地鼠小游戏设计(VGA显示、附代码、演示视频)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
基于FPGA的打地鼠小游戲設計
1、一個.v文件,便于讀者理解和使用;
2、游戲思路相關說明:
-
VGA顯示九宮格(地鼠洞穴)
-
綠色色塊(地鼠)、擊中地鼠(色塊變紅)
-
可調地鼠數量和地鼠出現速度
-
倒計時至零或數量達關卡目標即游戲結束;
3、使用資源:板載的5個按鍵、一個用于復位的撥碼開關;
4、阿汪先生用的板子型號為:xc7a35tcsg324-1 。
下列所有代碼可直接在各FPGA板上運行
`timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2019/05/21 09:48:34 // Design Name: // Module Name: VGA00 // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // //module VGA(clock,switch,disp_RGB,hsync,vsync,up,down,left,right,middle,rst ,QC_OUT,QA_OUT,led); input clock; //系統輸入時鐘100MHz input[1:0]switch; input rst; output [7:0] QC_OUT; output[3:0] QA_OUT; output [7:0] led; input up,down,left,right,middle; output[11:0]disp_RGB;//VGA數據輸出 output hsync;//VGA行同步信號 output vsync;//VGA場同步信號 reg [9:0] hcount; //VGA行掃描計數器 reg [9:0] vcount; //VGA場掃描計數器 reg [11:0] data; reg [11:0] h_dat; reg [11:0] v_dat; reg [11:0] x_dat; reg [11:0] data1; reg flag=0; wire hcount_ov; wire vcount_ov; wire dat_act; wire hsync; wire vsync; reg background=12'b010010000101; reg gezi=12'b01010100001; reg jieshuse=12'hf00; reg vga_clk=0; reg cnt_clk=0;//分頻計數always@(posedge clock) begin if(cnt_clk==1)begin vga_clk<=~vga_clk; cnt_clk<=0; end else cnt_clk<=cnt_clk+1; end //***************VGA驅動部分*****************8// //行掃描 // VGA行、場掃描時序參數表 parameter hsync_end =10'd95, hdat_begin=10'd143, hdat_end=10'd783, hpixel_end=10'd799, vsync_end=10'd1, vdat_begin =10'd34, vdat_end=10'd514, vline_end=10'd524;always@(posedge clock) begin if(cnt_clk==1)begin vga_clk<=~vga_clk; cnt_clk<=0; end else cnt_clk<=cnt_clk+1; end //***************VGA驅動部分*****************8// //行掃描always@(posedge vga_clk) beginif(hcount_ov)hcount<=10'd0;elsehcount <= hcount + 10'd1;end assign hcount_ov =(hcount==hpixel_end);//場掃描 always@(posedge vga_clk) begin if(hcount_ov) begin if(vcount_ov)vcount<=10'd0;else vcount<=vcount+10'd1;endendassign vcount_ov=(vcount==vline_end);//數據、同步信號assign dat_act=((hcount>=hdat_begin)&&(hcount<hdat_end))&&((vcount>=vdat_begin)&&(vcount<vdat_end));assign hsync=(hcount>hsync_end);assign vsync=(vcount>vsync_end);assign disp_RGB=(dat_act)?data:12'h00;//顯示圖像 /* always@(posedge vga_clk) begincase(switch[1:0])2'd0:data<=h_dat;2'd1:data<=v_dat;2'd2:data<=h_dat&v_dat;2'd3:data<=x_dat&h_dat&v_dat;endcase; end *///計時1秒 reg [28:0]jishu_1s=0; reg clk_1s=0;localparam tick=50000000; always @ (posedge clock) beginif(jishu_1s==tick)beginjishu_1s<=0;clk_1s=~clk_1s;endelsebeginjishu_1s<=jishu_1s+1;end end//計時50ms reg clk_50ms=0;localparam DVSR=5000000;reg [28:0] js; always @ (posedge clock) beginif(js==DVSR)beginjs<=0;clk_50ms=~clk_50ms;endelsebeginjs<=js+1;end end//產生豎長條 always@(posedge vga_clk) beginif(hcount<=220||hcount>=620)v_dat <= 12'h000;//heielse if(hcount==240 ||hcount ==360||hcount ==480||hcount==600)v_dat <= 12'h000;//heielse v_dat <= 12'hfff;//bai end//產生橫長條 always@(posedge vga_clk) beginif(vcount<=70||vcount>=470)h_dat <= 12'h000;//heielse if(vcount==90 ||vcount ==210||vcount ==330||vcount ==450)h_dat <= 12'h000;elseh_dat <= 12'hfff; //背景 endparameter WIDTH = 60, //矩形長HEIGHT = 60, //矩形寬//顯示區域的邊界DISV_TOP = 10'd120,DISV_DOWN =DISV_TOP+HEIGHT,DISH_LEFT = 10'd270,DISH_RIGHT = DISH_LEFT + WIDTH;//初始矩形的位置,在顯示區的左下角 reg [9:0] topbound =DISV_TOP;reg [9:0] downbound ;reg [9:0] leftbound = DISH_LEFT ;reg [9:0] rightbound ;reg [2:0] weizhi=0;//5個位置信息 always@(posedge clk_50ms) begincase(weizhi[2:0])3'b000:begin leftbound<=10'd390; //上topbound<=10'd120;end3'b001:begin leftbound<=10'd270;topbound<=10'd240; //左end 3'b010: begin leftbound<=10'd390;topbound<=10'd240; //中 end3'b011: beginleftbound<=10'd510;topbound<=10'd240; //右end 3'b100: beginleftbound<=10'd390;topbound<=10'd360; //下endendcase endreg flag_on=0; //按鍵位置與屏幕上地鼠位置相同,則改變屏幕上地鼠色塊的顏色always @(posedge clk_50ms) begin if( up==1 && weizhi==0 )beginflag<=1;// flag_on<=1;endelse if( left==1 && weizhi==1 )beginflag<=1;// flag_on<=1;endelse if( middle==1 && weizhi==2 )beginflag<=1;// flag_on<=1;endelse if( right==1 && weizhi==3 )beginflag<=1;flag_on<=1;endelse if( down==1 && weizhi==4 )beginflag<=1;// flag_on<=1;endelse beginflag<=0;// flag_on<=0;endend//4位數碼管顯示部分的變量定義 reg [7:0] Q1; reg [7:0] Q2; reg [7:0] Q3; reg [7:0] Q4; reg [7:0] Q; reg [7:0] Q_OUT; reg [5:0] i=0;//每過2秒色塊換一個位置 //20位的偽隨機數 wire [7:0] position[0:19]; assign position[0]=0; assign position[1]=4; assign position[2]=2; assign position[3]=1; assign position[4]=3; assign position[5]=0; assign position[6]=4; assign position[7]=1; assign position[8]=2; assign position[9]=4; assign position[10]=0; assign position[11]=2; assign position[12]=1; assign position[13]=3; assign position[14]=1; assign position[15]=0; assign position[16]=3; assign position[17]=2; assign position[18]=1; assign position[19]=4; reg [11:0]data2=12'h652;reg count_20=0; reg [5:0]num=0; reg [5:0]num1=0; reg [5:0]cnt_30ss=30; reg flag_kaishi=0;reg flag_jieshu=0;reg [4:0]cnt_30s=0;//地鼠出現時間及相關參數控制模塊always@(posedge clk_1s) begin i<=i+1; weizhi<=position[i];if(i>=19) i<=0;if(weizhi>=5) weizhi<=0;if(flag==1) num1<=num1+1;if(num1==30)begin num1<=0;x_dat<= data2; endif(rst==1) num1<=0;if( flag_kaishi ) cnt_30ss<=cnt_30ss-1;if(cnt_30ss==0) cnt_30ss<=0; end//著色一個小色塊always @(posedge clock) begin rightbound = leftbound + 10'd60 ;downbound = topbound + 10'd60;if( hcount >= leftbound && hcount <= rightbound && vcount<= downbound && vcount >= topbound && flag==0)x_dat<= 12'h0f0;else if( hcount >= leftbound && hcount <= rightbound && vcount<= downbound && vcount >= topbound && flag==1)beginx_dat<= 12'hf00; end else x_dat<=12'hfff; //黑色end //計數刷新,倒計時重新置數always@(posedge clock) beginif(rst==1)num<=0;cnt_30ss<=30; end//顯示圖像 always@(posedge clock) beginif(rst)begindata1<=h_dat&v_dat;cnt_30ss<=30;flag_kaishi<=0;flag_jieshu<=0;end//第一次進入或復位后,有按鍵按下,則進入游戲畫面if(!rst && up==1||down==1||left==1||right==1||middle==1)flag_kaishi=1;//游戲開始且游戲結束標志位未置一,則顯示游戲畫面if(!rst && flag_kaishi==1 && !flag_jieshu)data1<=x_dat&h_dat&v_dat;//倒計時30s結束,結束標志位置一if(cnt_30ss==0)beginflag_jieshu=1; end //顯示色彩及九宮格背景case(switch[1:0])2'd0:data<=data1;2'd1:data<=data1;2'd2:data<=data1;2'd3:data<=data2;endcase; endreg[28:0]jishu_96hz=0; //余暉至少要96Hz 100MHz/2^19=190.73Hz reg [2:0]hex_in;localparam tick1=200008;reg clk_96hz=0; reg clk_190;reg [7:0] QC_OUT;reg [3:0] QA_OUT; // reg [5:0]cnt_30s1=24;// reg [5:0] num1=26;//時鐘分頻96hz always@(posedge clock) beginif(jishu_96hz==tick1)beginjishu_96hz<=0;clk_96hz=~clk_96hz;endelsebeginjishu_96hz<=jishu_96hz+1;end end//數碼管顯示數值計算部分always@(posedge clock) beginnum=num1; Q1=num/10; Q2=cnt_30ss%10; Q3=cnt_30ss/10; Q4=num%10; end//數碼管譯碼always @(posedge vga_clk)begincase(Q)0: QC_OUT <= 8'b11111100; 1: QC_OUT <= 8'b01100000; 2: QC_OUT <= 8'b11011010; 3: QC_OUT <= 8'b11110010; 4: QC_OUT <= 8'b01100110; 5: QC_OUT<=8'b10110110; 6: QC_OUT<=8'b10111110; 7: QC_OUT<=8'b11100000; 8: QC_OUT<=8'b11111110; 9: QC_OUT<=8'b11110110; default: QC_OUT <= 8'b00000000; endcase end//數碼管片選always@(posedge clk_96hz )case(QA_OUT)4'd1:beginQ<=Q1;QA_OUT<= 2; end4'd2:beginQ<=Q2;QA_OUT<=4;end4'd4:beginQ<=Q3; QA_OUT<=8;end4'd8:beginQ<=Q4;QA_OUT<=1;enddefault : begin QA_OUT<=4'b0001;endendcase//阿汪先生的博客.ws endmodule實際效果:
演示視頻.
總結
以上是生活随笔為你收集整理的【Verilog】基于FPGA的打地鼠小游戏设计(VGA显示、附代码、演示视频)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络流 练习
- 下一篇: excel公式不执行。原因是设置问题:公