You are on page 1of 11

SNAKE Game on S3E FPGA kit

[ Developed using Verilog only ]


 

 
 
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. 

 
Schematic Diagram
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

B[4]
Old Tail Location is lost

B[3]

B[2]

B[1]
Updated head location
B[0]

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
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.
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
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.
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
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.
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 )
Visit
http://www.hypernucldie.com
for more projects

You might also like