arcade snake game using verilog

11
SNAKE Game on S3E FPGA kit [ Developed using Verilog only ]

Upload: hypernuclide

Post on 04-Apr-2015

4.928 views

Category:

Documents


4 download

DESCRIPTION

A code for arcade snake game in verilog on VGA

TRANSCRIPT

Page 1: Arcade Snake game using verilog

SNAKE Game on S3E FPGA kit [ Developed using Verilog only ]

 

 

 

 

 

 

 

 

 

 

 

 

  

Page 2: Arcade Snake game using verilog

Introduction The main objective of the game is to feed the snake with as much food as possible. The snake moves continuously, with the user controlling the direction of the snake's head (up, down, left, or right) with the help of pushbuttons on the S3E FPGA kit. Furthermore, the snake‟s length grows a block with every block of food eaten. The trick is to grow as long as possible until it reaches the “You Won” window without bumping into the snake‟s body or touching the walls. This becomes tricky when a really long snake has to move in the limited space provided by VGA display. Each time the snake eats a piece of food, its body grows longer. The player cannot stop the snake from moving while the game is in progress. The display component will be handled by using a VGA interface. There are 3 levels in the game and in each level the snake increases by 5X where X is level number and also the speed at which the snake moves is increased. A brief description of project is as follows. The snake body has been generated by using a stack which stores the locations and when the snake is moving around the body parts behind the snake keep copying the locations of the head. In this way we can create a snake which can bend while turning. The food for the snake is generated by using a random generator. Rules 1) What is the goal of the game? The goal is to eat food while avoiding losing the snake's lives. The higher the level you are playing on, the more the speed of the game will be. Therefore the Higher the level makes the game play faster. We are totally using 3 levels for this game. The speed at which the snake moves in level 3 will comparably faster to that of level 1. 2) What kills my snake? When is the game over? The snake dies if its head collides with its body or with the walls. So, the snake shouldn‟t run in to the walls or touch itself. 3) What happens when my snake eats food? Each time the snake eats food, the snake grows one unit longer in a level. Every time a block of food is eaten by the snake, a new food will appear on the screen. 4) Controls for the game? Pushbuttons are used as the inputs which act as the direction for the snake movement. 

 

 

 

 

 

 

 

 

 

 

 

 

 

Page 3: Arcade Snake game using verilog

Schematic Diagram

Page 4: Arcade Snake game using verilog

Icon module bot_icon (

input [7:0] pixel_col,

input [7:0]pixel_row,

input [7:0] LocX_reg,

input [7:0] LocY_reg,

input [7:0] Food_locX,

input [7:0] Food_locY,

input clk,

input reset,

input icon_tick,

input ctrl_off,

output reg [2:0] icon,

output reg [7:0]s_len = 8'd10,

output reg game_over = 0,

output reg food_gen = 0

);

Features:

Snakes body generation

Variable change in length when level changes

Food eating

Game over logic

The pixel_col & pixel_col are input which come from the dtg module LocX_reg & LocY_reg are the

inputs from snake_movement module this is the head movement of the snake.The head location is stored in

the body_stack[0].

Body Stack:

All the body locations are stored in a stack.The below figure shows how the body locations are

modified each time the head location of the snake changes its location

Old Tail Location is lost

Updated head location

Body stack

The new head locations are generated by pressing the push buttons or from the snake movement module.

This module also checks if the food is getting generated in the specified region. The following snippet of

code shows how this is done.

if (ctrl_off ==0 &&(Food_locX > 8'h89 || Food_locY > 8'h6D || Food_locX < 8'h11 || Food_locY < 8'h0B))

Here 8‟h89 , 8‟h6D are the boundaries for the column and 8,h11 and 8‟h0B are the boundaries for the row.If

this condition satisfies the food generation flag is set high which will generate the new location for the food.

Food Eating and Variable lengths for different levels: if(ctrl_off == 0 && body_stack[0]=={Food_locX,Food_locY}) begin //Check if the head

location of the snake is eual tothe location of the food

B[4]

B[3]

B[2]

B[0]

B[1]

Page 5: Arcade Snake game using verilog

food_gen = 1; //If the above condition is met the food_gen is set high to

generate the new location for the food

/*The levels of the snake game are based on the updating length of the snake !*/

if( s_len == 8'd8 ) /*Contion to jump from lvl - 1 to lvl - 2*/

s_len = s_len + 8'd5;

else if(s_len == 14) /*Contion to jump from lvl - 2 to lvl - 3*/

s_len = s_len + 8'd10;

else if( s_len == 25) /*Contion to jump from lvl - 3 to You Won !*/

s_len = s_len + 8'd15;

else

s_len = s_len + 8'd1; /*When the snake is in a particular level its body

increments by 1 when it eats food */

end

else begin

food_gen = 0;

end

Depending on the length of the snake the levels are designed and depending on the levels the length of the

snake will be changing hence by length of the snake depends on the length for each level. The condition for

changing the levels is discussed in snake movement module.

The following condition checks if the snake ate the food body_stack[0]=={Food_locX,Food_locY}

At the same time food generation flag is set high.

Game Over: for(j=100;j>=1;j=j-1) begin

if( (body_stack[0] == body_stack[j]) &&(j <= s_len))begin

game_over = 1;

end

else begin

j=j;

end

end

if ( (s_len >= 8'd40)||( body_stack[0][15:8] == 8'h91 )|| ( body_stack[0][15:8]

== 8'h10 )|| ( body_stack[0][7:0] == 8'h6F )||( body_stack[0][7:0] == 8'h0A ) )

game_over = 1;

end

If the head location of the snake equals any of the body locations it indicates that the snake bit itself and

hence the game_over register will bet set high.The game_over register will also be set high when the snake

head hits the wall boundary or when the snake length >= 8’d40.Since initially some meta-stability problems

Are encountered game_over register is again set to 0.The meta-stability problem is handled in snake

movement module.

Page 6: Arcade Snake game using verilog

Snake Movement module snake_movement(

input clk,

input reset,

input game_over,

input db_btn_west,

input db_btn_east,

input db_btn_north,

input db_btn_south,

output [7:0] LocSX,

output [7:0] LocSY,

input [7:0] s_len,

output reg icon_tick = 0,

output reg ctrl_off=0

);

Features:

Variable snake speeds for different levels

Snake movement based on the user inputs

Handling meta-stability

Variable snake speeds for different levels: always @(posedge icon_tick) begin

if(s_len >= 8'd6 && s_len <= 8'd8)begin

snake_speed = snake_cnt1;

end

else if(s_len >= 8'd13 && s_len <= 8'd14) begin

snake_speed = snake_cnt2;

end

else begin

snake_speed = snake_cnt3;

end

……………………………………………………………..

……………………………………………………………..

end

The icon is generated at icon_tick frequency so changing the clock speed will change the speed of the snake

on the display. The speed changes based on the length of the snake[ i.e different levels ].These conditions

indicate different levels. Based on different levels the speeds are stored in the snake_speed register and this

snake_speed register determines the icon_tick frequency, this is a feedback network.

Snake movement based on the user inputs:

Suppose the snake is moving in the east direction and the user presses the east button or west button the

snake moves in the direction of east unaffected. This is handled by the following code if ( user_inputs == 4'b0010 && current_heading != 4'b0001 && current_heading !=

4'b0010)begin

current_heading = 4'b0010;

end

else if ( user_inputs == 4'b0001 && current_heading != 4'b0001 && current_heading

!= 4'b0010)begin

current_heading = 4'b0001;

end

else if ( user_inputs == 4'b0100 && current_heading != 4'b0100 && current_heading

!= 4'b1000)begin

current_heading = 4'b0100;

end

Page 7: Arcade Snake game using verilog

else if ( user_inputs == 4'b1000 && current_heading != 4'b0100 && current_heading

!= 4'b1000)begin

current_heading = 4'b1000;

end

The following case statement takes care of the movement of the snake as follows if(reset) begin

LocSX_reg = 8'h40;

LocSY_reg = 8'h40;

end

else begin

case(current_heading)

4'b0001: LocSX_reg = LocSX_reg - 1;

4'b0010: LocSX_reg = LocSX_reg + 1;

4'b0100: LocSY_reg = LocSY_reg - 1;

4'b1000: LocSY_reg = LocSY_reg + 1;

endcase

end

Handling meta-stability:

The game over flag is set high initially while resetting the game.This has been handled as follows always @ (posedge game_over or posedge reset) begin

if (reset) begin

ctrl_off = 0;

k = 0;

end

else begin

k = k + 1;

if(game_over && (k > 1))

ctrl_off = 1;

end

end

The offset value for k register is purely based on observation.

Page 8: Arcade Snake game using verilog

Snake World module snake_world(

input [7:0] pixel_col,

input [7:0] pixel_row,

input rand_en,

input ctrl_off,

input [7:0] s_len,

output reg [7:0] LocX = 8'h43,

output reg [7:0] LocY = 8'h43,

output reg [1:0] food_icon,

output reg [1:0] snake_world_pixels

);

Features:

Dynamic Text generation

Random generation of locations for food

The complete snake world is designed using the dynamic display which highlights particular row and

column. Using this method we can display texts and different shapes used for the project.

From the above figure, assigning specific pixel column and pixel row highlights that block on the VGA

display depending on the color given to that block.

Dynamic Text generation: if (pixel_col > 8'h30 && pixel_col < 8'h3D && pixel_row > 8'h23 && pixel_row <

8'h27) begin

snake_world_pixels = 2'b10;

end

else if (pixel_col > 8'h30 && pixel_col < 8'h34 && pixel_row > 8'h26 &&

pixel_row < 8'h2D) begin

snake_world_pixels = 2'b10;

end

else if (pixel_col > 8'h30 && pixel_col < 8'h3D && pixel_row > 8'h2C &&

pixel_row < 8'h30) begin

snake_world_pixels = 2'b10;

end

else if (pixel_col > 8'h39 && pixel_col < 8'h3D && pixel_row > 8'h29 &&

pixel_ow < 8'h2D) begin

snake_world_pixels = 2'b10;

end

Page 9: Arcade Snake game using verilog

The above code snippet generates the letter „G‟ dynamically on the VGA display. Selecting specific pixel

columns and pixel rows highlights that specific block of display and colors it with assigned color using the

colorizer. All different letters used for the display in the final were generated by assigning the pixel coloumn

and pixel row values. This way it is very easy to display some cool text and images on the screen without

compromising the display clarity.

Random generation of locations for food

always@(*) begin

locX_reg = ((x + 4271)*4273 - 9973*3)*57;

locY_reg = ((y + 3343)*3347 - 9857*3)*55;

x = locX_reg;

y = locY_reg;

end

Consider the equation((x + 4271)*4273 - 9973*3)*57.Substitute a value for x it will generate a a large

number but observe that the locX_reg , x registers are only 8-bit wide hence the only the first 8-bits will be

selected and remaining all bits will be ignored and at the end of the always block the x,y store the values of

locX_reg and locY_reg.This x,y values will be substituted in the equations again this is like afeedback and

each time a value is generated only the last 8-bits will be taken.And also observe that the always block is

free running.Check the below snippet of code how this will be used to create bounds for the generated pixel

locations.

Page 10: Arcade Snake game using verilog

DTG

The actual image is obtained by a sequence of horizontal lines that are constantly refreshed. The

screen refresh process begins in the top left corner and paints one block at a time from left to right. At the

end of the first row, the row increments and the column address are reset to the first column. Once the entire

screen has been painted the refresh process begins again from the top left corner. The horiz_sync and

ver_sync were used to generate horizontal (VGA_hsync) and vertical (VGA_vsync) synchronized signals

for VGA monitor respectively. They are pulse signals which indicate the beginning of a new frame or row.

The pictures displayed on the VGA screen are realized by setting appropriate pixel values. Each pixel point

on the screen has its exclusive X and Y coordinate

System signal for VGA

The DTG (Display Timing Generator) gets the 25MHZ pixel clock as an input and produces the

vert_sync and horiz_sync which are used to control the horizontal and vertical scans on the monitor. These

two signals are decoded from the internal counters, whose outputs are the pixel_coloumn and pixel_row

signals. These two signals indicate the relative positions of the scnas and specify the current location of the

block. The DTG also generates the video_on signal to indicate whether to enable or disable the display.

Colorizer

The colorizer module maps the background, icon and the food to the screen based on their priority.The order

of priority is as follows with highest priority on the top and least at the bottom

Icon ( red )

Food ( green )

Background Text ( blue )

Page 11: Arcade Snake game using verilog

Visit http://www.hypernucldie.com

for more projects